1669a5db4SJeff Garzik /* 2669a5db4SJeff Garzik * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers. 3669a5db4SJeff Garzik * 4669a5db4SJeff Garzik * This driver is heavily based upon: 5669a5db4SJeff Garzik * 6669a5db4SJeff Garzik * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 7669a5db4SJeff Garzik * 8669a5db4SJeff Garzik * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> 9669a5db4SJeff Garzik * Portions Copyright (C) 2001 Sun Microsystems, Inc. 10669a5db4SJeff Garzik * Portions Copyright (C) 2003 Red Hat Inc 11669a5db4SJeff Garzik * 12669a5db4SJeff Garzik * TODO 13669a5db4SJeff Garzik * PLL mode 14669a5db4SJeff Garzik * Look into engine reset on timeout errors. Should not be 15669a5db4SJeff Garzik * required. 16669a5db4SJeff Garzik */ 17669a5db4SJeff Garzik 18669a5db4SJeff Garzik #include <linux/kernel.h> 19669a5db4SJeff Garzik #include <linux/module.h> 20669a5db4SJeff Garzik #include <linux/pci.h> 21669a5db4SJeff Garzik #include <linux/init.h> 22669a5db4SJeff Garzik #include <linux/blkdev.h> 23669a5db4SJeff Garzik #include <linux/delay.h> 24669a5db4SJeff Garzik #include <scsi/scsi_host.h> 25669a5db4SJeff Garzik #include <linux/libata.h> 26669a5db4SJeff Garzik 27669a5db4SJeff Garzik #define DRV_NAME "pata_hpt37x" 286929da44SAlan #define DRV_VERSION "0.5.2" 29669a5db4SJeff Garzik 30669a5db4SJeff Garzik struct hpt_clock { 31669a5db4SJeff Garzik u8 xfer_speed; 32669a5db4SJeff Garzik u32 timing; 33669a5db4SJeff Garzik }; 34669a5db4SJeff Garzik 35669a5db4SJeff Garzik struct hpt_chip { 36669a5db4SJeff Garzik const char *name; 37669a5db4SJeff Garzik unsigned int base; 38669a5db4SJeff Garzik struct hpt_clock const *clocks[4]; 39669a5db4SJeff Garzik }; 40669a5db4SJeff Garzik 41669a5db4SJeff Garzik /* key for bus clock timings 42669a5db4SJeff Garzik * bit 43669a5db4SJeff Garzik * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW 44669a5db4SJeff Garzik * DMA. cycles = value + 1 45669a5db4SJeff Garzik * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW 46669a5db4SJeff Garzik * DMA. cycles = value + 1 47669a5db4SJeff Garzik * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file 48669a5db4SJeff Garzik * register access. 49669a5db4SJeff Garzik * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file 50669a5db4SJeff Garzik * register access. 51669a5db4SJeff Garzik * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. 52669a5db4SJeff Garzik * during task file register access. 53669a5db4SJeff Garzik * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA 54669a5db4SJeff Garzik * xfer. 55669a5db4SJeff Garzik * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task 56669a5db4SJeff Garzik * register access. 57669a5db4SJeff Garzik * 28 UDMA enable 58669a5db4SJeff Garzik * 29 DMA enable 59669a5db4SJeff Garzik * 30 PIO_MST enable. if set, the chip is in bus master mode during 60669a5db4SJeff Garzik * PIO. 61669a5db4SJeff Garzik * 31 FIFO enable. 62669a5db4SJeff Garzik */ 63669a5db4SJeff Garzik 64669a5db4SJeff Garzik /* from highpoint documentation. these are old values */ 65669a5db4SJeff Garzik static const struct hpt_clock hpt370_timings_33[] = { 66669a5db4SJeff Garzik /* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */ 67669a5db4SJeff Garzik { XFER_UDMA_5, 0x16454e31 }, 68669a5db4SJeff Garzik { XFER_UDMA_4, 0x16454e31 }, 69669a5db4SJeff Garzik { XFER_UDMA_3, 0x166d4e31 }, 70669a5db4SJeff Garzik { XFER_UDMA_2, 0x16494e31 }, 71669a5db4SJeff Garzik { XFER_UDMA_1, 0x164d4e31 }, 72669a5db4SJeff Garzik { XFER_UDMA_0, 0x16514e31 }, 73669a5db4SJeff Garzik 74669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x26514e21 }, 75669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x26514e33 }, 76669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x26514e97 }, 77669a5db4SJeff Garzik 78669a5db4SJeff Garzik { XFER_PIO_4, 0x06514e21 }, 79669a5db4SJeff Garzik { XFER_PIO_3, 0x06514e22 }, 80669a5db4SJeff Garzik { XFER_PIO_2, 0x06514e33 }, 81669a5db4SJeff Garzik { XFER_PIO_1, 0x06914e43 }, 82669a5db4SJeff Garzik { XFER_PIO_0, 0x06914e57 }, 83669a5db4SJeff Garzik { 0, 0x06514e57 } 84669a5db4SJeff Garzik }; 85669a5db4SJeff Garzik 86669a5db4SJeff Garzik static const struct hpt_clock hpt370_timings_66[] = { 87669a5db4SJeff Garzik { XFER_UDMA_5, 0x14846231 }, 88669a5db4SJeff Garzik { XFER_UDMA_4, 0x14886231 }, 89669a5db4SJeff Garzik { XFER_UDMA_3, 0x148c6231 }, 90669a5db4SJeff Garzik { XFER_UDMA_2, 0x148c6231 }, 91669a5db4SJeff Garzik { XFER_UDMA_1, 0x14906231 }, 92669a5db4SJeff Garzik { XFER_UDMA_0, 0x14986231 }, 93669a5db4SJeff Garzik 94669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x26514e21 }, 95669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x26514e33 }, 96669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x26514e97 }, 97669a5db4SJeff Garzik 98669a5db4SJeff Garzik { XFER_PIO_4, 0x06514e21 }, 99669a5db4SJeff Garzik { XFER_PIO_3, 0x06514e22 }, 100669a5db4SJeff Garzik { XFER_PIO_2, 0x06514e33 }, 101669a5db4SJeff Garzik { XFER_PIO_1, 0x06914e43 }, 102669a5db4SJeff Garzik { XFER_PIO_0, 0x06914e57 }, 103669a5db4SJeff Garzik { 0, 0x06514e57 } 104669a5db4SJeff Garzik }; 105669a5db4SJeff Garzik 106669a5db4SJeff Garzik /* these are the current (4 sep 2001) timings from highpoint */ 107669a5db4SJeff Garzik static const struct hpt_clock hpt370a_timings_33[] = { 108669a5db4SJeff Garzik { XFER_UDMA_5, 0x12446231 }, 109669a5db4SJeff Garzik { XFER_UDMA_4, 0x12446231 }, 110669a5db4SJeff Garzik { XFER_UDMA_3, 0x126c6231 }, 111669a5db4SJeff Garzik { XFER_UDMA_2, 0x12486231 }, 112669a5db4SJeff Garzik { XFER_UDMA_1, 0x124c6233 }, 113669a5db4SJeff Garzik { XFER_UDMA_0, 0x12506297 }, 114669a5db4SJeff Garzik 115669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x22406c31 }, 116669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x22406c33 }, 117669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x22406c97 }, 118669a5db4SJeff Garzik 119669a5db4SJeff Garzik { XFER_PIO_4, 0x06414e31 }, 120669a5db4SJeff Garzik { XFER_PIO_3, 0x06414e42 }, 121669a5db4SJeff Garzik { XFER_PIO_2, 0x06414e53 }, 122669a5db4SJeff Garzik { XFER_PIO_1, 0x06814e93 }, 123669a5db4SJeff Garzik { XFER_PIO_0, 0x06814ea7 }, 124669a5db4SJeff Garzik { 0, 0x06814ea7 } 125669a5db4SJeff Garzik }; 126669a5db4SJeff Garzik 127669a5db4SJeff Garzik /* 2x 33MHz timings */ 128669a5db4SJeff Garzik static const struct hpt_clock hpt370a_timings_66[] = { 129669a5db4SJeff Garzik { XFER_UDMA_5, 0x1488e673 }, 130669a5db4SJeff Garzik { XFER_UDMA_4, 0x1488e673 }, 131669a5db4SJeff Garzik { XFER_UDMA_3, 0x1498e673 }, 132669a5db4SJeff Garzik { XFER_UDMA_2, 0x1490e673 }, 133669a5db4SJeff Garzik { XFER_UDMA_1, 0x1498e677 }, 134669a5db4SJeff Garzik { XFER_UDMA_0, 0x14a0e73f }, 135669a5db4SJeff Garzik 136669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x2480fa73 }, 137669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x2480fa77 }, 138669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x2480fb3f }, 139669a5db4SJeff Garzik 140669a5db4SJeff Garzik { XFER_PIO_4, 0x0c82be73 }, 141669a5db4SJeff Garzik { XFER_PIO_3, 0x0c82be95 }, 142669a5db4SJeff Garzik { XFER_PIO_2, 0x0c82beb7 }, 143669a5db4SJeff Garzik { XFER_PIO_1, 0x0d02bf37 }, 144669a5db4SJeff Garzik { XFER_PIO_0, 0x0d02bf5f }, 145669a5db4SJeff Garzik { 0, 0x0d02bf5f } 146669a5db4SJeff Garzik }; 147669a5db4SJeff Garzik 148669a5db4SJeff Garzik static const struct hpt_clock hpt370a_timings_50[] = { 149669a5db4SJeff Garzik { XFER_UDMA_5, 0x12848242 }, 150669a5db4SJeff Garzik { XFER_UDMA_4, 0x12ac8242 }, 151669a5db4SJeff Garzik { XFER_UDMA_3, 0x128c8242 }, 152669a5db4SJeff Garzik { XFER_UDMA_2, 0x120c8242 }, 153669a5db4SJeff Garzik { XFER_UDMA_1, 0x12148254 }, 154669a5db4SJeff Garzik { XFER_UDMA_0, 0x121882ea }, 155669a5db4SJeff Garzik 156669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x22808242 }, 157669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x22808254 }, 158669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x228082ea }, 159669a5db4SJeff Garzik 160669a5db4SJeff Garzik { XFER_PIO_4, 0x0a81f442 }, 161669a5db4SJeff Garzik { XFER_PIO_3, 0x0a81f443 }, 162669a5db4SJeff Garzik { XFER_PIO_2, 0x0a81f454 }, 163669a5db4SJeff Garzik { XFER_PIO_1, 0x0ac1f465 }, 164669a5db4SJeff Garzik { XFER_PIO_0, 0x0ac1f48a }, 165669a5db4SJeff Garzik { 0, 0x0ac1f48a } 166669a5db4SJeff Garzik }; 167669a5db4SJeff Garzik 168669a5db4SJeff Garzik static const struct hpt_clock hpt372_timings_33[] = { 169669a5db4SJeff Garzik { XFER_UDMA_6, 0x1c81dc62 }, 170669a5db4SJeff Garzik { XFER_UDMA_5, 0x1c6ddc62 }, 171669a5db4SJeff Garzik { XFER_UDMA_4, 0x1c8ddc62 }, 172669a5db4SJeff Garzik { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ 173669a5db4SJeff Garzik { XFER_UDMA_2, 0x1c91dc62 }, 174669a5db4SJeff Garzik { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ 175669a5db4SJeff Garzik { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ 176669a5db4SJeff Garzik 177669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x2c829262 }, 178669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ 179669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ 180669a5db4SJeff Garzik 181669a5db4SJeff Garzik { XFER_PIO_4, 0x0c829c62 }, 182669a5db4SJeff Garzik { XFER_PIO_3, 0x0c829c84 }, 183669a5db4SJeff Garzik { XFER_PIO_2, 0x0c829ca6 }, 184669a5db4SJeff Garzik { XFER_PIO_1, 0x0d029d26 }, 185669a5db4SJeff Garzik { XFER_PIO_0, 0x0d029d5e }, 186669a5db4SJeff Garzik { 0, 0x0d029d5e } 187669a5db4SJeff Garzik }; 188669a5db4SJeff Garzik 189669a5db4SJeff Garzik static const struct hpt_clock hpt372_timings_50[] = { 190669a5db4SJeff Garzik { XFER_UDMA_5, 0x12848242 }, 191669a5db4SJeff Garzik { XFER_UDMA_4, 0x12ac8242 }, 192669a5db4SJeff Garzik { XFER_UDMA_3, 0x128c8242 }, 193669a5db4SJeff Garzik { XFER_UDMA_2, 0x120c8242 }, 194669a5db4SJeff Garzik { XFER_UDMA_1, 0x12148254 }, 195669a5db4SJeff Garzik { XFER_UDMA_0, 0x121882ea }, 196669a5db4SJeff Garzik 197669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x22808242 }, 198669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x22808254 }, 199669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x228082ea }, 200669a5db4SJeff Garzik 201669a5db4SJeff Garzik { XFER_PIO_4, 0x0a81f442 }, 202669a5db4SJeff Garzik { XFER_PIO_3, 0x0a81f443 }, 203669a5db4SJeff Garzik { XFER_PIO_2, 0x0a81f454 }, 204669a5db4SJeff Garzik { XFER_PIO_1, 0x0ac1f465 }, 205669a5db4SJeff Garzik { XFER_PIO_0, 0x0ac1f48a }, 206669a5db4SJeff Garzik { 0, 0x0a81f443 } 207669a5db4SJeff Garzik }; 208669a5db4SJeff Garzik 209669a5db4SJeff Garzik static const struct hpt_clock hpt372_timings_66[] = { 210669a5db4SJeff Garzik { XFER_UDMA_6, 0x1c869c62 }, 211669a5db4SJeff Garzik { XFER_UDMA_5, 0x1cae9c62 }, 212669a5db4SJeff Garzik { XFER_UDMA_4, 0x1c8a9c62 }, 213669a5db4SJeff Garzik { XFER_UDMA_3, 0x1c8e9c62 }, 214669a5db4SJeff Garzik { XFER_UDMA_2, 0x1c929c62 }, 215669a5db4SJeff Garzik { XFER_UDMA_1, 0x1c9a9c62 }, 216669a5db4SJeff Garzik { XFER_UDMA_0, 0x1c829c62 }, 217669a5db4SJeff Garzik 218669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x2c829c62 }, 219669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x2c829c66 }, 220669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x2c829d2e }, 221669a5db4SJeff Garzik 222669a5db4SJeff Garzik { XFER_PIO_4, 0x0c829c62 }, 223669a5db4SJeff Garzik { XFER_PIO_3, 0x0c829c84 }, 224669a5db4SJeff Garzik { XFER_PIO_2, 0x0c829ca6 }, 225669a5db4SJeff Garzik { XFER_PIO_1, 0x0d029d26 }, 226669a5db4SJeff Garzik { XFER_PIO_0, 0x0d029d5e }, 227669a5db4SJeff Garzik { 0, 0x0d029d26 } 228669a5db4SJeff Garzik }; 229669a5db4SJeff Garzik 230669a5db4SJeff Garzik static const struct hpt_clock hpt374_timings_33[] = { 231669a5db4SJeff Garzik { XFER_UDMA_6, 0x12808242 }, 232669a5db4SJeff Garzik { XFER_UDMA_5, 0x12848242 }, 233669a5db4SJeff Garzik { XFER_UDMA_4, 0x12ac8242 }, 234669a5db4SJeff Garzik { XFER_UDMA_3, 0x128c8242 }, 235669a5db4SJeff Garzik { XFER_UDMA_2, 0x120c8242 }, 236669a5db4SJeff Garzik { XFER_UDMA_1, 0x12148254 }, 237669a5db4SJeff Garzik { XFER_UDMA_0, 0x121882ea }, 238669a5db4SJeff Garzik 239669a5db4SJeff Garzik { XFER_MW_DMA_2, 0x22808242 }, 240669a5db4SJeff Garzik { XFER_MW_DMA_1, 0x22808254 }, 241669a5db4SJeff Garzik { XFER_MW_DMA_0, 0x228082ea }, 242669a5db4SJeff Garzik 243669a5db4SJeff Garzik { XFER_PIO_4, 0x0a81f442 }, 244669a5db4SJeff Garzik { XFER_PIO_3, 0x0a81f443 }, 245669a5db4SJeff Garzik { XFER_PIO_2, 0x0a81f454 }, 246669a5db4SJeff Garzik { XFER_PIO_1, 0x0ac1f465 }, 247669a5db4SJeff Garzik { XFER_PIO_0, 0x0ac1f48a }, 248669a5db4SJeff Garzik { 0, 0x06814e93 } 249669a5db4SJeff Garzik }; 250669a5db4SJeff Garzik 251669a5db4SJeff Garzik static const struct hpt_chip hpt370 = { 252669a5db4SJeff Garzik "HPT370", 253669a5db4SJeff Garzik 48, 254669a5db4SJeff Garzik { 255669a5db4SJeff Garzik hpt370_timings_33, 256669a5db4SJeff Garzik NULL, 257669a5db4SJeff Garzik NULL, 258669a5db4SJeff Garzik hpt370_timings_66 259669a5db4SJeff Garzik } 260669a5db4SJeff Garzik }; 261669a5db4SJeff Garzik 262669a5db4SJeff Garzik static const struct hpt_chip hpt370a = { 263669a5db4SJeff Garzik "HPT370A", 264669a5db4SJeff Garzik 48, 265669a5db4SJeff Garzik { 266669a5db4SJeff Garzik hpt370a_timings_33, 267669a5db4SJeff Garzik NULL, 268669a5db4SJeff Garzik hpt370a_timings_50, 269669a5db4SJeff Garzik hpt370a_timings_66 270669a5db4SJeff Garzik } 271669a5db4SJeff Garzik }; 272669a5db4SJeff Garzik 273669a5db4SJeff Garzik static const struct hpt_chip hpt372 = { 274669a5db4SJeff Garzik "HPT372", 275669a5db4SJeff Garzik 55, 276669a5db4SJeff Garzik { 277669a5db4SJeff Garzik hpt372_timings_33, 278669a5db4SJeff Garzik NULL, 279669a5db4SJeff Garzik hpt372_timings_50, 280669a5db4SJeff Garzik hpt372_timings_66 281669a5db4SJeff Garzik } 282669a5db4SJeff Garzik }; 283669a5db4SJeff Garzik 284669a5db4SJeff Garzik static const struct hpt_chip hpt302 = { 285669a5db4SJeff Garzik "HPT302", 286669a5db4SJeff Garzik 66, 287669a5db4SJeff Garzik { 288669a5db4SJeff Garzik hpt372_timings_33, 289669a5db4SJeff Garzik NULL, 290669a5db4SJeff Garzik hpt372_timings_50, 291669a5db4SJeff Garzik hpt372_timings_66 292669a5db4SJeff Garzik } 293669a5db4SJeff Garzik }; 294669a5db4SJeff Garzik 295669a5db4SJeff Garzik static const struct hpt_chip hpt371 = { 296669a5db4SJeff Garzik "HPT371", 297669a5db4SJeff Garzik 66, 298669a5db4SJeff Garzik { 299669a5db4SJeff Garzik hpt372_timings_33, 300669a5db4SJeff Garzik NULL, 301669a5db4SJeff Garzik hpt372_timings_50, 302669a5db4SJeff Garzik hpt372_timings_66 303669a5db4SJeff Garzik } 304669a5db4SJeff Garzik }; 305669a5db4SJeff Garzik 306669a5db4SJeff Garzik static const struct hpt_chip hpt372a = { 307669a5db4SJeff Garzik "HPT372A", 308669a5db4SJeff Garzik 66, 309669a5db4SJeff Garzik { 310669a5db4SJeff Garzik hpt372_timings_33, 311669a5db4SJeff Garzik NULL, 312669a5db4SJeff Garzik hpt372_timings_50, 313669a5db4SJeff Garzik hpt372_timings_66 314669a5db4SJeff Garzik } 315669a5db4SJeff Garzik }; 316669a5db4SJeff Garzik 317669a5db4SJeff Garzik static const struct hpt_chip hpt374 = { 318669a5db4SJeff Garzik "HPT374", 319669a5db4SJeff Garzik 48, 320669a5db4SJeff Garzik { 321669a5db4SJeff Garzik hpt374_timings_33, 322669a5db4SJeff Garzik NULL, 323669a5db4SJeff Garzik NULL, 324669a5db4SJeff Garzik NULL 325669a5db4SJeff Garzik } 326669a5db4SJeff Garzik }; 327669a5db4SJeff Garzik 328669a5db4SJeff Garzik /** 329669a5db4SJeff Garzik * hpt37x_find_mode - reset the hpt37x bus 330669a5db4SJeff Garzik * @ap: ATA port 331669a5db4SJeff Garzik * @speed: transfer mode 332669a5db4SJeff Garzik * 333669a5db4SJeff Garzik * Return the 32bit register programming information for this channel 334669a5db4SJeff Garzik * that matches the speed provided. 335669a5db4SJeff Garzik */ 336669a5db4SJeff Garzik 337669a5db4SJeff Garzik static u32 hpt37x_find_mode(struct ata_port *ap, int speed) 338669a5db4SJeff Garzik { 339669a5db4SJeff Garzik struct hpt_clock *clocks = ap->host->private_data; 340669a5db4SJeff Garzik 341669a5db4SJeff Garzik while(clocks->xfer_speed) { 342669a5db4SJeff Garzik if (clocks->xfer_speed == speed) 343669a5db4SJeff Garzik return clocks->timing; 344669a5db4SJeff Garzik clocks++; 345669a5db4SJeff Garzik } 346669a5db4SJeff Garzik BUG(); 347669a5db4SJeff Garzik return 0xffffffffU; /* silence compiler warning */ 348669a5db4SJeff Garzik } 349669a5db4SJeff Garzik 350669a5db4SJeff Garzik static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) 351669a5db4SJeff Garzik { 352669a5db4SJeff Garzik unsigned char model_num[40]; 353669a5db4SJeff Garzik char *s; 354669a5db4SJeff Garzik unsigned int len; 355669a5db4SJeff Garzik int i = 0; 356669a5db4SJeff Garzik 357669a5db4SJeff Garzik ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, 358669a5db4SJeff Garzik sizeof(model_num)); 359669a5db4SJeff Garzik s = &model_num[0]; 360669a5db4SJeff Garzik len = strnlen(s, sizeof(model_num)); 361669a5db4SJeff Garzik 362669a5db4SJeff Garzik /* ATAPI specifies that empty space is blank-filled; remove blanks */ 363669a5db4SJeff Garzik while ((len > 0) && (s[len - 1] == ' ')) { 364669a5db4SJeff Garzik len--; 365669a5db4SJeff Garzik s[len] = 0; 366669a5db4SJeff Garzik } 367669a5db4SJeff Garzik 368669a5db4SJeff Garzik while(list[i] != NULL) { 369669a5db4SJeff Garzik if (!strncmp(list[i], s, len)) { 370669a5db4SJeff Garzik printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n", 371669a5db4SJeff Garzik modestr, list[i]); 372669a5db4SJeff Garzik return 1; 373669a5db4SJeff Garzik } 374669a5db4SJeff Garzik i++; 375669a5db4SJeff Garzik } 376669a5db4SJeff Garzik return 0; 377669a5db4SJeff Garzik } 378669a5db4SJeff Garzik 379669a5db4SJeff Garzik static const char *bad_ata33[] = { 380669a5db4SJeff Garzik "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", 381669a5db4SJeff Garzik "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", 382669a5db4SJeff Garzik "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", 383669a5db4SJeff Garzik "Maxtor 90510D4", 384669a5db4SJeff Garzik "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", 385669a5db4SJeff Garzik "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", 386669a5db4SJeff Garzik "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", 387669a5db4SJeff Garzik NULL 388669a5db4SJeff Garzik }; 389669a5db4SJeff Garzik 390669a5db4SJeff Garzik static const char *bad_ata100_5[] = { 391669a5db4SJeff Garzik "IBM-DTLA-307075", 392669a5db4SJeff Garzik "IBM-DTLA-307060", 393669a5db4SJeff Garzik "IBM-DTLA-307045", 394669a5db4SJeff Garzik "IBM-DTLA-307030", 395669a5db4SJeff Garzik "IBM-DTLA-307020", 396669a5db4SJeff Garzik "IBM-DTLA-307015", 397669a5db4SJeff Garzik "IBM-DTLA-305040", 398669a5db4SJeff Garzik "IBM-DTLA-305030", 399669a5db4SJeff Garzik "IBM-DTLA-305020", 400669a5db4SJeff Garzik "IC35L010AVER07-0", 401669a5db4SJeff Garzik "IC35L020AVER07-0", 402669a5db4SJeff Garzik "IC35L030AVER07-0", 403669a5db4SJeff Garzik "IC35L040AVER07-0", 404669a5db4SJeff Garzik "IC35L060AVER07-0", 405669a5db4SJeff Garzik "WDC AC310200R", 406669a5db4SJeff Garzik NULL 407669a5db4SJeff Garzik }; 408669a5db4SJeff Garzik 409669a5db4SJeff Garzik /** 410669a5db4SJeff Garzik * hpt370_filter - mode selection filter 411669a5db4SJeff Garzik * @ap: ATA interface 412669a5db4SJeff Garzik * @adev: ATA device 413669a5db4SJeff Garzik * 414669a5db4SJeff Garzik * Block UDMA on devices that cause trouble with this controller. 415669a5db4SJeff Garzik */ 416669a5db4SJeff Garzik 417669a5db4SJeff Garzik static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) 418669a5db4SJeff Garzik { 4196929da44SAlan if (adev->class == ATA_DEV_ATA) { 420669a5db4SJeff Garzik if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) 421669a5db4SJeff Garzik mask &= ~ATA_MASK_UDMA; 422669a5db4SJeff Garzik if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) 423669a5db4SJeff Garzik mask &= ~(0x1F << ATA_SHIFT_UDMA); 424669a5db4SJeff Garzik } 425669a5db4SJeff Garzik return ata_pci_default_filter(ap, adev, mask); 426669a5db4SJeff Garzik } 427669a5db4SJeff Garzik 428669a5db4SJeff Garzik /** 429669a5db4SJeff Garzik * hpt370a_filter - mode selection filter 430669a5db4SJeff Garzik * @ap: ATA interface 431669a5db4SJeff Garzik * @adev: ATA device 432669a5db4SJeff Garzik * 433669a5db4SJeff Garzik * Block UDMA on devices that cause trouble with this controller. 434669a5db4SJeff Garzik */ 435669a5db4SJeff Garzik 436669a5db4SJeff Garzik static unsigned long hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask) 437669a5db4SJeff Garzik { 438669a5db4SJeff Garzik if (adev->class != ATA_DEV_ATA) { 439669a5db4SJeff Garzik if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) 440669a5db4SJeff Garzik mask &= ~ (0x1F << ATA_SHIFT_UDMA); 441669a5db4SJeff Garzik } 442669a5db4SJeff Garzik return ata_pci_default_filter(ap, adev, mask); 443669a5db4SJeff Garzik } 444669a5db4SJeff Garzik 445669a5db4SJeff Garzik /** 446669a5db4SJeff Garzik * hpt37x_pre_reset - reset the hpt37x bus 447669a5db4SJeff Garzik * @ap: ATA port to reset 448669a5db4SJeff Garzik * 449669a5db4SJeff Garzik * Perform the initial reset handling for the 370/372 and 374 func 0 450669a5db4SJeff Garzik */ 451669a5db4SJeff Garzik 452669a5db4SJeff Garzik static int hpt37x_pre_reset(struct ata_port *ap) 453669a5db4SJeff Garzik { 454669a5db4SJeff Garzik u8 scr2, ata66; 455669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 456b5bf24b9SAlan Cox static const struct pci_bits hpt37x_enable_bits[] = { 457b5bf24b9SAlan Cox { 0x50, 1, 0x04, 0x04 }, 458b5bf24b9SAlan Cox { 0x54, 1, 0x04, 0x04 } 459b5bf24b9SAlan Cox }; 460b5bf24b9SAlan Cox if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) 461b5bf24b9SAlan Cox return -ENOENT; 462669a5db4SJeff Garzik 463669a5db4SJeff Garzik pci_read_config_byte(pdev, 0x5B, &scr2); 464669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); 465669a5db4SJeff Garzik /* Cable register now active */ 466669a5db4SJeff Garzik pci_read_config_byte(pdev, 0x5A, &ata66); 467669a5db4SJeff Garzik /* Restore state */ 468669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x5B, scr2); 469669a5db4SJeff Garzik 470669a5db4SJeff Garzik if (ata66 & (1 << ap->port_no)) 471669a5db4SJeff Garzik ap->cbl = ATA_CBL_PATA40; 472669a5db4SJeff Garzik else 473669a5db4SJeff Garzik ap->cbl = ATA_CBL_PATA80; 474669a5db4SJeff Garzik 475669a5db4SJeff Garzik /* Reset the state machine */ 476669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x50, 0x37); 477669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x54, 0x37); 478669a5db4SJeff Garzik udelay(100); 479669a5db4SJeff Garzik 480669a5db4SJeff Garzik return ata_std_prereset(ap); 481669a5db4SJeff Garzik } 482669a5db4SJeff Garzik 483669a5db4SJeff Garzik /** 484669a5db4SJeff Garzik * hpt37x_error_handler - reset the hpt374 485669a5db4SJeff Garzik * @ap: ATA port to reset 486669a5db4SJeff Garzik * 487669a5db4SJeff Garzik * Perform probe for HPT37x, except for HPT374 channel 2 488669a5db4SJeff Garzik */ 489669a5db4SJeff Garzik 490669a5db4SJeff Garzik static void hpt37x_error_handler(struct ata_port *ap) 491669a5db4SJeff Garzik { 492669a5db4SJeff Garzik ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset); 493669a5db4SJeff Garzik } 494669a5db4SJeff Garzik 495669a5db4SJeff Garzik static int hpt374_pre_reset(struct ata_port *ap) 496669a5db4SJeff Garzik { 497b5bf24b9SAlan Cox static const struct pci_bits hpt37x_enable_bits[] = { 498b5bf24b9SAlan Cox { 0x50, 1, 0x04, 0x04 }, 499b5bf24b9SAlan Cox { 0x54, 1, 0x04, 0x04 } 500b5bf24b9SAlan Cox }; 501669a5db4SJeff Garzik u16 mcr3, mcr6; 502669a5db4SJeff Garzik u8 ata66; 503669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 504b5bf24b9SAlan Cox 505b5bf24b9SAlan Cox if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) 506b5bf24b9SAlan Cox return -ENOENT; 507b5bf24b9SAlan Cox 508669a5db4SJeff Garzik /* Do the extra channel work */ 509669a5db4SJeff Garzik pci_read_config_word(pdev, 0x52, &mcr3); 510669a5db4SJeff Garzik pci_read_config_word(pdev, 0x56, &mcr6); 511669a5db4SJeff Garzik /* Set bit 15 of 0x52 to enable TCBLID as input 512669a5db4SJeff Garzik Set bit 15 of 0x56 to enable FCBLID as input 513669a5db4SJeff Garzik */ 514669a5db4SJeff Garzik pci_write_config_word(pdev, 0x52, mcr3 | 0x8000); 515669a5db4SJeff Garzik pci_write_config_word(pdev, 0x56, mcr6 | 0x8000); 516669a5db4SJeff Garzik pci_read_config_byte(pdev, 0x5A, &ata66); 517669a5db4SJeff Garzik /* Reset TCBLID/FCBLID to output */ 518669a5db4SJeff Garzik pci_write_config_word(pdev, 0x52, mcr3); 519669a5db4SJeff Garzik pci_write_config_word(pdev, 0x56, mcr6); 520669a5db4SJeff Garzik 521669a5db4SJeff Garzik if (ata66 & (1 << ap->port_no)) 522669a5db4SJeff Garzik ap->cbl = ATA_CBL_PATA40; 523669a5db4SJeff Garzik else 524669a5db4SJeff Garzik ap->cbl = ATA_CBL_PATA80; 525669a5db4SJeff Garzik 526669a5db4SJeff Garzik /* Reset the state machine */ 527669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x50, 0x37); 528669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x54, 0x37); 529669a5db4SJeff Garzik udelay(100); 530669a5db4SJeff Garzik 531669a5db4SJeff Garzik return ata_std_prereset(ap); 532669a5db4SJeff Garzik } 533669a5db4SJeff Garzik 534669a5db4SJeff Garzik /** 535669a5db4SJeff Garzik * hpt374_error_handler - reset the hpt374 536669a5db4SJeff Garzik * @classes: 537669a5db4SJeff Garzik * 538669a5db4SJeff Garzik * The 374 cable detect is a little different due to the extra 539669a5db4SJeff Garzik * channels. The function 0 channels work like usual but function 1 540669a5db4SJeff Garzik * is special 541669a5db4SJeff Garzik */ 542669a5db4SJeff Garzik 543669a5db4SJeff Garzik static void hpt374_error_handler(struct ata_port *ap) 544669a5db4SJeff Garzik { 545669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 546669a5db4SJeff Garzik 547669a5db4SJeff Garzik if (!(PCI_FUNC(pdev->devfn) & 1)) 548669a5db4SJeff Garzik hpt37x_error_handler(ap); 549669a5db4SJeff Garzik else 550669a5db4SJeff Garzik ata_bmdma_drive_eh(ap, hpt374_pre_reset, ata_std_softreset, NULL, ata_std_postreset); 551669a5db4SJeff Garzik } 552669a5db4SJeff Garzik 553669a5db4SJeff Garzik /** 554669a5db4SJeff Garzik * hpt370_set_piomode - PIO setup 555669a5db4SJeff Garzik * @ap: ATA interface 556669a5db4SJeff Garzik * @adev: device on the interface 557669a5db4SJeff Garzik * 558669a5db4SJeff Garzik * Perform PIO mode setup. 559669a5db4SJeff Garzik */ 560669a5db4SJeff Garzik 561669a5db4SJeff Garzik static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) 562669a5db4SJeff Garzik { 563669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 564669a5db4SJeff Garzik u32 addr1, addr2; 565669a5db4SJeff Garzik u32 reg; 566669a5db4SJeff Garzik u32 mode; 567669a5db4SJeff Garzik u8 fast; 568669a5db4SJeff Garzik 569669a5db4SJeff Garzik addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); 570669a5db4SJeff Garzik addr2 = 0x51 + 4 * ap->port_no; 571669a5db4SJeff Garzik 572669a5db4SJeff Garzik /* Fast interrupt prediction disable, hold off interrupt disable */ 573669a5db4SJeff Garzik pci_read_config_byte(pdev, addr2, &fast); 574669a5db4SJeff Garzik fast &= ~0x02; 575669a5db4SJeff Garzik fast |= 0x01; 576669a5db4SJeff Garzik pci_write_config_byte(pdev, addr2, fast); 577669a5db4SJeff Garzik 578669a5db4SJeff Garzik pci_read_config_dword(pdev, addr1, ®); 579669a5db4SJeff Garzik mode = hpt37x_find_mode(ap, adev->pio_mode); 580669a5db4SJeff Garzik mode &= ~0x8000000; /* No FIFO in PIO */ 581669a5db4SJeff Garzik mode &= ~0x30070000; /* Leave config bits alone */ 582669a5db4SJeff Garzik reg &= 0x30070000; /* Strip timing bits */ 583669a5db4SJeff Garzik pci_write_config_dword(pdev, addr1, reg | mode); 584669a5db4SJeff Garzik } 585669a5db4SJeff Garzik 586669a5db4SJeff Garzik /** 587669a5db4SJeff Garzik * hpt370_set_dmamode - DMA timing setup 588669a5db4SJeff Garzik * @ap: ATA interface 589669a5db4SJeff Garzik * @adev: Device being configured 590669a5db4SJeff Garzik * 591669a5db4SJeff Garzik * Set up the channel for MWDMA or UDMA modes. Much the same as with 592669a5db4SJeff Garzik * PIO, load the mode number and then set MWDMA or UDMA flag. 593669a5db4SJeff Garzik */ 594669a5db4SJeff Garzik 595669a5db4SJeff Garzik static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) 596669a5db4SJeff Garzik { 597669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 598669a5db4SJeff Garzik u32 addr1, addr2; 599669a5db4SJeff Garzik u32 reg; 600669a5db4SJeff Garzik u32 mode; 601669a5db4SJeff Garzik u8 fast; 602669a5db4SJeff Garzik 603669a5db4SJeff Garzik addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); 604669a5db4SJeff Garzik addr2 = 0x51 + 4 * ap->port_no; 605669a5db4SJeff Garzik 606669a5db4SJeff Garzik /* Fast interrupt prediction disable, hold off interrupt disable */ 607669a5db4SJeff Garzik pci_read_config_byte(pdev, addr2, &fast); 608669a5db4SJeff Garzik fast &= ~0x02; 609669a5db4SJeff Garzik fast |= 0x01; 610669a5db4SJeff Garzik pci_write_config_byte(pdev, addr2, fast); 611669a5db4SJeff Garzik 612669a5db4SJeff Garzik pci_read_config_dword(pdev, addr1, ®); 613669a5db4SJeff Garzik mode = hpt37x_find_mode(ap, adev->dma_mode); 614669a5db4SJeff Garzik mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ 615669a5db4SJeff Garzik mode &= ~0xC0000000; /* Leave config bits alone */ 616669a5db4SJeff Garzik reg &= 0xC0000000; /* Strip timing bits */ 617669a5db4SJeff Garzik pci_write_config_dword(pdev, addr1, reg | mode); 618669a5db4SJeff Garzik } 619669a5db4SJeff Garzik 620669a5db4SJeff Garzik /** 621669a5db4SJeff Garzik * hpt370_bmdma_start - DMA engine begin 622669a5db4SJeff Garzik * @qc: ATA command 623669a5db4SJeff Garzik * 624669a5db4SJeff Garzik * The 370 and 370A want us to reset the DMA engine each time we 625669a5db4SJeff Garzik * use it. The 372 and later are fine. 626669a5db4SJeff Garzik */ 627669a5db4SJeff Garzik 628669a5db4SJeff Garzik static void hpt370_bmdma_start(struct ata_queued_cmd *qc) 629669a5db4SJeff Garzik { 630669a5db4SJeff Garzik struct ata_port *ap = qc->ap; 631669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 632669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); 633669a5db4SJeff Garzik udelay(10); 634669a5db4SJeff Garzik ata_bmdma_start(qc); 635669a5db4SJeff Garzik } 636669a5db4SJeff Garzik 637669a5db4SJeff Garzik /** 638669a5db4SJeff Garzik * hpt370_bmdma_end - DMA engine stop 639669a5db4SJeff Garzik * @qc: ATA command 640669a5db4SJeff Garzik * 641669a5db4SJeff Garzik * Work around the HPT370 DMA engine. 642669a5db4SJeff Garzik */ 643669a5db4SJeff Garzik 644669a5db4SJeff Garzik static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) 645669a5db4SJeff Garzik { 646669a5db4SJeff Garzik struct ata_port *ap = qc->ap; 647669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 648669a5db4SJeff Garzik u8 dma_stat = inb(ap->ioaddr.bmdma_addr + 2); 649669a5db4SJeff Garzik u8 dma_cmd; 650669a5db4SJeff Garzik unsigned long bmdma = ap->ioaddr.bmdma_addr; 651669a5db4SJeff Garzik 652669a5db4SJeff Garzik if (dma_stat & 0x01) { 653669a5db4SJeff Garzik udelay(20); 654669a5db4SJeff Garzik dma_stat = inb(bmdma + 2); 655669a5db4SJeff Garzik } 656669a5db4SJeff Garzik if (dma_stat & 0x01) { 657669a5db4SJeff Garzik /* Clear the engine */ 658669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); 659669a5db4SJeff Garzik udelay(10); 660669a5db4SJeff Garzik /* Stop DMA */ 661669a5db4SJeff Garzik dma_cmd = inb(bmdma ); 662669a5db4SJeff Garzik outb(dma_cmd & 0xFE, bmdma); 663669a5db4SJeff Garzik /* Clear Error */ 664669a5db4SJeff Garzik dma_stat = inb(bmdma + 2); 665669a5db4SJeff Garzik outb(dma_stat | 0x06 , bmdma + 2); 666669a5db4SJeff Garzik /* Clear the engine */ 667669a5db4SJeff Garzik pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); 668669a5db4SJeff Garzik udelay(10); 669669a5db4SJeff Garzik } 670669a5db4SJeff Garzik ata_bmdma_stop(qc); 671669a5db4SJeff Garzik } 672669a5db4SJeff Garzik 673669a5db4SJeff Garzik /** 674669a5db4SJeff Garzik * hpt372_set_piomode - PIO setup 675669a5db4SJeff Garzik * @ap: ATA interface 676669a5db4SJeff Garzik * @adev: device on the interface 677669a5db4SJeff Garzik * 678669a5db4SJeff Garzik * Perform PIO mode setup. 679669a5db4SJeff Garzik */ 680669a5db4SJeff Garzik 681669a5db4SJeff Garzik static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) 682669a5db4SJeff Garzik { 683669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 684669a5db4SJeff Garzik u32 addr1, addr2; 685669a5db4SJeff Garzik u32 reg; 686669a5db4SJeff Garzik u32 mode; 687669a5db4SJeff Garzik u8 fast; 688669a5db4SJeff Garzik 689669a5db4SJeff Garzik addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); 690669a5db4SJeff Garzik addr2 = 0x51 + 4 * ap->port_no; 691669a5db4SJeff Garzik 692669a5db4SJeff Garzik /* Fast interrupt prediction disable, hold off interrupt disable */ 693669a5db4SJeff Garzik pci_read_config_byte(pdev, addr2, &fast); 694669a5db4SJeff Garzik fast &= ~0x07; 695669a5db4SJeff Garzik pci_write_config_byte(pdev, addr2, fast); 696669a5db4SJeff Garzik 697669a5db4SJeff Garzik pci_read_config_dword(pdev, addr1, ®); 698669a5db4SJeff Garzik mode = hpt37x_find_mode(ap, adev->pio_mode); 699669a5db4SJeff Garzik 700669a5db4SJeff Garzik printk("Find mode for %d reports %X\n", adev->pio_mode, mode); 701669a5db4SJeff Garzik mode &= ~0x80000000; /* No FIFO in PIO */ 702669a5db4SJeff Garzik mode &= ~0x30070000; /* Leave config bits alone */ 703669a5db4SJeff Garzik reg &= 0x30070000; /* Strip timing bits */ 704669a5db4SJeff Garzik pci_write_config_dword(pdev, addr1, reg | mode); 705669a5db4SJeff Garzik } 706669a5db4SJeff Garzik 707669a5db4SJeff Garzik /** 708669a5db4SJeff Garzik * hpt372_set_dmamode - DMA timing setup 709669a5db4SJeff Garzik * @ap: ATA interface 710669a5db4SJeff Garzik * @adev: Device being configured 711669a5db4SJeff Garzik * 712669a5db4SJeff Garzik * Set up the channel for MWDMA or UDMA modes. Much the same as with 713669a5db4SJeff Garzik * PIO, load the mode number and then set MWDMA or UDMA flag. 714669a5db4SJeff Garzik */ 715669a5db4SJeff Garzik 716669a5db4SJeff Garzik static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) 717669a5db4SJeff Garzik { 718669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 719669a5db4SJeff Garzik u32 addr1, addr2; 720669a5db4SJeff Garzik u32 reg; 721669a5db4SJeff Garzik u32 mode; 722669a5db4SJeff Garzik u8 fast; 723669a5db4SJeff Garzik 724669a5db4SJeff Garzik addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); 725669a5db4SJeff Garzik addr2 = 0x51 + 4 * ap->port_no; 726669a5db4SJeff Garzik 727669a5db4SJeff Garzik /* Fast interrupt prediction disable, hold off interrupt disable */ 728669a5db4SJeff Garzik pci_read_config_byte(pdev, addr2, &fast); 729669a5db4SJeff Garzik fast &= ~0x07; 730669a5db4SJeff Garzik pci_write_config_byte(pdev, addr2, fast); 731669a5db4SJeff Garzik 732669a5db4SJeff Garzik pci_read_config_dword(pdev, addr1, ®); 733669a5db4SJeff Garzik mode = hpt37x_find_mode(ap, adev->dma_mode); 734669a5db4SJeff Garzik printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); 735669a5db4SJeff Garzik mode &= ~0xC0000000; /* Leave config bits alone */ 736669a5db4SJeff Garzik mode |= 0x80000000; /* FIFO in MWDMA or UDMA */ 737669a5db4SJeff Garzik reg &= 0xC0000000; /* Strip timing bits */ 738669a5db4SJeff Garzik pci_write_config_dword(pdev, addr1, reg | mode); 739669a5db4SJeff Garzik } 740669a5db4SJeff Garzik 741669a5db4SJeff Garzik /** 742669a5db4SJeff Garzik * hpt37x_bmdma_end - DMA engine stop 743669a5db4SJeff Garzik * @qc: ATA command 744669a5db4SJeff Garzik * 745669a5db4SJeff Garzik * Clean up after the HPT372 and later DMA engine 746669a5db4SJeff Garzik */ 747669a5db4SJeff Garzik 748669a5db4SJeff Garzik static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc) 749669a5db4SJeff Garzik { 750669a5db4SJeff Garzik struct ata_port *ap = qc->ap; 751669a5db4SJeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 7526929da44SAlan int mscreg = 0x50 + 4 * ap->port_no; 753669a5db4SJeff Garzik u8 bwsr_stat, msc_stat; 754669a5db4SJeff Garzik 755669a5db4SJeff Garzik pci_read_config_byte(pdev, 0x6A, &bwsr_stat); 756669a5db4SJeff Garzik pci_read_config_byte(pdev, mscreg, &msc_stat); 757669a5db4SJeff Garzik if (bwsr_stat & (1 << ap->port_no)) 758669a5db4SJeff Garzik pci_write_config_byte(pdev, mscreg, msc_stat | 0x30); 759669a5db4SJeff Garzik ata_bmdma_stop(qc); 760669a5db4SJeff Garzik } 761669a5db4SJeff Garzik 762669a5db4SJeff Garzik 763669a5db4SJeff Garzik static struct scsi_host_template hpt37x_sht = { 764669a5db4SJeff Garzik .module = THIS_MODULE, 765669a5db4SJeff Garzik .name = DRV_NAME, 766669a5db4SJeff Garzik .ioctl = ata_scsi_ioctl, 767669a5db4SJeff Garzik .queuecommand = ata_scsi_queuecmd, 768669a5db4SJeff Garzik .can_queue = ATA_DEF_QUEUE, 769669a5db4SJeff Garzik .this_id = ATA_SHT_THIS_ID, 770669a5db4SJeff Garzik .sg_tablesize = LIBATA_MAX_PRD, 771669a5db4SJeff Garzik .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 772669a5db4SJeff Garzik .emulated = ATA_SHT_EMULATED, 773669a5db4SJeff Garzik .use_clustering = ATA_SHT_USE_CLUSTERING, 774669a5db4SJeff Garzik .proc_name = DRV_NAME, 775669a5db4SJeff Garzik .dma_boundary = ATA_DMA_BOUNDARY, 776669a5db4SJeff Garzik .slave_configure = ata_scsi_slave_config, 777afdfe899STejun Heo .slave_destroy = ata_scsi_slave_destroy, 778669a5db4SJeff Garzik .bios_param = ata_std_bios_param, 779669a5db4SJeff Garzik }; 780669a5db4SJeff Garzik 781669a5db4SJeff Garzik /* 782669a5db4SJeff Garzik * Configuration for HPT370 783669a5db4SJeff Garzik */ 784669a5db4SJeff Garzik 785669a5db4SJeff Garzik static struct ata_port_operations hpt370_port_ops = { 786669a5db4SJeff Garzik .port_disable = ata_port_disable, 787669a5db4SJeff Garzik .set_piomode = hpt370_set_piomode, 788669a5db4SJeff Garzik .set_dmamode = hpt370_set_dmamode, 789669a5db4SJeff Garzik .mode_filter = hpt370_filter, 790669a5db4SJeff Garzik 791669a5db4SJeff Garzik .tf_load = ata_tf_load, 792669a5db4SJeff Garzik .tf_read = ata_tf_read, 793669a5db4SJeff Garzik .check_status = ata_check_status, 794669a5db4SJeff Garzik .exec_command = ata_exec_command, 795669a5db4SJeff Garzik .dev_select = ata_std_dev_select, 796669a5db4SJeff Garzik 797669a5db4SJeff Garzik .freeze = ata_bmdma_freeze, 798669a5db4SJeff Garzik .thaw = ata_bmdma_thaw, 799669a5db4SJeff Garzik .error_handler = hpt37x_error_handler, 800669a5db4SJeff Garzik .post_internal_cmd = ata_bmdma_post_internal_cmd, 801669a5db4SJeff Garzik 802669a5db4SJeff Garzik .bmdma_setup = ata_bmdma_setup, 803669a5db4SJeff Garzik .bmdma_start = hpt370_bmdma_start, 804669a5db4SJeff Garzik .bmdma_stop = hpt370_bmdma_stop, 805669a5db4SJeff Garzik .bmdma_status = ata_bmdma_status, 806669a5db4SJeff Garzik 807669a5db4SJeff Garzik .qc_prep = ata_qc_prep, 808669a5db4SJeff Garzik .qc_issue = ata_qc_issue_prot, 809bda30288SJeff Garzik 810669a5db4SJeff Garzik .data_xfer = ata_pio_data_xfer, 811669a5db4SJeff Garzik 812669a5db4SJeff Garzik .irq_handler = ata_interrupt, 813669a5db4SJeff Garzik .irq_clear = ata_bmdma_irq_clear, 814669a5db4SJeff Garzik 815669a5db4SJeff Garzik .port_start = ata_port_start, 816669a5db4SJeff Garzik .port_stop = ata_port_stop, 817669a5db4SJeff Garzik .host_stop = ata_host_stop 818669a5db4SJeff Garzik }; 819669a5db4SJeff Garzik 820669a5db4SJeff Garzik /* 821669a5db4SJeff Garzik * Configuration for HPT370A. Close to 370 but less filters 822669a5db4SJeff Garzik */ 823669a5db4SJeff Garzik 824669a5db4SJeff Garzik static struct ata_port_operations hpt370a_port_ops = { 825669a5db4SJeff Garzik .port_disable = ata_port_disable, 826669a5db4SJeff Garzik .set_piomode = hpt370_set_piomode, 827669a5db4SJeff Garzik .set_dmamode = hpt370_set_dmamode, 828669a5db4SJeff Garzik .mode_filter = hpt370a_filter, 829669a5db4SJeff Garzik 830669a5db4SJeff Garzik .tf_load = ata_tf_load, 831669a5db4SJeff Garzik .tf_read = ata_tf_read, 832669a5db4SJeff Garzik .check_status = ata_check_status, 833669a5db4SJeff Garzik .exec_command = ata_exec_command, 834669a5db4SJeff Garzik .dev_select = ata_std_dev_select, 835669a5db4SJeff Garzik 836669a5db4SJeff Garzik .freeze = ata_bmdma_freeze, 837669a5db4SJeff Garzik .thaw = ata_bmdma_thaw, 838669a5db4SJeff Garzik .error_handler = hpt37x_error_handler, 839669a5db4SJeff Garzik .post_internal_cmd = ata_bmdma_post_internal_cmd, 840669a5db4SJeff Garzik 841669a5db4SJeff Garzik .bmdma_setup = ata_bmdma_setup, 842669a5db4SJeff Garzik .bmdma_start = hpt370_bmdma_start, 843669a5db4SJeff Garzik .bmdma_stop = hpt370_bmdma_stop, 844669a5db4SJeff Garzik .bmdma_status = ata_bmdma_status, 845669a5db4SJeff Garzik 846669a5db4SJeff Garzik .qc_prep = ata_qc_prep, 847669a5db4SJeff Garzik .qc_issue = ata_qc_issue_prot, 848bda30288SJeff Garzik 849669a5db4SJeff Garzik .data_xfer = ata_pio_data_xfer, 850669a5db4SJeff Garzik 851669a5db4SJeff Garzik .irq_handler = ata_interrupt, 852669a5db4SJeff Garzik .irq_clear = ata_bmdma_irq_clear, 853669a5db4SJeff Garzik 854669a5db4SJeff Garzik .port_start = ata_port_start, 855669a5db4SJeff Garzik .port_stop = ata_port_stop, 856669a5db4SJeff Garzik .host_stop = ata_host_stop 857669a5db4SJeff Garzik }; 858669a5db4SJeff Garzik 859669a5db4SJeff Garzik /* 860669a5db4SJeff Garzik * Configuration for HPT372, HPT371, HPT302. Slightly different PIO 861669a5db4SJeff Garzik * and DMA mode setting functionality. 862669a5db4SJeff Garzik */ 863669a5db4SJeff Garzik 864669a5db4SJeff Garzik static struct ata_port_operations hpt372_port_ops = { 865669a5db4SJeff Garzik .port_disable = ata_port_disable, 866669a5db4SJeff Garzik .set_piomode = hpt372_set_piomode, 867669a5db4SJeff Garzik .set_dmamode = hpt372_set_dmamode, 868669a5db4SJeff Garzik .mode_filter = ata_pci_default_filter, 869669a5db4SJeff Garzik 870669a5db4SJeff Garzik .tf_load = ata_tf_load, 871669a5db4SJeff Garzik .tf_read = ata_tf_read, 872669a5db4SJeff Garzik .check_status = ata_check_status, 873669a5db4SJeff Garzik .exec_command = ata_exec_command, 874669a5db4SJeff Garzik .dev_select = ata_std_dev_select, 875669a5db4SJeff Garzik 876669a5db4SJeff Garzik .freeze = ata_bmdma_freeze, 877669a5db4SJeff Garzik .thaw = ata_bmdma_thaw, 878669a5db4SJeff Garzik .error_handler = hpt37x_error_handler, 879669a5db4SJeff Garzik .post_internal_cmd = ata_bmdma_post_internal_cmd, 880669a5db4SJeff Garzik 881669a5db4SJeff Garzik .bmdma_setup = ata_bmdma_setup, 882669a5db4SJeff Garzik .bmdma_start = ata_bmdma_start, 883669a5db4SJeff Garzik .bmdma_stop = hpt37x_bmdma_stop, 884669a5db4SJeff Garzik .bmdma_status = ata_bmdma_status, 885669a5db4SJeff Garzik 886669a5db4SJeff Garzik .qc_prep = ata_qc_prep, 887669a5db4SJeff Garzik .qc_issue = ata_qc_issue_prot, 888bda30288SJeff Garzik 889669a5db4SJeff Garzik .data_xfer = ata_pio_data_xfer, 890669a5db4SJeff Garzik 891669a5db4SJeff Garzik .irq_handler = ata_interrupt, 892669a5db4SJeff Garzik .irq_clear = ata_bmdma_irq_clear, 893669a5db4SJeff Garzik 894669a5db4SJeff Garzik .port_start = ata_port_start, 895669a5db4SJeff Garzik .port_stop = ata_port_stop, 896669a5db4SJeff Garzik .host_stop = ata_host_stop 897669a5db4SJeff Garzik }; 898669a5db4SJeff Garzik 899669a5db4SJeff Garzik /* 900669a5db4SJeff Garzik * Configuration for HPT374. Mode setting works like 372 and friends 901669a5db4SJeff Garzik * but we have a different cable detection procedure. 902669a5db4SJeff Garzik */ 903669a5db4SJeff Garzik 904669a5db4SJeff Garzik static struct ata_port_operations hpt374_port_ops = { 905669a5db4SJeff Garzik .port_disable = ata_port_disable, 906669a5db4SJeff Garzik .set_piomode = hpt372_set_piomode, 907669a5db4SJeff Garzik .set_dmamode = hpt372_set_dmamode, 908669a5db4SJeff Garzik .mode_filter = ata_pci_default_filter, 909669a5db4SJeff Garzik 910669a5db4SJeff Garzik .tf_load = ata_tf_load, 911669a5db4SJeff Garzik .tf_read = ata_tf_read, 912669a5db4SJeff Garzik .check_status = ata_check_status, 913669a5db4SJeff Garzik .exec_command = ata_exec_command, 914669a5db4SJeff Garzik .dev_select = ata_std_dev_select, 915669a5db4SJeff Garzik 916669a5db4SJeff Garzik .freeze = ata_bmdma_freeze, 917669a5db4SJeff Garzik .thaw = ata_bmdma_thaw, 918669a5db4SJeff Garzik .error_handler = hpt374_error_handler, 919669a5db4SJeff Garzik .post_internal_cmd = ata_bmdma_post_internal_cmd, 920669a5db4SJeff Garzik 921669a5db4SJeff Garzik .bmdma_setup = ata_bmdma_setup, 922669a5db4SJeff Garzik .bmdma_start = ata_bmdma_start, 923669a5db4SJeff Garzik .bmdma_stop = hpt37x_bmdma_stop, 924669a5db4SJeff Garzik .bmdma_status = ata_bmdma_status, 925669a5db4SJeff Garzik 926669a5db4SJeff Garzik .qc_prep = ata_qc_prep, 927669a5db4SJeff Garzik .qc_issue = ata_qc_issue_prot, 928bda30288SJeff Garzik 929669a5db4SJeff Garzik .data_xfer = ata_pio_data_xfer, 930669a5db4SJeff Garzik 931669a5db4SJeff Garzik .irq_handler = ata_interrupt, 932669a5db4SJeff Garzik .irq_clear = ata_bmdma_irq_clear, 933669a5db4SJeff Garzik 934669a5db4SJeff Garzik .port_start = ata_port_start, 935669a5db4SJeff Garzik .port_stop = ata_port_stop, 936669a5db4SJeff Garzik .host_stop = ata_host_stop 937669a5db4SJeff Garzik }; 938669a5db4SJeff Garzik 939669a5db4SJeff Garzik /** 940669a5db4SJeff Garzik * htp37x_clock_slot - Turn timing to PC clock entry 941669a5db4SJeff Garzik * @freq: Reported frequency timing 942669a5db4SJeff Garzik * @base: Base timing 943669a5db4SJeff Garzik * 944669a5db4SJeff Garzik * Turn the timing data intoa clock slot (0 for 33, 1 for 40, 2 for 50 945669a5db4SJeff Garzik * and 3 for 66Mhz) 946669a5db4SJeff Garzik */ 947669a5db4SJeff Garzik 948669a5db4SJeff Garzik static int hpt37x_clock_slot(unsigned int freq, unsigned int base) 949669a5db4SJeff Garzik { 950669a5db4SJeff Garzik unsigned int f = (base * freq) / 192; /* Mhz */ 951669a5db4SJeff Garzik if (f < 40) 952669a5db4SJeff Garzik return 0; /* 33Mhz slot */ 953669a5db4SJeff Garzik if (f < 45) 954669a5db4SJeff Garzik return 1; /* 40Mhz slot */ 955669a5db4SJeff Garzik if (f < 55) 956669a5db4SJeff Garzik return 2; /* 50Mhz slot */ 957669a5db4SJeff Garzik return 3; /* 60Mhz slot */ 958669a5db4SJeff Garzik } 959669a5db4SJeff Garzik 960669a5db4SJeff Garzik /** 961669a5db4SJeff Garzik * hpt37x_calibrate_dpll - Calibrate the DPLL loop 962669a5db4SJeff Garzik * @dev: PCI device 963669a5db4SJeff Garzik * 964669a5db4SJeff Garzik * Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this 965669a5db4SJeff Garzik * succeeds 966669a5db4SJeff Garzik */ 967669a5db4SJeff Garzik 968669a5db4SJeff Garzik static int hpt37x_calibrate_dpll(struct pci_dev *dev) 969669a5db4SJeff Garzik { 970669a5db4SJeff Garzik u8 reg5b; 971669a5db4SJeff Garzik u32 reg5c; 972669a5db4SJeff Garzik int tries; 973669a5db4SJeff Garzik 974669a5db4SJeff Garzik for(tries = 0; tries < 0x5000; tries++) { 975669a5db4SJeff Garzik udelay(50); 976669a5db4SJeff Garzik pci_read_config_byte(dev, 0x5b, ®5b); 977669a5db4SJeff Garzik if (reg5b & 0x80) { 978669a5db4SJeff Garzik /* See if it stays set */ 979669a5db4SJeff Garzik for(tries = 0; tries < 0x1000; tries ++) { 980669a5db4SJeff Garzik pci_read_config_byte(dev, 0x5b, ®5b); 981669a5db4SJeff Garzik /* Failed ? */ 982669a5db4SJeff Garzik if ((reg5b & 0x80) == 0) 983669a5db4SJeff Garzik return 0; 984669a5db4SJeff Garzik } 985669a5db4SJeff Garzik /* Turn off tuning, we have the DPLL set */ 986669a5db4SJeff Garzik pci_read_config_dword(dev, 0x5c, ®5c); 987669a5db4SJeff Garzik pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); 988669a5db4SJeff Garzik return 1; 989669a5db4SJeff Garzik } 990669a5db4SJeff Garzik } 991669a5db4SJeff Garzik /* Never went stable */ 992669a5db4SJeff Garzik return 0; 993669a5db4SJeff Garzik } 994669a5db4SJeff Garzik /** 995669a5db4SJeff Garzik * hpt37x_init_one - Initialise an HPT37X/302 996669a5db4SJeff Garzik * @dev: PCI device 997669a5db4SJeff Garzik * @id: Entry in match table 998669a5db4SJeff Garzik * 999669a5db4SJeff Garzik * Initialise an HPT37x device. There are some interesting complications 1000669a5db4SJeff Garzik * here. Firstly the chip may report 366 and be one of several variants. 1001669a5db4SJeff Garzik * Secondly all the timings depend on the clock for the chip which we must 1002669a5db4SJeff Garzik * detect and look up 1003669a5db4SJeff Garzik * 1004669a5db4SJeff Garzik * This is the known chip mappings. It may be missing a couple of later 1005669a5db4SJeff Garzik * releases. 1006669a5db4SJeff Garzik * 1007669a5db4SJeff Garzik * Chip version PCI Rev Notes 1008669a5db4SJeff Garzik * HPT366 4 (HPT366) 0 Other driver 1009669a5db4SJeff Garzik * HPT366 4 (HPT366) 1 Other driver 1010669a5db4SJeff Garzik * HPT368 4 (HPT366) 2 Other driver 1011669a5db4SJeff Garzik * HPT370 4 (HPT366) 3 UDMA100 1012669a5db4SJeff Garzik * HPT370A 4 (HPT366) 4 UDMA100 1013669a5db4SJeff Garzik * HPT372 4 (HPT366) 5 UDMA133 (1) 1014669a5db4SJeff Garzik * HPT372N 4 (HPT366) 6 Other driver 1015669a5db4SJeff Garzik * HPT372A 5 (HPT372) 1 UDMA133 (1) 1016669a5db4SJeff Garzik * HPT372N 5 (HPT372) 2 Other driver 1017669a5db4SJeff Garzik * HPT302 6 (HPT302) 1 UDMA133 1018669a5db4SJeff Garzik * HPT302N 6 (HPT302) 2 Other driver 1019669a5db4SJeff Garzik * HPT371 7 (HPT371) * UDMA133 1020669a5db4SJeff Garzik * HPT374 8 (HPT374) * UDMA133 4 channel 1021669a5db4SJeff Garzik * HPT372N 9 (HPT372N) * Other driver 1022669a5db4SJeff Garzik * 1023669a5db4SJeff Garzik * (1) UDMA133 support depends on the bus clock 1024669a5db4SJeff Garzik */ 1025669a5db4SJeff Garzik 1026669a5db4SJeff Garzik static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) 1027669a5db4SJeff Garzik { 1028669a5db4SJeff Garzik /* HPT370 - UDMA100 */ 1029669a5db4SJeff Garzik static struct ata_port_info info_hpt370 = { 1030669a5db4SJeff Garzik .sht = &hpt37x_sht, 1031669a5db4SJeff Garzik .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 1032669a5db4SJeff Garzik .pio_mask = 0x1f, 1033669a5db4SJeff Garzik .mwdma_mask = 0x07, 1034669a5db4SJeff Garzik .udma_mask = 0x3f, 1035669a5db4SJeff Garzik .port_ops = &hpt370_port_ops 1036669a5db4SJeff Garzik }; 1037669a5db4SJeff Garzik /* HPT370A - UDMA100 */ 1038669a5db4SJeff Garzik static struct ata_port_info info_hpt370a = { 1039669a5db4SJeff Garzik .sht = &hpt37x_sht, 1040669a5db4SJeff Garzik .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 1041669a5db4SJeff Garzik .pio_mask = 0x1f, 1042669a5db4SJeff Garzik .mwdma_mask = 0x07, 1043669a5db4SJeff Garzik .udma_mask = 0x3f, 1044669a5db4SJeff Garzik .port_ops = &hpt370a_port_ops 1045669a5db4SJeff Garzik }; 1046669a5db4SJeff Garzik /* HPT371, 372 and friends - UDMA133 */ 1047669a5db4SJeff Garzik static struct ata_port_info info_hpt372 = { 1048669a5db4SJeff Garzik .sht = &hpt37x_sht, 1049669a5db4SJeff Garzik .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 1050669a5db4SJeff Garzik .pio_mask = 0x1f, 1051669a5db4SJeff Garzik .mwdma_mask = 0x07, 1052669a5db4SJeff Garzik .udma_mask = 0x7f, 1053669a5db4SJeff Garzik .port_ops = &hpt372_port_ops 1054669a5db4SJeff Garzik }; 1055669a5db4SJeff Garzik /* HPT371, 372 and friends - UDMA100 at 50MHz clock */ 1056669a5db4SJeff Garzik static struct ata_port_info info_hpt372_50 = { 1057669a5db4SJeff Garzik .sht = &hpt37x_sht, 1058669a5db4SJeff Garzik .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 1059669a5db4SJeff Garzik .pio_mask = 0x1f, 1060669a5db4SJeff Garzik .mwdma_mask = 0x07, 1061669a5db4SJeff Garzik .udma_mask = 0x3f, 1062669a5db4SJeff Garzik .port_ops = &hpt372_port_ops 1063669a5db4SJeff Garzik }; 1064669a5db4SJeff Garzik /* HPT374 - UDMA133 */ 1065669a5db4SJeff Garzik static struct ata_port_info info_hpt374 = { 1066669a5db4SJeff Garzik .sht = &hpt37x_sht, 1067669a5db4SJeff Garzik .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 1068669a5db4SJeff Garzik .pio_mask = 0x1f, 1069669a5db4SJeff Garzik .mwdma_mask = 0x07, 1070669a5db4SJeff Garzik .udma_mask = 0x7f, 1071669a5db4SJeff Garzik .port_ops = &hpt374_port_ops 1072669a5db4SJeff Garzik }; 1073669a5db4SJeff Garzik 1074669a5db4SJeff Garzik static const int MHz[4] = { 33, 40, 50, 66 }; 1075669a5db4SJeff Garzik 1076669a5db4SJeff Garzik struct ata_port_info *port_info[2]; 1077669a5db4SJeff Garzik struct ata_port_info *port; 1078669a5db4SJeff Garzik 1079669a5db4SJeff Garzik u8 irqmask; 1080669a5db4SJeff Garzik u32 class_rev; 1081669a5db4SJeff Garzik u32 freq; 1082669a5db4SJeff Garzik 1083669a5db4SJeff Garzik const struct hpt_chip *chip_table; 1084669a5db4SJeff Garzik int clock_slot; 1085669a5db4SJeff Garzik 1086669a5db4SJeff Garzik pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 1087669a5db4SJeff Garzik class_rev &= 0xFF; 1088669a5db4SJeff Garzik 1089669a5db4SJeff Garzik if (dev->device == PCI_DEVICE_ID_TTI_HPT366) { 1090669a5db4SJeff Garzik /* May be a later chip in disguise. Check */ 1091669a5db4SJeff Garzik /* Older chips are in the HPT366 driver. Ignore them */ 1092669a5db4SJeff Garzik if (class_rev < 3) 1093669a5db4SJeff Garzik return -ENODEV; 1094669a5db4SJeff Garzik /* N series chips have their own driver. Ignore */ 1095669a5db4SJeff Garzik if (class_rev == 6) 1096669a5db4SJeff Garzik return -ENODEV; 1097669a5db4SJeff Garzik 1098669a5db4SJeff Garzik switch(class_rev) { 1099669a5db4SJeff Garzik case 3: 1100669a5db4SJeff Garzik port = &info_hpt370; 1101669a5db4SJeff Garzik chip_table = &hpt370; 1102669a5db4SJeff Garzik break; 1103669a5db4SJeff Garzik case 4: 1104669a5db4SJeff Garzik port = &info_hpt370a; 1105669a5db4SJeff Garzik chip_table = &hpt370a; 1106669a5db4SJeff Garzik break; 1107669a5db4SJeff Garzik case 5: 1108669a5db4SJeff Garzik port = &info_hpt372; 1109669a5db4SJeff Garzik chip_table = &hpt372; 1110669a5db4SJeff Garzik break; 1111669a5db4SJeff Garzik default: 1112669a5db4SJeff Garzik printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev); 1113669a5db4SJeff Garzik return -ENODEV; 1114669a5db4SJeff Garzik } 1115669a5db4SJeff Garzik } else { 1116669a5db4SJeff Garzik switch(dev->device) { 1117669a5db4SJeff Garzik case PCI_DEVICE_ID_TTI_HPT372: 1118669a5db4SJeff Garzik /* 372N if rev >= 2*/ 1119669a5db4SJeff Garzik if (class_rev >= 2) 1120669a5db4SJeff Garzik return -ENODEV; 1121669a5db4SJeff Garzik port = &info_hpt372; 1122669a5db4SJeff Garzik chip_table = &hpt372a; 1123669a5db4SJeff Garzik break; 1124669a5db4SJeff Garzik case PCI_DEVICE_ID_TTI_HPT302: 1125669a5db4SJeff Garzik /* 302N if rev > 1 */ 1126669a5db4SJeff Garzik if (class_rev > 1) 1127669a5db4SJeff Garzik return -ENODEV; 1128669a5db4SJeff Garzik port = &info_hpt372; 1129669a5db4SJeff Garzik /* Check this */ 1130669a5db4SJeff Garzik chip_table = &hpt302; 1131669a5db4SJeff Garzik break; 1132669a5db4SJeff Garzik case PCI_DEVICE_ID_TTI_HPT371: 1133669a5db4SJeff Garzik port = &info_hpt372; 1134669a5db4SJeff Garzik chip_table = &hpt371; 1135669a5db4SJeff Garzik break; 1136669a5db4SJeff Garzik case PCI_DEVICE_ID_TTI_HPT374: 1137669a5db4SJeff Garzik chip_table = &hpt374; 1138669a5db4SJeff Garzik port = &info_hpt374; 1139669a5db4SJeff Garzik break; 1140669a5db4SJeff Garzik default: 1141669a5db4SJeff Garzik printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device); 1142669a5db4SJeff Garzik return -ENODEV; 1143669a5db4SJeff Garzik } 1144669a5db4SJeff Garzik } 1145669a5db4SJeff Garzik /* Ok so this is a chip we support */ 1146669a5db4SJeff Garzik 1147669a5db4SJeff Garzik pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); 1148669a5db4SJeff Garzik pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); 1149669a5db4SJeff Garzik pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); 1150669a5db4SJeff Garzik pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); 1151669a5db4SJeff Garzik 1152669a5db4SJeff Garzik pci_read_config_byte(dev, 0x5A, &irqmask); 1153669a5db4SJeff Garzik irqmask &= ~0x10; 1154669a5db4SJeff Garzik pci_write_config_byte(dev, 0x5a, irqmask); 1155669a5db4SJeff Garzik 1156669a5db4SJeff Garzik /* 1157669a5db4SJeff Garzik * default to pci clock. make sure MA15/16 are set to output 1158669a5db4SJeff Garzik * to prevent drives having problems with 40-pin cables. Needed 1159669a5db4SJeff Garzik * for some drives such as IBM-DTLA which will not enter ready 1160669a5db4SJeff Garzik * state on reset when PDIAG is a input. 1161669a5db4SJeff Garzik */ 1162669a5db4SJeff Garzik 1163669a5db4SJeff Garzik pci_write_config_byte(dev, 0x5b, 0x23); 1164669a5db4SJeff Garzik 1165669a5db4SJeff Garzik pci_read_config_dword(dev, 0x70, &freq); 1166669a5db4SJeff Garzik if ((freq >> 12) != 0xABCDE) { 1167669a5db4SJeff Garzik int i; 1168669a5db4SJeff Garzik u8 sr; 1169669a5db4SJeff Garzik u32 total = 0; 1170669a5db4SJeff Garzik 1171669a5db4SJeff Garzik printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n"); 1172669a5db4SJeff Garzik 1173669a5db4SJeff Garzik /* This is the process the HPT371 BIOS is reported to use */ 1174669a5db4SJeff Garzik for(i = 0; i < 128; i++) { 1175669a5db4SJeff Garzik pci_read_config_byte(dev, 0x78, &sr); 1176669a5db4SJeff Garzik total += sr; 1177669a5db4SJeff Garzik udelay(15); 1178669a5db4SJeff Garzik } 1179669a5db4SJeff Garzik freq = total / 128; 1180669a5db4SJeff Garzik } 1181669a5db4SJeff Garzik freq &= 0x1FF; 1182669a5db4SJeff Garzik 1183669a5db4SJeff Garzik /* 1184669a5db4SJeff Garzik * Turn the frequency check into a band and then find a timing 1185669a5db4SJeff Garzik * table to match it. 1186669a5db4SJeff Garzik */ 1187669a5db4SJeff Garzik 1188669a5db4SJeff Garzik clock_slot = hpt37x_clock_slot(freq, chip_table->base); 1189669a5db4SJeff Garzik if (chip_table->clocks[clock_slot] == NULL) { 1190669a5db4SJeff Garzik /* 1191669a5db4SJeff Garzik * We need to try PLL mode instead 1192669a5db4SJeff Garzik */ 1193669a5db4SJeff Garzik unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192; 1194669a5db4SJeff Garzik unsigned int f_high = f_low + 2; 1195669a5db4SJeff Garzik int adjust; 1196669a5db4SJeff Garzik 1197669a5db4SJeff Garzik for(adjust = 0; adjust < 8; adjust++) { 1198669a5db4SJeff Garzik if (hpt37x_calibrate_dpll(dev)) 1199669a5db4SJeff Garzik break; 1200669a5db4SJeff Garzik /* See if it'll settle at a fractionally different clock */ 1201669a5db4SJeff Garzik if ((adjust & 3) == 3) { 1202669a5db4SJeff Garzik f_low --; 1203669a5db4SJeff Garzik f_high ++; 1204669a5db4SJeff Garzik } 1205669a5db4SJeff Garzik pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); 1206669a5db4SJeff Garzik } 1207669a5db4SJeff Garzik if (adjust == 8) { 1208669a5db4SJeff Garzik printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); 1209669a5db4SJeff Garzik return -ENODEV; 1210669a5db4SJeff Garzik } 1211669a5db4SJeff Garzik /* Check if this works for all cases */ 1212669a5db4SJeff Garzik port->private_data = (void *)hpt370_timings_66; 1213669a5db4SJeff Garzik 1214669a5db4SJeff Garzik printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]); 1215669a5db4SJeff Garzik } else { 1216669a5db4SJeff Garzik port->private_data = (void *)chip_table->clocks[clock_slot]; 1217669a5db4SJeff Garzik /* 1218669a5db4SJeff Garzik * Perform a final fixup. The 371 and 372 clock determines 1219669a5db4SJeff Garzik * if UDMA133 is available. 1220669a5db4SJeff Garzik */ 1221669a5db4SJeff Garzik 1222669a5db4SJeff Garzik if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */ 1223669a5db4SJeff Garzik printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n"); 1224669a5db4SJeff Garzik if (port == &info_hpt372) 1225669a5db4SJeff Garzik port = &info_hpt372_50; 1226669a5db4SJeff Garzik else BUG(); 1227669a5db4SJeff Garzik } 1228669a5db4SJeff Garzik printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); 1229669a5db4SJeff Garzik } 1230669a5db4SJeff Garzik port_info[0] = port_info[1] = port; 1231669a5db4SJeff Garzik /* Now kick off ATA set up */ 1232669a5db4SJeff Garzik return ata_pci_init_one(dev, port_info, 2); 1233669a5db4SJeff Garzik } 1234669a5db4SJeff Garzik 12352d2744fcSJeff Garzik static const struct pci_device_id hpt37x[] = { 12362d2744fcSJeff Garzik { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, 12372d2744fcSJeff Garzik { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), }, 12382d2744fcSJeff Garzik { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), }, 12392d2744fcSJeff Garzik { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), }, 12402d2744fcSJeff Garzik { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), }, 12412d2744fcSJeff Garzik 12422d2744fcSJeff Garzik { }, 1243669a5db4SJeff Garzik }; 1244669a5db4SJeff Garzik 1245669a5db4SJeff Garzik static struct pci_driver hpt37x_pci_driver = { 1246669a5db4SJeff Garzik .name = DRV_NAME, 1247669a5db4SJeff Garzik .id_table = hpt37x, 1248669a5db4SJeff Garzik .probe = hpt37x_init_one, 1249669a5db4SJeff Garzik .remove = ata_pci_remove_one 1250669a5db4SJeff Garzik }; 1251669a5db4SJeff Garzik 1252669a5db4SJeff Garzik static int __init hpt37x_init(void) 1253669a5db4SJeff Garzik { 1254669a5db4SJeff Garzik return pci_register_driver(&hpt37x_pci_driver); 1255669a5db4SJeff Garzik } 1256669a5db4SJeff Garzik 1257669a5db4SJeff Garzik static void __exit hpt37x_exit(void) 1258669a5db4SJeff Garzik { 1259669a5db4SJeff Garzik pci_unregister_driver(&hpt37x_pci_driver); 1260669a5db4SJeff Garzik } 1261669a5db4SJeff Garzik 1262669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox"); 1263669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x"); 1264669a5db4SJeff Garzik MODULE_LICENSE("GPL"); 1265669a5db4SJeff Garzik MODULE_DEVICE_TABLE(pci, hpt37x); 1266669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION); 1267669a5db4SJeff Garzik 1268669a5db4SJeff Garzik module_init(hpt37x_init); 1269669a5db4SJeff Garzik module_exit(hpt37x_exit); 1270