2 * (c) 2015 Paul Thacker <paul.thacker@microchip.com>
4 * SPDX-License-Identifier: GPL-2.0+
12 #include <mach/pic32.h>
13 #include <dt-bindings/clock/microchip,clock.h>
15 DECLARE_GLOBAL_DATA_PTR
;
17 /* UART Control Registers */
19 #define U_MODCLR (U_MOD + _CLR_OFFSET)
20 #define U_MODSET (U_MOD + _SET_OFFSET)
22 #define U_STACLR (U_STA + _CLR_OFFSET)
23 #define U_STASET (U_STA + _SET_OFFSET)
29 #define UART_ENABLE BIT(15)
32 #define UART_RX_ENABLE BIT(12)
33 #define UART_TX_BRK BIT(11)
34 #define UART_TX_ENABLE BIT(10)
35 #define UART_TX_FULL BIT(9)
36 #define UART_TX_EMPTY BIT(8)
37 #define UART_RX_OVER BIT(1)
38 #define UART_RX_DATA_AVAIL BIT(0)
40 struct pic32_uart_priv
{
46 * Initialize the serial port with the given baudrate.
47 * The settings are always 8 data bits, no parity, 1 stop bit, no start bits.
49 static int pic32_serial_init(void __iomem
*base
, ulong clk
, u32 baudrate
)
51 u32 div
= DIV_ROUND_CLOSEST(clk
, baudrate
* 16);
53 /* wait for TX FIFO to empty */
54 wait_for_bit(__func__
, base
+ U_STA
, UART_TX_EMPTY
,
55 true, CONFIG_SYS_HZ
, false);
58 writel(UART_TX_BRK
, base
+ U_STASET
);
60 /* disable and clear mode */
61 writel(0, base
+ U_MOD
);
62 writel(0, base
+ U_STA
);
64 /* set baud rate generator */
65 writel(div
- 1, base
+ U_BRG
);
67 /* enable the UART for TX and RX */
68 writel(UART_TX_ENABLE
| UART_RX_ENABLE
, base
+ U_STASET
);
71 writel(UART_ENABLE
, base
+ U_MODSET
);
75 /* Check whether any char pending in RX fifo */
76 static int pic32_uart_pending_input(void __iomem
*base
)
78 /* check if rx buffer overrun error has occurred */
79 if (readl(base
+ U_STA
) & UART_RX_OVER
) {
82 /* clear overrun error to keep receiving */
83 writel(UART_RX_OVER
, base
+ U_STACLR
);
86 /* In PIC32 there is no way to know number of outstanding
87 * chars in rx-fifo. Only it can be known whether there is any.
89 return readl(base
+ U_STA
) & UART_RX_DATA_AVAIL
;
92 static int pic32_uart_pending(struct udevice
*dev
, bool input
)
94 struct pic32_uart_priv
*priv
= dev_get_priv(dev
);
97 return pic32_uart_pending_input(priv
->base
);
99 return !(readl(priv
->base
+ U_STA
) & UART_TX_EMPTY
);
102 static int pic32_uart_setbrg(struct udevice
*dev
, int baudrate
)
104 struct pic32_uart_priv
*priv
= dev_get_priv(dev
);
106 return pic32_serial_init(priv
->base
, priv
->uartclk
, baudrate
);
109 static int pic32_uart_putc(struct udevice
*dev
, const char ch
)
111 struct pic32_uart_priv
*priv
= dev_get_priv(dev
);
113 /* Check if Tx FIFO is full */
114 if (readl(priv
->base
+ U_STA
) & UART_TX_FULL
)
117 /* pump the char to tx buffer */
118 writel(ch
, priv
->base
+ U_TXR
);
123 static int pic32_uart_getc(struct udevice
*dev
)
125 struct pic32_uart_priv
*priv
= dev_get_priv(dev
);
127 /* return error if RX fifo is empty */
128 if (!pic32_uart_pending_input(priv
->base
))
131 /* read the character from rx buffer */
132 return readl(priv
->base
+ U_RXR
) & 0xff;
135 static int pic32_uart_probe(struct udevice
*dev
)
137 struct pic32_uart_priv
*priv
= dev_get_priv(dev
);
144 addr
= fdtdec_get_addr_size(gd
->fdt_blob
, dev_of_offset(dev
), "reg",
146 if (addr
== FDT_ADDR_T_NONE
)
149 priv
->base
= ioremap(addr
, size
);
152 ret
= clk_get_by_index(dev
, 0, &clk
);
155 priv
->uartclk
= clk_get_rate(&clk
);
158 /* initialize serial */
159 return pic32_serial_init(priv
->base
, priv
->uartclk
, CONFIG_BAUDRATE
);
162 static const struct dm_serial_ops pic32_uart_ops
= {
163 .putc
= pic32_uart_putc
,
164 .pending
= pic32_uart_pending
,
165 .getc
= pic32_uart_getc
,
166 .setbrg
= pic32_uart_setbrg
,
169 static const struct udevice_id pic32_uart_ids
[] = {
170 { .compatible
= "microchip,pic32mzda-uart" },
174 U_BOOT_DRIVER(pic32_serial
) = {
175 .name
= "pic32-uart",
177 .of_match
= pic32_uart_ids
,
178 .probe
= pic32_uart_probe
,
179 .ops
= &pic32_uart_ops
,
180 .flags
= DM_FLAG_PRE_RELOC
,
181 .priv_auto_alloc_size
= sizeof(struct pic32_uart_priv
),
184 #ifdef CONFIG_DEBUG_UART_PIC32
185 #include <debug_uart.h>
187 static inline void _debug_uart_init(void)
189 void __iomem
*base
= (void __iomem
*)CONFIG_DEBUG_UART_BASE
;
191 pic32_serial_init(base
, CONFIG_DEBUG_UART_CLOCK
, CONFIG_BAUDRATE
);
194 static inline void _debug_uart_putc(int ch
)
196 writel(ch
, CONFIG_DEBUG_UART_BASE
+ U_TXR
);