diff options
author | dfr <dfr@FreeBSD.org> | 2000-07-18 09:01:09 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2000-07-18 09:01:09 +0000 |
commit | 5aef58d7b9d8523da7d5c51472067b91b09bd239 (patch) | |
tree | d607ec799631b59af355708f699bd1aa8039aa43 /sys/dev/ppc | |
parent | cc48e301037a7473b6f5da1ca019ad6ac61a1ebe (diff) | |
download | FreeBSD-src-5aef58d7b9d8523da7d5c51472067b91b09bd239.zip FreeBSD-src-5aef58d7b9d8523da7d5c51472067b91b09bd239.tar.gz |
Add smc37c935 chipset support and clean up the code which tries to
allocate a short port range in some alpha configurations.
Submitted by: "Andrew M. Miklic" <miklic@udlkern.fc.hp.com>,
Mark Abene <phiber@radicalmedia.com>
Diffstat (limited to 'sys/dev/ppc')
-rw-r--r-- | sys/dev/ppc/ppc.c | 140 | ||||
-rw-r--r-- | sys/dev/ppc/ppcreg.h | 31 |
2 files changed, 139 insertions, 32 deletions
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c index c6818a2..ab25faf 100644 --- a/sys/dev/ppc/ppc.c +++ b/sys/dev/ppc/ppc.c @@ -112,7 +112,8 @@ static driver_t ppc_driver = { static char *ppc_models[] = { "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306", - "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 0 + "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", + "SMC FDC37C935", 0 }; /* list of available modes */ @@ -883,6 +884,91 @@ end_detect: } /* + * SMC FDC37C935 configuration + * Found on many Alpha machines + */ +static int +ppc_smc37c935_detect(struct ppc_data *ppc, int chipset_mode) +{ + int s; + int type = -1; + + s = splhigh(); + outb(SMC935_CFG, 0x55); /* enter config mode */ + outb(SMC935_CFG, 0x55); + splx(s); + + outb(SMC935_IND, SMC935_ID); /* check device id */ + if (inb(SMC935_DAT) == 0x2) + type = SMC_37C935; + + if (type == -1) { + outb(SMC935_CFG, 0xaa); /* exit config mode */ + return (-1); + } + + ppc->ppc_model = type; + + outb(SMC935_IND, SMC935_LOGDEV); /* select parallel port, */ + outb(SMC935_DAT, 3); /* which is logical device 3 */ + + /* set io port base */ + outb(SMC935_IND, SMC935_PORTHI); + outb(SMC935_DAT, (u_char)((ppc->ppc_base & 0xff00) >> 8)); + outb(SMC935_IND, SMC935_PORTLO); + outb(SMC935_DAT, (u_char)(ppc->ppc_base & 0xff)); + + if (!chipset_mode) + ppc->ppc_avm = PPB_COMPATIBLE; /* default mode */ + else { + ppc->ppc_avm = chipset_mode; + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_CENT); /* start in compatible mode */ + + /* SPP + EPP or just plain SPP */ + if (chipset_mode & (PPB_SPP)) { + if (chipset_mode & PPB_EPP) { + if (ppc->ppc_epp == EPP_1_9) { + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_EPP19SPP); + } + if (ppc->ppc_epp == EPP_1_7) { + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_EPP17SPP); + } + } else { + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_SPP); + } + } + + /* ECP + EPP or just plain ECP */ + if (chipset_mode & PPB_ECP) { + if (chipset_mode & PPB_EPP) { + if (ppc->ppc_epp == EPP_1_9) { + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_ECPEPP19); + } + if (ppc->ppc_epp == EPP_1_7) { + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_ECPEPP17); + } + } else { + outb(SMC935_IND, SMC935_PPMODE); + outb(SMC935_DAT, SMC935_ECP); + } + } + } + + outb(SMC935_CFG, 0xaa); /* exit config mode */ + + ppc->ppc_type = PPC_TYPE_SMCLIKE; + ppc_smclike_setmode(ppc, chipset_mode); + + return (chipset_mode); +} + +/* * Winbond W83877F stuff * * EFER: extended function enable register @@ -1162,6 +1248,7 @@ ppc_detect(struct ppc_data *ppc, int chipset_mode) { ppc_pc873xx_detect, ppc_smc37c66xgt_detect, ppc_w83877f_detect, + ppc_smc37c935_detect, ppc_generic_detect, NULL }; @@ -1744,7 +1831,8 @@ ppc_probe(device_t dev) device_printf(dev, "parallel port not found.\n"); return ENXIO; } - bus_set_resource(dev, SYS_RES_IOPORT, 0, port, IO_LPTSIZE); + bus_set_resource(dev, SYS_RES_IOPORT, 0, port, + IO_LPTSIZE_EXTENDED); } #endif #ifdef __alpha__ @@ -1752,42 +1840,34 @@ ppc_probe(device_t dev) * There isn't a bios list on alpha. Put it in the usual place. */ if (error) { - bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3bc, IO_LPTSIZE); + bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3bc, + IO_LPTSIZE_NORMAL); } #endif /* IO port is mandatory */ + + /* Try "extended" IO port range...*/ ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &ppc->rid_ioport, 0, ~0, - IO_LPTSIZE, RF_ACTIVE); - if (ppc->res_ioport == 0) { - device_printf(dev, "cannot reserve I/O port range\n"); - goto error; - } - - /* Assume we support the extended IO range of some ppc chipsets...*/ - - ppc->rid_extraio = 1; - ppc->res_extraio = - bus_alloc_resource(dev, - SYS_RES_IOPORT, - &ppc->rid_extraio, - 0, - ~0, - IO_LPTSIZE, - RF_ACTIVE); - - /* If we cannot reserve the extra ports for the extended IO range, - indicate this with a non-threatening message (this is not an error, - so don't treat it as such)... */ - - if (ppc->res_extraio == 0) { - - ppc->rid_extraio = 0; + IO_LPTSIZE_EXTENDED, RF_ACTIVE); + if (ppc->res_ioport != 0) { if (bootverbose) - device_printf(dev, -"This ppc chipset does not support the extended I/O port range...no problem\n"); + device_printf(dev, "using extended I/O port range\n"); + } else { + /* Failed? If so, then try the "normal" IO port range... */ + ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, + &ppc->rid_ioport, 0, ~0, + IO_LPTSIZE_NORMAL, + RF_ACTIVE); + if (ppc->res_ioport != 0) { + if (bootverbose) + device_printf(dev, "using normal I/O port range\n"); + } else { + device_printf(dev, "cannot reserve I/O port range\n"); + goto error; + } } ppc->ppc_base = rman_get_start(ppc->res_ioport); diff --git a/sys/dev/ppc/ppcreg.h b/sys/dev/ppc/ppcreg.h index ab0bf6f..2d2266a 100644 --- a/sys/dev/ppc/ppcreg.h +++ b/sys/dev/ppc/ppcreg.h @@ -43,6 +43,7 @@ #define WINB_W83877AF 8 #define WINB_UNKNOWN 9 #define NS_PC87334 10 +#define SMC_37C935 11 /* * Parallel Port Chipset Type. SMC versus GENERIC (others) @@ -100,8 +101,8 @@ struct ppc_data { device_t ppbus; /* parallel port chipset corresponding ppbus */ - int rid_irq, rid_drq, rid_ioport, rid_extraio; - struct resource *res_irq, *res_drq, *res_ioport, *res_extraio; + int rid_irq, rid_drq, rid_ioport; + struct resource *res_irq, *res_drq, *res_ioport; void *intr_cookie; @@ -206,6 +207,32 @@ struct ppc_data { #define SMC_ECPEPP 0x3 /* ECP and EPP */ /* + * Register defines for the SMC FDC37C935 parts + */ + +/* Configuration ports */ +#define SMC935_CFG 0x370 +#define SMC935_IND 0x370 +#define SMC935_DAT 0x371 + +/* Registers */ +#define SMC935_LOGDEV 0x7 +#define SMC935_ID 0x20 +#define SMC935_PORTHI 0x60 +#define SMC935_PORTLO 0x61 +#define SMC935_PPMODE 0xf0 + +/* Parallel port modes */ +#define SMC935_SPP 0x38 + 0 +#define SMC935_EPP19SPP 0x38 + 1 +#define SMC935_ECP 0x38 + 2 +#define SMC935_ECPEPP19 0x38 + 3 +#define SMC935_CENT 0x38 + 4 +#define SMC935_EPP17SPP 0x38 + 5 +#define SMC935_UNUSED 0x38 + 6 +#define SMC935_ECPEPP17 0x38 + 7 + +/* * Register defines for the Winbond W83877F parts */ |