* [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and
@ 2013-01-04 9:34 Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 1/9] FDT: Add compatible string for DWMMC Amar
` (8 more replies)
0 siblings, 9 replies; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch set enables and initialises DWMMC for Exynos5250 on SMDK5250.
Adds driver changes required for DWMMC.
Adds FDT support for DWMMC.
Adds EMMC boot support 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" present at the following link
http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/149991
Changes from V1:
1)Corrected in response to review comments.
2)Created separate board files for FDT and non-FDT versions.
3)Added binding file for DWMMC device node.
4)Removed the propname 'index' from device node.
5)Prefixed the vendor name 'samsung' before propname in device node.
6)Ensured to have same signature for the function exynos_dwmci_init()
for both FDT and non-FDT versions.
7)EMMC clock setting has been moved from spl_boot.c to clock_init.c.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of the
hard coded value (1 << 10).
2)In the file exynos_dw_mmc.c, replaced the new function
exynos5_mmc_set_clk_div() with the existing function set_mmc_clk().
set_mmc_clk() will do the purpose.
3)In the file exynos_dw_mmc.c, computation of FSYS block clock
divisor (pre-ratio) value is added.
4)Removed the new function exynos5_mmc_set_clk_div() from clock.c.
Amar (9):
FDT: Add compatible string for DWMMC
EXYNOS5: FDT: Add DWMMC device node data
DWMMC: Initialise dwmci and resolve EMMC read write issues
EXYNOS5: DWMMC: Added FDT support for DWMMC
EXYNOS5: DWMMC: API to set mmc clock divisor
SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
MMC: APIs to support resize of EMMC boot partition
SMDK5250: Enable EMMC booting
COMMON: MMC: Command to support EMMC booting and to
arch/arm/cpu/armv7/exynos/clock.c | 4 +-
arch/arm/dts/exynos5250.dtsi | 32 ++++
arch/arm/include/asm/arch-exynos/clk.h | 3 +
arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
board/samsung/dts/exynos5250-smdk5250.dts | 22 +++
board/samsung/smdk5250/Makefile | 4 +
board/samsung/smdk5250/clock_init.c | 15 ++
board/samsung/smdk5250/clock_init.h | 5 +
board/samsung/smdk5250/exynos5-dt.c | 242 ++++++++++++++++++++++++++++++
board/samsung/smdk5250/smdk5250.c | 97 ++++++------
board/samsung/smdk5250/spl_boot.c | 52 ++++++-
common/cmd_mmc.c | 84 ++++++++++-
doc/device-tree-bindings/exynos/dwmmc.txt | 29 ++++
drivers/mmc/dw_mmc.c | 14 +-
drivers/mmc/exynos_dw_mmc.c | 129 +++++++++++++++-
drivers/mmc/mmc.c | 118 +++++++++++++++
include/configs/exynos5250-dt.h | 2 +
include/dwmmc.h | 4 +
include/fdtdec.h | 1 +
include/i2c.h | 2 +
include/mmc.h | 16 ++
lib/fdtdec.c | 1 +
22 files changed, 806 insertions(+), 74 deletions(-)
create mode 100644 board/samsung/smdk5250/exynos5-dt.c
create mode 100644 doc/device-tree-bindings/exynos/dwmmc.txt
--
1.8.0
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 1/9] FDT: Add compatible string for DWMMC
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
@ 2013-01-04 9:34 ` Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data Amar
` (7 subsequent siblings)
8 siblings, 0 replies; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
Add required compatible information for DWMMC driver.
Changes from V1:
No change.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
No change.
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Signed-off-by: Amar <amarendra.xt@samsung.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
include/fdtdec.h | 1 +
lib/fdtdec.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/include/fdtdec.h b/include/fdtdec.h
index ce10bf4..dcd4142 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -76,6 +76,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,
};
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index aa75710..646d5d6 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -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.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 1/9] FDT: Add compatible string for DWMMC Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 15:21 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues Amar
` (6 subsequent siblings)
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch adds DWMMC device node data for exynos5.
This patch also adds binding file for DWMMC device node.
Changes from V1:
1)Added binding file for DWMMC device node at the location
"doc/device-tree-bindings/exynos/dwmmc.txt".
2)Removed the propname 'index' from device node.
3)Prefixed the vendor name 'samsung' before propname in device node.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
No change.
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Signed-off-by: Amar <amarendra.xt@samsung.com>X
---
arch/arm/dts/exynos5250.dtsi | 32 +++++++++++++++++++++++++++++++
board/samsung/dts/exynos5250-smdk5250.dts | 22 +++++++++++++++++++++
doc/device-tree-bindings/exynos/dwmmc.txt | 29 ++++++++++++++++++++++++++++
3 files changed, 83 insertions(+)
create mode 100644 doc/device-tree-bindings/exynos/dwmmc.txt
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
index 1008797..b701ae5 100644
--- a/arch/arm/dts/exynos5250.dtsi
+++ b/arch/arm/dts/exynos5250.dtsi
@@ -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>;
+ };
};
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts
index a8e62da..9baf622 100644
--- a/board/samsung/dts/exynos5250-smdk5250.dts
+++ b/board/samsung/dts/exynos5250-smdk5250.dts
@@ -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,22 @@
compatible = "wolfson,wm8994-codec";
};
};
+
+ dwmmc at 12200000 {
+ samsung,bus-width = <8>;
+ samsung,timing = <1 3 3>;
+ };
+
+ dwmmc at 12210000 {
+ status = "disabled";
+ };
+
+ dwmmc at 12220000 {
+ samsung,bus-width = <4>;
+ samsung,timing = <1 2 3>;
+ };
+
+ dwmmc at 12230000 {
+ status = "disabled";
+ };
};
diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt b/doc/device-tree-bindings/exynos/dwmmc.txt
new file mode 100644
index 0000000..6232ad6
--- /dev/null
+++ b/doc/device-tree-bindings/exynos/dwmmc.txt
@@ -0,0 +1,29 @@
+* Exynos 5250 DWC_mobile_storage
+
+The Exynos 5250 provides DWC_mobile_storage interface which supports
+. Embedded Multimedia Cards (EMMC-version 4.5)
+. Secure Digital memory (SD mem-version 2.0)
+. Secure Digital I/O (SDIO-version 3.0)
+. Consumer Electronics Advanced Transport Architecture (CE-ATA-version 1.1)
+
+The Exynos 5250 DWC_mobile_storage provides four channels.
+SOC specific and Board specific properties are channel specific.
+
+Required SoC Specific Properties:
+
+- compatible: should be
+ - samsung,exynos5250-dwmmc: for exynos5250 platforms
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- interrupts: The interrupt number to the cpu.
+
+Required Board Specific Properties:
+
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- samsung,bus-width: The width of the bus used to interface the devices
+ supported by DWC_mobile_storage (SD-MMC/EMMC/SDIO).
+- samsung,timing: The timing values to be written into the
+ Drv/sample clock selection register of corresponding channel.
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 1/9] FDT: Add compatible string for DWMMC Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 15:26 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC Amar
` (5 subsequent siblings)
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch enumerates dwmci and set auto stop command during
dwmci initialisation.
EMMC read/write is not happening in current implementation
due to improper fifo size computation. Hence Modified the fifo size
computation to resolve EMMC read write issues.
Changes from V1:
1)Created the macros RX_WMARK_SHIFT and RX_WMARK_MASK in header file.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of
the hard coded value (1 << 10).
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
drivers/mmc/dw_mmc.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 4070d4e..776fdb6 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -136,6 +136,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
return TIMEOUT;
}
timeout--;
+ mdelay(1);
}
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
@@ -314,7 +315,7 @@ static void dwmci_set_ios(struct mmc *mmc)
static int dwmci_init(struct mmc *mmc)
{
struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
- u32 fifo_size, fifoth_val;
+ u32 fifo_size, fifoth_val, ier;
dwmci_writel(host, DWMCI_PWREN, 1);
@@ -323,6 +324,14 @@ static int dwmci_init(struct mmc *mmc)
return -1;
}
+ /* Enumerate at 400KHz */
+ dwmci_setup_bus(host, mmc->f_min);
+
+ /* Set auto stop command */
+ ier = dwmci_readl(host, DWMCI_CTRL);
+ ier |= DWMCI_CTRL_SEND_AS_CCSD;
+ dwmci_writel(host, DWMCI_CTRL, ier);
+
dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
dwmci_writel(host, DWMCI_INTMASK, 0);
@@ -332,10 +341,11 @@ static int dwmci_init(struct mmc *mmc)
dwmci_writel(host, DWMCI_BMOD, 1);
fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
+ fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
if (host->fifoth_val)
fifoth_val = host->fifoth_val;
else
- fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 -1) |
+ fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 - 1) |
TX_WMARK(fifo_size/2);
dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
` (2 preceding siblings ...)
2013-01-04 9:34 ` [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 15:33 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor Amar
` (4 subsequent siblings)
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch adds FDT support for DWMMC, by reading the DWMMC node data
from the device tree and initialising DWMMC channels as per data
obtained from the node.
Changes from V1:
1)Updated code to have same signature for the function
exynos_dwmci_init() for both FDT and non-FDT versions.
2)Updated code to pass device_id parameter to the function
exynos5_mmc_set_clk_div() instead of index.
3)Updated code to decode the value of "samsung,width" from FDT.
4)Channel index is computed instead of getting from FDT.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
1)Replaced the new function exynos5_mmc_set_clk_div() with the
existing function set_mmc_clk(). set_mmc_clk() will do the purpose.
2)Computation of FSYS block clock divisor (pre-ratio) is added.
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
drivers/mmc/exynos_dw_mmc.c | 129 +++++++++++++++++++++++++++++--
include/dwmmc.h | 4 +
3 files changed, 130 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
index 8acdf9b..40dcc7b 100644
--- a/arch/arm/include/asm/arch-exynos/dwmmc.h
+++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
@@ -29,8 +29,12 @@
int exynos_dwmci_init(u32 regbase, int bus_width, int index);
+#ifdef CONFIG_OF_CONTROL
+unsigned int exynos_dwmmc_init(const void *blob);
+#else
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
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 72a31b7..d7ca7d0 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -19,39 +19,154 @@
*/
#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>
+
+#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
+#define ONE_MEGA_HZ 1000000
+#define SCALED_VAL_FOUR_HUNDRED 400
static char *EXYNOS_NAME = "EXYNOS DWMMC";
+u32 timing[3];
+/*
+ * Function used as callback function to initialise the
+ * CLKSEL register for every mmc channel.
+ */
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)
+{
+ return get_mmc_clk(dev_index);
}
int exynos_dwmci_init(u32 regbase, int bus_width, int index)
{
struct dwmci_host *host = NULL;
+ unsigned int clock, div;
host = malloc(sizeof(struct dwmci_host));
if (!host) {
printf("dwmci_host malloc fail!\n");
return 1;
}
+ /*
+ * The max operating freq of FSYS block is 400MHz.
+ * Scale down the 400MHz to number 400.
+ * Scale down the MPLL clock by dividing MPLL_CLK with ONE_MEGA_HZ.
+ * Arrive at the divisor value taking 400 as the reference.
+ */
+
+ /* get mpll clock and divide it by ONE_MEGA_HZ */
+ clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
+
+ /* Arrive at the divisor value. */
+ for (div = 0; div <= 0xf; div++) {
+ if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
+ break;
+ }
+
+ /* set the clock divisor for mmc */
+ set_mmc_clk(index, div);
+
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;
-
- add_dwmci(host, 52000000, 400000);
+ host->mmc_clk = exynos_dwmci_get_clk;
+ /* Add the mmc chennel to be registered with mmc core */
+ 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;
+ 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];
+
+ if (node <= 0)
+ continue;
+
+ /* Extract device id for each mmc channel */
+ dev_id = pinmux_decode_periph_id(blob, node);
+
+ /* Get the bus width from the device node */
+ bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
+ if (bus_width < 0) {
+ debug("DWMMC: Can't get bus-width\n");
+ return -1;
+ }
+ if (8 == bus_width)
+ flag = PINMUX_FLAG_8BIT_MODE;
+ else
+ flag = PINMUX_FLAG_NONE;
+
+ /* config pinmux for each mmc channel */
+ err = exynos_pinmux_config(dev_id, flag);
+ if (err) {
+ debug("DWMMC not configured\n");
+ return err;
+ }
+
+ index = dev_id - PERIPH_ID_SDMMC0;
+
+ /* Get the base address from the device node */
+ base = fdtdec_get_addr(blob, node, "reg");
+ if (!base) {
+ debug("DWMMC: Can't get base address\n");
+ return -1;
+ }
+ /* Extract the timing info from the node */
+ err = fdtdec_get_int_array(blob, node, "samsung,timing",
+ timing, 3);
+ if (err) {
+ debug("Can't get sdr-timings for divider\n");
+ return -1;
+ }
+ /* Initialise each mmc channel */
+ err = exynos_dwmci_init(base, bus_width, index);
+ if (err) {
+ debug("Can't do dwmci init\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+#endif
diff --git a/include/dwmmc.h b/include/dwmmc.h
index c8b1d40..4a42849 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -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;
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
` (3 preceding siblings ...)
2013-01-04 9:34 ` [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 15:35 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT Amar
` (3 subsequent siblings)
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This API computes the divisor value based on MPLL clock and
writes it into the FSYS1 register.
Changes from V1:
1)Updated the function exynos5_mmc_set_clk_div() to receive
'device_i'd as input parameter instead of 'index'.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
1)Removed the new API exynos5_mmc_set_clk_div() from clock.c,
because existing API set_mmc_clk() can be used to set mmc clock.
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
arch/arm/cpu/armv7/exynos/clock.c | 4 ++--
arch/arm/include/asm/arch-exynos/clk.h | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
index 973b84e..89574ba 100644
--- a/arch/arm/cpu/armv7/exynos/clock.c
+++ b/arch/arm/cpu/armv7/exynos/clock.c
@@ -490,7 +490,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;
@@ -539,7 +539,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;
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
index 1935b0b..a4d5b4e 100644
--- a/arch/arm/include/asm/arch-exynos/clk.h
+++ b/arch/arm/include/asm/arch-exynos/clk.h
@@ -29,6 +29,9 @@
#define VPLL 4
#define BPLL 5
+#define FSYS1_MMC0_DIV_MASK 0xff0f
+#define FSYS1_MMC0_DIV_VAL 0x0701
+
unsigned long get_pll_clk(int pllreg);
unsigned long get_arm_clk(void);
unsigned long get_i2c_clk(void);
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
` (4 preceding siblings ...)
2013-01-04 9:34 ` [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 16:57 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition Amar
` (2 subsequent siblings)
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch enables and initialises DWMMC for SMDK5250.
Supports both FDT and non-FDT. This patch creates a new file
'exynos5-dt.c' meant for FDT support.
exynos5-dt.c: This file shall contain all code which supports FDT.
Any addition of FDT support for any module needs to be
added in this file.
smdk5250.c: This file shall contain the code which supports non-FDT.
version. Any addition of non-FDT support for any module
needs to be added in this file.
May be, the file smdk5250.c can be removed in near future
when non-FDT is not required.
The Makefile is updated to compile only one of the files
exynos5-dt.c / smdk5250.c based on FDT configuration.
NOTE:
Please note that all additions corresponding to FDT need to be added into the
file exynos5-dt.c.
At same time if non-FDT support is required then add the corresponding
updations into smdk5250.c.
Changes from V1:
1)A new file 'exynos5-dt.c' is created meant for FDT support
2)Makefile is updated to compile only one of the files
exynos5-dt.c / smdk5250.c based on FDT configuration
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
No change.
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
board/samsung/smdk5250/Makefile | 4 +
board/samsung/smdk5250/exynos5-dt.c | 242 ++++++++++++++++++++++++++++++++++++
board/samsung/smdk5250/smdk5250.c | 97 +++++++--------
include/configs/exynos5250-dt.h | 2 +
include/i2c.h | 2 +
5 files changed, 292 insertions(+), 55 deletions(-)
create mode 100644 board/samsung/smdk5250/exynos5-dt.c
diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile
index 47c6a5a..ecca9f3 100644
--- a/board/samsung/smdk5250/Makefile
+++ b/board/samsung/smdk5250/Makefile
@@ -32,8 +32,12 @@ COBJS += tzpc_init.o
COBJS += smdk5250_spl.o
ifndef CONFIG_SPL_BUILD
+ifdef CONFIG_OF_CONTROL
+COBJS += exynos5-dt.o
+else
COBJS += smdk5250.o
endif
+endif
ifdef CONFIG_SPL_BUILD
COBJS += spl_boot.o
diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c
new file mode 100644
index 0000000..da539ca
--- /dev/null
+++ b/board/samsung/smdk5250/exynos5-dt.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <i2c.h>
+#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>
+#include <asm/arch/sromc.h>
+#include <power/pmic.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
+#ifdef CONFIG_EXYNOS_SPI
+ spi_init();
+#endif
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_7_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_7_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE)
+ + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE);
+ return 0;
+}
+
+#if defined(CONFIG_POWER)
+int power_init_board(void)
+{
+ if (pmic_init(I2C_PMIC))
+ return -1;
+ else
+ return 0;
+}
+#endif
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
+ PHYS_SDRAM_1_SIZE);
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
+ PHYS_SDRAM_2_SIZE);
+ gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
+ gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
+ PHYS_SDRAM_3_SIZE);
+ gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
+ gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
+ PHYS_SDRAM_4_SIZE);
+ gd->bd->bi_dram[4].start = PHYS_SDRAM_5;
+ gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5,
+ PHYS_SDRAM_5_SIZE);
+ gd->bd->bi_dram[5].start = PHYS_SDRAM_6;
+ gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6,
+ PHYS_SDRAM_6_SIZE);
+ gd->bd->bi_dram[6].start = PHYS_SDRAM_7;
+ gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7,
+ PHYS_SDRAM_7_SIZE);
+ gd->bd->bi_dram[7].start = PHYS_SDRAM_8;
+ gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8,
+ PHYS_SDRAM_8_SIZE);
+}
+
+static int decode_sromc(const void *blob, struct fdt_sromc *config)
+{
+ int err;
+ int node;
+
+ node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
+ if (node < 0) {
+ debug("Could not find SROMC node\n");
+ return node;
+ }
+
+ config->bank = fdtdec_get_int(blob, node, "bank", 0);
+ config->width = fdtdec_get_int(blob, node, "width", 2);
+
+ err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
+ FDT_SROM_TIMING_COUNT);
+ if (err < 0) {
+ debug("Could not decode SROMC configuration\n");
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_SMC911X
+ u32 smc_bw_conf, smc_bc_conf;
+ struct fdt_sromc config;
+ fdt_addr_t base_addr;
+ int node;
+
+ node = decode_sromc(gd->fdt_blob, &config);
+ if (node < 0) {
+ debug("%s: Could not find sromc configuration\n", __func__);
+ return 0;
+ }
+ node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
+ if (node < 0) {
+ debug("%s: Could not find lan9215 configuration\n", __func__);
+ return 0;
+ }
+
+ /* We now have a node, so any problems from now on are errors */
+ base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
+ if (base_addr == FDT_ADDR_T_NONE) {
+ debug("%s: Could not find lan9215 address\n", __func__);
+ return -1;
+ }
+
+ /* Ethernet needs data bus width of 16 bits */
+ if (config.width != 2) {
+ debug("%s: Unsupported bus width %d\n", __func__,
+ config.width);
+ return -1;
+ }
+ smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
+ | SROMC_BYTE_ENABLE(config.bank);
+
+ smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |\
+ SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
+ SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
+ SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
+ SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |\
+ SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
+ SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
+
+ /* Select and configure the SROMC bank */
+ exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
+ s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
+ return smc911x_initialize(0, base_addr);
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+ printf("\nBoard: SMDK5250\n");
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+int board_mmc_init(bd_t *bis)
+{
+ int ret = 0;
+
+ /* dwmmc initializattion for available channels */
+ ret = exynos_dwmmc_init(gd->fdt_blob);
+ if (ret)
+ debug("dwmmc init failed\n");
+
+ return ret;
+}
+#endif
+
+static int board_uart_init(void)
+{
+ int err;
+
+ err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
+ if (err) {
+ debug("UART0 not configured\n");
+ return err;
+ }
+
+ err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
+ if (err) {
+ debug("UART1 not configured\n");
+ return err;
+ }
+
+ err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
+ if (err) {
+ debug("UART2 not configured\n");
+ return err;
+ }
+
+ err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
+ if (err) {
+ debug("UART3 not configured\n");
+ return err;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+ int err;
+ err = board_uart_init();
+ if (err) {
+ debug("UART init failed\n");
+ return err;
+ }
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+ board_i2c_init(gd->fdt_blob);
+#endif
+ return err;
+}
+#endif
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c
index 73c3ec0..e0fec11 100644
--- a/board/samsung/smdk5250/smdk5250.c
+++ b/board/samsung/smdk5250/smdk5250.c
@@ -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>
@@ -95,59 +96,13 @@ void dram_init_banksize(void)
PHYS_SDRAM_8_SIZE);
}
-#ifdef CONFIG_OF_CONTROL
-static int decode_sromc(const void *blob, struct fdt_sromc *config)
-{
- int err;
- int node;
-
- node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
- if (node < 0) {
- debug("Could not find SROMC node\n");
- return node;
- }
-
- config->bank = fdtdec_get_int(blob, node, "bank", 0);
- config->width = fdtdec_get_int(blob, node, "width", 2);
-
- err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
- FDT_SROM_TIMING_COUNT);
- if (err < 0) {
- debug("Could not decode SROMC configuration\n");
- return -FDT_ERR_NOTFOUND;
- }
-
- return 0;
-}
-#endif
-
int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_SMC911X
u32 smc_bw_conf, smc_bc_conf;
struct fdt_sromc config;
fdt_addr_t base_addr;
- int node;
-
-#ifdef CONFIG_OF_CONTROL
- node = decode_sromc(gd->fdt_blob, &config);
- if (node < 0) {
- debug("%s: Could not find sromc configuration\n", __func__);
- return 0;
- }
- node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
- if (node < 0) {
- debug("%s: Could not find lan9215 configuration\n", __func__);
- return 0;
- }
- /* We now have a node, so any problems from now on are errors */
- base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
- if (base_addr == FDT_ADDR_T_NONE) {
- debug("%s: Could not find lan9215 address\n", __func__);
- return -1;
- }
-#else
/* Non-FDT configuration - bank number and timing parameters*/
config.bank = CONFIG_ENV_SROM_BANK;
config.width = 2;
@@ -160,7 +115,6 @@ int board_eth_init(bd_t *bis)
config.timing[FDT_SROM_TACP] = 0x09;
config.timing[FDT_SROM_PMC] = 0x01;
base_addr = CONFIG_SMC911X_BASE;
-#endif
/* Ethernet needs data bus width of 16 bits */
if (config.width != 2) {
@@ -199,16 +153,31 @@ int checkboard(void)
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
- int err;
+ int err = 0, ret = 0;
err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
- if (err) {
+ if (err)
debug("SDMMC0 not configured\n");
- return err;
- }
-
- err = s5p_mmc_init(0, 8);
- return err;
+ ret |= 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;
+
+ return ret;
}
#endif
@@ -243,6 +212,24 @@ static int board_uart_init(void)
return 0;
}
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+static int board_i2c_init(void)
+{
+ int i, err;
+
+ for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) {
+ err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
+ PINMUX_FLAG_NONE);
+ if (err) {
+ debug("I2C%d not configured\n", (PERIPH_ID_I2C0 + i));
+ return err;
+ }
+ }
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ return 0;
+}
+#endif
+
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
@@ -253,7 +240,7 @@ int board_early_init_f(void)
return err;
}
#ifdef CONFIG_SYS_I2C_INIT_BOARD
- board_i2c_init(gd->fdt_blob);
+ board_i2c_init();
#endif
return err;
}
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
index 59182f4..6ce73dc 100644
--- a/include/configs/exynos5250-dt.h
+++ b/include/configs/exynos5250-dt.h
@@ -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
diff --git a/include/i2c.h b/include/i2c.h
index c60d075..0944141 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -263,6 +263,7 @@ extern int get_multi_sda_pin(void);
extern int multi_i2c_init(void);
#endif
+#ifdef CONFIG_OF_CONTROL
/**
* Get FDT values for i2c bus.
*
@@ -270,6 +271,7 @@ extern int multi_i2c_init(void);
* @return the number of I2C bus
*/
void board_i2c_init(const void *blob);
+#endif
/**
* Find the I2C bus number by given a FDT I2C node.
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
` (5 preceding siblings ...)
2013-01-04 9:34 ` [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT Amar
@ 2013-01-04 9:34 ` Amar
2013-01-04 10:27 ` Jaehoon Chung
2013-01-04 9:34 ` [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to Amar
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch adds APIs to open, close and to resize boot partiton for EMMC.
Changes from V1:
New patch.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
No change.
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
drivers/mmc/mmc.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/mmc.h | 16 ++++++++
2 files changed, 134 insertions(+)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 72e8ce6..8175b49 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1327,3 +1327,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;
+}
diff --git a/include/mmc.h b/include/mmc.h
index a13e2bd..999f0a3 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -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)
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
` (6 preceding siblings ...)
2013-01-04 9:34 ` [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 16:39 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to Amar
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch adds support for EMMC booting on SMDK5250.
Changes from V1:
1)Updated spl_boot.c file to maintain irom pointer table
instead of using the #define values defined in header file.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
No change.
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
board/samsung/smdk5250/clock_init.c | 15 +++++++++++
board/samsung/smdk5250/clock_init.h | 5 ++++
board/samsung/smdk5250/spl_boot.c | 52 ++++++++++++++++++++++++++++++++-----
3 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c
index c009ae5..154993c 100644
--- a/board/samsung/smdk5250/clock_init.c
+++ b/board/samsung/smdk5250/clock_init.c
@@ -28,6 +28,7 @@
#include <asm/arch/clk.h>
#include <asm/arch/clock.h>
#include <asm/arch/spl.h>
+#include <asm/arch/dwmmc.h>
#include "clock_init.h"
#include "setup.h"
@@ -664,3 +665,17 @@ void clock_init_dp_clock(void)
/* We run DP at 267 Mhz */
setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1);
}
+
+/*
+ * Set clock divisor value for booting from EMMC.
+ * Set DWMMC channel-0 clk div to operate mmc0 device at 50MHz.
+ */
+void emmc_boot_clk_div_set(void)
+{
+ struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
+ unsigned int div_mmc;
+
+ div_mmc = readl((unsigned int) &clk->div_fsys1) & ~FSYS1_MMC0_DIV_MASK;
+ div_mmc |= FSYS1_MMC0_DIV_VAL;
+ writel(div_mmc, (unsigned int) &clk->div_fsys1);
+}
diff --git a/board/samsung/smdk5250/clock_init.h b/board/samsung/smdk5250/clock_init.h
index f751bcb..20a1d47 100644
--- a/board/samsung/smdk5250/clock_init.h
+++ b/board/samsung/smdk5250/clock_init.h
@@ -146,4 +146,9 @@ struct mem_timings *clock_get_mem_timings(void);
* Initialize clock for the device
*/
void system_clock_init(void);
+
+/*
+ * Set clock divisor value for booting from EMMC.
+ */
+void emmc_boot_clk_div_set(void);
#endif
diff --git a/board/samsung/smdk5250/spl_boot.c b/board/samsung/smdk5250/spl_boot.c
index d8f3c1e..906e197 100644
--- a/board/samsung/smdk5250/spl_boot.c
+++ b/board/samsung/smdk5250/spl_boot.c
@@ -23,16 +23,38 @@
#include<common.h>
#include<config.h>
+#include <asm/arch-exynos/dmc.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+
+#include "clock_init.h"
+
+/* Index into irom ptr table */
+enum index {
+ MMC_INDEX,
+ EMMC44_INDEX,
+ EMMC44_END_INDEX,
+ SPI_INDEX,
+};
+
+/* IROM Function Pointers Table */
+u32 irom_ptr_table[] = {
+ [MMC_INDEX] = 0x02020030, /* iROM Function Pointer-SDMMC boot */
+ [EMMC44_INDEX] = 0x02020044, /* iROM Function Pointer-EMMC4.4 boot*/
+ [EMMC44_END_INDEX] = 0x02020048,/* iROM Function Pointer
+ -EMMC4.4 end boot operation */
+ [SPI_INDEX] = 0x02020058, /* iROM Function Pointer-SPI boot */
+ };
+
enum boot_mode {
BOOT_MODE_MMC = 4,
BOOT_MODE_SERIAL = 20,
+ BOOT_MODE_EMMC = 8, /* EMMC4.4 */
/* 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);
-
/*
* Copy U-boot from mmc to RAM:
* COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
@@ -40,23 +62,39 @@ enum boot_mode {
*/
void copy_uboot_to_ram(void)
{
- spi_copy_func_t spi_copy;
enum boot_mode bootmode;
- u32 (*copy_bl2)(u32, u32, u32);
-
+ u32 (*spi_copy)(u32 offset, u32 nblock, u32 dst);
+ u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst);
+ u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
+ void (*end_bootop_from_emmc)(void);
+ /* read Operation Mode ststus register to find the bootmode */
bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
switch (bootmode) {
case BOOT_MODE_SERIAL:
- spi_copy = *(spi_copy_func_t *)EXYNOS_COPY_SPI_FNPTR_ADDR;
+ spi_copy = (void *) *(u32 *)irom_ptr_table[SPI_INDEX];
spi_copy(SPI_FLASH_UBOOT_POS, CONFIG_BL2_SIZE,
CONFIG_SYS_TEXT_BASE);
break;
case BOOT_MODE_MMC:
- copy_bl2 = (void *) *(u32 *)COPY_BL2_FNPTR_ADDR;
+ copy_bl2 = (void *) *(u32 *)irom_ptr_table[MMC_INDEX];
copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
CONFIG_SYS_TEXT_BASE);
break;
+ case BOOT_MODE_EMMC:
+ /* Set the FSYS1 clock divisor value for EMMC boot */
+ emmc_boot_clk_div_set();
+
+ copy_bl2_from_emmc =
+ (void *) *(u32 *)irom_ptr_table[EMMC44_INDEX];
+ end_bootop_from_emmc =
+ (void *) *(u32 *)irom_ptr_table[EMMC44_END_INDEX];
+
+ copy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+ end_bootop_from_emmc();
+
+ break;
+
default:
break;
}
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
` (7 preceding siblings ...)
2013-01-04 9:34 ` [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting Amar
@ 2013-01-04 9:34 ` Amar
2013-01-10 16:46 ` Simon Glass
8 siblings, 1 reply; 42+ messages in thread
From: Amar @ 2013-01-04 9:34 UTC (permalink / raw)
To: u-boot
This patch adds commands to open, close and resize boot partitions on EMMC.
Changes from V1:
1)Combined the common piece of code between 'open' and 'close'
operations.
Changes from V2:
1)Updation of commit message and resubmition of proper patch set.
Changes from V3:
No change.
Signed-off-by: Amar <amarendra.xt@samsung.com>
---
common/cmd_mmc.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 7dacd51..1dabb5b 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -248,6 +248,84 @@ 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) ||
+ (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
+ 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 (strcmp(argv[1], "open") == 0) {
+ 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"
+ " images are written\n");
+ printf("!EMMC boot partition"
+ " has continuity at"
+ " image writing time.\n");
+ printf("!So, Do not close boot"
+ " partition, Before, all"
+ " images are written.\n");
+ return 0;
+ } else {
+ printf("EMMC OPEN Failed.\n");
+ return 1;
+ }
+ }
+
+ if (strcmp(argv[1], "close") == 0) {
+ if (!(mmc_boot_close(mmc))) {
+ printf("EMMC CLOSE Success.\n");
+ return 0;
+ } else {
+ printf("EMMC CLOSE Failed.\n");
+ return 1;
+ }
+ }
+ } else if (strcmp(argv[1], "bootpart") == 0) {
+ int dev;
+ dev = simple_strtoul(argv[2], NULL, 10);
+
+ u32 bootsize = simple_strtoul(argv[3], NULL, 10);
+ u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
+ struct mmc *mmc = find_mmc_device(dev);
+ 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);
+ return 0;
+ } else {
+ printf("EMMC boot partition Size change Failed.\n");
+ return 1;
+ }
}
state = MMC_INVALID;
@@ -317,5 +395,9 @@ 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"
+ " - change sizes of boot and RPMB partions of specified device\n");
#endif
--
1.8.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition
2013-01-04 9:34 ` [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition Amar
@ 2013-01-04 10:27 ` Jaehoon Chung
2013-01-07 4:19 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-04 10:27 UTC (permalink / raw)
To: u-boot
Hi Amar,
I wonder that include the moviNAND specific code in mmc.c?
mmc_boot_partiton_size_change() looks like every vendor can use this function.
Best Regards,
Jaehoon Chung
On 01/04/2013 06:34 PM, Amar wrote:
> This patch adds APIs to open, close and to resize boot partiton for EMMC.
>
> Changes from V1:
> New patch.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> No change.
>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> drivers/mmc/mmc.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/mmc.h | 16 ++++++++
> 2 files changed, 134 insertions(+)
>
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 72e8ce6..8175b49 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -1327,3 +1327,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 at 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;
> +}
> diff --git a/include/mmc.h b/include/mmc.h
> index a13e2bd..999f0a3 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -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)
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition
2013-01-04 10:27 ` Jaehoon Chung
@ 2013-01-07 4:19 ` Amarendra Reddy
2013-01-07 4:34 ` Jaehoon Chung
0 siblings, 1 reply; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-07 4:19 UTC (permalink / raw)
To: u-boot
Hi Jaehoon,
Yes, the functions mmc_boot_partiton_size_change(), mmc_boot_open()
& mmc_boot_close() can be used
by any vendor to open/close/resize-boot-partition of emmc device.
The above 3 functions call the static function "static int
mmc_send_cmd(...)" located in drivers/mmc/mmc.c.
Any vendor can use the above 3 functions, if placed in drivers/mmc/mmc.c.
Thanks & Regards
Amarendra Reddy
On 4 January 2013 15:57, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi Amar,
>
> I wonder that include the moviNAND specific code in mmc.c?
> mmc_boot_partiton_size_change() looks like every vendor can use this
> function.
>
> Best Regards,
> Jaehoon Chung
>
> On 01/04/2013 06:34 PM, Amar wrote:
> > This patch adds APIs to open, close and to resize boot partiton for EMMC.
> >
> > Changes from V1:
> > New patch.
> >
> > Changes from V2:
> > 1)Updation of commit message and resubmition of proper patch set.
> >
> > Changes from V3:
> > No change.
> >
> > Signed-off-by: Amar <amarendra.xt@samsung.com>
> > ---
> > drivers/mmc/mmc.c | 118
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > include/mmc.h | 16 ++++++++
> > 2 files changed, 134 insertions(+)
> >
> > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> > index 72e8ce6..8175b49 100644
> > --- a/drivers/mmc/mmc.c
> > +++ b/drivers/mmc/mmc.c
> > @@ -1327,3 +1327,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 at 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;
> > +}
> > diff --git a/include/mmc.h b/include/mmc.h
> > index a13e2bd..999f0a3 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -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)
> >
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition
2013-01-07 4:19 ` Amarendra Reddy
@ 2013-01-07 4:34 ` Jaehoon Chung
2013-01-07 5:54 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-07 4:34 UTC (permalink / raw)
To: u-boot
Hi Amar,
If you want to access the boot partition, Need to add open/close()?
I think we can use like "mmc_boot_part_access(struct mmc *mmc, int ack, int part_num, int access)"
How about this? i think it is more generic...
On 01/07/2013 01:19 PM, Amarendra Reddy wrote:
> Hi Jaehoon,
>
> Yes, the functions mmc_boot_partiton_size_change(), mmc_boot_open()
> & mmc_boot_close() can be used
> by any vendor to open/close/resize-boot-partition of emmc device.
How can any vendor use with resize-boot-partition?
you used the vendor command.(you added the comment "Only use this command for raw eMMC moviNAND")
And i think good that these functions are used with cmd_mmc.
Best Regards,
Jaehoon Chung
> The above 3 functions call the static function "static int
> mmc_send_cmd(...)" located in drivers/mmc/mmc.c.
> Any vendor can use the above 3 functions, if placed in drivers/mmc/mmc.c.
>
> Thanks & Regards
> Amarendra Reddy
>
> On 4 January 2013 15:57, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>
>> Hi Amar,
>>
>> I wonder that include the moviNAND specific code in mmc.c?
>> mmc_boot_partiton_size_change() looks like every vendor can use this
>> function.
>>
>> Best Regards,
>> Jaehoon Chung
>>
>> On 01/04/2013 06:34 PM, Amar wrote:
>>> This patch adds APIs to open, close and to resize boot partiton for EMMC.
>>>
>>> Changes from V1:
>>> New patch.
>>>
>>> Changes from V2:
>>> 1)Updation of commit message and resubmition of proper patch set.
>>>
>>> Changes from V3:
>>> No change.
>>>
>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>> ---
>>> drivers/mmc/mmc.c | 118
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> include/mmc.h | 16 ++++++++
>>> 2 files changed, 134 insertions(+)
>>>
>>> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
>>> index 72e8ce6..8175b49 100644
>>> --- a/drivers/mmc/mmc.c
>>> +++ b/drivers/mmc/mmc.c
>>> @@ -1327,3 +1327,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 at 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;
>>> +}
>>> diff --git a/include/mmc.h b/include/mmc.h
>>> index a13e2bd..999f0a3 100644
>>> --- a/include/mmc.h
>>> +++ b/include/mmc.h
>>> @@ -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)
>>>
>>
>> _______________________________________________
>> 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
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition
2013-01-07 4:34 ` Jaehoon Chung
@ 2013-01-07 5:54 ` Amarendra Reddy
2013-01-07 9:23 ` Jaehoon Chung
0 siblings, 1 reply; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-07 5:54 UTC (permalink / raw)
To: u-boot
Hi Jaehoon,
The sequence to be followed to access(read/write) boot partitions is i)
open() the boot partition, ii) Do the job , iii) Then close() boot
partition.
I understand that
1) You want a single generic function "mmc_boot_part_access(struct mmc
*mmc, int ack, int part_num, int access)" to be used
instead of two functions open() and close().
2) By doing so user can specify which boot partition to be accessed (opened
/ closed).
Please comment.
Thanks & Regards
Amarendra Reddy
On 7 January 2013 10:04, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi Amar,
>
> If you want to access the boot partition, Need to add open/close()?
> I think we can use like "mmc_boot_part_access(struct mmc *mmc, int ack,
> int part_num, int access)"
> How about this? i think it is more generic...
>
> On 01/07/2013 01:19 PM, Amarendra Reddy wrote:
> > Hi Jaehoon,
> >
> > Yes, the functions mmc_boot_partiton_size_change(), mmc_boot_open()
> > & mmc_boot_close() can be used
> > by any vendor to open/close/resize-boot-partition of emmc device.
> How can any vendor use with resize-boot-partition?
> you used the vendor command.(you added the comment "Only use this command
> for raw eMMC moviNAND")
> And i think good that these functions are used with cmd_mmc.
>
> Best Regards,
> Jaehoon Chung
> > The above 3 functions call the static function "static int
> > mmc_send_cmd(...)" located in drivers/mmc/mmc.c.
> > Any vendor can use the above 3 functions, if placed in drivers/mmc/mmc.c.
> >
> > Thanks & Regards
> > Amarendra Reddy
> >
> > On 4 January 2013 15:57, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> >
> >> Hi Amar,
> >>
> >> I wonder that include the moviNAND specific code in mmc.c?
> >> mmc_boot_partiton_size_change() looks like every vendor can use this
> >> function.
> >>
> >> Best Regards,
> >> Jaehoon Chung
> >>
> >> On 01/04/2013 06:34 PM, Amar wrote:
> >>> This patch adds APIs to open, close and to resize boot partiton for
> EMMC.
> >>>
> >>> Changes from V1:
> >>> New patch.
> >>>
> >>> Changes from V2:
> >>> 1)Updation of commit message and resubmition of proper patch set.
> >>>
> >>> Changes from V3:
> >>> No change.
> >>>
> >>> Signed-off-by: Amar <amarendra.xt@samsung.com>
> >>> ---
> >>> drivers/mmc/mmc.c | 118
> >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>> include/mmc.h | 16 ++++++++
> >>> 2 files changed, 134 insertions(+)
> >>>
> >>> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> >>> index 72e8ce6..8175b49 100644
> >>> --- a/drivers/mmc/mmc.c
> >>> +++ b/drivers/mmc/mmc.c
> >>> @@ -1327,3 +1327,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 at 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;
> >>> +}
> >>> diff --git a/include/mmc.h b/include/mmc.h
> >>> index a13e2bd..999f0a3 100644
> >>> --- a/include/mmc.h
> >>> +++ b/include/mmc.h
> >>> @@ -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)
> >>>
> >>
> >> _______________________________________________
> >> 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
> >
>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition
2013-01-07 5:54 ` Amarendra Reddy
@ 2013-01-07 9:23 ` Jaehoon Chung
0 siblings, 0 replies; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-07 9:23 UTC (permalink / raw)
To: u-boot
On 01/07/2013 02:54 PM, Amarendra Reddy wrote:
> Hi Jaehoon,
>
> The sequence to be followed to access(read/write) boot partitions is i)
> open() the boot partition, ii) Do the job , iii) Then close() boot
> partition.
>
> I understand that
> 1) You want a single generic function "mmc_boot_part_access(struct mmc
> *mmc, int ack, int part_num, int access)" to be used
> instead of two functions open() and close().
> 2) By doing so user can specify which boot partition to be accessed (opened
> / closed).
It is just my suggestion..I didn't know other.
Well, I want to know Andy's opinion.
Best Regards,
Jaehoon Chung
>
> Please comment.
>
> Thanks & Regards
> Amarendra Reddy
>
>
> On 7 January 2013 10:04, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>
>> Hi Amar,
>>
>> If you want to access the boot partition, Need to add open/close()?
>> I think we can use like "mmc_boot_part_access(struct mmc *mmc, int ack,
>> int part_num, int access)"
>> How about this? i think it is more generic...
>>
>> On 01/07/2013 01:19 PM, Amarendra Reddy wrote:
>>> Hi Jaehoon,
>>>
>>> Yes, the functions mmc_boot_partiton_size_change(), mmc_boot_open()
>>> & mmc_boot_close() can be used
>>> by any vendor to open/close/resize-boot-partition of emmc device.
>> How can any vendor use with resize-boot-partition?
>> you used the vendor command.(you added the comment "Only use this command
>> for raw eMMC moviNAND")
>> And i think good that these functions are used with cmd_mmc.
>>
>> Best Regards,
>> Jaehoon Chung
>> > The above 3 functions call the static function "static int
>>> mmc_send_cmd(...)" located in drivers/mmc/mmc.c.
>>> Any vendor can use the above 3 functions, if placed in drivers/mmc/mmc.c.
>>>
>>> Thanks & Regards
>>> Amarendra Reddy
>>>
>>> On 4 January 2013 15:57, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>
>>>> Hi Amar,
>>>>
>>>> I wonder that include the moviNAND specific code in mmc.c?
>>>> mmc_boot_partiton_size_change() looks like every vendor can use this
>>>> function.
>>>>
>>>> Best Regards,
>>>> Jaehoon Chung
>>>>
>>>> On 01/04/2013 06:34 PM, Amar wrote:
>>>>> This patch adds APIs to open, close and to resize boot partiton for
>> EMMC.
>>>>>
>>>>> Changes from V1:
>>>>> New patch.
>>>>>
>>>>> Changes from V2:
>>>>> 1)Updation of commit message and resubmition of proper patch set.
>>>>>
>>>>> Changes from V3:
>>>>> No change.
>>>>>
>>>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>>>> ---
>>>>> drivers/mmc/mmc.c | 118
>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>> include/mmc.h | 16 ++++++++
>>>>> 2 files changed, 134 insertions(+)
>>>>>
>>>>> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
>>>>> index 72e8ce6..8175b49 100644
>>>>> --- a/drivers/mmc/mmc.c
>>>>> +++ b/drivers/mmc/mmc.c
>>>>> @@ -1327,3 +1327,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 at 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;
>>>>> +}
>>>>> diff --git a/include/mmc.h b/include/mmc.h
>>>>> index a13e2bd..999f0a3 100644
>>>>> --- a/include/mmc.h
>>>>> +++ b/include/mmc.h
>>>>> @@ -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)
>>>>>
>>>>
>>>> _______________________________________________
>>>> 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
>>>
>>
>>
>
>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data
2013-01-04 9:34 ` [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data Amar
@ 2013-01-10 15:21 ` Simon Glass
2013-01-15 9:11 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 15:21 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This patch adds DWMMC device node data for exynos5.
> This patch also adds binding file for DWMMC device node.
>
> Changes from V1:
> 1)Added binding file for DWMMC device node at the location
> "doc/device-tree-bindings/exynos/dwmmc.txt".
> 2)Removed the propname 'index' from device node.
> 3)Prefixed the vendor name 'samsung' before propname in device node.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> No change.
Sorry I may be too late with this comment.
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Signed-off-by: Amar <amarendra.xt@samsung.com>X
> ---
> arch/arm/dts/exynos5250.dtsi | 32 +++++++++++++++++++++++++++++++
> board/samsung/dts/exynos5250-smdk5250.dts | 22 +++++++++++++++++++++
> doc/device-tree-bindings/exynos/dwmmc.txt | 29 ++++++++++++++++++++++++++++
> 3 files changed, 83 insertions(+)
> create mode 100644 doc/device-tree-bindings/exynos/dwmmc.txt
>
> diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
> index 1008797..b701ae5 100644
> --- a/arch/arm/dts/exynos5250.dtsi
> +++ b/arch/arm/dts/exynos5250.dtsi
> @@ -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>;
> + };
> };
> diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts
> index a8e62da..9baf622 100644
> --- a/board/samsung/dts/exynos5250-smdk5250.dts
> +++ b/board/samsung/dts/exynos5250-smdk5250.dts
> @@ -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";
I think this should be mmc0, mmc1 instead of dwmmc0, dwmmc1, since
ultimate we might want to support different drivers for each. The
alias is support to link the generic mmc device number with the
driver, and I don't think the numbering should be specific to the
driver.
> };
>
> sromc at 12250000 {
> @@ -59,4 +63,22 @@
> compatible = "wolfson,wm8994-codec";
> };
> };
> +
> + dwmmc at 12200000 {
> + samsung,bus-width = <8>;
> + samsung,timing = <1 3 3>;
> + };
> +
> + dwmmc at 12210000 {
> + status = "disabled";
> + };
> +
> + dwmmc at 12220000 {
> + samsung,bus-width = <4>;
> + samsung,timing = <1 2 3>;
> + };
> +
> + dwmmc at 12230000 {
> + status = "disabled";
> + };
> };
> diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt b/doc/device-tree-bindings/exynos/dwmmc.txt
> new file mode 100644
> index 0000000..6232ad6
> --- /dev/null
> +++ b/doc/device-tree-bindings/exynos/dwmmc.txt
> @@ -0,0 +1,29 @@
> +* Exynos 5250 DWC_mobile_storage
> +
> +The Exynos 5250 provides DWC_mobile_storage interface which supports
> +. Embedded Multimedia Cards (EMMC-version 4.5)
> +. Secure Digital memory (SD mem-version 2.0)
> +. Secure Digital I/O (SDIO-version 3.0)
> +. Consumer Electronics Advanced Transport Architecture (CE-ATA-version 1.1)
> +
> +The Exynos 5250 DWC_mobile_storage provides four channels.
> +SOC specific and Board specific properties are channel specific.
> +
> +Required SoC Specific Properties:
> +
> +- compatible: should be
> + - samsung,exynos5250-dwmmc: for exynos5250 platforms
> +
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +
> +- interrupts: The interrupt number to the cpu.
> +
> +Required Board Specific Properties:
> +
> +- #address-cells: should be 1.
> +- #size-cells: should be 0.
> +- samsung,bus-width: The width of the bus used to interface the devices
> + supported by DWC_mobile_storage (SD-MMC/EMMC/SDIO).
typically 4 or 8
> +- samsung,timing: The timing values to be written into the
> + Drv/sample clock selection register of corresponding channel.
Please add a bit more detail here - there are 3 values - what do they mean?
You should add an example for your binding (something will illustrates
the binding).
Also does the kernel use the same binding?
Regards,
Simon
> --
> 1.8.0
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues
2013-01-04 9:34 ` [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues Amar
@ 2013-01-10 15:26 ` Simon Glass
2013-01-11 4:01 ` Jaehoon Chung
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 15:26 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This patch enumerates dwmci and set auto stop command during
> dwmci initialisation.
> EMMC read/write is not happening in current implementation
> due to improper fifo size computation. Hence Modified the fifo size
> computation to resolve EMMC read write issues.
>
> Changes from V1:
> 1)Created the macros RX_WMARK_SHIFT and RX_WMARK_MASK in header file.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> 1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of
> the hard coded value (1 << 10).
I suggest you take a look@patman which might simplify your patch
sending and change logs - see tools/patman/README for details.
>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> drivers/mmc/dw_mmc.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 4070d4e..776fdb6 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -136,6 +136,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> return TIMEOUT;
> }
> timeout--;
> + mdelay(1);
How long will this delay in total?
> }
>
> dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
> @@ -314,7 +315,7 @@ static void dwmci_set_ios(struct mmc *mmc)
> static int dwmci_init(struct mmc *mmc)
> {
> struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
> - u32 fifo_size, fifoth_val;
> + u32 fifo_size, fifoth_val, ier;
>
> dwmci_writel(host, DWMCI_PWREN, 1);
>
> @@ -323,6 +324,14 @@ static int dwmci_init(struct mmc *mmc)
> return -1;
> }
>
> + /* Enumerate at 400KHz */
> + dwmci_setup_bus(host, mmc->f_min);
> +
> + /* Set auto stop command */
> + ier = dwmci_readl(host, DWMCI_CTRL);
> + ier |= DWMCI_CTRL_SEND_AS_CCSD;
> + dwmci_writel(host, DWMCI_CTRL, ier);
> +
> dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
> dwmci_writel(host, DWMCI_INTMASK, 0);
>
> @@ -332,10 +341,11 @@ static int dwmci_init(struct mmc *mmc)
> dwmci_writel(host, DWMCI_BMOD, 1);
>
> fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
> + fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
> if (host->fifoth_val)
> fifoth_val = host->fifoth_val;
> else
> - fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 -1) |
> + fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 - 1) |
> TX_WMARK(fifo_size/2);
{} around this else I think. Also space around /
> dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);
>
> --
> 1.8.0
>
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-04 9:34 ` [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC Amar
@ 2013-01-10 15:33 ` Simon Glass
2013-01-11 4:12 ` Jaehoon Chung
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 15:33 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This patch adds FDT support for DWMMC, by reading the DWMMC node data
> from the device tree and initialising DWMMC channels as per data
> obtained from the node.
>
> Changes from V1:
> 1)Updated code to have same signature for the function
> exynos_dwmci_init() for both FDT and non-FDT versions.
> 2)Updated code to pass device_id parameter to the function
> exynos5_mmc_set_clk_div() instead of index.
> 3)Updated code to decode the value of "samsung,width" from FDT.
> 4)Channel index is computed instead of getting from FDT.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> 1)Replaced the new function exynos5_mmc_set_clk_div() with the
> existing function set_mmc_clk(). set_mmc_clk() will do the purpose.
> 2)Computation of FSYS block clock divisor (pre-ratio) is added.
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
> drivers/mmc/exynos_dw_mmc.c | 129 +++++++++++++++++++++++++++++--
> include/dwmmc.h | 4 +
> 3 files changed, 130 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
> index 8acdf9b..40dcc7b 100644
> --- a/arch/arm/include/asm/arch-exynos/dwmmc.h
> +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
> @@ -29,8 +29,12 @@
>
> int exynos_dwmci_init(u32 regbase, int bus_width, int index);
>
> +#ifdef CONFIG_OF_CONTROL
> +unsigned int exynos_dwmmc_init(const void *blob);
> +#else
> static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
Why unsigned?
I'm really not that keen on functions which change their signature
based on an #ifdef. Can we perhaps have
int exynos_dwmmc_init(const void *blob);
which will pass NULL when there is no FDT, and
int exynos_dwmmc_add_port(int index, int bus_width)
for use by non-FDT boards?
> {
> unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
> return exynos_dwmci_init(base, bus_width, index);
> }
> +#endif
> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
> index 72a31b7..d7ca7d0 100644
> --- a/drivers/mmc/exynos_dw_mmc.c
> +++ b/drivers/mmc/exynos_dw_mmc.c
> @@ -19,39 +19,154 @@
> */
>
> #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>
> +
> +#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
> +#define ONE_MEGA_HZ 1000000
> +#define SCALED_VAL_FOUR_HUNDRED 400
I don't think you need these last two - you can just write the number
in the code
>
> static char *EXYNOS_NAME = "EXYNOS DWMMC";
Same with this I think
> +u32 timing[3];
>
> +/*
> + * Function used as callback function to initialise the
> + * CLKSEL register for every mmc channel.
> + */
> 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)
> +{
> + return get_mmc_clk(dev_index);
> }
>
> int exynos_dwmci_init(u32 regbase, int bus_width, int index)
> {
> struct dwmci_host *host = NULL;
> + unsigned int clock, div;
> host = malloc(sizeof(struct dwmci_host));
> if (!host) {
> printf("dwmci_host malloc fail!\n");
> return 1;
> }
>
> + /*
> + * The max operating freq of FSYS block is 400MHz.
> + * Scale down the 400MHz to number 400.
> + * Scale down the MPLL clock by dividing MPLL_CLK with ONE_MEGA_HZ.
> + * Arrive at the divisor value taking 400 as the reference.
> + */
> +
> + /* get mpll clock and divide it by ONE_MEGA_HZ */
> + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
> +
> + /* Arrive at the divisor value. */
> + for (div = 0; div <= 0xf; div++) {
> + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
> + break;
> + }
What if you don't find the right divisor?
> +
> + /* set the clock divisor for mmc */
> + set_mmc_clk(index, div);
> +
> 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]));
timing should be a parameter, not a global. For the non-FDT case
perhaps you can accept NULL, meaning default? Then:
if (timing)
do the code above
else
do the code below
> +#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;
> -
> - add_dwmci(host, 52000000, 400000);
> + host->mmc_clk = exynos_dwmci_get_clk;
> + /* Add the mmc chennel to be registered with mmc core */
> + add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
Is error checking needed here?
>
> 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;
> + 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];
> +
> + if (node <= 0)
> + continue;
> +
> + /* Extract device id for each mmc channel */
> + dev_id = pinmux_decode_periph_id(blob, node);
> +
> + /* Get the bus width from the device node */
> + bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
> + if (bus_width < 0) {
<= 0? The function will return 0 if there is no property.
> + debug("DWMMC: Can't get bus-width\n");
> + return -1;
> + }
> + if (8 == bus_width)
> + flag = PINMUX_FLAG_8BIT_MODE;
> + else
> + flag = PINMUX_FLAG_NONE;
> +
> + /* config pinmux for each mmc channel */
> + err = exynos_pinmux_config(dev_id, flag);
> + if (err) {
> + debug("DWMMC not configured\n");
> + return err;
> + }
> +
> + index = dev_id - PERIPH_ID_SDMMC0;
> +
> + /* Get the base address from the device node */
> + base = fdtdec_get_addr(blob, node, "reg");
> + if (!base) {
> + debug("DWMMC: Can't get base address\n");
> + return -1;
> + }
> + /* Extract the timing info from the node */
> + err = fdtdec_get_int_array(blob, node, "samsung,timing",
> + timing, 3);
> + if (err) {
> + debug("Can't get sdr-timings for divider\n");
> + return -1;
> + }
> + /* Initialise each mmc channel */
> + err = exynos_dwmci_init(base, bus_width, index);
> + if (err) {
> + debug("Can't do dwmci init\n");
> + return -1;
> + }
> + }
> +
> + return 0;
> +}
> +#endif
> diff --git a/include/dwmmc.h b/include/dwmmc.h
> index c8b1d40..4a42849 100644
> --- a/include/dwmmc.h
> +++ b/include/dwmmc.h
> @@ -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)
> +
Remove this extra line?
>
> #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;
>
> --
> 1.8.0
>
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor
2013-01-04 9:34 ` [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor Amar
@ 2013-01-10 15:35 ` Simon Glass
2013-01-11 3:52 ` Jaehoon Chung
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 15:35 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This API computes the divisor value based on MPLL clock and
> writes it into the FSYS1 register.
>
> Changes from V1:
> 1)Updated the function exynos5_mmc_set_clk_div() to receive
> 'device_i'd as input parameter instead of 'index'.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> 1)Removed the new API exynos5_mmc_set_clk_div() from clock.c,
> because existing API set_mmc_clk() can be used to set mmc clock.
>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> arch/arm/cpu/armv7/exynos/clock.c | 4 ++--
> arch/arm/include/asm/arch-exynos/clk.h | 3 +++
> 2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
> index 973b84e..89574ba 100644
> --- a/arch/arm/cpu/armv7/exynos/clock.c
> +++ b/arch/arm/cpu/armv7/exynos/clock.c
> @@ -490,7 +490,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;
Is this fixing a warning?
>
> sel = readl(&clk->src_fsys);
> sel = (sel >> (dev_index << 2)) & 0xf;
> @@ -539,7 +539,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;
> diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
> index 1935b0b..a4d5b4e 100644
> --- a/arch/arm/include/asm/arch-exynos/clk.h
> +++ b/arch/arm/include/asm/arch-exynos/clk.h
> @@ -29,6 +29,9 @@
> #define VPLL 4
> #define BPLL 5
>
> +#define FSYS1_MMC0_DIV_MASK 0xff0f
> +#define FSYS1_MMC0_DIV_VAL 0x0701
What is this used for? I don't see it in this patch.
Overall it is not clear what this patch is for.
> +
> unsigned long get_pll_clk(int pllreg);
> unsigned long get_arm_clk(void);
> unsigned long get_i2c_clk(void);
> --
> 1.8.0
>
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting
2013-01-04 9:34 ` [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting Amar
@ 2013-01-10 16:39 ` Simon Glass
2013-01-15 9:14 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 16:39 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This patch adds support for EMMC booting on SMDK5250.
>
> Changes from V1:
> 1)Updated spl_boot.c file to maintain irom pointer table
> instead of using the #define values defined in header file.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> No change.
>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> board/samsung/smdk5250/clock_init.c | 15 +++++++++++
> board/samsung/smdk5250/clock_init.h | 5 ++++
> board/samsung/smdk5250/spl_boot.c | 52 ++++++++++++++++++++++++++++++++-----
> 3 files changed, 65 insertions(+), 7 deletions(-)
>
> diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c
> index c009ae5..154993c 100644
> --- a/board/samsung/smdk5250/clock_init.c
> +++ b/board/samsung/smdk5250/clock_init.c
> @@ -28,6 +28,7 @@
> #include <asm/arch/clk.h>
> #include <asm/arch/clock.h>
> #include <asm/arch/spl.h>
> +#include <asm/arch/dwmmc.h>
>
> #include "clock_init.h"
> #include "setup.h"
> @@ -664,3 +665,17 @@ void clock_init_dp_clock(void)
> /* We run DP at 267 Mhz */
> setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1);
> }
> +
> +/*
> + * Set clock divisor value for booting from EMMC.
> + * Set DWMMC channel-0 clk div to operate mmc0 device at 50MHz.
> + */
> +void emmc_boot_clk_div_set(void)
> +{
> + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
> + unsigned int div_mmc;
> +
> + div_mmc = readl((unsigned int) &clk->div_fsys1) & ~FSYS1_MMC0_DIV_MASK;
> + div_mmc |= FSYS1_MMC0_DIV_VAL;
> + writel(div_mmc, (unsigned int) &clk->div_fsys1);
> +}
> diff --git a/board/samsung/smdk5250/clock_init.h b/board/samsung/smdk5250/clock_init.h
> index f751bcb..20a1d47 100644
> --- a/board/samsung/smdk5250/clock_init.h
> +++ b/board/samsung/smdk5250/clock_init.h
> @@ -146,4 +146,9 @@ struct mem_timings *clock_get_mem_timings(void);
> * Initialize clock for the device
> */
> void system_clock_init(void);
> +
> +/*
> + * Set clock divisor value for booting from EMMC.
> + */
> +void emmc_boot_clk_div_set(void);
> #endif
> diff --git a/board/samsung/smdk5250/spl_boot.c b/board/samsung/smdk5250/spl_boot.c
> index d8f3c1e..906e197 100644
> --- a/board/samsung/smdk5250/spl_boot.c
> +++ b/board/samsung/smdk5250/spl_boot.c
> @@ -23,16 +23,38 @@
> #include<common.h>
> #include<config.h>
>
> +#include <asm/arch-exynos/dmc.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/clk.h>
> +
> +#include "clock_init.h"
> +
> +/* Index into irom ptr table */
> +enum index {
> + MMC_INDEX,
> + EMMC44_INDEX,
> + EMMC44_END_INDEX,
> + SPI_INDEX,
> +};
> +
> +/* IROM Function Pointers Table */
> +u32 irom_ptr_table[] = {
> + [MMC_INDEX] = 0x02020030, /* iROM Function Pointer-SDMMC boot */
> + [EMMC44_INDEX] = 0x02020044, /* iROM Function Pointer-EMMC4.4 boot*/
> + [EMMC44_END_INDEX] = 0x02020048,/* iROM Function Pointer
> + -EMMC4.4 end boot operation */
> + [SPI_INDEX] = 0x02020058, /* iROM Function Pointer-SPI boot */
> + };
> +
> enum boot_mode {
> BOOT_MODE_MMC = 4,
> BOOT_MODE_SERIAL = 20,
> + BOOT_MODE_EMMC = 8, /* EMMC4.4 */
> /* 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);
> -
> /*
> * Copy U-boot from mmc to RAM:
> * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
> @@ -40,23 +62,39 @@ enum boot_mode {
> */
> void copy_uboot_to_ram(void)
> {
> - spi_copy_func_t spi_copy;
> enum boot_mode bootmode;
> - u32 (*copy_bl2)(u32, u32, u32);
> -
> + u32 (*spi_copy)(u32 offset, u32 nblock, u32 dst);
> + u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst);
> + u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
> + void (*end_bootop_from_emmc)(void);
> + /* read Operation Mode ststus register to find the bootmode */
> bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
>
> switch (bootmode) {
> case BOOT_MODE_SERIAL:
> - spi_copy = *(spi_copy_func_t *)EXYNOS_COPY_SPI_FNPTR_ADDR;
> + spi_copy = (void *) *(u32 *)irom_ptr_table[SPI_INDEX];
This looks OK to me. My only suggestion is to put the lookup in a function like:
static void *get_irom_func(int index)
and avoid all the casting here.
> spi_copy(SPI_FLASH_UBOOT_POS, CONFIG_BL2_SIZE,
> CONFIG_SYS_TEXT_BASE);
> break;
Re SPI, the IROM performance is quite slow - do you plan to send up
the U-Boot SPI code version? with a 32KB SPL there might be room to
just use the normal driver.
> case BOOT_MODE_MMC:
> - copy_bl2 = (void *) *(u32 *)COPY_BL2_FNPTR_ADDR;
> + copy_bl2 = (void *) *(u32 *)irom_ptr_table[MMC_INDEX];
> copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
> CONFIG_SYS_TEXT_BASE);
> break;
> + case BOOT_MODE_EMMC:
> + /* Set the FSYS1 clock divisor value for EMMC boot */
> + emmc_boot_clk_div_set();
> +
> + copy_bl2_from_emmc =
> + (void *) *(u32 *)irom_ptr_table[EMMC44_INDEX];
> + end_bootop_from_emmc =
> + (void *) *(u32 *)irom_ptr_table[EMMC44_END_INDEX];
> +
> + copy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
> + end_bootop_from_emmc();
> +
> + break;
> +
> default:
> break;
> }
> --
> 1.8.0
>
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to
2013-01-04 9:34 ` [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to Amar
@ 2013-01-10 16:46 ` Simon Glass
2013-01-11 3:54 ` Jaehoon Chung
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 16:46 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This patch adds commands to open, close and resize boot partitions on EMMC.
>
> Changes from V1:
> 1)Combined the common piece of code between 'open' and 'close'
> operations.
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> No change.
>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> common/cmd_mmc.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 83 insertions(+), 1 deletion(-)
>
> diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
> index 7dacd51..1dabb5b 100644
> --- a/common/cmd_mmc.c
> +++ b/common/cmd_mmc.c
> @@ -248,6 +248,84 @@ 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) ||
> + (strcmp(argv[1], "close") == 0)) {
How about putting this block in its own function?
> + int dev;
> + struct mmc *mmc;
> +
> + if (argc == 2)
> + dev = curr_device;
> + else if (argc == 3)
> + dev = simple_strtoul(argv[2], NULL, 10);
> + 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 (strcmp(argv[1], "open") == 0) {
> + 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"
> + " images are written\n");
Do you need to split these strings so much? Perhaps when it is in a
function the indenting will be less?
> + printf("!EMMC boot partition"
> + " has continuity at"
> + " image writing time.\n");
> + printf("!So, Do not close boot"
> + " partition, Before, all"
> + " images are written.\n");
> + return 0;
> + } else {
> + printf("EMMC OPEN Failed.\n");
> + return 1;
You could put this above the other block and reduce indenting:
if (mmc_boot_open(mmc)) {
printf("EMMC OPEN Failed.\n");
return 1;
}
...code continues
> + }
> + }
> +
> + if (strcmp(argv[1], "close") == 0) {
> + if (!(mmc_boot_close(mmc))) {
> + printf("EMMC CLOSE Success.\n");
Shouldn't print a message on success
> + return 0;
> + } else {
> + printf("EMMC CLOSE Failed.\n");
> + return 1;
> + }
> + }
> + } else if (strcmp(argv[1], "bootpart") == 0) {
> + int dev;
> + dev = simple_strtoul(argv[2], NULL, 10);
> +
> + u32 bootsize = simple_strtoul(argv[3], NULL, 10);
> + u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
> + struct mmc *mmc = find_mmc_device(dev);
> + 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);
> + return 0;
> + } else {
> + printf("EMMC boot partition Size change Failed.\n");
> + return 1;
> + }
> }
>
> state = MMC_INVALID;
> @@ -317,5 +395,9 @@ 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"
> + " - change sizes of boot and RPMB partions of specified device\n");
> #endif
Also did you see Wolfgang's suggestion that we put the partition stuff
in the 'part' command (at least that's what I think he said). You
could have 'part open', 'part close' and maybe 'part resize'?
Regards,
Simon
> --
> 1.8.0
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
2013-01-04 9:34 ` [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT Amar
@ 2013-01-10 16:57 ` Simon Glass
2013-01-11 17:58 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-10 16:57 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> This patch enables and initialises DWMMC for SMDK5250.
> Supports both FDT and non-FDT. This patch creates a new file
> 'exynos5-dt.c' meant for FDT support.
> exynos5-dt.c: This file shall contain all code which supports FDT.
> Any addition of FDT support for any module needs to be
> added in this file.
> smdk5250.c: This file shall contain the code which supports non-FDT.
> version. Any addition of non-FDT support for any module
> needs to be added in this file.
> May be, the file smdk5250.c can be removed in near future
> when non-FDT is not required.
>
> The Makefile is updated to compile only one of the files
> exynos5-dt.c / smdk5250.c based on FDT configuration.
>
> NOTE:
> Please note that all additions corresponding to FDT need to be added into the
> file exynos5-dt.c.
> At same time if non-FDT support is required then add the corresponding
> updations into smdk5250.c.
>
> Changes from V1:
> 1)A new file 'exynos5-dt.c' is created meant for FDT support
> 2)Makefile is updated to compile only one of the files
> exynos5-dt.c / smdk5250.c based on FDT configuration
>
> Changes from V2:
> 1)Updation of commit message and resubmition of proper patch set.
>
> Changes from V3:
> No change.
>
> Signed-off-by: Amar <amarendra.xt@samsung.com>
> ---
> board/samsung/smdk5250/Makefile | 4 +
> board/samsung/smdk5250/exynos5-dt.c | 242 ++++++++++++++++++++++++++++++++++++
> board/samsung/smdk5250/smdk5250.c | 97 +++++++--------
> include/configs/exynos5250-dt.h | 2 +
> include/i2c.h | 2 +
> 5 files changed, 292 insertions(+), 55 deletions(-)
> create mode 100644 board/samsung/smdk5250/exynos5-dt.c
>
> diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile
> index 47c6a5a..ecca9f3 100644
> --- a/board/samsung/smdk5250/Makefile
> +++ b/board/samsung/smdk5250/Makefile
> @@ -32,8 +32,12 @@ COBJS += tzpc_init.o
> COBJS += smdk5250_spl.o
>
> ifndef CONFIG_SPL_BUILD
> +ifdef CONFIG_OF_CONTROL
> +COBJS += exynos5-dt.o
> +else
> COBJS += smdk5250.o
> endif
> +endif
>
> ifdef CONFIG_SPL_BUILD
> COBJS += spl_boot.o
> diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c
> new file mode 100644
> index 0000000..da539ca
> --- /dev/null
> +++ b/board/samsung/smdk5250/exynos5-dt.c
> @@ -0,0 +1,242 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <fdtdec.h>
> +#include <asm/io.h>
> +#include <i2c.h>
> +#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>
> +#include <asm/arch/sromc.h>
> +#include <power/pmic.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int board_init(void)
> +{
> + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
> +#ifdef CONFIG_EXYNOS_SPI
> + spi_init();
> +#endif
> + return 0;
> +}
> +
> +int dram_init(void)
> +{
> + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_7_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_7_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE)
> + + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE);
This looks ugly - is there any other way of doing this? Also 7 appears
in more than one line.
Since the banks are all SDRAM_BANK_SIZE apart, perhaps you could just
use a for loop with a single base address?
If this function is common with the other file then perhaps it should
go in a common file?
> + return 0;
> +}
> +
> +#if defined(CONFIG_POWER)
> +int power_init_board(void)
> +{
> + if (pmic_init(I2C_PMIC))
debug()
> + return -1;
> + else
> + return 0;
> +}
> +#endif
> +
> +void dram_init_banksize(void)
> +{
> + gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
> + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
> + PHYS_SDRAM_1_SIZE);
> + gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
> + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
> + PHYS_SDRAM_2_SIZE);
> + gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
> + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
> + PHYS_SDRAM_3_SIZE);
> + gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
> + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
> + PHYS_SDRAM_4_SIZE);
> + gd->bd->bi_dram[4].start = PHYS_SDRAM_5;
> + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5,
> + PHYS_SDRAM_5_SIZE);
> + gd->bd->bi_dram[5].start = PHYS_SDRAM_6;
> + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6,
> + PHYS_SDRAM_6_SIZE);
> + gd->bd->bi_dram[6].start = PHYS_SDRAM_7;
> + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7,
> + PHYS_SDRAM_7_SIZE);
> + gd->bd->bi_dram[7].start = PHYS_SDRAM_8;
> + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8,
> + PHYS_SDRAM_8_SIZE);
and here
> +}
> +
> +static int decode_sromc(const void *blob, struct fdt_sromc *config)
> +{
> + int err;
> + int node;
> +
> + node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
> + if (node < 0) {
> + debug("Could not find SROMC node\n");
> + return node;
> + }
> +
> + config->bank = fdtdec_get_int(blob, node, "bank", 0);
> + config->width = fdtdec_get_int(blob, node, "width", 2);
> +
> + err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
> + FDT_SROM_TIMING_COUNT);
> + if (err < 0) {
> + debug("Could not decode SROMC configuration\n");
Suggest:
debug("Could not decode SROMC configuration: %s\n", fdt_strerror(err));
> + return -FDT_ERR_NOTFOUND;
return err? Or the caller might just want -1
> + }
> +
> + return 0;
> +}
> +
> +int board_eth_init(bd_t *bis)
> +{
> +#ifdef CONFIG_SMC911X
> + u32 smc_bw_conf, smc_bc_conf;
> + struct fdt_sromc config;
> + fdt_addr_t base_addr;
> + int node;
> +
> + node = decode_sromc(gd->fdt_blob, &config);
> + if (node < 0) {
> + debug("%s: Could not find sromc configuration\n", __func__);
> + return 0;
> + }
> + node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
> + if (node < 0) {
> + debug("%s: Could not find lan9215 configuration\n", __func__);
> + return 0;
> + }
> +
> + /* We now have a node, so any problems from now on are errors */
> + base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
> + if (base_addr == FDT_ADDR_T_NONE) {
> + debug("%s: Could not find lan9215 address\n", __func__);
> + return -1;
> + }
> +
> + /* Ethernet needs data bus width of 16 bits */
> + if (config.width != 2) {
> + debug("%s: Unsupported bus width %d\n", __func__,
> + config.width);
> + return -1;
> + }
> + smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
> + | SROMC_BYTE_ENABLE(config.bank);
> +
> + smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |\
Can you remove the \ from each line?
> + SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
> + SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
> + SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
> + SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |\
> + SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
> + SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
> +
> + /* Select and configure the SROMC bank */
> + exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
> + s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
> + return smc911x_initialize(0, base_addr);
> +#endif
> + return 0;
> +}
> +
> +#ifdef CONFIG_DISPLAY_BOARDINFO
> +int checkboard(void)
> +{
> + printf("\nBoard: SMDK5250\n");
> +
> + return 0;
> +}
> +#endif
> +
> +#ifdef CONFIG_GENERIC_MMC
> +int board_mmc_init(bd_t *bis)
> +{
> + int ret = 0;
Remove =0
> +
> + /* dwmmc initializattion for available channels */
> + ret = exynos_dwmmc_init(gd->fdt_blob);
> + if (ret)
> + debug("dwmmc init failed\n");
> +
> + return ret;
> +}
> +#endif
> +
> +static int board_uart_init(void)
> +{
> + int err;
> +
> + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
> + if (err) {
> + debug("UART0 not configured\n");
> + return err;
> + }
> +
> + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
> + if (err) {
> + debug("UART1 not configured\n");
> + return err;
> + }
> +
> + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
> + if (err) {
> + debug("UART2 not configured\n");
> + return err;
> + }
> +
> + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
> + if (err) {
> + debug("UART3 not configured\n");
> + return err;
> + }
Loop for this?
> +
> + return 0;
> +}
> +
> +#ifdef CONFIG_BOARD_EARLY_INIT_F
> +int board_early_init_f(void)
> +{
> + int err;
blank line
> + err = board_uart_init();
> + if (err) {
> + debug("UART init failed\n");
> + return err;
> + }
> +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> + board_i2c_init(gd->fdt_blob);
> +#endif
> + return err;
> +}
> +#endif
> diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c
> index 73c3ec0..e0fec11 100644
> --- a/board/samsung/smdk5250/smdk5250.c
> +++ b/board/samsung/smdk5250/smdk5250.c
> @@ -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>
> @@ -95,59 +96,13 @@ void dram_init_banksize(void)
> PHYS_SDRAM_8_SIZE);
> }
>
> -#ifdef CONFIG_OF_CONTROL
> -static int decode_sromc(const void *blob, struct fdt_sromc *config)
> -{
> - int err;
> - int node;
> -
> - node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
> - if (node < 0) {
> - debug("Could not find SROMC node\n");
> - return node;
> - }
> -
> - config->bank = fdtdec_get_int(blob, node, "bank", 0);
> - config->width = fdtdec_get_int(blob, node, "width", 2);
> -
> - err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
> - FDT_SROM_TIMING_COUNT);
> - if (err < 0) {
> - debug("Could not decode SROMC configuration\n");
> - return -FDT_ERR_NOTFOUND;
> - }
> -
> - return 0;
> -}
> -#endif
> -
> int board_eth_init(bd_t *bis)
> {
> #ifdef CONFIG_SMC911X
> u32 smc_bw_conf, smc_bc_conf;
> struct fdt_sromc config;
> fdt_addr_t base_addr;
> - int node;
> -
> -#ifdef CONFIG_OF_CONTROL
> - node = decode_sromc(gd->fdt_blob, &config);
> - if (node < 0) {
> - debug("%s: Could not find sromc configuration\n", __func__);
> - return 0;
> - }
> - node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
> - if (node < 0) {
> - debug("%s: Could not find lan9215 configuration\n", __func__);
> - return 0;
> - }
>
> - /* We now have a node, so any problems from now on are errors */
> - base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
> - if (base_addr == FDT_ADDR_T_NONE) {
> - debug("%s: Could not find lan9215 address\n", __func__);
> - return -1;
> - }
> -#else
> /* Non-FDT configuration - bank number and timing parameters*/
> config.bank = CONFIG_ENV_SROM_BANK;
> config.width = 2;
> @@ -160,7 +115,6 @@ int board_eth_init(bd_t *bis)
> config.timing[FDT_SROM_TACP] = 0x09;
> config.timing[FDT_SROM_PMC] = 0x01;
> base_addr = CONFIG_SMC911X_BASE;
> -#endif
>
> /* Ethernet needs data bus width of 16 bits */
> if (config.width != 2) {
> @@ -199,16 +153,31 @@ int checkboard(void)
> #ifdef CONFIG_GENERIC_MMC
> int board_mmc_init(bd_t *bis)
> {
> - int err;
> + int err = 0, ret = 0;
>
> err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
> - if (err) {
> + if (err)
> debug("SDMMC0 not configured\n");
> - return err;
> - }
> -
> - err = s5p_mmc_init(0, 8);
> - return err;
> + ret |= err;
> +
> + /*EMMC: dwmmc Channel-0 with 8 bit bus width */
> + err = exynos_dwmmc_init(0, 8);
This is not really init of the whole dwmmc, only a port - suggest
exynos_dwmmc_add_port() or similar
> + 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;
> +
> + return ret;
> }
> #endif
>
> @@ -243,6 +212,24 @@ static int board_uart_init(void)
> return 0;
> }
>
> +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> +static int board_i2c_init(void)
> +{
> + int i, err;
> +
> + for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) {
> + err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
> + PINMUX_FLAG_NONE);
> + if (err) {
> + debug("I2C%d not configured\n", (PERIPH_ID_I2C0 + i));
> + return err;
> + }
> + }
> + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> + return 0;
> +}
> +#endif
> +
> #ifdef CONFIG_BOARD_EARLY_INIT_F
> int board_early_init_f(void)
> {
> @@ -253,7 +240,7 @@ int board_early_init_f(void)
> return err;
> }
> #ifdef CONFIG_SYS_I2C_INIT_BOARD
> - board_i2c_init(gd->fdt_blob);
> + board_i2c_init();
> #endif
> return err;
> }
> diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
> index 59182f4..6ce73dc 100644
> --- a/include/configs/exynos5250-dt.h
> +++ b/include/configs/exynos5250-dt.h
> @@ -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
>
> diff --git a/include/i2c.h b/include/i2c.h
> index c60d075..0944141 100644
> --- a/include/i2c.h
> +++ b/include/i2c.h
> @@ -263,6 +263,7 @@ extern int get_multi_sda_pin(void);
> extern int multi_i2c_init(void);
> #endif
>
> +#ifdef CONFIG_OF_CONTROL
> /**
> * Get FDT values for i2c bus.
> *
> @@ -270,6 +271,7 @@ extern int multi_i2c_init(void);
> * @return the number of I2C bus
> */
> void board_i2c_init(const void *blob);
> +#endif
Do you need this #ifdef? It would be better to avoid having the same
function with a different signature.
>
> /**
> * Find the I2C bus number by given a FDT I2C node.
> --
> 1.8.0
>
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor
2013-01-10 15:35 ` Simon Glass
@ 2013-01-11 3:52 ` Jaehoon Chung
2013-01-11 13:23 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-11 3:52 UTC (permalink / raw)
To: u-boot
On 01/11/2013 12:35 AM, Simon Glass wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> This API computes the divisor value based on MPLL clock and
>> writes it into the FSYS1 register.
>>
>> Changes from V1:
>> 1)Updated the function exynos5_mmc_set_clk_div() to receive
>> 'device_i'd as input parameter instead of 'index'.
>>
>> Changes from V2:
>> 1)Updation of commit message and resubmition of proper patch set.
>>
>> Changes from V3:
>> 1)Removed the new API exynos5_mmc_set_clk_div() from clock.c,
>> because existing API set_mmc_clk() can be used to set mmc clock.
>>
>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>> ---
>> arch/arm/cpu/armv7/exynos/clock.c | 4 ++--
>> arch/arm/include/asm/arch-exynos/clk.h | 3 +++
>> 2 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c
>> index 973b84e..89574ba 100644
>> --- a/arch/arm/cpu/armv7/exynos/clock.c
>> +++ b/arch/arm/cpu/armv7/exynos/clock.c
>> @@ -490,7 +490,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;
>
> Is this fixing a warning?
Maybe..fix the compiler warning..
>
>>
>> sel = readl(&clk->src_fsys);
>> sel = (sel >> (dev_index << 2)) & 0xf;
>> @@ -539,7 +539,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;
>> diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h
>> index 1935b0b..a4d5b4e 100644
>> --- a/arch/arm/include/asm/arch-exynos/clk.h
>> +++ b/arch/arm/include/asm/arch-exynos/clk.h
>> @@ -29,6 +29,9 @@
>> #define VPLL 4
>> #define BPLL 5
>>
>> +#define FSYS1_MMC0_DIV_MASK 0xff0f
>> +#define FSYS1_MMC0_DIV_VAL 0x0701
>
> What is this used for? I don't see it in this patch.
>
> Overall it is not clear what this patch is for.
This define didn't need. That value is not static value, isn't?
Best Regards,
Jaehoon Chung
>
>> +
>> unsigned long get_pll_clk(int pllreg);
>> unsigned long get_arm_clk(void);
>> unsigned long get_i2c_clk(void);
>> --
>> 1.8.0
>>
>
> Regards,
> Simon
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to
2013-01-10 16:46 ` Simon Glass
@ 2013-01-11 3:54 ` Jaehoon Chung
2013-01-11 5:41 ` Simon Glass
0 siblings, 1 reply; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-11 3:54 UTC (permalink / raw)
To: u-boot
On 01/11/2013 01:46 AM, Simon Glass wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> This patch adds commands to open, close and resize boot partitions on EMMC.
>>
>> Changes from V1:
>> 1)Combined the common piece of code between 'open' and 'close'
>> operations.
>>
>> Changes from V2:
>> 1)Updation of commit message and resubmition of proper patch set.
>>
>> Changes from V3:
>> No change.
>>
>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>> ---
>> common/cmd_mmc.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 83 insertions(+), 1 deletion(-)
>>
>> diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
>> index 7dacd51..1dabb5b 100644
>> --- a/common/cmd_mmc.c
>> +++ b/common/cmd_mmc.c
>> @@ -248,6 +248,84 @@ 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) ||
>> + (strcmp(argv[1], "close") == 0)) {
>
> How about putting this block in its own function?
>
>> + int dev;
>> + struct mmc *mmc;
>> +
>> + if (argc == 2)
>> + dev = curr_device;
>> + else if (argc == 3)
>> + dev = simple_strtoul(argv[2], NULL, 10);
>> + 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 (strcmp(argv[1], "open") == 0) {
>> + 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"
>> + " images are written\n");
>
> Do you need to split these strings so much? Perhaps when it is in a
> function the indenting will be less?
>
>> + printf("!EMMC boot partition"
>> + " has continuity at"
>> + " image writing time.\n");
>> + printf("!So, Do not close boot"
>> + " partition, Before, all"
>> + " images are written.\n");
>> + return 0;
>> + } else {
>> + printf("EMMC OPEN Failed.\n");
>> + return 1;
>
> You could put this above the other block and reduce indenting:
>
> if (mmc_boot_open(mmc)) {
> printf("EMMC OPEN Failed.\n");
> return 1;
> }
> ...code continues
>
>> + }
>> + }
>> +
>> + if (strcmp(argv[1], "close") == 0) {
>> + if (!(mmc_boot_close(mmc))) {
>> + printf("EMMC CLOSE Success.\n");
>
> Shouldn't print a message on success
>
>> + return 0;
>> + } else {
>> + printf("EMMC CLOSE Failed.\n");
>> + return 1;
>> + }
>> + }
>> + } else if (strcmp(argv[1], "bootpart") == 0) {
>> + int dev;
>> + dev = simple_strtoul(argv[2], NULL, 10);
>> +
>> + u32 bootsize = simple_strtoul(argv[3], NULL, 10);
>> + u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
>> + struct mmc *mmc = find_mmc_device(dev);
>> + 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);
>> + return 0;
>> + } else {
>> + printf("EMMC boot partition Size change Failed.\n");
>> + return 1;
>> + }
>> }
>>
>> state = MMC_INVALID;
>> @@ -317,5 +395,9 @@ 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"
>> + " - change sizes of boot and RPMB partions of specified device\n");
>> #endif
>
> Also did you see Wolfgang's suggestion that we put the partition stuff
> in the 'part' command (at least that's what I think he said). You
> could have 'part open', 'part close' and maybe 'part resize'?
How about using "mmc bootpart <device_num> <ack> <enable> <access>"
Also i think that we can reduce the code line.
Best Regards,
Jaehoon Chung
>
> Regards,
> Simon
>
>> --
>> 1.8.0
>>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues
2013-01-10 15:26 ` Simon Glass
@ 2013-01-11 4:01 ` Jaehoon Chung
2013-01-11 5:43 ` Simon Glass
2013-01-15 8:26 ` Amarendra Reddy
0 siblings, 2 replies; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-11 4:01 UTC (permalink / raw)
To: u-boot
On 01/11/2013 12:26 AM, Simon Glass wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> This patch enumerates dwmci and set auto stop command during
>> dwmci initialisation.
>> EMMC read/write is not happening in current implementation
>> due to improper fifo size computation. Hence Modified the fifo size
>> computation to resolve EMMC read write issues.
>>
>> Changes from V1:
>> 1)Created the macros RX_WMARK_SHIFT and RX_WMARK_MASK in header file.
>>
>> Changes from V2:
>> 1)Updation of commit message and resubmition of proper patch set.
>>
>> Changes from V3:
>> 1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of
>> the hard coded value (1 << 10).
>
> I suggest you take a look at patman which might simplify your patch
> sending and change logs - see tools/patman/README for details.
>
>>
>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>> ---
>> drivers/mmc/dw_mmc.c | 14 ++++++++++++--
>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>> index 4070d4e..776fdb6 100644
>> --- a/drivers/mmc/dw_mmc.c
>> +++ b/drivers/mmc/dw_mmc.c
>> @@ -136,6 +136,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>> return TIMEOUT;
>> }
>> timeout--;
>> + mdelay(1);
>
> How long will this delay in total?
i didn't sure why add the mdelay(1)..i think mdelay(1) is too long.
Isn't there other approach to resolve read/write issue?
Best Regards,
Jaehoon Chung
>
>> }
>>
>> dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
>> @@ -314,7 +315,7 @@ static void dwmci_set_ios(struct mmc *mmc)
>> static int dwmci_init(struct mmc *mmc)
>> {
>> struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
>> - u32 fifo_size, fifoth_val;
>> + u32 fifo_size, fifoth_val, ier;
>>
>> dwmci_writel(host, DWMCI_PWREN, 1);
>>
>> @@ -323,6 +324,14 @@ static int dwmci_init(struct mmc *mmc)
>> return -1;
>> }
>>
>> + /* Enumerate at 400KHz */
>> + dwmci_setup_bus(host, mmc->f_min);
>> +
>> + /* Set auto stop command */
>> + ier = dwmci_readl(host, DWMCI_CTRL);
>> + ier |= DWMCI_CTRL_SEND_AS_CCSD;
>> + dwmci_writel(host, DWMCI_CTRL, ier);
>> +
>> dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
>> dwmci_writel(host, DWMCI_INTMASK, 0);
>>
>> @@ -332,10 +341,11 @@ static int dwmci_init(struct mmc *mmc)
>> dwmci_writel(host, DWMCI_BMOD, 1);
>>
>> fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
>> + fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
>> if (host->fifoth_val)
>> fifoth_val = host->fifoth_val;
>> else
>> - fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 -1) |
>> + fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 - 1) |
>> TX_WMARK(fifo_size/2);
>
> {} around this else I think. Also space around /
>
>> dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);
>>
>> --
>> 1.8.0
>>
>
> Regards,
> Simon
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-10 15:33 ` Simon Glass
@ 2013-01-11 4:12 ` Jaehoon Chung
2013-01-11 5:44 ` Simon Glass
0 siblings, 1 reply; 42+ messages in thread
From: Jaehoon Chung @ 2013-01-11 4:12 UTC (permalink / raw)
To: u-boot
On 01/11/2013 12:33 AM, Simon Glass wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> This patch adds FDT support for DWMMC, by reading the DWMMC node data
>> from the device tree and initialising DWMMC channels as per data
>> obtained from the node.
>>
>> Changes from V1:
>> 1)Updated code to have same signature for the function
>> exynos_dwmci_init() for both FDT and non-FDT versions.
>> 2)Updated code to pass device_id parameter to the function
>> exynos5_mmc_set_clk_div() instead of index.
>> 3)Updated code to decode the value of "samsung,width" from FDT.
>> 4)Channel index is computed instead of getting from FDT.
>>
>> Changes from V2:
>> 1)Updation of commit message and resubmition of proper patch set.
>>
>> Changes from V3:
>> 1)Replaced the new function exynos5_mmc_set_clk_div() with the
>> existing function set_mmc_clk(). set_mmc_clk() will do the purpose.
>> 2)Computation of FSYS block clock divisor (pre-ratio) is added.
>>
>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>> ---
>> arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
>> drivers/mmc/exynos_dw_mmc.c | 129 +++++++++++++++++++++++++++++--
>> include/dwmmc.h | 4 +
>> 3 files changed, 130 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
>> index 8acdf9b..40dcc7b 100644
>> --- a/arch/arm/include/asm/arch-exynos/dwmmc.h
>> +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
>> @@ -29,8 +29,12 @@
>>
>> int exynos_dwmci_init(u32 regbase, int bus_width, int index);
>>
>> +#ifdef CONFIG_OF_CONTROL
>> +unsigned int exynos_dwmmc_init(const void *blob);
>> +#else
>> static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
>
> Why unsigned?
>
> I'm really not that keen on functions which change their signature
> based on an #ifdef. Can we perhaps have
>
> int exynos_dwmmc_init(const void *blob);
>
> which will pass NULL when there is no FDT, and
>
> int exynos_dwmmc_add_port(int index, int bus_width)
>
> for use by non-FDT boards?
>
>> {
>> unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
>> return exynos_dwmci_init(base, bus_width, index);
>> }
>> +#endif
>> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
>> index 72a31b7..d7ca7d0 100644
>> --- a/drivers/mmc/exynos_dw_mmc.c
>> +++ b/drivers/mmc/exynos_dw_mmc.c
>> @@ -19,39 +19,154 @@
>> */
>>
>> #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>
>> +
>> +#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
>> +#define ONE_MEGA_HZ 1000000
>> +#define SCALED_VAL_FOUR_HUNDRED 400
>
> I don't think you need these last two - you can just write the number
> in the code
Why didn't add into the dwmmc.h?
>
>>
>> static char *EXYNOS_NAME = "EXYNOS DWMMC";
>
> Same with this I think
Sorry..What means? Also need not?
>
>> +u32 timing[3];
>>
>> +/*
>> + * Function used as callback function to initialise the
>> + * CLKSEL register for every mmc channel.
>> + */
>> 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)
>> +{
>> + return get_mmc_clk(dev_index);
>> }
>>
>> int exynos_dwmci_init(u32 regbase, int bus_width, int index)
>> {
>> struct dwmci_host *host = NULL;
>> + unsigned int clock, div;
>> host = malloc(sizeof(struct dwmci_host));
>> if (!host) {
>> printf("dwmci_host malloc fail!\n");
>> return 1;
>> }
>>
>> + /*
>> + * The max operating freq of FSYS block is 400MHz.
>> + * Scale down the 400MHz to number 400.
>> + * Scale down the MPLL clock by dividing MPLL_CLK with ONE_MEGA_HZ.
>> + * Arrive at the divisor value taking 400 as the reference.
>> + */
>> +
>> + /* get mpll clock and divide it by ONE_MEGA_HZ */
>> + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
>> +
>> + /* Arrive at the divisor value. */
>> + for (div = 0; div <= 0xf; div++) {
>> + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
>> + break;
>> + }
>
> What if you don't find the right divisor?
i want to use like this.
sclk = mmc_get_clk(); -> then we can get the FSYS1 clock value
div = DIV_ROUND_UP(sclk, freq); => freq is request clock value.
mmc_set_clk(index, div);
Then we can set to div value at clock register.
It didn't need to add this code...
>> +
>> + /* set the clock divisor for mmc */
>> + set_mmc_clk(index, div);
>> +
>> 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]));
>
> timing should be a parameter, not a global. For the non-FDT case
> perhaps you can accept NULL, meaning default? Then:
>
> if (timing)
> do the code above
> else
> do the code below
>
>> +#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;
>> -
>> - add_dwmci(host, 52000000, 400000);
>> + host->mmc_clk = exynos_dwmci_get_clk;
>> + /* Add the mmc chennel to be registered with mmc core */
>> + add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
>
> Is error checking needed here?
>
>>
>> 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;
>> + 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];
>> +
>> + if (node <= 0)
>> + continue;
>> +
>> + /* Extract device id for each mmc channel */
>> + dev_id = pinmux_decode_periph_id(blob, node);
>> +
>> + /* Get the bus width from the device node */
>> + bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
>> + if (bus_width < 0) {
>
> <= 0? The function will return 0 if there is no property.
>
>> + debug("DWMMC: Can't get bus-width\n");
>> + return -1;
>> + }
>> + if (8 == bus_width)
>> + flag = PINMUX_FLAG_8BIT_MODE;
>> + else
>> + flag = PINMUX_FLAG_NONE;
>> +
>> + /* config pinmux for each mmc channel */
>> + err = exynos_pinmux_config(dev_id, flag);
>> + if (err) {
>> + debug("DWMMC not configured\n");
>> + return err;
>> + }
>> +
>> + index = dev_id - PERIPH_ID_SDMMC0;
>> +
>> + /* Get the base address from the device node */
>> + base = fdtdec_get_addr(blob, node, "reg");
>> + if (!base) {
>> + debug("DWMMC: Can't get base address\n");
>> + return -1;
>> + }
>> + /* Extract the timing info from the node */
>> + err = fdtdec_get_int_array(blob, node, "samsung,timing",
>> + timing, 3);
>> + if (err) {
>> + debug("Can't get sdr-timings for divider\n");
>> + return -1;
>> + }
>> + /* Initialise each mmc channel */
>> + err = exynos_dwmci_init(base, bus_width, index);
>> + if (err) {
>> + debug("Can't do dwmci init\n");
>> + return -1;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +#endif
>> diff --git a/include/dwmmc.h b/include/dwmmc.h
>> index c8b1d40..4a42849 100644
>> --- a/include/dwmmc.h
>> +++ b/include/dwmmc.h
>> @@ -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)
>> +
>
> Remove this extra line?
>
>>
>> #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;
>>
>> --
>> 1.8.0
>>
> Regards,
> Simon
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to
2013-01-11 3:54 ` Jaehoon Chung
@ 2013-01-11 5:41 ` Simon Glass
2013-01-11 13:50 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-11 5:41 UTC (permalink / raw)
To: u-boot
HI Jaehoon,
On Thu, Jan 10, 2013 at 7:54 PM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 01/11/2013 01:46 AM, Simon Glass wrote:
>> Hi Amar,
>>
>> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>>> This patch adds commands to open, close and resize boot partitions on EMMC.
>>>
>>> Changes from V1:
>>> 1)Combined the common piece of code between 'open' and 'close'
>>> operations.
>>>
>>> Changes from V2:
>>> 1)Updation of commit message and resubmition of proper patch set.
>>>
>>> Changes from V3:
>>> No change.
>>>
>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>> ---
>>> common/cmd_mmc.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>> 1 file changed, 83 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
>>> index 7dacd51..1dabb5b 100644
>>> --- a/common/cmd_mmc.c
>>> +++ b/common/cmd_mmc.c
>>> @@ -248,6 +248,84 @@ 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) ||
>>> + (strcmp(argv[1], "close") == 0)) {
>>
>> How about putting this block in its own function?
>>
>>> + int dev;
>>> + struct mmc *mmc;
>>> +
>>> + if (argc == 2)
>>> + dev = curr_device;
>>> + else if (argc == 3)
>>> + dev = simple_strtoul(argv[2], NULL, 10);
>>> + 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 (strcmp(argv[1], "open") == 0) {
>>> + 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"
>>> + " images are written\n");
>>
>> Do you need to split these strings so much? Perhaps when it is in a
>> function the indenting will be less?
>>
>>> + printf("!EMMC boot partition"
>>> + " has continuity at"
>>> + " image writing time.\n");
>>> + printf("!So, Do not close boot"
>>> + " partition, Before, all"
>>> + " images are written.\n");
>>> + return 0;
>>> + } else {
>>> + printf("EMMC OPEN Failed.\n");
>>> + return 1;
>>
>> You could put this above the other block and reduce indenting:
>>
>> if (mmc_boot_open(mmc)) {
>> printf("EMMC OPEN Failed.\n");
>> return 1;
>> }
>> ...code continues
>>
>>> + }
>>> + }
>>> +
>>> + if (strcmp(argv[1], "close") == 0) {
>>> + if (!(mmc_boot_close(mmc))) {
>>> + printf("EMMC CLOSE Success.\n");
>>
>> Shouldn't print a message on success
>>
>>> + return 0;
>>> + } else {
>>> + printf("EMMC CLOSE Failed.\n");
>>> + return 1;
>>> + }
>>> + }
>>> + } else if (strcmp(argv[1], "bootpart") == 0) {
>>> + int dev;
>>> + dev = simple_strtoul(argv[2], NULL, 10);
>>> +
>>> + u32 bootsize = simple_strtoul(argv[3], NULL, 10);
>>> + u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
>>> + struct mmc *mmc = find_mmc_device(dev);
>>> + 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);
>>> + return 0;
>>> + } else {
>>> + printf("EMMC boot partition Size change Failed.\n");
>>> + return 1;
>>> + }
>>> }
>>>
>>> state = MMC_INVALID;
>>> @@ -317,5 +395,9 @@ 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"
>>> + " - change sizes of boot and RPMB partions of specified device\n");
>>> #endif
>>
>> Also did you see Wolfgang's suggestion that we put the partition stuff
>> in the 'part' command (at least that's what I think he said). You
>> could have 'part open', 'part close' and maybe 'part resize'?
> How about using "mmc bootpart <device_num> <ack> <enable> <access>"
Maybe - what do these parameters mean?
> Also i think that we can reduce the code line.
OK good.
Regards,
Simon
>
> Best Regards,
> Jaehoon Chung
>>
>> Regards,
>> Simon
>>
>>> --
>>> 1.8.0
>>>
>>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues
2013-01-11 4:01 ` Jaehoon Chung
@ 2013-01-11 5:43 ` Simon Glass
2013-01-15 8:26 ` Amarendra Reddy
1 sibling, 0 replies; 42+ messages in thread
From: Simon Glass @ 2013-01-11 5:43 UTC (permalink / raw)
To: u-boot
Hi Jaehoon,
On Thu, Jan 10, 2013 at 8:01 PM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 01/11/2013 12:26 AM, Simon Glass wrote:
>> Hi Amar,
>>
>> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>>> This patch enumerates dwmci and set auto stop command during
>>> dwmci initialisation.
>>> EMMC read/write is not happening in current implementation
>>> due to improper fifo size computation. Hence Modified the fifo size
>>> computation to resolve EMMC read write issues.
>>>
>>> Changes from V1:
>>> 1)Created the macros RX_WMARK_SHIFT and RX_WMARK_MASK in header file.
>>>
>>> Changes from V2:
>>> 1)Updation of commit message and resubmition of proper patch set.
>>>
>>> Changes from V3:
>>> 1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of
>>> the hard coded value (1 << 10).
>>
>> I suggest you take a look at patman which might simplify your patch
>> sending and change logs - see tools/patman/README for details.
>>
>>>
>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>> ---
>>> drivers/mmc/dw_mmc.c | 14 ++++++++++++--
>>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>>> index 4070d4e..776fdb6 100644
>>> --- a/drivers/mmc/dw_mmc.c
>>> +++ b/drivers/mmc/dw_mmc.c
>>> @@ -136,6 +136,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>>> return TIMEOUT;
>>> }
>>> timeout--;
>>> + mdelay(1);
>>
>> How long will this delay in total?
> i didn't sure why add the mdelay(1)..i think mdelay(1) is too long.
> Isn't there other approach to resolve read/write issue?
I'm not sure what the root cause is, so I don't know. Perhaps someone
can investigate?
Regards,
Simon
>
> Best Regards,
> Jaehoon Chung
[snip]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-11 4:12 ` Jaehoon Chung
@ 2013-01-11 5:44 ` Simon Glass
2013-01-11 13:06 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-11 5:44 UTC (permalink / raw)
To: u-boot
Hi Jaehoon,
On Thu, Jan 10, 2013 at 8:12 PM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 01/11/2013 12:33 AM, Simon Glass wrote:
>> Hi Amar,
>>
>> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>>> This patch adds FDT support for DWMMC, by reading the DWMMC node data
>>> from the device tree and initialising DWMMC channels as per data
>>> obtained from the node.
>>>
>>> Changes from V1:
>>> 1)Updated code to have same signature for the function
>>> exynos_dwmci_init() for both FDT and non-FDT versions.
>>> 2)Updated code to pass device_id parameter to the function
>>> exynos5_mmc_set_clk_div() instead of index.
>>> 3)Updated code to decode the value of "samsung,width" from FDT.
>>> 4)Channel index is computed instead of getting from FDT.
>>>
>>> Changes from V2:
>>> 1)Updation of commit message and resubmition of proper patch set.
>>>
>>> Changes from V3:
>>> 1)Replaced the new function exynos5_mmc_set_clk_div() with the
>>> existing function set_mmc_clk(). set_mmc_clk() will do the purpose.
>>> 2)Computation of FSYS block clock divisor (pre-ratio) is added.
>>>
>>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>> ---
>>> arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
>>> drivers/mmc/exynos_dw_mmc.c | 129 +++++++++++++++++++++++++++++--
>>> include/dwmmc.h | 4 +
>>> 3 files changed, 130 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
>>> index 8acdf9b..40dcc7b 100644
>>> --- a/arch/arm/include/asm/arch-exynos/dwmmc.h
>>> +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
>>> @@ -29,8 +29,12 @@
>>>
>>> int exynos_dwmci_init(u32 regbase, int bus_width, int index);
>>>
>>> +#ifdef CONFIG_OF_CONTROL
>>> +unsigned int exynos_dwmmc_init(const void *blob);
>>> +#else
>>> static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
>>
>> Why unsigned?
>>
>> I'm really not that keen on functions which change their signature
>> based on an #ifdef. Can we perhaps have
>>
>> int exynos_dwmmc_init(const void *blob);
>>
>> which will pass NULL when there is no FDT, and
>>
>> int exynos_dwmmc_add_port(int index, int bus_width)
>>
>> for use by non-FDT boards?
>>
>>> {
>>> unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
>>> return exynos_dwmci_init(base, bus_width, index);
>>> }
>>> +#endif
>>> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
>>> index 72a31b7..d7ca7d0 100644
>>> --- a/drivers/mmc/exynos_dw_mmc.c
>>> +++ b/drivers/mmc/exynos_dw_mmc.c
>>> @@ -19,39 +19,154 @@
>>> */
>>>
>>> #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>
>>> +
>>> +#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
>>> +#define ONE_MEGA_HZ 1000000
>>> +#define SCALED_VAL_FOUR_HUNDRED 400
>>
>> I don't think you need these last two - you can just write the number
>> in the code
> Why didn't add into the dwmmc.h?
>>
>>>
>>> static char *EXYNOS_NAME = "EXYNOS DWMMC";
>>
>> Same with this I think
> Sorry..What means? Also need not?
Yes I mean that you probably don't need this - just put the string in the code.
>>
>>> +u32 timing[3];
>>>
>>> +/*
>>> + * Function used as callback function to initialise the
>>> + * CLKSEL register for every mmc channel.
>>> + */
>>> 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)
>>> +{
>>> + return get_mmc_clk(dev_index);
>>> }
>>>
>>> int exynos_dwmci_init(u32 regbase, int bus_width, int index)
>>> {
>>> struct dwmci_host *host = NULL;
>>> + unsigned int clock, div;
>>> host = malloc(sizeof(struct dwmci_host));
>>> if (!host) {
>>> printf("dwmci_host malloc fail!\n");
>>> return 1;
>>> }
>>>
>>> + /*
>>> + * The max operating freq of FSYS block is 400MHz.
>>> + * Scale down the 400MHz to number 400.
>>> + * Scale down the MPLL clock by dividing MPLL_CLK with ONE_MEGA_HZ.
>>> + * Arrive at the divisor value taking 400 as the reference.
>>> + */
>>> +
>>> + /* get mpll clock and divide it by ONE_MEGA_HZ */
>>> + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
>>> +
>>> + /* Arrive at the divisor value. */
>>> + for (div = 0; div <= 0xf; div++) {
>>> + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
>>> + break;
>>> + }
>>
>> What if you don't find the right divisor?
> i want to use like this.
>
> sclk = mmc_get_clk(); -> then we can get the FSYS1 clock value
> div = DIV_ROUND_UP(sclk, freq); => freq is request clock value.
> mmc_set_clk(index, div);
>
> Then we can set to div value at clock register.
> It didn't need to add this code...
OK, sounds good.
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-11 5:44 ` Simon Glass
@ 2013-01-11 13:06 ` Amarendra Reddy
2013-01-22 5:23 ` Joonyoung Shim
0 siblings, 1 reply; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-11 13:06 UTC (permalink / raw)
To: u-boot
Hi Simon / Jaehoon,
Thanks for review comments.
Please find the responses below.
Thanks & Regards
Amarendra Reddy
On 11 January 2013 11:14, Simon Glass <sjg@chromium.org> wrote:
> Hi Jaehoon,
>
> On Thu, Jan 10, 2013 at 8:12 PM, Jaehoon Chung <jh80.chung@samsung.com>
> wrote:
> > On 01/11/2013 12:33 AM, Simon Glass wrote:
> >> Hi Amar,
> >>
> >> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> >>> This patch adds FDT support for DWMMC, by reading the DWMMC node data
> >>> from the device tree and initialising DWMMC channels as per data
> >>> obtained from the node.
> >>>
> >>> Changes from V1:
> >>> 1)Updated code to have same signature for the function
> >>> exynos_dwmci_init() for both FDT and non-FDT versions.
> >>> 2)Updated code to pass device_id parameter to the function
> >>> exynos5_mmc_set_clk_div() instead of index.
> >>> 3)Updated code to decode the value of "samsung,width" from FDT.
> >>> 4)Channel index is computed instead of getting from FDT.
> >>>
> >>> Changes from V2:
> >>> 1)Updation of commit message and resubmition of proper patch
> set.
> >>>
> >>> Changes from V3:
> >>> 1)Replaced the new function exynos5_mmc_set_clk_div() with the
> >>> existing function set_mmc_clk(). set_mmc_clk() will do the
> purpose.
> >>> 2)Computation of FSYS block clock divisor (pre-ratio) is added.
> >>>
> >>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> >>> Signed-off-by: Amar <amarendra.xt@samsung.com>
> >>> ---
> >>> arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
> >>> drivers/mmc/exynos_dw_mmc.c | 129
> +++++++++++++++++++++++++++++--
> >>> include/dwmmc.h | 4 +
> >>> 3 files changed, 130 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h
> b/arch/arm/include/asm/arch-exynos/dwmmc.h
> >>> index 8acdf9b..40dcc7b 100644
> >>> --- a/arch/arm/include/asm/arch-exynos/dwmmc.h
> >>> +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
> >>> @@ -29,8 +29,12 @@
> >>>
> >>> int exynos_dwmci_init(u32 regbase, int bus_width, int index);
> >>>
> >>> +#ifdef CONFIG_OF_CONTROL
> >>> +unsigned int exynos_dwmmc_init(const void *blob);
> >>> +#else
> >>> static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
> >>
> >> Why unsigned?
>
Ok, shall replace "unsigned int exynos_dwmmc_init(int index, int
bus_width)" with
int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32
clksel).
Regarding the parameter *'clksel':*
i) "timing" value shall be passed in case of FDT, to be written into CLKSEL
register.
ii) NULL will be passed in case of non-FDT.
> >>
> >> I'm really not that keen on functions which change their signature
> >> based on an #ifdef. Can we perhaps have
> >>
> >> int exynos_dwmmc_init(const void *blob);
> >>
> >> which will pass NULL when there is no FDT, and
> >>
> >> int exynos_dwmmc_add_port(int index, int bus_width)
> >>
> >> for use by non-FDT boards?
>
Ok. I will call the function int exynos_dwmmc_init(NULL) for non-FDT and
int exynos_dwmmc_init(const void *blob) for FDT.
And use "int exynos_dwmci_add_port(int index, u32 regbase, int bus_width,
u32 clksel)".
> >>
> >>> {
> >>> unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
> >>> return exynos_dwmci_init(base, bus_width, index);
> >>> }
> >>> +#endif
> >>> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
> >>> index 72a31b7..d7ca7d0 100644
> >>> --- a/drivers/mmc/exynos_dw_mmc.c
> >>> +++ b/drivers/mmc/exynos_dw_mmc.c
> >>> @@ -19,39 +19,154 @@
> >>> */
> >>>
> >>> #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>
> >>> +
> >>> +#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
> >>> +#define ONE_MEGA_HZ 1000000
> >>> +#define SCALED_VAL_FOUR_HUNDRED 400
> >>
> >> I don't think you need these last two - you can just write the number
> >> in the code
> > Why didn't add into the dwmmc.h?
>
Ok, will just write the number in the code.
> >>
> >>>
> >>> static char *EXYNOS_NAME = "EXYNOS DWMMC";
> >>
> >> Same with this I think
> > Sorry..What means? Also need not?
>
> Yes I mean that you probably don't need this - just put the string in the
> code.
>
Ok.
>
> >>
> >>> +u32 timing[3];
> >>>
> >>> +/*
> >>> + * Function used as callback function to initialise the
> >>> + * CLKSEL register for every mmc channel.
> >>> + */
> >>> 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)
> >>> +{
> >>> + return get_mmc_clk(dev_index);
> >>> }
> >>>
> >>> int exynos_dwmci_init(u32 regbase, int bus_width, int index)
> >>> {
> >>> struct dwmci_host *host = NULL;
> >>> + unsigned int clock, div;
> >>> host = malloc(sizeof(struct dwmci_host));
> >>> if (!host) {
> >>> printf("dwmci_host malloc fail!\n");
> >>> return 1;
> >>> }
> >>>
> >>> + /*
> >>> + * The max operating freq of FSYS block is 400MHz.
> >>> + * Scale down the 400MHz to number 400.
> >>> + * Scale down the MPLL clock by dividing MPLL_CLK with
> ONE_MEGA_HZ.
> >>> + * Arrive at the divisor value taking 400 as the reference.
> >>> + */
> >>> +
> >>> + /* get mpll clock and divide it by ONE_MEGA_HZ */
> >>> + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
> >>> +
> >>> + /* Arrive at the divisor value. */
> >>> + for (div = 0; div <= 0xf; div++) {
> >>> + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
> >>> + break;
> >>> + }
> >>
> >> What if you don't find the right divisor?
> > i want to use like this.
> >
> > sclk = mmc_get_clk(); -> then we can get the FSYS1 clock value
> > div = DIV_ROUND_UP(sclk, freq); => freq is request clock value.
> > mmc_set_clk(index, div);
> >
> > Then we can set to div value at clock register.
> > It didn't need to add this code...
>
> OK, sounds good.
>
> Ok, shall implement as suggested by Jaehoon.
> Regards,
> Simon
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor
2013-01-11 3:52 ` Jaehoon Chung
@ 2013-01-11 13:23 ` Amarendra Reddy
2013-01-11 14:28 ` Simon Glass
0 siblings, 1 reply; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-11 13:23 UTC (permalink / raw)
To: u-boot
Hi Jaehoon / Simon,
Thanks for review comments.
Please find my responses below.
Thanks & Regards
Amarendra Reddy
On 11 January 2013 09:22, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 01/11/2013 12:35 AM, Simon Glass wrote:
> > Hi Amar,
> >
> > On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> >> This API computes the divisor value based on MPLL clock and
> >> writes it into the FSYS1 register.
> >>
> >> Changes from V1:
> >> 1)Updated the function exynos5_mmc_set_clk_div() to receive
> >> 'device_i'd as input parameter instead of 'index'.
> >>
> >> Changes from V2:
> >> 1)Updation of commit message and resubmition of proper patch
> set.
> >>
> >> Changes from V3:
> >> 1)Removed the new API exynos5_mmc_set_clk_div() from clock.c,
> >> because existing API set_mmc_clk() can be used to set mmc clock.
> >>
> >> Signed-off-by: Amar <amarendra.xt@samsung.com>
> >> ---
> >> arch/arm/cpu/armv7/exynos/clock.c | 4 ++--
> >> arch/arm/include/asm/arch-exynos/clk.h | 3 +++
> >> 2 files changed, 5 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/arch/arm/cpu/armv7/exynos/clock.c
> b/arch/arm/cpu/armv7/exynos/clock.c
> >> index 973b84e..89574ba 100644
> >> --- a/arch/arm/cpu/armv7/exynos/clock.c
> >> +++ b/arch/arm/cpu/armv7/exynos/clock.c
> >> @@ -490,7 +490,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;
> >
> > Is this fixing a warning?
> Maybe..fix the compiler warning..
>
As 'shift' was uninitialised, it had garbage value which was causing a
problem when "dev_index = 0 or 2".
> >
> >>
> >> sel = readl(&clk->src_fsys);
> >> sel = (sel >> (dev_index << 2)) & 0xf;
> >> @@ -539,7 +539,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;
> >> diff --git a/arch/arm/include/asm/arch-exynos/clk.h
> b/arch/arm/include/asm/arch-exynos/clk.h
> >> index 1935b0b..a4d5b4e 100644
> >> --- a/arch/arm/include/asm/arch-exynos/clk.h
> >> +++ b/arch/arm/include/asm/arch-exynos/clk.h
> >> @@ -29,6 +29,9 @@
> >> #define VPLL 4
> >> #define BPLL 5
> >>
> >> +#define FSYS1_MMC0_DIV_MASK 0xff0f
> >> +#define FSYS1_MMC0_DIV_VAL 0x0701
> >
> > What is this used for? I don't see it in this patch.
> >
> > Overall it is not clear what this patch is for.
> This define didn't need. That value is not static value, isn't?
>
In fact, V2 of this patch had a new function (which I added). That new
function was using the #define values.
But later in V4 the new function has been removed.
As of now the #define values are used in the file
board/samsung/smdk5250/clock_init.c.
The values are used during "booting from EMMC".
> Best Regards,
> Jaehoon Chung
> >
> >> +
> >> unsigned long get_pll_clk(int pllreg);
> >> unsigned long get_arm_clk(void);
> >> unsigned long get_i2c_clk(void);
> >> --
> >> 1.8.0
> >>
> >
> > Regards,
> > Simon
> >
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to
2013-01-11 5:41 ` Simon Glass
@ 2013-01-11 13:50 ` Amarendra Reddy
2013-01-11 14:31 ` Simon Glass
0 siblings, 1 reply; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-11 13:50 UTC (permalink / raw)
To: u-boot
Hi Simon / Jaehoon,
Please find my responses below.
Thanks & Regards
Amarendra reddy
On 11 January 2013 11:11, Simon Glass <sjg@chromium.org> wrote:
> HI Jaehoon,
>
> On Thu, Jan 10, 2013 at 7:54 PM, Jaehoon Chung <jh80.chung@samsung.com>
> wrote:
> > On 01/11/2013 01:46 AM, Simon Glass wrote:
> >> Hi Amar,
> >>
> >> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> >>> This patch adds commands to open, close and resize boot partitions on
> EMMC.
> >>>
> >>> Changes from V1:
> >>> 1)Combined the common piece of code between 'open' and 'close'
> >>> operations.
> >>>
> >>> Changes from V2:
> >>> 1)Updation of commit message and resubmition of proper patch
> set.
> >>>
> >>> Changes from V3:
> >>> No change.
> >>>
> >>> Signed-off-by: Amar <amarendra.xt@samsung.com>
> >>> ---
> >>> common/cmd_mmc.c | 84
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >>> 1 file changed, 83 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
> >>> index 7dacd51..1dabb5b 100644
> >>> --- a/common/cmd_mmc.c
> >>> +++ b/common/cmd_mmc.c
> >>> @@ -248,6 +248,84 @@ 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) ||
> >>> + (strcmp(argv[1], "close") == 0)) {
> >>
> >> How about putting this block in its own function?
>
Ok. Shall put the entire block in a new function.
> >>
> >>> + int dev;
> >>> + struct mmc *mmc;
> >>> +
> >>> + if (argc == 2)
> >>> + dev = curr_device;
> >>> + else if (argc == 3)
> >>> + dev = simple_strtoul(argv[2], NULL, 10);
> >>> + 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 (strcmp(argv[1], "open") == 0) {
> >>> + 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"
> >>> + " images are written\n");
> >>
> >> Do you need to split these strings so much? Perhaps when it is in a
> >> function the indenting will be less?
>
Ok.
> >>
> >>> + printf("!EMMC boot partition"
> >>> + " has continuity at"
> >>> + " image writing time.\n");
> >>> + printf("!So, Do not close boot"
> >>> + " partition, Before, all"
> >>> + " images are written.\n");
> >>> + return 0;
> >>> + } else {
> >>> + printf("EMMC OPEN Failed.\n");
> >>> + return 1;
> >>
> >> You could put this above the other block and reduce indenting:
> >>
> >> if (mmc_boot_open(mmc)) {
> >> printf("EMMC OPEN Failed.\n");
> >> return 1;
> >> }
> >> ...code continues
> >>
>
Ok.
> >>> + }
> >>> + }
> >>> +
> >>> + if (strcmp(argv[1], "close") == 0) {
> >>> + if (!(mmc_boot_close(mmc))) {
> >>> + printf("EMMC CLOSE Success.\n");
> >>
> >> Shouldn't print a message on success
> >>
>
Ok. shall remove the print message in success case.
>>> + return 0;
>>> + } else {
>>> + printf("EMMC CLOSE Failed.\n");
>>> + return 1;
>>> + }
>>> + }
>>> + } else if (strcmp(argv[1], "bootpart") == 0) {
>>> + int dev;
>>> + dev = simple_strtoul(argv[2], NULL, 10);
>>> +
>>> + u32 bootsize = simple_strtoul(argv[3], NULL, 10);
>>> + u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
>>> + struct mmc *mmc = find_mmc_device(dev);
>>> + 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);
>>> + return 0;
>>> + } else {
>>> + printf("EMMC boot partition Size change
Failed.\n");
>>> + return 1;
>>> + }
>>> }
>>>
>>> state = MMC_INVALID;
>>> @@ -317,5 +395,9 @@ 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"
>>> + " - change sizes of boot and RPMB partions of specified
device\n");
>>> #endif
>>
>> Also did you see Wolfgang's suggestion that we put the partition stuff
>> in the 'part' command (at least that's what I think he said). You
>> could have 'part open', 'part close' and maybe 'part resize'?
> How about using "mmc bootpart <device_num> <ack> <enable> <access>"
Maybe - what do these parameters mean?
>
>
The functions "mmc_boot_open()" and "mmc_boot_close()" have lot of
commom code. So Jaehoon suggested to
combine them into single generic function as below
1) So a single generic function "mmc_boot_part_access(struct mmc *mmc, int
ack, int part_num, int access)" to be used
instead of two functions open() and close().
2) By doing so user can specify which boot partition to be accessed (opened
/ closed).
The parameters *ack, part_num, access,* represent the values of bits in the
PARTITION_CONFIG field
of the Extended CSD register in order to address one of the partitions.
PARTITION_CONFIG - [179]:
-------------------------------------------
Bit 6: BOOT_ACK (R/W/E)
0x0 : No boot acknowledge sent (default)
0x1 : Boot acknowledge sent during boot operation
Bit[5:3] : BOOT_PARTITION_ENABLE (R/W/E)
User selects boot data that will be sent to master
0x0 : Device not boot enabled (default)
0x1 : Boot partition 1 enabled for boot
0x2 : Boot partition 2 enabled for boot
Bit[2:0] : PARTITION_ACCESS (before BOOT_PARTITION_ACCESS, R/W/E_P)
User selects partitions to access
0x0 : No access to boot partition (default)
0x1 : R/W boot partition 1
0x2 : R/W boot partition 2
0x3 : R/W Replay Protected Memory Block (RPMB)
Please comment on the above.
> > Also i think that we can reduce the code line.
>
> OK good.
>
> Regards,
> Simon
>
> >
> > Best Regards,
> > Jaehoon Chung
> >>
> >> Regards,
> >> Simon
> >>
> >>> --
> >>> 1.8.0
> >>>
> >>
> >
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor
2013-01-11 13:23 ` Amarendra Reddy
@ 2013-01-11 14:28 ` Simon Glass
0 siblings, 0 replies; 42+ messages in thread
From: Simon Glass @ 2013-01-11 14:28 UTC (permalink / raw)
To: u-boot
Hi Amarendra,
On Fri, Jan 11, 2013 at 5:23 AM, Amarendra Reddy
<amar.lavanuru@gmail.com> wrote:
> Hi Jaehoon / Simon,
>
> Thanks for review comments.
> Please find my responses below.
>
> Thanks & Regards
> Amarendra Reddy
>
> On 11 January 2013 09:22, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>
>> On 01/11/2013 12:35 AM, Simon Glass wrote:
>> > Hi Amar,
>> >
>> > On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> >> This API computes the divisor value based on MPLL clock and
>> >> writes it into the FSYS1 register.
>> >>
>> >> Changes from V1:
>> >> 1)Updated the function exynos5_mmc_set_clk_div() to receive
>> >> 'device_i'd as input parameter instead of 'index'.
>> >>
>> >> Changes from V2:
>> >> 1)Updation of commit message and resubmition of proper patch
>> >> set.
>> >>
>> >> Changes from V3:
>> >> 1)Removed the new API exynos5_mmc_set_clk_div() from clock.c,
>> >> because existing API set_mmc_clk() can be used to set mmc
>> >> clock.
>> >>
>> >> Signed-off-by: Amar <amarendra.xt@samsung.com>
>> >> ---
>> >> arch/arm/cpu/armv7/exynos/clock.c | 4 ++--
>> >> arch/arm/include/asm/arch-exynos/clk.h | 3 +++
>> >> 2 files changed, 5 insertions(+), 2 deletions(-)
>> >>
>> >> diff --git a/arch/arm/cpu/armv7/exynos/clock.c
>> >> b/arch/arm/cpu/armv7/exynos/clock.c
>> >> index 973b84e..89574ba 100644
>> >> --- a/arch/arm/cpu/armv7/exynos/clock.c
>> >> +++ b/arch/arm/cpu/armv7/exynos/clock.c
>> >> @@ -490,7 +490,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;
>> >
>> > Is this fixing a warning?
>> Maybe..fix the compiler warning..
>
>
> As 'shift' was uninitialised, it had garbage value which was causing a
> problem when "dev_index = 0 or 2".
OK good.
>>
>> >
>> >>
>> >> sel = readl(&clk->src_fsys);
>> >> sel = (sel >> (dev_index << 2)) & 0xf;
>> >> @@ -539,7 +539,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;
>> >> diff --git a/arch/arm/include/asm/arch-exynos/clk.h
>> >> b/arch/arm/include/asm/arch-exynos/clk.h
>> >> index 1935b0b..a4d5b4e 100644
>> >> --- a/arch/arm/include/asm/arch-exynos/clk.h
>> >> +++ b/arch/arm/include/asm/arch-exynos/clk.h
>> >> @@ -29,6 +29,9 @@
>> >> #define VPLL 4
>> >> #define BPLL 5
>> >>
>> >> +#define FSYS1_MMC0_DIV_MASK 0xff0f
>> >> +#define FSYS1_MMC0_DIV_VAL 0x0701
>> >
>> > What is this used for? I don't see it in this patch.
>> >
>> > Overall it is not clear what this patch is for.
>> This define didn't need. That value is not static value, isn't?
>
> In fact, V2 of this patch had a new function (which I added). That new
> function was using the #define values.
> But later in V4 the new function has been removed.
>
> As of now the #define values are used in the file
> board/samsung/smdk5250/clock_init.c.
> The values are used during "booting from EMMC".
OK I see. I suppose they could move to that patch, but I suppose it
isn't important so long as the patches go in in the right order.
Regards,
Simon
>
>>
>> Best Regards,
>> Jaehoon Chung
>> >
>> >> +
>> >> unsigned long get_pll_clk(int pllreg);
>> >> unsigned long get_arm_clk(void);
>> >> unsigned long get_i2c_clk(void);
>> >> --
>> >> 1.8.0
>> >>
>> >
>> > Regards,
>> > Simon
>> >
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to
2013-01-11 13:50 ` Amarendra Reddy
@ 2013-01-11 14:31 ` Simon Glass
0 siblings, 0 replies; 42+ messages in thread
From: Simon Glass @ 2013-01-11 14:31 UTC (permalink / raw)
To: u-boot
Hi Amarendra,
On Fri, Jan 11, 2013 at 5:50 AM, Amarendra Reddy
<amar.lavanuru@gmail.com> wrote:
> Hi Simon / Jaehoon,
>
> Please find my responses below.
>
> Thanks & Regards
> Amarendra reddy
>
> On 11 January 2013 11:11, Simon Glass <sjg@chromium.org> wrote:
>>
>> HI Jaehoon,
>>
>> On Thu, Jan 10, 2013 at 7:54 PM, Jaehoon Chung <jh80.chung@samsung.com>
>> wrote:
>> > On 01/11/2013 01:46 AM, Simon Glass wrote:
>> >> Hi Amar,
>> >>
>> >> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> >>> This patch adds commands to open, close and resize boot partitions on
>> >>> EMMC.
>> >>>
>> >>> Changes from V1:
>> >>> 1)Combined the common piece of code between 'open' and 'close'
>> >>> operations.
>> >>>
>> >>> Changes from V2:
>> >>> 1)Updation of commit message and resubmition of proper patch
>> >>> set.
>> >>>
>> >>> Changes from V3:
>> >>> No change.
>> >>>
>> >>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>> >>> ---
>> >>> common/cmd_mmc.c | 84
>> >>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> >>> 1 file changed, 83 insertions(+), 1 deletion(-)
>> >>>
>> >>> diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
>> >>> index 7dacd51..1dabb5b 100644
>> >>> --- a/common/cmd_mmc.c
>> >>> +++ b/common/cmd_mmc.c
>> >>> @@ -248,6 +248,84 @@ 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) ||
>> >>> + (strcmp(argv[1], "close") == 0)) {
>> >>
>> >> How about putting this block in its own function?
>
>
> Ok. Shall put the entire block in a new function.
>>
>> >>
>> >>> + int dev;
>> >>> + struct mmc *mmc;
>> >>> +
>> >>> + if (argc == 2)
>> >>> + dev = curr_device;
>> >>> + else if (argc == 3)
>> >>> + dev = simple_strtoul(argv[2], NULL, 10);
>> >>> + 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 (strcmp(argv[1], "open") == 0) {
>> >>> + 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"
>> >>> + " images are written\n");
>> >>
>> >> Do you need to split these strings so much? Perhaps when it is in a
>> >> function the indenting will be less?
>
> Ok.
>>
>> >>
>> >>> + printf("!EMMC boot partition"
>> >>> + " has continuity at"
>> >>> + " image writing time.\n");
>> >>> + printf("!So, Do not close boot"
>> >>> + " partition, Before, all"
>> >>> + " images are written.\n");
>> >>> + return 0;
>> >>> + } else {
>> >>> + printf("EMMC OPEN Failed.\n");
>> >>> + return 1;
>> >>
>> >> You could put this above the other block and reduce indenting:
>> >>
>> >> if (mmc_boot_open(mmc)) {
>> >> printf("EMMC OPEN Failed.\n");
>> >> return 1;
>> >> }
>> >> ...code continues
>> >>
>
> Ok.
>>
>> >>> + }
>> >>> + }
>> >>> +
>> >>> + if (strcmp(argv[1], "close") == 0) {
>> >>> + if (!(mmc_boot_close(mmc))) {
>> >>> + printf("EMMC CLOSE Success.\n");
>> >>
>> >> Shouldn't print a message on success
>> >>
>
> Ok. shall remove the print message in success case.
>
>>>> + return 0;
>>>> + } else {
>>>> + printf("EMMC CLOSE Failed.\n");
>>>> + return 1;
>>>> + }
>>>> + }
>>>> + } else if (strcmp(argv[1], "bootpart") == 0) {
>>>> + int dev;
>>>> + dev = simple_strtoul(argv[2], NULL, 10);
>>>> +
>>>> + u32 bootsize = simple_strtoul(argv[3], NULL, 10);
>>>> + u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
>>>> + struct mmc *mmc = find_mmc_device(dev);
>>>> + 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);
>>>> + return 0;
>>>> + } else {
>>>> + printf("EMMC boot partition Size change
>>>> Failed.\n");
>>>> + return 1;
>>>> + }
>>>> }
>>>>
>>>> state = MMC_INVALID;
>>>> @@ -317,5 +395,9 @@ 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"
>>>> + " - change sizes of boot and RPMB partions of specified
>>>> device\n");
>>>> #endif
>>>
>>> Also did you see Wolfgang's suggestion that we put the partition stuff
>>> in the 'part' command (at least that's what I think he said). You
>>> could have 'part open', 'part close' and maybe 'part resize'?
>> How about using "mmc bootpart <device_num> <ack> <enable> <access>"
>
>> Maybe - what do these parameters mean?
>>
>
> The functions "mmc_boot_open()" and "mmc_boot_close()" have lot of commom
> code. So Jaehoon suggested to
> combine them into single generic function as below
> 1) So a single generic function "mmc_boot_part_access(struct mmc *mmc, int
> ack, int part_num, int access)" to be used
> instead of two functions open() and close().
> 2) By doing so user can specify which boot partition to be accessed (opened
> / closed).
>
> The parameters ack, part_num, access, represent the values of bits in the
> PARTITION_CONFIG field
> of the Extended CSD register in order to address one of the partitions.
> PARTITION_CONFIG - [179]:
> -------------------------------------------
> Bit 6: BOOT_ACK (R/W/E)
> 0x0 : No boot acknowledge sent (default)
> 0x1 : Boot acknowledge sent during boot operation
> Bit[5:3] : BOOT_PARTITION_ENABLE (R/W/E)
> User selects boot data that will be sent to master
> 0x0 : Device not boot enabled (default)
> 0x1 : Boot partition 1 enabled for boot
> 0x2 : Boot partition 2 enabled for boot
> Bit[2:0] : PARTITION_ACCESS (before BOOT_PARTITION_ACCESS, R/W/E_P)
> User selects partitions to access
> 0x0 : No access to boot partition (default)
> 0x1 : R/W boot partition 1
> 0x2 : R/W boot partition 2
> 0x3 : R/W Replay Protected Memory Block (RPMB)
>
> Please comment on the above.
Yes sounds good.
>>
>> > Also i think that we can reduce the code line.
>>
>> OK good.
>>
[snip]
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
2013-01-10 16:57 ` Simon Glass
@ 2013-01-11 17:58 ` Amarendra Reddy
2013-01-12 16:41 ` Simon Glass
0 siblings, 1 reply; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-11 17:58 UTC (permalink / raw)
To: u-boot
Hi Simon,
Thanks for review comments.
Please find my responses below.
Thanks & Regards
Amarendra Reddy
On 10 January 2013 22:27, Simon Glass <sjg@chromium.org> wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> > This patch enables and initialises DWMMC for SMDK5250.
> > Supports both FDT and non-FDT. This patch creates a new file
> > 'exynos5-dt.c' meant for FDT support.
> > exynos5-dt.c: This file shall contain all code which supports
> FDT.
> > Any addition of FDT support for any module needs
> to be
> > added in this file.
> > smdk5250.c: This file shall contain the code which supports
> non-FDT.
> > version. Any addition of non-FDT support for any
> module
> > needs to be added in this file.
> > May be, the file smdk5250.c can be removed in
> near future
> > when non-FDT is not required.
> >
> > The Makefile is updated to compile only one of the files
> > exynos5-dt.c / smdk5250.c based on FDT configuration.
> >
> > NOTE:
> > Please note that all additions corresponding to FDT need to be added
> into the
> > file exynos5-dt.c.
> > At same time if non-FDT support is required then add the corresponding
> > updations into smdk5250.c.
> >
> > Changes from V1:
> > 1)A new file 'exynos5-dt.c' is created meant for FDT support
> > 2)Makefile is updated to compile only one of the files
> > exynos5-dt.c / smdk5250.c based on FDT configuration
> >
> > Changes from V2:
> > 1)Updation of commit message and resubmition of proper patch set.
> >
> > Changes from V3:
> > No change.
> >
> > Signed-off-by: Amar <amarendra.xt@samsung.com>
> > ---
> > board/samsung/smdk5250/Makefile | 4 +
> > board/samsung/smdk5250/exynos5-dt.c | 242
> ++++++++++++++++++++++++++++++++++++
> > board/samsung/smdk5250/smdk5250.c | 97 +++++++--------
> > include/configs/exynos5250-dt.h | 2 +
> > include/i2c.h | 2 +
> > 5 files changed, 292 insertions(+), 55 deletions(-)
> > create mode 100644 board/samsung/smdk5250/exynos5-dt.c
> >
> > diff --git a/board/samsung/smdk5250/Makefile
> b/board/samsung/smdk5250/Makefile
> > index 47c6a5a..ecca9f3 100644
> > --- a/board/samsung/smdk5250/Makefile
> > +++ b/board/samsung/smdk5250/Makefile
> > @@ -32,8 +32,12 @@ COBJS += tzpc_init.o
> > COBJS += smdk5250_spl.o
> >
> > ifndef CONFIG_SPL_BUILD
> > +ifdef CONFIG_OF_CONTROL
> > +COBJS += exynos5-dt.o
> > +else
> > COBJS += smdk5250.o
> > endif
> > +endif
> >
> > ifdef CONFIG_SPL_BUILD
> > COBJS += spl_boot.o
> > diff --git a/board/samsung/smdk5250/exynos5-dt.c
> b/board/samsung/smdk5250/exynos5-dt.c
> > new file mode 100644
> > index 0000000..da539ca
> > --- /dev/null
> > +++ b/board/samsung/smdk5250/exynos5-dt.c
> > @@ -0,0 +1,242 @@
> > +/*
> > + * Copyright (C) 2012 Samsung Electronics
> > + *
> > + * See file CREDITS for list of people who contributed to this
> > + * project.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of
> > + * the License, or (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> > + * MA 02111-1307 USA
> > + */
> > +
> > +#include <common.h>
> > +#include <fdtdec.h>
> > +#include <asm/io.h>
> > +#include <i2c.h>
> > +#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>
> > +#include <asm/arch/sromc.h>
> > +#include <power/pmic.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +int board_init(void)
> > +{
> > + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
> > +#ifdef CONFIG_EXYNOS_SPI
> > + spi_init();
> > +#endif
> > + return 0;
> > +}
> > +
> > +int dram_init(void)
> > +{
> > + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1,
> PHYS_SDRAM_1_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_2,
> PHYS_SDRAM_2_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_3,
> PHYS_SDRAM_3_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_4,
> PHYS_SDRAM_4_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_5,
> PHYS_SDRAM_7_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_6,
> PHYS_SDRAM_7_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_7,
> PHYS_SDRAM_7_SIZE)
> > + + get_ram_size((long *)PHYS_SDRAM_8,
> PHYS_SDRAM_8_SIZE);
>
> This looks ugly - is there any other way of doing this? Also 7 appears
> in more than one line.
>
> Since the banks are all SDRAM_BANK_SIZE apart, perhaps you could just
> use a for loop with a single base address?
>
> If this function is common with the other file then perhaps it should
> go in a common file?
>
>
In fact, this file "exynos5-dt.c" has been created for FDT support.
Existing code from "smdk5250.c" has been copied into "exynos5-dt.c".
The above piece of code computing 'gd->ram_size = ' is also copied from
smdk5250.c.
So, Is it required to do changes for existing code as well?
Please comment.
> + return 0;
> > +}
> > +
> > +#if defined(CONFIG_POWER)
> > +int power_init_board(void)
> > +{
> > + if (pmic_init(I2C_PMIC))
>
> debug()
>
> > + return -1;
> > + else
> > + return 0;
> > +}
> > +#endif
> > +
> > +void dram_init_banksize(void)
> > +{
> > + gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
> > + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
> > +
> PHYS_SDRAM_1_SIZE);
> > + gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
> > + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
> > +
> PHYS_SDRAM_2_SIZE);
> > + gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
> > + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
> > +
> PHYS_SDRAM_3_SIZE);
> > + gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
> > + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
> > +
> PHYS_SDRAM_4_SIZE);
> > + gd->bd->bi_dram[4].start = PHYS_SDRAM_5;
> > + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5,
> > +
> PHYS_SDRAM_5_SIZE);
> > + gd->bd->bi_dram[5].start = PHYS_SDRAM_6;
> > + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6,
> > +
> PHYS_SDRAM_6_SIZE);
> > + gd->bd->bi_dram[6].start = PHYS_SDRAM_7;
> > + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7,
> > +
> PHYS_SDRAM_7_SIZE);
> > + gd->bd->bi_dram[7].start = PHYS_SDRAM_8;
> > + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8,
> > +
> PHYS_SDRAM_8_SIZE);
>
> and here
>
> > +}
> > +
> > +static int decode_sromc(const void *blob, struct fdt_sromc *config)
> > +{
> > + int err;
> > + int node;
> > +
> > + node = fdtdec_next_compatible(blob, 0,
> COMPAT_SAMSUNG_EXYNOS5_SROMC);
> > + if (node < 0) {
> > + debug("Could not find SROMC node\n");
> > + return node;
> > + }
> > +
> > + config->bank = fdtdec_get_int(blob, node, "bank", 0);
> > + config->width = fdtdec_get_int(blob, node, "width", 2);
> > +
> > + err = fdtdec_get_int_array(blob, node, "srom-timing",
> config->timing,
> > + FDT_SROM_TIMING_COUNT);
> > + if (err < 0) {
> > + debug("Could not decode SROMC configuration\n");
>
> Suggest:
>
> debug("Could not decode SROMC configuration: %s\n", fdt_strerror(err));
>
> > + return -FDT_ERR_NOTFOUND;
>
> return err? Or the caller might just want -1
>
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +int board_eth_init(bd_t *bis)
> > +{
> > +#ifdef CONFIG_SMC911X
> > + u32 smc_bw_conf, smc_bc_conf;
> > + struct fdt_sromc config;
> > + fdt_addr_t base_addr;
> > + int node;
> > +
> > + node = decode_sromc(gd->fdt_blob, &config);
> > + if (node < 0) {
> > + debug("%s: Could not find sromc configuration\n",
> __func__);
> > + return 0;
> > + }
> > + node = fdtdec_next_compatible(gd->fdt_blob, node,
> COMPAT_SMSC_LAN9215);
> > + if (node < 0) {
> > + debug("%s: Could not find lan9215 configuration\n",
> __func__);
> > + return 0;
> > + }
> > +
> > + /* We now have a node, so any problems from now on are errors */
> > + base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
> > + if (base_addr == FDT_ADDR_T_NONE) {
> > + debug("%s: Could not find lan9215 address\n", __func__);
> > + return -1;
> > + }
> > +
> > + /* Ethernet needs data bus width of 16 bits */
> > + if (config.width != 2) {
> > + debug("%s: Unsupported bus width %d\n", __func__,
> > + config.width);
> > + return -1;
> > + }
> > + smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
> > + | SROMC_BYTE_ENABLE(config.bank);
> > +
> > + smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |\
>
> Can you remove the \ from each line?
>
> > + SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
> > + SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
> > + SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
> > + SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |\
> > + SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
> > + SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
> > +
> > + /* Select and configure the SROMC bank */
> > + exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
> > + s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
> > + return smc911x_initialize(0, base_addr);
> > +#endif
> > + return 0;
> > +}
> > +
> > +#ifdef CONFIG_DISPLAY_BOARDINFO
> > +int checkboard(void)
> > +{
> > + printf("\nBoard: SMDK5250\n");
> > +
> > + return 0;
> > +}
> > +#endif
> > +
> > +#ifdef CONFIG_GENERIC_MMC
> > +int board_mmc_init(bd_t *bis)
> > +{
> > + int ret = 0;
>
> Remove =0
>
> > +
> > + /* dwmmc initializattion for available channels */
> > + ret = exynos_dwmmc_init(gd->fdt_blob);
> > + if (ret)
> > + debug("dwmmc init failed\n");
> > +
> > + return ret;
> > +}
> > +#endif
> > +
> > +static int board_uart_init(void)
> > +{
> > + int err;
> > +
> > + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
> > + if (err) {
> > + debug("UART0 not configured\n");
> > + return err;
> > + }
> > +
> > + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
> > + if (err) {
> > + debug("UART1 not configured\n");
> > + return err;
> > + }
> > +
> > + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
> > + if (err) {
> > + debug("UART2 not configured\n");
> > + return err;
> > + }
> > +
> > + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
> > + if (err) {
> > + debug("UART3 not configured\n");
> > + return err;
> > + }
>
> Loop for this?
>
> > +
> > + return 0;
> > +}
> > +
> > +#ifdef CONFIG_BOARD_EARLY_INIT_F
> > +int board_early_init_f(void)
> > +{
> > + int err;
>
> blank line
>
> > + err = board_uart_init();
> > + if (err) {
> > + debug("UART init failed\n");
> > + return err;
> > + }
> > +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> > + board_i2c_init(gd->fdt_blob);
> > +#endif
> > + return err;
> > +}
> > +#endif
> > diff --git a/board/samsung/smdk5250/smdk5250.c
> b/board/samsung/smdk5250/smdk5250.c
> > index 73c3ec0..e0fec11 100644
> > --- a/board/samsung/smdk5250/smdk5250.c
> > +++ b/board/samsung/smdk5250/smdk5250.c
> > @@ -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>
> > @@ -95,59 +96,13 @@ void dram_init_banksize(void)
> >
> PHYS_SDRAM_8_SIZE);
> > }
> >
> > -#ifdef CONFIG_OF_CONTROL
> > -static int decode_sromc(const void *blob, struct fdt_sromc *config)
> > -{
> > - int err;
> > - int node;
> > -
> > - node = fdtdec_next_compatible(blob, 0,
> COMPAT_SAMSUNG_EXYNOS5_SROMC);
> > - if (node < 0) {
> > - debug("Could not find SROMC node\n");
> > - return node;
> > - }
> > -
> > - config->bank = fdtdec_get_int(blob, node, "bank", 0);
> > - config->width = fdtdec_get_int(blob, node, "width", 2);
> > -
> > - err = fdtdec_get_int_array(blob, node, "srom-timing",
> config->timing,
> > - FDT_SROM_TIMING_COUNT);
> > - if (err < 0) {
> > - debug("Could not decode SROMC configuration\n");
> > - return -FDT_ERR_NOTFOUND;
> > - }
> > -
> > - return 0;
> > -}
> > -#endif
> > -
> > int board_eth_init(bd_t *bis)
> > {
> > #ifdef CONFIG_SMC911X
> > u32 smc_bw_conf, smc_bc_conf;
> > struct fdt_sromc config;
> > fdt_addr_t base_addr;
> > - int node;
> > -
> > -#ifdef CONFIG_OF_CONTROL
> > - node = decode_sromc(gd->fdt_blob, &config);
> > - if (node < 0) {
> > - debug("%s: Could not find sromc configuration\n",
> __func__);
> > - return 0;
> > - }
> > - node = fdtdec_next_compatible(gd->fdt_blob, node,
> COMPAT_SMSC_LAN9215);
> > - if (node < 0) {
> > - debug("%s: Could not find lan9215 configuration\n",
> __func__);
> > - return 0;
> > - }
> >
> > - /* We now have a node, so any problems from now on are errors */
> > - base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
> > - if (base_addr == FDT_ADDR_T_NONE) {
> > - debug("%s: Could not find lan9215 address\n", __func__);
> > - return -1;
> > - }
> > -#else
> > /* Non-FDT configuration - bank number and timing parameters*/
> > config.bank = CONFIG_ENV_SROM_BANK;
> > config.width = 2;
> > @@ -160,7 +115,6 @@ int board_eth_init(bd_t *bis)
> > config.timing[FDT_SROM_TACP] = 0x09;
> > config.timing[FDT_SROM_PMC] = 0x01;
> > base_addr = CONFIG_SMC911X_BASE;
> > -#endif
> >
> > /* Ethernet needs data bus width of 16 bits */
> > if (config.width != 2) {
> > @@ -199,16 +153,31 @@ int checkboard(void)
> > #ifdef CONFIG_GENERIC_MMC
> > int board_mmc_init(bd_t *bis)
> > {
> > - int err;
> > + int err = 0, ret = 0;
> >
> > err = exynos_pinmux_config(PERIPH_ID_SDMMC0,
> PINMUX_FLAG_8BIT_MODE);
> > - if (err) {
> > + if (err)
> > debug("SDMMC0 not configured\n");
> > - return err;
> > - }
> > -
> > - err = s5p_mmc_init(0, 8);
> > - return err;
> > + ret |= err;
> > +
> > + /*EMMC: dwmmc Channel-0 with 8 bit bus width */
> > + err = exynos_dwmmc_init(0, 8);
>
> This is not really init of the whole dwmmc, only a port - suggest
> exynos_dwmmc_add_port() or similar
>
Instead of calling exynos_dwmmc_add_port() here, I shall call
exynos_dwmmc_init(*NULL*) here, as this is a non-FDT case. Inside the
function
exynos_dwmmc_init( * blob)
{
#ifdef CONFIG_OF_CONTROL
/* Read data from FDT */
exynos_dwmmc_add_port(index, bus_width, ...)
#else
exynos_dwmmc_add_port(0,8...)
exynos_dwmmc_add_port(2,4...)
#endif
}
Please comment on the above.
>
> > + 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;
> > +
> > + return ret;
> > }
> > #endif
> >
> > @@ -243,6 +212,24 @@ static int board_uart_init(void)
> > return 0;
> > }
> >
> > +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> > +static int board_i2c_init(void)
> > +{
> > + int i, err;
> > +
> > + for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) {
> > + err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
> > + PINMUX_FLAG_NONE);
> > + if (err) {
> > + debug("I2C%d not configured\n", (PERIPH_ID_I2C0
> + i));
> > + return err;
> > + }
> > + }
> > + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> > + return 0;
> > +}
> > +#endif
> > +
> > #ifdef CONFIG_BOARD_EARLY_INIT_F
> > int board_early_init_f(void)
> > {
> > @@ -253,7 +240,7 @@ int board_early_init_f(void)
> > return err;
> > }
> > #ifdef CONFIG_SYS_I2C_INIT_BOARD
> > - board_i2c_init(gd->fdt_blob);
> > + board_i2c_init();
> > #endif
> > return err;
> > }
> > diff --git a/include/configs/exynos5250-dt.h
> b/include/configs/exynos5250-dt.h
> > index 59182f4..6ce73dc 100644
> > --- a/include/configs/exynos5250-dt.h
> > +++ b/include/configs/exynos5250-dt.h
> > @@ -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
> >
> > diff --git a/include/i2c.h b/include/i2c.h
> > index c60d075..0944141 100644
> > --- a/include/i2c.h
> > +++ b/include/i2c.h
> > @@ -263,6 +263,7 @@ extern int get_multi_sda_pin(void);
> > extern int multi_i2c_init(void);
> > #endif
> >
> > +#ifdef CONFIG_OF_CONTROL
> > /**
> > * Get FDT values for i2c bus.
> > *
> > @@ -270,6 +271,7 @@ extern int multi_i2c_init(void);
> > * @return the number of I2C bus
> > */
> > void board_i2c_init(const void *blob);
> > +#endif
>
> Do you need this #ifdef? It would be better to avoid having the same
> function with a different signature.
>
> OK. Shall take care in next patch set.
i) call board_i2c_init(NULL) in case of non-FDT.
ii) call board_i2c_init(const void *blob) in case of FDT.
> >
> > /**
> > * Find the I2C bus number by given a FDT I2C node.
> > --
> > 1.8.0
> >
> Regards,
> Simon
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
2013-01-11 17:58 ` Amarendra Reddy
@ 2013-01-12 16:41 ` Simon Glass
2013-01-15 9:16 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2013-01-12 16:41 UTC (permalink / raw)
To: u-boot
Hi Amar,
On Fri, Jan 11, 2013 at 9:58 AM, Amarendra Reddy
<amar.lavanuru@gmail.com> wrote:
> Hi Simon,
>
> Thanks for review comments.
> Please find my responses below.
>
> Thanks & Regards
> Amarendra Reddy
>
> On 10 January 2013 22:27, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi Amar,
>>
>> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>> > This patch enables and initialises DWMMC for SMDK5250.
>> > Supports both FDT and non-FDT. This patch creates a new file
>> > 'exynos5-dt.c' meant for FDT support.
>> > exynos5-dt.c: This file shall contain all code which supports
>> > FDT.
>> > Any addition of FDT support for any module needs
>> > to be
>> > added in this file.
>> > smdk5250.c: This file shall contain the code which supports
>> > non-FDT.
>> > version. Any addition of non-FDT support for any
>> > module
>> > needs to be added in this file.
>> > May be, the file smdk5250.c can be removed in
>> > near future
>> > when non-FDT is not required.
>> >
>> > The Makefile is updated to compile only one of the files
>> > exynos5-dt.c / smdk5250.c based on FDT configuration.
>> >
>> > NOTE:
>> > Please note that all additions corresponding to FDT need to be added
>> > into the
>> > file exynos5-dt.c.
>> > At same time if non-FDT support is required then add the corresponding
>> > updations into smdk5250.c.
>> >
>> > Changes from V1:
>> > 1)A new file 'exynos5-dt.c' is created meant for FDT support
>> > 2)Makefile is updated to compile only one of the files
>> > exynos5-dt.c / smdk5250.c based on FDT configuration
>> >
>> > Changes from V2:
>> > 1)Updation of commit message and resubmition of proper patch
>> > set.
>> >
>> > Changes from V3:
>> > No change.
>> >
>> > Signed-off-by: Amar <amarendra.xt@samsung.com>
>> > ---
>> > board/samsung/smdk5250/Makefile | 4 +
>> > board/samsung/smdk5250/exynos5-dt.c | 242
>> > ++++++++++++++++++++++++++++++++++++
>> > board/samsung/smdk5250/smdk5250.c | 97 +++++++--------
>> > include/configs/exynos5250-dt.h | 2 +
>> > include/i2c.h | 2 +
>> > 5 files changed, 292 insertions(+), 55 deletions(-)
>> > create mode 100644 board/samsung/smdk5250/exynos5-dt.c
>> >
>> > diff --git a/board/samsung/smdk5250/Makefile
>> > b/board/samsung/smdk5250/Makefile
>> > index 47c6a5a..ecca9f3 100644
>> > --- a/board/samsung/smdk5250/Makefile
>> > +++ b/board/samsung/smdk5250/Makefile
>> > @@ -32,8 +32,12 @@ COBJS += tzpc_init.o
>> > COBJS += smdk5250_spl.o
>> >
>> > ifndef CONFIG_SPL_BUILD
>> > +ifdef CONFIG_OF_CONTROL
>> > +COBJS += exynos5-dt.o
>> > +else
>> > COBJS += smdk5250.o
>> > endif
>> > +endif
>> >
>> > ifdef CONFIG_SPL_BUILD
>> > COBJS += spl_boot.o
>> > diff --git a/board/samsung/smdk5250/exynos5-dt.c
>> > b/board/samsung/smdk5250/exynos5-dt.c
>> > new file mode 100644
>> > index 0000000..da539ca
>> > --- /dev/null
>> > +++ b/board/samsung/smdk5250/exynos5-dt.c
>> > @@ -0,0 +1,242 @@
>> > +/*
>> > + * Copyright (C) 2012 Samsung Electronics
>> > + *
>> > + * See file CREDITS for list of people who contributed to this
>> > + * project.
>> > + *
>> > + * This program is free software; you can redistribute it and/or
>> > + * modify it under the terms of the GNU General Public License as
>> > + * published by the Free Software Foundation; either version 2 of
>> > + * the License, or (at your option) any later version.
>> > + *
>> > + * This program is distributed in the hope that it will be useful,
>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> > + * GNU General Public License for more details.
>> > + *
>> > + * You should have received a copy of the GNU General Public License
>> > + * along with this program; if not, write to the Free Software
>> > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> > + * MA 02111-1307 USA
>> > + */
>> > +
>> > +#include <common.h>
>> > +#include <fdtdec.h>
>> > +#include <asm/io.h>
>> > +#include <i2c.h>
>> > +#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>
>> > +#include <asm/arch/sromc.h>
>> > +#include <power/pmic.h>
>> > +
>> > +DECLARE_GLOBAL_DATA_PTR;
>> > +
>> > +int board_init(void)
>> > +{
>> > + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
>> > +#ifdef CONFIG_EXYNOS_SPI
>> > + spi_init();
>> > +#endif
>> > + return 0;
>> > +}
>> > +
>> > +int dram_init(void)
>> > +{
>> > + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1,
>> > PHYS_SDRAM_1_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_2,
>> > PHYS_SDRAM_2_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_3,
>> > PHYS_SDRAM_3_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_4,
>> > PHYS_SDRAM_4_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_5,
>> > PHYS_SDRAM_7_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_6,
>> > PHYS_SDRAM_7_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_7,
>> > PHYS_SDRAM_7_SIZE)
>> > + + get_ram_size((long *)PHYS_SDRAM_8,
>> > PHYS_SDRAM_8_SIZE);
>>
>> This looks ugly - is there any other way of doing this? Also 7 appears
>> in more than one line.
>>
>> Since the banks are all SDRAM_BANK_SIZE apart, perhaps you could just
>> use a for loop with a single base address?
>>
>> If this function is common with the other file then perhaps it should
>> go in a common file?
>>
>
> In fact, this file "exynos5-dt.c" has been created for FDT support.
> Existing code from "smdk5250.c" has been copied into "exynos5-dt.c".
> The above piece of code computing 'gd->ram_size = ' is also copied from
> smdk5250.c.
>
> So, Is it required to do changes for existing code as well?
> Please comment.
I suppose I am responding to a patch to add a copy of this code into a
new file. Yes I think it would be better to create a common file that
both include, and then add a cleaned-up version of that function
(assuming it can be cleaned up as I suggested) to that common file,
and call the function from both places.
Copying code can cause bad problems when people want to refactor later.
>
>> > + return 0;
>> > +}
>> > +
>> > +#if defined(CONFIG_POWER)
>> > +int power_init_board(void)
>> > +{
>> > + if (pmic_init(I2C_PMIC))
>>
>> debug()
>>
>> > + return -1;
>> > + else
>> > + return 0;
>> > +}
>> > +#endif
>> > +
>> > +void dram_init_banksize(void)
>> > +{
>> > + gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
>> > + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
>> > +
>> > PHYS_SDRAM_1_SIZE);
>> > + gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
>> > + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
>> > +
>> > PHYS_SDRAM_2_SIZE);
>> > + gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
>> > + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
>> > +
>> > PHYS_SDRAM_3_SIZE);
>> > + gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
>> > + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
>> > +
>> > PHYS_SDRAM_4_SIZE);
>> > + gd->bd->bi_dram[4].start = PHYS_SDRAM_5;
>> > + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5,
>> > +
>> > PHYS_SDRAM_5_SIZE);
>> > + gd->bd->bi_dram[5].start = PHYS_SDRAM_6;
>> > + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6,
>> > +
>> > PHYS_SDRAM_6_SIZE);
>> > + gd->bd->bi_dram[6].start = PHYS_SDRAM_7;
>> > + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7,
>> > +
>> > PHYS_SDRAM_7_SIZE);
>> > + gd->bd->bi_dram[7].start = PHYS_SDRAM_8;
>> > + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8,
>> > +
>> > PHYS_SDRAM_8_SIZE);
>>
>> and here
>>
>> > +}
>> > +
>> > +static int decode_sromc(const void *blob, struct fdt_sromc *config)
>> > +{
>> > + int err;
>> > + int node;
>> > +
>> > + node = fdtdec_next_compatible(blob, 0,
>> > COMPAT_SAMSUNG_EXYNOS5_SROMC);
>> > + if (node < 0) {
>> > + debug("Could not find SROMC node\n");
>> > + return node;
>> > + }
>> > +
>> > + config->bank = fdtdec_get_int(blob, node, "bank", 0);
>> > + config->width = fdtdec_get_int(blob, node, "width", 2);
>> > +
>> > + err = fdtdec_get_int_array(blob, node, "srom-timing",
>> > config->timing,
>> > + FDT_SROM_TIMING_COUNT);
>> > + if (err < 0) {
>> > + debug("Could not decode SROMC configuration\n");
>>
>> Suggest:
>>
>> debug("Could not decode SROMC configuration: %s\n", fdt_strerror(err));
>>
>> > + return -FDT_ERR_NOTFOUND;
>>
>> return err? Or the caller might just want -1
>>
>> > + }
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +int board_eth_init(bd_t *bis)
>> > +{
>> > +#ifdef CONFIG_SMC911X
>> > + u32 smc_bw_conf, smc_bc_conf;
>> > + struct fdt_sromc config;
>> > + fdt_addr_t base_addr;
>> > + int node;
>> > +
>> > + node = decode_sromc(gd->fdt_blob, &config);
>> > + if (node < 0) {
>> > + debug("%s: Could not find sromc configuration\n",
>> > __func__);
>> > + return 0;
>> > + }
>> > + node = fdtdec_next_compatible(gd->fdt_blob, node,
>> > COMPAT_SMSC_LAN9215);
>> > + if (node < 0) {
>> > + debug("%s: Could not find lan9215 configuration\n",
>> > __func__);
>> > + return 0;
>> > + }
>> > +
>> > + /* We now have a node, so any problems from now on are errors */
>> > + base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
>> > + if (base_addr == FDT_ADDR_T_NONE) {
>> > + debug("%s: Could not find lan9215 address\n", __func__);
>> > + return -1;
>> > + }
>> > +
>> > + /* Ethernet needs data bus width of 16 bits */
>> > + if (config.width != 2) {
>> > + debug("%s: Unsupported bus width %d\n", __func__,
>> > + config.width);
>> > + return -1;
>> > + }
>> > + smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
>> > + | SROMC_BYTE_ENABLE(config.bank);
>> > +
>> > + smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |\
>>
>> Can you remove the \ from each line?
>>
>> > + SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
>> > + SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
>> > + SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
>> > + SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |\
>> > + SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
>> > + SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
>> > +
>> > + /* Select and configure the SROMC bank */
>> > + exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
>> > + s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
>> > + return smc911x_initialize(0, base_addr);
>> > +#endif
>> > + return 0;
>> > +}
>> > +
>> > +#ifdef CONFIG_DISPLAY_BOARDINFO
>> > +int checkboard(void)
>> > +{
>> > + printf("\nBoard: SMDK5250\n");
>> > +
>> > + return 0;
>> > +}
>> > +#endif
>> > +
>> > +#ifdef CONFIG_GENERIC_MMC
>> > +int board_mmc_init(bd_t *bis)
>> > +{
>> > + int ret = 0;
>>
>> Remove =0
>>
>> > +
>> > + /* dwmmc initializattion for available channels */
>> > + ret = exynos_dwmmc_init(gd->fdt_blob);
>> > + if (ret)
>> > + debug("dwmmc init failed\n");
>> > +
>> > + return ret;
>> > +}
>> > +#endif
>> > +
>> > +static int board_uart_init(void)
>> > +{
>> > + int err;
>> > +
>> > + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
>> > + if (err) {
>> > + debug("UART0 not configured\n");
>> > + return err;
>> > + }
>> > +
>> > + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
>> > + if (err) {
>> > + debug("UART1 not configured\n");
>> > + return err;
>> > + }
>> > +
>> > + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
>> > + if (err) {
>> > + debug("UART2 not configured\n");
>> > + return err;
>> > + }
>> > +
>> > + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
>> > + if (err) {
>> > + debug("UART3 not configured\n");
>> > + return err;
>> > + }
>>
>> Loop for this?
>>
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +#ifdef CONFIG_BOARD_EARLY_INIT_F
>> > +int board_early_init_f(void)
>> > +{
>> > + int err;
>>
>> blank line
>>
>> > + err = board_uart_init();
>> > + if (err) {
>> > + debug("UART init failed\n");
>> > + return err;
>> > + }
>> > +#ifdef CONFIG_SYS_I2C_INIT_BOARD
>> > + board_i2c_init(gd->fdt_blob);
>> > +#endif
>> > + return err;
>> > +}
>> > +#endif
>> > diff --git a/board/samsung/smdk5250/smdk5250.c
>> > b/board/samsung/smdk5250/smdk5250.c
>> > index 73c3ec0..e0fec11 100644
>> > --- a/board/samsung/smdk5250/smdk5250.c
>> > +++ b/board/samsung/smdk5250/smdk5250.c
>> > @@ -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>
>> > @@ -95,59 +96,13 @@ void dram_init_banksize(void)
>> >
>> > PHYS_SDRAM_8_SIZE);
>> > }
>> >
>> > -#ifdef CONFIG_OF_CONTROL
>> > -static int decode_sromc(const void *blob, struct fdt_sromc *config)
>> > -{
>> > - int err;
>> > - int node;
>> > -
>> > - node = fdtdec_next_compatible(blob, 0,
>> > COMPAT_SAMSUNG_EXYNOS5_SROMC);
>> > - if (node < 0) {
>> > - debug("Could not find SROMC node\n");
>> > - return node;
>> > - }
>> > -
>> > - config->bank = fdtdec_get_int(blob, node, "bank", 0);
>> > - config->width = fdtdec_get_int(blob, node, "width", 2);
>> > -
>> > - err = fdtdec_get_int_array(blob, node, "srom-timing",
>> > config->timing,
>> > - FDT_SROM_TIMING_COUNT);
>> > - if (err < 0) {
>> > - debug("Could not decode SROMC configuration\n");
>> > - return -FDT_ERR_NOTFOUND;
>> > - }
>> > -
>> > - return 0;
>> > -}
>> > -#endif
>> > -
>> > int board_eth_init(bd_t *bis)
>> > {
>> > #ifdef CONFIG_SMC911X
>> > u32 smc_bw_conf, smc_bc_conf;
>> > struct fdt_sromc config;
>> > fdt_addr_t base_addr;
>> > - int node;
>> > -
>> > -#ifdef CONFIG_OF_CONTROL
>> > - node = decode_sromc(gd->fdt_blob, &config);
>> > - if (node < 0) {
>> > - debug("%s: Could not find sromc configuration\n",
>> > __func__);
>> > - return 0;
>> > - }
>> > - node = fdtdec_next_compatible(gd->fdt_blob, node,
>> > COMPAT_SMSC_LAN9215);
>> > - if (node < 0) {
>> > - debug("%s: Could not find lan9215 configuration\n",
>> > __func__);
>> > - return 0;
>> > - }
>> >
>> > - /* We now have a node, so any problems from now on are errors */
>> > - base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
>> > - if (base_addr == FDT_ADDR_T_NONE) {
>> > - debug("%s: Could not find lan9215 address\n", __func__);
>> > - return -1;
>> > - }
>> > -#else
>> > /* Non-FDT configuration - bank number and timing parameters*/
>> > config.bank = CONFIG_ENV_SROM_BANK;
>> > config.width = 2;
>> > @@ -160,7 +115,6 @@ int board_eth_init(bd_t *bis)
>> > config.timing[FDT_SROM_TACP] = 0x09;
>> > config.timing[FDT_SROM_PMC] = 0x01;
>> > base_addr = CONFIG_SMC911X_BASE;
>> > -#endif
>> >
>> > /* Ethernet needs data bus width of 16 bits */
>> > if (config.width != 2) {
>> > @@ -199,16 +153,31 @@ int checkboard(void)
>> > #ifdef CONFIG_GENERIC_MMC
>> > int board_mmc_init(bd_t *bis)
>> > {
>> > - int err;
>> > + int err = 0, ret = 0;
>> >
>> > err = exynos_pinmux_config(PERIPH_ID_SDMMC0,
>> > PINMUX_FLAG_8BIT_MODE);
>> > - if (err) {
>> > + if (err)
>> > debug("SDMMC0 not configured\n");
>> > - return err;
>> > - }
>> > -
>> > - err = s5p_mmc_init(0, 8);
>> > - return err;
>> > + ret |= err;
>> > +
>> > + /*EMMC: dwmmc Channel-0 with 8 bit bus width */
>> > + err = exynos_dwmmc_init(0, 8);
>>
>> This is not really init of the whole dwmmc, only a port - suggest
>> exynos_dwmmc_add_port() or similar
>
>
> Instead of calling exynos_dwmmc_add_port() here, I shall call
> exynos_dwmmc_init(NULL) here, as this is a non-FDT case. Inside the function
> exynos_dwmmc_init( * blob)
That's fine. Don't forget that gd->fdt_blob is NULL when there is no
fdt, so you can use
exynos_dwmmc_init(gd->fdt_blob)
in both cases. However if it just one line of code then that's fine.
Note that in the absence of an FDT it is supposed to be the board file
which knows which MMC ports are active.
> {
> #ifdef CONFIG_OF_CONTROL
>
> /* Read data from FDT */
>
> exynos_dwmmc_add_port(index, bus_width, ...)
This code should go in the mmc driver. One of the ideas behind FDT is
that the drivers can figure out by themselves what ports to set up.
Also only the driver knows about its particular fields.
>
> #else
>
> exynos_dwmmc_add_port(0,8...)
>
> exynos_dwmmc_add_port(2,4...)
This code should go in the board file, since without an FDT the driver
can't know what ports to init.
>
> #endif
> }
>
> Please comment on the above.
>>
>>
>> > + 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;
>> > +
>> > + return ret;
>> > }
>> > #endif
>> >
>> > @@ -243,6 +212,24 @@ static int board_uart_init(void)
>> > return 0;
>> > }
>> >
>> > +#ifdef CONFIG_SYS_I2C_INIT_BOARD
>> > +static int board_i2c_init(void)
>> > +{
>> > + int i, err;
>> > +
>> > + for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) {
>> > + err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
>> > + PINMUX_FLAG_NONE);
>> > + if (err) {
>> > + debug("I2C%d not configured\n", (PERIPH_ID_I2C0
>> > + i));
>> > + return err;
>> > + }
>> > + }
>> > + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
>> > + return 0;
>> > +}
>> > +#endif
>> > +
>> > #ifdef CONFIG_BOARD_EARLY_INIT_F
>> > int board_early_init_f(void)
>> > {
>> > @@ -253,7 +240,7 @@ int board_early_init_f(void)
>> > return err;
>> > }
>> > #ifdef CONFIG_SYS_I2C_INIT_BOARD
>> > - board_i2c_init(gd->fdt_blob);
>> > + board_i2c_init();
>> > #endif
>> > return err;
>> > }
>> > diff --git a/include/configs/exynos5250-dt.h
>> > b/include/configs/exynos5250-dt.h
>> > index 59182f4..6ce73dc 100644
>> > --- a/include/configs/exynos5250-dt.h
>> > +++ b/include/configs/exynos5250-dt.h
>> > @@ -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
>> >
>> > diff --git a/include/i2c.h b/include/i2c.h
>> > index c60d075..0944141 100644
>> > --- a/include/i2c.h
>> > +++ b/include/i2c.h
>> > @@ -263,6 +263,7 @@ extern int get_multi_sda_pin(void);
>> > extern int multi_i2c_init(void);
>> > #endif
>> >
>> > +#ifdef CONFIG_OF_CONTROL
>> > /**
>> > * Get FDT values for i2c bus.
>> > *
>> > @@ -270,6 +271,7 @@ extern int multi_i2c_init(void);
>> > * @return the number of I2C bus
>> > */
>> > void board_i2c_init(const void *blob);
>> > +#endif
>>
>> Do you need this #ifdef? It would be better to avoid having the same
>> function with a different signature.
>>
> OK. Shall take care in next patch set.
> i) call board_i2c_init(NULL) in case of non-FDT.
> ii) call board_i2c_init(const void *blob) in case of FDT.
>>
>> >
>> > /**
>> > * Find the I2C bus number by given a FDT I2C node.
>> > --
>> > 1.8.0
>> >
>> Regards,
>> Simon
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>
>
Regards,
Simon
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues
2013-01-11 4:01 ` Jaehoon Chung
2013-01-11 5:43 ` Simon Glass
@ 2013-01-15 8:26 ` Amarendra Reddy
1 sibling, 0 replies; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-15 8:26 UTC (permalink / raw)
To: u-boot
Hi Jaehoon,
On 11 January 2013 09:31, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 01/11/2013 12:26 AM, Simon Glass wrote:
> > Hi Amar,
> >
> > On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> >> This patch enumerates dwmci and set auto stop command during
> >> dwmci initialisation.
> >> EMMC read/write is not happening in current implementation
> >> due to improper fifo size computation. Hence Modified the fifo size
> >> computation to resolve EMMC read write issues.
> >>
> >> Changes from V1:
> >> 1)Created the macros RX_WMARK_SHIFT and RX_WMARK_MASK in header
> file.
> >>
> >> Changes from V2:
> >> 1)Updation of commit message and resubmition of proper patch
> set.
> >>
> >> Changes from V3:
> >> 1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of
> >> the hard coded value (1 << 10).
> >
> > I suggest you take a look at patman which might simplify your patch
> > sending and change logs - see tools/patman/README for details.
> >
> >>
> >> Signed-off-by: Amar <amarendra.xt@samsung.com>
> >> ---
> >> drivers/mmc/dw_mmc.c | 14 ++++++++++++--
> >> 1 file changed, 12 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> >> index 4070d4e..776fdb6 100644
> >> --- a/drivers/mmc/dw_mmc.c
> >> +++ b/drivers/mmc/dw_mmc.c
> >> @@ -136,6 +136,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct
> mmc_cmd *cmd,
> >> return TIMEOUT;
> >> }
> >> timeout--;
> >> + mdelay(1);
> >
> > How long will this delay in total?
> i didn't sure why add the mdelay(1)..i think mdelay(1) is too long.
> Isn't there other approach to resolve read/write issue?
>
Other approach is
In the function dwmci_send_cmd(..), currently the variable "timeout =
100000".
If we change to "timeout = 200000", it works.
>
> Best Regards,
> Jaehoon Chung
> >
> >> }
> >>
> >> dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
> >> @@ -314,7 +315,7 @@ static void dwmci_set_ios(struct mmc *mmc)
> >> static int dwmci_init(struct mmc *mmc)
> >> {
> >> struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
> >> - u32 fifo_size, fifoth_val;
> >> + u32 fifo_size, fifoth_val, ier;
> >>
> >> dwmci_writel(host, DWMCI_PWREN, 1);
> >>
> >> @@ -323,6 +324,14 @@ static int dwmci_init(struct mmc *mmc)
> >> return -1;
> >> }
> >>
> >> + /* Enumerate at 400KHz */
> >> + dwmci_setup_bus(host, mmc->f_min);
> >> +
> >> + /* Set auto stop command */
> >> + ier = dwmci_readl(host, DWMCI_CTRL);
> >> + ier |= DWMCI_CTRL_SEND_AS_CCSD;
> >> + dwmci_writel(host, DWMCI_CTRL, ier);
> >> +
> >> dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
> >> dwmci_writel(host, DWMCI_INTMASK, 0);
> >>
> >> @@ -332,10 +341,11 @@ static int dwmci_init(struct mmc *mmc)
> >> dwmci_writel(host, DWMCI_BMOD, 1);
> >>
> >> fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
> >> + fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
> >> if (host->fifoth_val)
> >> fifoth_val = host->fifoth_val;
> >> else
> >> - fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 -1) |
> >> + fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 - 1) |
> >> TX_WMARK(fifo_size/2);
> >
> > {} around this else I think. Also space around /
> >
> >> dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);
> >>
> >> --
> >> 1.8.0
> >>
> >
> > Regards,
> > Simon
> >
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data
2013-01-10 15:21 ` Simon Glass
@ 2013-01-15 9:11 ` Amarendra Reddy
0 siblings, 0 replies; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-15 9:11 UTC (permalink / raw)
To: u-boot
Hi Simon,
On 10 January 2013 20:51, Simon Glass <sjg@chromium.org> wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> > This patch adds DWMMC device node data for exynos5.
> > This patch also adds binding file for DWMMC device node.
> >
> > Changes from V1:
> > 1)Added binding file for DWMMC device node at the location
> > "doc/device-tree-bindings/exynos/dwmmc.txt".
> > 2)Removed the propname 'index' from device node.
> > 3)Prefixed the vendor name 'samsung' before propname in device
> node.
> >
> > Changes from V2:
> > 1)Updation of commit message and resubmition of proper patch set.
> >
> > Changes from V3:
> > No change.
>
> Sorry I may be too late with this comment.
>
> >
> > Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> > Signed-off-by: Amar <amarendra.xt@samsung.com>X
> > ---
> > arch/arm/dts/exynos5250.dtsi | 32
> +++++++++++++++++++++++++++++++
> > board/samsung/dts/exynos5250-smdk5250.dts | 22 +++++++++++++++++++++
> > doc/device-tree-bindings/exynos/dwmmc.txt | 29
> ++++++++++++++++++++++++++++
> > 3 files changed, 83 insertions(+)
> > create mode 100644 doc/device-tree-bindings/exynos/dwmmc.txt
> >
> > diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
> > index 1008797..b701ae5 100644
> > --- a/arch/arm/dts/exynos5250.dtsi
> > +++ b/arch/arm/dts/exynos5250.dtsi
> > @@ -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>;
> > + };
> > };
> > diff --git a/board/samsung/dts/exynos5250-smdk5250.dts
> b/board/samsung/dts/exynos5250-smdk5250.dts
> > index a8e62da..9baf622 100644
> > --- a/board/samsung/dts/exynos5250-smdk5250.dts
> > +++ b/board/samsung/dts/exynos5250-smdk5250.dts
> > @@ -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";
>
> I think this should be mmc0, mmc1 instead of dwmmc0, dwmmc1, since
> ultimate we might want to support different drivers for each. The
> alias is support to link the generic mmc device number with the
> driver, and I don't think the numbering should be specific to the
> driver.
>
> Ok.
> > };
> >
> > sromc at 12250000 {
> > @@ -59,4 +63,22 @@
> > compatible = "wolfson,wm8994-codec";
> > };
> > };
> > +
> > + dwmmc at 12200000 {
> > + samsung,bus-width = <8>;
> > + samsung,timing = <1 3 3>;
> > + };
> > +
> > + dwmmc at 12210000 {
> > + status = "disabled";
> > + };
> > +
> > + dwmmc at 12220000 {
> > + samsung,bus-width = <4>;
> > + samsung,timing = <1 2 3>;
> > + };
> > +
> > + dwmmc at 12230000 {
> > + status = "disabled";
> > + };
> > };
> > diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt
> b/doc/device-tree-bindings/exynos/dwmmc.txt
> > new file mode 100644
> > index 0000000..6232ad6
> > --- /dev/null
> > +++ b/doc/device-tree-bindings/exynos/dwmmc.txt
> > @@ -0,0 +1,29 @@
> > +* Exynos 5250 DWC_mobile_storage
> > +
> > +The Exynos 5250 provides DWC_mobile_storage interface which supports
> > +. Embedded Multimedia Cards (EMMC-version 4.5)
> > +. Secure Digital memory (SD mem-version 2.0)
> > +. Secure Digital I/O (SDIO-version 3.0)
> > +. Consumer Electronics Advanced Transport Architecture (CE-ATA-version
> 1.1)
> > +
> > +The Exynos 5250 DWC_mobile_storage provides four channels.
> > +SOC specific and Board specific properties are channel specific.
> > +
> > +Required SoC Specific Properties:
> > +
> > +- compatible: should be
> > + - samsung,exynos5250-dwmmc: for exynos5250 platforms
> > +
> > +- reg: physical base address of the controller and length of memory
> mapped
> > + region.
> > +
> > +- interrupts: The interrupt number to the cpu.
> > +
> > +Required Board Specific Properties:
> > +
> > +- #address-cells: should be 1.
> > +- #size-cells: should be 0.
> > +- samsung,bus-width: The width of the bus used to interface the devices
> > + supported by DWC_mobile_storage (SD-MMC/EMMC/SDIO).
>
> typically 4 or 8
> Ok. I will mention this.
> > +- samsung,timing: The timing values to be written into the
> > + Drv/sample clock selection register of corresponding channel.
>
> Please add a bit more detail here - there are 3 values - what do they mean?
> Ok
>
> You should add an example for your binding (something will illustrates
> the binding).
> Ok
>
> Also does the kernel use the same binding?
>
> The uboot binding is a subset of kernel binding.
> Regards,
> Simon
>
>
> > --
> > 1.8.0
> >
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting
2013-01-10 16:39 ` Simon Glass
@ 2013-01-15 9:14 ` Amarendra Reddy
0 siblings, 0 replies; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-15 9:14 UTC (permalink / raw)
To: u-boot
Hi Simon,
Thanks for review comments.
Please find my responses below.
Thanks & Regards
Amarendra
On 10 January 2013 22:09, Simon Glass <sjg@chromium.org> wrote:
> Hi Amar,
>
> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> > This patch adds support for EMMC booting on SMDK5250.
> >
> > Changes from V1:
> > 1)Updated spl_boot.c file to maintain irom pointer table
> > instead of using the #define values defined in header file.
> >
> > Changes from V2:
> > 1)Updation of commit message and resubmition of proper patch set.
> >
> > Changes from V3:
> > No change.
> >
> > Signed-off-by: Amar <amarendra.xt@samsung.com>
> > ---
> > board/samsung/smdk5250/clock_init.c | 15 +++++++++++
> > board/samsung/smdk5250/clock_init.h | 5 ++++
> > board/samsung/smdk5250/spl_boot.c | 52
> ++++++++++++++++++++++++++++++++-----
> > 3 files changed, 65 insertions(+), 7 deletions(-)
> >
> > diff --git a/board/samsung/smdk5250/clock_init.c
> b/board/samsung/smdk5250/clock_init.c
> > index c009ae5..154993c 100644
> > --- a/board/samsung/smdk5250/clock_init.c
> > +++ b/board/samsung/smdk5250/clock_init.c
> > @@ -28,6 +28,7 @@
> > #include <asm/arch/clk.h>
> > #include <asm/arch/clock.h>
> > #include <asm/arch/spl.h>
> > +#include <asm/arch/dwmmc.h>
> >
> > #include "clock_init.h"
> > #include "setup.h"
> > @@ -664,3 +665,17 @@ void clock_init_dp_clock(void)
> > /* We run DP at 267 Mhz */
> > setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1);
> > }
> > +
> > +/*
> > + * Set clock divisor value for booting from EMMC.
> > + * Set DWMMC channel-0 clk div to operate mmc0 device at 50MHz.
> > + */
> > +void emmc_boot_clk_div_set(void)
> > +{
> > + struct exynos5_clock *clk = (struct exynos5_clock
> *)EXYNOS5_CLOCK_BASE;
> > + unsigned int div_mmc;
> > +
> > + div_mmc = readl((unsigned int) &clk->div_fsys1) &
> ~FSYS1_MMC0_DIV_MASK;
> > + div_mmc |= FSYS1_MMC0_DIV_VAL;
> > + writel(div_mmc, (unsigned int) &clk->div_fsys1);
> > +}
> > diff --git a/board/samsung/smdk5250/clock_init.h
> b/board/samsung/smdk5250/clock_init.h
> > index f751bcb..20a1d47 100644
> > --- a/board/samsung/smdk5250/clock_init.h
> > +++ b/board/samsung/smdk5250/clock_init.h
> > @@ -146,4 +146,9 @@ struct mem_timings *clock_get_mem_timings(void);
> > * Initialize clock for the device
> > */
> > void system_clock_init(void);
> > +
> > +/*
> > + * Set clock divisor value for booting from EMMC.
> > + */
> > +void emmc_boot_clk_div_set(void);
> > #endif
> > diff --git a/board/samsung/smdk5250/spl_boot.c
> b/board/samsung/smdk5250/spl_boot.c
> > index d8f3c1e..906e197 100644
> > --- a/board/samsung/smdk5250/spl_boot.c
> > +++ b/board/samsung/smdk5250/spl_boot.c
> > @@ -23,16 +23,38 @@
> > #include<common.h>
> > #include<config.h>
> >
> > +#include <asm/arch-exynos/dmc.h>
> > +#include <asm/arch/clock.h>
> > +#include <asm/arch/clk.h>
> > +
> > +#include "clock_init.h"
> > +
> > +/* Index into irom ptr table */
> > +enum index {
> > + MMC_INDEX,
> > + EMMC44_INDEX,
> > + EMMC44_END_INDEX,
> > + SPI_INDEX,
> > +};
> > +
> > +/* IROM Function Pointers Table */
> > +u32 irom_ptr_table[] = {
> > + [MMC_INDEX] = 0x02020030, /* iROM Function Pointer-SDMMC
> boot */
> > + [EMMC44_INDEX] = 0x02020044, /* iROM Function Pointer-EMMC4.4
> boot*/
> > + [EMMC44_END_INDEX] = 0x02020048,/* iROM Function Pointer
> > + -EMMC4.4 end boot
> operation */
> > + [SPI_INDEX] = 0x02020058, /* iROM Function Pointer-SPI
> boot */
> > + };
> > +
> > enum boot_mode {
> > BOOT_MODE_MMC = 4,
> > BOOT_MODE_SERIAL = 20,
> > + BOOT_MODE_EMMC = 8, /* EMMC4.4 */
> > /* 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);
> > -
> > /*
> > * Copy U-boot from mmc to RAM:
> > * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains
> > @@ -40,23 +62,39 @@ enum boot_mode {
> > */
> > void copy_uboot_to_ram(void)
> > {
> > - spi_copy_func_t spi_copy;
> > enum boot_mode bootmode;
> > - u32 (*copy_bl2)(u32, u32, u32);
> > -
> > + u32 (*spi_copy)(u32 offset, u32 nblock, u32 dst);
> > + u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst);
> > + u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
> > + void (*end_bootop_from_emmc)(void);
> > + /* read Operation Mode ststus register to find the bootmode */
> > bootmode = readl(EXYNOS5_POWER_BASE) & OM_STAT;
> >
> > switch (bootmode) {
> > case BOOT_MODE_SERIAL:
> > - spi_copy = *(spi_copy_func_t
> *)EXYNOS_COPY_SPI_FNPTR_ADDR;
> > + spi_copy = (void *) *(u32 *)irom_ptr_table[SPI_INDEX];
>
> This looks OK to me. My only suggestion is to put the lookup in a function
> like:
>
> static void *get_irom_func(int index)
>
> and avoid all the casting here.
>
> Ok will implement in next patch set.
> > spi_copy(SPI_FLASH_UBOOT_POS, CONFIG_BL2_SIZE,
> > CONFIG_SYS_TEXT_BASE);
> > break;
>
> Re SPI, the IROM performance is quite slow - do you plan to send up
> the U-Boot SPI code version? with a 32KB SPL there might be room to
> just use the normal driver.
>
Ok shall be taken in a new patch set.
>
> > case BOOT_MODE_MMC:
> > - copy_bl2 = (void *) *(u32 *)COPY_BL2_FNPTR_ADDR;
> > + copy_bl2 = (void *) *(u32 *)irom_ptr_table[MMC_INDEX];
> > copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
> > CONFIG_SYS_TEXT_BASE);
> > break;
> > + case BOOT_MODE_EMMC:
> > + /* Set the FSYS1 clock divisor value for EMMC boot */
> > + emmc_boot_clk_div_set();
> > +
> > + copy_bl2_from_emmc =
> > + (void *) *(u32 *)irom_ptr_table[EMMC44_INDEX];
> > + end_bootop_from_emmc =
> > + (void *) *(u32
> *)irom_ptr_table[EMMC44_END_INDEX];
> > +
> > + copy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT,
> CONFIG_SYS_TEXT_BASE);
> > + end_bootop_from_emmc();
> > +
> > + break;
> > +
> > default:
> > break;
> > }
> > --
> > 1.8.0
> >
>
> Regards,
> Simon
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
2013-01-12 16:41 ` Simon Glass
@ 2013-01-15 9:16 ` Amarendra Reddy
0 siblings, 0 replies; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-15 9:16 UTC (permalink / raw)
To: u-boot
Hi Simon,
Thanks for the review comments.
Please find my responses below.
Thanks & Regards
Amarendra Reddy
On 12 January 2013 22:11, Simon Glass <sjg@chromium.org> wrote:
> Hi Amar,
>
> On Fri, Jan 11, 2013 at 9:58 AM, Amarendra Reddy
> <amar.lavanuru@gmail.com> wrote:
> > Hi Simon,
> >
> > Thanks for review comments.
> > Please find my responses below.
> >
> > Thanks & Regards
> > Amarendra Reddy
> >
> > On 10 January 2013 22:27, Simon Glass <sjg@chromium.org> wrote:
> >>
> >> Hi Amar,
> >>
> >> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
> >> > This patch enables and initialises DWMMC for SMDK5250.
> >> > Supports both FDT and non-FDT. This patch creates a new file
> >> > 'exynos5-dt.c' meant for FDT support.
> >> > exynos5-dt.c: This file shall contain all code which
> supports
> >> > FDT.
> >> > Any addition of FDT support for any module
> needs
> >> > to be
> >> > added in this file.
> >> > smdk5250.c: This file shall contain the code which
> supports
> >> > non-FDT.
> >> > version. Any addition of non-FDT support for
> any
> >> > module
> >> > needs to be added in this file.
> >> > May be, the file smdk5250.c can be removed in
> >> > near future
> >> > when non-FDT is not required.
> >> >
> >> > The Makefile is updated to compile only one of the files
> >> > exynos5-dt.c / smdk5250.c based on FDT configuration.
> >> >
> >> > NOTE:
> >> > Please note that all additions corresponding to FDT need to be added
> >> > into the
> >> > file exynos5-dt.c.
> >> > At same time if non-FDT support is required then add the corresponding
> >> > updations into smdk5250.c.
> >> >
> >> > Changes from V1:
> >> > 1)A new file 'exynos5-dt.c' is created meant for FDT support
> >> > 2)Makefile is updated to compile only one of the files
> >> > exynos5-dt.c / smdk5250.c based on FDT configuration
> >> >
> >> > Changes from V2:
> >> > 1)Updation of commit message and resubmition of proper patch
> >> > set.
> >> >
> >> > Changes from V3:
> >> > No change.
> >> >
> >> > Signed-off-by: Amar <amarendra.xt@samsung.com>
> >> > ---
> >> > board/samsung/smdk5250/Makefile | 4 +
> >> > board/samsung/smdk5250/exynos5-dt.c | 242
> >> > ++++++++++++++++++++++++++++++++++++
> >> > board/samsung/smdk5250/smdk5250.c | 97 +++++++--------
> >> > include/configs/exynos5250-dt.h | 2 +
> >> > include/i2c.h | 2 +
> >> > 5 files changed, 292 insertions(+), 55 deletions(-)
> >> > create mode 100644 board/samsung/smdk5250/exynos5-dt.c
> >> >
> >> > diff --git a/board/samsung/smdk5250/Makefile
> >> > b/board/samsung/smdk5250/Makefile
> >> > index 47c6a5a..ecca9f3 100644
> >> > --- a/board/samsung/smdk5250/Makefile
> >> > +++ b/board/samsung/smdk5250/Makefile
> >> > @@ -32,8 +32,12 @@ COBJS += tzpc_init.o
> >> > COBJS += smdk5250_spl.o
> >> >
> >> > ifndef CONFIG_SPL_BUILD
> >> > +ifdef CONFIG_OF_CONTROL
> >> > +COBJS += exynos5-dt.o
> >> > +else
> >> > COBJS += smdk5250.o
> >> > endif
> >> > +endif
> >> >
> >> > ifdef CONFIG_SPL_BUILD
> >> > COBJS += spl_boot.o
> >> > diff --git a/board/samsung/smdk5250/exynos5-dt.c
> >> > b/board/samsung/smdk5250/exynos5-dt.c
> >> > new file mode 100644
> >> > index 0000000..da539ca
> >> > --- /dev/null
> >> > +++ b/board/samsung/smdk5250/exynos5-dt.c
> >> > @@ -0,0 +1,242 @@
> >> > +/*
> >> > + * Copyright (C) 2012 Samsung Electronics
> >> > + *
> >> > + * See file CREDITS for list of people who contributed to this
> >> > + * project.
> >> > + *
> >> > + * This program is free software; you can redistribute it and/or
> >> > + * modify it under the terms of the GNU General Public License as
> >> > + * published by the Free Software Foundation; either version 2 of
> >> > + * the License, or (at your option) any later version.
> >> > + *
> >> > + * This program is distributed in the hope that it will be useful,
> >> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> >> > + * GNU General Public License for more details.
> >> > + *
> >> > + * You should have received a copy of the GNU General Public License
> >> > + * along with this program; if not, write to the Free Software
> >> > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> >> > + * MA 02111-1307 USA
> >> > + */
> >> > +
> >> > +#include <common.h>
> >> > +#include <fdtdec.h>
> >> > +#include <asm/io.h>
> >> > +#include <i2c.h>
> >> > +#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>
> >> > +#include <asm/arch/sromc.h>
> >> > +#include <power/pmic.h>
> >> > +
> >> > +DECLARE_GLOBAL_DATA_PTR;
> >> > +
> >> > +int board_init(void)
> >> > +{
> >> > + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
> >> > +#ifdef CONFIG_EXYNOS_SPI
> >> > + spi_init();
> >> > +#endif
> >> > + return 0;
> >> > +}
> >> > +
> >> > +int dram_init(void)
> >> > +{
> >> > + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1,
> >> > PHYS_SDRAM_1_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_2,
> >> > PHYS_SDRAM_2_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_3,
> >> > PHYS_SDRAM_3_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_4,
> >> > PHYS_SDRAM_4_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_5,
> >> > PHYS_SDRAM_7_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_6,
> >> > PHYS_SDRAM_7_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_7,
> >> > PHYS_SDRAM_7_SIZE)
> >> > + + get_ram_size((long *)PHYS_SDRAM_8,
> >> > PHYS_SDRAM_8_SIZE);
> >>
> >> This looks ugly - is there any other way of doing this? Also 7 appears
> >> in more than one line.
> >>
> >> Since the banks are all SDRAM_BANK_SIZE apart, perhaps you could just
> >> use a for loop with a single base address?
> >>
> >> If this function is common with the other file then perhaps it should
> >> go in a common file?
> >>
> >
> > In fact, this file "exynos5-dt.c" has been created for FDT support.
> > Existing code from "smdk5250.c" has been copied into "exynos5-dt.c".
> > The above piece of code computing 'gd->ram_size = ' is also copied from
> > smdk5250.c.
> >
> > So, Is it required to do changes for existing code as well?
> > Please comment.
>
> I suppose I am responding to a patch to add a copy of this code into a
> new file. Yes I think it would be better to create a common file that
> both include, and then add a cleaned-up version of that function
> (assuming it can be cleaned up as I suggested) to that common file,
> and call the function from both places.
>
> Copying code can cause bad problems when people want to refactor later.
>
> Ok. Shall update the file exynos5-dt.c in response to your review
comments.
> >
> >> > + return 0;
> >> > +}
> >> > +
> >> > +#if defined(CONFIG_POWER)
> >> > +int power_init_board(void)
> >> > +{
> >> > + if (pmic_init(I2C_PMIC))
> >>
> >> debug()
> >>
> >> > + return -1;
> >> > + else
> >> > + return 0;
> >> > +}
> >> > +#endif
> >> > +
> >> > +void dram_init_banksize(void)
> >> > +{
> >> > + gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
> >> > + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
> >> > +
> >> > PHYS_SDRAM_1_SIZE);
> >> > + gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
> >> > + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
> >> > +
> >> > PHYS_SDRAM_2_SIZE);
> >> > + gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
> >> > + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
> >> > +
> >> > PHYS_SDRAM_3_SIZE);
> >> > + gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
> >> > + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
> >> > +
> >> > PHYS_SDRAM_4_SIZE);
> >> > + gd->bd->bi_dram[4].start = PHYS_SDRAM_5;
> >> > + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5,
> >> > +
> >> > PHYS_SDRAM_5_SIZE);
> >> > + gd->bd->bi_dram[5].start = PHYS_SDRAM_6;
> >> > + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6,
> >> > +
> >> > PHYS_SDRAM_6_SIZE);
> >> > + gd->bd->bi_dram[6].start = PHYS_SDRAM_7;
> >> > + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7,
> >> > +
> >> > PHYS_SDRAM_7_SIZE);
> >> > + gd->bd->bi_dram[7].start = PHYS_SDRAM_8;
> >> > + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8,
> >> > +
> >> > PHYS_SDRAM_8_SIZE);
> >>
> >> and here
> >>
> >> > +}
> >> > +
> >> > +static int decode_sromc(const void *blob, struct fdt_sromc *config)
> >> > +{
> >> > + int err;
> >> > + int node;
> >> > +
> >> > + node = fdtdec_next_compatible(blob, 0,
> >> > COMPAT_SAMSUNG_EXYNOS5_SROMC);
> >> > + if (node < 0) {
> >> > + debug("Could not find SROMC node\n");
> >> > + return node;
> >> > + }
> >> > +
> >> > + config->bank = fdtdec_get_int(blob, node, "bank", 0);
> >> > + config->width = fdtdec_get_int(blob, node, "width", 2);
> >> > +
> >> > + err = fdtdec_get_int_array(blob, node, "srom-timing",
> >> > config->timing,
> >> > + FDT_SROM_TIMING_COUNT);
> >> > + if (err < 0) {
> >> > + debug("Could not decode SROMC configuration\n");
> >>
> >> Suggest:
> >>
> >> debug("Could not decode SROMC configuration: %s\n", fdt_strerror(err));
> >>
> >> > + return -FDT_ERR_NOTFOUND;
> >>
> >> return err? Or the caller might just want -1
> >>
> >> > + }
> >> > +
> >> > + return 0;
> >> > +}
> >> > +
> >> > +int board_eth_init(bd_t *bis)
> >> > +{
> >> > +#ifdef CONFIG_SMC911X
> >> > + u32 smc_bw_conf, smc_bc_conf;
> >> > + struct fdt_sromc config;
> >> > + fdt_addr_t base_addr;
> >> > + int node;
> >> > +
> >> > + node = decode_sromc(gd->fdt_blob, &config);
> >> > + if (node < 0) {
> >> > + debug("%s: Could not find sromc configuration\n",
> >> > __func__);
> >> > + return 0;
> >> > + }
> >> > + node = fdtdec_next_compatible(gd->fdt_blob, node,
> >> > COMPAT_SMSC_LAN9215);
> >> > + if (node < 0) {
> >> > + debug("%s: Could not find lan9215 configuration\n",
> >> > __func__);
> >> > + return 0;
> >> > + }
> >> > +
> >> > + /* We now have a node, so any problems from now on are errors
> */
> >> > + base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
> >> > + if (base_addr == FDT_ADDR_T_NONE) {
> >> > + debug("%s: Could not find lan9215 address\n",
> __func__);
> >> > + return -1;
> >> > + }
> >> > +
> >> > + /* Ethernet needs data bus width of 16 bits */
> >> > + if (config.width != 2) {
> >> > + debug("%s: Unsupported bus width %d\n", __func__,
> >> > + config.width);
> >> > + return -1;
> >> > + }
> >> > + smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
> >> > + | SROMC_BYTE_ENABLE(config.bank);
> >> > +
> >> > + smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |\
> >>
> >> Can you remove the \ from each line?
> >>
> >> > + SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
> >> > + SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
> >> > + SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
> >> > + SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |\
> >> > + SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
> >> > + SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
> >> > +
> >> > + /* Select and configure the SROMC bank */
> >> > + exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
> >> > + s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
> >> > + return smc911x_initialize(0, base_addr);
> >> > +#endif
> >> > + return 0;
> >> > +}
> >> > +
> >> > +#ifdef CONFIG_DISPLAY_BOARDINFO
> >> > +int checkboard(void)
> >> > +{
> >> > + printf("\nBoard: SMDK5250\n");
> >> > +
> >> > + return 0;
> >> > +}
> >> > +#endif
> >> > +
> >> > +#ifdef CONFIG_GENERIC_MMC
> >> > +int board_mmc_init(bd_t *bis)
> >> > +{
> >> > + int ret = 0;
> >>
> >> Remove =0
> >>
> >> > +
> >> > + /* dwmmc initializattion for available channels */
> >> > + ret = exynos_dwmmc_init(gd->fdt_blob);
> >> > + if (ret)
> >> > + debug("dwmmc init failed\n");
> >> > +
> >> > + return ret;
> >> > +}
> >> > +#endif
> >> > +
> >> > +static int board_uart_init(void)
> >> > +{
> >> > + int err;
> >> > +
> >> > + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
> >> > + if (err) {
> >> > + debug("UART0 not configured\n");
> >> > + return err;
> >> > + }
> >> > +
> >> > + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
> >> > + if (err) {
> >> > + debug("UART1 not configured\n");
> >> > + return err;
> >> > + }
> >> > +
> >> > + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
> >> > + if (err) {
> >> > + debug("UART2 not configured\n");
> >> > + return err;
> >> > + }
> >> > +
> >> > + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
> >> > + if (err) {
> >> > + debug("UART3 not configured\n");
> >> > + return err;
> >> > + }
> >>
> >> Loop for this?
> >>
> >> > +
> >> > + return 0;
> >> > +}
> >> > +
> >> > +#ifdef CONFIG_BOARD_EARLY_INIT_F
> >> > +int board_early_init_f(void)
> >> > +{
> >> > + int err;
> >>
> >> blank line
> >>
> >> > + err = board_uart_init();
> >> > + if (err) {
> >> > + debug("UART init failed\n");
> >> > + return err;
> >> > + }
> >> > +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> >> > + board_i2c_init(gd->fdt_blob);
> >> > +#endif
> >> > + return err;
> >> > +}
> >> > +#endif
> >> > diff --git a/board/samsung/smdk5250/smdk5250.c
> >> > b/board/samsung/smdk5250/smdk5250.c
> >> > index 73c3ec0..e0fec11 100644
> >> > --- a/board/samsung/smdk5250/smdk5250.c
> >> > +++ b/board/samsung/smdk5250/smdk5250.c
> >> > @@ -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>
> >> > @@ -95,59 +96,13 @@ void dram_init_banksize(void)
> >> >
> >> > PHYS_SDRAM_8_SIZE);
> >> > }
> >> >
> >> > -#ifdef CONFIG_OF_CONTROL
> >> > -static int decode_sromc(const void *blob, struct fdt_sromc *config)
> >> > -{
> >> > - int err;
> >> > - int node;
> >> > -
> >> > - node = fdtdec_next_compatible(blob, 0,
> >> > COMPAT_SAMSUNG_EXYNOS5_SROMC);
> >> > - if (node < 0) {
> >> > - debug("Could not find SROMC node\n");
> >> > - return node;
> >> > - }
> >> > -
> >> > - config->bank = fdtdec_get_int(blob, node, "bank", 0);
> >> > - config->width = fdtdec_get_int(blob, node, "width", 2);
> >> > -
> >> > - err = fdtdec_get_int_array(blob, node, "srom-timing",
> >> > config->timing,
> >> > - FDT_SROM_TIMING_COUNT);
> >> > - if (err < 0) {
> >> > - debug("Could not decode SROMC configuration\n");
> >> > - return -FDT_ERR_NOTFOUND;
> >> > - }
> >> > -
> >> > - return 0;
> >> > -}
> >> > -#endif
> >> > -
> >> > int board_eth_init(bd_t *bis)
> >> > {
> >> > #ifdef CONFIG_SMC911X
> >> > u32 smc_bw_conf, smc_bc_conf;
> >> > struct fdt_sromc config;
> >> > fdt_addr_t base_addr;
> >> > - int node;
> >> > -
> >> > -#ifdef CONFIG_OF_CONTROL
> >> > - node = decode_sromc(gd->fdt_blob, &config);
> >> > - if (node < 0) {
> >> > - debug("%s: Could not find sromc configuration\n",
> >> > __func__);
> >> > - return 0;
> >> > - }
> >> > - node = fdtdec_next_compatible(gd->fdt_blob, node,
> >> > COMPAT_SMSC_LAN9215);
> >> > - if (node < 0) {
> >> > - debug("%s: Could not find lan9215 configuration\n",
> >> > __func__);
> >> > - return 0;
> >> > - }
> >> >
> >> > - /* We now have a node, so any problems from now on are errors
> */
> >> > - base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
> >> > - if (base_addr == FDT_ADDR_T_NONE) {
> >> > - debug("%s: Could not find lan9215 address\n",
> __func__);
> >> > - return -1;
> >> > - }
> >> > -#else
> >> > /* Non-FDT configuration - bank number and timing parameters*/
> >> > config.bank = CONFIG_ENV_SROM_BANK;
> >> > config.width = 2;
> >> > @@ -160,7 +115,6 @@ int board_eth_init(bd_t *bis)
> >> > config.timing[FDT_SROM_TACP] = 0x09;
> >> > config.timing[FDT_SROM_PMC] = 0x01;
> >> > base_addr = CONFIG_SMC911X_BASE;
> >> > -#endif
> >> >
> >> > /* Ethernet needs data bus width of 16 bits */
> >> > if (config.width != 2) {
> >> > @@ -199,16 +153,31 @@ int checkboard(void)
> >> > #ifdef CONFIG_GENERIC_MMC
> >> > int board_mmc_init(bd_t *bis)
> >> > {
> >> > - int err;
> >> > + int err = 0, ret = 0;
> >> >
> >> > err = exynos_pinmux_config(PERIPH_ID_SDMMC0,
> >> > PINMUX_FLAG_8BIT_MODE);
> >> > - if (err) {
> >> > + if (err)
> >> > debug("SDMMC0 not configured\n");
> >> > - return err;
> >> > - }
> >> > -
> >> > - err = s5p_mmc_init(0, 8);
> >> > - return err;
> >> > + ret |= err;
> >> > +
> >> > + /*EMMC: dwmmc Channel-0 with 8 bit bus width */
> >> > + err = exynos_dwmmc_init(0, 8);
> >>
> >> This is not really init of the whole dwmmc, only a port - suggest
> >> exynos_dwmmc_add_port() or similar
> >
> >
> > Instead of calling exynos_dwmmc_add_port() here, I shall call
> > exynos_dwmmc_init(NULL) here, as this is a non-FDT case. Inside the
> function
> > exynos_dwmmc_init( * blob)
>
> That's fine. Don't forget that gd->fdt_blob is NULL when there is no
> fdt, so you can use
>
> exynos_dwmmc_init(gd->fdt_blob)
>
> in both cases. However if it just one line of code then that's fine.
>
> Note that in the absence of an FDT it is supposed to be the board file
> which knows which MMC ports are active.
>
> > {
> > #ifdef CONFIG_OF_CONTROL
> >
> > /* Read data from FDT */
> >
> > exynos_dwmmc_add_port(index, bus_width, ...)
>
> This code should go in the mmc driver. One of the ideas behind FDT is
> that the drivers can figure out by themselves what ports to set up.
> Also only the driver knows about its particular fields.
>
Ok.
>
> >
> > #else
> >
> > exynos_dwmmc_add_port(0,8...)
> >
> > exynos_dwmmc_add_port(2,4...)
>
> This code should go in the board file, since without an FDT the driver
> can't know what ports to init.
>
Ok.
>
> >
> > #endif
> > }
> >
> > Please comment on the above.
> >>
> >>
> >> > + 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;
> >> > +
> >> > + return ret;
> >> > }
> >> > #endif
> >> >
> >> > @@ -243,6 +212,24 @@ static int board_uart_init(void)
> >> > return 0;
> >> > }
> >> >
> >> > +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> >> > +static int board_i2c_init(void)
> >> > +{
> >> > + int i, err;
> >> > +
> >> > + for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) {
> >> > + err = exynos_pinmux_config((PERIPH_ID_I2C0 + i),
> >> > + PINMUX_FLAG_NONE);
> >> > + if (err) {
> >> > + debug("I2C%d not configured\n",
> (PERIPH_ID_I2C0
> >> > + i));
> >> > + return err;
> >> > + }
> >> > + }
> >> > + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> >> > + return 0;
> >> > +}
> >> > +#endif
> >> > +
> >> > #ifdef CONFIG_BOARD_EARLY_INIT_F
> >> > int board_early_init_f(void)
> >> > {
> >> > @@ -253,7 +240,7 @@ int board_early_init_f(void)
> >> > return err;
> >> > }
> >> > #ifdef CONFIG_SYS_I2C_INIT_BOARD
> >> > - board_i2c_init(gd->fdt_blob);
> >> > + board_i2c_init();
> >> > #endif
> >> > return err;
> >> > }
> >> > diff --git a/include/configs/exynos5250-dt.h
> >> > b/include/configs/exynos5250-dt.h
> >> > index 59182f4..6ce73dc 100644
> >> > --- a/include/configs/exynos5250-dt.h
> >> > +++ b/include/configs/exynos5250-dt.h
> >> > @@ -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
> >> >
> >> > diff --git a/include/i2c.h b/include/i2c.h
> >> > index c60d075..0944141 100644
> >> > --- a/include/i2c.h
> >> > +++ b/include/i2c.h
> >> > @@ -263,6 +263,7 @@ extern int get_multi_sda_pin(void);
> >> > extern int multi_i2c_init(void);
> >> > #endif
> >> >
> >> > +#ifdef CONFIG_OF_CONTROL
> >> > /**
> >> > * Get FDT values for i2c bus.
> >> > *
> >> > @@ -270,6 +271,7 @@ extern int multi_i2c_init(void);
> >> > * @return the number of I2C bus
> >> > */
> >> > void board_i2c_init(const void *blob);
> >> > +#endif
> >>
> >> Do you need this #ifdef? It would be better to avoid having the same
> >> function with a different signature.
> >>
> > OK. Shall take care in next patch set.
> > i) call board_i2c_init(NULL) in case of non-FDT.
> > ii) call board_i2c_init(const void *blob) in case of FDT.
> >>
> >> >
> >> > /**
> >> > * Find the I2C bus number by given a FDT I2C node.
> >> > --
> >> > 1.8.0
> >> >
> >> Regards,
> >> Simon
> >> _______________________________________________
> >> U-Boot mailing list
> >> U-Boot at lists.denx.de
> >> http://lists.denx.de/mailman/listinfo/u-boot
> >
> >
>
> Regards,
> Simon
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-11 13:06 ` Amarendra Reddy
@ 2013-01-22 5:23 ` Joonyoung Shim
2013-01-22 6:41 ` Amarendra Reddy
0 siblings, 1 reply; 42+ messages in thread
From: Joonyoung Shim @ 2013-01-22 5:23 UTC (permalink / raw)
To: u-boot
On 01/11/2013 10:06 PM, Amarendra Reddy wrote:
> Hi Simon / Jaehoon,
>
> Thanks for review comments.
> Please find the responses below.
>
> Thanks & Regards
> Amarendra Reddy
>
> On 11 January 2013 11:14, Simon Glass <sjg@chromium.org> wrote:
>
>> Hi Jaehoon,
>>
>> On Thu, Jan 10, 2013 at 8:12 PM, Jaehoon Chung <jh80.chung@samsung.com>
>> wrote:
>>> On 01/11/2013 12:33 AM, Simon Glass wrote:
>>>> Hi Amar,
>>>>
>>>> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>>>>> This patch adds FDT support for DWMMC, by reading the DWMMC node data
>>>>> from the device tree and initialising DWMMC channels as per data
>>>>> obtained from the node.
>>>>>
>>>>> Changes from V1:
>>>>> 1)Updated code to have same signature for the function
>>>>> exynos_dwmci_init() for both FDT and non-FDT versions.
>>>>> 2)Updated code to pass device_id parameter to the function
>>>>> exynos5_mmc_set_clk_div() instead of index.
>>>>> 3)Updated code to decode the value of "samsung,width" from FDT.
>>>>> 4)Channel index is computed instead of getting from FDT.
>>>>>
>>>>> Changes from V2:
>>>>> 1)Updation of commit message and resubmition of proper patch
>> set.
>>>>> Changes from V3:
>>>>> 1)Replaced the new function exynos5_mmc_set_clk_div() with the
>>>>> existing function set_mmc_clk(). set_mmc_clk() will do the
>> purpose.
>>>>> 2)Computation of FSYS block clock divisor (pre-ratio) is added.
>>>>>
>>>>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>>>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>>>> ---
>>>>> arch/arm/include/asm/arch-exynos/dwmmc.h | 4 +
>>>>> drivers/mmc/exynos_dw_mmc.c | 129
>> +++++++++++++++++++++++++++++--
>>>>> include/dwmmc.h | 4 +
>>>>> 3 files changed, 130 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h
>> b/arch/arm/include/asm/arch-exynos/dwmmc.h
>>>>> index 8acdf9b..40dcc7b 100644
>>>>> --- a/arch/arm/include/asm/arch-exynos/dwmmc.h
>>>>> +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
>>>>> @@ -29,8 +29,12 @@
>>>>>
>>>>> int exynos_dwmci_init(u32 regbase, int bus_width, int index);
>>>>>
>>>>> +#ifdef CONFIG_OF_CONTROL
>>>>> +unsigned int exynos_dwmmc_init(const void *blob);
>>>>> +#else
>>>>> static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
>>>> Why unsigned?
> Ok, shall replace "unsigned int exynos_dwmmc_init(int index, int
> bus_width)" with
> int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32
> clksel).
> Regarding the parameter *'clksel':*
> i) "timing" value shall be passed in case of FDT, to be written into CLKSEL
> register.
> ii) NULL will be passed in case of non-FDT.
>
>
>> >>
>>>> I'm really not that keen on functions which change their signature
>>>> based on an #ifdef. Can we perhaps have
>>>>
>>>> int exynos_dwmmc_init(const void *blob);
>>>>
>>>> which will pass NULL when there is no FDT, and
>>>>
>>>> int exynos_dwmmc_add_port(int index, int bus_width)
>>>>
>>>> for use by non-FDT boards?
> Ok. I will call the function int exynos_dwmmc_init(NULL) for non-FDT and
> int exynos_dwmmc_init(const void *blob) for FDT.
> And use "int exynos_dwmci_add_port(int index, u32 regbase, int bus_width,
> u32 clksel)".
>
But patch v5 doesn't use exynos_dwmmc_init(NULL) and it uses
exynos_dwmci_add_port directly in board file.
Why we need blob argument in exynos_dwmmc_init? Already spi_init() just
uses gd->fdt_blob directly of drivers/spi/exynos_spi.c
I think exynos_dwmmc_init function needs a struct argument for int index
and int bus_width such follows.
struct exynos_dwmmc_config {
int index;
int bus_width;
};
exynos_dwmmc_init(struct exynos_dwmmc_config *config)
{
...
}
If config is NULL and gd->fdt_blob isn't NULL, we can get index and
bus_width from blob.
Thanks.
>> >>
>>>>> {
>>>>> unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
>>>>> return exynos_dwmci_init(base, bus_width, index);
>>>>> }
>>>>> +#endif
>>>>> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
>>>>> index 72a31b7..d7ca7d0 100644
>>>>> --- a/drivers/mmc/exynos_dw_mmc.c
>>>>> +++ b/drivers/mmc/exynos_dw_mmc.c
>>>>> @@ -19,39 +19,154 @@
>>>>> */
>>>>>
>>>>> #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>
>>>>> +
>>>>> +#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
>>>>> +#define ONE_MEGA_HZ 1000000
>>>>> +#define SCALED_VAL_FOUR_HUNDRED 400
>>>> I don't think you need these last two - you can just write the number
>>>> in the code
>>> Why didn't add into the dwmmc.h?
> Ok, will just write the number in the code.
>
>> >>
>>>>> static char *EXYNOS_NAME = "EXYNOS DWMMC";
>>>> Same with this I think
>>> Sorry..What means? Also need not?
>> Yes I mean that you probably don't need this - just put the string in the
>> code.
>>
> Ok.
>
>>>>> +u32 timing[3];
>>>>>
>>>>> +/*
>>>>> + * Function used as callback function to initialise the
>>>>> + * CLKSEL register for every mmc channel.
>>>>> + */
>>>>> 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)
>>>>> +{
>>>>> + return get_mmc_clk(dev_index);
>>>>> }
>>>>>
>>>>> int exynos_dwmci_init(u32 regbase, int bus_width, int index)
>>>>> {
>>>>> struct dwmci_host *host = NULL;
>>>>> + unsigned int clock, div;
>>>>> host = malloc(sizeof(struct dwmci_host));
>>>>> if (!host) {
>>>>> printf("dwmci_host malloc fail!\n");
>>>>> return 1;
>>>>> }
>>>>>
>>>>> + /*
>>>>> + * The max operating freq of FSYS block is 400MHz.
>>>>> + * Scale down the 400MHz to number 400.
>>>>> + * Scale down the MPLL clock by dividing MPLL_CLK with
>> ONE_MEGA_HZ.
>>>>> + * Arrive at the divisor value taking 400 as the reference.
>>>>> + */
>>>>> +
>>>>> + /* get mpll clock and divide it by ONE_MEGA_HZ */
>>>>> + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
>>>>> +
>>>>> + /* Arrive at the divisor value. */
>>>>> + for (div = 0; div <= 0xf; div++) {
>>>>> + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
>>>>> + break;
>>>>> + }
>>>> What if you don't find the right divisor?
>>> i want to use like this.
>>>
>>> sclk = mmc_get_clk(); -> then we can get the FSYS1 clock value
>>> div = DIV_ROUND_UP(sclk, freq); => freq is request clock value.
>>> mmc_set_clk(index, div);
>>>
>>> Then we can set to div value at clock register.
>>> It didn't need to add this code...
>> OK, sounds good.
>>
>> Ok, shall implement as suggested by Jaehoon.
>
>> Regards,
>> Simon
>> _______________________________________________
>> 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
^ permalink raw reply [flat|nested] 42+ messages in thread
* [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC
2013-01-22 5:23 ` Joonyoung Shim
@ 2013-01-22 6:41 ` Amarendra Reddy
0 siblings, 0 replies; 42+ messages in thread
From: Amarendra Reddy @ 2013-01-22 6:41 UTC (permalink / raw)
To: u-boot
Hi Joonyoung,
Thanks for the comments.
Please find my response below.
Thanks & Regards
Amarendra
On 22 January 2013 10:53, Joonyoung Shim <jy0922.shim@samsung.com> wrote:
> On 01/11/2013 10:06 PM, Amarendra Reddy wrote:
>
>> Hi Simon / Jaehoon,
>>
>> Thanks for review comments.
>> Please find the responses below.
>>
>> Thanks & Regards
>> Amarendra Reddy
>>
>> On 11 January 2013 11:14, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi Jaehoon,
>>>
>>> On Thu, Jan 10, 2013 at 8:12 PM, Jaehoon Chung <jh80.chung@samsung.com>
>>> wrote:
>>>
>>>> On 01/11/2013 12:33 AM, Simon Glass wrote:
>>>>
>>>>> Hi Amar,
>>>>>
>>>>> On Fri, Jan 4, 2013 at 1:34 AM, Amar <amarendra.xt@samsung.com> wrote:
>>>>>
>>>>>> This patch adds FDT support for DWMMC, by reading the DWMMC node data
>>>>>> from the device tree and initialising DWMMC channels as per data
>>>>>> obtained from the node.
>>>>>>
>>>>>> Changes from V1:
>>>>>> 1)Updated code to have same signature for the function
>>>>>> exynos_dwmci_init() for both FDT and non-FDT versions.
>>>>>> 2)Updated code to pass device_id parameter to the function
>>>>>> exynos5_mmc_set_clk_div() instead of index.
>>>>>> 3)Updated code to decode the value of "samsung,width" from
>>>>>> FDT.
>>>>>> 4)Channel index is computed instead of getting from FDT.
>>>>>>
>>>>>> Changes from V2:
>>>>>> 1)Updation of commit message and resubmition of proper patch
>>>>>>
>>>>> set.
>>>
>>>> Changes from V3:
>>>>>> 1)Replaced the new function exynos5_mmc_set_clk_div() with
>>>>>> the
>>>>>> existing function set_mmc_clk(). set_mmc_clk() will do the
>>>>>>
>>>>> purpose.
>>>
>>>> 2)Computation of FSYS block clock divisor (pre-ratio) is
>>>>>> added.
>>>>>>
>>>>>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>>>>>> Signed-off-by: Amar <amarendra.xt@samsung.com>
>>>>>> ---
>>>>>> arch/arm/include/asm/arch-**exynos/dwmmc.h | 4 +
>>>>>> drivers/mmc/exynos_dw_mmc.c | 129
>>>>>>
>>>>> +++++++++++++++++++++++++++++-**-
>>>
>>>> include/dwmmc.h | 4 +
>>>>>> 3 files changed, 130 insertions(+), 7 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm/include/asm/arch-**exynos/dwmmc.h
>>>>>>
>>>>> b/arch/arm/include/asm/arch-**exynos/dwmmc.h
>>>
>>>> index 8acdf9b..40dcc7b 100644
>>>>>> --- a/arch/arm/include/asm/arch-**exynos/dwmmc.h
>>>>>> +++ b/arch/arm/include/asm/arch-**exynos/dwmmc.h
>>>>>> @@ -29,8 +29,12 @@
>>>>>>
>>>>>> int exynos_dwmci_init(u32 regbase, int bus_width, int index);
>>>>>>
>>>>>> +#ifdef CONFIG_OF_CONTROL
>>>>>> +unsigned int exynos_dwmmc_init(const void *blob);
>>>>>> +#else
>>>>>> static inline unsigned int exynos_dwmmc_init(int index, int
>>>>>> bus_width)
>>>>>>
>>>>> Why unsigned?
>>>>>
>>>> Ok, shall replace "unsigned int exynos_dwmmc_init(int index, int
>> bus_width)" with
>> int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32
>> clksel).
>> Regarding the parameter *'clksel':*
>>
>> i) "timing" value shall be passed in case of FDT, to be written into
>> CLKSEL
>> register.
>> ii) NULL will be passed in case of non-FDT.
>>
>>
>> >>
>>>
>>>> I'm really not that keen on functions which change their signature
>>>>> based on an #ifdef. Can we perhaps have
>>>>>
>>>>> int exynos_dwmmc_init(const void *blob);
>>>>>
>>>>> which will pass NULL when there is no FDT, and
>>>>>
>>>>> int exynos_dwmmc_add_port(int index, int bus_width)
>>>>>
>>>>> for use by non-FDT boards?
>>>>>
>>>> Ok. I will call the function int exynos_dwmmc_init(NULL) for non-FDT and
>> int exynos_dwmmc_init(const void *blob) for FDT.
>> And use "int exynos_dwmci_add_port(int index, u32 regbase, int bus_width,
>> u32 clksel)".
>>
>>
> But patch v5 doesn't use exynos_dwmmc_init(NULL) and it uses
> exynos_dwmci_add_port directly in board file.
>
> The initial thought was to use
a) exynos_dwmmc_init(const void *blob) for FDT and
b) exynos_dwmmc_init(NULL) for non-FDT
But there were review comments from Simon, stating that
"exynos_dwmmc_add_port() should go in the board file, since without an FDT
the driver can't know what ports to init".
Only the board file knows the port numbers.
Hence exynos_dwmmc_init(NULL) is not used in non-FDT case.
Please find below comments from Simon, regarding the same
***********************************************************************
>Note that in the absence of an FDT it is supposed to be the board file
>which knows which MMC ports are active.
> {
> #ifdef CONFIG_OF_CONTROL
>
> /* Read data from FDT */
>
> exynos_dwmmc_add_port(index, bus_width, ...)
>This code should go in the mmc driver. One of the ideas behind FDT is
>that the drivers can figure out by themselves what ports to set up.
>Also only the driver knows about its particular fields.
>
> #else
>
> exynos_dwmmc_add_port(0,8...)
>
> exynos_dwmmc_add_port(2,4...)
>This code should go in the board file, since without an FDT the driver
>can't know what ports to init.
**********************************************************************
> Why we need blob argument in exynos_dwmmc_init? Already spi_init() just
> uses gd->fdt_blob directly of drivers/spi/exynos_spi.c
>
Yes, in case of spi_init(), there is no explicit mention (hard code) of
port numbers, bus_width etc.
But for dwmmc, in case of non-FDT, we need to hard code port number and
bus_width and this is done in board file.
> I think exynos_dwmmc_init function needs a struct argument for int index
> and int bus_width such follows.
>
> struct exynos_dwmmc_config {
> int index;
> int bus_width;
> };
>
> exynos_dwmmc_init(struct exynos_dwmmc_config *config)
> {
> ...
> }
>
> If config is NULL and gd->fdt_blob isn't NULL, we can get index and
> bus_width from blob.
>
> Yes, this is a good approach.
Also in near future the non-FDT part may be removed, retaining only the FDT
part.
Please comment whether to add this new approach by using 'struct
exynos_dwmmc_config', I can add in next patch.
> Thanks.
>
>
>
> >>
>>>
>>>> {
>>>>>> unsigned int base = samsung_get_base_mmc() + (0x10000 *
>>>>>> index);
>>>>>> return exynos_dwmci_init(base, bus_width, index);
>>>>>> }
>>>>>> +#endif
>>>>>> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
>>>>>> index 72a31b7..d7ca7d0 100644
>>>>>> --- a/drivers/mmc/exynos_dw_mmc.c
>>>>>> +++ b/drivers/mmc/exynos_dw_mmc.c
>>>>>> @@ -19,39 +19,154 @@
>>>>>> */
>>>>>>
>>>>>> #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>
>>>>>> +
>>>>>> +#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
>>>>>> +#define ONE_MEGA_HZ 1000000
>>>>>> +#define SCALED_VAL_FOUR_HUNDRED 400
>>>>>>
>>>>> I don't think you need these last two - you can just write the number
>>>>> in the code
>>>>>
>>>> Why didn't add into the dwmmc.h?
>>>>
>>> Ok, will just write the number in the code.
>>
>> >>
>>>
>>>> static char *EXYNOS_NAME = "EXYNOS DWMMC";
>>>>>>
>>>>> Same with this I think
>>>>>
>>>> Sorry..What means? Also need not?
>>>>
>>> Yes I mean that you probably don't need this - just put the string in the
>>> code.
>>>
>>> Ok.
>>
>> +u32 timing[3];
>>>>>>
>>>>>> +/*
>>>>>> + * Function used as callback function to initialise the
>>>>>> + * CLKSEL register for every mmc channel.
>>>>>> + */
>>>>>> 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)
>>>>>> +{
>>>>>> + return get_mmc_clk(dev_index);
>>>>>> }
>>>>>>
>>>>>> int exynos_dwmci_init(u32 regbase, int bus_width, int index)
>>>>>> {
>>>>>> struct dwmci_host *host = NULL;
>>>>>> + unsigned int clock, div;
>>>>>> host = malloc(sizeof(struct dwmci_host));
>>>>>> if (!host) {
>>>>>> printf("dwmci_host malloc fail!\n");
>>>>>> return 1;
>>>>>> }
>>>>>>
>>>>>> + /*
>>>>>> + * The max operating freq of FSYS block is 400MHz.
>>>>>> + * Scale down the 400MHz to number 400.
>>>>>> + * Scale down the MPLL clock by dividing MPLL_CLK with
>>>>>>
>>>>> ONE_MEGA_HZ.
>>>
>>>> + * Arrive at the divisor value taking 400 as the reference.
>>>>>> + */
>>>>>> +
>>>>>> + /* get mpll clock and divide it by ONE_MEGA_HZ */
>>>>>> + clock = get_pll_clk(MPLL) / ONE_MEGA_HZ;
>>>>>> +
>>>>>> + /* Arrive at the divisor value. */
>>>>>> + for (div = 0; div <= 0xf; div++) {
>>>>>> + if ((clock / (div + 1)) <= SCALED_VAL_FOUR_HUNDRED)
>>>>>> + break;
>>>>>> + }
>>>>>>
>>>>> What if you don't find the right divisor?
>>>>>
>>>> i want to use like this.
>>>>
>>>> sclk = mmc_get_clk(); -> then we can get the FSYS1 clock value
>>>> div = DIV_ROUND_UP(sclk, freq); => freq is request clock value.
>>>> mmc_set_clk(index, div);
>>>>
>>>> Then we can set to div value at clock register.
>>>> It didn't need to add this code...
>>>>
>>> OK, sounds good.
>>>
>>> Ok, shall implement as suggested by Jaehoon.
>>>
>>
>> Regards,
>>> Simon
>>> ______________________________**_________________
>>> U-Boot mailing list
>>> U-Boot at lists.denx.de
>>> http://lists.denx.de/mailman/**listinfo/u-boot<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<http://lists.denx.de/mailman/listinfo/u-boot>
>>
>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2013-01-22 6:41 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-04 9:34 [U-Boot] [PATCH V4 0/9] EXYNOS5: Enable DWMMC, add FDT support for DWMMC and Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 1/9] FDT: Add compatible string for DWMMC Amar
2013-01-04 9:34 ` [U-Boot] [PATCH V4 2/9] EXYNOS5: FDT: Add DWMMC device node data Amar
2013-01-10 15:21 ` Simon Glass
2013-01-15 9:11 ` Amarendra Reddy
2013-01-04 9:34 ` [U-Boot] [PATCH V4 3/9] DWMMC: Initialise dwmci and resolve EMMC read write issues Amar
2013-01-10 15:26 ` Simon Glass
2013-01-11 4:01 ` Jaehoon Chung
2013-01-11 5:43 ` Simon Glass
2013-01-15 8:26 ` Amarendra Reddy
2013-01-04 9:34 ` [U-Boot] [PATCH V4 4/9] EXYNOS5: DWMMC: Added FDT support for DWMMC Amar
2013-01-10 15:33 ` Simon Glass
2013-01-11 4:12 ` Jaehoon Chung
2013-01-11 5:44 ` Simon Glass
2013-01-11 13:06 ` Amarendra Reddy
2013-01-22 5:23 ` Joonyoung Shim
2013-01-22 6:41 ` Amarendra Reddy
2013-01-04 9:34 ` [U-Boot] [PATCH V4 5/9] EXYNOS5: DWMMC: API to set mmc clock divisor Amar
2013-01-10 15:35 ` Simon Glass
2013-01-11 3:52 ` Jaehoon Chung
2013-01-11 13:23 ` Amarendra Reddy
2013-01-11 14:28 ` Simon Glass
2013-01-04 9:34 ` [U-Boot] [PATCH V4 6/9] SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT Amar
2013-01-10 16:57 ` Simon Glass
2013-01-11 17:58 ` Amarendra Reddy
2013-01-12 16:41 ` Simon Glass
2013-01-15 9:16 ` Amarendra Reddy
2013-01-04 9:34 ` [U-Boot] [PATCH V4 7/9] MMC: APIs to support resize of EMMC boot partition Amar
2013-01-04 10:27 ` Jaehoon Chung
2013-01-07 4:19 ` Amarendra Reddy
2013-01-07 4:34 ` Jaehoon Chung
2013-01-07 5:54 ` Amarendra Reddy
2013-01-07 9:23 ` Jaehoon Chung
2013-01-04 9:34 ` [U-Boot] [PATCH V4 8/9] SMDK5250: Enable EMMC booting Amar
2013-01-10 16:39 ` Simon Glass
2013-01-15 9:14 ` Amarendra Reddy
2013-01-04 9:34 ` [U-Boot] [PATCH V4 9/9] COMMON: MMC: Command to support EMMC booting and to Amar
2013-01-10 16:46 ` Simon Glass
2013-01-11 3:54 ` Jaehoon Chung
2013-01-11 5:41 ` Simon Glass
2013-01-11 13:50 ` Amarendra Reddy
2013-01-11 14:31 ` Simon Glass
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox