summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/dts/sun50i-a64-pinebook-u-boot.dtsi2
-rw-r--r--arch/arm/dts/sunxi-u-boot.dtsi4
-rw-r--r--arch/arm/mach-sunxi/Kconfig1
-rw-r--r--board/sunxi/board.c15
-rw-r--r--configs/Linksprite_pcDuino3_defconfig1
-rw-r--r--configs/amarula_a64_relic_defconfig2
-rw-r--r--drivers/clk/sunxi/clk_a10.c4
-rw-r--r--drivers/clk/sunxi/clk_a10s.c3
-rw-r--r--drivers/clk/sunxi/clk_a23.c6
-rw-r--r--drivers/clk/sunxi/clk_a31.c8
-rw-r--r--drivers/clk/sunxi/clk_a64.c6
-rw-r--r--drivers/clk/sunxi/clk_a80.c32
-rw-r--r--drivers/clk/sunxi/clk_a83t.c6
-rw-r--r--drivers/clk/sunxi/clk_h3.c6
-rw-r--r--drivers/clk/sunxi/clk_h6.c6
-rw-r--r--drivers/clk/sunxi/clk_r40.c8
-rw-r--r--drivers/clk/sunxi/clk_sunxi.c12
-rw-r--r--drivers/clk/sunxi/clk_v3s.c6
-rw-r--r--drivers/mmc/sunxi_mmc.c53
20 files changed, 173 insertions, 9 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cefa8f40d0..f0edb10003 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -851,6 +851,7 @@ config ARCH_SUNXI
select DM_ETH
select DM_GPIO
select DM_KEYBOARD
+ select DM_MMC if MMC
select DM_SERIAL
select DM_USB if DISTRO_DEFAULTS
select OF_BOARD_SETUP
diff --git a/arch/arm/dts/sun50i-a64-pinebook-u-boot.dtsi b/arch/arm/dts/sun50i-a64-pinebook-u-boot.dtsi
index a99b7171d0..650ab97ec9 100644
--- a/arch/arm/dts/sun50i-a64-pinebook-u-boot.dtsi
+++ b/arch/arm/dts/sun50i-a64-pinebook-u-boot.dtsi
@@ -4,6 +4,8 @@
*
*/
+#include "sunxi-u-boot.dtsi"
+
/* The ANX6345 eDP-bridge is on r_i2c */
&r_i2c {
anx6345: edp-bridge@38 {
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index 8a9f2a6417..fdd4c80aa4 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,6 +1,10 @@
#include <config.h>
/ {
+ aliases {
+ mmc1 = &mmc2;
+ };
+
binman {
filename = "u-boot-sunxi-with-spl.bin";
pad-byte = <0xff>;
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 3c54f5106d..74e234cded 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -154,7 +154,6 @@ config MACH_SUN4I
bool "sun4i (Allwinner A10)"
select CPU_V7A
select ARM_CORTEX_CPU_IS_UP
- select DM_MMC if MMC
select DM_SCSI if SCSI
select PHY_SUN4I_USB
select DRAM_SUN4I
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index ad14837291..98bc3cd0c1 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -208,6 +208,10 @@ enum env_location env_get_location(enum env_operation op, int prio)
}
#endif
+#ifdef CONFIG_DM_MMC
+static void mmc_pinmux_setup(int sdc);
+#endif
+
/* add board specific code here */
int board_init(void)
{
@@ -269,6 +273,17 @@ int board_init(void)
i2c_init_board();
#endif
+#ifdef CONFIG_DM_MMC
+ /*
+ * Temporary workaround for enabling MMC clocks until a sunxi DM
+ * pinctrl driver lands.
+ */
+ mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
+ mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+#endif
+#endif /* CONFIG_DM_MMC */
+
/* Uses dm gpio code so do this here and not in i2c_init_board() */
return soft_i2c_board_init();
}
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
index 9156f132d1..18f658e96b 100644
--- a/configs/Linksprite_pcDuino3_defconfig
+++ b/configs/Linksprite_pcDuino3_defconfig
@@ -14,7 +14,6 @@ CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3"
CONFIG_SCSI_AHCI=y
-CONFIG_DM_MMC=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_MII=y
CONFIG_SUN7I_GMAC=y
diff --git a/configs/amarula_a64_relic_defconfig b/configs/amarula_a64_relic_defconfig
index f5857cfbb3..2e6011fa45 100644
--- a/configs/amarula_a64_relic_defconfig
+++ b/configs/amarula_a64_relic_defconfig
@@ -11,5 +11,7 @@ CONFIG_NR_DRAM_BANKS=1
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-amarula-relic"
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/drivers/clk/sunxi/clk_a10.c b/drivers/clk/sunxi/clk_a10.c
index b00f51af8b..2aa41efe17 100644
--- a/drivers/clk/sunxi/clk_a10.c
+++ b/drivers/clk/sunxi/clk_a10.c
@@ -18,6 +18,10 @@ static struct ccu_clk_gate a10_gates[] = {
[CLK_AHB_OHCI0] = GATE(0x060, BIT(2)),
[CLK_AHB_EHCI1] = GATE(0x060, BIT(3)),
[CLK_AHB_OHCI1] = GATE(0x060, BIT(4)),
+ [CLK_AHB_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_AHB_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_AHB_MMC2] = GATE(0x060, BIT(10)),
+ [CLK_AHB_MMC3] = GATE(0x060, BIT(11)),
[CLK_APB1_UART0] = GATE(0x06c, BIT(16)),
[CLK_APB1_UART1] = GATE(0x06c, BIT(17)),
diff --git a/drivers/clk/sunxi/clk_a10s.c b/drivers/clk/sunxi/clk_a10s.c
index aa904ce067..87b74e52dc 100644
--- a/drivers/clk/sunxi/clk_a10s.c
+++ b/drivers/clk/sunxi/clk_a10s.c
@@ -16,6 +16,9 @@ static struct ccu_clk_gate a10s_gates[] = {
[CLK_AHB_OTG] = GATE(0x060, BIT(0)),
[CLK_AHB_EHCI] = GATE(0x060, BIT(1)),
[CLK_AHB_OHCI] = GATE(0x060, BIT(2)),
+ [CLK_AHB_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_AHB_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_AHB_MMC2] = GATE(0x060, BIT(10)),
[CLK_APB1_UART0] = GATE(0x06c, BIT(16)),
[CLK_APB1_UART1] = GATE(0x06c, BIT(17)),
diff --git a/drivers/clk/sunxi/clk_a23.c b/drivers/clk/sunxi/clk_a23.c
index 854259bf81..1ef2359286 100644
--- a/drivers/clk/sunxi/clk_a23.c
+++ b/drivers/clk/sunxi/clk_a23.c
@@ -13,6 +13,9 @@
#include <dt-bindings/reset/sun8i-a23-a33-ccu.h>
static struct ccu_clk_gate a23_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
[CLK_BUS_OTG] = GATE(0x060, BIT(24)),
[CLK_BUS_EHCI] = GATE(0x060, BIT(26)),
[CLK_BUS_OHCI] = GATE(0x060, BIT(29)),
@@ -35,6 +38,9 @@ static struct ccu_reset a23_resets[] = {
[RST_USB_PHY1] = RESET(0x0cc, BIT(1)),
[RST_USB_HSIC] = RESET(0x0cc, BIT(2)),
+ [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(24)),
[RST_BUS_EHCI] = RESET(0x2c0, BIT(26)),
[RST_BUS_OHCI] = RESET(0x2c0, BIT(29)),
diff --git a/drivers/clk/sunxi/clk_a31.c b/drivers/clk/sunxi/clk_a31.c
index a38d76cb7c..5bd8b7dccc 100644
--- a/drivers/clk/sunxi/clk_a31.c
+++ b/drivers/clk/sunxi/clk_a31.c
@@ -13,6 +13,10 @@
#include <dt-bindings/reset/sun6i-a31-ccu.h>
static struct ccu_clk_gate a31_gates[] = {
+ [CLK_AHB1_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_AHB1_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_AHB1_MMC2] = GATE(0x060, BIT(10)),
+ [CLK_AHB1_MMC3] = GATE(0x060, BIT(11)),
[CLK_AHB1_OTG] = GATE(0x060, BIT(24)),
[CLK_AHB1_EHCI0] = GATE(0x060, BIT(26)),
[CLK_AHB1_EHCI1] = GATE(0x060, BIT(27)),
@@ -40,6 +44,10 @@ static struct ccu_reset a31_resets[] = {
[RST_USB_PHY1] = RESET(0x0cc, BIT(1)),
[RST_USB_PHY2] = RESET(0x0cc, BIT(2)),
+ [RST_AHB1_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_AHB1_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_AHB1_MMC2] = RESET(0x2c0, BIT(10)),
+ [RST_AHB1_MMC3] = RESET(0x2c0, BIT(11)),
[RST_AHB1_OTG] = RESET(0x2c0, BIT(24)),
[RST_AHB1_EHCI0] = RESET(0x2c0, BIT(26)),
[RST_AHB1_EHCI1] = RESET(0x2c0, BIT(27)),
diff --git a/drivers/clk/sunxi/clk_a64.c b/drivers/clk/sunxi/clk_a64.c
index a2ba6eefc5..910275fbce 100644
--- a/drivers/clk/sunxi/clk_a64.c
+++ b/drivers/clk/sunxi/clk_a64.c
@@ -13,6 +13,9 @@
#include <dt-bindings/reset/sun50i-a64-ccu.h>
static const struct ccu_clk_gate a64_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
[CLK_BUS_OTG] = GATE(0x060, BIT(23)),
[CLK_BUS_EHCI0] = GATE(0x060, BIT(24)),
[CLK_BUS_EHCI1] = GATE(0x060, BIT(25)),
@@ -38,6 +41,9 @@ static const struct ccu_reset a64_resets[] = {
[RST_USB_PHY1] = RESET(0x0cc, BIT(1)),
[RST_USB_HSIC] = RESET(0x0cc, BIT(2)),
+ [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(23)),
[RST_BUS_EHCI0] = RESET(0x2c0, BIT(24)),
[RST_BUS_EHCI1] = RESET(0x2c0, BIT(25)),
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c
index d6dd6a1fa1..aec1d80c46 100644
--- a/drivers/clk/sunxi/clk_a80.c
+++ b/drivers/clk/sunxi/clk_a80.c
@@ -13,6 +13,8 @@
#include <dt-bindings/reset/sun9i-a80-ccu.h>
static const struct ccu_clk_gate a80_gates[] = {
+ [CLK_BUS_MMC] = GATE(0x580, BIT(8)),
+
[CLK_BUS_UART0] = GATE(0x594, BIT(16)),
[CLK_BUS_UART1] = GATE(0x594, BIT(17)),
[CLK_BUS_UART2] = GATE(0x594, BIT(18)),
@@ -22,6 +24,8 @@ static const struct ccu_clk_gate a80_gates[] = {
};
static const struct ccu_reset a80_resets[] = {
+ [RST_BUS_MMC] = RESET(0x5a0, BIT(8)),
+
[RST_BUS_UART0] = RESET(0x5b4, BIT(16)),
[RST_BUS_UART1] = RESET(0x5b4, BIT(17)),
[RST_BUS_UART2] = RESET(0x5b4, BIT(18)),
@@ -30,19 +34,45 @@ static const struct ccu_reset a80_resets[] = {
[RST_BUS_UART5] = RESET(0x5b4, BIT(21)),
};
+static const struct ccu_clk_gate a80_mmc_gates[] = {
+ [0] = GATE(0x0, BIT(16)),
+ [1] = GATE(0x4, BIT(16)),
+ [2] = GATE(0x8, BIT(16)),
+ [3] = GATE(0xc, BIT(16)),
+};
+
+static const struct ccu_reset a80_mmc_resets[] = {
+ [0] = GATE(0x0, BIT(18)),
+ [1] = GATE(0x4, BIT(18)),
+ [2] = GATE(0x8, BIT(18)),
+ [3] = GATE(0xc, BIT(18)),
+};
+
static const struct ccu_desc a80_ccu_desc = {
.gates = a80_gates,
.resets = a80_resets,
};
+static const struct ccu_desc a80_mmc_clk_desc = {
+ .gates = a80_mmc_gates,
+ .resets = a80_mmc_resets,
+};
+
static int a80_clk_bind(struct udevice *dev)
{
- return sunxi_reset_bind(dev, ARRAY_SIZE(a80_resets));
+ ulong count = ARRAY_SIZE(a80_resets);
+
+ if (device_is_compatible(dev, "allwinner,sun9i-a80-mmc-config-clk"))
+ count = ARRAY_SIZE(a80_mmc_resets);
+
+ return sunxi_reset_bind(dev, count);
}
static const struct udevice_id a80_ccu_ids[] = {
{ .compatible = "allwinner,sun9i-a80-ccu",
.data = (ulong)&a80_ccu_desc },
+ { .compatible = "allwinner,sun9i-a80-mmc-config-clk",
+ .data = (ulong)&a80_mmc_clk_desc },
{ }
};
diff --git a/drivers/clk/sunxi/clk_a83t.c b/drivers/clk/sunxi/clk_a83t.c
index 1ef6ac5b25..b5a555da36 100644
--- a/drivers/clk/sunxi/clk_a83t.c
+++ b/drivers/clk/sunxi/clk_a83t.c
@@ -13,6 +13,9 @@
#include <dt-bindings/reset/sun8i-a83t-ccu.h>
static struct ccu_clk_gate a83t_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
[CLK_BUS_OTG] = GATE(0x060, BIT(24)),
[CLK_BUS_EHCI0] = GATE(0x060, BIT(26)),
[CLK_BUS_EHCI1] = GATE(0x060, BIT(27)),
@@ -36,6 +39,9 @@ static struct ccu_reset a83t_resets[] = {
[RST_USB_PHY1] = RESET(0x0cc, BIT(1)),
[RST_USB_HSIC] = RESET(0x0cc, BIT(2)),
+ [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(24)),
[RST_BUS_EHCI0] = RESET(0x2c0, BIT(26)),
[RST_BUS_EHCI1] = RESET(0x2c0, BIT(27)),
diff --git a/drivers/clk/sunxi/clk_h3.c b/drivers/clk/sunxi/clk_h3.c
index f82949b3b6..416aec2b89 100644
--- a/drivers/clk/sunxi/clk_h3.c
+++ b/drivers/clk/sunxi/clk_h3.c
@@ -13,6 +13,9 @@
#include <dt-bindings/reset/sun8i-h3-ccu.h>
static struct ccu_clk_gate h3_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
[CLK_BUS_OTG] = GATE(0x060, BIT(23)),
[CLK_BUS_EHCI0] = GATE(0x060, BIT(24)),
[CLK_BUS_EHCI1] = GATE(0x060, BIT(25)),
@@ -44,6 +47,9 @@ static struct ccu_reset h3_resets[] = {
[RST_USB_PHY2] = RESET(0x0cc, BIT(2)),
[RST_USB_PHY3] = RESET(0x0cc, BIT(3)),
+ [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(23)),
[RST_BUS_EHCI0] = RESET(0x2c0, BIT(24)),
[RST_BUS_EHCI1] = RESET(0x2c0, BIT(25)),
diff --git a/drivers/clk/sunxi/clk_h6.c b/drivers/clk/sunxi/clk_h6.c
index 0da3a40e3d..902612da91 100644
--- a/drivers/clk/sunxi/clk_h6.c
+++ b/drivers/clk/sunxi/clk_h6.c
@@ -13,6 +13,9 @@
#include <dt-bindings/reset/sun50i-h6-ccu.h>
static struct ccu_clk_gate h6_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)),
+ [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)),
+ [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)),
[CLK_BUS_UART0] = GATE(0x90c, BIT(0)),
[CLK_BUS_UART1] = GATE(0x90c, BIT(1)),
[CLK_BUS_UART2] = GATE(0x90c, BIT(2)),
@@ -20,6 +23,9 @@ static struct ccu_clk_gate h6_gates[] = {
};
static struct ccu_reset h6_resets[] = {
+ [RST_BUS_MMC0] = RESET(0x84c, BIT(16)),
+ [RST_BUS_MMC1] = RESET(0x84c, BIT(17)),
+ [RST_BUS_MMC2] = RESET(0x84c, BIT(18)),
[RST_BUS_UART0] = RESET(0x90c, BIT(16)),
[RST_BUS_UART1] = RESET(0x90c, BIT(17)),
[RST_BUS_UART2] = RESET(0x90c, BIT(18)),
diff --git a/drivers/clk/sunxi/clk_r40.c b/drivers/clk/sunxi/clk_r40.c
index fd7aae97ea..b9457e1971 100644
--- a/drivers/clk/sunxi/clk_r40.c
+++ b/drivers/clk/sunxi/clk_r40.c
@@ -13,6 +13,10 @@
#include <dt-bindings/reset/sun8i-r40-ccu.h>
static struct ccu_clk_gate r40_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
+ [CLK_BUS_MMC3] = GATE(0x060, BIT(11)),
[CLK_BUS_OTG] = GATE(0x060, BIT(25)),
[CLK_BUS_EHCI0] = GATE(0x060, BIT(26)),
[CLK_BUS_EHCI1] = GATE(0x060, BIT(27)),
@@ -43,6 +47,10 @@ static struct ccu_reset r40_resets[] = {
[RST_USB_PHY1] = RESET(0x0cc, BIT(1)),
[RST_USB_PHY2] = RESET(0x0cc, BIT(2)),
+ [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
+ [RST_BUS_MMC3] = RESET(0x2c0, BIT(11)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(25)),
[RST_BUS_EHCI0] = RESET(0x2c0, BIT(26)),
[RST_BUS_EHCI1] = RESET(0x2c0, BIT(27)),
diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c
index 62ce2994e4..6d4aeb5315 100644
--- a/drivers/clk/sunxi/clk_sunxi.c
+++ b/drivers/clk/sunxi/clk_sunxi.c
@@ -8,6 +8,7 @@
#include <clk-uclass.h>
#include <dm.h>
#include <errno.h>
+#include <reset.h>
#include <asm/io.h>
#include <asm/arch/ccu.h>
#include <linux/log2.h>
@@ -61,6 +62,9 @@ struct clk_ops sunxi_clk_ops = {
int sunxi_clk_probe(struct udevice *dev)
{
struct ccu_priv *priv = dev_get_priv(dev);
+ struct clk_bulk clk_bulk;
+ struct reset_ctl_bulk rst_bulk;
+ int ret;
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
@@ -70,5 +74,13 @@ int sunxi_clk_probe(struct udevice *dev)
if (!priv->desc)
return -EINVAL;
+ ret = clk_get_bulk(dev, &clk_bulk);
+ if (!ret)
+ clk_enable_bulk(&clk_bulk);
+
+ ret = reset_get_bulk(dev, &rst_bulk);
+ if (!ret)
+ reset_deassert_bulk(&rst_bulk);
+
return 0;
}
diff --git a/drivers/clk/sunxi/clk_v3s.c b/drivers/clk/sunxi/clk_v3s.c
index 25ad87500e..c8a9027889 100644
--- a/drivers/clk/sunxi/clk_v3s.c
+++ b/drivers/clk/sunxi/clk_v3s.c
@@ -13,6 +13,9 @@
#include <dt-bindings/reset/sun8i-v3s-ccu.h>
static struct ccu_clk_gate v3s_gates[] = {
+ [CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
+ [CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
+ [CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
[CLK_BUS_OTG] = GATE(0x060, BIT(24)),
[CLK_BUS_UART0] = GATE(0x06c, BIT(16)),
@@ -25,6 +28,9 @@ static struct ccu_clk_gate v3s_gates[] = {
static struct ccu_reset v3s_resets[] = {
[RST_USB_PHY0] = RESET(0x0cc, BIT(0)),
+ [RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
+ [RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
+ [RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(24)),
[RST_BUS_UART0] = RESET(0x2d8, BIT(16)),
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 302332bf97..9f426661c4 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -12,6 +12,8 @@
#include <errno.h>
#include <malloc.h>
#include <mmc.h>
+#include <clk.h>
+#include <reset.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cpu.h>
@@ -21,7 +23,6 @@
#ifdef CONFIG_DM_MMC
struct sunxi_mmc_variant {
- u16 gate_offset;
u16 mclk_offset;
};
#endif
@@ -607,9 +608,11 @@ static int sunxi_mmc_probe(struct udevice *dev)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sunxi_mmc_plat *plat = dev_get_platdata(dev);
struct sunxi_mmc_priv *priv = dev_get_priv(dev);
+ struct reset_ctl_bulk reset_bulk;
+ struct clk gate_clk;
struct mmc_config *cfg = &plat->cfg;
struct ofnode_phandle_args args;
- u32 *gate_reg, *ccu_reg;
+ u32 *ccu_reg;
int bus_width, ret;
cfg->name = dev->name;
@@ -641,15 +644,22 @@ static int sunxi_mmc_probe(struct udevice *dev)
priv->mmc_no = ((uintptr_t)priv->reg - SUNXI_MMC0_BASE) / 0x1000;
priv->mclkreg = (void *)ccu_reg +
(priv->variant->mclk_offset + (priv->mmc_no * 4));
- gate_reg = (void *)ccu_reg + priv->variant->gate_offset;
- setbits_le32(gate_reg, BIT(AHB_GATE_OFFSET_MMC(priv->mmc_no)));
+
+ ret = clk_get_by_name(dev, "ahb", &gate_clk);
+ if (!ret)
+ clk_enable(&gate_clk);
+
+ ret = reset_get_bulk(dev, &reset_bulk);
+ if (!ret)
+ reset_deassert_bulk(&reset_bulk);
ret = mmc_set_mod_clk(priv, 24000000);
if (ret)
return ret;
/* This GPIO is optional */
- if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
+ if (!dev_read_bool(dev, "non-removable") &&
+ !gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
GPIOD_IS_IN)) {
int cd_pin = gpio_get_number(&priv->cd_gpio);
@@ -676,10 +686,17 @@ static int sunxi_mmc_bind(struct udevice *dev)
}
static const struct sunxi_mmc_variant sun4i_a10_variant = {
- .gate_offset = 0x60,
.mclk_offset = 0x88,
};
+static const struct sunxi_mmc_variant sun9i_a80_variant = {
+ .mclk_offset = 0x410,
+};
+
+static const struct sunxi_mmc_variant sun50i_h6_variant = {
+ .mclk_offset = 0x830,
+};
+
static const struct udevice_id sunxi_mmc_ids[] = {
{
.compatible = "allwinner,sun4i-a10-mmc",
@@ -693,6 +710,30 @@ static const struct udevice_id sunxi_mmc_ids[] = {
.compatible = "allwinner,sun7i-a20-mmc",
.data = (ulong)&sun4i_a10_variant,
},
+ {
+ .compatible = "allwinner,sun8i-a83t-emmc",
+ .data = (ulong)&sun4i_a10_variant,
+ },
+ {
+ .compatible = "allwinner,sun9i-a80-mmc",
+ .data = (ulong)&sun9i_a80_variant,
+ },
+ {
+ .compatible = "allwinner,sun50i-a64-mmc",
+ .data = (ulong)&sun4i_a10_variant,
+ },
+ {
+ .compatible = "allwinner,sun50i-a64-emmc",
+ .data = (ulong)&sun4i_a10_variant,
+ },
+ {
+ .compatible = "allwinner,sun50i-h6-mmc",
+ .data = (ulong)&sun50i_h6_variant,
+ },
+ {
+ .compatible = "allwinner,sun50i-h6-emmc",
+ .data = (ulong)&sun50i_h6_variant,
+ },
{ /* sentinel */ }
};