1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  * Copyright (c) 2024 sensry.io
4  */
5 
6 #ifndef GANYMED_SY1XX_UDMA_H
7 #define GANYMED_SY1XX_UDMA_H
8 
9 #include <stdint.h>
10 #include <zephyr/arch/common/sys_io.h>
11 #include <soc.h>
12 
13 /* UDMA */
14 
15 #define SY1XX_UDMA_PERIPH_AREA_SIZE_LOG2 7
16 #define SY1XX_UDMA_PERIPH_OFFSET(id)     (((id) << SY1XX_UDMA_PERIPH_AREA_SIZE_LOG2))
17 
18 #define SY1XX_ARCHI_UDMA_UART_ID(id)  (0 + (id))
19 #define SY1XX_ARCHI_UDMA_SPIM_ID(id)  (3 + (id))
20 #define SY1XX_ARCHI_UDMA_I2C_ID(id)   (10 + (id))
21 #define SY1XX_ARCHI_UDMA_I2S_ID(id)   (14 + (id))
22 #define SY1XX_ARCHI_UDMA_HYPER_ID(id) (19 + (id))
23 #define SY1XX_ARCHI_UDMA_TSN_ID(id)   (20 + (id))
24 
25 #define SY1XX_UDMA_CHANNEL_RX_OFFSET     0x00
26 #define SY1XX_UDMA_CHANNEL_TX_OFFSET     0x10
27 #define SY1XX_UDMA_CHANNEL_CUSTOM_OFFSET 0x20
28 
29 /*
30  * For each channel, the RX and TX part have the following registers
31  * The offsets are given relative to the offset of the RX or TX part
32  */
33 
34 /* Start address register */
35 #define SY1XX_UDMA_CHANNEL_SADDR_OFFSET  0x0
36 /* Size register */
37 #define SY1XX_UDMA_CHANNEL_SIZE_OFFSET   0x4
38 /* Configuration register */
39 #define SY1XX_UDMA_CHANNEL_CFG_OFFSET    0x8
40 /* Int configuration register */
41 #define SY1XX_UDMA_CHANNEL_INTCFG_OFFSET 0xC
42 
43 /*
44  * The configuration register of the RX and TX parts for each channel can be accessed using the
45  * following bits
46  */
47 
48 #define SY1XX_UDMA_CHANNEL_CFG_SHADOW_BIT (5)
49 #define SY1XX_UDMA_CHANNEL_CFG_CLEAR_BIT  (5)
50 #define SY1XX_UDMA_CHANNEL_CFG_EN_BIT     (4)
51 #define SY1XX_UDMA_CHANNEL_CFG_SIZE_BIT   (1)
52 #define SY1XX_UDMA_CHANNEL_CFG_CONT_BIT   (0)
53 
54 /* Indicates if a shadow transfer is there */
55 #define SY1XX_UDMA_CHANNEL_CFG_SHADOW  (1 << SY1XX_UDMA_CHANNEL_CFG_SHADOW_BIT)
56 /* Stop and clear all pending transfers */
57 #define SY1XX_UDMA_CHANNEL_CFG_CLEAR   (1 << SY1XX_UDMA_CHANNEL_CFG_CLEAR_BIT)
58 /* Start a transfer */
59 #define SY1XX_UDMA_CHANNEL_CFG_EN      (1 << SY1XX_UDMA_CHANNEL_CFG_EN_BIT)
60 /* Configure for 8-bits transfer */
61 #define SY1XX_UDMA_CHANNEL_CFG_SIZE_8  (0 << SY1XX_UDMA_CHANNEL_CFG_SIZE_BIT)
62 /* Configure for 16-bits transfer */
63 #define SY1XX_UDMA_CHANNEL_CFG_SIZE_16 (1 << SY1XX_UDMA_CHANNEL_CFG_SIZE_BIT)
64 /* Configure for 32-bits transfer */
65 #define SY1XX_UDMA_CHANNEL_CFG_SIZE_32 (2 << SY1XX_UDMA_CHANNEL_CFG_SIZE_BIT)
66 /* Configure for continuous mode */
67 #define SY1XX_UDMA_CHANNEL_CFG_CONT    (1 << SY1XX_UDMA_CHANNEL_CFG_CONT_BIT)
68 
69 /* Configuration area offset */
70 #define SY1XX_UDMA_CONF_OFFSET    0xF80
71 /* Clock-gating control register */
72 #define SY1XX_UDMA_CONF_CG_OFFSET 0x00
73 
plp_udma_cg_set(unsigned int value)74 static inline void plp_udma_cg_set(unsigned int value)
75 {
76 	sys_write32(value, SY1XX_ARCHI_SOC_PERIPHERALS_ADDR + SY1XX_ARCHI_UDMA_OFFSET +
77 				   SY1XX_UDMA_CONF_OFFSET + SY1XX_UDMA_CONF_CG_OFFSET);
78 }
79 
80 typedef enum {
81 	SY1XX_UDMA_MODULE_UART,
82 	SY1XX_UDMA_MODULE_I2C,
83 	SY1XX_UDMA_MODULE_SPI,
84 	SY1XX_UDMA_MODULE_MAC,
85 	SY1XX_UDMA_MAX_MODULE_COUNT
86 } sy1xx_udma_module_t;
87 
88 void sy1xx_udma_enable_clock(sy1xx_udma_module_t module, uint32_t instance);
89 void sy1xx_drivers_udma_disable_clock(sy1xx_udma_module_t module, uint32_t instance);
90 
91 int32_t sy1xx_udma_cancel(uint32_t base, uint32_t channel);
92 int32_t sy1xx_udma_is_ready(uint32_t base, uint32_t channel);
93 int32_t sy1xx_udma_wait_for_finished(uint32_t base, uint32_t channel);
94 int32_t sy1xx_udma_wait_for_status(uint32_t base);
95 int32_t sy1xx_udma_start(uint32_t base, uint32_t channel, uint32_t saddr, uint32_t size,
96 			 uint32_t optional_cfg);
97 int32_t sy1xx_udma_get_remaining(uint32_t base, uint32_t channel);
98 
99 typedef enum {
100 	SY1XX_UDMA_SADDR_REG = 0x00,
101 	SY1XX_UDMA_SIZE_REG = 0x04,
102 	SY1XX_UDMA_CFG_REG = 0x08,
103 
104 } udma_regs_t;
105 
106 typedef enum {
107 	SY1XX_UDMA_RX_SADDR_REG = 0x00,
108 	SY1XX_UDMA_RX_SIZE_REG = 0x04,
109 	SY1XX_UDMA_RX_CFG_REG = 0x08,
110 
111 	SY1XX_UDMA_TX_SADDR_REG = 0x10,
112 	SY1XX_UDMA_TX_SIZE_REG = 0x14,
113 	SY1XX_UDMA_TX_CFG_REG = 0x18,
114 
115 	SY1XX_UDMA_STATUS = 0x20,
116 	SY1XX_UDMA_SETUP_REG = 0x24,
117 } udma_reg_t;
118 
119 #define SY1XX_UDMA_RX_DATA_ADDR_INC_SIZE_8  (0x0 << 1)
120 #define SY1XX_UDMA_RX_DATA_ADDR_INC_SIZE_16 (0x1 << 1)
121 #define SY1XX_UDMA_RX_DATA_ADDR_INC_SIZE_32 (0x2 << 1)
122 
123 #define SY1XX_UDMA_RX_CHANNEL 0
124 #define SY1XX_UDMA_TX_CHANNEL 1
125 
126 #define SY1XX_UDMA_READ_REG(udma_base, reg)         sys_read32(udma_base + reg)
127 #define SY1XX_UDMA_WRITE_REG(udma_base, reg, value) sys_write32(value, udma_base + reg)
128 
129 #define SY1XX_UDMA_CANCEL_RX(udma_base) sy1xx_udma_cancel(udma_base, SY1XX_UDMA_RX_CHANNEL)
130 #define SY1XX_UDMA_CANCEL_TX(udma_base) sy1xx_udma_cancel(udma_base, SY1XX_UDMA_TX_CHANNEL)
131 
132 #define SY1XX_UDMA_IS_FINISHED_RX(udma_base) sy1xx_udma_is_ready(udma_base, SY1XX_UDMA_RX_CHANNEL)
133 #define SY1XX_UDMA_IS_FINISHED_TX(udma_base) sy1xx_udma_is_ready(udma_base, SY1XX_UDMA_TX_CHANNEL)
134 
135 #define SY1XX_UDMA_WAIT_FOR_FINISHED_RX(udma_base)                                                 \
136 	sy1xx_udma_wait_for_finished(udma_base, SY1XX_UDMA_RX_CHANNEL)
137 #define SY1XX_UDMA_WAIT_FOR_FINISHED_TX(udma_base)                                                 \
138 	sy1xx_udma_wait_for_finished(udma_base, SY1XX_UDMA_TX_CHANNEL)
139 
140 #define SY1XX_UDMA_START_RX(base, addr, size, cfg)                                                 \
141 	sy1xx_udma_start(base, SY1XX_UDMA_RX_CHANNEL, addr, size, cfg)
142 #define SY1XX_UDMA_START_TX(base, addr, size, cfg)                                                 \
143 	sy1xx_udma_start(base, SY1XX_UDMA_TX_CHANNEL, addr, size, cfg)
144 
145 #define SY1XX_UDMA_GET_REMAINING_RX(base) sy1xx_udma_get_remaining(base, SY1XX_UDMA_RX_CHANNEL)
146 #define SY1XX_UDMA_GET_REMAINING_TX(base) sy1xx_udma_get_remaining(base, SY1XX_UDMA_TX_CHANNEL)
147 
148 #define SY1XX_UDMA_WAIT_FOR_STATUS_IDLE(udma_base) sy1xx_udma_wait_for_status(udma_base)
149 
150 #endif /* GANYMED_SY1XX_UDMA_H */
151