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