[U-Boot] [PATCH 0/9] sunxi: enable DM_MMC

This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)

Add the MMC clock gates and reset bits for all the Allwinner SoCs. This allows them to be used by the MMC driver.
We don't advertise the mod clock yet, as this is still handled by the MMC driver.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/clk/sunxi/clk_a10.c | 4 ++++ drivers/clk/sunxi/clk_a10s.c | 3 +++ drivers/clk/sunxi/clk_a23.c | 6 ++++++ drivers/clk/sunxi/clk_a31.c | 8 ++++++++ drivers/clk/sunxi/clk_a64.c | 6 ++++++ drivers/clk/sunxi/clk_a83t.c | 6 ++++++ drivers/clk/sunxi/clk_h3.c | 6 ++++++ drivers/clk/sunxi/clk_h6.c | 6 ++++++ drivers/clk/sunxi/clk_r40.c | 8 ++++++++ 9 files changed, 53 insertions(+)
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_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..98af372ec5 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_MMC0] = RESET(0x2c0, BIT(9)), + [RST_BUS_MMC0] = 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)),

The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc")) + 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,allwinner,sun9i-a80-mmc", + .data = (ulong)&a80_mmc_clk_desc }, { } };

On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc"))
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,allwinner,sun9i-a80-mmc",
This can be "allwinner,sun9i-a80-mmc-config-clk"

On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki jagan@amarulasolutions.com wrote:
On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc"))
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,allwinner,sun9i-a80-mmc",
This can be "allwinner,sun9i-a80-mmc-config-clk"
*Must*, not can. :)
ChenYu

On Mon, 21 Jan 2019 17:34:25 +0800 Chen-Yu Tsai wens@csie.org wrote:
On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki jagan@amarulasolutions.com wrote:
On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc"))
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,allwinner,sun9i-a80-mmc",
This can be "allwinner,sun9i-a80-mmc-config-clk"
*Must*, not can. :)
Indeed, thanks for spotting this, Jagan.
Also I just figured that we need to enable the parent clocks and resets of this clock itself. I hope we can do this unconditionally, even for the complex CCU, as enabling fixed-clocks should be covered by the clock framework already.
Cheers, Andre.

On Mon, Jan 21, 2019 at 5:39 PM Andre Przywara andre.przywara@arm.com wrote:
On Mon, 21 Jan 2019 17:34:25 +0800 Chen-Yu Tsai wens@csie.org wrote:
On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki jagan@amarulasolutions.com wrote:
On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc"))
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,allwinner,sun9i-a80-mmc",
This can be "allwinner,sun9i-a80-mmc-config-clk"
*Must*, not can. :)
Indeed, thanks for spotting this, Jagan.
Also I just figured that we need to enable the parent clocks and resets of this clock itself. I hope we can do this unconditionally, even for the complex CCU, as enabling fixed-clocks should be covered by the clock framework already.
You need to deassert the reset control for the MMC clock config block, otherwise none of the toggles are going to work. And you can't assert it afterwards, otherwise the bits revert to default. Also, you need to enable the bus clock to be able to access the bits.
So yeah, you can do this unconditionally. The Linux driver simply tries to be smarter and only enables the bus clock when toggling the bits.
Regards ChenYu

