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_pcr_api.h"
14 #include "mec_mailbox_api.h"
15 #include "mec_retval.h"
16
17 #define MEC_MBOX_GIRQ 15
18 #define MEC_MBOX_GIRQ_POS 20
19
20 #define MEC_MBOX0_ECIA_INFO MEC5_ECIA_INFO(15, 20, 7, 60)
21
22 /* Each mailbox device implements 32 8-bit mailboxes */
23 #define MEC_MBOX_MAX_INDEX 31
24
25 struct mec_mbox_info {
26 uint32_t base_addr;
27 uint32_t devi;
28 uint16_t pcr_id;
29 };
30
31 static const struct mec_mbox_info mbox_instances[MEC5_MAILBOX_INSTANCES] = {
32 { MEC_MBOX0_BASE, MEC_MBOX0_ECIA_INFO, MEC_PCR_MBOX0 },
33 };
34
find_mbox_info(uint32_t base_addr)35 static struct mec_mbox_info const *find_mbox_info(uint32_t base_addr)
36 {
37 for (size_t i = 0; i < MEC5_MAILBOX_INSTANCES; i++) {
38 if (base_addr == mbox_instances[i].base_addr) {
39 return &mbox_instances[i];
40 }
41 }
42
43 return NULL;
44 }
45
46
47 /* ---- Public API ---- */
48
mec_hal_mbox_init(struct mec_mbox_regs * base,uint32_t swi_ien_msk,uint32_t flags)49 int mec_hal_mbox_init(struct mec_mbox_regs *base, uint32_t swi_ien_msk, uint32_t flags)
50 {
51 const struct mec_mbox_info *mbi = find_mbox_info((uint32_t)base);
52
53 if (!mbi) {
54 return MEC_RET_ERR_INVAL;
55 }
56
57 struct mec_mbox_regs *const regs = (struct mec_mbox_regs *)mbi->base_addr;
58
59 mec_hal_pcr_clr_blk_slp_en(mbi->pcr_id);
60 mec_hal_girq_ctrl(mbi->devi, 0);
61
62 if (flags & MEC_MBOX_FLAG_RESET) {
63 mec_hal_pcr_blk_reset(mbi->pcr_id);
64 } else {
65 regs->H2EC = 0xffu; /* clear EC MBOX interrupt status */
66 }
67
68 mec_hal_girq_clr_src(mbi->devi);
69
70 regs->ECSMIM = (uint8_t)(swi_ien_msk & 0xffu);
71
72 if (flags & MEC_MBOX_FLAG_INTR_EN) {
73 mec_hal_girq_ctrl(mbi->devi, 1);
74 }
75
76 return MEC_RET_OK;
77 }
78
mec_hal_mbox_girq_ctrl(struct mec_mbox_regs * base,uint8_t enable)79 int mec_hal_mbox_girq_ctrl(struct mec_mbox_regs *base, uint8_t enable)
80 {
81 const struct mec_mbox_info *mbi = find_mbox_info((uint32_t)base);
82
83 if (!mbi) {
84 return MEC_RET_ERR_INVAL;
85 }
86
87 mec_hal_girq_ctrl(mbi->devi, enable);
88
89 return MEC_RET_OK;
90 }
91
mec_hal_mbox_girq_clr(struct mec_mbox_regs * base)92 int mec_hal_mbox_girq_clr(struct mec_mbox_regs *base)
93 {
94 const struct mec_mbox_info *mbi = find_mbox_info((uint32_t)base);
95
96 if (!mbi) {
97 return MEC_RET_ERR_INVAL;
98 }
99
100 mec_hal_girq_clr_src(mbi->devi);
101
102 return MEC_RET_OK;
103 }
104
mec_hal_mbox_girq_result(struct mec_mbox_regs * base)105 uint32_t mec_hal_mbox_girq_result(struct mec_mbox_regs *base)
106 {
107 const struct mec_mbox_info *mbi = find_mbox_info((uint32_t)base);
108
109 if (!mbi) {
110 return 0;
111 }
112
113 return mec_hal_girq_result(mbi->devi);
114 }
115
mec_hal_mbox_sirq_set(struct mec_mbox_regs * base,uint8_t bitmap)116 int mec_hal_mbox_sirq_set(struct mec_mbox_regs *base, uint8_t bitmap)
117 {
118 if (!base) {
119 return MEC_RET_ERR_INVAL;
120 }
121
122 if (bitmap) {
123 base->ECSMIT |= bitmap;
124 }
125
126 return MEC_RET_OK;
127 }
128
mec_hal_mbox_sirq_en_mask(struct mec_mbox_regs * base,uint8_t val,uint8_t mask)129 int mec_hal_mbox_sirq_en_mask(struct mec_mbox_regs *base, uint8_t val, uint8_t mask)
130 {
131 if (!base) {
132 return MEC_RET_ERR_INVAL;
133 }
134
135 if (mask) {
136 base->ECSMIM = (base->ECSMIM & ~mask) | (val & mask);
137 }
138
139 return MEC_RET_OK;
140 }
141
mec_hal_mbox_get_host_to_ec(struct mec_mbox_regs * base,uint8_t * data)142 int mec_hal_mbox_get_host_to_ec(struct mec_mbox_regs *base, uint8_t *data)
143 {
144 if (!base) {
145 return MEC_RET_ERR_INVAL;
146 }
147
148 uint8_t host_to_ec = base->H2EC;
149
150 if (data) {
151 *data = host_to_ec;
152 }
153
154 return MEC_RET_OK;
155 }
156
mec_hal_mbox_set_host_to_ec(struct mec_mbox_regs * base,uint8_t data)157 int mec_hal_mbox_set_host_to_ec(struct mec_mbox_regs *base, uint8_t data)
158 {
159 if (!base) {
160 return MEC_RET_ERR_INVAL;
161 }
162
163 base->H2EC = data;
164
165 return MEC_RET_OK;
166 }
167
mec_hal_mbox_get_ec_to_host(struct mec_mbox_regs * base,uint8_t * data)168 int mec_hal_mbox_get_ec_to_host(struct mec_mbox_regs *base, uint8_t *data)
169 {
170 if (!base) {
171 return MEC_RET_ERR_INVAL;
172 }
173
174 uint8_t ec_to_host = base->EC2H;
175
176 if (data) {
177 *data = ec_to_host;
178 }
179
180 return MEC_RET_OK;
181 }
182
mec_hal_mbox_set_ec_to_host(struct mec_mbox_regs * base,uint8_t data)183 int mec_hal_mbox_set_ec_to_host(struct mec_mbox_regs *base, uint8_t data)
184 {
185 if (!base) {
186 return MEC_RET_ERR_INVAL;
187 }
188
189 base->EC2H = data;
190
191 return MEC_RET_OK;
192 }
193
mec_hal_mbox_get(struct mec_mbox_regs * base,uint8_t mbox,uint8_t * data)194 int mec_hal_mbox_get(struct mec_mbox_regs *base, uint8_t mbox, uint8_t *data)
195 {
196 if (!base || (mbox > MEC_MBOX_MAX_INDEX) || !data) {
197 return MEC_RET_ERR_INVAL;
198 }
199
200 volatile uint8_t *p = (volatile uint8_t *)&base->MBOXD[0];
201
202 *data = p[mbox];
203
204 return MEC_RET_OK;
205 }
206
mec_hal_mbox_put(struct mec_mbox_regs * base,uint8_t mbox,uint8_t data)207 int mec_hal_mbox_put(struct mec_mbox_regs *base, uint8_t mbox, uint8_t data)
208 {
209 if (!base || (mbox > MEC_MBOX_MAX_INDEX)) {
210 return MEC_RET_ERR_INVAL;
211 }
212
213 volatile uint8_t *p = (volatile uint8_t *)&base->MBOXD[0];
214
215 p[mbox] = data;
216
217 return MEC_RET_OK;
218 }
219
220 /* 32 8-bit mailboxes are grouped as 8 32-bit registers */
mec_hal_mbox32_get(struct mec_mbox_regs * base,uint8_t mbox,uint32_t * data)221 int mec_hal_mbox32_get(struct mec_mbox_regs *base, uint8_t mbox, uint32_t *data)
222 {
223 if (!base || (mbox > (MEC_MBOX_MAX_INDEX / 4)) || !data) {
224 return MEC_RET_ERR_INVAL;
225 }
226
227 *data = base->MBOXD[mbox];
228
229 return MEC_RET_OK;
230 }
231
mec_hal_mbox32_put(struct mec_mbox_regs * base,uint8_t mbox,uint32_t data)232 int mec_hal_mbox32_put(struct mec_mbox_regs *base, uint8_t mbox, uint32_t data)
233 {
234 if (!base || (mbox > (MEC_MBOX_MAX_INDEX / 4))) {
235 return MEC_RET_ERR_INVAL;
236 }
237
238 base->MBOXD[mbox] = data;
239
240 return MEC_RET_OK;
241 }
242
243 /* end mec_mailbox.c */
244