mmc: fix rk3126 support
authorlintao <lintao@rock-chips.com>
Tue, 5 Aug 2014 04:29:23 +0000 (12:29 +0800)
committerlintao <lintao@rock-chips.com>
Tue, 5 Aug 2014 04:32:46 +0000 (12:32 +0800)
(1) Add cd_gpio support
(2) defconf IDMAC

arch/arm/boot/dts/rk312x-pinctrl.dtsi
arch/arm/boot/dts/rk312x-sdk.dtsi
arch/arm/boot/dts/rk312x.dtsi
arch/arm/configs/rockchip_defconfig
drivers/mmc/host/rk_sdmmc.c
drivers/mmc/host/rk_sdmmc.h

index 16c7b42121b6ff3aaab23641f722eff3bc08ecdd..8dec9bc2cc67961267585cc0ca122e7cb56d083b 100755 (executable)
 
                        };
 
+                       sdmmc0_pwren: sdmmc0-pwren{
+                               rockchip,pins = <MMC0_PWREN>;
+                               rockchip,pull = <VALUE_PULL_UP>;
+                       };
 
                        sdmmc0_bus1: sdmmc0-bus-width1 {
                                rockchip,pins = <MMC0_D0>;
                                        <GPIO1_B7>,  //CMD
                                        <GPIO1_C0>,  //CLK
                                        <GPIO1_C1>,  //DET
+                                       <GPIO1_B6>,  //PWREN
                                        <GPIO1_C2>,  //D0
                                        <GPIO1_C3>,  //D1
                                        <GPIO1_C4>,  //D2
index d1545aeb22080d29171bfacfdad0004c3595335f..b770b89eb895f863efde47a6e5bb5824017450b6 100755 (executable)
        clock-freq-min-max = <400000 50000000>;
        supports-highspeed;
        supports-sd;
+       cd-gpios = <&gpio2 GPIO_A7 GPIO_ACTIVE_HIGH>;/*CD GPIO*/
        broken-cd;
        card-detect-delay = <200>;
        ignore-pm-notify;
        keep-power-in-suspend;
-       //vmmc-supply = <&rk808_ldo5_reg>;
+       vmmc-supply = <&rk818_ldo9_reg>;
        status = "disabled";
 };
 
index a421946c150c77828f383cafedcdc2a71526d439..d3fa2c431a385e7b79bee8afa4fe280e580f95f1 100755 (executable)
                #address-cells = <1>;
                #size-cells = <0>;
                pinctrl-names = "default", "idle";
-               pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>;
+               pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_pwren &sdmmc0_dectn &sdmmc0_bus4>;
                pinctrl-1 = <&sdmmc0_gpio>;
-               //cd-gpios = <&gpio1 GPIO_C1 GPIO_ACTIVE_HIGH>;/*CD GPIO*/
                clocks = <&clk_sdmmc0>, <&clk_gates5 10>;
                clock-names = "clk_mmc", "hclk_mmc";
                dmas = <&pdma 10>;
