|
@@ -54,7 +54,7 @@
|
|
|
static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
|
|
|
{
|
|
|
uint32_t coremask, value;
|
|
|
- int count;
|
|
|
+ int count, resetreg;
|
|
|
|
|
|
coremask = (1 << core);
|
|
|
|
|
@@ -65,12 +65,24 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
|
|
|
nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
|
|
|
}
|
|
|
|
|
|
+ /* On 9XX, mark coherent first */
|
|
|
+ if (cpu_is_xlp9xx()) {
|
|
|
+ value = nlm_read_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE);
|
|
|
+ value &= ~coremask;
|
|
|
+ nlm_write_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE, value);
|
|
|
+ }
|
|
|
+
|
|
|
/* Remove CPU Reset */
|
|
|
- value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
|
|
|
+ resetreg = cpu_is_xlp9xx() ? SYS_9XX_CPU_RESET : SYS_CPU_RESET;
|
|
|
+ value = nlm_read_sys_reg(sysbase, resetreg);
|
|
|
value &= ~coremask;
|
|
|
- nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value);
|
|
|
+ nlm_write_sys_reg(sysbase, resetreg, value);
|
|
|
+
|
|
|
+ /* We are done on 9XX */
|
|
|
+ if (cpu_is_xlp9xx())
|
|
|
+ return 1;
|
|
|
|
|
|
- /* Poll for CPU to mark itself coherent */
|
|
|
+ /* Poll for CPU to mark itself coherent on other type of XLP */
|
|
|
count = 100000;
|
|
|
do {
|
|
|
value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);
|
|
@@ -98,33 +110,48 @@ static int wait_for_cpus(int cpu, int bootcpu)
|
|
|
static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
|
|
|
{
|
|
|
struct nlm_soc_info *nodep;
|
|
|
- uint64_t syspcibase;
|
|
|
+ uint64_t syspcibase, fusebase;
|
|
|
uint32_t syscoremask, mask, fusemask;
|
|
|
int core, n, cpu;
|
|
|
|
|
|
for (n = 0; n < NLM_NR_NODES; n++) {
|
|
|
- syspcibase = nlm_get_sys_pcibase(n);
|
|
|
- if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
|
|
|
- break;
|
|
|
+ if (n != 0) {
|
|
|
+ /* check if node exists and is online */
|
|
|
+ if (cpu_is_xlp9xx()) {
|
|
|
+ int b = xlp9xx_get_socbus(n);
|
|
|
+ pr_info("Node %d SoC PCI bus %d.\n", n, b);
|
|
|
+ if (b == 0)
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ syspcibase = nlm_get_sys_pcibase(n);
|
|
|
+ if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ nlm_node_init(n);
|
|
|
+ }
|
|
|
|
|
|
/* read cores in reset from SYS */
|
|
|
- if (n != 0)
|
|
|
- nlm_node_init(n);
|
|
|
nodep = nlm_get_node(n);
|
|
|
|
|
|
- fusemask = nlm_read_sys_reg(nodep->sysbase,
|
|
|
- SYS_EFUSE_DEVICE_CFG_STATUS0);
|
|
|
- switch (read_c0_prid() & 0xff00) {
|
|
|
- case PRID_IMP_NETLOGIC_XLP3XX:
|
|
|
- mask = 0xf;
|
|
|
- break;
|
|
|
- case PRID_IMP_NETLOGIC_XLP2XX:
|
|
|
- mask = 0x3;
|
|
|
- break;
|
|
|
- case PRID_IMP_NETLOGIC_XLP8XX:
|
|
|
- default:
|
|
|
- mask = 0xff;
|
|
|
- break;
|
|
|
+ if (cpu_is_xlp9xx()) {
|
|
|
+ fusebase = nlm_get_fuse_regbase(n);
|
|
|
+ fusemask = nlm_read_reg(fusebase, FUSE_9XX_DEVCFG6);
|
|
|
+ mask = 0xfffff;
|
|
|
+ } else {
|
|
|
+ fusemask = nlm_read_sys_reg(nodep->sysbase,
|
|
|
+ SYS_EFUSE_DEVICE_CFG_STATUS0);
|
|
|
+ switch (read_c0_prid() & 0xff00) {
|
|
|
+ case PRID_IMP_NETLOGIC_XLP3XX:
|
|
|
+ mask = 0xf;
|
|
|
+ break;
|
|
|
+ case PRID_IMP_NETLOGIC_XLP2XX:
|
|
|
+ mask = 0x3;
|
|
|
+ break;
|
|
|
+ case PRID_IMP_NETLOGIC_XLP8XX:
|
|
|
+ default:
|
|
|
+ mask = 0xff;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -137,6 +164,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
|
|
|
if (n == 0)
|
|
|
nodep->coremask = 1;
|
|
|
|
|
|
+ pr_info("Node %d - SYS/FUSE coremask %x\n", n, syscoremask);
|
|
|
for (core = 0; core < NLM_CORES_PER_NODE; core++) {
|
|
|
/* we will be on node 0 core 0 */
|
|
|
if (n == 0 && core == 0)
|