On Tue, Mar 17, 2015 at 08:59:10AM +0000, Haojian Zhuang wrote:
If mmc controler is accessed in bootloader, it's required to execute disable boot before resetting the controller & enabling the clock in kernel driver.
Signed-off-by: Haojian Zhuang haojian.zhuang@linaro.org
.../devicetree/bindings/mmc/k3-dw-mshc.txt | 7 +++++ drivers/mmc/host/dw_mmc-k3.c | 33 ++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 1 + 3 files changed, 41 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt index 3b35449..cf12cfa 100644 --- a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -14,6 +14,13 @@ Required Properties:
- compatible: should be one of the following.
- "hisilicon,hi4511-dw-mshc": for controllers with hi4511 specific extensions.
+Optional Properties:
+* "hisilicon,disable-boot"
- Disable boot before reseting mmc controller and enabling clocks. It's
- required on Hisilicon Hi6220 SoC if the mmc controller is accessed in
- bootloader.
I don't follow. Why do we need another property?
What exactly does this cause to happen at the MMC controller prior to the reset, why exactly is this necessary, and why can we not always do this regardless?
That patch looks like we're poking the device prior to resetting it, which seems completely backwards.
Also, the description above seems to rely on the kernel behaviour w.r.t. the reset and clocking, which isn't great.
Mark.
Example: /* for Hi3620 */ diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 83a9f49..3042a7c 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/delay.h> #include <linux/mmc/host.h> #include <linux/mmc/dw_mmc.h> #include <linux/of_address.h> @@ -29,8 +30,40 @@ static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) host->bus_hz = clk_get_rate(host->ciu_clk); } +static void disable_boot(struct dw_mci *host) +{
- int timeout = 0;
- unsigned int data;
- mci_writel(host, CTRL, SDMMC_CTRL_FIFO_RESET);
- mci_writel(host, CMD, SDMMC_CMD_START | SDMMC_CMD_DISABLE_BOOT);
- while (1) {
data = mci_readl(host, CMD) & 0x80000000;
if (data == 0)
break;
if (timeout < 2000) {
timeout++;
mdelay(1);
} else {
dev_warn(host->dev, "failed to stop MMC\n");
break;
}
- }
+}
+static int dw_mci_k3_parse_dt(struct dw_mci *host) +{
- struct device_node *np = host->dev->of_node;
- if (of_find_property(np, "hisilicon,disable-boot", NULL)) {
disable_boot(host);
- }
- return 0;
+}
static const struct dw_mci_drv_data k3_drv_data = { .set_ios = dw_mci_k3_set_ios,
- .parse_dt = dw_mci_k3_parse_dt,
}; static const struct of_device_id dw_mci_k3_match[] = { diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 01b99e8..8c5977b 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -115,6 +115,7 @@ #define SDMMC_CMD_START BIT(31) #define SDMMC_CMD_USE_HOLD_REG BIT(29) #define SDMMC_CMD_VOLT_SWITCH BIT(28) +#define SDMMC_CMD_DISABLE_BOOT BIT(26) #define SDMMC_CMD_CCS_EXP BIT(23) #define SDMMC_CMD_CEATA_RD BIT(22)
#define SDMMC_CMD_UPD_CLK BIT(21)
1.9.1
Dev mailing list Dev@lists.96boards.org https://lists.96boards.org/mailman/listinfo/dev