Skip to contentSkip to conversation

EXYNOS5: Enable dwmmc

PATCH Superseded Amar 4 participants 30 messages Dec 17, 2012 – Dec 27, 2012

Subsystems (4)

v1 of 9 Superseded Latest is v9 →

lore
Share & tools
lore

Amar

author
#0 lore raw

cover EXYNOS5: Enable dwmmc

This patch set enables and initialises dwmmc for Exynos5250 on SMDK5250. Adds driver changes required for dwmmc.
Adds dt support for dwmmc.
Adds eMMC booting feature for SMDK5250.

This patch set is based on:
"EXYNOS: mmc: support DesignWare Controller for Samsung-SoC", which is merged in u-boot-mmc
"Exynos: clock: support get_mmc_clk for exynos"
"Add DT based ethernet driver for SMDK5250"
"SMDK5250: Add FDT support"

Amar (9):
FDT: Add compatible string for DWMMC
EXYNOS5: FDT: Add DWMMC device node data
DWMMC: Initialise dwmci and resolved the boot partition write issue
EXYNOS5: DWMMC: Added dt support for DWMMC
EXYNOS5: DWMMC: API to set mmc clock divisor
SMDK5250: Enable DWMMC
MMC: APIs to support creation of boot partition
SMDK5250: Enable eMMC booting
COMMON: MMC: Command to support eMMC booting

 arch/arm/cpu/armv7/exynos/clock.c         |   39 +++++++++-
 arch/arm/dts/exynos5250.dtsi              |   32 ++++++++
 arch/arm/include/asm/arch-exynos/clk.h    |    1 +
 arch/arm/include/asm/arch-exynos/dwmmc.h  |    4 +
 board/samsung/dts/exynos5250-smdk5250.dts |   24 ++++++
 board/samsung/smdk5250/smdk5250.c         |   36 ++++++++-
 board/samsung/smdk5250/spl_boot.c         |   38 +++++++++-
 common/cmd_mmc.c                          |  101 ++++++++++++++++++++++++-
 drivers/mmc/dw_mmc.c                      |   12 +++-
 drivers/mmc/exynos_dw_mmc.c               |  117 +++++++++++++++++++++++++++--
 drivers/mmc/mmc.c                         |  118 +++++++++++++++++++++++++++++
 include/configs/exynos5250-dt.h           |    9 ++
 include/dwmmc.h                           |    4 +
 include/fdtdec.h                          |    1 +
 include/mmc.h                             |   16 ++++
 lib/fdtdec.c                              |    1 +
 16 files changed, 538 insertions(+), 15 deletions(-)
author
#1 lore raw

PATCH 1/9 FDT: Add compatible string for DWMMC

Add required compatible information for DWMMC driver.

---
 include/fdtdec.h |    1 +
 lib/fdtdec.c     |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)
include/fdtdec.h +1 -0
index 539bb1b..f09c281 100644
@@ -74,6 +74,7 @@ enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS5_SOUND,	/* Exynos Sound */
 	COMPAT_WOLFSON_WM8994_CODEC,	/* Wolfson WM8994 Sound Codec */
 	COMPAT_SAMSUNG_EXYNOS_SPI,	/* Exynos SPI */
+	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
 
 	COMPAT_COUNT,
 };
lib/fdtdec.c +1 -0
index 44c249d..6597661 100644
@@ -51,6 +51,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
 	COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
 	COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"),
+	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
Signature · 1 line
1.7.0.4
#2 lore raw

PATCH 1/9 FDT: Add compatible string for DWMMC

Quoted 3 lines · Amar

Add required compatible information for DWMMC driver.

Quoted 32 lines
---
 include/fdtdec.h |    1 +
 lib/fdtdec.c     |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)
include/fdtdec.h +1 -0
index 539bb1b..f09c281 100644
@@ -74,6 +74,7 @@ enum fdt_compat_id {
        COMPAT_SAMSUNG_EXYNOS5_SOUND,   /* Exynos Sound */
        COMPAT_WOLFSON_WM8994_CODEC,    /* Wolfson WM8994 Sound Codec */
        COMPAT_SAMSUNG_EXYNOS_SPI,      /* Exynos SPI */
+       COMPAT_SAMSUNG_EXYNOS5_DWMMC,   /* Exynos5 DWMMC controller */
 
        COMPAT_COUNT,
 };
lib/fdtdec.c +1 -1
index 44c249d..6597661 100644
@@ -51,6 +51,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
        COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
        COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"),
+       COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
--

1.7.0.4

author
#3 lore raw

PATCH 2/9 EXYNOS5: FDT: Add DWMMC device node data

In reply to Amar

Add DWMMC device node data for exynos5

---
 arch/arm/dts/exynos5250.dtsi              |   32 +++++++++++++++++++++++++++++
 board/samsung/dts/exynos5250-smdk5250.dts |   24 +++++++++++++++++++++
 2 files changed, 56 insertions(+), 0 deletions(-)
arch/arm/dts/exynos5250.dtsi +32 -0
index 1008797..b701ae5 100644
@@ -138,4 +138,36 @@
 		reg = <0x131b0000 0x30>;
 		interrupts = <0 130 0>;
 	};
+
+	dwmmc at 12200000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "samsung,exynos5250-dwmmc";
+		reg = <0x12200000 0x1000>;
+		interrupts = <0 75 0>;
+	};
+
+	dwmmc at 12210000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "samsung,exynos5250-dwmmc";
+		reg = <0x12210000 0x1000>;
+		interrupts = <0 76 0>;
+	};
+
+	dwmmc at 12220000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "samsung,exynos5250-dwmmc";
+		reg = <0x12220000 0x1000>;
+		interrupts = <0 77 0>;
+	};
+
+	dwmmc at 12230000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "samsung,exynos5250-dwmmc";
+		reg = <0x12230000 0x1000>;
+		interrupts = <0 78 0>;
+	};
 };
board/samsung/dts/exynos5250-smdk5250.dts +24 -0
index a8e62da..b1b8d71 100644
@@ -30,6 +30,10 @@
 		spi2 = "/spi at 12d40000";
 		spi3 = "/spi at 131a0000";
 		spi4 = "/spi at 131b0000";
+		dwmmc0 = "/dwmmc at 12200000";
+		dwmmc1 = "/dwmmc at 12210000";
+		dwmmc2 = "/dwmmc at 12220000";
+		dwmmc3 = "/dwmmc at 12230000";
 	};
 
 	sromc at 12250000 {
@@ -59,4 +63,24 @@
 			compatible = "wolfson,wm8994-codec";
 		};
 	};
+
+	dwmmc at 12200000 {
+		index = <0>;
+		bus-width = <8>;
+		timing = <1 3 3>;
+	};
+
+	dwmmc at 12210000 {
+		status = "disabled";
+	};
+
+	dwmmc at 12220000 {
+		index = <2>;
+		bus-width = <4>;
+		timing = <1 2 3>;
+	};
+
+	dwmmc at 12230000 {
+		status = "disabled";
+	};
 };
Signature · 1 line
1.7.0.4
#4 lore raw

PATCH 2/9 EXYNOS5: FDT: Add DWMMC device node data

Hi Amar,

Quoted 6 lines · Amar

Add DWMMC device node data for exynos5

---
 arch/arm/dts/exynos5250.dtsi              |   32 +++++++++++++++++++++++++++++
 board/samsung/dts/exynos5250-smdk5250.dts |   24 +++++++++++++++++++++

Do you also have a binding file for this please?

Quoted 59 lines
 2 files changed, 56 insertions(+), 0 deletions(-)
arch/arm/dts/exynos5250.dtsi +32 -0
index 1008797..b701ae5 100644
@@ -138,4 +138,36 @@
                reg = <0x131b0000 0x30>;
                interrupts = <0 130 0>;
        };
+
+       dwmmc at 12200000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12200000 0x1000>;
+               interrupts = <0 75 0>;
+       };
+
+       dwmmc at 12210000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12210000 0x1000>;
+               interrupts = <0 76 0>;
+       };
+
+       dwmmc at 12220000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12220000 0x1000>;
+               interrupts = <0 77 0>;
+       };
+
+       dwmmc at 12230000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12230000 0x1000>;
+               interrupts = <0 78 0>;
+       };
 };
board/samsung/dts/exynos5250-smdk5250.dts +4 -0
index a8e62da..b1b8d71 100644
@@ -30,6 +30,10 @@
                spi2 = "/spi at 12d40000";
                spi3 = "/spi at 131a0000";
                spi4 = "/spi at 131b0000";
+               dwmmc0 = "/dwmmc at 12200000";
+               dwmmc1 = "/dwmmc at 12210000";
+               dwmmc2 = "/dwmmc at 12220000";
+               dwmmc3 = "/dwmmc at 12230000";
        };
 
        sromc at 12250000 {

board/samsung/dts/exynos5250-smdk5250.dts line 68

Quoted 6 lines
board/samsung/dts/exynos5250-smdk5250.dts +3 -0
@@ -59,4 +63,24 @@
                        compatible = "wolfson,wm8994-codec";
                };
        };
+
+       dwmmc at 12200000 {
+               index = <0>;

Do you really need the index? You have the numbering from the aliaes I think.

board/samsung/dts/exynos5250-smdk5250.dts line 70

Quoted 2 lines
board/samsung/dts/exynos5250-smdk5250.dts +2 -0
+               bus-width = <8>;
+               timing = <1 3 3>;

Might need a "samsung," prefix on these?

Quoted 17 lines
board/samsung/dts/exynos5250-smdk5250.dts +15 -1
+       };
+
+       dwmmc at 12210000 {
+               status = "disabled";
+       };
+
+       dwmmc at 12220000 {
+               index = <2>;
+               bus-width = <4>;
+               timing = <1 2 3>;
+       };
+
+       dwmmc at 12230000 {
+               status = "disabled";
+       };
 };
--
Quoted 2 lines

1.7.0.4

Regards,
Simon

#5 lore raw

PATCH 2/9 EXYNOS5: FDT: Add DWMMC device node data

Quoted 80 lines · Simon Glass

Hi Amar,

Quoted 6 lines · Amar

Add DWMMC device node data for exynos5

---
 arch/arm/dts/exynos5250.dtsi              |   32 +++++++++++++++++++++++++++++
 board/samsung/dts/exynos5250-smdk5250.dts |   24 +++++++++++++++++++++

Do you also have a binding file for this please?

Quoted 59 lines
 2 files changed, 56 insertions(+), 0 deletions(-)
arch/arm/dts/exynos5250.dtsi +32 -0
index 1008797..b701ae5 100644
@@ -138,4 +138,36 @@
                reg = <0x131b0000 0x30>;
                interrupts = <0 130 0>;
        };
+
+       dwmmc at 12200000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12200000 0x1000>;
+               interrupts = <0 75 0>;
+       };
+
+       dwmmc at 12210000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12210000 0x1000>;
+               interrupts = <0 76 0>;
+       };
+
+       dwmmc at 12220000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12220000 0x1000>;
+               interrupts = <0 77 0>;
+       };
+
+       dwmmc at 12230000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12230000 0x1000>;
+               interrupts = <0 78 0>;
+       };
 };
board/samsung/dts/exynos5250-smdk5250.dts +4 -0
index a8e62da..b1b8d71 100644
@@ -30,6 +30,10 @@
                spi2 = "/spi at 12d40000";
                spi3 = "/spi at 131a0000";
                spi4 = "/spi at 131b0000";
+               dwmmc0 = "/dwmmc at 12200000";
+               dwmmc1 = "/dwmmc at 12210000";
+               dwmmc2 = "/dwmmc at 12220000";
+               dwmmc3 = "/dwmmc at 12230000";
        };
 
        sromc at 12250000 {

board/samsung/dts/exynos5250-smdk5250.dts line 68

Quoted 6 lines
board/samsung/dts/exynos5250-smdk5250.dts +3 -0
@@ -59,4 +63,24 @@
                        compatible = "wolfson,wm8994-codec";
                };
        };
+
+       dwmmc at 12200000 {
+               index = <0>;

Do you really need the index? You have the numbering from the aliaes I think.

Quoted 4 lines

board/samsung/dts/exynos5250-smdk5250.dts line 70

Quoted 2 lines
board/samsung/dts/exynos5250-smdk5250.dts +2 -0
+               bus-width = <8>;
+               timing = <1 3 3>;

Might need a "samsung," prefix on these?

I think better that use the "exynos" instead of "samsung". how about?

Quoted 28 lines
Quoted 18 lines
board/samsung/dts/exynos5250-smdk5250.dts +15 -1
+       };
+
+       dwmmc at 12210000 {
+               status = "disabled";
+       };
+
+       dwmmc at 12220000 {
+               index = <2>;
+               bus-width = <4>;
+               timing = <1 2 3>;
+       };
+
+       dwmmc at 12230000 {
+               status = "disabled";
+       };
 };
--
Quoted 2 lines

1.7.0.4

Regards,
Simon
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#6 lore raw

PATCH 2/9 EXYNOS5: FDT: Add DWMMC device node data

Hi,

Quoted 82 lines · Jaehoon Chung
Quoted 8 lines · Simon Glass

Hi Amar,

Quoted 5 lines · Amar

Add DWMMC device node data for exynos5

---
 arch/arm/dts/exynos5250.dtsi              |   32

+++++++++++++++++++++++++++++

Quoted 40 lines
Quoted 1 line
 board/samsung/dts/exynos5250-smdk5250.dts |   24 +++++++++++++++++++++

Do you also have a binding file for this please?

Quoted 36 lines
 2 files changed, 56 insertions(+), 0 deletions(-)
arch/arm/dts/exynos5250.dtsi +26 -0
index 1008797..b701ae5 100644
@@ -138,4 +138,36 @@
                reg = <0x131b0000 0x30>;
                interrupts = <0 130 0>;
        };
+
+       dwmmc at 12200000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12200000 0x1000>;
+               interrupts = <0 75 0>;
+       };
+
+       dwmmc at 12210000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12210000 0x1000>;
+               interrupts = <0 76 0>;
+       };
+
+       dwmmc at 12220000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12220000 0x1000>;
+               interrupts = <0 77 0>;
+       };
+
+       dwmmc at 12230000 {
Quoted 8 lines

Review

Quoted 8 lines
arch/arm/dts/exynos5250.dtsi +6 -0
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12230000 0x1000>;
+               interrupts = <0 78 0>;
+       };
 };
(quoted diff) +0 -0

b/board/samsung/dts/exynos5250-smdk5250.dts

Quoted 13 lines
Quoted 13 lines

index a8e62da..b1b8d71 100644

board/samsung/dts/exynos5250-smdk5250.dts +4 -0
@@ -30,6 +30,10 @@
                spi2 = "/spi at 12d40000";
                spi3 = "/spi at 131a0000";
                spi4 = "/spi at 131b0000";
+               dwmmc0 = "/dwmmc at 12200000";
+               dwmmc1 = "/dwmmc at 12210000";
+               dwmmc2 = "/dwmmc at 12220000";
+               dwmmc3 = "/dwmmc at 12230000";
        };
 
Quoted 10 lines

board/samsung/dts/exynos5250-smdk5250.dts line 68

Quoted 8 lines
board/samsung/dts/exynos5250-smdk5250.dts +3 -0
        sromc at 12250000 {
@@ -59,4 +63,24 @@
                        compatible = "wolfson,wm8994-codec";
                };
        };
+
+       dwmmc at 12200000 {
+               index = <0>;

Do you really need the index? You have the numbering from the aliaes I

Quoted 9 lines

think.

Quoted 5 lines

board/samsung/dts/exynos5250-smdk5250.dts line 70

Quoted 3 lines
board/samsung/dts/exynos5250-smdk5250.dts +2 -0
+               bus-width = <8>;
+               timing = <1 3 3>;

Might need a "samsung," prefix on these?

I think better that use the "exynos" instead of "samsung". how about?

Well I think you are supposed to use vendor,propname when you define your own private binding.

Quoted 30 lines
Quoted 28 lines
Quoted 18 lines
board/samsung/dts/exynos5250-smdk5250.dts +15 -1
+       };
+
+       dwmmc at 12210000 {
+               status = "disabled";
+       };
+
+       dwmmc at 12220000 {
+               index = <2>;
+               bus-width = <4>;
+               timing = <1 2 3>;
+       };
+
+       dwmmc at 12230000 {
+               status = "disabled";
+       };
 };
