OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [ide/] [pci/] [cy82c693.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/drivers/ide/pci/cy82c693.c             Version 0.40    Sep. 10, 2002
3
 *
4
 *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
5
 *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
6
 *
7
 * CYPRESS CY82C693 chipset IDE controller
8
 *
9
 * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
10
 * Writing the driver was quite simple, since most of the job is
11
 * done by the generic pci-ide support.
12
 * The hard part was finding the CY82C693's datasheet on Cypress's
13
 * web page :-(. But Altavista solved this problem :-).
14
 *
15
 *
16
 * Notes:
17
 * - I recently got a 16.8G IBM DTTA, so I was able to test it with
18
 *   a large and fast disk - the results look great, so I'd say the
19
 *   driver is working fine :-)
20
 *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
21
 * - this is my first linux driver, so there's probably a lot  of room
22
 *   for optimizations and bug fixing, so feel free to do it.
23
 * - use idebus=xx parameter to set PCI bus speed - needed to calc
24
 *   timings for PIO modes (default will be 40)
25
 * - if using PIO mode it's a good idea to set the PIO mode and
26
 *   32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
27
 * - I had some problems with my IBM DHEA with PIO modes < 2
28
 *   (lost interrupts) ?????
29
 * - first tests with DMA look okay, they seem to work, but there is a
30
 *   problem with sound - the BusMaster IDE TimeOut should fixed this
31
 *
32
 * Ancient History:
33
 * AMH@1999-08-24: v0.34 init_cy82c693_chip moved to pci_init_cy82c693
34
 * ASK@1999-01-23: v0.33 made a few minor code clean ups
35
 *                       removed DMA clock speed setting by default
36
 *                       added boot message
37
 * ASK@1998-11-01: v0.32 added support to set BusMaster IDE TimeOut
38
 *                       added support to set DMA Controller Clock Speed
39
 * ASK@1998-10-31: v0.31 fixed problem with setting to high DMA modes
40
 *                       on some drives.
41
 * ASK@1998-10-29: v0.3 added support to set DMA modes
42
 * ASK@1998-10-28: v0.2 added support to set PIO modes
43
 * ASK@1998-10-27: v0.1 first version - chipset detection
44
 *
45
 */
46
 
47
#include <linux/config.h>
48
#include <linux/module.h>
49
#include <linux/types.h>
50
#include <linux/pci.h>
51
#include <linux/delay.h>
52
#include <linux/ide.h>
53
#include <linux/init.h>
54
 
55
#include <asm/io.h>
56
 
57
#include "ide_modes.h"
58
#include "cy82c693.h"
59
 
60
/*
61
 * calc clocks using bus_speed
62
 * returns (rounded up) time in bus clocks for time in ns
63
 */
64
static int calc_clk (int time, int bus_speed)
65
{
66
        int clocks;
67
 
68
        clocks = (time*bus_speed+999)/1000 -1;
69
 
70
        if (clocks < 0)
71
                clocks = 0;
72
 
73
        if (clocks > 0x0F)
74
                clocks = 0x0F;
75
 
76
        return clocks;
77
}
78
 
79
/*
80
 * compute the values for the clock registers for PIO
81
 * mode and pci_clk [MHz] speed
82
 *
83
 * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used
84
 *       for mode 3 and 4 drives 8 and 16-bit timings are the same
85
 *
86
 */
87
static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
88
{
89
        int clk1, clk2;
90
        int bus_speed = system_bus_clock();     /* get speed of PCI bus */
91
 
92
        /* we don't check against CY82C693's min and max speed,
93
         * so you can play with the idebus=xx parameter
94
         */
95
 
96
        if (pio > CY82C693_MAX_PIO)
97
                pio = CY82C693_MAX_PIO;
98
 
99
        /* let's calc the address setup time clocks */
100
        p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed);
101
 
102
        /* let's calc the active and recovery time clocks */
103
        clk1 = calc_clk(ide_pio_timings[pio].active_time, bus_speed);
104
 