On Mon, 21 Jan 2019 18:02:17 +0800 Chen-Yu Tsai wens@csie.org wrote:
On Mon, Jan 21, 2019 at 5:39 PM Andre Przywara andre.przywara@arm.com wrote:
On Mon, 21 Jan 2019 17:34:25 +0800 Chen-Yu Tsai wens@csie.org wrote:
On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki jagan@amarulasolutions.com wrote:
On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc"))
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,allwinner,sun9i-a80-mmc",
This can be "allwinner,sun9i-a80-mmc-config-clk"
*Must*, not can. :)
Indeed, thanks for spotting this, Jagan.
Also I just figured that we need to enable the parent clocks and resets of this clock itself. I hope we can do this unconditionally, even for the complex CCU, as enabling fixed-clocks should be covered by the clock framework already.
You need to deassert the reset control for the MMC clock config block, otherwise none of the toggles are going to work. And you can't assert it afterwards, otherwise the bits revert to default. Also, you need to enable the bus clock to be able to access the bits.
Yeah, that was what I was thinking of.
So yeah, you can do this unconditionally. The Linux driver simply tries to be smarter and only enables the bus clock when toggling the bits.
With "unconditionally" I meant doing this in the probe routine, which right now I *share* between the CCU clocks and this config clock. The patch is pretty small because of this.
The CCU has only fixed parent clocks and no resets, so I think we can add parent clock and optional reset handling there and should cover this config clock as well, without providing a separate probe routine (and the rest of the boilerplate).
Cheers, Andre.

On Mon, Jan 21, 2019 at 6:12 PM Andre Przywara andre.przywara@arm.com wrote:
On Mon, 21 Jan 2019 18:02:17 +0800 Chen-Yu Tsai wens@csie.org wrote:
On Mon, Jan 21, 2019 at 5:39 PM Andre Przywara andre.przywara@arm.com wrote:
On Mon, 21 Jan 2019 17:34:25 +0800 Chen-Yu Tsai wens@csie.org wrote:
On Mon, Jan 21, 2019 at 5:32 PM Jagan Teki jagan@amarulasolutions.com wrote:
On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
The A80 handles resets and clock gates for the MMC devices differently, outside of the CCU IP block. Consequently we have a separate clock device with a separate binding for that.
Implement that with the respective clock gates and resets to allow the A80 taking part in the DM_MMC game.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/clk/sunxi/clk_a80.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk_a80.c b/drivers/clk/sunxi/clk_a80.c index d6dd6a1fa1..2bfc2ca9f5 100644 --- a/drivers/clk/sunxi/clk_a80.c +++ b/drivers/clk/sunxi/clk_a80.c @@ -30,19 +30,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,allwinner,sun9i-a80-mmc"))
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,allwinner,sun9i-a80-mmc",
This can be "allwinner,sun9i-a80-mmc-config-clk"
*Must*, not can. :)
Indeed, thanks for spotting this, Jagan.
Also I just figured that we need to enable the parent clocks and resets of this clock itself. I hope we can do this unconditionally, even for the complex CCU, as enabling fixed-clocks should be covered by the clock framework already.
You need to deassert the reset control for the MMC clock config block, otherwise none of the toggles are going to work. And you can't assert it afterwards, otherwise the bits revert to default. Also, you need to enable the bus clock to be able to access the bits.
Yeah, that was what I was thinking of.
So yeah, you can do this unconditionally. The Linux driver simply tries to be smarter and only enables the bus clock when toggling the bits.
With "unconditionally" I meant doing this in the probe routine, which right now I *share* between the CCU clocks and this config clock. The patch is pretty small because of this.
The CCU has only fixed parent clocks and no resets, so I think we can add parent clock and optional reset handling there and should cover this config clock as well, without providing a separate probe routine (and the rest of the boilerplate).
I think I'm missing some context here. You want to do this in the shared *bind* function in this file? Or the shared *probe* function in drivers/clk/sunxi/clk_sunxi.c ?
I assume it's the former? In which case you already have a conditional to check the compatible string. So you could just expand that block and put it there?
Either way I think it's not up to me about what's acceptable. :)
ChenYu

Now that we have the gate clocks and the reset gates in our new Allwinner clock driver, let's make use of them in the MMC driver, when DM_MMC is defined. We treat the reset device as optional now, as the older SoCs don't implement it.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mmc/sunxi_mmc.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 302332bf97..35cdccdd7f 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,8 +644,14 @@ 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) @@ -676,7 +685,6 @@ static int sunxi_mmc_bind(struct udevice *dev) }
static const struct sunxi_mmc_variant sun4i_a10_variant = { - .gate_offset = 0x60, .mclk_offset = 0x88, };

