aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmc
diff options
context:
space:
mode:
authorArindam Nath <arindam.nath@amd.com>2011-05-05 02:49:04 -0400
committerChris Ball <cjb@laptop.org>2011-05-24 23:53:46 -0400
commitb513ea250eb7c36a8afb3df938d632ca6b4df7cd (patch)
tree41b597f488ffa21c675f49bd8c8ea00d177125e2 /include/linux/mmc
parent3a3035114307cd55e024662bb295a87b849f0bd4 (diff)
mmc: sd: add support for tuning during uhs initialization
Host Controller needs tuning during initialization to operate SDR50 and SDR104 UHS-I cards. Whether SDR50 mode actually needs tuning is indicated by bit 45 of the Host Controller Capabilities register. A new command CMD19 has been defined in the Physical Layer spec v3.01 to request the card to send tuning pattern. We enable Buffer Read Ready interrupt at the very begining of tuning procedure, because that is the only interrupt generated by the Host Controller during tuning. We program the block size to 64 in the Block Size register. We make sure that DMA Enable and Multi Block Select in the Transfer Mode register are set to 0 before actually sending CMD19. The tuning block is sent by the card to the Host Controller using DAT lines, so we set Data Present Select (bit 5) in the Command register. The Host Controller is responsible for doing the verfication of tuning block sent by the card at the hardware level. After sending CMD19, we wait for Buffer Read Ready interrupt. In case we don't receive an interrupt after the specified timeout value, we fall back on fixed sampling clock by setting Execute Tuning (bit 6) and Sampling Clock Select (bit 7) of Host Control2 register to 0. Before exiting the tuning procedure, we disable Buffer Read Ready interrupt and re-enable other interrupts. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath <arindam.nath@amd.com> Reviewed-by: Philip Rakity <prakity@marvell.com> Tested-by: Philip Rakity <prakity@marvell.com> Acked-by: Zhangfei Gao <zhangfei.gao@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'include/linux/mmc')
-rw-r--r--include/linux/mmc/host.h1
-rw-r--r--include/linux/mmc/mmc.h1
-rw-r--r--include/linux/mmc/sdhci.h4
3 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 52b5dc914a8c..ca7007fdb399 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -136,6 +136,7 @@ struct mmc_host_ops {
136 void (*init_card)(struct mmc_host *host, struct mmc_card *card); 136 void (*init_card)(struct mmc_host *host, struct mmc_card *card);
137 137
138 int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); 138 int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
139 int (*execute_tuning)(struct mmc_host *host);
139}; 140};
140 141
141struct mmc_card; 142struct mmc_card;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 373b2bf5e5b5..9fa5a73f393d 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -50,6 +50,7 @@
50#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ 50#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
51#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ 51#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
52#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ 52#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
53#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
53 54
54 /* class 3 */ 55 /* class 3 */
55#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ 56#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 92e1c9ad126c..b74c8530e959 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -111,6 +111,7 @@ struct sdhci_host {
111#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ 111#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */
112#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ 112#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
113#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ 113#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
114#define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */
114 115
115 unsigned int version; /* SDHCI spec. version */ 116 unsigned int version; /* SDHCI spec. version */
116 117
@@ -147,6 +148,9 @@ struct sdhci_host {
147 unsigned int ocr_avail_sd; 148 unsigned int ocr_avail_sd;
148 unsigned int ocr_avail_mmc; 149 unsigned int ocr_avail_mmc;
149 150
151 wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
152 unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
153
150 unsigned long private[0] ____cacheline_aligned; 154 unsigned long private[0] ____cacheline_aligned;
151}; 155};
152#endif /* __SDHCI_H */ 156#endif /* __SDHCI_H */