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:
parent
653b7b4943
commit
8464af7949
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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!");
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user