ramips: use upstream MMC driver
authorDENG Qingfang <dengqf6@mail2.sysu.edu.cn>
Sat, 16 Nov 2019 14:14:37 +0000 (22:14 +0800)
committerPetr Štetiar <ynezz@true.cz>
Fri, 6 Dec 2019 22:24:24 +0000 (23:24 +0100)
Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
target/linux/mediatek/modules.mk
target/linux/ramips/dts/mt7621.dtsi
target/linux/ramips/patches-4.19/0060-mmc-mtk-sd-add-support-for-mt7620.patch [new file with mode: 0644]
target/linux/ramips/patches-4.19/0061-mmc-mtk-sd-dont-hardcode-interrupt-trig.patch [new file with mode: 0644]
target/linux/ramips/patches-4.19/0062-mmc-mtk-sd-enable-internal-card-detect-logic.patch [new file with mode: 0644]

index 7f8c038caeb8d3a0918805d3853efdeab523ed17..acdfd15c990489e5a5d8a10dab88f2f6ba8fe629 100644 (file)
@@ -18,7 +18,7 @@ $(eval $(call KernelPackage,ata-ahci-mtk))
 define KernelPackage/sdhci-mtk
   SUBMENU:=Other modules
   TITLE:=Mediatek SDHCI driver
-  DEPENDS:=@TARGET_mediatek_mt7622 +kmod-sdhci
+  DEPENDS:=@(TARGET_mediatek_mt7622||TARGET_ramips_mt7620||TARGET_ramips_mt7621) +kmod-sdhci
   KCONFIG:=CONFIG_MMC_MTK 
   FILES:= \
        $(LINUX_DIR)/drivers/mmc/host/mtk-sd.ko
index 51635827f6fe17c2c90cc6e1a37684f63076095e..6ab576473bc28a712a92cb1bd30f3ecebc9297a6 100644 (file)
                clock-frequency = <50000000>;
        };
 
