* [PATCH v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe()
@ 2021-07-29 10:32 Yoshihiro Shimoda
2021-08-11 8:28 ` Wolfram Sang
2021-08-16 13:59 ` Ulf Hansson
0 siblings, 2 replies; 3+ messages in thread
From: Yoshihiro Shimoda @ 2021-07-29 10:32 UTC (permalink / raw)
To: ulf.hansson, wsa+renesas
Cc: linux-mmc, linux-renesas-soc, Yoshihiro Shimoda, Geert Uytterhoeven
Refactor renesas_sdhi_probe() to avoid increasing numbers of
sdhi_quirks_match[] entry when we add other stable SoCs like
r8a779m*.
Note that the sdhi_quirks_match[] is only needed on
renesas_sdhi_internal_dmac.c so that of_data of
renesas_sdhi_sys_dmac.c keeps as-is.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Changes from v3:
- Add Reviewed-by tag (Geert-san, thanks!)
- Remove Reported-by tag.
- Modify renesas_sdhi_internal_dmac_probe() for readability.
https://lore.kernel.org/linux-mmc/20210702112956.1065875-1-yoshihiro.shimoda.uh@renesas.com/
Changes from RFC v2:
- Remove "RFC" mark from the subject.
- Add a comment to the Reported-by tag.
- Move all quirks to internal_dmac.c so that expands the renesas_sdhi_probe()
arguments. So, update the commit subject and description.
- Don't modify the renesas_sdhi_sys_dmac.c's of_data.
- Replace tabs with a space in of_data_with_quirks variables.
https://lore.kernel.org/linux-renesas-soc/20210629102033.847369-1-yoshihiro.shimoda.uh@renesas.com/
Changes from RFC v1:
- Fix build error in sys_dmac.c, reported by kernel test robot, so that
add Reported-by tag.
- Always set quirks, not using else statement.
- Fix a NULL dereference if of_device_get_match_data() returns NULL.
https://lore.kernel.org/linux-renesas-soc/20210625075508.664674-1-yoshihiro.shimoda.uh@renesas.com/
drivers/mmc/host/renesas_sdhi.h | 9 +-
drivers/mmc/host/renesas_sdhi_core.c | 90 +-----------
drivers/mmc/host/renesas_sdhi_internal_dmac.c | 135 +++++++++++++++++-
drivers/mmc/host/renesas_sdhi_sys_dmac.c | 3 +-
4 files changed, 141 insertions(+), 96 deletions(-)
diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 53eded81a53e..0c45e82ff0de 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -42,6 +42,11 @@ struct renesas_sdhi_quirks {
const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
};
+struct renesas_sdhi_of_data_with_quirks {
+ const struct renesas_sdhi_of_data *of_data;
+ const struct renesas_sdhi_quirks *quirks;
+};
+
struct tmio_mmc_dma {
enum dma_slave_buswidth dma_buswidth;
bool (*filter)(struct dma_chan *chan, void *arg);
@@ -78,6 +83,8 @@ struct renesas_sdhi {
container_of((host)->pdata, struct renesas_sdhi, mmc_data)
int renesas_sdhi_probe(struct platform_device *pdev,
- const struct tmio_mmc_dma_ops *dma_ops);
+ const struct tmio_mmc_dma_ops *dma_ops,
+ const struct renesas_sdhi_of_data *of_data,
+ const struct renesas_sdhi_quirks *quirks);
int renesas_sdhi_remove(struct platform_device *pdev);
#endif
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index e49ca0f7fe9a..6fc4cf3c9dce 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -305,27 +305,6 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
#define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK 0x1f
#define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE BIT(7)
-static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
- { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15,
- 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11,
- 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
-};
-
-static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
- { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
- { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
-};
-
-static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10,
- 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
-};
-
static inline u32 sd_scc_read32(struct tmio_mmc_host *host,
struct renesas_sdhi *priv, int addr)
{
@@ -895,69 +874,12 @@ static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)
renesas_sdhi_sdbuf_width(host, enable ? width : 16);
}
-static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
- .hs400_disabled = true,
- .hs400_4taps = true,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
- .hs400_4taps = true,
- .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
- .hs400_disabled = true,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
- .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
- .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
- .hs400_4taps = true,
- .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
- .hs400_calib_table = r8a7796_es13_calib_table,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
- .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
- .hs400_calib_table = r8a77965_calib_table,
-};
-
-static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
- .hs400_calib_table = r8a77990_calib_table,
-};
-
-/*
- * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
- * So, we want to treat them equally and only have a match for ES1.2 to enforce
- * this if there ever will be a way to distinguish ES1.2.
- */
-static const struct soc_device_attribute sdhi_quirks_match[] = {
- { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
- { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
- { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
- { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },
- { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
- { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
- { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 },
- { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 },
- { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },
- { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 },
- { /* Sentinel. */ },
-};
-
int renesas_sdhi_probe(struct platform_device *pdev,
- const struct tmio_mmc_dma_ops *dma_ops)
+ const struct tmio_mmc_dma_ops *dma_ops,
+ const struct renesas_sdhi_of_data *of_data,
+ const struct renesas_sdhi_quirks *quirks)
{
struct tmio_mmc_data *mmd = pdev->dev.platform_data;
- const struct renesas_sdhi_quirks *quirks = NULL;
- const struct renesas_sdhi_of_data *of_data;
- const struct soc_device_attribute *attr;
struct tmio_mmc_data *mmc_data;
struct tmio_mmc_dma *dma_priv;
struct tmio_mmc_host *host;
@@ -966,12 +888,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
struct resource *res;
u16 ver;
- of_data = of_device_get_match_data(&pdev->dev);
-
- attr = soc_device_match(sdhi_quirks_match);
- if (attr)
- quirks = attr->data;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index e8f4863d8f1a..7660f7ea74dd 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -15,6 +15,7 @@
#include <linux/mmc/host.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
#include <linux/sys_soc.h>
@@ -92,7 +93,7 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
},
};
-static const struct renesas_sdhi_of_data of_rza2_compatible = {
+static const struct renesas_sdhi_of_data of_data_rza2 = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
TMIO_MMC_HAVE_CBSY,
.tmio_ocr_mask = MMC_VDD_32_33,
@@ -107,7 +108,11 @@ static const struct renesas_sdhi_of_data of_rza2_compatible = {
.max_segs = 1,
};
-static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
+static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = {
+ .of_data = &of_data_rza2,
+};
+
+static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
.capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
@@ -122,11 +127,116 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
.max_segs = 1,
};
+static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+ { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15,
+ 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11,
+ 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
+};
+
+static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+ { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
+ { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
+};
+
+static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10,
+ 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
+ .hs400_disabled = true,
+ .hs400_4taps = true,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
+ .hs400_4taps = true,
+ .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
+ .hs400_disabled = true,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
+ .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
+ .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
+ .hs400_4taps = true,
+ .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+ .hs400_calib_table = r8a7796_es13_calib_table,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
+ .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
+ .hs400_calib_table = r8a77965_calib_table,
+};
+
+static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
+ .hs400_calib_table = r8a77990_calib_table,
+};
+
+/*
+ * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
+ * So, we want to treat them equally and only have a match for ES1.2 to enforce
+ * this if there ever will be a way to distinguish ES1.2.
+ */
+static const struct soc_device_attribute sdhi_quirks_match[] = {
+ { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
+ { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
+ { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
+ { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
+ { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
+ { /* Sentinel. */ },
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = {
+ .of_data = &of_data_rcar_gen3,
+ .quirks = &sdhi_quirks_bad_taps2367,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = {
+ .of_data = &of_data_rcar_gen3,
+ .quirks = &sdhi_quirks_bad_taps1357,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {
+ .of_data = &of_data_rcar_gen3,
+ .quirks = &sdhi_quirks_r8a77965,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {
+ .of_data = &of_data_rcar_gen3,
+ .quirks = &sdhi_quirks_nohs400,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = {
+ .of_data = &of_data_rcar_gen3,
+ .quirks = &sdhi_quirks_r8a77990,
+};
+
+static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = {
+ .of_data = &of_data_rcar_gen3,
+};
+
static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
{ .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, },
{ .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, },
- { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, },
{ .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },
+ { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },
+ { .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },
+ { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },
{ .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
{},
};
@@ -405,16 +515,27 @@ static const struct soc_device_attribute soc_dma_quirks[] = {
static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
{
- const struct soc_device_attribute *soc = soc_device_match(soc_dma_quirks);
+ const struct soc_device_attribute *attr;
+ const struct renesas_sdhi_of_data_with_quirks *of_data_quirks;
+ const struct renesas_sdhi_quirks *quirks;
struct device *dev = &pdev->dev;
- if (soc)
- global_flags |= (unsigned long)soc->data;
+ of_data_quirks = of_device_get_match_data(&pdev->dev);
+ quirks = of_data_quirks->quirks;
+
+ attr = soc_device_match(soc_dma_quirks);
+ if (attr)
+ global_flags |= (unsigned long)attr->data;
+
+ attr = soc_device_match(sdhi_quirks_match);
+ if (attr)
+ quirks = attr->data;
/* value is max of SD_SECCNT. Confirmed by HW engineers */
dma_set_max_seg_size(dev, 0xffffffff);
- return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);
+ return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops,
+ of_data_quirks->of_data, quirks);
}
static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = {
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
index 6956b83469c8..99e3426df702 100644
--- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
@@ -451,7 +451,8 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_sys_dmac_dma_ops = {
static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev)
{
- return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops);
+ return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops,
+ of_device_get_match_data(&pdev->dev), NULL);
}
static const struct dev_pm_ops renesas_sdhi_sys_dmac_dev_pm_ops = {
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe()
2021-07-29 10:32 [PATCH v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe() Yoshihiro Shimoda
@ 2021-08-11 8:28 ` Wolfram Sang
2021-08-16 13:59 ` Ulf Hansson
1 sibling, 0 replies; 3+ messages in thread
From: Wolfram Sang @ 2021-08-11 8:28 UTC (permalink / raw)
To: Yoshihiro Shimoda
Cc: ulf.hansson, linux-mmc, linux-renesas-soc, Geert Uytterhoeven
[-- Attachment #1: Type: text/plain, Size: 1093 bytes --]
On Thu, Jul 29, 2021 at 07:32:34PM +0900, Yoshihiro Shimoda wrote:
> Refactor renesas_sdhi_probe() to avoid increasing numbers of
> sdhi_quirks_match[] entry when we add other stable SoCs like
> r8a779m*.
>
> Note that the sdhi_quirks_match[] is only needed on
> renesas_sdhi_internal_dmac.c so that of_data of
> renesas_sdhi_sys_dmac.c keeps as-is.
>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
I like this change! Not only does it avoid the white listing, but it
also puts things where they belong! Looks much more sorted to me.
I think we can base even further cleanup on this. Like merging
soc_dma_quirks into the other quirks. But we can do this incrementally.
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
I also tested this on H3 ES1.0, M3-W ES1.0, M3-N, and E3 with some debug
output. It all made sense and SDHI still works:
I also tested H3 ES2.0 without debug output. SDHI still worked.
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe()
2021-07-29 10:32 [PATCH v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe() Yoshihiro Shimoda
2021-08-11 8:28 ` Wolfram Sang
@ 2021-08-16 13:59 ` Ulf Hansson
1 sibling, 0 replies; 3+ messages in thread
From: Ulf Hansson @ 2021-08-16 13:59 UTC (permalink / raw)
To: Yoshihiro Shimoda
Cc: Wolfram Sang, linux-mmc, Linux-Renesas, Geert Uytterhoeven
On Thu, 29 Jul 2021 at 12:32, Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com> wrote:
>
> Refactor renesas_sdhi_probe() to avoid increasing numbers of
> sdhi_quirks_match[] entry when we add other stable SoCs like
> r8a779m*.
>
> Note that the sdhi_quirks_match[] is only needed on
> renesas_sdhi_internal_dmac.c so that of_data of
> renesas_sdhi_sys_dmac.c keeps as-is.
>
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Applied for next, thanks!
Kind regards
Uffe
> ---
> Changes from v3:
> - Add Reviewed-by tag (Geert-san, thanks!)
> - Remove Reported-by tag.
> - Modify renesas_sdhi_internal_dmac_probe() for readability.
> https://lore.kernel.org/linux-mmc/20210702112956.1065875-1-yoshihiro.shimoda.uh@renesas.com/
>
> Changes from RFC v2:
> - Remove "RFC" mark from the subject.
> - Add a comment to the Reported-by tag.
> - Move all quirks to internal_dmac.c so that expands the renesas_sdhi_probe()
> arguments. So, update the commit subject and description.
> - Don't modify the renesas_sdhi_sys_dmac.c's of_data.
> - Replace tabs with a space in of_data_with_quirks variables.
> https://lore.kernel.org/linux-renesas-soc/20210629102033.847369-1-yoshihiro.shimoda.uh@renesas.com/
>
> Changes from RFC v1:
> - Fix build error in sys_dmac.c, reported by kernel test robot, so that
> add Reported-by tag.
> - Always set quirks, not using else statement.
> - Fix a NULL dereference if of_device_get_match_data() returns NULL.
> https://lore.kernel.org/linux-renesas-soc/20210625075508.664674-1-yoshihiro.shimoda.uh@renesas.com/
>
> drivers/mmc/host/renesas_sdhi.h | 9 +-
> drivers/mmc/host/renesas_sdhi_core.c | 90 +-----------
> drivers/mmc/host/renesas_sdhi_internal_dmac.c | 135 +++++++++++++++++-
> drivers/mmc/host/renesas_sdhi_sys_dmac.c | 3 +-
> 4 files changed, 141 insertions(+), 96 deletions(-)
>
> diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
> index 53eded81a53e..0c45e82ff0de 100644
> --- a/drivers/mmc/host/renesas_sdhi.h
> +++ b/drivers/mmc/host/renesas_sdhi.h
> @@ -42,6 +42,11 @@ struct renesas_sdhi_quirks {
> const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
> };
>
> +struct renesas_sdhi_of_data_with_quirks {
> + const struct renesas_sdhi_of_data *of_data;
> + const struct renesas_sdhi_quirks *quirks;
> +};
> +
> struct tmio_mmc_dma {
> enum dma_slave_buswidth dma_buswidth;
> bool (*filter)(struct dma_chan *chan, void *arg);
> @@ -78,6 +83,8 @@ struct renesas_sdhi {
> container_of((host)->pdata, struct renesas_sdhi, mmc_data)
>
> int renesas_sdhi_probe(struct platform_device *pdev,
> - const struct tmio_mmc_dma_ops *dma_ops);
> + const struct tmio_mmc_dma_ops *dma_ops,
> + const struct renesas_sdhi_of_data *of_data,
> + const struct renesas_sdhi_quirks *quirks);
> int renesas_sdhi_remove(struct platform_device *pdev);
> #endif
> diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
> index e49ca0f7fe9a..6fc4cf3c9dce 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -305,27 +305,6 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
> #define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK 0x1f
> #define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE BIT(7)
>
> -static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
> - { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15,
> - 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
> - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11,
> - 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
> -};
> -
> -static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
> - { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
> - 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
> - { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17,
> - 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
> -};
> -
> -static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
> - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
> - { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10,
> - 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
> -};
> -
> static inline u32 sd_scc_read32(struct tmio_mmc_host *host,
> struct renesas_sdhi *priv, int addr)
> {
> @@ -895,69 +874,12 @@ static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)
> renesas_sdhi_sdbuf_width(host, enable ? width : 16);
> }
>
> -static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
> - .hs400_disabled = true,
> - .hs400_4taps = true,
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
> - .hs400_4taps = true,
> - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
> - .hs400_disabled = true,
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
> - .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
> - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
> - .hs400_4taps = true,
> - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> - .hs400_calib_table = r8a7796_es13_calib_table,
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
> - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> - .hs400_calib_table = r8a77965_calib_table,
> -};
> -
> -static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
> - .hs400_calib_table = r8a77990_calib_table,
> -};
> -
> -/*
> - * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
> - * So, we want to treat them equally and only have a match for ES1.2 to enforce
> - * this if there ever will be a way to distinguish ES1.2.
> - */
> -static const struct soc_device_attribute sdhi_quirks_match[] = {
> - { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
> - { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
> - { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
> - { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },
> - { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
> - { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
> - { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 },
> - { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 },
> - { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 },
> - { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 },
> - { /* Sentinel. */ },
> -};
> -
> int renesas_sdhi_probe(struct platform_device *pdev,
> - const struct tmio_mmc_dma_ops *dma_ops)
> + const struct tmio_mmc_dma_ops *dma_ops,
> + const struct renesas_sdhi_of_data *of_data,
> + const struct renesas_sdhi_quirks *quirks)
> {
> struct tmio_mmc_data *mmd = pdev->dev.platform_data;
> - const struct renesas_sdhi_quirks *quirks = NULL;
> - const struct renesas_sdhi_of_data *of_data;
> - const struct soc_device_attribute *attr;
> struct tmio_mmc_data *mmc_data;
> struct tmio_mmc_dma *dma_priv;
> struct tmio_mmc_host *host;
> @@ -966,12 +888,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
> struct resource *res;
> u16 ver;
>
> - of_data = of_device_get_match_data(&pdev->dev);
> -
> - attr = soc_device_match(sdhi_quirks_match);
> - if (attr)
> - quirks = attr->data;
> -
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!res)
> return -EINVAL;
> diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> index e8f4863d8f1a..7660f7ea74dd 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -15,6 +15,7 @@
> #include <linux/mmc/host.h>
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> +#include <linux/of_device.h>
> #include <linux/pagemap.h>
> #include <linux/scatterlist.h>
> #include <linux/sys_soc.h>
> @@ -92,7 +93,7 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
> },
> };
>
> -static const struct renesas_sdhi_of_data of_rza2_compatible = {
> +static const struct renesas_sdhi_of_data of_data_rza2 = {
> .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
> TMIO_MMC_HAVE_CBSY,
> .tmio_ocr_mask = MMC_VDD_32_33,
> @@ -107,7 +108,11 @@ static const struct renesas_sdhi_of_data of_rza2_compatible = {
> .max_segs = 1,
> };
>
> -static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
> +static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = {
> + .of_data = &of_data_rza2,
> +};
> +
> +static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
> .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
> TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
> .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
> @@ -122,11 +127,116 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = {
> .max_segs = 1,
> };
>
> +static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
> + { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15,
> + 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
> + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11,
> + 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
> +};
> +
> +static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
> + { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
> + 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
> + { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17,
> + 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
> +};
> +
> +static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
> + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
> + { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10,
> + 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
> + .hs400_disabled = true,
> + .hs400_4taps = true,
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
> + .hs400_4taps = true,
> + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
> + .hs400_disabled = true,
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
> + .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
> + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
> + .hs400_4taps = true,
> + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> + .hs400_calib_table = r8a7796_es13_calib_table,
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
> + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
> + .hs400_calib_table = r8a77965_calib_table,
> +};
> +
> +static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
> + .hs400_calib_table = r8a77990_calib_table,
> +};
> +
> +/*
> + * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
> + * So, we want to treat them equally and only have a match for ES1.2 to enforce
> + * this if there ever will be a way to distinguish ES1.2.
> + */
> +static const struct soc_device_attribute sdhi_quirks_match[] = {
> + { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
> + { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
> + { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
> + { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
> + { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
> + { /* Sentinel. */ },
> +};
> +
> +static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = {
> + .of_data = &of_data_rcar_gen3,
> + .quirks = &sdhi_quirks_bad_taps2367,
> +};
> +
> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = {
> + .of_data = &of_data_rcar_gen3,
> + .quirks = &sdhi_quirks_bad_taps1357,
> +};
> +
> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {
> + .of_data = &of_data_rcar_gen3,
> + .quirks = &sdhi_quirks_r8a77965,
> +};
> +
> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {
> + .of_data = &of_data_rcar_gen3,
> + .quirks = &sdhi_quirks_nohs400,
> +};
> +
> +static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = {
> + .of_data = &of_data_rcar_gen3,
> + .quirks = &sdhi_quirks_r8a77990,
> +};
> +
> +static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = {
> + .of_data = &of_data_rcar_gen3,
> +};
> +
> static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
> { .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, },
> { .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, },
> - { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
> + { .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, },
> { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
> + { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },
> + { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },
> + { .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },
> + { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },
> { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
> {},
> };
> @@ -405,16 +515,27 @@ static const struct soc_device_attribute soc_dma_quirks[] = {
>
> static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
> {
> - const struct soc_device_attribute *soc = soc_device_match(soc_dma_quirks);
> + const struct soc_device_attribute *attr;
> + const struct renesas_sdhi_of_data_with_quirks *of_data_quirks;
> + const struct renesas_sdhi_quirks *quirks;
> struct device *dev = &pdev->dev;
>
> - if (soc)
> - global_flags |= (unsigned long)soc->data;
> + of_data_quirks = of_device_get_match_data(&pdev->dev);
> + quirks = of_data_quirks->quirks;
> +
> + attr = soc_device_match(soc_dma_quirks);
> + if (attr)
> + global_flags |= (unsigned long)attr->data;
> +
> + attr = soc_device_match(sdhi_quirks_match);
> + if (attr)
> + quirks = attr->data;
>
> /* value is max of SD_SECCNT. Confirmed by HW engineers */
> dma_set_max_seg_size(dev, 0xffffffff);
>
> - return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);
> + return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops,
> + of_data_quirks->of_data, quirks);
> }
>
> static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = {
> diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> index 6956b83469c8..99e3426df702 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -451,7 +451,8 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_sys_dmac_dma_ops = {
>
> static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev)
> {
> - return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops);
> + return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops,
> + of_device_get_match_data(&pdev->dev), NULL);
> }
>
> static const struct dev_pm_ops renesas_sdhi_sys_dmac_dev_pm_ops = {
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-08-16 14:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-29 10:32 [PATCH v4] mmc: host: renesas_sdhi: Refactor renesas_sdhi_probe() Yoshihiro Shimoda
2021-08-11 8:28 ` Wolfram Sang
2021-08-16 13:59 ` Ulf Hansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).