--
Quoted 2 lines

1.7.0.4

Regards,
Simon
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#7 lore raw

PATCH 2/9 EXYNOS5: FDT: Add DWMMC device node data

Hi

Quoted 137 lines · Simon Glass

Hi,

On Fri, Dec 21, 2012 at 1:19 AM, Jaehoon Chung <[email protected]

Quoted 6 lines

wrote:

Quoted 3 lines · Simon Glass

Hi Amar,

On Mon, Dec 17, 2012 at 3:19 AM, Amar <[email protected]>

Quoted 7 lines · wrote:
Quoted 5 lines
Quoted 5 lines

Add DWMMC device node data for exynos5

---
 arch/arm/dts/exynos5250.dtsi              |   32

+++++++++++++++++++++++++++++

Quoted 1 line
Quoted 1 line
 board/samsung/dts/exynos5250-smdk5250.dts |   24

+++++++++++++++++++++

Quoted 6 lines
Quoted 6 lines

Do you also have a binding file for this please?

Review

Quoted 3 lines
 2 files changed, 56 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/arch/arm/dts/exynos5250.dtsi

Quoted 65 lines
Quoted 33 lines
Quoted 33 lines

index 1008797..b701ae5 100644

arch/arm/dts/exynos5250.dtsi +26 -0
@@ -138,4 +138,36 @@
                reg = <0x131b0000 0x30>;
                interrupts = <0 130 0>;
        };
+
+       dwmmc at 12200000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12200000 0x1000>;
+               interrupts = <0 75 0>;
+       };
+
+       dwmmc at 12210000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12210000 0x1000>;
+               interrupts = <0 76 0>;
+       };
+
+       dwmmc at 12220000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12220000 0x1000>;
+               interrupts = <0 77 0>;
+       };
+
+       dwmmc at 12230000 {
Quoted 8 lines

Review

Quoted 8 lines
arch/arm/dts/exynos5250.dtsi +6 -0
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos5250-dwmmc";
+               reg = <0x12230000 0x1000>;
+               interrupts = <0 78 0>;
+       };
 };
(quoted diff) +0 -0

b/board/samsung/dts/exynos5250-smdk5250.dts

Quoted 13 lines
Quoted 13 lines

index a8e62da..b1b8d71 100644

board/samsung/dts/exynos5250-smdk5250.dts +4 -0
@@ -30,6 +30,10 @@
                spi2 = "/spi at 12d40000";
                spi3 = "/spi at 131a0000";
                spi4 = "/spi at 131b0000";
+               dwmmc0 = "/dwmmc at 12200000";
+               dwmmc1 = "/dwmmc at 12210000";
+               dwmmc2 = "/dwmmc at 12220000";
+               dwmmc3 = "/dwmmc at 12230000";
        };
 
Quoted 10 lines

board/samsung/dts/exynos5250-smdk5250.dts line 68

Quoted 8 lines
board/samsung/dts/exynos5250-smdk5250.dts +3 -0
        sromc at 12250000 {
@@ -59,4 +63,24 @@
                        compatible = "wolfson,wm8994-codec";
                };
        };
+
+       dwmmc at 12200000 {
+               index = <0>;

Do you really need the index? You have the numbering from the aliaes I

Quoted 9 lines

think.

Quoted 5 lines

board/samsung/dts/exynos5250-smdk5250.dts line 70

Quoted 3 lines
board/samsung/dts/exynos5250-smdk5250.dts +2 -0
+               bus-width = <8>;
+               timing = <1 3 3>;

Might need a "samsung," prefix on these?

I think better that use the "exynos" instead of "samsung". how about?

Well I think you are supposed to use vendor,propname when you define your own private binding.

Ok, I shall use "samsung," prefix.

Quoted 20 lines
Quoted 20 lines
Quoted 20 lines
board/samsung/dts/exynos5250-smdk5250.dts +15 -1
+       };
+
+       dwmmc at 12210000 {
+               status = "disabled";
+       };
+
+       dwmmc at 12220000 {
+               index = <2>;
+               bus-width = <4>;
+               timing = <1 2 3>;
+       };
+
+       dwmmc at 12230000 {
+               status = "disabled";
+       };
 };
--

1.7.0.4

Quoted 10 lines
Quoted 8 lines

Regards,
Simon
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Quoted 6 lines

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Thanks & Regards
Amarendra Reddy

author
#8 lore raw

PATCH 4/9 EXYNOS5: DWMMC: Added dt support for DWMMC

In reply to Amar
---
 arch/arm/include/asm/arch-exynos/dwmmc.h |    4 +
 drivers/mmc/exynos_dw_mmc.c              |  117 ++++++++++++++++++++++++++++--
 include/dwmmc.h                          |    4 +
 3 files changed, 119 insertions(+), 6 deletions(-)
arch/arm/include/asm/arch-exynos/dwmmc.h +4 -0
index 8acdf9b..92352df 100644
@@ -27,6 +27,9 @@
 #define DWMCI_SET_DRV_CLK(x)	((x) << 16)
 #define DWMCI_SET_DIV_RATIO(x)	((x) << 24)
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob);
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index);
 
 static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
@@ -34,3 +37,4 @@ static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
 	unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
 	return exynos_dwmci_init(base, bus_width, index);
 }
+#endif
drivers/mmc/exynos_dw_mmc.c +111 -6

148 lines not on this page · raw message

include/dwmmc.h +4 -0
index c8b1d40..4a42849 100644
@@ -123,6 +123,9 @@
 #define MSIZE(x)		((x) << 28)
 #define RX_WMARK(x)		((x) << 16)
 #define TX_WMARK(x)		(x)
+#define RX_WMARK_SHIFT		16
+#define RX_WMARK_MASK		(0xfff << RX_WMARK_SHIFT)
+
 
 #define DWMCI_IDMAC_OWN		(1 << 31)
 #define DWMCI_IDMAC_CH		(1 << 4)
@@ -144,6 +147,7 @@ struct dwmci_host {
 	unsigned int bus_hz;
 	int dev_index;
 	int buswidth;
+	u32 clksel_val;
 	u32 fifoth_val;
 	struct mmc *mmc;
 
Signature · 1 line
1.7.0.4
#9 lore raw

PATCH 4/9 EXYNOS5: DWMMC: Added dt support for DWMMC

Hi Amar,

Quoted 2 lines · Amar

Good to see this patch! Please can you add a short commit message?

Quoted 1 line

---

 arch/arm/include/asm/arch-exynos/dwmmc.h |    4 +
Quoted 39 lines
 drivers/mmc/exynos_dw_mmc.c              |  117
++++++++++++++++++++++++++++--
 include/dwmmc.h                          |    4 +
 3 files changed, 119 insertions(+), 6 deletions(-)
arch/arm/include/asm/arch-exynos/dwmmc.h +4 -0
index 8acdf9b..92352df 100644
@@ -27,6 +27,9 @@
 #define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
 #define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob);
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index);
 
 static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
@@ -34,3 +37,4 @@ static inline unsigned int exynos_dwmmc_init(int index,
 int bus_width)
        unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
        return exynos_dwmci_init(base, bus_width, index);
 }
+#endif
drivers/mmc/exynos_dw_mmc.c +3 -1
index 72a31b7..3b3e3e5 100644
@@ -19,23 +19,38 @@
  */
 
 #include <common.h>
-#include <malloc.h>
 #include <dwmmc.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <malloc.h>

drivers/mmc/exynos_dw_mmc.c line 35

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/pinmux.h>
+
+#define        DWMMC_MAX_CH_NUM                4
+#define        DWMMC_MAX_FREQ                  52000000
+#define        DWMMC_MIN_FREQ                  400000
+#define        DWMMC_MMC0_CLKSEL_VAL           0x03030001
+#define        DWMMC_MMC2_CLKSEL_VAL           0x03020001
 

What do these last two values mean? I think clock setting should be done in clock.c, not here.

Quoted 14 lines
drivers/mmc/exynos_dw_mmc.c +4 -4
 static char *EXYNOS_NAME = "EXYNOS DWMMC";
 
 static void exynos_dwmci_clksel(struct dwmci_host *host)
 {
-       u32 val;
-       val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
-               DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(0);
+       dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
+}
 
-       dwmci_writel(host, DWMCI_CLKSEL, val);
+unsigned int exynos_dwmci_get_clk(int dev_index)
+{

drivers/mmc/exynos_dw_mmc.c

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +6 -0
+       return get_mmc_clk(dev_index);
 }
 
+#ifdef CONFIG_OF_CONTROL
+static int exynos_dwmci_init(u32 regbase, int bus_width,
+                                       int index, u32 *timing)
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index)
+#endif
 

I'm really not keen on having the same function with different signatures. My first question is whether we need to support operation without CONFIG_OF_CONTROL. If so, I suggest having an init routine that takes an FDT blob as a parameter, and a separate add_port function which can be called by non-FDT-enabled board files. The init routine will call the add_port function for each port it finds in the FDT.

Also please can you briefly comment non-trivial functions?

Quoted 55 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 {
        struct dwmci_host *host = NULL;
        host = malloc(sizeof(struct dwmci_host));
drivers/mmc/exynos_dw_mmc.c +35 -1
@@ -44,14 +59,104 @@ int exynos_dwmci_init(u32 regbase, int bus_width, int
 index)
                return 1;
        }
 
+       /* set the clock divisor - clk_div_fsys for mmc */
+       if (exynos5_mmc_set_clk_div(index)) {
+               debug("mmc clock div set failed\n");
+               return -1;
+       }
+
        host->name = EXYNOS_NAME;
        host->ioaddr = (void *)regbase;
        host->buswidth = bus_width;
+#ifdef CONFIG_OF_CONTROL
+       host->clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
+                               DWMCI_SET_DRV_CLK(timing[1]) |
+                               DWMCI_SET_DIV_RATIO(timing[2]));
+#else
+       if (0 == index)
+               host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
+       if (2 == index)
+               host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
+#endif
        host->clksel = exynos_dwmci_clksel;
        host->dev_index = index;
+       host->mmc_clk = exynos_dwmci_get_clk;
 
-       add_dwmci(host, 52000000, 400000);
+       add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
 
        return 0;
 }
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob)
+{
+       u32 base;
+       int index, bus_width;
+       int node_list[DWMMC_MAX_CH_NUM];
+       int err = 0;
+       int dev_id, flag;
+       u32 timing[3];
+       int count, i;
+
+       count = fdtdec_find_aliases_for_id(blob, "dwmmc",
+                               COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
+                               DWMMC_MAX_CH_NUM);
+
+       for (i = 0; i < count; i++) {
+               int node = node_list[i];

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int · line 116

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               if (node <= 0)
+                       continue;
+
+               /* config pinmux for each mmc channel */
+               dev_id = pinmux_decode_periph_id(blob, node);
+               if (dev_id == PERIPH_ID_SDMMC0)
+                       flag = PINMUX_FLAG_8BIT_MODE;
+               else
+                       flag = PINMUX_FLAG_NONE;

This should be decoded from the FDT - e.g. fdtdec_get_int(blob, node, "samsung,width") == 8.

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               err = exynos_pinmux_config(dev_id, flag);
+               if (err) {
+                       debug("DWMMC not configured\n");
+                       return err;
+               }
+
+               /* Get the base address from the device node */
+               base = fdtdec_get_addr(blob, node, "reg");
+               if (!base) {

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 136

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+                       debug("DWMMC: Can't get base address\n");
+                       return -1;
+               }
+
+               /* Get the channel index from the device node */
+               index = fdtdec_get_int(blob, node, "index", 0);
+               if (index < 0) {
+                       debug("DWMMC: Can't get channel index\n");
+                       return -1;
+               }

What is this needed for? Doesn't the reg address tell you everything you need here?

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 143

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
+
+               /* Get the bus width from the device node */
+               bus_width = fdtdec_get_int(blob, node, "bus-width", 0);
+               if (bus_width < 0) {
+                       debug("DWMMC: Can't get bus-width\n");
+                       return -1;
+               }

+

Quoted 23 lines
drivers/mmc/exynos_dw_mmc.c +18 -0
+               err = fdtdec_get_int_array(blob, node, "timing",
+                                       timing, 3);
+               if (err) {
+                       debug("Can't get sdr-timings for divider\n");
+                       return -1;
+               }
+
+               err =  exynos_dwmci_init(base, bus_width,
+                                               index, timing);
+               if (err) {
+                       debug("Can't do dwmci init\n");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+#endif
include/dwmmc.h +0 -0
index c8b1d40..4a42849 100644

include/dwmmc.h line 129

Quoted 7 lines
include/dwmmc.h +3 -0
@@ -123,6 +123,9 @@
 #define MSIZE(x)               ((x) << 28)
 #define RX_WMARK(x)            ((x) << 16)
 #define TX_WMARK(x)            (x)
+#define RX_WMARK_SHIFT         16
+#define RX_WMARK_MASK          (0xfff << RX_WMARK_SHIFT)
+
 

Extra blank line here?

Quoted 12 lines
include/dwmmc.h +1 -1
 #define DWMCI_IDMAC_OWN                (1 << 31)
 #define DWMCI_IDMAC_CH         (1 << 4)
@@ -144,6 +147,7 @@ struct dwmci_host {
        unsigned int bus_hz;
        int dev_index;
        int buswidth;
+       u32 clksel_val;
        u32 fifoth_val;
        struct mmc *mmc;
 
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

#10 lore raw

PATCH 4/9 EXYNOS5: DWMMC: Added dt support for DWMMC

Hi Simon,

Thanks for your review comments.
Please find the responses below.

Thanks & Regards
Amarendra Reddy

Quoted 66 lines · Simon Glass

Hi Amar,

Quoted 2 lines · Amar

Good to see this patch! Please can you add a short commit message?
Oops.. sorry. I will put the commit msg.

Quoted 1 line

---

 arch/arm/include/asm/arch-exynos/dwmmc.h |    4 +
Quoted 39 lines
 drivers/mmc/exynos_dw_mmc.c              |  117
++++++++++++++++++++++++++++--
 include/dwmmc.h                          |    4 +
 3 files changed, 119 insertions(+), 6 deletions(-)
arch/arm/include/asm/arch-exynos/dwmmc.h +4 -0
index 8acdf9b..92352df 100644
@@ -27,6 +27,9 @@
 #define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
 #define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob);
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index);
 
 static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
@@ -34,3 +37,4 @@ static inline unsigned int exynos_dwmmc_init(int index,
 int bus_width)
        unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
        return exynos_dwmci_init(base, bus_width, index);
 }
+#endif
drivers/mmc/exynos_dw_mmc.c +3 -1
index 72a31b7..3b3e3e5 100644
@@ -19,23 +19,38 @@
  */
 
 #include <common.h>
-#include <malloc.h>
 #include <dwmmc.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <malloc.h>

drivers/mmc/exynos_dw_mmc.c line 35

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/pinmux.h>
+
+#define        DWMMC_MAX_CH_NUM                4
+#define        DWMMC_MAX_FREQ                  52000000
+#define        DWMMC_MIN_FREQ                  400000
+#define        DWMMC_MMC0_CLKSEL_VAL           0x03030001
+#define        DWMMC_MMC2_CLKSEL_VAL           0x03020001
 

What do these last two values mean? I think clock setting should be done in clock.c, not here.

Quoted 1 line

In case of non-dt support, these two values are written into respective

clock selection register-CLKSEL, to select the clock for MMC-channel0 and MMC-channel2.
Will move clock setting into clock.c and the #defines will be moved into include/asm/arch/clk.h.

Quoted 34 lines

drivers/mmc/exynos_dw_mmc.c

Quoted 9 lines
drivers/mmc/exynos_dw_mmc.c +0 -3
 static char *EXYNOS_NAME = "EXYNOS DWMMC";
 
 static void exynos_dwmci_clksel(struct dwmci_host *host)
 {
-       u32 val;
-       val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
-               DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) |

DWMCI_SET_DIV_RATIO(0);

Quoted 6 lines
drivers/mmc/exynos_dw_mmc.c +4 -1
+       dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
+}
 
-       dwmci_writel(host, DWMCI_CLKSEL, val);
+unsigned int exynos_dwmci_get_clk(int dev_index)
+{

drivers/mmc/exynos_dw_mmc.c

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +6 -0
+       return get_mmc_clk(dev_index);
 }
 
+#ifdef CONFIG_OF_CONTROL
+static int exynos_dwmci_init(u32 regbase, int bus_width,
+                                       int index, u32 *timing)
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index)
+#endif
 

