diff options
author | sos <sos@FreeBSD.org> | 2004-12-08 10:02:41 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2004-12-08 10:02:41 +0000 |
commit | d4647dd77b4747a05894d30fac7982203a55590e (patch) | |
tree | 170272731f30d145b04ca0c69e0c0d427010f8d5 /sys/dev/ata | |
parent | 5dc3dca989cf334ec3e33136af0d2fd116829952 (diff) | |
download | FreeBSD-src-d4647dd77b4747a05894d30fac7982203a55590e.zip FreeBSD-src-d4647dd77b4747a05894d30fac7982203a55590e.tar.gz |
Add first shot on support for the new Promise SATAII chips.
HW donated by: pil.dk
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-chipset.c | 152 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.h | 12 |
2 files changed, 116 insertions, 48 deletions
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index 83c38a5..6cc76b7 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -1177,32 +1177,37 @@ ata_promise_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_PDC20246, 0, PROLD, 0x00, ATA_UDMA2, "Promise PDC20246" }, - { ATA_PDC20262, 0, PRNEW, 0x00, ATA_UDMA4, "Promise PDC20262" }, - { ATA_PDC20263, 0, PRNEW, 0x00, ATA_UDMA4, "Promise PDC20263" }, - { ATA_PDC20265, 0, PRNEW, 0x00, ATA_UDMA5, "Promise PDC20265" }, - { ATA_PDC20267, 0, PRNEW, 0x00, ATA_UDMA5, "Promise PDC20267" }, - { ATA_PDC20268, 0, PRTX, PRTX4, ATA_UDMA5, "Promise PDC20268" }, - { ATA_PDC20269, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20269" }, - { ATA_PDC20270, 0, PRTX, PRTX4, ATA_UDMA5, "Promise PDC20270" }, - { ATA_PDC20271, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20271" }, - { ATA_PDC20275, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20275" }, - { ATA_PDC20276, 0, PRTX, PRSX6K, ATA_UDMA6, "Promise PDC20276" }, - { ATA_PDC20277, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20277" }, - { ATA_PDC20318, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20318" }, - { ATA_PDC20319, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20319" }, - { ATA_PDC20371, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20371" }, - { ATA_PDC20375, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20375" }, - { ATA_PDC20376, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20376" }, - { ATA_PDC20377, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20377" }, - { ATA_PDC20378, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20378" }, - { ATA_PDC20379, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20379" }, - { ATA_PDC20617, 0, PRMIO, PRDUAL, ATA_UDMA6, "Promise PDC20617" }, - { ATA_PDC20618, 0, PRMIO, PRDUAL, ATA_UDMA6, "Promise PDC20618" }, - { ATA_PDC20619, 0, PRMIO, PRDUAL, ATA_UDMA6, "Promise PDC20619" }, - { ATA_PDC20620, 0, PRMIO, PRDUAL, ATA_UDMA6, "Promise PDC20620" }, - { ATA_PDC20621, 0, PRMIO, PRSX4X, ATA_UDMA5, "Promise PDC20621" }, - { ATA_PDC20622, 0, PRMIO, PRSX4X, ATA_SA150, "Promise PDC20622" }, + {{ ATA_PDC20246, 0, PROLD, 0x00, ATA_UDMA2, "Promise PDC20246" }, + { ATA_PDC20262, 0, PRNEW, 0x00, ATA_UDMA4, "Promise PDC20262" }, + { ATA_PDC20263, 0, PRNEW, 0x00, ATA_UDMA4, "Promise PDC20263" }, + { ATA_PDC20265, 0, PRNEW, 0x00, ATA_UDMA5, "Promise PDC20265" }, + { ATA_PDC20267, 0, PRNEW, 0x00, ATA_UDMA5, "Promise PDC20267" }, + { ATA_PDC20268, 0, PRTX, PRTX4, ATA_UDMA5, "Promise PDC20268" }, + { ATA_PDC20269, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20269" }, + { ATA_PDC20270, 0, PRTX, PRTX4, ATA_UDMA5, "Promise PDC20270" }, + { ATA_PDC20271, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20271" }, + { ATA_PDC20275, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20275" }, + { ATA_PDC20276, 0, PRTX, PRSX6K, ATA_UDMA6, "Promise PDC20276" }, + { ATA_PDC20277, 0, PRTX, 0x00, ATA_UDMA6, "Promise PDC20277" }, + { ATA_PDC20318, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20318" }, + { ATA_PDC20319, 0, PRMIO, PRSATA, ATA_SA150, "Promise PDC20319" }, + { ATA_PDC20371, 0, PRMIO, PRCMBO, ATA_SA150, "Promise PDC20371" }, + { ATA_PDC20375, 0, PRMIO, PRCMBO, ATA_SA150, "Promise PDC20375" }, + { ATA_PDC20376, 0, PRMIO, PRCMBO, ATA_SA150, "Promise PDC20376" }, + { ATA_PDC20377, 0, PRMIO, PRCMBO, ATA_SA150, "Promise PDC20377" }, + { ATA_PDC20378, 0, PRMIO, PRCMBO, ATA_SA150, "Promise PDC20378" }, + { ATA_PDC20379, 0, PRMIO, PRCMBO, ATA_SA150, "Promise PDC20379" }, + { ATA_PDC20571, 0, PRMIO, PRCMBO2, ATA_SA150, "Promise PDC20571" }, + { ATA_PDC20575, 0, PRMIO, PRCMBO2, ATA_SA150, "Promise PDC20575" }, + { ATA_PDC20579, 0, PRMIO, PRCMBO2, ATA_SA150, "Promise PDC20579" }, + { ATA_PDC20580, 0, PRMIO, PRCMBO2, ATA_SA150, "Promise PDC20580" }, + { ATA_PDC20617, 0, PRMIO, PRPATA, ATA_UDMA6, "Promise PDC20617" }, + { ATA_PDC20618, 0, PRMIO, PRPATA, ATA_UDMA6, "Promise PDC20618" }, + { ATA_PDC20619, 0, PRMIO, PRPATA, ATA_UDMA6, "Promise PDC20619" }, + { ATA_PDC20620, 0, PRMIO, PRPATA, ATA_UDMA6, "Promise PDC20620" }, + { ATA_PDC20621, 0, PRMIO, PRSX4X, ATA_UDMA5, "Promise PDC20621" }, + { ATA_PDC20622, 0, PRMIO, PRSX4X, ATA_SA150, "Promise PDC20622" }, + { ATA_PDC40518, 0, PRMIO, PRSATA2, ATA_SA150, "Promise PDC40518" }, { 0, 0, 0, 0, 0, 0}}; char buffer[64]; uintptr_t devid = 0; @@ -1304,11 +1309,11 @@ ata_promise_chipinit(device_t dev) ctlr->dmainit = ata_promise_mio_dmainit; ctlr->allocate = ata_promise_mio_allocate; - if (ctlr->chip->cfg2 & PRDUAL) { + if (ctlr->chip->cfg2 & PRPATA) { ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x01) > 0) + ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2; } - else if (ctlr->chip->cfg2 & PRSATA) { + else if (ctlr->chip->cfg2 & PRCMBO) { ATA_OUTL(ctlr->r_res2, 0x06c, 0x000000ff); ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 3; } @@ -1372,7 +1377,8 @@ ata_promise_mio_allocate(device_t dev, struct ata_channel *ch) ch->r_io[ATA_ALTSTAT].offset = offset + 0x0238 + (ch->unit << 7); ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2; ch->flags |= ATA_USE_16BIT; - + if (ctlr->chip->cfg2 & (PRSATA | PRSATA2)) + ch->flags |= ATA_NO_SLAVE; ata_generic_hw(ch); if (ctlr->chip->cfg2 & PRSX4X) ch->hw.command = ata_promise_sx4_command; @@ -1390,15 +1396,19 @@ ata_promise_mio_intr(void *data) u_int32_t status = 0; int unit; - if (ctlr->chip->cfg2 & PRSATA) { + if (ctlr->chip->cfg2 & (PRSATA | PRCMBO)) { status = ATA_INL(ctlr->r_res2, 0x06c); ATA_OUTL(ctlr->r_res2, 0x06c, status & 0x000000ff); } - + if (ctlr->chip->cfg2 & (PRSATA2 | PRCMBO2)) { + ATA_OUTL(ctlr->r_res2, 0x040, vector & 0x0000ffff); + status = ATA_INL(ctlr->r_res2, 0x060); + ATA_OUTL(ctlr->r_res2, 0x060, status & 0x000000ff); + } for (unit = 0; unit < ctlr->channels; unit++) { if (status & (0x00000011 << unit)) - if ((ch = ctlr->interrupt[unit].argument) && ch->reset) - ch->reset(ch); + if ((ch = ctlr->interrupt[unit].argument)) + ata_promise_mio_reset(ch); if (vector & (1 << (unit + 1))) if ((ch = ctlr->interrupt[unit].argument)) ctlr->interrupt[unit].function(ch); @@ -1471,6 +1481,7 @@ ata_promise_mio_reset(struct ata_channel *ch) if (ctlr->chip->cfg2 & PRSX4X) { struct ata_promise_sx4 *hpktp = ctlr->driver; + /* softreset channels ATA module */ ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), ch->unit + 1); DELAY(1000); @@ -1478,6 +1489,7 @@ ata_promise_mio_reset(struct ata_channel *ch) (ATA_INL(ctlr->r_res2, 0xc0260 + (ch->unit << 7)) & ~0x00003f9f) | (ch->unit + 1)); + /* softreset HOST module */ mtx_lock(&hpktp->mtx); ATA_OUTL(ctlr->r_res2, 0xc012c, (ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f) | (1 << 11)); @@ -1486,26 +1498,74 @@ ata_promise_mio_reset(struct ata_channel *ch) (ATA_INL(ctlr->r_res2, 0xc012c) & ~0x00000f9f)); mtx_unlock(&hpktp->mtx); } - else { - if (ctlr->chip->cfg2 & PRSATA) - ATA_OUTL(ctlr->r_res2, 0x06c, (0x00110000 << ch->unit)); + else if (ctlr->chip->cfg2 & PRSATA) { + u_int32_t status = 0; + int timeout; - ATA_OUTL(ctlr->r_res2, 0x0048, - ATA_INL(ctlr->r_res2, 0x0048) & ~((1 << 12) << (ch->unit))); - DELAY(10); - ATA_OUTL(ctlr->r_res2, 0x0048, - ATA_INL(ctlr->r_res2, 0x0048) | ((1 << 12) << (ch->unit))); - DELAY(100); + /* mask plug/unplug intr */ + ATA_OUTL(ctlr->r_res2, 0x06c, (0x00110000 << ch->unit)); - if (ctlr->chip->cfg2 & PRSATA) - ATA_OUTL(ctlr->r_res2, 0x06c, (0x00000011 << ch->unit)); + /* softreset channels ATA module */ + ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11)); + ata_udelay(10000); + ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), + (ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) & + ~0x00003f9f) | (ch->unit + 1)); - ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), 0x00000800); - DELAY(1000); + /* enable PHY XXX SOS */ + /* wait up to 1 sec for "connect well" */ + for (timeout = 0; timeout > 1000000 ; timeout += 100) { + status = ATA_INL(ctlr->r_res2, 0x400 + (ch->unit << 8)); + if ((status & 0x313) == 0x112) + break; + ata_udelay(10000); + } + if (timeout >= 1000000) + device_printf(ch->dev, "connect status=%08x\n", status); + + /* enable plug/unplug intr */ + ATA_OUTL(ctlr->r_res2, 0x06c, (0x00000011 << ch->unit)); + } + else if (ctlr->chip->cfg2 & PRSATA2) { + u_int32_t status = 0; + int timeout; + + /* set PM port */ + ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f); + + /* mask plug/unplug intr */ + ATA_OUTL(ctlr->r_res2, 0x060, (0x00110000 << ch->unit)); + + /* softreset channels ATA module */ + ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (1 << 11)); + ata_udelay(10000); ATA_OUTL(ctlr->r_res2, 0x0260 + (ch->unit << 7), (ATA_INL(ctlr->r_res2, 0x0260 + (ch->unit << 7)) & ~0x00003f9f) | (ch->unit + 1)); + + /* enable PHY XXX SOS */ + /* set PHY mode to "improved" */ + ATA_OUTL(ctlr->r_res2, 0x414 + (ch->unit << 8), + (ATA_INL(ctlr->r_res2, 0x414 + (ch->unit << 8)) & + ~0x00000003) | 0x00000001); + + /* wait up to 1 sec for "connect well" */ + for (timeout = 0; timeout > 1000000 ; timeout += 100) { + status = ATA_INL(ctlr->r_res2, 0x400 + (ch->unit << 8)); + + if ((status & 0x737) == 0x113 || (status & 0x727) == 0x123) + break; + ata_udelay(10000); + } + if (timeout >= 1000000) + device_printf(ch->dev, "connect status=%08x\n", status); + + /* enable plug/unplug intr */ + ATA_OUTL(ctlr->r_res2, 0x060, (0x00000011 << ch->unit)); + + /* set PM port */ + ATA_OUTL(ctlr->r_res2, 0x4e8 + (ch->unit * 0x100), 0x00); } } diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index a8c5608..e054bcb 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -165,6 +165,11 @@ struct ata_pci_controller { #define ATA_PDC20377 0x3377105a #define ATA_PDC20378 0x3373105a #define ATA_PDC20379 0x3372105a +#define ATA_PDC20571 0x3571105a +#define ATA_PDC20575 0x3d75105a +#define ATA_PDC20579 0x3574105a +#define ATA_PDC20580 0x3570105a +#define ATA_PDC40518 0x3d18105a #define ATA_PDC20617 0x6617105a #define ATA_PDC20618 0x6626105a #define ATA_PDC20619 0x6629105a @@ -272,8 +277,11 @@ struct ata_pci_controller { #define PRTX4 0x01 #define PRSX4X 0x02 #define PRSX6K 0x04 -#define PRSATA 0x08 -#define PRDUAL 0x10 +#define PRPATA 0x08 +#define PRCMBO 0x10 +#define PRCMBO2 0x20 +#define PRSATA 0x40 +#define PRSATA2 0x80 #define SWKS33 0 #define SWKS66 1 |