import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / ide / stb03xxx.c
1 /*
2  *    Copyright 2001 MontaVista Software Inc.
3  *      Completed implementation.
4  *      Author: MontaVista Software, Inc.  <source@mvista.com>
5  *              Hai-Pao Fan <hpfan@mvista.com>
6  *
7  *    Module name: stb03xxx.c
8  *
9  *    Description:
10  */
11
12 #include <linux/types.h>
13 #include <linux/hdreg.h>
14 #include <linux/delay.h>
15 #include <linux/ide.h>
16
17 #include <asm/io.h>
18 #include <asm/scatterlist.h>
19 #include <asm/ppc405_dma.h>
20
21 #include "ide_modes.h"
22
23 #define REDWOOD_IDE_CMD         0xf2100000
24 #define REDWOOD_IDE_CTRL        0xf4100000
25 #define IDE_CMD_OFF             0x00100000
26 #define IDE_CTL_OFF             0x00100000
27
28 #define IDE_INTRQ       25              /* interrupt level(int0) */
29
30 #define REDWOOD_DMA_ADDR        0xfce00000
31
32
33 /* use DMA channel 2 for IDE DMA operations */
34
35 #define IDE_DMA_INT     6               /* IDE dma channel 2 interrupt */
36
37 /* DMACR2 */
38 #define IDE_DMACR_CE    0x80000000      /* 00 channel enable */
39 #define IDE_DMACR_CIE   0x40000000      /* 01 channel interrupt enable */
40 #define IDE_DMACR_TD    0x20000000      /* 02 transfer direction */
41                                         /* 0 = write 1 = read */
42 #define IDE_DMACR_PL    0x10000000      /* 03 peripheral location */
43 #define IDE_DMACR_PW    0x0C000000      /* 04-05 peripheral width */
44 #define IDE_DMACR_DAI   0x02000000      /* 06 destination address increment */
45 #define IDE_DMACR_SAI   0x01000000      /* 07 source address increment */
46 #define IDE_DMACR_CP    0x00800000      /* 08 high order channel priority bit*/
47 #define IDE_DMACR_TM    0x00600000      /* 09-10 transfer mode */
48 #define IDE_DMACR_PSC   0x00180000      /* 11-12 peripheral setup cycles */
49 #define IDE_DMACR_PWC   0x0007E000      /* 13-18 peripheral wait cycles */
50 #define IDE_DMACR_PHC   0x00001C00      /* 19-21 peripheral hold cycles */
51 #define IDE_DMACR_ETD   0x00000200      /* 22 EOT/TC */
52 #define IDE_DMACR_TCE   0x00000100      /* 23 TC Enable */
53 #define IDE_DMACR_CH    0x00000080      /* 24 chaining enable */
54 #define IDE_DMACR_ECE   0x00000020      /* 26 EOT chain mode enable */
55 #define IDE_DMACR_TCD   0x00000010      /* 27 TC chain mode enable */
56 #define IDE_DMACR_DEC   0x00000004      /* 29 destination address decrement */
57 #define IDE_DMACR_CP1   0x00000001      /* 31 low order channel priority bit */
58
59 #define IDE_DMASR_TC    0x20000000
60 #define IDE_DMASR_EOT   0x02000000
61 #define IDE_DMASR_ERR   0x00200000
62 #define IDE_DMASR_CB    0x00000100
63 #define IDE_DMASR_CT    0x00000020
64
65 unsigned long dmacr_def = 0x0000AB02;   /* pwc=101 phc=10, res:30=1 */
66 extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
67
68
69 #define WMODE   0               /* default to DMA line mode */
70 #define PIOMODE 0
71 static volatile unsigned long dmastat;
72
73 /* Function Prototypes */
74 static void redwood_ide_tune_drive(ide_drive_t *, byte);
75 static byte redwood_ide_dma_2_pio(byte);
76 static int redwood_ide_tune_chipset(ide_drive_t *, byte);
77 static int redwood_ide_dmaproc(ide_dma_action_t, ide_drive_t *);
78
79
80 static void redwood_ide_tune_drive(ide_drive_t *drive, byte pio)
81 {
82         pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
83 }
84
85 static byte redwood_ide_dma_2_pio(byte xfer_rate)
86 {
87         switch(xfer_rate) {
88         case XFER_UDMA_5:
89         case XFER_UDMA_4:
90         case XFER_UDMA_3:
91         case XFER_UDMA_2:
92         case XFER_UDMA_1:
93         case XFER_UDMA_0:
94         case XFER_MW_DMA_2:
95         case XFER_PIO_4:
96                 return 4;
97         case XFER_MW_DMA_1:
98         case XFER_PIO_3:
99                 return 3;
100         case XFER_SW_DMA_2:
101         case XFER_PIO_2:
102                 return 2;
103         case XFER_MW_DMA_0:
104         case XFER_SW_DMA_1:
105         case XFER_SW_DMA_0:
106         case XFER_PIO_1:
107         case XFER_PIO_0:
108         case XFER_PIO_SLOW:
109         default:
110                 return 0;
111         }
112 }
113
114 static int redwood_ide_tune_chipset (ide_drive_t *drive, byte speed)
115 {
116         int err=0;
117
118         redwood_ide_tune_drive(drive, redwood_ide_dma_2_pio(speed));
119
120         if (!drive->init_speed)
121                 drive->init_speed = speed;
122         err = ide_config_drive_speed(drive, speed);
123         drive->current_speed = speed;
124         return err;     
125 }
126
127 static int redwood_config_drive_for_dma(ide_drive_t *drive)
128 {
129         struct hd_driveid *id = drive->id;
130         byte speed;
131         int func = ide_dma_off;
132
133         /*
134          * Enable DMA on any drive that has multiword DMA
135          */
136         if (id->field_valid & 2) {
137                 if (id->dma_mword & 0x0004) {
138                         speed = XFER_MW_DMA_2;
139                         func = ide_dma_on;
140                 } else if (id->dma_mword & 0x0002) {
141                         speed = XFER_MW_DMA_1;
142                         func = ide_dma_on;
143                 } else if (id->dma_mword & 1) {
144                         speed = XFER_MW_DMA_0;
145                         func = ide_dma_on;
146                 } else if (id->dma_1word & 0x0004) {
147                         speed = XFER_SW_DMA_2;
148                         func = ide_dma_on;
149                 } else {
150                         speed = XFER_PIO_0 +
151                                 ide_get_best_pio_mode(drive, 255, 5, NULL);
152                 }
153         }
154
155         redwood_ide_tune_drive(drive, redwood_ide_dma_2_pio(speed));
156         return redwood_ide_dmaproc(func, drive);
157 }
158
159 ide_startstop_t redwood_ide_intr (ide_drive_t *drive)
160 {
161         int i;
162         byte dma_stat;
163         unsigned int nsect;
164         ide_hwgroup_t *hwgroup = HWGROUP(drive);
165         struct request *rq = hwgroup->rq;
166         unsigned long block,b1,b2,b3,b4;
167
168         nsect = rq->current_nr_sectors;
169
170         dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
171
172         rq->sector += nsect;
173         rq->buffer += nsect<<9;
174         rq->errors = 0;
175         i = (rq->nr_sectors -= nsect);
176         ide_end_request(1, HWGROUP(drive));
177         if (i > 0) {
178                 b1 = IN_BYTE(IDE_SECTOR_REG);
179                 b2 = IN_BYTE(IDE_LCYL_REG);
180                 b3 = IN_BYTE(IDE_HCYL_REG);
181                 b4 = IN_BYTE(IDE_SELECT_REG);
182                 block = ((b4 & 0x0f) << 24) + (b3 << 16) + (b2 << 8) + (b1);
183                 block++;
184                 if (drive->select.b.lba) {
185                         OUT_BYTE(block,IDE_SECTOR_REG);
186                         OUT_BYTE(block>>=8,IDE_LCYL_REG);
187                         OUT_BYTE(block>>=8,IDE_HCYL_REG);
188                         OUT_BYTE(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
189                 } else {
190                         unsigned int sect,head,cyl,track;
191                         track = block / drive->sect;
192                         sect = block % drive->sect + 1;
193                         OUT_BYTE(sect,IDE_SECTOR_REG);
194                         head = track % drive->head;
195                         cyl = track / drive->head;
196                         OUT_BYTE(cyl,IDE_LCYL_REG);
197                         OUT_BYTE(cyl>>8,IDE_HCYL_REG);
198                         OUT_BYTE(head|drive->select.all,IDE_SELECT_REG);
199                 }
200
201                 if (rq->cmd == READ)
202                         dma_stat = HWIF(drive)->dmaproc(ide_dma_read, drive);
203                 else
204                         dma_stat = HWIF(drive)->dmaproc(ide_dma_write, drive);
205                 return ide_started;
206         }
207         return ide_stopped;
208 }
209
210 void redwood_ide_dma_intr (int irq, void *dev_id, struct pt_regs *regs)
211 {
212         dmastat = mfdcr(DCRN_DMASR);
213
214         mtdcr(DCRN_DMASR,
215                 IDE_DMASR_TC | IDE_DMASR_EOT | IDE_DMASR_ERR | IDE_DMASR_CT);
216
217         /* clear UIC bit */
218         mtdcr(DCRN_UIC_SR(UIC0), (0x80000000 >> IDE_DMA_INT));
219 }
220
221 static int redwood_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
222 {
223         ide_hwif_t *hwif = HWIF(drive);
224         int i, reading = 0;
225         struct request *rq=HWGROUP(drive)->rq;
226         unsigned long flags;
227         unsigned long length;
228
229         switch (func) {
230         case ide_dma_off:
231         case ide_dma_off_quietly:
232                 /*disable_dma*/
233                 return 0;
234
235         case ide_dma_on:
236 #if PIOMODE
237                 return 1;
238 #endif
239
240                 mtdcr(DCRN_DMACR2,0);
241                 mtdcr(DCRN_DMASR, IDE_DMASR_TC | IDE_DMASR_EOT | IDE_DMASR_ERR
242                                 | IDE_DMASR_CT);
243
244                 /* level-sensitive (UICTR bit = 0) and positive-active (UICPR bit = 1) */
245                 mtdcr(DCRN_UIC_PR(UIC0), (mfdcr(DCRN_UIC_PR(UIC0)) | UIC_D2));
246                 save_flags(flags);
247                 cli();
248                 if ( ide_request_irq(IDE_DMA_INT, &redwood_ide_dma_intr, SA_INTERRUPT,
249                         hwif->name, hwif->hwgroup) ) {
250                         printk("ide_redwood: ide_request_irq failed int=%d\n",
251                                         IDE_DMA_INT);
252                         restore_flags(flags);
253                         return 1;
254                 }
255                 restore_flags(flags);
256
257                 drive->using_dma = (func == ide_dma_on);
258 #if WMODE
259                 mtdcr(DCRN_DCRXBCR, 0);
260                 mtdcr(DCRN_CICCR, mfdcr(DCRN_CICCR) | 0x00000400);
261 #else
262                 /* Configure CIC reg for line mode dma */
263                 mtdcr(DCRN_CICCR, mfdcr(DCRN_CICCR) & ~0x00000400);
264 #endif
265                 return 0;       
266
267         case ide_dma_check:
268                 return redwood_config_drive_for_dma(drive);
269         case ide_dma_read:
270                 reading = 1;
271         case ide_dma_write:
272                 if (drive->media != ide_disk)
273                         return -1;
274
275                 if (mfdcr(DCRN_DMACR2) & IDE_DMACR_CE)  /* DMA is busy? */
276                         return -1;
277
278                 mtdcr(DCRN_DMASR, IDE_DMASR_TC | IDE_DMASR_EOT | IDE_DMASR_ERR
279                                 | IDE_DMASR_CT);
280
281                 if (reading) {
282                         dma_cache_inv((unsigned long) rq->buffer,
283                                 rq->current_nr_sectors * 512);
284 #if WMODE
285                         mtdcr(DCRN_DMASA2,0);
286 #else
287                         mtdcr(DCRN_DMASA2,0xfce00000);
288 #endif
289                         mtdcr(DCRN_DMADA2, virt_to_bus(rq->buffer));
290                 } else {
291                         dma_cache_wback_inv((unsigned long) rq->buffer,
292                                 rq->current_nr_sectors * 512);
293                         mtdcr(DCRN_DMASA2, virt_to_bus(rq->buffer));
294 #if WMODE
295                         mtdcr(DCRN_DMADA2,0);
296 #else
297                         mtdcr(DCRN_DMADA2,0xfce00000);
298 #endif
299                 }
300
301 #if WMODE
302                 length = rq->current_nr_sectors * 512/2;
303 #else
304                 length = rq->current_nr_sectors * 512/16;
305 #endif
306                 OUT_BYTE(rq->current_nr_sectors,IDE_NSECTOR_REG);
307                 mtdcr(DCRN_DMACT2, length);
308                 
309                 /* CE=0 disable DMA */
310                 /* Set up the Line Buffer Control Register
311                  * 11d1xxxx0.. - 11=Mode 2 (120 ns cycle), d=1/0(read/write)
312                  * 1=active, 0=1X clock mode.
313                  */
314
315                 if (reading) {
316 #if WMODE
317                         mtdcr(DCRN_DMACR2, 0x66000000 | dmacr_def);
318 #else
319                         mtdcr(DCRN_DCRXBCR,0xD0000000);
320                         mtdcr(DCRN_DMACR2, 0x6E600000 | dmacr_def);
321 #endif
322                 } else {
323 #if WMODE
324                         mtdcr(DCRN_DMACR2, 0x46000000 | dmacr_def);
325 #else
326                         mtdcr(DCRN_DCRXBCR, 0xF0000000);
327                         mtdcr(DCRN_DMACR2, 0x4D600000 | dmacr_def);
328 #endif
329                 }
330
331                 set_dma_mode(hwif->hw.dma, reading
332                                 ? DMA_MODE_READ : DMA_MODE_WRITE);
333                 drive->waiting_for_dma = 1;
334                 ide_set_handler(drive, &redwood_ide_intr, WAIT_CMD, NULL);
335                 OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
336
337         case ide_dma_begin:
338                 /* enable DMA */
339                 mtdcr(DCRN_DMACR2,mfdcr(DCRN_DMACR2) | 0x80000000);
340
341                 /* wait for dma to complete (channel 2 terminal count) */
342                 for (i=0; i < 5000000; i++) {
343                         if (dmastat & DMA_CS2)
344                                 break;  
345                 }
346                 dmastat = 0;
347                 return 0;
348
349         case ide_dma_end:
350                 drive->waiting_for_dma = 0;
351
352                 /* disable DMA */
353                 mtdcr(DCRN_DMACR2, mfdcr(DCRN_DMACR2) & ~0x80000000);
354                 mtdcr(DCRN_DCRXBCR,0);
355                 return 0;
356
357         case ide_dma_test_irq:
358                 return 1;       /* returns 1 if dma irq issued, 0 otherwise */
359
360         case ide_dma_bad_drive:
361         case ide_dma_good_drive:
362         case ide_dma_verbose:
363         case ide_dma_timeout:
364         case ide_dma_retune:
365         case ide_dma_lostirq:
366                 printk("ide_dmaproc: chipset supported %s func only: %d\n",
367                                 ide_dmafunc_verbose(func), func);
368                 return 1;
369         default:
370                 printk("ide_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func);
371                         return 1;
372
373                 //return ide_dmaproc(func, drive);
374         }
375
376 }
377
378 int nonpci_ide_default_irq(ide_ioreg_t base)
379 {
380         return IDE_INTRQ;
381 }
382
383
384 void
385 nonpci_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
386 {
387         unsigned long reg = data_port;
388         unsigned long ioaddr;
389         unsigned long xilinx;
390         int i, index;
391
392         if (!request_region(REDWOOD_IDE_CMD, 0x10, "IDE"))
393                 return;
394
395         if (!request_region(REDWOOD_IDE_CTRL, 2, "IDE")) {
396                 release_region(REDWOOD_IDE_CMD, 0x10);
397                 return;
398         }
399
400         mtdcr(DCRN_DCRXICR, 0x40000000);        /* set dcrx internal arbiter */
401
402         /* reconstruct phys addrs from EBIU config regs for CS2# */
403         reg = ((mfdcr(DCRN_BRCR2) & 0xff000000) >> 4) | 0xf0000000;
404         xilinx = reg | 0x00040000;
405         reg = reg | IDE_CMD_OFF;
406
407         ioaddr = (unsigned long)ioremap(reg, 0x10);
408         xilinx = (unsigned long)ioremap(xilinx, 0x10);
409
410         hw->irq = IDE_INTRQ;
411
412         for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
413                 hw->io_ports[i] = ioaddr;
414                 ioaddr += 2;
415         }
416         hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ioremap(REDWOOD_IDE_CTRL,2);
417
418         /* add RE & OEN to value set by boot rom */
419         mtdcr(DCRN_BRCR3, 0x407cfffe);
420
421         /* init CIC control reg to enable IDE interface PIO mode */
422         mtdcr(DCRN_CICCR, (mfdcr(DCRN_CICCR) & 0xffff7bff) | 0x0003);
423
424         i=readw(xilinx);
425         if(i & 0x0001) {
426                 writew( i & ~0x8001, xilinx);
427                 writew( 0, xilinx+7*2);
428                 udelay(10*1000);        /* 10 ms */
429         }
430
431         /* init xilinx control registers - enable ide mux, clear reset bit */
432         writew( i | 0x8001, xilinx);
433         writew( 0, xilinx+7*2);
434
435         /* wait until drive is not busy (it may be spinning up) */
436         for (i=0; i < 10; i++) {
437                 unsigned char stat;
438                 stat = inb_p(hw->io_ports[7]);
439                 /* wait for !busy & ready */
440                 if ((stat & 0x80) == 0)
441                         break;
442
443                 udelay(1000*1000);              /* 1 second */
444         }
445
446         /* use DMA channel 2 for IDE DMA operations */
447         hw->dma = 2;
448
449         mtdcr(DCRN_DMACR2, 0x4d600000 | dmacr_def);
450         mtdcr(DCRN_DMASR, 0xffffffff); /* clear status register */
451
452         /* init CIC select2 reg to connect external DMA port 3 to internal
453          * DMA channel 2
454          */
455         mtdcr(DCRN_DMAS2, (mfdcr(DCRN_DMAS2) & 0xfffffff0) | 0x00000002);
456
457         index = 0;
458
459         ide_hwifs[index].tuneproc = &redwood_ide_tune_drive;
460         ide_hwifs[index].drives[0].autotune = 1;
461         ide_hwifs[index].autodma = 1;
462         ide_hwifs[index].dmaproc = &redwood_ide_dmaproc;
463         ide_hwifs[index].speedproc = &redwood_ide_tune_chipset;
464         ide_hwifs[index].noprobe = 0;
465
466         memcpy(ide_hwifs[index].io_ports, hw->io_ports, sizeof(hw->io_ports));
467         ide_hwifs[index].irq = IDE_INTRQ;
468 }
469