I'm really not keen on having the same function with different signatures. My first question is whether we need to support operation without CONFIG_OF_CONTROL. If so, I suggest having an init routine that takes an FDT blob as a parameter, and a separate add_port function which can be called by non-FDT-enabled board files. The init routine will call the add_port function for each port it finds in the FDT.

Quoted 1 line

I think we need support operation without CONFIG_OF_CONTROL atleast untill

the entire FDT is formed.
Hence I will implement it as per your suggestion.

Quoted 170 lines

Also please can you briefly comment non-trivial functions?
OK.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width,

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 {
        struct dwmci_host *host = NULL;
        host = malloc(sizeof(struct dwmci_host));
drivers/mmc/exynos_dw_mmc.c +0 -0
@@ -44,14 +59,104 @@ int exynos_dwmci_init(u32 regbase, int bus_width,

int

Quoted 51 lines
drivers/mmc/exynos_dw_mmc.c +35 -1
 index)
                return 1;
        }
 
+       /* set the clock divisor - clk_div_fsys for mmc */
+       if (exynos5_mmc_set_clk_div(index)) {
+               debug("mmc clock div set failed\n");
+               return -1;
+       }
+
        host->name = EXYNOS_NAME;
        host->ioaddr = (void *)regbase;
        host->buswidth = bus_width;
+#ifdef CONFIG_OF_CONTROL
+       host->clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
+                               DWMCI_SET_DRV_CLK(timing[1]) |
+                               DWMCI_SET_DIV_RATIO(timing[2]));
+#else
+       if (0 == index)
+               host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
+       if (2 == index)
+               host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
+#endif
        host->clksel = exynos_dwmci_clksel;
        host->dev_index = index;
+       host->mmc_clk = exynos_dwmci_get_clk;
 
-       add_dwmci(host, 52000000, 400000);
+       add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
 
        return 0;
 }
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob)
+{
+       u32 base;
+       int index, bus_width;
+       int node_list[DWMMC_MAX_CH_NUM];
+       int err = 0;
+       int dev_id, flag;
+       u32 timing[3];
+       int count, i;
+
+       count = fdtdec_find_aliases_for_id(blob, "dwmmc",
+                               COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
+                               DWMMC_MAX_CH_NUM);
+
+       for (i = 0; i < count; i++) {
+               int node = node_list[i];

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 116

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               if (node <= 0)
+                       continue;
+
+               /* config pinmux for each mmc channel */
+               dev_id = pinmux_decode_periph_id(blob, node);
+               if (dev_id == PERIPH_ID_SDMMC0)
+                       flag = PINMUX_FLAG_8BIT_MODE;
+               else
+                       flag = PINMUX_FLAG_NONE;

This should be decoded from the FDT - e.g. fdtdec_get_int(blob, node, "samsung,width") == 8.

OK.

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               err = exynos_pinmux_config(dev_id, flag);
+               if (err) {
+                       debug("DWMMC not configured\n");
+                       return err;
+               }
+
+               /* Get the base address from the device node */
+               base = fdtdec_get_addr(blob, node, "reg");
+               if (!base) {

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 136

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+                       debug("DWMMC: Can't get base address\n");
+                       return -1;
+               }
+
+               /* Get the channel index from the device node */
+               index = fdtdec_get_int(blob, node, "index", 0);
+               if (index < 0) {
+                       debug("DWMMC: Can't get channel index\n");
+                       return -1;
+               }

What is this needed for? Doesn't the reg address tell you everything you need here?
Ok will change accordingly.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 143

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
+
+               /* Get the bus width from the device node */
+               bus_width = fdtdec_get_int(blob, node, "bus-width", 0);
+               if (bus_width < 0) {
+                       debug("DWMMC: Can't get bus-width\n");
+                       return -1;
+               }

+

Quoted 23 lines
drivers/mmc/exynos_dw_mmc.c +18 -0
+               err = fdtdec_get_int_array(blob, node, "timing",
+                                       timing, 3);
+               if (err) {
+                       debug("Can't get sdr-timings for divider\n");
+                       return -1;
+               }
+
+               err =  exynos_dwmci_init(base, bus_width,
+                                               index, timing);
+               if (err) {
+                       debug("Can't do dwmci init\n");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+#endif
include/dwmmc.h +0 -0
index c8b1d40..4a42849 100644

include/dwmmc.h line 129

Quoted 7 lines
include/dwmmc.h +3 -0
@@ -123,6 +123,9 @@
 #define MSIZE(x)               ((x) << 28)
 #define RX_WMARK(x)            ((x) << 16)
 #define TX_WMARK(x)            (x)
+#define RX_WMARK_SHIFT         16
+#define RX_WMARK_MASK          (0xfff << RX_WMARK_SHIFT)
+
 

Extra blank line here?
Will remove it.

Quoted 12 lines
include/dwmmc.h +1 -1
 #define DWMCI_IDMAC_OWN                (1 << 31)
 #define DWMCI_IDMAC_CH         (1 << 4)
@@ -144,6 +147,7 @@ struct dwmci_host {
        unsigned int bus_hz;
        int dev_index;
        int buswidth;
+       u32 clksel_val;
        u32 fifoth_val;
        struct mmc *mmc;
 
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#11 lore raw

PATCH 4/9 EXYNOS5: DWMMC: Added dt support for DWMMC

Quoted 76 lines · Amarendra Reddy

Hi Simon,

Thanks for your review comments.
Please find the responses below.

Thanks & Regards
Amarendra Reddy

Quoted 66 lines · Simon Glass

Hi Amar,

Quoted 2 lines · Amar

Good to see this patch! Please can you add a short commit message?
Oops.. sorry. I will put the commit msg.

Quoted 1 line

---

 arch/arm/include/asm/arch-exynos/dwmmc.h |    4 +
Quoted 39 lines
 drivers/mmc/exynos_dw_mmc.c              |  117
++++++++++++++++++++++++++++--
 include/dwmmc.h                          |    4 +
 3 files changed, 119 insertions(+), 6 deletions(-)
arch/arm/include/asm/arch-exynos/dwmmc.h +4 -0
index 8acdf9b..92352df 100644
@@ -27,6 +27,9 @@
 #define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
 #define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob);
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index);
 
 static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
@@ -34,3 +37,4 @@ static inline unsigned int exynos_dwmmc_init(int index,
 int bus_width)
        unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
        return exynos_dwmci_init(base, bus_width, index);
 }
+#endif
drivers/mmc/exynos_dw_mmc.c +3 -1
index 72a31b7..3b3e3e5 100644
@@ -19,23 +19,38 @@
  */
 
 #include <common.h>
-#include <malloc.h>
 #include <dwmmc.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <malloc.h>

drivers/mmc/exynos_dw_mmc.c line 35

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/pinmux.h>
+
+#define        DWMMC_MAX_CH_NUM                4
+#define        DWMMC_MAX_FREQ                  52000000
+#define        DWMMC_MIN_FREQ                  400000
+#define        DWMMC_MMC0_CLKSEL_VAL           0x03030001
+#define        DWMMC_MMC2_CLKSEL_VAL           0x03020001
 

What do these last two values mean? I think clock setting should be done in clock.c, not here.

Quoted 5 lines
Quoted 1 line

In case of non-dt support, these two values are written into respective

clock selection register-CLKSEL, to select the clock for MMC-channel0 and MMC-channel2.
Will move clock setting into clock.c and the #defines will be moved into include/asm/arch/clk.h.

I didn't want to move into clk.h. Why do you move there? It is related with CLKSEL register into DesignWare IP.

Quoted 218 lines
Quoted 35 lines

drivers/mmc/exynos_dw_mmc.c

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +0 -3
 static char *EXYNOS_NAME = "EXYNOS DWMMC";
 
 static void exynos_dwmci_clksel(struct dwmci_host *host)
 {
-       u32 val;
-       val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
-               DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) |

DWMCI_SET_DIV_RATIO(0);

Quoted 6 lines
drivers/mmc/exynos_dw_mmc.c +4 -1
+       dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
+}
 
-       dwmci_writel(host, DWMCI_CLKSEL, val);
+unsigned int exynos_dwmci_get_clk(int dev_index)
+{

drivers/mmc/exynos_dw_mmc.c

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +6 -0
+       return get_mmc_clk(dev_index);
 }
 
+#ifdef CONFIG_OF_CONTROL
+static int exynos_dwmci_init(u32 regbase, int bus_width,
+                                       int index, u32 *timing)
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index)
+#endif
 

I'm really not keen on having the same function with different signatures. My first question is whether we need to support operation without CONFIG_OF_CONTROL. If so, I suggest having an init routine that takes an FDT blob as a parameter, and a separate add_port function which can be called by non-FDT-enabled board files. The init routine will call the add_port function for each port it finds in the FDT.

Quoted 1 line

I think we need support operation without CONFIG_OF_CONTROL atleast untill

the entire FDT is formed.
Hence I will implement it as per your suggestion.

Quoted 164 lines

Also please can you briefly comment non-trivial functions?
OK.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width,

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 {
        struct dwmci_host *host = NULL;
        host = malloc(sizeof(struct dwmci_host));
drivers/mmc/exynos_dw_mmc.c +0 -0
@@ -44,14 +59,104 @@ int exynos_dwmci_init(u32 regbase, int bus_width,

int

Quoted 51 lines
drivers/mmc/exynos_dw_mmc.c +35 -1
 index)
                return 1;
        }
 
+       /* set the clock divisor - clk_div_fsys for mmc */
+       if (exynos5_mmc_set_clk_div(index)) {
+               debug("mmc clock div set failed\n");
+               return -1;
+       }
+
        host->name = EXYNOS_NAME;
        host->ioaddr = (void *)regbase;
        host->buswidth = bus_width;
+#ifdef CONFIG_OF_CONTROL
+       host->clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
+                               DWMCI_SET_DRV_CLK(timing[1]) |
+                               DWMCI_SET_DIV_RATIO(timing[2]));
+#else
+       if (0 == index)
+               host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
+       if (2 == index)
+               host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
+#endif
        host->clksel = exynos_dwmci_clksel;
        host->dev_index = index;
+       host->mmc_clk = exynos_dwmci_get_clk;
 
-       add_dwmci(host, 52000000, 400000);
+       add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
 
        return 0;
 }
 
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob)
+{
+       u32 base;
+       int index, bus_width;
+       int node_list[DWMMC_MAX_CH_NUM];
+       int err = 0;
+       int dev_id, flag;
+       u32 timing[3];
+       int count, i;
+
+       count = fdtdec_find_aliases_for_id(blob, "dwmmc",
+                               COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
+                               DWMMC_MAX_CH_NUM);
+
+       for (i = 0; i < count; i++) {
+               int node = node_list[i];

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 116

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               if (node <= 0)
+                       continue;
+
+               /* config pinmux for each mmc channel */
+               dev_id = pinmux_decode_periph_id(blob, node);
+               if (dev_id == PERIPH_ID_SDMMC0)
+                       flag = PINMUX_FLAG_8BIT_MODE;
+               else
+                       flag = PINMUX_FLAG_NONE;

This should be decoded from the FDT - e.g. fdtdec_get_int(blob, node, "samsung,width") == 8.

OK.

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               err = exynos_pinmux_config(dev_id, flag);
+               if (err) {
+                       debug("DWMMC not configured\n");
+                       return err;
+               }
+
+               /* Get the base address from the device node */
+               base = fdtdec_get_addr(blob, node, "reg");
+               if (!base) {

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 136

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+                       debug("DWMMC: Can't get base address\n");
+                       return -1;
+               }
+
+               /* Get the channel index from the device node */
+               index = fdtdec_get_int(blob, node, "index", 0);
+               if (index < 0) {
+                       debug("DWMMC: Can't get channel index\n");
+                       return -1;
+               }

What is this needed for? Doesn't the reg address tell you everything you need here?
Ok will change accordingly.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 143

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
+
+               /* Get the bus width from the device node */
+               bus_width = fdtdec_get_int(blob, node, "bus-width", 0);
+               if (bus_width < 0) {
+                       debug("DWMMC: Can't get bus-width\n");
+                       return -1;
+               }

+

Quoted 23 lines
drivers/mmc/exynos_dw_mmc.c +18 -0
+               err = fdtdec_get_int_array(blob, node, "timing",
+                                       timing, 3);
+               if (err) {
+                       debug("Can't get sdr-timings for divider\n");
+                       return -1;
+               }
+
+               err =  exynos_dwmci_init(base, bus_width,
+                                               index, timing);
+               if (err) {
+                       debug("Can't do dwmci init\n");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+#endif
include/dwmmc.h +0 -0
index c8b1d40..4a42849 100644

include/dwmmc.h line 129

Quoted 7 lines
include/dwmmc.h +3 -0
@@ -123,6 +123,9 @@
 #define MSIZE(x)               ((x) << 28)
 #define RX_WMARK(x)            ((x) << 16)
 #define TX_WMARK(x)            (x)
+#define RX_WMARK_SHIFT         16
+#define RX_WMARK_MASK          (0xfff << RX_WMARK_SHIFT)
+
 

Extra blank line here?
Will remove it.

Quoted 12 lines
include/dwmmc.h +1 -1
 #define DWMCI_IDMAC_OWN                (1 << 31)
 #define DWMCI_IDMAC_CH         (1 << 4)
@@ -144,6 +147,7 @@ struct dwmci_host {
        unsigned int bus_hz;
        int dev_index;
        int buswidth;
+       u32 clksel_val;
        u32 fifoth_val;
        struct mmc *mmc;
 
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

Quoted 6 lines

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#12 lore raw

PATCH 4/9 EXYNOS5: DWMMC: Added dt support for DWMMC

Hi Jaehoon,
Thanks for your comments.
Please find the response below.

Thanks & Regards
Amarendra

Quoted 80 lines · Jaehoon Chung
Quoted 37 lines · Amarendra Reddy

Hi Simon,

Thanks for your review comments.
Please find the responses below.

Thanks & Regards
Amarendra Reddy

Quoted 27 lines · Simon Glass

Hi Amar,

Quoted 2 lines · Amar

Good to see this patch! Please can you add a short commit message?
Oops.. sorry. I will put the commit msg.

Quoted 1 line

---

 arch/arm/include/asm/arch-exynos/dwmmc.h |    4 +
Quoted 14 lines
 drivers/mmc/exynos_dw_mmc.c              |  117
++++++++++++++++++++++++++++--
 include/dwmmc.h                          |    4 +
 3 files changed, 119 insertions(+), 6 deletions(-)
arch/arm/include/asm/arch-exynos/dwmmc.h +0 -0
index 8acdf9b..92352df 100644
@@ -27,6 +27,9 @@
 #define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
 #define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
 
Quoted 7 lines
Quoted 7 lines

arch/arm/include/asm/arch-exynos/dwmmc.h static inline unsigned int exynos_dwmmc_init(int

Quoted 7 lines
arch/arm/include/asm/arch-exynos/dwmmc.h +3 -0
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob);
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index);
 
 static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
@@ -34,3 +37,4 @@ static inline unsigned int exynos_dwmmc_init(int

index,

Quoted 22 lines
Quoted 22 lines
Quoted 22 lines
arch/arm/include/asm/arch-exynos/dwmmc.h +1 -0
 int bus_width)
        unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
        return exynos_dwmci_init(base, bus_width, index);
 }
+#endif
drivers/mmc/exynos_dw_mmc.c +5 -1
index 72a31b7..3b3e3e5 100644
@@ -19,23 +19,38 @@
  */
 
 #include <common.h>
-#include <malloc.h>
 #include <dwmmc.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <malloc.h>
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/pinmux.h>
+
Quoted 8 lines
Quoted 8 lines

drivers/mmc/exynos_dw_mmc.c line 35

Quoted 6 lines
drivers/mmc/exynos_dw_mmc.c +5 -0
+#define        DWMMC_MAX_CH_NUM                4
+#define        DWMMC_MAX_FREQ                  52000000
+#define        DWMMC_MIN_FREQ                  400000
+#define        DWMMC_MMC0_CLKSEL_VAL           0x03030001
+#define        DWMMC_MMC2_CLKSEL_VAL           0x03020001
 

What do these last two values mean? I think clock setting should be

done in

Quoted 3 lines
Quoted 3 lines

clock.c, not here.

In case of non-dt support, these two values are written into respective

Quoted 8 lines
Quoted 4 lines

clock selection register-CLKSEL, to select the clock for MMC-channel0 and MMC-channel2.
Will move clock setting into clock.c and the #defines will be moved into include/asm/arch/clk.h.

I didn't want to move into clk.h. Why do you move there? It is related with CLKSEL register into DesignWare IP.

Ok, now I understand that all register settings corresponding to

DesignWare IP should be present in exynos_dw_mmc.c / dw_mmc.c. Fine, I will not move CLKSEL register setting into clock.c / clk.h.

Quoted 223 lines
Quoted 20 lines
Quoted 20 lines

drivers/mmc/exynos_dw_mmc.c

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +0 -3
 static char *EXYNOS_NAME = "EXYNOS DWMMC";
 
 static void exynos_dwmci_clksel(struct dwmci_host *host)
 {
-       u32 val;
-       val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
-               DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) |

DWMCI_SET_DIV_RATIO(0);

Quoted 9 lines
drivers/mmc/exynos_dw_mmc.c +5 -1
+       dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
+}
 
-       dwmci_writel(host, DWMCI_CLKSEL, val);
+unsigned int exynos_dwmci_get_clk(int dev_index)
+{
+       return get_mmc_clk(dev_index);
 }
 
Quoted 9 lines
Quoted 9 lines

drivers/mmc/exynos_dw_mmc.c

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +5 -0
+#ifdef CONFIG_OF_CONTROL
+static int exynos_dwmci_init(u32 regbase, int bus_width,
+                                       int index, u32 *timing)
+#else
 int exynos_dwmci_init(u32 regbase, int bus_width, int index)
+#endif
 

I'm really not keen on having the same function with different

signatures.

Quoted 7 lines
Quoted 7 lines

My first question is whether we need to support operation without CONFIG_OF_CONTROL. If so, I suggest having an init routine that takes an FDT blob as a parameter, and a separate add_port function which can be called by non-FDT-enabled board files. The init routine will call the add_port function for each port it finds in the FDT.

I think we need support operation without CONFIG_OF_CONTROL atleast

untill

Quoted 45 lines

the entire FDT is formed.
Hence I will implement it as per your suggestion.

Quoted 41 lines

Also please can you briefly comment non-trivial functions?
OK.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width,

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 {
        struct dwmci_host *host = NULL;
        host = malloc(sizeof(struct dwmci_host));
drivers/mmc/exynos_dw_mmc.c +0 -0
@@ -44,14 +59,104 @@ int exynos_dwmci_init(u32 regbase, int bus_width,

int

Quoted 33 lines
drivers/mmc/exynos_dw_mmc.c +18 -1
 index)
                return 1;
        }
 
+       /* set the clock divisor - clk_div_fsys for mmc */
+       if (exynos5_mmc_set_clk_div(index)) {
+               debug("mmc clock div set failed\n");
+               return -1;
+       }
+
        host->name = EXYNOS_NAME;
        host->ioaddr = (void *)regbase;
        host->buswidth = bus_width;
+#ifdef CONFIG_OF_CONTROL
+       host->clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
+                               DWMCI_SET_DRV_CLK(timing[1]) |
+                               DWMCI_SET_DIV_RATIO(timing[2]));
+#else
+       if (0 == index)
+               host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
+       if (2 == index)
+               host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
+#endif
        host->clksel = exynos_dwmci_clksel;
        host->dev_index = index;