105
        /* calc recovery timing */
106
        clk2 =  ide_pio_timings[pio].cycle_time -
107
                ide_pio_timings[pio].active_time -
108
                ide_pio_timings[pio].setup_time;
109
 
110
        clk2 = calc_clk(clk2, bus_speed);
111
 
112
        clk1 = (clk1<<4)|clk2;  /* combine active and recovery clocks */
113
 
114
        /* note: we use the same values for 16bit IOR and IOW
115
         *      those are all the same, since I don't have other
116
         *      timings than those from ide_modes.h
117
         */
118
 
119
        p_pclk->time_16r = (u8)clk1;
120
        p_pclk->time_16w = (u8)clk1;
121
 
122
        /* what are good values for 8bit ?? */
123
        p_pclk->time_8 = (u8)clk1;
124
}
125
 
126
/*
127
 * set DMA mode a specific channel for CY82C693
128
 */
129
 
130
static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
131
{
132
        u8 index = 0, data = 0;
133
 
134
        if (mode>2)     /* make sure we set a valid mode */
135
                mode = 2;
136
 
137
        if (mode > drive->id->tDMA)  /* to be absolutly sure we have a valid mode */
138
                mode = drive->id->tDMA;
139
 
140
        index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
141
 
142
#if CY82C693_DEBUG_LOGS
143
        /* for debug let's show the previous values */
144
 
145
        HWIF(drive)->OUTB(index, CY82_INDEX_PORT);
146
        data = HWIF(drive)->INB(CY82_DATA_PORT);
147
 
148
        printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
149
                drive->name, HWIF(drive)->channel, drive->select.b.unit,
150
                (data&0x3), ((data>>2)&1));
151
#endif /* CY82C693_DEBUG_LOGS */
152
 
153
        data = (u8)mode|(u8)(single<<2);
154
 
155
        HWIF(drive)->OUTB(index, CY82_INDEX_PORT);
156
        HWIF(drive)->OUTB(data, CY82_DATA_PORT);
157
 
158
#if CY82C693_DEBUG_INFO
159
        printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
160
                drive->name, HWIF(drive)->channel, drive->select.b.unit,
161
                mode, single);
162
#endif /* CY82C693_DEBUG_INFO */
163
 
164
        /*
165
         * note: below we set the value for Bus Master IDE TimeOut Register
166
         * I'm not absolutly sure what this does, but it solved my problem
167
         * with IDE DMA and sound, so I now can play sound and work with
168
         * my IDE driver at the same time :-)
169
         *
170
         * If you know the correct (best) value for this register please
171
         * let me know - ASK
172
         */
173
 
174
        data = BUSMASTER_TIMEOUT;
175
        HWIF(drive)->OUTB(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
176
        HWIF(drive)->OUTB(data, CY82_DATA_PORT);
177
 
178
#if CY82C693_DEBUG_INFO 
179
        printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
180
                drive->name, data);
181
#endif /* CY82C693_DEBUG_INFO */
182
}
183
 
184
/*
185
 * used to set DMA mode for CY82C693 (single and multi modes)
186
 */
187
int cy82c693_ide_dma_on (ide_drive_t *drive)
188
{
189
        struct hd_driveid *id = drive->id;
190
 
191
#if CY82C693_DEBUG_INFO
192
        printk (KERN_INFO "dma_on: %s\n", drive->name);
193
#endif /* CY82C693_DEBUG_INFO */
194
 
195
        /* Enable DMA on any drive that has DMA
196
         * (multi or single) enabled
197
         */
198
        if (id->field_valid & 2) {      /* regular DMA */
199
                int mmode, smode;
200
 
201
                mmode = id->dma_mword & (id->dma_mword >> 8);
202
                smode = id->dma_1word & (id->dma_1word >> 8);
203
 
204
                if (mmode != 0) {
205
                        /* enable multi */
206
                        cy82c693_dma_enable(drive, (mmode >> 1), 0);
207
                } else if (smode != 0) {
208
                        /* enable single */
209
                        cy82c693_dma_enable(drive, (smode >> 1), 1);
210
                }
211
        }
212
        return __ide_dma_on(drive);
213
}
214
 