Even though the H6 MMC device is fully compatible to the A64 implementation, we need to differentiate between the two, as the mod clock is on a different address, and we don't use the DT for that yet.
Add a separate "variant" which just holds the different MMIO address.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mmc/sunxi_mmc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 35cdccdd7f..16646012bc 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -688,6 +688,10 @@ static const struct sunxi_mmc_variant sun4i_a10_variant = { .mclk_offset = 0x88, };
+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", @@ -701,6 +705,14 @@ static const struct udevice_id sunxi_mmc_ids[] = { .compatible = "allwinner,sun7i-a20-mmc", .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 */ } };

From: Jagan Teki jagan@amarulasolutions.com
From our driver's perspective there is no difference between the MMC
controllers for the A83T, A64 and H5 compared to the A10/A20 type.
As we now have support for the formerly missing reset gates, we can add their compatible strings, to make those SoCs work with DM_MMC.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mmc/sunxi_mmc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 16646012bc..62b658c435 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -705,6 +705,18 @@ 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,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,

Add the Allwinner A80 mod clock address and bind it to its compatible string. The special config clock is handled via the clock driver.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mmc/sunxi_mmc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 62b658c435..87424c23dc 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -692,6 +692,10 @@ static const struct sunxi_mmc_variant sun50i_h6_variant = { .mclk_offset = 0x830, };
+static const struct sunxi_mmc_variant sun9i_a80_variant = { + .mclk_offset = 0x410, +}; + static const struct udevice_id sunxi_mmc_ids[] = { { .compatible = "allwinner,sun4i-a10-mmc", @@ -709,6 +713,10 @@ static const struct udevice_id sunxi_mmc_ids[] = { .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,

If a board DT describes a cd-gpios property, but also marks the storage as non-removable, we must ignore the GPIO (as Linux does).
Teach the DM_MMC part of the Allwinner MMC driver about the non-removable DT property, to fix DM_MMC access on the SoPine and Pine64-LTS board.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mmc/sunxi_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 87424c23dc..374775194d 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -658,7 +658,8 @@ static int sunxi_mmc_probe(struct udevice *dev) 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);

On Sat, Jan 19, 2019 at 7:03 AM Andre Przywara andre.przywara@arm.com wrote:
If a board DT describes a cd-gpios property, but also marks the storage as non-removable, we must ignore the GPIO (as Linux does).
Teach the DM_MMC part of the Allwinner MMC driver about the non-removable DT property, to fix DM_MMC access on the SoPine and Pine64-LTS board.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/mmc/sunxi_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 87424c23dc..374775194d 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -658,7 +658,8 @@ static int sunxi_mmc_probe(struct udevice *dev) 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,
How about fixing this in dts?

On Fri, 25 Jan 2019 12:46:38 +0530 Jagan Teki jagan@amarulasolutions.com wrote:
On Sat, Jan 19, 2019 at 7:03 AM Andre Przywara andre.przywara@arm.com wrote:
If a board DT describes a cd-gpios property, but also marks the storage as non-removable, we must ignore the GPIO (as Linux does).
Teach the DM_MMC part of the Allwinner MMC driver about the non-removable DT property, to fix DM_MMC access on the SoPine and Pine64-LTS board.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/mmc/sunxi_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 87424c23dc..374775194d 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -658,7 +658,8 @@ static int sunxi_mmc_probe(struct udevice *dev) 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,
How about fixing this in dts?
Sure, eventually, once I confirmed that there is really no CD wire connected. But since Linux can cope with that, U-Boot should do so as well.
Cheers, Andre.

On Sat, Jan 19, 2019 at 7:03 AM Andre Przywara andre.przywara@arm.com wrote:
If a board DT describes a cd-gpios property, but also marks the storage as non-removable, we must ignore the GPIO (as Linux does).
Teach the DM_MMC part of the Allwinner MMC driver about the non-removable DT property, to fix DM_MMC access on the SoPine and Pine64-LTS board.
Signed-off-by: Andre Przywara andre.przywara@arm.com
Applied to u-boot-sunxi/master

From: Jagan Teki jagan@amarulasolutions.com
Enable DM_MMC for all Allwinner SoCs, this will eventually enable BLK.
Also removed DM_MMC enablement in few parts of sunxi configurations.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - 3 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a23cbd5719..075c3dfe81 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/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/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

On Fri, 18 Jan 2019 at 18:33, Andre Przywara andre.przywara@arm.com wrote:
From: Jagan Teki jagan@amarulasolutions.com
Enable DM_MMC for all Allwinner SoCs, this will eventually enable BLK.
Also removed DM_MMC enablement in few parts of sunxi configurations.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com Signed-off-by: Andre Przywara andre.przywara@arm.com
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - 3 files changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

The Allwinner MMC supports both the legacy approach and the driver model, at the cost of quite some #ifdefs.
Mark the closing #endifs with their respective config symbol, to make it more obvious where each part ends and begins.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mmc/sunxi_mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 374775194d..ee0bc9da89 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -104,7 +104,7 @@ static int mmc_resource_init(int sdc_no)
return ret; } -#endif +#endif /* !DM_MMC */
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) { @@ -566,7 +566,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
return mmc_create(cfg, priv); } -#else +#else /* DM_MMC */
static int sunxi_mmc_set_ios(struct udevice *dev) { @@ -747,4 +747,4 @@ U_BOOT_DRIVER(sunxi_mmc_drv) = { .platdata_auto_alloc_size = sizeof(struct sunxi_mmc_plat), .priv_auto_alloc_size = sizeof(struct sunxi_mmc_priv), }; -#endif +#endif /* DM_MMC */

Hi Andre,
On Fri, 18 Jan 2019 at 18:33, Andre Przywara andre.przywara@arm.com wrote:
The Allwinner MMC supports both the legacy approach and the driver model, at the cost of quite some #ifdefs.
Mark the closing #endifs with their respective config symbol, to make it more obvious where each part ends and begins.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/mmc/sunxi_mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
We should be able to remove the non-DM_MMC code now.
Regards, Simon

On Thu, 31 Jan 2019 03:04:21 -0700 Simon Glass sjg@chromium.org wrote:
Hi Andre,
On Fri, 18 Jan 2019 at 18:33, Andre Przywara andre.przywara@arm.com wrote:
The Allwinner MMC supports both the legacy approach and the driver model, at the cost of quite some #ifdefs.
Mark the closing #endifs with their respective config symbol, to make it more obvious where each part ends and begins.
Signed-off-by: Andre Przywara andre.przywara@arm.com
drivers/mmc/sunxi_mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
We should be able to remove the non-DM_MMC code now.
Unfortunately not, since the SPL still uses the legacy interface. Not sure we can easily fix that without blowing up the code, given that the 64-bit SPL is REALLY tight. If you are around in Brussels on the weekend, we can have a chat about that.
Cheers, Andre.

On Fri, Jan 18, 2019 at 5:32 PM Andre Przywara andre.przywara@arm.com wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
It breaks autoboot for eMMC on Pinebook.
It complains:
Card did not respond to voltage select! MMC: no card present
Card itself is present, i.e. if I do these command I see card info:
mmc dev 2 mmc info
Regards, Vasily
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5

On 19/01/2019 18:32, Vasily Khoruzhick wrote:
On Fri, Jan 18, 2019 at 5:32 PM Andre Przywara andre.przywara@arm.com wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
It breaks autoboot for eMMC on Pinebook.
It complains:
Card did not respond to voltage select! MMC: no card present
Card itself is present, i.e. if I do these command I see card info:
mmc dev 2 mmc info
Thanks for the report! So is this with this U-Boot on an SD card or on the eMMC?
Can you try to add the mmc1 = &mmc2; alias that Jagan suggested: https://lists.denx.de/pipermail/u-boot/2019-January/354367.html
Thanks, Andre.
Regards, Vasily
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5

On Sat, Jan 19, 2019 at 12:35 PM André Przywara andre.przywara@arm.com wrote:
Thanks for the report! So is this with this U-Boot on an SD card or on the eMMC?
This is with u-boot on eMMC and no SD card present in the slot.
Can you try to add the mmc1 = &mmc2; alias that Jagan suggested: https://lists.denx.de/pipermail/u-boot/2019-January/354367.html
It didn't help.
Thanks, Andre.
Regards, Vasily
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5

On Sat, Jan 19, 2019 at 01:30:46AM +0000, Andre Przywara wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
Testing with A10 Gemei G9 Tablet, FEL mode is broken:
a) With usb-boot via fel:
I get following error/warning: Loading Environment from FAT... Card did not respond to voltage select!
=> mmc list mmc@1c0f000: 0 ### All commands below stalls for a bit (~2 seconds), but return nothing => mmc info => mmc dev 0 => mmc part
b) When booting from SD-card [1], card is properly found, identified and even partitions are there.
dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 seek=8 bs=1024
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.

