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
This commit is contained in:
Rafal Jaworowski 2008-04-26 17:47:28 +00:00
parent 653b7b4943
commit 8464af7949
4 changed files with 50 additions and 19 deletions

View File

@ -44,6 +44,7 @@ powerpc_mb(void)
#include <sys/types.h> #include <sys/types.h>
#include <machine/psl.h> #include <machine/psl.h>
#include <machine/spr.h>
struct thread; struct thread;
@ -122,6 +123,16 @@ mfpvr(void)
return (value); 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 static __inline void
eieio(void) eieio(void)
{ {

View File

@ -113,6 +113,8 @@ devclass_t ocpbus_devclass;
DRIVER_MODULE(ocpbus, nexus, ocpbus_driver, ocpbus_devclass, 0, 0); DRIVER_MODULE(ocpbus, nexus, ocpbus_driver, ocpbus_devclass, 0, 0);
static int law_max = 0;
static __inline uint32_t static __inline uint32_t
ccsr_read4(uintptr_t addr) 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); sr = 0x80000000 | (trgt << 20) | (ffsl(size) - 2);
/* Check if already programmed. */ /* Check if already programmed. */
for (i = 0; i < 8; i++) { for (i = 0; i < law_max; i++) {
if (sr == ccsr_read4(OCP85XX_LAWSR(i)) && if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
bar == ccsr_read4(OCP85XX_LAWBAR(i))) bar == ccsr_read4(OCP85XX_LAWBAR(i)))
return (0); return (0);
} }
/* Find an unused access window .*/ /* 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) if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0)
break; break;
} }
if (i == 8) if (i == law_max)
return (ENOSPC); return (ENOSPC);
ccsr_write4(OCP85XX_LAWBAR(i), bar); 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 static int
ocpbus_probe (device_t dev) 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"); device_set_desc(dev, "On-Chip Peripherals bus");
return (BUS_PROBE_DEFAULT); return (BUS_PROBE_DEFAULT);
@ -234,10 +246,10 @@ ocpbus_probe (device_t dev)
static int static int
ocpbus_attach (device_t dev) ocpbus_attach (device_t dev)
{ {
struct ocpbus_softc *sc; struct ocpbus_softc *sc;
int error, i; int error, i, tgt;
uint32_t sr; uint32_t sr;
u_long start, end; u_long start, end;
sc = device_get_softc(dev); sc = device_get_softc(dev);
@ -284,13 +296,18 @@ ocpbus_attach (device_t dev)
return (error); 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)); sr = ccsr_read4(OCP85XX_LAWSR(i));
if ((sr & 0x80000000) == 0) if ((sr & 0x80000000) == 0)
continue; continue;
if ((sr & 0x00f00000) == 0x00f00000) tgt = (sr & 0x01f00000) >> 20;
if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2)
continue; continue;
ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff); 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, 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) driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep)
{ {
int error; int error;
if (res == NULL) if (res == NULL)
panic("ocpbus_setup_intr: NULL irq resource!"); panic("ocpbus_setup_intr: NULL irq resource!");

View File

@ -36,6 +36,15 @@
#define OCP85XX_LAWBAR(n) (CCSRBAR_VA + 0xc08 + 0x20 * (n)) #define OCP85XX_LAWBAR(n) (CCSRBAR_VA + 0xc08 + 0x20 * (n))
#define OCP85XX_LAWSR(n) (CCSRBAR_VA + 0xc10 + 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. * Power-On Reset configuration.
*/ */
@ -67,12 +76,6 @@
#define OCP85XX_QUICC_OFF 0x80000 #define OCP85XX_QUICC_OFF 0x80000
#define OCP85XX_QUICC_SIZE 0x20000 #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 * PIC definitions
*/ */

View File

@ -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__)); KASSERT(wnd > 0, ("%s: inbound window 0 is invalid", __func__));
switch (tgt) { switch (tgt) {
case OCP85XX_TGTIF_RAM: case OCP85XX_TGTIF_RAM1:
attr = 0xa0f55000 | (ffsl(size) - 2); attr = 0xa0f55000 | (ffsl(size) - 2);
break; break;
default: default:
@ -721,7 +721,7 @@ pci_ocp_attach(device_t dev)
pci_ocp_inbound(sc, 1, -1, 0, 0, 0); pci_ocp_inbound(sc, 1, -1, 0, 0, 0);
pci_ocp_inbound(sc, 2, -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; maxslot = (sc->sc_pcie) ? 1 : 31;
pci_ocp_init(sc, sc->sc_busnr, maxslot); pci_ocp_init(sc, sc->sc_busnr, maxslot);