Skip to contentSkip to conversation

drivers: mmc: dwmmc: enable support for DT

PATCH New Beomho Seo 3 participants 5 messages Mar 20, 2014 – Apr 10, 2014

Subsystems (3)
lore
Share & tools
lore

Beomho Seo

author
#0 lore raw

PATCH v3 1/4 drivers: mmc: dwmmc: enable support for DT

This patch enables for device tree for dw-mmc driver. Driver have been fixed because it is used exynos5 and exynos4. Add, fdt compat id of exynos4 dwmmc.

---
Changes for v3:
- None.

 drivers/mmc/exynos_dw_mmc.c |   21 +++++++++++++++++----
 include/fdtdec.h            |    1 +
 lib/fdtdec.c                |    1 +
 3 files changed, 19 insertions(+), 4 deletions(-)
drivers/mmc/exynos_dw_mmc.c +17 -4
index de8cdcc..b9d41d4 100644
@@ -13,6 +13,7 @@
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
 
 #define	DWMMC_MAX_CH_NUM		4
 #define	DWMMC_MAX_FREQ			52000000
@@ -82,6 +83,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 	freq = 52000000;
 	sclk = get_mmc_clk(index);
 	div = DIV_ROUND_UP(sclk, freq);
+	div -= 1;
 	/* set the clock divisor for mmc */
 	set_mmc_clk(index, div);
 
