/*
* linux/drivers/ide/pci/siimage.c Version 1.16 Jul 13 2007
*
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
* Copyright (C) 2007 MontaVista Software, Inc.
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
* Documentation for CMD680:
* http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
*
* Documentation for SiI 3112:
* http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
*
* Errata and other documentation only available under NDA.
*
*
* FAQ Items:
* If you are using Marvell SATA-IDE adapters with Maxtor drives
* ensure the system is set up for ATA100/UDMA5 not UDMA6.
*
* If you are using WD drives with SATA bridges you must set the
* drive to "Single". "Master" will hang
*
* If you have strange problems with nVidia chipset systems please
* see the SI support documentation and update your system BIOS
* if neccessary
*
* The Dell DRAC4 has some interesting features including effectively hot
* unplugging/replugging the virtual CD interface when the DRAC is reset.
* This often causes drivers/ide/siimage to panic but is ok with the rather
* smarter code in libata.
*
* TODO:
* - IORDY fixes
* - VDMA support
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
/**
* pdev_is_sata - check if device is SATA
* @pdev: PCI device to check
*
* Returns true if this is a SATA controller
*/
static int pdev_is_sata(struct pci_dev *pdev)
{
switch(pdev->device)
{
case PCI_DEVICE_ID_SII_3112:
case PCI_DEVICE_ID_SII_1210SA:
return 1;
case PCI_DEVICE_ID_SII_680:
return 0;
}
BUG();
return 0;
}
/**
* is_sata - check if hwif is SATA
* @hwif: interface to check
*
* Returns true if this is a SATA controller
*/
static inline int is_sata(ide_hwif_t *hwif)
{
return pdev_is_sata(hwif->pci_dev);
}
/**
* siimage_selreg - return register base
* @hwif: interface
* @r: config offset
*
* Turn a config register offset into the right address in either
* PCI space or MMIO space to access the control register in question
* Thankfully this is a configuration operation so isnt performance
* criticial.
*/
static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
{
unsigned long base = (unsigned long)hwif->hwif_data;
base += 0xA0 + r;
if(hwif->mmio)
base += (hwif->channel << 6);
else
base += (hwif->channel << 4);
return base;
}
/**
* siimage_seldev - return register base
* @hwif: interface
* @r: config offset
*
* Turn a config register offset into the right address in either
* PCI space or MMIO space to access the control register in question
* including accounting for the unit shift.
*/
static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long base = (unsigned long)hwif->hwif_data;
base += 0xA0 + r;
if(hwif->mmio)
base += (hwif->channel << 6);
else
base += (hwif->channel << 4);
base |= drive->select.b.unit << drive->select.b.unit;
return base;
}
/**
* sil_udma_filter - compute UDMA mask
* @drive: IDE device
*
* Compute the available UDMA speeds for the device on the interface.
*
* For the CMD680 this depends on the clocking mode (scsc), for the
* SI3112 SATA controller life is a bit simpler.
*/
static u8 sil_udma_filter(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long base = (unsigned long) hwif->hwif_data;
u8 mask = 0, scsc = 0;
if (hwif->mmio)
scsc = hwif->INB(base + 0x4A);
else
pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
if (is_sata(hwif)) {
mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
goto out;
}
if ((scsc & 0x30) == 0x10) /* 133 */
mask = 0x7f;
else if ((scsc & 0x30) == 0x20) /* 2xPCI */
mask = 0x7f;
else if ((scsc & 0x30) == 0x00) /* 100 */
mask = 0x3f;
else /* Disabled ? */
BUG();
out:
return mask;
}
/**
* sil_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
*
* Load the timing settings for this device mode into the
* controller. If we are in PIO mode 3 or 4 turn on IORDY
* monitoring (bit 9). The TF timing is bits 31:16
*/
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
{
const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
ide_hwif_t *hwif = HWIF(drive);
ide_drive_t *pair = &hwif->drives[drive->dn ^ 1];
u32 speedt = 0;
u16 speedp = 0;
unsigned long addr = siimage_seldev(drive, 0x04);
unsigned long tfaddr = siimage_selreg(hwif,