xref: /rk3399_rockchip-uboot/drivers/serial/serial_stm32x7.c (revision a359eaa59857079678a2fa5ff0e4c0894de4ee1d)
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 <dm.h>
10 #include <asm/io.h>
11 #include <serial.h>
12 #include <dm/platform_data/serial_stm32x7.h>
13 #include "serial_stm32x7.h"
14 
15 DECLARE_GLOBAL_DATA_PTR;
16 
17 static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
18 {
19 	struct stm32x7_serial_platdata *plat = dev->platdata;
20 	struct stm32_usart *const usart = plat->base;
21 	writel(plat->clock/baudrate, &usart->brr);
22 
23 	return 0;
24 }
25 
26 static int stm32_serial_getc(struct udevice *dev)
27 {
28 	struct stm32x7_serial_platdata *plat = dev->platdata;
29 	struct stm32_usart *const usart = plat->base;
30 
31 	if ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0)
32 		return -EAGAIN;
33 
34 	return readl(&usart->rd_dr);
35 }
36 
37 static int stm32_serial_putc(struct udevice *dev, const char c)
38 {
39 	struct stm32x7_serial_platdata *plat = dev->platdata;
40 	struct stm32_usart *const usart = plat->base;
41 
42 	if ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0)
43 		return -EAGAIN;
44 
45 	writel(c, &usart->tx_dr);
46 
47 	return 0;
48 }
49 
50 static int stm32_serial_pending(struct udevice *dev, bool input)
51 {
52 	struct stm32x7_serial_platdata *plat = dev->platdata;
53 	struct stm32_usart *const usart = plat->base;
54 
55 	if (input)
56 		return readl(&usart->sr) & USART_SR_FLAG_RXNE ? 1 : 0;
57 	else
58 		return readl(&usart->sr) & USART_SR_FLAG_TXE ? 0 : 1;
59 }
60 
61 static int stm32_serial_probe(struct udevice *dev)
62 {
63 	struct stm32x7_serial_platdata *plat = dev->platdata;
64 	struct stm32_usart *const usart = plat->base;
65 	setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE);
66 
67 	return 0;
68 }
69 
70 static const struct dm_serial_ops stm32_serial_ops = {
71 	.putc = stm32_serial_putc,
72 	.pending = stm32_serial_pending,
73 	.getc = stm32_serial_getc,
74 	.setbrg = stm32_serial_setbrg,
75 };
76 
77 U_BOOT_DRIVER(serial_stm32) = {
78 	.name = "serial_stm32x7",
79 	.id = UCLASS_SERIAL,
80 	.ops = &stm32_serial_ops,
81 	.probe = stm32_serial_probe,
82 	.flags = DM_FLAG_PRE_RELOC,
83 };
84