1 /*
2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stddef.h>
7 #include <stdint.h>
8
9 #include <device_mec5.h>
10 #include "mec_defs.h"
11 #include "mec_ecia_api.h"
12 #include "mec_espi_api.h"
13 #include "mec_pcr_api.h"
14 #include "mec_retval.h"
15
16 /* ---- eSPI Reset interrupt ---- */
17 #define MEC_ESPI_RESET_ECIA_INFO MEC5_ECIA_INFO(19, 7, 11, 110)
18
set_supported_channels(struct mec_espi_io_regs * iobase,uint32_t capabilities)19 static void set_supported_channels(struct mec_espi_io_regs *iobase, uint32_t capabilities)
20 {
21 uint32_t mask = (MEC_ESPI_IO_CAP0_PC_SUPP_Msk | MEC_ESPI_IO_CAP0_VW_SUPP_Msk
22 | MEC_ESPI_IO_CAP0_OOB_SUPP_Msk | MEC_ESPI_IO_CAP0_FC_SUPP_Msk);
23 uint32_t temp = 0;
24
25 if (capabilities & MEC_BIT(MEC_ESPI_CFG_PERIPH_CHAN_SUP_POS)) {
26 temp |= MEC_BIT(MEC_ESPI_IO_CAP0_PC_SUPP_Pos);
27 }
28
29 if (capabilities & MEC_BIT(MEC_ESPI_CFG_VW_CHAN_SUP_POS)) {
30 temp |= MEC_BIT(MEC_ESPI_IO_CAP0_VW_SUPP_Pos);
31 }
32
33 if (capabilities & MEC_BIT(MEC_ESPI_CFG_OOB_CHAN_SUP_POS)) {
34 temp |= MEC_BIT(MEC_ESPI_IO_CAP0_OOB_SUPP_Pos);
35 }
36
37 if (capabilities & MEC_BIT(MEC_ESPI_CFG_FLASH_CHAN_SUP_POS)) {
38 temp |= MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos);
39 }
40
41 iobase->CAP0 = (uint8_t)((iobase->CAP0 & ~mask) | temp);
42 }
43
set_supported_max_freq(struct mec_espi_io_regs * iobase,uint32_t capabilities)44 static void set_supported_max_freq(struct mec_espi_io_regs *iobase, uint32_t capabilities)
45 {
46 uint32_t mask = MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Msk;
47 uint32_t temp = capabilities & MEC_ESPI_CFG_MAX_SUPP_FREQ_MSK;
48
49 temp >>= MEC_ESPI_CFG_MAX_SUPP_FREQ_POS;
50 temp = (temp << MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Pos) & MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Msk;
51
52 iobase->CAP1 = (uint8_t)((iobase->CAP1 & ~mask) | temp);
53 }
54
55 /* eSPI capabilties 1 register has maximum supported frequency field.
56 * The field values match the API enum mec_espi_max_freq values.
57 */
get_max_freq(struct mec_espi_io_regs * iobase)58 static uint32_t get_max_freq(struct mec_espi_io_regs *iobase)
59 {
60 uint32_t hwfreq =
61 ((iobase->CAP1 & MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Msk) >> MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Pos);
62
63 return hwfreq;
64 }
65
set_supported_io_modes(struct mec_espi_io_regs * iobase,uint32_t capabilities)66 static void set_supported_io_modes(struct mec_espi_io_regs *iobase, uint32_t capabilities)
67 {
68 uint32_t temp = iobase->CAP1 & ~(MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Msk);
69
70 temp |= ((((capabilities >> MEC_ESPI_CFG_IO_MODE_SUPP_POS)
71 & MEC_ESPI_CFG_IO_MODE_SUPP_MSK0) << MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Pos)
72 & MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Msk);
73
74 iobase->CAP1 = (uint8_t)(temp & 0xffu);
75 }
76
77 /* eSPI capabilities 1 register contains a bitfield for supported I/O modes.
78 * Our API enum mec_espi_io_mode values are indentical hardware bitfield values.
79 */
get_supported_io_modes(struct mec_espi_io_regs * iobase)80 static uint32_t get_supported_io_modes(struct mec_espi_io_regs *iobase)
81 {
82 uint32_t iom =
83 ((iobase->CAP1 & MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Msk) >> MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Pos);
84
85 return ((iom << MEC_ESPI_CFG_IO_MODE_SUPP_POS) & MEC_ESPI_CFG_IO_MODE_SUPP_MSK);
86 }
87
set_supported_alert_io_pin_mode(struct mec_espi_io_regs * iobase,uint32_t capabilities)88 static void set_supported_alert_io_pin_mode(struct mec_espi_io_regs *iobase, uint32_t capabilities)
89 {
90 uint32_t temp = iobase->CAP1 & ~(MEC_ESPI_IO_CAP1_ALERT_OD_SUPP_Msk);
91
92 if (capabilities & MEC_BIT(MEC_ESPI_CFG_ALERT_OD_SUPP_POS)) {
93 temp |= MEC_BIT(MEC_ESPI_IO_CAP1_ALERT_OD_SUPP_Pos);
94 }
95
96 iobase->CAP1 = (uint8_t)(temp & 0xffu);
97 }
98
set_pc_capabilities(struct mec_espi_io_regs * iobase,uint32_t capabilities)99 static void set_pc_capabilities(struct mec_espi_io_regs *iobase, uint32_t capabilities)
100 {
101 uint32_t temp = iobase->CAPPC & ~(MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Msk);
102
103 temp |= ((((capabilities >> MEC_ESPI_CFG_PC_MAX_PLD_SZ_POS)
104 & MEC_ESPI_CFG_PC_MAX_PLD_SZ_MSK0) << MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Pos)
105 & MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Msk);
106
107 iobase->CAPPC = (uint8_t)(temp & 0xffu);
108 }
109
get_pc_max_pld_size(struct mec_espi_io_regs * iobase)110 static uint32_t get_pc_max_pld_size(struct mec_espi_io_regs *iobase)
111 {
112 uint32_t pldsz =
113 ((iobase->CAPPC & MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Msk) >> MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Pos);
114
115 return ((pldsz << MEC_ESPI_CFG_PC_MAX_PLD_SZ_POS) & MEC_ESPI_CFG_PC_MAX_PLD_SZ_MSK);
116 }
117
set_vw_capabilities(struct mec_espi_io_regs * iobase,uint32_t capabilities)118 static void set_vw_capabilities(struct mec_espi_io_regs *iobase, uint32_t capabilities)
119 {
120 uint32_t temp = iobase->CAPVW & ~(MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Msk);
121
122 temp |= ((((capabilities >> MEC_ESPI_CFG_VW_CNT_MAX_POS)
123 & MEC_ESPI_CFG_VW_CNT_MAX_MSK0) << MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Pos)
124 & MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Msk);
125
126 iobase->CAPVW = (uint8_t)(temp & 0xffu);
127 }
128
get_vw_groups_max_cnt(struct mec_espi_io_regs * iobase)129 static uint32_t get_vw_groups_max_cnt(struct mec_espi_io_regs *iobase)
130 {
131 uint32_t nvwg =
132 ((iobase->CAPVW & MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Msk) >> MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Pos);
133
134 return ((nvwg << MEC_ESPI_CFG_VW_CNT_MAX_POS) & MEC_ESPI_CFG_VW_CNT_MAX_MSK);
135 }
136
set_oob_capabilities(struct mec_espi_io_regs * iobase,uint32_t capabilities)137 static void set_oob_capabilities(struct mec_espi_io_regs *iobase, uint32_t capabilities)
138 {
139 uint32_t temp = iobase->CAPOOB & ~(MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Msk);
140
141 temp |= ((((capabilities >> MEC_ESPI_CFG_OOB_MAX_PLD_SZ_POS)
142 & MEC_ESPI_CFG_OOB_MAX_PLD_SZ_MSK0) << MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Pos)
143 & MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Msk);
144
145 iobase->CAPOOB = (uint8_t)(temp & 0xffu);
146 }
147
get_oob_pld_size(struct mec_espi_io_regs * iobase)148 static uint32_t get_oob_pld_size(struct mec_espi_io_regs *iobase)
149 {
150 uint32_t pldsz =
151 ((iobase->CAPOOB & MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Msk) >> MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Pos);
152
153 return ((pldsz << MEC_ESPI_CFG_OOB_MAX_PLD_SZ_POS) & MEC_ESPI_CFG_OOB_MAX_PLD_SZ_MSK);
154 }
155
set_fc_max_pld(struct mec_espi_io_regs * iobase,uint32_t capabilities)156 static void set_fc_max_pld(struct mec_espi_io_regs *iobase, uint32_t capabilities)
157 {
158 uint32_t temp = ((capabilities >> MEC_ESPI_CFG_FLASH_MAX_PLD_SZ_POS)
159 & MEC_ESPI_CFG_FLASH_MAX_PLD_SZ_MSK0);
160 uint8_t msk = MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk;
161 uint8_t regval = (uint8_t)((temp << MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Pos)
162 & MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk);
163
164 iobase->CAPFC = (iobase->CAPFC & ~msk) | regval;
165 }
166
get_fc_pld_size(struct mec_espi_io_regs * iobase)167 static uint32_t get_fc_pld_size(struct mec_espi_io_regs *iobase)
168 {
169 uint32_t pldsz =
170 ((iobase->CAPFC & MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk) >> MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Pos);
171
172 return ((pldsz << MEC_ESPI_CFG_FLASH_MAX_PLD_SZ_POS) & MEC_ESPI_CFG_FLASH_MAX_PLD_SZ_MSK);
173 }
174
fc_sharing_hw(uint32_t cfg)175 static uint8_t fc_sharing_hw(uint32_t cfg)
176 {
177 uint8_t cap = 0;
178
179 if (cfg & MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_TAF_POS)) {
180 if (cfg & MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_CAF_POS)) {
181 cap |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_CAF_TAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
182 } else { /* TAF only */
183 cap |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_TAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
184 }
185 } else {
186 cap |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_CAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
187 }
188
189 return cap;
190 }
191
fc_sharing_get(uint32_t fc_cap)192 static uint32_t fc_sharing_get(uint32_t fc_cap)
193 {
194 uint32_t cfg = 0;
195
196 fc_cap = (fc_cap & MEC_ESPI_IO_CAPFC_SHARING_SUPP_Msk) >> MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos;
197 if (fc_cap == MEC_ESPI_IO_CAPFC_SHARING_SUPP_TAF) {
198 cfg |= MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_TAF_POS);
199 } else {
200 cfg |= MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_CAF_POS);
201 if (fc_cap == MEC_ESPI_IO_CAPFC_SHARING_SUPP_CAF_TAF) {
202 cfg |= MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_TAF_POS);
203 }
204 }
205
206 return cfg;
207 }
208
set_fc_shared_mode(struct mec_espi_io_regs * iobase,uint32_t capabilities)209 static void set_fc_shared_mode(struct mec_espi_io_regs *iobase, uint32_t capabilities)
210 {
211 uint8_t msk = MEC_ESPI_IO_CAPFC_SHARING_SUPP_Msk;
212 uint8_t regval = fc_sharing_hw(capabilities);
213
214 iobase->CAPFC = (iobase->CAPFC & ~msk) | regval;
215 }
216
get_fc_shared_mode(struct mec_espi_io_regs * iobase)217 static uint32_t get_fc_shared_mode(struct mec_espi_io_regs *iobase)
218 {
219 uint32_t fcsh = fc_sharing_get(iobase->CAPFC);
220
221 return fcsh;
222 }
223
set_fc_capabilities(struct mec_espi_io_regs * iobase,uint32_t capabilities)224 static void set_fc_capabilities(struct mec_espi_io_regs *iobase, uint32_t capabilities)
225 {
226 uint32_t temp = ((capabilities >> MEC_ESPI_CFG_FLASH_MAX_PLD_SZ_POS)
227 & MEC_ESPI_CFG_FLASH_MAX_PLD_SZ_MSK0);
228 uint8_t msk = (MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk | MEC_ESPI_IO_CAPFC_SHARING_SUPP_Msk
229 | MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Msk);
230 uint8_t regval = (uint8_t)((temp << MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Pos)
231 & MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk);
232
233 if (capabilities & MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_TAF_POS)) {
234 if (capabilities & MEC_BIT(MEC_ESPI_CFG_FLASH_SHARED_CAF_POS)) {
235 regval |=
236 (MEC_ESPI_IO_CAPFC_SHARING_SUPP_CAF_TAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
237 } else {
238 regval |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_TAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
239 }
240 } else {
241 regval |= (MEC_ESPI_IO_CAPFC_SHARING_SUPP_CAF << MEC_ESPI_IO_CAPFC_SHARING_SUPP_Pos);
242 }
243
244 iobase->CAPFC = (iobase->CAPFC & ~msk) | regval;
245 }
246
get_fc_taf_max_rdsz(struct mec_espi_io_regs * iobase)247 static uint32_t get_fc_taf_max_rdsz(struct mec_espi_io_regs *iobase)
248 {
249 uint32_t rdsz = 0;
250 uint32_t capfc = iobase->CAPFC;
251
252 rdsz = ((capfc & MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Msk)
253 >> MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Pos);
254 rdsz &= MEC_ESPI_CAP_FLASH_SHARED_MAX_RD_REQ_SZ_MSK0;
255 rdsz <<= MEC_ESPI_CAP_FLASH_SHARED_MAX_RD_REQ_SZ_POS;
256
257 return rdsz;
258 }
259
260 /* If Platform Reset is peformed is different way than eSPI PLTRST# virtual wire
261 * we set a bit so our eSPI controller will ignore PLTRST# VWire.
262 */
set_pltrst_source(struct mec_espi_io_regs * iobase,uint32_t capabilities)263 static void set_pltrst_source(struct mec_espi_io_regs *iobase, uint32_t capabilities)
264 {
265 uint8_t host_reset_sel = 0;
266
267 if (capabilities & MEC_BIT(MEC_ESPI_CFG_PLTRST_EXT_POS)) {
268 iobase->PLTRST_SRC |= MEC_BIT(MEC_ESPI_IO_PLTRST_SRC_SEL_Pos);
269 } else { /* use PLTRST# virtual wire */
270 iobase->PLTRST_SRC &= (uint8_t)~MEC_BIT(MEC_ESPI_IO_PLTRST_SRC_SEL_Pos);
271 host_reset_sel = MEC_PCR_PLATFORM_RST_IS_ESPI_PLTRST;
272 }
273
274 mec_hal_pcr_host_reset_select(host_reset_sel);
275 }
276
277 /* ---- Public API ---- */
mec_hal_espi_reset_change_clr(struct mec_espi_io_regs * iobase)278 void mec_hal_espi_reset_change_clr(struct mec_espi_io_regs *iobase)
279 {
280 iobase->ERIS = MEC_BIT(MEC_ESPI_IO_ERIS_CHG_Pos);
281 mec_hal_girq_clr_src(MEC_ESPI_RESET_ECIA_INFO);
282 }
283
284 /* Return bits indicating ESPI_RESET# has changed and its current state */
mec_hal_espi_reset_state(struct mec_espi_io_regs * iobase)285 uint32_t mec_hal_espi_reset_state(struct mec_espi_io_regs *iobase)
286 {
287 return iobase->ERIS & (MEC_ESPI_IO_ERIS_CHG_Msk | MEC_ESPI_IO_ERIS_STATE_Msk);
288 }
289
mec_hal_espi_reset_change_intr_en(struct mec_espi_io_regs * iobase,uint8_t enable)290 void mec_hal_espi_reset_change_intr_en(struct mec_espi_io_regs *iobase, uint8_t enable)
291 {
292 if (enable) {
293 iobase->ERIE |= MEC_BIT(MEC_ESPI_IO_ERIE_CHG_INTR_Pos);
294 } else {
295 iobase->ERIE &= (uint8_t)~MEC_BIT(MEC_ESPI_IO_ERIE_CHG_INTR_Pos);
296 }
297 }
298
299 /* ESPI_RESET edge interrupt ECIA control */
mec_hal_espi_reset_girq_ctrl(uint8_t enable)300 void mec_hal_espi_reset_girq_ctrl(uint8_t enable)
301 {
302 mec_hal_girq_ctrl(MEC_ESPI_RESET_ECIA_INFO, (int)enable);
303 }
304
mec_hal_espi_reset_girq_status_clr(void)305 void mec_hal_espi_reset_girq_status_clr(void)
306 {
307 mec_hal_girq_clr_src(MEC_ESPI_RESET_ECIA_INFO);
308 }
309
mec_hal_espi_reset_girq_status(void)310 uint32_t mec_hal_espi_reset_girq_status(void)
311 {
312 return mec_hal_girq_src(MEC_ESPI_RESET_ECIA_INFO);
313 }
314
mec_hal_espi_reset_girq_result(void)315 uint32_t mec_hal_espi_reset_girq_result(void)
316 {
317 return mec_hal_girq_result(MEC_ESPI_RESET_ECIA_INFO);
318 }
319
320 /* NOTE eSPI is only fully reset by a full chip reset or power cycle.
321 * The external ESPI_RESET# signal when asserted does hold portions of the logic
322 * in reset state. Please refer to the Microchip eSPI block document.
323 */
mec_hal_espi_init(struct mec_espi_config * cfg)324 int mec_hal_espi_init(struct mec_espi_config *cfg)
325 {
326 if (!cfg) {
327 return MEC_RET_ERR_INVAL;
328 }
329
330 struct mec_espi_io_regs *iobase = cfg->iobase;
331 uint32_t girq_en = 0u;
332
333 set_supported_channels(iobase, cfg->capabilities);
334 set_supported_max_freq(iobase, cfg->capabilities);
335 set_supported_io_modes(iobase, cfg->capabilities);
336 set_supported_alert_io_pin_mode(iobase, cfg->capabilities);
337 set_pc_capabilities(iobase, cfg->capabilities);
338 set_vw_capabilities(iobase, cfg->capabilities);
339 set_oob_capabilities(iobase, cfg->capabilities);
340 set_fc_capabilities(iobase, cfg->capabilities);
341 set_pltrst_source(iobase, cfg->capabilities);
342
343 mec_hal_espi_reset_change_intr_en(iobase, 0);
344 mec_hal_espi_reset_change_clr(iobase);
345
346 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_VW_CT_GIRQ_EN_POS)) {
347 MEC_ECIA0->GIRQ[MEC_GIRQ_IDX_GIRQ24].EN_SET = 0x0fffffffu;
348 MEC_ECIA0->GIRQ[MEC_GIRQ_IDX_GIRQ25].EN_SET = 0x0000ffffu;
349 }
350
351 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_PC_GIRQ_EN_POS)) {
352 girq_en |= MEC_BIT(MEC_ESPI_PC_GIRQ_POS);
353 }
354
355 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_BM1_GIRQ_EN_POS)) {
356 girq_en |= MEC_BIT(MEC_ESPI_PC_BM1_GIRQ_POS);
357 }
358
359 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_BM2_GIRQ_EN_POS)) {
360 girq_en |= MEC_BIT(MEC_ESPI_PC_BM2_GIRQ_POS);
361 }
362
363 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_LTR_GIRQ_EN_POS)) {
364 girq_en |= MEC_BIT(MEC_ESPI_PC_LTR_GIRQ_POS);
365 }
366
367 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_OOB_UP_GIRQ_EN_POS)) {
368 girq_en |= MEC_BIT(MEC_ESPI_OOB_UP_GIRQ_POS);
369 }
370
371 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_OOB_DN_GIRQ_EN_POS)) {
372 girq_en |= MEC_BIT(MEC_ESPI_OOB_DN_GIRQ_POS);
373 }
374
375 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_FC_GIRQ_EN_POS)) {
376 girq_en |= MEC_BIT(MEC_ESPI_FC_GIRQ_POS);
377 }
378
379 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_VW_CHEN_GIRQ_EN_POS)) {
380 girq_en |= MEC_BIT(MEC_ESPI_VW_CHEN_GIRQ_POS);
381 }
382
383 if (cfg->cfg_flags & MEC_BIT(MEC_ESPI_CFG_FLAG_ERST_GIRQ_EN_POS)) {
384 girq_en |= MEC_BIT(MEC_ESPI_RESET_GIRQ_POS);
385 }
386
387 MEC_ECIA0->GIRQ[MEC_GIRQ_IDX_GIRQ19].EN_SET = girq_en;
388
389 return 0;
390 }
391
392 /* Enable eSPI controller after all static configuration has been performed.
393 * MEC eSPI activate must be set before the Host de-asserts ESPI_RESET#.
394 */
mec_hal_espi_activate(struct mec_espi_io_regs * iobase,uint8_t enable)395 void mec_hal_espi_activate(struct mec_espi_io_regs *iobase, uint8_t enable)
396 {
397 if (enable) {
398 iobase->ACTV |= MEC_BIT(MEC_ESPI_IO_ACTV_EN_Pos);
399 } else {
400 iobase->ACTV &= (uint32_t)~MEC_BIT(MEC_ESPI_IO_ACTV_EN_Pos);
401 }
402 }
403
mec_hal_espi_is_activated(struct mec_espi_io_regs * iobase)404 int mec_hal_espi_is_activated(struct mec_espi_io_regs *iobase)
405 {
406 if (iobase) {
407 if (iobase->ACTV & MEC_BIT(MEC_ESPI_IO_ACTV_EN_Pos)) {
408 return 1;
409 }
410 }
411
412 return 0;
413 }
414
mec_hal_espi_capability_set(struct mec_espi_io_regs * iobase,enum mec_espi_global_cap cap,uint32_t cfg)415 int mec_hal_espi_capability_set(struct mec_espi_io_regs *iobase,
416 enum mec_espi_global_cap cap, uint32_t cfg)
417 {
418 if (!iobase) {
419 return MEC_RET_ERR_INVAL;
420 }
421
422 switch (cap) {
423 case MEC_ESPI_CAP_MAX_FREQ:
424 set_supported_max_freq(iobase, cfg);
425 break;
426 case MEC_ESPI_CAP_IO_MODE:
427 set_supported_io_modes(iobase, cfg);
428 break;
429 case MEC_ESPI_CAP_ALERT_OD:
430 set_supported_alert_io_pin_mode(iobase, cfg);
431 break;
432 case MEC_ESPI_CAP_PERIPH_CHAN:
433 if (cfg & MEC_BIT(MEC_ESPI_CFG_PERIPH_CHAN_SUP_POS)) {
434 iobase->CAP0 |= MEC_BIT(MEC_ESPI_IO_CAP0_PC_SUPP_Pos);
435 } else {
436 iobase->CAP0 &= (uint8_t)~MEC_BIT(MEC_ESPI_IO_CAP0_PC_SUPP_Pos);
437 }
438 break;
439 case MEC_ESPI_CAP_PC_MAX_PLD_SIZE:
440 set_pc_capabilities(iobase, cfg);
441 break;
442 case MEC_ESPI_CAP_VWIRE_CHAN:
443 if (cfg & MEC_BIT(MEC_ESPI_CFG_VW_CHAN_SUP_POS)) {
444 iobase->CAP0 |= MEC_BIT(MEC_ESPI_IO_CAP0_VW_SUPP_Pos);
445 } else {
446 iobase->CAP0 &= (uint8_t)~MEC_BIT(MEC_ESPI_IO_CAP0_VW_SUPP_Pos);
447 }
448 break;
449 case MEC_ESPI_CAP_MAX_VW_COUNT:
450 set_vw_capabilities(iobase, cfg);
451 break;
452 case MEC_ESPI_CAP_OOB_CHAN:
453 if (cfg & MEC_BIT(MEC_ESPI_CFG_OOB_CHAN_SUP_POS)) {
454 iobase->CAP0 |= MEC_BIT(MEC_ESPI_IO_CAP0_OOB_SUPP_Pos);
455 } else {
456 iobase->CAP0 &= (uint8_t)~MEC_BIT(MEC_ESPI_IO_CAP0_OOB_SUPP_Pos);
457 }
458 break;
459 case MEC_ESPI_CAP_OOB_MAX_PLD_SIZE:
460 set_oob_capabilities(iobase, cfg);
461 break;
462 case MEC_ESPI_CAP_FLASH_CHAN:
463 if (cfg & MEC_BIT(MEC_ESPI_CFG_FLASH_CHAN_SUP_POS)) {
464 iobase->CAP0 |= MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos);
465 } else {
466 iobase->CAP0 &= (uint8_t)~MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos);
467 }
468 break;
469 case MEC_ESPI_CAP_FC_MAX_PLD_SIZE:
470 set_fc_max_pld(iobase, cfg);
471 break;
472 case MEC_ESPI_CAP_FC_SHARING:
473 set_fc_shared_mode(iobase, cfg);
474 break;
475 default:
476 return MEC_RET_ERR_INVAL;
477 }
478
479 return MEC_RET_OK;
480 }
481
mec_hal_espi_capabilities_get(struct mec_espi_io_regs * iobase,uint32_t * cfg)482 int mec_hal_espi_capabilities_get(struct mec_espi_io_regs *iobase, uint32_t *cfg)
483 {
484 uint32_t cv = 0;
485
486 if (!iobase || !cfg) {
487 return MEC_RET_ERR_INVAL;
488 }
489
490 /* Max frequency */
491 cv |= ((get_max_freq(iobase) << MEC_ESPI_CFG_MAX_SUPP_FREQ_POS)
492 & MEC_ESPI_CFG_MAX_SUPP_FREQ_MSK);
493
494 /* IO Mode */
495 cv |= get_supported_io_modes(iobase);
496
497 /* Supports open-drain Alert pin */
498 if (iobase->CAP1 & MEC_BIT(MEC_ESPI_IO_CAP1_ALERT_OD_SUPP_Pos)) {
499 cv |= MEC_BIT(MEC_ESPI_CFG_ALERT_OD_SUPP_POS);
500 }
501
502 /* Peripheral channel */
503 if (iobase->CAP0 & MEC_BIT(MEC_ESPI_IO_CAP0_PC_SUPP_Pos)) {
504 cv |= MEC_BIT(MEC_ESPI_CFG_PERIPH_CHAN_SUP_POS);
505 }
506 cv |= get_pc_max_pld_size(iobase);
507
508 /* VW channel */
509 if (iobase->CAP0 & MEC_BIT(MEC_ESPI_IO_CAP0_VW_SUPP_Pos)) {
510 cv |= MEC_BIT(MEC_ESPI_CFG_VW_CHAN_SUP_POS);
511 }
512 cv |= get_vw_groups_max_cnt(iobase);
513
514 /* OOB channel */
515 if (iobase->CAP0 & MEC_BIT(MEC_ESPI_IO_CAP0_OOB_SUPP_Pos)) {
516 cv |= MEC_BIT(MEC_ESPI_CFG_OOB_CHAN_SUP_POS);
517 }
518 cv |= get_oob_pld_size(iobase);
519
520 /* Flash channel */
521 if (iobase->CAP0 & MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos)) {
522 cv |= MEC_BIT(MEC_ESPI_CFG_FLASH_CHAN_SUP_POS);
523 }
524 cv |= get_fc_pld_size(iobase);
525 cv |= get_fc_shared_mode(iobase);
526 cv |= get_fc_taf_max_rdsz(iobase);
527
528 *cfg = cv;
529
530 return MEC_RET_OK;
531 }
532
set_espi_global_cap(struct mec_espi_io_regs * iobase,uint32_t cfg)533 static void set_espi_global_cap(struct mec_espi_io_regs *iobase, uint32_t cfg)
534 {
535 uint32_t msk = (MEC_ESPI_IO_CAP0_PC_SUPP_Msk | MEC_ESPI_IO_CAP0_VW_SUPP_Msk
536 | MEC_ESPI_IO_CAP0_OOB_SUPP_Msk | MEC_ESPI_IO_CAP0_FC_SUPP_Msk);
537 uint32_t cap = 0;
538
539 if (cfg & MEC_BIT(MEC_ESPI_CAP_GL_SUPP_PC_POS)) {
540 cap |= MEC_BIT(MEC_ESPI_IO_CAP0_PC_SUPP_Pos);
541 }
542 if (cfg & MEC_BIT(MEC_ESPI_CAP_GL_SUPP_VW_POS)) {
543 cap |= MEC_BIT(MEC_ESPI_IO_CAP0_VW_SUPP_Pos);
544 }
545 if (cfg & MEC_BIT(MEC_ESPI_CAP_GL_SUPP_OOB_POS)) {
546 cap |= MEC_BIT(MEC_ESPI_IO_CAP0_OOB_SUPP_Pos);
547 }
548 if (cfg & MEC_BIT(MEC_ESPI_CAP_GL_SUPP_FLASH_POS)) {
549 cap |= MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos);
550 }
551 iobase->CAP0 = (iobase->CAP0 & (uint8_t)~msk) | (uint8_t)(cap & msk);
552
553 cap = (cfg & MEC_ESPI_CAP_GL_MAX_FREQ_MSK) >> MEC_ESPI_CAP_GL_MAX_FREQ_POS;
554 cap |= (((cfg & MEC_ESPI_CAP_GL_IOM_MSK) >> MEC_ESPI_CAP_GL_IOM_POS)
555 << MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Pos);
556
557 if (cfg & MEC_BIT(MEC_ESPI_CAP_GL_SUPP_ALERT_OD_POS)) {
558 cap |= MEC_BIT(MEC_ESPI_IO_CAP1_ALERT_OD_SUPP_Pos);
559 }
560
561 msk = (MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Msk | MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Msk
562 | MEC_ESPI_IO_CAP1_ALERT_OD_SEL_Msk);
563 iobase->CAP1 = (iobase->CAP1 & (uint8_t)~msk) | (uint8_t)(cap & msk);
564
565 msk = MEC_ESPI_IO_PLTRST_SRC_SEL_Msk;
566 cap = 0;
567 if (cfg & MEC_BIT(MEC_ESPI_CAP_GL_PLTRST_EXT_POS)) {
568 cap |= MEC_BIT(MEC_ESPI_IO_PLTRST_SRC_SEL_Pos);
569 }
570
571 iobase->PLTRST_SRC = (iobase->PLTRST_SRC & (uint8_t)~msk) | (uint8_t)(cap & msk);
572 }
573
get_espi_global_cap(struct mec_espi_io_regs * iobase)574 static uint32_t get_espi_global_cap(struct mec_espi_io_regs *iobase)
575 {
576 uint32_t cfg = 0;
577 uint32_t hwval = iobase->CAP0;
578
579 if (hwval & MEC_BIT(MEC_ESPI_IO_CAP0_PC_SUPP_Pos)) {
580 cfg |= MEC_BIT(MEC_ESPI_CAP_GL_SUPP_PC_POS);
581 }
582 if (hwval & MEC_BIT(MEC_ESPI_IO_CAP0_VW_SUPP_Pos)) {
583 cfg |= MEC_BIT(MEC_ESPI_CAP_GL_SUPP_VW_POS);
584 }
585 if (hwval & MEC_BIT(MEC_ESPI_IO_CAP0_OOB_SUPP_Pos)) {
586 cfg |= MEC_BIT(MEC_ESPI_CAP_GL_SUPP_OOB_POS);
587 }
588 if (hwval & MEC_BIT(MEC_ESPI_IO_CAP0_FC_SUPP_Pos)) {
589 cfg |= MEC_BIT(MEC_ESPI_CAP_GL_SUPP_FLASH_POS);
590 }
591
592 hwval = iobase->CAP1;
593 cfg |= (((hwval & MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Msk) >> MEC_ESPI_IO_CAP1_MAX_FREQ_SUPP_Pos)
594 << MEC_ESPI_CAP_GL_MAX_FREQ_POS);
595 cfg |= (((hwval & MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Msk) >> MEC_ESPI_IO_CAP1_IO_MODE_SUPP_Pos)
596 << MEC_ESPI_CAP_GL_IOM_POS);
597 if (hwval & MEC_BIT(MEC_ESPI_IO_CAP1_ALERT_OD_SUPP_Pos)) {
598 cfg |= MEC_BIT(MEC_ESPI_CAP_GL_SUPP_ALERT_OD_POS);
599 }
600
601 if (iobase->PLTRST_SRC & MEC_BIT(MEC_ESPI_IO_PLTRST_SRC_SEL_Pos)) {
602 cfg |= MEC_BIT(MEC_ESPI_CAP_GL_PLTRST_EXT_POS);
603 }
604
605 return cfg;
606 }
607
set_espi_pc_cap(struct mec_espi_io_regs * iobase,uint32_t cfg)608 static void set_espi_pc_cap(struct mec_espi_io_regs *iobase, uint32_t cfg)
609 {
610 uint32_t msk = MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Msk;
611 uint32_t cap = (((cfg & MEC_ESPI_CAP_PC_MAX_PLD_SIZE_MSK) >> MEC_ESPI_CAP_PC_MAX_PLD_SIZE_POS)
612 << MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Pos);
613
614 iobase->CAPPC = (uint8_t)((iobase->CAPPC & (uint8_t)~msk) | (cap & msk));
615 }
616
get_espi_pc_cap(struct mec_espi_io_regs * iobase)617 static uint32_t get_espi_pc_cap(struct mec_espi_io_regs *iobase)
618 {
619 uint32_t rval =
620 ((iobase->CAPPC & MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Msk) >> MEC_ESPI_IO_CAPPC_PC_MAX_PLD_Pos);
621
622 return ((rval << MEC_ESPI_CAP_PC_MAX_PLD_SIZE_POS) & MEC_ESPI_CAP_PC_MAX_PLD_SIZE_MSK);
623 }
624
set_espi_vw_cap(struct mec_espi_io_regs * iobase,uint32_t cfg)625 static void set_espi_vw_cap(struct mec_espi_io_regs *iobase, uint32_t cfg)
626 {
627 uint32_t msk = MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Msk;
628 uint32_t cap =
629 (((cfg & MEC_ESPI_CAP_VW_MAX_VW_GRP_CNT_MSK) >> MEC_ESPI_CAP_VW_MAX_VW_GRP_CNT_POS)
630 << MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Pos);
631
632 iobase->CAPVW = (uint8_t)((iobase->CAPVW & (uint8_t)~msk) | (cap & msk));
633 }
634
get_espi_vw_cap(struct mec_espi_io_regs * iobase)635 static uint32_t get_espi_vw_cap(struct mec_espi_io_regs *iobase)
636 {
637 uint32_t rval =
638 ((iobase->CAPVW & MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Msk) >> MEC_ESPI_IO_CAPVW_MAX_VW_CNT_Pos);
639
640 return ((rval << MEC_ESPI_CAP_VW_MAX_VW_GRP_CNT_POS) & MEC_ESPI_CAP_VW_MAX_VW_GRP_CNT_MSK);
641 }
642
set_espi_oob_cap(struct mec_espi_io_regs * iobase,uint32_t cfg)643 static void set_espi_oob_cap(struct mec_espi_io_regs *iobase, uint32_t cfg)
644 {
645 uint32_t msk = MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Msk;
646 uint32_t cap =
647 (((cfg & MEC_ESPI_CAP_OOB_MAX_PLD_SIZE_MSK) >> MEC_ESPI_CAP_OOB_MAX_PLD_SIZE_POS)
648 << MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Pos);
649
650 iobase->CAPOOB = (uint8_t)((iobase->CAPOOB & (uint8_t)~msk) | (cap | msk));
651 }
652
get_espi_oob_cap(struct mec_espi_io_regs * iobase)653 static uint32_t get_espi_oob_cap(struct mec_espi_io_regs *iobase)
654 {
655 uint32_t rval =
656 ((iobase->CAPOOB & MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Msk) >> MEC_ESPI_IO_CAPOOB_MAX_PLD_SIZE_Pos);
657
658 return ((rval << MEC_ESPI_CAP_OOB_MAX_PLD_SIZE_POS) & MEC_ESPI_CAP_OOB_MAX_PLD_SIZE_MSK);
659 }
660
set_espi_fc_cap(struct mec_espi_io_regs * iobase,uint32_t cfg)661 static void set_espi_fc_cap(struct mec_espi_io_regs *iobase, uint32_t cfg)
662 {
663 uint32_t msk = (MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk | MEC_ESPI_IO_CAPFC_SHARING_SUPP_Msk
664 | MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Msk);
665 uint32_t cap = 0;
666
667 iobase->TAFEBS =
668 (uint8_t)((cfg & MEC_ESPI_CAP_FC_TAF_ERBSZ_MSK) >> MEC_ESPI_CAP_FC_TAF_ERBSZ_POS);
669
670 cap = ((cfg & MEC_ESPI_CAP_FC_MAX_PLD_SIZE_MSK) >> MEC_ESPI_CAP_FC_MAX_PLD_SIZE_POS);
671 cap <<= MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Pos;
672 cap |= (((cfg & MEC_ESPI_CAP_FC_TAF_MAX_RDREQ_SIZE_MSK)
673 >> MEC_ESPI_CAP_FC_TAF_MAX_RDREQ_SIZE_POS) << MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Pos);
674
675 cap |= fc_sharing_hw(cfg);
676
677 iobase->CAPFC = (uint8_t)((iobase->CAPFC & (uint8_t)~msk) | (cap & msk));
678 }
679
get_espi_fc_cap(struct mec_espi_io_regs * iobase)680 static uint32_t get_espi_fc_cap(struct mec_espi_io_regs *iobase)
681 {
682 uint32_t capfc = iobase->CAPFC;
683 uint32_t cfg = fc_sharing_get(capfc);
684 uint32_t temp = ((capfc & MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Msk)
685 >> MEC_ESPI_IO_CAPFC_MAX_PLD_SIZE_Pos);
686
687 cfg |= (temp << MEC_ESPI_CAP_FC_MAX_PLD_SIZE_POS);
688 temp = ((capfc & MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Msk)
689 >> MEC_ESPI_IO_CAPFC_TAF_MAX_READ_SIZE_Pos);
690
691 cfg |= (temp << MEC_ESPI_CAP_FC_TAF_MAX_RDREQ_SIZE_POS);
692 cfg |= (((uint32_t)iobase->TAFEBS & 0xffu) << MEC_ESPI_CAP_FC_TAF_ERBSZ_POS);
693
694 return cfg;
695 }
696
mec_hal_espi_cap_set(struct mec_espi_io_regs * iobase,enum mec_espi_cap_id id,uint32_t cfg)697 int mec_hal_espi_cap_set(struct mec_espi_io_regs *iobase, enum mec_espi_cap_id id, uint32_t cfg)
698 {
699 if (!iobase) {
700 return MEC_RET_ERR_INVAL;
701 }
702
703 switch (id) {
704 case MEC_ESPI_CAP_ID_GLOBAL:
705 set_espi_global_cap(iobase, cfg);
706 break;
707 case MEC_ESPI_CAP_ID_PC:
708 set_espi_pc_cap(iobase, cfg);
709 break;
710 case MEC_ESPI_CAP_ID_VW:
711 set_espi_vw_cap(iobase, cfg);
712 break;
713 case MEC_ESPI_CAP_ID_OOB:
714 set_espi_oob_cap(iobase, cfg);
715 break;
716 case MEC_ESPI_CAP_ID_FC:
717 set_espi_fc_cap(iobase, cfg);
718 break;
719 default:
720 return MEC_RET_ERR_INVAL;
721 }
722
723 return MEC_RET_OK;
724 }
725
mec_hal_espi_cap_get(struct mec_espi_io_regs * iobase,enum mec_espi_cap_id id)726 uint32_t mec_hal_espi_cap_get(struct mec_espi_io_regs *iobase, enum mec_espi_cap_id id)
727 {
728 uint32_t cap = 0u;
729
730 switch (id) {
731 case MEC_ESPI_CAP_ID_GLOBAL:
732 cap = get_espi_global_cap(iobase);
733 break;
734 case MEC_ESPI_CAP_ID_PC:
735 cap = get_espi_pc_cap(iobase);
736 break;
737 case MEC_ESPI_CAP_ID_VW:
738 cap = get_espi_vw_cap(iobase);
739 break;
740 case MEC_ESPI_CAP_ID_OOB:
741 cap = get_espi_oob_cap(iobase);
742 break;
743 case MEC_ESPI_CAP_ID_FC:
744 cap = get_espi_fc_cap(iobase);
745 break;
746 default:
747 break;
748 }
749
750 return cap;
751 }
752
753 /* end mec_espi.c */
754