+       host->mmc_clk = exynos_dwmci_get_clk;
 
-       add_dwmci(host, 52000000, 400000);
+       add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
 
        return 0;
 }
Quoted 13 lines
Quoted 5 lines
Quoted 5 lines
drivers/mmc/exynos_dw_mmc.c +5 -0
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob)
+{
+       u32 base;
+       int index, bus_width;
Quoted 8 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index)

Quoted 8 lines
drivers/mmc/exynos_dw_mmc.c +8 -0
+       int node_list[DWMMC_MAX_CH_NUM];
+       int err = 0;
+       int dev_id, flag;
+       u32 timing[3];
+       int count, i;
+
+       count = fdtdec_find_aliases_for_id(blob, "dwmmc",
+                               COMPAT_SAMSUNG_EXYNOS5_DWMMC,

node_list,

Quoted 124 lines
Quoted 110 lines
Quoted 5 lines
drivers/mmc/exynos_dw_mmc.c +4 -0
+                               DWMMC_MAX_CH_NUM);
+
+       for (i = 0; i < count; i++) {
+               int node = node_list[i];

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 116

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               if (node <= 0)
+                       continue;
+
+               /* config pinmux for each mmc channel */
+               dev_id = pinmux_decode_periph_id(blob, node);
+               if (dev_id == PERIPH_ID_SDMMC0)
+                       flag = PINMUX_FLAG_8BIT_MODE;
+               else
+                       flag = PINMUX_FLAG_NONE;

This should be decoded from the FDT - e.g. fdtdec_get_int(blob, node, "samsung,width") == 8.

OK.

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+
+               err = exynos_pinmux_config(dev_id, flag);
+               if (err) {
+                       debug("DWMMC not configured\n");
+                       return err;
+               }
+
+               /* Get the base address from the device node */
+               base = fdtdec_get_addr(blob, node, "reg");
+               if (!base) {

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 136

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +10 -0
+                       debug("DWMMC: Can't get base address\n");
+                       return -1;
+               }
+
+               /* Get the channel index from the device node */
+               index = fdtdec_get_int(blob, node, "index", 0);
+               if (index < 0) {
+                       debug("DWMMC: Can't get channel index\n");
+                       return -1;
+               }

What is this needed for? Doesn't the reg address tell you everything you need here?
Ok will change accordingly.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_init(u32 regbase, int bus_width, int index) · line 143

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +7 -0
+
+               /* Get the bus width from the device node */
+               bus_width = fdtdec_get_int(blob, node, "bus-width", 0);
+               if (bus_width < 0) {
+                       debug("DWMMC: Can't get bus-width\n");
+                       return -1;
+               }

+

Quoted 23 lines
drivers/mmc/exynos_dw_mmc.c +18 -0
+               err = fdtdec_get_int_array(blob, node, "timing",
+                                       timing, 3);
+               if (err) {
+                       debug("Can't get sdr-timings for divider\n");
+                       return -1;
+               }
+
+               err =  exynos_dwmci_init(base, bus_width,
+                                               index, timing);
+               if (err) {
+                       debug("Can't do dwmci init\n");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+#endif
include/dwmmc.h +0 -0
index c8b1d40..4a42849 100644

include/dwmmc.h line 129

Quoted 7 lines
include/dwmmc.h +3 -0
@@ -123,6 +123,9 @@
 #define MSIZE(x)               ((x) << 28)
 #define RX_WMARK(x)            ((x) << 16)
 #define TX_WMARK(x)            (x)
+#define RX_WMARK_SHIFT         16
+#define RX_WMARK_MASK          (0xfff << RX_WMARK_SHIFT)
+
 

Extra blank line here?
Will remove it.

Quoted 12 lines
include/dwmmc.h +1 -1
 #define DWMCI_IDMAC_OWN                (1 << 31)
 #define DWMCI_IDMAC_CH         (1 << 4)
@@ -144,6 +147,7 @@ struct dwmci_host {
        unsigned int bus_hz;
        int dev_index;
        int buswidth;
+       u32 clksel_val;
        u32 fifoth_val;
        struct mmc *mmc;
 
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

Quoted 6 lines

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

author
#13 lore raw

PATCH 5/9 EXYNOS5: DWMMC: API to set mmc clock divisor

In reply to Amar

This API computes the divisor value based on MPLL clock and writes it into the FSYS1 register.

---
 arch/arm/cpu/armv7/exynos/clock.c      |   39 ++++++++++++++++++++++++++++++-
 arch/arm/include/asm/arch-exynos/clk.h |    1 +
 2 files changed, 38 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/exynos/clock.c +37 -2
index 731bbff..6517296 100644
@@ -379,7 +379,7 @@ static unsigned long exynos4_get_mmc_clk(int dev_index)
 		(struct exynos4_clock *)samsung_get_base_clock();
 	unsigned long uclk, sclk;
 	unsigned int sel, ratio, pre_ratio;
-	int shift;
+	int shift = 0;
 
 	sel = readl(&clk->src_fsys);
 	sel = (sel >> (dev_index << 2)) & 0xf;
@@ -428,7 +428,7 @@ static unsigned long exynos5_get_mmc_clk(int dev_index)
 		(struct exynos5_clock *)samsung_get_base_clock();
 	unsigned long uclk, sclk;
 	unsigned int sel, ratio, pre_ratio;
-	int shift;
+	int shift = 0;
 
 	sel = readl(&clk->src_fsys);
 	sel = (sel >> (dev_index << 2)) & 0xf;
@@ -526,6 +526,41 @@ static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
 	writel(val, addr);
 }
 
+/* exynos5: set the mmc clock div ratio in fsys1 */
+int exynos5_mmc_set_clk_div(int dev_index)
+{
+	struct exynos5_clock *clk =
+		(struct exynos5_clock *)samsung_get_base_clock();
+	unsigned int addr;
+	unsigned int clock;
+	unsigned int tmp;
+	unsigned int i;
+
+	/* get mpll clock */
+	clock = get_pll_clk(MPLL) / 1000000;
+
+	/*
+	 * CLK_DIV_FSYS1
+	 * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0]
+	 * CLK_DIV_FSYS2
+	 * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0]
+	 */
+	if (dev_index < 2) {
+		addr = (unsigned int)&clk->div_fsys1;
+	} else {
+		addr = (unsigned int)&clk->div_fsys2;
+	}
+
+	tmp = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+	for (i = 0; i <= 0xf; i++) {
+		if ((clock / (i + 1)) <= 400) {
+			writel(tmp | i << 0, addr);
+			break;
+		}
+	}
+	return 0;
+}
+
 /* get_lcd_clk: return lcd clock frequency */
 static unsigned long exynos4_get_lcd_clk(void)
 {
arch/arm/include/asm/arch-exynos/clk.h +1 -0
index ff155d8..b0ecdd4 100644
@@ -36,6 +36,7 @@ unsigned long get_pwm_clk(void);
 unsigned long get_uart_clk(int dev_index);
 unsigned long get_mmc_clk(int deV_index);
 void set_mmc_clk(int dev_index, unsigned int div);
+int exynos5_mmc_set_clk_div(int dev_index);
 unsigned long get_lcd_clk(void);
 void set_lcd_clk(void);
 void set_mipi_clk(void);
Signature · 1 line
1.7.0.4
#14 lore raw

PATCH 5/9 EXYNOS5: DWMMC: API to set mmc clock divisor

Hi Amar,

Quoted 34 lines · Amar

This API computes the divisor value based on MPLL clock and writes it into the FSYS1 register.

---
 arch/arm/cpu/armv7/exynos/clock.c      |   39
++++++++++++++++++++++++++++++-
 arch/arm/include/asm/arch-exynos/clk.h |    1 +
 2 files changed, 38 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/exynos/clock.c +2 -2
index 731bbff..6517296 100644
@@ -379,7 +379,7 @@ static unsigned long exynos4_get_mmc_clk(int dev_index)
                (struct exynos4_clock *)samsung_get_base_clock();
        unsigned long uclk, sclk;
        unsigned int sel, ratio, pre_ratio;
-       int shift;
+       int shift = 0;
 
        sel = readl(&clk->src_fsys);
        sel = (sel >> (dev_index << 2)) & 0xf;
@@ -428,7 +428,7 @@ static unsigned long exynos5_get_mmc_clk(int dev_index)
                (struct exynos5_clock *)samsung_get_base_clock();
        unsigned long uclk, sclk;
        unsigned int sel, ratio, pre_ratio;
-       int shift;
+       int shift = 0;
 
        sel = readl(&clk->src_fsys);
        sel = (sel >> (dev_index << 2)) & 0xf;

arch/arm/cpu/armv7/exynos/clock.c static void exynos5_set_mmc_clk(int dev_index, · line 532

Quoted 7 lines
arch/arm/cpu/armv7/exynos/clock.c +2 -0
@@ -526,6 +526,41 @@ static void exynos5_set_mmc_clk(int dev_index,
 unsigned int div)
        writel(val, addr);
 }
 
+/* exynos5: set the mmc clock div ratio in fsys1 */
+int exynos5_mmc_set_clk_div(int dev_index)
 

Shouldn't this take a periph_id instead of a dev_index?

Quoted 50 lines
arch/arm/cpu/armv7/exynos/clock.c +33 -0
+{
+       struct exynos5_clock *clk =
+               (struct exynos5_clock *)samsung_get_base_clock();
+       unsigned int addr;
+       unsigned int clock;
+       unsigned int tmp;
+       unsigned int i;
+
+       /* get mpll clock */
+       clock = get_pll_clk(MPLL) / 1000000;
+
+       /*
+        * CLK_DIV_FSYS1
+        * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0]
+        * CLK_DIV_FSYS2
+        * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0]
+        */
+       if (dev_index < 2) {
+               addr = (unsigned int)&clk->div_fsys1;
+       } else {
+               addr = (unsigned int)&clk->div_fsys2;
+       }
+
+       tmp = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+       for (i = 0; i <= 0xf; i++) {
+               if ((clock / (i + 1)) <= 400) {
+                       writel(tmp | i << 0, addr);
+                       break;
+               }
+       }
+       return 0;
+}
+
 /* get_lcd_clk: return lcd clock frequency */

static unsigned long exynos4_get_lcd_clk(void)
{

arch/arm/include/asm/arch-exynos/clk.h +1 -1
index ff155d8..b0ecdd4 100644
@@ -36,6 +36,7 @@ unsigned long get_pwm_clk(void);
 unsigned long get_uart_clk(int dev_index);
 unsigned long get_mmc_clk(int deV_index);
 void set_mmc_clk(int dev_index, unsigned int div);
+int exynos5_mmc_set_clk_div(int dev_index);
 unsigned long get_lcd_clk(void);
 void set_lcd_clk(void);
 void set_mipi_clk(void);
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

#15 lore raw

PATCH 5/9 EXYNOS5: DWMMC: API to set mmc clock divisor

Hi Simon,

Thanks for your review comments.
Please find the responses below.

Thanks & Regards
Amarendra Reddy

Quoted 116 lines · Simon Glass

Hi Amar,

arch/arm/cpu/armv7/exynos/clock.c static unsigned long exynos4_get_mmc_clk(int

Quoted 16 lines · Amar

This API computes the divisor value based on MPLL clock and writes it into the FSYS1 register.

---
 arch/arm/cpu/armv7/exynos/clock.c      |   39
++++++++++++++++++++++++++++++-
 arch/arm/include/asm/arch-exynos/clk.h |    1 +
 2 files changed, 38 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/exynos/clock.c +0 -0
index 731bbff..6517296 100644
@@ -379,7 +379,7 @@ static unsigned long exynos4_get_mmc_clk(int

dev_index)

arch/arm/cpu/armv7/exynos/clock.c static unsigned long exynos5_get_mmc_clk(int

Quoted 9 lines
arch/arm/cpu/armv7/exynos/clock.c +1 -1
                (struct exynos4_clock *)samsung_get_base_clock();
        unsigned long uclk, sclk;
        unsigned int sel, ratio, pre_ratio;
-       int shift;
+       int shift = 0;
 
        sel = readl(&clk->src_fsys);
        sel = (sel >> (dev_index << 2)) & 0xf;
@@ -428,7 +428,7 @@ static unsigned long exynos5_get_mmc_clk(int

dev_index)

Quoted 9 lines
arch/arm/cpu/armv7/exynos/clock.c +1 -1
                (struct exynos5_clock *)samsung_get_base_clock();
        unsigned long uclk, sclk;
        unsigned int sel, ratio, pre_ratio;
-       int shift;
+       int shift = 0;
 
        sel = readl(&clk->src_fsys);
        sel = (sel >> (dev_index << 2)) & 0xf;

arch/arm/cpu/armv7/exynos/clock.c static void exynos5_set_mmc_clk(int dev_index, · line 532

Quoted 7 lines
arch/arm/cpu/armv7/exynos/clock.c +2 -0
@@ -526,6 +526,41 @@ static void exynos5_set_mmc_clk(int dev_index,
 unsigned int div)
        writel(val, addr);
 }
 
+/* exynos5: set the mmc clock div ratio in fsys1 */
+int exynos5_mmc_set_clk_div(int dev_index)
 

Shouldn't this take a periph_id instead of a dev_index?

Ok will convert index int to peripheral_id in the calling function.

Quoted 50 lines
arch/arm/cpu/armv7/exynos/clock.c +33 -0
+{
+       struct exynos5_clock *clk =
+               (struct exynos5_clock *)samsung_get_base_clock();
+       unsigned int addr;
+       unsigned int clock;
+       unsigned int tmp;
+       unsigned int i;
+
+       /* get mpll clock */
+       clock = get_pll_clk(MPLL) / 1000000;
+
+       /*
+        * CLK_DIV_FSYS1
+        * MMC0_PRE_RATIO [15:8], MMC0_RATIO [3:0]
+        * CLK_DIV_FSYS2
+        * MMC2_PRE_RATIO [15:8], MMC2_RATIO [3:0]
+        */
+       if (dev_index < 2) {
+               addr = (unsigned int)&clk->div_fsys1;
+       } else {
+               addr = (unsigned int)&clk->div_fsys2;
+       }
+
+       tmp = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+       for (i = 0; i <= 0xf; i++) {
+               if ((clock / (i + 1)) <= 400) {
+                       writel(tmp | i << 0, addr);
+                       break;
+               }
+       }
+       return 0;
+}
+
 /* get_lcd_clk: return lcd clock frequency */

static unsigned long exynos4_get_lcd_clk(void)
{

arch/arm/include/asm/arch-exynos/clk.h +1 -1
index ff155d8..b0ecdd4 100644
@@ -36,6 +36,7 @@ unsigned long get_pwm_clk(void);
 unsigned long get_uart_clk(int dev_index);
 unsigned long get_mmc_clk(int deV_index);
 void set_mmc_clk(int dev_index, unsigned int div);
+int exynos5_mmc_set_clk_div(int dev_index);
 unsigned long get_lcd_clk(void);
 void set_lcd_clk(void);
 void set_mipi_clk(void);
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

author
#16 lore raw

PATCH 6/9 SMDK5250: Enable DWMMC

In reply to Amar

This patch enables DWMMC for SMDK5250.
Support both dt and non-dt versions.

---
 board/samsung/smdk5250/smdk5250.c |   36 ++++++++++++++++++++++++++++++++----
 include/configs/exynos5250-dt.h   |    9 +++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)
board/samsung/smdk5250/smdk5250.c +32 -4
index 4d24978..7a9c8f6 100644
@@ -27,6 +27,7 @@
 #include <netdev.h>
 #include <spi.h>
 #include <asm/arch/cpu.h>
+#include <asm/arch/dwmmc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
@@ -192,16 +193,43 @@ int checkboard(void)
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-	int err;
+	int err = 0, ret = 0;
 
+#ifdef CONFIG_OF_CONTROL
+	/* dwmmc initializattion for available channels */
+	err = exynos_dwmmc_init(gd->fdt_blob);
+	if (err) {
+		debug("dwmmc init failed\n");
+	}
+	ret |= err;
+#else
 	err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
 	if (err) {
 		debug("SDMMC0 not configured\n");
-		return err;
 	}
+	ret |= err;
 
-	err = s5p_mmc_init(0, 8);
-	return err;
+	/*eMMC: dwmmc Channel-0 with 8 bit bus width */
+	err = exynos_dwmmc_init(0, 8);
+	if (err) {
+		debug("dwmmc Channel-0 init failed\n");
+	}
+	ret |= err;
+
+	err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE);
+	if (err) {
+		debug("SDMMC2 not configured\n");
+	}
+	ret |= err;
+
+	/*SD: dwmmc Channel-2 with 4 bit bus width */
+	err = exynos_dwmmc_init(2, 4);
+	if (err) {
+		debug("dwmmc Channel-2 init failed\n");
+	}
+	ret |= err;
+#endif
+	return ret;
 }
 #endif
 
include/configs/exynos5250-dt.h +9 -0
index 12f555c..3b89e20 100644
@@ -84,6 +84,8 @@
 #define CONFIG_MMC
 #define CONFIG_SDHCI
 #define CONFIG_S5P_SDHCI
+#define CONFIG_DWMMC
+#define CONFIG_EXYNOS_DWMMC
 
 #define CONFIG_BOARD_EARLY_INIT_F
 
@@ -116,6 +118,13 @@
 #define CONFIG_SPL
 #define COPY_BL2_FNPTR_ADDR	0x02020030
 
+/* eMMC4.4 SPL */
+#define EMMC44_COPY_BL2_FNPTR_ADDR	0x02020044
+#define EMMC44_END_BOOTOP_FNPTR_ADDR	0x02020048
+
+#define FSYS1_MMC0_DIV_MASK		0xff0f
+
+
 /* specific .lds file */
 #define CONFIG_SPL_LDSCRIPT	"board/samsung/smdk5250/smdk5250-uboot-spl.lds"
 #define CONFIG_SPL_TEXT_BASE	0x02023400
Signature · 1 line
1.7.0.4
#17 lore raw

PATCH 6/9 SMDK5250: Enable DWMMC

Hi Amar,

Quoted 36 lines · Amar

This patch enables DWMMC for SMDK5250.
Support both dt and non-dt versions.

---
 board/samsung/smdk5250/smdk5250.c |   36
++++++++++++++++++++++++++++++++----
 include/configs/exynos5250-dt.h   |    9 +++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)
board/samsung/smdk5250/smdk5250.c +8 -1
index 4d24978..7a9c8f6 100644
@@ -27,6 +27,7 @@
 #include <netdev.h>
 #include <spi.h>
 #include <asm/arch/cpu.h>
+#include <asm/arch/dwmmc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
@@ -192,16 +193,43 @@ int checkboard(void)
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       int err;
+       int err = 0, ret = 0;
 
+#ifdef CONFIG_OF_CONTROL
+       /* dwmmc initializattion for available channels */
+       err = exynos_dwmmc_init(gd->fdt_blob);
+       if (err) {
+               debug("dwmmc init failed\n");
+       }

board/samsung/smdk5250/smdk5250.c int checkboard(void) · line 212

Quoted 10 lines
board/samsung/smdk5250/smdk5250.c +3 -1
+       ret |= err;
+#else
        err = exynos_pinmux_config(PERIPH_ID_SDMMC0,
 PINMUX_FLAG_8BIT_MODE);
        if (err) {
                debug("SDMMC0 not configured\n");
-               return err;
        }
+       ret |= err;
 

Perhaps we need an exynos5-dt.c board file instead of using smdk5250? It seems like you will end up with lots of #ifdefs otherwise.

board/samsung/smdk5250/smdk5250.c int checkboard(void) · line 235

Quoted 8 lines
board/samsung/smdk5250/smdk5250.c +4 -2
-       err = s5p_mmc_init(0, 8);
-       return err;
+       /*eMMC: dwmmc Channel-0 with 8 bit bus width */
+       err = exynos_dwmmc_init(0, 8);
+       if (err) {
+               debug("dwmmc Channel-0 init failed\n");
 

Don't need {} here.

board/samsung/smdk5250/smdk5250.c int checkboard(void) · line 235

Quoted 7 lines
board/samsung/smdk5250/smdk5250.c +6 -0
+       }
+       ret |= err;
+
+       err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE);
+       if (err) {
+               debug("SDMMC2 not configured\n");
 

and here

Quoted 20 lines
board/samsung/smdk5250/smdk5250.c +11 -0
+       }
+       ret |= err;
+
+       /*SD: dwmmc Channel-2 with 4 bit bus width */
+       err = exynos_dwmmc_init(2, 4);
+       if (err) {
+               debug("dwmmc Channel-2 init failed\n");
+       }
+       ret |= err;
+#endif
+       return ret;

}
#endif

include/configs/exynos5250-dt.h +0 -0
index 12f555c..3b89e20 100644

include/configs/exynos5250-dt.h line 88

Quoted 5 lines
include/configs/exynos5250-dt.h +1 -0
@@ -84,6 +84,8 @@
 #define CONFIG_MMC
 #define CONFIG_SDHCI
 #define CONFIG_S5P_SDHCI
+#define CONFIG_DWMMC
 

What does this config enable? Is it in a README somewhere?

include/configs/exynos5250-dt.h line 124

Quoted 12 lines
include/configs/exynos5250-dt.h +4 -0
+#define CONFIG_EXYNOS_DWMMC
 
 #define CONFIG_BOARD_EARLY_INIT_F
@@ -116,6 +118,13 @@
 #define CONFIG_SPL
 #define COPY_BL2_FNPTR_ADDR    0x02020030
 
+/* eMMC4.4 SPL */
+#define EMMC44_COPY_BL2_FNPTR_ADDR     0x02020044
+#define EMMC44_END_BOOTOP_FNPTR_ADDR   0x02020048
 

What are these for?

include/configs/exynos5250-dt.h

Quoted 3 lines
include/configs/exynos5250-dt.h +2 -0
+
+#define FSYS1_MMC0_DIV_MASK            0xff0f
 

This seems like something for the SOC headers, not the board header.

Quoted 10 lines
include/configs/exynos5250-dt.h +2 -0
+
+
 /* specific .lds file */

#define CONFIG_SPL_LDSCRIPT
"board/samsung/smdk5250/smdk5250-uboot-spl.lds"
#define CONFIG_SPL_TEXT_BASE 0x02023400
--
1.7.0.4

Regards,
Simon

#18 lore raw

PATCH 6/9 SMDK5250: Enable DWMMC

Hi Simon,

Thanks for the review comments.
Please find the responses below.

Thanks & Regards
Amarendra Reddy

Quoted 159 lines · Simon Glass

Hi Amar,

Quoted 36 lines · Amar

This patch enables DWMMC for SMDK5250.
Support both dt and non-dt versions.

---
 board/samsung/smdk5250/smdk5250.c |   36
++++++++++++++++++++++++++++++++----
 include/configs/exynos5250-dt.h   |    9 +++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)
