Add support for the ATI IXP[234]00 series chipsets.

HW donated by: sentex
This commit is contained in:
Søren Schmidt 2005-10-12 20:00:26 +00:00
parent febd0759f3
commit 7ebce0231b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151267
4 changed files with 126 additions and 1 deletions

View File

@ -77,6 +77,8 @@ static int ata_ali_sata_allocate(device_t dev);
static void ata_ali_reset(device_t dev);
static void ata_ali_setmode(device_t dev, int mode);
static int ata_amd_chipinit(device_t dev);
static int ata_ati_chipinit(device_t dev);
static void ata_ati_setmode(device_t dev, int mode);
static int ata_cyrix_chipinit(device_t dev);
static void ata_cyrix_setmode(device_t dev, int mode);
static int ata_cypress_chipinit(device_t dev);
@ -1110,6 +1112,115 @@ ata_amd_chipinit(device_t dev)
}
/*
* ATI chipset support functions
*/
int
ata_ati_ident(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
struct ata_chip_id *idx;
static struct ata_chip_id ids[] =
{{ ATA_ATI_IXP200, 0x00, 0, 0, ATA_UDMA5, "ATI IXP200" },
{ ATA_ATI_IXP300, 0x00, 0, 0, ATA_UDMA6, "ATI IXP300" },
{ ATA_ATI_IXP400, 0x00, 0, 0, ATA_UDMA6, "ATI IXP400" },
{ ATA_ATI_IXP300_S1, 0x00, SIIMEMIO, 0, ATA_SA150, "ATI IXP300" },
{ ATA_ATI_IXP400_S1, 0x00, SIIMEMIO, 0, ATA_SA150, "ATI IXP400" },
{ ATA_ATI_IXP400_S2, 0x00, SIIMEMIO, 0, ATA_SA150, "ATI IXP400" },
{ 0, 0, 0, 0, 0, 0}};
char buffer[64];
if (!(idx = ata_match_chip(dev, ids)))
return ENXIO;
sprintf(buffer, "%s %s controller", idx->text, ata_mode2str(idx->max_dma));
device_set_desc_copy(dev, buffer);
ctlr->chip = idx;
/* the ATI SATA controller is actually a SiI 3112 controller*/
if (ctlr->chip->cfg1 & SIIMEMIO)
ctlr->chipinit = ata_sii_chipinit;
else
ctlr->chipinit = ata_ati_chipinit;
return 0;
}
static int
ata_ati_chipinit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
if (ata_setup_interrupt(dev))
return ENXIO;
ctlr->setmode = ata_ati_setmode;
return 0;
}
static void
ata_ati_setmode(device_t dev, int mode)
{
device_t gparent = GRANDPARENT(dev);
struct ata_pci_controller *ctlr = device_get_softc(gparent);
struct ata_channel *ch = device_get_softc(device_get_parent(dev));
struct ata_device *atadev = device_get_softc(dev);
int devno = (ch->unit << 1) + ATA_DEV(atadev->unit);
int offset = (devno ^ 0x01) << 3;
int error;
u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
mode = ata_check_80pin(dev, mode);
error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
if (bootverbose)
device_printf(dev, "%ssetting %s on %s chip\n",
(error) ? "FAILURE " : "",
ata_mode2str(mode), ctlr->chip->text);
if (!error) {
if (mode >= ATA_UDMA0) {
pci_write_config(gparent, 0x56,
(pci_read_config(gparent, 0x56, 2) &
~(0xf << (devno << 2))) |
((mode & ATA_MODE_MASK) << (devno << 2)), 2);
pci_write_config(gparent, 0x54,
pci_read_config(gparent, 0x54, 1) |
(0x01 << devno), 1);
pci_write_config(gparent, 0x44,
(pci_read_config(gparent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[2] << offset), 4);
}
else if (mode >= ATA_WDMA0) {
pci_write_config(gparent, 0x54,
pci_read_config(gparent, 0x54, 1) &
~(0x01 << devno), 1);
pci_write_config(gparent, 0x44,
(pci_read_config(gparent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[mode & ATA_MODE_MASK] << offset), 4);
}
else
pci_write_config(gparent, 0x54,
pci_read_config(gparent, 0x54, 1) &
~(0x01 << devno), 1);
pci_write_config(gparent, 0x4a,
(pci_read_config(gparent, 0x4a, 2) &
~(0xf << (devno << 2))) |
(((mode - ATA_PIO0) & ATA_MODE_MASK) << (devno<<2)),2);
pci_write_config(gparent, 0x40,
(pci_read_config(gparent, 0x40, 4) &
~(0xff << offset)) |
(piotimings[ata_mode2idx(mode)] << offset), 4);
atadev->mode = mode;
}
}
/*
* Cyrix chipset support functions
*/
@ -3260,7 +3371,7 @@ ata_serverworks_setmode(device_t dev, int mode)
pci_write_config(gparent, 0x44,
(pci_read_config(gparent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[mode & ATA_MODE_MASK] << offset),4);
(dmatimings[mode & ATA_MODE_MASK] << offset), 4);
}
else
pci_write_config(gparent, 0x54,

View File

@ -90,6 +90,10 @@ ata_pci_probe(device_t dev)
if (!ata_amd_ident(dev))
return 0;
break;
case ATA_ATI_ID:
if (!ata_ati_ident(dev))
return 0;
break;
case ATA_CYRIX_ID:
if (!ata_cyrix_ident(dev))
return 0;

View File

@ -97,6 +97,14 @@ struct ata_connect_task {
#define ATA_ALI_5288 0x528810b9
#define ATA_ALI_5289 0x528910b9
#define ATA_ATI_ID 0x1002
#define ATA_ATI_IXP200 0x43491002
#define ATA_ATI_IXP300 0x43691002
#define ATA_ATI_IXP400 0x43761002
#define ATA_ATI_IXP300_S1 0x436e1002
#define ATA_ATI_IXP400_S1 0x43791002
#define ATA_ATI_IXP400_S2 0x437a1002
#define ATA_CENATEK_ID 0x16ca
#define ATA_CENATEK_ROCKET 0x000116ca
@ -373,6 +381,7 @@ int ata_generic_ident(device_t);
int ata_acard_ident(device_t);
int ata_ali_ident(device_t);
int ata_amd_ident(device_t);
int ata_ati_ident(device_t);
int ata_cyrix_ident(device_t);
int ata_cypress_ident(device_t);
int ata_highpoint_ident(device_t);

View File

@ -1225,6 +1225,7 @@ ata_raid_read_metadata(device_t subdisk)
return 0;
break;
case ATA_ATI_ID:
case ATA_SILICON_IMAGE_ID:
if (ata_raid_sii_read_meta(subdisk, ata_raid_arrays))
return 0;