diff options
Diffstat (limited to 'drivers/mfd/rtsx_pcr.c')
-rw-r--r-- | drivers/mfd/rtsx_pcr.c | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 9fc57009e228..481a98a10ecd 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -55,6 +55,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = { | |||
55 | { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 55 | { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
56 | { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 56 | { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
57 | { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | 57 | { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
58 | { PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 }, | ||
58 | { 0, } | 59 | { 0, } |
59 | }; | 60 | }; |
60 | 61 | ||
@@ -325,7 +326,6 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr, | |||
325 | val = ((u64)addr << 32) | ((u64)len << 12) | option; | 326 | val = ((u64)addr << 32) | ((u64)len << 12) | option; |
326 | 327 | ||
327 | put_unaligned_le64(val, ptr); | 328 | put_unaligned_le64(val, ptr); |
328 | ptr++; | ||
329 | pcr->sgi++; | 329 | pcr->sgi++; |
330 | } | 330 | } |
331 | 331 | ||
@@ -591,8 +591,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
591 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk) | 591 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk) |
592 | { | 592 | { |
593 | int err, clk; | 593 | int err, clk; |
594 | u8 N, min_N, max_N, clk_divider; | 594 | u8 n, clk_divider, mcu_cnt, div; |
595 | u8 mcu_cnt, div, max_div; | ||
596 | u8 depth[] = { | 595 | u8 depth[] = { |
597 | [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M, | 596 | [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M, |
598 | [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M, | 597 | [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M, |
@@ -616,10 +615,6 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
616 | card_clock /= 1000000; | 615 | card_clock /= 1000000; |
617 | dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock); | 616 | dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock); |
618 | 617 | ||
619 | min_N = 80; | ||
620 | max_N = 208; | ||
621 | max_div = CLK_DIV_8; | ||
622 | |||
623 | clk = card_clock; | 618 | clk = card_clock; |
624 | if (!initial_mode && double_clk) | 619 | if (!initial_mode && double_clk) |
625 | clk = card_clock * 2; | 620 | clk = card_clock * 2; |
@@ -631,30 +626,30 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
631 | return 0; | 626 | return 0; |
632 | 627 | ||
633 | if (pcr->ops->conv_clk_and_div_n) | 628 | if (pcr->ops->conv_clk_and_div_n) |
634 | N = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N); | 629 | n = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N); |
635 | else | 630 | else |
636 | N = (u8)(clk - 2); | 631 | n = (u8)(clk - 2); |
637 | if ((clk <= 2) || (N > max_N)) | 632 | if ((clk <= 2) || (n > MAX_DIV_N_PCR)) |
638 | return -EINVAL; | 633 | return -EINVAL; |
639 | 634 | ||
640 | mcu_cnt = (u8)(125/clk + 3); | 635 | mcu_cnt = (u8)(125/clk + 3); |
641 | if (mcu_cnt > 15) | 636 | if (mcu_cnt > 15) |
642 | mcu_cnt = 15; | 637 | mcu_cnt = 15; |
643 | 638 | ||
644 | /* Make sure that the SSC clock div_n is equal or greater than min_N */ | 639 | /* Make sure that the SSC clock div_n is not less than MIN_DIV_N_PCR */ |
645 | div = CLK_DIV_1; | 640 | div = CLK_DIV_1; |
646 | while ((N < min_N) && (div < max_div)) { | 641 | while ((n < MIN_DIV_N_PCR) && (div < CLK_DIV_8)) { |
647 | if (pcr->ops->conv_clk_and_div_n) { | 642 | if (pcr->ops->conv_clk_and_div_n) { |
648 | int dbl_clk = pcr->ops->conv_clk_and_div_n(N, | 643 | int dbl_clk = pcr->ops->conv_clk_and_div_n(n, |
649 | DIV_N_TO_CLK) * 2; | 644 | DIV_N_TO_CLK) * 2; |
650 | N = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk, | 645 | n = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk, |
651 | CLK_TO_DIV_N); | 646 | CLK_TO_DIV_N); |
652 | } else { | 647 | } else { |
653 | N = (N + 2) * 2 - 2; | 648 | n = (n + 2) * 2 - 2; |
654 | } | 649 | } |
655 | div++; | 650 | div++; |
656 | } | 651 | } |
657 | dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div); | 652 | dev_dbg(&(pcr->pci->dev), "n = %d, div = %d\n", n, div); |
658 | 653 | ||
659 | ssc_depth = depth[ssc_depth]; | 654 | ssc_depth = depth[ssc_depth]; |
660 | if (double_clk) | 655 | if (double_clk) |
@@ -671,7 +666,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, | |||
671 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); | 666 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); |
672 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, | 667 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, |
673 | SSC_DEPTH_MASK, ssc_depth); | 668 | SSC_DEPTH_MASK, ssc_depth); |
674 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); | 669 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n); |
675 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); | 670 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); |
676 | if (vpclk) { | 671 | if (vpclk) { |
677 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, | 672 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, |
@@ -713,6 +708,25 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card) | |||
713 | } | 708 | } |
714 | EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); | 709 | EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); |
715 | 710 | ||
711 | int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card) | ||
712 | { | ||
713 | unsigned int cd_mask[] = { | ||
714 | [RTSX_SD_CARD] = SD_EXIST, | ||
715 | [RTSX_MS_CARD] = MS_EXIST | ||
716 | }; | ||
717 | |||
718 | if (!pcr->ms_pmos) { | ||
719 | /* When using single PMOS, accessing card is not permitted | ||
720 | * if the existing card is not the designated one. | ||
721 | */ | ||
722 | if (pcr->card_exist & (~cd_mask[card])) | ||
723 | return -EIO; | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | EXPORT_SYMBOL_GPL(rtsx_pci_card_exclusive_check); | ||
729 | |||
716 | int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | 730 | int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) |
717 | { | 731 | { |
718 | if (pcr->ops->switch_output_voltage) | 732 | if (pcr->ops->switch_output_voltage) |
@@ -758,7 +772,7 @@ static void rtsx_pci_card_detect(struct work_struct *work) | |||
758 | struct delayed_work *dwork; | 772 | struct delayed_work *dwork; |
759 | struct rtsx_pcr *pcr; | 773 | struct rtsx_pcr *pcr; |
760 | unsigned long flags; | 774 | unsigned long flags; |
761 | unsigned int card_detect = 0; | 775 | unsigned int card_detect = 0, card_inserted, card_removed; |
762 | u32 irq_status; | 776 | u32 irq_status; |
763 | 777 | ||
764 | dwork = to_delayed_work(work); | 778 | dwork = to_delayed_work(work); |
@@ -766,25 +780,35 @@ static void rtsx_pci_card_detect(struct work_struct *work) | |||
766 | 780 | ||
767 | dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); | 781 | dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); |
768 | 782 | ||
783 | mutex_lock(&pcr->pcr_mutex); | ||
769 | spin_lock_irqsave(&pcr->lock, flags); | 784 | spin_lock_irqsave(&pcr->lock, flags); |
770 | 785 | ||
771 | irq_status = rtsx_pci_readl(pcr, RTSX_BIPR); | 786 | irq_status = rtsx_pci_readl(pcr, RTSX_BIPR); |
772 | dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status); | 787 | dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status); |
773 | 788 | ||
774 | if (pcr->card_inserted || pcr->card_removed) { | 789 | irq_status &= CARD_EXIST; |
790 | card_inserted = pcr->card_inserted & irq_status; | ||
791 | card_removed = pcr->card_removed; | ||
792 | pcr->card_inserted = 0; | ||
793 | pcr->card_removed = 0; | ||
794 | |||
795 | spin_unlock_irqrestore(&pcr->lock, flags); | ||
796 | |||
797 | if (card_inserted || card_removed) { | ||
775 | dev_dbg(&(pcr->pci->dev), | 798 | dev_dbg(&(pcr->pci->dev), |
776 | "card_inserted: 0x%x, card_removed: 0x%x\n", | 799 | "card_inserted: 0x%x, card_removed: 0x%x\n", |
777 | pcr->card_inserted, pcr->card_removed); | 800 | card_inserted, card_removed); |
778 | 801 | ||
779 | if (pcr->ops->cd_deglitch) | 802 | if (pcr->ops->cd_deglitch) |
780 | pcr->card_inserted = pcr->ops->cd_deglitch(pcr); | 803 | card_inserted = pcr->ops->cd_deglitch(pcr); |
804 | |||
805 | card_detect = card_inserted | card_removed; | ||
781 | 806 | ||
782 | card_detect = pcr->card_inserted | pcr->card_removed; | 807 | pcr->card_exist |= card_inserted; |
783 | pcr->card_inserted = 0; | 808 | pcr->card_exist &= ~card_removed; |
784 | pcr->card_removed = 0; | ||
785 | } | 809 | } |
786 | 810 | ||
787 | spin_unlock_irqrestore(&pcr->lock, flags); | 811 | mutex_unlock(&pcr->pcr_mutex); |
788 | 812 | ||
789 | if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event) | 813 | if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event) |
790 | pcr->slots[RTSX_SD_CARD].card_event( | 814 | pcr->slots[RTSX_SD_CARD].card_event( |
@@ -836,10 +860,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
836 | } | 860 | } |
837 | } | 861 | } |
838 | 862 | ||
839 | if (pcr->card_inserted || pcr->card_removed) | ||
840 | schedule_delayed_work(&pcr->carddet_work, | ||
841 | msecs_to_jiffies(200)); | ||
842 | |||
843 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { | 863 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { |
844 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { | 864 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { |
845 | pcr->trans_result = TRANS_RESULT_FAIL; | 865 | pcr->trans_result = TRANS_RESULT_FAIL; |
@@ -852,6 +872,10 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
852 | } | 872 | } |
853 | } | 873 | } |
854 | 874 | ||
875 | if (pcr->card_inserted || pcr->card_removed) | ||
876 | schedule_delayed_work(&pcr->carddet_work, | ||
877 | msecs_to_jiffies(200)); | ||
878 | |||
855 | spin_unlock(&pcr->lock); | 879 | spin_unlock(&pcr->lock); |
856 | return IRQ_HANDLED; | 880 | return IRQ_HANDLED; |
857 | } | 881 | } |
@@ -974,6 +998,14 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) | |||
974 | return err; | 998 | return err; |
975 | } | 999 | } |
976 | 1000 | ||
1001 | /* No CD interrupt if probing driver with card inserted. | ||
1002 | * So we need to initialize pcr->card_exist here. | ||
1003 | */ | ||
1004 | if (pcr->ops->cd_deglitch) | ||
1005 | pcr->card_exist = pcr->ops->cd_deglitch(pcr); | ||
1006 | else | ||
1007 | pcr->card_exist = rtsx_pci_readl(pcr, RTSX_BIPR) & CARD_EXIST; | ||
1008 | |||
977 | return 0; | 1009 | return 0; |
978 | } | 1010 | } |
979 | 1011 | ||
@@ -997,6 +1029,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) | |||
997 | case 0x5289: | 1029 | case 0x5289: |
998 | rtl8411_init_params(pcr); | 1030 | rtl8411_init_params(pcr); |
999 | break; | 1031 | break; |
1032 | |||
1033 | case 0x5227: | ||
1034 | rts5227_init_params(pcr); | ||
1035 | break; | ||
1000 | } | 1036 | } |
1001 | 1037 | ||
1002 | dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n", | 1038 | dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n", |
@@ -1030,6 +1066,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, | |||
1030 | pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device, | 1066 | pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device, |
1031 | (int)pcidev->revision); | 1067 | (int)pcidev->revision); |
1032 | 1068 | ||
1069 | ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); | ||
1070 | if (ret < 0) | ||
1071 | return ret; | ||
1072 | |||
1033 | ret = pci_enable_device(pcidev); | 1073 | ret = pci_enable_device(pcidev); |
1034 | if (ret) | 1074 | if (ret) |
1035 | return ret; | 1075 | return ret; |