1/*
2 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6#include <stdlib.h>
7#include <string.h>
8
9#include <sel4vm/guest_vm.h>
10#include <sel4vmmplatsupport/device.h>
11#include <sel4vmmplatsupport/arch/ac_device.h>
12#include <sel4vmmplatsupport/plat/device_map.h>
13#include <sel4vmmplatsupport/plat/vclock.h>
14
15#define CLOCK_REG_DEFN(r, o, s, b) { .bank = CLKREGS_##r, .offset = o, .shift = s, .bits = b }
16#define CLK_DEFN(c) { .nregs = sizeof(c)/sizeof(*c), .regs = &c[0] }
17#define CLK_DEFN_NONE() { .nregs = 0, .regs = NULL }
18
19struct clock_reg {
20    int bank;
21    int offset;
22    int shift;
23    int bits;
24};
25
26struct clock_data {
27    int nregs;
28    struct clock_reg *regs;
29};
30
31struct clock_reg sclkmpll_data[] = {
32    CLOCK_REG_DEFN(CORE, 0x000, 0, 32), /* LOCK */
33    CLOCK_REG_DEFN(CORE, 0x100, 0, 32), /* CON0 */
34    CLOCK_REG_DEFN(CORE, 0x104, 0, 32), /* CON1 */
35};
36struct clock_reg sclkbpll_data[] = {
37    CLOCK_REG_DEFN(CDREX, 0x010, 0, 32), /* LOCK */
38    CLOCK_REG_DEFN(CDREX, 0x110, 0, 32), /* CON0 */
39    CLOCK_REG_DEFN(CDREX, 0x114, 0, 32), /* CON1 */
40};
41struct clock_reg sclkcpll_data[] = {
42    CLOCK_REG_DEFN(TOP, 0x020, 0, 32), /* LOCK */
43    CLOCK_REG_DEFN(TOP, 0x120, 0, 32), /* CON0 */
44    CLOCK_REG_DEFN(TOP, 0x124, 0, 32), /* CON1 */
45    CLOCK_REG_DEFN(TOP, 0x128, 0, 32), /* CON2 */
46};
47struct clock_reg sclkgpll_data[] = {
48    CLOCK_REG_DEFN(TOP, 0x050, 0, 32), /* LOCK */
49    CLOCK_REG_DEFN(TOP, 0x150, 0, 32), /* CON0 */
50    CLOCK_REG_DEFN(TOP, 0x154, 0, 32), /* CON1 */
51};
52struct clock_reg sclkepll_data[] = {
53    CLOCK_REG_DEFN(TOP, 0x030, 0, 32), /* LOCK */
54    CLOCK_REG_DEFN(TOP, 0x130, 0, 32), /* CON0 */
55    CLOCK_REG_DEFN(TOP, 0x134, 0, 32), /* CON1 */
56    CLOCK_REG_DEFN(TOP, 0x138, 0, 32), /* CON2 */
57};
58struct clock_reg sclkvpll_data[] = {
59    CLOCK_REG_DEFN(TOP, 0x040, 0, 32), /* LOCK */
60    CLOCK_REG_DEFN(TOP, 0x140, 0, 32), /* CON0 */
61    CLOCK_REG_DEFN(TOP, 0x144, 0, 32), /* CON1 */
62    CLOCK_REG_DEFN(TOP, 0x148, 0, 32), /* CON2 */
63};
64
65struct clock_reg uart0_data[] = {
66    CLOCK_REG_DEFN(TOP, 0x250, 0, 4), /* SEL  */
67    CLOCK_REG_DEFN(TOP, 0x350, 0, 1), /* MASK */
68    CLOCK_REG_DEFN(TOP, 0x558, 0, 4), /* DIV  */
69    CLOCK_REG_DEFN(TOP, 0x658, 0, 1), /* DIVSTAT */
70    CLOCK_REG_DEFN(TOP, 0x950, 0, 1), /* GATE */
71};
72struct clock_reg uart1_data[] = {
73    CLOCK_REG_DEFN(TOP, 0x250, 4, 4), /* SEL */
74    CLOCK_REG_DEFN(TOP, 0x350, 4, 1), /* MASK */
75    CLOCK_REG_DEFN(TOP, 0x558, 4, 4), /* DIV  */
76    CLOCK_REG_DEFN(TOP, 0x658, 4, 1), /* DIVSTAT */
77    CLOCK_REG_DEFN(TOP, 0x950, 1, 1), /* GATE */
78};
79struct clock_reg uart2_data[] = {
80    CLOCK_REG_DEFN(TOP, 0x250, 8, 4), /* SEL */
81    CLOCK_REG_DEFN(TOP, 0x350, 8, 1), /* MASK */
82    CLOCK_REG_DEFN(TOP, 0x558, 8, 4), /* DIV  */
83    CLOCK_REG_DEFN(TOP, 0x658, 8, 1), /* DIVSTAT */
84    CLOCK_REG_DEFN(TOP, 0x950, 2, 1), /* GATE */
85};
86struct clock_reg uart3_data[] = {
87    CLOCK_REG_DEFN(TOP, 0x250, 12, 4), /* SEL */
88    CLOCK_REG_DEFN(TOP, 0x350, 12, 1), /* MASK */
89    CLOCK_REG_DEFN(TOP, 0x558, 12, 4), /* DIV  */
90    CLOCK_REG_DEFN(TOP, 0x658, 12, 1), /* DIVSTAT */
91    CLOCK_REG_DEFN(TOP, 0x950,  3, 1), /* GATE */
92};
93
94struct clock_reg spi0_data[] = {
95    CLOCK_REG_DEFN(TOP, 0x254, 16, 4), /* SEL */
96    CLOCK_REG_DEFN(TOP, 0x354, 16, 1), /* MASK */
97    CLOCK_REG_DEFN(TOP, 0x55C,  0, 4), /* DIV  */
98    CLOCK_REG_DEFN(TOP, 0x55C,  8, 8), /* DIV_PRE  */
99    CLOCK_REG_DEFN(TOP, 0x65C,  0, 1), /* DIVSTAT */
100    CLOCK_REG_DEFN(TOP, 0x65C,  8, 1), /* DIVSTAT_PRE */
101    CLOCK_REG_DEFN(TOP, 0x950, 16, 1), /* GATE */
102};
103struct clock_reg spi1_data[] = {
104    CLOCK_REG_DEFN(TOP, 0x254, 20, 4), /* SEL */
105    CLOCK_REG_DEFN(TOP, 0x354, 20, 1), /* MASK */
106    CLOCK_REG_DEFN(TOP, 0x55C, 16, 4), /* DIV  */
107    CLOCK_REG_DEFN(TOP, 0x55C, 24, 8), /* DIV_PRE  */
108    CLOCK_REG_DEFN(TOP, 0x65C, 16, 1), /* DIVSTAT */
109    CLOCK_REG_DEFN(TOP, 0x65C, 24, 1), /* DIVSTAT_PRE */
110    CLOCK_REG_DEFN(TOP, 0x950, 17, 1), /* GATE */
111};
112struct clock_reg spi2_data[] = {
113    CLOCK_REG_DEFN(TOP, 0x254, 24, 4), /* SEL */
114    CLOCK_REG_DEFN(TOP, 0x354, 24, 1), /* MASK */
115    CLOCK_REG_DEFN(TOP, 0x560,  0, 4), /* DIV  */
116    CLOCK_REG_DEFN(TOP, 0x560,  8, 8), /* DIV_PRE  */
117    CLOCK_REG_DEFN(TOP, 0x660,  0, 1), /* DIVSTAT */
118    CLOCK_REG_DEFN(TOP, 0x660,  8, 1), /* DIVSTAT_PRE */
119    CLOCK_REG_DEFN(TOP, 0x950, 18, 1), /* GATE */
120};
121
122struct clock_reg i2c0_data[] = {
123    CLOCK_REG_DEFN(TOP, 0x950, 6, 1), /* GATE */
124};
125struct clock_reg i2c1_data[] = {
126    CLOCK_REG_DEFN(TOP, 0x950, 7, 1), /* GATE */
127};
128struct clock_reg i2c2_data[] = {
129    CLOCK_REG_DEFN(TOP, 0x950, 8, 1), /* GATE */
130};
131struct clock_reg i2c3_data[] = {
132    CLOCK_REG_DEFN(TOP, 0x950, 9, 1), /* GATE */
133};
134struct clock_reg i2c4_data[] = {
135    CLOCK_REG_DEFN(TOP, 0x950, 10, 1), /* GATE */
136};
137struct clock_reg i2c5_data[] = {
138    CLOCK_REG_DEFN(TOP, 0x950, 11, 1), /* GATE */
139};
140struct clock_reg i2c6_data[] = {
141    CLOCK_REG_DEFN(TOP, 0x950, 12, 1), /* GATE */
142};
143struct clock_reg i2c7_data[] = {
144    CLOCK_REG_DEFN(TOP, 0x950, 13, 1), /* GATE */
145};
146
147struct clock_reg mmc0_data[] = {
148    CLOCK_REG_DEFN(TOP, 0x244, 0, 4), /* SEL */
149    CLOCK_REG_DEFN(TOP, 0x340, 0, 1), /* MASK */
150    CLOCK_REG_DEFN(TOP, 0x54C, 0, 4), /* DIV */
151    CLOCK_REG_DEFN(TOP, 0x54C, 8, 8), /* DIV_PRE */
152    CLOCK_REG_DEFN(TOP, 0x64C, 0, 1), /* DIVSTAT */
153    CLOCK_REG_DEFN(TOP, 0x64C, 8, 1), /* DIVSTAT_PRE */
154    CLOCK_REG_DEFN(TOP, 0x944, 12, 1), /* GATE */
155};
156struct clock_reg mmc1_data[] = {
157    CLOCK_REG_DEFN(TOP, 0x244, 4, 4), /* SEL */
158    CLOCK_REG_DEFN(TOP, 0x340, 4, 1), /* MASK */
159    CLOCK_REG_DEFN(TOP, 0x54C, 16, 4), /* DIV */
160    CLOCK_REG_DEFN(TOP, 0x54C, 24, 8), /* DIV_PRE */
161    CLOCK_REG_DEFN(TOP, 0x64C, 16, 1), /* DIVSTAT */
162    CLOCK_REG_DEFN(TOP, 0x64C, 24, 1), /* DIVSTAT_PRE */
163    CLOCK_REG_DEFN(TOP, 0x944, 13, 1), /* GATE */
164};
165struct clock_reg mmc2_data[] = {
166    CLOCK_REG_DEFN(TOP, 0x244, 8, 4), /* SEL */
167    CLOCK_REG_DEFN(TOP, 0x340, 8, 1), /* MASK */
168    CLOCK_REG_DEFN(TOP, 0x550, 0, 4), /* DIV */
169    CLOCK_REG_DEFN(TOP, 0x550, 8, 8), /* DIV_PRE */
170    CLOCK_REG_DEFN(TOP, 0x650, 0, 1), /* DIVSTAT */
171    CLOCK_REG_DEFN(TOP, 0x650, 8, 1), /* DIVSTAT_PRE */
172    CLOCK_REG_DEFN(TOP, 0x944, 14, 1), /* GATE */
173};
174struct clock_reg mmc3_data[] = {
175    CLOCK_REG_DEFN(TOP, 0x244, 12, 4), /* SEL */
176    CLOCK_REG_DEFN(TOP, 0x340, 12, 1), /* MASK */
177    CLOCK_REG_DEFN(TOP, 0x550, 16, 4), /* DIV */
178    CLOCK_REG_DEFN(TOP, 0x550, 24, 8), /* DIV_PRE */
179    CLOCK_REG_DEFN(TOP, 0x650, 16, 1), /* DIVSTAT */
180    CLOCK_REG_DEFN(TOP, 0x650, 24, 1), /* DIVSTAT_PRE */
181    CLOCK_REG_DEFN(TOP, 0x944, 15, 1), /* GATE */
182};
183
184struct clock_data clock_data[] = {
185    [CLK_MASTER  ] = CLK_DEFN_NONE(),
186    [CLK_SCLKMPLL] = CLK_DEFN(sclkmpll_data),
187    [CLK_SCLKBPLL] = CLK_DEFN(sclkbpll_data),
188    [CLK_SCLKCPLL] = CLK_DEFN(sclkcpll_data),
189    [CLK_SCLKGPLL] = CLK_DEFN(sclkgpll_data),
190    [CLK_SCLKEPLL] = CLK_DEFN(sclkepll_data),
191    [CLK_SCLKVPLL] = CLK_DEFN(sclkvpll_data),
192    [CLK_SPI0    ] = CLK_DEFN(spi0_data),
193    [CLK_SPI1    ] = CLK_DEFN(spi1_data),
194    [CLK_SPI2    ] = CLK_DEFN(spi2_data),
195    [CLK_SPI0_ISP] = CLK_DEFN_NONE(),
196    [CLK_SPI1_ISP] = CLK_DEFN_NONE(),
197    [CLK_UART0   ] = CLK_DEFN(uart0_data),
198    [CLK_UART1   ] = CLK_DEFN(uart1_data),
199    [CLK_UART2   ] = CLK_DEFN(uart2_data),
200    [CLK_UART3   ] = CLK_DEFN(uart3_data),
201    [CLK_PWM     ] = CLK_DEFN_NONE(),
202    [CLK_I2C0    ] = CLK_DEFN(i2c0_data),
203    [CLK_I2C1    ] = CLK_DEFN(i2c1_data),
204    [CLK_I2C2    ] = CLK_DEFN(i2c2_data),
205    [CLK_I2C3    ] = CLK_DEFN(i2c3_data),
206    [CLK_I2C4    ] = CLK_DEFN(i2c4_data),
207    [CLK_I2C5    ] = CLK_DEFN(i2c5_data),
208    [CLK_I2C6    ] = CLK_DEFN(i2c6_data),
209    [CLK_I2C7    ] = CLK_DEFN(i2c7_data),
210    [CLK_MMC0    ] = CLK_DEFN(mmc0_data),
211    [CLK_MMC1    ] = CLK_DEFN(mmc1_data),
212    [CLK_MMC2    ] = CLK_DEFN(mmc2_data),
213    [CLK_MMC3    ] = CLK_DEFN(mmc3_data)
214};
215
216const struct device dev_cmu_cpu = {
217    .name = "CMU_CPU",
218    .pstart = CMU_CPU_PADDR,
219    .size = 0x1000,
220    .handle_device_fault = NULL,
221    .priv = NULL
222};
223
224const struct device dev_cmu_core = {
225    .name = "CMU_CORE",
226    .pstart = CMU_CORE_PADDR,
227    .size = 0x1000,
228    .handle_device_fault = NULL,
229    .priv = NULL
230};
231
232const struct device dev_cmu_acp = {
233    .name = "CMU_ACP",
234    .pstart = CMU_ACP_PADDR,
235    .size = 0x1000,
236    .handle_device_fault = NULL,
237    .priv = NULL
238};
239
240const struct device dev_cmu_isp = {
241    .name = "CMU_ISP",
242    .pstart = CMU_ISP_PADDR,
243    .size = 0x1000,
244    .handle_device_fault = NULL,
245    .priv = NULL
246};
247
248const struct device dev_cmu_top = {
249    .name = "CMU_TOP",
250    .pstart = CMU_TOP_PADDR,
251    .size = 0x1000,
252    .handle_device_fault = NULL,
253    .priv = NULL
254};
255
256const struct device dev_cmu_cdrex = {
257    .name = "CMU_CDREX",
258    .pstart = CMU_CDREX_PADDR,
259    .size = 0x1000,
260    .handle_device_fault = NULL,
261    .priv = NULL
262};
263
264const struct device dev_cmu_mem = {
265    .name = "CMU_MEM",
266    .pstart = CMU_MEM_PADDR,
267    .size = 0x1000,
268    .handle_device_fault = NULL,
269    .priv = NULL
270};
271
272static const struct device *clock_devices[] = {
273    [CLKREGS_CPU  ] = &dev_cmu_cpu,
274    [CLKREGS_CORE ] = &dev_cmu_core,
275    [CLKREGS_ACP  ] = &dev_cmu_acp,
276    [CLKREGS_ISP  ] = &dev_cmu_isp,
277    [CLKREGS_TOP  ] = &dev_cmu_top,
278    [CLKREGS_LEX  ] = NULL,
279    [CLKREGS_R0X  ] = NULL,
280    [CLKREGS_R1X  ] = NULL,
281    [CLKREGS_CDREX] = &dev_cmu_cdrex,
282    [CLKREGS_MEM  ] = &dev_cmu_mem,
283};
284
285struct clock_device {
286    void *mask[NCLKREGS];
287};
288
289
290struct clock_device *
291vm_install_ac_clock(vm_t *vm, enum vacdev_default default_ac, enum vacdev_action action)
292{
293    struct clock_device *clkd;
294    int i;
295    uint8_t ac = (default_ac == VACDEV_DEFAULT_ALLOW) ? 0xff : 0x00;
296    /* Initialise private data */
297    clkd = (struct clock_device *)calloc(1, sizeof(*clkd));
298    if (clkd == NULL) {
299        return NULL;
300    }
301    for (i = 0; i < NCLKREGS; i++) {
302        int err;
303        if (clock_devices[i] == NULL) {
304            continue;
305        }
306
307        /* map device masks */
308        clkd->mask[i] = calloc(1, BIT(12));
309        if (clkd->mask[i] == NULL) {
310            return NULL;
311        }
312        memset(clkd->mask[i], ac, BIT(12));
313        /* Install generic access control */
314        err = vm_install_generic_ac_device(vm, clock_devices[i], clkd->mask[i],
315                                           BIT(12), action);
316        if (err) {
317            return NULL;
318        }
319    }
320    return clkd;
321}
322
323int vm_clock_config(struct clock_device *clkd, enum clk_id clk_id, int grant)
324{
325    struct clock_data *data = &clock_data[clk_id];
326    int i;
327    assert(data);
328    assert(data->nregs);
329    for (i = 0; i < data->nregs; i++) {
330        uint32_t *mask;
331        uint32_t mask_val;
332        mask = (uint32_t *)(clkd->mask[data->regs[i].bank] + data->regs[i].offset);
333        /* MASK(x) does not handle 32 bit masks */
334        mask_val = ((1UL << data->regs[i].bits) - 1) << data->regs[i].shift;
335        if (grant) {
336            *mask |= mask_val;
337        } else {
338            *mask &= ~mask_val;
339        }
340    }
341    return 0;
342}
343
344int vm_clock_provide(struct clock_device *clkd, enum clk_id clk_id)
345{
346    return vm_clock_config(clkd, clk_id, 1);
347}
348
349int vm_clock_restrict(struct clock_device *clkd, enum clk_id clk_id)
350{
351    return vm_clock_config(clkd, clk_id, 0);
352}
353