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

mmc: omap_hsmmc: add autocmd23 support

Add support for autocmd23 support

Signed-off-by: Balaji T K <balajitk@ti.com>
Signed-off-by: Chris Ball <chris@printf.net>

authored by

Balaji T K and committed by
Chris Ball
a2e77152 bf129e1c

+36 -3
+36 -3
drivers/mmc/host/omap_hsmmc.c
··· 45 45 /* OMAP HSMMC Host Controller Registers */ 46 46 #define OMAP_HSMMC_SYSSTATUS 0x0014 47 47 #define OMAP_HSMMC_CON 0x002C 48 + #define OMAP_HSMMC_SDMASA 0x0100 48 49 #define OMAP_HSMMC_BLK 0x0104 49 50 #define OMAP_HSMMC_ARG 0x0108 50 51 #define OMAP_HSMMC_CMD 0x010C ··· 59 58 #define OMAP_HSMMC_STAT 0x0130 60 59 #define OMAP_HSMMC_IE 0x0134 61 60 #define OMAP_HSMMC_ISE 0x0138 61 + #define OMAP_HSMMC_AC12 0x013C 62 62 #define OMAP_HSMMC_CAPA 0x0140 63 63 64 64 #define VS18 (1 << 26) ··· 83 81 #define DTO_MASK 0x000F0000 84 82 #define DTO_SHIFT 16 85 83 #define INIT_STREAM (1 << 1) 84 + #define ACEN_ACMD23 (2 << 2) 86 85 #define DP_SELECT (1 << 21) 87 86 #define DDIR (1 << 4) 88 87 #define DMAE 0x1 ··· 114 111 #define DTO_EN (1 << 20) 115 112 #define DCRC_EN (1 << 21) 116 113 #define DEB_EN (1 << 22) 114 + #define ACE_EN (1 << 24) 117 115 #define CERR_EN (1 << 28) 118 116 #define BADA_EN (1 << 29) 119 117 120 - #define INT_EN_MASK (BADA_EN | CERR_EN | DEB_EN | DCRC_EN |\ 118 + #define INT_EN_MASK (BADA_EN | CERR_EN | ACE_EN | DEB_EN | DCRC_EN |\ 121 119 DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ 122 120 BRR_EN | BWR_EN | TC_EN | CC_EN) 121 + 122 + #define CNI (1 << 7) 123 + #define ACIE (1 << 4) 124 + #define ACEB (1 << 3) 125 + #define ACCE (1 << 2) 126 + #define ACTO (1 << 1) 127 + #define ACNE (1 << 0) 123 128 124 129 #define MMC_AUTOSUSPEND_DELAY 100 125 130 #define MMC_TIMEOUT_MS 20 /* 20 mSec */ ··· 140 129 #define VDD_3V0 3000000 /* 300000 uV */ 141 130 #define VDD_165_195 (ffs(MMC_VDD_165_195) - 1) 142 131 132 + #define AUTO_CMD23 (1 << 1) /* Auto CMD23 support */ 143 133 /* 144 134 * One controller can have multiple slots, like on some omap boards using 145 135 * omap.c controller driver. Luckily this is not currently done on any known ··· 205 193 int use_reg; 206 194 int req_in_progress; 207 195 unsigned long clk_rate; 196 + unsigned int flags; 208 197 struct omap_hsmmc_next next_data; 209 198 struct omap_mmc_platform_data *pdata; 210 199 }; ··· 826 813 827 814 cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); 828 815 816 + if ((host->flags & AUTO_CMD23) && mmc_op_multi(cmd->opcode) && 817 + host->mrq->sbc) { 818 + cmdreg |= ACEN_ACMD23; 819 + OMAP_HSMMC_WRITE(host->base, SDMASA, host->mrq->sbc->arg); 820 + } 829 821 if (data) { 830 822 cmdreg |= DP_SELECT | MSBS | BCE; 831 823 if (data->flags & MMC_DATA_READ) ··· 923 905 host->cmd = NULL; 924 906 925 907 if (host->mrq->sbc && (host->cmd == host->mrq->sbc) && 926 - !host->mrq->sbc->error) { 908 + !host->mrq->sbc->error && !(host->flags & AUTO_CMD23)) { 927 909 omap_hsmmc_start_dma_transfer(host); 928 910 omap_hsmmc_start_command(host, host->mrq->cmd, 929 911 host->mrq->data); ··· 1066 1048 { 1067 1049 struct mmc_data *data; 1068 1050 int end_cmd = 0, end_trans = 0; 1051 + int error = 0; 1069 1052 1070 1053 data = host->data; 1071 1054 dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); ··· 1081 1062 else if (status & (CCRC_EN | DCRC_EN)) 1082 1063 hsmmc_command_incomplete(host, -EILSEQ, end_cmd); 1083 1064 1065 + if (status & ACE_EN) { 1066 + u32 ac12; 1067 + ac12 = OMAP_HSMMC_READ(host->base, AC12); 1068 + if (!(ac12 & ACNE) && host->mrq->sbc) { 1069 + end_cmd = 1; 1070 + if (ac12 & ACTO) 1071 + error = -ETIMEDOUT; 1072 + else if (ac12 & (ACCE | ACEB | ACIE)) 1073 + error = -EILSEQ; 1074 + host->mrq->sbc->error = error; 1075 + hsmmc_command_incomplete(host, error, end_cmd); 1076 + } 1077 + dev_dbg(mmc_dev(host->mmc), "AC12 err: 0x%x\n", ac12); 1078 + } 1084 1079 if (host->data || host->response_busy) { 1085 1080 end_trans = !end_cmd; 1086 1081 host->response_busy = 0; ··· 1546 1513 mmc_request_done(mmc, req); 1547 1514 return; 1548 1515 } 1549 - if (req->sbc) { 1516 + if (req->sbc && !(host->flags & AUTO_CMD23)) { 1550 1517 omap_hsmmc_start_command(host, req->sbc, NULL); 1551 1518 return; 1552 1519 }