summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-09-10 23:09:04 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-09-10 23:09:04 +0000
commit20c74eccfe7fb154cd76298e06e47d3c4c881a70 (patch)
tree3246b23449b07b244e2facb1f26a19892113d337 /sys/arch
parent5a996f81f5f1fa975b23c4becb995cceea77dc17 (diff)
Use PLL6 as a parent clock for the SDx clocks for frequencies > 400 kHz.
This makes sximmc(4) much faster since we can actually provide the appropriate clock rates for the modern SD cards. This uncovered a bug in the code that calculated the PLL6 output frequencies, which this commit also fixes.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/armv7/sunxi/sxiccmu.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/arch/armv7/sunxi/sxiccmu.c b/sys/arch/armv7/sunxi/sxiccmu.c
index af4784eaa9d..c6ef6819544 100644
--- a/sys/arch/armv7/sunxi/sxiccmu.c
+++ b/sys/arch/armv7/sunxi/sxiccmu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxiccmu.c,v 1.18 2016/08/28 20:17:10 kettenis Exp $ */
+/* $OpenBSD: sxiccmu.c,v 1.19 2016/09/10 23:09:03 kettenis Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2013 Artturi Alm
@@ -368,11 +368,11 @@ sxiccmu_pll6_get_frequency(void *cookie, uint32_t *cells)
case 0:
return (freq * n * k) / m / 6; /* pll6_sata */
case 1:
- return (freq * n * k) / m / 2; /* pll6_other */
+ return (freq * n * k) / 2; /* pll6_other */
case 2:
- return (freq * n * k) / m; /* pll6 */
+ return (freq * n * k); /* pll6 */
case 3:
- return (freq * n * k) / m / 4; /* pll6_div_4 */
+ return (freq * n * k) / 4; /* pll6_div_4 */
}
return 0;
@@ -468,6 +468,8 @@ sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
{
struct sxiccmu_clock *sc = cookie;
uint32_t reg, m, n;
+ uint32_t clk_src;
+ uint32_t parent_freq;
if (cells[0] != 0)
return -1;
@@ -475,12 +477,19 @@ sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
switch (freq) {
case 400000:
n = 2, m = 15;
+ clk_src = CCU_SDx_CLK_SRC_SEL_OSC24M;
break;
case 25000000:
case 26000000:
case 50000000:
- /* XXX OSC24M */
+ case 52000000:
n = 0, m = 0;
+ clk_src = CCU_SDx_CLK_SRC_SEL_PLL6;
+ parent_freq = clock_get_frequency_idx(sc->sc_node, 1);
+ while ((parent_freq / (1 << n) / 16) > freq)
+ n++;
+ while ((parent_freq / (1 << n) / (m + 1)) > freq)
+ m++;
break;
default:
return -1;
@@ -488,7 +497,7 @@ sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
reg = SXIREAD4(sc, 0);
reg &= ~CCU_SDx_CLK_SRC_SEL_MASK;
- reg |= CCU_SDx_CLK_SRC_SEL_OSC24M;
+ reg |= clk_src;
reg &= ~CCU_SDx_CLK_DIV_RATIO_N_MASK;
reg |= n << CCU_SDx_CLK_DIV_RATIO_N_SHIFT;
reg &= ~CCU_SDx_CLK_DIV_RATIO_M_MASK;