1 /* Copyright 2013-2017 IBM Corp.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * 	http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <skiboot.h>
19 #include <fsp.h>
20 #include <fsp-sysparam.h>
21 #include <opal.h>
22 #include <console.h>
23 #include <hostservices.h>
24 #include <ipmi.h>
25 #include <debug_descriptor.h>
26 #include <occ.h>
27 
28 #include "ibm-fsp.h"
29 
map_debug_areas(void)30 static void map_debug_areas(void)
31 {
32 	uint64_t t, i;
33 
34 	/* Our memcons is in a section of its own and already
35 	 * aligned to 4K. The buffers are mapped as a whole
36 	 */
37 	fsp_tce_map(PSI_DMA_MEMCONS, &memcons, 0x1000);
38 	fsp_tce_map(PSI_DMA_LOG_BUF, (void*)INMEM_CON_START, INMEM_CON_LEN);
39 
40 	debug_descriptor.memcons_tce = PSI_DMA_MEMCONS;
41 	t = memcons.obuf_phys - INMEM_CON_START + PSI_DMA_LOG_BUF;
42 	debug_descriptor.memcons_obuf_tce = t;
43 	t = memcons.ibuf_phys - INMEM_CON_START + PSI_DMA_LOG_BUF;
44 	debug_descriptor.memcons_ibuf_tce = t;
45 
46 	/* We only have space in the TCE table for the trace
47 	 * areas on P8
48 	 */
49 	if (proc_gen != proc_gen_p8)
50 		return;
51 
52 	t = PSI_DMA_TRACE_BASE;
53 	for (i = 0; i < debug_descriptor.num_traces; i++) {
54 		/*
55 		 * Trace buffers are misaligned by 0x10 due to the lock
56 		 * in the trace structure, and their size is also not
57 		 * completely aligned. (They are allocated so that with
58 		 * the lock included, they do cover entire multiple of
59 		 * a 4K page however).
60 		 *
61 		 * This means we have to map the lock into the TCEs and
62 		 * align everything. Not a huge deal but needs to be
63 		 * taken into account.
64 		 *
65 		 * Note: Maybe we should map them read-only...
66 		 */
67 		uint64_t tstart, tend, toff, tsize;
68 
69 		tstart = ALIGN_DOWN(debug_descriptor.trace_phys[i], 0x1000);
70 		tend = ALIGN_UP(debug_descriptor.trace_phys[i] +
71 				debug_descriptor.trace_size[i], 0x1000);
72 		toff = debug_descriptor.trace_phys[i] - tstart;
73 		tsize = tend - tstart;
74 
75 		fsp_tce_map(t, (void *)tstart, tsize);
76 		debug_descriptor.trace_tce[i] = t + toff;
77 		t += tsize;
78 	}
79 }
80 
81 
ibm_fsp_init(void)82 void ibm_fsp_init(void)
83 {
84 	/* Early initializations of the FSP interface */
85 	fsp_init();
86 	map_debug_areas();
87 	fsp_sysparam_init();
88 
89 	/* Get ready to receive E0 class messages. We need to respond
90 	 * to some of these for the init sequence to make forward progress
91 	 */
92 	fsp_console_preinit();
93 
94 	/* Get ready to receive OCC related messages */
95 	occ_fsp_init();
96 
97 	/* Get ready to receive Memory [Un]corretable Error messages. */
98 	fsp_memory_err_init();
99 
100 	/* Initialize elog access */
101 	fsp_elog_read_init();
102 	fsp_elog_write_init();
103 
104 	/* Initiate dump service */
105 	fsp_dump_init();
106 
107 	/* Start FSP/HV state controller & perform OPL */
108 	fsp_opl();
109 
110 	/* Preload hostservices lids */
111 	hservices_lid_preload();
112 
113 	/* Initialize SP attention area */
114 	fsp_attn_init();
115 
116 	/* Initialize monitoring of TOD topology change event notification */
117 	fsp_chiptod_init();
118 
119 	/* Send MDST table notification to FSP */
120 	op_display(OP_LOG, OP_MOD_INIT, 0x0000);
121 	fsp_mdst_table_init();
122 
123 	/* Initialize the panel */
124 	op_display(OP_LOG, OP_MOD_INIT, 0x0001);
125 	fsp_oppanel_init();
126 
127 	/* Start the surveillance process */
128 	op_display(OP_LOG, OP_MOD_INIT, 0x0002);
129 	fsp_init_surveillance();
130 
131 	/* IPMI */
132 	fsp_ipmi_init();
133 	ipmi_opal_init();
134 
135 	/* Initialize sensor access */
136 	op_display(OP_LOG, OP_MOD_INIT, 0x0003);
137 	fsp_init_sensor();
138 
139 	/* LED */
140 	op_display(OP_LOG, OP_MOD_INIT, 0x0004);
141 	fsp_led_init();
142 
143 	/* Monitor for DIAG events */
144 	op_display(OP_LOG, OP_MOD_INIT, 0x0005);
145 	fsp_init_diag();
146 
147 	/* Finish initializing the console */
148 	op_display(OP_LOG, OP_MOD_INIT, 0x0006);
149 	fsp_console_init();
150 
151 	/* Read our initial RTC value */
152 	op_display(OP_LOG, OP_MOD_INIT, 0x0008);
153 	fsp_rtc_init();
154 
155 	/* Initialize code update access */
156 	op_display(OP_LOG, OP_MOD_INIT, 0x0009);
157 	fsp_code_update_init();
158 
159 	/* EPOW */
160 	op_display(OP_LOG, OP_MOD_INIT, 0x000A);
161 	fsp_epow_init();
162 
163 	/* EPOW */
164 	op_display(OP_LOG, OP_MOD_INIT, 0x000B);
165 	fsp_dpo_init();
166 
167 	/* Setup console */
168 	if (fsp_present())
169 		fsp_console_add_nodes();
170 
171 	if (proc_gen >= proc_gen_p9)
172 		prd_init();
173 
174 	preload_io_vpd();
175 }
176 
ibm_fsp_finalise_dt(bool is_reboot)177 void ibm_fsp_finalise_dt(bool is_reboot)
178 {
179 	if (is_reboot)
180 		return;
181 
182 	/*
183 	 * LED related SPCN commands might take a while to
184 	 * complete. Call this as late as possible to
185 	 * ensure we have all the LED information.
186 	 */
187 	create_led_device_nodes();
188 
189 	/*
190 	 * OCC takes few secs to boot.  Call this as late as
191 	 * as possible to avoid delay.
192 	 */
193 	occ_pstates_init();
194 
195 	/* Wait for FW VPD data read to complete */
196 	fsp_code_update_wait_vpd(true);
197 
198 	fsp_console_select_stdout();
199 }
200 
ibm_fsp_exit(void)201 void ibm_fsp_exit(void)
202 {
203 	op_panel_disable_src_echo();
204 
205 	/* Clear SRCs on the op-panel when Linux starts */
206 	op_panel_clear_src();
207 }
208 
ibm_fsp_cec_reboot(void)209 int64_t ibm_fsp_cec_reboot(void)
210 {
211 	uint32_t cmd = FSP_CMD_REBOOT;
212 
213 	if (!fsp_present())
214 		return OPAL_UNSUPPORTED;
215 
216 	/* Flash new firmware */
217 	if (fsp_flash_term_hook &&
218 	    fsp_flash_term_hook() == OPAL_SUCCESS)
219 		cmd = FSP_CMD_DEEP_REBOOT;
220 
221 	printf("FSP: Sending 0x%02x reboot command to FSP...\n", cmd);
222 
223 	/* If that failed, talk to the FSP */
224 	if (fsp_sync_msg(fsp_mkmsg(cmd, 0), true))
225 		return OPAL_BUSY_EVENT;
226 
227 	return OPAL_SUCCESS;
228 }
229 
ibm_fsp_cec_power_down(uint64_t request)230 int64_t ibm_fsp_cec_power_down(uint64_t request)
231 {
232 	/* Request is:
233 	 *
234 	 * 0 = normal
235 	 * 1 = immediate
236 	 * (we do not allow 2 for "pci cfg reset" just yet)
237 	 */
238 
239 	if (request !=0 && request != 1)
240 		return OPAL_PARAMETER;
241 
242 	if (!fsp_present())
243 		return OPAL_UNSUPPORTED;
244 
245 	/* Flash new firmware */
246 	if (fsp_flash_term_hook)
247 		fsp_flash_term_hook();
248 
249 	printf("FSP: Sending shutdown command to FSP...\n");
250 
251 	if (fsp_sync_msg(fsp_mkmsg(FSP_CMD_POWERDOWN_NORM, 1, request), true))
252 		return OPAL_BUSY_EVENT;
253 
254 	fsp_reset_links();
255 	return OPAL_SUCCESS;
256 }
257 
ibm_fsp_sensor_read(uint32_t sensor_hndl,int token,uint64_t * sensor_data)258 int64_t ibm_fsp_sensor_read(uint32_t sensor_hndl, int token,
259 				uint64_t *sensor_data)
260 {
261 	return fsp_opal_read_sensor(sensor_hndl, token, sensor_data);
262 }
263 
fsp_heartbeat_time(void)264 int __attrconst fsp_heartbeat_time(void)
265 {
266 	/* Same as core/timer.c HEARTBEAT_DEFAULT_MS * 10 */
267 	return 200 * 10;
268 }
269 
fsp_psihb_interrupt(void)270 static void fsp_psihb_interrupt(void)
271 {
272 	/* Poll the console buffers on any interrupt since we don't
273 	 * get send notifications
274 	 */
275 	fsp_console_poll(NULL);
276 }
277 
278 struct platform_psi fsp_platform_psi = {
279 	.psihb_interrupt = fsp_psihb_interrupt,
280 	.link_established = fsp_reinit_fsp,
281 	.fsp_interrupt = fsp_interrupt,
282 };
283 
284 struct platform_prd fsp_platform_prd = {
285 	.msg_response = hservice_hbrt_msg_response,
286 	.send_error_log = hservice_send_error_log,
287 	.send_hbrt_msg = hservice_send_hbrt_msg,
288 	.wakeup = hservice_wakeup,
289 	.fsp_occ_load_start_status = fsp_occ_load_start_status,
290 	.fsp_occ_reset_status = fsp_occ_reset_status,
291 };
292