aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Lin <shawn.lin@rock-chips.com>2016-09-02 00:14:36 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-09-26 15:31:35 -0400
commitec0baaa6b33932a25432e17e0bca8d96083caffa (patch)
tree2234ceb302d97bdf746b33de836571b9dcdcd236
parent1712c9373f98ae8ed41599a8d7841a6fba29c264 (diff)
mmc: dw_mmc: split out preparation of desc for IDMAC32 and IDMAC64
We intend to add more check for descriptors when preparing desc. Let's spilt out the separate body to make the dw_mci_translate_sglist not so lengthy. After spliting out these two functions, we could remove dw_mci_translate_sglist and call both of them when staring idmac. Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c149
1 files changed, 79 insertions, 70 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c23e252c037f..ff9b0fcf8300 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -467,112 +467,121 @@ static void dw_mci_dmac_complete_dma(void *arg)
467 } 467 }
468} 468}
469 469
470static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, 470static inline void dw_mci_prepare_desc64(struct dw_mci *host,
471 unsigned int sg_len) 471 struct mmc_data *data,
472 unsigned int sg_len)
472{ 473{
473 unsigned int desc_len; 474 unsigned int desc_len;
475 struct idmac_desc_64addr *desc_first, *desc_last, *desc;
474 int i; 476 int i;
475 477
476 if (host->dma_64bit_address == 1) { 478 desc_first = desc_last = desc = host->sg_cpu;
477 struct idmac_desc_64addr *desc_first, *desc_last, *desc;
478
479 desc_first = desc_last = desc = host->sg_cpu;
480 479
481 for (i = 0; i < sg_len; i++) { 480 for (i = 0; i < sg_len; i++) {
482 unsigned int length = sg_dma_len(&data->sg[i]); 481 unsigned int length = sg_dma_len(&data->sg[i]);
483 482
484 u64 mem_addr = sg_dma_address(&data->sg[i]); 483 u64 mem_addr = sg_dma_address(&data->sg[i]);
485 484
486 for ( ; length ; desc++) { 485 for ( ; length ; desc++) {
487 desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? 486 desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ?
488 length : DW_MCI_DESC_DATA_LENGTH; 487 length : DW_MCI_DESC_DATA_LENGTH;
489 488
490 length -= desc_len; 489 length -= desc_len;
491 490
492 /* 491 /*
493 * Set the OWN bit and disable interrupts 492 * Set the OWN bit and disable interrupts
494 * for this descriptor 493 * for this descriptor
495 */ 494 */
496 desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | 495 desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC |
497 IDMAC_DES0_CH; 496 IDMAC_DES0_CH;
498 497
499 /* Buffer length */ 498 /* Buffer length */
500 IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len); 499 IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len);
501 500
502 /* Physical address to DMA to/from */ 501 /* Physical address to DMA to/from */
503 desc->des4 = mem_addr & 0xffffffff; 502 desc->des4 = mem_addr & 0xffffffff;
504 desc->des5 = mem_addr >> 32; 503 desc->des5 = mem_addr >> 32;
505 504
506 /* Update physical address for the next desc */ 505 /* Update physical address for the next desc */
507 mem_addr += desc_len; 506 mem_addr += desc_len;
508 507
509 /* Save pointer to the last descriptor */ 508 /* Save pointer to the last descriptor */
510 desc_last = desc; 509 desc_last = desc;
511 }
512 } 510 }
511 }
513 512
514 /* Set first descriptor */ 513 /* Set first descriptor */
515 desc_first->des0 |= IDMAC_DES0_FD; 514 desc_first->des0 |= IDMAC_DES0_FD;
516 515
517 /* Set last descriptor */ 516 /* Set last descriptor */
518 desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); 517 desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC);
519 desc_last->des0 |= IDMAC_DES0_LD; 518 desc_last->des0 |= IDMAC_DES0_LD;
519}
520 520
521 } else {
522 struct idmac_desc *desc_first, *desc_last, *desc;
523 521
524 desc_first = desc_last = desc = host->sg_cpu; 522static inline void dw_mci_prepare_desc32(struct dw_mci *host,
523 struct mmc_data *data,
524 unsigned int sg_len)
525{
526 unsigned int desc_len;
527 struct idmac_desc *desc_first, *desc_last, *desc;
528 int i;
525 529
526 for (i = 0; i < sg_len; i++) { 530 desc_first = desc_last = desc = host->sg_cpu;
527 unsigned int length = sg_dma_len(&data->sg[i]);
528 531
529 u32 mem_addr = sg_dma_address(&data->sg[i]); 532 for (i = 0; i < sg_len; i++) {
533 unsigned int length = sg_dma_len(&data->sg[i]);
530 534
531 for ( ; length ; desc++) { 535 u32 mem_addr = sg_dma_address(&data->sg[i]);
532 desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ?
533 length : DW_MCI_DESC_DATA_LENGTH;
534 536
535 length -= desc_len; 537 for ( ; length ; desc++) {
538 desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ?
539 length : DW_MCI_DESC_DATA_LENGTH;
536 540
537 /* 541 length -= desc_len;
538 * Set the OWN bit and disable interrupts
539 * for this descriptor
540 */
541 desc->des0 = cpu_to_le32(IDMAC_DES0_OWN |
542 IDMAC_DES0_DIC |
543 IDMAC_DES0_CH);
544 542
545 /* Buffer length */ 543 /*
546 IDMAC_SET_BUFFER1_SIZE(desc, desc_len); 544 * Set the OWN bit and disable interrupts
545 * for this descriptor
546 */
547 desc->des0 = cpu_to_le32(IDMAC_DES0_OWN |
548 IDMAC_DES0_DIC |
549 IDMAC_DES0_CH);
547 550
548 /* Physical address to DMA to/from */ 551 /* Buffer length */
549 desc->des2 = cpu_to_le32(mem_addr); 552 IDMAC_SET_BUFFER1_SIZE(desc, desc_len);
550 553
551 /* Update physical address for the next desc */ 554 /* Physical address to DMA to/from */
552 mem_addr += desc_len; 555 desc->des2 = cpu_to_le32(mem_addr);
553 556
554 /* Save pointer to the last descriptor */ 557 /* Update physical address for the next desc */
555 desc_last = desc; 558 mem_addr += desc_len;
556 }
557 }
558
559 /* Set first descriptor */
560 desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD);
561 559
562 /* Set last descriptor */ 560 /* Save pointer to the last descriptor */
563 desc_last->des0 &= cpu_to_le32(~(IDMAC_DES0_CH | 561 desc_last = desc;
564 IDMAC_DES0_DIC)); 562 }
565 desc_last->des0 |= cpu_to_le32(IDMAC_DES0_LD);
566 } 563 }
567 564
568 wmb(); /* drain writebuffer */ 565 /* Set first descriptor */
566 desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD);
567
568 /* Set last descriptor */
569 desc_last->des0 &= cpu_to_le32(~(IDMAC_DES0_CH |
570 IDMAC_DES0_DIC));
571 desc_last->des0 |= cpu_to_le32(IDMAC_DES0_LD);
569} 572}
570 573
571static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) 574static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
572{ 575{
573 u32 temp; 576 u32 temp;
574 577
575 dw_mci_translate_sglist(host, host->data, sg_len); 578 if (host->dma_64bit_address == 1)
579 dw_mci_prepare_desc64(host, host->data, sg_len);
580 else
581 dw_mci_prepare_desc32(host, host->data, sg_len);
582
583 /* drain writebuffer */
584 wmb();
576 585
577 /* Make sure to reset DMA in case we did PIO before this */ 586 /* Make sure to reset DMA in case we did PIO before this */
578 dw_mci_ctrl_reset(host, SDMMC_CTRL_DMA_RESET); 587 dw_mci_ctrl_reset(host, SDMMC_CTRL_DMA_RESET);