1 /*
2 * Copyright (c) 2022 Arm Limited. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "dma350_ch_drv.h"
18
19 #include <stddef.h>
20 #include <stdint.h>
21
dma350_ch_init(struct dma350_ch_dev_t * dev)22 enum dma350_ch_error_t dma350_ch_init(struct dma350_ch_dev_t *dev)
23 {
24 dev->data.state = DMA350_CH_INITIALIZED;
25
26 return DMA350_CH_ERR_NONE;
27 }
28
dma350_cmdlink_generate(struct dma350_cmdlink_gencfg_t * cmdlink_cfg,uint32_t * buffer,uint32_t * buffer_end)29 uint32_t *dma350_cmdlink_generate(struct dma350_cmdlink_gencfg_t *cmdlink_cfg,
30 uint32_t *buffer, uint32_t *buffer_end)
31 {
32 uint32_t *cfg;
33 uint32_t header_sel;
34 /* Check if cmdlink fits inside the buffer. */
35 /* Header bit 0 and 1 have no associated registers. +1 is For the header */
36 if (&buffer[__builtin_popcount((cmdlink_cfg->header) & 0xFFFFFFFCUL) + 1] >=
37 buffer_end) {
38 return NULL;
39 }
40 cfg = (uint32_t *)&cmdlink_cfg->cfg;
41 *(buffer++) = cmdlink_cfg->header;
42
43 /* Note: REGCLEAR (Bit 0) has no associated field and Bit 1 is reserved,
44 * cfg starts from Bit 2 */
45 for (header_sel = (0x1UL << 2); header_sel; header_sel <<= 1) {
46 if (cmdlink_cfg->header & header_sel) {
47 *(buffer++) = *(cfg++);
48 } else {
49 cfg++;
50 }
51 }
52 return buffer;
53 }
54
dma350_cmdlink_init(struct dma350_cmdlink_gencfg_t * cmdlink_cfg)55 void dma350_cmdlink_init(struct dma350_cmdlink_gencfg_t *cmdlink_cfg)
56 {
57 static const struct dma350_cmdlink_gencfg_t default_cmdlink = {
58 .header = 0,
59 .cfg = {.intren = DMA350_CH_INTREN_RESET_VALUE,
60 .ctrl = DMA350_CH_CTRL_RESET_VALUE,
61 .srcaddr = 0,
62 .srcaddrhi = 0,
63 .desaddr = 0,
64 .desaddrhi = 0,
65 .xsize = 0,
66 .xsizehi = 0,
67 .srctranscfg = DMA350_CH_SRCTRANSCFG_RESET_VALUE,
68 .destranscfg = DMA350_CH_DESTRANSCFG_RESET_VALUE,
69 .xaddrinc = 0,
70 .yaddrstride = 0,
71 .fillval = 0,
72 .ysize = 0,
73 .tmpltcfg = 0,
74 .srctmplt = 0,
75 .destmplt = 0,
76 .srctrigincfg = 0,
77 .destrigincfg = 0,
78 .trigoutcfg = 0,
79 .gpoen0 = 0,
80 .reserved0 = 0,
81 .gpoval0 = 0,
82 .reserved1 = 0,
83 .streamintcfg = 0,
84 .reserved2 = 0,
85 .linkattr = 0,
86 .autocfg = DMA350_CH_AUTOCFG_RESET_VALUE,
87 .linkaddr = DMA350_CH_LINKADDR_RESET_VALUE,
88 .linkaddrhi = 0}};
89 *cmdlink_cfg = default_cmdlink;
90 }
91
dma350_ch_wait_status(struct dma350_ch_dev_t * dev)92 union dma350_ch_status_t dma350_ch_wait_status(struct dma350_ch_dev_t *dev)
93 {
94 /* Reference implementation with busy wait */
95 while(dma350_ch_is_busy(dev));
96
97 return dma350_ch_get_status(dev);
98 }
99