312-ixp4xx_pata_optimization.patch 3.4 KB

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