Skip to content

Commit bd5305d

Browse files
fugangduangregkh
authored andcommitted
tty: serial: fsl_lpuart: do software reset for imx7ulp and imx8qxp
Do software reset for communication port on imx7ulp and imx8qxp after the port is registered if the UART controller support the feature. Do partition reset with LPUART's power on, LPUART registers will keep the previous status, like on i.MX8QXP platform, which is not expected action, so need to set the RST bit of GLOBAL register to reset all uart internal logic and registers. Currently, only i.MX7ULP and i.MX8QXP LPUART controllers include global register that support the software reset. Signed-off-by: Fugang Duan <[email protected]> Signed-off-by: Sherry Sun <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4842215 commit bd5305d

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

drivers/tty/serial/fsl_lpuart.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <linux/clk.h>
99
#include <linux/console.h>
10+
#include <linux/delay.h>
1011
#include <linux/dma-mapping.h>
1112
#include <linux/dmaengine.h>
1213
#include <linux/dmapool.h>
@@ -109,6 +110,11 @@
109110
#define UARTSFIFO_TXOF 0x02
110111
#define UARTSFIFO_RXUF 0x01
111112

113+
/* 32-bit global registers only for i.MX7ULP/i.MX8x
114+
* Used to reset all internal logic and registers, except the Global Register.
115+
*/
116+
#define UART_GLOBAL 0x8
117+
112118
/* 32-bit register definition */
113119
#define UARTBAUD 0x00
114120
#define UARTSTAT 0x04
@@ -219,6 +225,10 @@
219225
#define UARTWATER_TXWATER_OFF 0
220226
#define UARTWATER_RXWATER_OFF 16
221227

228+
#define UART_GLOBAL_RST 0x2
229+
#define GLOBAL_RST_MIN_US 20
230+
#define GLOBAL_RST_MAX_US 40
231+
222232
/* Rx DMA timeout in ms, which is used to calculate Rx ring buffer size */
223233
#define DMA_RX_TIMEOUT (10)
224234

@@ -320,6 +330,11 @@ static inline bool is_layerscape_lpuart(struct lpuart_port *sport)
320330
sport->devtype == LS1028A_LPUART);
321331
}
322332

333+
static inline bool is_imx7ulp_lpuart(struct lpuart_port *sport)
334+
{
335+
return sport->devtype == IMX7ULP_LPUART;
336+
}
337+
323338
static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport)
324339
{
325340
return sport->devtype == IMX8QXP_LPUART;
@@ -383,6 +398,33 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport)
383398
#define lpuart_enable_clks(x) __lpuart_enable_clks(x, true)
384399
#define lpuart_disable_clks(x) __lpuart_enable_clks(x, false)
385400

401+
static int lpuart_global_reset(struct lpuart_port *sport)
402+
{
403+
struct uart_port *port = &sport->port;
404+
void __iomem *global_addr;
405+
int ret;
406+
407+
if (uart_console(port))
408+
return 0;
409+
410+
ret = clk_prepare_enable(sport->ipg_clk);
411+
if (ret) {
412+
dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
413+
return ret;
414+
}
415+
416+
if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) {
417+
global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF;
418+
writel(UART_GLOBAL_RST, global_addr);
419+
usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
420+
writel(0, global_addr);
421+
usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
422+
}
423+
424+
clk_disable_unprepare(sport->ipg_clk);
425+
return 0;
426+
}
427+
386428
static void lpuart_stop_tx(struct uart_port *port)
387429
{
388430
unsigned char temp;
@@ -2699,6 +2741,10 @@ static int lpuart_probe(struct platform_device *pdev)
26992741
if (ret)
27002742
goto failed_attach_port;
27012743

2744+
ret = lpuart_global_reset(sport);
2745+
if (ret)
2746+
goto failed_reset;
2747+
27022748
ret = uart_get_rs485_mode(&sport->port);
27032749
if (ret)
27042750
goto failed_get_rs485;
@@ -2715,6 +2761,8 @@ static int lpuart_probe(struct platform_device *pdev)
27152761
return 0;
27162762

27172763
failed_get_rs485:
2764+
failed_reset:
2765+
uart_remove_one_port(&lpuart_reg, &sport->port);
27182766
failed_attach_port:
27192767
failed_irq_request:
27202768
lpuart_disable_clks(sport);

0 commit comments

Comments
 (0)