board/samsung/smdk5250/smdk5250.c +8 -1
index 4d24978..7a9c8f6 100644
@@ -27,6 +27,7 @@
 #include <netdev.h>
 #include <spi.h>
 #include <asm/arch/cpu.h>
+#include <asm/arch/dwmmc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
@@ -192,16 +193,43 @@ int checkboard(void)
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       int err;
+       int err = 0, ret = 0;
 
+#ifdef CONFIG_OF_CONTROL
+       /* dwmmc initializattion for available channels */
+       err = exynos_dwmmc_init(gd->fdt_blob);
+       if (err) {
+               debug("dwmmc init failed\n");
+       }

board/samsung/smdk5250/smdk5250.c int checkboard(void) · line 212

Quoted 10 lines
board/samsung/smdk5250/smdk5250.c +3 -1
+       ret |= err;
+#else
        err = exynos_pinmux_config(PERIPH_ID_SDMMC0,
 PINMUX_FLAG_8BIT_MODE);
        if (err) {
                debug("SDMMC0 not configured\n");
-               return err;
        }
+       ret |= err;
 

Perhaps we need an exynos5-dt.c board file instead of using smdk5250? It seems like you will end up with lots of #ifdefs otherwise.

OK.

board/samsung/smdk5250/smdk5250.c int checkboard(void) · line 235

Quoted 8 lines
board/samsung/smdk5250/smdk5250.c +4 -2
-       err = s5p_mmc_init(0, 8);
-       return err;
+       /*eMMC: dwmmc Channel-0 with 8 bit bus width */
+       err = exynos_dwmmc_init(0, 8);
+       if (err) {
+               debug("dwmmc Channel-0 init failed\n");
 

Don't need {} here.
OK.

board/samsung/smdk5250/smdk5250.c int checkboard(void) · line 235

Quoted 7 lines
board/samsung/smdk5250/smdk5250.c +6 -0
+       }
+       ret |= err;
+
+       err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE);
+       if (err) {
+               debug("SDMMC2 not configured\n");
 

and here
OK.

Quoted 20 lines
board/samsung/smdk5250/smdk5250.c +11 -0
+       }
+       ret |= err;
+
+       /*SD: dwmmc Channel-2 with 4 bit bus width */
+       err = exynos_dwmmc_init(2, 4);
+       if (err) {
+               debug("dwmmc Channel-2 init failed\n");
+       }
+       ret |= err;
+#endif
+       return ret;

}
#endif

include/configs/exynos5250-dt.h +0 -0
index 12f555c..3b89e20 100644

include/configs/exynos5250-dt.h line 88

Quoted 5 lines
include/configs/exynos5250-dt.h +1 -0
@@ -84,6 +84,8 @@
 #define CONFIG_MMC
 #define CONFIG_SDHCI
 #define CONFIG_S5P_SDHCI
+#define CONFIG_DWMMC
 

What does this config enable? Is it in a README somewhere? CONFIG_DWMMC is for enaling DWMMC. It has to be added into README.

include/configs/exynos5250-dt.h line 124

Quoted 12 lines
include/configs/exynos5250-dt.h +4 -0
+#define CONFIG_EXYNOS_DWMMC
 
 #define CONFIG_BOARD_EARLY_INIT_F
@@ -116,6 +118,13 @@
 #define CONFIG_SPL
 #define COPY_BL2_FNPTR_ADDR    0x02020030
 
+/* eMMC4.4 SPL */
+#define EMMC44_COPY_BL2_FNPTR_ADDR     0x02020044
+#define EMMC44_END_BOOTOP_FNPTR_ADDR   0x02020048
 

What are these for?

These are the IROM function pointers used druing SPL boot.
Any how these #defines wii be removed, as a table for all iROM function
pointers will be maintained in spl_boot.c.

+

include/configs/exynos5250-dt.h line 126

Quoted 2 lines
include/configs/exynos5250-dt.h +1 -0
+#define FSYS1_MMC0_DIV_MASK            0xff0f
 

This seems like something for the SOC headers, not the board header.

FSYS1_MMC0_DIV_MASK will be moved into include/asm/arch/clk.h

Quoted 10 lines
include/configs/exynos5250-dt.h +2 -1
+
+
 /* specific .lds file */
 #define CONFIG_SPL_LDSCRIPT
 "board/samsung/smdk5250/smdk5250-uboot-spl.lds"
 #define CONFIG_SPL_TEXT_BASE   0x02023400
