amd74xx.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/drivers/ide/amd74xx.c Version 0.05 June 9, 2000
  3.  *
  4.  * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
  5.  * May be copied or modified under the terms of the GNU General Public License
  6.  *
  7.  */
  8. #include <linux/config.h>
  9. #include <linux/types.h>
  10. #include <linux/kernel.h>
  11. #include <linux/delay.h>
  12. #include <linux/timer.h>
  13. #include <linux/mm.h>
  14. #include <linux/ioport.h>
  15. #include <linux/blkdev.h>
  16. #include <linux/hdreg.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/init.h>
  19. #include <linux/pci.h>
  20. #include <linux/ide.h>
  21. #include <asm/io.h>
  22. #include <asm/irq.h>
  23. #include "ide_modes.h"
  24. #define DISPLAY_VIPER_TIMINGS
  25. #if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
  26. #include <linux/stat.h>
  27. #include <linux/proc_fs.h>
  28. static int amd74xx_get_info(char *, char **, off_t, int);
  29. extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
  30. extern char *ide_media_verbose(ide_drive_t *);
  31. static struct pci_dev *bmide_dev;
  32. static int amd74xx_get_info (char *buffer, char **addr, off_t offset, int count)
  33. {
  34. char *p = buffer;
  35. u32 bibma = pci_resource_start(bmide_dev, 4);
  36. u8 c0 = 0, c1 = 0;
  37. /*
  38.  * at that point bibma+0x2 et bibma+0xa are byte registers
  39.  * to investigate:
  40.  */
  41. c0 = inb_p((unsigned short)bibma + 0x02);
  42. c1 = inb_p((unsigned short)bibma + 0x0a);
  43. p += sprintf(p, "n                                AMD %04X VIPER Chipset.n", bmide_dev->device);
  44. p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------n");
  45. p += sprintf(p, "                %sabled                         %sabledn",
  46. (c0&0x80) ? "dis" : " en",
  47. (c1&0x80) ? "dis" : " en");
  48. p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------n");
  49. p += sprintf(p, "DMA enabled:    %s              %s             %s               %sn",
  50. (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
  51. (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
  52. p += sprintf(p, "UDMAn");
  53. p += sprintf(p, "DMAn");
  54. p += sprintf(p, "PIOn");
  55. return p-buffer; /* => must be less than 4k! */
  56. }
  57. #endif  /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */
  58. byte amd74xx_proc = 0;
  59. extern char *ide_xfer_verbose (byte xfer_rate);
  60. static unsigned int amd74xx_swdma_check (struct pci_dev *dev)
  61. {
  62. unsigned int class_rev;
  63. if ((dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) ||
  64.     (dev->device == PCI_DEVICE_ID_AMD_VIPER_7441))
  65. return 0;
  66. pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
  67. class_rev &= 0xff;
  68. return ((int) (class_rev >= 7) ? 1 : 0);
  69. }
  70. static int amd74xx_swdma_error(ide_drive_t *drive)
  71. {
  72. printk("%s: single-word DMA not support (revision < C4)n", drive->name);
  73. return 0;
  74. }
  75. /*
  76.  * Here is where all the hard work goes to program the chipset.
  77.  *
  78.  */
  79. static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed)
  80. {
  81. ide_hwif_t *hwif = HWIF(drive);
  82. struct pci_dev *dev = hwif->pci_dev;
  83. int err = 0;
  84. byte unit = (drive->select.b.unit & 0x01);
  85. #ifdef CONFIG_BLK_DEV_IDEDMA
  86. unsigned long dma_base = hwif->dma_base;
  87. #endif /* CONFIG_BLK_DEV_IDEDMA */
  88. byte drive_pci = 0x00;
  89. byte drive_pci2 = 0x00;
  90. byte ultra_timing = 0x00;
  91. byte dma_pio_timing = 0x00;
  92. byte pio_timing = 0x00;
  93.         switch (drive->dn) {
  94. case 0: drive_pci = 0x53; drive_pci2 = 0x4b; break;
  95. case 1: drive_pci = 0x52; drive_pci2 = 0x4a; break;
  96. case 2: drive_pci = 0x51; drive_pci2 = 0x49; break;
  97. case 3: drive_pci = 0x50; drive_pci2 = 0x48; break;
  98. default:
  99.                         return -1;
  100.         }
  101. pci_read_config_byte(dev, drive_pci, &ultra_timing);
  102. pci_read_config_byte(dev, drive_pci2, &dma_pio_timing);
  103. pci_read_config_byte(dev, 0x4c, &pio_timing);
  104. #ifdef DEBUG
  105. printk("%s:%d: Speed 0x%02x UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02xn",
  106. drive->name, drive->dn, speed, ultra_timing, dma_pio_timing, pio_timing);
  107. #endif
  108. ultra_timing &= ~0xC7;
  109. dma_pio_timing &= ~0xFF;
  110. pio_timing &= ~(0x03 << drive->dn);
  111. #ifdef DEBUG
  112. printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02xn",
  113. drive->name, ultra_timing, dma_pio_timing, pio_timing);
  114. #endif
  115. switch(speed) {
  116. #ifdef CONFIG_BLK_DEV_IDEDMA
  117. case XFER_UDMA_7:
  118. case XFER_UDMA_6:
  119. speed = XFER_UDMA_5;
  120. case XFER_UDMA_5:
  121. ultra_timing |= 0x46;
  122. dma_pio_timing |= 0x20;
  123. break;
  124. case XFER_UDMA_4:
  125. ultra_timing |= 0x45;
  126. dma_pio_timing |= 0x20;
  127. break;
  128. case XFER_UDMA_3:
  129. ultra_timing |= 0x44;
  130. dma_pio_timing |= 0x20;
  131. break;
  132. case XFER_UDMA_2:
  133. ultra_timing |= 0x40;
  134. dma_pio_timing |= 0x20;
  135. break;
  136. case XFER_UDMA_1:
  137. ultra_timing |= 0x41;
  138. dma_pio_timing |= 0x20;
  139. break;
  140. case XFER_UDMA_0:
  141. ultra_timing |= 0x42;
  142. dma_pio_timing |= 0x20;
  143. break;
  144. case XFER_MW_DMA_2:
  145. dma_pio_timing |= 0x20;
  146. break;
  147. case XFER_MW_DMA_1:
  148. dma_pio_timing |= 0x21;
  149. break;
  150. case XFER_MW_DMA_0:
  151. dma_pio_timing |= 0x77;
  152. break;
  153. case XFER_SW_DMA_2:
  154. if (!amd74xx_swdma_check(dev))
  155. return amd74xx_swdma_error(drive);
  156. dma_pio_timing |= 0x42;
  157. break;
  158. case XFER_SW_DMA_1:
  159. if (!amd74xx_swdma_check(dev))
  160. return amd74xx_swdma_error(drive);
  161. dma_pio_timing |= 0x65;
  162. break;
  163. case XFER_SW_DMA_0:
  164. if (!amd74xx_swdma_check(dev))
  165. return amd74xx_swdma_error(drive);
  166. dma_pio_timing |= 0xA8;
  167. break;
  168. #endif /* CONFIG_BLK_DEV_IDEDMA */
  169. case XFER_PIO_4:
  170. dma_pio_timing |= 0x20;
  171. break;
  172. case XFER_PIO_3:
  173. dma_pio_timing |= 0x22;
  174. break;
  175. case XFER_PIO_2:
  176. dma_pio_timing |= 0x42;
  177. break;
  178. case XFER_PIO_1:
  179. dma_pio_timing |= 0x65;
  180. break;
  181. case XFER_PIO_0:
  182. default:
  183. dma_pio_timing |= 0xA8;
  184. break;
  185.         }
  186. pio_timing |= (0x03 << drive->dn);
  187. if (!drive->init_speed)
  188. drive->init_speed = speed;
  189. #ifdef CONFIG_BLK_DEV_IDEDMA
  190. pci_write_config_byte(dev, drive_pci, ultra_timing);
  191. #endif /* CONFIG_BLK_DEV_IDEDMA */
  192. pci_write_config_byte(dev, drive_pci2, dma_pio_timing);
  193. pci_write_config_byte(dev, 0x4c, pio_timing);
  194. #ifdef DEBUG
  195. printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02xn",
  196. drive->name, ultra_timing, dma_pio_timing, pio_timing);
  197. #endif
  198. #ifdef CONFIG_BLK_DEV_IDEDMA
  199. if (speed > XFER_PIO_4) {
  200. outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
  201. } else {
  202. outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
  203. }
  204. #endif /* CONFIG_BLK_DEV_IDEDMA */
  205. err = ide_config_drive_speed(drive, speed);
  206. drive->current_speed = speed;
  207. return (err);
  208. }
  209. static void config_chipset_for_pio (ide_drive_t *drive)
  210. {
  211. unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
  212. unsigned short xfer_pio = drive->id->eide_pio_modes;
  213. byte timing, speed, pio;
  214. pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
  215. if (xfer_pio> 4)
  216. xfer_pio = 0;
  217. if (drive->id->eide_pio_iordy > 0) {
  218. for (xfer_pio = 5;
  219. xfer_pio>0 &&
  220. drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
  221. xfer_pio--);
  222. } else {
  223. xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
  224.    (drive->id->eide_pio_modes & 2) ? 0x04 :
  225.    (drive->id->eide_pio_modes & 1) ? 0x03 :
  226.    (drive->id->tPIO & 2) ? 0x02 :
  227.    (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
  228. }
  229. timing = (xfer_pio >= pio) ? xfer_pio : pio;
  230. switch(timing) {
  231. case 4: speed = XFER_PIO_4;break;
  232. case 3: speed = XFER_PIO_3;break;
  233. case 2: speed = XFER_PIO_2;break;
  234. case 1: speed = XFER_PIO_1;break;
  235. default:
  236. speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
  237. break;
  238. }
  239. (void) amd74xx_tune_chipset(drive, speed);
  240. drive->current_speed = speed;
  241. }
  242. static void amd74xx_tune_drive (ide_drive_t *drive, byte pio)
  243. {
  244. byte speed;
  245. switch(pio) {
  246. case 4: speed = XFER_PIO_4;break;
  247. case 3: speed = XFER_PIO_3;break;
  248. case 2: speed = XFER_PIO_2;break;
  249. case 1: speed = XFER_PIO_1;break;
  250. default: speed = XFER_PIO_0;break;
  251. }
  252. (void) amd74xx_tune_chipset(drive, speed);
  253. }
  254. #ifdef CONFIG_BLK_DEV_IDEDMA
  255. /*
  256.  * This allows the configuration of ide_pci chipset registers
  257.  * for cards that learn about the drive's UDMA, DMA, PIO capabilities
  258.  * after the drive is reported by the OS.
  259.  */
  260. static int config_chipset_for_dma (ide_drive_t *drive)
  261. {
  262. ide_hwif_t *hwif = HWIF(drive);
  263. struct pci_dev *dev = hwif->pci_dev;
  264. struct hd_driveid *id = drive->id;
  265. byte udma_66 = eighty_ninty_three(drive);
  266. byte udma_100 = ((dev->device==PCI_DEVICE_ID_AMD_VIPER_7411)||
  267.    (dev->device==PCI_DEVICE_ID_AMD_VIPER_7441)) ? 1 : 0;
  268. byte speed = 0x00;
  269. int  rval;
  270. if (udma_100)
  271. udma_66 = eighty_ninty_three(drive);
  272. if ((id->dma_ultra & 0x0020) && (udma_66) && (udma_100)) {
  273. speed = XFER_UDMA_5;
  274. } else if ((id->dma_ultra & 0x0010) && (udma_66)) {
  275. speed = XFER_UDMA_4;
  276. } else if ((id->dma_ultra & 0x0008) && (udma_66)) {
  277. speed = XFER_UDMA_3;
  278. } else if (id->dma_ultra & 0x0004) {
  279. speed = XFER_UDMA_2;
  280. } else if (id->dma_ultra & 0x0002) {
  281. speed = XFER_UDMA_1;
  282. } else if (id->dma_ultra & 0x0001) {
  283. speed = XFER_UDMA_0;
  284. } else if (id->dma_mword & 0x0004) {
  285. speed = XFER_MW_DMA_2;
  286. } else if (id->dma_mword & 0x0002) {
  287. speed = XFER_MW_DMA_1;
  288. } else if (id->dma_mword & 0x0001) {
  289. speed = XFER_MW_DMA_0;
  290. } else {
  291. return ((int) ide_dma_off_quietly);
  292. }
  293. (void) amd74xx_tune_chipset(drive, speed);
  294. rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
  295. ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
  296. ((id->dma_mword >> 8) & 7) ? ide_dma_on :
  297.      ide_dma_off_quietly);
  298. return rval;
  299. }
  300. static int config_drive_xfer_rate (ide_drive_t *drive)
  301. {
  302. struct hd_driveid *id = drive->id;
  303. ide_dma_action_t dma_func = ide_dma_on;
  304. if (id && (id->capability & 1) && HWIF(drive)->autodma) {
  305. /* Consult the list of known "bad" drives */
  306. if (ide_dmaproc(ide_dma_bad_drive, drive)) {
  307. dma_func = ide_dma_off;
  308. goto fast_ata_pio;
  309. }
  310. dma_func = ide_dma_off_quietly;
  311. if (id->field_valid & 4) {
  312. if (id->dma_ultra & 0x003F) {
  313. /* Force if Capable UltraDMA */
  314. dma_func = config_chipset_for_dma(drive);
  315. if ((id->field_valid & 2) &&
  316.     (dma_func != ide_dma_on))
  317. goto try_dma_modes;
  318. }
  319. } else if (id->field_valid & 2) {
  320. try_dma_modes:
  321. if ((id->dma_mword & 0x0007) ||
  322.     ((id->dma_1word & 0x007) &&
  323.      (amd74xx_swdma_check(HWIF(drive)->pci_dev)))) {
  324. /* Force if Capable regular DMA modes */
  325. dma_func = config_chipset_for_dma(drive);
  326. if (dma_func != ide_dma_on)
  327. goto no_dma_set;
  328. }
  329. } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
  330. if (id->eide_dma_time > 150) {
  331. goto no_dma_set;
  332. }
  333. /* Consult the list of known "good" drives */
  334. dma_func = config_chipset_for_dma(drive);
  335. if (dma_func != ide_dma_on)
  336. goto no_dma_set;
  337. } else {
  338. goto fast_ata_pio;
  339. }
  340. } else if ((id->capability & 8) || (id->field_valid & 2)) {
  341. fast_ata_pio:
  342. dma_func = ide_dma_off_quietly;
  343. no_dma_set:
  344. config_chipset_for_pio(drive);
  345. }
  346. return HWIF(drive)->dmaproc(dma_func, drive);
  347. }
  348. /*
  349.  * amd74xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
  350.  */
  351. int amd74xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
  352. {
  353. switch (func) {
  354. case ide_dma_check:
  355. return config_drive_xfer_rate(drive);
  356. default:
  357. break;
  358. }
  359. return ide_dmaproc(func, drive); /* use standard DMA stuff */
  360. }
  361. #endif /* CONFIG_BLK_DEV_IDEDMA */
  362. unsigned int __init pci_init_amd74xx (struct pci_dev *dev, const char *name)
  363. {
  364. unsigned long fixdma_base = pci_resource_start(dev, 4);
  365. #ifdef CONFIG_BLK_DEV_IDEDMA
  366. if (!amd74xx_swdma_check(dev))
  367. printk("%s: disabling single-word DMA support (revision < C4)n", name);
  368. #endif /* CONFIG_BLK_DEV_IDEDMA */
  369. if (!fixdma_base) {
  370. /*
  371.  *
  372.  */
  373. } else {
  374. /*
  375.  * enable DMA capable bit, and "not" simplex only
  376.  */
  377. outb(inb(fixdma_base+2) & 0x60, fixdma_base+2);
  378. if (inb(fixdma_base+2) & 0x80)
  379. printk("%s: simplex device: DMA will fail!!n", name);
  380. }
  381. #if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
  382. if (!amd74xx_proc) {
  383. amd74xx_proc = 1;
  384. bmide_dev = dev;
  385. amd74xx_display_info = &amd74xx_get_info;
  386. }
  387. #endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */
  388. return 0;
  389. }
  390. unsigned int __init ata66_amd74xx (ide_hwif_t *hwif)
  391. {
  392. struct pci_dev *dev = hwif->pci_dev;
  393. byte cable_80_pin[2] = { 0, 0 };
  394. byte ata66 = 0;
  395. byte tmpbyte;
  396. /*
  397.  * Ultra66 cable detection (from Host View)
  398.  * 7411, 7441, 0x42, bit0: primary, bit2: secondary 80 pin
  399.  */
  400. pci_read_config_byte(dev, 0x42, &tmpbyte);
  401. /*
  402.  * 0x42, bit0 is 1 => primary channel
  403.  * has 80-pin (from host view)
  404.  */
  405. if (tmpbyte & 0x01) cable_80_pin[0] = 1;
  406. /*
  407.  * 0x42, bit2 is 1 => secondary channel
  408.  * has 80-pin (from host view)
  409.  */
  410. if (tmpbyte & 0x04) cable_80_pin[1] = 1;
  411. switch(dev->device) {
  412. case PCI_DEVICE_ID_AMD_VIPER_7441:
  413. case PCI_DEVICE_ID_AMD_VIPER_7411:
  414. ata66 = (hwif->channel) ?
  415. cable_80_pin[1] :
  416. cable_80_pin[0];
  417. default:
  418. break;
  419. }
  420. #ifdef CONFIG_AMD74XX_OVERRIDE
  421. return(1);
  422. #else
  423. return (unsigned int) ata66;
  424. #endif /* CONFIG_AMD74XX_OVERRIDE */
  425. }
  426. void __init ide_init_amd74xx (ide_hwif_t *hwif)
  427. {
  428. hwif->tuneproc = &amd74xx_tune_drive;
  429. hwif->speedproc = &amd74xx_tune_chipset;
  430. #ifndef CONFIG_BLK_DEV_IDEDMA
  431. hwif->drives[0].autotune = 1;
  432. hwif->drives[1].autotune = 1;
  433. hwif->autodma = 0;
  434. return;
  435. #else
  436. if (hwif->dma_base) {
  437. hwif->dmaproc = &amd74xx_dmaproc;
  438. if (!noautodma)
  439. hwif->autodma = 1;
  440. } else {
  441. hwif->autodma = 0;
  442. hwif->drives[0].autotune = 1;
  443. hwif->drives[1].autotune = 1;
  444. }
  445. #endif /* CONFIG_BLK_DEV_IDEDMA */
  446. }
  447. void __init ide_dmacapable_amd74xx (ide_hwif_t *hwif, unsigned long dmabase)
  448. {
  449. ide_setup_dma(hwif, dmabase, 8);
  450. }