diff options
author | raj <raj@FreeBSD.org> | 2008-04-26 17:47:28 +0000 |
---|---|---|
committer | raj <raj@FreeBSD.org> | 2008-04-26 17:47:28 +0000 |
commit | a681868ea5dbad90ea028a90173c94ddb1059477 (patch) | |
tree | 36feaa767c4375b80d7765bb9e44f8e36bdaef88 /sys/powerpc | |
parent | 08c272026d9b7b1389020a5077bd757317f6d1da (diff) | |
download | FreeBSD-src-a681868ea5dbad90ea028a90173c94ddb1059477.zip FreeBSD-src-a681868ea5dbad90ea028a90173c94ddb1059477.tar.gz |
Improve handling of Local Access Windows on MPC85xx systems:
- detect number of LAWs in run time and initalize accordingly
- introduce decode windows target IDs used in MPC8572
- other minor updates
Obtained from: Freescale, Semihalf
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/include/cpufunc.h | 11 | ||||
-rw-r--r-- | sys/powerpc/mpc85xx/ocpbus.c | 39 | ||||
-rw-r--r-- | sys/powerpc/mpc85xx/ocpbus.h | 15 | ||||
-rw-r--r-- | sys/powerpc/mpc85xx/pci_ocp.c | 4 |
4 files changed, 50 insertions, 19 deletions
diff --git a/sys/powerpc/include/cpufunc.h b/sys/powerpc/include/cpufunc.h index f02ff3b..3eb0ac0 100644 --- a/sys/powerpc/include/cpufunc.h +++ b/sys/powerpc/include/cpufunc.h @@ -44,6 +44,7 @@ powerpc_mb(void) #include <sys/types.h> #include <machine/psl.h> +#include <machine/spr.h> struct thread; @@ -122,6 +123,16 @@ mfpvr(void) return (value); } +static __inline register_t +mfsvr(void) +{ + register_t value; + + __asm __volatile ("mfspr %0, %1" : "=r"(value) : "K"(SPR_SVR)); + + return (value); +} + static __inline void eieio(void) { diff --git a/sys/powerpc/mpc85xx/ocpbus.c b/sys/powerpc/mpc85xx/ocpbus.c index cf86eed..e85361e 100644 --- a/sys/powerpc/mpc85xx/ocpbus.c +++ b/sys/powerpc/mpc85xx/ocpbus.c @@ -113,6 +113,8 @@ devclass_t ocpbus_devclass; DRIVER_MODULE(ocpbus, nexus, ocpbus_driver, ocpbus_devclass, 0, 0); +static int law_max = 0; + static __inline uint32_t ccsr_read4(uintptr_t addr) { @@ -204,18 +206,18 @@ ocpbus_write_law(int trgt, int type, u_long *startp, u_long *countp) sr = 0x80000000 | (trgt << 20) | (ffsl(size) - 2); /* Check if already programmed. */ - for (i = 0; i < 8; i++) { + for (i = 0; i < law_max; i++) { if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && bar == ccsr_read4(OCP85XX_LAWBAR(i))) return (0); } /* Find an unused access window .*/ - for (i = 0; i < 8; i++) { + for (i = 0; i < law_max; i++) { if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0) break; } - if (i == 8) + if (i == law_max) return (ENOSPC); ccsr_write4(OCP85XX_LAWBAR(i), bar); @@ -226,6 +228,16 @@ ocpbus_write_law(int trgt, int type, u_long *startp, u_long *countp) static int ocpbus_probe (device_t dev) { + struct ocpbus_softc *sc; + uint32_t svr; + + sc = device_get_softc(dev); + + svr = mfsvr(); + if (svr == SVR_MPC8572E || svr == SVR_MPC8572) + law_max = 12; + else + law_max = 8; device_set_desc(dev, "On-Chip Peripherals bus"); return (BUS_PROBE_DEFAULT); @@ -234,10 +246,10 @@ ocpbus_probe (device_t dev) static int ocpbus_attach (device_t dev) { - struct ocpbus_softc *sc; - int error, i; - uint32_t sr; - u_long start, end; + struct ocpbus_softc *sc; + int error, i, tgt; + uint32_t sr; + u_long start, end; sc = device_get_softc(dev); @@ -284,13 +296,18 @@ ocpbus_attach (device_t dev) return (error); } - /* Clear local access windows. */ - for (i = 0; i < 8; i++) { + /* + * Clear local access windows. Skip DRAM entries, so we don't shoot + * ourselves in the foot. + */ + for (i = 0; i < law_max; i++) { sr = ccsr_read4(OCP85XX_LAWSR(i)); if ((sr & 0x80000000) == 0) continue; - if ((sr & 0x00f00000) == 0x00f00000) + tgt = (sr & 0x01f00000) >> 20; + if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2) continue; + ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff); } @@ -597,7 +614,7 @@ static int ocpbus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep) { - int error; + int error; if (res == NULL) panic("ocpbus_setup_intr: NULL irq resource!"); diff --git a/sys/powerpc/mpc85xx/ocpbus.h b/sys/powerpc/mpc85xx/ocpbus.h index eb3c5c4..3e2c575 100644 --- a/sys/powerpc/mpc85xx/ocpbus.h +++ b/sys/powerpc/mpc85xx/ocpbus.h @@ -36,6 +36,15 @@ #define OCP85XX_LAWBAR(n) (CCSRBAR_VA + 0xc08 + 0x20 * (n)) #define OCP85XX_LAWSR(n) (CCSRBAR_VA + 0xc10 + 0x20 * (n)) +#define OCP85XX_TGTIF_PCI0 0 +#define OCP85XX_TGTIF_PCI1 1 +#define OCP85XX_TGTIF_PCI2 2 +#define OCP85XX_TGTIF_LBC 4 +#define OCP85XX_TGTIF_RAM_INTL 11 +#define OCP85XX_TGTIF_RIO 12 +#define OCP85XX_TGTIF_RAM1 15 +#define OCP85XX_TGTIF_RAM2 22 + /* * Power-On Reset configuration. */ @@ -67,12 +76,6 @@ #define OCP85XX_QUICC_OFF 0x80000 #define OCP85XX_QUICC_SIZE 0x20000 -#define OCP85XX_TGTIF_PCI0 0 -#define OCP85XX_TGTIF_PCI1 1 -#define OCP85XX_TGTIF_PCI2 2 -#define OCP85XX_TGTIF_LBC 4 -#define OCP85XX_TGTIF_RAM 15 - /* * PIC definitions */ diff --git a/sys/powerpc/mpc85xx/pci_ocp.c b/sys/powerpc/mpc85xx/pci_ocp.c index e315454..babfc6a 100644 --- a/sys/powerpc/mpc85xx/pci_ocp.c +++ b/sys/powerpc/mpc85xx/pci_ocp.c @@ -590,7 +590,7 @@ pci_ocp_inbound(struct pci_ocp_softc *sc, int wnd, int tgt, u_long start, KASSERT(wnd > 0, ("%s: inbound window 0 is invalid", __func__)); switch (tgt) { - case OCP85XX_TGTIF_RAM: + case OCP85XX_TGTIF_RAM1: attr = 0xa0f55000 | (ffsl(size) - 2); break; default: @@ -721,7 +721,7 @@ pci_ocp_attach(device_t dev) pci_ocp_inbound(sc, 1, -1, 0, 0, 0); pci_ocp_inbound(sc, 2, -1, 0, 0, 0); - pci_ocp_inbound(sc, 3, OCP85XX_TGTIF_RAM, 0, 2U*1024U*1024U*1024U, 0); + pci_ocp_inbound(sc, 3, OCP85XX_TGTIF_RAM1, 0, 2U*1024U*1024U*1024U, 0); maxslot = (sc->sc_pcie) ? 1 : 31; pci_ocp_init(sc, sc->sc_busnr, maxslot); |