Add some code to set the SD/MMC clocks.
authorkettenis <kettenis@openbsd.org>
Sat, 20 Aug 2016 19:34:44 +0000 (19:34 +0000)
committerkettenis <kettenis@openbsd.org>
Sat, 20 Aug 2016 19:34:44 +0000 (19:34 +0000)
sys/arch/armv7/sunxi/sxiccmu.c
sys/arch/armv7/sunxi/sxiccmuvar.h

index a0c6ba4..54e5425 100644 (file)
@@ -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
 #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);
+}
index eb47d0f..0a6e1bd 100644 (file)
@@ -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,