On 20/01/2019 19:51, Priit Laes wrote:
Hi,
On Sat, Jan 19, 2019 at 01:30:46AM +0000, Andre Przywara wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
Testing with A10 Gemei G9 Tablet, FEL mode is broken:
a) With usb-boot via fel:
I get following error/warning: Loading Environment from FAT... Card did not respond to voltage select!
=> mmc list mmc@1c0f000: 0 ### All commands below stalls for a bit (~2 seconds), but return nothing => mmc info => mmc dev 0 => mmc part
Ah, thanks for mentioning that. Can reproduce this on the Pine64-LTS. And I was already wondering why we wouldn't need the pinctrl parts I was working on ...
So if we boot from SD card, the SPL sets up the pinmux for the SD pins, and stuff works. For U-Boot proper we rely on board_mmc_init() to do this for us, but this gets only called for !DM_MMC configurations. If we boot with a SPL which doesn't initialise the MMC (booting via FEL or SPI or NAND), the pinmux setup is missing and it fails.
If anyone has a clever idea how to fix this without too much hacking and without bringing in a DM_PINCTRL driver, I am all ears.
Thanks for testing and the report!
Cheers, Andre.
b) When booting from SD-card [1], card is properly found, identified and even partitions are there.
dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 seek=8 bs=1024
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.