@@ -118,15 +120,21 @@ int exynos_dwmmc_init(const void *blob)
 {
 	int index, bus_width;
 	int node_list[DWMMC_MAX_CH_NUM];
-	int err = 0, dev_id, flag, count, i;
+	int err = 0, dev_id, flag, count, i, compat_id;
 	u32 clksel_val, base, timing[3];
 
+#ifdef CONFIG_EXYNOS4
+	compat_id = COMPAT_SAMSUNG_EXYNOS4_DWMMC;
+#else
+	compat_id = COMPAT_SAMSUNG_EXYNOS5_DWMMC;
+#endif
+
 	count = fdtdec_find_aliases_for_id(blob, "mmc",
-				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
-				DWMMC_MAX_CH_NUM);
+				compat_id, node_list, DWMMC_MAX_CH_NUM);
 
 	for (i = 0; i < count; i++) {
 		int node = node_list[i];
+		struct fdt_gpio_state pwr_gpio;
 
 		if (node <= 0)
 			continue;
@@ -145,6 +153,9 @@ int exynos_dwmmc_init(const void *blob)
 		else
 			flag = PINMUX_FLAG_NONE;
 
+		fdtdec_decode_gpio(blob, node, "pwr-gpios", &pwr_gpio);
+		if (fdt_gpio_isvalid(&pwr_gpio))
+			gpio_direction_output(pwr_gpio.gpio, 1);
 		/* config pinmux for each mmc channel */
 		err = exynos_pinmux_config(dev_id, flag);
 		if (err) {
@@ -152,7 +163,9 @@ int exynos_dwmmc_init(const void *blob)
 			return err;
 		}
 
-		index = dev_id - PERIPH_ID_SDMMC0;
+		index = fdtdec_get_int(blob, node, "index", dev_id);
+		if (index == dev_id)
+			index = dev_id - PERIPH_ID_SDMMC0;
 
 		/* Get the base address from the device node */
 		base = fdtdec_get_addr(blob, node, "reg");
include/fdtdec.h +1 -0
index 63027bd..15f50fe 100644
@@ -83,6 +83,7 @@ enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS5_DP,	/* Exynos Display port controller */
 	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_MMC,	/* Exynos MMC controller */
+	COMPAT_SAMSUNG_EXYNOS4_DWMMC,	/* Exynos4 DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_SERIAL,	/* Exynos UART */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
 	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
lib/fdtdec.c +1 -0
index be04598..79179cf 100644
@@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
 	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
+	COMPAT(SAMSUNG_EXYNOS4_DWMMC, "samsung,exynos4412-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v3 1/4 drivers: mmc: dwmmc: enable support for DT

Dear Beonho Seo,

Quoted 32 lines · Beomho Seo

This patch enables for device tree for dw-mmc driver. Driver have been fixed because it is used exynos5 and exynos4. Add, fdt compat id of exynos4 dwmmc.

---
Changes for v3:
- None.

 drivers/mmc/exynos_dw_mmc.c |   21 +++++++++++++++++----
 include/fdtdec.h            |    1 +
 lib/fdtdec.c                |    1 +
 3 files changed, 19 insertions(+), 4 deletions(-)
drivers/mmc/exynos_dw_mmc.c +1 -0
index de8cdcc..b9d41d4 100644
@@ -13,6 +13,7 @@
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
 
 #define	DWMMC_MAX_CH_NUM		4
 #define	DWMMC_MAX_FREQ			52000000

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) · line 86

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +1 -0
@@ -82,6 +83,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 	freq = 52000000;
 	sclk = get_mmc_clk(index);
 	div = DIV_ROUND_UP(sclk, freq);
+	div -= 1;

why?

Quoted 6 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 	/* set the clock divisor for mmc */
 	set_mmc_clk(index, div);
 
@@ -118,15 +120,21 @@ int exynos_dwmmc_init(const void *blob)
 {
 	int index, bus_width;

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 130

Quoted 10 lines
drivers/mmc/exynos_dw_mmc.c +6 -1
 	int node_list[DWMMC_MAX_CH_NUM];
-	int err = 0, dev_id, flag, count, i;
+	int err = 0, dev_id, flag, count, i, compat_id;
 	u32 clksel_val, base, timing[3];
 
+#ifdef CONFIG_EXYNOS4
+	compat_id = COMPAT_SAMSUNG_EXYNOS4_DWMMC;
+#else
+	compat_id = COMPAT_SAMSUNG_EXYNOS5_DWMMC;
+#endif

NAK.
please don't use ifdef.

Quoted 13 lines
drivers/mmc/exynos_dw_mmc.c +3 -2
+
 	count = fdtdec_find_aliases_for_id(blob, "mmc",
-				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
-				DWMMC_MAX_CH_NUM);
+				compat_id, node_list, DWMMC_MAX_CH_NUM);
 
 	for (i = 0; i < count; i++) {
 		int node = node_list[i];
+		struct fdt_gpio_state pwr_gpio;
 
 		if (node <= 0)
 			continue;

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 158

Quoted 6 lines
drivers/mmc/exynos_dw_mmc.c +3 -0
@@ -145,6 +153,9 @@ int exynos_dwmmc_init(const void *blob)
 		else
 			flag = PINMUX_FLAG_NONE;
 
+		fdtdec_decode_gpio(blob, node, "pwr-gpios", &pwr_gpio);
+		if (fdt_gpio_isvalid(&pwr_gpio))
+			gpio_direction_output(pwr_gpio.gpio, 1);

please add blank line.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 168

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +3 -1
 		/* config pinmux for each mmc channel */
 		err = exynos_pinmux_config(dev_id, flag);
 		if (err) {
@@ -152,7 +163,9 @@ int exynos_dwmmc_init(const void *blob)
 			return err;
 		}
 
-		index = dev_id - PERIPH_ID_SDMMC0;
+		index = fdtdec_get_int(blob, node, "index", dev_id);
+		if (index == dev_id)
+			index = dev_id - PERIPH_ID_SDMMC0;

I can't understand why this routine is needed.
Could you please explain?

include/fdtdec.h enum fdt_compat_id { · line 86

Quoted 12 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 		/* Get the base address from the device node */
 		base = fdtdec_get_addr(blob, node, "reg");
include/fdtdec.h +1 -0
index 63027bd..15f50fe 100644
@@ -83,6 +83,7 @@ enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS5_DP,	/* Exynos Display port controller */
 	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_MMC,	/* Exynos MMC controller */
+	COMPAT_SAMSUNG_EXYNOS4_DWMMC,	/* Exynos4 DWMMC controller */

Do we need to separate exynos4 dwmmc and exynos5 dwmmc?

Jaehoon,
how you think?

Quoted 9 lines
include/fdtdec.h +0 -0
 	COMPAT_SAMSUNG_EXYNOS_SERIAL,	/* Exynos UART */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
 	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
lib/fdtdec.c +0 -0
index be04598..79179cf 100644

lib/fdtdec.c static const char * const compat_names[COMPAT_COUNT] = { · line 62

Quoted 7 lines
lib/fdtdec.c +1 -0
@@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
 	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
+	COMPAT(SAMSUNG_EXYNOS4_DWMMC, "samsung,exynos4412-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),

Thanks,
Minkyu Kang.

#2 lore raw

PATCH v3 1/4 drivers: mmc: dwmmc: enable support for DT

Quoted 53 lines · Minkyu Kang

Dear Beonho Seo,

Quoted 32 lines · Beomho Seo

This patch enables for device tree for dw-mmc driver. Driver have been fixed because it is used exynos5 and exynos4. Add, fdt compat id of exynos4 dwmmc.

---
Changes for v3:
- None.

 drivers/mmc/exynos_dw_mmc.c |   21 +++++++++++++++++----
 include/fdtdec.h            |    1 +
 lib/fdtdec.c                |    1 +
 3 files changed, 19 insertions(+), 4 deletions(-)
drivers/mmc/exynos_dw_mmc.c +1 -0
index de8cdcc..b9d41d4 100644
@@ -13,6 +13,7 @@
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
 
 #define	DWMMC_MAX_CH_NUM		4
 #define	DWMMC_MAX_FREQ			52000000

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) · line 86

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +1 -0
@@ -82,6 +83,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 	freq = 52000000;
 	sclk = get_mmc_clk(index);
 	div = DIV_ROUND_UP(sclk, freq);
+	div -= 1;

why?

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +1 -1
 	/* set the clock divisor for mmc */
 	set_mmc_clk(index, div);
 
@@ -118,15 +120,21 @@ int exynos_dwmmc_init(const void *blob)
 {
 	int index, bus_width;
 	int node_list[DWMMC_MAX_CH_NUM];
-	int err = 0, dev_id, flag, count, i;
+	int err = 0, dev_id, flag, count, i, compat_id;
 	u32 clksel_val, base, timing[3];
 
Quoted 8 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 130

Quoted 5 lines
drivers/mmc/exynos_dw_mmc.c +5 -0
+#ifdef CONFIG_EXYNOS4
+	compat_id = COMPAT_SAMSUNG_EXYNOS4_DWMMC;
+#else
+	compat_id = COMPAT_SAMSUNG_EXYNOS5_DWMMC;
+#endif

NAK.
please don't use ifdef.

In my patch, this is used the below.
+
+ if (cpu_is_exynos4())
+ compat_id = COMPAT_SAMSUNG_EXYNOS4_DWMMC;
+ else if (cpu_is_exynos5())
+ compat_id = COMPAT_SAMSUNG_EXYNOS5_DWMMC;
+ else
+ compat_id = COMPAT_UNKNOWN;
+

Quoted 39 lines
Quoted 14 lines
drivers/mmc/exynos_dw_mmc.c +3 -2
+
 	count = fdtdec_find_aliases_for_id(blob, "mmc",
-				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
-				DWMMC_MAX_CH_NUM);
+				compat_id, node_list, DWMMC_MAX_CH_NUM);
 
 	for (i = 0; i < count; i++) {
 		int node = node_list[i];
+		struct fdt_gpio_state pwr_gpio;
 
 		if (node <= 0)
 			continue;

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 158

Quoted 6 lines
drivers/mmc/exynos_dw_mmc.c +3 -0
@@ -145,6 +153,9 @@ int exynos_dwmmc_init(const void *blob)
 		else
 			flag = PINMUX_FLAG_NONE;
 
+		fdtdec_decode_gpio(blob, node, "pwr-gpios", &pwr_gpio);
+		if (fdt_gpio_isvalid(&pwr_gpio))
+			gpio_direction_output(pwr_gpio.gpio, 1);

please add blank line.

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 168

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +3 -1
 		/* config pinmux for each mmc channel */
 		err = exynos_pinmux_config(dev_id, flag);
 		if (err) {
@@ -152,7 +163,9 @@ int exynos_dwmmc_init(const void *blob)
 			return err;
 		}
 
-		index = dev_id - PERIPH_ID_SDMMC0;
+		index = fdtdec_get_int(blob, node, "index", dev_id);
+		if (index == dev_id)
+			index = dev_id - PERIPH_ID_SDMMC0;

I can't understand why this routine is needed.
Could you please explain?

Quoted 1 line
Quoted 13 lines

include/fdtdec.h enum fdt_compat_id { · line 86

Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 		/* Get the base address from the device node */
 		base = fdtdec_get_addr(blob, node, "reg");
include/fdtdec.h +1 -0
index 63027bd..15f50fe 100644
@@ -83,6 +83,7 @@ enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS5_DP,	/* Exynos Display port controller */
 	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_MMC,	/* Exynos MMC controller */
+	COMPAT_SAMSUNG_EXYNOS4_DWMMC,	/* Exynos4 DWMMC controller */

Do we need to separate exynos4 dwmmc and exynos5 dwmmc?

It didn't need to separate.

Best Regards,
Jaehoon Chung

Quoted 28 lines

Jaehoon,
how you think?

Quoted 9 lines
include/fdtdec.h +0 -0
 	COMPAT_SAMSUNG_EXYNOS_SERIAL,	/* Exynos UART */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
 	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
lib/fdtdec.c +0 -0
index be04598..79179cf 100644

lib/fdtdec.c static const char * const compat_names[COMPAT_COUNT] = { · line 62

Quoted 7 lines
lib/fdtdec.c +1 -0
@@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
 	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
+	COMPAT(SAMSUNG_EXYNOS4_DWMMC, "samsung,exynos4412-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),

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

author
#3 lore raw

PATCH v3 1/4 drivers: mmc: dwmmc: enable support for DT

In reply to Minkyu Kang

Thank you for your advice.

Quoted 32 lines · Minkyu Kang

Dear Beonho Seo,

Quoted 29 lines · Beomho Seo

This patch enables for device tree for dw-mmc driver. Driver have been fixed because it is used exynos5 and exynos4. Add, fdt compat id of exynos4 dwmmc.

---
Changes for v3:
- None.

 drivers/mmc/exynos_dw_mmc.c |   21 +++++++++++++++++----
 include/fdtdec.h            |    1 +
 lib/fdtdec.c                |    1 +
 3 files changed, 19 insertions(+), 4 deletions(-)
drivers/mmc/exynos_dw_mmc.c +1 -0
index de8cdcc..b9d41d4 100644
@@ -13,6 +13,7 @@
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
 
Quoted 10 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) · line 86

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +1 -0
 #define	DWMMC_MAX_CH_NUM		4
 #define	DWMMC_MAX_FREQ			52000000
@@ -82,6 +83,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 	freq = 52000000;
 	sclk = get_mmc_clk(index);
 	div = DIV_ROUND_UP(sclk, freq);
+	div -= 1;

why?

It need for set accurately required frequency.
Above code prevent to set below the required frequency. For example above case,
If sclk is 100 MHz and required frequency 50 MHz, Where div = 2. and then mmc clock set 33 MHz calculating.
So It need div minus one.

Quoted 11 lines
Quoted 11 lines
drivers/mmc/exynos_dw_mmc.c +1 -1
 	/* set the clock divisor for mmc */
 	set_mmc_clk(index, div);
 
@@ -118,15 +120,21 @@ int exynos_dwmmc_init(const void *blob)
 {
 	int index, bus_width;
 	int node_list[DWMMC_MAX_CH_NUM];
-	int err = 0, dev_id, flag, count, i;
+	int err = 0, dev_id, flag, count, i, compat_id;
 	u32 clksel_val, base, timing[3];
 
Quoted 9 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 130

Quoted 5 lines
drivers/mmc/exynos_dw_mmc.c +5 -0
+#ifdef CONFIG_EXYNOS4
+	compat_id = COMPAT_SAMSUNG_EXYNOS4_DWMMC;
+#else
+	compat_id = COMPAT_SAMSUNG_EXYNOS5_DWMMC;
+#endif

NAK.
please don't use ifdef.

OK. I will change it.

Quoted 16 lines
Quoted 16 lines
drivers/mmc/exynos_dw_mmc.c +3 -2
+
 	count = fdtdec_find_aliases_for_id(blob, "mmc",
-				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
-				DWMMC_MAX_CH_NUM);
+				compat_id, node_list, DWMMC_MAX_CH_NUM);
 
 	for (i = 0; i < count; i++) {
 		int node = node_list[i];
+		struct fdt_gpio_state pwr_gpio;
 
 		if (node <= 0)
 			continue;
@@ -145,6 +153,9 @@ int exynos_dwmmc_init(const void *blob)
 		else
 			flag = PINMUX_FLAG_NONE;
 
Quoted 6 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 158

Quoted 3 lines
drivers/mmc/exynos_dw_mmc.c +3 -0
+		fdtdec_decode_gpio(blob, node, "pwr-gpios", &pwr_gpio);
+		if (fdt_gpio_isvalid(&pwr_gpio))
+			gpio_direction_output(pwr_gpio.gpio, 1);

please add blank line.

OK. I will add blank line.

Quoted 7 lines
Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 		/* config pinmux for each mmc channel */
 		err = exynos_pinmux_config(dev_id, flag);
 		if (err) {
@@ -152,7 +163,9 @@ int exynos_dwmmc_init(const void *blob)
 			return err;
 		}
 
Quoted 8 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 168

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +3 -1
-		index = dev_id - PERIPH_ID_SDMMC0;
+		index = fdtdec_get_int(blob, node, "index", dev_id);
+		if (index == dev_id)
+			index = dev_id - PERIPH_ID_SDMMC0;

I can't understand why this routine is needed.
Could you please explain?

SDMMC index(0, 1 ... 4) is need to get/set mmc clk.
It is decided the difference between dev_id and PERIPH_ID_SDMMC0(=75).
But If dev_id is PERIPH_ID_SDMMC4(=131), index is set inaccurately.
So I add index property at device tree. and then parse it.
If index property not exist, index is decided the difference between dev_id and PERIPH_ID_SDMMC0.

Quoted 15 lines

include/fdtdec.h enum fdt_compat_id { · line 86

Quoted 12 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 		/* Get the base address from the device node */
 		base = fdtdec_get_addr(blob, node, "reg");
include/fdtdec.h +1 -0
index 63027bd..15f50fe 100644
@@ -83,6 +83,7 @@ enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS5_DP,	/* Exynos Display port controller */
 	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_MMC,	/* Exynos MMC controller */
+	COMPAT_SAMSUNG_EXYNOS4_DWMMC,	/* Exynos4 DWMMC controller */

Do we need to separate exynos4 dwmmc and exynos5 dwmmc?

OK, I will change and test it.

Quoted 23 lines

Jaehoon,
how you think?

Quoted 9 lines
include/fdtdec.h +0 -0
 	COMPAT_SAMSUNG_EXYNOS_SERIAL,	/* Exynos UART */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
 	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
lib/fdtdec.c +0 -0
index be04598..79179cf 100644

lib/fdtdec.c static const char * const compat_names[COMPAT_COUNT] = { · line 62

Quoted 7 lines
lib/fdtdec.c +1 -0
@@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
 	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
+	COMPAT(SAMSUNG_EXYNOS4_DWMMC, "samsung,exynos4412-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),

Thanks,
Minkyu Kang.

#4 lore raw

PATCH v3 1/4 drivers: mmc: dwmmc: enable support for DT

Hi, Minkyu.

Quoted 46 lines · Beomho Seo

Thank you for your advice.

Quoted 32 lines · Minkyu Kang

Dear Beonho Seo,

Quoted 29 lines · Beomho Seo

This patch enables for device tree for dw-mmc driver. Driver have been fixed because it is used exynos5 and exynos4. Add, fdt compat id of exynos4 dwmmc.

---
Changes for v3:
- None.

 drivers/mmc/exynos_dw_mmc.c |   21 +++++++++++++++++----
 include/fdtdec.h            |    1 +
 lib/fdtdec.c                |    1 +
 3 files changed, 19 insertions(+), 4 deletions(-)
drivers/mmc/exynos_dw_mmc.c +1 -0
index de8cdcc..b9d41d4 100644
@@ -13,6 +13,7 @@
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
 
Quoted 10 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) · line 86

Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +1 -0
 #define	DWMMC_MAX_CH_NUM		4
 #define	DWMMC_MAX_FREQ			52000000
@@ -82,6 +83,7 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
 	freq = 52000000;
 	sclk = get_mmc_clk(index);
 	div = DIV_ROUND_UP(sclk, freq);
+	div -= 1;

why?

Quoted 6 lines

It need for set accurately required frequency.
Above code prevent to set below the required frequency. For example above case,
If sclk is 100 MHz and required frequency 50 MHz, Where div = 2. and then mmc clock set 33 MHz calculating.
So It need div minus one.

It didn't consider how div value is set into CMU register.
SCLK = (MOUT/(PRE_RATIO + 1))/(RATIO + 1).
Finally, it didn't consider for plus one. Source clock is set to wrong value.

It needs to change other approach than using just "div -= 1".

If i understood something wrong, let me know, plz.

Best Regards,
Jaehoon Chung

Quoted 114 lines
Quoted 12 lines
Quoted 12 lines
drivers/mmc/exynos_dw_mmc.c +1 -1
 	/* set the clock divisor for mmc */
 	set_mmc_clk(index, div);
 
@@ -118,15 +120,21 @@ int exynos_dwmmc_init(const void *blob)
 {
 	int index, bus_width;
 	int node_list[DWMMC_MAX_CH_NUM];
-	int err = 0, dev_id, flag, count, i;
+	int err = 0, dev_id, flag, count, i, compat_id;
 	u32 clksel_val, base, timing[3];
 
Quoted 9 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 130

Quoted 5 lines
drivers/mmc/exynos_dw_mmc.c +5 -0
+#ifdef CONFIG_EXYNOS4
+	compat_id = COMPAT_SAMSUNG_EXYNOS4_DWMMC;
+#else
+	compat_id = COMPAT_SAMSUNG_EXYNOS5_DWMMC;
+#endif

NAK.
please don't use ifdef.

OK. I will change it.

Quoted 16 lines
Quoted 16 lines
drivers/mmc/exynos_dw_mmc.c +3 -2
+
 	count = fdtdec_find_aliases_for_id(blob, "mmc",
-				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
-				DWMMC_MAX_CH_NUM);
+				compat_id, node_list, DWMMC_MAX_CH_NUM);
 
 	for (i = 0; i < count; i++) {
 		int node = node_list[i];
+		struct fdt_gpio_state pwr_gpio;
 
 		if (node <= 0)
 			continue;
@@ -145,6 +153,9 @@ int exynos_dwmmc_init(const void *blob)
 		else
 			flag = PINMUX_FLAG_NONE;
 
Quoted 6 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 158

Quoted 3 lines
drivers/mmc/exynos_dw_mmc.c +3 -0
+		fdtdec_decode_gpio(blob, node, "pwr-gpios", &pwr_gpio);
+		if (fdt_gpio_isvalid(&pwr_gpio))
+			gpio_direction_output(pwr_gpio.gpio, 1);

please add blank line.

OK. I will add blank line.

Quoted 7 lines
Quoted 7 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 		/* config pinmux for each mmc channel */
 		err = exynos_pinmux_config(dev_id, flag);
 		if (err) {
@@ -152,7 +163,9 @@ int exynos_dwmmc_init(const void *blob)
 			return err;
 		}
 
Quoted 8 lines

drivers/mmc/exynos_dw_mmc.c int exynos_dwmmc_init(const void *blob) · line 168

Quoted 4 lines
drivers/mmc/exynos_dw_mmc.c +3 -1
-		index = dev_id - PERIPH_ID_SDMMC0;
+		index = fdtdec_get_int(blob, node, "index", dev_id);
+		if (index == dev_id)
+			index = dev_id - PERIPH_ID_SDMMC0;

I can't understand why this routine is needed.
Could you please explain?

SDMMC index(0, 1 ... 4) is need to get/set mmc clk.
It is decided the difference between dev_id and PERIPH_ID_SDMMC0(=75).
But If dev_id is PERIPH_ID_SDMMC4(=131), index is set inaccurately.
So I add index property at device tree. and then parse it.
If index property not exist, index is decided the difference between dev_id and PERIPH_ID_SDMMC0.

Quoted 15 lines

include/fdtdec.h enum fdt_compat_id { · line 86

Quoted 12 lines
drivers/mmc/exynos_dw_mmc.c +0 -0
 		/* Get the base address from the device node */
 		base = fdtdec_get_addr(blob, node, "reg");
include/fdtdec.h +1 -0
index 63027bd..15f50fe 100644
@@ -83,6 +83,7 @@ enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS5_DP,	/* Exynos Display port controller */
 	COMPAT_SAMSUNG_EXYNOS5_DWMMC,	/* Exynos5 DWMMC controller */
 	COMPAT_SAMSUNG_EXYNOS_MMC,	/* Exynos MMC controller */
+	COMPAT_SAMSUNG_EXYNOS4_DWMMC,	/* Exynos4 DWMMC controller */

Do we need to separate exynos4 dwmmc and exynos5 dwmmc?

OK, I will change and test it.

Quoted 23 lines

Jaehoon,
how you think?

Quoted 9 lines
include/fdtdec.h +0 -0
 	COMPAT_SAMSUNG_EXYNOS_SERIAL,	/* Exynos UART */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
 	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
lib/fdtdec.c +0 -0
index be04598..79179cf 100644

lib/fdtdec.c static const char * const compat_names[COMPAT_COUNT] = { · line 62

Quoted 7 lines
lib/fdtdec.c +1 -0
@@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
 	COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
+	COMPAT(SAMSUNG_EXYNOS4_DWMMC, "samsung,exynos4412-dwmmc"),
 	COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),

Thanks,
Minkyu Kang.