--

1.7.0.4

Regards,
Simon

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

author
#19 lore raw

PATCH 7/9 MMC: APIs to support creation of boot partition

In reply to Amar

This pathc adds APIs to open, close and to create boot partiton for eMMC.

---
 drivers/mmc/mmc.c |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     |   16 +++++++
 2 files changed, 134 insertions(+), 0 deletions(-)
drivers/mmc/mmc.c +118 -0
index 5ffd8c5..88b0435 100644
@@ -1302,3 +1302,121 @@ int mmc_initialize(bd_t *bis)
 
 	return 0;
 }
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+				unsigned long rpmbsize)
+{
+	int err;
+	struct mmc_cmd cmd;
+
+	/* Only use this command for raw eMMC moviNAND */
+	/* Enter backdoor mode */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = MMC_CMD62_ARG1;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
+		return err;
+	}
+
+	/* Boot partition changing mode */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = MMC_CMD62_ARG2;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
+		return err;
+	}
+	/* boot partition size is multiple of 128KB */
+	bootsize = ((bootsize*1024)/128);
+
+	/* Arg: boot partition size */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = bootsize;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
+		return err;
+	}
+	/* RPMB partition size is multiple of 128KB */
+	rpmbsize = ((rpmbsize*1024)/128);
+	/* Arg: RPMB partition size */
+	cmd.cmdidx = MMC_CMD_RES_MAN;
+	cmd.resp_type = MMC_RSP_R1b;
+	cmd.cmdarg = rpmbsize;
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
+		return err;
+	}
+	return 0;
+}
+
+int mmc_boot_open(struct mmc *mmc)
+{
+	int err;
+	struct mmc_cmd cmd;
+
+	/* Boot ack enable, boot partition enable , boot partition access */
+	cmd.cmdidx = MMC_CMD_SWITCH;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24 |
+			EXT_CSD_PART_CONF << 16 |
+			(EXT_CSD_BOOT_ACK_ENABLE |
+			EXT_CSD_BOOT_PARTITION_ENABLE |
+			EXT_CSD_PARTITION_ACCESS_ENABLE) << 8);
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_open: Error1 = %d\n", err);
+		return err;
+	}
+
+	/* 4bit transfer mode@booting time. */
+	cmd.cmdidx = MMC_CMD_SWITCH;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24|
+			EXT_CSD_BOOT_BUS_WIDTH << 16|
+			((1<<0) << 8));
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_open: Error2 = %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+int mmc_boot_close(struct mmc *mmc)
+{
+	int err;
+	struct mmc_cmd cmd;
+
+	/* Boot ack enable, boot partition enable , boot partition access */
+	cmd.cmdidx = MMC_CMD_SWITCH;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24|
+			EXT_CSD_PART_CONF << 16|
+			(EXT_CSD_BOOT_ACK_ENABLE |
+			EXT_CSD_BOOT_PARTITION_ENABLE |
+			EXT_CSD_PARTITION_ACCESS_DISABLE) << 8);
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("mmc_boot_close: Error = %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
include/mmc.h +16 -0
index a13e2bd..999f0a3 100644
@@ -86,6 +86,11 @@
 #define MMC_CMD_APP_CMD			55
 #define MMC_CMD_SPI_READ_OCR		58
 #define MMC_CMD_SPI_CRC_ON_OFF		59
+#define MMC_CMD_RES_MAN			62
+
+#define MMC_CMD62_ARG1			0xefac62ec
+#define MMC_CMD62_ARG2			0xcbaea7
+
 
 #define SD_CMD_SEND_RELATIVE_ADDR	3
 #define SD_CMD_SWITCH_FUNC		6
@@ -153,6 +158,7 @@
  */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
+#define EXT_CSD_BOOT_BUS_WIDTH		177
 #define EXT_CSD_PART_CONF		179	/* R/W */
 #define EXT_CSD_BUS_WIDTH		183	/* R/W */
 #define EXT_CSD_HS_TIMING		185	/* R/W */
@@ -177,6 +183,12 @@
 #define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_8	2	/* Card is in 8 bit mode */
 
+#define EXT_CSD_BOOT_ACK_ENABLE			(1<<6)
+#define EXT_CSD_BOOT_PARTITION_ENABLE		(1<<3)
+#define EXT_CSD_PARTITION_ACCESS_ENABLE		(1<<0)
+#define EXT_CSD_PARTITION_ACCESS_DISABLE	(0<<0)
+
+
 #define R1_ILLEGAL_COMMAND		(1 << 22)
 #define R1_APP_CMD			(1 << 5)
 
@@ -275,6 +287,10 @@ int board_mmc_getcd(struct mmc *mmc);
 int mmc_switch_part(int dev_num, unsigned int part_num);
 int mmc_getcd(struct mmc *mmc);
 void spl_mmc_load(void) __noreturn;
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+					unsigned long rpmbsize);
+int mmc_boot_open(struct mmc *mmc);
+int mmc_boot_close(struct mmc *mmc);
 
 #ifdef CONFIG_GENERIC_MMC
 #define mmc_host_is_spi(mmc)	((mmc)->host_caps & MMC_MODE_SPI)
Signature · 1 line
1.7.0.4
#20 lore raw

PATCH 7/9 MMC: APIs to support creation of boot partition

Hi Amar,

Quoted 4 lines · Amar

This pathc adds APIs to open, close and to create boot partiton for eMMC.

I think you should run checkpatch (or patman!) on your patches to get rid of little errors. Or maybe you need to upgrade your checkpatch.

Quoted 18 lines
---
 drivers/mmc/mmc.c |  118
+++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     |   16 +++++++
 2 files changed, 134 insertions(+), 0 deletions(-)
drivers/mmc/mmc.c +2 -0
index 5ffd8c5..88b0435 100644
@@ -1302,3 +1302,121 @@ int mmc_initialize(bd_t *bis)
 
        return 0;
 }
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long

bootsize,

drivers/mmc/mmc.c int mmc_initialize(bd_t *bis) · line 1313

Quoted 7 lines
drivers/mmc/mmc.c +7 -0
+                               unsigned long rpmbsize)
+{
+       int err;
+       struct mmc_cmd cmd;
+
+       /* Only use this command for raw eMMC moviNAND */
+       /* Enter backdoor mode */

/*
* line 1
* line 2
*/

drivers/mmc/mmc.c int mmc_initialize(bd_t *bis) · line 1317

Quoted 4 lines
drivers/mmc/mmc.c +4 -0
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG1;
+

[snip]

Regards,
Simon

#21 lore raw

PATCH 7/9 MMC: APIs to support creation of boot partition

Hi Simon,

Ok. I will ensure to get rid of these little errors.

Thanks & Regards
Amarendra Reddy

Quoted 61 lines · Simon Glass

Hi Amar,

Quoted 4 lines · Amar

This pathc adds APIs to open, close and to create boot partiton for eMMC.

I think you should run checkpatch (or patman!) on your patches to get rid of little errors. Or maybe you need to upgrade your checkpatch.

Quoted 18 lines
---
 drivers/mmc/mmc.c |  118
+++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     |   16 +++++++
 2 files changed, 134 insertions(+), 0 deletions(-)
drivers/mmc/mmc.c +2 -0
index 5ffd8c5..88b0435 100644
@@ -1302,3 +1302,121 @@ int mmc_initialize(bd_t *bis)
 
        return 0;
 }
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long

bootsize,

drivers/mmc/mmc.c int mmc_initialize(bd_t *bis) · line 1313

Quoted 7 lines
drivers/mmc/mmc.c +7 -0
+                               unsigned long rpmbsize)
+{
+       int err;
+       struct mmc_cmd cmd;
+
+       /* Only use this command for raw eMMC moviNAND */
+       /* Enter backdoor mode */

/*
* line 1
* line 2
*/

drivers/mmc/mmc.c int mmc_initialize(bd_t *bis) · line 1317

Quoted 4 lines
drivers/mmc/mmc.c +4 -0
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG1;
+

[snip]

Regards,
Simon

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

author
#22 lore raw

PATCH 8/9 SMDK5250: Enable eMMC booting

In reply to Amar

This patch adds support for eMMC booting on SMDK5250

---
 board/samsung/smdk5250/spl_boot.c |   38 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 1 deletions(-)
board/samsung/smdk5250/spl_boot.c +37 -1
index d8f3c1e..2648b4e 100644
@@ -23,15 +23,40 @@
 #include<common.h>
 #include<config.h>
 
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+
+#define FSYS1_MMC0_DIV_VAL      0x0701
+
 enum boot_mode {
 	BOOT_MODE_MMC = 4,
+	BOOT_MODE_eMMC = 8, /* eMMC44 */
 	BOOT_MODE_SERIAL = 20,
 	/* Boot based on Operating Mode pin settings */
 	BOOT_MODE_OM = 32,
 	BOOT_MODE_USB,	/* Boot using USB download */
 };
 
-	typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
+typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
+static void set_emmc_clk(void);
+
+/*
+* Set MMC0 clock divisor value.
+* So that the mmc0 device operating freq is 50MHz.
+*/
+static void set_emmc_clk(void)
+{
+	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
+	unsigned int addr;
+	unsigned int div_mmc;
+
+	addr = (unsigned int) &clk->div_fsys1;
+
+	div_mmc = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+	div_mmc |= FSYS1_MMC0_DIV_VAL;
+	writel(div_mmc, addr);
+}
+
 
 /*
 * Copy U-boot from mmc to RAM:
@@ -43,6 +68,8 @@ void copy_uboot_to_ram(void)
 	spi_copy_func_t spi_copy;
 	enum boot_mode bootmode;
 	u32 (*copy_bl2)(u32, u32, u32);
+	u32 (*copy_bl2_emmc)(u32, u32);
+	void (*end_bootop_emmc)(void);
 
 	bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
 
@@ -57,6 +84,15 @@ void copy_uboot_to_ram(void)
 		copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
 						CONFIG_SYS_TEXT_BASE);
 		break;
+	case BOOT_MODE_eMMC:
+		set_emmc_clk();
+		end_bootop_emmc = (void *) *(u32 *)EMMC44_END_BOOTOP_FNPTR_ADDR;
+		copy_bl2_emmc = (void *) *(u32 *)EMMC44_COPY_BL2_FNPTR_ADDR;
+
+		copy_bl2_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+		end_bootop_emmc();
+		break;
+
 	default:
 		break;
 	}
Signature · 1 line
1.7.0.4
#23 lore raw

PATCH 8/9 SMDK5250: Enable eMMC booting

Hi Amar,

Quoted 14 lines · Amar

This patch adds support for eMMC booting on SMDK5250

---
 board/samsung/smdk5250/spl_boot.c |   38
++++++++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 1 deletions(-)
board/samsung/smdk5250/spl_boot.c +0 -0
index d8f3c1e..2648b4e 100644

board/samsung/smdk5250/spl_boot.c line 30

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -23,15 +23,40 @@
 #include<common.h>
 #include<config.h>
 
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+
+#define FSYS1_MMC0_DIV_VAL      0x0701
 

Should go in arch/arm/include/... ?

board/samsung/smdk5250/spl_boot.c line 39

Quoted 5 lines
board/samsung/smdk5250/spl_boot.c +2 -0
+
 enum boot_mode {
        BOOT_MODE_MMC = 4,
+       BOOT_MODE_eMMC = 8, /* eMMC44 */
 

I think should you use upper case E, although I'm not completely sure.

board/samsung/smdk5250/spl_boot.c line 60

Quoted 9 lines
board/samsung/smdk5250/spl_boot.c +1 -1
        BOOT_MODE_SERIAL = 20,
        /* Boot based on Operating Mode pin settings */
        BOOT_MODE_OM = 32,
        BOOT_MODE_USB,  /* Boot using USB download */
 };
 
-       typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
+typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
 

Should avoid adding typedefs.

board/samsung/smdk5250/spl_boot.c line 45

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +5 -0
+static void set_emmc_clk(void);
+
+/*
+* Set MMC0 clock divisor value.
+* So that the mmc0 device operating freq is 50MHz.

Do we only support booting from mmc0? That's fine, but I suggest adding a little comment.

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+*/
+static void set_emmc_clk(void)
+{
+       struct exynos5_clock *clk = (struct exynos5_clock

*)EXYNOS5_CLOCK_BASE;

board/samsung/smdk5250/spl_boot.c line 57

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +8 -0
+       unsigned int addr;
+       unsigned int div_mmc;
+
+       addr = (unsigned int) &clk->div_fsys1;
+
+       div_mmc = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+       div_mmc |= FSYS1_MMC0_DIV_VAL;
+       writel(div_mmc, addr);

Can this function go in clock.c?

Quoted 15 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+}
+
 
 /*
 * Copy U-boot from mmc to RAM:
@@ -43,6 +68,8 @@ void copy_uboot_to_ram(void)
        spi_copy_func_t spi_copy;
        enum boot_mode bootmode;
        u32 (*copy_bl2)(u32, u32, u32);
+       u32 (*copy_bl2_emmc)(u32, u32);
+       void (*end_bootop_emmc)(void);
 
        bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
 

board/samsung/smdk5250/spl_boot.c void copy_uboot_to_ram(void) · line 93

Quoted 10 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -57,6 +84,15 @@ void copy_uboot_to_ram(void)
                copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
                                                CONFIG_SYS_TEXT_BASE);
                break;
+       case BOOT_MODE_eMMC:
+               set_emmc_clk();
+               end_bootop_emmc = (void *) *(u32
 *)EMMC44_END_BOOTOP_FNPTR_ADDR;
+               copy_bl2_emmc = (void *) *(u32
 *)EMMC44_COPY_BL2_FNPTR_ADDR;
 

I think these are pointers to functions in the IROM. Do they have the same signature? Is it possible to create a table of them somewhere instead of using defines?

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +5 -0
+
+               copy_bl2_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+               end_bootop_emmc();
+               break;
+
        default:
                break;
        }
Quoted 4 lines

--
1.7.0.4

Regards,
Simon

#24 lore raw

PATCH 8/9 SMDK5250: Enable eMMC booting

Hi SImon,

Thanks for the review comments.
Please find below the responses for your comments.

Thanks & Regards
Amarendra

Quoted 73 lines · Simon Glass

Hi Amar,

Quoted 14 lines · Amar

This patch adds support for eMMC booting on SMDK5250

---
 board/samsung/smdk5250/spl_boot.c |   38
++++++++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 1 deletions(-)
board/samsung/smdk5250/spl_boot.c +0 -0
index d8f3c1e..2648b4e 100644

board/samsung/smdk5250/spl_boot.c line 30

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -23,15 +23,40 @@
 #include<common.h>
 #include<config.h>
 
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+
+#define FSYS1_MMC0_DIV_VAL      0x0701
 

Should go in arch/arm/include/... ?

OK. shall move it.

board/samsung/smdk5250/spl_boot.c line 39

Quoted 5 lines
board/samsung/smdk5250/spl_boot.c +2 -0
+
 enum boot_mode {
        BOOT_MODE_MMC = 4,
+       BOOT_MODE_eMMC = 8, /* eMMC44 */
 

I think should you use upper case E, although I'm not completely sure. OK. will make it upper case to be consistent every where.

board/samsung/smdk5250/spl_boot.c line 60

Quoted 9 lines
board/samsung/smdk5250/spl_boot.c +1 -1
        BOOT_MODE_SERIAL = 20,
        /* Boot based on Operating Mode pin settings */
        BOOT_MODE_OM = 32,
        BOOT_MODE_USB,  /* Boot using USB download */
 };
 
-       typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
+typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
 

Should avoid adding typedefs.
Ok.