On Mon, Jan 21, 2019 at 12:54:52AM +0000, André Przywara wrote:
On 20/01/2019 19:51, Priit Laes wrote:
Hi,
On Sat, Jan 19, 2019 at 01:30:46AM +0000, Andre Przywara wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
Testing with A10 Gemei G9 Tablet, FEL mode is broken:
a) With usb-boot via fel:
I get following error/warning: Loading Environment from FAT... Card did not respond to voltage select!
=> mmc list mmc@1c0f000: 0 ### All commands below stalls for a bit (~2 seconds), but return nothing => mmc info => mmc dev 0 => mmc part
Similar issue with A20 Olinuxino Lime2 revk with SPI.
a) Fel mode usb-boot failure (cannot properly initialize sd / emmc) b) SPI boot failure (cannot properly initialize sd / emmc)
c) Regular SD-card boot works ok! d) eMMC boot works ok!
Ah, thanks for mentioning that. Can reproduce this on the Pine64-LTS. And I was already wondering why we wouldn't need the pinctrl parts I was working on ...
So if we boot from SD card, the SPL sets up the pinmux for the SD pins, and stuff works. For U-Boot proper we rely on board_mmc_init() to do this for us, but this gets only called for !DM_MMC configurations. If we boot with a SPL which doesn't initialise the MMC (booting via FEL or SPI or NAND), the pinmux setup is missing and it fails.
If anyone has a clever idea how to fix this without too much hacking and without bringing in a DM_PINCTRL driver, I am all ears.
Well, we know that there are basically only a few SPL boot options..
Thanks for testing and the report!
Cheers, Andre.
b) When booting from SD-card [1], card is properly found, identified and even partitions are there.
dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 seek=8 bs=1024
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.

