in pata_hpt3x2n.c [472:603]
static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* HPT372N - UDMA133 */
static const struct ata_port_info info_hpt372n = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt372n_port_ops
};
/* HPT302N and HPT371N - UDMA133 */
static const struct ata_port_info info_hpt3xxn = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt3xxn_port_ops
};
const struct ata_port_info *ppi[] = { &info_hpt3xxn, NULL };
u8 rev = dev->revision;
u8 irqmask;
unsigned int pci_mhz;
unsigned int f_low, f_high;
int adjust;
unsigned long iobase = pci_resource_start(dev, 4);
void *hpriv = (void *)USE_DPLL;
int rc;
rc = pcim_enable_device(dev);
if (rc)
return rc;
switch (dev->device) {
case PCI_DEVICE_ID_TTI_HPT366:
/* 372N if rev >= 6 */
if (rev < 6)
return -ENODEV;
goto hpt372n;
case PCI_DEVICE_ID_TTI_HPT371:
/* 371N if rev >= 2 */
if (rev < 2)
return -ENODEV;
break;
case PCI_DEVICE_ID_TTI_HPT372:
/* 372N if rev >= 2 */
if (rev < 2)
return -ENODEV;
goto hpt372n;
case PCI_DEVICE_ID_TTI_HPT302:
/* 302N if rev >= 2 */
if (rev < 2)
return -ENODEV;
break;
case PCI_DEVICE_ID_TTI_HPT372N:
hpt372n:
ppi[0] = &info_hpt372n;
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);
/*
* HPT371 chips physically have only one channel, the secondary one,
* but the primary channel registers do exist! Go figure...
* So, we manually disable the non-existing channel here
* (if the BIOS hasn't done this already).
*/
if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
u8 mcr1;
pci_read_config_byte(dev, 0x50, &mcr1);
mcr1 &= ~0x04;
pci_write_config_byte(dev, 0x50, mcr1);
}
/*
* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or
* 50 for UDMA100. Right now we always use 66
*/
pci_mhz = hpt3x2n_pci_clock(dev);
f_low = (pci_mhz * 48) / 66; /* PCI Mhz for 66Mhz DPLL */
f_high = f_low + 2; /* Tolerance */
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
/* PLL clock */
pci_write_config_byte(dev, 0x5B, 0x21);
/* Unlike the 37x we don't try jiggling the frequency */
for (adjust = 0; adjust < 8; adjust++) {
if (hpt3xn_calibrate_dpll(dev))
break;
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
}
if (adjust == 8) {
dev_err(&dev->dev, "DPLL did not stabilize!\n");
return -ENODEV;
}
dev_info(&dev->dev, "bus clock %dMHz, using 66MHz DPLL\n", pci_mhz);
/*
* Set our private data up. We only need a few flags
* so we use it directly.
*/
if (pci_mhz > 60)
hpriv = (void *)(PCI66 | USE_DPLL);
/*
* On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
* the MISC. register to stretch the UltraDMA Tss timing.
* NOTE: This register is only writeable via I/O space.
*/
if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
/* Now kick off ATA set up */
return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0);
}