diff options
Diffstat (limited to 'drivers/ide/alim15x3.c')
-rw-r--r-- | drivers/ide/alim15x3.c | 171 |
1 files changed, 92 insertions, 79 deletions
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 0abc43f3101e..2c8016ad0e26 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 2002 Alan Cox | 8 | * Copyright (C) 2002 Alan Cox |
9 | * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> | 9 | * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> |
10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> | 10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> |
11 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 11 | * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz |
12 | * | 12 | * |
13 | * (U)DMA capable version of ali 1533/1543(C), 1535(D) | 13 | * (U)DMA capable version of ali 1533/1543(C), 1535(D) |
14 | * | 14 | * |
@@ -48,61 +48,84 @@ static u8 m5229_revision; | |||
48 | static u8 chip_is_1543c_e; | 48 | static u8 chip_is_1543c_e; |
49 | static struct pci_dev *isa_dev; | 49 | static struct pci_dev *isa_dev; |
50 | 50 | ||
51 | static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on) | ||
52 | { | ||
53 | struct pci_dev *pdev = to_pci_dev(hwif->dev); | ||
54 | int pio_fifo = 0x54 + hwif->channel; | ||
55 | u8 fifo; | ||
56 | int shift = 4 * (drive->dn & 1); | ||
57 | |||
58 | pci_read_config_byte(pdev, pio_fifo, &fifo); | ||
59 | fifo &= ~(0x0F << shift); | ||
60 | fifo |= (on << shift); | ||
61 | pci_write_config_byte(pdev, pio_fifo, fifo); | ||
62 | } | ||
63 | |||
64 | static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive, | ||
65 | struct ide_timing *t, u8 ultra) | ||
66 | { | ||
67 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
68 | int port = hwif->channel ? 0x5c : 0x58; | ||
69 | int udmat = 0x56 + hwif->channel; | ||
70 | u8 unit = drive->dn & 1, udma; | ||
71 | int shift = 4 * unit; | ||
72 | |||
73 | /* Set up the UDMA */ | ||
74 | pci_read_config_byte(dev, udmat, &udma); | ||
75 | udma &= ~(0x0F << shift); | ||
76 | udma |= ultra << shift; | ||
77 | pci_write_config_byte(dev, udmat, udma); | ||
78 | |||
79 | if (t == NULL) | ||
80 | return; | ||
81 | |||
82 | t->setup = clamp_val(t->setup, 1, 8) & 7; | ||
83 | t->act8b = clamp_val(t->act8b, 1, 8) & 7; | ||
84 | t->rec8b = clamp_val(t->rec8b, 1, 16) & 15; | ||
85 | t->active = clamp_val(t->active, 1, 8) & 7; | ||
86 | t->recover = clamp_val(t->recover, 1, 16) & 15; | ||
87 | |||
88 | pci_write_config_byte(dev, port, t->setup); | ||
89 | pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b); | ||
90 | pci_write_config_byte(dev, port + unit + 2, | ||
91 | (t->active << 4) | t->recover); | ||
92 | } | ||
93 | |||
51 | /** | 94 | /** |
52 | * ali_set_pio_mode - set host controller for PIO mode | 95 | * ali_set_pio_mode - set host controller for PIO mode |
96 | * @hwif: port | ||
53 | * @drive: drive | 97 | * @drive: drive |
54 | * @pio: PIO mode number | ||
55 | * | 98 | * |
56 | * Program the controller for the given PIO mode. | 99 | * Program the controller for the given PIO mode. |
57 | */ | 100 | */ |
58 | 101 | ||
59 | static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) | 102 | static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
60 | { | 103 | { |
61 | ide_hwif_t *hwif = drive->hwif; | 104 | ide_drive_t *pair = ide_get_pair_dev(drive); |
62 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
63 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | ||
64 | int s_time = t->setup, a_time = t->active, c_time = t->cycle; | ||
65 | u8 s_clc, a_clc, r_clc; | ||
66 | unsigned long flags; | ||
67 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; | 105 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; |
68 | int port = hwif->channel ? 0x5c : 0x58; | 106 | unsigned long T = 1000000 / bus_speed; /* PCI clock based */ |
69 | int portFIFO = hwif->channel ? 0x55 : 0x54; | 107 | struct ide_timing t; |
70 | u8 cd_dma_fifo = 0, unit = drive->dn & 1; | 108 | |
71 | 109 | ide_timing_compute(drive, drive->pio_mode, &t, T, 1); | |
72 | if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) | 110 | if (pair) { |
73 | s_clc = 0; | 111 | struct ide_timing p; |
74 | if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8) | 112 | |
75 | a_clc = 0; | 113 | ide_timing_compute(pair, pair->pio_mode, &p, T, 1); |
76 | 114 | ide_timing_merge(&p, &t, &t, | |
77 | if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { | 115 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); |
78 | r_clc = 1; | 116 | if (pair->dma_mode) { |
79 | } else { | 117 | ide_timing_compute(pair, pair->dma_mode, &p, T, 1); |
80 | if (r_clc >= 16) | 118 | ide_timing_merge(&p, &t, &t, |
81 | r_clc = 0; | 119 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); |
120 | } | ||
82 | } | 121 | } |
83 | local_irq_save(flags); | 122 | |
84 | |||
85 | /* | 123 | /* |
86 | * PIO mode => ATA FIFO on, ATAPI FIFO off | 124 | * PIO mode => ATA FIFO on, ATAPI FIFO off |
87 | */ | 125 | */ |
88 | pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); | 126 | ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00); |
89 | if (drive->media==ide_disk) { | 127 | |
90 | if (unit) { | 128 | ali_program_timings(hwif, drive, &t, 0); |
91 | pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); | ||
92 | } else { | ||
93 | pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); | ||
94 | } | ||
95 | } else { | ||
96 | if (unit) { | ||
97 | pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); | ||
98 | } else { | ||
99 | pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | pci_write_config_byte(dev, port, s_clc); | ||
104 | pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); | ||
105 | local_irq_restore(flags); | ||
106 | } | 129 | } |
107 | 130 | ||
108 | /** | 131 | /** |
@@ -132,44 +155,42 @@ static u8 ali_udma_filter(ide_drive_t *drive) | |||
132 | 155 | ||
133 | /** | 156 | /** |
134 | * ali_set_dma_mode - set host controller for DMA mode | 157 | * ali_set_dma_mode - set host controller for DMA mode |
158 | * @hwif: port | ||
135 | * @drive: drive | 159 | * @drive: drive |
136 | * @speed: DMA mode | ||
137 | * | 160 | * |
138 | * Configure the hardware for the desired IDE transfer mode. | 161 | * Configure the hardware for the desired IDE transfer mode. |
139 | */ | 162 | */ |
140 | 163 | ||
141 | static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) | 164 | static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) |
142 | { | 165 | { |
143 | ide_hwif_t *hwif = drive->hwif; | 166 | static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD }; |
144 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 167 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
145 | u8 speed1 = speed; | 168 | ide_drive_t *pair = ide_get_pair_dev(drive); |
146 | u8 unit = drive->dn & 1; | 169 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; |
170 | unsigned long T = 1000000 / bus_speed; /* PCI clock based */ | ||
171 | const u8 speed = drive->dma_mode; | ||
147 | u8 tmpbyte = 0x00; | 172 | u8 tmpbyte = 0x00; |
148 | int m5229_udma = (hwif->channel) ? 0x57 : 0x56; | 173 | struct ide_timing t; |
149 | |||
150 | if (speed == XFER_UDMA_6) | ||
151 | speed1 = 0x47; | ||
152 | 174 | ||
153 | if (speed < XFER_UDMA_0) { | 175 | if (speed < XFER_UDMA_0) { |
154 | u8 ultra_enable = (unit) ? 0x7f : 0xf7; | 176 | ide_timing_compute(drive, drive->dma_mode, &t, T, 1); |
155 | /* | 177 | if (pair) { |
156 | * clear "ultra enable" bit | 178 | struct ide_timing p; |
157 | */ | 179 | |
158 | pci_read_config_byte(dev, m5229_udma, &tmpbyte); | 180 | ide_timing_compute(pair, pair->pio_mode, &p, T, 1); |
159 | tmpbyte &= ultra_enable; | 181 | ide_timing_merge(&p, &t, &t, |
160 | pci_write_config_byte(dev, m5229_udma, tmpbyte); | 182 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); |
161 | 183 | if (pair->dma_mode) { | |
162 | /* | 184 | ide_timing_compute(pair, pair->dma_mode, |
163 | * FIXME: Oh, my... DMA timings are never set. | 185 | &p, T, 1); |
164 | */ | 186 | ide_timing_merge(&p, &t, &t, |
187 | IDE_TIMING_SETUP | IDE_TIMING_8BIT); | ||
188 | } | ||
189 | } | ||
190 | ali_program_timings(hwif, drive, &t, 0); | ||
165 | } else { | 191 | } else { |
166 | pci_read_config_byte(dev, m5229_udma, &tmpbyte); | 192 | ali_program_timings(hwif, drive, NULL, |
167 | tmpbyte &= (0x0f << ((1-unit) << 2)); | 193 | udma_timing[speed - XFER_UDMA_0]); |
168 | /* | ||
169 | * enable ultra dma and set timing | ||
170 | */ | ||
171 | tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2)); | ||
172 | pci_write_config_byte(dev, m5229_udma, tmpbyte); | ||
173 | if (speed >= XFER_UDMA_3) { | 194 | if (speed >= XFER_UDMA_3) { |
174 | pci_read_config_byte(dev, 0x4b, &tmpbyte); | 195 | pci_read_config_byte(dev, 0x4b, &tmpbyte); |
175 | tmpbyte |= 1; | 196 | tmpbyte |= 1; |
@@ -355,19 +376,13 @@ static int ali_cable_override(struct pci_dev *pdev) | |||
355 | * | 376 | * |
356 | * This checks if the controller and the cable are capable | 377 | * This checks if the controller and the cable are capable |
357 | * of UDMA66 transfers. It doesn't check the drives. | 378 | * of UDMA66 transfers. It doesn't check the drives. |
358 | * But see note 2 below! | ||
359 | * | ||
360 | * FIXME: frobs bits that are not defined on newer ALi devicea | ||
361 | */ | 379 | */ |
362 | 380 | ||
363 | static u8 ali_cable_detect(ide_hwif_t *hwif) | 381 | static u8 ali_cable_detect(ide_hwif_t *hwif) |
364 | { | 382 | { |
365 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 383 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
366 | unsigned long flags; | ||
367 | u8 cbl = ATA_CBL_PATA40, tmpbyte; | 384 | u8 cbl = ATA_CBL_PATA40, tmpbyte; |
368 | 385 | ||
369 | local_irq_save(flags); | ||
370 | |||
371 | if (m5229_revision >= 0xC2) { | 386 | if (m5229_revision >= 0xC2) { |
372 | /* | 387 | /* |
373 | * m5229 80-pin cable detection (from Host View) | 388 | * m5229 80-pin cable detection (from Host View) |
@@ -387,8 +402,6 @@ static u8 ali_cable_detect(ide_hwif_t *hwif) | |||
387 | } | 402 | } |
388 | } | 403 | } |
389 | 404 | ||
390 | local_irq_restore(flags); | ||
391 | |||
392 | return cbl; | 405 | return cbl; |
393 | } | 406 | } |
394 | 407 | ||
@@ -584,6 +597,6 @@ static void __exit ali15x3_ide_exit(void) | |||
584 | module_init(ali15x3_ide_init); | 597 | module_init(ali15x3_ide_init); |
585 | module_exit(ali15x3_ide_exit); | 598 | module_exit(ali15x3_ide_exit); |
586 | 599 | ||
587 | MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox"); | 600 | MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz"); |
588 | MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE"); | 601 | MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE"); |
589 | MODULE_LICENSE("GPL"); | 602 | MODULE_LICENSE("GPL"); |