aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-03-23 20:10:36 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-03-23 20:10:36 -0400
commitbba1594d348b59d6172e02bf74fba837c8273989 (patch)
tree223e67a4ad043d4ec9361e89c59592ea60e7ddff /drivers/mmc/host/mmci.c
parent9e5ed094c89e55fbf11d2e81d60be98eb12346c0 (diff)
parent7437cfa532842ce75189826742bddf1ba137f58e (diff)
Merge branch 'mmci' into amba
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c166
1 files changed, 121 insertions, 45 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 6692392c05dd..deb73e2b7460 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -53,6 +53,8 @@ static unsigned int fmax = 515633;
53 * @sdio: variant supports SDIO 53 * @sdio: variant supports SDIO
54 * @st_clkdiv: true if using a ST-specific clock divider algorithm 54 * @st_clkdiv: true if using a ST-specific clock divider algorithm
55 * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register 55 * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
56 * @pwrreg_powerup: power up value for MMCIPOWER register
57 * @signal_direction: input/out direction of bus signals can be indicated
56 */ 58 */
57struct variant_data { 59struct variant_data {
58 unsigned int clkreg; 60 unsigned int clkreg;
@@ -63,18 +65,22 @@ struct variant_data {
63 bool sdio; 65 bool sdio;
64 bool st_clkdiv; 66 bool st_clkdiv;
65 bool blksz_datactrl16; 67 bool blksz_datactrl16;
68 u32 pwrreg_powerup;
69 bool signal_direction;
66}; 70};
67 71
68static struct variant_data variant_arm = { 72static struct variant_data variant_arm = {
69 .fifosize = 16 * 4, 73 .fifosize = 16 * 4,
70 .fifohalfsize = 8 * 4, 74 .fifohalfsize = 8 * 4,
71 .datalength_bits = 16, 75 .datalength_bits = 16,
76 .pwrreg_powerup = MCI_PWR_UP,
72}; 77};
73 78
74static struct variant_data variant_arm_extended_fifo = { 79static struct variant_data variant_arm_extended_fifo = {
75 .fifosize = 128 * 4, 80 .fifosize = 128 * 4,
76 .fifohalfsize = 64 * 4, 81 .fifohalfsize = 64 * 4,
77 .datalength_bits = 16, 82 .datalength_bits = 16,
83 .pwrreg_powerup = MCI_PWR_UP,
78}; 84};
79 85
80static struct variant_data variant_u300 = { 86static struct variant_data variant_u300 = {
@@ -83,6 +89,8 @@ static struct variant_data variant_u300 = {
83 .clkreg_enable = MCI_ST_U300_HWFCEN, 89 .clkreg_enable = MCI_ST_U300_HWFCEN,
84 .datalength_bits = 16, 90 .datalength_bits = 16,
85 .sdio = true, 91 .sdio = true,
92 .pwrreg_powerup = MCI_PWR_ON,
93 .signal_direction = true,
86}; 94};
87 95
88static struct variant_data variant_ux500 = { 96static struct variant_data variant_ux500 = {
@@ -93,6 +101,8 @@ static struct variant_data variant_ux500 = {
93 .datalength_bits = 24, 101 .datalength_bits = 24,
94 .sdio = true, 102 .sdio = true,
95 .st_clkdiv = true, 103 .st_clkdiv = true,
104 .pwrreg_powerup = MCI_PWR_ON,
105 .signal_direction = true,
96}; 106};
97 107
98static struct variant_data variant_ux500v2 = { 108static struct variant_data variant_ux500v2 = {
@@ -104,11 +114,35 @@ static struct variant_data variant_ux500v2 = {
104 .sdio = true, 114 .sdio = true,
105 .st_clkdiv = true, 115 .st_clkdiv = true,
106 .blksz_datactrl16 = true, 116 .blksz_datactrl16 = true,
117 .pwrreg_powerup = MCI_PWR_ON,
118 .signal_direction = true,
107}; 119};
108 120
109/* 121/*
110 * This must be called with host->lock held 122 * This must be called with host->lock held
111 */ 123 */
124static void mmci_write_clkreg(struct mmci_host *host, u32 clk)
125{
126 if (host->clk_reg != clk) {
127 host->clk_reg = clk;
128 writel(clk, host->base + MMCICLOCK);
129 }
130}
131
132/*
133 * This must be called with host->lock held
134 */
135static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
136{
137 if (host->pwr_reg != pwr) {
138 host->pwr_reg = pwr;
139 writel(pwr, host->base + MMCIPOWER);
140 }
141}
142
143/*
144 * This must be called with host->lock held
145 */
112static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 146static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
113{ 147{
114 struct variant_data *variant = host->variant; 148 struct variant_data *variant = host->variant;
@@ -153,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
153 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 187 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
154 clk |= MCI_ST_8BIT_BUS; 188 clk |= MCI_ST_8BIT_BUS;
155 189
156 writel(clk, host->base + MMCICLOCK); 190 mmci_write_clkreg(host, clk);
157} 191}
158 192
159static void 193static void
@@ -166,14 +200,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
166 host->mrq = NULL; 200 host->mrq = NULL;
167 host->cmd = NULL; 201 host->cmd = NULL;
168 202
169 /*
170 * Need to drop the host lock here; mmc_request_done may call
171 * back into the driver...
172 */
173 spin_unlock(&host->lock);
174 pm_runtime_put(mmc_dev(host->mmc));
175 mmc_request_done(host->mmc, mrq); 203 mmc_request_done(host->mmc, mrq);
176 spin_lock(&host->lock); 204
205 pm_runtime_mark_last_busy(mmc_dev(host->mmc));
206 pm_runtime_put_autosuspend(mmc_dev(host->mmc));
177} 207}
178 208
179static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 209static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
@@ -607,6 +637,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
607 if (data->flags & MMC_DATA_READ) 637 if (data->flags & MMC_DATA_READ)
608 datactrl |= MCI_DPSM_DIRECTION; 638 datactrl |= MCI_DPSM_DIRECTION;
609 639
640 /* The ST Micro variants has a special bit to enable SDIO */
641 if (variant->sdio && host->mmc->card)
642 if (mmc_card_sdio(host->mmc->card))
643 datactrl |= MCI_ST_DPSM_SDIOEN;
644
610 /* 645 /*
611 * Attempt to use DMA operation mode, if this 646 * Attempt to use DMA operation mode, if this
612 * should fail, fall back to PIO mode 647 * should fail, fall back to PIO mode
@@ -635,11 +670,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
635 irqmask = MCI_TXFIFOHALFEMPTYMASK; 670 irqmask = MCI_TXFIFOHALFEMPTYMASK;
636 } 671 }
637 672
638 /* The ST Micro variants has a special bit to enable SDIO */
639 if (variant->sdio && host->mmc->card)
640 if (mmc_card_sdio(host->mmc->card))
641 datactrl |= MCI_ST_DPSM_SDIOEN;
642
643 writel(datactrl, base + MMCIDATACTRL); 673 writel(datactrl, base + MMCIDATACTRL);
644 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 674 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
645 mmci_set_mask1(host, irqmask); 675 mmci_set_mask1(host, irqmask);
@@ -786,7 +816,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
786 if (count <= 0) 816 if (count <= 0)
787 break; 817 break;
788 818
789 readsl(base + MMCIFIFO, ptr, count >> 2); 819 /*
820 * SDIO especially may want to send something that is
821 * not divisible by 4 (as opposed to card sectors
822 * etc). Therefore make sure to always read the last bytes
823 * while only doing full 32-bit reads towards the FIFO.
824 */
825 if (unlikely(count & 0x3)) {
826 if (count < 4) {
827 unsigned char buf[4];
828 readsl(base + MMCIFIFO, buf, 1);
829 memcpy(ptr, buf, count);
830 } else {
831 readsl(base + MMCIFIFO, ptr, count >> 2);
832 count &= ~0x3;
833 }
834 } else {
835 readsl(base + MMCIFIFO, ptr, count >> 2);
836 }
790 837
791 ptr += count; 838 ptr += count;
792 remain -= count; 839 remain -= count;
@@ -821,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
821 */ 868 */
822 if (variant->sdio && 869 if (variant->sdio &&
823 mmc_card_sdio(host->mmc->card)) { 870 mmc_card_sdio(host->mmc->card)) {
871 u32 clk;
824 if (count < 8) 872 if (count < 8)
825 writel(readl(host->base + MMCICLOCK) & 873 clk = host->clk_reg & ~variant->clkreg_enable;
826 ~variant->clkreg_enable,
827 host->base + MMCICLOCK);
828 else 874 else
829 writel(readl(host->base + MMCICLOCK) | 875 clk = host->clk_reg | variant->clkreg_enable;
830 variant->clkreg_enable, 876
831 host->base + MMCICLOCK); 877 mmci_write_clkreg(host, clk);
832 } 878 }
833 879
834 /* 880 /*
@@ -1015,10 +1061,17 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1015static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 1061static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1016{ 1062{
1017 struct mmci_host *host = mmc_priv(mmc); 1063 struct mmci_host *host = mmc_priv(mmc);
1064 struct variant_data *variant = host->variant;
1018 u32 pwr = 0; 1065 u32 pwr = 0;
1019 unsigned long flags; 1066 unsigned long flags;
1020 int ret; 1067 int ret;
1021 1068
1069 pm_runtime_get_sync(mmc_dev(mmc));
1070
1071 if (host->plat->ios_handler &&
1072 host->plat->ios_handler(mmc_dev(mmc), ios))
1073 dev_err(mmc_dev(mmc), "platform ios_handler failed\n");
1074
1022 switch (ios->power_mode) { 1075 switch (ios->power_mode) {
1023 case MMC_POWER_OFF: 1076 case MMC_POWER_OFF:
1024 if (host->vcc) 1077 if (host->vcc)
@@ -1035,22 +1088,38 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1035 * power should be rare so we print an error 1088 * power should be rare so we print an error
1036 * and return here. 1089 * and return here.
1037 */ 1090 */
1038 return; 1091 goto out;
1039 } 1092 }
1040 } 1093 }
1041 if (host->plat->vdd_handler) 1094 /*
1042 pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, 1095 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
1043 ios->power_mode); 1096 * and instead uses MCI_PWR_ON so apply whatever value is
1044 /* The ST version does not have this, fall through to POWER_ON */ 1097 * configured in the variant data.
1045 if (host->hw_designer != AMBA_VENDOR_ST) { 1098 */
1046 pwr |= MCI_PWR_UP; 1099 pwr |= variant->pwrreg_powerup;
1047 break; 1100
1048 } 1101 break;
1049 case MMC_POWER_ON: 1102 case MMC_POWER_ON:
1050 pwr |= MCI_PWR_ON; 1103 pwr |= MCI_PWR_ON;
1051 break; 1104 break;
1052 } 1105 }
1053 1106
1107 if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
1108 /*
1109 * The ST Micro variant has some additional bits
1110 * indicating signal direction for the signals in
1111 * the SD/MMC bus and feedback-clock usage.
1112 */
1113 pwr |= host->plat->sigdir;
1114
1115 if (ios->bus_width == MMC_BUS_WIDTH_4)
1116 pwr &= ~MCI_ST_DATA74DIREN;
1117 else if (ios->bus_width == MMC_BUS_WIDTH_1)
1118 pwr &= (~MCI_ST_DATA74DIREN &
1119 ~MCI_ST_DATA31DIREN &
1120 ~MCI_ST_DATA2DIREN);
1121 }
1122
1054 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { 1123 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
1055 if (host->hw_designer != AMBA_VENDOR_ST) 1124 if (host->hw_designer != AMBA_VENDOR_ST)
1056 pwr |= MCI_ROD; 1125 pwr |= MCI_ROD;
@@ -1066,13 +1135,13 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1066 spin_lock_irqsave(&host->lock, flags); 1135 spin_lock_irqsave(&host->lock, flags);
1067 1136
1068 mmci_set_clkreg(host, ios->clock); 1137 mmci_set_clkreg(host, ios->clock);
1069 1138 mmci_write_pwrreg(host, pwr);
1070 if (host->pwr != pwr) {
1071 host->pwr = pwr;
1072 writel(pwr, host->base + MMCIPOWER);
1073 }
1074 1139
1075 spin_unlock_irqrestore(&host->lock, flags); 1140 spin_unlock_irqrestore(&host->lock, flags);
1141
1142 out:
1143 pm_runtime_mark_last_busy(mmc_dev(mmc));
1144 pm_runtime_put_autosuspend(mmc_dev(mmc));
1076} 1145}
1077 1146
1078static int mmci_get_ro(struct mmc_host *mmc) 1147static int mmci_get_ro(struct mmc_host *mmc)
@@ -1345,6 +1414,8 @@ static int __devinit mmci_probe(struct amba_device *dev,
1345 1414
1346 mmci_dma_setup(host); 1415 mmci_dma_setup(host);
1347 1416
1417 pm_runtime_set_autosuspend_delay(&dev->dev, 50);
1418 pm_runtime_use_autosuspend(&dev->dev);
1348 pm_runtime_put(&dev->dev); 1419 pm_runtime_put(&dev->dev);
1349 1420
1350 mmc_add_host(mmc); 1421 mmc_add_host(mmc);
@@ -1429,43 +1500,49 @@ static int __devexit mmci_remove(struct amba_device *dev)
1429 return 0; 1500 return 0;
1430} 1501}
1431 1502
1432#ifdef CONFIG_PM 1503#ifdef CONFIG_SUSPEND
1433static int mmci_suspend(struct amba_device *dev, pm_message_t state) 1504static int mmci_suspend(struct device *dev)
1434{ 1505{
1435 struct mmc_host *mmc = amba_get_drvdata(dev); 1506 struct amba_device *adev = to_amba_device(dev);
1507 struct mmc_host *mmc = amba_get_drvdata(adev);
1436 int ret = 0; 1508 int ret = 0;
1437 1509
1438 if (mmc) { 1510 if (mmc) {
1439 struct mmci_host *host = mmc_priv(mmc); 1511 struct mmci_host *host = mmc_priv(mmc);
1440 1512
1441 ret = mmc_suspend_host(mmc); 1513 ret = mmc_suspend_host(mmc);
1442 if (ret == 0) 1514 if (ret == 0) {
1515 pm_runtime_get_sync(dev);
1443 writel(0, host->base + MMCIMASK0); 1516 writel(0, host->base + MMCIMASK0);
1517 }
1444 } 1518 }
1445 1519
1446 return ret; 1520 return ret;
1447} 1521}
1448 1522
1449static int mmci_resume(struct amba_device *dev) 1523static int mmci_resume(struct device *dev)
1450{ 1524{
1451 struct mmc_host *mmc = amba_get_drvdata(dev); 1525 struct amba_device *adev = to_amba_device(dev);
1526 struct mmc_host *mmc = amba_get_drvdata(adev);
1452 int ret = 0; 1527 int ret = 0;
1453 1528
1454 if (mmc) { 1529 if (mmc) {
1455 struct mmci_host *host = mmc_priv(mmc); 1530 struct mmci_host *host = mmc_priv(mmc);
1456 1531
1457 writel(MCI_IRQENABLE, host->base + MMCIMASK0); 1532 writel(MCI_IRQENABLE, host->base + MMCIMASK0);
1533 pm_runtime_put(dev);
1458 1534
1459 ret = mmc_resume_host(mmc); 1535 ret = mmc_resume_host(mmc);
1460 } 1536 }
1461 1537
1462 return ret; 1538 return ret;
1463} 1539}
1464#else
1465#define mmci_suspend NULL
1466#define mmci_resume NULL
1467#endif 1540#endif
1468 1541
1542static const struct dev_pm_ops mmci_dev_pm_ops = {
1543 SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
1544};
1545
1469static struct amba_id mmci_ids[] = { 1546static struct amba_id mmci_ids[] = {
1470 { 1547 {
1471 .id = 0x00041180, 1548 .id = 0x00041180,
@@ -1511,11 +1588,10 @@ MODULE_DEVICE_TABLE(amba, mmci_ids);
1511static struct amba_driver mmci_driver = { 1588static struct amba_driver mmci_driver = {
1512 .drv = { 1589 .drv = {
1513 .name = DRIVER_NAME, 1590 .name = DRIVER_NAME,
1591 .pm = &mmci_dev_pm_ops,
1514 }, 1592 },
1515 .probe = mmci_probe, 1593 .probe = mmci_probe,
1516 .remove = __devexit_p(mmci_remove), 1594 .remove = __devexit_p(mmci_remove),
1517 .suspend = mmci_suspend,
1518 .resume = mmci_resume,
1519 .id_table = mmci_ids, 1595 .id_table = mmci_ids,
1520}; 1596};
1521 1597