aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/stm32-usart.c130
-rw-r--r--drivers/tty/serial/stm32-usart.h3
2 files changed, 132 insertions, 1 deletions
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 0fa735b60f2d..345fbf314269 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -62,6 +62,113 @@ static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
62 writel_relaxed(val, port->membase + reg); 62 writel_relaxed(val, port->membase + reg);
63} 63}
64 64
65static void stm32_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
66 u32 delay_DDE, u32 baud)
67{
68 u32 rs485_deat_dedt;
69 u32 rs485_deat_dedt_max = (USART_CR1_DEAT_MASK >> USART_CR1_DEAT_SHIFT);
70 bool over8;
71
72 *cr3 |= USART_CR3_DEM;
73 over8 = *cr1 & USART_CR1_OVER8;
74
75 if (over8)
76 rs485_deat_dedt = delay_ADE * baud * 8;
77 else
78 rs485_deat_dedt = delay_ADE * baud * 16;
79
80 rs485_deat_dedt = DIV_ROUND_CLOSEST(rs485_deat_dedt, 1000);
81 rs485_deat_dedt = rs485_deat_dedt > rs485_deat_dedt_max ?
82 rs485_deat_dedt_max : rs485_deat_dedt;
83 rs485_deat_dedt = (rs485_deat_dedt << USART_CR1_DEAT_SHIFT) &
84 USART_CR1_DEAT_MASK;
85 *cr1 |= rs485_deat_dedt;
86
87 if (over8)
88 rs485_deat_dedt = delay_DDE * baud * 8;
89 else
90 rs485_deat_dedt = delay_DDE * baud * 16;
91
92 rs485_deat_dedt = DIV_ROUND_CLOSEST(rs485_deat_dedt, 1000);
93 rs485_deat_dedt = rs485_deat_dedt > rs485_deat_dedt_max ?
94 rs485_deat_dedt_max : rs485_deat_dedt;
95 rs485_deat_dedt = (rs485_deat_dedt << USART_CR1_DEDT_SHIFT) &
96 USART_CR1_DEDT_MASK;
97 *cr1 |= rs485_deat_dedt;
98}
99
100static int stm32_config_rs485(struct uart_port *port,
101 struct serial_rs485 *rs485conf)
102{
103 struct stm32_port *stm32_port = to_stm32_port(port);
104 struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
105 struct stm32_usart_config *cfg = &stm32_port->info->cfg;
106 u32 usartdiv, baud, cr1, cr3;
107 bool over8;
108 unsigned long flags;
109
110 spin_lock_irqsave(&port->lock, flags);
111 stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
112
113 port->rs485 = *rs485conf;
114
115 rs485conf->flags |= SER_RS485_RX_DURING_TX;
116
117 if (rs485conf->flags & SER_RS485_ENABLED) {
118 cr1 = readl_relaxed(port->membase + ofs->cr1);
119 cr3 = readl_relaxed(port->membase + ofs->cr3);
120 usartdiv = readl_relaxed(port->membase + ofs->brr);
121 usartdiv = usartdiv & GENMASK(15, 0);
122 over8 = cr1 & USART_CR1_OVER8;
123
124 if (over8)
125 usartdiv = usartdiv | (usartdiv & GENMASK(4, 0))
126 << USART_BRR_04_R_SHIFT;
127
128 baud = DIV_ROUND_CLOSEST(port->uartclk, usartdiv);
129 stm32_config_reg_rs485(&cr1, &cr3,
130 rs485conf->delay_rts_before_send,
131 rs485conf->delay_rts_after_send, baud);
132
133 if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
134 cr3 &= ~USART_CR3_DEP;
135 rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
136 } else {
137 cr3 |= USART_CR3_DEP;
138 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
139 }
140
141 writel_relaxed(cr3, port->membase + ofs->cr3);
142 writel_relaxed(cr1, port->membase + ofs->cr1);
143 } else {
144 stm32_clr_bits(port, ofs->cr3, USART_CR3_DEM | USART_CR3_DEP);
145 stm32_clr_bits(port, ofs->cr1,
146 USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
147 }
148
149 stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
150 spin_unlock_irqrestore(&port->lock, flags);
151
152 return 0;
153}
154
155static int stm32_init_rs485(struct uart_port *port,
156 struct platform_device *pdev)
157{
158 struct serial_rs485 *rs485conf = &port->rs485;
159
160 rs485conf->flags = 0;
161 rs485conf->delay_rts_before_send = 0;
162 rs485conf->delay_rts_after_send = 0;
163
164 if (!pdev->dev.of_node)
165 return -ENODEV;
166
167 uart_get_rs485_mode(&pdev->dev, rs485conf);
168
169 return 0;
170}
171
65static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res, 172static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res,
66 bool threaded) 173 bool threaded)
67{ 174{
@@ -498,6 +605,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
498 struct stm32_port *stm32_port = to_stm32_port(port); 605 struct stm32_port *stm32_port = to_stm32_port(port);
499 struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 606 struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
500 struct stm32_usart_config *cfg = &stm32_port->info->cfg; 607 struct stm32_usart_config *cfg = &stm32_port->info->cfg;
608 struct serial_rs485 *rs485conf = &port->rs485;
501 unsigned int baud; 609 unsigned int baud;
502 u32 usartdiv, mantissa, fraction, oversampling; 610 u32 usartdiv, mantissa, fraction, oversampling;
503 tcflag_t cflag = termios->c_cflag; 611 tcflag_t cflag = termios->c_cflag;
@@ -515,7 +623,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
515 writel_relaxed(0, port->membase + ofs->cr1); 623 writel_relaxed(0, port->membase + ofs->cr1);
516 624
517 cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; 625 cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
518 cr1 |= BIT(cfg->uart_enable_bit); 626
519 if (stm32_port->fifoen) 627 if (stm32_port->fifoen)
520 cr1 |= USART_CR1_FIFOEN; 628 cr1 |= USART_CR1_FIFOEN;
521 cr2 = 0; 629 cr2 = 0;
@@ -553,9 +661,11 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
553 */ 661 */
554 if (usartdiv < 16) { 662 if (usartdiv < 16) {
555 oversampling = 8; 663 oversampling = 8;
664 cr1 |= USART_CR1_OVER8;
556 stm32_set_bits(port, ofs->cr1, USART_CR1_OVER8); 665 stm32_set_bits(port, ofs->cr1, USART_CR1_OVER8);
557 } else { 666 } else {
558 oversampling = 16; 667 oversampling = 16;
668 cr1 &= ~USART_CR1_OVER8;
559 stm32_clr_bits(port, ofs->cr1, USART_CR1_OVER8); 669 stm32_clr_bits(port, ofs->cr1, USART_CR1_OVER8);
560 } 670 }
561 671
@@ -592,10 +702,28 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
592 if (stm32_port->rx_ch) 702 if (stm32_port->rx_ch)
593 cr3 |= USART_CR3_DMAR; 703 cr3 |= USART_CR3_DMAR;
594 704
705 if (rs485conf->flags & SER_RS485_ENABLED) {
706 stm32_config_reg_rs485(&cr1, &cr3,
707 rs485conf->delay_rts_before_send,
708 rs485conf->delay_rts_after_send, baud);
709 if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
710 cr3 &= ~USART_CR3_DEP;
711 rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
712 } else {
713 cr3 |= USART_CR3_DEP;
714 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
715 }
716
717 } else {
718 cr3 &= ~(USART_CR3_DEM | USART_CR3_DEP);
719 cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
720 }
721
595 writel_relaxed(cr3, port->membase + ofs->cr3); 722 writel_relaxed(cr3, port->membase + ofs->cr3);
596 writel_relaxed(cr2, port->membase + ofs->cr2); 723 writel_relaxed(cr2, port->membase + ofs->cr2);
597 writel_relaxed(cr1, port->membase + ofs->cr1); 724 writel_relaxed(cr1, port->membase + ofs->cr1);
598 725
726 stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
599 spin_unlock_irqrestore(&port->lock, flags); 727 spin_unlock_irqrestore(&port->lock, flags);
600} 728}
601 729
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index 2294d0f05872..6f294e280ea3 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -135,6 +135,7 @@ struct stm32_usart_info stm32h7_info = {
135#define USART_BRR_DIV_F_MASK GENMASK(3, 0) 135#define USART_BRR_DIV_F_MASK GENMASK(3, 0)
136#define USART_BRR_DIV_M_MASK GENMASK(15, 4) 136#define USART_BRR_DIV_M_MASK GENMASK(15, 4)
137#define USART_BRR_DIV_M_SHIFT 4 137#define USART_BRR_DIV_M_SHIFT 4
138#define USART_BRR_04_R_SHIFT 1
138 139
139/* USART_CR1 */ 140/* USART_CR1 */
140#define USART_CR1_SBK BIT(0) 141#define USART_CR1_SBK BIT(0)
@@ -162,6 +163,8 @@ struct stm32_usart_info stm32h7_info = {
162#define USART_CR1_M1 BIT(28) /* F7 */ 163#define USART_CR1_M1 BIT(28) /* F7 */
163#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27)) 164#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
164#define USART_CR1_FIFOEN BIT(29) /* H7 */ 165#define USART_CR1_FIFOEN BIT(29) /* H7 */
166#define USART_CR1_DEAT_SHIFT 21
167#define USART_CR1_DEDT_SHIFT 16
165 168
166/* USART_CR2 */ 169/* USART_CR2 */
167#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */ 170#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */