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_ecia_api.h"
13 #include "mec_espi_api.h"
14 #include "mec_retval.h"
15
16 /* ---- eSPI Peripheral Channel ---- */
17 #define MEC_ESPI_PC_ECIA_INFO MEC5_ECIA_INFO(19, 0, 11, 103)
18 #define MEC_ESPI_LTR_ECIA_INFO MEC5_ECIA_INFO(19, 3, 11, 106)
19
xlat_intr_to_hw(uint32_t bitmap)20 static uint32_t xlat_intr_to_hw(uint32_t bitmap)
21 {
22 uint32_t hwbm = 0;
23
24 if (bitmap & MEC_BIT(MEC_ESPI_PC_INTR_CHEN_CHG_POS)) {
25 hwbm |= MEC_BIT(MEC_ESPI_IO_PCSTS_PCEN_CHG_Pos);
26 }
27
28 if (bitmap & MEC_BIT(MEC_ESPI_PC_INTR_BMEN_CHG_POS)) {
29 hwbm |= MEC_BIT(MEC_ESPI_IO_PCSTS_PCBMEN_CHG_Pos);
30 }
31
32 if (bitmap & MEC_BIT(MEC_ESPI_PC_INTR_BERR_POS)) {
33 hwbm |= MEC_BIT(MEC_ESPI_IO_PCSTS_EC_BUS_ERR_Pos);
34 }
35
36 return hwbm;
37 }
38
39 /* ---- Public API ---- */
40
mec_hal_espi_pc_ready_set(struct mec_espi_io_regs * iobase)41 void mec_hal_espi_pc_ready_set(struct mec_espi_io_regs *iobase)
42 {
43 iobase->PCRDY = MEC_BIT(MEC_ESPI_IO_PCRDY_PC_READY_Pos);
44 }
45
mec_hal_espi_pc_is_ready(struct mec_espi_io_regs * iobase)46 int mec_hal_espi_pc_is_ready(struct mec_espi_io_regs *iobase)
47 {
48 if (iobase->PCRDY & MEC_BIT(MEC_ESPI_IO_PCRDY_PC_READY_Pos)) {
49 return 1u;
50 }
51
52 return 0;
53 }
54
55 /* Peripheral channel enable state is status register bit[24]; move to bit[0].
56 * Enable change is status register bit[25]; move to bit[1].
57 */
mec_hal_espi_pc_en_status(struct mec_espi_io_regs * iobase)58 uint32_t mec_hal_espi_pc_en_status(struct mec_espi_io_regs *iobase)
59 {
60 uint32_t temp = iobase->PCSTS & (MEC_ESPI_IO_PCSTS_PCEN_VAL_Msk
61 | MEC_ESPI_IO_PCSTS_PCEN_CHG_Msk);
62
63 return (temp >> MEC_ESPI_IO_PCSTS_PCEN_VAL_Pos);
64 }
65
66 /* Peripheral channel bus master enable state is status register bit[27]; move to bit[0].
67 * BM enable change is bit[28]; move to bit[1].
68 * the enable's current state.
69 */
mec_hal_espi_pc_bm_status(struct mec_espi_io_regs * iobase)70 uint32_t mec_hal_espi_pc_bm_status(struct mec_espi_io_regs *iobase)
71 {
72 uint32_t temp = iobase->PCSTS & (MEC_ESPI_IO_PCSTS_PCBM_VAL_Msk
73 | MEC_ESPI_IO_PCSTS_PCBMEN_CHG_Msk);
74
75 return (temp >> MEC_ESPI_IO_PCSTS_PCBM_VAL_Pos);
76 }
77
mec_hal_espi_pc_status(struct mec_espi_io_regs * iobase)78 uint32_t mec_hal_espi_pc_status(struct mec_espi_io_regs *iobase)
79 {
80 uint32_t sts = 0;
81 uint32_t temp = iobase->PCSTS;
82
83 if (temp & MEC_BIT(MEC_ESPI_IO_PCSTS_EC_BUS_ERR_Pos)) {
84 sts |= MEC_BIT(MEC_ESPI_PC_ISTS_BERR_POS);
85 }
86 if (temp & MEC_BIT(MEC_ESPI_IO_PCSTS_PCEN_VAL_Pos)) {
87 sts |= MEC_BIT(MEC_ESPI_PC_ISTS_CHEN_CHG_POS);
88 }
89 if (temp & MEC_BIT(MEC_ESPI_IO_PCSTS_PCEN_CHG_Pos)) {
90 sts |= MEC_BIT(MEC_ESPI_PC_ISTS_CHEN_STATE_POS);
91 }
92 if (temp & MEC_BIT(MEC_ESPI_IO_PCSTS_PCBM_VAL_Pos)) {
93 sts |= MEC_BIT(MEC_ESPI_PC_ISTS_BMEN_STATE_POS);
94 }
95 if (temp & MEC_BIT(MEC_ESPI_IO_PCSTS_PCBMEN_CHG_Pos)) {
96 sts |= MEC_BIT(MEC_ESPI_PC_ISTS_BMEN_CHG_POS);
97 }
98
99 return sts;
100 }
101
mec_hal_espi_pc_status_clr(struct mec_espi_io_regs * iobase,uint32_t bitmap)102 void mec_hal_espi_pc_status_clr(struct mec_espi_io_regs *iobase, uint32_t bitmap)
103 {
104 uint32_t regval = 0;
105
106 regval = xlat_intr_to_hw(bitmap);
107 iobase->PCSTS = regval;
108 }
109
mec_hal_espi_pc_intr_en(struct mec_espi_io_regs * iobase,uint32_t bitmap)110 void mec_hal_espi_pc_intr_en(struct mec_espi_io_regs *iobase, uint32_t bitmap)
111 {
112 uint32_t regval = 0;
113
114 regval = xlat_intr_to_hw(bitmap);
115 iobase->PCIEN |= regval;
116 }
117
mec_hal_espi_pc_intr_dis(struct mec_espi_io_regs * iobase,uint32_t bitmap)118 void mec_hal_espi_pc_intr_dis(struct mec_espi_io_regs *iobase, uint32_t bitmap)
119 {
120 uint32_t regval = 0;
121
122 regval = xlat_intr_to_hw(bitmap);
123 iobase->PCIEN &= ~regval;
124 }
125
mec_hal_espi_pc_status_clr_all(struct mec_espi_io_regs * iobase)126 void mec_hal_espi_pc_status_clr_all(struct mec_espi_io_regs *iobase)
127 {
128 iobase->PCSTS = (MEC_ESPI_IO_PCSTS_EC_BUS_ERR_Msk
129 | MEC_ESPI_IO_PCSTS_PCEN_CHG_Msk
130 | MEC_ESPI_IO_PCSTS_PCBMEN_CHG_Msk);
131 }
132
mec_hal_espi_pc_error_addr(struct mec_espi_io_regs * iobase)133 uint64_t mec_hal_espi_pc_error_addr(struct mec_espi_io_regs *iobase)
134 {
135 union {
136 uint64_t lw;
137 uint32_t w[2];
138 } err_addr;
139
140 err_addr.w[0] = iobase->PCERR[0];
141 err_addr.w[1] = iobase->PCERR[1];
142
143 return err_addr.lw;
144 }
145
mec_hal_espi_pc_last_cycle(struct mec_espi_io_regs * iobase,struct mec_espi_pc_last_cycle * lc)146 void mec_hal_espi_pc_last_cycle(struct mec_espi_io_regs *iobase,
147 struct mec_espi_pc_last_cycle *lc)
148 {
149 uint32_t temp;
150
151 lc->host_pc_addr_lsw = iobase->PCLC[0];
152 lc->host_pc_addr_msw = iobase->PCLC[1];
153 temp = iobase->PCLC[2];
154 lc->len = (uint16_t)(temp & 0xfffu);
155 lc->cycle_type = (uint8_t)((temp >> 12) & 0xffu);
156 lc->tag = (uint8_t)((temp >> 20) & 0xfu);
157 }
158
159 /* PC GIRQ */
mec_hal_espi_pc_girq_ctrl(uint8_t enable)160 void mec_hal_espi_pc_girq_ctrl(uint8_t enable)
161 {
162 mec_hal_girq_ctrl(MEC_ESPI_PC_ECIA_INFO, (int)enable);
163 }
164
mec_hal_espi_pc_girq_status_clr(void)165 void mec_hal_espi_pc_girq_status_clr(void)
166 {
167 mec_hal_girq_clr_src(MEC_ESPI_PC_ECIA_INFO);
168 }
169
mec_hal_espi_pc_girq_status(void)170 uint32_t mec_hal_espi_pc_girq_status(void)
171 {
172 return mec_hal_girq_src(MEC_ESPI_PC_ECIA_INFO);
173 }
174
mec_hal_espi_pc_girq_result(void)175 uint32_t mec_hal_espi_pc_girq_result(void)
176 {
177 return mec_hal_girq_result(MEC_ESPI_PC_ECIA_INFO);
178 }
179
180 /* Peripheral Channel LTR */
181
mec_hal_espi_pc_ltr_status(struct mec_espi_io_regs * iobase)182 uint32_t mec_hal_espi_pc_ltr_status(struct mec_espi_io_regs *iobase)
183 {
184 return iobase->PCLTRSTS;
185 }
186
mec_hal_espi_pc_ltr_intr_en(struct mec_espi_io_regs * iobase,uint32_t enmask)187 void mec_hal_espi_pc_ltr_intr_en(struct mec_espi_io_regs *iobase, uint32_t enmask)
188 {
189 iobase->PCLTREN = enmask;
190 }
191
mec_hal_espi_pc_ltr_ctrl(struct mec_espi_io_regs * iobase,uint8_t tag,uint8_t start)192 void mec_hal_espi_pc_ltr_ctrl(struct mec_espi_io_regs *iobase, uint8_t tag, uint8_t start)
193 {
194 uint32_t ctrl = iobase->PCLTRCTL & (uint32_t)~(MEC_ESPI_IO_PCLTRCTL_LTR_TX_TAG_Msk);
195
196 ctrl |= (((uint32_t)tag << MEC_ESPI_IO_PCLTRCTL_LTR_TX_TAG_Pos)
197 & MEC_ESPI_IO_PCLTRCTL_LTR_TX_TAG_Msk);
198
199 iobase->PCLTRCTL = ctrl;
200
201 if (start) {
202 iobase->PCLTRCTL |= MEC_BIT(MEC_ESPI_IO_PCLTRCTL_START_Pos);
203 }
204 }
205
mec_hal_espi_pc_ltr_msg(struct mec_espi_io_regs * iobase,uint16_t nunits,uint8_t time_unit,uint8_t rsvd_bits,uint8_t max_lat)206 void mec_hal_espi_pc_ltr_msg(struct mec_espi_io_regs *iobase, uint16_t nunits, uint8_t time_unit,
207 uint8_t rsvd_bits, uint8_t max_lat)
208 {
209 uint32_t msg = (((uint32_t)nunits << MEC_ESPI_IO_PCLTRM_VALUE_Pos)
210 & MEC_ESPI_IO_PCLTRM_VALUE_Msk);
211
212 msg |= (((uint32_t)time_unit << MEC_ESPI_IO_PCLTRM_SCALE_Pos) & MEC_ESPI_IO_PCLTRM_SCALE_Msk);
213 msg |= (((uint32_t)rsvd_bits << MEC_ESPI_IO_PCLTRM_TX_RSVD_BITS_Pos)
214 & MEC_ESPI_IO_PCLTRM_TX_RSVD_BITS_Msk);
215 if (max_lat) {
216 msg |= MEC_BIT(MEC_ESPI_IO_PCLTRM_SEL_MAX_LAT_Pos);
217 }
218
219 iobase->PCLTRM = (iobase->PCLTRM & ~(0xffffu)) | msg;
220 }
221
mec_hal_espi_pc_ltr_girq_ctrl(uint8_t enable)222 void mec_hal_espi_pc_ltr_girq_ctrl(uint8_t enable)
223 {
224 mec_hal_girq_ctrl(MEC_ESPI_LTR_ECIA_INFO, (int)enable);
225 }
226
mec_hal_espi_pc_ltr_girq_status_clr(void)227 void mec_hal_espi_pc_ltr_girq_status_clr(void)
228 {
229 mec_hal_girq_clr_src(MEC_ESPI_LTR_ECIA_INFO);
230 }
231
mec_hal_espi_pc_ltr_girq_status(void)232 uint32_t mec_hal_espi_pc_ltr_girq_status(void)
233 {
234 return mec_hal_girq_src(MEC_ESPI_LTR_ECIA_INFO);
235 }
236
mec_hal_espi_pc_ltr_girq_result(void)237 uint32_t mec_hal_espi_pc_ltr_girq_result(void)
238 {
239 return mec_hal_girq_result(MEC_ESPI_LTR_ECIA_INFO);
240 }
241
242 /* end mec_espi_pc.c */
243