diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index b28f7cf68d..cee9e5e231 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <fsl_lpuart.h>
 #include <watchdog.h>
@@ -104,6 +105,29 @@ u32 __weak get_lpuart_clk(void)
 	return CONFIG_SYS_CLK_FREQ;
 }
 
+#if IS_ENABLED(CONFIG_CLK)
+ulong get_lpuart_clk_rate(struct udevice *dev)
+{
+	struct clk per_clk;
+	ulong rate;
+	int ret;
+
+	ret = clk_get_by_name(dev, "per", &per_clk);
+	if (ret) {
+		dev_err(dev, "Failed to get per clk: %d\n", ret);
+		return ret;
+	}
+
+	rate = clk_get_rate(&per_clk);
+	if ((long)rate <= 0) {
+		dev_err(dev, "Failed to get per clk rate: %ld\n", (long)rate);
+		return ret;
+	}
+
+	return  rate;
+}
+#endif
+
 static bool is_lpuart32(struct udevice *dev)
 {
 	struct lpuart_serial_platdata *plat = dev->platdata;
@@ -111,13 +135,19 @@ static bool is_lpuart32(struct udevice *dev)
 	return plat->flags & LPUART_FLAG_REGMAP_32BIT_REG;
 }
 
-static void _lpuart_serial_setbrg(struct lpuart_serial_platdata *plat,
+static void _lpuart_serial_setbrg(struct udevice *dev,
 				  int baudrate)
 {
+	struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
 	struct lpuart_fsl *base = plat->reg;
-	u32 clk = get_lpuart_clk();
+	u32 clk;
 	u16 sbr;
 
+	if (IS_ENABLED(CONFIG_CLK))
+		clk = get_lpuart_clk_rate(dev);
+	else
+		clk = get_lpuart_clk();
+
 	sbr = (u16)(clk / (16 * baudrate));
 
 	/* place adjustment later - n/32 BRFA */
@@ -162,8 +192,9 @@ static int _lpuart_serial_tstc(struct lpuart_serial_platdata *plat)
  * Initialise the serial port with the given baudrate. The settings
  * are always 8 data bits, no parity, 1 stop bit, no start bits.
  */
-static int _lpuart_serial_init(struct lpuart_serial_platdata *plat)
+static int _lpuart_serial_init(struct udevice *dev)
 {
+	struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
 	struct lpuart_fsl *base = (struct lpuart_fsl *)plat->reg;
 	u8 ctrl;
 
@@ -182,19 +213,25 @@ static int _lpuart_serial_init(struct lpuart_serial_platdata *plat)
 	__raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);
 
 	/* provide data bits, parity, stop bit, etc */
-	_lpuart_serial_setbrg(plat, gd->baudrate);
+	_lpuart_serial_setbrg(dev, gd->baudrate);
 
 	__raw_writeb(UC2_RE | UC2_TE, &base->uc2);
 
 	return 0;
 }
 
-static void _lpuart32_serial_setbrg_7ulp(struct lpuart_serial_platdata *plat,
+static void _lpuart32_serial_setbrg_7ulp(struct udevice *dev,
 					 int baudrate)
 {
+	struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
 	struct lpuart_fsl_reg32 *base = plat->reg;
 	u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
-	u32 clk = get_lpuart_clk();
+	u32 clk;
+
+	if (IS_ENABLED(CONFIG_CLK))
+		clk = get_lpuart_clk_rate(dev);
+	else
+		clk = get_lpuart_clk();
 
 	baud_diff = baudrate;
 	osr = 0;
@@ -248,13 +285,19 @@ static void _lpuart32_serial_setbrg_7ulp(struct lpuart_serial_platdata *plat,
 	out_le32(&base->baud, tmp);
 }
 
-static void _lpuart32_serial_setbrg(struct lpuart_serial_platdata *plat,
+static void _lpuart32_serial_setbrg(struct udevice *dev,
 				    int baudrate)
 {
+	struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
 	struct lpuart_fsl_reg32 *base = plat->reg;
-	u32 clk = get_lpuart_clk();
+	u32 clk;
 	u32 sbr;
 
+	if (IS_ENABLED(CONFIG_CLK))
+		clk = get_lpuart_clk_rate(dev);
+	else
+		clk = get_lpuart_clk();
+
 	sbr = (clk / (16 * baudrate));
 
 	/* place adjustment later - n/32 BRFA */
@@ -321,8 +364,9 @@ static int _lpuart32_serial_tstc(struct lpuart_serial_platdata *plat)
  * Initialise the serial port with the given baudrate. The settings
  * are always 8 data bits, no parity, 1 stop bit, no start bits.
  */
-static int _lpuart32_serial_init(struct lpuart_serial_platdata *plat)
+static int _lpuart32_serial_init(struct udevice *dev)
 {
+	struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
 	struct lpuart_fsl_reg32 *base = (struct lpuart_fsl_reg32 *)plat->reg;
 	u32 val, tx_fifo_size;
 
@@ -350,10 +394,10 @@ static int _lpuart32_serial_init(struct lpuart_serial_platdata *plat)
 	lpuart_write32(plat->flags, &base->match, 0);
 
 	if (plat->devtype == DEV_MX7ULP || plat->devtype == DEV_IMX8) {
-		_lpuart32_serial_setbrg_7ulp(plat, gd->baudrate);
+		_lpuart32_serial_setbrg_7ulp(dev, gd->baudrate);
 	} else {
 		/* provide data bits, parity, stop bit, etc */
-		_lpuart32_serial_setbrg(plat, gd->baudrate);
+		_lpuart32_serial_setbrg(dev, gd->baudrate);
 	}
 
 	lpuart_write32(plat->flags, &base->ctrl, CTRL_RE | CTRL_TE);
@@ -363,15 +407,15 @@ static int _lpuart32_serial_init(struct lpuart_serial_platdata *plat)
 
 static int lpuart_serial_setbrg(struct udevice *dev, int baudrate)
 {
-	struct lpuart_serial_platdata *plat = dev->platdata;
+	struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
 
 	if (is_lpuart32(dev)) {
 		if (plat->devtype == DEV_MX7ULP || plat->devtype == DEV_IMX8)
-			_lpuart32_serial_setbrg_7ulp(plat, baudrate);
+			_lpuart32_serial_setbrg_7ulp(dev, baudrate);
 		else
-			_lpuart32_serial_setbrg(plat, baudrate);
+			_lpuart32_serial_setbrg(dev, baudrate);
 	} else {
-		_lpuart_serial_setbrg(plat, baudrate);
+		_lpuart_serial_setbrg(dev, baudrate);
 	}
 
 	return 0;
@@ -423,12 +467,10 @@ static int lpuart_serial_pending(struct udevice *dev, bool input)
 
 static int lpuart_serial_probe(struct udevice *dev)
 {
-	struct lpuart_serial_platdata *plat = dev->platdata;
-
 	if (is_lpuart32(dev))
-		return _lpuart32_serial_init(plat);
+		return _lpuart32_serial_init(dev);
 	else
-		return _lpuart_serial_init(plat);
+		return _lpuart_serial_init(dev);
 }
 
 static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
