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