@@ -200,11 +200,11 @@ void pxa2xx_cpll_change(struct pxa2xx_freq *freq,
int pxa2xx_determine_rate(struct clk_rate_request *req,
struct pxa2xx_freq *freqs, int nb_freqs)
{
- int i, closest_below = -1, closest_above = -1;
+ int i, closest_below = -1, closest_above = -1, ret = 0;
unsigned long rate;
for (i = 0; i < nb_freqs; i++) {
- rate = freqs[i].cpll_khz * KHz;
+ rate = freqs[i].cpll;
if (rate == req->rate)
break;
if (rate < req->min_rate)
@@ -220,17 +220,17 @@ int pxa2xx_determine_rate(struct clk_rate_request *req,
req->best_parent_hw = NULL;
if (i < nb_freqs)
- return 0;
-
- if (closest_below >= 0) {
- req->rate = freqs[closest_below].cpll_khz * KHz;
- return 0;
- }
+ ret = 0;
+ else if (closest_below >= 0)
+ rate = freqs[closest_below].cpll;
+ else if (closest_above >= 0)
+ rate = freqs[closest_above].cpll;
+ else
+ ret = -EINVAL;
- if (closest_above >= 0) {
- req->rate = freqs[closest_above].cpll_khz * KHz;
- return 0;
- }
+ pr_debug("%s(rate=%lu) rate=%lu: %d\n", __func__, req->rate, rate, ret);
+ if (!rate)
+ req->rate = rate;
- return -EINVAL;
+ return ret;
}
@@ -136,7 +136,7 @@ struct desc_clk_cken {
NULL, cken_reg, cken_bit, flag)
struct pxa2xx_freq {
- unsigned int cpll_khz;
+ unsigned long cpll;
unsigned int membus_khz;
unsigned int cccr;
unsigned int div2;
@@ -179,13 +179,19 @@ static struct desc_clk_cken pxa25x_clocks[] __initdata = {
clk_pxa25x_memory_parents, 0),
};
+/*
+ * In this table, PXA25x_CCCR(N2, M, L) has the following meaning, where :
+ * - freq_cpll = n * m * L * 3.6864 MHz
+ * - n = N2 / 2
+ * - m = 2^(M - 1), where 1 <= M <= 3
+ * - l = L_clk_mult[L], ie. { 0, 27, 32, 36, 40, 45, 0, }[L]
+ */
static struct pxa2xx_freq pxa25x_freqs[] = {
/* CPU MEMBUS CCCR DIV2 CCLKCFG */
- { 99500, 99500, PXA25x_CCCR(2, 1, 1), 1, PXA25x_CLKCFG(1)},
- {199100, 99500, PXA25x_CCCR(4, 1, 1), 0, PXA25x_CLKCFG(1)},
- {298500, 99500, PXA25x_CCCR(6, 1, 1), 0, PXA25x_CLKCFG(1)},
- {298600, 99500, PXA25x_CCCR(2, 1, 16), 0, PXA25x_CLKCFG(1)},
- {398100, 99500, PXA25x_CCCR(4, 2, 1), 0, PXA25x_CLKCFG(1)},
+ { 99532800, 99500, PXA25x_CCCR(2, 1, 1), 1, PXA25x_CLKCFG(1)},
+ {199065600, 99500, PXA25x_CCCR(4, 1, 1), 0, PXA25x_CLKCFG(1)},
+ {298598400, 99500, PXA25x_CCCR(3, 2, 1), 0, PXA25x_CLKCFG(1)},
+ {398131200, 99500, PXA25x_CCCR(4, 2, 1), 0, PXA25x_CLKCFG(1)},
};
static u8 clk_pxa25x_core_get_parent(struct clk_hw *hw)
@@ -257,8 +263,9 @@ static int clk_pxa25x_cpll_set_rate(struct clk_hw *hw, unsigned long rate,
{
int i;
+ pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate);
for (i = 0; i < ARRAY_SIZE(pxa25x_freqs); i++)
- if (pxa25x_freqs[i].cpll_khz * KHz == rate)
+ if (pxa25x_freqs[i].cpll == rate)
break;
if (i >= ARRAY_SIZE(pxa25x_freqs))
@@ -215,13 +215,13 @@ static struct desc_clk_cken pxa27x_clocks[] __initdata = {
* change sequences.
*/
static struct pxa2xx_freq pxa27x_freqs[] = {
- {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, PXA27x_CLKCFG(1, 0, 1) },
- {156000, 104000, PXA27x_CCCR(1, 8, 3), 0, PXA27x_CLKCFG(1, 0, 1) },
- {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, PXA27x_CLKCFG(0, 0, 1) },
- {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, PXA27x_CLKCFG(1, 0, 1) },
- {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, PXA27x_CLKCFG(1, 0, 1) },
- {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, PXA27x_CLKCFG(1, 0, 1) },
- {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, PXA27x_CLKCFG(1, 0, 1) },
+ {104000000, 104000, PXA27x_CCCR(1, 8, 2), 0, PXA27x_CLKCFG(1, 0, 1) },
+ {156000000, 104000, PXA27x_CCCR(1, 8, 3), 0, PXA27x_CLKCFG(1, 0, 1) },
+ {208000000, 208000, PXA27x_CCCR(0, 16, 2), 1, PXA27x_CLKCFG(0, 0, 1) },
+ {312000000, 208000, PXA27x_CCCR(1, 16, 3), 1, PXA27x_CLKCFG(1, 0, 1) },
+ {416000000, 208000, PXA27x_CCCR(1, 16, 4), 1, PXA27x_CLKCFG(1, 0, 1) },
+ {520000000, 208000, PXA27x_CCCR(1, 16, 5), 1, PXA27x_CLKCFG(1, 0, 1) },
+ {624000000, 208000, PXA27x_CCCR(1, 16, 6), 1, PXA27x_CLKCFG(1, 0, 1) },
};
static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw,
@@ -244,7 +244,6 @@ static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw,
return N;
}
-
static int clk_pxa27x_cpll_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
@@ -257,8 +256,9 @@ static int clk_pxa27x_cpll_set_rate(struct clk_hw *hw, unsigned long rate,
{
int i;
+ pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate);
for (i = 0; i < ARRAY_SIZE(pxa27x_freqs); i++)
- if (pxa27x_freqs[i].cpll_khz * KHz == rate)
+ if (pxa27x_freqs[i].cpll == rate)
break;
if (i >= ARRAY_SIZE(pxa27x_freqs))