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