summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-01-07 23:33:54 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-01-07 23:33:54 +0000
commit0f844d2e21c8aaefd64bdfbb4adee05bf5d3eaab (patch)
tree4bb77539541aab80a3b7c276c490a8d97c7df041
parenta6f3fdb89d9c3f3f3a8989b1bfae6058ac4f221f (diff)
Make getting the parent clock for the SD/MMC controller work on the
Allwinner H3.
-rw-r--r--sys/arch/armv7/sunxi/sxiccmu.c33
-rw-r--r--sys/arch/armv7/sunxi/sxiccmu_clocks.h2
2 files changed, 24 insertions, 11 deletions
diff --git a/sys/arch/armv7/sunxi/sxiccmu.c b/sys/arch/armv7/sunxi/sxiccmu.c
index c1414dabf63..7b67f749ff4 100644
--- a/sys/arch/armv7/sunxi/sxiccmu.c
+++ b/sys/arch/armv7/sunxi/sxiccmu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxiccmu.c,v 1.26 2016/11/21 20:22:43 kettenis Exp $ */
+/* $OpenBSD: sxiccmu.c,v 1.27 2017/01/07 23:33:53 kettenis Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2013 Artturi Alm
@@ -528,15 +528,11 @@ sxiccmu_gmac_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
#define CCU_SDx_CLK_DIV_RATIO_M_SHIFT 0
int
-sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
+sxiccmu_mmc_do_set_frequency(struct sxiccmu_clock *sc, uint32_t freq,
+ uint32_t parent_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;
switch (freq) {
case 400000:
@@ -549,7 +545,6 @@ sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
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)
@@ -571,6 +566,19 @@ sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
return 0;
}
+int
+sxiccmu_mmc_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
+{
+ struct sxiccmu_clock *sc = cookie;
+ uint32_t parent_freq;
+
+ if (cells[0] != 0)
+ return -1;
+
+ parent_freq = clock_get_frequency_idx(sc->sc_node, 1);
+ return sxiccmu_mmc_do_set_frequency(sc, freq, parent_freq);
+}
+
void
sxiccmu_mmc_enable(void *cookie, uint32_t *cells, int on)
{
@@ -632,6 +640,9 @@ sxiccmu_ccu_get_frequency(void *cookie, uint32_t *cells)
}
switch (idx) {
+ case H3_CLK_PLL_PERIPH0:
+ /* XXX default value. */
+ return 600000000;
case H3_CLK_APB2:
/* XXX Controlled by a MUX. */
return 24000000;
@@ -647,16 +658,18 @@ sxiccmu_ccu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
struct sxiccmu_softc *sc = cookie;
struct sxiccmu_clock clock;
uint32_t idx = cells[0];
+ uint32_t parent, parent_freq;
switch (idx) {
case H3_CLK_MMC0:
case H3_CLK_MMC1:
case H3_CLK_MMC2:
- idx = 0;
clock.sc_iot = sc->sc_iot;
bus_space_subregion(sc->sc_iot, sc->sc_ioh,
sc->sc_gates[idx].reg, 4, &clock.sc_ioh);
- return sxiccmu_mmc_set_frequency(&clock, &idx, freq);
+ parent = H3_CLK_PLL_PERIPH0;
+ parent_freq = sxiccmu_ccu_get_frequency(sc, &parent);
+ return sxiccmu_mmc_do_set_frequency(&clock, freq, parent_freq);
}
printf("%s: 0x%08x\n", __func__, cells[0]);
diff --git a/sys/arch/armv7/sunxi/sxiccmu_clocks.h b/sys/arch/armv7/sunxi/sxiccmu_clocks.h
index 8d6b607188b..84791762035 100644
--- a/sys/arch/armv7/sunxi/sxiccmu_clocks.h
+++ b/sys/arch/armv7/sunxi/sxiccmu_clocks.h
@@ -5,7 +5,7 @@
* Clocks Signals
*/
-#define H3_PLL_PERIPH0 9
+#define H3_CLK_PLL_PERIPH0 9
#define H3_CLK_APB2 18