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

Commit 5a812999 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

[MIPS] Workaround for RM7000 WAIT instruction aka erratum 38

parent 17099b11
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -75,6 +75,27 @@ static void r4k_wait_irqoff(void)
	local_irq_enable();
}

/*
 * The RM7000 variant has to handle erratum 38.  The workaround is to not
 * have any pending stores when the WAIT instruction is executed.
 */
static void rm7k_wait_irqoff(void)
{
	local_irq_disable();
	if (!need_resched())
		__asm__(
		"	.set	push					\n"
		"	.set	mips3					\n"
		"	.set	noat					\n"
		"	mfc0	$1, $12					\n"
		"	sync						\n"
		"	mtc0	$1, $12		# stalls until W stage	\n"
		"	wait						\n"
		"	mtc0	$1, $12		# stalls until W stage	\n"
		"	.set	pop					\n");
	local_irq_enable();
}

/* The Au1xxx wait is available only if using 32khz counter or
 * external timer source, but specifically not CP0 Counter. */
int allow_au1k_wait;
@@ -132,7 +153,6 @@ static inline void check_wait(void)
	case CPU_R4700:
	case CPU_R5000:
	case CPU_NEVADA:
	case CPU_RM7000:
	case CPU_4KC:
	case CPU_4KEC:
	case CPU_4KSC:
@@ -142,6 +162,10 @@ static inline void check_wait(void)
		cpu_wait = r4k_wait;
		break;

	case CPU_RM7000:
		cpu_wait = rm7k_wait_irqoff;
		break;

	case CPU_24K:
	case CPU_34K:
		cpu_wait = r4k_wait;