1 // SPDX-License-Identifier: GPL-2.0
3 * Serial port driver for NXP LPC18xx/43xx UART
5 * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
8 * Copyright (c) 2014 MundoReader S.L.
9 * Matthias Brugger <matthias.bgg@gmail.com>
12 #include <linux/clk.h>
14 #include <linux/module.h>
16 #include <linux/platform_device.h>
20 /* Additional LPC18xx/43xx 8250 registers and bits */
21 #define LPC18XX_UART_RS485CTRL (0x04c / sizeof(u32))
22 #define LPC18XX_UART_RS485CTRL_NMMEN BIT(0)
23 #define LPC18XX_UART_RS485CTRL_DCTRL BIT(4)
24 #define LPC18XX_UART_RS485CTRL_OINV BIT(5)
25 #define LPC18XX_UART_RS485DLY (0x054 / sizeof(u32))
26 #define LPC18XX_UART_RS485DLY_MAX 255
28 struct lpc18xx_uart_data
{
29 struct uart_8250_dma dma
;
35 static int lpc18xx_rs485_config(struct uart_port
*port
,
36 struct serial_rs485
*rs485
)
38 struct uart_8250_port
*up
= up_to_u8250p(port
);
39 u32 rs485_ctrl_reg
= 0;
40 u32 rs485_dly_reg
= 0;
43 if (rs485
->flags
& SER_RS485_ENABLED
)
44 memset(rs485
->padding
, 0, sizeof(rs485
->padding
));
46 memset(rs485
, 0, sizeof(*rs485
));
48 rs485
->flags
&= SER_RS485_ENABLED
| SER_RS485_RTS_ON_SEND
|
49 SER_RS485_RTS_AFTER_SEND
;
51 if (rs485
->flags
& SER_RS485_ENABLED
) {
52 rs485_ctrl_reg
|= LPC18XX_UART_RS485CTRL_NMMEN
|
53 LPC18XX_UART_RS485CTRL_DCTRL
;
55 if (rs485
->flags
& SER_RS485_RTS_ON_SEND
) {
56 rs485_ctrl_reg
|= LPC18XX_UART_RS485CTRL_OINV
;
57 rs485
->flags
&= ~SER_RS485_RTS_AFTER_SEND
;
59 rs485
->flags
|= SER_RS485_RTS_AFTER_SEND
;
63 if (rs485
->delay_rts_after_send
) {
64 baud_clk
= port
->uartclk
/ up
->dl_read(up
);
65 rs485_dly_reg
= DIV_ROUND_UP(rs485
->delay_rts_after_send
66 * baud_clk
, MSEC_PER_SEC
);
68 if (rs485_dly_reg
> LPC18XX_UART_RS485DLY_MAX
)
69 rs485_dly_reg
= LPC18XX_UART_RS485DLY_MAX
;
71 /* Calculate the resulting delay in ms */
72 rs485
->delay_rts_after_send
= (rs485_dly_reg
* MSEC_PER_SEC
)
76 /* Delay RTS before send not supported */
77 rs485
->delay_rts_before_send
= 0;
79 serial_out(up
, LPC18XX_UART_RS485CTRL
, rs485_ctrl_reg
);
80 serial_out(up
, LPC18XX_UART_RS485DLY
, rs485_dly_reg
);
87 static void lpc18xx_uart_serial_out(struct uart_port
*p
, int offset
, int value
)
90 * For DMA mode one must ensure that the UART_FCR_DMA_SELECT
91 * bit is set when FIFO is enabled. Even if DMA is not used
92 * setting this bit doesn't seem to affect anything.
94 if (offset
== UART_FCR
&& (value
& UART_FCR_ENABLE_FIFO
))
95 value
|= UART_FCR_DMA_SELECT
;
97 offset
= offset
<< p
->regshift
;
98 writel(value
, p
->membase
+ offset
);
101 static int lpc18xx_serial_probe(struct platform_device
*pdev
)
103 struct lpc18xx_uart_data
*data
;
104 struct uart_8250_port uart
;
105 struct resource
*res
;
108 irq
= platform_get_irq(pdev
, 0);
112 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
114 dev_err(&pdev
->dev
, "memory resource not found");
118 memset(&uart
, 0, sizeof(uart
));
120 uart
.port
.membase
= devm_ioremap(&pdev
->dev
, res
->start
,
122 if (!uart
.port
.membase
)
125 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
129 data
->clk_uart
= devm_clk_get(&pdev
->dev
, "uartclk");
130 if (IS_ERR(data
->clk_uart
)) {
131 dev_err(&pdev
->dev
, "uart clock not found\n");
132 return PTR_ERR(data
->clk_uart
);
135 data
->clk_reg
= devm_clk_get(&pdev
->dev
, "reg");
136 if (IS_ERR(data
->clk_reg
)) {
137 dev_err(&pdev
->dev
, "reg clock not found\n");
138 return PTR_ERR(data
->clk_reg
);
141 ret
= clk_prepare_enable(data
->clk_reg
);
143 dev_err(&pdev
->dev
, "unable to enable reg clock\n");
147 ret
= clk_prepare_enable(data
->clk_uart
);
149 dev_err(&pdev
->dev
, "unable to enable uart clock\n");
153 ret
= of_alias_get_id(pdev
->dev
.of_node
, "serial");
155 uart
.port
.line
= ret
;
157 data
->dma
.rx_param
= data
;
158 data
->dma
.tx_param
= data
;
160 spin_lock_init(&uart
.port
.lock
);
161 uart
.port
.dev
= &pdev
->dev
;
163 uart
.port
.iotype
= UPIO_MEM32
;
164 uart
.port
.mapbase
= res
->start
;
165 uart
.port
.regshift
= 2;
166 uart
.port
.type
= PORT_16550A
;
167 uart
.port
.flags
= UPF_FIXED_PORT
| UPF_FIXED_TYPE
| UPF_SKIP_TEST
;
168 uart
.port
.uartclk
= clk_get_rate(data
->clk_uart
);
169 uart
.port
.private_data
= data
;
170 uart
.port
.rs485_config
= lpc18xx_rs485_config
;
171 uart
.port
.serial_out
= lpc18xx_uart_serial_out
;
173 uart
.dma
= &data
->dma
;
174 uart
.dma
->rxconf
.src_maxburst
= 1;
175 uart
.dma
->txconf
.dst_maxburst
= 1;
177 ret
= serial8250_register_8250_port(&uart
);
179 dev_err(&pdev
->dev
, "unable to register 8250 port\n");
184 platform_set_drvdata(pdev
, data
);
189 clk_disable_unprepare(data
->clk_uart
);
191 clk_disable_unprepare(data
->clk_reg
);
195 static int lpc18xx_serial_remove(struct platform_device
*pdev
)
197 struct lpc18xx_uart_data
*data
= platform_get_drvdata(pdev
);
199 serial8250_unregister_port(data
->line
);
200 clk_disable_unprepare(data
->clk_uart
);
201 clk_disable_unprepare(data
->clk_reg
);
206 static const struct of_device_id lpc18xx_serial_match
[] = {
207 { .compatible
= "nxp,lpc1850-uart" },
210 MODULE_DEVICE_TABLE(of
, lpc18xx_serial_match
);
212 static struct platform_driver lpc18xx_serial_driver
= {
213 .probe
= lpc18xx_serial_probe
,
214 .remove
= lpc18xx_serial_remove
,
216 .name
= "lpc18xx-uart",
217 .of_match_table
= lpc18xx_serial_match
,
220 module_platform_driver(lpc18xx_serial_driver
);
222 MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
223 MODULE_DESCRIPTION("Serial port driver NXP LPC18xx/43xx devices");
224 MODULE_LICENSE("GPL v2");