215
/*
216
 * tune ide drive - set PIO mode
217
 */
218
static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
219
{
220
        ide_hwif_t *hwif = HWIF(drive);
221
        struct pci_dev *dev = hwif->pci_dev;
222
        pio_clocks_t pclk;
223
        unsigned int addrCtrl;
224
 
225
        /* select primary or secondary channel */
226
        if (hwif->index > 0) {  /* drive is on the secondary channel */
227
                dev = pci_find_slot(dev->bus->number, dev->devfn+1);
228
                if (!dev) {
229
                        printk(KERN_ERR "%s: tune_drive: "
230
                                "Cannot find secondary interface!\n",
231
                                drive->name);
232
                        return;
233
                }
234
        }
235
 
236
#if CY82C693_DEBUG_LOGS
237
        /* for debug let's show the register values */
238
 
239
        if (drive->select.b.unit == 0) {
240
                /*
241
                 * get master drive registers
242
                 * address setup control register
243
                 * is 32 bit !!!
244
                 */
245
                pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
246
                addrCtrl &= 0x0F;
247
 
248
                /* now let's get the remaining registers */
249
                pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r);
250
                pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w);
251
                pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8);
252
        } else {
253
                /*
254
                 * set slave drive registers
255
                 * address setup control register
256
                 * is 32 bit !!!
257
                 */
258
                pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
259
 
260
                addrCtrl &= 0xF0;
261
                addrCtrl >>= 4;
262
 
263
                /* now let's get the remaining registers */
264
                pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r);
265
                pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w);
266
                pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8);
267
        }
268
 
269
        printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is "
270
                "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
271
                drive->name, hwif->channel, drive->select.b.unit,
272
                addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
273
#endif /* CY82C693_DEBUG_LOGS */
274
 
275
        /* first let's calc the pio modes */
276
        pio = ide_get_best_pio_mode(drive, pio, CY82C693_MAX_PIO, NULL);
277
 
278
#if CY82C693_DEBUG_INFO
279
        printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio);
280
#endif /* CY82C693_DEBUG_INFO */
281
 
282
        /* let's calc the values for this PIO mode */
283
        compute_clocks(pio, &pclk);
284
 
285
        /* now let's write  the clocks registers */
286
        if (drive->select.b.unit == 0) {
287
                /*
288
                 * set master drive
289
                 * address setup control register
290
                 * is 32 bit !!!
291
                 */
292
                pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
293
 
294
                addrCtrl &= (~0xF);
295
                addrCtrl |= (unsigned int)pclk.address_time;
296
                pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
297
 
298
                /* now let's set the remaining registers */
299
                pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
300
                pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
301
                pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
302
 
303
                addrCtrl &= 0xF;
304
        } else {
305
                /*
306
                 * set slave drive
307
                 * address setup control register
308
                 * is 32 bit !!!
309
                 */
310
                pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
311
 
312
                addrCtrl &= (~0xF0);
313
                addrCtrl |= ((unsigned int)pclk.address_time<<4);
314
                pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
315
 
316
                /* now let's set the remaining registers */
317
                pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
318
                pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
319
                pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
320
 
321
                addrCtrl >>= 4;
322
                addrCtrl &= 0xF;
323
        }
324
 
325
#if CY82C693_DEBUG_INFO
326
        printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to "
327
                "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
328
                drive->name, hwif->channel, drive->select.b.unit,
329
                addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
330
#endif /* CY82C693_DEBUG_INFO */
331
}
332
 
333
/*
334
 * this function is called during init and is used to setup the cy82c693 chip
335
 */
