3 * Kamil Lulko, <kamil.lulko@gmail.com>
5 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/arch/stm32.h>
13 #include <dm/platform_data/serial_stm32.h>
25 #define USART_CR1_RE (1 << 2)
26 #define USART_CR1_TE (1 << 3)
27 #define USART_CR1_UE (1 << 13)
29 #define USART_SR_FLAG_RXNE (1 << 5)
30 #define USART_SR_FLAG_TXE (1 << 7)
32 #define USART_BRR_F_MASK 0xF
33 #define USART_BRR_M_SHIFT 4
34 #define USART_BRR_M_MASK 0xFFF0
36 DECLARE_GLOBAL_DATA_PTR
;
38 #define MAX_SERIAL_PORTS 4
41 * RCC USART specific definitions
43 #define RCC_ENR_USART1EN (1 << 4)
44 #define RCC_ENR_USART2EN (1 << 17)
45 #define RCC_ENR_USART3EN (1 << 18)
46 #define RCC_ENR_USART6EN (1 << 5)
48 /* Array used to figure out which RCC bit needs to be set */
49 static const unsigned long usart_port_rcc_pairs
[MAX_SERIAL_PORTS
][2] = {
50 { STM32_USART1_BASE
, RCC_ENR_USART1EN
},
51 { STM32_USART2_BASE
, RCC_ENR_USART2EN
},
52 { STM32_USART3_BASE
, RCC_ENR_USART3EN
},
53 { STM32_USART6_BASE
, RCC_ENR_USART6EN
}
56 static int stm32_serial_setbrg(struct udevice
*dev
, int baudrate
)
58 struct stm32_serial_platdata
*plat
= dev
->platdata
;
59 struct stm32_usart
*const usart
= plat
->base
;
60 u32 clock
, int_div
, frac_div
, tmp
;
62 if (((u32
)usart
& STM32_BUS_MASK
) == STM32_APB1PERIPH_BASE
)
63 clock
= clock_get(CLOCK_APB1
);
64 else if (((u32
)usart
& STM32_BUS_MASK
) == STM32_APB2PERIPH_BASE
)
65 clock
= clock_get(CLOCK_APB2
);
69 int_div
= (25 * clock
) / (4 * baudrate
);
70 tmp
= ((int_div
/ 100) << USART_BRR_M_SHIFT
) & USART_BRR_M_MASK
;
71 frac_div
= int_div
- (100 * (tmp
>> USART_BRR_M_SHIFT
));
72 tmp
|= (((frac_div
* 16) + 50) / 100) & USART_BRR_F_MASK
;
73 writel(tmp
, &usart
->brr
);
78 static int stm32_serial_getc(struct udevice
*dev
)
80 struct stm32_serial_platdata
*plat
= dev
->platdata
;
81 struct stm32_usart
*const usart
= plat
->base
;
83 if ((readl(&usart
->sr
) & USART_SR_FLAG_RXNE
) == 0)
86 return readl(&usart
->dr
);
89 static int stm32_serial_putc(struct udevice
*dev
, const char c
)
91 struct stm32_serial_platdata
*plat
= dev
->platdata
;
92 struct stm32_usart
*const usart
= plat
->base
;
94 if ((readl(&usart
->sr
) & USART_SR_FLAG_TXE
) == 0)
97 writel(c
, &usart
->dr
);
102 static int stm32_serial_pending(struct udevice
*dev
, bool input
)
104 struct stm32_serial_platdata
*plat
= dev
->platdata
;
105 struct stm32_usart
*const usart
= plat
->base
;
108 return readl(&usart
->sr
) & USART_SR_FLAG_RXNE
? 1 : 0;
110 return readl(&usart
->sr
) & USART_SR_FLAG_TXE
? 0 : 1;
113 static int stm32_serial_probe(struct udevice
*dev
)
115 struct stm32_serial_platdata
*plat
= dev
->platdata
;
116 struct stm32_usart
*const usart
= plat
->base
;
120 for (i
= 0; i
< MAX_SERIAL_PORTS
; i
++) {
121 if ((u32
)usart
== usart_port_rcc_pairs
[i
][0]) {
127 if (usart_port
== -1)
130 if (((u32
)usart
& STM32_BUS_MASK
) == STM32_APB1PERIPH_BASE
)
131 setbits_le32(&STM32_RCC
->apb1enr
,
132 usart_port_rcc_pairs
[usart_port
][1]);
133 else if (((u32
)usart
& STM32_BUS_MASK
) == STM32_APB2PERIPH_BASE
)
134 setbits_le32(&STM32_RCC
->apb2enr
,
135 usart_port_rcc_pairs
[usart_port
][1]);
139 setbits_le32(&usart
->cr1
, USART_CR1_RE
| USART_CR1_TE
| USART_CR1_UE
);
144 static const struct dm_serial_ops stm32_serial_ops
= {
145 .putc
= stm32_serial_putc
,
146 .pending
= stm32_serial_pending
,
147 .getc
= stm32_serial_getc
,
148 .setbrg
= stm32_serial_setbrg
,
151 U_BOOT_DRIVER(serial_stm32
) = {
152 .name
= "serial_stm32",
154 .ops
= &stm32_serial_ops
,
155 .probe
= stm32_serial_probe
,
156 .flags
= DM_FLAG_PRE_RELOC
,