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