xref: /openbmc/linux/arch/powerpc/kernel/idle_85xx.S (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*6556fd1aSChristophe Leroy/* SPDX-License-Identifier: GPL-2.0-or-later */
2*6556fd1aSChristophe Leroy/*
3*6556fd1aSChristophe Leroy * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
4*6556fd1aSChristophe Leroy * Dave Liu <daveliu@freescale.com>
5*6556fd1aSChristophe Leroy * copy from idle_6xx.S and modify for e500 based processor,
6*6556fd1aSChristophe Leroy * implement the power_save function in idle.
7*6556fd1aSChristophe Leroy */
8*6556fd1aSChristophe Leroy
9*6556fd1aSChristophe Leroy#include <linux/threads.h>
10*6556fd1aSChristophe Leroy#include <asm/reg.h>
11*6556fd1aSChristophe Leroy#include <asm/page.h>
12*6556fd1aSChristophe Leroy#include <asm/cputable.h>
13*6556fd1aSChristophe Leroy#include <asm/thread_info.h>
14*6556fd1aSChristophe Leroy#include <asm/ppc_asm.h>
15*6556fd1aSChristophe Leroy#include <asm/asm-offsets.h>
16*6556fd1aSChristophe Leroy#include <asm/feature-fixups.h>
17*6556fd1aSChristophe Leroy
18*6556fd1aSChristophe Leroy	.text
19*6556fd1aSChristophe Leroy
20*6556fd1aSChristophe Leroy_GLOBAL(e500_idle)
21*6556fd1aSChristophe Leroy	lwz	r4,TI_LOCAL_FLAGS(r2)	/* set napping bit */
22*6556fd1aSChristophe Leroy	ori	r4,r4,_TLF_NAPPING	/* so when we take an exception */
23*6556fd1aSChristophe Leroy	stw	r4,TI_LOCAL_FLAGS(r2)	/* it will return to our caller */
24*6556fd1aSChristophe Leroy
25*6556fd1aSChristophe Leroy#ifdef CONFIG_PPC_E500MC
26*6556fd1aSChristophe Leroy	wrteei	1
27*6556fd1aSChristophe Leroy1:	wait
28*6556fd1aSChristophe Leroy
29*6556fd1aSChristophe Leroy	/*
30*6556fd1aSChristophe Leroy	 * Guard against spurious wakeups (e.g. from a hypervisor) --
31*6556fd1aSChristophe Leroy	 * any real interrupt will cause us to return to LR due to
32*6556fd1aSChristophe Leroy	 * _TLF_NAPPING.
33*6556fd1aSChristophe Leroy	 */
34*6556fd1aSChristophe Leroy	b	1b
35*6556fd1aSChristophe Leroy#else
36*6556fd1aSChristophe Leroy	/* Check if we can nap or doze, put HID0 mask in r3 */
37*6556fd1aSChristophe Leroy	lis	r3,0
38*6556fd1aSChristophe LeroyBEGIN_FTR_SECTION
39*6556fd1aSChristophe Leroy	lis	r3,HID0_DOZE@h
40*6556fd1aSChristophe LeroyEND_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
41*6556fd1aSChristophe Leroy
42*6556fd1aSChristophe LeroyBEGIN_FTR_SECTION
43*6556fd1aSChristophe Leroy	/* Now check if user enabled NAP mode */
44*6556fd1aSChristophe Leroy	lis	r4,powersave_nap@ha
45*6556fd1aSChristophe Leroy	lwz	r4,powersave_nap@l(r4)
46*6556fd1aSChristophe Leroy	cmpwi	0,r4,0
47*6556fd1aSChristophe Leroy	beq	1f
48*6556fd1aSChristophe Leroy	stwu	r1,-16(r1)
49*6556fd1aSChristophe Leroy	mflr	r0
50*6556fd1aSChristophe Leroy	stw	r0,20(r1)
51*6556fd1aSChristophe Leroy	bl	flush_dcache_L1
52*6556fd1aSChristophe Leroy	lwz	r0,20(r1)
53*6556fd1aSChristophe Leroy	addi	r1,r1,16
54*6556fd1aSChristophe Leroy	mtlr	r0
55*6556fd1aSChristophe Leroy	lis	r3,HID0_NAP@h
56*6556fd1aSChristophe LeroyEND_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
57*6556fd1aSChristophe Leroy1:
58*6556fd1aSChristophe Leroy	/* Go to NAP or DOZE now */
59*6556fd1aSChristophe Leroy	mfspr	r4,SPRN_HID0
60*6556fd1aSChristophe Leroy	rlwinm	r4,r4,0,~(HID0_DOZE|HID0_NAP|HID0_SLEEP)
61*6556fd1aSChristophe Leroy	or	r4,r4,r3
62*6556fd1aSChristophe Leroy	isync
63*6556fd1aSChristophe Leroy	mtspr	SPRN_HID0,r4
64*6556fd1aSChristophe Leroy	isync
65*6556fd1aSChristophe Leroy
66*6556fd1aSChristophe Leroy	mfmsr	r7
67*6556fd1aSChristophe Leroy	oris	r7,r7,MSR_WE@h
68*6556fd1aSChristophe Leroy	ori	r7,r7,MSR_EE
69*6556fd1aSChristophe Leroy	msync
70*6556fd1aSChristophe Leroy	mtmsr	r7
71*6556fd1aSChristophe Leroy	isync
72*6556fd1aSChristophe Leroy2:	b	2b
73*6556fd1aSChristophe Leroy#endif /* !E500MC */
74*6556fd1aSChristophe Leroy
75*6556fd1aSChristophe Leroy/*
76*6556fd1aSChristophe Leroy * Return from NAP/DOZE mode, restore some CPU specific registers,
77*6556fd1aSChristophe Leroy * r2 containing address of current.
78*6556fd1aSChristophe Leroy * r11 points to the exception frame.
79*6556fd1aSChristophe Leroy * We have to preserve r10.
80*6556fd1aSChristophe Leroy */
81*6556fd1aSChristophe Leroy_GLOBAL(power_save_ppc32_restore)
82*6556fd1aSChristophe Leroy	lwz	r9,_LINK(r11)		/* interrupted in e500_idle */
83*6556fd1aSChristophe Leroy	stw	r9,_NIP(r11)		/* make it do a blr */
84*6556fd1aSChristophe Leroy	blr
85*6556fd1aSChristophe Leroy_ASM_NOKPROBE_SYMBOL(power_save_ppc32_restore)
86