From e42d7427b9ce77174eef079be0e04e22bdb8fd07 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 7 Apr 2016 16:41:46 +0100 Subject: [PATCH] WIP: mmc: mmci: add qcom specific program end support 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 --- drivers/mmc/host/mmci.c | 15 ++++++++++++++- drivers/mmc/host/mmci.h | 11 ++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f67e096e83d5..037e7dd3ed23 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -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; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index a1f5e4f49e2a..0c8644ae5237 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -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) @@ -124,6 +128,9 @@ #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) @@ -169,6 +176,7 @@ #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 */ @@ -176,7 +184,7 @@ #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; -- 2.39.5