board/samsung/smdk5250/spl_boot.c line 45

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +5 -0
+static void set_emmc_clk(void);
+
+/*
+* Set MMC0 clock divisor value.
+* So that the mmc0 device operating freq is 50MHz.

Do we only support booting from mmc0? That's fine, but I suggest adding a little comment.
OK.

Quoted 10 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+*/
+static void set_emmc_clk(void)
+{
+       struct exynos5_clock *clk = (struct exynos5_clock

*)EXYNOS5_CLOCK_BASE;

board/samsung/smdk5250/spl_boot.c +5 -0
+       unsigned int addr;
+       unsigned int div_mmc;
+
+       addr = (unsigned int) &clk->div_fsys1;
+
Quoted 9 lines

board/samsung/smdk5250/spl_boot.c line 57

Quoted 4 lines
board/samsung/smdk5250/spl_boot.c +3 -0
+       div_mmc = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+       div_mmc |= FSYS1_MMC0_DIV_VAL;
+       writel(div_mmc, addr);

Can this function go in clock.c?
This function is used by SPL, only during EMMC boot. Hence can be moved into board/samsung/smdk5250/clock_init.c.

Please comment on this.

Quoted 17 lines
Quoted 17 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+}
+
 
 /*
 * Copy U-boot from mmc to RAM:
@@ -43,6 +68,8 @@ void copy_uboot_to_ram(void)
        spi_copy_func_t spi_copy;
        enum boot_mode bootmode;
        u32 (*copy_bl2)(u32, u32, u32);
+       u32 (*copy_bl2_emmc)(u32, u32);
+       void (*end_bootop_emmc)(void);
 
        bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
 
Quoted 17 lines

board/samsung/smdk5250/spl_boot.c void copy_uboot_to_ram(void) · line 93

Quoted 11 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -57,6 +84,15 @@ void copy_uboot_to_ram(void)
                copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
                                                CONFIG_SYS_TEXT_BASE);
                break;
+       case BOOT_MODE_eMMC:
+               set_emmc_clk();
+               end_bootop_emmc = (void *) *(u32
 *)EMMC44_END_BOOTOP_FNPTR_ADDR;
+               copy_bl2_emmc = (void *) *(u32
 *)EMMC44_COPY_BL2_FNPTR_ADDR;
 

I think these are pointers to functions in the IROM. Do they have the same signature? Is it possible to create a table of them somewhere instead of using defines?
OK.

The signatures are different for different booting devices.
More over, SDMMC / SPI / USB booting requires only one function pointer. Where as EMMC 4.3/4.4 requires two of those function pointers.

May be something like this can be used to create table

void (*ptr_table[])(void) = {
        (void *)0x02020030, /* iROM Function Pointer - SDMMC boot       */
        (void *)0x0202003C, /* iROM Function Pointer - EMMC 4.3 boot    */
        (void *)0x02020040, /* iROM Function Pointer - EMMC 4.3 end boot op
*/
        (void *)0x02020044, /* iROM Function Pointer - EMMC 4.4 boot    */
        (void *)0x02020048, /* iROM Function Pointer - EMMC 4.4 end boot op
*/
        (void *)0x02020050, /* iROM Function Pointer - EFNAND boot      */
        (void *)0x02020058, /* iROM Function Pointer - SPI boot         */
        (void *)0x02020070  /* iROM Function Pointer - USB boot         */
        };

Usage:

    copy_bl2_from_emmc = (void *) *(u32 *)ptr_table[3];
Quoted 25 lines

end_bootop_from_emmc = (void *) *(u32 *)ptr_table[4];

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +5 -0
+
+               copy_bl2_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+               end_bootop_emmc();
+               break;
+
        default:
                break;
        }
Quoted 4 lines

--
1.7.0.4

Regards,
Simon

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#25 lore raw

PATCH 8/9 SMDK5250: Enable eMMC booting

Hi Amarendra,

Quoted 97 lines · Amarendra Reddy

Hi SImon,

Thanks for the review comments.
Please find below the responses for your comments.

Thanks & Regards
Amarendra

Quoted 88 lines · Simon Glass

Hi Amar,

Quoted 14 lines · Amar

This patch adds support for eMMC booting on SMDK5250

---
 board/samsung/smdk5250/spl_boot.c |   38
++++++++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 1 deletions(-)
board/samsung/smdk5250/spl_boot.c +0 -0
index d8f3c1e..2648b4e 100644

board/samsung/smdk5250/spl_boot.c line 30

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -23,15 +23,40 @@
 #include<common.h>
 #include<config.h>
 
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+
+#define FSYS1_MMC0_DIV_VAL      0x0701
 

Should go in arch/arm/include/... ?

OK. shall move it.

board/samsung/smdk5250/spl_boot.c line 39

Quoted 5 lines
board/samsung/smdk5250/spl_boot.c +2 -0
+
 enum boot_mode {
        BOOT_MODE_MMC = 4,
+       BOOT_MODE_eMMC = 8, /* eMMC44 */
 

I think should you use upper case E, although I'm not completely sure. OK. will make it upper case to be consistent every where.

board/samsung/smdk5250/spl_boot.c line 60

Quoted 9 lines
board/samsung/smdk5250/spl_boot.c +1 -1
        BOOT_MODE_SERIAL = 20,
        /* Boot based on Operating Mode pin settings */
        BOOT_MODE_OM = 32,
        BOOT_MODE_USB,  /* Boot using USB download */
 };
 
-       typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
+typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
 

Should avoid adding typedefs.
Ok.

board/samsung/smdk5250/spl_boot.c line 45

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +5 -0
+static void set_emmc_clk(void);
+
+/*
+* Set MMC0 clock divisor value.
+* So that the mmc0 device operating freq is 50MHz.

Do we only support booting from mmc0? That's fine, but I suggest adding a little comment.
OK.

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+*/
+static void set_emmc_clk(void)
+{
+       struct exynos5_clock *clk = (struct exynos5_clock

*)EXYNOS5_CLOCK_BASE;

board/samsung/smdk5250/spl_boot.c line 57

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +8 -0
+       unsigned int addr;
+       unsigned int div_mmc;
+
+       addr = (unsigned int) &clk->div_fsys1;
+
+       div_mmc = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+       div_mmc |= FSYS1_MMC0_DIV_VAL;
+       writel(div_mmc, addr);

Can this function go in clock.c?
This function is used by SPL, only during EMMC boot. Hence can be moved into board/samsung/smdk5250/clock_init.c.

Please comment on this.

Yes that seems reasonable. There is a lot of code in clock_init that should eventually move to U-Boot proper (i.e. we should only init clocks in SPL that are actually needed in SPL). This can be addressed after Hatim (copied) has finished creating the upstream patches for clock_init / lowlevel_init refactor.

Quoted 39 lines
Quoted 17 lines
Quoted 17 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+}
+
 
 /*
 * Copy U-boot from mmc to RAM:
@@ -43,6 +68,8 @@ void copy_uboot_to_ram(void)
        spi_copy_func_t spi_copy;
        enum boot_mode bootmode;
        u32 (*copy_bl2)(u32, u32, u32);
+       u32 (*copy_bl2_emmc)(u32, u32);
+       void (*end_bootop_emmc)(void);
 
        bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
 
Quoted 16 lines

board/samsung/smdk5250/spl_boot.c void copy_uboot_to_ram(void) · line 93

Quoted 11 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -57,6 +84,15 @@ void copy_uboot_to_ram(void)
                copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
                                                CONFIG_SYS_TEXT_BASE);
                break;
+       case BOOT_MODE_eMMC:
+               set_emmc_clk();
+               end_bootop_emmc = (void *) *(u32
 *)EMMC44_END_BOOTOP_FNPTR_ADDR;
+               copy_bl2_emmc = (void *) *(u32
 *)EMMC44_COPY_BL2_FNPTR_ADDR;
 

I think these are pointers to functions in the IROM. Do they have the same signature? Is it possible to create a table of them somewhere instead of using defines?
OK.

The signatures are different for different booting devices. More over, SDMMC / SPI / USB booting requires only one function pointer. Where as EMMC 4.3/4.4 requires two of those function pointers.

May be something like this can be used to create table

Quoted 12 lines
void (*ptr_table[])(void) = {
        (void *)0x02020030, /* iROM Function Pointer - SDMMC boot       */
        (void *)0x0202003C, /* iROM Function Pointer - EMMC 4.3 boot    */
        (void *)0x02020040, /* iROM Function Pointer - EMMC 4.3 end boot op
*/
        (void *)0x02020044, /* iROM Function Pointer - EMMC 4.4 boot    */
        (void *)0x02020048, /* iROM Function Pointer - EMMC 4.4 end boot op
*/
        (void *)0x02020050, /* iROM Function Pointer - EFNAND boot      */
        (void *)0x02020058, /* iROM Function Pointer - SPI boot         */
        (void *)0x02020070  /* iROM Function Pointer - USB boot         */
        };

Well I suggest just having addresses in the table (ulong) instead of pointers if you can, so there are fewer casts.

Quoted 5 lines

Usage:

    copy_bl2_from_emmc = (void *) *(u32 *)ptr_table[3];
Quoted 2 lines

end_bootop_from_emmc = (void *) *(u32 *)ptr_table[4];

Seems reasonable, but please do create an enum for the available function numbers rather than just using 3 or 4.

Quoted 19 lines
Quoted 19 lines
Quoted 13 lines
board/samsung/smdk5250/spl_boot.c +2 -0
+
+               copy_bl2_emmc(BL2_SIZE_BLOC_COUNT,

CONFIG_SYS_TEXT_BASE);

board/samsung/smdk5250/spl_boot.c +3 -1
+               end_bootop_emmc();
+               break;
+
        default:
                break;
        }
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

Quoted 6 lines
Quoted 5 lines

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Regards,
Simon

#26 lore raw

PATCH 8/9 SMDK5250: Enable eMMC booting

Hi Simon,
Thanks for review comments.
Please find my responses below.

Thanks & Regards
Amarendra

Quoted 213 lines · Simon Glass

Hi Amarendra,

Quoted 58 lines · Amarendra Reddy

Hi SImon,

Thanks for the review comments.
Please find below the responses for your comments.

Thanks & Regards
Amarendra

Quoted 49 lines · Simon Glass

Hi Amar,

Quoted 14 lines · Amar

This patch adds support for eMMC booting on SMDK5250

---
 board/samsung/smdk5250/spl_boot.c |   38
++++++++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 1 deletions(-)
board/samsung/smdk5250/spl_boot.c +0 -0
index d8f3c1e..2648b4e 100644

board/samsung/smdk5250/spl_boot.c line 30

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +4 -0
@@ -23,15 +23,40 @@
 #include<common.h>
 #include<config.h>
 
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+
+#define FSYS1_MMC0_DIV_VAL      0x0701
 

Should go in arch/arm/include/... ?

OK. shall move it.

board/samsung/smdk5250/spl_boot.c line 39

Quoted 5 lines
board/samsung/smdk5250/spl_boot.c +2 -0
+
 enum boot_mode {
        BOOT_MODE_MMC = 4,
+       BOOT_MODE_eMMC = 8, /* eMMC44 */
 

I think should you use upper case E, although I'm not completely sure. OK. will make it upper case to be consistent every where.

Quoted 7 lines
board/samsung/smdk5250/spl_boot.c +0 -1
        BOOT_MODE_SERIAL = 20,
        /* Boot based on Operating Mode pin settings */
        BOOT_MODE_OM = 32,
        BOOT_MODE_USB,  /* Boot using USB download */
 };
 
-       typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32

dst);

Quoted 7 lines
Quoted 7 lines

board/samsung/smdk5250/spl_boot.c line 60

Quoted 2 lines
board/samsung/smdk5250/spl_boot.c +1 -0
+typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
 

Should avoid adding typedefs.
Ok.

Quoted 8 lines
Quoted 8 lines

board/samsung/smdk5250/spl_boot.c line 45

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +5 -0
+static void set_emmc_clk(void);
+
+/*
+* Set MMC0 clock divisor value.
+* So that the mmc0 device operating freq is 50MHz.

Do we only support booting from mmc0? That's fine, but I suggest adding

a

Quoted 23 lines
Quoted 23 lines

little comment.
OK.

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+*/
+static void set_emmc_clk(void)
+{
+       struct exynos5_clock *clk = (struct exynos5_clock

*)EXYNOS5_CLOCK_BASE;

board/samsung/smdk5250/spl_boot.c line 57

Quoted 8 lines
board/samsung/smdk5250/spl_boot.c +8 -0
+       unsigned int addr;
+       unsigned int div_mmc;
+
+       addr = (unsigned int) &clk->div_fsys1;
+
+       div_mmc = readl(addr) & ~FSYS1_MMC0_DIV_MASK;
+       div_mmc |= FSYS1_MMC0_DIV_VAL;
+       writel(div_mmc, addr);

Can this function go in clock.c?
This function is used by SPL, only during EMMC boot. Hence can be moved into board/samsung/smdk5250/clock_init.c.

Quoted 1 line
Quoted 1 line

Please comment on this.

Yes that seems reasonable. There is a lot of code in clock_init that should eventually move to U-Boot proper (i.e. we should only init clocks in SPL that are actually needed in SPL). This can be addressed after Hatim (copied) has finished creating the upstream patches for clock_init / lowlevel_init refactor.
Ok.

Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
board/samsung/smdk5250/spl_boot.c +4 -0
+}
+
 
 /*
 * Copy U-boot from mmc to RAM:
@@ -43,6 +68,8 @@ void copy_uboot_to_ram(void)
        spi_copy_func_t spi_copy;
        enum boot_mode bootmode;
        u32 (*copy_bl2)(u32, u32, u32);
+       u32 (*copy_bl2_emmc)(u32, u32);
+       void (*end_bootop_emmc)(void);
 
        bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
 
Quoted 13 lines
Quoted 5 lines
Quoted 5 lines
board/samsung/smdk5250/spl_boot.c +1 -0
@@ -57,6 +84,15 @@ void copy_uboot_to_ram(void)
                copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
                                                CONFIG_SYS_TEXT_BASE);
                break;
+       case BOOT_MODE_eMMC:
Quoted 8 lines

board/samsung/smdk5250/spl_boot.c void copy_uboot_to_ram(void) · line 93

Quoted 6 lines
board/samsung/smdk5250/spl_boot.c +3 -0
+               set_emmc_clk();
+               end_bootop_emmc = (void *) *(u32
 *)EMMC44_END_BOOTOP_FNPTR_ADDR;
+               copy_bl2_emmc = (void *) *(u32
 *)EMMC44_COPY_BL2_FNPTR_ADDR;
 

I think these are pointers to functions in the IROM. Do they have the

same

Quoted 11 lines
Quoted 3 lines

signature? Is it possible to create a table of them somewhere instead of using defines?
OK.

The signatures are different for different booting devices. More over, SDMMC / SPI / USB booting requires only one function pointer. Where as EMMC 4.3/4.4 requires two of those function pointers.

May be something like this can be used to create table

void (*ptr_table[])(void) = {
        (void *)0x02020030, /* iROM Function Pointer - SDMMC boot

*/

Quoted 1 line
        (void *)0x0202003C, /* iROM Function Pointer - EMMC 4.3 boot

*/

Quoted 1 line
        (void *)0x02020040, /* iROM Function Pointer - EMMC 4.3 end boot

op

Quoted 2 lines

*/

        (void *)0x02020044, /* iROM Function Pointer - EMMC 4.4 boot

*/

Quoted 1 line
        (void *)0x02020048, /* iROM Function Pointer - EMMC 4.4 end boot

op

Quoted 2 lines

*/

        (void *)0x02020050, /* iROM Function Pointer - EFNAND boot

*/

Quoted 1 line
        (void *)0x02020058, /* iROM Function Pointer - SPI boot

*/

Quoted 1 line
        (void *)0x02020070  /* iROM Function Pointer - USB boot

*/

Quoted 1 line
        };

Well I suggest just having addresses in the table (ulong) instead of pointers if you can, so there are fewer casts.
Ok.

Quoted 5 lines

Usage:

    copy_bl2_from_emmc = (void *) *(u32 *)ptr_table[3];
Quoted 2 lines

end_bootop_from_emmc = (void *) *(u32 *)ptr_table[4];

