6767#define ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT 10
6868#define ESP32_UART_RX_FLOW_EN BIT(23)
6969#define ESP32S3_UART_RX_FLOW_EN BIT(22)
70+ #define ESP32S3_UART_CLK_CONF_REG 0x78
71+ #define ESP32S3_UART_SCLK_DIV_B GENMASK(5, 0)
72+ #define ESP32S3_UART_SCLK_DIV_A GENMASK(11, 6)
73+ #define ESP32S3_UART_SCLK_DIV_NUM GENMASK(19, 12)
74+ #define ESP32S3_UART_SCLK_SEL GENMASK(21, 20)
75+ #define APB_CLK 1
76+ #define RC_FAST_CLK 2
77+ #define XTAL_CLK 3
78+ #define ESP32S3_UART_SCLK_EN BIT(22)
79+ #define ESP32S3_UART_RST_CORE BIT(23)
80+ #define ESP32S3_UART_TX_SCLK_EN BIT(24)
81+ #define ESP32S3_UART_RX_SCLK_EN BIT(25)
82+ #define ESP32S3_UART_TX_RST_CORE BIT(26)
83+ #define ESP32S3_UART_RX_RST_CORE BIT(27)
84+
85+ #define ESP32S3_UART_CLK_CONF_DEFAULT \
86+ (ESP32S3_UART_RX_SCLK_EN | \
87+ ESP32S3_UART_TX_SCLK_EN | \
88+ ESP32S3_UART_SCLK_EN | \
89+ FIELD_PREP(ESP32S3_UART_SCLK_SEL, XTAL_CLK))
7090
7191struct esp32_port {
7292 struct uart_port port ;
@@ -80,6 +100,7 @@ struct esp32_uart_variant {
80100 u32 txfifo_empty_thrhd_shift ;
81101 u32 rx_flow_en ;
82102 const char * type ;
103+ bool has_clkconf ;
83104};
84105
85106static const struct esp32_uart_variant esp32_variant = {
@@ -98,6 +119,7 @@ static const struct esp32_uart_variant esp32s3_variant = {
98119 .txfifo_empty_thrhd_shift = ESP32S3_UART_TXFIFO_EMPTY_THRHD_SHIFT ,
99120 .rx_flow_en = ESP32S3_UART_RX_FLOW_EN ,
100121 .type = "ESP32S3 UART" ,
122+ .has_clkconf = true,
101123};
102124
103125static const struct of_device_id esp32_uart_dt_ids [] = {
@@ -314,6 +336,9 @@ static int esp32_uart_startup(struct uart_port *port)
314336 }
315337
316338 spin_lock_irqsave (& port -> lock , flags );
339+ if (port_variant (port )-> has_clkconf )
340+ esp32_uart_write (port , ESP32S3_UART_CLK_CONF_REG ,
341+ ESP32S3_UART_CLK_CONF_DEFAULT );
317342 esp32_uart_write (port , UART_CONF1_REG ,
318343 (1 << UART_RXFIFO_FULL_THRHD_SHIFT ) |
319344 (1 << port_variant (port )-> txfifo_empty_thrhd_shift ));
@@ -335,10 +360,24 @@ static void esp32_uart_shutdown(struct uart_port *port)
335360
336361static bool esp32_uart_set_baud (struct uart_port * port , u32 baud )
337362{
338- u32 div = port -> uartclk / baud ;
339- u32 frag = (port -> uartclk * 16 ) / baud - div * 16 ;
363+ u32 sclk = port -> uartclk ;
364+ u32 div = sclk / baud ;
365+
366+ if (port_variant (port )-> has_clkconf ) {
367+ u32 sclk_div = div / port_variant (port )-> clkdiv_mask ;
368+
369+ if (div > port_variant (port )-> clkdiv_mask ) {
370+ sclk /= (sclk_div + 1 );
371+ div = sclk / baud ;
372+ }
373+ esp32_uart_write (port , ESP32S3_UART_CLK_CONF_REG ,
374+ FIELD_PREP (ESP32S3_UART_SCLK_DIV_NUM , sclk_div ) |
375+ ESP32S3_UART_CLK_CONF_DEFAULT );
376+ }
340377
341378 if (div <= port_variant (port )-> clkdiv_mask ) {
379+ u32 frag = (sclk * 16 ) / baud - div * 16 ;
380+
342381 esp32_uart_write (port , UART_CLKDIV_REG ,
343382 div | FIELD_PREP (UART_CLKDIV_FRAG , frag ));
344383 return true;
@@ -355,11 +394,15 @@ static void esp32_uart_set_termios(struct uart_port *port,
355394 u32 conf0 , conf1 ;
356395 u32 baud ;
357396 const u32 rx_flow_en = port_variant (port )-> rx_flow_en ;
397+ u32 max_div = port_variant (port )-> clkdiv_mask ;
358398
359399 termios -> c_cflag &= ~CMSPAR ;
360400
401+ if (port_variant (port )-> has_clkconf )
402+ max_div *= FIELD_MAX (ESP32S3_UART_SCLK_DIV_NUM );
403+
361404 baud = uart_get_baud_rate (port , termios , old ,
362- port -> uartclk / port_variant ( port ) -> clkdiv_mask ,
405+ port -> uartclk / max_div ,
363406 port -> uartclk / 16 );
364407
365408 spin_lock_irqsave (& port -> lock , flags );
0 commit comments