+       mmc_clock: mmc_clock@0 {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <48000000>;
+       };
+
+       mmc_fixed_3v3: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "mmc_power";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
+       mmc_fixed_1v8_io: fixedregulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "mmc_io";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
        palmbus: palmbus@1E000000 {
                compatible = "palmbus";
                reg = <0x1E000000 0x100000>;
        sdhci: sdhci@1E130000 {
                status = "disabled";
 
-               compatible = "ralink,mt7620-sdhci";
+               compatible = "mediatek,mt7620-mmc";
                reg = <0x1E130000 0x4000>;
 
-               interrupt-parent = <&gic>;
-               interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
+               bus-width = <4>;
+               max-frequency = <48000000>;
+               cap-sd-highspeed;
+               cap-mmc-highspeed;
+               vmmc-supply = <&mmc_fixed_3v3>;
+               vqmmc-supply = <&mmc_fixed_1v8_io>;
+               disable-wp;
 
-               pinctrl-names = "default";
+               pinctrl-names = "default", "state_uhs";
                pinctrl-0 = <&sdhci_pins>;
+               pinctrl-1 = <&sdhci_pins>;
+
+               clocks = <&mmc_clock &mmc_clock>;
+               clock-names = "source", "hclk";
+
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        xhci: xhci@1E1C0000 {
diff --git a/target/linux/ramips/patches-4.19/0060-mmc-mtk-sd-add-support-for-mt7620.patch b/target/linux/ramips/patches-4.19/0060-mmc-mtk-sd-add-support-for-mt7620.patch
new file mode 100644 (file)
index 0000000..2a3bc6b
--- /dev/null
@@ -0,0 +1,44 @@
+From afb7c7910bf3c42b56f99c9d6bb82099d0a0794d Mon Sep 17 00:00:00 2001
+From: NeilBrown <neil@brown.name>
+Date: Sat, 4 May 2019 20:24:56 +1000
+Subject: mmc: mtk-sd: add support for config found in mt7620 family SOCs.
+
+mt7620 family MIPS SOCs contain the mtk-sd silicon.
+Add support for this.
+
+Signed-off-by: NeilBrown <neil@brown.name>
+Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+(limited to 'drivers/mmc/host/mtk-sd.c')
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -465,12 +465,24 @@ static const struct mtk_mmc_compatible m
+       .support_64g = false,
+ };
++static const struct mtk_mmc_compatible mt7620_compat = {
++      .clk_div_bits = 8,
++      .hs400_tune = false,
++      .pad_tune_reg = MSDC_PAD_TUNE,
++      .async_fifo = false,
++      .data_tune = false,
++      .busy_check = false,
++      .stop_clk_fix = false,
++      .enhance_rx = false,
++};
++
+ static const struct of_device_id msdc_of_ids[] = {
+       { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
+       { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
+       { .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
+       { .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
+       { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
++      { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
+       {}
+ };
+ MODULE_DEVICE_TABLE(of, msdc_of_ids);
diff --git a/target/linux/ramips/patches-4.19/0061-mmc-mtk-sd-dont-hardcode-interrupt-trig.patch b/target/linux/ramips/patches-4.19/0061-mmc-mtk-sd-dont-hardcode-interrupt-trig.patch
new file mode 100644 (file)
index 0000000..46f347f
--- /dev/null
@@ -0,0 +1,37 @@
+From 42edb0d5ac3ee1ac247e3f56be4263f14ed99f11 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neil@brown.name>
+Date: Sat, 4 May 2019 20:24:56 +1000
+Subject: mmc: mtk-sd: don't hard-code interrupt trigger type
+
+When using devicetree for configuration, interrupt trigger type
+should be described in the dts file, not hard-coded in the C code.
+
+The mtk-sd silicon in the mt7621 soc uses an active-high interrupt
+and so cannot be used with the current code.
+
+So replace IRQF_TRIGGER_LOW with IRQF_TRIGGER_NONE.
+
+Also IRQF_ONESHOT is not needed - it is used for threaded interrupt
+handlers, and this driver does not used a threaded interrupt handler.
+So remove that setting.
+
+Signed-off-by: NeilBrown <neil@brown.name>
+Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+(limited to 'drivers/mmc/host/mtk-sd.c')
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1990,7 +1990,7 @@ static int msdc_drv_probe(struct platfor
+       msdc_init_hw(host);
+       ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq,
+-              IRQF_TRIGGER_LOW | IRQF_ONESHOT, pdev->name, host);
++                             IRQF_TRIGGER_NONE, pdev->name, host);
+       if (ret)
+               goto release;
diff --git a/target/linux/ramips/patches-4.19/0062-mmc-mtk-sd-enable-internal-card-detect-logic.patch b/target/linux/ramips/patches-4.19/0062-mmc-mtk-sd-enable-internal-card-detect-logic.patch
new file mode 100644 (file)
index 0000000..1831656
--- /dev/null
@@ -0,0 +1,164 @@
+From d087bde516053bd8dab4f79665586200b6a98c77 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neil@brown.name>
+Date: Sat, 4 May 2019 20:24:57 +1000
+Subject: mmc: mtk-sd: enable internal card-detect logic.
+
+The mtk-sd silicon has integrated card-detect logic that is
+enabled on the MT7621.  The circuit is phased out on newer hardware so
+we should be careful to only enabled it on hardware known to support
+it.  This a new "use_internal_cd" flag in struct mtk_mmc_compatible.
+
+If the sdhci isn't marked non-removable and doesn't have a
+cd-gpio configured, and if use_internal_cd is set, then assume the
+internal cd logic should be used as recommended by
+ Documentation/devicetree/bindings/mmc/mmc.txt
+
+Signed-off-by: NeilBrown <neil@brown.name>
+Reviewed-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 64 ++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 60 insertions(+), 4 deletions(-)
+
+(limited to 'drivers/mmc/host/mtk-sd.c')
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -276,6 +276,8 @@
+ #define CMD_TIMEOUT         (HZ/10 * 5)       /* 100ms x5 */
+ #define DAT_TIMEOUT         (HZ    * 5)       /* 1000ms x5 */
++#define DEFAULT_DEBOUNCE      (8)     /* 8 cycles CD debounce */
++
+ #define PAD_DELAY_MAX 32 /* PAD delay cells */
+ /*--------------------------------------------------------------------------*/
+ /* Descriptor Structure                                                     */
+@@ -345,6 +347,7 @@ struct mtk_mmc_compatible {
+       bool stop_clk_fix;
+       bool enhance_rx;
+       bool support_64g;
++      bool use_internal_cd;
+ };
+ struct msdc_tune_para {
+@@ -400,6 +403,7 @@ struct msdc_host {
+       bool hs400_cmd_resp_sel_rising;
+                                /* cmd response sample selection for HS400 */
+       bool hs400_mode;        /* current eMMC will run at hs400 mode */
++      bool internal_cd;       /* Use internal card-detect logic */
+       struct msdc_save_para save_para; /* used when gate HCLK */
+       struct msdc_tune_para def_tune_para; /* default tune setting */
+       struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
+@@ -474,6 +478,7 @@ static const struct mtk_mmc_compatible m
+       .busy_check = false,
+       .stop_clk_fix = false,
+       .enhance_rx = false,
++      .use_internal_cd = true,
+ };
+ static const struct of_device_id msdc_of_ids[] = {
+@@ -1322,6 +1327,12 @@ static irqreturn_t msdc_irq(int irq, voi
+               data = host->data;
+               spin_unlock_irqrestore(&host->lock, flags);
++              if ((events & event_mask) & MSDC_INT_CDSC) {
++                      if (host->internal_cd)
++                              mmc_detect_change(host->mmc, msecs_to_jiffies(20));
++                      events &= ~MSDC_INT_CDSC;
++              }
++
+               if (!(events & event_mask))
+                       break;
+@@ -1355,14 +1366,24 @@ static void msdc_init_hw(struct msdc_hos
+       /* Reset */
+       msdc_reset_hw(host);
+-      /* Disable card detection */
+-      sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
+-
+       /* Disable and clear all interrupts */
+       writel(0, host->base + MSDC_INTEN);
+       val = readl(host->base + MSDC_INT);
+       writel(val, host->base + MSDC_INT);
++      /* Configure card detection */
++      if (host->internal_cd) {
++              sdr_set_field(host->base + MSDC_PS, MSDC_PS_CDDEBOUNCE,
++                            DEFAULT_DEBOUNCE);
++              sdr_set_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
++              sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC);
++              sdr_set_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP);
++      } else {
++              sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP);
++              sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
++              sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CDSC);
++      }
++
+       writel(0, host->base + tune_reg);
+       writel(0, host->base + MSDC_IOCON);
+       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+@@ -1434,6 +1455,13 @@ static void msdc_init_hw(struct msdc_hos
+ static void msdc_deinit_hw(struct msdc_host *host)
+ {
+       u32 val;
++
++      if (host->internal_cd) {
++              /* Disabled card-detect */
++              sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
++              sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_INSWKUP);
++      }
++
+       /* Disable and clear all interrupts */
+       writel(0, host->base + MSDC_INTEN);
+@@ -1831,13 +1859,31 @@ static void msdc_hw_reset(struct mmc_hos
+       sdr_clr_bits(host->base + EMMC_IOCON, 1);
+ }
++static int msdc_get_cd(struct mmc_host *mmc)
++{
++      struct msdc_host *host = mmc_priv(mmc);
++      int val;
++
++      if (mmc->caps & MMC_CAP_NONREMOVABLE)
++              return 1;
++
++      if (!host->internal_cd)
++              return mmc_gpio_get_cd(mmc);
++
++      val = readl(host->base + MSDC_PS) & MSDC_PS_CDSTS;
++      if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)
++              return !!val;
++      else
++              return !val;
++}
++
+ static const struct mmc_host_ops mt_msdc_ops = {
+       .post_req = msdc_post_req,
+       .pre_req = msdc_pre_req,
+       .request = msdc_ops_request,
+       .set_ios = msdc_ops_set_ios,
+       .get_ro = mmc_gpio_get_ro,
+-      .get_cd = mmc_gpio_get_cd,
++      .get_cd = msdc_get_cd,
+       .start_signal_voltage_switch = msdc_ops_switch_volt,
+       .card_busy = msdc_card_busy,
+       .execute_tuning = msdc_execute_tuning,
+@@ -1957,6 +2003,16 @@ static int msdc_drv_probe(struct platfor
+       else
+               mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
++      if (!(mmc->caps & MMC_CAP_NONREMOVABLE) &&
++          !mmc_can_gpio_cd(mmc) &&
++          host->dev_comp->use_internal_cd) {
++              /*
++               * Is removable but no GPIO declared, so
++               * use internal functionality.
++               */
++              host->internal_cd = true;
++      }
++
+       mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
+       /* MMC core transfer sizes tunable parameters */
+       mmc->max_segs = MAX_BD_NUM;