aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-07-10 15:21:12 -0400
committerChris Ball <cjb@laptop.org>2013-08-25 00:10:17 -0400
commit967bcb77177cda1a426fdb2350e6ec61bcf5b5eb (patch)
tree778eae304fbbaf0fb8da452dfd01100dee612b09 /drivers/mmc/host
parentacd6d772a04989eb836e98f005155793f51efc7d (diff)
mmc: sh_mmcif: revision-specific Command Completion Signal handling
Some earlier MMCIF IP revisions contained Command Completion Signal support, which has been dropped again in modern versions. Sopport for this feature is added in a way to preserve the current behaviour by default, i.e. when it is not enabled in platform data. Patch is based on work by Nobuyuki HIRAI. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/sh_mmcif.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 2acfa41d609f..6fa6868d1030 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -134,6 +134,8 @@
134 INT_BUFWEN | INT_CMD12DRE | INT_BUFRE | \ 134 INT_BUFWEN | INT_CMD12DRE | INT_BUFRE | \
135 INT_DTRANE | INT_CMD12RBE | INT_CMD12CRE) 135 INT_DTRANE | INT_CMD12RBE | INT_CMD12CRE)
136 136
137#define INT_CCS (INT_CCSTO | INT_CCSRCV | INT_CCSDE)
138
137/* CE_INT_MASK */ 139/* CE_INT_MASK */
138#define MASK_ALL 0x00000000 140#define MASK_ALL 0x00000000
139#define MASK_MCCSDE (1 << 29) 141#define MASK_MCCSDE (1 << 29)
@@ -162,7 +164,7 @@
162 164
163#define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \ 165#define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \
164 MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \ 166 MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \
165 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \ 167 MASK_MCRCSTO | MASK_MWDATTO | \
166 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO) 168 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
167 169
168#define MASK_CLEAN (INT_ERR_STS | MASK_MRBSYE | MASK_MCRSPE | \ 170#define MASK_CLEAN (INT_ERR_STS | MASK_MRBSYE | MASK_MCRSPE | \
@@ -244,6 +246,7 @@ struct sh_mmcif_host {
244 int sg_blkidx; 246 int sg_blkidx;
245 bool power; 247 bool power;
246 bool card_present; 248 bool card_present;
249 bool ccs_enable; /* Command Completion Signal support */
247 struct mutex thread_lock; 250 struct mutex thread_lock;
248 251
249 /* DMA support */ 252 /* DMA support */
@@ -492,8 +495,10 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
492 495
493 sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_ON); 496 sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_ON);
494 sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_OFF); 497 sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_OFF);
498 if (host->ccs_enable)
499 tmp |= SCCSTO_29;
495 sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp | 500 sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp |
496 SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29); 501 SRSPTO_256 | SRBSYTO_29 | SRWDTO_29);
497 /* byte swap on */ 502 /* byte swap on */
498 sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP); 503 sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP);
499} 504}
@@ -873,6 +878,9 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
873 break; 878 break;
874 } 879 }
875 880
881 if (host->ccs_enable)
882 mask |= MASK_MCCSTO;
883
876 if (mrq->data) { 884 if (mrq->data) {
877 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); 885 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
878 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 886 sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET,
@@ -880,7 +888,10 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
880 } 888 }
881 opc = sh_mmcif_set_cmd(host, mrq); 889 opc = sh_mmcif_set_cmd(host, mrq);
882 890
883 sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0); 891 if (host->ccs_enable)
892 sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0);
893 else
894 sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0 | INT_CCS);
884 sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); 895 sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
885 /* set arg */ 896 /* set arg */
886 sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); 897 sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
@@ -1245,11 +1256,14 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
1245static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) 1256static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
1246{ 1257{
1247 struct sh_mmcif_host *host = dev_id; 1258 struct sh_mmcif_host *host = dev_id;
1248 u32 state; 1259 u32 state, mask;
1249 1260
1250 state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); 1261 state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
1251 sh_mmcif_writel(host->addr, MMCIF_CE_INT, 1262 mask = sh_mmcif_readl(host->addr, MMCIF_CE_INT_MASK);
1252 ~(state & sh_mmcif_readl(host->addr, MMCIF_CE_INT_MASK))); 1263 if (host->ccs_enable)
1264 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~(state & mask));
1265 else
1266 sh_mmcif_writel(host->addr, MMCIF_CE_INT, INT_CCS | ~(state & mask));
1253 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state & MASK_CLEAN); 1267 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state & MASK_CLEAN);
1254 1268
1255 if (state & ~MASK_CLEAN) 1269 if (state & ~MASK_CLEAN)
@@ -1383,6 +1397,7 @@ static int sh_mmcif_probe(struct platform_device *pdev)
1383 host->mmc = mmc; 1397 host->mmc = mmc;
1384 host->addr = reg; 1398 host->addr = reg;
1385 host->timeout = msecs_to_jiffies(1000); 1399 host->timeout = msecs_to_jiffies(1000);
1400 host->ccs_enable = !pd || !pd->ccs_unsupported;
1386 1401
1387 host->pd = pdev; 1402 host->pd = pdev;
1388 1403