index 09bfd429f1db7351f5ac8594e395f43cd599d99c..9a6d883ac5ea173b08d950cbdd21286adf9d1e46 100644 (file)
@@ -483,6 +483,7 @@ CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
index 0bdaf81e81f06f1c008b891bd061be7972904718..5d591d049f830e46635ddb5c5f1c4ee16d81bd81 100755 (executable)
@@ -1489,12 +1489,33 @@ static int dw_mci_set_sdio_status(struct mmc_host *mmc, int val)
 
 static int dw_mci_get_cd(struct mmc_host *mmc)
 {
-       int present;
-       struct dw_mci_slot *slot = mmc_priv(mmc);
-       struct dw_mci_board *brd = slot->host->pdata;
-       struct dw_mci *host = slot->host;
-       int gpio_cd = mmc_gpio_get_cd(mmc);
-       
+        int present;
+        struct dw_mci_slot *slot = mmc_priv(mmc);
+        struct dw_mci_board *brd = slot->host->pdata;
+        struct dw_mci *host = slot->host;
+        int gpio_cd = mmc_gpio_get_cd(mmc);
+        int gpio_val;
+
+        if (cpu_is_rk312x() &&
+                soc_is_rk3126() &&
+                (mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)) {
+                gpio_cd = slot->cd_gpio;
+                if (gpio_is_valid(gpio_cd)) {
+                        gpio_val = gpio_get_value_cansleep(gpio_cd);
+                        msleep(10);
+                        if (gpio_val == gpio_get_value_cansleep(gpio_cd)) {
+                                gpio_cd = gpio_get_value_cansleep(gpio_cd) == 0 ? 1 : 0;
+                                if (gpio_cd == 0)
+                                        dw_mci_ctrl_all_reset(host);
+                        } else {
+                                /* Jitter */
+                                return slot->last_detect_state;
+                        }
+                } else {
+                        dev_err(host->dev, "dw_mci_get_cd: invalid gpio_cd!\n");
+                }
+        }
+
         if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
                 return test_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 
@@ -1508,6 +1529,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
        else
                present = (mci_readl(slot->host, CDETECT) & (1 << slot->id))
                        == 0 ? 1 : 0;
+
        spin_lock_bh(&host->lock);
        if (present) {
                set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
@@ -3102,6 +3124,42 @@ static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot,
        if (mmc_gpio_request_cd(mmc, gpio, 0))
                dev_warn(dev, "gpio [%d] request failed\n", gpio);
 }
+
+static irqreturn_t dw_mci_gpio_cd_irqt(int irq, void *dev_id)
+{
+        struct mmc_host *mmc = dev_id;
+        struct dw_mci_slot *slot = mmc_priv(mmc);
+        struct dw_mci *host = slot->host;
+
+        queue_work(host->card_workqueue, &host->card_work);
+
+        return IRQ_HANDLED;
+}
+
+static void dw_mci_of_set_cd_gpio_irq(struct device *dev, u32 gpio,
+                                        struct mmc_host *mmc)
+{
+        struct dw_mci_slot *slot = mmc_priv(mmc);
+        struct dw_mci *host = slot->host;
+        int irq;
+        int ret;
+
+        /* Having a missing entry is valid; return silently */
+        if (!gpio_is_valid(gpio))
+                return;
+
+        irq = gpio_to_irq(gpio);
+        if (irq >= 0) {
+                ret = devm_request_threaded_irq(&mmc->class_dev, irq,
+                        NULL, dw_mci_gpio_cd_irqt,
+                        IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                        "dw_mci_cd", mmc);
+                if (ret < 0)
+                        irq = ret;
+        } else {
+                dev_err(host->dev, "Request cd-gpio interrupt error!\n");
+        }
+}
 #else /* CONFIG_OF */
 static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
 {
@@ -3175,6 +3233,20 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
        if (of_find_property(host->dev->of_node, "supports-emmc", NULL))
                mmc->restrict_caps |= RESTRICT_CARD_TYPE_EMMC;
 
+        /* We assume only low-level chip use gpio_cd */
+        if (cpu_is_rk312x() &&
+                soc_is_rk3126() &&
+                (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)) {
+                slot->cd_gpio = of_get_named_gpio(host->dev->of_node, "cd-gpios", 0);
+                if (gpio_is_valid(slot->cd_gpio)) {
+                        /* Request gpio int for card detection */
+                        dw_mci_of_set_cd_gpio_irq(host->dev, slot->cd_gpio,host->mmc);
+                } else {
+                        slot->cd_gpio = -ENODEV;
+                        dev_err(host->dev, "failed to get your cd-gpios!\n");
+                }
+        }
+
        if (host->pdata->get_ocr)
                mmc->ocr_avail = host->pdata->get_ocr(id);
        else
@@ -3916,20 +3988,25 @@ int dw_mci_suspend(struct dw_mci *host)
                 host->dma_ops->exit(host);
 
         /*only for sdmmc controller*/
-        if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD){
+        if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
                 host->mmc->rescan_disable = 1;
-                if(cancel_delayed_work_sync(&host->mmc->detect))
+                if (cancel_delayed_work_sync(&host->mmc->detect))
                        wake_unlock(&host->mmc->detect_wake_lock);
 
                 disable_irq(host->irq);
-                if(pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
+                if (pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
                         MMC_DBG_ERR_FUNC(host->mmc, "Idle pinctrl setting failed! [%s]",
                                                 mmc_hostname(host->mmc));
-                dw_mci_of_get_cd_gpio(host->dev,0,host->mmc);
+
                 mci_writel(host, RINTSTS, 0xFFFFFFFF);
                 mci_writel(host, INTMASK, 0x00);
                 mci_writel(host, CTRL, 0x00);
-                enable_irq_wake(host->mmc->slot.cd_irq);
+
+                /* Soc rk3126 already in gpio_cd mode */
+                if (!(cpu_is_rk312x() && soc_is_rk3126())) {
+                        dw_mci_of_get_cd_gpio(host->dev, 0, host->mmc);
+                        enable_irq_wake(host->mmc->slot.cd_irq);
+                }
         }
         return 0;
 }
@@ -3949,8 +4026,11 @@ int dw_mci_resume(struct dw_mci *host)
         }
        /*only for sdmmc controller*/
        if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
-               disable_irq_wake(host->mmc->slot.cd_irq);
-                mmc_gpio_free_cd(host->mmc);
+                /* Soc rk3126 already in gpio_cd mode */
+                if (!(cpu_is_rk312x() && soc_is_rk3126())) {
+                        disable_irq_wake(host->mmc->slot.cd_irq);
+                        mmc_gpio_free_cd(host->mmc);
+                }
                if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
                         MMC_DBG_ERR_FUNC(host->mmc, "Default pinctrl setting failed! [%s]",
                                                 mmc_hostname(host->mmc));
index 1166e4698e0631989ee71b414889d787333e5860..d3ed86bb6a20f365f1d8c7bac365b7e1980ca514 100755 (executable)
@@ -293,7 +293,8 @@ struct dw_mci_slot {
 
        int                     quirks;
        int                     wp_gpio;
-    int         pwr_en_gpio;
+       int                     cd_gpio;
+        int                     pwr_en_gpio;
        u32                     ctype;
        u32         pre_ctype;