summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-12-08 10:02:41 +0000
committersos <sos@FreeBSD.org>2004-12-08 10:02:41 +0000
commitd4647dd77b4747a05894d30fac7982203a55590e (patch)
tree170272731f30d145b04ca0c69e0c0d427010f8d5 /sys/dev/ata
parent5dc3dca989cf334ec3e33136af0d2fd116829952 (diff)
downloadFreeBSD-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.c152
-rw-r--r--sys/dev/ata/ata-pci.h12
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
OpenPOWER on IntegriCloud