1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * This file contains low level CPU setup functions.
4 *    Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
5 */
6
7#include <asm/processor.h>
8#include <asm/page.h>
9#include <asm/cputable.h>
10#include <asm/ppc_asm.h>
11#include <asm/asm-offsets.h>
12#include <asm/cache.h>
13
14_GLOBAL(__cpu_preinit_ppc970)
15	/* Do nothing if not running in HV mode */
16	mfmsr	r0
17	rldicl.	r0,r0,4,63
18	beqlr
19
20	/* Make sure HID4:rm_ci is off before MMU is turned off, that large
21	 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
22	 * HID5:DCBZ32_ill
23	 */
24	li	r0,0
25	mfspr	r3,SPRN_HID4
26	rldimi	r3,r0,40,23	/* clear bit 23 (rm_ci) */
27	rldimi	r3,r0,2,61	/* clear bit 61 (lg_pg_en) */
28	sync
29	mtspr	SPRN_HID4,r3
30	isync
31	sync
32	mfspr	r3,SPRN_HID5
33	rldimi	r3,r0,6,56	/* clear bits 56 & 57 (DCBZ*) */
34	sync
35	mtspr	SPRN_HID5,r3
36	isync
37	sync
38
39	/* Setup some basic HID1 features */
40	mfspr	r0,SPRN_HID1
41	li	r3,0x1200		/* enable i-fetch cacheability */
42	sldi	r3,r3,44		/* and prefetch */
43	or	r0,r0,r3
44	mtspr	SPRN_HID1,r0
45	mtspr	SPRN_HID1,r0
46	isync
47
48	/* Clear HIOR */
49	li	r0,0
50	sync
51	mtspr	SPRN_HIOR,0		/* Clear interrupt prefix */
52	isync
53	blr
54
55/* Definitions for the table use to save CPU states */
56#define CS_HID0		0
57#define CS_HID1		8
58#define	CS_HID4		16
59#define CS_HID5		24
60#define CS_SIZE		32
61
62	.data
63	.balign	L1_CACHE_BYTES,0
64cpu_state_storage:
65	.space	CS_SIZE
66	.balign	L1_CACHE_BYTES,0
67	.text
68
69
70_GLOBAL(__setup_cpu_ppc970)
71	/* Do nothing if not running in HV mode */
72	mfmsr	r0
73	rldicl.	r0,r0,4,63
74	beq	no_hv_mode
75
76	mfspr	r0,SPRN_HID0
77	li	r11,5			/* clear DOZE and SLEEP */
78	rldimi	r0,r11,52,8		/* set NAP and DPM */
79	li	r11,0
80	rldimi	r0,r11,32,31		/* clear EN_ATTN */
81	b	load_hids		/* Jump to shared code */
82
83
84_GLOBAL(__setup_cpu_ppc970MP)
85	/* Do nothing if not running in HV mode */
86	mfmsr	r0
87	rldicl.	r0,r0,4,63
88	beq	no_hv_mode
89
90	mfspr	r0,SPRN_HID0
91	li	r11,0x15		/* clear DOZE and SLEEP */
92	rldimi	r0,r11,52,6		/* set DEEPNAP, NAP and DPM */
93	li	r11,0
94	rldimi	r0,r11,32,31		/* clear EN_ATTN */
95
96load_hids:
97	mtspr	SPRN_HID0,r0
98	mfspr	r0,SPRN_HID0
99	mfspr	r0,SPRN_HID0
100	mfspr	r0,SPRN_HID0
101	mfspr	r0,SPRN_HID0
102	mfspr	r0,SPRN_HID0
103	mfspr	r0,SPRN_HID0
104	sync
105	isync
106
107	/* Try to set LPES = 01 in HID4 */
108	mfspr	r0,SPRN_HID4
109	clrldi	r0,r0,1			/* clear LPES0 */
110	ori	r0,r0,HID4_LPES1	/* set LPES1 */
111	sync
112	mtspr	SPRN_HID4,r0
113	isync
114
115	/* Save away cpu state */
116	LOAD_REG_ADDR(r5,cpu_state_storage)
117
118	/* Save HID0,1,4 and 5 */
119	mfspr	r3,SPRN_HID0
120	std	r3,CS_HID0(r5)
121	mfspr	r3,SPRN_HID1
122	std	r3,CS_HID1(r5)
123	mfspr	r4,SPRN_HID4
124	std	r4,CS_HID4(r5)
125	mfspr	r3,SPRN_HID5
126	std	r3,CS_HID5(r5)
127
128	/* See if we successfully set LPES1 to 1; if not we are in Apple mode */
129	andi.	r4,r4,HID4_LPES1
130	bnelr
131
132no_hv_mode:
133	/* Disable CPU_FTR_HVMODE and exit, since we don't have HV mode */
134	ld	r5,CPU_SPEC_FEATURES(r4)
135	LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE)
136	andc	r5,r5,r6
137	std	r5,CPU_SPEC_FEATURES(r4)
138	blr
139
140/* Called with no MMU context (typically MSR:IR/DR off) to
141 * restore CPU state as backed up by the previous
142 * function. This does not include cache setting
143 */
144_GLOBAL(__restore_cpu_ppc970)
145	/* Do nothing if not running in HV mode */
146	mfmsr	r0
147	rldicl.	r0,r0,4,63
148	beqlr
149
150	LOAD_REG_ADDR(r5,cpu_state_storage)
151	/* Before accessing memory, we make sure rm_ci is clear */
152	li	r0,0
153	mfspr	r3,SPRN_HID4
154	rldimi	r3,r0,40,23	/* clear bit 23 (rm_ci) */
155	sync
156	mtspr	SPRN_HID4,r3
157	isync
158	sync
159
160	/* Clear interrupt prefix */
161	li	r0,0
162	sync
163	mtspr	SPRN_HIOR,0
164	isync
165
166	/* Restore HID0 */
167	ld	r3,CS_HID0(r5)
168	sync
169	isync
170	mtspr	SPRN_HID0,r3
171	mfspr	r3,SPRN_HID0
172	mfspr	r3,SPRN_HID0
173	mfspr	r3,SPRN_HID0
174	mfspr	r3,SPRN_HID0
175	mfspr	r3,SPRN_HID0
176	mfspr	r3,SPRN_HID0
177	sync
178	isync
179
180	/* Restore HID1 */
181	ld	r3,CS_HID1(r5)
182	sync
183	isync
184	mtspr	SPRN_HID1,r3
185	mtspr	SPRN_HID1,r3
186	sync
187	isync
188
189	/* Restore HID4 */
190	ld	r3,CS_HID4(r5)
191	sync
192	isync
193	mtspr	SPRN_HID4,r3
194	sync
195	isync
196
197	/* Restore HID5 */
198	ld	r3,CS_HID5(r5)
199	sync
200	isync
201	mtspr	SPRN_HID5,r3
202	sync
203	isync
204	blr
205
206