diff options
-rw-r--r-- | drivers/tty/serial/stm32-usart.c | 130 | ||||
-rw-r--r-- | drivers/tty/serial/stm32-usart.h | 3 |
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 | ||
65 | static 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 | |||
100 | static 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 | |||
155 | static 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 | |||
65 | static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res, | 172 | static 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 */ |