Hi,
....
Testing with A10 Gemei G9 Tablet, FEL mode is broken:
a) With usb-boot via fel:
I get following error/warning: Loading Environment from FAT... Card did not respond to voltage select!
=> mmc list mmc@1c0f000: 0 ### All commands below stalls for a bit (~2 seconds), but return nothing => mmc info => mmc dev 0 => mmc part
Similar issue with A20 Olinuxino Lime2 revk with SPI.
a) Fel mode usb-boot failure (cannot properly initialize sd / emmc) b) SPI boot failure (cannot properly initialize sd / emmc)
c) Regular SD-card boot works ok! d) eMMC boot works ok!
Can you please try whether the patch below fixes this? At least it worked for me with FEL booting my Pine64-LTS.
Not totally happy with it, but it seems like we do a similar trick for I2C anyway, so ...
Cheers, Andre
--- board/sunxi/board.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index ad14837291..e330367d1d 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 I2C clocks until proper sunxi DM + * clk, reset and pinctrl drivers land. + */ + 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(); }

On Mon, Jan 21, 2019 at 08:51:10AM +0000, Andre Przywara wrote:
Hi,
....
Testing with A10 Gemei G9 Tablet, FEL mode is broken:
a) With usb-boot via fel:
I get following error/warning: Loading Environment from FAT... Card did not respond to voltage select!
=> mmc list mmc@1c0f000: 0 ### All commands below stalls for a bit (~2 seconds), but return nothing => mmc info => mmc dev 0 => mmc part
Similar issue with A20 Olinuxino Lime2 revk with SPI.
a) Fel mode usb-boot failure (cannot properly initialize sd / emmc) b) SPI boot failure (cannot properly initialize sd / emmc)
c) Regular SD-card boot works ok! d) eMMC boot works ok!
Can you please try whether the patch below fixes this? At least it worked for me with FEL booting my Pine64-LTS.
Not totally happy with it, but it seems like we do a similar trick for I2C anyway, so ...
Yes, it fixes it.
Tested on A20-Olinuxino-Lime2-emmc.
PS. Comment regarding i2c looks a bit odd..
Cheers, Andre
board/sunxi/board.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index ad14837291..e330367d1d 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 I2C clocks until proper sunxi DM
* clk, reset and pinctrl drivers land.
*/
- 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();
}
2.14.5
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.

