From ac5efc358bd6257c2553580d122ae85ffdb0391b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 21 Jul 2017 23:11:59 +0200 Subject: [PATCH 01/47] mmc: uniphier-sd: Fix long response processing The long response entry 0..3 LSByte comes from the next response register MSByte, not from the next response register LSByte. Fix this to make the driver report correct values in response 136 . Signed-off-by: Marek Vasut Cc: Masahiro Yamada Cc: Jaehoon Chung Acked-by: Masahiro Yamada --- drivers/mmc/uniphier-sd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 3c462bd583..e272b14153 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -470,13 +470,13 @@ static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, u32 rsp_71_40 = readl(priv->regbase + UNIPHIER_SD_RSP32); u32 rsp_39_8 = readl(priv->regbase + UNIPHIER_SD_RSP10); - cmd->response[0] = (rsp_127_104 & 0xffffff) << 8 | - (rsp_103_72 & 0xff); - cmd->response[1] = (rsp_103_72 & 0xffffff) << 8 | - (rsp_71_40 & 0xff); - cmd->response[2] = (rsp_71_40 & 0xffffff) << 8 | - (rsp_39_8 & 0xff); - cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; + cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) | + ((rsp_103_72 & 0xff000000) >> 24); + cmd->response[1] = ((rsp_103_72 & 0x00ffffff) << 8) | + ((rsp_71_40 & 0xff000000) >> 24); + cmd->response[2] = ((rsp_71_40 & 0x00ffffff) << 8) | + ((rsp_39_8 & 0xff000000) >> 24); + cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; } else { /* bit 39-8 */ cmd->response[0] = readl(priv->regbase + UNIPHIER_SD_RSP10); From d1c18ca1103956087f303cf6a28fc84ba5b25922 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 21 Jul 2017 23:22:54 +0200 Subject: [PATCH 02/47] mmc: sh_sdhi: Add DM and DT probing support Add MMC DM and DT probing support into the SH SDHI driver. This patch abstracts out the common bits of the send command and set ios functions, so they can be used both by DM and non DM setups and adds the DM probe support. Signed-off-by: Marek Vasut Cc: Hiroyuki Yokoyama Cc: Nobuhiro Iwamatsu Cc: Jaehoon Chung Reviewed-by: Nobuhiro Iwamatsu --- drivers/mmc/sh_sdhi.c | 165 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 145 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index d181b63905..fd710399b6 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -13,15 +13,18 @@ #include #include #include +#include #include -#include +#include +#include +#include #include #include #define DRIVER_NAME "sh-sdhi" struct sh_sdhi_host { - unsigned long addr; + void __iomem *addr; int ch; int bus_shift; unsigned long quirks; @@ -50,11 +53,6 @@ static inline u16 sh_sdhi_readw(struct sh_sdhi_host *host, int reg) return readw(host->addr + (reg << host->bus_shift)); } -static void *mmc_priv(struct mmc *mmc) -{ - return (void *)mmc->priv; -} - static void sh_sdhi_detect(struct sh_sdhi_host *host) { sh_sdhi_writew(host, SDHI_OPTION, @@ -634,23 +632,17 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, return ret; } -static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int sh_sdhi_send_cmd_common(struct sh_sdhi_host *host, + struct mmc_cmd *cmd, struct mmc_data *data) { - struct sh_sdhi_host *host = mmc_priv(mmc); - int ret; - host->sd_error = 0; - ret = sh_sdhi_start_cmd(host, data, cmd); - - return ret; + return sh_sdhi_start_cmd(host, data, cmd); } -static int sh_sdhi_set_ios(struct mmc *mmc) +static int sh_sdhi_set_ios_common(struct sh_sdhi_host *host, struct mmc *mmc) { int ret; - struct sh_sdhi_host *host = mmc_priv(mmc); ret = sh_sdhi_clock_control(host, mmc->clock); if (ret) @@ -674,9 +666,8 @@ static int sh_sdhi_set_ios(struct mmc *mmc) return 0; } -static int sh_sdhi_initialize(struct mmc *mmc) +static int sh_sdhi_initialize_common(struct sh_sdhi_host *host) { - struct sh_sdhi_host *host = mmc_priv(mmc); int ret = sh_sdhi_sync_reset(host); sh_sdhi_writew(host, SDHI_PORTSEL, USE_1PORT); @@ -692,6 +683,34 @@ static int sh_sdhi_initialize(struct mmc *mmc) return ret; } +#ifndef CONFIG_DM_MMC +static void *mmc_priv(struct mmc *mmc) +{ + return (void *)mmc->priv; +} + +static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + + return sh_sdhi_send_cmd_common(host, cmd, data); +} + +static int sh_sdhi_set_ios(struct mmc *mmc) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + + return sh_sdhi_set_ios_common(host, mmc); +} + +static int sh_sdhi_initialize(struct mmc *mmc) +{ + struct sh_sdhi_host *host = mmc_priv(mmc); + + return sh_sdhi_initialize_common(host); +} + static const struct mmc_ops sh_sdhi_ops = { .send_cmd = sh_sdhi_send_cmd, .set_ios = sh_sdhi_set_ios, @@ -743,7 +762,7 @@ int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks) } host->ch = ch; - host->addr = addr; + host->addr = (void __iomem *)addr; host->quirks = quirks; if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) @@ -757,3 +776,109 @@ error: free(host); return ret; } + +#else + +struct sh_sdhi_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +int sh_sdhi_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct sh_sdhi_host *host = dev_get_priv(dev); + + return sh_sdhi_send_cmd_common(host, cmd, data); +} + +int sh_sdhi_dm_set_ios(struct udevice *dev) +{ + struct sh_sdhi_host *host = dev_get_priv(dev); + struct mmc *mmc = mmc_get_mmc_dev(dev); + + return sh_sdhi_set_ios_common(host, mmc); +} + +static const struct dm_mmc_ops sh_sdhi_dm_ops = { + .send_cmd = sh_sdhi_dm_send_cmd, + .set_ios = sh_sdhi_dm_set_ios, +}; + +static int sh_sdhi_dm_bind(struct udevice *dev) +{ + struct sh_sdhi_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} + +static int sh_sdhi_dm_probe(struct udevice *dev) +{ + struct sh_sdhi_plat *plat = dev_get_platdata(dev); + struct sh_sdhi_host *host = dev_get_priv(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + const u32 quirks = dev_get_driver_data(dev); + fdt_addr_t base; + + base = devfdt_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + host->addr = devm_ioremap(dev, base, SZ_2K); + if (!host->addr) + return -ENOMEM; + + host->quirks = quirks; + + if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) + host->bus_shift = 2; + else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF) + host->bus_shift = 1; + + plat->cfg.name = dev->name; + plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; + + switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", + 1)) { + case 8: + plat->cfg.host_caps |= MMC_MODE_8BIT; + break; + case 4: + plat->cfg.host_caps |= MMC_MODE_4BIT; + break; + case 1: + break; + default: + dev_err(dev, "Invalid \"bus-width\" value\n"); + return -EINVAL; + } + + sh_sdhi_initialize_common(host); + + plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; + plat->cfg.f_min = CLKDEV_INIT; + plat->cfg.f_max = CLKDEV_HS_DATA; + plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + upriv->mmc = &plat->mmc; + + return 0; +} + +static const struct udevice_id sh_sdhi_sd_match[] = { + { .compatible = "renesas,sdhi-r8a7795", .data = SH_SDHI_QUIRK_64BIT_BUF }, + { .compatible = "renesas,sdhi-r8a7796", .data = SH_SDHI_QUIRK_64BIT_BUF }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sh_sdhi_mmc) = { + .name = "sh-sdhi-mmc", + .id = UCLASS_MMC, + .of_match = sh_sdhi_sd_match, + .bind = sh_sdhi_dm_bind, + .probe = sh_sdhi_dm_probe, + .priv_auto_alloc_size = sizeof(struct sh_sdhi_host), + .platdata_auto_alloc_size = sizeof(struct sh_sdhi_plat), + .ops = &sh_sdhi_dm_ops, +}; +#endif From a3f0a7d5b50aa558ecab1fc3a9f5d773eac94051 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 21 Jul 2017 23:22:55 +0200 Subject: [PATCH 03/47] mmc: sh_sdhi: Fix the ACMD handling The command handling in this driver is awful, esp. because the driver depends on command numbers to determine whether this is APPCMD or not. Also, handling of command RSP response types is totally wrong. This patch at least plucks out some of the custom command encoding and fixes the APPCMD handling. The RSP handling still needs work, yet that might not be needed as it turns out the uniphier-sd.c driver is in much better shape and supports the same IP, so we might be able to just drop this driver in favor of the uniphier one. Signed-off-by: Marek Vasut Cc: Hiroyuki Yokoyama Cc: Nobuhiro Iwamatsu Cc: Jaehoon Chung Reviewed-by: Nobuhiro Iwamatsu --- arch/arm/mach-rmobile/include/mach/sh_sdhi.h | 5 - drivers/mmc/sh_sdhi.c | 107 ++++++++++--------- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/arch/arm/mach-rmobile/include/mach/sh_sdhi.h b/arch/arm/mach-rmobile/include/mach/sh_sdhi.h index 1fb0648b12..00a135faa1 100644 --- a/arch/arm/mach-rmobile/include/mach/sh_sdhi.h +++ b/arch/arm/mach-rmobile/include/mach/sh_sdhi.h @@ -49,11 +49,6 @@ /* SDHI CMD VALUE */ #define CMD_MASK 0x0000ffff -#define SDHI_APP 0x0040 -#define SDHI_MMC_SEND_OP_COND 0x0701 -#define SDHI_SD_APP_SEND_SCR 0x0073 -#define SDHI_SD_SWITCH 0x1C06 -#define SDHI_MMC_SEND_EXT_CSD 0x1C08 /* SDHI_PORTSEL */ #define USE_1PORT (1 << 8) /* 1 port */ diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index fd710399b6..3c5616e507 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -31,6 +31,7 @@ struct sh_sdhi_host { unsigned char wait_int; unsigned char sd_error; unsigned char detect_waiting; + unsigned char app_cmd; }; static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val) @@ -475,65 +476,64 @@ static void sh_sdhi_get_response(struct sh_sdhi_host *host, struct mmc_cmd *cmd) static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host, struct mmc_data *data, unsigned short opc) { - switch (opc) { - case SD_CMD_APP_SEND_OP_COND: - case SD_CMD_APP_SEND_SCR: - opc |= SDHI_APP; - break; - case SD_CMD_APP_SET_BUS_WIDTH: - /* SD_APP_SET_BUS_WIDTH*/ + if (host->app_cmd) { if (!data) - opc |= SDHI_APP; - else /* SD_SWITCH */ - opc = SDHI_SD_SWITCH; - break; - case MMC_CMD_SEND_OP_COND: - opc = SDHI_MMC_SEND_OP_COND; - break; - case MMC_CMD_SEND_EXT_CSD: - if (data) - opc = SDHI_MMC_SEND_EXT_CSD; - break; - default: - break; + host->app_cmd = 0; + return opc | BIT(6); + } + + switch (opc) { + case MMC_CMD_SWITCH: + return opc | (data ? 0x1c00 : 0x40); + case MMC_CMD_SEND_EXT_CSD: + return opc | (data ? 0x1c00 : 0); + case MMC_CMD_SEND_OP_COND: + return opc | 0x0700; + case MMC_CMD_APP_CMD: + host->app_cmd = 1; + default: + return opc; } - return opc; } static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host, struct mmc_data *data, unsigned short opc) { - unsigned short ret; - - switch (opc) { - case MMC_CMD_READ_MULTIPLE_BLOCK: - ret = sh_sdhi_multi_read(host, data); - break; - case MMC_CMD_WRITE_MULTIPLE_BLOCK: - ret = sh_sdhi_multi_write(host, data); - break; - case MMC_CMD_WRITE_SINGLE_BLOCK: - ret = sh_sdhi_single_write(host, data); - break; - case MMC_CMD_READ_SINGLE_BLOCK: - case SDHI_SD_APP_SEND_SCR: - case SDHI_SD_SWITCH: /* SD_SWITCH */ - case SDHI_MMC_SEND_EXT_CSD: - ret = sh_sdhi_single_read(host, data); - break; - default: - printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); - ret = -EINVAL; - break; + if (host->app_cmd) { + host->app_cmd = 0; + switch (opc) { + case SD_CMD_APP_SEND_SCR: + case SD_CMD_APP_SD_STATUS: + return sh_sdhi_single_read(host, data); + default: + printf(DRIVER_NAME": SD: NOT SUPPORT APP CMD = d'%04d\n", + opc); + return -EINVAL; + } + } else { + switch (opc) { + case MMC_CMD_WRITE_MULTIPLE_BLOCK: + return sh_sdhi_multi_write(host, data); + case MMC_CMD_READ_MULTIPLE_BLOCK: + return sh_sdhi_multi_read(host, data); + case MMC_CMD_WRITE_SINGLE_BLOCK: + return sh_sdhi_single_write(host, data); + case MMC_CMD_READ_SINGLE_BLOCK: + case MMC_CMD_SWITCH: + case MMC_CMD_SEND_EXT_CSD:; + return sh_sdhi_single_read(host, data); + default: + printf(DRIVER_NAME": SD: NOT SUPPORT CMD = d'%04d\n", opc); + return -EINVAL; + } } - return ret; } static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, struct mmc_data *data, struct mmc_cmd *cmd) { long time; - unsigned short opc = cmd->cmdidx; + unsigned short shcmd, opc = cmd->cmdidx; int ret = 0; unsigned long timeout; @@ -561,7 +561,8 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, } sh_sdhi_writew(host, SDHI_SIZE, data->blocksize); } - opc = sh_sdhi_set_cmd(host, data, opc); + + shcmd = sh_sdhi_set_cmd(host, data, opc); /* * U-Boot cannot use interrupt. @@ -592,11 +593,12 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, INFO2M_RESP_TIMEOUT | INFO2M_ILA) & sh_sdhi_readw(host, SDHI_INFO2_MASK)); - sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK)); - + sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(shcmd & CMD_MASK)); time = sh_sdhi_wait_interrupt_flag(host); - if (!time) + if (!time) { + host->app_cmd = 0; return sh_sdhi_error_manage(host); + } if (host->sd_error) { switch (cmd->cmdidx) { @@ -614,15 +616,20 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, } host->sd_error = 0; host->wait_int = 0; + host->app_cmd = 0; return ret; } - if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) + + if (sh_sdhi_readw(host, SDHI_INFO1) & INFO1_RESP_END) { + host->app_cmd = 0; return -EINVAL; + } if (host->wait_int) { sh_sdhi_get_response(host, cmd); host->wait_int = 0; } + if (data) ret = sh_sdhi_data_trans(host, data, opc); From 8cd46cba5397e134e6217310d5b0529b3fa46274 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 21 Jul 2017 23:22:56 +0200 Subject: [PATCH 04/47] mmc: sd_sdhi: Enable clock using clock framework Since we now have clock driver for the RCar Gen3 , add support for enabling the clock into the SH SDHI driver to prevent hacks in the board files. Signed-off-by: Marek Vasut Cc: Nobuhiro Iwamatsu Cc: Jaehoon Chung Reviewed-by: Nobuhiro Iwamatsu --- drivers/mmc/sh_sdhi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index 3c5616e507..eef061abb2 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -20,6 +20,7 @@ #include #include #include +#include #define DRIVER_NAME "sh-sdhi" @@ -824,8 +825,10 @@ static int sh_sdhi_dm_probe(struct udevice *dev) struct sh_sdhi_plat *plat = dev_get_platdata(dev); struct sh_sdhi_host *host = dev_get_priv(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct clk sh_sdhi_clk; const u32 quirks = dev_get_driver_data(dev); fdt_addr_t base; + int ret; base = devfdt_get_addr(dev); if (base == FDT_ADDR_T_NONE) @@ -835,6 +838,18 @@ static int sh_sdhi_dm_probe(struct udevice *dev) if (!host->addr) return -ENOMEM; + ret = clk_get_by_index(dev, 0, &sh_sdhi_clk); + if (ret) { + debug("failed to get clock, ret=%d\n", ret); + return ret; + } + + ret = clk_enable(&sh_sdhi_clk); + if (ret) { + debug("failed to enable clock, ret=%d\n", ret); + return ret; + } + host->quirks = quirks; if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF) From 722b150e6f51290f7c8686a5284f8770db27e140 Mon Sep 17 00:00:00 2001 From: "Wenyou.Yang@microchip.com" Date: Wed, 26 Jul 2017 14:35:42 +0800 Subject: [PATCH 05/47] mmc: gen_atmel_mci: Fix wrong arguments used of bind() The bind() method is called before the device is probed and so the device has no private data, should use the platform data, and set up a new struct to hold the mmc and cfg members. Signed-off-by: Wenyou Yang Reviewed-by: Simon Glass --- drivers/mmc/gen_atmel_mci.c | 66 ++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index e9f061e55d..22154d13d7 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -36,13 +36,22 @@ DECLARE_GLOBAL_DATA_PTR; # define MCI_BUS 0 #endif -struct atmel_mci_priv { +#ifdef CONFIG_DM_MMC +struct atmel_mci_plat { + struct mmc mmc; struct mmc_config cfg; struct atmel_mci *mci; +}; +#endif + +struct atmel_mci_priv { +#ifndef CONFIG_DM_MMC + struct mmc_config cfg; + struct atmel_mci *mci; +#endif unsigned int initialized:1; unsigned int curr_clk; #ifdef CONFIG_DM_MMC - struct mmc mmc; ulong bus_clk_rate; #endif }; @@ -67,18 +76,21 @@ static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg) /* Setup for MCI Clock and Block Size */ #ifdef CONFIG_DM_MMC -static void mci_set_mode(struct atmel_mci_priv *priv, u32 hz, u32 blklen) +static void mci_set_mode(struct udevice *dev, u32 hz, u32 blklen) { - struct mmc *mmc = &priv->mmc; + struct atmel_mci_plat *plat = dev_get_platdata(dev); + struct atmel_mci_priv *priv = dev_get_priv(dev); + struct mmc *mmc = &plat->mmc; u32 bus_hz = priv->bus_clk_rate; + atmel_mci_t *mci = plat->mci; #else static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) { struct atmel_mci_priv *priv = mmc->priv; u32 bus_hz = get_mci_clk_rate(); + atmel_mci_t *mci = priv->mci; #endif - atmel_mci_t *mci = priv->mci; u32 clkdiv = 255; unsigned int version = atmel_mci_get_version(mci); u32 clkodd = 0; @@ -222,15 +234,17 @@ io_fail: static int atmel_mci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { + struct atmel_mci_plat *plat = dev_get_platdata(dev); struct atmel_mci_priv *priv = dev_get_priv(dev); struct mmc *mmc = mmc_get_mmc_dev(dev); + atmel_mci_t *mci = plat->mci; #else static int mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct atmel_mci_priv *priv = mmc->priv; -#endif atmel_mci_t *mci = priv->mci; +#endif u32 cmdr; u32 error_flags = 0; u32 status; @@ -362,22 +376,23 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) #ifdef CONFIG_DM_MMC static int atmel_mci_set_ios(struct udevice *dev) { - struct atmel_mci_priv *priv = dev_get_priv(dev); + struct atmel_mci_plat *plat = dev_get_platdata(dev); struct mmc *mmc = mmc_get_mmc_dev(dev); + atmel_mci_t *mci = plat->mci; #else /* Entered into mmc structure during driver init */ static int mci_set_ios(struct mmc *mmc) { struct atmel_mci_priv *priv = mmc->priv; -#endif atmel_mci_t *mci = priv->mci; +#endif int bus_width = mmc->bus_width; unsigned int version = atmel_mci_get_version(mci); int busw; /* Set the clock speed */ #ifdef CONFIG_DM_MMC - mci_set_mode(priv, mmc->clock, MMC_DEFAULT_BLKLEN); + mci_set_mode(dev, mmc->clock, MMC_DEFAULT_BLKLEN); #else mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN); #endif @@ -410,15 +425,17 @@ static int mci_set_ios(struct mmc *mmc) } #ifdef CONFIG_DM_MMC -static int atmel_mci_hw_init(struct atmel_mci_priv *priv) +static int atmel_mci_hw_init(struct udevice *dev) { + struct atmel_mci_plat *plat = dev_get_platdata(dev); + atmel_mci_t *mci = plat->mci; #else /* Entered into mmc structure during driver init */ static int mci_init(struct mmc *mmc) { struct atmel_mci_priv *priv = mmc->priv; -#endif atmel_mci_t *mci = priv->mci; +#endif /* Initialize controller */ writel(MMCI_BIT(SWRST), &mci->cr); /* soft reset */ @@ -433,7 +450,7 @@ static int mci_init(struct mmc *mmc) /* Set default clocks and blocklen */ #ifdef CONFIG_DM_MMC - mci_set_mode(priv, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); + mci_set_mode(dev, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); #else mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN); #endif @@ -509,12 +526,14 @@ static const struct dm_mmc_ops atmel_mci_mmc_ops = { .set_ios = atmel_mci_set_ios, }; -static void atmel_mci_setup_cfg(struct atmel_mci_priv *priv) +static void atmel_mci_setup_cfg(struct udevice *dev) { + struct atmel_mci_plat *plat = dev_get_platdata(dev); + struct atmel_mci_priv *priv = dev_get_priv(dev); struct mmc_config *cfg; u32 version; - cfg = &priv->cfg; + cfg = &plat->cfg; cfg->name = "Atmel mci"; cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; @@ -522,7 +541,7 @@ static void atmel_mci_setup_cfg(struct atmel_mci_priv *priv) * If the version is above 3.0, the capabilities of the 8-bit * bus width and high speed are supported. */ - version = atmel_mci_get_version(priv->mci); + version = atmel_mci_get_version(plat->mci); if ((version & 0xf00) >= 0x300) { cfg->host_caps = MMC_MODE_8BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz; @@ -568,7 +587,7 @@ failed: static int atmel_mci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - struct atmel_mci_priv *priv = dev_get_priv(dev); + struct atmel_mci_plat *plat = dev_get_platdata(dev); struct mmc *mmc; int ret; @@ -576,25 +595,25 @@ static int atmel_mci_probe(struct udevice *dev) if (ret) return ret; - priv->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev); + plat->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev); - atmel_mci_setup_cfg(priv); + atmel_mci_setup_cfg(dev); - mmc = &priv->mmc; - mmc->cfg = &priv->cfg; + mmc = &plat->mmc; + mmc->cfg = &plat->cfg; mmc->dev = dev; upriv->mmc = mmc; - atmel_mci_hw_init(priv); + atmel_mci_hw_init(dev); return 0; } static int atmel_mci_bind(struct udevice *dev) { - struct atmel_mci_priv *priv = dev_get_priv(dev); + struct atmel_mci_plat *plat = dev_get_platdata(dev); - return mmc_bind(dev, &priv->mmc, &priv->cfg); + return mmc_bind(dev, &plat->mmc, &plat->cfg); } static const struct udevice_id atmel_mci_ids[] = { @@ -608,6 +627,7 @@ U_BOOT_DRIVER(atmel_mci) = { .of_match = atmel_mci_ids, .bind = atmel_mci_bind, .probe = atmel_mci_probe, + .platdata_auto_alloc_size = sizeof(struct atmel_mci_plat), .priv_auto_alloc_size = sizeof(struct atmel_mci_priv), .ops = &atmel_mci_mmc_ops, }; From 745fb9c25e9fd4c59e375cf8f6e2eb8ff75d6d95 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:52 -0600 Subject: [PATCH 06/47] dm: core: Avoid calling dm_scan_fdt_dev() with of-platdata We cannot call dm_scan_fdt_dev() with of-platdata since there is no device tree. Fix this with an #if check. Fixes: 3be9a37 (dm: syscon: scan sub-nodes of the syscon node) Signed-off-by: Simon Glass --- drivers/core/syscon-uclass.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 2148469abc..a69937e63c 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -104,5 +104,8 @@ static const struct udevice_id generic_syscon_ids[] = { U_BOOT_DRIVER(generic_syscon) = { .name = "syscon", .id = UCLASS_SYSCON, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif .of_match = generic_syscon_ids, }; From 6faa4ed74df2d83cbb959ba799032da4249893b6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:53 -0600 Subject: [PATCH 07/47] dm: blk: Add a function to find an interface-type name Add a function to find the name of an interface type (e.g. "sata", "scsi") from the interface type enum. This is useful for generic code (not specific to SATA or SCSI, for example) that wants to display the type of interface it is dealing with. Signed-off-by: Simon Glass --- drivers/block/blk-uclass.c | 5 +++++ drivers/block/blk_legacy.c | 7 +++++++ include/blk.h | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index a3737badec..3adb92b58e 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -57,6 +57,11 @@ static enum uclass_id if_type_to_uclass_id(enum if_type if_type) return if_type_uclass_id[if_type]; } +const char *blk_get_if_type_name(enum if_type if_type) +{ + return if_typename_str[if_type]; +} + struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) { struct blk_desc *desc; diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c index 7b90a8a6e1..981872ecb3 100644 --- a/drivers/block/blk_legacy.c +++ b/drivers/block/blk_legacy.c @@ -38,6 +38,13 @@ static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) return NULL; } +const char *blk_get_if_type_name(enum if_type if_type) +{ + struct blk_driver *drv = blk_driver_lookup_type(if_type); + + return drv ? drv->if_typename : NULL; +} + /** * get_desc() - Get the block device descriptor for the given device number * diff --git a/include/blk.h b/include/blk.h index 61b56281b3..8672e32fe1 100644 --- a/include/blk.h +++ b/include/blk.h @@ -624,4 +624,12 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, */ int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart); +/** + * blk_get_if_type_name() - Get the name of an interface type + * + * @if_type: Interface type to check + * @return name of interface, or NULL if none + */ +const char *blk_get_if_type_name(enum if_type if_type); + #endif From 4395f6673901196b58821e2e9e37fb8e93b25528 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:54 -0600 Subject: [PATCH 08/47] dm: blk: Add a generic function for block device commands Most block devices provide a command (e.g. 'sata', 'scsi', 'ide') and these commands generally do the same thing. This makes it harder to maintain this code and keep it consistent. We now have a block device interface which is either implemented by driver model (when CONFIG_BLK is enabled) or with a legacy interface. Therefore it is possible to handle most of what these commands do with generic code. Add a new generic function to process block-device commands using the interface type and the current device number for that type. Signed-off-by: Simon Glass --- cmd/Makefile | 1 + cmd/blk_common.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++ include/blk.h | 12 ++++++ 3 files changed, 117 insertions(+) create mode 100644 cmd/blk_common.c diff --git a/cmd/Makefile b/cmd/Makefile index 13c86f8fcc..4a865bd7d7 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -15,6 +15,7 @@ obj-y += version.o # command obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_ARMFLASH) += armflash.o +obj-y += blk_common.o obj-$(CONFIG_SOURCE) += source.o obj-$(CONFIG_CMD_SOURCE) += source.o obj-$(CONFIG_CMD_BDI) += bdinfo.o diff --git a/cmd/blk_common.c b/cmd/blk_common.c new file mode 100644 index 0000000000..86c75e78d8 --- /dev/null +++ b/cmd/blk_common.c @@ -0,0 +1,104 @@ +/* + * Handling of common block commands + * + * Copyright (c) 2017 Google, Inc + * + * (C) Copyright 2000-2011 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#ifdef HAVE_BLOCK_DEVICE +int blk_common_cmd(int argc, char * const argv[], enum if_type if_type, + int *cur_devnump) +{ + const char *if_name = blk_get_if_type_name(if_type); + + switch (argc) { + case 0: + case 1: + return CMD_RET_USAGE; + case 2: + if (strncmp(argv[1], "inf", 3) == 0) { + blk_list_devices(if_type); + return 0; + } else if (strncmp(argv[1], "dev", 3) == 0) { + if (blk_print_device_num(if_type, *cur_devnump)) { + printf("\nno %s devices available\n", if_name); + return CMD_RET_FAILURE; + } + return 0; + } else if (strncmp(argv[1], "part", 4) == 0) { + if (blk_list_part(if_type)) + printf("\nno %s devices available\n", if_name); + return 0; + } + return CMD_RET_USAGE; + case 3: + if (strncmp(argv[1], "dev", 3) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + + if (!blk_show_device(if_type, dev)) { + *cur_devnump = dev; + printf("... is now current device\n"); + } else { + return CMD_RET_FAILURE; + } + return 0; + } else if (strncmp(argv[1], "part", 4) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + + if (blk_print_part_devnum(if_type, dev)) { + printf("\n%s device %d not available\n", + if_name, dev); + return CMD_RET_FAILURE; + } + return 0; + } + return CMD_RET_USAGE; + + default: /* at least 4 args */ + if (strcmp(argv[1], "read") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + + printf("\n%s read: device %d block # %lld, count %ld ... ", + if_name, *cur_devnump, (unsigned long long)blk, + cnt); + + n = blk_read_devnum(if_type, *cur_devnump, blk, cnt, + (ulong *)addr); + + printf("%ld blocks read: %s\n", n, + n == cnt ? "OK" : "ERROR"); + return n == cnt ? 0 : 1; + } else if (strcmp(argv[1], "write") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + + printf("\n%s write: device %d block # %lld, count %ld ... ", + if_name, *cur_devnump, (unsigned long long)blk, + cnt); + + n = blk_write_devnum(if_type, *cur_devnump, blk, cnt, + (ulong *)addr); + + printf("%ld blocks written: %s\n", n, + n == cnt ? "OK" : "ERROR"); + return n == cnt ? 0 : 1; + } else { + return CMD_RET_USAGE; + } + + return 0; + } +} +#endif diff --git a/include/blk.h b/include/blk.h index 8672e32fe1..a106f9ca0e 100644 --- a/include/blk.h +++ b/include/blk.h @@ -632,4 +632,16 @@ int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart); */ const char *blk_get_if_type_name(enum if_type if_type); +/** + * blk_common_cmd() - handle common commands with block devices + * + * @args: Number of arguments to the command (argv[0] is the command itself) + * @argv: Command arguments + * @if_type: Interface type + * @cur_devnump: Current device number for this interface type + * @return 0 if OK, CMD_RET_ERROR on error + */ +int blk_common_cmd(int argc, char * const argv[], enum if_type if_type, + int *cur_devnump); + #endif From e29e71e93ad9180eed008a12d720e810d87b5f3d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:55 -0600 Subject: [PATCH 09/47] dm: sata: Adjust the 'sata' command to use blk_common_cmd() Instead of having separate code in the 'sata' command, adjust it to use the common function. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- cmd/sata.c | 83 +----------------------------------------------------- 1 file changed, 1 insertion(+), 82 deletions(-) diff --git a/cmd/sata.c b/cmd/sata.c index 4c53022ff6..d34a56dccc 100644 --- a/cmd/sata.c +++ b/cmd/sata.c @@ -40,88 +40,7 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) sata_curr_device = rc; } - switch (argc) { - case 0: - case 1: - return CMD_RET_USAGE; - case 2: - if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(IF_TYPE_SATA); - return 0; - } else if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(IF_TYPE_SATA, - sata_curr_device)) { - printf("\nno SATA devices available\n"); - return CMD_RET_FAILURE; - } - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(IF_TYPE_SATA)) - puts("\nno SATA devices available\n"); - return 0; - } - return CMD_RET_USAGE; - case 3: - if (strncmp(argv[1], "dev", 3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (!blk_show_device(IF_TYPE_SATA, dev)) { - sata_curr_device = dev; - printf("... is now current device\n"); - } else { - return CMD_RET_FAILURE; - } - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (blk_print_part_devnum(IF_TYPE_SATA, dev)) { - printf("\nSATA device %d not available\n", - dev); - return CMD_RET_FAILURE; - } - return rc; - } - return CMD_RET_USAGE; - - default: /* at least 4 args */ - if (strcmp(argv[1], "read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nSATA read: device %d block # %ld, count %ld ... ", - sata_curr_device, blk, cnt); - - n = blk_read_devnum(IF_TYPE_SATA, sata_curr_device, blk, - cnt, (ulong *)addr); - - printf("%ld blocks read: %s\n", - n, (n==cnt) ? "OK" : "ERROR"); - return (n == cnt) ? 0 : 1; - } else if (strcmp(argv[1], "write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nSATA write: device %d block # %ld, count %ld ... ", - sata_curr_device, blk, cnt); - - n = blk_write_devnum(IF_TYPE_SATA, sata_curr_device, - blk, cnt, (ulong *)addr); - - printf("%ld blocks written: %s\n", - n, (n == cnt) ? "OK" : "ERROR"); - return (n == cnt) ? 0 : 1; - } else { - return CMD_RET_USAGE; - } - - return rc; - } + return blk_common_cmd(argc, argv, IF_TYPE_SATA, &sata_curr_device); } U_BOOT_CMD( From 1eaadd342310cc9a77c8ffbdb5d77af5f09fcf77 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:56 -0600 Subject: [PATCH 10/47] dm: scsi: Adjust the 'scsi' command to use blk_common_cmd() Instead of having separate code in the 'scsi' command, adjust it to use the common function. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- cmd/scsi.c | 79 +++--------------------------------------------------- 1 file changed, 3 insertions(+), 76 deletions(-) diff --git a/cmd/scsi.c b/cmd/scsi.c index 8e36de107e..b9d086fb6b 100644 --- a/cmd/scsi.c +++ b/cmd/scsi.c @@ -29,11 +29,7 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { int ret; - switch (argc) { - case 0: - case 1: - return CMD_RET_USAGE; - case 2: + if (argc == 2) { if (strncmp(argv[1], "res", 3) == 0) { printf("\nReset SCSI\n"); #ifndef CONFIG_DM_SCSI @@ -44,84 +40,15 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_FAILURE; return ret; } - if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(IF_TYPE_SCSI); - return 0; - } - if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) { - printf("\nno SCSI devices available\n"); - return CMD_RET_FAILURE; - } - - return 0; - } if (strncmp(argv[1], "scan", 4) == 0) { ret = scsi_scan(true); if (ret) return CMD_RET_FAILURE; return ret; } - if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(IF_TYPE_SCSI)) - printf("\nno SCSI devices available\n"); - return 0; - } - return CMD_RET_USAGE; - case 3: - if (strncmp(argv[1], "dev", 3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); + } - if (!blk_show_device(IF_TYPE_SCSI, dev)) { - scsi_curr_dev = dev; - printf("... is now current device\n"); - } else { - return CMD_RET_FAILURE; - } - return 0; - } - if (strncmp(argv[1], "part", 4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (blk_print_part_devnum(IF_TYPE_SCSI, dev)) { - printf("\nSCSI device %d not available\n", - dev); - return CMD_RET_FAILURE; - } - return 0; - } - return CMD_RET_USAGE; - default: - /* at least 4 args */ - if (strcmp(argv[1], "read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong blk = simple_strtoul(argv[3], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - - printf("\nSCSI read: device %d block # %ld, count %ld ... ", - scsi_curr_dev, blk, cnt); - n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, - cnt, (ulong *)addr); - printf("%ld blocks read: %s\n", n, - n == cnt ? "OK" : "ERROR"); - return 0; - } else if (strcmp(argv[1], "write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong blk = simple_strtoul(argv[3], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - - printf("\nSCSI write: device %d block # %ld, count %ld ... ", - scsi_curr_dev, blk, cnt); - n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, - cnt, (ulong *)addr); - printf("%ld blocks written: %s\n", n, - n == cnt ? "OK" : "ERROR"); - return 0; - } - } /* switch */ - return CMD_RET_USAGE; + return blk_common_cmd(argc, argv, IF_TYPE_SCSI, &scsi_curr_dev); } U_BOOT_CMD( From 09ed0d616d62f87bf854532e4e01950fbcd0bb42 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:57 -0600 Subject: [PATCH 11/47] dm: ide: Adjust the 'ide' command to use blk_common_cmd() Instead of having separate code in the 'ide' command, adjust it to use the common function. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- cmd/ide.c | 107 ++---------------------------------------------------- 1 file changed, 3 insertions(+), 104 deletions(-) diff --git a/cmd/ide.c b/cmd/ide.c index 10fb2f95a7..e3c32420cf 100644 --- a/cmd/ide.c +++ b/cmd/ide.c @@ -34,116 +34,15 @@ static int curr_device = -1; int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - int rcode = 0; - - switch (argc) { - case 0: - case 1: - return CMD_RET_USAGE; - case 2: + if (argc == 2) { if (strncmp(argv[1], "res", 3) == 0) { puts("\nReset IDE: "); ide_init(); return 0; - } else if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(IF_TYPE_IDE); - return 0; - - } else if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(IF_TYPE_IDE, curr_device)) { - printf("\nno IDE devices available\n"); - return CMD_RET_FAILURE; - } - - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(IF_TYPE_IDE)) - printf("\nno IDE devices available\n"); - return 1; } - return CMD_RET_USAGE; - case 3: - if (strncmp(argv[1], "dev", 3) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (!blk_show_device(IF_TYPE_IDE, dev)) { - curr_device = dev; - printf("... is now current device\n"); - } else { - return CMD_RET_FAILURE; - } - return 0; - } else if (strncmp(argv[1], "part", 4) == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - - if (blk_print_part_devnum(IF_TYPE_IDE, dev)) { - printf("\nIDE device %d not available\n", dev); - return CMD_RET_FAILURE; - } - return 1; - } - - return CMD_RET_USAGE; - default: - /* at least 4 args */ - - if (strcmp(argv[1], "read") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - -#ifdef CONFIG_SYS_64BIT_LBA - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); - - printf("\nIDE read: device %d block # %lld, count %ld...", - curr_device, blk, cnt); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nIDE read: device %d block # %ld, count %ld...", - curr_device, blk, cnt); -#endif - - n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt, - (ulong *)addr); - - printf("%ld blocks read: %s\n", - n, (n == cnt) ? "OK" : "ERROR"); - if (n == cnt) - return 0; - else - return 1; - } else if (strcmp(argv[1], "write") == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong cnt = simple_strtoul(argv[4], NULL, 16); - ulong n; - -#ifdef CONFIG_SYS_64BIT_LBA - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); - - printf("\nIDE write: device %d block # %lld, count %ld...", - curr_device, blk, cnt); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); - - printf("\nIDE write: device %d block # %ld, count %ld...", - curr_device, blk, cnt); -#endif - n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt, - (ulong *)addr); - - printf("%ld blocks written: %s\n", n, - n == cnt ? "OK" : "ERROR"); - if (n == cnt) - return 0; - else - return 1; - } else { - return CMD_RET_USAGE; - } - - return rcode; } + + return blk_common_cmd(argc, argv, IF_TYPE_IDE, &curr_device); } int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) From c16ad675d58e3e4b0ced00004ddef450dc62314a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:58 -0600 Subject: [PATCH 12/47] dm: usb: Adjust the 'usb' command to use blk_common_cmd() Instead of having separate code in the 'usb' command, adjust it to use the common function. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- cmd/usb.c | 111 ++---------------------------------------------------- 1 file changed, 3 insertions(+), 108 deletions(-) diff --git a/cmd/usb.c b/cmd/usb.c index 992d414081..d95bcf5c8e 100644 --- a/cmd/usb.c +++ b/cmd/usb.c @@ -621,9 +621,6 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) struct usb_device *udev = NULL; int i; extern char usb_started; -#ifdef CONFIG_USB_STORAGE - struct blk_desc *stor_dev; -#endif if (argc < 2) return CMD_RET_USAGE; @@ -712,112 +709,10 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); - if (strncmp(argv[1], "part", 4) == 0) { - int devno, ok = 0; - if (argc == 2) { - for (devno = 0; ; ++devno) { - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - devno); - if (stor_dev == NULL) - break; - if (stor_dev->type != DEV_TYPE_UNKNOWN) { - ok++; - if (devno) - printf("\n"); - debug("print_part of %x\n", devno); - part_print(stor_dev); - } - } - } else { - devno = simple_strtoul(argv[2], NULL, 16); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno); - if (stor_dev != NULL && - stor_dev->type != DEV_TYPE_UNKNOWN) { - ok++; - debug("print_part of %x\n", devno); - part_print(stor_dev); - } - } - if (!ok) { - printf("\nno USB devices available\n"); - return 1; - } - return 0; - } - if (strcmp(argv[1], "read") == 0) { - if (usb_stor_curr_dev < 0) { - printf("no current device selected\n"); - return 1; - } - if (argc == 5) { - unsigned long addr = simple_strtoul(argv[2], NULL, 16); - unsigned long blk = simple_strtoul(argv[3], NULL, 16); - unsigned long cnt = simple_strtoul(argv[4], NULL, 16); - unsigned long n; - printf("\nUSB read: device %d block # %ld, count %ld" - " ... ", usb_stor_curr_dev, blk, cnt); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - usb_stor_curr_dev); - n = blk_dread(stor_dev, blk, cnt, (ulong *)addr); - printf("%ld blocks read: %s\n", n, - (n == cnt) ? "OK" : "ERROR"); - if (n == cnt) - return 0; - return 1; - } - } - if (strcmp(argv[1], "write") == 0) { - if (usb_stor_curr_dev < 0) { - printf("no current device selected\n"); - return 1; - } - if (argc == 5) { - unsigned long addr = simple_strtoul(argv[2], NULL, 16); - unsigned long blk = simple_strtoul(argv[3], NULL, 16); - unsigned long cnt = simple_strtoul(argv[4], NULL, 16); - unsigned long n; - printf("\nUSB write: device %d block # %ld, count %ld" - " ... ", usb_stor_curr_dev, blk, cnt); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - usb_stor_curr_dev); - n = blk_dwrite(stor_dev, blk, cnt, (ulong *)addr); - printf("%ld blocks write: %s\n", n, - (n == cnt) ? "OK" : "ERROR"); - if (n == cnt) - return 0; - return 1; - } - } - if (strncmp(argv[1], "dev", 3) == 0) { - if (argc == 3) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); - printf("\nUSB device %d: ", dev); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, dev); - if ((stor_dev == NULL) || - (stor_dev->if_type == IF_TYPE_UNKNOWN)) { - printf("unknown device\n"); - return 1; - } - printf("\n Device %d: ", dev); - dev_print(stor_dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) - return 1; - usb_stor_curr_dev = dev; - printf("... is now current device\n"); - return 0; - } else { - printf("\nUSB device %d: ", usb_stor_curr_dev); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, - usb_stor_curr_dev); - dev_print(stor_dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) - return 1; - return 0; - } - return 0; - } -#endif /* CONFIG_USB_STORAGE */ + return blk_common_cmd(argc, argv, IF_TYPE_USB, &usb_stor_curr_dev); +#else return CMD_RET_USAGE; +#endif /* CONFIG_USB_STORAGE */ } U_BOOT_CMD( From 7074b2a3649acc9fd6e5db8d24c2c9c6fc35d5df Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:34:59 -0600 Subject: [PATCH 13/47] dm: blk: Update return value in blk_create_devicef() This returns 'ret' but the value is always zero. Update it to simply return 0, for clarity. Signed-off-by: Simon Glass --- drivers/block/blk-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 3adb92b58e..3aec569d12 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -596,7 +596,7 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name, } device_set_name_alloced(*devp); - return ret; + return 0; } int blk_unbind_all(int if_type) From e88afccc44562912a681ce14e348408277d942cb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:00 -0600 Subject: [PATCH 14/47] dm: core: Add a comment about the device_remove() flags We should explain which flags are used for this function. Update the comment to indicate this. Signed-off-by: Simon Glass --- include/dm/device-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index 81ab893b60..eaeadd48d2 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -98,7 +98,7 @@ int device_probe(struct udevice *dev); * children are deactivated first. * * @dev: Pointer to device to remove - * @flags: Flags for selective device removal + * @flags: Flags for selective device removal (DM_REMOVE_...) * @return 0 if OK, -ve on error (an error here is normally a very bad thing) */ #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) From d7f094354cd1fce13e7307f06029d5f1533adbbe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:01 -0600 Subject: [PATCH 15/47] dm: sata: dwc_ahsata: Make functions static Some functions are not called from outside this file. Make these static to make that obvious. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 78572a5b73..b587ec4492 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -696,7 +696,7 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, return 0; } -void dwc_ahsata_flush_cache(int dev) +static void dwc_ahsata_flush_cache(int dev) { struct ahci_uc_priv *probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; @@ -793,7 +793,7 @@ u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt, return blkcnt; } -void dwc_ahsata_flush_cache_ext(int dev) +static void dwc_ahsata_flush_cache_ext(int dev) { struct ahci_uc_priv *probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; @@ -823,8 +823,8 @@ static void dwc_ahsata_init_wcache(int dev, u16 *id) probe_ent->flags |= SATA_FLAG_FLUSH_EXT; } -u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, + const void *buffer, int is_write) { u32 start, blks; u8 *addr; @@ -857,8 +857,8 @@ u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, return blkcnt; } -u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, + const void *buffer, int is_write) { u32 start, blks; u8 *addr; From 1dae3b06b770189c4ede3a168f566606aff00f9c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:02 -0600 Subject: [PATCH 16/47] dm: sata: dw_sata: Drop dwc_ahsata_rw_ncq_cmd() This function is not called from anywhere. Drop it. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 43 ---------------------------------------- 1 file changed, 43 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index b587ec4492..49552ca633 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -750,49 +750,6 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, return 0; } -u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt, - u8 *buffer, int is_write) -{ - struct ahci_uc_priv *probe_ent = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); - struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; - u64 block; - - if (sata_dev_desc[dev].lba48 != 1) { - printf("execute FPDMA command on non-LBA48 hard disk\n\r"); - return -1; - } - - block = (u64)start; - - memset(cfis, 0, sizeof(struct sata_fis_h2d)); - - cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; - cfis->pm_port_c = 0x80; /* is command */ - - cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE - : ATA_CMD_FPDMA_READ; - - cfis->lba_high_exp = (block >> 40) & 0xff; - cfis->lba_mid_exp = (block >> 32) & 0xff; - cfis->lba_low_exp = (block >> 24) & 0xff; - cfis->lba_high = (block >> 16) & 0xff; - cfis->lba_mid = (block >> 8) & 0xff; - cfis->lba_low = block & 0xff; - - cfis->device = ATA_LBA; - cfis->features_exp = (blkcnt >> 8) & 0xff; - cfis->features = blkcnt & 0xff; - - /* Use the latest queue */ - ahci_exec_ata_cmd(probe_ent, port, cfis, - buffer, ATA_SECT_SIZE * blkcnt, is_write); - - return blkcnt; -} - static void dwc_ahsata_flush_cache_ext(int dev) { struct ahci_uc_priv *probe_ent = From c5273acf5c1da65a6337f6ea8f563e728ab07452 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:03 -0600 Subject: [PATCH 17/47] dm: sata: dw_sata: Move exported functions to the end With the driver model conversion we will not have any exported functions. Move all exported functions to be together at the end of the file so that we can deal with them in one #ifdef block. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 124 +++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 49552ca633..8a030a1d11 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -556,68 +556,6 @@ static int ahci_port_start(struct ahci_uc_priv *probe_ent, return 0; } -int init_sata(int dev) -{ - int i; - u32 linkmap; - struct ahci_uc_priv *probe_ent = NULL; - -#if defined(CONFIG_MX6) - if (!is_mx6dq() && !is_mx6dqp()) - return 1; -#endif - if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { - printf("The sata index %d is out of ranges\n\r", dev); - return -1; - } - - ahci_init_one(dev); - - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - linkmap = probe_ent->link_port_map; - - if (0 == linkmap) { - printf("No port device detected!\n"); - return 1; - } - - for (i = 0; i < probe_ent->n_ports; i++) { - if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { - if (ahci_port_start(probe_ent, (u8)i)) { - printf("Can not start port %d\n", i); - return 1; - } - probe_ent->hard_port_no = i; - break; - } - } - - return 0; -} - -int reset_sata(int dev) -{ - struct ahci_uc_priv *probe_ent; - struct sata_host_regs *host_mmio; - - if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { - printf("The sata index %d is out of ranges\n\r", dev); - return -1; - } - - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - if (NULL == probe_ent) - /* not initialized, so nothing to reset */ - return 0; - - host_mmio = (struct sata_host_regs *)probe_ent->mmio_base; - setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); - while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) - udelay(100); - - return 0; -} - static void dwc_ahsata_print_info(int dev) { struct blk_desc *pdev = &(sata_dev_desc[dev]); @@ -847,6 +785,68 @@ static u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, return blkcnt; } +int init_sata(int dev) +{ + int i; + u32 linkmap; + struct ahci_uc_priv *probe_ent = NULL; + +#if defined(CONFIG_MX6) + if (!is_mx6dq() && !is_mx6dqp()) + return 1; +#endif + if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { + printf("The sata index %d is out of ranges\n\r", dev); + return -1; + } + + ahci_init_one(dev); + + probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + linkmap = probe_ent->link_port_map; + + if (0 == linkmap) { + printf("No port device detected!\n"); + return 1; + } + + for (i = 0; i < probe_ent->n_ports; i++) { + if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { + if (ahci_port_start(probe_ent, (u8)i)) { + printf("Can not start port %d\n", i); + return 1; + } + probe_ent->hard_port_no = i; + break; + } + } + + return 0; +} + +int reset_sata(int dev) +{ + struct ahci_uc_priv *probe_ent; + struct sata_host_regs *host_mmio; + + if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { + printf("The sata index %d is out of ranges\n\r", dev); + return -1; + } + + probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + if (NULL == probe_ent) + /* not initialized, so nothing to reset */ + return 0; + + host_mmio = (struct sata_host_regs *)probe_ent->mmio_base; + setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); + while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) + udelay(100); + + return 0; +} + int sata_port_status(int dev, int port) { struct sata_port_regs *port_mmio; From 09bb951bf3ebf2f94001e27add9b94e881a8cb75 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:04 -0600 Subject: [PATCH 18/47] dm: sata: dw_sata: Rename 'probe_ent' to uc_priv With driver model this becomes uclass-private data. Rename the parameter varable to reflect this. With the driver model conversion we will not have any exported functions. Move all exported functions to be together at the end of the file so that we can deal with them in one #ifdef block. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 175 +++++++++++++++++++-------------------- 1 file changed, 85 insertions(+), 90 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 8a030a1d11..2eb9c81957 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -100,11 +100,10 @@ static int waiting_for_cmd_completed(u8 *offset, return (i < timeout_msec) ? 0 : -1; } -static int ahci_setup_oobr(struct ahci_uc_priv *probe_ent, - int clk) +static int ahci_setup_oobr(struct ahci_uc_priv *uc_priv, int clk) { struct sata_host_regs *host_mmio = - (struct sata_host_regs *)probe_ent->mmio_base; + (struct sata_host_regs *)uc_priv->mmio_base; writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr)); writel(0x02060b14, &(host_mmio->oobr)); @@ -112,13 +111,13 @@ static int ahci_setup_oobr(struct ahci_uc_priv *probe_ent, return 0; } -static int ahci_host_init(struct ahci_uc_priv *probe_ent) +static int ahci_host_init(struct ahci_uc_priv *uc_priv) { u32 tmp, cap_save, num_ports; int i, j, timeout = 1000; struct sata_port_regs *port_mmio = NULL; struct sata_host_regs *host_mmio = - (struct sata_host_regs *)probe_ent->mmio_base; + (struct sata_host_regs *)uc_priv->mmio_base; int clk = mxc_get_clock(MXC_SATA_CLK); cap_save = readl(&(host_mmio->cap)); @@ -141,7 +140,7 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) /* Set timer 1ms */ writel(clk / 1000, &(host_mmio->timer1ms)); - ahci_setup_oobr(probe_ent, 0); + ahci_setup_oobr(uc_priv, 0); writel_with_flush(SATA_HOST_GHC_AE, &(host_mmio->ghc)); writel(cap_save, &(host_mmio->cap)); @@ -155,21 +154,19 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) * software to determine how many Ports are available and * which Port registers need to be initialized. */ - probe_ent->cap = readl(&(host_mmio->cap)); - probe_ent->port_map = readl(&(host_mmio->pi)); + uc_priv->cap = readl(&(host_mmio->cap)); + uc_priv->port_map = readl(&(host_mmio->pi)); /* Determine how many command slots the HBA supports */ - probe_ent->n_ports = - (probe_ent->cap & SATA_HOST_CAP_NP_MASK) + 1; + uc_priv->n_ports = (uc_priv->cap & SATA_HOST_CAP_NP_MASK) + 1; debug("cap 0x%x port_map 0x%x n_ports %d\n", - probe_ent->cap, probe_ent->port_map, probe_ent->n_ports); + uc_priv->cap, uc_priv->port_map, uc_priv->n_ports); - for (i = 0; i < probe_ent->n_ports; i++) { - probe_ent->port[i].port_mmio = - ahci_port_base(host_mmio, i); + for (i = 0; i < uc_priv->n_ports; i++) { + uc_priv->port[i].port_mmio = ahci_port_base(host_mmio, i); port_mmio = - (struct sata_port_regs *)probe_ent->port[i].port_mmio; + (struct sata_port_regs *)uc_priv->port[i].port_mmio; /* Ensure that the DWC_ahsata is in idle state */ tmp = readl(&(port_mmio->cmd)); @@ -263,7 +260,7 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) tmp = readl(&(port_mmio->ssts)); debug("Port %d status: 0x%x\n", i, tmp); if ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x03) - probe_ent->link_port_map |= (0x01 << i); + uc_priv->link_port_map |= (0x01 << i); } tmp = readl(&(host_mmio->ghc)); @@ -275,17 +272,17 @@ static int ahci_host_init(struct ahci_uc_priv *probe_ent) return 0; } -static void ahci_print_info(struct ahci_uc_priv *probe_ent) +static void ahci_print_info(struct ahci_uc_priv *uc_priv) { struct sata_host_regs *host_mmio = - (struct sata_host_regs *)probe_ent->mmio_base; + (struct sata_host_regs *)uc_priv->mmio_base; u32 vers, cap, impl, speed; const char *speed_s; const char *scc_s; vers = readl(&(host_mmio->vs)); - cap = probe_ent->cap; - impl = probe_ent->port_map; + cap = uc_priv->cap; + impl = uc_priv->port_map; speed = (cap & SATA_HOST_CAP_ISS_MASK) >> SATA_HOST_CAP_ISS_OFFSET; @@ -331,29 +328,29 @@ static void ahci_print_info(struct ahci_uc_priv *probe_ent) static int ahci_init_one(int pdev) { int rc; - struct ahci_uc_priv *probe_ent = NULL; + struct ahci_uc_priv *uc_priv = NULL; - probe_ent = malloc(sizeof(struct ahci_uc_priv)); - memset(probe_ent, 0, sizeof(struct ahci_uc_priv)); - probe_ent->dev = pdev; + uc_priv = malloc(sizeof(struct ahci_uc_priv)); + memset(uc_priv, 0, sizeof(struct ahci_uc_priv)); + uc_priv->dev = pdev; - probe_ent->host_flags = ATA_FLAG_SATA + uc_priv->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI; - probe_ent->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; + uc_priv->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; /* initialize adapter */ - rc = ahci_host_init(probe_ent); + rc = ahci_host_init(uc_priv); if (rc) goto err_out; - ahci_print_info(probe_ent); + ahci_print_info(uc_priv); - /* Save the private struct to block device struct */ - sata_dev_desc[pdev].priv = (void *)probe_ent; + /* Save the uc_private struct to block device struct */ + sata_dev_desc[pdev].priv = (void *)uc_priv; return 0; @@ -361,10 +358,10 @@ err_out: return rc; } -static int ahci_fill_sg(struct ahci_uc_priv *probe_ent, - u8 port, unsigned char *buf, int buf_len) +static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, + unsigned char *buf, int buf_len) { - struct ahci_ioports *pp = &(probe_ent->port[port]); + struct ahci_ioports *pp = &(uc_priv->port[port]); struct ahci_sg *ahci_sg = pp->cmd_tbl_sg; u32 sg_count, max_bytes; int i; @@ -408,11 +405,11 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts) #define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0) -static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, - u8 port, struct sata_fis_h2d *cfis, - u8 *buf, u32 buf_len, s32 is_write) +static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, + struct sata_fis_h2d *cfis, u8 *buf, u32 buf_len, + s32 is_write) { - struct ahci_ioports *pp = &(probe_ent->port[port]); + struct ahci_ioports *pp = &(uc_priv->port[port]); struct sata_port_regs *port_mmio = (struct sata_port_regs *)pp->port_mmio; u32 opts; @@ -433,7 +430,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, memcpy((u8 *)(pp->cmd_tbl), cfis, sizeof(struct sata_fis_h2d)); if (buf && buf_len) - sg_count = ahci_fill_sg(probe_ent, port, buf, buf_len); + sg_count = ahci_fill_sg(uc_priv, port, buf, buf_len); opts = (sizeof(struct sata_fis_h2d) >> 2) | (sg_count << 16); if (is_write) { opts |= 0x40; @@ -461,7 +458,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent, static void ahci_set_feature(u8 dev, u8 port) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; @@ -471,15 +468,14 @@ static void ahci_set_feature(u8 dev, u8 port) cfis->pm_port_c = 1 << 7; cfis->command = ATA_CMD_SET_FEATURES; cfis->features = SETFEATURES_XFER; - cfis->sector_count = ffs(probe_ent->udma_mask + 1) + 0x3e; + cfis->sector_count = ffs(uc_priv->udma_mask + 1) + 0x3e; - ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, READ_CMD); + ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, READ_CMD); } -static int ahci_port_start(struct ahci_uc_priv *probe_ent, - u8 port) +static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { - struct ahci_ioports *pp = &(probe_ent->port[port]); + struct ahci_ioports *pp = &(uc_priv->port[port]); struct sata_port_regs *port_mmio = (struct sata_port_regs *)pp->port_mmio; u32 port_status; @@ -574,11 +570,11 @@ static void dwc_ahsata_print_info(int dev) static void dwc_ahsata_identify(int dev, u16 *id) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; memset(cfis, 0, sizeof(struct sata_fis_h2d)); @@ -586,30 +582,29 @@ static void dwc_ahsata_identify(int dev, u16 *id) cfis->pm_port_c = 0x80; /* is command */ cfis->command = ATA_CMD_ID_ATA; - ahci_exec_ata_cmd(probe_ent, port, cfis, - (u8 *)id, ATA_ID_WORDS * 2, READ_CMD); + ahci_exec_ata_cmd(uc_priv, port, cfis, (u8 *)id, ATA_ID_WORDS * 2, + READ_CMD); ata_swap_buf_le16(id, ATA_ID_WORDS); } static void dwc_ahsata_xfer_mode(int dev, u16 *id) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - probe_ent->pio_mask = id[ATA_ID_PIO_MODES]; - probe_ent->udma_mask = id[ATA_ID_UDMA_MODES]; - debug("pio %04x, udma %04x\n\r", - probe_ent->pio_mask, probe_ent->udma_mask); + uc_priv->pio_mask = id[ATA_ID_PIO_MODES]; + uc_priv->udma_mask = id[ATA_ID_UDMA_MODES]; + debug("pio %04x, udma %04x\n\r", uc_priv->pio_mask, uc_priv->udma_mask); } static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; u32 block; block = start; @@ -627,8 +622,8 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, cfis->lba_low = block & 0xff; cfis->sector_count = (u8)(blkcnt & 0xff); - if (ahci_exec_ata_cmd(probe_ent, port, cfis, - buffer, ATA_SECT_SIZE * blkcnt, is_write) > 0) + if (ahci_exec_ata_cmd(uc_priv, port, cfis, buffer, + ATA_SECT_SIZE * blkcnt, is_write) > 0) return blkcnt; else return 0; @@ -636,11 +631,11 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, static void dwc_ahsata_flush_cache(int dev) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; memset(cfis, 0, sizeof(struct sata_fis_h2d)); @@ -648,17 +643,17 @@ static void dwc_ahsata_flush_cache(int dev) cfis->pm_port_c = 0x80; /* is command */ cfis->command = ATA_CMD_FLUSH; - ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0); + ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, 0); } static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; u64 block; block = (u64)start; @@ -681,8 +676,8 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, cfis->sector_count_exp = (blkcnt >> 8) & 0xff; cfis->sector_count = blkcnt & 0xff; - if (ahci_exec_ata_cmd(probe_ent, port, cfis, buffer, - ATA_SECT_SIZE * blkcnt, is_write) > 0) + if (ahci_exec_ata_cmd(uc_priv, port, cfis, buffer, + ATA_SECT_SIZE * blkcnt, is_write) > 0) return blkcnt; else return 0; @@ -690,11 +685,11 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, static void dwc_ahsata_flush_cache_ext(int dev) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; memset(cfis, 0, sizeof(struct sata_fis_h2d)); @@ -702,20 +697,20 @@ static void dwc_ahsata_flush_cache_ext(int dev) cfis->pm_port_c = 0x80; /* is command */ cfis->command = ATA_CMD_FLUSH_EXT; - ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, 0); + ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, 0); } static void dwc_ahsata_init_wcache(int dev, u16 *id) { - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id)) - probe_ent->flags |= SATA_FLAG_WCACHE; + uc_priv->flags |= SATA_FLAG_WCACHE; if (ata_id_has_flush(id)) - probe_ent->flags |= SATA_FLAG_FLUSH; + uc_priv->flags |= SATA_FLAG_FLUSH; if (ata_id_has_flush_ext(id)) - probe_ent->flags |= SATA_FLAG_FLUSH_EXT; + uc_priv->flags |= SATA_FLAG_FLUSH_EXT; } static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, @@ -789,7 +784,7 @@ int init_sata(int dev) { int i; u32 linkmap; - struct ahci_uc_priv *probe_ent = NULL; + struct ahci_uc_priv *uc_priv = NULL; #if defined(CONFIG_MX6) if (!is_mx6dq() && !is_mx6dqp()) @@ -802,21 +797,21 @@ int init_sata(int dev) ahci_init_one(dev); - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - linkmap = probe_ent->link_port_map; + uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + linkmap = uc_priv->link_port_map; if (0 == linkmap) { printf("No port device detected!\n"); return 1; } - for (i = 0; i < probe_ent->n_ports; i++) { + for (i = 0; i < uc_priv->n_ports; i++) { if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { - if (ahci_port_start(probe_ent, (u8)i)) { + if (ahci_port_start(uc_priv, (u8)i)) { printf("Can not start port %d\n", i); return 1; } - probe_ent->hard_port_no = i; + uc_priv->hard_port_no = i; break; } } @@ -826,7 +821,7 @@ int init_sata(int dev) int reset_sata(int dev) { - struct ahci_uc_priv *probe_ent; + struct ahci_uc_priv *uc_priv; struct sata_host_regs *host_mmio; if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) { @@ -834,12 +829,12 @@ int reset_sata(int dev) return -1; } - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - if (NULL == probe_ent) + uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + if (NULL == uc_priv) /* not initialized, so nothing to reset */ return 0; - host_mmio = (struct sata_host_regs *)probe_ent->mmio_base; + host_mmio = (struct sata_host_regs *)uc_priv->mmio_base; setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) udelay(100); @@ -850,7 +845,7 @@ int reset_sata(int dev) int sata_port_status(int dev, int port) { struct sata_port_regs *port_mmio; - struct ahci_uc_priv *probe_ent = NULL; + struct ahci_uc_priv *uc_priv = NULL; if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) return -EINVAL; @@ -858,8 +853,8 @@ int sata_port_status(int dev, int port) if (sata_dev_desc[dev].priv == NULL) return -ENODEV; - probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - port_mmio = (struct sata_port_regs *)probe_ent->port[port].port_mmio; + uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + port_mmio = (struct sata_port_regs *)uc_priv->port[port].port_mmio; return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK; } @@ -883,9 +878,9 @@ ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) { u32 rc; - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - u32 flags = probe_ent->flags; + u32 flags = uc_priv->flags; if (sata_dev_desc[dev].lba48) { rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, @@ -910,9 +905,9 @@ int scan_sata(int dev) u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; u16 *id; u64 n_sectors; - struct ahci_uc_priv *probe_ent = + struct ahci_uc_priv *uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - u8 port = probe_ent->hard_port_no; + u8 port = uc_priv->hard_port_no; struct blk_desc *pdev = &(sata_dev_desc[dev]); id = (u16 *)memalign(ARCH_DMA_MINALIGN, @@ -953,8 +948,8 @@ int scan_sata(int dev) } /* Get the NCQ queue depth from device */ - probe_ent->flags &= (~SATA_FLAG_Q_DEP_MASK); - probe_ent->flags |= ata_id_queue_depth(id); + uc_priv->flags &= (~SATA_FLAG_Q_DEP_MASK); + uc_priv->flags |= ata_id_queue_depth(id); /* Get the xfer mode from device */ dwc_ahsata_xfer_mode(dev, id); From 4b640dbcac372f0ff712cab76409600bde6e0b42 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:05 -0600 Subject: [PATCH 19/47] dm: sata: dw_sata: Drop unnecessary casts Most of the casts in this driver are not necessary. With driver model we do not cast from void *. Update the driver to follow this rule. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 60 +++++++++++++++------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 2eb9c81957..8db894b16f 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -102,8 +102,7 @@ static int waiting_for_cmd_completed(u8 *offset, static int ahci_setup_oobr(struct ahci_uc_priv *uc_priv, int clk) { - struct sata_host_regs *host_mmio = - (struct sata_host_regs *)uc_priv->mmio_base; + struct sata_host_regs *host_mmio = uc_priv->mmio_base; writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr)); writel(0x02060b14, &(host_mmio->oobr)); @@ -116,8 +115,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) u32 tmp, cap_save, num_ports; int i, j, timeout = 1000; struct sata_port_regs *port_mmio = NULL; - struct sata_host_regs *host_mmio = - (struct sata_host_regs *)uc_priv->mmio_base; + struct sata_host_regs *host_mmio = uc_priv->mmio_base; int clk = mxc_get_clock(MXC_SATA_CLK); cap_save = readl(&(host_mmio->cap)); @@ -165,8 +163,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) for (i = 0; i < uc_priv->n_ports; i++) { uc_priv->port[i].port_mmio = ahci_port_base(host_mmio, i); - port_mmio = - (struct sata_port_regs *)uc_priv->port[i].port_mmio; + port_mmio = uc_priv->port[i].port_mmio; /* Ensure that the DWC_ahsata is in idle state */ tmp = readl(&(port_mmio->cmd)); @@ -274,8 +271,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) static void ahci_print_info(struct ahci_uc_priv *uc_priv) { - struct sata_host_regs *host_mmio = - (struct sata_host_regs *)uc_priv->mmio_base; + struct sata_host_regs *host_mmio = uc_priv->mmio_base; u32 vers, cap, impl, speed; const char *speed_s; const char *scc_s; @@ -350,7 +346,7 @@ static int ahci_init_one(int pdev) ahci_print_info(uc_priv); /* Save the uc_private struct to block device struct */ - sata_dev_desc[pdev].priv = (void *)uc_priv; + sata_dev_desc[pdev].priv = uc_priv; return 0; @@ -410,8 +406,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, s32 is_write) { struct ahci_ioports *pp = &(uc_priv->port[port]); - struct sata_port_regs *port_mmio = - (struct sata_port_regs *)pp->port_mmio; + struct sata_port_regs *port_mmio = pp->port_mmio; u32 opts; int sg_count = 0, cmd_slot = 0; @@ -458,8 +453,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, static void ahci_set_feature(u8 dev, u8 port) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; @@ -476,8 +470,7 @@ static void ahci_set_feature(u8 dev, u8 port) static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { struct ahci_ioports *pp = &(uc_priv->port[port]); - struct sata_port_regs *port_mmio = - (struct sata_port_regs *)pp->port_mmio; + struct sata_port_regs *port_mmio = pp->port_mmio; u32 port_status; u32 mem; int timeout = 10000000; @@ -570,8 +563,7 @@ static void dwc_ahsata_print_info(int dev) static void dwc_ahsata_identify(int dev, u16 *id) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -589,8 +581,7 @@ static void dwc_ahsata_identify(int dev, u16 *id) static void dwc_ahsata_xfer_mode(int dev, u16 *id) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; uc_priv->pio_mask = id[ATA_ID_PIO_MODES]; uc_priv->udma_mask = id[ATA_ID_UDMA_MODES]; @@ -600,8 +591,7 @@ static void dwc_ahsata_xfer_mode(int dev, u16 *id) static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -631,8 +621,7 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, static void dwc_ahsata_flush_cache(int dev) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -649,8 +638,7 @@ static void dwc_ahsata_flush_cache(int dev) static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -685,8 +673,7 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, static void dwc_ahsata_flush_cache_ext(int dev) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -702,8 +689,7 @@ static void dwc_ahsata_flush_cache_ext(int dev) static void dwc_ahsata_init_wcache(int dev, u16 *id) { - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id)) uc_priv->flags |= SATA_FLAG_WCACHE; @@ -797,7 +783,7 @@ int init_sata(int dev) ahci_init_one(dev); - uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + uc_priv = sata_dev_desc[dev].priv; linkmap = uc_priv->link_port_map; if (0 == linkmap) { @@ -829,12 +815,12 @@ int reset_sata(int dev) return -1; } - uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + uc_priv = sata_dev_desc[dev].priv; if (NULL == uc_priv) /* not initialized, so nothing to reset */ return 0; - host_mmio = (struct sata_host_regs *)uc_priv->mmio_base; + host_mmio = uc_priv->mmio_base; setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) udelay(100); @@ -853,8 +839,8 @@ int sata_port_status(int dev, int port) if (sata_dev_desc[dev].priv == NULL) return -ENODEV; - uc_priv = (struct ahci_uc_priv *)sata_dev_desc[dev].priv; - port_mmio = (struct sata_port_regs *)uc_priv->port[port].port_mmio; + uc_priv = sata_dev_desc[dev].priv; + port_mmio = uc_priv->port[port].port_mmio; return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK; } @@ -878,8 +864,7 @@ ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) { u32 rc; - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; u32 flags = uc_priv->flags; if (sata_dev_desc[dev].lba48) { @@ -905,8 +890,7 @@ int scan_sata(int dev) u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; u16 *id; u64 n_sectors; - struct ahci_uc_priv *uc_priv = - (struct ahci_uc_priv *)sata_dev_desc[dev].priv; + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; u8 port = uc_priv->hard_port_no; struct blk_desc *pdev = &(sata_dev_desc[dev]); From 47c0f3692d27702cb11f67fe05b71b98d77d007c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:06 -0600 Subject: [PATCH 20/47] dm: sata: dw_sata: Pass uc_priv to internal functions With driver model sata_dev_desc[] does not exist. We still want to use the common code of this driver so update it to pass struct ahci_uc_priv * to each of these functions, instead of an integer which must be looked up in sata_dev_desc[]. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 89 ++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 8db894b16f..33804e92dc 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -451,9 +451,8 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, return buf_len; } -static void ahci_set_feature(u8 dev, u8 port) +static void ahci_set_feature(struct ahci_uc_priv *uc_priv, u8 port) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; @@ -545,10 +544,8 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) return 0; } -static void dwc_ahsata_print_info(int dev) +static void dwc_ahsata_print_info(struct blk_desc *pdev) { - struct blk_desc *pdev = &(sata_dev_desc[dev]); - printf("SATA Device Info:\n\r"); #ifdef CONFIG_SYS_64BIT_LBA printf("S/N: %s\n\rProduct model number: %s\n\r" @@ -561,9 +558,8 @@ static void dwc_ahsata_print_info(int dev) #endif } -static void dwc_ahsata_identify(int dev, u16 *id) +static void dwc_ahsata_identify(struct ahci_uc_priv *uc_priv, u16 *id) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -579,19 +575,16 @@ static void dwc_ahsata_identify(int dev, u16 *id) ata_swap_buf_le16(id, ATA_ID_WORDS); } -static void dwc_ahsata_xfer_mode(int dev, u16 *id) +static void dwc_ahsata_xfer_mode(struct ahci_uc_priv *uc_priv, u16 *id) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; - uc_priv->pio_mask = id[ATA_ID_PIO_MODES]; uc_priv->udma_mask = id[ATA_ID_UDMA_MODES]; debug("pio %04x, udma %04x\n\r", uc_priv->pio_mask, uc_priv->udma_mask); } -static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, - u8 *buffer, int is_write) +static u32 dwc_ahsata_rw_cmd(struct ahci_uc_priv *uc_priv, u32 start, + u32 blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -619,9 +612,8 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt, return 0; } -static void dwc_ahsata_flush_cache(int dev) +static void dwc_ahsata_flush_cache(struct ahci_uc_priv *uc_priv) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -635,10 +627,9 @@ static void dwc_ahsata_flush_cache(int dev) ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, 0); } -static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, - u8 *buffer, int is_write) +static u32 dwc_ahsata_rw_cmd_ext(struct ahci_uc_priv *uc_priv, u32 start, + lbaint_t blkcnt, u8 *buffer, int is_write) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -671,9 +662,8 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt, return 0; } -static void dwc_ahsata_flush_cache_ext(int dev) +static void dwc_ahsata_flush_cache_ext(struct ahci_uc_priv *uc_priv) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN); struct sata_fis_h2d *cfis = &h2d; u8 port = uc_priv->hard_port_no; @@ -687,10 +677,8 @@ static void dwc_ahsata_flush_cache_ext(int dev) ahci_exec_ata_cmd(uc_priv, port, cfis, NULL, 0, 0); } -static void dwc_ahsata_init_wcache(int dev, u16 *id) +static void dwc_ahsata_init_wcache(struct ahci_uc_priv *uc_priv, u16 *id) { - struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; - if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id)) uc_priv->flags |= SATA_FLAG_WCACHE; if (ata_id_has_flush(id)) @@ -699,8 +687,9 @@ static void dwc_ahsata_init_wcache(int dev, u16 *id) uc_priv->flags |= SATA_FLAG_FLUSH_EXT; } -static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static u32 ata_low_level_rw_lba48(struct ahci_uc_priv *uc_priv, u32 blknr, + lbaint_t blkcnt, const void *buffer, + int is_write) { u32 start, blks; u8 *addr; @@ -714,15 +703,16 @@ static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, do { if (blks > max_blks) { - if (max_blks != dwc_ahsata_rw_cmd_ext(dev, start, - max_blks, addr, is_write)) + if (max_blks != dwc_ahsata_rw_cmd_ext(uc_priv, start, + max_blks, addr, + is_write)) return 0; start += max_blks; blks -= max_blks; addr += ATA_SECT_SIZE * max_blks; } else { - if (blks != dwc_ahsata_rw_cmd_ext(dev, start, - blks, addr, is_write)) + if (blks != dwc_ahsata_rw_cmd_ext(uc_priv, start, blks, + addr, is_write)) return 0; start += blks; blks = 0; @@ -733,8 +723,9 @@ static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt, return blkcnt; } -static u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, - const void *buffer, int is_write) +static u32 ata_low_level_rw_lba28(struct ahci_uc_priv *uc_priv, u32 blknr, + lbaint_t blkcnt, const void *buffer, + int is_write) { u32 start, blks; u8 *addr; @@ -747,15 +738,16 @@ static u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt, max_blks = ATA_MAX_SECTORS; do { if (blks > max_blks) { - if (max_blks != dwc_ahsata_rw_cmd(dev, start, - max_blks, addr, is_write)) + if (max_blks != dwc_ahsata_rw_cmd(uc_priv, start, + max_blks, addr, + is_write)) return 0; start += max_blks; blks -= max_blks; addr += ATA_SECT_SIZE * max_blks; } else { - if (blks != dwc_ahsata_rw_cmd(dev, start, - blks, addr, is_write)) + if (blks != dwc_ahsata_rw_cmd(uc_priv, start, blks, + addr, is_write)) return 0; start += blks; blks = 0; @@ -850,13 +842,14 @@ int sata_port_status(int dev, int port) */ ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) { + struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; u32 rc; if (sata_dev_desc[dev].lba48) - rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, READ_CMD); else - rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, READ_CMD); return rc; } @@ -868,17 +861,17 @@ ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) u32 flags = uc_priv->flags; if (sata_dev_desc[dev].lba48) { - rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, - buffer, WRITE_CMD); + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, + WRITE_CMD); if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH_EXT)) - dwc_ahsata_flush_cache_ext(dev); + dwc_ahsata_flush_cache_ext(uc_priv); } else { - rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, - buffer, WRITE_CMD); + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, + WRITE_CMD); if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH)) - dwc_ahsata_flush_cache(dev); + dwc_ahsata_flush_cache(uc_priv); } return rc; } @@ -903,7 +896,7 @@ int scan_sata(int dev) } /* Identify device to get information */ - dwc_ahsata_identify(dev, id); + dwc_ahsata_identify(uc_priv, id); /* Serial number */ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); @@ -936,17 +929,17 @@ int scan_sata(int dev) uc_priv->flags |= ata_id_queue_depth(id); /* Get the xfer mode from device */ - dwc_ahsata_xfer_mode(dev, id); + dwc_ahsata_xfer_mode(uc_priv, id); /* Get the write cache status from device */ - dwc_ahsata_init_wcache(dev, id); + dwc_ahsata_init_wcache(uc_priv, id); /* Set the xfer mode to highest speed */ - ahci_set_feature(dev, port); + ahci_set_feature(uc_priv, port); free((void *)id); - dwc_ahsata_print_info(dev); + dwc_ahsata_print_info(&sata_dev_desc[dev]); is_ready = 1; From 3e59c30fcfea44add02e98cdc28153ee644491b0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:07 -0600 Subject: [PATCH 21/47] dm: sata: dw_sata: Drop unnecessary brackets There is a strange &(var) coding style in this driver. Adjust it to use &var instead, which is more usual. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 98 ++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 33804e92dc..63e7b7d7a1 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -104,8 +104,8 @@ static int ahci_setup_oobr(struct ahci_uc_priv *uc_priv, int clk) { struct sata_host_regs *host_mmio = uc_priv->mmio_base; - writel(SATA_HOST_OOBR_WE, &(host_mmio->oobr)); - writel(0x02060b14, &(host_mmio->oobr)); + writel(SATA_HOST_OOBR_WE, &host_mmio->oobr); + writel(0x02060b14, &host_mmio->oobr); return 0; } @@ -118,16 +118,15 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) struct sata_host_regs *host_mmio = uc_priv->mmio_base; int clk = mxc_get_clock(MXC_SATA_CLK); - cap_save = readl(&(host_mmio->cap)); + cap_save = readl(&host_mmio->cap); cap_save |= SATA_HOST_CAP_SSS; /* global controller reset */ - tmp = readl(&(host_mmio->ghc)); + tmp = readl(&host_mmio->ghc); if ((tmp & SATA_HOST_GHC_HR) == 0) - writel_with_flush(tmp | SATA_HOST_GHC_HR, &(host_mmio->ghc)); + writel_with_flush(tmp | SATA_HOST_GHC_HR, &host_mmio->ghc); - while ((readl(&(host_mmio->ghc)) & SATA_HOST_GHC_HR) - && --timeout) + while ((readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) && --timeout) ; if (timeout <= 0) { @@ -136,15 +135,14 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) } /* Set timer 1ms */ - writel(clk / 1000, &(host_mmio->timer1ms)); + writel(clk / 1000, &host_mmio->timer1ms); ahci_setup_oobr(uc_priv, 0); - writel_with_flush(SATA_HOST_GHC_AE, &(host_mmio->ghc)); - writel(cap_save, &(host_mmio->cap)); + writel_with_flush(SATA_HOST_GHC_AE, &host_mmio->ghc); + writel(cap_save, &host_mmio->cap); num_ports = (cap_save & SATA_HOST_CAP_NP_MASK) + 1; - writel_with_flush((1 << num_ports) - 1, - &(host_mmio->pi)); + writel_with_flush((1 << num_ports) - 1, &host_mmio->pi); /* * Determine which Ports are implemented by the DWC_ahsata, @@ -152,8 +150,8 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) * software to determine how many Ports are available and * which Port registers need to be initialized. */ - uc_priv->cap = readl(&(host_mmio->cap)); - uc_priv->port_map = readl(&(host_mmio->pi)); + uc_priv->cap = readl(&host_mmio->cap); + uc_priv->port_map = readl(&host_mmio->pi); /* Determine how many command slots the HBA supports */ uc_priv->n_ports = (uc_priv->cap & SATA_HOST_CAP_NP_MASK) + 1; @@ -166,7 +164,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) port_mmio = uc_priv->port[i].port_mmio; /* Ensure that the DWC_ahsata is in idle state */ - tmp = readl(&(port_mmio->cmd)); + tmp = readl(&port_mmio->cmd); /* * When P#CMD.ST, P#CMD.CR, P#CMD.FRE and P#CMD.FR @@ -181,7 +179,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) * 0 when read. */ tmp &= ~SATA_PORT_CMD_ST; - writel_with_flush(tmp, &(port_mmio->cmd)); + writel_with_flush(tmp, &port_mmio->cmd); /* * spec says 500 msecs for each bit, so @@ -190,7 +188,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) mdelay(500); timeout = 1000; - while ((readl(&(port_mmio->cmd)) & SATA_PORT_CMD_CR) + while ((readl(&port_mmio->cmd) & SATA_PORT_CMD_CR) && --timeout) ; @@ -201,12 +199,12 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) } /* Spin-up device */ - tmp = readl(&(port_mmio->cmd)); - writel((tmp | SATA_PORT_CMD_SUD), &(port_mmio->cmd)); + tmp = readl(&port_mmio->cmd); + writel((tmp | SATA_PORT_CMD_SUD), &port_mmio->cmd); /* Wait for spin-up to finish */ timeout = 1000; - while (!(readl(&(port_mmio->cmd)) | SATA_PORT_CMD_SUD) + while (!(readl(&port_mmio->cmd) | SATA_PORT_CMD_SUD) && --timeout) ; if (timeout <= 0) { @@ -216,7 +214,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) for (j = 0; j < 100; ++j) { mdelay(10); - tmp = readl(&(port_mmio->ssts)); + tmp = readl(&port_mmio->ssts); if (((tmp & SATA_PORT_SSTS_DET_MASK) == 0x3) || ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x1)) break; @@ -224,7 +222,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) /* Wait for COMINIT bit 26 (DIAG_X) in SERR */ timeout = 1000; - while (!(readl(&(port_mmio->serr)) | SATA_PORT_SERR_DIAG_X) + while (!(readl(&port_mmio->serr) | SATA_PORT_SERR_DIAG_X) && --timeout) ; if (timeout <= 0) { @@ -237,33 +235,33 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) * register, by writing ones to each implemented\ * bit location. */ - tmp = readl(&(port_mmio->serr)); + tmp = readl(&port_mmio->serr); debug("P#SERR 0x%x\n", tmp); - writel(tmp, &(port_mmio->serr)); + writel(tmp, &port_mmio->serr); /* Ack any pending irq events for this port */ - tmp = readl(&(host_mmio->is)); + tmp = readl(&host_mmio->is); debug("IS 0x%x\n", tmp); if (tmp) - writel(tmp, &(host_mmio->is)); + writel(tmp, &host_mmio->is); - writel(1 << i, &(host_mmio->is)); + writel(1 << i, &host_mmio->is); /* set irq mask (enables interrupts) */ - writel(DEF_PORT_IRQ, &(port_mmio->ie)); + writel(DEF_PORT_IRQ, &port_mmio->ie); /* register linkup ports */ - tmp = readl(&(port_mmio->ssts)); + tmp = readl(&port_mmio->ssts); debug("Port %d status: 0x%x\n", i, tmp); if ((tmp & SATA_PORT_SSTS_DET_MASK) == 0x03) uc_priv->link_port_map |= (0x01 << i); } - tmp = readl(&(host_mmio->ghc)); + tmp = readl(&host_mmio->ghc); debug("GHC 0x%x\n", tmp); - writel(tmp | SATA_HOST_GHC_IE, &(host_mmio->ghc)); - tmp = readl(&(host_mmio->ghc)); + writel(tmp | SATA_HOST_GHC_IE, &host_mmio->ghc); + tmp = readl(&host_mmio->ghc); debug("GHC 0x%x\n", tmp); return 0; @@ -276,7 +274,7 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv) const char *speed_s; const char *scc_s; - vers = readl(&(host_mmio->vs)); + vers = readl(&host_mmio->vs); cap = uc_priv->cap; impl = uc_priv->port_map; @@ -357,7 +355,7 @@ err_out: static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, unsigned char *buf, int buf_len) { - struct ahci_ioports *pp = &(uc_priv->port[port]); + struct ahci_ioports *pp = &uc_priv->port[port]; struct ahci_sg *ahci_sg = pp->cmd_tbl_sg; u32 sg_count, max_bytes; int i; @@ -405,12 +403,12 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, struct sata_fis_h2d *cfis, u8 *buf, u32 buf_len, s32 is_write) { - struct ahci_ioports *pp = &(uc_priv->port[port]); + struct ahci_ioports *pp = &uc_priv->port[port]; struct sata_port_regs *port_mmio = pp->port_mmio; u32 opts; int sg_count = 0, cmd_slot = 0; - cmd_slot = AHCI_GET_CMD_SLOT(readl(&(port_mmio->ci))); + cmd_slot = AHCI_GET_CMD_SLOT(readl(&port_mmio->ci)); if (32 == cmd_slot) { printf("Can't find empty command slot!\n"); return 0; @@ -434,10 +432,10 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, ahci_fill_cmd_slot(pp, cmd_slot, opts); flush_cache((int)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ); - writel_with_flush(1 << cmd_slot, &(port_mmio->ci)); + writel_with_flush(1 << cmd_slot, &port_mmio->ci); - if (waiting_for_cmd_completed((u8 *)&(port_mmio->ci), - 10000, 0x1 << cmd_slot)) { + if (waiting_for_cmd_completed((u8 *)&port_mmio->ci, 10000, + 0x1 << cmd_slot)) { printf("timeout exit!\n"); return -1; } @@ -468,14 +466,14 @@ static void ahci_set_feature(struct ahci_uc_priv *uc_priv, u8 port) static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { - struct ahci_ioports *pp = &(uc_priv->port[port]); + struct ahci_ioports *pp = &uc_priv->port[port]; struct sata_port_regs *port_mmio = pp->port_mmio; u32 port_status; u32 mem; int timeout = 10000000; debug("Enter start port: %d\n", port); - port_status = readl(&(port_mmio->ssts)); + port_status = readl(&port_mmio->ssts); debug("Port %d status: %x\n", port, port_status); if ((port_status & 0xf) != 0x03) { printf("No Link on this port!\n"); @@ -515,17 +513,17 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) mem += AHCI_CMD_TBL_HDR; - writel_with_flush(0x00004444, &(port_mmio->dmacr)); + writel_with_flush(0x00004444, &port_mmio->dmacr); pp->cmd_tbl_sg = (struct ahci_sg *)mem; - writel_with_flush((u32)pp->cmd_slot, &(port_mmio->clb)); - writel_with_flush(pp->rx_fis, &(port_mmio->fb)); + writel_with_flush((u32)pp->cmd_slot, &port_mmio->clb); + writel_with_flush(pp->rx_fis, &port_mmio->fb); /* Enable FRE */ - writel_with_flush((SATA_PORT_CMD_FRE | readl(&(port_mmio->cmd))), - &(port_mmio->cmd)); + writel_with_flush((SATA_PORT_CMD_FRE | readl(&port_mmio->cmd)), + &port_mmio->cmd); /* Wait device ready */ - while ((readl(&(port_mmio->tfd)) & (SATA_PORT_TFD_STS_ERR | + while ((readl(&port_mmio->tfd) & (SATA_PORT_TFD_STS_ERR | SATA_PORT_TFD_STS_DRQ | SATA_PORT_TFD_STS_BSY)) && --timeout) ; @@ -537,7 +535,7 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | - PORT_CMD_START, &(port_mmio->cmd)); + PORT_CMD_START, &port_mmio->cmd); debug("Exit start port %d\n", port); @@ -834,7 +832,7 @@ int sata_port_status(int dev, int port) uc_priv = sata_dev_desc[dev].priv; port_mmio = uc_priv->port[port].port_mmio; - return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK; + return readl(&port_mmio->ssts) & SATA_PORT_SSTS_DET_MASK; } /* @@ -885,7 +883,7 @@ int scan_sata(int dev) u64 n_sectors; struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; u8 port = uc_priv->hard_port_no; - struct blk_desc *pdev = &(sata_dev_desc[dev]); + struct blk_desc *pdev = &sata_dev_desc[dev]; id = (u16 *)memalign(ARCH_DMA_MINALIGN, roundup(ARCH_DMA_MINALIGN, From 0f07df4301528fe51efa10a6559450632ef35ce7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:08 -0600 Subject: [PATCH 22/47] dm: sata: dw_sata: Sort #include directives Sort the header file inclusions into the correct order. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 63e7b7d7a1..b6915d217b 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -5,19 +5,18 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include +#include #include #include -#include - -#include +#include #include -#include -#include +#include #include -#include #include #include +#include +#include +#include #include "dwc_ahsata.h" struct sata_port_regs { From 90abb28fcfc00d5396000bcda8a8ce871b8412ff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:09 -0600 Subject: [PATCH 23/47] dm: sata: dw_sata: Rename the dwc_ahsata private header Rename dwc_ahsata.h to indicate that it is a private header file. We plan to create another header with some public functions. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 2 +- drivers/ata/{dwc_ahsata.h => dwc_ahsata_priv.h} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename drivers/ata/{dwc_ahsata.h => dwc_ahsata_priv.h} (99%) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index b6915d217b..8056bc94a3 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -17,7 +17,7 @@ #include #include #include -#include "dwc_ahsata.h" +#include "dwc_ahsata_priv.h" struct sata_port_regs { u32 clb; diff --git a/drivers/ata/dwc_ahsata.h b/drivers/ata/dwc_ahsata_priv.h similarity index 99% rename from drivers/ata/dwc_ahsata.h rename to drivers/ata/dwc_ahsata_priv.h index caa2e501f9..6089c0b268 100644 --- a/drivers/ata/dwc_ahsata.h +++ b/drivers/ata/dwc_ahsata_priv.h @@ -5,8 +5,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef __FSL_SATA_H__ -#define __FSL_SATA_H__ +#ifndef __DWC_AHSATA_PRIV_H__ +#define __DWC_AHSATA_PRIV_H__ #define DWC_AHSATA_MAX_CMD_SLOTS 32 @@ -317,4 +317,4 @@ #define READ_CMD 0 #define WRITE_CMD 1 -#endif /* __FSL_SATA_H__ */ +#endif /* __DWC_AHSATA_H__ */ From 5908d85eb7be81588bb90ad61b07fb8dd0ec3f58 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:10 -0600 Subject: [PATCH 24/47] dm: sata: dw_sata: Drop is_ready This variable is set but never used. Drop it. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 8056bc94a3..4b89a8b788 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -77,8 +77,6 @@ struct sata_host_regs { #define writel_with_flush(a, b) do { writel(a, b); readl(b); } while (0) -static int is_ready; - static inline void __iomem *ahci_port_base(void __iomem *base, u32 port) { return base + 0x100 + (port * 0x80); @@ -938,7 +936,5 @@ int scan_sata(int dev) dwc_ahsata_print_info(&sata_dev_desc[dev]); - is_ready = 1; - return 0; } From 036a803e1b69b9eb5747d63b9469cccc090114f4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:11 -0600 Subject: [PATCH 25/47] dm: sata: dw_sata: More ahci_init_one() futher down This function will not be used with driver model and it relates to the other exported functions. Move it down next to them. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 66 ++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 4b89a8b788..2695bef222 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -316,39 +316,6 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv) cap & (1 << 13) ? "part " : ""); } -static int ahci_init_one(int pdev) -{ - int rc; - struct ahci_uc_priv *uc_priv = NULL; - - uc_priv = malloc(sizeof(struct ahci_uc_priv)); - memset(uc_priv, 0, sizeof(struct ahci_uc_priv)); - uc_priv->dev = pdev; - - uc_priv->host_flags = ATA_FLAG_SATA - | ATA_FLAG_NO_LEGACY - | ATA_FLAG_MMIO - | ATA_FLAG_PIO_DMA - | ATA_FLAG_NO_ATAPI; - - uc_priv->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; - - /* initialize adapter */ - rc = ahci_host_init(uc_priv); - if (rc) - goto err_out; - - ahci_print_info(uc_priv); - - /* Save the uc_private struct to block device struct */ - sata_dev_desc[pdev].priv = uc_priv; - - return 0; - -err_out: - return rc; -} - static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, unsigned char *buf, int buf_len) { @@ -753,6 +720,39 @@ static u32 ata_low_level_rw_lba28(struct ahci_uc_priv *uc_priv, u32 blknr, return blkcnt; } +static int ahci_init_one(int pdev) +{ + int rc; + struct ahci_uc_priv *uc_priv = NULL; + + uc_priv = malloc(sizeof(struct ahci_uc_priv)); + memset(uc_priv, 0, sizeof(struct ahci_uc_priv)); + uc_priv->dev = pdev; + + uc_priv->host_flags = ATA_FLAG_SATA + | ATA_FLAG_NO_LEGACY + | ATA_FLAG_MMIO + | ATA_FLAG_PIO_DMA + | ATA_FLAG_NO_ATAPI; + + uc_priv->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; + + /* initialize adapter */ + rc = ahci_host_init(uc_priv); + if (rc) + goto err_out; + + ahci_print_info(uc_priv); + + /* Save the uc_private struct to block device struct */ + sata_dev_desc[pdev].priv = uc_priv; + + return 0; + +err_out: + return rc; +} + int init_sata(int dev) { int i; From 752126a05a73303192d704250a0e68156241784d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:12 -0600 Subject: [PATCH 26/47] dm: sata: dw_sata: Set up common versions of operations Driver model wants to use the core functions in this file but accesses the uclass-private data in a different way. Move the code into new 'common' functions and set up stubs to call these. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 236 ++++++++++++++++++++++----------------- 1 file changed, 131 insertions(+), 105 deletions(-) diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 2695bef222..1e3ddd75db 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -720,6 +721,130 @@ static u32 ata_low_level_rw_lba28(struct ahci_uc_priv *uc_priv, u32 blknr, return blkcnt; } +static int dwc_ahci_start_ports(struct ahci_uc_priv *uc_priv) +{ + u32 linkmap; + int i; + + linkmap = uc_priv->link_port_map; + + if (0 == linkmap) { + printf("No port device detected!\n"); + return -ENXIO; + } + + for (i = 0; i < uc_priv->n_ports; i++) { + if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { + if (ahci_port_start(uc_priv, (u8)i)) { + printf("Can not start port %d\n", i); + return 1; + } + uc_priv->hard_port_no = i; + break; + } + } + + return 0; +} + +static int dwc_ahsata_scan_common(struct ahci_uc_priv *uc_priv, + struct blk_desc *pdev) +{ + u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 }; + u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 }; + u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; + u64 n_sectors; + u8 port = uc_priv->hard_port_no; + ALLOC_CACHE_ALIGN_BUFFER(u16, id, ATA_ID_WORDS); + + /* Identify device to get information */ + dwc_ahsata_identify(uc_priv, id); + + /* Serial number */ + ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); + memcpy(pdev->product, serial, sizeof(serial)); + + /* Firmware version */ + ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); + memcpy(pdev->revision, firmware, sizeof(firmware)); + + /* Product model */ + ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); + memcpy(pdev->vendor, product, sizeof(product)); + + /* Totoal sectors */ + n_sectors = ata_id_n_sectors(id); + pdev->lba = (u32)n_sectors; + + pdev->type = DEV_TYPE_HARDDISK; + pdev->blksz = ATA_SECT_SIZE; + pdev->lun = 0; + + /* Check if support LBA48 */ + if (ata_id_has_lba48(id)) { + pdev->lba48 = 1; + debug("Device support LBA48\n\r"); + } + + /* Get the NCQ queue depth from device */ + uc_priv->flags &= (~SATA_FLAG_Q_DEP_MASK); + uc_priv->flags |= ata_id_queue_depth(id); + + /* Get the xfer mode from device */ + dwc_ahsata_xfer_mode(uc_priv, id); + + /* Get the write cache status from device */ + dwc_ahsata_init_wcache(uc_priv, id); + + /* Set the xfer mode to highest speed */ + ahci_set_feature(uc_priv, port); + + dwc_ahsata_print_info(pdev); + + return 0; +} + +/* + * SATA interface between low level driver and command layer + */ +static ulong sata_read_common(struct ahci_uc_priv *uc_priv, + struct blk_desc *desc, ulong blknr, + lbaint_t blkcnt, void *buffer) +{ + u32 rc; + + if (desc->lba48) + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, + READ_CMD); + else + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, + READ_CMD); + + return rc; +} + +static ulong sata_write_common(struct ahci_uc_priv *uc_priv, + struct blk_desc *desc, ulong blknr, + lbaint_t blkcnt, const void *buffer) +{ + u32 rc; + u32 flags = uc_priv->flags; + + if (desc->lba48) { + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, + WRITE_CMD); + if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH_EXT)) + dwc_ahsata_flush_cache_ext(uc_priv); + } else { + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, + WRITE_CMD); + if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH)) + dwc_ahsata_flush_cache(uc_priv); + } + + return rc; +} + static int ahci_init_one(int pdev) { int rc; @@ -755,8 +880,6 @@ err_out: int init_sata(int dev) { - int i; - u32 linkmap; struct ahci_uc_priv *uc_priv = NULL; #if defined(CONFIG_MX6) @@ -771,25 +894,8 @@ int init_sata(int dev) ahci_init_one(dev); uc_priv = sata_dev_desc[dev].priv; - linkmap = uc_priv->link_port_map; - if (0 == linkmap) { - printf("No port device detected!\n"); - return 1; - } - - for (i = 0; i < uc_priv->n_ports; i++) { - if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { - if (ahci_port_start(uc_priv, (u8)i)) { - printf("Can not start port %d\n", i); - return 1; - } - uc_priv->hard_port_no = i; - break; - } - } - - return 0; + return dwc_ahci_start_ports(uc_priv) ? 1 : 0; } int reset_sata(int dev) @@ -838,103 +944,23 @@ int sata_port_status(int dev, int port) ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) { struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; - u32 rc; - if (sata_dev_desc[dev].lba48) - rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, - buffer, READ_CMD); - else - rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, - buffer, READ_CMD); - return rc; + return sata_read_common(uc_priv, &sata_dev_desc[dev], blknr, blkcnt, + buffer); } ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) { - u32 rc; struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; - u32 flags = uc_priv->flags; - if (sata_dev_desc[dev].lba48) { - rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, - WRITE_CMD); - if ((flags & SATA_FLAG_WCACHE) && - (flags & SATA_FLAG_FLUSH_EXT)) - dwc_ahsata_flush_cache_ext(uc_priv); - } else { - rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, - WRITE_CMD); - if ((flags & SATA_FLAG_WCACHE) && - (flags & SATA_FLAG_FLUSH)) - dwc_ahsata_flush_cache(uc_priv); - } - return rc; + return sata_write_common(uc_priv, &sata_dev_desc[dev], blknr, blkcnt, + buffer); } int scan_sata(int dev) { - u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 }; - u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 }; - u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; - u16 *id; - u64 n_sectors; struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; - u8 port = uc_priv->hard_port_no; struct blk_desc *pdev = &sata_dev_desc[dev]; - id = (u16 *)memalign(ARCH_DMA_MINALIGN, - roundup(ARCH_DMA_MINALIGN, - (ATA_ID_WORDS * 2))); - if (!id) { - printf("id malloc failed\n\r"); - return -1; - } - - /* Identify device to get information */ - dwc_ahsata_identify(uc_priv, id); - - /* Serial number */ - ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); - memcpy(pdev->product, serial, sizeof(serial)); - - /* Firmware version */ - ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); - memcpy(pdev->revision, firmware, sizeof(firmware)); - - /* Product model */ - ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); - memcpy(pdev->vendor, product, sizeof(product)); - - /* Totoal sectors */ - n_sectors = ata_id_n_sectors(id); - pdev->lba = (u32)n_sectors; - - pdev->type = DEV_TYPE_HARDDISK; - pdev->blksz = ATA_SECT_SIZE; - pdev->lun = 0 ; - - /* Check if support LBA48 */ - if (ata_id_has_lba48(id)) { - pdev->lba48 = 1; - debug("Device support LBA48\n\r"); - } - - /* Get the NCQ queue depth from device */ - uc_priv->flags &= (~SATA_FLAG_Q_DEP_MASK); - uc_priv->flags |= ata_id_queue_depth(id); - - /* Get the xfer mode from device */ - dwc_ahsata_xfer_mode(uc_priv, id); - - /* Get the write cache status from device */ - dwc_ahsata_init_wcache(uc_priv, id); - - /* Set the xfer mode to highest speed */ - ahci_set_feature(uc_priv, port); - - free((void *)id); - - dwc_ahsata_print_info(&sata_dev_desc[dev]); - - return 0; + return dwc_ahsata_scan_common(uc_priv, pdev); } From f19f1ecb6025f0e2afb237a59b24462c5340787a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:13 -0600 Subject: [PATCH 27/47] dm: sata: Support driver model with the 'sata' command Update this command to support driver model. This has a different way of starting and stopping SATA. Signed-off-by: Simon Glass --- cmd/sata.c | 95 +++++++++++++++++++++++++++++++++++++----- common/splash_source.c | 2 +- include/sata.h | 5 ++- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/cmd/sata.c b/cmd/sata.c index d34a56dccc..7817442532 100644 --- a/cmd/sata.c +++ b/cmd/sata.c @@ -11,33 +11,106 @@ */ #include +#include +#include #include #include #include +#include +#include static int sata_curr_device = -1; +int sata_remove(int devnum) +{ +#ifdef CONFIG_AHCI + struct udevice *dev; + int rc; + + rc = uclass_find_device(UCLASS_AHCI, devnum, &dev); + if (!rc && !dev) + rc = uclass_find_first_device(UCLASS_AHCI, &dev); + if (rc || !dev) { + printf("Cannot find SATA device %d (err=%d)\n", devnum, rc); + return CMD_RET_FAILURE; + } + + rc = device_remove(dev, DM_REMOVE_NORMAL); + if (rc) { + printf("Cannot remove SATA device '%s' (err=%d)\n", dev->name, + rc); + return CMD_RET_FAILURE; + } + + return 0; +#else + return sata_stop(); +#endif +} + +int sata_probe(int devnum) +{ +#ifdef CONFIG_AHCI + struct udevice *dev; + struct udevice *blk; + int rc; + + rc = uclass_get_device(UCLASS_AHCI, devnum, &dev); + if (rc) + rc = uclass_find_first_device(UCLASS_AHCI, &dev); + if (rc) { + printf("Cannot probe SATA device %d (err=%d)\n", devnum, rc); + return CMD_RET_FAILURE; + } + rc = sata_scan(dev); + if (rc) { + printf("Cannot scan SATA device %d (err=%d)\n", devnum, rc); + return CMD_RET_FAILURE; + } + + rc = blk_get_from_parent(dev, &blk); + if (!rc) { + struct blk_desc *desc = dev_get_uclass_platdata(blk); + + if (desc->lba > 0 && desc->blksz > 0) + part_init(desc); + } + + return 0; +#else + return sata_initialize() < 0 ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +#endif +} + static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rc = 0; - if (argc == 2 && strcmp(argv[1], "stop") == 0) - return sata_stop(); + if (argc >= 2) { + int devnum = 0; - if (argc == 2 && strcmp(argv[1], "init") == 0) { - if (sata_curr_device != -1) - sata_stop(); + if (argc == 3) + devnum = (int)simple_strtoul(argv[2], NULL, 10); + if (!strcmp(argv[1], "stop")) + return sata_remove(devnum); - return (sata_initialize() < 0) ? - CMD_RET_FAILURE : CMD_RET_SUCCESS; + if (!strcmp(argv[1], "init")) { + if (sata_curr_device != -1) { + rc = sata_remove(devnum); + if (rc) + return rc; + } + + return sata_probe(devnum); + } } /* If the user has not yet run `sata init`, do it now */ if (sata_curr_device == -1) { - rc = sata_initialize(); - if (rc == -1) + rc = sata_probe(0); + if (rc < 0) return CMD_RET_FAILURE; - sata_curr_device = rc; + sata_curr_device = 0; } return blk_common_cmd(argc, argv, IF_TYPE_SATA, &sata_curr_device); @@ -47,7 +120,7 @@ U_BOOT_CMD( sata, 5, 1, do_sata, "SATA sub system", "init - init SATA sub system\n" - "sata stop - disable SATA sub system\n" + "sata stop [dev] - disable SATA sub system or device\n" "sata info - show available SATA devices\n" "sata device [dev] - show or set current device\n" "sata part [dev] - print partition table\n" diff --git a/common/splash_source.c b/common/splash_source.c index 867a798487..206a45df37 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -166,7 +166,7 @@ static inline int splash_init_usb(void) #ifdef CONFIG_SATA static int splash_init_sata(void) { - return sata_initialize(); + return sata_probe(0); } #else static inline int splash_init_sata(void) diff --git a/include/sata.h b/include/sata.h index d18cc9aa87..d89f7a8a29 100644 --- a/include/sata.h +++ b/include/sata.h @@ -2,7 +2,7 @@ #define __SATA_H__ #include -#if !defined(CONFIG_DM_SCSI) +#if !defined(CONFIG_DM_SCSI) && !defined(CONFIG_AHCI) int init_sata(int dev); int reset_sata(int dev); int scan_sata(int dev); @@ -18,4 +18,7 @@ int sata_port_status(int dev, int port); extern struct blk_desc sata_dev_desc[]; #endif +int sata_probe(int devnum); +int sata_remove(int devnum); + #endif From 7e0712b26ee877ca46cc7ba9978c52a9c3f40dc4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:14 -0600 Subject: [PATCH 28/47] dm: sata: imx: Allow driver model to be used for sata Update the sata call to work with driver model. Signed-off-by: Simon Glass --- arch/arm/mach-imx/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 9e83b4221e..1017eb84f9 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -279,7 +279,7 @@ void arch_preboot_os(void) imx_pcie_remove(); #endif #if defined(CONFIG_SATA) - sata_stop(); + sata_remove(0); #if defined(CONFIG_MX6) disable_sata_clock(); #endif From b8341f1c39df8708ee783038d8abb2b50dd83fac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:15 -0600 Subject: [PATCH 29/47] dm: sata: Update the AHCI uclass to support operations At present the AHCI uclass is just a shell and we still use the global functions to access SATA. Fix this by adding operations to the uclass. Signed-off-by: Simon Glass --- drivers/ata/sata.c | 37 +++++++++++++++++++++++++++++++ include/ahci.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c index 42ff5c7755..b3ebc05ead 100644 --- a/drivers/ata/sata.c +++ b/drivers/ata/sata.c @@ -11,17 +11,52 @@ */ #include +#include #include #include +#ifndef CONFIG_AHCI struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; +#endif +int sata_reset(struct udevice *dev) +{ + struct ahci_ops *ops = ahci_get_ops(dev); + + if (!ops->reset) + return -ENOSYS; + + return ops->reset(dev); +} + +int sata_dm_port_status(struct udevice *dev, int port) +{ + struct ahci_ops *ops = ahci_get_ops(dev); + + if (!ops->port_status) + return -ENOSYS; + + return ops->port_status(dev, port); +} + +int sata_scan(struct udevice *dev) +{ + struct ahci_ops *ops = ahci_get_ops(dev); + + if (!ops->scan) + return -ENOSYS; + + return ops->scan(dev); +} + +#ifndef CONFIG_AHCI #ifdef CONFIG_PARTITIONS struct blk_desc *sata_get_dev(int dev) { return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; } #endif +#endif #ifdef CONFIG_BLK static unsigned long sata_bread(struct udevice *dev, lbaint_t start, @@ -49,6 +84,7 @@ static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start, } #endif +#ifndef CONFIG_AHCI int __sata_initialize(void) { int rc, ret = -1; @@ -95,6 +131,7 @@ __weak int __sata_stop(void) return err; } int sata_stop(void) __attribute__((weak, alias("__sata_stop"))); +#endif #ifdef CONFIG_BLK static const struct blk_ops sata_blk_ops = { diff --git a/include/ahci.h b/include/ahci.h index 29f4ba1d13..33171b7ffd 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -176,6 +176,60 @@ struct ahci_uc_priv { u32 link_port_map; /*linkup port map*/ }; +struct ahci_ops { + /** + * reset() - reset the controller + * + * @dev: Controller to reset + * @return 0 if OK, -ve on error + */ + int (*reset)(struct udevice *dev); + + /** + * port_status() - get the status of a SATA port + * + * @dev: Controller to reset + * @port: Port number to check (0 for first) + * @return 0 if detected, -ENXIO if nothing on port, other -ve on error + */ + int (*port_status)(struct udevice *dev, int port); + + /** + * scan() - scan SATA ports + * + * @dev: Controller to scan + * @return 0 if OK, -ve on error + */ + int (*scan)(struct udevice *dev); +}; + +#define ahci_get_ops(dev) ((struct ahci_ops *)(dev)->driver->ops) + +/** + * sata_reset() - reset the controller + * + * @dev: Controller to reset + * @return 0 if OK, -ve on error + */ +int sata_reset(struct udevice *dev); + +/** + * sata_port_status() - get the status of a SATA port + * + * @dev: Controller to reset + * @port: Port number to check (0 for first) + * @return 0 if detected, -ENXIO if nothin on port, other -ve on error + */ +int sata_dm_port_status(struct udevice *dev, int port); + +/** + * sata_scan() - scan SATA ports + * + * @dev: Controller to scan + * @return 0 if OK, -ve on error + */ +int sata_scan(struct udevice *dev); + int ahci_init(void __iomem *base); int ahci_reset(void __iomem *base); From c893f1e6e5cd6ccd4c7aaaf760f27fa6779e351c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:16 -0600 Subject: [PATCH 30/47] dm: sata: dwc_ahsata: Add support for driver model Update this driver to support driver model. This involves implementing the AHCI operations and reusing existing common code. Signed-off-by: Simon Glass --- drivers/ata/dwc_ahsata.c | 113 +++++++++++++++++++++++++++++++++++++++ include/dwc_ahsata.h | 16 ++++++ 2 files changed, 129 insertions(+) create mode 100644 include/dwc_ahsata.h diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 1e3ddd75db..480ae115af 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include #include @@ -845,6 +847,7 @@ static ulong sata_write_common(struct ahci_uc_priv *uc_priv, return rc; } +#if !CONFIG_IS_ENABLED(AHCI) static int ahci_init_one(int pdev) { int rc; @@ -964,3 +967,113 @@ int scan_sata(int dev) return dwc_ahsata_scan_common(uc_priv, pdev); } +#endif /* CONFIG_IS_ENABLED(AHCI) */ + +#if CONFIG_IS_ENABLED(AHCI) + +int dwc_ahsata_port_status(struct udevice *dev, int port) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct sata_port_regs *port_mmio; + + port_mmio = uc_priv->port[port].port_mmio; + return readl(&port_mmio->ssts) & SATA_PORT_SSTS_DET_MASK ? 0 : -ENXIO; +} + +int dwc_ahsata_bus_reset(struct udevice *dev) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct sata_host_regs *host_mmio = uc_priv->mmio_base; + + setbits_le32(&host_mmio->ghc, SATA_HOST_GHC_HR); + while (readl(&host_mmio->ghc) & SATA_HOST_GHC_HR) + udelay(100); + + return 0; +} + +int dwc_ahsata_scan(struct udevice *dev) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct blk_desc *desc; + struct udevice *blk; + int ret; + + /* + * Create only one block device and do detection + * to make sure that there won't be a lot of + * block devices created + */ + device_find_first_child(dev, &blk); + if (!blk) { + ret = blk_create_devicef(dev, "dwc_ahsata_blk", "blk", + IF_TYPE_SATA, -1, 512, 0, &blk); + if (ret) { + debug("Can't create device\n"); + return ret; + } + } + + desc = dev_get_uclass_platdata(blk); + ret = dwc_ahsata_scan_common(uc_priv, desc); + if (ret) { + debug("%s: Failed to scan bus\n", __func__); + return ret; + } + + return 0; +} + +int dwc_ahsata_probe(struct udevice *dev) +{ + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + int ret; + + uc_priv->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI; + uc_priv->mmio_base = (void __iomem *)dev_read_addr(dev); + + /* initialize adapter */ + ret = ahci_host_init(uc_priv); + if (ret) + return ret; + + ahci_print_info(uc_priv); + + return dwc_ahci_start_ports(uc_priv); +} + +static ulong dwc_ahsata_read(struct udevice *blk, lbaint_t blknr, + lbaint_t blkcnt, void *buffer) +{ + struct blk_desc *desc = dev_get_uclass_platdata(blk); + struct udevice *dev = dev_get_parent(blk); + struct ahci_uc_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + return sata_read_common(uc_priv, desc, blknr, blkcnt, buffer); +} + +static ulong dwc_ahsata_write(struct udevice *blk, lbaint_t blknr, + lbaint_t blkcnt, const void *buffer) +{ + struct blk_desc *desc = dev_get_uclass_platdata(blk); + struct udevice *dev = dev_get_parent(blk); + struct ahci_uc_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + return sata_write_common(uc_priv, desc, blknr, blkcnt, buffer); +} + +static const struct blk_ops dwc_ahsata_blk_ops = { + .read = dwc_ahsata_read, + .write = dwc_ahsata_write, +}; + +U_BOOT_DRIVER(dwc_ahsata_blk) = { + .name = "dwc_ahsata_blk", + .id = UCLASS_BLK, + .ops = &dwc_ahsata_blk_ops, +}; + +#endif diff --git a/include/dwc_ahsata.h b/include/dwc_ahsata.h new file mode 100644 index 0000000000..cae275fe75 --- /dev/null +++ b/include/dwc_ahsata.h @@ -0,0 +1,16 @@ +/* + * Copyright 2017 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DWC_AHSATA_H__ +#define __DWC_AHSATA_H__ + +int dwc_ahsata_bus_reset(struct udevice *dev); +int dwc_ahsata_probe(struct udevice *dev); +int dwc_ahsata_scan(struct udevice *dev); +int dwc_ahsata_port_status(struct udevice *dev, int port); + +#endif From 09b465fd0fff6e540bbc1c34fdebb07f5d8091ef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:17 -0600 Subject: [PATCH 31/47] dm: mmc: fsl_esdhc: Pass private data to internal functions With driver model we will not use mmc->priv to access driver-private data. To accomodate this, update internal functions so that we can pass the private data directly. This will allow the caller to obtain it as it prefers. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index b69c9b71e4..d3de91fd5a 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -156,10 +156,9 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) /* * PIO Read/Write Mode reduce the performace as DMA is not used in this mode. */ -static void -esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data) +static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv, + struct mmc_data *data) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; uint blocks; char *buffer; @@ -218,10 +217,10 @@ esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data) } #endif -static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) +static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, + struct mmc_data *data) { int timeout; - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; #if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) dma_addr_t addr; @@ -384,7 +383,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Set up for a data transfer if we have one */ if (data) { - err = esdhc_setup_data(mmc, data); + err = esdhc_setup_data(priv, mmc, data); if(err) return err; @@ -470,7 +469,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Wait until all of the blocks are transferred */ if (data) { #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO - esdhc_pio_read_write(mmc, data); + esdhc_pio_read_write(priv, data); #else do { irqstat = esdhc_read32(®s->irqstat); @@ -522,7 +521,7 @@ out: return err; } -static void set_sysctl(struct mmc *mmc, uint clock) +static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) { int div = 1; #ifdef ARCH_MXC @@ -531,7 +530,6 @@ static void set_sysctl(struct mmc *mmc, uint clock) int pre_div = 2; #endif int ddr_pre_div = mmc->ddr_mode ? 2 : 1; - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; int sdhc_clk = priv->sdhc_clk; uint clk; @@ -569,9 +567,8 @@ static void set_sysctl(struct mmc *mmc, uint clock) } #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK -static void esdhc_clock_control(struct mmc *mmc, bool enable) +static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; u32 value; u32 time_out; @@ -605,12 +602,12 @@ static int esdhc_set_ios(struct mmc *mmc) #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK /* Select to use peripheral clock */ - esdhc_clock_control(mmc, false); + esdhc_clock_control(priv, false); esdhc_setbits32(®s->scr, ESDHCCTL_PCS); - esdhc_clock_control(mmc, true); + esdhc_clock_control(priv, true); #endif /* Set the clock speed */ - set_sysctl(mmc, mmc->clock); + set_sysctl(priv, mmc, mmc->clock); /* Set the bus width */ esdhc_clrbits32(®s->proctl, PROCTL_DTW_4 | PROCTL_DTW_8); From 9586aa6ea3958dc0dd608e41c27d79d66309ba12 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:18 -0600 Subject: [PATCH 32/47] dm: mmc: fsl_esdhc: Set up common versions of operations Driver model wants to use the core functions in this file but accesses the driver-private data in a different way. Move the code into new 'common' functions and set up stubs to call these. Also sort the operations into alphabetical order for consistency. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 47 +++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index d3de91fd5a..dd312d279c 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -348,13 +348,12 @@ static void check_and_invalidate_dcache_range * Sends a command out on the bus. Takes the mmc pointer, * a command pointer, and an optional data pointer. */ -static int -esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data) { int err = 0; uint xfertyp; uint irqstat; - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 @@ -595,9 +594,8 @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable) } #endif -static int esdhc_set_ios(struct mmc *mmc) +static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK @@ -620,9 +618,8 @@ static int esdhc_set_ios(struct mmc *mmc) return 0; } -static int esdhc_init(struct mmc *mmc) +static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; int timeout = 1000; @@ -676,9 +673,8 @@ static int esdhc_init(struct mmc *mmc) return 0; } -static int esdhc_getcd(struct mmc *mmc) +static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) { - struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; int timeout = 1000; @@ -716,11 +712,40 @@ static void esdhc_reset(struct fsl_esdhc *regs) printf("MMC/SD: Reset never completed.\n"); } +static int esdhc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_getcd_common(priv); +} + +static int esdhc_init(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_init_common(priv, mmc); +} + +static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_send_cmd_common(priv, mmc, cmd, data); +} + +static int esdhc_set_ios(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_set_ios_common(priv, mmc); +} + static const struct mmc_ops esdhc_ops = { + .getcd = esdhc_getcd, + .init = esdhc_init, .send_cmd = esdhc_send_cmd, .set_ios = esdhc_set_ios, - .init = esdhc_init, - .getcd = esdhc_getcd, }; static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) From 446e077a21024edb3d8636a979a99abbcaec9846 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:19 -0600 Subject: [PATCH 33/47] dm: mmc: fsl_esdhc: Detect reset failure Since esdhc_reset() can fail it should return an error code. Update this and also adjust the timeout mechanism to use get_timer(), which is a more common approach. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index dd312d279c..1e1e92d740 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -698,18 +698,23 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) return timeout > 0; } -static void esdhc_reset(struct fsl_esdhc *regs) +static int esdhc_reset(struct fsl_esdhc *regs) { - unsigned long timeout = 100; /* wait max 100 ms */ + ulong start; /* reset the controller */ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); /* hardware clears the bit when it is done */ - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) - udelay(1000); - if (!timeout) - printf("MMC/SD: Reset never completed.\n"); + start = get_timer(0); + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) { + if (get_timer(start) > 100) { + printf("MMC/SD: Reset never completed.\n"); + return -ETIMEDOUT; + } + } + + return 0; } static int esdhc_getcd(struct mmc *mmc) @@ -753,6 +758,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) struct fsl_esdhc *regs; struct mmc *mmc; u32 caps, voltage_caps; + int ret; if (!priv) return -EINVAL; @@ -760,7 +766,9 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) regs = priv->esdhc_regs; /* First reset the eSDHC controller */ - esdhc_reset(regs); + ret = esdhc_reset(regs); + if (ret) + return ret; #ifndef CONFIG_FSL_USDHC esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN From 201e828b22d79bafc7a68a93e1ade4b242a12325 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:20 -0600 Subject: [PATCH 34/47] dm: mmc: fsl_esdhc: Detect init failure Since esdhc_init_common() can fail it should return an error code. Update this and also adjust the timeout mechanism to use get_timer(), which is a more common approach. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 1e1e92d740..abb1f1e246 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -621,14 +621,17 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { struct fsl_esdhc *regs = priv->esdhc_regs; - int timeout = 1000; + ulong start; /* Reset the entire host controller */ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); /* Wait until the controller is available */ - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout) - udelay(1000); + start = get_timer(0); + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) { + if (get_timer(start) > 1000) + return -ETIMEDOUT; + } #if defined(CONFIG_FSL_USDHC) /* RSTA doesn't reset MMC_BOOT register, so manually reset it */ From e88e1d9c048671d6fd896318dab2484b4ecb1da3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:21 -0600 Subject: [PATCH 35/47] dm: mmc: fsl_esdhc: Set up platform data With driver model we want to store the mmc and configuration structure in platform data. Set up structure up and use it for non-DM as well. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 61 ++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index abb1f1e246..bb6fac2f39 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -81,6 +81,11 @@ struct fsl_esdhc { uint scr; /* eSDHC control register */ }; +struct fsl_esdhc_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + /** * struct fsl_esdhc_priv * @@ -101,7 +106,6 @@ struct fsl_esdhc_priv { struct fsl_esdhc *esdhc_regs; unsigned int sdhc_clk; unsigned int bus_width; - struct mmc_config cfg; struct mmc *mmc; struct udevice *dev; int non_removable; @@ -756,8 +760,10 @@ static const struct mmc_ops esdhc_ops = { .set_ios = esdhc_set_ios, }; -static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) +static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, + struct fsl_esdhc_plat *plat) { + struct mmc_config *cfg; struct fsl_esdhc *regs; struct mmc *mmc; u32 caps, voltage_caps; @@ -785,7 +791,8 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); - memset(&priv->cfg, 0, sizeof(priv->cfg)); + cfg = &plat->cfg; + memset(cfg, '\0', sizeof(*cfg)); voltage_caps = 0; caps = esdhc_read32(®s->hostcapblt); @@ -807,49 +814,49 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv) if (caps & ESDHC_HOSTCAPBLT_VS33) voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; - priv->cfg.name = "FSL_SDHC"; - priv->cfg.ops = &esdhc_ops; + cfg->name = "FSL_SDHC"; + cfg->ops = &esdhc_ops; #ifdef CONFIG_SYS_SD_VOLTAGE - priv->cfg.voltages = CONFIG_SYS_SD_VOLTAGE; + cfg->voltages = CONFIG_SYS_SD_VOLTAGE; #else - priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; #endif - if ((priv->cfg.voltages & voltage_caps) == 0) { + if ((cfg->voltages & voltage_caps) == 0) { printf("voltage not supported by controller\n"); return -1; } if (priv->bus_width == 8) - priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; + cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; else if (priv->bus_width == 4) - priv->cfg.host_caps = MMC_MODE_4BIT; + cfg->host_caps = MMC_MODE_4BIT; - priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; + cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; #ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE - priv->cfg.host_caps |= MMC_MODE_DDR_52MHz; + cfg->host_caps |= MMC_MODE_DDR_52MHz; #endif if (priv->bus_width > 0) { if (priv->bus_width < 8) - priv->cfg.host_caps &= ~MMC_MODE_8BIT; + cfg->host_caps &= ~MMC_MODE_8BIT; if (priv->bus_width < 4) - priv->cfg.host_caps &= ~MMC_MODE_4BIT; + cfg->host_caps &= ~MMC_MODE_4BIT; } if (caps & ESDHC_HOSTCAPBLT_HSS) - priv->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; #ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) - priv->cfg.host_caps &= ~MMC_MODE_8BIT; + cfg->host_caps &= ~MMC_MODE_8BIT; #endif - priv->cfg.f_min = 400000; - priv->cfg.f_max = min(priv->sdhc_clk, (u32)52000000); + cfg->f_min = 400000; + cfg->f_max = min(priv->sdhc_clk, (u32)52000000); - priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - mmc = mmc_create(&priv->cfg, priv); + mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; @@ -876,6 +883,7 @@ static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) { + struct fsl_esdhc_plat *plat; struct fsl_esdhc_priv *priv; int ret; @@ -885,17 +893,24 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) priv = calloc(sizeof(struct fsl_esdhc_priv), 1); if (!priv) return -ENOMEM; + plat = calloc(sizeof(struct fsl_esdhc_plat), 1); + if (!plat) { + free(priv); + return -ENOMEM; + } ret = fsl_esdhc_cfg_to_priv(cfg, priv); if (ret) { debug("%s xlate failure\n", __func__); + free(plat); free(priv); return ret; } - ret = fsl_esdhc_init(priv); + ret = fsl_esdhc_init(priv, plat); if (ret) { debug("%s init failure\n", __func__); + free(plat); free(priv); return ret; } @@ -996,6 +1011,7 @@ __weak void init_clk_usdhc(u32 index) static int fsl_esdhc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); @@ -1090,7 +1106,7 @@ static int fsl_esdhc_probe(struct udevice *dev) return -EINVAL; } - ret = fsl_esdhc_init(priv); + ret = fsl_esdhc_init(priv, plat); if (ret) { dev_err(dev, "fsl_esdhc_init failure\n"); return ret; @@ -1118,6 +1134,7 @@ U_BOOT_DRIVER(fsl_esdhc) = { .id = UCLASS_MMC, .of_match = fsl_esdhc_ids, .probe = fsl_esdhc_probe, + .platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat), .priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv), }; #endif From d6eb25e9878617f9a1d7f06ec21c9b981bb0a4e5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:22 -0600 Subject: [PATCH 36/47] dm: mmc: fsl_esdhc: Drop mmc_init() call from fsl_esdhc_init() We want to use fsl_esdhc_init() with driver model. Move the mmc_init() out of this function so that we can use it for our common init. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index bb6fac2f39..662824fda1 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -765,7 +765,6 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, { struct mmc_config *cfg; struct fsl_esdhc *regs; - struct mmc *mmc; u32 caps, voltage_caps; int ret; @@ -856,12 +855,6 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - mmc = mmc_create(cfg, priv); - if (mmc == NULL) - return -1; - - priv->mmc = mmc; - return 0; } @@ -885,6 +878,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) { struct fsl_esdhc_plat *plat; struct fsl_esdhc_priv *priv; + struct mmc *mmc; int ret; if (!cfg) @@ -915,6 +909,12 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) return ret; } + mmc = mmc_create(&plat->cfg, priv); + if (!mmc) + return -EIO; + + priv->mmc = mmc; + return 0; } From 4aac33f510b12df4dceb279d87c86833f9f016c1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:23 -0600 Subject: [PATCH 37/47] dm: mmc: fsl_esdhc: Update to support livetree Update this driver to support a live device tree. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 662824fda1..d4257b29ee 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -1013,8 +1013,6 @@ static int fsl_esdhc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct fsl_esdhc_plat *plat = dev_get_platdata(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); - const void *fdt = gd->fdt_blob; - int node = dev_of_offset(dev); #ifdef CONFIG_DM_REGULATOR struct udevice *vqmmc_dev; #endif @@ -1022,14 +1020,14 @@ static int fsl_esdhc_probe(struct udevice *dev) unsigned int val; int ret; - addr = devfdt_get_addr(dev); + addr = dev_read_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; priv->esdhc_regs = (struct fsl_esdhc *)addr; priv->dev = dev; - val = fdtdec_get_int(fdt, node, "bus-width", -1); + val = dev_read_u32_default(dev, "bus-width", -1); if (val == 8) priv->bus_width = 8; else if (val == 4) @@ -1037,21 +1035,21 @@ static int fsl_esdhc_probe(struct udevice *dev) else priv->bus_width = 1; - if (fdt_get_property(fdt, node, "non-removable", NULL)) { + if (dev_read_bool(dev, "non-removable")) { priv->non_removable = 1; } else { priv->non_removable = 0; #ifdef CONFIG_DM_GPIO - gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios", - 0, &priv->cd_gpio, GPIOD_IS_IN); + gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, + GPIOD_IS_IN); #endif } priv->wp_enable = 1; #ifdef CONFIG_DM_GPIO - ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "wp-gpios", 0, - &priv->wp_gpio, GPIOD_IS_IN); + ret = gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, + GPIOD_IS_IN); if (ret) priv->wp_enable = 0; #endif From 653282b5672c6a9b50cb045510e95f44e20ab8a7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:24 -0600 Subject: [PATCH 38/47] dm: mmc: fsl_esdhc: Update to support MMC operations This driver does not currently support CONFIG_DM_MMC_OPS. Update it to fully convert it to driver model. Signed-off-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 69 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index d4257b29ee..0f51d0d896 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -106,7 +106,9 @@ struct fsl_esdhc_priv { struct fsl_esdhc *esdhc_regs; unsigned int sdhc_clk; unsigned int bus_width; +#if !CONFIG_IS_ENABLED(BLK) struct mmc *mmc; +#endif struct udevice *dev; int non_removable; int wp_enable; @@ -690,7 +692,7 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) return 1; #endif -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) if (priv->non_removable) return 1; #ifdef CONFIG_DM_GPIO @@ -724,6 +726,7 @@ static int esdhc_reset(struct fsl_esdhc *regs) return 0; } +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) static int esdhc_getcd(struct mmc *mmc) { struct fsl_esdhc_priv *priv = mmc->priv; @@ -759,6 +762,7 @@ static const struct mmc_ops esdhc_ops = { .send_cmd = esdhc_send_cmd, .set_ios = esdhc_set_ios, }; +#endif static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, struct fsl_esdhc_plat *plat) @@ -791,7 +795,9 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); cfg = &plat->cfg; +#ifndef CONFIG_DM_MMC memset(cfg, '\0', sizeof(*cfg)); +#endif voltage_caps = 0; caps = esdhc_read32(®s->hostcapblt); @@ -814,7 +820,9 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; cfg->name = "FSL_SDHC"; +#if !CONFIG_IS_ENABLED(DM_MMC_OPS) cfg->ops = &esdhc_ops; +#endif #ifdef CONFIG_SYS_SD_VOLTAGE cfg->voltages = CONFIG_SYS_SD_VOLTAGE; #else @@ -1002,7 +1010,7 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd) } #endif -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) #include __weak void init_clk_usdhc(u32 index) { @@ -1018,6 +1026,7 @@ static int fsl_esdhc_probe(struct udevice *dev) #endif fdt_addr_t addr; unsigned int val; + struct mmc *mmc; int ret; addr = dev_read_addr(dev); @@ -1110,12 +1119,47 @@ static int fsl_esdhc_probe(struct udevice *dev) return ret; } - upriv->mmc = priv->mmc; - priv->mmc->dev = dev; + mmc = &plat->mmc; + mmc->cfg = &plat->cfg; + mmc->dev = dev; + upriv->mmc = mmc; - return 0; + return esdhc_init_common(priv, mmc); } +#if CONFIG_IS_ENABLED(DM_MMC_OPS) +static int fsl_esdhc_get_cd(struct udevice *dev) +{ + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return true; + return esdhc_getcd_common(priv); +} + +static int fsl_esdhc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return esdhc_send_cmd_common(priv, &plat->mmc, cmd, data); +} + +static int fsl_esdhc_set_ios(struct udevice *dev) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + struct fsl_esdhc_priv *priv = dev_get_priv(dev); + + return esdhc_set_ios_common(priv, &plat->mmc); +} + +static const struct dm_mmc_ops fsl_esdhc_ops = { + .get_cd = fsl_esdhc_get_cd, + .send_cmd = fsl_esdhc_send_cmd, + .set_ios = fsl_esdhc_set_ios, +}; +#endif + static const struct udevice_id fsl_esdhc_ids[] = { { .compatible = "fsl,imx6ul-usdhc", }, { .compatible = "fsl,imx6sx-usdhc", }, @@ -1127,10 +1171,25 @@ static const struct udevice_id fsl_esdhc_ids[] = { { /* sentinel */ } }; +#if CONFIG_IS_ENABLED(BLK) +static int fsl_esdhc_bind(struct udevice *dev) +{ + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} +#endif + U_BOOT_DRIVER(fsl_esdhc) = { .name = "fsl-esdhc-mmc", .id = UCLASS_MMC, .of_match = fsl_esdhc_ids, +#if CONFIG_IS_ENABLED(DM_MMC_OPS) + .ops = &fsl_esdhc_ops, +#endif +#if CONFIG_IS_ENABLED(BLK) + .bind = fsl_esdhc_bind, +#endif .probe = fsl_esdhc_probe, .platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat), .priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv), From 8d331e38e056542399f8453141b42eb725edae37 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:25 -0600 Subject: [PATCH 39/47] dm: imx: cm_fx6: Support driver model for SATA Add support for using driver model for SATA with the cm_fx6 board. The old code remains for now to permit testing. Signed-off-by: Simon Glass --- board/compulab/cm_fx6/cm_fx6.c | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index c59884a8c3..ecefe394f1 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -9,7 +9,9 @@ */ #include +#include #include +#include #include #include #include @@ -29,6 +31,7 @@ #include #include #include +#include #include #include "common.h" #include "../common/eeprom.h" @@ -206,6 +209,8 @@ static int cm_fx6_setup_issd(void) } #define CM_FX6_SATA_INIT_RETRIES 10 + +# if !CONFIG_IS_ENABLED(AHCI) int sata_initialize(void) { int err, i; @@ -246,6 +251,7 @@ int sata_stop(void) return 0; } +# endif #else static int cm_fx6_setup_issd(void) { return 0; } #endif @@ -757,3 +763,66 @@ U_BOOT_DEVICE(cm_fx6_serial) = { .name = "serial_mxc", .platdata = &cm_fx6_mxc_serial_plat, }; + +#if CONFIG_IS_ENABLED(AHCI) +static int sata_imx_probe(struct udevice *dev) +{ + int i, err; + + /* Make sure this gpio has logical 0 value */ + gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); + udelay(100); + cm_fx6_sata_power(1); + + for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) { + err = setup_sata(); + if (err) { + printf("SATA setup failed: %d\n", err); + return err; + } + + udelay(100); + + err = dwc_ahsata_probe(dev); + if (!err) + break; + + /* There is no device on the SATA port */ + if (sata_dm_port_status(0, 0) == 0) + break; + + /* There's a device, but link not established. Retry */ + device_remove(dev, DM_REMOVE_NORMAL); + } + + return 0; +} + +static int sata_imx_remove(struct udevice *dev) +{ + cm_fx6_sata_power(0); + mdelay(250); + + return 0; +} + +struct ahci_ops sata_imx_ops = { + .port_status = dwc_ahsata_port_status, + .reset = dwc_ahsata_bus_reset, + .scan = dwc_ahsata_scan, +}; + +static const struct udevice_id sata_imx_ids[] = { + { .compatible = "fsl,imx6q-ahci" }, + { } +}; + +U_BOOT_DRIVER(sata_imx) = { + .name = "dwc_ahci", + .id = UCLASS_AHCI, + .of_match = sata_imx_ids, + .ops = &sata_imx_ops, + .probe = sata_imx_probe, + .remove = sata_imx_remove, /* reset bus to stop it */ +}; +#endif /* AHCI */ From 5ec1f560f3cf082108cd6ed1fd29ae6557aa5a59 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:26 -0600 Subject: [PATCH 40/47] dm: imx: cm_fx6: Add device tree for cm_fx6 Add this file so we can use device-tree control for cm_fx6. It comes from linux 4.12. Signed-off-by: Simon Glass --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6q-cm-fx6.dts | 115 ++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 arch/arm/dts/imx6q-cm-fx6.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2cbdb17ca5..a8b61e9542 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -357,6 +357,7 @@ dtb-$(CONFIG_MX6) += imx6ull-14x14-evk.dtb \ imx6sll-evk.dtb \ imx6dl-icore.dtb \ imx6dl-icore-rqs.dtb \ + imx6q-cm-fx6.dtb \ imx6q-icore.dtb \ imx6q-icore-rqs.dtb \ imx6q-logicpd.dtb \ diff --git a/arch/arm/dts/imx6q-cm-fx6.dts b/arch/arm/dts/imx6q-cm-fx6.dts new file mode 100644 index 0000000000..4f1fced40e --- /dev/null +++ b/arch/arm/dts/imx6q-cm-fx6.dts @@ -0,0 +1,115 @@ +/* + * Copyright 2013 CompuLab Ltd. + * + * Author: Valentin Raevsky + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx6q.dtsi" + +/ { + model = "CompuLab CM-FX6"; + compatible = "compulab,cm-fx6", "fsl,imx6q"; + + memory { + reg = <0x10000000 0x80000000>; + }; + + leds { + compatible = "gpio-leds"; + + heartbeat-led { + label = "Heartbeat"; + gpios = <&gpio2 31 0>; + linux,default-trigger = "heartbeat"; + }; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + status = "okay"; +}; + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + status = "okay"; +}; + +&iomuxc { + imx6q-cm-fx6 { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + >; + }; + + pinctrl_gpmi_nand: gpminandgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1 + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1 + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000 + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1 + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1 + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1 + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1 + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1 + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1 + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1 + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1 + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1 + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1 + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1 + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1 + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + }; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&usdhc3 { + status = "okay"; +}; From 4f6478d646a265d992bd4bba9adc318f5e580b26 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:27 -0600 Subject: [PATCH 41/47] dm: imx: cm_fx6: Add MMC support for CONFIG_BLK When CONFIG_BLK is enabled our weak board_mmc_init() will not be called. Since there is no clock driver for MX6 yet, we must manually enable the clocks. Signed-off-by: Simon Glass --- board/compulab/cm_fx6/cm_fx6.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index ecefe394f1..ff3bab7889 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -678,6 +678,17 @@ int board_init(void) cm_fx6_setup_display(); + /* This should be done in the MMC driver when MX6 has a clock driver */ +#ifdef CONFIG_FSL_ESDHC + if (IS_ENABLED(CONFIG_BLK)) { + int i; + + cm_fx6_set_usdhc_iomux(); + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) + enable_usdhc_clk(1, i); + } +#endif + return 0; } From 5248930ebf48448b76a59069a5a96037264c3d6e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:28 -0600 Subject: [PATCH 42/47] dm: imx: cm_fx6: Enable more driver model support Enable driver model for MMC (including BLK), SATA and USB. Note that USB does not yet work correctly since the nodes are disabled. Hopefully this can be resolved by the maintainer. Signed-off-by: Simon Glass --- configs/cm_fx6_defconfig | 8 +++++++- drivers/mmc/fsl_esdhc.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig index bbe82a678d..d3aab58cf6 100644 --- a/configs/cm_fx6_defconfig +++ b/configs/cm_fx6_defconfig @@ -11,6 +11,8 @@ CONFIG_SPL_SPI_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_VIDEO=y # CONFIG_CMD_BMODE is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6q-cm-fx6" +CONFIG_AHCI=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6QDL" CONFIG_ENV_IS_IN_SPI_FLASH=y @@ -49,6 +51,8 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y +CONFIG_OF_CONTROL=y +CONFIG_DM_MMC=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_ATMEL=y CONFIG_SPI_FLASH_EON=y @@ -59,9 +63,11 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_SST=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_PHYLIB=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y -CONFIG_OF_LIBFDT=y CONFIG_FDT_FIXUP_PARTITIONS=y diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 0f51d0d896..b49a269e4b 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -866,7 +866,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, return 0; } -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, struct fsl_esdhc_priv *priv) { From 2088747743a38f7d074aa034809874c1f17e218a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:29 -0600 Subject: [PATCH 43/47] dm: imx: Move i.MX devices to use CONFIG_DM_MMC_OPS Now that the driver supports it, move these boards over to use driver model fully for MMC. Signed-off-by: Simon Glass --- configs/imx6q_logic_defconfig | 1 - configs/imx6qdl_icore_mmc_defconfig | 1 - configs/imx6qdl_icore_rqs_defconfig | 1 - configs/imx6ul_geam_mmc_defconfig | 1 - configs/imx6ul_geam_nand_defconfig | 1 - configs/imx6ul_isiot_emmc_defconfig | 1 - configs/imx6ul_isiot_mmc_defconfig | 1 - configs/imx6ul_isiot_nand_defconfig | 1 - configs/ls1012aqds_qspi_defconfig | 1 - configs/ls1012ardb_qspi_defconfig | 1 - configs/mx6slevk_defconfig | 1 - configs/mx6slevk_spinor_defconfig | 1 - configs/mx6sllevk_defconfig | 1 - configs/mx6sllevk_plugin_defconfig | 1 - configs/mx6sxsabreauto_defconfig | 1 - configs/mx6ull_14x14_evk_defconfig | 1 - configs/mx6ull_14x14_evk_plugin_defconfig | 1 - configs/mx7dsabresd_defconfig | 1 - configs/mx7dsabresd_secure_defconfig | 1 - configs/mx7ulp_evk_defconfig | 1 - configs/mx7ulp_evk_plugin_defconfig | 1 - configs/opos6uldev_defconfig | 1 - 22 files changed, 22 deletions(-) diff --git a/configs/imx6q_logic_defconfig b/configs/imx6q_logic_defconfig index 1070f892c4..bb13abedf7 100644 --- a/configs/imx6q_logic_defconfig +++ b/configs/imx6q_logic_defconfig @@ -31,7 +31,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_NAND=y CONFIG_NAND_MXS=y CONFIG_PHYLIB=y diff --git a/configs/imx6qdl_icore_mmc_defconfig b/configs/imx6qdl_icore_mmc_defconfig index 090480aacb..ec39d09134 100644 --- a/configs/imx6qdl_icore_mmc_defconfig +++ b/configs/imx6qdl_icore_mmc_defconfig @@ -38,7 +38,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_LIST="imx6q-icore imx6dl-icore" # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6qdl_icore_rqs_defconfig b/configs/imx6qdl_icore_rqs_defconfig index 78128a0872..ba3ac1bbf9 100644 --- a/configs/imx6qdl_icore_rqs_defconfig +++ b/configs/imx6qdl_icore_rqs_defconfig @@ -36,7 +36,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_LIST="imx6q-icore-rqs imx6dl-icore-rqs" # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_geam_mmc_defconfig b/configs/imx6ul_geam_mmc_defconfig index dfeb083c8f..d0abfd8029 100644 --- a/configs/imx6ul_geam_mmc_defconfig +++ b/configs/imx6ul_geam_mmc_defconfig @@ -35,7 +35,6 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_geam_nand_defconfig b/configs/imx6ul_geam_nand_defconfig index ed81f61759..3c07901180 100644 --- a/configs/imx6ul_geam_nand_defconfig +++ b/configs/imx6ul_geam_nand_defconfig @@ -34,7 +34,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_NAND=y CONFIG_NAND_MXS=y CONFIG_PHYLIB=y diff --git a/configs/imx6ul_isiot_emmc_defconfig b/configs/imx6ul_isiot_emmc_defconfig index 318deb692d..eeb0509e20 100644 --- a/configs/imx6ul_isiot_emmc_defconfig +++ b/configs/imx6ul_isiot_emmc_defconfig @@ -33,7 +33,6 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_BLK is not set -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_isiot_mmc_defconfig b/configs/imx6ul_isiot_mmc_defconfig index 8abfbabfcc..afa64d8055 100644 --- a/configs/imx6ul_isiot_mmc_defconfig +++ b/configs/imx6ul_isiot_mmc_defconfig @@ -35,7 +35,6 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y diff --git a/configs/imx6ul_isiot_nand_defconfig b/configs/imx6ul_isiot_nand_defconfig index ad11ac3a37..9acf6c535f 100644 --- a/configs/imx6ul_isiot_nand_defconfig +++ b/configs/imx6ul_isiot_nand_defconfig @@ -34,7 +34,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y # CONFIG_BLK is not set CONFIG_SYS_I2C_MXC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_NAND=y CONFIG_NAND_MXS=y CONFIG_PHYLIB=y diff --git a/configs/ls1012aqds_qspi_defconfig b/configs/ls1012aqds_qspi_defconfig index ff58a74986..426992e577 100644 --- a/configs/ls1012aqds_qspi_defconfig +++ b/configs/ls1012aqds_qspi_defconfig @@ -36,7 +36,6 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y # CONFIG_BLK is not set CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_NETDEVICES=y diff --git a/configs/ls1012ardb_qspi_defconfig b/configs/ls1012ardb_qspi_defconfig index 6a150221b2..4eaaecd991 100644 --- a/configs/ls1012ardb_qspi_defconfig +++ b/configs/ls1012ardb_qspi_defconfig @@ -34,7 +34,6 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y # CONFIG_BLK is not set CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_NETDEVICES=y diff --git a/configs/mx6slevk_defconfig b/configs/mx6slevk_defconfig index ee27daa68e..f7f4b0edf1 100644 --- a/configs/mx6slevk_defconfig +++ b/configs/mx6slevk_defconfig @@ -32,7 +32,6 @@ CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y diff --git a/configs/mx6slevk_spinor_defconfig b/configs/mx6slevk_spinor_defconfig index 354eae3f57..a3d68512cf 100644 --- a/configs/mx6slevk_spinor_defconfig +++ b/configs/mx6slevk_spinor_defconfig @@ -33,7 +33,6 @@ CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y diff --git a/configs/mx6sllevk_defconfig b/configs/mx6sllevk_defconfig index 916fa091fa..11d2500949 100644 --- a/configs/mx6sllevk_defconfig +++ b/configs/mx6sllevk_defconfig @@ -29,7 +29,6 @@ CONFIG_OF_CONTROL=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_PMIC=y diff --git a/configs/mx6sllevk_plugin_defconfig b/configs/mx6sllevk_plugin_defconfig index 12f865713d..064c949e35 100644 --- a/configs/mx6sllevk_plugin_defconfig +++ b/configs/mx6sllevk_plugin_defconfig @@ -30,7 +30,6 @@ CONFIG_OF_CONTROL=y CONFIG_DM_GPIO=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_PMIC=y diff --git a/configs/mx6sxsabreauto_defconfig b/configs/mx6sxsabreauto_defconfig index a8144fe802..ebf0a9aacb 100644 --- a/configs/mx6sxsabreauto_defconfig +++ b/configs/mx6sxsabreauto_defconfig @@ -34,7 +34,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig index 2c03f8cba8..6ed18da376 100644 --- a/configs/mx6ull_14x14_evk_defconfig +++ b/configs/mx6ull_14x14_evk_defconfig @@ -27,7 +27,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR=y diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig index 1a5bbb6265..2c5ae76f26 100644 --- a/configs/mx6ull_14x14_evk_plugin_defconfig +++ b/configs/mx6ull_14x14_evk_plugin_defconfig @@ -28,7 +28,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR=y diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig index 7c99420e85..8f2e33adc8 100644 --- a/configs/mx7dsabresd_defconfig +++ b/configs/mx7dsabresd_defconfig @@ -45,7 +45,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_EON=y CONFIG_PHYLIB=y diff --git a/configs/mx7dsabresd_secure_defconfig b/configs/mx7dsabresd_secure_defconfig index ea087d2af4..bba933f250 100644 --- a/configs/mx7dsabresd_secure_defconfig +++ b/configs/mx7dsabresd_secure_defconfig @@ -47,7 +47,6 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_EON=y CONFIG_PHYLIB=y diff --git a/configs/mx7ulp_evk_defconfig b/configs/mx7ulp_evk_defconfig index 5918f3c0c7..49b576954b 100644 --- a/configs/mx7ulp_evk_defconfig +++ b/configs/mx7ulp_evk_defconfig @@ -16,7 +16,6 @@ CONFIG_DM_GPIO=y CONFIG_IMX_RGPIO2P=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX7ULP=y CONFIG_DM_REGULATOR=y diff --git a/configs/mx7ulp_evk_plugin_defconfig b/configs/mx7ulp_evk_plugin_defconfig index 5918f3c0c7..49b576954b 100644 --- a/configs/mx7ulp_evk_plugin_defconfig +++ b/configs/mx7ulp_evk_plugin_defconfig @@ -16,7 +16,6 @@ CONFIG_DM_GPIO=y CONFIG_IMX_RGPIO2P=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX7ULP=y CONFIG_DM_REGULATOR=y diff --git a/configs/opos6uldev_defconfig b/configs/opos6uldev_defconfig index f4511af293..88ba18eaeb 100644 --- a/configs/opos6uldev_defconfig +++ b/configs/opos6uldev_defconfig @@ -62,7 +62,6 @@ CONFIG_SYSCON=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MXC=y CONFIG_PWRSEQ=y -# CONFIG_DM_MMC_OPS is not set CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_NETDEVICES=y From b9a40c0c0ad82944c55d10b866a96b25c48e9f5f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:30 -0600 Subject: [PATCH 44/47] dm: mmc: Correct Kconfig condition for SPL_DM_MMC_OPS This should depend on SPL_DM_MMC, not SPL_DM. For it and update the only affected board's defconfig. Signed-off-by: Simon Glass --- drivers/mmc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 51a87cdd77..ecf5a92949 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -43,7 +43,7 @@ config SPL_DM_MMC config SPL_DM_MMC_OPS bool "Support MMC controller operations using Driver Model in SPL" - depends on SPL_DM && DM_MMC_OPS + depends on SPL_DM_MMC && DM_MMC_OPS default y help Driver model provides a means of supporting device operations. This From e7881d85a94b2e35b12a163c3af671057e9ca5e8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 29 Jul 2017 11:35:31 -0600 Subject: [PATCH 45/47] dm: mmc: Drop CONFIG_DM_MMC_OPS All boards which use DM_MMC have now been converted to use DM_MMC_OPS. Drop the option and good riddance. Signed-off-by: Simon Glass --- arch/arm/Kconfig | 2 -- drivers/mmc/Kconfig | 40 +++++++++-------------------------- drivers/mmc/dw_mmc.c | 8 +++---- drivers/mmc/fsl_esdhc.c | 8 +++---- drivers/mmc/mmc-uclass.c | 4 ---- drivers/mmc/mmc.c | 12 +++++------ drivers/mmc/mmc_legacy.c | 2 +- drivers/mmc/sdhci.c | 8 +++---- include/configs/am335x_evm.h | 1 - include/configs/am335x_shc.h | 1 - include/configs/chiliboard.h | 1 - include/configs/omap3_logic.h | 1 - include/dwmmc.h | 2 +- include/mmc.h | 6 +++--- include/sdhci.h | 2 +- 15 files changed, 33 insertions(+), 65 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 39b001fd53..f75cfad47a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -726,7 +726,6 @@ config ARCH_ZYNQ select DM_GPIO select SPL_DM if SPL select DM_MMC - select DM_MMC_OPS select DM_SPI select DM_SERIAL select DM_SPI_FLASH @@ -1075,7 +1074,6 @@ config ARCH_ROCKCHIP select DM_GPIO select DM_I2C select DM_MMC - select DM_MMC_OPS select DM_SERIAL select DM_SPI select DM_SPI_FLASH diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index ecf5a92949..56c352e72a 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -20,16 +20,6 @@ config DM_MMC appear as block devices in U-Boot and can support filesystems such as EXT4 and FAT. -config DM_MMC_OPS - bool "Support MMC controller operations using Driver Model" - depends on DM_MMC - default y if DM_MMC - help - Driver model provides a means of supporting device operations. This - option moves MMC operations under the control of driver model. The - option will be removed as soon as all DM_MMC drivers use it, as it - will the only supported behaviour. - config SPL_DM_MMC bool "Enable MMC controllers using Driver Model in SPL" depends on SPL_DM && DM_MMC @@ -41,16 +31,6 @@ config SPL_DM_MMC appear as block devices in U-Boot and can support filesystems such as EXT4 and FAT. -config SPL_DM_MMC_OPS - bool "Support MMC controller operations using Driver Model in SPL" - depends on SPL_DM_MMC && DM_MMC_OPS - default y - help - Driver model provides a means of supporting device operations. This - option moves MMC operations under the control of driver model. The - option will be removed as soon as all DM_MMC drivers use it, as it - will the only supported behaviour. - if MMC config SPL_MMC_TINY @@ -124,7 +104,7 @@ config MMC_DW_SOCFPGA config MMC_MESON_GX bool "Meson GX EMMC controller support" - depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_MESON + depends on DM_MMC && BLK && ARCH_MESON help Support for EMMC host controller on Meson GX ARM SoCs platform (S905) @@ -155,7 +135,7 @@ config MMC_PCI config MMC_OMAP_HS bool "TI OMAP High Speed Multimedia Card Interface support" - select DM_MMC_OPS if DM_MMC + select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR help This selects the TI OMAP High Speed Multimedia card Interface. If you have an omap2plus board with a Multimedia Card slot, @@ -184,7 +164,7 @@ config SH_SDHI config MMC_UNIPHIER bool "UniPhier SD/MMC Host Controller support" depends on ARCH_UNIPHIER - depends on BLK && DM_MMC_OPS + depends on BLK && DM_MMC depends on OF_CONTROL help This selects support for the SD/MMC Host Controller on UniPhier SoCs. @@ -192,7 +172,7 @@ config MMC_UNIPHIER config MMC_SANDBOX bool "Sandbox MMC support" depends on SANDBOX - depends on BLK && DM_MMC_OPS && OF_CONTROL + depends on BLK && DM_MMC && OF_CONTROL help This select a dummy sandbox MMC driver. At present this does nothing other than allow sandbox to be build with MMC support. This @@ -227,7 +207,7 @@ config MMC_SDHCI_SDMA config MMC_SDHCI_ATMEL bool "Atmel SDHCI controller support" depends on ARCH_AT91 - depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_AT91 + depends on DM_MMC && BLK && ARCH_AT91 depends on MMC_SDHCI help This enables support for the Atmel SDHCI controller, which supports @@ -251,7 +231,7 @@ config MMC_SDHCI_BCM2835 config MMC_SDHCI_CADENCE bool "SDHCI support for the Cadence SD/SDIO/eMMC controller" - depends on BLK && DM_MMC_OPS + depends on BLK && DM_MMC depends on MMC_SDHCI depends on OF_CONTROL help @@ -273,7 +253,7 @@ config MMC_SDHCI_KONA config MMC_SDHCI_MSM bool "Qualcomm SDHCI controller" - depends on BLK && DM_MMC_OPS + depends on BLK && DM_MMC depends on MMC_SDHCI help Enables support for SDHCI 2.0 controller present on some Qualcomm @@ -303,7 +283,7 @@ config MMC_SDHCI_PIC32 config MMC_SDHCI_ROCKCHIP bool "Arasan SDHCI controller for Rockchip support" depends on ARCH_ROCKCHIP - depends on DM_MMC && BLK && DM_MMC_OPS + depends on DM_MMC && BLK depends on MMC_SDHCI help Support for Arasan SDHCI host controller on Rockchip ARM SoCs platform @@ -376,7 +356,7 @@ config MMC_SDHCI_TEGRA config MMC_SDHCI_ZYNQ bool "Arasan SDHCI controller support" depends on ARCH_ZYNQ || ARCH_ZYNQMP - depends on DM_MMC && OF_CONTROL && BLK && DM_MMC_OPS + depends on DM_MMC && OF_CONTROL && BLK depends on MMC_SDHCI help Support for Arasan SDHCI host controller on Zynq/ZynqMP ARM SoCs platform @@ -391,7 +371,7 @@ config MMC_SUNXI config GENERIC_ATMEL_MCI bool "Atmel Multimedia Card Interface support" - depends on DM_MMC && BLK && DM_MMC_OPS && ARCH_AT91 + depends on DM_MMC && BLK && ARCH_AT91 help This enables support for Atmel High Speed Multimedia Card Interface (HSMCI), which supports the MultiMedia Card (MMC) Specification V4.3, diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 700f764432..23f642980b 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -184,7 +184,7 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host, return mode; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -383,7 +383,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) return 0; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int dwmci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -466,7 +466,7 @@ static int dwmci_init(struct mmc *mmc) return 0; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC int dwmci_probe(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -491,7 +491,7 @@ void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host, u32 max_clk, u32 min_clk) { cfg->name = host->name; -#ifndef CONFIG_DM_MMC_OPS +#ifndef CONFIG_DM_MMC cfg->ops = &dwmci_ops; #endif cfg->f_min = min_clk; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index b49a269e4b..cc188c4260 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -726,7 +726,7 @@ static int esdhc_reset(struct fsl_esdhc *regs) return 0; } -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) static int esdhc_getcd(struct mmc *mmc) { struct fsl_esdhc_priv *priv = mmc->priv; @@ -820,7 +820,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; cfg->name = "FSL_SDHC"; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) cfg->ops = &esdhc_ops; #endif #ifdef CONFIG_SYS_SD_VOLTAGE @@ -1127,7 +1127,7 @@ static int fsl_esdhc_probe(struct udevice *dev) return esdhc_init_common(priv, mmc); } -#if CONFIG_IS_ENABLED(DM_MMC_OPS) +#if CONFIG_IS_ENABLED(DM_MMC) static int fsl_esdhc_get_cd(struct udevice *dev) { struct fsl_esdhc_priv *priv = dev_get_priv(dev); @@ -1184,9 +1184,7 @@ U_BOOT_DRIVER(fsl_esdhc) = { .name = "fsl-esdhc-mmc", .id = UCLASS_MMC, .of_match = fsl_esdhc_ids, -#if CONFIG_IS_ENABLED(DM_MMC_OPS) .ops = &fsl_esdhc_ops, -#endif #if CONFIG_IS_ENABLED(BLK) .bind = fsl_esdhc_bind, #endif diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 3e907253ea..5dda20cda5 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -15,7 +15,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -79,7 +78,6 @@ int mmc_getcd(struct mmc *mmc) { return dm_mmc_get_cd(mmc->dev); } -#endif struct mmc *mmc_get_mmc_dev(struct udevice *dev) { @@ -198,10 +196,8 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) struct udevice *bdev; int ret, devnum = -1; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) if (!mmc_get_ops(dev)) return -ENOSYS; -#endif #ifndef CONFIG_SPL_BUILD /* Use the fixed index with aliase node's index */ ret = dev_read_alias_seq(dev, &devnum); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 38e1c800e1..38d2e07dd5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -53,7 +53,7 @@ struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) } #endif -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -149,7 +149,7 @@ void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd) } #endif -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { int ret; @@ -839,7 +839,7 @@ int mmc_hwpart_config(struct mmc *mmc, return 0; } -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) int mmc_getcd(struct mmc *mmc) { int cd; @@ -1075,7 +1075,7 @@ static const u8 multipliers[] = { 80, }; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) static void mmc_set_ios(struct mmc *mmc) { if (mmc->cfg->ops->set_ios) @@ -1652,7 +1652,7 @@ int mmc_start_init(struct mmc *mmc) /* we pretend there's no card when init is NULL */ no_card = mmc_getcd(mmc) == 0; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) no_card = no_card || (mmc->cfg->ops->init == NULL); #endif if (no_card) { @@ -1673,7 +1673,7 @@ int mmc_start_init(struct mmc *mmc) if (err) return err; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) +#if CONFIG_IS_ENABLED(DM_MMC) /* The device has already been probed ready for use */ #else /* made sure it's not NULL earlier */ diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index 59dc3df35f..100b931e5b 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -150,7 +150,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) cfg->f_max == 0 || cfg->b_max == 0) return NULL; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) if (cfg->ops == NULL || cfg->ops->send_cmd == NULL) return NULL; #endif diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 161a6b1399..11d1f0c24c 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -134,7 +134,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, #define SDHCI_CMD_DEFAULT_TIMEOUT 100 #define SDHCI_READ_STATUS_TIMEOUT 1000 -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -422,7 +422,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC static int sdhci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -502,7 +502,7 @@ static int sdhci_init(struct mmc *mmc) return 0; } -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC int sdhci_probe(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -543,7 +543,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, host->version = sdhci_readw(host, SDHCI_HOST_VERSION); cfg->name = host->name; -#ifndef CONFIG_DM_MMC_OPS +#ifndef CONFIG_DM_MMC cfg->ops = &sdhci_ops; #endif diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index c9420b2d73..973f63f891 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -282,7 +282,6 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef CONFIG_TIMER #undef CONFIG_DM_USB #endif diff --git a/include/configs/am335x_shc.h b/include/configs/am335x_shc.h index 62ab2d7227..3fdbfdcdc6 100644 --- a/include/configs/am335x_shc.h +++ b/include/configs/am335x_shc.h @@ -256,7 +256,6 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef CONFIG_TIMER #endif diff --git a/include/configs/chiliboard.h b/include/configs/chiliboard.h index fb3e67466e..20075915fd 100644 --- a/include/configs/chiliboard.h +++ b/include/configs/chiliboard.h @@ -183,7 +183,6 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef CONFIG_TIMER #undef CONFIG_DM_USB #endif diff --git a/include/configs/omap3_logic.h b/include/configs/omap3_logic.h index 5490fc945a..b4311ab13b 100644 --- a/include/configs/omap3_logic.h +++ b/include/configs/omap3_logic.h @@ -23,7 +23,6 @@ * DM support in SPL */ #undef CONFIG_DM_MMC -#undef CONFIG_DM_MMC_OPS #undef OMAP_HSMMC_USE_GPIO /* select serial console configuration for SPL */ diff --git a/include/dwmmc.h b/include/dwmmc.h index 4dda0091ce..a9058824e0 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -291,7 +291,7 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); #endif /* !CONFIG_BLK */ -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC /* Export the operations to drivers */ int dwmci_probe(struct udevice *dev); extern const struct dm_mmc_ops dm_dwmci_ops; diff --git a/include/mmc.h b/include/mmc.h index cb8bf6a971..16a5c20a28 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -321,7 +321,7 @@ struct mmc_data { /* forward decl. */ struct mmc; -#if CONFIG_IS_ENABLED(DM_MMC_OPS) +#if CONFIG_IS_ENABLED(DM_MMC) struct dm_mmc_ops { /** * send_cmd() - Send a command to the MMC device @@ -385,7 +385,7 @@ struct mmc_ops { struct mmc_config { const char *name; -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) const struct mmc_ops *ops; #endif uint host_caps; @@ -519,7 +519,7 @@ int mmc_switch_part(struct mmc *mmc, unsigned int part_num); int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode); -#if !CONFIG_IS_ENABLED(DM_MMC_OPS) +#if !CONFIG_IS_ENABLED(DM_MMC) int mmc_getcd(struct mmc *mmc); int board_mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); diff --git a/include/sdhci.h b/include/sdhci.h index 6a43271e96..7e84012f60 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -410,7 +410,7 @@ int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); int add_sdhci(struct sdhci_host *host, u32 f_max, u32 f_min); #endif /* !CONFIG_BLK */ -#ifdef CONFIG_DM_MMC_OPS +#ifdef CONFIG_DM_MMC /* Export the operations to drivers */ int sdhci_probe(struct udevice *dev); extern const struct dm_mmc_ops sdhci_ops; From bdb6099666933491ce393e52132e05604da91b1a Mon Sep 17 00:00:00 2001 From: Angelo Dureghello Date: Tue, 1 Aug 2017 14:27:10 +0200 Subject: [PATCH 46/47] cmd: mmc: add mmc partconf read capability This patch allows to show the EXT_CSD[179] partition_config register info, just by specifying the dev param: U-Boot> mmc partconf 0 EXT_CSD[179], PARTITION_CONFIG: BOOT_ACK: 0x0 BOOT_PARTITION_ENABLE: 0x0 PARTITION_ACCESS: 0x0 Signed-off-by: Angelo Dureghello Signed-off-by: Anatolij Gustschin --- cmd/mmc.c | 38 ++++++++++++++++++++++++++++++++------ drivers/mmc/mmc_boot.c | 17 +++++++++++++---- include/mmc.h | 4 ++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/cmd/mmc.c b/cmd/mmc.c index f7b75684ad..00697fc1f2 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -643,6 +643,28 @@ static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag, printf("EMMC RPMB partition Size %d MB\n", rpmbsize); return CMD_RET_SUCCESS; } + +static int mmc_partconf_print(struct mmc *mmc) +{ + u8 ack, access, part; + + if (mmc->part_config == MMCPART_NOAVAILABLE) { + printf("No part_config info for ver. 0x%x\n", mmc->version); + return CMD_RET_FAILURE; + } + + access = EXT_CSD_EXTRACT_PARTITION_ACCESS(mmc->part_config); + ack = EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config); + part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config); + + printf("EXT_CSD[179], PARTITION_CONFIG:\n" + "BOOT_ACK: 0x%x\n" + "BOOT_PARTITION_ENABLE: 0x%x\n" + "PARTITION_ACCESS: 0x%x\n", ack, part, access); + + return CMD_RET_SUCCESS; +} + static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -650,13 +672,10 @@ static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, struct mmc *mmc; u8 ack, part_num, access; - if (argc != 5) + if (argc != 2 && argc != 5) return CMD_RET_USAGE; dev = simple_strtoul(argv[1], NULL, 10); - ack = simple_strtoul(argv[2], NULL, 10); - part_num = simple_strtoul(argv[3], NULL, 10); - access = simple_strtoul(argv[4], NULL, 10); mmc = init_mmc_device(dev, false); if (!mmc) @@ -667,6 +686,13 @@ static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } + if (argc == 2) + return mmc_partconf_print(mmc); + + ack = simple_strtoul(argv[2], NULL, 10); + part_num = simple_strtoul(argv[3], NULL, 10); + access = simple_strtoul(argv[4], NULL, 10); + /* acknowledge to be sent during boot operation */ return mmc_set_part_conf(mmc, ack, part_num, access); } @@ -832,8 +858,8 @@ U_BOOT_CMD( " - Set the BOOT_BUS_WIDTH field of the specified device\n" "mmc bootpart-resize \n" " - Change sizes of boot and RPMB partitions of specified device\n" - "mmc partconf dev boot_ack boot_partition partition_access\n" - " - Change the bits of the PARTITION_CONFIG field of the specified device\n" + "mmc partconf dev [boot_ack boot_partition partition_access]\n" + " - Show or change the bits of the PARTITION_CONFIG field of the specified device\n" "mmc rst-function dev value\n" " - Change the RST_n_FUNCTION field of the specified device\n" " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n" diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c index ac6f56f157..6d77ce95e7 100644 --- a/drivers/mmc/mmc_boot.c +++ b/drivers/mmc/mmc_boot.c @@ -100,10 +100,19 @@ int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode) */ int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) { - return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, - EXT_CSD_BOOT_ACK(ack) | - EXT_CSD_BOOT_PART_NUM(part_num) | - EXT_CSD_PARTITION_ACCESS(access)); + int ret; + u8 part_conf; + + part_conf = EXT_CSD_BOOT_ACK(ack) | + EXT_CSD_BOOT_PART_NUM(part_num) | + EXT_CSD_PARTITION_ACCESS(access); + + ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, + part_conf); + if (!ret) + mmc->part_config = part_conf; + + return ret; } /* diff --git a/include/mmc.h b/include/mmc.h index 16a5c20a28..010ebe048c 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -221,6 +221,10 @@ #define EXT_CSD_BOOT_PART_NUM(x) (x << 3) #define EXT_CSD_PARTITION_ACCESS(x) (x << 0) +#define EXT_CSD_EXTRACT_BOOT_ACK(x) (((x) >> 6) & 0x1) +#define EXT_CSD_EXTRACT_BOOT_PART(x) (((x) >> 3) & 0x7) +#define EXT_CSD_EXTRACT_PARTITION_ACCESS(x) ((x) & 0x7) + #define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3) #define EXT_CSD_BOOT_BUS_WIDTH_RESET(x) (x << 2) #define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x) (x) From a191ccaf12fb4fadedcd3c76df6327e2bb0f182b Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 9 Aug 2017 00:21:00 -0700 Subject: [PATCH 47/47] mmc: Support generic PCI SD host controller This changes pci_mmc driver to use PCI_CLASS_SYSTEM_SDHCI instead of individual vendor id & device id pair to support generic PCI SD host controller. Signed-off-by: Bin Meng --- drivers/mmc/pci_mmc.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c index 6db89779ba..05c0044a7a 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -64,12 +64,7 @@ U_BOOT_DRIVER(pci_mmc) = { }; static struct pci_device_id mmc_supported[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_SDIO) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_SD) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_EMMC2) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1) }, + { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_SDHCI << 8, 0xffff00) }, {}, };