1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved 4 * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics. 5 */ 6 7 #include <common.h> 8 #include <clk.h> 9 #include <dm.h> 10 #include <serial.h> 11 #include <watchdog.h> 12 #include <asm/io.h> 13 #include <asm/arch/stm32.h> 14 #include "serial_stm32.h" 15 16 static void _stm32_serial_setbrg(fdt_addr_t base, 17 struct stm32_uart_info *uart_info, 18 u32 clock_rate, 19 int baudrate) 20 { 21 bool stm32f4 = uart_info->stm32f4; 22 u32 int_div, mantissa, fraction, oversampling; 23 24 int_div = DIV_ROUND_CLOSEST(clock_rate, baudrate); 25 26 if (int_div < 16) { 27 oversampling = 8; 28 setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8); 29 } else { 30 oversampling = 16; 31 clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8); 32 } 33 34 mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT; 35 fraction = int_div % oversampling; 36 37 writel(mantissa | fraction, base + BRR_OFFSET(stm32f4)); 38 } 39 40 static int stm32_serial_setbrg(struct udevice *dev, int baudrate) 41 { 42 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 43 44 _stm32_serial_setbrg(plat->base, plat->uart_info, 45 plat->clock_rate, baudrate); 46 47 return 0; 48 } 49 50 static int stm32_serial_setconfig(struct udevice *dev, uint serial_config) 51 { 52 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 53 bool stm32f4 = plat->uart_info->stm32f4; 54 u8 uart_enable_bit = plat->uart_info->uart_enable_bit; 55 u32 cr1 = plat->base + CR1_OFFSET(stm32f4); 56 u32 config = 0; 57 uint parity = SERIAL_GET_PARITY(serial_config); 58 uint bits = SERIAL_GET_BITS(serial_config); 59 uint stop = SERIAL_GET_STOP(serial_config); 60 61 /* 62 * only parity config is implemented, check if other serial settings 63 * are the default one. 64 * (STM32F4 serial IP didn't support parity setting) 65 */ 66 if (bits != SERIAL_8_BITS || stop != SERIAL_ONE_STOP || stm32f4) 67 return -ENOTSUPP; /* not supported in driver*/ 68 69 clrbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit)); 70 /* update usart configuration (uart need to be disable) 71 * PCE: parity check enable 72 * PS : '0' : Even / '1' : Odd 73 * M[1:0] = '00' : 8 Data bits 74 * M[1:0] = '01' : 9 Data bits with parity 75 */ 76 switch (parity) { 77 default: 78 case SERIAL_PAR_NONE: 79 config = 0; 80 break; 81 case SERIAL_PAR_ODD: 82 config = USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0; 83 break; 84 case SERIAL_PAR_EVEN: 85 config = USART_CR1_PCE | USART_CR1_M0; 86 break; 87 } 88 89 clrsetbits_le32(cr1, 90 USART_CR1_PCE | USART_CR1_PS | USART_CR1_M1 | 91 USART_CR1_M0, 92 config); 93 setbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit)); 94 95 return 0; 96 } 97 98 static int stm32_serial_getc(struct udevice *dev) 99 { 100 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 101 bool stm32f4 = plat->uart_info->stm32f4; 102 fdt_addr_t base = plat->base; 103 u32 isr = readl(base + ISR_OFFSET(stm32f4)); 104 105 if ((isr & USART_ISR_RXNE) == 0) 106 return -EAGAIN; 107 108 if (isr & (USART_ISR_PE | USART_ISR_ORE)) { 109 if (!stm32f4) 110 setbits_le32(base + ICR_OFFSET, 111 USART_ICR_PCECF | USART_ICR_ORECF); 112 else 113 readl(base + RDR_OFFSET(stm32f4)); 114 return -EIO; 115 } 116 117 return readl(base + RDR_OFFSET(stm32f4)); 118 } 119 120 static int _stm32_serial_putc(fdt_addr_t base, 121 struct stm32_uart_info *uart_info, 122 const char c) 123 { 124 bool stm32f4 = uart_info->stm32f4; 125 126 if ((readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_TXE) == 0) 127 return -EAGAIN; 128 129 writel(c, base + TDR_OFFSET(stm32f4)); 130 131 return 0; 132 } 133 134 static int stm32_serial_putc(struct udevice *dev, const char c) 135 { 136 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 137 138 return _stm32_serial_putc(plat->base, plat->uart_info, c); 139 } 140 141 static int stm32_serial_pending(struct udevice *dev, bool input) 142 { 143 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 144 bool stm32f4 = plat->uart_info->stm32f4; 145 fdt_addr_t base = plat->base; 146 147 if (input) 148 return readl(base + ISR_OFFSET(stm32f4)) & 149 USART_ISR_RXNE ? 1 : 0; 150 else 151 return readl(base + ISR_OFFSET(stm32f4)) & 152 USART_ISR_TXE ? 0 : 1; 153 } 154 155 static void _stm32_serial_init(fdt_addr_t base, 156 struct stm32_uart_info *uart_info) 157 { 158 bool stm32f4 = uart_info->stm32f4; 159 u8 uart_enable_bit = uart_info->uart_enable_bit; 160 161 /* Disable uart-> enable fifo -> enable uart */ 162 clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE | 163 BIT(uart_enable_bit)); 164 if (uart_info->has_fifo) 165 setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN); 166 setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE | 167 BIT(uart_enable_bit)); 168 } 169 170 static int stm32_serial_probe(struct udevice *dev) 171 { 172 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 173 struct clk clk; 174 int ret; 175 176 plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev); 177 178 ret = clk_get_by_index(dev, 0, &clk); 179 if (ret < 0) 180 return ret; 181 182 ret = clk_enable(&clk); 183 if (ret) { 184 dev_err(dev, "failed to enable clock\n"); 185 return ret; 186 } 187 188 plat->clock_rate = clk_get_rate(&clk); 189 if (plat->clock_rate < 0) { 190 clk_disable(&clk); 191 return plat->clock_rate; 192 }; 193 194 _stm32_serial_init(plat->base, plat->uart_info); 195 196 return 0; 197 } 198 199 static const struct udevice_id stm32_serial_id[] = { 200 { .compatible = "st,stm32-uart", .data = (ulong)&stm32f4_info}, 201 { .compatible = "st,stm32f7-uart", .data = (ulong)&stm32f7_info}, 202 { .compatible = "st,stm32h7-uart", .data = (ulong)&stm32h7_info}, 203 {} 204 }; 205 206 static int stm32_serial_ofdata_to_platdata(struct udevice *dev) 207 { 208 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 209 210 plat->base = devfdt_get_addr(dev); 211 if (plat->base == FDT_ADDR_T_NONE) 212 return -EINVAL; 213 214 return 0; 215 } 216 217 static const struct dm_serial_ops stm32_serial_ops = { 218 .putc = stm32_serial_putc, 219 .pending = stm32_serial_pending, 220 .getc = stm32_serial_getc, 221 .setbrg = stm32_serial_setbrg, 222 .setconfig = stm32_serial_setconfig 223 }; 224 225 U_BOOT_DRIVER(serial_stm32) = { 226 .name = "serial_stm32", 227 .id = UCLASS_SERIAL, 228 .of_match = of_match_ptr(stm32_serial_id), 229 .ofdata_to_platdata = of_match_ptr(stm32_serial_ofdata_to_platdata), 230 .platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata), 231 .ops = &stm32_serial_ops, 232 .probe = stm32_serial_probe, 233 .flags = DM_FLAG_PRE_RELOC, 234 }; 235 236 #ifdef CONFIG_DEBUG_UART_STM32 237 #include <debug_uart.h> 238 static inline struct stm32_uart_info *_debug_uart_info(void) 239 { 240 struct stm32_uart_info *uart_info; 241 242 #if defined(CONFIG_STM32F4) 243 uart_info = &stm32f4_info; 244 #elif defined(CONFIG_STM32F7) 245 uart_info = &stm32f7_info; 246 #else 247 uart_info = &stm32h7_info; 248 #endif 249 return uart_info; 250 } 251 252 static inline void _debug_uart_init(void) 253 { 254 fdt_addr_t base = CONFIG_DEBUG_UART_BASE; 255 struct stm32_uart_info *uart_info = _debug_uart_info(); 256 257 _stm32_serial_init(base, uart_info); 258 _stm32_serial_setbrg(base, uart_info, 259 CONFIG_DEBUG_UART_CLOCK, 260 CONFIG_BAUDRATE); 261 printf("DEBUG done\n"); 262 } 263 264 static inline void _debug_uart_putc(int c) 265 { 266 fdt_addr_t base = CONFIG_DEBUG_UART_BASE; 267 struct stm32_uart_info *uart_info = _debug_uart_info(); 268 269 while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN) 270 WATCHDOG_RESET(); 271 } 272 273 DEBUG_UART_FUNCS 274 #endif 275