From dd18df440ae1802ca51aa4995f508fe350b1f46d Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 11 Dec 2018 14:49:18 +0100 Subject: pinctrl: stm32: Add st,stm32f769-pinctrl compatible string Due to DT kernel synchronisation, add new pinctrl compatible string for stm32f769. Signed-off-by: Patrice Chotard --- drivers/pinctrl/pinctrl_stm32.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 24affe0414..43dbdd9d6a 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -421,6 +421,7 @@ static const struct udevice_id stm32_pinctrl_ids[] = { { .compatible = "st,stm32f429-pinctrl" }, { .compatible = "st,stm32f469-pinctrl" }, { .compatible = "st,stm32f746-pinctrl" }, + { .compatible = "st,stm32f769-pinctrl" }, { .compatible = "st,stm32h743-pinctrl" }, { .compatible = "st,stm32mp157-pinctrl" }, { .compatible = "st,stm32mp157-z-pinctrl" }, -- cgit v1.2.3 From 6f41d1a17e20fcc99329c2001d465945fca447a1 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 5 Dec 2018 14:04:32 +0100 Subject: mmc: arm_pl180_mmci: Sync compatible with kernel Initially the compatible string was wrongly set to "st,stm32f4xx-sdio". Use compatible string used by kernel instead and identify mmci variant using "arm,primecell-periphid" property. Currently, the DM part of mmci driver is only used by STM32 SoCs, that's why the switch case gets only one entry. It will be populated easily with new variant in the future. Signed-off-by: Patrice Chotard --- drivers/mmc/arm_pl180_mmci.c | 14 ++++++++++++-- drivers/mmc/arm_pl180_mmci.h | 3 +-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index f71d79ecd6..ea8eb0d509 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -422,6 +422,7 @@ static int arm_pl180_mmc_probe(struct udevice *dev) struct mmc_config *cfg = &pdata->cfg; struct clk clk; u32 bus_width; + u32 periphid; int ret; ret = clk_get_by_index(dev, 0, &clk); @@ -439,7 +440,15 @@ static int arm_pl180_mmc_probe(struct udevice *dev) host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN; host->clock_in = clk_get_rate(&clk); - host->version2 = dev_get_driver_data(dev); + + periphid = dev_read_u32_default(dev, "arm,primecell-periphid", 0); + switch (periphid) { + case STM32_MMCI_ID: /* stm32 variant */ + host->version2 = false; + break; + default: + host->version2 = true; + } cfg->name = dev->name; cfg->voltages = VOLTAGE_WINDOW_SD; @@ -526,7 +535,8 @@ static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev) } static const struct udevice_id arm_pl180_mmc_match[] = { - { .compatible = "st,stm32f4xx-sdio", .data = VERSION1 }, + { .compatible = "arm,pl180" }, + { .compatible = "arm,primecell" }, { /* sentinel */ } }; diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h index 36487be288..61ee96a112 100644 --- a/drivers/mmc/arm_pl180_mmci.h +++ b/drivers/mmc/arm_pl180_mmci.h @@ -141,8 +141,7 @@ #define SDI_FIFO_BURST_SIZE 8 -#define VERSION1 false -#define VERSION2 true +#define STM32_MMCI_ID 0x00880180 struct sdi_registers { u32 power; /* 0x00*/ -- cgit v1.2.3 From b61153523821da301712202dad870547cae23860 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 16 Nov 2018 10:25:54 +0100 Subject: mmc: stm32_sdmmc2: Update DT properties with v4.19 bindings Some properties name has been updated: - st,dirpol becomes st,sig-dir - st,negedge becomes st,neg-edge - st,pin-ckin becomes st,use-ckin Signed-off-by: Patrick Delaunay Signed-off-by: Patrice Chotard --- drivers/mmc/stm32_sdmmc2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index a36612dd93..bab7efe754 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -585,11 +585,11 @@ static int stm32_sdmmc2_probe(struct udevice *dev) if (priv->base == FDT_ADDR_T_NONE) return -EINVAL; - if (dev_read_bool(dev, "st,negedge")) + if (dev_read_bool(dev, "st,neg-edge")) priv->clk_reg_msk |= SDMMC_CLKCR_NEGEDGE; - if (dev_read_bool(dev, "st,dirpol")) + if (dev_read_bool(dev, "st,sig-dir")) priv->pwr_reg_msk |= SDMMC_POWER_DIRPOL; - if (dev_read_bool(dev, "st,pin-ckin")) + if (dev_read_bool(dev, "st,use-ckin")) priv->clk_reg_msk |= SDMMC_CLKCR_SELCLKRX_CKIN; ret = clk_get_by_index(dev, 0, &priv->clk); -- cgit v1.2.3 From c406a474311c1ee3c4303a7e85db4a8e45966e31 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 6 Dec 2018 15:58:10 +0100 Subject: mmc: stm32_sdmmc2: Fix r1b timeout issue On response type r1b, if DTIME is not defined or too short, the Datatimeout and DPSM flag occurs. Like the DPSM is activated all next data transfer will be frozen. To avoid this freeze: -The driver must define a DTIME on all r1b response type. -DTIME of SDMMC must be defined for alls stop transmission (for read and write request) even if MMC_RSP_BUSY is not set. -If busy timeout occur, an abort request must be sent to reinitialize the DPSM. Signed-off-by: Christophe Kerello Signed-off-by: Patrice Chotard Tested-by: Patrick DELAUNAY --- drivers/mmc/stm32_sdmmc2.c | 61 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index bab7efe754..ed31ca126e 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -190,6 +190,7 @@ struct stm32_sdmmc2_ctx { #define SDMMC_IDMACTRL_IDMAEN BIT(0) #define SDMMC_CMD_TIMEOUT 0xFFFFFFFF +#define SDMMC_BUSYD0END_TIMEOUT_US 1000000 static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, struct mmc_data *data, @@ -209,9 +210,6 @@ static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, idmabase0 = (u32)data->src; } - /* Set the SDMMC Data TimeOut value */ - writel(SDMMC_CMD_TIMEOUT, priv->base + SDMMC_DTIMER); - /* Set the SDMMC DataLength value */ writel(ctx->data_length, priv->base + SDMMC_DLEN); @@ -236,8 +234,11 @@ static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv, } static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv, - struct mmc_cmd *cmd, u32 cmd_param) + struct mmc_cmd *cmd, u32 cmd_param, + struct stm32_sdmmc2_ctx *ctx) { + u32 timeout = 0; + if (readl(priv->base + SDMMC_CMD) & SDMMC_CMD_CPSMEN) writel(0, priv->base + SDMMC_CMD); @@ -251,6 +252,26 @@ static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv, cmd_param |= SDMMC_CMD_WAITRESP_1; } + /* + * SDMMC_DTIME must be set in two case: + * - on data transfert. + * - on busy request. + * If not done or too short, the dtimeout flag occurs and DPSM stays + * enabled/busy and waits for abort (stop transmission cmd). + * Next data command is not possible whereas DPSM is activated. + */ + if (ctx->data_length) { + timeout = SDMMC_CMD_TIMEOUT; + } else { + writel(0, priv->base + SDMMC_DCTRL); + + if (cmd->resp_type & MMC_RSP_BUSY) + timeout = SDMMC_CMD_TIMEOUT; + } + + /* Set the SDMMC Data TimeOut value */ + writel(timeout, priv->base + SDMMC_DTIMER); + /* Clear flags */ writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); @@ -309,6 +330,31 @@ static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv, cmd->response[2] = readl(priv->base + SDMMC_RESP3); cmd->response[3] = readl(priv->base + SDMMC_RESP4); } + + /* Wait for BUSYD0END flag if busy status is detected */ + if (cmd->resp_type & MMC_RSP_BUSY && + status & SDMMC_STA_BUSYD0) { + mask = SDMMC_STA_DTIMEOUT | SDMMC_STA_BUSYD0END; + + /* Polling status register */ + ret = readl_poll_timeout(priv->base + SDMMC_STA, + status, status & mask, + SDMMC_BUSYD0END_TIMEOUT_US); + + if (ret < 0) { + debug("%s: timeout reading SDMMC_STA\n", + __func__); + ctx->dpsm_abort = true; + return ret; + } + + if (status & SDMMC_STA_DTIMEOUT) { + debug("%s: error SDMMC_STA_DTIMEOUT (0x%x)\n", + __func__, status); + ctx->dpsm_abort = true; + return -ETIMEDOUT; + } + } } return 0; @@ -395,7 +441,7 @@ retry_cmd: stm32_sdmmc2_start_data(priv, data, &ctx); } - stm32_sdmmc2_start_cmd(priv, cmd, cmdat); + stm32_sdmmc2_start_cmd(priv, cmd, cmdat, &ctx); debug("%s: send cmd %d data: 0x%x @ 0x%x\n", __func__, cmd->cmdidx, @@ -425,7 +471,10 @@ retry_cmd: debug("%s: send STOP command to abort dpsm treatments\n", __func__); - stm32_sdmmc2_start_cmd(priv, &stop_cmd, SDMMC_CMD_CMDSTOP); + ctx.data_length = 0; + + stm32_sdmmc2_start_cmd(priv, &stop_cmd, + SDMMC_CMD_CMDSTOP, &ctx); stm32_sdmmc2_end_cmd(priv, &stop_cmd, &ctx); writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR); -- cgit v1.2.3