]>
Commit | Line | Data |
---|---|---|
f1352651 | 1 | /* |
fa82f871 | 2 | * Copyright (C) Excito Elektronik i Skåne AB, All rights reserved. |
f1352651 TK |
3 | * Author: Tor Krill <[email protected]> |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
f1352651 TK |
6 | * |
7 | * This is a driver for Silicon Image sil3114 sata chip modelled on | |
8 | * the ata_piix driver | |
9 | */ | |
10 | ||
11 | #include <common.h> | |
12 | #include <pci.h> | |
13 | #include <command.h> | |
14 | #include <config.h> | |
15 | #include <asm/byteorder.h> | |
16 | #include <asm/io.h> | |
17 | #include <ide.h> | |
e46a4350 | 18 | #include <sata.h> |
f1352651 TK |
19 | #include <libata.h> |
20 | #include "sata_sil3114.h" | |
21 | ||
22 | /* Convert sectorsize to wordsize */ | |
23 | #define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2) | |
24 | ||
25 | /* Forwards */ | |
26 | u8 sil3114_spin_up (int num); | |
27 | u8 sil3114_spin_down (int num); | |
28 | static int sata_bus_softreset (int num); | |
29 | static void sata_identify (int num, int dev); | |
30 | static u8 check_power_mode (int num); | |
31 | static void sata_port (struct sata_ioports *ioport); | |
32 | static void set_Feature_cmd (int num, int dev); | |
33 | static u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits, | |
34 | unsigned int max, u8 usealtstatus); | |
35 | static u8 sata_chk_status (struct sata_ioports *ioaddr, u8 usealtstatus); | |
36 | static void msleep (int count); | |
37 | ||
38 | static u32 iobase[6] = { 0, 0, 0, 0, 0, 0}; /* PCI BAR registers for device */ | |
f1352651 | 39 | |
6d0f6bcf | 40 | static struct sata_port port[CONFIG_SYS_SATA_MAX_DEVICE]; |
f1352651 TK |
41 | |
42 | static void output_data (struct sata_ioports *ioaddr, u16 * sect_buf, int words) | |
43 | { | |
44 | while (words--) { | |
45 | __raw_writew (*sect_buf++, (void *)ioaddr->data_addr); | |
46 | } | |
47 | } | |
48 | ||
49 | static int input_data (struct sata_ioports *ioaddr, u16 * sect_buf, int words) | |
50 | { | |
51 | while (words--) { | |
52 | *sect_buf++ = __raw_readw ((void *)ioaddr->data_addr); | |
53 | } | |
54 | return 0; | |
55 | } | |
56 | ||
57 | static int sata_bus_softreset (int num) | |
58 | { | |
59 | u8 status = 0; | |
60 | ||
61 | port[num].dev_mask = 1; | |
62 | ||
63 | port[num].ctl_reg = 0x08; /*Default value of control reg */ | |
64 | writeb (port[num].ctl_reg, port[num].ioaddr.ctl_addr); | |
65 | udelay (10); | |
66 | writeb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr); | |
67 | udelay (10); | |
68 | writeb (port[num].ctl_reg, port[num].ioaddr.ctl_addr); | |
69 | ||
70 | /* spec mandates ">= 2ms" before checking status. | |
71 | * We wait 150ms, because that was the magic delay used for | |
72 | * ATAPI devices in Hale Landis's ATADRVR, for the period of time | |
73 | * between when the ATA command register is written, and then | |
74 | * status is checked. Because waiting for "a while" before | |
75 | * checking status is fine, post SRST, we perform this magic | |
76 | * delay here as well. | |
77 | */ | |
78 | msleep (150); | |
79 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300, 0); | |
80 | while ((status & ATA_BUSY)) { | |
81 | msleep (100); | |
82 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3, 0); | |
83 | } | |
84 | ||
85 | if (status & ATA_BUSY) { | |
369d0aa9 | 86 | printf ("ata%u is slow to respond,plz be patient\n", num); |
f1352651 TK |
87 | } |
88 | ||
89 | while ((status & ATA_BUSY)) { | |
90 | msleep (100); | |
91 | status = sata_chk_status (&port[num].ioaddr, 0); | |
92 | } | |
93 | ||
94 | if (status & ATA_BUSY) { | |
369d0aa9 | 95 | printf ("ata%u failed to respond : ", num); |
f1352651 TK |
96 | printf ("bus reset failed\n"); |
97 | port[num].dev_mask = 0; | |
98 | return 1; | |
99 | } | |
100 | return 0; | |
101 | } | |
102 | ||
103 | static void sata_identify (int num, int dev) | |
104 | { | |
105 | u8 cmd = 0, status = 0, devno = num; | |
106 | u16 iobuf[ATA_SECTOR_WORDS]; | |
107 | u64 n_sectors = 0; | |
108 | ||
109 | memset (iobuf, 0, sizeof (iobuf)); | |
110 | ||
111 | if (!(port[num].dev_mask & 0x01)) { | |
112 | printf ("dev%d is not present on port#%d\n", dev, num); | |
113 | return; | |
114 | } | |
115 | ||
116 | debug ("port=%d dev=%d\n", num, dev); | |
117 | ||
118 | status = 0; | |
119 | cmd = ATA_CMD_ID_ATA; /*Device Identify Command */ | |
120 | writeb (cmd, port[num].ioaddr.command_addr); | |
121 | readb (port[num].ioaddr.altstatus_addr); | |
122 | udelay (10); | |
123 | ||
124 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000, 0); | |
125 | if (status & ATA_ERR) { | |
126 | printf ("\ndevice not responding\n"); | |
127 | port[num].dev_mask &= ~0x01; | |
128 | return; | |
129 | } | |
130 | ||
131 | input_data (&port[num].ioaddr, iobuf, ATA_SECTOR_WORDS); | |
132 | ||
133 | ata_swap_buf_le16 (iobuf, ATA_SECTOR_WORDS); | |
134 | ||
135 | debug ("Specific config: %x\n", iobuf[2]); | |
136 | ||
137 | /* we require LBA and DMA support (bits 8 & 9 of word 49) */ | |
138 | if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) { | |
139 | debug ("ata%u: no dma/lba\n", num); | |
140 | } | |
141 | #ifdef DEBUG | |
142 | ata_dump_id (iobuf); | |
143 | #endif | |
144 | n_sectors = ata_id_n_sectors (iobuf); | |
145 | ||
146 | if (n_sectors == 0) { | |
147 | port[num].dev_mask &= ~0x01; | |
148 | return; | |
149 | } | |
150 | ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].revision, | |
151 | ATA_ID_FW_REV, sizeof (sata_dev_desc[devno].revision)); | |
152 | ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].vendor, | |
153 | ATA_ID_PROD, sizeof (sata_dev_desc[devno].vendor)); | |
154 | ata_id_c_string (iobuf, (unsigned char *)sata_dev_desc[devno].product, | |
155 | ATA_ID_SERNO, sizeof (sata_dev_desc[devno].product)); | |
156 | ||
157 | /* TODO - atm we asume harddisk ie not removable */ | |
158 | sata_dev_desc[devno].removable = 0; | |
159 | ||
160 | sata_dev_desc[devno].lba = (u32) n_sectors; | |
5779a9e2 | 161 | debug("lba=0x%lx\n", sata_dev_desc[devno].lba); |
f1352651 TK |
162 | |
163 | #ifdef CONFIG_LBA48 | |
164 | if (iobuf[83] & (1 << 10)) { | |
165 | sata_dev_desc[devno].lba48 = 1; | |
166 | } else { | |
167 | sata_dev_desc[devno].lba48 = 0; | |
168 | } | |
169 | #endif | |
170 | ||
171 | /* assuming HD */ | |
172 | sata_dev_desc[devno].type = DEV_TYPE_HARDDISK; | |
173 | sata_dev_desc[devno].blksz = ATA_SECT_SIZE; | |
174 | sata_dev_desc[devno].lun = 0; /* just to fill something in... */ | |
175 | } | |
176 | ||
177 | static void set_Feature_cmd (int num, int dev) | |
178 | { | |
179 | u8 status = 0; | |
180 | ||
181 | if (!(port[num].dev_mask & 0x01)) { | |
182 | debug ("dev%d is not present on port#%d\n", dev, num); | |
183 | return; | |
184 | } | |
185 | ||
186 | writeb (SETFEATURES_XFER, port[num].ioaddr.feature_addr); | |
187 | writeb (XFER_PIO_4, port[num].ioaddr.nsect_addr); | |
188 | writeb (0, port[num].ioaddr.lbal_addr); | |
189 | writeb (0, port[num].ioaddr.lbam_addr); | |
190 | writeb (0, port[num].ioaddr.lbah_addr); | |
191 | ||
192 | writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr); | |
193 | writeb (ATA_CMD_SET_FEATURES, port[num].ioaddr.command_addr); | |
194 | ||
195 | udelay (50); | |
196 | msleep (150); | |
197 | ||
198 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000, 0); | |
199 | if ((status & (ATA_BUSY | ATA_ERR))) { | |
200 | printf ("Error : status 0x%02x\n", status); | |
201 | port[num].dev_mask &= ~0x01; | |
202 | } | |
203 | } | |
204 | ||
205 | u8 sil3114_spin_down (int num) | |
206 | { | |
207 | u8 status = 0; | |
208 | ||
209 | debug ("Spin down disk\n"); | |
210 | ||
211 | if (!(port[num].dev_mask & 0x01)) { | |
212 | debug ("Device ata%d is not present\n", num); | |
213 | return 1; | |
214 | } | |
215 | ||
216 | if ((status = check_power_mode (num)) == 0x00) { | |
217 | debug ("Already in standby\n"); | |
218 | return 0; | |
219 | } | |
220 | ||
221 | if (status == 0x01) { | |
222 | printf ("Failed to check power mode on ata%d\n", num); | |
223 | return 1; | |
224 | } | |
225 | ||
226 | if (!((status = sata_chk_status (&port[num].ioaddr, 0)) & ATA_DRDY)) { | |
227 | printf ("Device ata%d not ready\n", num); | |
228 | return 1; | |
229 | } | |
230 | ||
231 | writeb (0x00, port[num].ioaddr.feature_addr); | |
232 | ||
233 | writeb (0x00, port[num].ioaddr.nsect_addr); | |
234 | writeb (0x00, port[num].ioaddr.lbal_addr); | |
235 | writeb (0x00, port[num].ioaddr.lbam_addr); | |
236 | writeb (0x00, port[num].ioaddr.lbah_addr); | |
237 | ||
238 | writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr); | |
239 | writeb (ATA_CMD_STANDBY, port[num].ioaddr.command_addr); | |
240 | ||
241 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 30000, 0); | |
242 | if ((status & (ATA_BUSY | ATA_ERR))) { | |
243 | printf ("Error waiting for disk spin down: status 0x%02x\n", | |
244 | status); | |
245 | port[num].dev_mask &= ~0x01; | |
246 | return 1; | |
247 | } | |
248 | return 0; | |
249 | } | |
250 | ||
251 | u8 sil3114_spin_up (int num) | |
252 | { | |
253 | u8 status = 0; | |
254 | ||
255 | debug ("Spin up disk\n"); | |
256 | ||
257 | if (!(port[num].dev_mask & 0x01)) { | |
258 | debug ("Device ata%d is not present\n", num); | |
259 | return 1; | |
260 | } | |
261 | ||
262 | if ((status = check_power_mode (num)) != 0x00) { | |
263 | if (status == 0x01) { | |
264 | printf ("Failed to check power mode on ata%d\n", num); | |
265 | return 1; | |
266 | } else { | |
267 | /* should be up and running already */ | |
268 | return 0; | |
269 | } | |
270 | } | |
271 | ||
272 | if (!((status = sata_chk_status (&port[num].ioaddr, 0)) & ATA_DRDY)) { | |
273 | printf ("Device ata%d not ready\n", num); | |
274 | return 1; | |
275 | } | |
276 | ||
277 | debug ("Stautus of device check: %d\n", status); | |
278 | ||
279 | writeb (0x00, port[num].ioaddr.feature_addr); | |
280 | ||
281 | writeb (0x00, port[num].ioaddr.nsect_addr); | |
282 | writeb (0x00, port[num].ioaddr.lbal_addr); | |
283 | writeb (0x00, port[num].ioaddr.lbam_addr); | |
284 | writeb (0x00, port[num].ioaddr.lbah_addr); | |
285 | ||
286 | writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr); | |
287 | writeb (ATA_CMD_IDLE, port[num].ioaddr.command_addr); | |
288 | ||
289 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 30000, 0); | |
290 | if ((status & (ATA_BUSY | ATA_ERR))) { | |
291 | printf ("Error waiting for disk spin up: status 0x%02x\n", | |
292 | status); | |
293 | port[num].dev_mask &= ~0x01; | |
294 | return 1; | |
295 | } | |
296 | ||
297 | /* Wait for disk to enter Active state */ | |
298 | do { | |
299 | msleep (10); | |
300 | status = check_power_mode (num); | |
301 | } while ((status == 0x00) || (status == 0x80)); | |
302 | ||
303 | if (status == 0x01) { | |
304 | printf ("Falied waiting for disk to spin up\n"); | |
305 | return 1; | |
306 | } | |
307 | ||
308 | return 0; | |
309 | } | |
310 | ||
311 | /* Return value is not the usual here | |
312 | * 0x00 - Device stand by | |
313 | * 0x01 - Operation failed | |
314 | * 0x80 - Device idle | |
315 | * 0xff - Device active | |
316 | */ | |
317 | static u8 check_power_mode (int num) | |
318 | { | |
319 | u8 status = 0; | |
320 | u8 res = 0; | |
321 | if (!(port[num].dev_mask & 0x01)) { | |
322 | debug ("Device ata%d is not present\n", num); | |
323 | return 1; | |
324 | } | |
325 | ||
326 | if (!(sata_chk_status (&port[num].ioaddr, 0) & ATA_DRDY)) { | |
327 | printf ("Device ata%d not ready\n", num); | |
328 | return 1; | |
329 | } | |
330 | ||
331 | writeb (0, port[num].ioaddr.feature_addr); | |
332 | writeb (0, port[num].ioaddr.nsect_addr); | |
333 | writeb (0, port[num].ioaddr.lbal_addr); | |
334 | writeb (0, port[num].ioaddr.lbam_addr); | |
335 | writeb (0, port[num].ioaddr.lbah_addr); | |
336 | ||
337 | writeb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr); | |
338 | writeb (ATA_CMD_CHK_POWER, port[num].ioaddr.command_addr); | |
339 | ||
340 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000, 0); | |
341 | if ((status & (ATA_BUSY | ATA_ERR))) { | |
342 | printf | |
343 | ("Error waiting for check power mode complete : status 0x%02x\n", | |
344 | status); | |
345 | port[num].dev_mask &= ~0x01; | |
346 | return 1; | |
347 | } | |
348 | res = readb (port[num].ioaddr.nsect_addr); | |
349 | debug ("Check powermode: %d\n", res); | |
350 | return res; | |
351 | ||
352 | } | |
353 | ||
354 | static void sata_port (struct sata_ioports *ioport) | |
355 | { | |
356 | ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA; | |
357 | ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR; | |
358 | ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE; | |
359 | ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT; | |
360 | ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL; | |
361 | ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM; | |
362 | ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH; | |
363 | ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE; | |
364 | ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS; | |
365 | ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD; | |
366 | } | |
367 | ||
368 | static u8 wait_for_irq (int num, unsigned int max) | |
369 | { | |
370 | ||
371 | u32 port = iobase[5]; | |
372 | switch (num) { | |
373 | case 0: | |
374 | port += VND_TF_CNST_CH0; | |
375 | break; | |
376 | case 1: | |
377 | port += VND_TF_CNST_CH1; | |
378 | break; | |
379 | case 2: | |
380 | port += VND_TF_CNST_CH2; | |
381 | break; | |
382 | case 3: | |
383 | port += VND_TF_CNST_CH3; | |
384 | break; | |
385 | default: | |
386 | return 1; | |
387 | } | |
388 | ||
389 | do { | |
390 | if (readl (port) & VND_TF_CNST_INTST) { | |
391 | break; | |
392 | } | |
393 | udelay (1000); | |
394 | max--; | |
395 | } while ((max > 0)); | |
396 | ||
397 | return (max == 0); | |
398 | } | |
399 | ||
400 | static u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits, | |
401 | unsigned int max, u8 usealtstatus) | |
402 | { | |
403 | u8 status; | |
404 | ||
405 | do { | |
406 | if (!((status = sata_chk_status (ioaddr, usealtstatus)) & bits)) { | |
407 | break; | |
408 | } | |
409 | udelay (1000); | |
410 | max--; | |
411 | } while ((status & bits) && (max > 0)); | |
412 | ||
413 | return status; | |
414 | } | |
415 | ||
416 | static u8 sata_chk_status (struct sata_ioports *ioaddr, u8 usealtstatus) | |
417 | { | |
418 | if (!usealtstatus) { | |
419 | return readb (ioaddr->status_addr); | |
420 | } else { | |
421 | return readb (ioaddr->altstatus_addr); | |
422 | } | |
423 | } | |
424 | ||
425 | static void msleep (int count) | |
426 | { | |
427 | int i; | |
428 | ||
429 | for (i = 0; i < count; i++) | |
430 | udelay (1000); | |
431 | } | |
432 | ||
433 | /* Read up to 255 sectors | |
434 | * | |
435 | * Returns sectors read | |
436 | */ | |
437 | static u8 do_one_read (int device, ulong block, u8 blkcnt, u16 * buff, | |
438 | uchar lba48) | |
439 | { | |
440 | ||
441 | u8 sr = 0; | |
442 | u8 status; | |
443 | u64 blknr = (u64) block; | |
444 | ||
445 | if (!(sata_chk_status (&port[device].ioaddr, 0) & ATA_DRDY)) { | |
446 | printf ("Device ata%d not ready\n", device); | |
447 | return 0; | |
448 | } | |
449 | ||
450 | /* Set up transfer */ | |
451 | #ifdef CONFIG_LBA48 | |
452 | if (lba48) { | |
453 | /* write high bits */ | |
454 | writeb (0, port[device].ioaddr.nsect_addr); | |
455 | writeb ((blknr >> 24) & 0xFF, port[device].ioaddr.lbal_addr); | |
456 | writeb ((blknr >> 32) & 0xFF, port[device].ioaddr.lbam_addr); | |
457 | writeb ((blknr >> 40) & 0xFF, port[device].ioaddr.lbah_addr); | |
458 | } | |
459 | #endif | |
460 | writeb (blkcnt, port[device].ioaddr.nsect_addr); | |
461 | writeb (((blknr) >> 0) & 0xFF, port[device].ioaddr.lbal_addr); | |
462 | writeb ((blknr >> 8) & 0xFF, port[device].ioaddr.lbam_addr); | |
463 | writeb ((blknr >> 16) & 0xFF, port[device].ioaddr.lbah_addr); | |
464 | ||
465 | #ifdef CONFIG_LBA48 | |
466 | if (lba48) { | |
467 | writeb (ATA_LBA, port[device].ioaddr.device_addr); | |
468 | writeb (ATA_CMD_PIO_READ_EXT, port[device].ioaddr.command_addr); | |
469 | } else | |
470 | #endif | |
471 | { | |
472 | writeb (ATA_LBA | ((blknr >> 24) & 0xF), | |
473 | port[device].ioaddr.device_addr); | |
474 | writeb (ATA_CMD_PIO_READ, port[device].ioaddr.command_addr); | |
475 | } | |
476 | ||
477 | status = sata_busy_wait (&port[device].ioaddr, ATA_BUSY, 10000, 1); | |
478 | ||
479 | if (status & ATA_BUSY) { | |
480 | u8 err = 0; | |
481 | ||
482 | printf ("Device %d not responding status %d\n", device, status); | |
483 | err = readb (port[device].ioaddr.error_addr); | |
484 | printf ("Error reg = 0x%x\n", err); | |
485 | ||
486 | return (sr); | |
487 | } | |
488 | while (blkcnt--) { | |
489 | ||
490 | if (wait_for_irq (device, 500)) { | |
491 | printf ("ata%u irq failed\n", device); | |
492 | return sr; | |
493 | } | |
494 | ||
495 | status = sata_chk_status (&port[device].ioaddr, 0); | |
496 | if (status & ATA_ERR) { | |
497 | printf ("ata%u error %d\n", device, | |
498 | readb (port[device].ioaddr.error_addr)); | |
499 | return sr; | |
500 | } | |
501 | /* Read one sector */ | |
502 | input_data (&port[device].ioaddr, buff, ATA_SECTOR_WORDS); | |
503 | buff += ATA_SECTOR_WORDS; | |
504 | sr++; | |
505 | ||
506 | } | |
507 | return sr; | |
508 | } | |
509 | ||
510 | ulong sata_read (int device, ulong block, lbaint_t blkcnt, void *buff) | |
511 | { | |
512 | ulong n = 0, sread; | |
513 | u16 *buffer = (u16 *) buff; | |
514 | u8 status = 0; | |
515 | u64 blknr = (u64) block; | |
516 | unsigned char lba48 = 0; | |
517 | ||
518 | #ifdef CONFIG_LBA48 | |
519 | if (blknr > 0xfffffff) { | |
520 | if (!sata_dev_desc[device].lba48) { | |
521 | printf ("Drive doesn't support 48-bit addressing\n"); | |
522 | return 0; | |
523 | } | |
524 | /* more than 28 bits used, use 48bit mode */ | |
525 | lba48 = 1; | |
526 | } | |
527 | #endif | |
528 | ||
529 | while (blkcnt > 0) { | |
530 | ||
531 | if (blkcnt > 255) { | |
532 | sread = 255; | |
533 | } else { | |
534 | sread = blkcnt; | |
535 | } | |
536 | ||
537 | status = do_one_read (device, blknr, sread, buffer, lba48); | |
538 | if (status != sread) { | |
539 | printf ("Read failed\n"); | |
540 | return n; | |
541 | } | |
542 | ||
543 | blkcnt -= sread; | |
544 | blknr += sread; | |
545 | n += sread; | |
546 | buffer += sread * ATA_SECTOR_WORDS; | |
547 | } | |
548 | return n; | |
549 | } | |
550 | ||
551 | ulong sata_write (int device, ulong block, lbaint_t blkcnt, const void *buff) | |
552 | { | |
553 | ulong n = 0; | |
554 | u16 *buffer = (u16 *) buff; | |
555 | unsigned char status = 0, num = 0; | |
556 | u64 blknr = (u64) block; | |
557 | #ifdef CONFIG_LBA48 | |
558 | unsigned char lba48 = 0; | |
559 | ||
560 | if (blknr > 0xfffffff) { | |
561 | if (!sata_dev_desc[device].lba48) { | |
562 | printf ("Drive doesn't support 48-bit addressing\n"); | |
563 | return 0; | |
564 | } | |
565 | /* more than 28 bits used, use 48bit mode */ | |
566 | lba48 = 1; | |
567 | } | |
568 | #endif | |
569 | /*Port Number */ | |
570 | num = device; | |
571 | ||
572 | while (blkcnt-- > 0) { | |
573 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500, 0); | |
574 | if (status & ATA_BUSY) { | |
575 | printf ("ata%u failed to respond\n", port[num].port_no); | |
576 | return n; | |
577 | } | |
578 | #ifdef CONFIG_LBA48 | |
579 | if (lba48) { | |
580 | /* write high bits */ | |
581 | writeb (0, port[num].ioaddr.nsect_addr); | |
582 | writeb ((blknr >> 24) & 0xFF, | |
583 | port[num].ioaddr.lbal_addr); | |
584 | writeb ((blknr >> 32) & 0xFF, | |
585 | port[num].ioaddr.lbam_addr); | |
586 | writeb ((blknr >> 40) & 0xFF, | |
587 | port[num].ioaddr.lbah_addr); | |
588 | } | |
589 | #endif | |
590 | writeb (1, port[num].ioaddr.nsect_addr); | |
591 | writeb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr); | |
592 | writeb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); | |
593 | writeb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); | |
594 | #ifdef CONFIG_LBA48 | |
595 | if (lba48) { | |
596 | writeb (ATA_LBA, port[num].ioaddr.device_addr); | |
597 | writeb (ATA_CMD_PIO_WRITE_EXT, port[num].ioaddr.command_addr); | |
598 | } else | |
599 | #endif | |
600 | { | |
601 | writeb (ATA_LBA | ((blknr >> 24) & 0xF), | |
602 | port[num].ioaddr.device_addr); | |
603 | writeb (ATA_CMD_PIO_WRITE, port[num].ioaddr.command_addr); | |
604 | } | |
605 | ||
606 | msleep (50); | |
607 | /*may take up to 4 sec */ | |
608 | status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000, 0); | |
609 | if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) { | |
610 | printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n", | |
611 | device, (ulong) blknr, status); | |
612 | return (n); | |
613 | } | |
614 | ||
615 | output_data (&port[num].ioaddr, buffer, ATA_SECTOR_WORDS); | |
616 | readb (port[num].ioaddr.altstatus_addr); | |
617 | udelay (50); | |
618 | ||
619 | ++n; | |
620 | ++blknr; | |
621 | buffer += ATA_SECTOR_WORDS; | |
622 | } | |
623 | return n; | |
624 | } | |
625 | ||
626 | /* Driver implementation */ | |
627 | static u8 sil_get_device_cache_line (pci_dev_t pdev) | |
628 | { | |
629 | u8 cache_line = 0; | |
630 | pci_read_config_byte (pdev, PCI_CACHE_LINE_SIZE, &cache_line); | |
631 | return cache_line; | |
632 | } | |
633 | ||
634 | int init_sata (int dev) | |
635 | { | |
636 | static u8 init_done = 0; | |
637 | static int res = 1; | |
638 | pci_dev_t devno; | |
639 | u8 cls = 0; | |
640 | u16 cmd = 0; | |
641 | u32 sconf = 0; | |
642 | ||
643 | if (init_done) { | |
644 | return res; | |
645 | } | |
646 | ||
647 | init_done = 1; | |
648 | ||
649 | if ((devno = pci_find_device (SIL_VEND_ID, SIL3114_DEVICE_ID, 0)) == -1) { | |
650 | res = 1; | |
651 | return res; | |
652 | } | |
653 | ||
654 | /* Read out all BARs, even though we only use MMIO from BAR5 */ | |
655 | pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase[0]); | |
656 | pci_read_config_dword (devno, PCI_BASE_ADDRESS_1, &iobase[1]); | |
657 | pci_read_config_dword (devno, PCI_BASE_ADDRESS_2, &iobase[2]); | |
658 | pci_read_config_dword (devno, PCI_BASE_ADDRESS_3, &iobase[3]); | |
659 | pci_read_config_dword (devno, PCI_BASE_ADDRESS_4, &iobase[4]); | |
660 | pci_read_config_dword (devno, PCI_BASE_ADDRESS_5, &iobase[5]); | |
661 | ||
662 | if ((iobase[0] == 0xFFFFFFFF) || (iobase[1] == 0xFFFFFFFF) || | |
663 | (iobase[2] == 0xFFFFFFFF) || (iobase[3] == 0xFFFFFFFF) || | |
664 | (iobase[4] == 0xFFFFFFFF) || (iobase[5] == 0xFFFFFFFF)) { | |
665 | printf ("Error no base addr for SATA controller\n"); | |
666 | res = 1; | |
667 | return res; | |
668 | } | |
669 | ||
670 | /* mask off unused bits */ | |
671 | iobase[0] &= 0xfffffffc; | |
672 | iobase[1] &= 0xfffffff8; | |
673 | iobase[2] &= 0xfffffffc; | |
674 | iobase[3] &= 0xfffffff8; | |
675 | iobase[4] &= 0xfffffff0; | |
676 | iobase[5] &= 0xfffffc00; | |
677 | ||
678 | /* from sata_sil in Linux kernel */ | |
679 | cls = sil_get_device_cache_line (devno); | |
680 | if (cls) { | |
681 | cls >>= 3; | |
682 | cls++; /* cls = (line_size/8)+1 */ | |
683 | writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH0); | |
684 | writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH1); | |
685 | writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH2); | |
686 | writel (cls << 8 | cls, iobase[5] + VND_FIFOCFG_CH3); | |
687 | } else { | |
688 | printf ("Cache line not set. Driver may not function\n"); | |
689 | } | |
690 | ||
691 | /* Enable operation */ | |
692 | pci_read_config_word (devno, PCI_COMMAND, &cmd); | |
693 | cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; | |
694 | pci_write_config_word (devno, PCI_COMMAND, cmd); | |
695 | ||
696 | /* Disable interrupt usage */ | |
697 | pci_read_config_dword (devno, VND_SYSCONFSTAT, &sconf); | |
698 | sconf |= (VND_SYSCONFSTAT_CHN_0_INTBLOCK | VND_SYSCONFSTAT_CHN_1_INTBLOCK); | |
699 | pci_write_config_dword (devno, VND_SYSCONFSTAT, sconf); | |
700 | ||
701 | res = 0; | |
702 | return res; | |
703 | } | |
704 | ||
10ee8eca NK |
705 | int reset_sata(int dev) |
706 | { | |
707 | return 0; | |
708 | } | |
709 | ||
f1352651 TK |
710 | /* Check if device is connected to port */ |
711 | int sata_bus_probe (int portno) | |
712 | { | |
713 | u32 port = iobase[5]; | |
714 | u32 val; | |
715 | switch (portno) { | |
716 | case 0: | |
717 | port += VND_SSTATUS_CH0; | |
718 | break; | |
719 | case 1: | |
720 | port += VND_SSTATUS_CH1; | |
721 | break; | |
722 | case 2: | |
723 | port += VND_SSTATUS_CH2; | |
724 | break; | |
725 | case 3: | |
726 | port += VND_SSTATUS_CH3; | |
727 | break; | |
728 | default: | |
729 | return 0; | |
730 | } | |
731 | val = readl (port); | |
732 | if ((val & SATA_DET_PRES) == SATA_DET_PRES) { | |
733 | return 1; | |
734 | } else { | |
735 | return 0; | |
736 | } | |
737 | } | |
738 | ||
739 | int sata_phy_reset (int portno) | |
740 | { | |
741 | u32 port = iobase[5]; | |
742 | u32 val; | |
743 | switch (portno) { | |
744 | case 0: | |
745 | port += VND_SCONTROL_CH0; | |
746 | break; | |
747 | case 1: | |
748 | port += VND_SCONTROL_CH1; | |
749 | break; | |
750 | case 2: | |
751 | port += VND_SCONTROL_CH2; | |
752 | break; | |
753 | case 3: | |
754 | port += VND_SCONTROL_CH3; | |
755 | break; | |
756 | default: | |
757 | return 0; | |
758 | } | |
759 | val = readl (port); | |
760 | writel (val | SATA_SC_DET_RST, port); | |
761 | msleep (150); | |
762 | writel (val & ~SATA_SC_DET_RST, port); | |
763 | return 0; | |
764 | } | |
765 | ||
766 | int scan_sata (int dev) | |
767 | { | |
768 | /* A bit brain dead, but the code has a legacy */ | |
769 | switch (dev) { | |
770 | case 0: | |
771 | port[0].port_no = 0; | |
772 | port[0].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH0; | |
773 | port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr = | |
774 | (iobase[5] + VND_TF2_CH0) | ATA_PCI_CTL_OFS; | |
775 | port[0].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH0; | |
776 | break; | |
7625dd68 | 777 | #if (CONFIG_SYS_SATA_MAX_DEVICE >= 1) |
f1352651 TK |
778 | case 1: |
779 | port[1].port_no = 0; | |
780 | port[1].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH1; | |
781 | port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr = | |
782 | (iobase[5] + VND_TF2_CH1) | ATA_PCI_CTL_OFS; | |
783 | port[1].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH1; | |
784 | break; | |
7625dd68 | 785 | #elif (CONFIG_SYS_SATA_MAX_DEVICE >= 2) |
f1352651 TK |
786 | case 2: |
787 | port[2].port_no = 0; | |
788 | port[2].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH2; | |
789 | port[2].ioaddr.altstatus_addr = port[2].ioaddr.ctl_addr = | |
790 | (iobase[5] + VND_TF2_CH2) | ATA_PCI_CTL_OFS; | |
791 | port[2].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH2; | |
792 | break; | |
7625dd68 | 793 | #elif (CONFIG_SYS_SATA_MAX_DEVICE >= 3) |
f1352651 TK |
794 | case 3: |
795 | port[3].port_no = 0; | |
796 | port[3].ioaddr.cmd_addr = iobase[5] + VND_TF0_CH3; | |
797 | port[3].ioaddr.altstatus_addr = port[3].ioaddr.ctl_addr = | |
798 | (iobase[5] + VND_TF2_CH3) | ATA_PCI_CTL_OFS; | |
799 | port[3].ioaddr.bmdma_addr = iobase[5] + VND_BMDMA_CH3; | |
800 | break; | |
7625dd68 | 801 | #endif |
f1352651 TK |
802 | default: |
803 | printf ("Tried to scan unknown port: ata%d\n", dev); | |
804 | return 1; | |
805 | } | |
806 | ||
807 | /* Initialize other registers */ | |
808 | sata_port (&port[dev].ioaddr); | |
809 | ||
810 | /* Check for attached device */ | |
811 | if (!sata_bus_probe (dev)) { | |
812 | port[dev].port_state = 0; | |
813 | debug ("SATA#%d port is not present\n", dev); | |
814 | } else { | |
815 | debug ("SATA#%d port is present\n", dev); | |
816 | if (sata_bus_softreset (dev)) { | |
817 | /* soft reset failed, try a hard one */ | |
818 | sata_phy_reset (dev); | |
819 | if (sata_bus_softreset (dev)) { | |
820 | port[dev].port_state = 0; | |
821 | } else { | |
822 | port[dev].port_state = 1; | |
823 | } | |
824 | } else { | |
825 | port[dev].port_state = 1; | |
826 | } | |
827 | } | |
828 | if (port[dev].port_state == 1) { | |
829 | /* Probe device and set xfer mode */ | |
830 | sata_identify (dev, 0); | |
831 | set_Feature_cmd (dev, 0); | |
832 | } | |
833 | ||
834 | return 0; | |
835 | } |