ARM: mxs/clock-mx28: fix up name##_set_rate
For the lcdif clock get_rate looks as follows: read div from HW_CLKCTRL_DIS_LCDIF.DIV return clk_get_rate(clk->parent) / div with clk->parent being ref_pix_clk on my system. ref_pix_clk's rate depends on HW_CLKCTRL_FRAC1.PIXFRAC. The set_rate function for lcdif does: parent_rate = clk_get_rate(clk->parent); based on that calculate frac and div such that parent_rate * 18 / frac / div is near the requested rate. HW_CLKCTRL_FRAC1.PIXFRAC is updated with frac HW_CLKCTRL_DIS_LCDIF.DIV is updated with div For this calculation to be correct parent_rate needs to be initialized not with the clock rate of lcdif's parent (i.e. ref_pix) but that of its grandparent (i.e. ref_pix' parent == pll0_clk). The obvious downside of this patch is that now set_rate(lcdif) changes its parent's rate, too. Still this is better than a wrong rate. Acked-by: Shawn Guo <shawn.guo@freescale.com> LAKML-Reference: 20110225084950.GA13684@S2101-09.ap.freescale.net Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Родитель
32a90b6e65
Коммит
f61b9fc27e
|
@ -295,11 +295,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
|||
unsigned long diff, parent_rate, calc_rate; \
|
||||
int i; \
|
||||
\
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
|
||||
bm_busy = BM_CLKCTRL_##dr##_BUSY; \
|
||||
\
|
||||
if (clk->parent == &ref_xtal_clk) { \
|
||||
parent_rate = clk_get_rate(clk->parent); \
|
||||
div = DIV_ROUND_UP(parent_rate, rate); \
|
||||
if (clk == &cpu_clk) { \
|
||||
div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
|
||||
|
@ -309,6 +309,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
|
|||
if (div == 0 || div > div_max) \
|
||||
return -EINVAL; \
|
||||
} else { \
|
||||
/* \
|
||||
* hack alert: this block modifies clk->parent, too, \
|
||||
* so the base to use it the grand parent. \
|
||||
*/ \
|
||||
parent_rate = clk_get_rate(clk->parent->parent); \
|
||||
rate >>= PARENT_RATE_SHIFT; \
|
||||
parent_rate >>= PARENT_RATE_SHIFT; \
|
||||
diff = parent_rate; \
|
||||
|
|
Загрузка…
Ссылка в новой задаче