1 /* 2 * (C) Copyright 2016 3 * Vikas Manocha, <vikas.manocha@st.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <clk.h> 10 #include <dm.h> 11 #include <asm/io.h> 12 #include <serial.h> 13 #include <asm/arch/stm32.h> 14 #include <dm/platform_data/serial_stm32x7.h> 15 #include "serial_stm32x7.h" 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 static int stm32_serial_setbrg(struct udevice *dev, int baudrate) 20 { 21 struct stm32x7_serial_platdata *plat = dev->platdata; 22 struct stm32_usart *const usart = plat->base; 23 u32 clock, int_div, frac_div, tmp; 24 25 if (((u32)usart & STM32_BUS_MASK) == APB1_PERIPH_BASE) 26 clock = clock_get(CLOCK_APB1); 27 else if (((u32)usart & STM32_BUS_MASK) == APB2_PERIPH_BASE) 28 clock = clock_get(CLOCK_APB2); 29 else 30 return -EINVAL; 31 32 int_div = (25 * clock) / (4 * baudrate); 33 tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK; 34 frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT)); 35 tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK; 36 writel(tmp, &usart->brr); 37 38 return 0; 39 } 40 41 static int stm32_serial_getc(struct udevice *dev) 42 { 43 struct stm32x7_serial_platdata *plat = dev->platdata; 44 struct stm32_usart *const usart = plat->base; 45 46 if ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) 47 return -EAGAIN; 48 49 return readl(&usart->rd_dr); 50 } 51 52 static int stm32_serial_putc(struct udevice *dev, const char c) 53 { 54 struct stm32x7_serial_platdata *plat = dev->platdata; 55 struct stm32_usart *const usart = plat->base; 56 57 if ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) 58 return -EAGAIN; 59 60 writel(c, &usart->tx_dr); 61 62 return 0; 63 } 64 65 static int stm32_serial_pending(struct udevice *dev, bool input) 66 { 67 struct stm32x7_serial_platdata *plat = dev->platdata; 68 struct stm32_usart *const usart = plat->base; 69 70 if (input) 71 return readl(&usart->sr) & USART_SR_FLAG_RXNE ? 1 : 0; 72 else 73 return readl(&usart->sr) & USART_SR_FLAG_TXE ? 0 : 1; 74 } 75 76 static int stm32_serial_probe(struct udevice *dev) 77 { 78 struct stm32x7_serial_platdata *plat = dev->platdata; 79 struct stm32_usart *const usart = plat->base; 80 81 #ifdef CONFIG_CLK 82 int ret; 83 struct clk clk; 84 85 ret = clk_get_by_index(dev, 0, &clk); 86 if (ret < 0) 87 return ret; 88 89 ret = clk_enable(&clk); 90 if (ret) { 91 dev_err(dev, "failed to enable clock\n"); 92 return ret; 93 } 94 #endif 95 96 /* Disable usart-> disable overrun-> enable usart */ 97 clrbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); 98 setbits_le32(&usart->cr3, USART_CR3_OVRDIS); 99 setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); 100 101 return 0; 102 } 103 104 #if CONFIG_IS_ENABLED(OF_CONTROL) 105 static const struct udevice_id stm32_serial_id[] = { 106 {.compatible = "st,stm32-usart"}, 107 {.compatible = "st,stm32-uart"}, 108 {} 109 }; 110 111 static int stm32_serial_ofdata_to_platdata(struct udevice *dev) 112 { 113 struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); 114 fdt_addr_t addr; 115 116 addr = devfdt_get_addr(dev); 117 if (addr == FDT_ADDR_T_NONE) 118 return -EINVAL; 119 120 plat->base = (struct stm32_usart *)addr; 121 122 return 0; 123 } 124 #endif 125 126 static const struct dm_serial_ops stm32_serial_ops = { 127 .putc = stm32_serial_putc, 128 .pending = stm32_serial_pending, 129 .getc = stm32_serial_getc, 130 .setbrg = stm32_serial_setbrg, 131 }; 132 133 U_BOOT_DRIVER(serial_stm32) = { 134 .name = "serial_stm32x7", 135 .id = UCLASS_SERIAL, 136 .of_match = of_match_ptr(stm32_serial_id), 137 .ofdata_to_platdata = of_match_ptr(stm32_serial_ofdata_to_platdata), 138 .platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata), 139 .ops = &stm32_serial_ops, 140 .probe = stm32_serial_probe, 141 .flags = DM_FLAG_PRE_RELOC, 142 }; 143