aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/host
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2008-09-13 05:33:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-09-13 17:41:52 -0400
commit8e82f8c34b1759ae0d80fe96101746ec51fb1ba4 (patch)
tree376e4c63b96c214bc50290742996b0b9b4b01e10 /drivers/memstick/host
parent8d99f83b9478768d3a8d7d1bcd9bd182c75a0447 (diff)
memstick: fix MSProHG 8-bit interface mode support
- 8-bit interface mode never worked properly. The only adapter I have which supports the 8b mode (the Jmicron) had some problems with its clock wiring and they discovered it only now. We also discovered that ProHG media is more sensitive to the ordering of initialization commands. - Make the driver fall back to highest supported mode instead of always falling back to serial. The driver will attempt the switch to 8b mode for any new MSPro card, but not all of them support it. Previously, these new cards ended up in serial mode, which is not the best idea (they work fine with 4b, after all). - Edit some macros for better conformance to Sony documentation Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/memstick/host')
-rw-r--r--drivers/memstick/host/jmb38x_ms.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 3485c63d20b0..2fb95a5b72eb 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -81,6 +81,8 @@ struct jmb38x_ms {
81#define TPC_CODE_SZ_MASK 0x00000700 81#define TPC_CODE_SZ_MASK 0x00000700
82#define TPC_DATA_SZ_MASK 0x00000007 82#define TPC_DATA_SZ_MASK 0x00000007
83 83
84#define HOST_CONTROL_TDELAY_EN 0x00040000
85#define HOST_CONTROL_HW_OC_P 0x00010000
84#define HOST_CONTROL_RESET_REQ 0x00008000 86#define HOST_CONTROL_RESET_REQ 0x00008000
85#define HOST_CONTROL_REI 0x00004000 87#define HOST_CONTROL_REI 0x00004000
86#define HOST_CONTROL_LED 0x00000400 88#define HOST_CONTROL_LED 0x00000400
@@ -88,6 +90,7 @@ struct jmb38x_ms {
88#define HOST_CONTROL_RESET 0x00000100 90#define HOST_CONTROL_RESET 0x00000100
89#define HOST_CONTROL_POWER_EN 0x00000080 91#define HOST_CONTROL_POWER_EN 0x00000080
90#define HOST_CONTROL_CLOCK_EN 0x00000040 92#define HOST_CONTROL_CLOCK_EN 0x00000040
93#define HOST_CONTROL_REO 0x00000008
91#define HOST_CONTROL_IF_SHIFT 4 94#define HOST_CONTROL_IF_SHIFT 4
92 95
93#define HOST_CONTROL_IF_SERIAL 0x0 96#define HOST_CONTROL_IF_SERIAL 0x0
@@ -133,11 +136,15 @@ struct jmb38x_ms {
133#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 136#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
134 137
135#define CLOCK_CONTROL_40MHZ 0x00000001 138#define CLOCK_CONTROL_40MHZ 0x00000001
136#define CLOCK_CONTROL_50MHZ 0x00000002 139#define CLOCK_CONTROL_50MHZ 0x0000000a
137#define CLOCK_CONTROL_60MHZ 0x00000008 140#define CLOCK_CONTROL_60MHZ 0x00000008
138#define CLOCK_CONTROL_62_5MHZ 0x0000000c 141#define CLOCK_CONTROL_62_5MHZ 0x0000000c
139#define CLOCK_CONTROL_OFF 0x00000000 142#define CLOCK_CONTROL_OFF 0x00000000
140 143
144#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0
145#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
146#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
147
141enum { 148enum {
142 CMD_READY = 0x01, 149 CMD_READY = 0x01,
143 FIFO_READY = 0x02, 150 FIFO_READY = 0x02,
@@ -367,8 +374,7 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
367 return host->req->error; 374 return host->req->error;
368 } 375 }
369 376
370 dev_dbg(&msh->dev, "control %08x\n", 377 dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
371 readl(host->addr + HOST_CONTROL));
372 dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS)); 378 dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
373 dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS)); 379 dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
374 380
@@ -637,7 +643,7 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
637 ndelay(20); 643 ndelay(20);
638 } 644 }
639 dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); 645 dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
640 return -EIO; 646 /* return -EIO; */
641 647
642reset_next: 648reset_next:
643 writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN 649 writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -680,7 +686,9 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
680 686
681 host_ctl = 7; 687 host_ctl = 7;
682 host_ctl |= HOST_CONTROL_POWER_EN 688 host_ctl |= HOST_CONTROL_POWER_EN
683 | HOST_CONTROL_CLOCK_EN; 689 | HOST_CONTROL_CLOCK_EN
690 | HOST_CONTROL_HW_OC_P
691 | HOST_CONTROL_TDELAY_EN;
684 writel(host_ctl, host->addr + HOST_CONTROL); 692 writel(host_ctl, host->addr + HOST_CONTROL);
685 693
686 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 694 writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -704,33 +712,40 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
704 break; 712 break;
705 case MEMSTICK_INTERFACE: 713 case MEMSTICK_INTERFACE:
706 host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); 714 host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
715 pci_read_config_dword(host->chip->pdev,
716 PCI_CTL_CLOCK_DLY_ADDR,
717 &clock_delay);
718 clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
719 : ~PCI_CTL_CLOCK_DLY_MASK_A;
707 720
708 if (value == MEMSTICK_SERIAL) { 721 if (value == MEMSTICK_SERIAL) {
709 host_ctl &= ~HOST_CONTROL_FAST_CLK; 722 host_ctl &= ~HOST_CONTROL_FAST_CLK;
723 host_ctl &= ~HOST_CONTROL_REO;
710 host_ctl |= HOST_CONTROL_IF_SERIAL 724 host_ctl |= HOST_CONTROL_IF_SERIAL
711 << HOST_CONTROL_IF_SHIFT; 725 << HOST_CONTROL_IF_SHIFT;
712 host_ctl |= HOST_CONTROL_REI; 726 host_ctl |= HOST_CONTROL_REI;
713 clock_ctl = CLOCK_CONTROL_40MHZ; 727 clock_ctl = CLOCK_CONTROL_40MHZ;
714 clock_delay = 0;
715 } else if (value == MEMSTICK_PAR4) { 728 } else if (value == MEMSTICK_PAR4) {
716 host_ctl |= HOST_CONTROL_FAST_CLK; 729 host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO;
717 host_ctl |= HOST_CONTROL_IF_PAR4 730 host_ctl |= HOST_CONTROL_IF_PAR4
718 << HOST_CONTROL_IF_SHIFT; 731 << HOST_CONTROL_IF_SHIFT;
719 host_ctl &= ~HOST_CONTROL_REI; 732 host_ctl &= ~HOST_CONTROL_REI;
720 clock_ctl = CLOCK_CONTROL_40MHZ; 733 clock_ctl = CLOCK_CONTROL_40MHZ;
721 clock_delay = 4; 734 clock_delay |= host->id ? (4 << 12) : (4 << 8);
722 } else if (value == MEMSTICK_PAR8) { 735 } else if (value == MEMSTICK_PAR8) {
723 host_ctl |= HOST_CONTROL_FAST_CLK; 736 host_ctl |= HOST_CONTROL_FAST_CLK;
724 host_ctl |= HOST_CONTROL_IF_PAR8 737 host_ctl |= HOST_CONTROL_IF_PAR8
725 << HOST_CONTROL_IF_SHIFT; 738 << HOST_CONTROL_IF_SHIFT;
726 host_ctl &= ~HOST_CONTROL_REI; 739 host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO);
727 clock_ctl = CLOCK_CONTROL_60MHZ; 740 clock_ctl = CLOCK_CONTROL_50MHZ;
728 clock_delay = 0;
729 } else 741 } else
730 return -EINVAL; 742 return -EINVAL;
743
731 writel(host_ctl, host->addr + HOST_CONTROL); 744 writel(host_ctl, host->addr + HOST_CONTROL);
732 writel(clock_ctl, host->addr + CLOCK_CONTROL); 745 writel(clock_ctl, host->addr + CLOCK_CONTROL);
733 writel(clock_delay, host->addr + CLOCK_DELAY); 746 pci_write_config_dword(host->chip->pdev,
747 PCI_CTL_CLOCK_DLY_ADDR,
748 clock_delay);
734 break; 749 break;
735 }; 750 };
736 return 0; 751 return 0;