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_pcfg.h"
11 #include "mec_defs.h"
12 #include "mec_acpi_ec_api.h"
13 #include "mec_ecia_api.h"
14 #include "mec_espi_api.h"
15 #include "mec_pcr_api.h"
16 #include "mec_retval.h"
17
18 #define MEC_ACPI_EC_GIRQ 15
19
20 #define MEC_ACPI_EC0_IBF_GIRQ_POS 5
21 #define MEC_ACPI_EC0_OBE_GIRQ_POS 6
22 #define MEC_ACPI_EC1_IBF_GIRQ_POS 7
23 #define MEC_ACPI_EC1_OBE_GIRQ_POS 8
24 #define MEC_ACPI_EC2_IBF_GIRQ_POS 9
25 #define MEC_ACPI_EC2_OBE_GIRQ_POS 10
26 #define MEC_ACPI_EC3_IBF_GIRQ_POS 11
27 #define MEC_ACPI_EC3_OBE_GIRQ_POS 12
28 #define MEC_ACPI_EC4_IBF_GIRQ_POS 13
29 #define MEC_ACPI_EC4_OBE_GIRQ_POS 14
30
31 #define MEC_ACPI_EC0_IBF_ECIA_INFO MEC5_ECIA_INFO(15, 5, 7, 45)
32 #define MEC_ACPI_EC0_OBE_ECIA_INFO MEC5_ECIA_INFO(15, 6, 7, 46)
33 #define MEC_ACPI_EC1_IBF_ECIA_INFO MEC5_ECIA_INFO(15, 7, 7, 47)
34 #define MEC_ACPI_EC1_OBE_ECIA_INFO MEC5_ECIA_INFO(15, 8, 7, 48)
35 #define MEC_ACPI_EC2_IBF_ECIA_INFO MEC5_ECIA_INFO(15, 9, 7, 49)
36 #define MEC_ACPI_EC2_OBE_ECIA_INFO MEC5_ECIA_INFO(15, 10, 7, 50)
37 #define MEC_ACPI_EC3_IBF_ECIA_INFO MEC5_ECIA_INFO(15, 11, 7, 51)
38 #define MEC_ACPI_EC3_OBE_ECIA_INFO MEC5_ECIA_INFO(15, 12, 7, 52)
39 #define MEC_ACPI_EC4_IBF_ECIA_INFO MEC5_ECIA_INFO(15, 13, 7, 53)
40 #define MEC_ACPI_EC4_OBE_ECIA_INFO MEC5_ECIA_INFO(15, 14, 7, 54)
41
42 #define MEC_ACPI_EC_IBF_DEVI_IDX 0
43 #define MEC_ACPI_EC_OBE_DEVI_IDX 1
44
45 /* Hardware has a mode where each ACPI EC's IBF and OBE interrupt signal are
46 * OR'd together and connected to the NVIC bypassing the aggregator (GIRQ)
47 * hardware. Each ISR would determine IBF/OBE by looking at the ACPI EC
48 * status register.
49 */
50 #define MEC_ACPI_EC0_NVIC_NUM 175
51 #define MEC_ACPI_EC1_NVIC_NUM 176
52 #define MEC_ACPI_EC2_NVIC_NUM 177
53 #define MEC_ACPI_EC3_NVIC_NUM 178
54 #define MEC_ACPI_EC4_NVIC_NUM 179
55
56 #define MEC_ACPI_EC_STS_RW_MSK (MEC_BIT(2) | MEC_BIT(4) | MEC_BIT(5) | MEC_BIT(6) | MEC_BIT(7))
57 #define MEC_ACPI_EC_STS_RO_MSK (MEC_BIT(0) | MEC_BIT(1) | MEC_BIT(3))
58
59 struct mec_acpi_ec_info {
60 uintptr_t base_addr;
61 uint16_t pcr_id;
62 uint8_t ldn;
63 uint32_t devi[MEC_ACPI_EC_NUM_IRQS];
64 };
65
66 static const struct mec_acpi_ec_info acpi_ec_instances[] = {
67 { MEC_ACPI_EC0_BASE, MEC_PCR_ACPI_EC0, MEC_ESPI_LDN_ACPI_EC0,
68 {MEC_ACPI_EC0_IBF_ECIA_INFO, MEC_ACPI_EC0_OBE_ECIA_INFO} },
69 { MEC_ACPI_EC1_BASE, MEC_PCR_ACPI_EC1, MEC_ESPI_LDN_ACPI_EC1,
70 {MEC_ACPI_EC1_IBF_ECIA_INFO, MEC_ACPI_EC1_OBE_ECIA_INFO} },
71 { MEC_ACPI_EC2_BASE, MEC_PCR_ACPI_EC2, MEC_ESPI_LDN_ACPI_EC2,
72 {MEC_ACPI_EC2_IBF_ECIA_INFO, MEC_ACPI_EC2_OBE_ECIA_INFO} },
73 { MEC_ACPI_EC3_BASE, MEC_PCR_ACPI_EC3, MEC_ESPI_LDN_ACPI_EC3,
74 {MEC_ACPI_EC3_IBF_ECIA_INFO, MEC_ACPI_EC3_OBE_ECIA_INFO} },
75 { MEC_ACPI_EC4_BASE, MEC_PCR_ACPI_EC4, MEC_ESPI_LDN_ACPI_EC4,
76 {MEC_ACPI_EC4_IBF_ECIA_INFO, MEC_ACPI_EC4_OBE_ECIA_INFO} },
77 };
78 #define NUM_ACPI_EC_INSTANCES \
79 (sizeof(acpi_ec_instances) / sizeof(struct mec_acpi_ec_info))
80
find_acpi_ec_info(uintptr_t base_addr)81 static struct mec_acpi_ec_info const *find_acpi_ec_info(uintptr_t base_addr)
82 {
83 for (size_t i = 0; i < NUM_ACPI_EC_INSTANCES; i++) {
84 if (base_addr == acpi_ec_instances[i].base_addr) {
85 return &acpi_ec_instances[i];
86 }
87 }
88
89 return NULL;
90 }
91
92 /* ---- Public API ---- */
93
94 /* Initialize an ACPI EC controller.
95 * This peripheral is reset by chip reset (RESET_SYS).
96 * The Host I/O and Memory BAR's in the eSPI I/O component are reset by
97 * RESET_VCC and RESET_HOST (PCI_RESET# or PLTRST#).
98 */
mec_hal_acpi_ec_init(struct mec_acpi_ec_regs * regs,uint32_t flags)99 int mec_hal_acpi_ec_init(struct mec_acpi_ec_regs *regs, uint32_t flags)
100 {
101 const struct mec_acpi_ec_info *info = find_acpi_ec_info((uintptr_t)regs);
102
103 #ifdef MEC_ACPI_EC_BASE_CHECK
104 if (!info) {
105 return MEC_RET_ERR_INVAL;
106 }
107 #endif
108
109 mec_hal_acpi_ec_girq_dis(regs, MEC_ACPI_EC_IBF_IRQ | MEC_ACPI_EC_OBE_IRQ);
110 mec_hal_pcr_clr_blk_slp_en(info->pcr_id);
111 if (flags & MEC_ACPI_EC_RESET) {
112 mec_hal_pcr_blk_reset(info->pcr_id);
113 } else { /* clear IBF and OBE status */
114 regs->AEC_H2E_DATA;
115 }
116
117 mec_hal_acpi_ec_girq_clr(regs, MEC_ACPI_EC_IBF_IRQ | MEC_ACPI_EC_OBE_IRQ);
118
119 if (flags & MEC_ACPI_EC_4BYTE_MODE) {
120 regs->AEC_BYTE_CTRL |= MEC_BIT(MEC_ACPI_EC_AEC_BYTE_CTRL_FOUR_BYTE_MODE_Pos);
121 } else {
122 regs->AEC_BYTE_CTRL &= (uint8_t)~MEC_BIT(MEC_ACPI_EC_AEC_BYTE_CTRL_FOUR_BYTE_MODE_Pos);
123 }
124
125 if (flags & MEC_ACPI_EC_UD0A_SET) {
126 if (flags & MEC_ACPI_EC_UD0A_ONE) {
127 regs->AEC_STATUS |= MEC_BIT(MEC_ACPI_EC_AEC_STATUS_UD0A_Pos);
128 } else {
129 regs->AEC_STATUS &= (uint8_t)~MEC_BIT(MEC_ACPI_EC_AEC_STATUS_UD0A_Pos);
130 }
131 }
132
133 if (flags & MEC_ACPI_EC_UD1A_SET) {
134 if (flags & MEC_ACPI_EC_UD1A_ONE) {
135 regs->AEC_STATUS |= MEC_BIT(MEC_ACPI_EC_AEC_STATUS_UD1A_Pos);
136 } else {
137 regs->AEC_STATUS &= (uint8_t)~MEC_BIT(MEC_ACPI_EC_AEC_STATUS_UD1A_Pos);
138 }
139 }
140
141 mec_hal_acpi_ec_girq_dis(regs, flags);
142
143 return MEC_RET_OK;
144 }
145
acpi_ec_irq_bitmap(const struct mec_acpi_ec_info * info,uint32_t flags)146 static uint32_t acpi_ec_irq_bitmap(const struct mec_acpi_ec_info *info, uint32_t flags)
147 {
148 uint32_t bm = 0;
149
150 if (flags & MEC_ACPI_EC_IBF_IRQ) {
151 bm |= MEC_BIT(MEC5_ECIA_INFO_GIRQ_POS(info->devi[MEC_ACPI_EC_IBF_DEVI_IDX]));
152 }
153
154 if (flags & MEC_ACPI_EC_OBE_IRQ) {
155 bm |= MEC_BIT(MEC5_ECIA_INFO_GIRQ_POS(info->devi[MEC_ACPI_EC_OBE_DEVI_IDX]));
156 }
157
158 return bm;
159 }
160
mec_hal_acpi_ec_girq_en(struct mec_acpi_ec_regs * regs,uint32_t flags)161 int mec_hal_acpi_ec_girq_en(struct mec_acpi_ec_regs *regs, uint32_t flags)
162 {
163 const struct mec_acpi_ec_info *info = find_acpi_ec_info((uintptr_t)regs);
164 uint32_t bitmap = 0;
165
166 #ifdef MEC_ACPI_EC_BASE_CHECK
167 if (!info) {
168 return MEC_RET_ERR_INVAL;
169 }
170 #endif
171
172 bitmap = acpi_ec_irq_bitmap(info, flags);
173 mec_hal_girq_bm_en(MEC_ACPI_EC_GIRQ, bitmap, 1u);
174
175 return MEC_RET_OK;
176 }
177
mec_hal_acpi_ec_girq_dis(struct mec_acpi_ec_regs * regs,uint32_t flags)178 int mec_hal_acpi_ec_girq_dis(struct mec_acpi_ec_regs *regs, uint32_t flags)
179 {
180 const struct mec_acpi_ec_info *info = find_acpi_ec_info((uintptr_t)regs);
181 uint32_t bitmap = 0;
182
183 #ifdef MEC_ACPI_EC_BASE_CHECK
184 if (!info) {
185 return MEC_RET_ERR_INVAL;
186 }
187 #endif
188 bitmap = acpi_ec_irq_bitmap(info, flags);
189 mec_hal_girq_bm_en(MEC_ACPI_EC_GIRQ, bitmap, 0);
190
191 return MEC_RET_OK;
192 }
193
mec_hal_acpi_ec_girq_clr(struct mec_acpi_ec_regs * regs,uint32_t flags)194 int mec_hal_acpi_ec_girq_clr(struct mec_acpi_ec_regs *regs, uint32_t flags)
195 {
196 const struct mec_acpi_ec_info *info = find_acpi_ec_info((uintptr_t)regs);
197
198 #ifdef MEC_ACPI_EC_BASE_CHECK
199 if (!info) {
200 return MEC_RET_ERR_INVAL;
201 }
202 #endif
203 uint32_t clr_bitmap = acpi_ec_irq_bitmap(info, flags);
204
205 mec_hal_girq_bm_clr_src(MEC_ACPI_EC_GIRQ, clr_bitmap);
206
207 return MEC_RET_OK;
208 }
209
mec_hal_acpi_ec_girq_result(struct mec_acpi_ec_regs * regs)210 uint32_t mec_hal_acpi_ec_girq_result(struct mec_acpi_ec_regs *regs)
211 {
212 const struct mec_acpi_ec_info *info = find_acpi_ec_info((uintptr_t)regs);
213 uint32_t temp = 0u, result = 0u, ibf_bit = 0, obe_bit = 0;
214
215 #ifdef MEC_ACPI_EC_BASE_CHECK
216 if (!info) {
217 return result;
218 }
219 #endif
220
221 ibf_bit = MEC5_ECIA_INFO_GIRQ_POS(info->devi[MEC_ACPI_EC_IBF_DEVI_IDX]);
222 obe_bit = MEC5_ECIA_INFO_GIRQ_POS(info->devi[MEC_ACPI_EC_OBE_DEVI_IDX]);
223 temp = mec_hal_girq_result_get(MEC_ACPI_EC_GIRQ);
224 if (temp & MEC_BIT(ibf_bit)) {
225 result |= MEC_ACPI_EC_IBF_IRQ;
226 }
227 if (temp & MEC_BIT(obe_bit)) {
228 result |= MEC_ACPI_EC_OBE_IRQ;
229 }
230
231 return result;
232 }
233
234 /* ACPI EC has no block enable. Check the eSPI BARs? If either of the I/O or Mem
235 * BAR is enabled then report enabled.
236 */
mec_hal_acpi_ec_is_enabled(struct mec_acpi_ec_regs * regs)237 int mec_hal_acpi_ec_is_enabled(struct mec_acpi_ec_regs *regs)
238 {
239 struct mec_espi_io_regs *espi_io_base = (struct mec_espi_io_regs *)MEC_ESPI_IO_BASE;
240 struct mec_espi_mem_regs *espi_mem_base = (struct mec_espi_mem_regs *)MEC_ESPI_MEM_BASE;
241 const struct mec_acpi_ec_info *info = find_acpi_ec_info((uintptr_t)regs);
242
243 #ifdef MEC_ACPI_EC_BASE_CHECK
244 if (!info) {
245 return 0;
246 }
247 #endif
248
249 if (mec_hal_espi_iobar_is_enabled(espi_io_base, info->ldn)) {
250 return 1;
251 }
252
253 if (mec_hal_espi_mbar_is_enabled(espi_mem_base, info->ldn)) {
254 return 1;
255 }
256
257 return 0;
258 }
259
mec_hal_acpi_ec_is_4byte_mode(struct mec_acpi_ec_regs * regs)260 int mec_hal_acpi_ec_is_4byte_mode(struct mec_acpi_ec_regs *regs)
261 {
262 #ifdef MEC_ACPI_EC_BASE_CHECK
263 if (!regs) {
264 return 0u;
265 }
266 #endif
267 if (regs && (regs->AEC_BYTE_CTRL & MEC_BIT(MEC_ACPI_EC_AEC_BYTE_CTRL_FOUR_BYTE_MODE_Pos))) {
268 return 1;
269 }
270
271 return 0;
272 }
273
mec_hal_acpi_ec_status(struct mec_acpi_ec_regs * regs)274 uint8_t mec_hal_acpi_ec_status(struct mec_acpi_ec_regs *regs)
275 {
276 #ifdef MEC_ACPI_EC_BASE_CHECK
277 if (!regs) {
278 return 0u;
279 }
280 #endif
281 return regs->AEC_STATUS;
282 }
283
mec_hal_acpi_ec_status_wr(struct mec_acpi_ec_regs * regs,uint8_t val)284 void mec_hal_acpi_ec_status_wr(struct mec_acpi_ec_regs *regs, uint8_t val)
285 {
286 #ifdef MEC_ACPI_EC_BASE_CHECK
287 if (!regs) {
288 return;
289 }
290 #endif
291 regs->AEC_STATUS = val;
292 }
293
mec_hal_acpi_ec_status_set(struct mec_acpi_ec_regs * regs,uint8_t val)294 void mec_hal_acpi_ec_status_set(struct mec_acpi_ec_regs *regs, uint8_t val)
295 {
296 #ifdef MEC_ACPI_EC_BASE_CHECK
297 if (!regs) {
298 return;
299 }
300 #endif
301 regs->AEC_STATUS |= val;
302 }
303
mec_hal_acpi_ec_status_mask(struct mec_acpi_ec_regs * regs,uint8_t val,uint8_t msk)304 void mec_hal_acpi_ec_status_mask(struct mec_acpi_ec_regs *regs, uint8_t val, uint8_t msk)
305 {
306 #ifdef MEC_ACPI_EC_BASE_CHECK
307 if (!regs) {
308 return;
309 }
310 #endif
311 regs->AEC_STATUS = (regs->AEC_STATUS & ~msk) | (val & msk);
312 }
313
mec_hal_acpi_ec_status_obf(struct mec_acpi_ec_regs * regs)314 uint8_t mec_hal_acpi_ec_status_obf(struct mec_acpi_ec_regs *regs)
315 {
316 #ifdef MEC_ACPI_EC_BASE_CHECK
317 if (!regs) {
318 return 0;
319 }
320 #endif
321 return (regs->AEC_STATUS & MEC_ACPI_EC_AEC_STATUS_OBF_Msk) >> MEC_ACPI_EC_AEC_STATUS_OBF_Pos;
322 }
323
mec_hal_acpi_ec_status_ibf(struct mec_acpi_ec_regs * regs)324 uint8_t mec_hal_acpi_ec_status_ibf(struct mec_acpi_ec_regs *regs)
325 {
326 #ifdef MEC_ACPI_EC_BASE_CHECK
327 if (!regs) {
328 return 0;
329 }
330 #endif
331 return (regs->AEC_STATUS & MEC_ACPI_EC_AEC_STATUS_IBF_Msk) >> MEC_ACPI_EC_AEC_STATUS_IBF_Pos;
332 }
333
mec_hal_acpi_ec_host_to_ec_data_rd32(struct mec_acpi_ec_regs * regs)334 uint32_t mec_hal_acpi_ec_host_to_ec_data_rd32(struct mec_acpi_ec_regs *regs)
335 {
336 #ifdef MEC_ACPI_EC_BASE_CHECK
337 if (!regs) {
338 return 0;
339 }
340 #endif
341 return regs->AEC_H2E_DATA; /* defined as 32-bit register */
342 }
343
mec_hal_acpi_ec_host_to_ec_data_wr32(struct mec_acpi_ec_regs * regs,uint32_t data)344 void mec_hal_acpi_ec_host_to_ec_data_wr32(struct mec_acpi_ec_regs *regs, uint32_t data)
345 {
346 #ifdef MEC_ACPI_EC_BASE_CHECK
347 if (!regs) {
348 return;
349 }
350 #endif
351 regs->AEC_H2E_DATA = data;
352 }
353
mec_hal_acpi_ec_host_to_ec_data_rd8(struct mec_acpi_ec_regs * regs,uint8_t offset)354 uint8_t mec_hal_acpi_ec_host_to_ec_data_rd8(struct mec_acpi_ec_regs *regs, uint8_t offset)
355 {
356 #ifdef MEC_ACPI_EC_BASE_CHECK
357 if (!regs) {
358 return 0u;
359 }
360 #endif
361 uint32_t addr = (uint32_t)®s->AEC_H2E_DATA + (uint32_t)(offset & 0x3u);
362
363 return MEC_MMCR8(addr);
364 }
365
mec_hal_acpi_ec_host_to_ec_data_wr8(struct mec_acpi_ec_regs * regs,uint8_t offset,uint8_t data)366 void mec_hal_acpi_ec_host_to_ec_data_wr8(struct mec_acpi_ec_regs *regs, uint8_t offset,
367 uint8_t data)
368 {
369 #ifdef MEC_ACPI_EC_BASE_CHECK
370 if (!regs) {
371 return;
372 }
373 #endif
374 uint32_t addr = (uint32_t)®s->AEC_H2E_DATA + (uint32_t)(offset & 0x3u);
375
376 MEC_MMCR8(addr) = data;
377 }
378
379 /* --- */
mec_hal_acpi_ec_e2h_data_rd32(struct mec_acpi_ec_regs * regs)380 uint32_t mec_hal_acpi_ec_e2h_data_rd32(struct mec_acpi_ec_regs *regs)
381 {
382 #ifdef MEC_ACPI_EC_BASE_CHECK
383 if (!regs) {
384 return 0;
385 }
386 #endif
387 return regs->AEC_E2H_DATA; /* defined as 32-bit register */
388 }
389
mec_hal_acpi_ec_e2h_to_ec_data_wr32(struct mec_acpi_ec_regs * regs,uint32_t data)390 void mec_hal_acpi_ec_e2h_to_ec_data_wr32(struct mec_acpi_ec_regs *regs, uint32_t data)
391 {
392 #ifdef MEC_ACPI_EC_BASE_CHECK
393 if (!regs) {
394 return;
395 }
396 #endif
397 regs->AEC_E2H_DATA = data;
398 }
399
mec_hal_acpi_ec_e2h_data_rd8(struct mec_acpi_ec_regs * regs,uint8_t offset)400 uint8_t mec_hal_acpi_ec_e2h_data_rd8(struct mec_acpi_ec_regs *regs, uint8_t offset)
401 {
402 #ifdef MEC_ACPI_EC_BASE_CHECK
403 if (!regs) {
404 return 0u;
405 }
406 #endif
407 uint32_t addr = (uint32_t)®s->AEC_E2H_DATA + (uint32_t)(offset & 0x3u);
408
409 return MEC_MMCR8(addr);
410 }
411
mec_hal_acpi_ec_e2h_data_wr8(struct mec_acpi_ec_regs * regs,uint8_t offset,uint8_t data)412 void mec_hal_acpi_ec_e2h_data_wr8(struct mec_acpi_ec_regs *regs, uint8_t offset, uint8_t data)
413 {
414 #ifdef MEC_ACPI_EC_BASE_CHECK
415 if (!regs) {
416 return;
417 }
418 #endif
419 uint32_t addr = (uint32_t)®s->AEC_E2H_DATA + (uint32_t)(offset & 0x3u);
420
421 MEC_MMCR8(addr) = data;
422 }
423
424 /* end mec_acpi_ec.c */
425