| Date: | 2010-07-15 22:45:16 (13 years 5 months ago) |
|---|---|
| Author: | Lars C. |
| Commit: | 629b230c9b2ead5c9dc2dfb1c9ddf446259ea59b |
| Message: | MMC: jz4740: Avoid reloading the fifo address before each read/write This improves performance a bit |
| Files: |
drivers/mmc/host/jz4740_mmc.c (16 diffs) |
Change Details
| drivers/mmc/host/jz4740_mmc.c | ||
|---|---|---|
| 195 | 195 | |
| 196 | 196 | mmc_request_done(host->mmc, req); |
| 197 | 197 | } |
| 198 | ||
| 198 | 199 | static unsigned int jz4740_mmc_poll_irq(struct jz4740_mmc_host *host, |
| 199 | 200 | unsigned int irq) |
| 200 | 201 | { |
| 201 | unsigned int timeout = 1000; | |
| 202 | unsigned int timeout = 0x800; | |
| 202 | 203 | uint16_t status; |
| 203 | 204 | |
| 204 | 205 | do { |
| ... | ... | |
| 236 | 237 | struct mmc_data *data) |
| 237 | 238 | { |
| 238 | 239 | struct sg_mapping_iter *miter = &host->miter; |
| 240 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_TXFIFO; | |
| 239 | 241 | uint32_t *buf; |
| 240 | 242 | bool timeout; |
| 241 | 243 | size_t i, j; |
| ... | ... | |
| 250 | 252 | if (unlikely(timeout)) |
| 251 | 253 | goto poll_timeout; |
| 252 | 254 | |
| 253 | writel(buf[0], host->base + JZ_REG_MMC_TXFIFO); | |
| 254 | writel(buf[1], host->base + JZ_REG_MMC_TXFIFO); | |
| 255 | writel(buf[2], host->base + JZ_REG_MMC_TXFIFO); | |
| 256 | writel(buf[3], host->base + JZ_REG_MMC_TXFIFO); | |
| 257 | writel(buf[4], host->base + JZ_REG_MMC_TXFIFO); | |
| 258 | writel(buf[5], host->base + JZ_REG_MMC_TXFIFO); | |
| 259 | writel(buf[6], host->base + JZ_REG_MMC_TXFIFO); | |
| 260 | writel(buf[7], host->base + JZ_REG_MMC_TXFIFO); | |
| 255 | writel(buf[0], fifo_addr); | |
| 256 | writel(buf[1], fifo_addr); | |
| 257 | writel(buf[2], fifo_addr); | |
| 258 | writel(buf[3], fifo_addr); | |
| 259 | writel(buf[4], fifo_addr); | |
| 260 | writel(buf[5], fifo_addr); | |
| 261 | writel(buf[6], fifo_addr); | |
| 262 | writel(buf[7], fifo_addr); | |
| 261 | 263 | buf += 8; |
| 262 | 264 | --j; |
| 263 | 265 | } |
| ... | ... | |
| 267 | 269 | goto poll_timeout; |
| 268 | 270 | |
| 269 | 271 | while (i) { |
| 270 | writel(*buf, host->base + JZ_REG_MMC_TXFIFO); | |
| 272 | writel(*buf, fifo_addr); | |
| 271 | 273 | ++buf; |
| 272 | 274 | --i; |
| 273 | 275 | } |
| ... | ... | |
| 290 | 292 | struct mmc_data *data) |
| 291 | 293 | { |
| 292 | 294 | struct sg_mapping_iter *miter = &host->miter; |
| 295 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO; | |
| 293 | 296 | uint32_t *buf; |
| 294 | 297 | uint32_t d; |
| 295 | 298 | uint16_t status; |
| ... | ... | |
| 306 | 309 | if (unlikely(timeout)) |
| 307 | 310 | goto poll_timeout; |
| 308 | 311 | |
| 309 | buf[0] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 310 | buf[1] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 311 | buf[2] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 312 | buf[3] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 313 | buf[4] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 314 | buf[5] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 315 | buf[6] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 316 | buf[7] = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 312 | buf[0] = readl(fifo_addr); | |
| 313 | buf[1] = readl(fifo_addr); | |
| 314 | buf[2] = readl(fifo_addr); | |
| 315 | buf[3] = readl(fifo_addr); | |
| 316 | buf[4] = readl(fifo_addr); | |
| 317 | buf[5] = readl(fifo_addr); | |
| 318 | buf[6] = readl(fifo_addr); | |
| 319 | buf[7] = readl(fifo_addr); | |
| 317 | 320 | |
| 318 | 321 | buf += 8; |
| 319 | 322 | --j; |
| ... | ... | |
| 325 | 328 | goto poll_timeout; |
| 326 | 329 | |
| 327 | 330 | while (i >= 4) { |
| 328 | *buf++ = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 331 | *buf++ = readl(fifo_addr); | |
| 329 | 332 | i -= 4; |
| 330 | 333 | } |
| 331 | 334 | if (unlikely(i > 0)) { |
| 332 | d = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 335 | d = readl(fifo_addr); | |
| 333 | 336 | memcpy(buf, &d, i); |
| 334 | 337 | } |
| 335 | 338 | } |
| ... | ... | |
| 346 | 349 | timeout = 1000; |
| 347 | 350 | status = readl(host->base + JZ_REG_MMC_STATUS); |
| 348 | 351 | while (!(status & JZ_MMC_STATUS_DATA_FIFO_EMPTY) && --timeout) { |
| 349 | d = readl(host->base + JZ_REG_MMC_RXFIFO); | |
| 352 | d = readl(fifo_addr); | |
| 350 | 353 | status = readl(host->base + JZ_REG_MMC_STATUS); |
| 351 | 354 | } |
| 352 | 355 | |
| ... | ... | |
| 378 | 381 | { |
| 379 | 382 | int i; |
| 380 | 383 | uint16_t tmp; |
| 384 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_RESP_FIFO; | |
| 381 | 385 | |
| 382 | 386 | if (cmd->flags & MMC_RSP_136) { |
| 383 | tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO); | |
| 387 | tmp = readw(fifo_addr); | |
| 384 | 388 | for (i = 0; i < 4; ++i) { |
| 385 | 389 | cmd->resp[i] = tmp << 24; |
| 386 | tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO); | |
| 390 | tmp = readw(fifo_addr); | |
| 387 | 391 | cmd->resp[i] |= tmp << 8; |
| 388 | tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO); | |
| 392 | tmp = readw(fifo_addr); | |
| 389 | 393 | cmd->resp[i] |= tmp >> 8; |
| 390 | 394 | } |
| 391 | 395 | } else { |
| 392 | cmd->resp[0] = readw(host->base + JZ_REG_MMC_RESP_FIFO) << 24; | |
| 393 | cmd->resp[0] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) << 8; | |
| 394 | cmd->resp[0] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) & 0xff; | |
| 396 | cmd->resp[0] = readw(fifo_addr) << 24; | |
| 397 | cmd->resp[0] |= readw(fifo_addr) << 8; | |
| 398 | cmd->resp[0] |= readw(fifo_addr) & 0xff; | |
| 395 | 399 | } |
| 396 | 400 | } |
| 397 | 401 | |
| ... | ... | |
| 447 | 451 | struct mmc_data *data = cmd->data; |
| 448 | 452 | int direction; |
| 449 | 453 | |
| 450 | if (cmd->data->flags & MMC_DATA_READ) | |
| 454 | if (data->flags & MMC_DATA_READ) | |
| 451 | 455 | direction = SG_MITER_TO_SG; |
| 452 | 456 | else |
| 453 | 457 | direction = SG_MITER_FROM_SG; |
| ... | ... | |
| 461 | 465 | struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)devid; |
| 462 | 466 | struct mmc_command *cmd = host->req->cmd; |
| 463 | 467 | struct mmc_request *req = host->req; |
| 464 | bool timedout = false; | |
| 468 | bool timeout = false; | |
| 465 | 469 | |
| 466 | 470 | if (cmd->error) |
| 467 | 471 | host->state = JZ4740_MMC_STATE_DONE; |
| ... | ... | |
| 478 | 482 | |
| 479 | 483 | case JZ4740_MMC_STATE_TRANSFER_DATA: |
| 480 | 484 | if (cmd->data->flags & MMC_DATA_READ) |
| 481 | timedout = jz4740_mmc_read_data(host, cmd->data); | |
| 485 | timeout = jz4740_mmc_read_data(host, cmd->data); | |
| 482 | 486 | else |
| 483 | timedout = jz4740_mmc_write_data(host, cmd->data); | |
| 487 | timeout = jz4740_mmc_write_data(host, cmd->data); | |
| 484 | 488 | |
| 485 | if (unlikely(timedout)) { | |
| 489 | if (unlikely(timeout)) { | |
| 486 | 490 | host->state = JZ4740_MMC_STATE_TRANSFER_DATA; |
| 487 | 491 | break; |
| 488 | 492 | } |
| 489 | 493 | |
| 490 | 494 | jz4740_mmc_transfer_check_state(host, cmd->data); |
| 491 | 495 | |
| 492 | timedout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_DATA_TRAN_DONE); | |
| 493 | if (unlikely(timedout)) { | |
| 496 | timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_DATA_TRAN_DONE); | |
| 497 | if (unlikely(timeout)) { | |
| 494 | 498 | host->state = JZ4740_MMC_STATE_SEND_STOP; |
| 495 | 499 | break; |
| 496 | 500 | } |
| ... | ... | |
| 502 | 506 | |
| 503 | 507 | jz4740_mmc_send_command(host, req->stop); |
| 504 | 508 | |
| 505 | timedout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_PRG_DONE); | |
| 506 | if (timedout) { | |
| 509 | timeout = jz4740_mmc_poll_irq(host, JZ_MMC_IRQ_PRG_DONE); | |
| 510 | if (timeout) { | |
| 507 | 511 | host->state = JZ4740_MMC_STATE_DONE; |
| 508 | 512 | break; |
| 509 | 513 | } |
| ... | ... | |
| 511 | 515 | break; |
| 512 | 516 | } |
| 513 | 517 | |
| 514 | if (!timedout) | |
| 518 | if (!timeout) | |
| 515 | 519 | jz4740_mmc_request_done(host); |
| 516 | 520 | |
| 517 | 521 | return IRQ_HANDLED; |
| ... | ... | |
| 520 | 524 | static irqreturn_t jz_mmc_irq(int irq, void *devid) |
| 521 | 525 | { |
| 522 | 526 | struct jz4740_mmc_host *host = devid; |
| 527 | struct mmc_command *cmd = host->cmd; | |
| 523 | 528 | uint16_t irq_reg, status, tmp; |
| 524 | 529 | |
| 525 | 530 | irq_reg = readw(host->base + JZ_REG_MMC_IREG); |
| ... | ... | |
| 539 | 544 | irq_reg &= ~JZ_MMC_IRQ_SDIO; |
| 540 | 545 | } |
| 541 | 546 | |
| 542 | if (host->req && host->cmd && irq_reg) { | |
| 547 | if (host->req && cmd && irq_reg) { | |
| 543 | 548 | if (test_and_clear_bit(0, &host->waiting)) { |
| 544 | 549 | del_timer(&host->timeout_timer); |
| 545 | 550 | |
| 546 | 551 | status = readl(host->base + JZ_REG_MMC_STATUS); |
| 547 | 552 | |
| 548 | 553 | if (status & JZ_MMC_STATUS_TIMEOUT_RES) { |
| 549 | host->cmd->error = -ETIMEDOUT; | |
| 554 | cmd->error = -ETIMEDOUT; | |
| 550 | 555 | } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) { |
| 551 | host->cmd->error = -EIO; | |
| 556 | cmd->error = -EIO; | |
| 552 | 557 | } else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR | |
| 553 | 558 | JZ_MMC_STATUS_CRC_WRITE_ERROR)) { |
| 554 | host->cmd->data->error = -EIO; | |
| 559 | if (cmd->data) | |
| 560 | cmd->data->error = -EIO; | |
| 561 | cmd->error = -EIO; | |
| 555 | 562 | } else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR | |
| 556 | 563 | JZ_MMC_STATUS_CRC_WRITE_ERROR)) { |
| 557 | host->cmd->data->error = -EIO; | |
| 564 | if (cmd->data) | |
| 565 | cmd->data->error = -EIO; | |
| 566 | cmd->error = -EIO; | |
| 558 | 567 | } |
| 559 | 568 | |
| 560 | 569 | jz4740_mmc_set_irq_enabled(host, irq_reg, false); |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9
