]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
WIP: mmc: mmci: add qcom specific program end support
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Thu, 7 Apr 2016 15:41:46 +0000 (16:41 +0100)
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Tue, 12 Apr 2016 12:53:38 +0000 (13:53 +0100)
This patch adds support to programend interrupt which is very specific
to QCOM integration. This interrupt is use as busy signal when a command
forces the card to enter into programming state like CMD6 writing to
ext_csd registers.

This also fixes the __mmc_switch timeout issue reproted with latest
versions of the eMMC used on DB600c board.

This is just a WIP patch, will be cleaned up soon.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h

index f67e096e83d54b6cbca0e70f76c8b30a327308d0..037e7dd3ed231e5d060453f63cfdd66289dd1a03 100644 (file)
@@ -900,6 +900,11 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
        if (/*interrupt*/0)
                c |= MCI_CPSM_INTERRUPT;
 
+       if ((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
+               c |= MCI_QCOM_CSPM_PROGENA;
+               host->prog_enable = true;
+       }
+
        if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
                c |= host->variant->data_cmd_enable;
 
@@ -994,9 +999,17 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
        busy_resp = host->variant->busy_detect && (cmd->flags & MMC_RSP_BUSY);
 
        if (!((status|host->busy_status) & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|
-               MCI_CMDSENT|MCI_CMDRESPEND)))
+               MCI_CMDSENT|MCI_CMDRESPEND | MCI_QCOM_PROGDONE)))
                return;
 
+       if (host->prog_enable) {
+               if(status & MCI_QCOM_PROGDONE) {
+                       host->prog_enable = false;
+               } else {
+                       return;
+               }
+       }
+
        /* Check if we need to wait for busy completion. */
        if (host->busy_status && (status & MCI_ST_CARDBUSY))
                return;
index a1f5e4f49e2a3367038268f5bfc7ed43961482e4..0c8644ae52373fe0311ab93a7a5d38ecc785603f 100644 (file)
@@ -64,6 +64,7 @@
 #define MCI_ST_CE_ATACMD       (1 << 14)
 
 /* Modified on Qualcomm Integrations */
+#define MCI_QCOM_CSPM_PROGENA          BIT(11)
 #define MCI_QCOM_CSPM_DATCMD           BIT(12)
 #define MCI_QCOM_CSPM_MCIABORT         BIT(13)
 #define MCI_QCOM_CSPM_CCSENABLE                BIT(14)
@@ -95,6 +96,9 @@
 #define MCI_ST_DPSM_BUSYMODE   (1 << 14)
 #define MCI_ST_DPSM_DDRMODE    (1 << 15)
 
+#define MCI_QCOM_DATA_PEND     (1 << 17)
+#define MCI_QCOM_RX_DATA_PEND  (1 << 20)
+
 #define MMCIDATACNT            0x030
 #define MMCISTATUS             0x034
 #define MCI_CMDCRCFAIL         (1 << 0)
 #define MCI_ST_CEATAEND                (1 << 23)
 #define MCI_ST_CARDBUSY                (1 << 24)
 
+/* Extended status bits for the QCOM variants */
+#define MCI_QCOM_PROGDONE      (1 << 23)
+
 #define MMCICLEAR              0x038
 #define MCI_CMDCRCFAILCLR      (1 << 0)
 #define MCI_DATACRCFAILCLR     (1 << 1)
 #define MCI_ST_CEATAENDMASK    (1 << 23)
 #define MCI_ST_BUSYEND         (1 << 24)
 
+#define MCI_QCOM_PROGDONEMASK  (1 << 23)
 #define MMCIMASK1              0x040
 #define MMCIFIFOCNT            0x048
 #define MMCIFIFO               0x080 /* to 0x0bc */
 #define MCI_IRQENABLE  \
        (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK|     \
        MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK|       \
-       MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_STARTBITERRMASK)
+       MCI_CMDRESPENDMASK| MCI_QCOM_PROGDONEMASK |MCI_CMDSENTMASK|MCI_STARTBITERRMASK)
 
 /* These interrupts are directed to IRQ1 when two IRQ lines are available */
 #define MCI_IRQ1MASK \
@@ -204,6 +212,7 @@ struct mmci_host {
        struct mmc_host         *mmc;
        struct clk              *clk;
        bool                    singleirq;
+       bool                    prog_enable;
 
        spinlock_t              lock;