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