Seems reasonable, but please do create an enum for the available function numbers rather than just using 3 or 4.
Yes, I have used enum in actual implementation. The above was an example.

Quoted 18 lines
Quoted 18 lines
Quoted 12 lines
board/samsung/smdk5250/spl_boot.c +2 -0
+
+               copy_bl2_emmc(BL2_SIZE_BLOC_COUNT,

CONFIG_SYS_TEXT_BASE);

board/samsung/smdk5250/spl_boot.c +3 -1
+               end_bootop_emmc();
+               break;
+
        default:
                break;
        }
--
Quoted 3 lines

1.7.0.4

Regards,
Simon

Quoted 6 lines
Quoted 5 lines

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Regards,
Simon

author
#27 lore raw

PATCH 9/9 COMMON: MMC: Command to support eMMC booting

In reply to Amar

This patch adds commands to open, close and create partitions on eMMC

---
 common/cmd_mmc.c |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 100 insertions(+), 1 deletions(-)
common/cmd_mmc.c +100 -1
index 62a1c22..1fd6b94 100644
@@ -248,6 +248,102 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				curr_device, mmc->part_num);
 
 		return 0;
+	} else if (strcmp(argv[1], "open") == 0) {
+		int dev;
+		struct mmc *mmc;
+
+		if (argc == 2)
+			dev = curr_device;
+		else if (argc == 3)
+			dev = simple_strtoul(argv[2], NULL, 10);
+		else if (argc == 4)
+			return 1;
+
+		else
+			return CMD_RET_USAGE;
+
+		mmc = find_mmc_device(dev);
+		if (!mmc) {
+			printf("no mmc device at slot %x\n", dev);
+			return 1;
+		}
+
+		if (IS_SD(mmc)) {
+			printf("SD device cannot be opened/closed\n");
+			return 1;
+		}
+
+		if (!(mmc_boot_open(mmc))) {
+			printf("eMMC OPEN Success.!!\n");
+			printf("\t\t\t!!!Notice!!!\n");
+			printf("!You must close eMMC boot Partition"
+						"after all image writing!\n");
+			printf("!eMMC boot partition has continuity"
+						"at image writing time.!\n");
+			printf("!So, Do not close boot partition, Before,"
+						"all images is written.!\n");
+		} else {
+			printf("eMMC OPEN Failed.!!\n");
+		}
+		return 0;
+
+	} else if (strcmp(argv[1], "close") == 0) {
+		int dev;
+		struct mmc *mmc;
+
+		if (argc == 2)
+			dev = curr_device;
+		else if (argc == 3)
+			dev = simple_strtoul(argv[2], NULL, 10);
+		else if (argc == 4)
+			return 1;
+		else
+			return CMD_RET_USAGE;
+
+		mmc = find_mmc_device(dev);
+		if (!mmc) {
+			printf("no mmc device at slot %x\n", dev);
+			return 1;
+		}
+
+		if (IS_SD(mmc)) {
+			printf("SD device cannot be opened/closed\n");
+			return 1;
+		}
+
+		if (!(mmc_boot_close(mmc)))
+			printf("eMMC CLOSE Success.!!\n");
+		else
+			printf("eMMC CLOSE Failed.!!\n");
+
+		return 0;
+
+	} else if (strcmp(argv[1], "bootpart") == 0) {
+		int dev;
+		dev = simple_strtoul(argv[2], NULL, 10);
+
+		struct mmc *mmc = find_mmc_device(dev);
+		u32 bootsize = simple_strtoul(argv[3], NULL, 10);
+		u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
+
+		if (!mmc) {
+			printf("no mmc device at slot %x\n", dev);
+			return 1;
+		}
+
+		if (IS_SD(mmc)) {
+			printf("It is not a eMMC device\n");
+			return 1;
+		}
+
+		if (0 == mmc_boot_partition_size_change(mmc,
+						bootsize, rpmbsize)) {
+			printf("eMMC boot partition Size %d MB!!\n", bootsize);
+			printf("eMMC RPMB partition Size %d MB!!\n", rpmbsize);
+		} else {
+			printf("eMMC boot partition Size change Failed.!!\n");
+		}
+		return 0;
 	}
 
 	if (strcmp(argv[1], "read") == 0)
@@ -318,5 +414,8 @@ U_BOOT_CMD(
 	"mmc rescan\n"
 	"mmc part - lists available partition on current mmc device\n"
 	"mmc dev [dev] [part] - show or set current mmc device [partition]\n"
-	"mmc list - lists available devices");
+	"mmc list - lists available devices\n"
+	"mmc open <device num> - opens the specified device\n"
+	"mmc close <device num> - closes the specified device\n"
+	"mmc bootpart <device num> <boot part size MB> <RPMB part size MB>\n");
 #endif
Signature · 1 line
1.7.0.4
#28 lore raw

PATCH 9/9 COMMON: MMC: Command to support eMMC booting

Hi Amar,

Quoted 18 lines · Amar

This patch adds commands to open, close and create partitions on eMMC

---
 common/cmd_mmc.c |  101
+++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 100 insertions(+), 1 deletions(-)
common/cmd_mmc.c +1 -0
index 62a1c22..1fd6b94 100644
@@ -248,6 +248,102 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int
 argc, char * const argv[])
                                curr_device, mmc->part_num);
 
                return 0;
+       } else if (strcmp(argv[1], "open") == 0) {

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int · line 262

Quoted 10 lines
common/cmd_mmc.c +9 -0
+               int dev;
+               struct mmc *mmc;
+
+               if (argc == 2)
+                       dev = curr_device;
+               else if (argc == 3)
+                       dev = simple_strtoul(argv[2], NULL, 10);
+               else if (argc == 4)
+                       return 1;
 

Should this be CMD_RET_USAGE? What is returning 1 for?

Quoted 26 lines
common/cmd_mmc.c +22 -0
+
+               else
+                       return CMD_RET_USAGE;
+
+               mmc = find_mmc_device(dev);
+               if (!mmc) {
+                       printf("no mmc device at slot %x\n", dev);
+                       return 1;
+               }
+
+               if (IS_SD(mmc)) {
+                       printf("SD device cannot be opened/closed\n");
+                       return 1;
+               }
+
+               if (!(mmc_boot_open(mmc))) {
+                       printf("eMMC OPEN Success.!!\n");
+                       printf("\t\t\t!!!Notice!!!\n");
+                       printf("!You must close eMMC boot Partition"
+                                               "after all image
 writing!\n");
+                       printf("!eMMC boot partition has continuity"
+                                               "at image writing

time.!\n");

common/cmd_mmc.c +2 -0
+                       printf("!So, Do not close boot partition, Before,"
+                                               "all images is
Quoted 2 lines

written.!\n");

Maybe:

So, do not close boot partition before all images are written

+ } else {

Quoted 2 lines

+ printf("eMMC OPEN Failed.!!\n");

Is it eMMC or MMC? Lower case or upper case? Your messages should be consistent. And you don't need the !!! I think.

Quoted 4 lines
common/cmd_mmc.c +3 -0
+               }
+               return 0;
+

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 299

Quoted 10 lines
common/cmd_mmc.c +10 -0
+       } else if (strcmp(argv[1], "close") == 0) {
+               int dev;
+               struct mmc *mmc;
+
+               if (argc == 2)
+                       dev = curr_device;
+               else if (argc == 3)
+                       dev = simple_strtoul(argv[2], NULL, 10);
+               else if (argc == 4)
+                       return 1;

Same Q here as above.

Quoted 5 lines
common/cmd_mmc.c +4 -0
+               else
+                       return CMD_RET_USAGE;
+
+               mmc = find_mmc_device(dev);

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 275

Quoted 10 lines
common/cmd_mmc.c +10 -0
+               if (!mmc) {
+                       printf("no mmc device at slot %x\n", dev);
+                       return 1;
+               }
+
+               if (IS_SD(mmc)) {
+                       printf("SD device cannot be opened/closed\n");
+                       return 1;
+               }
+

Seems the open/close code is almost the same. Can you combine it?

Quoted 33 lines
common/cmd_mmc.c +28 -0
+               if (!(mmc_boot_close(mmc)))
+                       printf("eMMC CLOSE Success.!!\n");
+               else
+                       printf("eMMC CLOSE Failed.!!\n");
+
+               return 0;
+
+       } else if (strcmp(argv[1], "bootpart") == 0) {
+               int dev;
+               dev = simple_strtoul(argv[2], NULL, 10);
+
+               struct mmc *mmc = find_mmc_device(dev);
+               u32 bootsize = simple_strtoul(argv[3], NULL, 10);
+               u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
+
+               if (!mmc) {
+                       printf("no mmc device at slot %x\n", dev);
+                       return 1;
+               }
+
+               if (IS_SD(mmc)) {
+                       printf("It is not a eMMC device\n");
+                       return 1;
+               }
+
+               if (0 == mmc_boot_partition_size_change(mmc,
+                                               bootsize, rpmbsize)) {
+                       printf("eMMC boot partition Size %d MB!!\n",

bootsize);
+ printf("eMMC RPMB partition Size %d MB!!\n",
rpmbsize);

common/cmd_mmc.c +2 -0
+               } else {
+                       printf("eMMC boot partition Size change
Quoted 2 lines

Failed.!!\n");

return 1 here I think

Quoted 15 lines
common/cmd_mmc.c +2 -0
+               }
+               return 0;
        }
 
        if (strcmp(argv[1], "read") == 0)
@@ -318,5 +414,8 @@ U_BOOT_CMD(
        "mmc rescan\n"
        "mmc part - lists available partition on current mmc device\n"
        "mmc dev [dev] [part] - show or set current mmc device

[partition]\n"

common/cmd_mmc.c +4 -1
-       "mmc list - lists available devices");
+       "mmc list - lists available devices\n"
+       "mmc open <device num> - opens the specified device\n"
+       "mmc close <device num> - closes the specified device\n"
+       "mmc bootpart <device num> <boot part size MB> <RPMB part size
Quoted 2 lines

MB>\n");

Can you add another line of help here explaining what this does?

Quoted 5 lines

#endif
--
1.7.0.4

Regards,

Simon

#29 lore raw

PATCH 9/9 COMMON: MMC: Command to support eMMC booting

Hi SImon,

Thanks for the review comments.
Please find below the responses for your comments.

Thanks & Regards
Amarendra

Quoted 62 lines · Simon Glass

Hi Amar,

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag,

Quoted 13 lines · Amar

This patch adds commands to open, close and create partitions on eMMC

---
 common/cmd_mmc.c |  101
+++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 100 insertions(+), 1 deletions(-)
common/cmd_mmc.c +0 -0
index 62a1c22..1fd6b94 100644
@@ -248,6 +248,102 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag,

int

Quoted 5 lines
common/cmd_mmc.c +1 -0
 argc, char * const argv[])
                                curr_device, mmc->part_num);
 
                return 0;
+       } else if (strcmp(argv[1], "open") == 0) {

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 348

Quoted 10 lines
common/cmd_mmc.c +9 -0
+               int dev;
+               struct mmc *mmc;
+
+               if (argc == 2)
+                       dev = curr_device;
+               else if (argc == 3)
+                       dev = simple_strtoul(argv[2], NULL, 10);
+               else if (argc == 4)
+                       return 1;
 

Should this be CMD_RET_USAGE? What is returning 1 for?
Yes. Shall correct it.

Quoted 23 lines
common/cmd_mmc.c +22 -0
+
+               else
+                       return CMD_RET_USAGE;
+
+               mmc = find_mmc_device(dev);
+               if (!mmc) {
+                       printf("no mmc device at slot %x\n", dev);
+                       return 1;
+               }
+
+               if (IS_SD(mmc)) {
+                       printf("SD device cannot be opened/closed\n");
+                       return 1;
+               }
+
+               if (!(mmc_boot_open(mmc))) {
+                       printf("eMMC OPEN Success.!!\n");
+                       printf("\t\t\t!!!Notice!!!\n");
+                       printf("!You must close eMMC boot Partition"
+                                               "after all image
 writing!\n");
+                       printf("!eMMC boot partition has continuity"
+                                               "at image writing
Quoted 2 lines

time.!\n");
+ printf("!So, Do not close boot partition,

Before,"

Quoted 8 lines
Quoted 3 lines

+ "all images is
written.!\n");

Maybe:

So, do not close boot partition before all images are written
OK.. will change the wordings.

+ } else {

Quoted 37 lines
Quoted 2 lines

+ printf("eMMC OPEN Failed.!!\n");

Is it eMMC or MMC? Lower case or upper case? Your messages should be consistent. And you don't need the !!! I think.

OK. Will maintain EMMC consistently every where. Will remove "!!!".

+ }

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 299

Quoted 13 lines
common/cmd_mmc.c +12 -0
+               return 0;
+
+       } else if (strcmp(argv[1], "close") == 0) {
+               int dev;
+               struct mmc *mmc;
+
+               if (argc == 2)
+                       dev = curr_device;
+               else if (argc == 3)
+                       dev = simple_strtoul(argv[2], NULL, 10);
+               else if (argc == 4)
+                       return 1;

Same Q here as above.

Ok, will be addressed.

Quoted 9 lines
common/cmd_mmc.c +9 -0
+               else
+                       return CMD_RET_USAGE;
+
+               mmc = find_mmc_device(dev);
+               if (!mmc) {
+                       printf("no mmc device at slot %x\n", dev);
+                       return 1;
+               }
+
Quoted 9 lines

common/cmd_mmc.c static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) · line 275

Quoted 6 lines
common/cmd_mmc.c +5 -0
+               if (IS_SD(mmc)) {
+                       printf("SD device cannot be opened/closed\n");
+                       return 1;
+               }
+

Seems the open/close code is almost the same. Can you combine it?

Ok. Will combine open/close.

Quoted 30 lines
Quoted 30 lines
common/cmd_mmc.c +28 -0
+               if (!(mmc_boot_close(mmc)))
+                       printf("eMMC CLOSE Success.!!\n");
+               else
+                       printf("eMMC CLOSE Failed.!!\n");
+
+               return 0;
+
+       } else if (strcmp(argv[1], "bootpart") == 0) {
+               int dev;
+               dev = simple_strtoul(argv[2], NULL, 10);
+
+               struct mmc *mmc = find_mmc_device(dev);
+               u32 bootsize = simple_strtoul(argv[3], NULL, 10);
+               u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
+
+               if (!mmc) {
+                       printf("no mmc device at slot %x\n", dev);
+                       return 1;
+               }
+
+               if (IS_SD(mmc)) {
+                       printf("It is not a eMMC device\n");
+                       return 1;
+               }
+
+               if (0 == mmc_boot_partition_size_change(mmc,
+                                               bootsize, rpmbsize)) {
+                       printf("eMMC boot partition Size %d MB!!\n",

bootsize);

Quoted 9 lines
Quoted 6 lines

+ printf("eMMC RPMB partition Size %d MB!!\n",
rpmbsize);

common/cmd_mmc.c +2 -0
+               } else {
+                       printf("eMMC boot partition Size change

Failed.!!\n");

return 1 here I think

Yes. WIll be corrected.

Quoted 35 lines
Quoted 16 lines
common/cmd_mmc.c +2 -0
+               }
+               return 0;
        }
 
        if (strcmp(argv[1], "read") == 0)
@@ -318,5 +414,8 @@ U_BOOT_CMD(
        "mmc rescan\n"
        "mmc part - lists available partition on current mmc device\n"
        "mmc dev [dev] [part] - show or set current mmc device

[partition]\n"

common/cmd_mmc.c +4 -1
-       "mmc list - lists available devices");
+       "mmc list - lists available devices\n"
+       "mmc open <device num> - opens the specified device\n"
+       "mmc close <device num> - closes the specified device\n"
+       "mmc bootpart <device num> <boot part size MB> <RPMB part size
Quoted 2 lines

MB>\n");

Can you add another line of help here explaining what this does? OK. I will add another line of help for mmc bootpart.

Quoted 5 lines

#endif
--
1.7.0.4

Regards,

Simon

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot