162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#include <asm/reg.h>
362306a36Sopenharmony_ci#include <asm/ppc_asm.h>
462306a36Sopenharmony_ci#include <asm/processor.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci.text
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci_GLOBAL(mpc52xx_deep_sleep)
1062306a36Sopenharmony_cimpc52xx_deep_sleep: /* args r3-r6: SRAM, SDRAM regs, CDM regs, INTR regs */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci	/* enable interrupts */
1362306a36Sopenharmony_ci	mfmsr	r7
1462306a36Sopenharmony_ci	ori	r7, r7, 0x8000 /* EE */
1562306a36Sopenharmony_ci	mtmsr	r7
1662306a36Sopenharmony_ci	sync; isync;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci	li	r10, 0 /* flag that irq handler sets */
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	/* enable tmr7 (or any other) interrupt */
2162306a36Sopenharmony_ci	lwz	r8, 0x14(r6) /* intr->main_mask */
2262306a36Sopenharmony_ci	ori	r8, r8, 0x1
2362306a36Sopenharmony_ci	xori	r8, r8, 0x1
2462306a36Sopenharmony_ci	stw	r8, 0x14(r6)
2562306a36Sopenharmony_ci	sync
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* emulate tmr7 interrupt */
2862306a36Sopenharmony_ci	li	r8, 0x1
2962306a36Sopenharmony_ci	stw	r8, 0x40(r6) /* intr->main_emulate */
3062306a36Sopenharmony_ci	sync
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	/* wait for it to happen */
3362306a36Sopenharmony_ci1:
3462306a36Sopenharmony_ci	cmpi	cr0, r10, 1
3562306a36Sopenharmony_ci	bne	cr0, 1b
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	/* lock icache */
3862306a36Sopenharmony_ci	mfspr	r10, SPRN_HID0
3962306a36Sopenharmony_ci	ori	r10, r10, 0x2000
4062306a36Sopenharmony_ci	sync; isync;
4162306a36Sopenharmony_ci	mtspr	SPRN_HID0, r10
4262306a36Sopenharmony_ci	sync; isync;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	mflr	r9 /* save LR */
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	/* jump to sram */
4862306a36Sopenharmony_ci	mtlr	r3
4962306a36Sopenharmony_ci	blrl
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	mtlr	r9 /* restore LR */
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	/* unlock icache */
5462306a36Sopenharmony_ci	mfspr	r10, SPRN_HID0
5562306a36Sopenharmony_ci	ori	r10, r10, 0x2000
5662306a36Sopenharmony_ci	xori	r10, r10, 0x2000
5762306a36Sopenharmony_ci	sync; isync;
5862306a36Sopenharmony_ci	mtspr	SPRN_HID0, r10
5962306a36Sopenharmony_ci	sync; isync;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	/* return to C code */
6362306a36Sopenharmony_ci	blr
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci_GLOBAL(mpc52xx_ds_sram)
6762306a36Sopenharmony_cimpc52xx_ds_sram:
6862306a36Sopenharmony_ci	/* put SDRAM into self-refresh */
6962306a36Sopenharmony_ci	lwz	r8, 0x4(r4)	/* sdram->ctrl */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	oris	r8, r8, 0x8000 /* mode_en */
7262306a36Sopenharmony_ci	stw	r8, 0x4(r4)
7362306a36Sopenharmony_ci	sync
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	ori	r8, r8, 0x0002 /* soft_pre */
7662306a36Sopenharmony_ci	stw	r8, 0x4(r4)
7762306a36Sopenharmony_ci	sync
7862306a36Sopenharmony_ci	xori	r8, r8, 0x0002
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	xoris	r8, r8, 0x8000 /* !mode_en */
8162306a36Sopenharmony_ci	stw	r8, 0x4(r4)
8262306a36Sopenharmony_ci	sync
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	oris	r8, r8, 0x5000
8562306a36Sopenharmony_ci	xoris	r8, r8, 0x4000 /* ref_en !cke */
8662306a36Sopenharmony_ci	stw	r8, 0x4(r4)
8762306a36Sopenharmony_ci	sync
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	/* disable SDRAM clock */
9062306a36Sopenharmony_ci	lwz	r8, 0x14(r5) /* cdm->clkenable */
9162306a36Sopenharmony_ci	ori	r8, r8, 0x0008
9262306a36Sopenharmony_ci	xori	r8, r8, 0x0008
9362306a36Sopenharmony_ci	stw	r8, 0x14(r5)
9462306a36Sopenharmony_ci	sync
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	/* put mpc5200 to sleep */
9862306a36Sopenharmony_ci	mfmsr	r10
9962306a36Sopenharmony_ci	oris	r10, r10, 0x0004	/* POW = 1 */
10062306a36Sopenharmony_ci	sync; isync;
10162306a36Sopenharmony_ci	mtmsr	r10
10262306a36Sopenharmony_ci	sync; isync;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	/* enable clock */
10662306a36Sopenharmony_ci	lwz	r8, 0x14(r5)
10762306a36Sopenharmony_ci	ori	r8, r8, 0x0008
10862306a36Sopenharmony_ci	stw	r8, 0x14(r5)
10962306a36Sopenharmony_ci	sync
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	/* get ram out of self-refresh */
11262306a36Sopenharmony_ci	lwz	r8, 0x4(r4)
11362306a36Sopenharmony_ci	oris	r8, r8, 0x5000 /* cke ref_en */
11462306a36Sopenharmony_ci	stw	r8, 0x4(r4)
11562306a36Sopenharmony_ci	sync
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	blr
11862306a36Sopenharmony_ci_GLOBAL(mpc52xx_ds_sram_size)
11962306a36Sopenharmony_cimpc52xx_ds_sram_size:
12062306a36Sopenharmony_ci	.long $-mpc52xx_ds_sram
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/* ### interrupt handler for wakeup from deep-sleep ### */
12462306a36Sopenharmony_ci_GLOBAL(mpc52xx_ds_cached)
12562306a36Sopenharmony_cimpc52xx_ds_cached:
12662306a36Sopenharmony_ci	mtspr	SPRN_SPRG0, r7
12762306a36Sopenharmony_ci	mtspr	SPRN_SPRG1, r8
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/* disable emulated interrupt */
13062306a36Sopenharmony_ci	mfspr	r7, 311 /* MBAR */
13162306a36Sopenharmony_ci	addi	r7, r7, 0x540	/* intr->main_emul */
13262306a36Sopenharmony_ci	li	r8, 0
13362306a36Sopenharmony_ci	stw	r8, 0(r7)
13462306a36Sopenharmony_ci	sync
13562306a36Sopenharmony_ci	dcbf	0, r7
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	/* acknowledge wakeup, so CCS releases power pown */
13862306a36Sopenharmony_ci	mfspr	r7, 311	/* MBAR */
13962306a36Sopenharmony_ci	addi	r7, r7, 0x524	/* intr->enc_status */
14062306a36Sopenharmony_ci	lwz	r8, 0(r7)
14162306a36Sopenharmony_ci	ori	r8, r8, 0x0400
14262306a36Sopenharmony_ci	stw	r8, 0(r7)
14362306a36Sopenharmony_ci	sync
14462306a36Sopenharmony_ci	dcbf	0, r7
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/* flag - we handled the interrupt */
14762306a36Sopenharmony_ci	li	r10, 1
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	mfspr	r8, SPRN_SPRG1
15062306a36Sopenharmony_ci	mfspr	r7, SPRN_SPRG0
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	rfi
15362306a36Sopenharmony_ci_GLOBAL(mpc52xx_ds_cached_size)
15462306a36Sopenharmony_cimpc52xx_ds_cached_size:
15562306a36Sopenharmony_ci	.long $-mpc52xx_ds_cached
156