162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2006-2007 PA Semi, Inc
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Maintained by: Olof Johansson <olof@lixom.net>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <asm/processor.h>
962306a36Sopenharmony_ci#include <asm/page.h>
1062306a36Sopenharmony_ci#include <asm/ppc_asm.h>
1162306a36Sopenharmony_ci#include <asm/cputable.h>
1262306a36Sopenharmony_ci#include <asm/cache.h>
1362306a36Sopenharmony_ci#include <asm/thread_info.h>
1462306a36Sopenharmony_ci#include <asm/asm-offsets.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/* Power savings opcodes since not all binutils have them at this time */
1762306a36Sopenharmony_ci#define DOZE	.long	0x4c000324
1862306a36Sopenharmony_ci#define NAP	.long	0x4c000364
1962306a36Sopenharmony_ci#define SLEEP	.long	0x4c0003a4
2062306a36Sopenharmony_ci#define RVW	.long	0x4c0003e4
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Common sequence to do before going to any of the
2362306a36Sopenharmony_ci * powersavings modes.
2462306a36Sopenharmony_ci */
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define PRE_SLEEP_SEQUENCE	\
2762306a36Sopenharmony_ci	std	r3,8(r1);	\
2862306a36Sopenharmony_ci	ptesync	;		\
2962306a36Sopenharmony_ci	ld	r3,8(r1);	\
3062306a36Sopenharmony_ci1:	cmpd 	r3,r3;		\
3162306a36Sopenharmony_ci	bne	1b
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci_doze:
3462306a36Sopenharmony_ci	PRE_SLEEP_SEQUENCE
3562306a36Sopenharmony_ci	DOZE
3662306a36Sopenharmony_ci	b	.
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci_GLOBAL(idle_spin)
4062306a36Sopenharmony_ci	blr
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci_GLOBAL(idle_doze)
4362306a36Sopenharmony_ci	LOAD_REG_ADDR(r3, _doze)
4462306a36Sopenharmony_ci	b	sleep_common
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* Add more modes here later */
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cisleep_common:
4962306a36Sopenharmony_ci	mflr	r0
5062306a36Sopenharmony_ci	std	r0, 16(r1)
5162306a36Sopenharmony_ci	stdu	r1,-64(r1)
5262306a36Sopenharmony_ci#ifdef CONFIG_PPC_PASEMI_CPUFREQ
5362306a36Sopenharmony_ci	std	r3, 48(r1)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	/* Only do power savings when in astate 0 */
5662306a36Sopenharmony_ci	bl	check_astate
5762306a36Sopenharmony_ci	cmpwi	r3,0
5862306a36Sopenharmony_ci	bne	1f
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	ld	r3, 48(r1)
6162306a36Sopenharmony_ci#endif
6262306a36Sopenharmony_ci	LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE)
6362306a36Sopenharmony_ci	mfmsr	r4
6462306a36Sopenharmony_ci	andc	r5,r4,r6
6562306a36Sopenharmony_ci	mtmsrd	r5,0
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	mtctr	r3
6862306a36Sopenharmony_ci	bctrl
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	mtmsrd	r4,0
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci1:	addi	r1,r1,64
7362306a36Sopenharmony_ci	ld	r0,16(r1)
7462306a36Sopenharmony_ci	mtlr	r0
7562306a36Sopenharmony_ci	blr
7662306a36Sopenharmony_ci
77