preliminary 2.6.30 support
[openwrt/openwrt.git] / target / linux / ixp4xx / patches-2.6.30 / 312-ixp4xx_pata_optimization.patch
1 --- a/drivers/ata/pata_ixp4xx_cf.c
2 +++ b/drivers/ata/pata_ixp4xx_cf.c
3 @@ -24,18 +24,61 @@
4 #include <scsi/scsi_host.h>
5
6 #define DRV_NAME "pata_ixp4xx_cf"
7 -#define DRV_VERSION "0.2"
8 +#define DRV_VERSION "0.3"
9
10 static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
11 {
12 + struct ixp4xx_pata_data *data = link->ap->host->dev->platform_data;
13 + unsigned int pio_mask;
14 struct ata_device *dev;
15
16 - ata_for_each_dev(dev, link, ENABLED) {
17 - ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
18 - dev->pio_mode = XFER_PIO_0;
19 - dev->xfer_mode = XFER_PIO_0;
20 - dev->xfer_shift = ATA_SHIFT_PIO;
21 - dev->flags |= ATA_DFLAG_PIO;
22 + ata_link_for_each_dev(dev, link) {
23 + if (dev->id[ATA_ID_FIELD_VALID] & (1 << 1)) {
24 + pio_mask = dev->id[ATA_ID_PIO_MODES] & 0x03;
25 + if (pio_mask & (1 << 1)) {
26 + pio_mask = 4;
27 + } else {
28 + pio_mask = 3;
29 + }
30 + } else {
31 + pio_mask = (dev->id[ATA_ID_OLD_PIO_MODES] >> 8);
32 + }
33 + switch (pio_mask) {
34 + case 0:
35 + ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
36 + dev->pio_mode = XFER_PIO_0;
37 + dev->xfer_mode = XFER_PIO_0;
38 + *data->cs0_cfg = 0x8a473c03;
39 + break;
40 + case 1:
41 + ata_dev_printk(dev, KERN_INFO, "configured for PIO1\n");
42 + dev->pio_mode = XFER_PIO_1;
43 + dev->xfer_mode = XFER_PIO_1;
44 + *data->cs0_cfg = 0x86433c03;
45 + break;
46 + case 2:
47 + ata_dev_printk(dev, KERN_INFO, "configured for PIO2\n");
48 + dev->pio_mode = XFER_PIO_2;
49 + dev->xfer_mode = XFER_PIO_2;
50 + *data->cs0_cfg = 0x82413c03;
51 + break;
52 + case 3:
53 + ata_dev_printk(dev, KERN_INFO, "configured for PIO3\n");
54 + dev->pio_mode = XFER_PIO_3;
55 + dev->xfer_mode = XFER_PIO_3;
56 + *data->cs0_cfg = 0x80823c03;
57 + break;
58 + case 4:
59 + ata_dev_printk(dev, KERN_INFO, "configured for PIO4\n");
60 + dev->pio_mode = XFER_PIO_4;
61 + dev->xfer_mode = XFER_PIO_4;
62 + *data->cs0_cfg = 0x80403c03;
63 + break;
64 + }
65 + if (ata_dev_enabled(dev)) {
66 + dev->xfer_shift = ATA_SHIFT_PIO;
67 + dev->flags |= ATA_DFLAG_PIO;
68 + }
69 }
70 return 0;
71 }
72 @@ -46,6 +89,7 @@ static unsigned int ixp4xx_mmio_data_xfe
73 unsigned int i;
74 unsigned int words = buflen >> 1;
75 u16 *buf16 = (u16 *) buf;
76 + unsigned int pio_mask;
77 struct ata_port *ap = dev->link->ap;
78 void __iomem *mmio = ap->ioaddr.data_addr;
79 struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
80 @@ -53,8 +97,34 @@ static unsigned int ixp4xx_mmio_data_xfe
81 /* set the expansion bus in 16bit mode and restore
82 * 8 bit mode after the transaction.
83 */
84 - *data->cs0_cfg &= ~(0x01);
85 - udelay(100);
86 + if (dev->id[ATA_ID_FIELD_VALID] & (1 << 1)){
87 + pio_mask = dev->id[ATA_ID_PIO_MODES] & 0x03;
88 + if (pio_mask & (1 << 1)){
89 + pio_mask = 4;
90 + }else{
91 + pio_mask = 3;
92 + }
93 + }else{
94 + pio_mask = (dev->id[ATA_ID_OLD_PIO_MODES] >> 8);
95 + }
96 + switch (pio_mask){
97 + case 0:
98 + *data->cs0_cfg = 0xa9643c42;
99 + break;
100 + case 1:
101 + *data->cs0_cfg = 0x85033c42;
102 + break;
103 + case 2:
104 + *data->cs0_cfg = 0x80b23c42;
105 + break;
106 + case 3:
107 + *data->cs0_cfg = 0x80823c42;
108 + break;
109 + case 4:
110 + *data->cs0_cfg = 0x80403c42;
111 + break;
112 + }
113 + udelay(5);
114
115 /* Transfer multiple of 2 bytes */
116 if (rw == READ)
117 @@ -79,8 +149,24 @@ static unsigned int ixp4xx_mmio_data_xfe
118 words++;
119 }
120
121 - udelay(100);
122 - *data->cs0_cfg |= 0x01;
123 + udelay(5);
124 + switch (pio_mask){
125 + case 0:
126 + *data->cs0_cfg = 0x8a473c03;
127 + break;
128 + case 1:
129 + *data->cs0_cfg = 0x86433c03;
130 + break;
131 + case 2:
132 + *data->cs0_cfg = 0x82413c03;
133 + break;
134 + case 3:
135 + *data->cs0_cfg = 0x80823c03;
136 + break;
137 + case 4:
138 + *data->cs0_cfg = 0x80403c03;
139 + break;
140 + }
141
142 return words << 1;
143 }