aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/host/jmb38x_ms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/memstick/host/jmb38x_ms.c')
-rw-r--r--drivers/memstick/host/jmb38x_ms.c120
1 files changed, 84 insertions, 36 deletions
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index f2b894cd8b0..d89d925caec 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -61,6 +61,7 @@ struct jmb38x_ms_host {
61 struct memstick_request *req; 61 struct memstick_request *req;
62 unsigned char cmd_flags; 62 unsigned char cmd_flags;
63 unsigned char io_pos; 63 unsigned char io_pos;
64 unsigned char ifmode;
64 unsigned int io_word[2]; 65 unsigned int io_word[2];
65}; 66};
66 67
@@ -136,15 +137,14 @@ struct jmb38x_ms {
136#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 137#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
137#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 138#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
138 139
140#define CLOCK_CONTROL_BY_MMIO 0x00000008
139#define CLOCK_CONTROL_40MHZ 0x00000001 141#define CLOCK_CONTROL_40MHZ 0x00000001
140#define CLOCK_CONTROL_50MHZ 0x0000000a 142#define CLOCK_CONTROL_50MHZ 0x00000002
141#define CLOCK_CONTROL_60MHZ 0x00000008 143#define CLOCK_CONTROL_60MHZ 0x00000010
142#define CLOCK_CONTROL_62_5MHZ 0x0000000c 144#define CLOCK_CONTROL_62_5MHZ 0x00000004
143#define CLOCK_CONTROL_OFF 0x00000000 145#define CLOCK_CONTROL_OFF 0x00000000
144 146
145#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0 147#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0
146#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
147#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
148 148
149enum { 149enum {
150 CMD_READY = 0x01, 150 CMD_READY = 0x01,
@@ -390,8 +390,13 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
390 390
391 if (host->req->data_dir == READ) 391 if (host->req->data_dir == READ)
392 cmd |= TPC_DIR; 392 cmd |= TPC_DIR;
393 if (host->req->need_card_int) 393
394 cmd |= TPC_WAIT_INT; 394 if (host->req->need_card_int) {
395 if (host->ifmode == MEMSTICK_SERIAL)
396 cmd |= TPC_GET_INT;
397 else
398 cmd |= TPC_WAIT_INT;
399 }
395 400
396 data = host->req->data; 401 data = host->req->data;
397 402
@@ -529,7 +534,10 @@ static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
529 if (irq_status & INT_STATUS_ANY_ERR) { 534 if (irq_status & INT_STATUS_ANY_ERR) {
530 if (irq_status & INT_STATUS_CRC_ERR) 535 if (irq_status & INT_STATUS_CRC_ERR)
531 host->req->error = -EILSEQ; 536 host->req->error = -EILSEQ;
532 else 537 else if (irq_status & INT_STATUS_TPC_ERR) {
538 dev_dbg(&host->chip->pdev->dev, "TPC_ERR\n");
539 jmb38x_ms_complete_cmd(msh, 0);
540 } else
533 host->req->error = -ETIME; 541 host->req->error = -ETIME;
534 } else { 542 } else {
535 if (host->cmd_flags & DMA_DATA) { 543 if (host->cmd_flags & DMA_DATA) {
@@ -644,7 +652,6 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
644 ndelay(20); 652 ndelay(20);
645 } 653 }
646 dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); 654 dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
647 /* return -EIO; */
648 655
649reset_next: 656reset_next:
650 writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN 657 writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -675,7 +682,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
675{ 682{
676 struct jmb38x_ms_host *host = memstick_priv(msh); 683 struct jmb38x_ms_host *host = memstick_priv(msh);
677 unsigned int host_ctl = readl(host->addr + HOST_CONTROL); 684 unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
678 unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0; 685 unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0;
679 int rc = 0; 686 int rc = 0;
680 687
681 switch (param) { 688 switch (param) {
@@ -687,9 +694,7 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
687 694
688 host_ctl = 7; 695 host_ctl = 7;
689 host_ctl |= HOST_CONTROL_POWER_EN 696 host_ctl |= HOST_CONTROL_POWER_EN
690 | HOST_CONTROL_CLOCK_EN 697 | HOST_CONTROL_CLOCK_EN;
691 | HOST_CONTROL_HW_OC_P
692 | HOST_CONTROL_TDELAY_EN;
693 writel(host_ctl, host->addr + HOST_CONTROL); 698 writel(host_ctl, host->addr + HOST_CONTROL);
694 699
695 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 700 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -712,46 +717,88 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
712 return -EINVAL; 717 return -EINVAL;
713 break; 718 break;
714 case MEMSTICK_INTERFACE: 719 case MEMSTICK_INTERFACE:
720 dev_dbg(&host->chip->pdev->dev,
721 "Set Host Interface Mode to %d\n", value);
722 host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI |
723 HOST_CONTROL_REO);
724 host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P;
715 host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); 725 host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
716 pci_read_config_dword(host->chip->pdev,
717 PCI_CTL_CLOCK_DLY_ADDR,
718 &clock_delay);
719 clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
720 : ~PCI_CTL_CLOCK_DLY_MASK_A;
721 726
722 if (value == MEMSTICK_SERIAL) { 727 if (value == MEMSTICK_SERIAL) {
723 host_ctl &= ~HOST_CONTROL_FAST_CLK;
724 host_ctl &= ~HOST_CONTROL_REO;
725 host_ctl |= HOST_CONTROL_IF_SERIAL 728 host_ctl |= HOST_CONTROL_IF_SERIAL
726 << HOST_CONTROL_IF_SHIFT; 729 << HOST_CONTROL_IF_SHIFT;
727 host_ctl |= HOST_CONTROL_REI; 730 host_ctl |= HOST_CONTROL_REI;
728 clock_ctl = CLOCK_CONTROL_40MHZ; 731 clock_ctl |= CLOCK_CONTROL_40MHZ;
732 clock_delay = 0;
729 } else if (value == MEMSTICK_PAR4) { 733 } else if (value == MEMSTICK_PAR4) {
730 host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO; 734 host_ctl |= HOST_CONTROL_FAST_CLK;
731 host_ctl |= HOST_CONTROL_IF_PAR4 735 host_ctl |= HOST_CONTROL_IF_PAR4
732 << HOST_CONTROL_IF_SHIFT; 736 << HOST_CONTROL_IF_SHIFT;
733 host_ctl &= ~HOST_CONTROL_REI; 737 host_ctl |= HOST_CONTROL_REO;
734 clock_ctl = CLOCK_CONTROL_40MHZ; 738 clock_ctl |= CLOCK_CONTROL_40MHZ;
735 clock_delay |= host->id ? (4 << 12) : (4 << 8); 739 clock_delay = 4;
736 } else if (value == MEMSTICK_PAR8) { 740 } else if (value == MEMSTICK_PAR8) {
737 host_ctl |= HOST_CONTROL_FAST_CLK; 741 host_ctl |= HOST_CONTROL_FAST_CLK;
738 host_ctl |= HOST_CONTROL_IF_PAR8 742 host_ctl |= HOST_CONTROL_IF_PAR8
739 << HOST_CONTROL_IF_SHIFT; 743 << HOST_CONTROL_IF_SHIFT;
740 host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO); 744 clock_ctl |= CLOCK_CONTROL_50MHZ;
741 clock_ctl = CLOCK_CONTROL_50MHZ; 745 clock_delay = 0;
742 } else 746 } else
743 return -EINVAL; 747 return -EINVAL;
744 748
745 writel(host_ctl, host->addr + HOST_CONTROL); 749 writel(host_ctl, host->addr + HOST_CONTROL);
750 writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL);
746 writel(clock_ctl, host->addr + CLOCK_CONTROL); 751 writel(clock_ctl, host->addr + CLOCK_CONTROL);
747 pci_write_config_dword(host->chip->pdev, 752 pci_write_config_byte(host->chip->pdev,
748 PCI_CTL_CLOCK_DLY_ADDR, 753 PCI_CTL_CLOCK_DLY_ADDR + 1,
749 clock_delay); 754 clock_delay);
755 host->ifmode = value;
750 break; 756 break;
751 }; 757 };
752 return 0; 758 return 0;
753} 759}
754 760
761#define PCI_PMOS0_CONTROL 0xae
762#define PMOS0_ENABLE 0x01
763#define PMOS0_OVERCURRENT_LEVEL_2_4V 0x06
764#define PMOS0_EN_OVERCURRENT_DEBOUNCE 0x40
765#define PMOS0_SW_LED_POLARITY_ENABLE 0x80
766#define PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \
767 PMOS0_OVERCURRENT_LEVEL_2_4V)
768#define PCI_PMOS1_CONTROL 0xbd
769#define PMOS1_ACTIVE_BITS 0x4a
770#define PCI_CLOCK_CTL 0xb9
771
772static int jmb38x_ms_pmos(struct pci_dev *pdev, int flag)
773{
774 unsigned char val;
775
776 pci_read_config_byte(pdev, PCI_PMOS0_CONTROL, &val);
777 if (flag)
778 val |= PMOS0_ACTIVE_BITS;
779 else
780 val &= ~PMOS0_ACTIVE_BITS;
781 pci_write_config_byte(pdev, PCI_PMOS0_CONTROL, val);
782 dev_dbg(&pdev->dev, "JMB38x: set PMOS0 val 0x%x\n", val);
783
784 if (pci_resource_flags(pdev, 1)) {
785 pci_read_config_byte(pdev, PCI_PMOS1_CONTROL, &val);
786 if (flag)
787 val |= PMOS1_ACTIVE_BITS;
788 else
789 val &= ~PMOS1_ACTIVE_BITS;
790 pci_write_config_byte(pdev, PCI_PMOS1_CONTROL, val);
791 dev_dbg(&pdev->dev, "JMB38x: set PMOS1 val 0x%x\n", val);
792 }
793
794 pci_read_config_byte(pdev, PCI_CLOCK_CTL, &val);
795 pci_write_config_byte(pdev, PCI_CLOCK_CTL, val & ~0x0f);
796 pci_write_config_byte(pdev, PCI_CLOCK_CTL, val | 0x01);
797 dev_dbg(&pdev->dev, "Clock Control by PCI config is disabled!\n");
798
799 return 0;
800}
801
755#ifdef CONFIG_PM 802#ifdef CONFIG_PM
756 803
757static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state) 804static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state)
@@ -784,8 +831,7 @@ static int jmb38x_ms_resume(struct pci_dev *dev)
784 return rc; 831 return rc;
785 pci_set_master(dev); 832 pci_set_master(dev);
786 833
787 pci_read_config_dword(dev, 0xac, &rc); 834 jmb38x_ms_pmos(dev, 1);
788 pci_write_config_dword(dev, 0xac, rc | 0x00470000);
789 835
790 for (rc = 0; rc < jm->host_cnt; ++rc) { 836 for (rc = 0; rc < jm->host_cnt; ++rc) {
791 if (!jm->hosts[rc]) 837 if (!jm->hosts[rc])
@@ -894,8 +940,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev,
894 goto err_out; 940 goto err_out;
895 } 941 }
896 942
897 pci_read_config_dword(pdev, 0xac, &rc); 943 jmb38x_ms_pmos(pdev, 1);
898 pci_write_config_dword(pdev, 0xac, rc | 0x00470000);
899 944
900 cnt = jmb38x_ms_count_slots(pdev); 945 cnt = jmb38x_ms_count_slots(pdev);
901 if (!cnt) { 946 if (!cnt) {
@@ -976,6 +1021,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev)
976 jmb38x_ms_free_host(jm->hosts[cnt]); 1021 jmb38x_ms_free_host(jm->hosts[cnt]);
977 } 1022 }
978 1023
1024 jmb38x_ms_pmos(dev, 0);
1025
979 pci_set_drvdata(dev, NULL); 1026 pci_set_drvdata(dev, NULL);
980 pci_release_regions(dev); 1027 pci_release_regions(dev);
981 pci_disable_device(dev); 1028 pci_disable_device(dev);
@@ -983,8 +1030,9 @@ static void jmb38x_ms_remove(struct pci_dev *dev)
983} 1030}
984 1031
985static struct pci_device_id jmb38x_ms_id_tbl [] = { 1032static struct pci_device_id jmb38x_ms_id_tbl [] = {
986 { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID, 1033 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS) },
987 PCI_ANY_ID, 0, 0, 0 }, 1034 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB385_MS) },
1035 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB390_MS) },
988 { } 1036 { }
989}; 1037};
990 1038