summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-08-20 19:34:45 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-08-20 19:34:45 +0000
commit612a46d69f6570b5b12f011890bb9e8323a5fc08 (patch)
treeb3154bc894c8efafcbdc32a87ce4508ad20f292e /sys/arch
parent61dcdbeecd1f8d38b5d049d0002e75df1a56c987 (diff)
Add some code to set the SD/MMC clocks.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/armv7/sunxi/sxiccmu.c42
-rw-r--r--sys/arch/armv7/sunxi/sxiccmuvar.h4
2 files changed, 44 insertions, 2 deletions
diff --git a/sys/arch/armv7/sunxi/sxiccmu.c b/sys/arch/armv7/sunxi/sxiccmu.c
index a0c6ba44f47..54e5425059b 100644
--- a/sys/arch/armv7/sunxi/sxiccmu.c
+++ b/sys/arch/armv7/sunxi/sxiccmu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxiccmu.c,v 1.6 2016/08/13 21:48:44 kettenis Exp $ */
+/* $OpenBSD: sxiccmu.c,v 1.7 2016/08/20 19:34:44 kettenis Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2013 Artturi Alm
@@ -95,6 +95,17 @@
#define CCMU_NAND_CLK_SRC_GATING_PLL5 (2 << 24)
#define CCMU_NAND_CLK_SRC_GATING_MASK (3 << 24)
+#define CCMU_SDx_CLK(x) (0x88 + (x) * 4)
+#define CCMU_SDx_CLK_GATING (1U << 31)
+#define CCMU_SDx_CLK_SRC_GATING_OSC24M (0 << 24)
+#define CCMU_SDx_CLK_SRC_GATING_PLL6 (1 << 24)
+#define CCMU_SDx_CLK_SRC_GATING_PLL5 (2 << 24)
+#define CCMU_SDx_CLK_SRC_GATING_MASK (3 << 24)
+#define CCMU_SDx_CLK_FACTOR_N (3 << 16)
+#define CCMU_SDx_CLK_FACTOR_N_SHIFT 16
+#define CCMU_SDx_CLK_FACTOR_M (7 << 0)
+#define CCMU_SDx_CLK_FACTOR_M_SHIFT 0
+
#define CCMU_SATA_CLK 0xc8
#define CCMU_SATA_CLK_SRC_GATING (1 << 24)
@@ -321,3 +332,32 @@ sxiccmu_disablemodule(int mod)
break;
}
}
+
+void
+sxiccmu_set_sd_clock(int mod, int freq)
+{
+ struct sxiccmu_softc *sc = sxiccmu_cd.cd_devs[0];
+ uint32_t clk;
+ int m, n;
+
+ if (freq <= 400000) {
+ n = 2;
+ if (freq > 0)
+ m = ((24000000 / (1 << n)) / freq) - 1;
+ else
+ m = 15;
+ } else {
+ n = 0;
+ m = 0;
+ }
+
+ clk = SXIREAD4(sc, CCMU_SDx_CLK(mod - CCMU_SDMMC0));
+ clk &= ~CCMU_SDx_CLK_SRC_GATING_MASK;
+ clk |= CCMU_SDx_CLK_SRC_GATING_OSC24M;
+ clk &= ~CCMU_SDx_CLK_FACTOR_N;
+ clk |= n << CCMU_SDx_CLK_FACTOR_N_SHIFT;
+ clk &= ~CCMU_SDx_CLK_FACTOR_M;
+ clk |= m << CCMU_SDx_CLK_FACTOR_M_SHIFT;
+ clk |= CCMU_SDx_CLK_GATING;
+ SXIWRITE4(sc, CCMU_SDx_CLK(mod - CCMU_SDMMC0), clk);
+}
diff --git a/sys/arch/armv7/sunxi/sxiccmuvar.h b/sys/arch/armv7/sunxi/sxiccmuvar.h
index eb47d0f04bb..0a6e1bd19db 100644
--- a/sys/arch/armv7/sunxi/sxiccmuvar.h
+++ b/sys/arch/armv7/sunxi/sxiccmuvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxiccmuvar.h,v 1.3 2016/08/13 21:48:44 kettenis Exp $ */
+/* $OpenBSD: sxiccmuvar.h,v 1.4 2016/08/20 19:34:44 kettenis Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
*
@@ -18,6 +18,8 @@
void sxiccmu_enablemodule(int);
void sxiccmu_disablemodule(int);
+void sxiccmu_set_sd_clock(int, int);
+
enum CCMU_MODULES {
CCMU_EHCI0,
CCMU_EHCI1,