Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: renesas_sdhi: Refactor renesas_sdhi_probe()

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>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://lore.kernel.org/r/20210729103234.480743-1-yoshihiro.shimoda.uh@renesas.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Yoshihiro Shimoda and committed by
Ulf Hansson
71b7597c ee516535

+141 -96
+8 -1
drivers/mmc/host/renesas_sdhi.h
··· 42 42 const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX]; 43 43 }; 44 44 45 + struct renesas_sdhi_of_data_with_quirks { 46 + const struct renesas_sdhi_of_data *of_data; 47 + const struct renesas_sdhi_quirks *quirks; 48 + }; 49 + 45 50 struct tmio_mmc_dma { 46 51 enum dma_slave_buswidth dma_buswidth; 47 52 bool (*filter)(struct dma_chan *chan, void *arg); ··· 83 78 container_of((host)->pdata, struct renesas_sdhi, mmc_data) 84 79 85 80 int renesas_sdhi_probe(struct platform_device *pdev, 86 - const struct tmio_mmc_dma_ops *dma_ops); 81 + const struct tmio_mmc_dma_ops *dma_ops, 82 + const struct renesas_sdhi_of_data *of_data, 83 + const struct renesas_sdhi_quirks *quirks); 87 84 int renesas_sdhi_remove(struct platform_device *pdev); 88 85 #endif
+3 -87
drivers/mmc/host/renesas_sdhi_core.c
··· 305 305 #define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK 0x1f 306 306 #define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE BIT(7) 307 307 308 - static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = { 309 - { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15, 310 - 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 }, 311 - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11, 312 - 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 } 313 - }; 314 - 315 - static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = { 316 - { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, 317 - 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 }, 318 - { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 319 - 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 } 320 - }; 321 - 322 - static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = { 323 - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 325 - { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10, 326 - 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 } 327 - }; 328 - 329 308 static inline u32 sd_scc_read32(struct tmio_mmc_host *host, 330 309 struct renesas_sdhi *priv, int addr) 331 310 { ··· 874 895 renesas_sdhi_sdbuf_width(host, enable ? width : 16); 875 896 } 876 897 877 - static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = { 878 - .hs400_disabled = true, 879 - .hs400_4taps = true, 880 - }; 881 - 882 - static const struct renesas_sdhi_quirks sdhi_quirks_4tap = { 883 - .hs400_4taps = true, 884 - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 885 - }; 886 - 887 - static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = { 888 - .hs400_disabled = true, 889 - }; 890 - 891 - static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = { 892 - .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7), 893 - }; 894 - 895 - static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = { 896 - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 897 - }; 898 - 899 - static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = { 900 - .hs400_4taps = true, 901 - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 902 - .hs400_calib_table = r8a7796_es13_calib_table, 903 - }; 904 - 905 - static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = { 906 - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 907 - .hs400_calib_table = r8a77965_calib_table, 908 - }; 909 - 910 - static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = { 911 - .hs400_calib_table = r8a77990_calib_table, 912 - }; 913 - 914 - /* 915 - * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now. 916 - * So, we want to treat them equally and only have a match for ES1.2 to enforce 917 - * this if there ever will be a way to distinguish ES1.2. 918 - */ 919 - static const struct soc_device_attribute sdhi_quirks_match[] = { 920 - { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, 921 - { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 }, 922 - { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, 923 - { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 }, 924 - { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, 925 - { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, 926 - { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 }, 927 - { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 }, 928 - { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 }, 929 - { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 }, 930 - { /* Sentinel. */ }, 931 - }; 932 - 933 898 int renesas_sdhi_probe(struct platform_device *pdev, 934 - const struct tmio_mmc_dma_ops *dma_ops) 899 + const struct tmio_mmc_dma_ops *dma_ops, 900 + const struct renesas_sdhi_of_data *of_data, 901 + const struct renesas_sdhi_quirks *quirks) 935 902 { 936 903 struct tmio_mmc_data *mmd = pdev->dev.platform_data; 937 - const struct renesas_sdhi_quirks *quirks = NULL; 938 - const struct renesas_sdhi_of_data *of_data; 939 - const struct soc_device_attribute *attr; 940 904 struct tmio_mmc_data *mmc_data; 941 905 struct tmio_mmc_dma *dma_priv; 942 906 struct tmio_mmc_host *host; ··· 887 965 int num_irqs, irq, ret, i; 888 966 struct resource *res; 889 967 u16 ver; 890 - 891 - of_data = of_device_get_match_data(&pdev->dev); 892 - 893 - attr = soc_device_match(sdhi_quirks_match); 894 - if (attr) 895 - quirks = attr->data; 896 968 897 969 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 898 970 if (!res)
+128 -7
drivers/mmc/host/renesas_sdhi_internal_dmac.c
··· 15 15 #include <linux/mmc/host.h> 16 16 #include <linux/mod_devicetable.h> 17 17 #include <linux/module.h> 18 + #include <linux/of_device.h> 18 19 #include <linux/pagemap.h> 19 20 #include <linux/scatterlist.h> 20 21 #include <linux/sys_soc.h> ··· 93 92 }, 94 93 }; 95 94 96 - static const struct renesas_sdhi_of_data of_rza2_compatible = { 95 + static const struct renesas_sdhi_of_data of_data_rza2 = { 97 96 .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | 98 97 TMIO_MMC_HAVE_CBSY, 99 98 .tmio_ocr_mask = MMC_VDD_32_33, ··· 108 107 .max_segs = 1, 109 108 }; 110 109 111 - static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { 110 + static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = { 111 + .of_data = &of_data_rza2, 112 + }; 113 + 114 + static const struct renesas_sdhi_of_data of_data_rcar_gen3 = { 112 115 .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | 113 116 TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, 114 117 .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | ··· 127 122 .max_segs = 1, 128 123 }; 129 124 125 + static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = { 126 + { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15, 127 + 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 }, 128 + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11, 129 + 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 } 130 + }; 131 + 132 + static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = { 133 + { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, 134 + 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 }, 135 + { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 136 + 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 } 137 + }; 138 + 139 + static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = { 140 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 142 + { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10, 143 + 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 } 144 + }; 145 + 146 + static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = { 147 + .hs400_disabled = true, 148 + .hs400_4taps = true, 149 + }; 150 + 151 + static const struct renesas_sdhi_quirks sdhi_quirks_4tap = { 152 + .hs400_4taps = true, 153 + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 154 + }; 155 + 156 + static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = { 157 + .hs400_disabled = true, 158 + }; 159 + 160 + static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = { 161 + .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7), 162 + }; 163 + 164 + static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = { 165 + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 166 + }; 167 + 168 + static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = { 169 + .hs400_4taps = true, 170 + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 171 + .hs400_calib_table = r8a7796_es13_calib_table, 172 + }; 173 + 174 + static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = { 175 + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), 176 + .hs400_calib_table = r8a77965_calib_table, 177 + }; 178 + 179 + static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = { 180 + .hs400_calib_table = r8a77990_calib_table, 181 + }; 182 + 183 + /* 184 + * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now. 185 + * So, we want to treat them equally and only have a match for ES1.2 to enforce 186 + * this if there ever will be a way to distinguish ES1.2. 187 + */ 188 + static const struct soc_device_attribute sdhi_quirks_match[] = { 189 + { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, 190 + { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 }, 191 + { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, 192 + { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, 193 + { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, 194 + { /* Sentinel. */ }, 195 + }; 196 + 197 + static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = { 198 + .of_data = &of_data_rcar_gen3, 199 + .quirks = &sdhi_quirks_bad_taps2367, 200 + }; 201 + 202 + static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = { 203 + .of_data = &of_data_rcar_gen3, 204 + .quirks = &sdhi_quirks_bad_taps1357, 205 + }; 206 + 207 + static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = { 208 + .of_data = &of_data_rcar_gen3, 209 + .quirks = &sdhi_quirks_r8a77965, 210 + }; 211 + 212 + static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = { 213 + .of_data = &of_data_rcar_gen3, 214 + .quirks = &sdhi_quirks_nohs400, 215 + }; 216 + 217 + static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = { 218 + .of_data = &of_data_rcar_gen3, 219 + .quirks = &sdhi_quirks_r8a77990, 220 + }; 221 + 222 + static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = { 223 + .of_data = &of_data_rcar_gen3, 224 + }; 225 + 130 226 static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = { 131 227 { .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, }, 132 228 { .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, }, 133 - { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, }, 229 + { .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, }, 134 230 { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, }, 231 + { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, }, 232 + { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, }, 233 + { .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, }, 234 + { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, }, 135 235 { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, }, 136 236 {}, 137 237 }; ··· 515 405 516 406 static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev) 517 407 { 518 - const struct soc_device_attribute *soc = soc_device_match(soc_dma_quirks); 408 + const struct soc_device_attribute *attr; 409 + const struct renesas_sdhi_of_data_with_quirks *of_data_quirks; 410 + const struct renesas_sdhi_quirks *quirks; 519 411 struct device *dev = &pdev->dev; 520 412 521 - if (soc) 522 - global_flags |= (unsigned long)soc->data; 413 + of_data_quirks = of_device_get_match_data(&pdev->dev); 414 + quirks = of_data_quirks->quirks; 415 + 416 + attr = soc_device_match(soc_dma_quirks); 417 + if (attr) 418 + global_flags |= (unsigned long)attr->data; 419 + 420 + attr = soc_device_match(sdhi_quirks_match); 421 + if (attr) 422 + quirks = attr->data; 523 423 524 424 /* value is max of SD_SECCNT. Confirmed by HW engineers */ 525 425 dma_set_max_seg_size(dev, 0xffffffff); 526 426 527 - return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops); 427 + return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops, 428 + of_data_quirks->of_data, quirks); 528 429 } 529 430 530 431 static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = {
+2 -1
drivers/mmc/host/renesas_sdhi_sys_dmac.c
··· 451 451 452 452 static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev) 453 453 { 454 - return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops); 454 + return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops, 455 + of_device_get_match_data(&pdev->dev), NULL); 455 456 } 456 457 457 458 static const struct dev_pm_ops renesas_sdhi_sys_dmac_dev_pm_ops = {