xref: /openbmc/linux/arch/powerpc/kernel/cpu_setup_power.c (revision 91668ab7db4bcfae332e561df1de2401f3f18553)
1344fbab9SJordan Niethe // SPDX-License-Identifier: GPL-2.0-or-later
2344fbab9SJordan Niethe /*
3344fbab9SJordan Niethe  * Copyright 2020, Jordan Niethe, IBM Corporation.
4344fbab9SJordan Niethe  *
5344fbab9SJordan Niethe  * This file contains low level CPU setup functions.
6344fbab9SJordan Niethe  * Originally written in assembly by Benjamin Herrenschmidt & various other
7344fbab9SJordan Niethe  * authors.
8344fbab9SJordan Niethe  */
9344fbab9SJordan Niethe 
10344fbab9SJordan Niethe #include <asm/reg.h>
11344fbab9SJordan Niethe #include <asm/synch.h>
12344fbab9SJordan Niethe #include <linux/bitops.h>
13344fbab9SJordan Niethe #include <asm/cputable.h>
14344fbab9SJordan Niethe #include <asm/cpu_setup_power.h>
15344fbab9SJordan Niethe 
16344fbab9SJordan Niethe /* Disable CPU_FTR_HVMODE and return false if MSR:HV is not set */
17344fbab9SJordan Niethe static bool init_hvmode_206(struct cpu_spec *t)
18344fbab9SJordan Niethe {
19344fbab9SJordan Niethe 	u64 msr;
20344fbab9SJordan Niethe 
21344fbab9SJordan Niethe 	msr = mfmsr();
22344fbab9SJordan Niethe 	if (msr & MSR_HV)
23344fbab9SJordan Niethe 		return true;
24344fbab9SJordan Niethe 
25344fbab9SJordan Niethe 	t->cpu_features &= ~(CPU_FTR_HVMODE | CPU_FTR_P9_TM_HV_ASSIST);
26344fbab9SJordan Niethe 	return false;
27344fbab9SJordan Niethe }
28344fbab9SJordan Niethe 
29344fbab9SJordan Niethe static void init_LPCR_ISA300(u64 lpcr, u64 lpes)
30344fbab9SJordan Niethe {
31344fbab9SJordan Niethe 	/* POWER9 has no VRMASD */
32344fbab9SJordan Niethe 	lpcr |= (lpes << LPCR_LPES_SH) & LPCR_LPES;
33344fbab9SJordan Niethe 	lpcr |= LPCR_PECE0|LPCR_PECE1|LPCR_PECE2;
34344fbab9SJordan Niethe 	lpcr |= (4ull << LPCR_DPFD_SH) & LPCR_DPFD;
35344fbab9SJordan Niethe 	lpcr &= ~LPCR_HDICE;	/* clear HDICE */
36344fbab9SJordan Niethe 	lpcr |= (4ull << LPCR_VC_SH);
37344fbab9SJordan Niethe 	mtspr(SPRN_LPCR, lpcr);
38344fbab9SJordan Niethe 	isync();
39344fbab9SJordan Niethe }
40344fbab9SJordan Niethe 
41344fbab9SJordan Niethe /*
42344fbab9SJordan Niethe  * Setup a sane LPCR:
43344fbab9SJordan Niethe  *   Called with initial LPCR and desired LPES 2-bit value
44344fbab9SJordan Niethe  *
45344fbab9SJordan Niethe  *   LPES = 0b01 (HSRR0/1 used for 0x500)
46344fbab9SJordan Niethe  *   PECE = 0b111
47344fbab9SJordan Niethe  *   DPFD = 4
48344fbab9SJordan Niethe  *   HDICE = 0
49344fbab9SJordan Niethe  *   VC = 0b100 (VPM0=1, VPM1=0, ISL=0)
50344fbab9SJordan Niethe  *   VRMASD = 0b10000 (L=1, LP=00)
51344fbab9SJordan Niethe  *
52344fbab9SJordan Niethe  * Other bits untouched for now
53344fbab9SJordan Niethe  */
54344fbab9SJordan Niethe static void init_LPCR_ISA206(u64 lpcr, u64 lpes)
55344fbab9SJordan Niethe {
56344fbab9SJordan Niethe 	lpcr |= (0x10ull << LPCR_VRMASD_SH) & LPCR_VRMASD;
57344fbab9SJordan Niethe 	init_LPCR_ISA300(lpcr, lpes);
58344fbab9SJordan Niethe }
59344fbab9SJordan Niethe 
60344fbab9SJordan Niethe static void init_FSCR(void)
61344fbab9SJordan Niethe {
62344fbab9SJordan Niethe 	u64 fscr;
63344fbab9SJordan Niethe 
64344fbab9SJordan Niethe 	fscr = mfspr(SPRN_FSCR);
65344fbab9SJordan Niethe 	fscr |= FSCR_TAR|FSCR_EBB;
66344fbab9SJordan Niethe 	mtspr(SPRN_FSCR, fscr);
67344fbab9SJordan Niethe }
68344fbab9SJordan Niethe 
69344fbab9SJordan Niethe static void init_FSCR_power9(void)
70344fbab9SJordan Niethe {
71344fbab9SJordan Niethe 	u64 fscr;
72344fbab9SJordan Niethe 
73344fbab9SJordan Niethe 	fscr = mfspr(SPRN_FSCR);
74344fbab9SJordan Niethe 	fscr |= FSCR_SCV;
75344fbab9SJordan Niethe 	mtspr(SPRN_FSCR, fscr);
76344fbab9SJordan Niethe 	init_FSCR();
77344fbab9SJordan Niethe }
78344fbab9SJordan Niethe 
79344fbab9SJordan Niethe static void init_FSCR_power10(void)
80344fbab9SJordan Niethe {
81344fbab9SJordan Niethe 	u64 fscr;
82344fbab9SJordan Niethe 
83344fbab9SJordan Niethe 	fscr = mfspr(SPRN_FSCR);
84344fbab9SJordan Niethe 	fscr |= FSCR_PREFIX;
85344fbab9SJordan Niethe 	mtspr(SPRN_FSCR, fscr);
86344fbab9SJordan Niethe 	init_FSCR_power9();
87344fbab9SJordan Niethe }
88344fbab9SJordan Niethe 
89344fbab9SJordan Niethe static void init_HFSCR(void)
90344fbab9SJordan Niethe {
91344fbab9SJordan Niethe 	u64 hfscr;
92344fbab9SJordan Niethe 
93344fbab9SJordan Niethe 	hfscr = mfspr(SPRN_HFSCR);
94344fbab9SJordan Niethe 	hfscr |= HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|HFSCR_DSCR|\
95344fbab9SJordan Niethe 		 HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP;
96344fbab9SJordan Niethe 	mtspr(SPRN_HFSCR, hfscr);
97344fbab9SJordan Niethe }
98344fbab9SJordan Niethe 
99344fbab9SJordan Niethe static void init_PMU_HV(void)
100344fbab9SJordan Niethe {
101344fbab9SJordan Niethe 	mtspr(SPRN_MMCRC, 0);
102344fbab9SJordan Niethe }
103344fbab9SJordan Niethe 
104344fbab9SJordan Niethe static void init_PMU_HV_ISA207(void)
105344fbab9SJordan Niethe {
106344fbab9SJordan Niethe 	mtspr(SPRN_MMCRH, 0);
107344fbab9SJordan Niethe }
108344fbab9SJordan Niethe 
109344fbab9SJordan Niethe static void init_PMU(void)
110344fbab9SJordan Niethe {
111344fbab9SJordan Niethe 	mtspr(SPRN_MMCRA, 0);
112344fbab9SJordan Niethe 	mtspr(SPRN_MMCR0, 0);
113344fbab9SJordan Niethe 	mtspr(SPRN_MMCR1, 0);
114344fbab9SJordan Niethe 	mtspr(SPRN_MMCR2, 0);
115344fbab9SJordan Niethe }
116344fbab9SJordan Niethe 
117344fbab9SJordan Niethe static void init_PMU_ISA207(void)
118344fbab9SJordan Niethe {
119344fbab9SJordan Niethe 	mtspr(SPRN_MMCRS, 0);
120344fbab9SJordan Niethe }
121344fbab9SJordan Niethe 
122344fbab9SJordan Niethe static void init_PMU_ISA31(void)
123344fbab9SJordan Niethe {
124344fbab9SJordan Niethe 	mtspr(SPRN_MMCR3, 0);
125344fbab9SJordan Niethe 	mtspr(SPRN_MMCRA, MMCRA_BHRB_DISABLE);
126*91668ab7SAthira Rajeev 	mtspr(SPRN_MMCR0, MMCR0_PMCCEXT);
127344fbab9SJordan Niethe }
128344fbab9SJordan Niethe 
129344fbab9SJordan Niethe /*
130344fbab9SJordan Niethe  * Note that we can be called twice of pseudo-PVRs.
131344fbab9SJordan Niethe  * The parameter offset is not used.
132344fbab9SJordan Niethe  */
133344fbab9SJordan Niethe 
134344fbab9SJordan Niethe void __setup_cpu_power7(unsigned long offset, struct cpu_spec *t)
135344fbab9SJordan Niethe {
136344fbab9SJordan Niethe 	if (!init_hvmode_206(t))
137344fbab9SJordan Niethe 		return;
138344fbab9SJordan Niethe 
139344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
140344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
141344fbab9SJordan Niethe 	init_LPCR_ISA206(mfspr(SPRN_LPCR), LPCR_LPES1 >> LPCR_LPES_SH);
142344fbab9SJordan Niethe }
143344fbab9SJordan Niethe 
144344fbab9SJordan Niethe void __restore_cpu_power7(void)
145344fbab9SJordan Niethe {
146344fbab9SJordan Niethe 	u64 msr;
147344fbab9SJordan Niethe 
148344fbab9SJordan Niethe 	msr = mfmsr();
149344fbab9SJordan Niethe 	if (!(msr & MSR_HV))
150344fbab9SJordan Niethe 		return;
151344fbab9SJordan Niethe 
152344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
153344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
154344fbab9SJordan Niethe 	init_LPCR_ISA206(mfspr(SPRN_LPCR), LPCR_LPES1 >> LPCR_LPES_SH);
155344fbab9SJordan Niethe }
156344fbab9SJordan Niethe 
157344fbab9SJordan Niethe void __setup_cpu_power8(unsigned long offset, struct cpu_spec *t)
158344fbab9SJordan Niethe {
159344fbab9SJordan Niethe 	init_FSCR();
160344fbab9SJordan Niethe 	init_PMU();
161344fbab9SJordan Niethe 	init_PMU_ISA207();
162344fbab9SJordan Niethe 
163344fbab9SJordan Niethe 	if (!init_hvmode_206(t))
164344fbab9SJordan Niethe 		return;
165344fbab9SJordan Niethe 
166344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
167344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
168344fbab9SJordan Niethe 	init_LPCR_ISA206(mfspr(SPRN_LPCR) | LPCR_PECEDH, 0); /* LPES = 0 */
169344fbab9SJordan Niethe 	init_HFSCR();
170344fbab9SJordan Niethe 	init_PMU_HV();
171344fbab9SJordan Niethe 	init_PMU_HV_ISA207();
172344fbab9SJordan Niethe }
173344fbab9SJordan Niethe 
174344fbab9SJordan Niethe void __restore_cpu_power8(void)
175344fbab9SJordan Niethe {
176344fbab9SJordan Niethe 	u64 msr;
177344fbab9SJordan Niethe 
178344fbab9SJordan Niethe 	init_FSCR();
179344fbab9SJordan Niethe 	init_PMU();
180344fbab9SJordan Niethe 	init_PMU_ISA207();
181344fbab9SJordan Niethe 
182344fbab9SJordan Niethe 	msr = mfmsr();
183344fbab9SJordan Niethe 	if (!(msr & MSR_HV))
184344fbab9SJordan Niethe 		return;
185344fbab9SJordan Niethe 
186344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
187344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
188344fbab9SJordan Niethe 	init_LPCR_ISA206(mfspr(SPRN_LPCR) | LPCR_PECEDH, 0); /* LPES = 0 */
189344fbab9SJordan Niethe 	init_HFSCR();
190344fbab9SJordan Niethe 	init_PMU_HV();
191344fbab9SJordan Niethe 	init_PMU_HV_ISA207();
192344fbab9SJordan Niethe }
193344fbab9SJordan Niethe 
194344fbab9SJordan Niethe void __setup_cpu_power9(unsigned long offset, struct cpu_spec *t)
195344fbab9SJordan Niethe {
196344fbab9SJordan Niethe 	init_FSCR_power9();
197344fbab9SJordan Niethe 	init_PMU();
198344fbab9SJordan Niethe 
199344fbab9SJordan Niethe 	if (!init_hvmode_206(t))
200344fbab9SJordan Niethe 		return;
201344fbab9SJordan Niethe 
202344fbab9SJordan Niethe 	mtspr(SPRN_PSSCR, 0);
203344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
204344fbab9SJordan Niethe 	mtspr(SPRN_PID, 0);
205344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
206344fbab9SJordan Niethe 	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
207344fbab9SJordan Niethe 			 LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
208344fbab9SJordan Niethe 	init_HFSCR();
209344fbab9SJordan Niethe 	init_PMU_HV();
210344fbab9SJordan Niethe }
211344fbab9SJordan Niethe 
212344fbab9SJordan Niethe void __restore_cpu_power9(void)
213344fbab9SJordan Niethe {
214344fbab9SJordan Niethe 	u64 msr;
215344fbab9SJordan Niethe 
216344fbab9SJordan Niethe 	init_FSCR_power9();
217344fbab9SJordan Niethe 	init_PMU();
218344fbab9SJordan Niethe 
219344fbab9SJordan Niethe 	msr = mfmsr();
220344fbab9SJordan Niethe 	if (!(msr & MSR_HV))
221344fbab9SJordan Niethe 		return;
222344fbab9SJordan Niethe 
223344fbab9SJordan Niethe 	mtspr(SPRN_PSSCR, 0);
224344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
225344fbab9SJordan Niethe 	mtspr(SPRN_PID, 0);
226344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
227344fbab9SJordan Niethe 	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
228344fbab9SJordan Niethe 			 LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
229344fbab9SJordan Niethe 	init_HFSCR();
230344fbab9SJordan Niethe 	init_PMU_HV();
231344fbab9SJordan Niethe }
232344fbab9SJordan Niethe 
233344fbab9SJordan Niethe void __setup_cpu_power10(unsigned long offset, struct cpu_spec *t)
234344fbab9SJordan Niethe {
235344fbab9SJordan Niethe 	init_FSCR_power10();
236344fbab9SJordan Niethe 	init_PMU();
237344fbab9SJordan Niethe 	init_PMU_ISA31();
238344fbab9SJordan Niethe 
239344fbab9SJordan Niethe 	if (!init_hvmode_206(t))
240344fbab9SJordan Niethe 		return;
241344fbab9SJordan Niethe 
242344fbab9SJordan Niethe 	mtspr(SPRN_PSSCR, 0);
243344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
244344fbab9SJordan Niethe 	mtspr(SPRN_PID, 0);
245344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
246344fbab9SJordan Niethe 	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
247344fbab9SJordan Niethe 			 LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
248344fbab9SJordan Niethe 	init_HFSCR();
249344fbab9SJordan Niethe 	init_PMU_HV();
250344fbab9SJordan Niethe }
251344fbab9SJordan Niethe 
252344fbab9SJordan Niethe void __restore_cpu_power10(void)
253344fbab9SJordan Niethe {
254344fbab9SJordan Niethe 	u64 msr;
255344fbab9SJordan Niethe 
256344fbab9SJordan Niethe 	init_FSCR_power10();
257344fbab9SJordan Niethe 	init_PMU();
258344fbab9SJordan Niethe 	init_PMU_ISA31();
259344fbab9SJordan Niethe 
260344fbab9SJordan Niethe 	msr = mfmsr();
261344fbab9SJordan Niethe 	if (!(msr & MSR_HV))
262344fbab9SJordan Niethe 		return;
263344fbab9SJordan Niethe 
264344fbab9SJordan Niethe 	mtspr(SPRN_PSSCR, 0);
265344fbab9SJordan Niethe 	mtspr(SPRN_LPID, 0);
266344fbab9SJordan Niethe 	mtspr(SPRN_PID, 0);
267344fbab9SJordan Niethe 	mtspr(SPRN_PCR, PCR_MASK);
268344fbab9SJordan Niethe 	init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
269344fbab9SJordan Niethe 			 LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
270344fbab9SJordan Niethe 	init_HFSCR();
271344fbab9SJordan Niethe 	init_PMU_HV();
272344fbab9SJordan Niethe }
273