[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: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
committed by
Russell King
parent
9a5fedac18
commit
d5e6072b75
@@ -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)
|
|||||||
|
|
||||||
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);
|
||||||
dsor_exp = calc_dsor_exp(clk, rate);
|
if (dsor_exp > 3)
|
||||||
if (dsor_exp > 3)
|
dsor_exp = -EINVAL;
|
||||||
dsor_exp = -EINVAL;
|
if (dsor_exp < 0)
|
||||||
if (dsor_exp < 0)
|
return dsor_exp;
|
||||||
return dsor_exp;
|
|
||||||
|
|
||||||
regval = __raw_readw(DSP_CKCTL);
|
regval = __raw_readw(DSP_CKCTL);
|
||||||
regval &= ~(3 << clk->rate_offset);
|
regval &= ~(3 << clk->rate_offset);
|
||||||
regval |= dsor_exp << clk->rate_offset;
|
regval |= dsor_exp << clk->rate_offset;
|
||||||
__raw_writew(regval, DSP_CKCTL);
|
__raw_writew(regval, DSP_CKCTL);
|
||||||
clk->rate = clk->parent->rate / (1 << dsor_exp);
|
clk->rate = clk->parent->rate / (1 << dsor_exp);
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
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 = {
|
|||||||
|
|
||||||
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)
|
|||||||
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);
|
|||||||
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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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);
|
|||||||
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 */
|
||||||
|
Reference in New Issue
Block a user