1+ /*
2+ * Copyright (c) 2025 ispace, inc.
3+ *
4+ * SPDX-License-Identifier: Apache-2.0
5+ */
6+
7+ #include <zephyr/device.h>
8+ #include <zephyr/devicetree.h>
9+ #include <zephyr/drivers/uart.h>
10+ #include <zephyr/drivers/pinctrl.h>
11+ #include <zephyr/arch/arm/cortex_a_r/sys_io.h>
12+
13+ #define DT_DRV_COMPAT ti_tms570_uart
14+
15+ #define VCLK_FREQUENCY DT_PROP(DT_NODELABEL(clk_vclk), clock_frequency)
16+
17+ #define TMS570_GCR0 (0x00)
18+ #define TMS570_GCR1 (0x04)
19+ #define TMS570_GCR2 (0x08)
20+ #define TMS570_SETINT (0x0c)
21+ #define TMS570_CLEARINT (0x10)
22+ #define TMS570_SETINTLVL (0x14)
23+ #define TMS570_CLEARINTLVL (0x18)
24+ #define TMS570_FLR (0x1c)
25+ #define TMS570_INTVECT0 (0x20)
26+ #define TMS570_INTVECT1 (0x24)
27+ #define TMS570_FORMAT (0x28)
28+ #define TMS570_BRS (0x2c)
29+ #define TMS570_ED (0x30)
30+ #define TMS570_RD (0x34)
31+ #define TMS570_TD (0x38)
32+ #define TMS570_PIO0 (0x3c)
33+ #define TMS570_PIO1 (0x40)
34+ #define TMS570_PIO2 (0x44)
35+ #define TMS570_PIO3 (0x48)
36+ #define TMS570_PIO4 (0x4c)
37+ #define TMS570_PIO5 (0x50)
38+ #define TMS570_PIO6 (0x54)
39+ #define TMS570_PIO7 (0x58)
40+ #define TMS570_PIO8 (0x5c)
41+ #define TMS570_IODFTCTRL (0x90)
42+
43+ #define TMS570_SCI_REG_GCR0 (dev_cfg->base_addr + TMS570_GCR0)
44+ #define TMS570_SCI_REG_GCR1 (dev_cfg->base_addr + TMS570_GCR1)
45+ #define TMS570_SCI_REG_CLEARINT (dev_cfg->base_addr + TMS570_CLEARINT)
46+ #define TMS570_SCI_REG_CLEARINTLVL (dev_cfg->base_addr + TMS570_CLEARINTLVL)
47+ #define TMS570_SCI_REG_FORMAT (dev_cfg->base_addr + TMS570_FORMAT)
48+ #define TMS570_SCI_REG_BRS (dev_cfg->base_addr + TMS570_BRS)
49+ #define TMS570_SCI_REG_FUNC (dev_cfg->base_addr + TMS570_PIO0)
50+ #define TMS570_SCI_REG_PIO8 (dev_cfg->base_addr + TMS570_PIO8)
51+ #define TMS570_SCI_REG_RD (dev_cfg->base_addr + TMS570_RD)
52+ #define TMS570_SCI_REG_TD (dev_cfg->base_addr + TMS570_TD)
53+ #define TMS570_SCI_REG_FLR (dev_cfg->base_addr + TMS570_FLR)
54+
55+ #define GCR1_TXENA (1 << 25)
56+ #define GCR1_RXENA (1 << 24)
57+ #define GCR1_CONT (1 << 17)
58+ #define GCR1_LOOPBACK (1 << 16)
59+ #define GCR1_STOP_EXT_FRAME (1 << 13)
60+ #define GCR1_HGEN_CTRL (1 << 12)
61+ #define GCR1_CTYPE (1 << 11)
62+ #define GCR1_MBUF_MODE (1 << 10)
63+ #define GCR1_ADAPT (1 << 9)
64+ #define GCR1_SLEEP (1 << 8)
65+ #define GCR1_SWnRST (1 << 7)
66+ #define GCR1_LIN_MODE (1 << 6)
67+ #define GCR1_CLOCK (1 << 5)
68+ #define GCR1_STOP_BIT_1 (0 << 4)
69+ #define GCR1_STOP_BIT_2 (1 << 4)
70+ #define GCR1_PARITY_ENA (1 << 2)
71+ #define GCR1_PARITY_ODD ((0 << 3) | GCR1_PARITY_ENA)
72+ #define GCR1_PARITY_EVEN ((1 << 3) | GCR1_PARITY_ENA)
73+ #define GCR1_PARITY_NONE (0)
74+ #define GCR1_TIMING_MODE_SYNC (0 << 1)
75+ #define GCR1_TIMING_MODE_ASYNC (1 << 1)
76+ #define GCR1_COMM_MODE (1 << 0)
77+
78+ #define FLR_RX_RDY (1 << 9)
79+ #define FLR_TX_RDY (1 << 8)
80+
81+ #define FORMAT_CHARS_IN_FRAME (x ) (((x - 1) & 0x7) << 16)
82+ #define FORMAT_BITS_PER_CHAR (x ) (((x - 1) & 0x7))
83+ #define FORMAT_8_BIT_1_CHAR (FORMAT_CHARS_IN_FRAME(1) | FORMAT_BITS_PER_CHAR(8))
84+
85+ #define PIO_TX_EN (1 << 2)
86+ #define PIO_RX_EN (1 << 1)
87+
88+ /* Device data structure */
89+ struct uart_tms570_dev_cfg_t {
90+ const uint32_t base_addr ; /* Register base address */
91+ const uint32_t baud_rate ; /* Baud rate */
92+ const struct pinctrl_dev_config * pincfg ;
93+ };
94+
95+
96+ static void uart_tms570_poll_out (const struct device * dev , uint8_t c )
97+ {
98+ struct uart_tms570_dev_cfg_t * dev_cfg = (struct uart_tms570_dev_cfg_t * )dev -> config ;
99+ while ((sys_read32 (TMS570_SCI_REG_FLR ) & 0x00000100U ) == 0U ) {
100+ /* wait */
101+ };
102+
103+ sys_write32 (c , TMS570_SCI_REG_TD );
104+ }
105+
106+ static int uart_tms570_poll_in (const struct device * dev , uint8_t * c )
107+ {
108+ struct uart_tms570_dev_cfg_t * dev_cfg = (struct uart_tms570_dev_cfg_t * )dev -> config ;
109+ uint32_t flags ;
110+
111+ flags = sys_read32 (TMS570_SCI_REG_FLR );
112+ if ((flags & FLR_RX_RDY ) != 0 ) {
113+ * c = (uint8_t )sys_read32 (TMS570_SCI_REG_RD );
114+ return 0 ;
115+ } else {
116+ return -1 ;
117+ }
118+ }
119+
120+ static int uart_tms570_init (const struct device * dev )
121+ {
122+ struct uart_tms570_dev_cfg_t * dev_cfg = (struct uart_tms570_dev_cfg_t * )dev -> config ;
123+
124+ /* reset SCI */
125+ sys_write32 (0 , TMS570_SCI_REG_GCR0 );
126+ sys_write32 (1 , TMS570_SCI_REG_GCR0 );
127+
128+ /* enable and set up uart */
129+ sys_write32 (GCR1_TXENA | GCR1_RXENA | /* enable both tx and rx */
130+ GCR1_CLOCK | /* internal clock (device has no clock pin) */
131+ GCR1_STOP_BIT_1 |
132+ GCR1_PARITY_NONE |
133+ GCR1_TIMING_MODE_ASYNC ,
134+ TMS570_SCI_REG_GCR1 );
135+
136+ /* make pins SCI mode */
137+ sys_write32 (PIO_TX_EN | PIO_RX_EN , TMS570_SCI_REG_FUNC );
138+ pinctrl_apply_state (dev_cfg -> pincfg , PINCTRL_STATE_DEFAULT );
139+
140+ /* baudrate */
141+ sys_write32 (VCLK_FREQUENCY / ((dev_cfg -> baud_rate - 1 ) * 16 ), TMS570_SCI_REG_BRS );
142+
143+ /* we want 8 bit per char and 1 char per frame */
144+ sys_write32 (FORMAT_8_BIT_1_CHAR , TMS570_SCI_REG_FORMAT );
145+
146+ /* start */
147+ sys_write32 (sys_read32 (TMS570_SCI_REG_GCR1 ) | GCR1_SWnRST , TMS570_SCI_REG_GCR1 );
148+
149+ return 0 ;
150+ }
151+
152+ static const struct uart_driver_api uart_tms570_driver_api = {
153+ .poll_in = uart_tms570_poll_in ,
154+ .poll_out = uart_tms570_poll_out ,
155+ .err_check = NULL ,
156+ };
157+
158+ #define TMS570_UART_INIT (idx ) \
159+ PINCTRL_DT_INST_DEFINE(idx); \
160+ static struct uart_tms570_dev_cfg_t tms570__uart##idx##_cfg = { \
161+ .base_addr = DT_INST_REG_ADDR(idx), \
162+ .baud_rate = DT_INST_PROP(idx, current_speed), \
163+ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
164+ }; \
165+ DEVICE_DT_INST_DEFINE(idx, &uart_tms570_init, NULL, NULL, \
166+ &tms570__uart##idx##_cfg, PRE_KERNEL_1, \
167+ CONFIG_SERIAL_INIT_PRIORITY, \
168+ &uart_tms570_driver_api);
169+
170+ DT_INST_FOREACH_STATUS_OKAY (TMS570_UART_INIT )
0 commit comments