Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions drivers/clk/spacemit/ccu-k1.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,33 @@ CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), MPMU_ACGR, BIT(14), 0);
CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), MPMU_ACGR, BIT(16), 0);

CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc), MPMU_ACGR, BIT(1), CLK_IGNORE_UNUSED);
CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, 16, 13, 0, 13, 0);
CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, 16, 13, 0, 13, 0);
CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, 16, 13, 0, 13, 2, 0);
CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, 16, 13, 0, 13, 2, 0);

CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), MPMU_WDTPCR, BIT(1), 0);

CCU_FACTOR_GATE_DEFINE(i2s_sysclk, CCU_PARENT_HW(pll1_d16_153p6), MPMU_ISCCR, BIT(31), 50, 1);
CCU_FACTOR_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_sysclk), MPMU_ISCCR, BIT(29), 1, 1);
CCU_FACTOR_DEFINE(i2s_153p6, CCU_PARENT_HW(pll1_d8_307p2), 2, 1);

static const struct clk_parent_data i2s_153p6_base_parents[] = {
CCU_PARENT_HW(i2s_153p6),
CCU_PARENT_HW(pll1_d8_307p2),
};
CCU_MUX_DEFINE(i2s_153p6_base, i2s_153p6_base_parents, MPMU_FCCR, 29, 1, 0);

static const struct clk_parent_data i2s_sysclk_src_parents[] = {
CCU_PARENT_HW(pll1_d96_25p6),
CCU_PARENT_HW(i2s_153p6_base)
};
CCU_MUX_GATE_DEFINE(i2s_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR, 30, 1, BIT(31), 0);

CCU_DDN_DEFINE(i2s_sysclk, i2s_sysclk_src, MPMU_ISCCR, 0, 15, 15, 12, 1, 0);

CCU_FACTOR_DEFINE(i2s_bclk_factor, CCU_PARENT_HW(i2s_sysclk), 2, 1);
/*
* Divider of i2s_bclk always implies a 1/2 factor, which is
* described by i2s_bclk_factor.
*/
CCU_DIV_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_bclk_factor), MPMU_ISCCR, 27, 2, BIT(29), 0);

static const struct clk_parent_data apb_parents[] = {
CCU_PARENT_HW(pll1_d96_25p6),
Expand Down Expand Up @@ -756,6 +776,10 @@ static struct clk_hw *k1_ccu_mpmu_hws[] = {
[CLK_I2S_BCLK] = &i2s_bclk.common.hw,
[CLK_APB] = &apb_clk.common.hw,
[CLK_WDT_BUS] = &wdt_bus_clk.common.hw,
[CLK_I2S_153P6] = &i2s_153p6.common.hw,
[CLK_I2S_153P6_BASE] = &i2s_153p6_base.common.hw,
[CLK_I2S_SYSCLK_SRC] = &i2s_sysclk_src.common.hw,
[CLK_I2S_BCLK_FACTOR] = &i2s_bclk_factor.common.hw,
};

static const struct spacemit_ccu_data k1_ccu_mpmu_data = {
Expand Down
12 changes: 6 additions & 6 deletions drivers/clk/spacemit/ccu_ddn.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@

#include "ccu_ddn.h"

static unsigned long ccu_ddn_calc_rate(unsigned long prate,
unsigned long num, unsigned long den)
static unsigned long ccu_ddn_calc_rate(unsigned long prate, unsigned long num,
unsigned long den, unsigned int pre_div)
{
return prate * den / 2 / num;
return prate * den / pre_div / num;
}

static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn,
unsigned long rate, unsigned long prate,
unsigned long *num, unsigned long *den)
{
rational_best_approximation(rate, prate / 2,
rational_best_approximation(rate, prate / ddn->pre_div,
ddn->den_mask >> ddn->den_shift,
ddn->num_mask >> ddn->num_shift,
den, num);
return ccu_ddn_calc_rate(prate, *num, *den);
return ccu_ddn_calc_rate(prate, *num, *den, ddn->pre_div);
}

static long ccu_ddn_round_rate(struct clk_hw *hw, unsigned long rate,
Expand All @@ -58,7 +58,7 @@ static unsigned long ccu_ddn_recalc_rate(struct clk_hw *hw, unsigned long prate)
num = (val & ddn->num_mask) >> ddn->num_shift;
den = (val & ddn->den_mask) >> ddn->den_shift;

return ccu_ddn_calc_rate(prate, num, den);
return ccu_ddn_calc_rate(prate, num, den, ddn->pre_div);
}

static int ccu_ddn_set_rate(struct clk_hw *hw, unsigned long rate,
Expand Down
6 changes: 4 additions & 2 deletions drivers/clk/spacemit/ccu_ddn.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ struct ccu_ddn {
unsigned int num_shift;
unsigned int den_mask;
unsigned int den_shift;
unsigned int pre_div;
};

#define CCU_DDN_INIT(_name, _parent, _flags) \
CLK_HW_INIT_HW(#_name, &_parent.common.hw, &spacemit_ccu_ddn_ops, _flags)

#define CCU_DDN_DEFINE(_name, _parent, _reg_ctrl, _num_shift, _num_width, \
_den_shift, _den_width, _flags) \
_den_shift, _den_width, _pre_div, _flags) \
static struct ccu_ddn _name = { \
.common = { \
.reg_ctrl = _reg_ctrl, \
Expand All @@ -33,7 +34,8 @@ static struct ccu_ddn _name = { \
.num_mask = GENMASK(_num_shift + _num_width - 1, _num_shift), \
.num_shift = _num_shift, \
.den_mask = GENMASK(_den_shift + _den_width - 1, _den_shift), \
.den_shift = _den_shift, \
.den_shift = _den_shift, \
.pre_div = _pre_div, \
}

static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw)
Expand Down
4 changes: 4 additions & 0 deletions include/dt-bindings/clock/spacemit,k1-syscon.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@
#define CLK_I2S_BCLK 30
#define CLK_APB 31
#define CLK_WDT_BUS 32
#define CLK_I2S_153P6 33
#define CLK_I2S_153P6_BASE 34
#define CLK_I2S_SYSCLK_SRC 35
#define CLK_I2S_BCLK_FACTOR 36

/* MPMU resets */
#define RESET_WDT 0
Expand Down
1 change: 1 addition & 0 deletions include/soc/spacemit/k1-syscon.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ to_spacemit_ccu_adev(struct auxiliary_device *adev)

/* MPMU register offset */
#define MPMU_POSR 0x0010
#define MPMU_FCCR 0x0008
#define POSR_PLL1_LOCK BIT(27)
#define POSR_PLL2_LOCK BIT(28)
#define POSR_PLL3_LOCK BIT(29)
Expand Down
Loading