On Mon, 21 Jan 2019 00:54:52 +0000 André Przywara andre.przywara@arm.com wrote:
On 20/01/2019 19:51, Priit Laes wrote:
Hi,
On Sat, Jan 19, 2019 at 01:30:46AM +0000, Andre Przywara wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
Testing with A10 Gemei G9 Tablet, FEL mode is broken:
a) With usb-boot via fel:
I get following error/warning: Loading Environment from FAT... Card did not respond to voltage select! => mmc list mmc@1c0f000: 0 ### All commands below stalls for a bit (~2 seconds), but return nothing => mmc info => mmc dev 0 => mmc part
Ah, thanks for mentioning that. Can reproduce this on the Pine64-LTS. And I was already wondering why we wouldn't need the pinctrl parts I was working on ...
So if we boot from SD card, the SPL sets up the pinmux for the SD pins, and stuff works. For U-Boot proper we rely on board_mmc_init() to do this for us, but this gets only called for !DM_MMC configurations. If we boot with a SPL which doesn't initialise the MMC (booting via FEL or SPI or NAND), the pinmux setup is missing and it fails.
If anyone has a clever idea how to fix this without too much hacking and without bringing in a DM_PINCTRL driver, I am all ears.
I had similar problem with imx6. The DM_PINCTRL seems to be a must-have here.
There is a similar problem - driver model tends to re-configure the pinmux configuration in SPL and u-boot proper (also before relocation if asked).
Thanks for testing and the report!
Cheers, Andre.
b) When booting from SD-card [1], card is properly found, identified and even partitions are there.
dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 seek=8 bs=1024
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
Cheers, Andre.
Andre Przywara (7): sunxi: clk: add MMC gates/resets sunxi: clk: A80: add MMC clock support mmc: sunxi: Add DM clk and reset support mmc: sunxi: Add H6 support mmc: sunxi: Add A80 support mmc: sunxi: Honour non-removable property in DT mmc: sunxi: Mark end of DM_MMC #ifdefs
Jagan Teki (2): mmc: sunxi: Add missing compatible strings arm: sunxi: Enable DM_MMC
arch/arm/Kconfig | 1 + arch/arm/mach-sunxi/Kconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - drivers/clk/sunxi/clk_a10.c | 4 +++ drivers/clk/sunxi/clk_a10s.c | 3 ++ drivers/clk/sunxi/clk_a23.c | 6 ++++ drivers/clk/sunxi/clk_a31.c | 8 +++++ drivers/clk/sunxi/clk_a64.c | 6 ++++ drivers/clk/sunxi/clk_a80.c | 28 ++++++++++++++++- drivers/clk/sunxi/clk_a83t.c | 6 ++++ drivers/clk/sunxi/clk_h3.c | 6 ++++ drivers/clk/sunxi/clk_h6.c | 6 ++++ drivers/clk/sunxi/clk_r40.c | 8 +++++ drivers/mmc/sunxi_mmc.c | 59 +++++++++++++++++++++++++++++------ 14 files changed, 131 insertions(+), 12 deletions(-)
-- 2.14.5
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

On Sat, Jan 19, 2019 at 7:02 AM Andre Przywara andre.przywara@arm.com wrote:
This series enables the Allwinner MMC driver to drive all SoCs with its DM_MMC variant. We use the gates clock and reset support from the new clock driver, but keep the actual mod clock in its somewhat hackish state. Properly supporting this via the clock driver is a bit more work. The per-compatible variant struct for now only holds the mod clock address (which will go away), but we will need the struct later again for the various timing modes.
This allows us to eventually enable DM_MMC for all SoCs, and get rid of the nasty deprecation warning.
The first patch adds the MMC clock gates and resets to the clock driver. Patch 2/9 adds support for the A80 MMC config clock, which is a bit special. I can't test this, so please give this a try if you have a board.
Patch 3 uses the new clocks in the MMC driver, the following three patches add the remaining compatible strings along with their required mod clock addresses.
Patch 7 fixes the Pine64-LTS board, while patch 8 eventually enables everything. Patch 9 is some comment fix to make it easier to reason about what part of the driver is for DM_MMC and which is not.
I successfully compiled the HEAD for all 142 Allwinner boards, also compiled all patches for selected boards.
This was briefly tested on Pine-H64 (H6), Pine64-LTS (A64), OrangePi PC 2 (H5), OrangePi Zero (H2+) and BananaPi-M1 (A20).
Please run it on every board that you can get hold of to give this series a good shake.
This goes on top of current sunxi/master (543049ab5906) and is available on https://github.com/apritzel/u-boot/commits/sunxi-dm.
This replaces Jagan's v2 series "mmc: sunxi: Enable DM_MMC" in a more driver model compliant way, borrowing two patches from him.
You may be wait some tome before I'm commenting or for next version changes. Many changes like CLK and RESET support to mmc been in ML, since you are not happy with v2 I prepared the CLK version for v2 (in between you sent your version). Let me grab your few changes and finalize my v3.
participants (8)
-
Andre Przywara
-
André Przywara
-
Chen-Yu Tsai
-
Jagan Teki
-
Lukasz Majewski
-
Priit Laes
-
Simon Glass
-
Vasily Khoruzhick