in pata_hpt37x.c [754:1041]
static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
/* HPT370 - UDMA66 */
static const struct ata_port_info info_hpt370_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA66 */
static const struct ata_port_info info_hpt370a_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &hpt370a_port_ops
};
/* HPT372 - UDMA133 */
static const struct ata_port_info info_hpt372 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops
};
/* HPT371, 302 - UDMA133 */
static const struct ata_port_info info_hpt302 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt302_port_ops
};
/* HPT374 - UDMA100, function 1 uses different cable_detect method */
static const struct ata_port_info info_hpt374_fn0 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt372_port_ops
};
static const struct ata_port_info info_hpt374_fn1 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt374_fn1_port_ops
};
static const int MHz[4] = { 33, 40, 50, 66 };
void *private_data = NULL;
const struct ata_port_info *ppi[] = { NULL, NULL };
u8 rev = dev->revision;
u8 irqmask;
u8 mcr1;
u32 freq;
int prefer_dpll = 1;
unsigned long iobase = pci_resource_start(dev, 4);
const struct hpt_chip *chip_table;
int clock_slot;
int rc;
rc = pcim_enable_device(dev);
if (rc)
return rc;
switch (dev->device) {
case PCI_DEVICE_ID_TTI_HPT366:
/* May be a later chip in disguise. Check */
/* Older chips are in the HPT366 driver. Ignore them */
if (rev < 3)
return -ENODEV;
/* N series chips have their own driver. Ignore */
if (rev == 6)
return -ENODEV;
switch (rev) {
case 3:
ppi[0] = &info_hpt370;
chip_table = &hpt370;
prefer_dpll = 0;
break;
case 4:
ppi[0] = &info_hpt370a;
chip_table = &hpt370a;
prefer_dpll = 0;
break;
case 5:
ppi[0] = &info_hpt372;
chip_table = &hpt372;
break;
default:
dev_err(&dev->dev,
"Unknown HPT366 subtype, please report (%d)\n",
rev);
return -ENODEV;
}
break;
case PCI_DEVICE_ID_TTI_HPT372:
/* 372N if rev >= 2 */
if (rev >= 2)
return -ENODEV;
ppi[0] = &info_hpt372;
chip_table = &hpt372a;
break;
case PCI_DEVICE_ID_TTI_HPT302:
/* 302N if rev > 1 */
if (rev > 1)
return -ENODEV;
ppi[0] = &info_hpt302;
/* Check this */
chip_table = &hpt302;
break;
case PCI_DEVICE_ID_TTI_HPT371:
if (rev > 1)
return -ENODEV;
ppi[0] = &info_hpt302;
chip_table = &hpt371;
/*
* Single channel device, master is not present but the BIOS
* (or us for non x86) must mark it absent
*/
pci_read_config_byte(dev, 0x50, &mcr1);
mcr1 &= ~0x04;
pci_write_config_byte(dev, 0x50, mcr1);
break;
case PCI_DEVICE_ID_TTI_HPT374:
chip_table = &hpt374;
if (!(PCI_FUNC(dev->devfn) & 1))
*ppi = &info_hpt374_fn0;
else
*ppi = &info_hpt374_fn1;
break;
default:
dev_err(&dev->dev, "PCI table is bogus, please report (%d)\n",
dev->device);
return -ENODEV;
}
/* Ok so this is a chip we support */
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
pci_read_config_byte(dev, 0x5A, &irqmask);
irqmask &= ~0x10;
pci_write_config_byte(dev, 0x5a, irqmask);
/*
* default to pci clock. make sure MA15/16 are set to output
* to prevent drives having problems with 40-pin cables. Needed
* for some drives such as IBM-DTLA which will not enter ready
* state on reset when PDIAG is a input.
*/
pci_write_config_byte(dev, 0x5b, 0x23);
/*
* HighPoint does this for HPT372A.
* NOTE: This register is only writeable via I/O space.
*/
if (chip_table == &hpt372a)
outb(0x0e, iobase + 0x9c);
/*
* Some devices do not let this value be accessed via PCI space
* according to the old driver. In addition we must use the value
* from FN 0 on the HPT374.
*/
if (chip_table == &hpt374) {
freq = hpt374_read_freq(dev);
if (freq == 0)
return -ENODEV;
} else
freq = inl(iobase + 0x90);
if ((freq >> 12) != 0xABCDE) {
int i;
u8 sr;
u32 total = 0;
dev_warn(&dev->dev, "BIOS has not set timing clocks\n");
/* This is the process the HPT371 BIOS is reported to use */
for (i = 0; i < 128; i++) {
pci_read_config_byte(dev, 0x78, &sr);
total += sr & 0x1FF;
udelay(15);
}
freq = total / 128;
}
freq &= 0x1FF;
/*
* Turn the frequency check into a band and then find a timing
* table to match it.
*/
clock_slot = hpt37x_clock_slot(freq, chip_table->base);
if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
/*
* We need to try PLL mode instead
*
* For non UDMA133 capable devices we should
* use a 50MHz DPLL by choice
*/
unsigned int f_low, f_high;
int dpll, adjust;
/* Compute DPLL */
dpll = (ppi[0]->udma_mask & 0xC0) ? 3 : 2;
f_low = (MHz[clock_slot] * 48) / MHz[dpll];
f_high = f_low + 2;
if (clock_slot > 1)
f_high += 2;
/* Select the DPLL clock. */
pci_write_config_byte(dev, 0x5b, 0x21);
pci_write_config_dword(dev, 0x5C,
(f_high << 16) | f_low | 0x100);
for (adjust = 0; adjust < 8; adjust++) {
if (hpt37x_calibrate_dpll(dev))
break;
/*
* See if it'll settle at a fractionally
* different clock
*/
if (adjust & 1)
f_low -= adjust >> 1;
else
f_high += adjust >> 1;
pci_write_config_dword(dev, 0x5C,
(f_high << 16) | f_low | 0x100);
}
if (adjust == 8) {
dev_err(&dev->dev, "DPLL did not stabilize!\n");
return -ENODEV;
}
if (dpll == 3)
private_data = (void *)hpt37x_timings_66;
else
private_data = (void *)hpt37x_timings_50;
dev_info(&dev->dev, "bus clock %dMHz, using %dMHz DPLL\n",
MHz[clock_slot], MHz[dpll]);
} else {
private_data = (void *)chip_table->clocks[clock_slot];
/*
* Perform a final fixup. Note that we will have used the
* DPLL on the HPT372 which means we don't have to worry
* about lack of UDMA133 support on lower clocks
*/
if (clock_slot < 2 && ppi[0] == &info_hpt370)
ppi[0] = &info_hpt370_33;
if (clock_slot < 2 && ppi[0] == &info_hpt370a)
ppi[0] = &info_hpt370a_33;
dev_info(&dev->dev, "%s using %dMHz bus clock\n",
chip_table->name, MHz[clock_slot]);
}
/* Now kick off ATA set up */
return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data, 0);
}