diff options
author | Philipp Zabel <philipp.zabel@gmail.com> | 2009-06-04 14:12:32 -0400 |
---|---|---|
committer | Pierre Ossman <pierre@ossman.eu> | 2009-06-13 16:43:00 -0400 |
commit | 5e74672c0925335bb00772530634ac70179e8a19 (patch) | |
tree | 79439c648df81cd2fdce4e4fc50d90ff6ba20e04 /drivers/mmc | |
parent | f0e46cc4971f6be96010d9248e0fc076b229d989 (diff) |
tmio_mmc: add bus_shift support
Some ASIC3 devices in the wild are connected with the address bus shifted
by one line, so that its 16-bit registers appear 32-bit aligned in host
memory space.
Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Acked-by: Ian Molton <ian@mnementh.co.uk>
Signed-off-by: Pierre Ossman <pierre@ossman.eu>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/tmio_mmc.c | 129 | ||||
-rw-r--r-- | drivers/mmc/host/tmio_mmc.h | 77 |
2 files changed, 125 insertions, 81 deletions
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 49df71e6be17..01add9bd6289 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -37,8 +37,6 @@ | |||
37 | 37 | ||
38 | 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) |
39 | { | 39 | { |
40 | void __iomem *cnf = host->cnf; | ||
41 | void __iomem *ctl = host->ctl; | ||
42 | u32 clk = 0, clock, f_min = host->mmc->f_min; | 40 | u32 clk = 0, clock, f_min = host->mmc->f_min; |
43 | 41 | ||
44 | if (new_clock) { | 42 | if (new_clock) { |
@@ -50,45 +48,39 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | |||
50 | clk = 0x20000; | 48 | clk = 0x20000; |
51 | 49 | ||
52 | clk >>= 2; | 50 | clk >>= 2; |
53 | tmio_iowrite8((clk & 0x8000) ? 0 : 1, cnf + CNF_SD_CLK_MODE); | 51 | sd_config_write8(host, CNF_SD_CLK_MODE, (clk & 0x8000) ? 0 : 1); |
54 | clk |= 0x100; | 52 | clk |= 0x100; |
55 | } | 53 | } |
56 | 54 | ||
57 | tmio_iowrite16(clk, ctl + CTL_SD_CARD_CLK_CTL); | 55 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk); |
58 | } | 56 | } |
59 | 57 | ||
60 | static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) | 58 | static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) |
61 | { | 59 | { |
62 | void __iomem *ctl = host->ctl; | 60 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); |
63 | |||
64 | tmio_iowrite16(0x0000, ctl + CTL_CLK_AND_WAIT_CTL); | ||
65 | msleep(10); | 61 | msleep(10); |
66 | tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) & ~0x0100, | 62 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 & |
67 | ctl + CTL_SD_CARD_CLK_CTL); | 63 | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); |
68 | msleep(10); | 64 | msleep(10); |
69 | } | 65 | } |
70 | 66 | ||
71 | static void tmio_mmc_clk_start(struct tmio_mmc_host *host) | 67 | static void tmio_mmc_clk_start(struct tmio_mmc_host *host) |
72 | { | 68 | { |
73 | void __iomem *ctl = host->ctl; | 69 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | |
74 | 70 | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); | |
75 | tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) | 0x0100, | ||
76 | ctl + CTL_SD_CARD_CLK_CTL); | ||
77 | msleep(10); | 71 | msleep(10); |
78 | tmio_iowrite16(0x0100, ctl + CTL_CLK_AND_WAIT_CTL); | 72 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); |
79 | msleep(10); | 73 | msleep(10); |
80 | } | 74 | } |
81 | 75 | ||
82 | static void reset(struct tmio_mmc_host *host) | 76 | static void reset(struct tmio_mmc_host *host) |
83 | { | 77 | { |
84 | void __iomem *ctl = host->ctl; | ||
85 | |||
86 | /* FIXME - should we set stop clock reg here */ | 78 | /* FIXME - should we set stop clock reg here */ |
87 | tmio_iowrite16(0x0000, ctl + CTL_RESET_SD); | 79 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); |
88 | tmio_iowrite16(0x0000, ctl + CTL_RESET_SDIO); | 80 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); |
89 | msleep(10); | 81 | msleep(10); |
90 | tmio_iowrite16(0x0001, ctl + CTL_RESET_SD); | 82 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); |
91 | tmio_iowrite16(0x0001, ctl + CTL_RESET_SDIO); | 83 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); |
92 | msleep(10); | 84 | msleep(10); |
93 | } | 85 | } |
94 | 86 | ||
@@ -120,13 +112,12 @@ tmio_mmc_finish_request(struct tmio_mmc_host *host) | |||
120 | static int | 112 | static int |
121 | tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | 113 | tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) |
122 | { | 114 | { |
123 | void __iomem *ctl = host->ctl; | ||
124 | struct mmc_data *data = host->data; | 115 | struct mmc_data *data = host->data; |
125 | int c = cmd->opcode; | 116 | int c = cmd->opcode; |
126 | 117 | ||
127 | /* Command 12 is handled by hardware */ | 118 | /* Command 12 is handled by hardware */ |
128 | if (cmd->opcode == 12 && !cmd->arg) { | 119 | if (cmd->opcode == 12 && !cmd->arg) { |
129 | tmio_iowrite16(0x001, ctl + CTL_STOP_INTERNAL_ACTION); | 120 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001); |
130 | return 0; | 121 | return 0; |
131 | } | 122 | } |
132 | 123 | ||
@@ -151,18 +142,18 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | |||
151 | if (data) { | 142 | if (data) { |
152 | c |= DATA_PRESENT; | 143 | c |= DATA_PRESENT; |
153 | if (data->blocks > 1) { | 144 | if (data->blocks > 1) { |
154 | tmio_iowrite16(0x100, ctl + CTL_STOP_INTERNAL_ACTION); | 145 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100); |
155 | c |= TRANSFER_MULTI; | 146 | c |= TRANSFER_MULTI; |
156 | } | 147 | } |
157 | if (data->flags & MMC_DATA_READ) | 148 | if (data->flags & MMC_DATA_READ) |
158 | c |= TRANSFER_READ; | 149 | c |= TRANSFER_READ; |
159 | } | 150 | } |
160 | 151 | ||
161 | enable_mmc_irqs(ctl, TMIO_MASK_CMD); | 152 | enable_mmc_irqs(host, TMIO_MASK_CMD); |
162 | 153 | ||
163 | /* Fire off the command */ | 154 | /* Fire off the command */ |
164 | tmio_iowrite32(cmd->arg, ctl + CTL_ARG_REG); | 155 | sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg); |
165 | tmio_iowrite16(c, ctl + CTL_SD_CMD); | 156 | sd_ctrl_write16(host, CTL_SD_CMD, c); |
166 | 157 | ||
167 | return 0; | 158 | return 0; |
168 | } | 159 | } |
@@ -174,7 +165,6 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | |||
174 | */ | 165 | */ |
175 | static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | 166 | static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) |
176 | { | 167 | { |
177 | void __iomem *ctl = host->ctl; | ||
178 | struct mmc_data *data = host->data; | 168 | struct mmc_data *data = host->data; |
179 | unsigned short *buf; | 169 | unsigned short *buf; |
180 | unsigned int count; | 170 | unsigned int count; |
@@ -197,9 +187,9 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |||
197 | 187 | ||
198 | /* Transfer the data */ | 188 | /* Transfer the data */ |
199 | if (data->flags & MMC_DATA_READ) | 189 | if (data->flags & MMC_DATA_READ) |
200 | tmio_ioread16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); | 190 | sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); |
201 | else | 191 | else |
202 | tmio_iowrite16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1); | 192 | sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); |
203 | 193 | ||
204 | host->sg_off += count; | 194 | host->sg_off += count; |
205 | 195 | ||
@@ -213,7 +203,6 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |||
213 | 203 | ||
214 | static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | 204 | static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) |
215 | { | 205 | { |
216 | void __iomem *ctl = host->ctl; | ||
217 | struct mmc_data *data = host->data; | 206 | struct mmc_data *data = host->data; |
218 | struct mmc_command *stop; | 207 | struct mmc_command *stop; |
219 | 208 | ||
@@ -242,13 +231,13 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |||
242 | */ | 231 | */ |
243 | 232 | ||
244 | if (data->flags & MMC_DATA_READ) | 233 | if (data->flags & MMC_DATA_READ) |
245 | disable_mmc_irqs(ctl, TMIO_MASK_READOP); | 234 | disable_mmc_irqs(host, TMIO_MASK_READOP); |
246 | else | 235 | else |
247 | disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); | 236 | disable_mmc_irqs(host, TMIO_MASK_WRITEOP); |
248 | 237 | ||
249 | if (stop) { | 238 | if (stop) { |
250 | if (stop->opcode == 12 && !stop->arg) | 239 | if (stop->opcode == 12 && !stop->arg) |
251 | tmio_iowrite16(0x000, ctl + CTL_STOP_INTERNAL_ACTION); | 240 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000); |
252 | else | 241 | else |
253 | BUG(); | 242 | BUG(); |
254 | } | 243 | } |
@@ -259,9 +248,8 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) | |||
259 | static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | 248 | static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, |
260 | unsigned int stat) | 249 | unsigned int stat) |
261 | { | 250 | { |
262 | void __iomem *ctl = host->ctl, *addr; | ||
263 | struct mmc_command *cmd = host->cmd; | 251 | struct mmc_command *cmd = host->cmd; |
264 | int i; | 252 | int i, addr; |
265 | 253 | ||
266 | if (!host->cmd) { | 254 | if (!host->cmd) { |
267 | pr_debug("Spurious CMD irq\n"); | 255 | pr_debug("Spurious CMD irq\n"); |
@@ -275,8 +263,8 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |||
275 | * modify the order of the response for short response command types. | 263 | * modify the order of the response for short response command types. |
276 | */ | 264 | */ |
277 | 265 | ||
278 | for (i = 3, addr = ctl + CTL_RESPONSE ; i >= 0 ; i--, addr += 4) | 266 | for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4) |
279 | cmd->resp[i] = tmio_ioread32(addr); | 267 | cmd->resp[i] = sd_ctrl_read32(host, addr); |
280 | 268 | ||
281 | if (cmd->flags & MMC_RSP_136) { | 269 | if (cmd->flags & MMC_RSP_136) { |
282 | cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); | 270 | cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); |
@@ -298,9 +286,9 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |||
298 | */ | 286 | */ |
299 | if (host->data && !cmd->error) { | 287 | if (host->data && !cmd->error) { |
300 | if (host->data->flags & MMC_DATA_READ) | 288 | if (host->data->flags & MMC_DATA_READ) |
301 | enable_mmc_irqs(ctl, TMIO_MASK_READOP); | 289 | enable_mmc_irqs(host, TMIO_MASK_READOP); |
302 | else | 290 | else |
303 | enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP); | 291 | enable_mmc_irqs(host, TMIO_MASK_WRITEOP); |
304 | } else { | 292 | } else { |
305 | tmio_mmc_finish_request(host); | 293 | tmio_mmc_finish_request(host); |
306 | } | 294 | } |
@@ -312,20 +300,19 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, | |||
312 | static irqreturn_t tmio_mmc_irq(int irq, void *devid) | 300 | static irqreturn_t tmio_mmc_irq(int irq, void *devid) |
313 | { | 301 | { |
314 | struct tmio_mmc_host *host = devid; | 302 | struct tmio_mmc_host *host = devid; |
315 | void __iomem *ctl = host->ctl; | ||
316 | unsigned int ireg, irq_mask, status; | 303 | unsigned int ireg, irq_mask, status; |
317 | 304 | ||
318 | pr_debug("MMC IRQ begin\n"); | 305 | pr_debug("MMC IRQ begin\n"); |
319 | 306 | ||
320 | status = tmio_ioread32(ctl + CTL_STATUS); | 307 | status = sd_ctrl_read32(host, CTL_STATUS); |
321 | irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); | 308 | irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); |
322 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; | 309 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; |
323 | 310 | ||
324 | pr_debug_status(status); | 311 | pr_debug_status(status); |
325 | pr_debug_status(ireg); | 312 | pr_debug_status(ireg); |
326 | 313 | ||
327 | if (!ireg) { | 314 | if (!ireg) { |
328 | disable_mmc_irqs(ctl, status & ~irq_mask); | 315 | disable_mmc_irqs(host, status & ~irq_mask); |
329 | 316 | ||
330 | pr_debug("tmio_mmc: Spurious irq, disabling! " | 317 | pr_debug("tmio_mmc: Spurious irq, disabling! " |
331 | "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); | 318 | "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); |
@@ -337,7 +324,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
337 | while (ireg) { | 324 | while (ireg) { |
338 | /* Card insert / remove attempts */ | 325 | /* Card insert / remove attempts */ |
339 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | 326 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { |
340 | ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT | | 327 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | |
341 | TMIO_STAT_CARD_REMOVE); | 328 | TMIO_STAT_CARD_REMOVE); |
342 | mmc_detect_change(host->mmc, 0); | 329 | mmc_detect_change(host->mmc, 0); |
343 | } | 330 | } |
@@ -349,25 +336,25 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
349 | 336 | ||
350 | /* Command completion */ | 337 | /* Command completion */ |
351 | if (ireg & TMIO_MASK_CMD) { | 338 | if (ireg & TMIO_MASK_CMD) { |
352 | ack_mmc_irqs(ctl, TMIO_MASK_CMD); | 339 | ack_mmc_irqs(host, TMIO_MASK_CMD); |
353 | tmio_mmc_cmd_irq(host, status); | 340 | tmio_mmc_cmd_irq(host, status); |
354 | } | 341 | } |
355 | 342 | ||
356 | /* Data transfer */ | 343 | /* Data transfer */ |
357 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { | 344 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { |
358 | ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); | 345 | ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); |
359 | tmio_mmc_pio_irq(host); | 346 | tmio_mmc_pio_irq(host); |
360 | } | 347 | } |
361 | 348 | ||
362 | /* Data transfer completion */ | 349 | /* Data transfer completion */ |
363 | if (ireg & TMIO_STAT_DATAEND) { | 350 | if (ireg & TMIO_STAT_DATAEND) { |
364 | ack_mmc_irqs(ctl, TMIO_STAT_DATAEND); | 351 | ack_mmc_irqs(host, TMIO_STAT_DATAEND); |
365 | tmio_mmc_data_irq(host); | 352 | tmio_mmc_data_irq(host); |
366 | } | 353 | } |
367 | 354 | ||
368 | /* Check status - keep going until we've handled it all */ | 355 | /* Check status - keep going until we've handled it all */ |
369 | status = tmio_ioread32(ctl + CTL_STATUS); | 356 | status = sd_ctrl_read32(host, CTL_STATUS); |
370 | irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK); | 357 | irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); |
371 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; | 358 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; |
372 | 359 | ||
373 | pr_debug("Status at end of loop: %08x\n", status); | 360 | pr_debug("Status at end of loop: %08x\n", status); |
@@ -382,8 +369,6 @@ out: | |||
382 | static int tmio_mmc_start_data(struct tmio_mmc_host *host, | 369 | static int tmio_mmc_start_data(struct tmio_mmc_host *host, |
383 | struct mmc_data *data) | 370 | struct mmc_data *data) |
384 | { | 371 | { |
385 | void __iomem *ctl = host->ctl; | ||
386 | |||
387 | pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", | 372 | pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", |
388 | data->blksz, data->blocks); | 373 | data->blksz, data->blocks); |
389 | 374 | ||
@@ -398,8 +383,8 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host, | |||
398 | host->data = data; | 383 | host->data = data; |
399 | 384 | ||
400 | /* Set transfer length / blocksize */ | 385 | /* Set transfer length / blocksize */ |
401 | tmio_iowrite16(data->blksz, ctl + CTL_SD_XFER_LEN); | 386 | sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz); |
402 | tmio_iowrite16(data->blocks, ctl + CTL_XFER_BLK_COUNT); | 387 | sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks); |
403 | 388 | ||
404 | return 0; | 389 | return 0; |
405 | } | 390 | } |
@@ -440,8 +425,6 @@ fail: | |||
440 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 425 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
441 | { | 426 | { |
442 | struct tmio_mmc_host *host = mmc_priv(mmc); | 427 | struct tmio_mmc_host *host = mmc_priv(mmc); |
443 | void __iomem *cnf = host->cnf; | ||
444 | void __iomem *ctl = host->ctl; | ||
445 | 428 | ||
446 | if (ios->clock) | 429 | if (ios->clock) |
447 | tmio_mmc_set_clock(host, ios->clock); | 430 | tmio_mmc_set_clock(host, ios->clock); |
@@ -449,12 +432,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
449 | /* Power sequence - OFF -> ON -> UP */ | 432 | /* Power sequence - OFF -> ON -> UP */ |
450 | switch (ios->power_mode) { | 433 | switch (ios->power_mode) { |
451 | case MMC_POWER_OFF: /* power down SD bus */ | 434 | case MMC_POWER_OFF: /* power down SD bus */ |
452 | tmio_iowrite8(0x00, cnf + CNF_PWR_CTL_2); | 435 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); |
453 | tmio_mmc_clk_stop(host); | 436 | tmio_mmc_clk_stop(host); |
454 | break; | 437 | break; |
455 | case MMC_POWER_ON: /* power up SD bus */ | 438 | case MMC_POWER_ON: /* power up SD bus */ |
456 | 439 | ||
457 | tmio_iowrite8(0x02, cnf + CNF_PWR_CTL_2); | 440 | sd_config_write8(host, CNF_PWR_CTL_2, 0x02); |
458 | break; | 441 | break; |
459 | case MMC_POWER_UP: /* start bus clock */ | 442 | case MMC_POWER_UP: /* start bus clock */ |
460 | tmio_mmc_clk_start(host); | 443 | tmio_mmc_clk_start(host); |
@@ -463,10 +446,10 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
463 | 446 | ||
464 | switch (ios->bus_width) { | 447 | switch (ios->bus_width) { |
465 | case MMC_BUS_WIDTH_1: | 448 | case MMC_BUS_WIDTH_1: |
466 | tmio_iowrite16(0x80e0, ctl + CTL_SD_MEM_CARD_OPT); | 449 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); |
467 | break; | 450 | break; |
468 | case MMC_BUS_WIDTH_4: | 451 | case MMC_BUS_WIDTH_4: |
469 | tmio_iowrite16(0x00e0, ctl + CTL_SD_MEM_CARD_OPT); | 452 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); |
470 | break; | 453 | break; |
471 | } | 454 | } |
472 | 455 | ||
@@ -477,9 +460,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
477 | static int tmio_mmc_get_ro(struct mmc_host *mmc) | 460 | static int tmio_mmc_get_ro(struct mmc_host *mmc) |
478 | { | 461 | { |
479 | struct tmio_mmc_host *host = mmc_priv(mmc); | 462 | struct tmio_mmc_host *host = mmc_priv(mmc); |
480 | void __iomem *ctl = host->ctl; | ||
481 | 463 | ||
482 | return (tmio_ioread16(ctl + CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; | 464 | return (sd_ctrl_read16(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; |
483 | } | 465 | } |
484 | 466 | ||
485 | static struct mmc_host_ops tmio_mmc_ops = { | 467 | static struct mmc_host_ops tmio_mmc_ops = { |
@@ -509,12 +491,12 @@ static int tmio_mmc_resume(struct platform_device *dev) | |||
509 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 491 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
510 | struct mmc_host *mmc = platform_get_drvdata(dev); | 492 | struct mmc_host *mmc = platform_get_drvdata(dev); |
511 | struct tmio_mmc_host *host = mmc_priv(mmc); | 493 | struct tmio_mmc_host *host = mmc_priv(mmc); |
512 | void __iomem *cnf = host->cnf; | ||
513 | int ret = 0; | 494 | int ret = 0; |
514 | 495 | ||
515 | /* Enable the MMC/SD Control registers */ | 496 | /* Enable the MMC/SD Control registers */ |
516 | tmio_iowrite16(SDCREN, cnf + CNF_CMD); | 497 | sd_config_write16(host, CNF_CMD, SDCREN); |
517 | tmio_iowrite32(dev->resource[0].start & 0xfffe, cnf + CNF_CTL_BASE); | 498 | sd_config_write32(host, CNF_CTL_BASE, |
499 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); | ||
518 | 500 | ||
519 | /* Tell the MFD core we are ready to be enabled */ | 501 | /* Tell the MFD core we are ready to be enabled */ |
520 | if (cell->enable) { | 502 | if (cell->enable) { |
@@ -566,6 +548,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
566 | host->mmc = mmc; | 548 | host->mmc = mmc; |
567 | platform_set_drvdata(dev, mmc); | 549 | platform_set_drvdata(dev, mmc); |
568 | 550 | ||
551 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | ||
552 | host->bus_shift = resource_size(res_ctl) >> 10; | ||
553 | |||
569 | host->ctl = ioremap(res_ctl->start, resource_size(res_ctl)); | 554 | host->ctl = ioremap(res_ctl->start, resource_size(res_ctl)); |
570 | if (!host->ctl) | 555 | if (!host->ctl) |
571 | goto host_free; | 556 | goto host_free; |
@@ -581,9 +566,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
581 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 566 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
582 | 567 | ||
583 | /* Enable the MMC/SD Control registers */ | 568 | /* Enable the MMC/SD Control registers */ |
584 | tmio_iowrite16(SDCREN, host->cnf + CNF_CMD); | 569 | sd_config_write16(host, CNF_CMD, SDCREN); |
585 | tmio_iowrite32(dev->resource[0].start & 0xfffe, | 570 | sd_config_write32(host, CNF_CTL_BASE, |
586 | host->cnf + CNF_CTL_BASE); | 571 | (dev->resource[0].start >> host->bus_shift) & 0xfffe); |
587 | 572 | ||
588 | /* Tell the MFD core we are ready to be enabled */ | 573 | /* Tell the MFD core we are ready to be enabled */ |
589 | if (cell->enable) { | 574 | if (cell->enable) { |
@@ -593,13 +578,13 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
593 | } | 578 | } |
594 | 579 | ||
595 | /* Disable SD power during suspend */ | 580 | /* Disable SD power during suspend */ |
596 | tmio_iowrite8(0x01, host->cnf + CNF_PWR_CTL_3); | 581 | sd_config_write8(host, CNF_PWR_CTL_3, 0x01); |
597 | 582 | ||
598 | /* The below is required but why? FIXME */ | 583 | /* The below is required but why? FIXME */ |
599 | tmio_iowrite8(0x1f, host->cnf + CNF_STOP_CLK_CTL); | 584 | sd_config_write8(host, CNF_STOP_CLK_CTL, 0x1f); |
600 | 585 | ||
601 | /* Power down SD bus*/ | 586 | /* Power down SD bus*/ |
602 | tmio_iowrite8(0x0, host->cnf + CNF_PWR_CTL_2); | 587 | sd_config_write8(host, CNF_PWR_CTL_2, 0x00); |
603 | 588 | ||
604 | tmio_mmc_clk_stop(host); | 589 | tmio_mmc_clk_stop(host); |
605 | reset(host); | 590 | reset(host); |
@@ -610,7 +595,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
610 | else | 595 | else |
611 | goto unmap_cnf; | 596 | goto unmap_cnf; |
612 | 597 | ||
613 | disable_mmc_irqs(host->ctl, TMIO_MASK_ALL); | 598 | disable_mmc_irqs(host, TMIO_MASK_ALL); |
614 | 599 | ||
615 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", | 600 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", |
616 | host); | 601 | host); |
@@ -625,7 +610,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
625 | (unsigned long)host->ctl, host->irq); | 610 | (unsigned long)host->ctl, host->irq); |
626 | 611 | ||
627 | /* Unmask the IRQs we want to know about */ | 612 | /* Unmask the IRQs we want to know about */ |
628 | enable_mmc_irqs(host->ctl, TMIO_MASK_IRQ); | 613 | enable_mmc_irqs(host, TMIO_MASK_IRQ); |
629 | 614 | ||
630 | return 0; | 615 | return 0; |
631 | 616 | ||
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9c831ab2ece6..9fa998594974 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -83,34 +83,36 @@ | |||
83 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 83 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) |
84 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) | 84 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) |
85 | 85 | ||
86 | #define enable_mmc_irqs(ctl, i) \ | 86 | |
87 | #define enable_mmc_irqs(host, i) \ | ||
87 | do { \ | 88 | do { \ |
88 | u32 mask;\ | 89 | u32 mask;\ |
89 | mask = tmio_ioread32((ctl) + CTL_IRQ_MASK); \ | 90 | mask = sd_ctrl_read32((host), CTL_IRQ_MASK); \ |
90 | mask &= ~((i) & TMIO_MASK_IRQ); \ | 91 | mask &= ~((i) & TMIO_MASK_IRQ); \ |
91 | tmio_iowrite32(mask, (ctl) + CTL_IRQ_MASK); \ | 92 | sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \ |
92 | } while (0) | 93 | } while (0) |
93 | 94 | ||
94 | #define disable_mmc_irqs(ctl, i) \ | 95 | #define disable_mmc_irqs(host, i) \ |
95 | do { \ | 96 | do { \ |
96 | u32 mask;\ | 97 | u32 mask;\ |
97 | mask = tmio_ioread32((ctl) + CTL_IRQ_MASK); \ | 98 | mask = sd_ctrl_read32((host), CTL_IRQ_MASK); \ |
98 | mask |= ((i) & TMIO_MASK_IRQ); \ | 99 | mask |= ((i) & TMIO_MASK_IRQ); \ |
99 | tmio_iowrite32(mask, (ctl) + CTL_IRQ_MASK); \ | 100 | sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \ |
100 | } while (0) | 101 | } while (0) |
101 | 102 | ||
102 | #define ack_mmc_irqs(ctl, i) \ | 103 | #define ack_mmc_irqs(host, i) \ |
103 | do { \ | 104 | do { \ |
104 | u32 mask;\ | 105 | u32 mask;\ |
105 | mask = tmio_ioread32((ctl) + CTL_STATUS); \ | 106 | mask = sd_ctrl_read32((host), CTL_STATUS); \ |
106 | mask &= ~((i) & TMIO_MASK_IRQ); \ | 107 | mask &= ~((i) & TMIO_MASK_IRQ); \ |
107 | tmio_iowrite32(mask, (ctl) + CTL_STATUS); \ | 108 | sd_ctrl_write32((host), CTL_STATUS, mask); \ |
108 | } while (0) | 109 | } while (0) |
109 | 110 | ||
110 | 111 | ||
111 | struct tmio_mmc_host { | 112 | struct tmio_mmc_host { |
112 | void __iomem *cnf; | 113 | void __iomem *cnf; |
113 | void __iomem *ctl; | 114 | void __iomem *ctl; |
115 | unsigned long bus_shift; | ||
114 | struct mmc_command *cmd; | 116 | struct mmc_command *cmd; |
115 | struct mmc_request *mrq; | 117 | struct mmc_request *mrq; |
116 | struct mmc_data *data; | 118 | struct mmc_data *data; |
@@ -123,6 +125,63 @@ struct tmio_mmc_host { | |||
123 | unsigned int sg_off; | 125 | unsigned int sg_off; |
124 | }; | 126 | }; |
125 | 127 | ||
128 | #include <linux/io.h> | ||
129 | |||
130 | static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr) | ||
131 | { | ||
132 | return readw(host->ctl + (addr << host->bus_shift)); | ||
133 | } | ||
134 | |||
135 | static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr, | ||
136 | u16 *buf, int count) | ||
137 | { | ||
138 | readsw(host->ctl + (addr << host->bus_shift), buf, count); | ||
139 | } | ||
140 | |||
141 | static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr) | ||
142 | { | ||
143 | return readw(host->ctl + (addr << host->bus_shift)) | | ||
144 | readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16; | ||
145 | } | ||
146 | |||
147 | static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, | ||
148 | u16 val) | ||
149 | { | ||
150 | writew(val, host->ctl + (addr << host->bus_shift)); | ||
151 | } | ||
152 | |||
153 | static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr, | ||
154 | u16 *buf, int count) | ||
155 | { | ||
156 | writesw(host->ctl + (addr << host->bus_shift), buf, count); | ||
157 | } | ||
158 | |||
159 | static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, | ||
160 | u32 val) | ||
161 | { | ||
162 | writew(val, host->ctl + (addr << host->bus_shift)); | ||
163 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); | ||
164 | } | ||
165 | |||
166 | static inline void sd_config_write8(struct tmio_mmc_host *host, int addr, | ||
167 | u8 val) | ||
168 | { | ||
169 | writeb(val, host->cnf + (addr << host->bus_shift)); | ||
170 | } | ||
171 | |||
172 | static inline void sd_config_write16(struct tmio_mmc_host *host, int addr, | ||
173 | u16 val) | ||
174 | { | ||
175 | writew(val, host->cnf + (addr << host->bus_shift)); | ||
176 | } | ||
177 | |||
178 | static inline void sd_config_write32(struct tmio_mmc_host *host, int addr, | ||
179 | u32 val) | ||
180 | { | ||
181 | writew(val, host->cnf + (addr << host->bus_shift)); | ||
182 | writew(val >> 16, host->cnf + ((addr + 2) << host->bus_shift)); | ||
183 | } | ||
184 | |||
126 | #include <linux/scatterlist.h> | 185 | #include <linux/scatterlist.h> |
127 | #include <linux/blkdev.h> | 186 | #include <linux/blkdev.h> |
128 | 187 | ||