336
static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name)
337
{
338
        if (PCI_FUNC(dev->devfn) != 1)
339
                return 0;
340
 
341
#ifdef CY82C693_SETDMA_CLOCK
342
        u8 data = 0;
343
#endif /* CY82C693_SETDMA_CLOCK */ 
344
 
345
        /* write info about this verion of the driver */
346
        printk(KERN_INFO CY82_VERSION "\n");
347
 
348
#ifdef CY82C693_SETDMA_CLOCK
349
       /* okay let's set the DMA clock speed */
350
 
351
        outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
352
        data = inb(CY82_DATA_PORT);
353
 
354
#if CY82C693_DEBUG_INFO
355
        printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n",
356
                name, data);
357
#endif /* CY82C693_DEBUG_INFO */
358
 
359
        /*
360
         * for some reason sometimes the DMA controller
361
         * speed is set to ATCLK/2 ???? - we fix this here
362
         *
363
         * note: i don't know what causes this strange behaviour,
364
         *       but even changing the dma speed doesn't solve it :-(
365
         *       the ide performance is still only half the normal speed
366
         *
367
         *       if anybody knows what goes wrong with my machine, please
368
         *       let me know - ASK
369
         */
370
 
371
        data |= 0x03;
372
 
373
        outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
374
        outb(data, CY82_DATA_PORT);
375
 
376
#if CY82C693_DEBUG_INFO
377
        printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n",
378
                name, data);
379
#endif /* CY82C693_DEBUG_INFO */
380
 
381
#endif /* CY82C693_SETDMA_CLOCK */
382
        return 0;
383
}
384
 
385
/*
386
 * the init function - called for each ide channel once
387
 */
388
static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
389
{
390
        hwif->autodma = 0;
391
 
392
        hwif->chipset = ide_cy82c693;
393
        hwif->tuneproc = &cy82c693_tune_drive;
394
 
395
        if (!hwif->dma_base) {
396
                hwif->drives[0].autotune = 1;
397
                hwif->drives[1].autotune = 1;
398
                return;
399
        }
400
 
401
        hwif->atapi_dma = 1;
402
        hwif->mwdma_mask = 0x04;
403
        hwif->swdma_mask = 0x04;
404
 
405
        hwif->ide_dma_on = &cy82c693_ide_dma_on;
406
        if (!noautodma)
407
                hwif->autodma = 1;
408
        hwif->drives[0].autodma = hwif->autodma;
409
        hwif->drives[1].autodma = hwif->autodma;
410
}
411
 
412
static __initdata ide_hwif_t *primary;
413
 
414
void __init init_iops_cy82c693(ide_hwif_t *hwif)
415
{
416
        if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
417
                primary = hwif;
418
        else {
419
                hwif->mate = primary;
420
                hwif->channel = 1;
421
        }
422
}
423
 
424
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
425
{
426
        ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
427
        struct pci_dev *dev2;
428
 
429
        /* CY82C693 is more than only a IDE controller.
430
           Function 1 is primary IDE channel, function 2 - secondary. */
431
        if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
432
            PCI_FUNC(dev->devfn) == 1) {
433
                dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
434
                ide_setup_pci_devices(dev, dev2, d);
435
        }
436
        MOD_INC_USE_COUNT;
437
        return 0;
438
}
439
 
440
static struct pci_device_id cy82c693_pci_tbl[] __devinitdata = {
441
        { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
442
        { 0, },
443
};
444
 
445
static struct pci_driver driver = {
446
        .name           = "Cypress IDE",
447
        .id_table       = cy82c693_pci_tbl,
448
        .probe          = cy82c693_init_one,
449
};
450
 
451
static int cy82c693_ide_init(void)
452
{
453
        return ide_pci_register_driver(&driver);
454
}
455
 
456
static void cy82c693_ide_exit(void)
457
{
458
        ide_pci_unregister_driver(&driver);
459
}
460
 
461
module_init(cy82c693_ide_init);
462
module_exit(cy82c693_ide_exit);
463
 
464
MODULE_AUTHOR("Andreas Krebs, Andre Hedrick");
465
MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE");
466
MODULE_LICENSE("GPL");
467
 
468
EXPORT_NO_SYMBOLS;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.