diff options
Diffstat (limited to 'target/linux/ixp4xx/patches-2.6.38/312-ixp4xx_pata_optimization.patch')
-rw-r--r-- | target/linux/ixp4xx/patches-2.6.38/312-ixp4xx_pata_optimization.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/target/linux/ixp4xx/patches-2.6.38/312-ixp4xx_pata_optimization.patch b/target/linux/ixp4xx/patches-2.6.38/312-ixp4xx_pata_optimization.patch new file mode 100644 index 0000000..3bf1b74 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.38/312-ixp4xx_pata_optimization.patch @@ -0,0 +1,137 @@ +--- a/drivers/ata/pata_ixp4xx_cf.c ++++ b/drivers/ata/pata_ixp4xx_cf.c +@@ -24,16 +24,58 @@ + #include <scsi/scsi_host.h> + + #define DRV_NAME "pata_ixp4xx_cf" +-#define DRV_VERSION "0.2" ++#define DRV_VERSION "0.3" + + static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error) + { + struct ata_device *dev; ++ struct ixp4xx_pata_data *data = link->ap->host->dev->platform_data; ++ unsigned int pio_mask; + + ata_for_each_dev(dev, link, ENABLED) { +- ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); +- dev->pio_mode = XFER_PIO_0; +- dev->xfer_mode = XFER_PIO_0; ++ if (dev->id[ATA_ID_FIELD_VALID] & (1 << 1)) { ++ pio_mask = dev->id[ATA_ID_PIO_MODES] & 0x03; ++ if (pio_mask & (1 << 1)) { ++ pio_mask = 4; ++ } else { ++ pio_mask = 3; ++ } ++ } else { ++ pio_mask = (dev->id[ATA_ID_OLD_PIO_MODES] >> 8); ++ } ++ ++ switch (pio_mask){ ++ case 0: ++ ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); ++ dev->pio_mode = XFER_PIO_0; ++ dev->xfer_mode = XFER_PIO_0; ++ *data->cs0_cfg = 0x8a473c03; ++ break; ++ case 1: ++ ata_dev_printk(dev, KERN_INFO, "configured for PIO1\n"); ++ dev->pio_mode = XFER_PIO_1; ++ dev->xfer_mode = XFER_PIO_1; ++ *data->cs0_cfg = 0x86433c03; ++ break; ++ case 2: ++ ata_dev_printk(dev, KERN_INFO, "configured for PIO2\n"); ++ dev->pio_mode = XFER_PIO_2; ++ dev->xfer_mode = XFER_PIO_2; ++ *data->cs0_cfg = 0x82413c03; ++ break; ++ case 3: ++ ata_dev_printk(dev, KERN_INFO, "configured for PIO3\n"); ++ dev->pio_mode = XFER_PIO_3; ++ dev->xfer_mode = XFER_PIO_3; ++ *data->cs0_cfg = 0x80823c03; ++ break; ++ case 4: ++ ata_dev_printk(dev, KERN_INFO, "configured for PIO4\n"); ++ dev->pio_mode = XFER_PIO_4; ++ dev->xfer_mode = XFER_PIO_4; ++ *data->cs0_cfg = 0x80403c03; ++ break; ++ } + dev->xfer_shift = ATA_SHIFT_PIO; + dev->flags |= ATA_DFLAG_PIO; + } +@@ -46,6 +88,7 @@ static unsigned int ixp4xx_mmio_data_xfe + unsigned int i; + unsigned int words = buflen >> 1; + u16 *buf16 = (u16 *) buf; ++ unsigned int pio_mask; + struct ata_port *ap = dev->link->ap; + void __iomem *mmio = ap->ioaddr.data_addr; + struct ixp4xx_pata_data *data = ap->host->dev->platform_data; +@@ -53,8 +96,34 @@ static unsigned int ixp4xx_mmio_data_xfe + /* set the expansion bus in 16bit mode and restore + * 8 bit mode after the transaction. + */ +- *data->cs0_cfg &= ~(0x01); +- udelay(100); ++ if (dev->id[ATA_ID_FIELD_VALID] & (1 << 1)){ ++ pio_mask = dev->id[ATA_ID_PIO_MODES] & 0x03; ++ if (pio_mask & (1 << 1)){ ++ pio_mask = 4; ++ }else{ ++ pio_mask = 3; ++ } ++ }else{ ++ pio_mask = (dev->id[ATA_ID_OLD_PIO_MODES] >> 8); ++ } ++ switch (pio_mask){ ++ case 0: ++ *data->cs0_cfg = 0xa9643c42; ++ break; ++ case 1: ++ *data->cs0_cfg = 0x85033c42; ++ break; ++ case 2: ++ *data->cs0_cfg = 0x80b23c42; ++ break; ++ case 3: ++ *data->cs0_cfg = 0x80823c42; ++ break; ++ case 4: ++ *data->cs0_cfg = 0x80403c42; ++ break; ++ } ++ udelay(5); + + /* Transfer multiple of 2 bytes */ + if (rw == READ) +@@ -79,8 +148,24 @@ static unsigned int ixp4xx_mmio_data_xfe + words++; + } + +- udelay(100); +- *data->cs0_cfg |= 0x01; ++ udelay(5); ++ switch (pio_mask){ ++ case 0: ++ *data->cs0_cfg = 0x8a473c03; ++ break; ++ case 1: ++ *data->cs0_cfg = 0x86433c03; ++ break; ++ case 2: ++ *data->cs0_cfg = 0x82413c03; ++ break; ++ case 3: ++ *data->cs0_cfg = 0x80823c03; ++ break; ++ case 4: ++ *data->cs0_cfg = 0x80403c03; ++ break; ++ } + + return words << 1; + } |