linux/drivers/ide/cs5530.c
<<
val.2 val.2>> v val ="+search" method="post" onsubmit="return do_search(this);"> val.2 2<""> val.2 val.2Search val.2Prefs4 .2 v ="ajax+*" method="post" onsubmit="return false;"> v 2<""> al.2 24
2 21/*2 22 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>2 23 * Copyright (C) 2000 Mark Lord <mlord@pobox.com>2 24 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz2 25 *2 26 * May be copied or modified under the terms of the GNU General Public License2 27 *2 28 * Development of this chipset driver was funded2 29 * by the nice folks at Na> al Semiconductor.2 a> *2 11 * Documenta> :2 12 * CS5530 documenta> available from Na> al Semiconductor.2 13 */2 1442 15#include <linux/module.h>42 16#include <linux/typ2s.h>42 17#include <linux/kernel.h>42 18#include <linux/pci.h>42 19#include <linux/init.h>42 20#include <linux/ide.h>42 2142 22#include <asm/io.h>42 2342 24#define2DRV_NAME "cs5530"2 2542 26/*2 27 * Here are the standard PIO mode 0-4 timings for each "format".2 28 * Format-0 uses fast data reg timings, with slower command reg timings.2 29 * Format-1 uses fast timings for all registers, but won't work with all drives.2 3 a> */2 31static unsigned int cs5530_pio_timings[2][5] = {42 32 {0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010},42 33 {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}42 34};42 3542 36/*2 37 * After chip reset, the PIO timings are set to 0x0000e132, which is not > id.2 38 */2 39#define2CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132)42 40#define2CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20))42 4142 42/**2 43 * cs5530_set_pio_mode - set host controller for PIO mode2 44 * @hwif: port2 45 * @drive: drive2 46 *2 47 * Handles setting of PIO mode for the chipset.2 48 *2 49 * The init_hwif_cs5530() routine2guarantees that all drives2 5 a> * will have > id default PIO timings set up before we2get here.2 51 */2 5242 53static void cs5530_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)42 54{42 55 unsigned long basereg =2CS5530_BASEREG(hwif);42 56 unsigned int format =2(inl(basereg + 4) >> 31) & 1;42 57 const u8 pio =2drive->pio_mode - XFER_PIO_0;42 5842 59 outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));42 60}42 6142 62/**2 63 * cs5530_udma_filter - UDMA filter2 64 * @drive: drive2 65 *2 66 * cs5530_udma_filter() does UDMA mask filtering for the given drive2 67 * taking into the considera> capabilities of the mate device.2 68 *2 69 * The CS5530 specifies that two drives sharing a cable cannot mix2 7 a> * UDMA/MDMA. It has to be one2or the other, for the pair, though2 71 * different timings can still be chosen for each drive. We could2 72 * set the appropriate timing bits on the fly, but that might be2 73 * a bit confusing. So, for now we2statically handle this requirement2 74 * by looking at our mate drive to see what it is capable of, before2 75 * choosing a mode for our own drive.2 76 *2 77 * Note: This relies on the fact we2never fail from UDMA to MWDMA22 78 * but instead drop to PIO.2 79 */2 8042 81static u8 cs5530_udma_filter(ide_drive_t *drive)42 82{42 83 ide_hwif_t *hwif =2drive->hwif;42 84 ide_drive_t *mate =2ide_get_pair_dev(drive);42 85 u16 *mateid;42 86 u8 mask =2hwif->ultra_mask;42 8742 88 if2(mate ==2NULL)42 89 goto out;42 90 mateid =2mate->id;42 9142 92 if2(ata_id_has_dma(mateid) && __ide_dma_bad_drive(mate) ==20) {42 93 if2((mateid[ATA_ID_FIELD_VALID] & 4) &&42 94 (mateid[ATA_ID_UDMA_MODES] & 7))42 95 goto out;42 96 if2(mateid[ATA_ID_MWDMA_MODES] & 7)42 97 mask =20;42 98 }42 99out:42100 return mask;42101}4210242103static void cs5530_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)42104{42105 unsigned long basereg;42106 unsigned int reg, timings =20;4210742108 switch2(drive->dma_mode) {42109 case XFER_UDMA_0: timings =20x00921250; break;42110 case XFER_UDMA_1: timings =20x00911140; break;42111 case XFER_UDMA_2: timings =20x00911030; break;42112 case XFER_MW_DMA_0: timings =20x00077771; break;42113 case XFER_MW_DMA_1: timings =20x00012121; break;42114 case XFER_MW_DMA_2: timings =20x00002020; break;42115 }42116 basereg =2CS5530_BASEREG(hwif);42117 reg =2inl(basereg + 4); /*2get drive0 config register */2118 timings |=2reg & 0x80000000; /*2preserve PIO format bit */2119 if2((drive->2dn & 1) ==20) { /*2are we2configuring drive0? */2120 outl(timings, basereg + 4); /*2write drive0 config register */2121 } else {42122 if2(timings & 0x00100000)42123 reg |=2 0x00100000; /*2enable UDMA timings for both drives */2124 else42125 reg &= ~0x00100000; /*2disable UDMA timings for both drives */2126 outl(reg, basereg + 4); /*2write drive0 config register */2127 outl(timings, basereg + 12); /*2write drive1 config register */2128 }42129}4213042131/**2132 * init_chipset_5530 - set up 5530 bridge2133 * @dev: PCI device2134 *2135 * Initialize the cs5530 bridge for reliable IDE DMA opera> .2136 */213742138static int init_chipset_cs5530(struct pci_dev *dev)42139{42140 struct pci_dev *master_0 =2NULL, *cs5530_0 =2NULL;4214142142 if2(pci_resource_start(dev, 4) ==20)42143 return -EFAULT;4214442145 dev =2NULL;42146 while ((dev =2pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) !=2NULL) {42147 switch2(dev->device) {42148 case PCI_DEVICE_ID_CYRIX_PCI_MASTER:42149 master_0 =2pci_dev_get(dev);42150 break;42151 case PCI_DEVICE_ID_CYRIX_5530_LEGACY:42152 cs5530_0 =2pci_dev_get(dev);42153 break;42154 }42155 }42156 if2(!master_0) {42157 printk(KERN_ERR DRV_NAME ": unable to locate PCI MASTER func> \n"2158 goto out;42159 }42160 if2(!cs5530_0) {42161 printk(KERN_ERR DRV_NAME ": unable to locate CS5530 LEGACY func> \n"2162 goto out;42163 }4216442165 /*2166 * Enable BusMaster and MemoryWriteAndIn> idate for the cs5530:2167 * -->2 OR 0x14 into 16-bit PCI COMMAND reg of func> 0 of the cs55302168 */216942170 pci_set_master(cs5530_0);42171 pci_try_set_mwi(cs5530_0);4217242173 /*2174 * Set PCI CacheLineSize to 16-bytes:2175 * -->2Write 0x04 into 8-bit PCI CACHELINESIZE reg of func> 0 of the cs55302176 */217742178 pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04);4217942180 /*2181 * Disable trapping of UDMA register accesses (Win98 hatk)"drivers/ide/cs5530.c#L173" id<"L173" cla href="dr182" class="line" nam2<"L182">2182 * -->2Write 0x5006 into 16-bit reg at offset 0xd0 of func> 0 of the cs55302183 */218442185 pci_write_config_word(cs5530_0, 0xd0, 0x5006);4218642187 /*2188 * Bit-1 at 0x402enables MemoryWriteAndIn> idate inter al X-bus:2189 * The other settings are what is necessary to get the register219 a> * into a sane2state for IDE DMA opera> .2191 */219242193 pci_write_config_byte(master_0, 0x40, 0x1e);4219442195 /* 2196 * Set max PCI burst size (16-bytes seems to work best)"drivers/ide/cs5530.c#L173" id<"L173" cla97" id<"L197" class="line" nam2<"L197">2197 * 16bytes: set bit-1 at 0x41 (reg > ue of 0x16)drivers/ide/cs5530.c#L173" id<"L173" cla98" id<"L198" class="line" nam2<"L198">2198 * all others: clear bit-1 at 0x41, and do"drivers/ide/cs5530.c#L173" id<"L173" cla99" id<"L199" class="line" nam2<"L199">2199 * 128bytes: OR 0x00 at 0x41220 a> * 256bytes: OR 0x04 at 0x412201 * 512bytes: OR 0x08 at 0x412202 * 1024bytes: OR 0x0c at 0x412203 */220442205 pci_write_config_byte(master_0, 0x41, 0x14);4220642207 /*2208 * These settings are necessary to get the chip2209 * into a sane2state for IDE DMA opera> .221 a> */221142212 pci_write_config_byte(master_0, 0x42, 0x00);42213 pci_write_config_byte(master_0, 0x43, 0xc1);4221442215out:42216 pci_dev_put(master_0);42217 pci_dev_put(cs5530_0);42218 return 0;42219}4222042221/**2222 * init_hwif_cs5530 - initialise a IDE channel2222212422a> *212522a> * Inis rel ths.c#voked loo chies:1vers/i oncer each drinnel212622a> * cs5a> mat sinnel212722a> * spa v4212822a>421292/a>}4cs5t_hwif_cs5530 > href="+code=ide_hwif_t" class="sref">ide_hwif_t *hwif, 21302 > a href="drivers/ide/cs5530.c#L1612 id<"L1312 class="line" nam2<"L1312>213123a> basereg;4213223a> XFEu3a> href="+code=dev"0mings" class="sref">cs5"0mings" c>;421332/a>213423a> basereg =2CS5530_BASEREG(hwif);4213523a> cs5"0mings" c>;4<inl(basereg + 4);4213623a> if2(!CS5530_BASERDO_0<>(cs5"0mings" c>;4<213723a> outl(cs5530_pio_timings[cs5"0mings" c>;4basereg + ((<4213823a> if2(CS5530_BASERDO_0<>(inl(basereg + 4);8)213923a> href="+code=outl" class="sref">outl(cs5530_pio_timings[cs5"0mings" c>;4basereg + ((<8214024a>}421412/a>421422/a> tic voist cs5_hwiport_opc> href="+code=dev530_pio_ort_opclass="sref">cs5530_pio_ort_opc>;4<21432/a> .href="+code=dev_pio_mode" class="sref">cs5_pio_mode(cs5530_set_pio_mode(2144244> .href="+code=dev_pio_mode" class="sref">dma_dma_mode(cs5530_set_dma_mode(21452/a> cs5a_filter(cs5530_udma_filter(21462/a> }a href="drivers/ide/cs5530.c#L213" id<"L1372 class="line" nam2<"L1472>214724a>42148248> tic voist pio_hwiport_infc> href="+code=dev530_piopset_cslass="sref">cs5530_udmpset_cs>;4<21492/a> .href="+code=dev2<"Llass="sref">cs52<"L>(DRV_NAME 21502/a> .href="+code=devt_chipset_cslass="sref">cs5t_hwipset_cs>;4<< a href="+code=inlt_chipset_cs5530" class="sref">init_chipset_cs5530(st, href="drivers/ide/cs5530.c#L1612 id<"L1412 class="line" nam2<"L1512>21512/a> .href="+code=devt_chif" class="sref">hwit_chif" c> a href="+code=inlt_chif_cs5530 lass="sref">cs5t_hwif_cs5530 > , href="drivers/ide/cs5530.c#L1612 id<"L1422 class="line" nam2<"L1522>21522/a> .href="+code=dev_ort_opclass="sref">cs5_ort_opc>;4<< a p; 1;href="+code=dev530_pio_ort_opclass="sref">cs5530_pio_ort_opc>;4<, href="drivers/ide/cs5530.c#L1612 id<"L1432 class="line" nam2<"L1532>215325a> .href="+code=devhost_fla class="sref">cs5host_fla c> a href="+code=inlIDE_HFLAG_EGPCIIDE_HFLAG_EG | href="drivers/ide/cs5530.c#L1612 id<"L214" class="line" nam2<"L1542>21542/a> }4< href="+code=outIDE_HFLAG_POST_EGTDESPCIIDE_HFLAG_POST_EGTDES;4<, href="drivers/ide/cs5530.c#L1612 id<"L1352 class="line" nam2<"L1552>215525a> mas_mode" c>;4<< a href="+code=dev_ID__0<4lass="sref">mas_ID__0<4>;4<, href="drivers/ide/cs5530.c#L1612 id<"L1362 class="line" nam2<"L1562>21562/a> if2.href="+code=devmw_mode" class="sref">maskw_mode" c> a href="+code=inl_ID_MA2mas_ID_MA221572/a> .href="+code=deva_filk" class="sref">ultr_mode" c> a href="+code=inl_ID_U2mas_ID_U221582/a> }a href="drivers/ide/cs5530.c#L213" id<"L1592 class="line" nam2<"L1592>215925a>421602/a> tic int cs5530_sett_hwionc>(pci_dev *dev)4<,ist mat_dev *id;421612/a> a href="drivers/ide/cs5530.c#L1612 id<"L1622 class="line" nam2<"L1622>21622/a> urn cs5_hwipdevt_hwionc>(dev)4<,ip; 1;href="+code=dev530_piopset_cslass="sref">cs5530_udmpset_cs>;4NULL) {4a href="drivers/ide/cs5530.c#L213" id<"L1632 class="line" nam2<"L1632>21632/a> a href="drivers/ide/cs5530.c#L61"2 id<"L1642 class="line" nam2<"L1642>21642/a>421652/a> tic voist mat_dev *out530_pio_try_bc>[216626a> if2{ href="+code=PCI_CACVICE_IDlass="sref">out_CACVICE_ID>(PCIIX, PCI_ANYICE_ID_CYRIX_5530_LEGI) {4, 0 }, href="drivers/ide/cs5530.c#L1612 id<"L1672 class="line" nam2<"L1672>2167267> if2{ 0, }, href="drivers/ide/cs5530.c#L1612 id<"L1482 class="line" nam2<"L1682>216826a> }a href="drivers/ide/cs5530.c#L213" id<"L1692 class="line" nam2<"L1692>216926a>PCIES(mat_de>, out530_pio_try_bc>[217027a>4217127a>static mat_dev *mat530_pio_try;4<217227a> .href="+code=dev2<"Llass="sref">cs52<"L>(": u530 LEGI217327a> .href="+code=devid_tes Mlass="sref">cs5_h_tes M>;4<< a href="+code=dev530_pio_try_bclass="sref">out530_pio_try_bc>[2174274> .href="+code=devseobclass="sref">pci_eobc>(cs5530_sett_hwionc>(217527a> driremo c>(drithwipdevremo c>(217627a> if2.href="+code=devsuspenclass="sref">matsuspenc> if2a href="+code=inlthwipdevsuspenclass="sref">matthwipdevsuspenc>(217727a> .href="+code=devresu"Llass="sref">cs5resu"L>(cs5thwipdevresu"L>(217827a> }a href="drivers/ide/cs5530.c#L213" id<"L1792 class="line" nam2<"L1792>21792/a>4218028a> tic int cs5_tt_hw> *cs5530_piothwit_hw>(218128a> a href="drivers/ide/cs5530.c#L1612ef="dr1822 class="line" nam2<"L1822>218228a> urn mat_hwipdevister(mat530_pio_try;4<4a href="drivers/ide/cs5530.c#L213" id<"L1832 class="line" nam2<"L1832>218328a> a href="drivers/ide/cs5530.c#L61"2 id<"L1842 class="line" nam2<"L1842>21842/a>4218528a> tic void cs5_texhw> *cs5530_piothwiexhw>(21862/a>4218728a> mat_devunister(mat530_pio_try;4<4a href="drivers/ide/cs5530.c#L213" id<"L1482 class="line" nam2<"L1882>21882/a>218928a>4219 2 a>cs5modulwit_hw>(cs5530_piothwit_hw>(21912/a>cs5modulwiexhw>(cs5530_piothwiexhw>(21922/a>421932/a> href="+code=outESKERES(": uMark Lordot;21942/a>4PCIES(": u deviers/i modulwr eacCyrix/NS 0 LEGI219529a>PCIES(": uGPLot;21962/a> a/div> otherigi X-bLXR softw necloo chihref="drihttp://rce_st eage.net/projects/lxcl>LXR mentu_hwy>, X-bs/id capbyihref="drimailto:lxc@e" ux.no">lxc@e" ux.no>, <. a/div> lxc.e" ux.no kindly hosted loohref="drihttp://www.redpill-e" pro.no">Redpill L" pro AS>, .