diff options
Diffstat (limited to 'drivers/mmc/host/tmio_mmc.c')
-rw-r--r-- | drivers/mmc/host/tmio_mmc.c | 180 |
1 files changed, 77 insertions, 103 deletions
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 63fbd5b7d312..91991b460c45 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * | 10 | * |
11 | * Driver for the MMC / SD / SDIO cell found in: | 11 | * Driver for the MMC / SD / SDIO cell found in: |
12 | * | 12 | * |
13 | * TC6393XB TC6391XB TC6387XB T7L66XB | 13 | * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3 |
14 | * | 14 | * |
15 | * This driver draws mainly on scattered spec sheets, Reverse engineering | 15 | * This driver draws mainly on scattered spec sheets, Reverse engineering |
16 | * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit | 16 | * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit |
@@ -35,69 +35,47 @@ | |||
35 | 35 | ||
36 | #include "tmio_mmc.h" | 36 | #include "tmio_mmc.h" |
37 | 37 | ||
38 | /* | ||
39 | * Fixme - documentation conflicts on what the clock values are for the | ||
40 | * various dividers. | ||
41 | * One document I have says that its a divisor of a 24MHz clock, another 33. | ||
42 | * This probably depends on HCLK for a given platform, so we may need to | ||
43 | * require HCLK be passed to us from the MFD core. | ||
44 | * | ||
45 | */ | ||
46 | |||
47 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | 38 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) |
48 | { | 39 | { |
49 | void __iomem *cnf = host->cnf; | ||
50 | void __iomem *ctl = host->ctl; | ||
51 | u32 clk = 0, clock; | 40 | u32 clk = 0, clock; |
52 | 41 | ||
53 | if (new_clock) { | 42 | if (new_clock) { |
54 | for (clock = 46875, clk = 0x100; new_clock >= (clock<<1); ) { | 43 | for (clock = host->mmc->f_min, clk = 0x80000080; |
44 | new_clock >= (clock<<1); clk >>= 1) | ||
55 | clock <<= 1; | 45 | clock <<= 1; |
56 | clk >>= 1; | ||
57 | } | ||
58 | if (clk & 0x1) | ||
59 | clk = 0x20000; | ||
60 | |||
61 | clk >>= 2; | ||
62 | tmio_iowrite8((clk & 0x8000) ? 0 : 1, cnf + CNF_SD_CLK_MODE); | ||
63 | clk |= 0x100; | 46 | clk |= 0x100; |
64 | } | 47 | } |
65 | 48 | ||
66 | tmio_iowrite16(clk, ctl + CTL_SD_CARD_CLK_CTL); | 49 | sd_config_write8(host, CNF_SD_CLK_MODE, clk >> 22); |
50 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); | ||
67 | } | 51 | } |
68 | 52 | ||
69 | static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) | 53 | static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) |
70 | { | 54 | { |
71 | void __iomem *ctl = host->ctl; | 55 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); |
72 | |||
73 | tmio_iowrite16(0x0000, ctl + CTL_CLK_AND_WAIT_CTL); | ||
74 | msleep(10); | 56 | msleep(10); |
75 | tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) & ~0x0100, | 57 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 & |
76 | ctl + CTL_SD_CARD_CLK_CTL); | 58 | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); |
77 | msleep(10); | 59 | msleep(10); |
78 | } | 60 | } |
79 | 61 | ||
80 | static void tmio_mmc_clk_start(struct tmio_mmc_host *host) | 62 | static void tmio_mmc_clk_start(struct tmio_mmc_host *host) |
81 | { | 63 | { |
82 | void __iomem *ctl = host->ctl; | 64 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | |
83 | 65 | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); | |
84 | tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) | 0x0100, | ||
85 | ctl + CTL_SD_CARD_CLK_CTL); | ||
86 | msleep(10); | 66 | msleep(10); |
87 | tmio_iowrite16(0x0100, ctl + CTL_CLK_AND_WAIT_CTL); | 67 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); |
88 | msleep(10); | 68 | msleep(10); |
89 | } | 69 | } |
90 | 70 | ||
91 | static void reset(struct tmio_mmc_host *host) | 71 | static void reset(struct tmio_mmc_host *host) |
92 | { | 72 | { |
93 | void __iomem *ctl = host->ctl; | ||
94 | |||
95 | /* FIXME - should we set stop clock reg here */ | 73 | /* FIXME - should we set stop clock reg here */ |
96 | tmio_iowrite16(0x0000, ctl + CTL_RESET_SD); | 74 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); |
97 | tmio_iowrite16(0x0000, ctl + CTL_RESET_SDIO); | 75 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); |
98 | msleep(10); | 76 | msleep(10); |
99 | tmio_iowrite16(0x0001, ctl + CTL_RESET_SD); | 77 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); |
100 | tmio_iowrite16(0x0001, ctl + CTL_RESET_SDIO); | 78 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); |
101 | msleep(10); | 79 | msleep(10); |
102 | } | 80 | } |
103 | 81 | ||
@@ -129,13 +107,12 @@ tmio_mmc_finish_request(struct tmio_mmc_host *host) | |||
129 | static int | 107 | static int |
130 | tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | 108 | tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) |
131 | { | 109 | { |
132 | void __iomem *ctl = host->ctl; | ||
133 | struct mmc_data *data = host->data; | 110 | struct mmc_data *data = host->data; |
134 | int c = cmd->opcode; | 111 | int c = cmd->opcode; |
135 | 112 | ||
136 | /* Command 12 is handled by hardware */ | 113 | /* Command 12 is handled by hardware */ |
137 | if (cmd->opcode == 12 && !cmd->arg) { | 114 | if (cmd->opcode == 12 && !cmd->arg) { |
138 | tmio_iowrite16(0x001, ctl + CTL_STOP_INTERNAL_ACTION); | 115 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001); |
139 | return 0; | 116 | return 0; |
140 | } | 117 | } |
141 | 118 | ||
@@ -160,18 +137,18 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | |||
160 | if (data) { | 137 | if (data) { |
161 | c |= DATA_PRESENT; | 138 | c |= DATA_PRESENT; |
162 | if (data->blocks > 1) { | 139 | if (data->blocks > 1) { |
163 | tmio_iowrite16(0x100, ctl + CTL_STOP_INTERNAL_ACTION); | 140 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100); |
164 | c |= TRANSFER_MULTI; | 141 | c |= TRANSFER_MULTI; |
165 | } | 142 | } |
166 | if (data->flags & MMC_DATA_READ) | 143 | if (data->flags & MMC_DATA_READ) |
167 | c |= TRANSFER_READ; | 144 | c |= TRANSFER_READ; |
168 | } | 145 | } |
169 | 146 | ||
170 | enable_mmc_irqs(ctl, TMIO_MASK_CMD); | 147 | enable_mmc_irqs(host, TMIO_MASK_CMD); |
171 | 148 | ||
172 | /* Fire off the command */ | 149 | /* Fire off the command */ |
173 | tmio_iowrite32(cmd->arg, ctl + CTL_ARG_REG); | 150 | sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg); |
174 | tmio_iowrite16(c, ctl + CTL_SD_CMD); | 151 | sd_ctrl_write16(host, CTL_SD_CMD, c); |
175 | 152 | ||
176 | return 0; | 153 | return 0; |
177 | } | 154 | } |
@@ -183,7 +160,6 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | |||
183 | */ | 160 | */ |
184 | static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | 161 | static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) |
185 | { | 162 | { |
186 | void __iomem *ctl = host->ctl; | ||
187 | struct mmc_data *data = host->data; | 163 | struct mmc_data *data = host->data; |
188 | unsigned short *buf; | 164 | unsigned short *buf; |
189 | unsigned int count; | 165 | unsigned int count; |
@@ -206,9 +182,9 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |||
206 | 182 | ||
207 | /* Transfer the data */ | 183 | /* Transfer the data */ |
208 | if (data->flags & MMC_DATA_READ) | 184 | if (data->flags & MMC_DATA_READ) |
209 | tmio_ioread16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); | 185 | sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); |
210 | else | 186 | else |
211 | tmio_iowrite16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); | 187 | sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); |
212 | 188 | ||
213 | host->sg_off += count; | 189 | host->sg_off += count; |
214 | 190 | ||
@@ -222,7 +198,6 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |||
222 | 198 | ||
223 | static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | 199 | static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) |
224 | { | 200 | { |
225 | void __iomem *ctl = host->ctl; | ||
226 | struct mmc_data *data = host->data; | 201 | struct mmc_data *data = host->data; |
227 | struct mmc_command *stop; | 202 | struct mmc_command *stop; |
228 | 203 | ||
@@ -251,13 +226,13 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |||
251 | */ | 226 | */ |
252 | 227 | ||
253 | if (data->flags & MMC_DATA_READ) | 228 | if (data->flags & MMC_DATA_READ) |
254 | disable_mmc_irqs(ctl, TMIO_MASK_READOP); | 229 | disable_mmc_irqs(host, TMIO_MASK_READOP); |
255 | else | 230 | else |
256 | disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); | 231 | disable_mmc_irqs(host, TMIO_MASK_WRITEOP); |
257 | 232 | ||
258 | if (stop) { | 233 | if (stop) { |
259 | if (stop->opcode == 12 && !stop->arg) | 234 | if (stop->opcode == 12 && !stop->arg) |
260 | tmio_iowrite16(0x000, ctl + CTL_STOP_INTERNAL_ACTION); | 235 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000); |
261 | else | 236 | else |
262 | BUG(); | 237 | BUG(); |
263 | } | 238 | } |
@@ -268,9 +243,8 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |||
268 | static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | 243 | static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, |
269 | unsigned int stat) | 244 | unsigned int stat) |
270 | { | 245 | { |
271 | void __iomem *ctl = host->ctl, *addr; | ||
272 | struct mmc_command *cmd = host->cmd; | 246 | struct mmc_command *cmd = host->cmd; |
273 | int i; | 247 | int i, addr; |
274 | 248 | ||
275 | if (!host->cmd) { | 249 | if (!host->cmd) { |
276 | pr_debug("Spurious CMD irq\n"); | 250 | pr_debug("Spurious CMD irq\n"); |
@@ -284,8 +258,8 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |||
284 | * modify the order of the response for short response command types. | 258 | * modify the order of the response for short response command types. |
285 | */ | 259 | */ |
286 | 260 | ||
287 | for (i = 3, addr = ctl + CTL_RESPONSE ; i >= 0 ; i--, addr += 4) | 261 | for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4) |
288 | cmd->resp[i] = tmio_ioread32(addr); | 262 | cmd->resp[i] = sd_ctrl_read32(host, addr); |
289 | 263 | ||
290 | if (cmd->flags & MMC_RSP_136) { | 264 | if (cmd->flags & MMC_RSP_136) { |
291 | cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); | 265 | cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); |
@@ -307,9 +281,9 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |||
307 | */ | 281 | */ |
308 | if (host->data && !cmd->error) { | 282 | if (host->data && !cmd->error) { |
309 | if (host->data->flags & MMC_DATA_READ) | 283 | if (host->data->flags & MMC_DATA_READ) |
310 | enable_mmc_irqs(ctl, TMIO_MASK_READOP); | 284 | enable_mmc_irqs(host, TMIO_MASK_READOP); |
311 | else | 285 | else |
312 | enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); | 286 | enable_mmc_irqs(host, TMIO_MASK_WRITEOP); |
313 | } else { | 287 | } else { |
314 | tmio_mmc_finish_request(host); | 288 | tmio_mmc_finish_request(host); |
315 | } | 289 | } |
@@ -321,20 +295,19 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |||
321 | static irqreturn_t tmio_mmc_irq(int irq, void *devid) | 295 | static irqreturn_t tmio_mmc_irq(int irq, void *devid) |
322 | { | 296 | { |
323 | struct tmio_mmc_host *host = devid; | 297 | struct tmio_mmc_host *host = devid; |
324 | void __iomem *ctl = host->ctl; | ||
325 | unsigned int ireg, irq_mask, status; | 298 | unsigned int ireg, irq_mask, status; |
326 | 299 | ||
327 | pr_debug("MMC IRQ begin\n"); | 300 | pr_debug("MMC IRQ begin\n"); |
328 | 301 | ||
329 | status = tmio_ioread32(ctl + CTL_STATUS); | 302 | status = sd_ctrl_read32(host, CTL_STATUS); |
330 | irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); | 303 | irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); |
331 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; | 304 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; |
332 | 305 | ||
333 | pr_debug_status(status); | 306 | pr_debug_status(status); |
334 | pr_debug_status(ireg); | 307 | pr_debug_status(ireg); |
335 | 308 | ||
336 | if (!ireg) { | 309 | if (!ireg) { |
337 | disable_mmc_irqs(ctl, status & ~irq_mask); | 310 | disable_mmc_irqs(host, status & ~irq_mask); |
338 | 311 | ||
339 | pr_debug("tmio_mmc: Spurious irq, disabling! " | 312 | pr_debug("tmio_mmc: Spurious irq, disabling! " |
340 | "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); | 313 | "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); |
@@ -346,7 +319,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
346 | while (ireg) { | 319 | while (ireg) { |
347 | /* Card insert / remove attempts */ | 320 | /* Card insert / remove attempts */ |
348 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | 321 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { |
349 | ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT | | 322 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | |
350 | TMIO_STAT_CARD_REMOVE); | 323 | TMIO_STAT_CARD_REMOVE); |
351 | mmc_detect_change(host->mmc, 0); | 324 | mmc_detect_change(host->mmc, 0); |
352 | } | 325 | } |
@@ -358,25 +331,25 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
358 | 331 | ||
359 | /* Command completion */ | 332 | /* Command completion */ |
360 | if (ireg & TMIO_MASK_CMD) { | 333 | if (ireg & TMIO_MASK_CMD) { |
361 | ack_mmc_irqs(ctl, TMIO_MASK_CMD); | 334 | ack_mmc_irqs(host, TMIO_MASK_CMD); |
362 | tmio_mmc_cmd_irq(host, status); | 335 | tmio_mmc_cmd_irq(host, status); |
363 | } | 336 | } |
364 | 337 | ||
365 | /* Data transfer */ | 338 | /* Data transfer */ |
366 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { | 339 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { |
367 | ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); | 340 | ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); |
368 | tmio_mmc_pio_irq(host); | 341 | tmio_mmc_pio_irq(host); |
369 | } | 342 | } |
370 | 343 | ||
371 | /* Data transfer completion */ | 344 | /* Data transfer completion */ |
372 | if (ireg & TMIO_STAT_DATAEND) { | 345 | if (ireg & TMIO_STAT_DATAEND) { |
373 | ack_mmc_irqs(ctl, TMIO_STAT_DATAEND); | 346 | ack_mmc_irqs(host, TMIO_STAT_DATAEND); |
374 | tmio_mmc_data_irq(host); | 347 | tmio_mmc_data_irq(host); |
375 | } | 348 | } |
376 | 349 | ||
377 | /* Check status - keep going until we've handled it all */ | 350 | /* Check status - keep going until we've handled it all */ |
378 | status = tmio_ioread32(ctl + CTL_STATUS); | 351 | status = sd_ctrl_read32(host, CTL_STATUS); |
379 | irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); | 352 | irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); |
380 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; | 353 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; |
381 | 354 | ||
382 | pr_debug("Status at end of loop: %08x\n", status); | 355 | pr_debug("Status at end of loop: %08x\n", status); |
@@ -391,8 +364,6 @@ out: | |||
391 | static int tmio_mmc_start_data(struct tmio_mmc_host *host, | 364 | static int tmio_mmc_start_data(struct tmio_mmc_host *host, |
392 | struct mmc_data *data) | 365 | struct mmc_data *data) |
393 | { | 366 | { |
394 | void __iomem *ctl = host->ctl; | ||
395 | |||
396 | pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", | 367 | pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", |
397 | data->blksz, data->blocks); | 368 | data->blksz, data->blocks); |
398 | 369 | ||
@@ -407,8 +378,8 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host, | |||
407 | host->data = data; | 378 | host->data = data; |
408 | 379 | ||
409 | /* Set transfer length / blocksize */ | 380 | /* Set transfer length / blocksize */ |
410 | tmio_iowrite16(data->blksz, ctl + CTL_SD_XFER_LEN); | 381 | sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz); |
411 | tmio_iowrite16(data->blocks, ctl + CTL_XFER_BLK_COUNT); | 382 | sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks); |
412 | 383 | ||
413 | return 0; | 384 | return 0; |
414 | } | 385 | } |
@@ -449,8 +420,6 @@ fail: | |||
449 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 420 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
450 | { | 421 | { |
451 | struct tmio_mmc_host *host = mmc_priv(mmc); | 422 | struct tmio_mmc_host *host = mmc_priv(mmc); |
452 | void __iomem *cnf = host->cnf; | ||
453 | void __iomem *ctl = host->ctl; | ||
454 | 423 | ||
455 | if (ios->clock) | 424 | if (ios->clock) |
456 | tmio_mmc_set_clock(host, ios->clock); | 425 | tmio_mmc_set_clock(host, ios->clock); |
@@ -458,12 +427,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
458 | /* Power sequence - OFF -> ON -> UP */ | 427 | /* Power sequence - OFF -> ON -> UP */ |
459 | switch (ios->power_mode) { | 428 | switch (ios->power_mode) { |
460 | case MMC_POWER_OFF: /* power down SD bus */ | 429 | case MMC_POWER_OFF: /* power down SD bus */ |
461 | tmio_iowrite8(0x00, cnf + CNF_PWR_CTL_2); | 430 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); |
462 | tmio_mmc_clk_stop(host); | 431 | tmio_mmc_clk_stop(host); |
463 | break; | 432 | break; |
464 | case MMC_POWER_ON: /* power up SD bus */ | 433 | case MMC_POWER_ON: /* power up SD bus */ |
465 | 434 | ||
466 | tmio_iowrite8(0x02, cnf + CNF_PWR_CTL_2); | 435 | sd_config_write8(host, CNF_PWR_CTL_2, 0x02); |
467 | break; | 436 | break; |
468 | case MMC_POWER_UP: /* start bus clock */ | 437 | case MMC_POWER_UP: /* start bus clock */ |
469 | tmio_mmc_clk_start(host); | 438 | tmio_mmc_clk_start(host); |
@@ -472,10 +441,10 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
472 | 441 | ||
473 | switch (ios->bus_width) { | 442 | switch (ios->bus_width) { |
474 | case MMC_BUS_WIDTH_1: | 443 | case MMC_BUS_WIDTH_1: |
475 | tmio_iowrite16(0x80e0, ctl + CTL_SD_MEM_CARD_OPT); | 444 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); |
476 | break; | 445 | break; |
477 | case MMC_BUS_WIDTH_4: | 446 | case MMC_BUS_WIDTH_4: |
478 | tmio_iowrite16(0x00e0, ctl + CTL_SD_MEM_CARD_OPT); | 447 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); |
479 | break; | 448 | break; |
480 | } | 449 | } |
481 | 450 | ||
@@ -486,9 +455,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
486 | static int tmio_mmc_get_ro(struct mmc_host *mmc) | 455 | static int tmio_mmc_get_ro(struct mmc_host *mmc) |
487 | { | 456 | { |
488 | struct tmio_mmc_host *host = mmc_priv(mmc); | 457 | struct tmio_mmc_host *host = mmc_priv(mmc); |
489 | void __iomem *ctl = host->ctl; | ||
490 | 458 | ||
491 | return (tmio_ioread16(ctl + CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; | 459 | return (sd_ctrl_read16(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; |
492 | } | 460 | } |
493 | 461 | ||
494 | static struct mmc_host_ops tmio_mmc_ops = { | 462 | static struct mmc_host_ops tmio_mmc_ops = { |
@@ -518,13 +486,8 @@ static int tmio_mmc_resume(struct platform_device *dev) | |||
518 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 486 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
519 | struct mmc_host *mmc = platform_get_drvdata(dev); | 487 | struct mmc_host *mmc = platform_get_drvdata(dev); |
520 | struct tmio_mmc_host *host = mmc_priv(mmc); | 488 | struct tmio_mmc_host *host = mmc_priv(mmc); |
521 | void __iomem *cnf = host->cnf; | ||
522 | int ret = 0; | 489 | int ret = 0; |
523 | 490 | ||
524 | /* Enable the MMC/SD Control registers */ | ||
525 | tmio_iowrite16(SDCREN, cnf + CNF_CMD); | ||
526 | tmio_iowrite32(dev->resource[0].start & 0xfffe, cnf + CNF_CTL_BASE); | ||
527 | |||
528 | /* Tell the MFD core we are ready to be enabled */ | 491 | /* Tell the MFD core we are ready to be enabled */ |
529 | if (cell->enable) { | 492 | if (cell->enable) { |
530 | ret = cell->enable(dev); | 493 | ret = cell->enable(dev); |
@@ -532,6 +495,11 @@ static int tmio_mmc_resume(struct platform_device *dev) | |||
532 | goto out; | 495 | goto out; |
533 | } | 496 | } |
534 | 497 | ||
498 | /* Enable the MMC/SD Control registers */ | ||
499 | sd_config_write16(host, CNF_CMD, SDCREN); | ||
500 | sd_config_write32(host, CNF_CTL_BASE, | ||
501 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
502 | |||
535 | mmc_resume_host(mmc); | 503 | mmc_resume_host(mmc); |
536 | 504 | ||
537 | out: | 505 | out: |
@@ -545,20 +513,25 @@ out: | |||
545 | static int __devinit tmio_mmc_probe(struct platform_device *dev) | 513 | static int __devinit tmio_mmc_probe(struct platform_device *dev) |
546 | { | 514 | { |
547 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 515 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
516 | struct tmio_mmc_data *pdata; | ||
548 | struct resource *res_ctl, *res_cnf; | 517 | struct resource *res_ctl, *res_cnf; |
549 | struct tmio_mmc_host *host; | 518 | struct tmio_mmc_host *host; |
550 | struct mmc_host *mmc; | 519 | struct mmc_host *mmc; |
551 | int ret = -ENOMEM; | 520 | int ret = -EINVAL; |
552 | 521 | ||
553 | if (dev->num_resources != 3) | 522 | if (dev->num_resources != 3) |
554 | goto out; | 523 | goto out; |
555 | 524 | ||
556 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); | 525 | res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0); |
557 | res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); | 526 | res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1); |
558 | if (!res_ctl || !res_cnf) { | 527 | if (!res_ctl || !res_cnf) |
559 | ret = -EINVAL; | ||
560 | goto out; | 528 | goto out; |
561 | } | 529 | |
530 | pdata = cell->driver_data; | ||
531 | if (!pdata || !pdata->hclk) | ||
532 | goto out; | ||
533 | |||
534 | ret = -ENOMEM; | ||
562 | 535 | ||
563 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); | 536 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); |
564 | if (!mmc) | 537 | if (!mmc) |
@@ -568,6 +541,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
568 | host->mmc = mmc; | 541 | host->mmc = mmc; |
569 | platform_set_drvdata(dev, mmc); | 542 | platform_set_drvdata(dev, mmc); |
570 | 543 | ||
544 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | ||
545 | host->bus_shift = resource_size(res_ctl) >> 10; | ||
546 | |||
571 | host->ctl = ioremap(res_ctl->start, resource_size(res_ctl)); | 547 | host->ctl = ioremap(res_ctl->start, resource_size(res_ctl)); |
572 | if (!host->ctl) | 548 | if (!host->ctl) |
573 | goto host_free; | 549 | goto host_free; |
@@ -578,15 +554,10 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
578 | 554 | ||
579 | mmc->ops = &tmio_mmc_ops; | 555 | mmc->ops = &tmio_mmc_ops; |
580 | mmc->caps = MMC_CAP_4_BIT_DATA; | 556 | mmc->caps = MMC_CAP_4_BIT_DATA; |
581 | mmc->f_min = 46875; /* 24000000 / 512 */ | 557 | mmc->f_max = pdata->hclk; |
582 | mmc->f_max = 24000000; | 558 | mmc->f_min = mmc->f_max / 512; |
583 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 559 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
584 | 560 | ||
585 | /* Enable the MMC/SD Control registers */ | ||
586 | tmio_iowrite16(SDCREN, host->cnf + CNF_CMD); | ||
587 | tmio_iowrite32(dev->resource[0].start & 0xfffe, | ||
588 | host->cnf + CNF_CTL_BASE); | ||
589 | |||
590 | /* Tell the MFD core we are ready to be enabled */ | 561 | /* Tell the MFD core we are ready to be enabled */ |
591 | if (cell->enable) { | 562 | if (cell->enable) { |
592 | ret = cell->enable(dev); | 563 | ret = cell->enable(dev); |
@@ -594,14 +565,19 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
594 | goto unmap_cnf; | 565 | goto unmap_cnf; |
595 | } | 566 | } |
596 | 567 | ||
568 | /* Enable the MMC/SD Control registers */ | ||
569 | sd_config_write16(host, CNF_CMD, SDCREN); | ||
570 | sd_config_write32(host, CNF_CTL_BASE, | ||
571 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
572 | |||
597 | /* Disable SD power during suspend */ | 573 | /* Disable SD power during suspend */ |
598 | tmio_iowrite8(0x01, host->cnf + CNF_PWR_CTL_3); | 574 | sd_config_write8(host, CNF_PWR_CTL_3, 0x01); |
599 | 575 | ||
600 | /* The below is required but why? FIXME */ | 576 | /* The below is required but why? FIXME */ |
601 | tmio_iowrite8(0x1f, host->cnf + CNF_STOP_CLK_CTL); | 577 | sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f); |
602 | 578 | ||
603 | /* Power down SD bus*/ | 579 | /* Power down SD bus*/ |
604 | tmio_iowrite8(0x0, host->cnf + CNF_PWR_CTL_2); | 580 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); |
605 | 581 | ||
606 | tmio_mmc_clk_stop(host); | 582 | tmio_mmc_clk_stop(host); |
607 | reset(host); | 583 | reset(host); |
@@ -612,22 +588,20 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
612 | else | 588 | else |
613 | goto unmap_cnf; | 589 | goto unmap_cnf; |
614 | 590 | ||
615 | disable_mmc_irqs(host->ctl, TMIO_MASK_ALL); | 591 | disable_mmc_irqs(host, TMIO_MASK_ALL); |
616 | 592 | ||
617 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", | 593 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | |
618 | host); | 594 | IRQF_TRIGGER_FALLING, "tmio-mmc", host); |
619 | if (ret) | 595 | if (ret) |
620 | goto unmap_cnf; | 596 | goto unmap_cnf; |
621 | 597 | ||
622 | set_irq_type(host->irq, IRQ_TYPE_EDGE_FALLING); | ||
623 | |||
624 | mmc_add_host(mmc); | 598 | mmc_add_host(mmc); |
625 | 599 | ||
626 | printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), | 600 | printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), |
627 | (unsigned long)host->ctl, host->irq); | 601 | (unsigned long)host->ctl, host->irq); |
628 | 602 | ||
629 | /* Unmask the IRQs we want to know about */ | 603 | /* Unmask the IRQs we want to know about */ |
630 | enable_mmc_irqs(host->ctl, TMIO_MASK_IRQ); | 604 | enable_mmc_irqs(host, TMIO_MASK_IRQ); |
631 | 605 | ||
632 | return 0; | 606 | return 0; |
633 | 607 | ||