diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2013-07-10 15:21:12 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-08-25 00:10:17 -0400 |
commit | 967bcb77177cda1a426fdb2350e6ec61bcf5b5eb (patch) | |
tree | 778eae304fbbaf0fb8da452dfd01100dee612b09 /drivers/mmc/host | |
parent | acd6d772a04989eb836e98f005155793f51efc7d (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.c | 27 |
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) | |||
1245 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | 1256 | static 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 | ||