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