* [PATCH 1/3] mci: imx-esdhc: add layerscape flag
@ 2023-11-22 10:53 Sascha Hauer
2023-11-22 10:53 ` [PATCH 2/3] mci: imx-esdhc: Layerscape: fix clock setup Sascha Hauer
2023-11-22 10:53 ` [PATCH 3/3] mci: imx-esdhc: Layerscape: add eMMC DDR52 support Sascha Hauer
0 siblings, 2 replies; 3+ messages in thread
From: Sascha Hauer @ 2023-11-22 10:53 UTC (permalink / raw)
To: Barebox List
More Layerscape specifics are about to come. Instead of adding a
specific quirk flag for each of them, rename the ESDHC_FLAG_CACHE_SNOOPING
flag to ESDHC_FLAG_LAYERSCAPE to get a common layerscape flag.
>From looking at the Kernel driver it seems we can use these flag for the
modern Layerscape SoCs, we would have to revisit this once we support
LS1012.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 4 ++--
drivers/mci/imx-esdhc.h | 9 +++++++--
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index f30a791fa4..90a6c12439 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -232,7 +232,7 @@ static int esdhc_init(struct mci_host *mci, struct device *dev)
sdhci_write32(&host->sdhci, SDHCI_MMC_BOOT, 0);
/* Enable cache snooping */
- if (host->socdata->flags & ESDHC_FLAG_CACHE_SNOOPING)
+ if (esdhc_is_layerscape(host))
esdhc_setbits32(host, ESDHC_DMA_SYSCTL, ESDHC_SYSCTL_DMA_SNOOP);
/* Set the initial clock speed */
@@ -377,7 +377,7 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
static struct esdhc_soc_data esdhc_ls_data = {
.flags = ESDHC_FLAG_MULTIBLK_NO_INT | ESDHC_FLAG_BIGENDIAN |
- ESDHC_FLAG_CACHE_SNOOPING,
+ ESDHC_FLAG_LAYERSCAPE,
};
static __maybe_unused struct of_device_id fsl_esdhc_compatible[] = {
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
index b14039757a..6810039a96 100644
--- a/drivers/mci/imx-esdhc.h
+++ b/drivers/mci/imx-esdhc.h
@@ -103,8 +103,8 @@
#define ESDHC_FLAG_HS400 BIT(9)
/* Need to access registers in bigendian mode */
#define ESDHC_FLAG_BIGENDIAN BIT(10)
-/* Enable cache snooping */
-#define ESDHC_FLAG_CACHE_SNOOPING BIT(11)
+/* Layerscape variant ls1046a, ls1028a, ls1088a, revisit for ls1012a */
+#define ESDHC_FLAG_LAYERSCAPE BIT(11)
struct esdhc_soc_data {
u32 flags;
@@ -124,6 +124,11 @@ static inline int esdhc_is_usdhc(struct fsl_esdhc_host *data)
return !!(data->socdata->flags & ESDHC_FLAG_USDHC);
}
+static inline int esdhc_is_layerscape(struct fsl_esdhc_host *data)
+{
+ return !!(data->socdata->flags & ESDHC_FLAG_LAYERSCAPE);
+}
+
static inline struct fsl_esdhc_host *sdhci_to_esdhc(struct sdhci *sdhci)
{
return container_of(sdhci, struct fsl_esdhc_host, sdhci);
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/3] mci: imx-esdhc: Layerscape: fix clock setup
2023-11-22 10:53 [PATCH 1/3] mci: imx-esdhc: add layerscape flag Sascha Hauer
@ 2023-11-22 10:53 ` Sascha Hauer
2023-11-22 10:53 ` [PATCH 3/3] mci: imx-esdhc: Layerscape: add eMMC DDR52 support Sascha Hauer
1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2023-11-22 10:53 UTC (permalink / raw)
To: Barebox List
Set the PCS bit in the ESDHCCTL register. With this Peripheral/2 clock
is used which is the clock we are actually calculating the dividers for.
As the input clock is only half of the expected clock we have to account
for this in set_sysctl().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 8 ++++++--
drivers/mci/imx-esdhc.h | 2 +-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 90a6c12439..92aea9ed9d 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -51,6 +51,9 @@ static void set_sysctl(struct mci_host *mci, u32 clock, bool ddr)
u32 clk;
unsigned long cur_clock;
+ if (esdhc_is_layerscape(host))
+ sdhc_clk >>= 1;
+
/*
* With eMMC and imx53 (sdhc_clk=200MHz) a pre_div of 1 results in
* pre_div=1,div=4 (=50MHz)
@@ -231,9 +234,10 @@ static int esdhc_init(struct mci_host *mci, struct device *dev)
/* RSTA doesn't reset MMC_BOOT register, so manually reset it */
sdhci_write32(&host->sdhci, SDHCI_MMC_BOOT, 0);
- /* Enable cache snooping */
if (esdhc_is_layerscape(host))
- esdhc_setbits32(host, ESDHC_DMA_SYSCTL, ESDHC_SYSCTL_DMA_SNOOP);
+ esdhc_setbits32(host, ESDHC_DMA_SYSCTL,
+ ESDHC_SYSCTL_DMA_SNOOP | /* Enable cache snooping */
+ ESDHC_SYSCTL_PERIPHERAL_CLK_SEL);
/* Set the initial clock speed */
set_sysctl(mci, 400000, false);
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
index 6810039a96..047c32615d 100644
--- a/drivers/mci/imx-esdhc.h
+++ b/drivers/mci/imx-esdhc.h
@@ -60,7 +60,7 @@
#define ESDHC_DMA_SYSCTL 0x40c /* Layerscape specific */
#define ESDHC_SYSCTL_DMA_SNOOP BIT(6)
-
+#define ESDHC_SYSCTL_PERIPHERAL_CLK_SEL BIT(19)
/*
* The CMDTYPE of the CMD register (offset 0xE) should be set to
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 3/3] mci: imx-esdhc: Layerscape: add eMMC DDR52 support
2023-11-22 10:53 [PATCH 1/3] mci: imx-esdhc: add layerscape flag Sascha Hauer
2023-11-22 10:53 ` [PATCH 2/3] mci: imx-esdhc: Layerscape: fix clock setup Sascha Hauer
@ 2023-11-22 10:53 ` Sascha Hauer
1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2023-11-22 10:53 UTC (permalink / raw)
To: Barebox List
The Layerscape variant of the imx-esdhc also supports eMMC DDR52,
add support for this mode.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mci/imx-esdhc.c | 41 ++++++++++++++++++++++++++++++++++++-----
drivers/mci/imx-esdhc.h | 2 ++
2 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 92aea9ed9d..e1d4e3c2d4 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -45,12 +45,15 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
static void set_sysctl(struct mci_host *mci, u32 clock, bool ddr)
{
- int div, pre_div, ddr_pre_div = ddr ? 2 : 1;
+ int div, pre_div, ddr_pre_div = 1;
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
int sdhc_clk = clk_get_rate(host->clk);
u32 clk;
unsigned long cur_clock;
+ if (esdhc_is_usdhc(host) && ddr)
+ ddr_pre_div = 2;
+
if (esdhc_is_layerscape(host))
sdhc_clk >>= 1;
@@ -106,7 +109,7 @@ static void set_sysctl(struct mci_host *mci, u32 clock, bool ddr)
10 * MSECOND);
}
-static void esdhc_set_timing(struct fsl_esdhc_host *host, enum mci_timing timing)
+static void usdhc_set_timing(struct fsl_esdhc_host *host, enum mci_timing timing)
{
u32 mixctrl;
@@ -126,6 +129,30 @@ static void esdhc_set_timing(struct fsl_esdhc_host *host, enum mci_timing timing
host->sdhci.timing = timing;
}
+static void layerscape_set_timing(struct fsl_esdhc_host *host, enum mci_timing timing)
+{
+ esdhc_clrbits32(host, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_CKEN);
+
+ switch (timing) {
+ case MMC_TIMING_UHS_DDR50:
+ case MMC_TIMING_MMC_DDR52:
+ esdhc_clrsetbits32(host, SDHCI_ACMD12_ERR__HOST_CONTROL2,
+ SDHCI_ACMD12_ERR__HOST_CONTROL2_UHSM,
+ FIELD_PREP(SDHCI_ACMD12_ERR__HOST_CONTROL2_UHSM, 4));
+ break;
+ default:
+ esdhc_clrbits32(host, SDHCI_ACMD12_ERR__HOST_CONTROL2,
+ SDHCI_ACMD12_ERR__HOST_CONTROL2_UHSM);
+ break;
+ }
+
+ esdhc_setbits32(host, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_CKEN);
+
+ host->sdhci.timing = timing;
+}
+
static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
@@ -137,8 +164,12 @@ static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
* divide by 2 automatically. So need to do this before
* setting clock rate.
*/
- if (esdhc_is_usdhc(host) && host->sdhci.timing != ios->timing)
- esdhc_set_timing(host, ios->timing);
+ if (host->sdhci.timing != ios->timing) {
+ if (esdhc_is_usdhc(host))
+ usdhc_set_timing(host, ios->timing);
+ else if (esdhc_is_layerscape(host))
+ layerscape_set_timing(host, ios->timing);
+ }
/* Set the clock speed */
set_sysctl(mci, ios->clock, mci_timing_is_ddr(ios->timing));
@@ -319,7 +350,7 @@ static int fsl_esdhc_probe(struct device *dev)
if (ret)
goto err_clk_disable;
- if (esdhc_is_usdhc(host))
+ if (esdhc_is_usdhc(host) || esdhc_is_layerscape(host))
mci->host_caps |= MMC_CAP_MMC_3_3V_DDR | MMC_CAP_MMC_1_8V_DDR;
rate = clk_get_rate(host->clk);
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
index 047c32615d..eff556f2ff 100644
--- a/drivers/mci/imx-esdhc.h
+++ b/drivers/mci/imx-esdhc.h
@@ -39,6 +39,8 @@
#define PIO_TIMEOUT 100000
+#define SDHCI_ACMD12_ERR__HOST_CONTROL2_UHSM GENMASK(18, 16) /* Layerscape specific */
+
#define IMX_SDHCI_WML 0x44
#define IMX_SDHCI_MIXCTRL 0x48
/* Imported from Linux Kernel drivers/mmc/host/sdhci-esdhc-imx.c */
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-11-22 10:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-22 10:53 [PATCH 1/3] mci: imx-esdhc: add layerscape flag Sascha Hauer
2023-11-22 10:53 ` [PATCH 2/3] mci: imx-esdhc: Layerscape: fix clock setup Sascha Hauer
2023-11-22 10:53 ` [PATCH 3/3] mci: imx-esdhc: Layerscape: add eMMC DDR52 support Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox