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