This source file includes following definitions.
- inReg
- outReg
- ali14xx_tune_drive
- findPort
- initRegisters
- init_ali14xx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #undef REALLY_SLOW_IO
29
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/delay.h>
33 #include <linux/timer.h>
34 #include <linux/mm.h>
35 #include <linux/ioport.h>
36 #include <linux/blkdev.h>
37 #include <linux/hdreg.h>
38 #include <asm/io.h>
39 #include "ide.h"
40 #include "ide_modes.h"
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #define ALI_14xx_BUS_SPEED 50
55
56
57 #define ALI_NUM_PORTS 4
58 static int ports[ALI_NUM_PORTS] = {0x074, 0x0f4, 0x034, 0x0e4};
59
60
61 typedef struct { byte reg, data; } RegInitializer;
62
63 static RegInitializer initData[] = {
64 {0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
65 {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
66 {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
67 {0x29, 0x00}, {0x2a, 0x00}, {0x2f, 0x00}, {0x2b, 0x00},
68 {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x30, 0x00},
69 {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0xff},
70 {0x35, 0x03}, {0x00, 0x00}
71 };
72
73
74 static struct { int time1, time2; } timeTab[4] = {
75 {600, 165},
76 {383, 125},
77 {240, 100},
78 {180, 80}
79 };
80
81
82 static struct { byte reg1, reg2, reg3, reg4; } regTab[4] = {
83 {0x03, 0x26, 0x04, 0x27},
84 {0x05, 0x28, 0x06, 0x29},
85 {0x2b, 0x30, 0x2c, 0x31},
86 {0x2d, 0x32, 0x2e, 0x33},
87 };
88
89 static int basePort = 0;
90 static int regPort = 0;
91 static int dataPort = 0;
92 static byte regOn;
93 static byte regOff;
94
95
96
97
98
99
100 static inline byte inReg (byte reg)
101 {
102 outb_p(reg, regPort);
103 return inb(dataPort);
104 }
105
106
107
108
109 static void outReg (byte data, byte reg)
110 {
111 outb_p(reg, regPort);
112 outb_p(data, dataPort);
113 }
114
115
116
117
118
119
120 static void ali14xx_tune_drive (ide_drive_t *drive, byte pio)
121 {
122 int driveNum;
123 int time1, time2, time1a;
124 byte param1, param2, param3, param4;
125 struct hd_driveid *id = drive->id;
126 unsigned long flags;
127
128 if (pio == 255)
129 pio = ide_get_best_pio_mode(drive);
130 if (pio > 3)
131 pio = 3;
132
133
134 time1 = timeTab[pio].time1;
135 time2 = timeTab[pio].time2;
136 if (pio == 3) {
137 time1a = (id->capability & 0x08) ? id->eide_pio_iordy : id->eide_pio;
138 if (time1a != 0 && time1a < time1)
139 time1 = time1a;
140 }
141 param3 = param1 = (time2 * ALI_14xx_BUS_SPEED + 999) / 1000;
142 param4 = param2 = (time1 * ALI_14xx_BUS_SPEED + 999) / 1000 - param1;
143 if (pio != 3) {
144 param3 += 8;
145 param4 += 8;
146 }
147 printk("%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
148 drive->name, pio, time1, time2, param1, param2, param3, param4);
149
150
151 driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
152 save_flags(flags);
153 cli();
154 outb_p(regOn, basePort);
155 outReg(param1, regTab[driveNum].reg1);
156 outReg(param2, regTab[driveNum].reg2);
157 outReg(param3, regTab[driveNum].reg3);
158 outReg(param4, regTab[driveNum].reg4);
159 outb_p(regOff, basePort);
160 restore_flags(flags);
161 }
162
163
164
165
166 static int findPort (void)
167 {
168 int i;
169 byte t;
170 unsigned long flags;
171
172 save_flags(flags);
173 cli();
174 for (i = 0; i < ALI_NUM_PORTS; ++i) {
175 basePort = ports[i];
176 regOff = inb(basePort);
177 for (regOn = 0x30; regOn <= 0x33; ++regOn) {
178 outb_p(regOn, basePort);
179 if (inb(basePort) == regOn) {
180 regPort = basePort + 4;
181 dataPort = basePort + 8;
182 t = inReg(0) & 0xf0;
183 outb_p(regOff, basePort);
184 restore_flags(flags);
185 if (t != 0x50)
186 return 0;
187 return 1;
188 }
189 }
190 outb_p(regOff, basePort);
191 }
192 restore_flags(flags);
193 return 0;
194 }
195
196
197
198
199 static int initRegisters (void) {
200 RegInitializer *p;
201 byte t;
202 unsigned long flags;
203
204 save_flags(flags);
205 cli();
206 outb_p(regOn, basePort);
207 for (p = initData; p->reg != 0; ++p)
208 outReg(p->data, p->reg);
209 outb_p(0x01, regPort);
210 t = inb(regPort) & 0x01;
211 outb_p(regOff, basePort);
212 restore_flags(flags);
213 return t;
214 }
215
216 void init_ali14xx (void)
217 {
218
219 if (!findPort()) {
220 printk("ali14xx: not found\n");
221 return;
222 }
223
224 printk("ali14xx: base= 0x%03x, regOn = 0x%02x\n", basePort, regOn);
225 ide_hwifs[0].chipset = ide_ali14xx;
226 ide_hwifs[1].chipset = ide_ali14xx;
227 ide_hwifs[0].tuneproc = &ali14xx_tune_drive;
228 ide_hwifs[1].tuneproc = &ali14xx_tune_drive;
229
230
231 if (!initRegisters()) {
232 printk("ali14xx: Chip initialization failed\n");
233 return;
234 }
235 }