Commit d5e6072b authored by Russell King's avatar Russell King Committed by Russell King

[ARM] omap: handle RATE_CKCTL via .set_rate/.round_rate methods

It makes no sense to have the CKCTL rate selection implemented as a flag
and a special exception in the top level set_rate/round_rate methods.
Provide CKCTL set_rate/round_rate methods, and use these for where ever
RATE_CKCTL is used and they're not already overridden.  This allows us
to remove the RATE_CKCTL flag.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9a5fedac
...@@ -216,9 +216,6 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) ...@@ -216,9 +216,6 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
struct clk * parent; struct clk * parent;
unsigned dsor_exp; unsigned dsor_exp;
if (unlikely(!(clk->flags & RATE_CKCTL)))
return -EINVAL;
parent = clk->parent; parent = clk->parent;
if (unlikely(parent == NULL)) if (unlikely(parent == NULL))
return -EIO; return -EIO;
...@@ -307,26 +304,52 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate) ...@@ -307,26 +304,52 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
{ {
int ret = -EINVAL; int dsor_exp;
int dsor_exp; u16 regval;
__u16 regval;
if (clk->flags & RATE_CKCTL) {
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = __raw_readw(DSP_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
__raw_writew(regval, DSP_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
ret = 0;
}
return ret; dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = __raw_readw(DSP_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
__raw_writew(regval, DSP_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
return 0;
}
static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
{
int dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp < 0)
return dsor_exp;
if (dsor_exp > 3)
dsor_exp = 3;
return clk->parent->rate / (1 << dsor_exp);
}
static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
{
int dsor_exp;
u16 regval;
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = omap_readw(ARM_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
regval = verify_ckctl_value(regval);
omap_writew(regval, ARM_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
return 0;
} }
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate) static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
...@@ -572,20 +595,9 @@ static const struct clkops clkops_generic = { ...@@ -572,20 +595,9 @@ static const struct clkops clkops_generic = {
static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
{ {
int dsor_exp;
if (clk->flags & RATE_FIXED) if (clk->flags & RATE_FIXED)
return clk->rate; return clk->rate;
if (clk->flags & RATE_CKCTL) {
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp < 0)
return dsor_exp;
if (dsor_exp > 3)
dsor_exp = 3;
return clk->parent->rate / (1 << dsor_exp);
}
if (clk->round_rate != NULL) if (clk->round_rate != NULL)
return clk->round_rate(clk, rate); return clk->round_rate(clk, rate);
...@@ -595,27 +607,9 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) ...@@ -595,27 +607,9 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
{ {
int ret = -EINVAL; int ret = -EINVAL;
int dsor_exp;
__u16 regval;
if (clk->set_rate) if (clk->set_rate)
ret = clk->set_rate(clk, rate); ret = clk->set_rate(clk, rate);
else if (clk->flags & RATE_CKCTL) {
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = omap_readw(ARM_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
regval = verify_ckctl_value(regval);
omap_writew(regval, ARM_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
ret = 0;
}
return ret; return ret;
} }
......
...@@ -27,6 +27,9 @@ static void omap1_init_ext_clk(struct clk * clk); ...@@ -27,6 +27,9 @@ static void omap1_init_ext_clk(struct clk * clk);
static int omap1_select_table_rate(struct clk * clk, unsigned long rate); static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
struct mpu_rate { struct mpu_rate {
unsigned long rate; unsigned long rate;
unsigned long xtal; unsigned long xtal;
...@@ -189,9 +192,11 @@ static struct clk arm_ck = { ...@@ -189,9 +192,11 @@ static struct clk arm_ck = {
.ops = &clkops_null, .ops = &clkops_null,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES, CLOCK_IN_OMAP310 | RATE_PROPAGATES,
.rate_offset = CKCTL_ARMDIV_OFFSET, .rate_offset = CKCTL_ARMDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}; };
static struct arm_idlect1_clk armper_ck = { static struct arm_idlect1_clk armper_ck = {
...@@ -200,12 +205,13 @@ static struct arm_idlect1_clk armper_ck = { ...@@ -200,12 +205,13 @@ static struct arm_idlect1_clk armper_ck = {
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_CKCTL | CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2, .enable_reg = (void __iomem *)ARM_IDLECT2,
.enable_bit = EN_PERCK, .enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET, .rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}, },
.idlect_shift = 2, .idlect_shift = 2,
}; };
...@@ -279,22 +285,24 @@ static struct clk dsp_ck = { ...@@ -279,22 +285,24 @@ static struct clk dsp_ck = {
.name = "dsp_ck", .name = "dsp_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
RATE_CKCTL,
.enable_reg = (void __iomem *)ARM_CKCTL, .enable_reg = (void __iomem *)ARM_CKCTL,
.enable_bit = EN_DSPCK, .enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET, .rate_offset = CKCTL_DSPDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}; };
static struct clk dspmmu_ck = { static struct clk dspmmu_ck = {
.name = "dspmmu_ck", .name = "dspmmu_ck",
.ops = &clkops_null, .ops = &clkops_null,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
RATE_CKCTL,
.rate_offset = CKCTL_DSPMMUDIV_OFFSET, .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}; };
static struct clk dspper_ck = { static struct clk dspper_ck = {
...@@ -302,11 +310,12 @@ static struct clk dspper_ck = { ...@@ -302,11 +310,12 @@ static struct clk dspper_ck = {
.ops = &clkops_dspck, .ops = &clkops_dspck,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | VIRTUAL_IO_ADDRESS, VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK, .enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET, .rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc_dsp_domain, .recalc = &omap1_ckctl_recalc_dsp_domain,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = &omap1_clk_set_rate_dsp_domain, .set_rate = &omap1_clk_set_rate_dsp_domain,
}; };
...@@ -340,10 +349,11 @@ static struct arm_idlect1_clk tc_ck = { ...@@ -340,10 +349,11 @@ static struct arm_idlect1_clk tc_ck = {
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 | CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
RATE_CKCTL | RATE_PROPAGATES | RATE_PROPAGATES | CLOCK_IDLE_CONTROL,
CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET, .rate_offset = CKCTL_TCDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}, },
.idlect_shift = 6, .idlect_shift = 6,
}; };
...@@ -466,11 +476,13 @@ static struct clk lcd_ck_16xx = { ...@@ -466,11 +476,13 @@ static struct clk lcd_ck_16xx = {
.name = "lcd_ck", .name = "lcd_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL, .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
.enable_reg = (void __iomem *)ARM_IDLECT2, .enable_reg = (void __iomem *)ARM_IDLECT2,
.enable_bit = EN_LCDCK, .enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET, .rate_offset = CKCTL_LCDDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}; };
static struct arm_idlect1_clk lcd_ck_1510 = { static struct arm_idlect1_clk lcd_ck_1510 = {
...@@ -479,11 +491,13 @@ static struct arm_idlect1_clk lcd_ck_1510 = { ...@@ -479,11 +491,13 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1, .parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
RATE_CKCTL | CLOCK_IDLE_CONTROL, CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2, .enable_reg = (void __iomem *)ARM_IDLECT2,
.enable_bit = EN_LCDCK, .enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET, .rate_offset = CKCTL_LCDDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
}, },
.idlect_shift = 3, .idlect_shift = 3,
}; };
......
...@@ -124,7 +124,7 @@ extern void clk_enable_init_clocks(void); ...@@ -124,7 +124,7 @@ extern void clk_enable_init_clocks(void);
extern const struct clkops clkops_null; extern const struct clkops clkops_null;
/* Clock flags */ /* Clock flags */
#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */ /* bit 0 is free */
#define RATE_FIXED (1 << 1) /* Fixed clock rate */ #define RATE_FIXED (1 << 1) /* Fixed clock rate */
#define RATE_PROPAGATES (1 << 2) /* Program children too */ #define RATE_PROPAGATES (1 << 2) /* Program children too */
/* bits 3-4 are free */ /* bits 3-4 are free */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment