Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cba3b643 authored by Jayachandran C's avatar Jayachandran C Committed by John Crispin
Browse files

MIPS: Netlogic: Fix for quad-XLP boot



On multi-chip boards, the first core on slave SoCs may take much
more time to wakeup. Add code to wait for the core to come up before
proceeding with the rest of the boot up.

Update xlp_wakeup_core to also skip the boot node and the boot CPU
initialization which is already complete.

Signed-off-by: default avatarJayachandran C <jchandra@broadcom.com>
Patchwork: http://patchwork.linux-mips.org/patch/4783/


Signed-off-by: default avatarJohn Crispin <blogic@openwrt.org>
parent 37a7059b
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>

static int xlp_wakeup_core(uint64_t sysbase, int core)
static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
{
	uint32_t coremask, value;
	int count;
@@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
	struct nlm_soc_info *nodep;
	uint64_t syspcibase;
	uint32_t syscoremask;
	int core, n, cpu;
	int core, n, cpu, count, val;

	for (n = 0; n < NLM_NR_NODES; n++) {
		syspcibase = nlm_get_sys_pcibase(n);
		if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
			break;

		/* read cores in reset from SYS and account for boot cpu */
		/* read cores in reset from SYS */
		if (n != 0)
			nlm_node_init(n);
		nodep = nlm_get_node(n);
		syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
		if (n == 0)
		/* The boot cpu */
		if (n == 0) {
			syscoremask |= 1;
			nodep->coremask = 1;
		}

		for (core = 0; core < NLM_CORES_PER_NODE; core++) {
			/* we will be on node 0 core 0 */
			if (n == 0 && core == 0)
				continue;

			/* see if the core exists */
			if ((syscoremask & (1 << core)) == 0)
				continue;

			/* see if at least the first thread is enabled */
			/* see if at least the first hw thread is enabled */
			cpu = (n * NLM_CORES_PER_NODE + core)
						* NLM_THREADS_PER_CORE;
			if (!cpumask_test_cpu(cpu, wakeup_mask))
				continue;

			/* wake up the core */
			if (xlp_wakeup_core(nodep->sysbase, core))
			if (!xlp_wakeup_core(nodep->sysbase, n, core))
				continue;

			/* core is up */
			nodep->coremask |= 1u << core;
			else
				pr_err("Failed to enable core %d\n", core);

			/* spin until the first hw thread sets its ready */
			count = 0x20000000;
			do {
				val = *(volatile int *)&nlm_cpu_ready[cpu];
			} while (val == 0 && --count > 0);
		}
	}
}