// SPDX-License-Identifier: GPL-2.0-only /* * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers. * * This driver is heavily based upon: * * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 * * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. * * TODO * Look into engine reset on timeout errors. Should not be required.
*/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <scsi/scsi_host.h> #include <linux/libata.h>
/* key for bus clock timings * bit * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. * cycles = value + 1 * 4:8 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA. * cycles = value + 1 * 9:12 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file * register access. * 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file * register access. * 18:20 udma_cycle_time. Clock cycles for UDMA xfer. * 21 CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock. * 22:24 pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer. * 25:27 cmd_pre_high_time. Time to initialize 1st PIO cycle for task file * register access. * 28 UDMA enable. * 29 DMA enable. * 30 PIO_MST enable. If set, the chip is in bus master mode during * PIO xfer. * 31 FIFO enable. Only for PIO.
*/
/** * hpt37x_find_mode - reset the hpt37x bus * @ap: ATA port * @speed: transfer mode * * Return the 32bit register programming information for this channel * that matches the speed provided.
*/
/** * hpt370_filter - mode selection filter * @adev: ATA device * @mask: mode mask * * Block UDMA on devices that cause trouble with this controller.
*/
/** * hpt370a_filter - mode selection filter * @adev: ATA device * @mask: mode mask * * Block UDMA on devices that cause trouble with this controller.
*/
/** * hpt372_filter - mode selection filter * @adev: ATA device * @mask: mode mask * * The Marvell bridge chips used on the HighPoint SATA cards do not seem * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
*/ staticunsignedint hpt372_filter(struct ata_device *adev, unsignedint mask)
{ if (ata_id_is_sata(adev->id))
mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA);
return mask;
}
/** * hpt37x_cable_detect - Detect the cable type * @ap: ATA port to detect on * * Return the cable type attached to this port
*/
/* Do the extra channel work */
pci_read_config_word(pdev, mcrbase + 2, &mcr3); /* Set bit 15 of 0x52 to enable TCBLID as input */
pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000);
pci_read_config_byte(pdev, 0x5A, &ata66); /* Reset TCBLID/FCBLID to output */
pci_write_config_word(pdev, mcrbase + 2, mcr3);
/** * hpt37x_pre_reset - reset the hpt37x bus * @link: ATA link to reset * @deadline: deadline jiffies for the operation * * Perform the initial reset handling for the HPT37x.
*/
/** * hpt37x_clock_slot - Turn timing to PC clock entry * @freq: Reported frequency in MHz * * Turn the timing data into a clock slot (0 for 33, 1 for 40, 2 for 50 * and 3 for 66Mhz)
*/
/** * hpt37x_calibrate_dpll - Calibrate the DPLL loop * @dev: PCI device * * Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this * succeeds
*/
/* * 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 (pdev->device == PCI_DEVICE_ID_TTI_HPT374 &&
(PCI_FUNC(pdev->devfn) & 1)) { struct pci_dev *pdev_fn0;
pdev_fn0 = pci_get_slot(pdev->bus, pdev->devfn - 1); /* Someone hot plugged the controller on us? */ if (!pdev_fn0) return 0;
fcnt = inl(pci_resource_start(pdev_fn0, 4) + 0x90);
pci_dev_put(pdev_fn0);
} else {
fcnt = inl(pci_resource_start(pdev, 4) + 0x90);
}
if ((fcnt >> 12) != 0xABCDE) {
u32 total = 0; int i;
u16 sr;
dev_warn(&pdev->dev, "BIOS clock data not set\n");
/* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) {
pci_read_config_word(pdev, 0x78, &sr);
total += sr & 0x1FF;
udelay(15);
}
fcnt = total / 128;
}
fcnt &= 0x1FF;
freq = (fcnt * base) / 192; /* in MHz */
/* Clamp to bands */ if (freq < 40) return 33; if (freq < 45) return 40; if (freq < 55) return 50; return 66;
}
/** * hpt37x_init_one - Initialise an HPT37X/302 * @dev: PCI device * @id: Entry in match table * * Initialise an HPT37x device. There are some interesting complications * here. Firstly the chip may report 366 and be one of several variants. * Secondly all the timings depend on the clock for the chip which we must * detect and look up * * This is the known chip mappings. It may be missing a couple of later * releases. * * Chip version PCI Rev Notes * HPT366 4 (HPT366) 0 Other driver * HPT366 4 (HPT366) 1 Other driver * HPT368 4 (HPT366) 2 Other driver * HPT370 4 (HPT366) 3 UDMA100 * HPT370A 4 (HPT366) 4 UDMA100 * HPT372 4 (HPT366) 5 UDMA133 (1) * HPT372N 4 (HPT366) 6 Other driver * HPT372A 5 (HPT372) 1 UDMA133 (1) * HPT372N 5 (HPT372) 2 Other driver * HPT302 6 (HPT302) 1 UDMA133 * HPT302N 6 (HPT302) 2 Other driver * HPT371 7 (HPT371) * UDMA133 * HPT374 8 (HPT374) * UDMA133 4 channel * HPT372N 9 (HPT372N) * Other driver * * (1) UDMA133 support depends on the bus clock
*/
conststruct 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 */
/* * 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;
/* * 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);
freq = hpt37x_pci_clock(dev, chip_table->base); if (!freq) return -ENODEV;
/* * Turn the frequency check into a band and then find a timing * table to match it.
*/
clock_slot = hpt37x_clock_slot(freq); 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
*/ unsignedint f_low, f_high; int dpll, adjust;
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
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.