summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-03-02 13:44:46 -0600
committerTom Rini <[email protected]>2026-03-02 13:44:46 -0600
commitc0ca147ac6228949a6d6497531c9f2f4a0dc6c67 (patch)
tree203dffa4165dbe5c98fb0e2a4594185782d53dbb /drivers
parentf6963fc232603007c661411fb31c57f1a9678a87 (diff)
parent56e5f5290f2daf886bf6306f426cbb1171deac01 (diff)
Merge tag 'u-boot-imx-next-20260228' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx into next
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/29404 - Miscelanous improvements for Siemens Capricorn board. - Convert i.MX6 IPUv3 driver to use clock framework. - Skip voltage switching for fixed 1.8V regulator on fsl_esdhc_imx. - Support printing imx8m pinmux. - Enter fastboot on USB boot by default on phycore-imx93. - Use arch override for env_get_location() on imx95.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/imx/clk-imx6q.c424
-rw-r--r--drivers/clk/imx/clk.h9
-rw-r--r--drivers/misc/imx8/scu_api.c25
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c5
-rw-r--r--drivers/pinctrl/nxp/Kconfig6
-rw-r--r--drivers/pinctrl/nxp/Makefile2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx.h8
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx8m.c62
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx8mm.c310
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx8mn.c310
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx8mp.c309
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx8mq.c310
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx9.c89
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx91.c228
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx93.c244
-rw-r--r--drivers/pwm/pwm-imx.c44
-rw-r--r--drivers/video/imx/Kconfig7
-rw-r--r--drivers/video/imx/Makefile1
-rw-r--r--drivers/video/imx/ipu.h60
-rw-r--r--drivers/video/imx/ipu_clk_legacy.c310
-rw-r--r--drivers/video/imx/ipu_common.c371
-rw-r--r--drivers/video/imx/ipu_disp.c142
-rw-r--r--drivers/video/imx/mxc_ipuv3_fb.c17
23 files changed, 2838 insertions, 455 deletions
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index b69355cefc7..f57ac79f8ca 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -13,6 +13,21 @@
#include "clk.h"
+#define SET_CLK_RATE(id, rate) \
+ do { \
+ struct clk *clk; \
+ clk_get_by_id(id, &clk); \
+ clk_set_rate(clk, rate); \
+ } while (0)
+
+#define SET_CLK_PARENT(child_id, parent_id) \
+ do { \
+ struct clk *clk, *clk_parent; \
+ clk_get_by_id(parent_id, &clk_parent); \
+ clk_get_by_id(child_id, &clk); \
+ clk_set_parent(clk, clk_parent); \
+ } while (0)
+
static int imx6q_clk_request(struct clk *clk)
{
if (clk->id < IMX6QDL_CLK_DUMMY || clk->id >= IMX6QDL_CLK_END) {
@@ -31,12 +46,72 @@ static struct clk_ops imx6q_clk_ops = {
.disable = ccf_clk_disable,
};
-static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
-static const char *const periph_sels[] = { "periph_pre", "periph_clk2", };
-static const char *const periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m",
- "pll2_pfd0_352m", "pll2_198m", };
-static const char *const uart_sels[] = { "pll3_80m", "osc", };
-static const char *const ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *const usdhc_sels[] = {
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m",
+};
+static const char *const periph_sels[] = {
+ "periph_pre",
+ "periph_clk2",
+};
+static const char *periph2_sels[] = {
+ "periph2_pre",
+ "periph2_clk2",
+};
+static const char *const periph_pre_sels[] = {
+ "pll2_bus",
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m",
+ "pll2_198m",
+};
+static const char *const uart_sels[] = {
+ "pll3_80m",
+ "osc",
+};
+static const char *const ecspi_sels[] = {
+ "pll3_60m",
+ "osc",
+};
+static const char *const ipu_sels[] = {
+ "mmdc_ch0_axi",
+ "pll2_pfd2_396m",
+ "pll3_120m",
+ "pll3_pfd1_540m",
+};
+static const char *const ldb_di_sels[] = {
+ "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m",
+ "mmdc_ch1_axi", "pll3_usb_otg",
+};
+static const char *const ipu_di_pre_sels[] = {
+ "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div",
+ "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m",
+};
+static const char *const ipu1_di0_sels[] = {
+ "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1",
+};
+static const char *const ipu1_di1_sels[] = {
+ "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1",
+};
+static const char *const ipu2_di0_sels[] = {
+ "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1",
+};
+static const char *const ipu2_di1_sels[] = {
+ "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1",
+};
+static const char *ipu1_di0_sels_2[] = {
+ "ipu1_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf",
+};
+static const char *ipu1_di1_sels_2[] = {
+ "ipu1_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf",
+};
+static const char *ipu2_di0_sels_2[] = {
+ "ipu2_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf",
+};
+static const char *ipu2_di1_sels_2[] = {
+ "ipu2_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf",
+};
+
+static unsigned int share_count_mipi_core_cfg;
static int imx6q_clk_probe(struct udevice *dev)
{
@@ -52,15 +127,37 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_pllv3(dev, IMX_PLLV3_USB, "pll3_usb_otg", "osc",
base + 0x10, 0x3));
clk_dm(IMX6QDL_CLK_PLL3_60M,
- imx_clk_fixed_factor(dev, "pll3_60m", "pll3_usb_otg", 1, 8));
+ imx_clk_fixed_factor(dev, "pll3_60m", "pll3_usb_otg", 1, 8));
+ clk_dm(IMX6QDL_CLK_PLL3_80M,
+ imx_clk_fixed_factor(dev, "pll3_80m", "pll3_usb_otg", 1, 6));
+ clk_dm(IMX6QDL_CLK_PLL3_120M,
+ imx_clk_fixed_factor(dev, "pll3_120m", "pll3_usb_otg", 1, 4));
+ clk_dm(IMX6QDL_CLK_PLL5, imx_clk_pllv3(dev, IMX_PLLV3_AV, "pll5", "osc",
+ base + 0xa0, 0x7f));
+ clk_dm(IMX6QDL_CLK_PLL5_VIDEO,
+ imx_clk_gate(dev, "pll5_video", "pll5", base + 0xa0, 13));
+ clk_dm(IMX6QDL_CLK_PLL6, imx_clk_pllv3(dev, IMX_PLLV3_ENET, "pll6",
+ "osc", base + 0xe0, 0x3));
+ clk_dm(IMX6QDL_CLK_PLL6_ENET,
+ imx_clk_gate(dev, "pll6_enet", "pll6", base + 0xe0, 13));
+
clk_dm(IMX6QDL_CLK_PLL2_PFD0_352M,
imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0));
clk_dm(IMX6QDL_CLK_PLL2_PFD2_396M,
imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2));
- clk_dm(IMX6QDL_CLK_PLL6,
- imx_clk_pllv3(dev, IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3));
- clk_dm(IMX6QDL_CLK_PLL6_ENET,
- imx_clk_gate(dev, "pll6_enet", "pll6", base + 0xe0, 13));
+ clk_dm(IMX6QDL_CLK_PLL3_PFD1_540M,
+ imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1));
+
+ clk_dm(IMX6QDL_CLK_PLL2_198M,
+ imx_clk_fixed_factor(dev, "pll2_198m", "pll2_pfd2_396m", 1, 2));
+ clk_dm(IMX6QDL_CLK_PLL5_POST_DIV,
+ imx_clk_fixed_factor(dev, "pll5_post_div", "pll5_video", 1, 1));
+ clk_dm(IMX6QDL_CLK_PLL5_VIDEO_DIV,
+ imx_clk_fixed_factor(dev, "pll5_video_div", "pll5_post_div", 1,
+ 1));
+ clk_dm(IMX6QDL_CLK_VIDEO_27M,
+ imx_clk_fixed_factor(dev, "video_27m", "pll3_pfd1_540m", 1,
+ 20));
/* CCM clocks */
base = dev_read_addr_ptr(dev);
@@ -68,50 +165,253 @@ static int imx6q_clk_probe(struct udevice *dev)
return -EINVAL;
clk_dm(IMX6QDL_CLK_USDHC1_SEL,
- imx_clk_mux(dev, "usdhc1_sel", base + 0x1c, 16, 1,
- usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+ imx_clk_mux(dev, "usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels,
+ ARRAY_SIZE(usdhc_sels)));
clk_dm(IMX6QDL_CLK_USDHC2_SEL,
- imx_clk_mux(dev, "usdhc2_sel", base + 0x1c, 17, 1,
- usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+ imx_clk_mux(dev, "usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels,
+ ARRAY_SIZE(usdhc_sels)));
clk_dm(IMX6QDL_CLK_USDHC3_SEL,
- imx_clk_mux(dev, "usdhc3_sel", base + 0x1c, 18, 1,
- usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+ imx_clk_mux(dev, "usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels,
+ ARRAY_SIZE(usdhc_sels)));
clk_dm(IMX6QDL_CLK_USDHC4_SEL,
- imx_clk_mux(dev, "usdhc4_sel", base + 0x1c, 19, 1,
- usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+ imx_clk_mux(dev, "usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels,
+ ARRAY_SIZE(usdhc_sels)));
if (of_machine_is_compatible("fsl,imx6qp")) {
clk_dm(IMX6QDL_CLK_UART_SEL,
- imx_clk_mux(dev, "uart_sel", base + 0x24, 6, 1, uart_sels,
- ARRAY_SIZE(uart_sels)));
+ imx_clk_mux(dev, "uart_sel", base + 0x24, 6, 1,
+ uart_sels, ARRAY_SIZE(uart_sels)));
clk_dm(IMX6QDL_CLK_ECSPI_SEL,
- imx_clk_mux(dev, "ecspi_sel", base + 0x38, 18, 1, ecspi_sels,
- ARRAY_SIZE(ecspi_sels)));
+ imx_clk_mux(dev, "ecspi_sel", base + 0x38, 18, 1,
+ ecspi_sels, ARRAY_SIZE(ecspi_sels)));
}
+ clk_dm(IMX6QDL_CLK_PERIPH_PRE,
+ imx_clk_mux(dev, "periph_pre", base + 0x18, 18, 2,
+ periph_pre_sels, ARRAY_SIZE(periph_pre_sels)));
+ clk_dm(IMX6QDL_CLK_PERIPH2_PRE,
+ imx_clk_mux(dev, "periph2_pre", base + 0x18, 21, 2,
+ periph_pre_sels, ARRAY_SIZE(periph_pre_sels)));
+ clk_dm(IMX6QDL_CLK_PERIPH,
+ imx_clk_busy_mux(dev, "periph", base + 0x14, 25, 1, base + 0x48,
+ 5, periph_sels, ARRAY_SIZE(periph_sels)));
+ clk_dm(IMX6QDL_CLK_PERIPH2,
+ imx_clk_busy_mux(dev, "periph2", base + 0x14, 26, 1, base + 0x48,
+ 3, periph2_sels, ARRAY_SIZE(periph2_sels)));
+
clk_dm(IMX6QDL_CLK_USDHC1_PODF,
- imx_clk_divider(dev, "usdhc1_podf", "usdhc1_sel",
- base + 0x24, 11, 3));
+ imx_clk_divider(dev, "usdhc1_podf", "usdhc1_sel", base + 0x24,
+ 11, 3));
clk_dm(IMX6QDL_CLK_USDHC2_PODF,
- imx_clk_divider(dev, "usdhc2_podf", "usdhc2_sel",
- base + 0x24, 16, 3));
+ imx_clk_divider(dev, "usdhc2_podf", "usdhc2_sel", base + 0x24,
+ 16, 3));
clk_dm(IMX6QDL_CLK_USDHC3_PODF,
- imx_clk_divider(dev, "usdhc3_podf", "usdhc3_sel",
- base + 0x24, 19, 3));
+ imx_clk_divider(dev, "usdhc3_podf", "usdhc3_sel", base + 0x24,
+ 19, 3));
clk_dm(IMX6QDL_CLK_USDHC4_PODF,
- imx_clk_divider(dev, "usdhc4_podf", "usdhc4_sel",
- base + 0x24, 22, 3));
+ imx_clk_divider(dev, "usdhc4_podf", "usdhc4_sel", base + 0x24,
+ 22, 3));
if (of_machine_is_compatible("fsl,imx6qp")) {
clk_dm(IMX6QDL_CLK_UART_SERIAL_PODF,
- imx_clk_divider(dev, "uart_serial_podf", "uart_sel", base + 0x24, 0, 6));
+ imx_clk_divider(dev, "uart_serial_podf", "uart_sel",
+ base + 0x24, 0, 6));
clk_dm(IMX6QDL_CLK_ECSPI_ROOT,
- imx_clk_divider(dev, "ecspi_root", "ecspi_sel", base + 0x38, 19, 6));
+ imx_clk_divider(dev, "ecspi_root", "ecspi_sel",
+ base + 0x38, 19, 6));
} else {
clk_dm(IMX6QDL_CLK_UART_SERIAL_PODF,
- imx_clk_divider(dev, "uart_serial_podf", "pll3_80m", base + 0x24, 0, 6));
+ imx_clk_divider(dev, "uart_serial_podf", "pll3_80m",
+ base + 0x24, 0, 6));
clk_dm(IMX6QDL_CLK_ECSPI_ROOT,
- imx_clk_divider(dev, "ecspi_root", "pll3_60m", base + 0x38, 19, 6));
+ imx_clk_divider(dev, "ecspi_root", "pll3_60m",
+ base + 0x38, 19, 6));
+ }
+
+ clk_dm(IMX6QDL_CLK_AHB,
+ imx_clk_busy_divider(dev, "ahb", "periph", base + 0x14, 10, 3,
+ base + 0x48, 1));
+ clk_dm(IMX6QDL_CLK_IPG,
+ imx_clk_divider(dev, "ipg", "ahb", base + 0x14, 8, 2));
+ clk_dm(IMX6QDL_CLK_IPG_PER,
+ imx_clk_divider(dev, "ipg_per", "ipg", base + 0x1c, 0, 6));
+ clk_dm(IMX6QDL_CLK_UART_IPG,
+ imx_clk_gate2(dev, "uart_ipg", "ipg", base + 0x7c, 24));
+
+ if (of_machine_is_compatible("fsl,imx6qp")) {
+ clk_dm(IMX6QDL_CLK_MMDC_CH1_AXI_CG,
+ imx_clk_gate2(dev, "mmdc_ch1_axi_cg", "periph2",
+ base + 0x4, 18));
+ clk_dm(IMX6QDL_CLK_MMDC_CH1_AXI_PODF,
+ imx_clk_busy_divider(dev, "mmdc_ch1_axi_podf",
+ "mmdc_ch1_axi_cg", base + 0x14, 3,
+ 3, base + 0x48, 2));
+ } else {
+ clk_dm(IMX6QDL_CLK_MMDC_CH1_AXI_PODF,
+ imx_clk_busy_divider(dev, "mmdc_ch1_axi_podf", "periph2",
+ base + 0x14, 3, 3, base + 0x48, 2));
+ }
+
+ clk_dm(IMX6QDL_CLK_MMDC_CH0_AXI_PODF,
+ imx_clk_busy_divider(dev, "mmdc_ch0_axi_podf", "periph",
+ base + 0x14, 19, 3, base + 0x48, 4));
+
+ clk_dm(IMX6QDL_CLK_MMDC_CH0_AXI,
+ imx_clk_gate2_flags(dev, "mmdc_ch0_axi", "mmdc_ch0_axi_podf",
+ base + 0x74, 20, CLK_IS_CRITICAL));
+ clk_dm(IMX6QDL_CLK_MMDC_CH1_AXI,
+ imx_clk_gate2(dev, "mmdc_ch1_axi", "mmdc_ch1_axi_podf",
+ base + 0x74, 22));
+
+ clk_dm(IMX6QDL_CLK_IPU1_SEL,
+ imx_clk_mux(dev, "ipu1_sel", base + 0x3c, 9, 2, ipu_sels,
+ ARRAY_SIZE(ipu_sels)));
+ clk_dm(IMX6QDL_CLK_IPU2_SEL,
+ imx_clk_mux(dev, "ipu2_sel", base + 0x3c, 14, 2, ipu_sels,
+ ARRAY_SIZE(ipu_sels)));
+
+ if (of_machine_is_compatible("fsl,imx6qp")) {
+ clk_dm(IMX6QDL_CLK_LDB_DI0_SEL,
+ imx_clk_mux(dev, "ldb_di0_sel", base + 0x2c, 9, 3,
+ ldb_di_sels, ARRAY_SIZE(ldb_di_sels)));
+ clk_dm(IMX6QDL_CLK_LDB_DI1_SEL,
+ imx_clk_mux(dev, "ldb_di1_sel", base + 0x2c, 12, 3,
+ ldb_di_sels, ARRAY_SIZE(ldb_di_sels)));
+ } else {
+ /*
+ * Need to set these as read-only due to a hardware bug.
+ * Keeping default mux values. Fixed on the i.MX6 QuadPlus
+ */
+ clk_dm(IMX6QDL_CLK_LDB_DI0_SEL,
+ imx_clk_mux_flags(dev, "ldb_di0_sel", base + 0x2c, 9, 3,
+ ldb_di_sels, ARRAY_SIZE(ldb_di_sels),
+ CLK_SET_RATE_PARENT |
+ CLK_MUX_READ_ONLY));
+ clk_dm(IMX6QDL_CLK_LDB_DI1_SEL,
+ imx_clk_mux_flags(dev, "ldb_di1_sel", base + 0x2c, 12, 3,
+ ldb_di_sels, ARRAY_SIZE(ldb_di_sels),
+ CLK_SET_RATE_PARENT |
+ CLK_MUX_READ_ONLY));
+ }
+
+ clk_dm(IMX6QDL_CLK_IPU1_DI0_PRE_SEL,
+ imx_clk_mux_flags(dev, "ipu1_di0_pre_sel", base + 0x34, 6, 3,
+ ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU1_DI1_PRE_SEL,
+ imx_clk_mux_flags(dev, "ipu1_di1_pre_sel", base + 0x34, 15, 3,
+ ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU2_DI0_PRE_SEL,
+ imx_clk_mux_flags(dev, "ipu2_di0_pre_sel", base + 0x38, 6, 3,
+ ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU2_DI1_PRE_SEL,
+ imx_clk_mux_flags(dev, "ipu2_di1_pre_sel", base + 0x38, 15, 3,
+ ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels),
+ CLK_SET_RATE_PARENT));
+
+ if (of_machine_is_compatible("fsl,imx6qp")) {
+ clk_dm(IMX6QDL_CLK_LDB_DI0,
+ imx_clk_gate2(dev, "ldb_di0", "ldb_di0_sel", base + 0x74,
+ 12));
+ clk_dm(IMX6QDL_CLK_LDB_DI1,
+ imx_clk_gate2(dev, "ldb_di1", "ldb_di1_sel", base + 0x74,
+ 14));
+ clk_dm(IMX6QDL_CLK_LDB_DI0_DIV_3_5,
+ imx_clk_fixed_factor(dev, "ldb_di0_div_3_5", "ldb_di0",
+ 2, 7));
+ clk_dm(IMX6QDL_CLK_LDB_DI1_DIV_3_5,
+ imx_clk_fixed_factor(dev, "ldb_di1_div_3_5", "ldb_di1",
+ 2, 7));
+ clk_dm(IMX6QDL_CLK_LDB_DI0_PODF,
+ imx_clk_divider(dev, "ldb_di0_podf", "ldb_di0_div_3_5",
+ base + 0x20, 10, 1));
+ clk_dm(IMX6QDL_CLK_LDB_DI1_PODF,
+ imx_clk_divider(dev, "ldb_di1_podf", "ldb_di1_div_3_5",
+ base + 0x20, 11, 1));
+ } else {
+ clk_dm(IMX6QDL_CLK_LDB_DI0_DIV_3_5,
+ imx_clk_fixed_factor(dev, "ldb_di0_div_3_5",
+ "ldb_di0_sel", 2, 7));
+ clk_dm(IMX6QDL_CLK_LDB_DI1_DIV_3_5,
+ imx_clk_fixed_factor(dev, "ldb_di1_div_3_5",
+ "ldb_di1_sel", 2, 7));
+ clk_dm(IMX6QDL_CLK_LDB_DI0_PODF,
+ imx_clk_divider(dev, "ldb_di0_podf", "ldb_di0_div_3_5",
+ base + 0x20, 10, 1));
+ clk_dm(IMX6QDL_CLK_LDB_DI1_PODF,
+ imx_clk_divider(dev, "ldb_di1_podf", "ldb_di1_div_3_5",
+ base + 0x20, 11, 1));
+ clk_dm(IMX6QDL_CLK_LDB_DI0,
+ imx_clk_gate2(dev, "ldb_di0", "ldb_di0_podf",
+ base + 0x74, 12));
+ clk_dm(IMX6QDL_CLK_LDB_DI1,
+ imx_clk_gate2(dev, "ldb_di1", "ldb_di1_podf",
+ base + 0x74, 14));
+ }
+
+ clk_dm(IMX6QDL_CLK_IPU1_PODF,
+ imx_clk_divider(dev, "ipu1_podf", "ipu1_sel", base + 0x3c, 11,
+ 3));
+ clk_dm(IMX6QDL_CLK_IPU2_PODF,
+ imx_clk_divider(dev, "ipu2_podf", "ipu2_sel", base + 0x3c, 16,
+ 3));
+ clk_dm(IMX6QDL_CLK_IPU1_DI0_PRE,
+ imx_clk_divider(dev, "ipu1_di0_pre", "ipu1_di0_pre_sel",
+ base + 0x34, 3, 3));
+ clk_dm(IMX6QDL_CLK_IPU1_DI1_PRE,
+ imx_clk_divider(dev, "ipu1_di1_pre", "ipu1_di1_pre_sel",
+ base + 0x34, 12, 3));
+ clk_dm(IMX6QDL_CLK_IPU2_DI0_PRE,
+ imx_clk_divider(dev, "ipu2_di0_pre", "ipu2_di0_pre_sel",
+ base + 0x38, 3, 3));
+ clk_dm(IMX6QDL_CLK_IPU2_DI1_PRE,
+ imx_clk_divider(dev, "ipu2_di1_pre", "ipu2_di1_pre_sel",
+ base + 0x38, 12, 3));
+
+ if (of_machine_is_compatible("fsl,imx6qp")) {
+ clk_dm(IMX6QDL_CLK_IPU1_DI0_SEL,
+ imx_clk_mux_flags(dev, "ipu1_di0_sel", base + 0x34, 0, 3,
+ ipu1_di0_sels_2,
+ ARRAY_SIZE(ipu1_di0_sels_2),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU1_DI1_SEL,
+ imx_clk_mux_flags(dev, "ipu1_di1_sel", base + 0x34, 9, 3,
+ ipu1_di1_sels_2,
+ ARRAY_SIZE(ipu1_di1_sels_2),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU2_DI0_SEL,
+ imx_clk_mux_flags(dev, "ipu2_di0_sel", base + 0x38, 0, 3,
+ ipu2_di0_sels_2,
+ ARRAY_SIZE(ipu2_di0_sels_2),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU2_DI1_SEL,
+ imx_clk_mux_flags(dev, "ipu2_di1_sel", base + 0x38, 9, 3,
+ ipu2_di1_sels_2,
+ ARRAY_SIZE(ipu2_di1_sels_2),
+ CLK_SET_RATE_PARENT));
+ } else {
+ clk_dm(IMX6QDL_CLK_IPU1_DI0_SEL,
+ imx_clk_mux_flags(dev, "ipu1_di0_sel", base + 0x34, 0, 3,
+ ipu1_di0_sels,
+ ARRAY_SIZE(ipu1_di0_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU1_DI1_SEL,
+ imx_clk_mux_flags(dev, "ipu1_di1_sel", base + 0x34, 9, 3,
+ ipu1_di1_sels,
+ ARRAY_SIZE(ipu1_di1_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU2_DI0_SEL,
+ imx_clk_mux_flags(dev, "ipu2_di0_sel", base + 0x38, 0, 3,
+ ipu2_di0_sels,
+ ARRAY_SIZE(ipu2_di0_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_CLK_IPU2_DI1_SEL,
+ imx_clk_mux_flags(dev, "ipu2_di1_sel", base + 0x38, 9, 3,
+ ipu2_di1_sels,
+ ARRAY_SIZE(ipu2_di1_sels),
+ CLK_SET_RATE_PARENT));
}
clk_dm(IMX6QDL_CLK_ECSPI1,
@@ -122,10 +422,11 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "ecspi3", "ecspi_root", base + 0x6c, 4));
clk_dm(IMX6QDL_CLK_ECSPI4,
imx_clk_gate2(dev, "ecspi4", "ecspi_root", base + 0x6c, 6));
- clk_dm(IMX6QDL_CLK_UART_IPG,
- imx_clk_gate2(dev, "uart_ipg", "ipg", base + 0x7c, 24));
clk_dm(IMX6QDL_CLK_UART_SERIAL,
- imx_clk_gate2(dev, "uart_serial", "uart_serial_podf", base + 0x7c, 26));
+ imx_clk_gate2(dev, "uart_serial", "uart_serial_podf",
+ base + 0x7c, 26));
+ clk_dm(IMX6QDL_CLK_USBOH3,
+ imx_clk_gate2(dev, "usboh3", "ipg", base + 0x80, 0));
clk_dm(IMX6QDL_CLK_USDHC1,
imx_clk_gate2(dev, "usdhc1", "usdhc1_podf", base + 0x80, 2));
clk_dm(IMX6QDL_CLK_USDHC2,
@@ -134,20 +435,6 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "usdhc3", "usdhc3_podf", base + 0x80, 6));
clk_dm(IMX6QDL_CLK_USDHC4,
imx_clk_gate2(dev, "usdhc4", "usdhc4_podf", base + 0x80, 8));
-
- clk_dm(IMX6QDL_CLK_PERIPH_PRE,
- imx_clk_mux(dev, "periph_pre", base + 0x18, 18, 2, periph_pre_sels,
- ARRAY_SIZE(periph_pre_sels)));
- clk_dm(IMX6QDL_CLK_PERIPH,
- imx_clk_busy_mux(dev, "periph", base + 0x14, 25, 1, base + 0x48,
- 5, periph_sels, ARRAY_SIZE(periph_sels)));
- clk_dm(IMX6QDL_CLK_AHB,
- imx_clk_busy_divider(dev, "ahb", "periph", base + 0x14, 10, 3,
- base + 0x48, 1));
- clk_dm(IMX6QDL_CLK_IPG,
- imx_clk_divider(dev, "ipg", "ahb", base + 0x14, 8, 2));
- clk_dm(IMX6QDL_CLK_IPG_PER,
- imx_clk_divider(dev, "ipg_per", "ipg", base + 0x1c, 0, 6));
clk_dm(IMX6QDL_CLK_I2C1,
imx_clk_gate2(dev, "i2c1", "ipg_per", base + 0x70, 6));
clk_dm(IMX6QDL_CLK_I2C2,
@@ -162,17 +449,44 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "pwm3", "ipg_per", base + 0x78, 20));
clk_dm(IMX6QDL_CLK_PWM4,
imx_clk_gate2(dev, "pwm4", "ipg_per", base + 0x78, 22));
-
- clk_dm(IMX6QDL_CLK_ENET, imx_clk_gate2(dev, "enet", "ipg", base + 0x6c, 10));
+ clk_dm(IMX6QDL_CLK_ENET,
+ imx_clk_gate2(dev, "enet", "ipg", base + 0x6c, 10));
clk_dm(IMX6QDL_CLK_ENET_REF,
imx_clk_fixed_factor(dev, "enet_ref", "pll6_enet", 1, 1));
+ clk_dm(IMX6QDL_CLK_MIPI_CORE_CFG,
+ imx_clk_gate2_shared(dev, "mipi_core_cfg", "video_27m",
+ base + 0x74, 16,
+ &share_count_mipi_core_cfg));
+ clk_dm(IMX6QDL_CLK_HDMI_IAHB,
+ imx_clk_gate2(dev, "hdmi_iahb", "ahb", base + 0x70, 0));
+ clk_dm(IMX6QDL_CLK_HDMI_ISFR,
+ imx_clk_gate2(dev, "hdmi_isfr", "mipi_core_cfg", base + 0x70,
+ 4));
+ clk_dm(IMX6QDL_CLK_IPU1,
+ imx_clk_gate2(dev, "ipu1", "ipu1_podf", base + 0x74, 0));
+ clk_dm(IMX6QDL_CLK_IPU2,
+ imx_clk_gate2(dev, "ipu2", "ipu2_podf", base + 0x74, 6));
+ clk_dm(IMX6QDL_CLK_IPU1_DI0,
+ imx_clk_gate2(dev, "ipu1_di0", "ipu1_di0_sel", base + 0x74, 2));
+ clk_dm(IMX6QDL_CLK_IPU1_DI1,
+ imx_clk_gate2(dev, "ipu1_di1", "ipu1_di1_sel", base + 0x74, 4));
+ clk_dm(IMX6QDL_CLK_IPU2_DI0,
+ imx_clk_gate2(dev, "ipu2_di0", "ipu2_di0_sel", base + 0x74, 8));
+ clk_dm(IMX6QDL_CLK_IPU2_DI1,
+ imx_clk_gate2(dev, "ipu2_di1", "ipu2_di1_sel", base + 0x74, 10));
+
+ if (of_machine_is_compatible("fsl,imx6dl")) {
+ SET_CLK_RATE(IMX6QDL_CLK_PLL3_PFD1_540M, 540000000UL);
+ SET_CLK_PARENT(IMX6QDL_CLK_IPU1_SEL,
+ IMX6QDL_CLK_PLL3_PFD1_540M);
+ }
return 0;
}
static const struct udevice_id imx6q_clk_ids[] = {
{ .compatible = "fsl,imx6q-ccm" },
- { },
+ {},
};
U_BOOT_DRIVER(imx6q_clk) = {
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 7d14dbc395f..b53f35df84f 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -95,6 +95,15 @@ static inline struct clk *imx_clk_gate2(struct udevice *dev, const char *name,
shift, 0x3, 0, NULL);
}
+static inline struct clk *
+imx_clk_gate2_flags(struct udevice *dev, const char *name, const char *parent,
+ void __iomem *reg, u8 shift, unsigned long flags)
+{
+ return clk_register_gate2(dev, name, parent,
+ flags | CLK_SET_RATE_PARENT, reg, shift, 0x3,
+ 0, NULL);
+}
+
static inline struct clk *imx_clk_gate2_shared(struct udevice *dev, const char *name,
const char *parent,
void __iomem *reg, u8 shift,
diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c
index d9cc7acb970..c15a4a629ad 100644
--- a/drivers/misc/imx8/scu_api.c
+++ b/drivers/misc/imx8/scu_api.c
@@ -374,6 +374,31 @@ void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
__func__, status, RPC_R8(&msg));
}
+int sc_misc_get_boot_type(sc_ipc_t ipc, sc_misc_bt_t *type)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ int size = sizeof(struct sc_rpc_msg_s);
+ struct sc_rpc_msg_s msg;
+ int ret;
+
+ if (!dev)
+ hang();
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SIZE(&msg) = 1U;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_TYPE;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret < 0)
+ return ret;
+
+ if (type)
+ *type = (u8)RPC_U8(&msg, 0U);
+
+ return 0;
+}
+
int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx)
{
struct udevice *dev = gd->arch.scu_dev;
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 7dc76563b7e..335b44a8a1a 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -752,10 +752,11 @@ static int esdhc_set_voltage(struct mmc *mmc)
int ret;
priv->signal_voltage = mmc->signal_voltage;
+ if (priv->vs18_enable)
+ return -ENOTSUPP;
+
switch (mmc->signal_voltage) {
case MMC_SIGNAL_VOLTAGE_330:
- if (priv->vs18_enable)
- return -ENOTSUPP;
if (CONFIG_IS_ENABLED(DM_REGULATOR) &&
!IS_ERR_OR_NULL(priv->vqmmc_dev)) {
ret = regulator_set_value(priv->vqmmc_dev,
diff --git a/drivers/pinctrl/nxp/Kconfig b/drivers/pinctrl/nxp/Kconfig
index 84d9a3641ff..b2a19557a27 100644
--- a/drivers/pinctrl/nxp/Kconfig
+++ b/drivers/pinctrl/nxp/Kconfig
@@ -103,13 +103,13 @@ config PINCTRL_IMX8M
registers.
config PINCTRL_IMX93
- bool "IMX8M pinctrl driver"
+ bool "IMX93/1 pinctrl driver"
depends on ARCH_IMX9 && PINCTRL_FULL
select PINCTRL_IMX_MMIO
help
- Say Y here to enable the imx8m pinctrl driver
+ Say Y here to enable the imx9[3,1] pinctrl driver
- This provides a simple pinctrl driver for i.MX8M SoC familiy.
+ This provides a simple pinctrl driver for i.MX9[3,1] SoC.
This feature depends on device tree configuration. This driver
is different from the linux one, this is a simple implementation,
only parses the 'fsl,pins' property and configure related
diff --git a/drivers/pinctrl/nxp/Makefile b/drivers/pinctrl/nxp/Makefile
index 7d861ae52c1..7f1cc5a182f 100644
--- a/drivers/pinctrl/nxp/Makefile
+++ b/drivers/pinctrl/nxp/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_PINCTRL_IMX7ULP) += pinctrl-imx7ulp.o
obj-$(CONFIG_PINCTRL_IMX8ULP) += pinctrl-imx8ulp.o
obj-$(CONFIG_PINCTRL_IMX8) += pinctrl-imx8.o
obj-$(CONFIG_PINCTRL_IMX8M) += pinctrl-imx8m.o
-obj-$(CONFIG_PINCTRL_IMX93) += pinctrl-imx93.o
+obj-$(CONFIG_PINCTRL_IMX93) += pinctrl-imx9.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_VYBRID) += pinctrl-vf610.o
obj-$(CONFIG_PINCTRL_IMXRT) += pinctrl-imxrt.o
diff --git a/drivers/pinctrl/nxp/pinctrl-imx.h b/drivers/pinctrl/nxp/pinctrl-imx.h
index 9adf999d3bb..569bb869abd 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx.h
+++ b/drivers/pinctrl/nxp/pinctrl-imx.h
@@ -6,6 +6,14 @@
#ifndef __DRIVERS_PINCTRL_IMX_H
#define __DRIVERS_PINCTRL_IMX_H
+#define PINCTRL_PIN(a, b) { .number = a, .name = b }
+#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
+
+struct imx_pinctrl_pin_desc {
+ unsigned int number;
+ const char *name;
+};
+
/**
* @base: the address to the controller in virtual memory
* @input_sel_base: the address of the select input in virtual memory.
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8m.c b/drivers/pinctrl/nxp/pinctrl-imx8m.c
index d9c63b3aca6..6eec1a277b3 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx8m.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx8m.c
@@ -4,21 +4,83 @@
*/
#include <dm/device.h>
+#include <dm/device_compat.h>
#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <asm/io.h>
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __section(".data");
static const struct udevice_id imx8m_pinctrl_match[] = {
+#if IS_ENABLED(CONFIG_IMX8MQ)
{ .compatible = "fsl,imx8mq-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
+#endif
+#if IS_ENABLED(CONFIG_IMX8MM)
{ .compatible = "fsl,imx8mm-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
+#endif
+#if IS_ENABLED(CONFIG_IMX8MN)
{ .compatible = "fsl,imx8mn-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
+#endif
+#if IS_ENABLED(CONFIG_IMX8MP)
{ .compatible = "fsl,imx8mp-iomuxc", .data = (ulong)&imx8mq_pinctrl_soc_info },
+#endif
{ /* sentinel */ }
};
+#if CONFIG_IS_ENABLED(CMD_PINMUX)
+
+#if IS_ENABLED(CONFIG_IMX8MP)
+#include "pinctrl-imx8mp.c"
+#elif IS_ENABLED(CONFIG_IMX8MN)
+#include "pinctrl-imx8mn.c"
+#elif IS_ENABLED(CONFIG_IMX8MM)
+#include "pinctrl-imx8mm.c"
+#elif IS_ENABLED(CONFIG_IMX8MQ)
+#include "pinctrl-imx8mq.c"
+#endif
+
+static int imx8m_get_pins_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(imx8m_pinctrl_pads);
+}
+
+static const char *imx8m_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ /* sanity checking */
+ if (selector != imx8m_pinctrl_pads[selector].number) {
+ dev_err(dev,
+ "selector(%u) not match with imx8m_pinctrl_pads[selector].number(%u)\n",
+ selector, imx8m_pinctrl_pads[selector].number);
+ return NULL;
+ }
+
+ return imx8m_pinctrl_pads[selector].name;
+}
+
+static int imx8m_get_pin_muxing(struct udevice *dev, unsigned int selector,
+ char *buf, int size)
+{
+ struct imx_pinctrl_priv *priv = dev_get_priv(dev);
+ struct imx_pinctrl_soc_info *info = priv->info;
+ u32 mux_reg = selector << 2;
+ u32 mux_mode = readl(info->base + mux_reg);
+
+ snprintf(buf, size, "Function(%d) at: 0x%p", mux_mode & 0x7, info->base + mux_reg);
+
+ return 0;
+}
+#endif
+
static const struct pinctrl_ops imx8m_pinctrl_ops = {
+#if CONFIG_IS_ENABLED(CMD_PINMUX)
+ .get_pin_name = imx8m_get_pin_name,
+ .get_pins_count = imx8m_get_pins_count,
+ .get_pin_muxing = imx8m_get_pin_muxing,
+#endif
.set_state = imx_pinctrl_set_state_mmio,
};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8mm.c b/drivers/pinctrl/nxp/pinctrl-imx8mm.c
new file mode 100644
index 00000000000..9aa2303b618
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx8mm.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 NXP
+ */
+
+#include "pinctrl-imx.h"
+
+enum imx8mm_pads {
+ RESERVE0 = 0,
+ RESERVE1 = 1,
+ RESERVE2 = 2,
+ RESERVE3 = 3,
+ RESERVE4 = 4,
+ RESERVE5 = 5,
+ RESERVE6 = 6,
+ RESERVE7 = 7,
+ RESERVE8 = 8,
+ RESERVE9 = 9,
+ GPIO1_IO00 = 10,
+ GPIO1_IO01 = 11,
+ GPIO1_IO02 = 12,
+ GPIO1_IO03 = 13,
+ GPIO1_IO04 = 14,
+ GPIO1_IO05 = 15,
+ GPIO1_IO06 = 16,
+ GPIO1_IO07 = 17,
+ GPIO1_IO08 = 18,
+ GPIO1_IO09 = 19,
+ GPIO1_IO10 = 20,
+ GPIO1_IO11 = 21,
+ GPIO1_IO12 = 22,
+ GPIO1_IO13 = 23,
+ GPIO1_IO14 = 24,
+ GPIO1_IO15 = 25,
+ ENET_MDC = 26,
+ ENET_MDIO = 27,
+ ENET_TD3 = 28,
+ ENET_TD2 = 29,
+ ENET_TD1 = 30,
+ ENET_TD0 = 31,
+ ENET_TX_CTL = 32,
+ ENET_TXC = 33,
+ ENET_RX_CTL = 34,
+ ENET_RXC = 35,
+ ENET_RD0 = 36,
+ ENET_RD1 = 37,
+ ENET_RD2 = 38,
+ ENET_RD3 = 39,
+ SD1_CLK = 40,
+ SD1_CMD = 41,
+ SD1_DATA0 = 42,
+ SD1_DATA1 = 43,
+ SD1_DATA2 = 44,
+ SD1_DATA3 = 45,
+ SD1_DATA4 = 46,
+ SD1_DATA5 = 47,
+ SD1_DATA6 = 48,
+ SD1_DATA7 = 49,
+ SD1_RESET_B = 50,
+ SD1_STROBE = 51,
+ SD2_CD_B = 52,
+ SD2_CLK = 53,
+ SD2_CMD = 54,
+ SD2_DATA0 = 55,
+ SD2_DATA1 = 56,
+ SD2_DATA2 = 57,
+ SD2_DATA3 = 58,
+ SD2_RESET_B = 59,
+ SD2_WP = 60,
+ NAND_ALE = 61,
+ NAND_CE0 = 62,
+ NAND_CE1 = 63,
+ NAND_CE2 = 64,
+ NAND_CE3 = 65,
+ NAND_CLE = 66,
+ NAND_DATA00 = 67,
+ NAND_DATA01 = 68,
+ NAND_DATA02 = 69,
+ NAND_DATA03 = 70,
+ NAND_DATA04 = 71,
+ NAND_DATA05 = 72,
+ NAND_DATA06 = 73,
+ NAND_DATA07 = 74,
+ NAND_DQS = 75,
+ NAND_RE_B = 76,
+ NAND_READY_B = 77,
+ NAND_WE_B = 78,
+ NAND_WP_B = 79,
+ SAI5_RXFS = 80,
+ SAI5_RXC = 81,
+ SAI5_RXD0 = 82,
+ SAI5_RXD1 = 83,
+ SAI5_RXD2 = 84,
+ SAI5_RXD3 = 85,
+ SAI5_MCLK = 86,
+ SAI1_RXFS = 87,
+ SAI1_RXC = 88,
+ SAI1_RXD0 = 89,
+ SAI1_RXD1 = 90,
+ SAI1_RXD2 = 91,
+ SAI1_RXD3 = 92,
+ SAI1_RXD4 = 93,
+ SAI1_RXD5 = 94,
+ SAI1_RXD6 = 95,
+ SAI1_RXD7 = 96,
+ SAI1_TXFS = 97,
+ SAI1_TXC = 98,
+ SAI1_TXD0 = 99,
+ SAI1_TXD1 = 100,
+ SAI1_TXD2 = 101,
+ SAI1_TXD3 = 102,
+ SAI1_TXD4 = 103,
+ SAI1_TXD5 = 104,
+ SAI1_TXD6 = 105,
+ SAI1_TXD7 = 106,
+ SAI1_MCLK = 107,
+ SAI2_RXFS = 108,
+ SAI2_RXC = 109,
+ SAI2_RXD0 = 110,
+ SAI2_TXFS = 111,
+ SAI2_TXC = 112,
+ SAI2_TXD0 = 113,
+ SAI2_MCLK = 114,
+ SAI3_RXFS = 115,
+ SAI3_RXC = 116,
+ SAI3_RXD = 117,
+ SAI3_TXFS = 118,
+ SAI3_TXC = 119,
+ SAI3_TXD = 120,
+ SAI3_MCLK = 121,
+ SPDIF_TX = 122,
+ SPDIF_RX = 123,
+ SPDIF_EXT_CLK = 124,
+ ECSPI1_SCLK = 125,
+ ECSPI1_MOSI = 126,
+ ECSPI1_MISO = 127,
+ ECSPI1_SS0 = 128,
+ ECSPI2_SCLK = 129,
+ ECSPI2_MOSI = 130,
+ ECSPI2_MISO = 131,
+ ECSPI2_SS0 = 132,
+ I2C1_SCL = 133,
+ I2C1_SDA = 134,
+ I2C2_SCL = 135,
+ I2C2_SDA = 136,
+ I2C3_SCL = 137,
+ I2C3_SDA = 138,
+ I2C4_SCL = 139,
+ I2C4_SDA = 140,
+ UART1_RXD = 141,
+ UART1_TXD = 142,
+ UART2_RXD = 143,
+ UART2_TXD = 144,
+ UART3_RXD = 145,
+ UART3_TXD = 146,
+ UART4_RXD = 147,
+ UART4_TXD = 148,
+};
+
+static const struct imx_pinctrl_pin_desc imx8m_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(RESERVE0),
+ IMX_PINCTRL_PIN(RESERVE1),
+ IMX_PINCTRL_PIN(RESERVE2),
+ IMX_PINCTRL_PIN(RESERVE3),
+ IMX_PINCTRL_PIN(RESERVE4),
+ IMX_PINCTRL_PIN(RESERVE5),
+ IMX_PINCTRL_PIN(RESERVE6),
+ IMX_PINCTRL_PIN(RESERVE7),
+ IMX_PINCTRL_PIN(RESERVE8),
+ IMX_PINCTRL_PIN(RESERVE9),
+ IMX_PINCTRL_PIN(GPIO1_IO00),
+ IMX_PINCTRL_PIN(GPIO1_IO01),
+ IMX_PINCTRL_PIN(GPIO1_IO02),
+ IMX_PINCTRL_PIN(GPIO1_IO03),
+ IMX_PINCTRL_PIN(GPIO1_IO04),
+ IMX_PINCTRL_PIN(GPIO1_IO05),
+ IMX_PINCTRL_PIN(GPIO1_IO06),
+ IMX_PINCTRL_PIN(GPIO1_IO07),
+ IMX_PINCTRL_PIN(GPIO1_IO08),
+ IMX_PINCTRL_PIN(GPIO1_IO09),
+ IMX_PINCTRL_PIN(GPIO1_IO10),
+ IMX_PINCTRL_PIN(GPIO1_IO11),
+ IMX_PINCTRL_PIN(GPIO1_IO12),
+ IMX_PINCTRL_PIN(GPIO1_IO13),
+ IMX_PINCTRL_PIN(GPIO1_IO14),
+ IMX_PINCTRL_PIN(GPIO1_IO15),
+ IMX_PINCTRL_PIN(ENET_MDC),
+ IMX_PINCTRL_PIN(ENET_MDIO),
+ IMX_PINCTRL_PIN(ENET_TD3),
+ IMX_PINCTRL_PIN(ENET_TD2),
+ IMX_PINCTRL_PIN(ENET_TD1),
+ IMX_PINCTRL_PIN(ENET_TD0),
+ IMX_PINCTRL_PIN(ENET_TX_CTL),
+ IMX_PINCTRL_PIN(ENET_TXC),
+ IMX_PINCTRL_PIN(ENET_RX_CTL),
+ IMX_PINCTRL_PIN(ENET_RXC),
+ IMX_PINCTRL_PIN(ENET_RD0),
+ IMX_PINCTRL_PIN(ENET_RD1),
+ IMX_PINCTRL_PIN(ENET_RD2),
+ IMX_PINCTRL_PIN(ENET_RD3),
+ IMX_PINCTRL_PIN(SD1_CLK),
+ IMX_PINCTRL_PIN(SD1_CMD),
+ IMX_PINCTRL_PIN(SD1_DATA0),
+ IMX_PINCTRL_PIN(SD1_DATA1),
+ IMX_PINCTRL_PIN(SD1_DATA2),
+ IMX_PINCTRL_PIN(SD1_DATA3),
+ IMX_PINCTRL_PIN(SD1_DATA4),
+ IMX_PINCTRL_PIN(SD1_DATA5),
+ IMX_PINCTRL_PIN(SD1_DATA6),
+ IMX_PINCTRL_PIN(SD1_DATA7),
+ IMX_PINCTRL_PIN(SD1_RESET_B),
+ IMX_PINCTRL_PIN(SD1_STROBE),
+ IMX_PINCTRL_PIN(SD2_CD_B),
+ IMX_PINCTRL_PIN(SD2_CLK),
+ IMX_PINCTRL_PIN(SD2_CMD),
+ IMX_PINCTRL_PIN(SD2_DATA0),
+ IMX_PINCTRL_PIN(SD2_DATA1),
+ IMX_PINCTRL_PIN(SD2_DATA2),
+ IMX_PINCTRL_PIN(SD2_DATA3),
+ IMX_PINCTRL_PIN(SD2_RESET_B),
+ IMX_PINCTRL_PIN(SD2_WP),
+ IMX_PINCTRL_PIN(NAND_ALE),
+ IMX_PINCTRL_PIN(NAND_CE0),
+ IMX_PINCTRL_PIN(NAND_CE1),
+ IMX_PINCTRL_PIN(NAND_CE2),
+ IMX_PINCTRL_PIN(NAND_CE3),
+ IMX_PINCTRL_PIN(NAND_CLE),
+ IMX_PINCTRL_PIN(NAND_DATA00),
+ IMX_PINCTRL_PIN(NAND_DATA01),
+ IMX_PINCTRL_PIN(NAND_DATA02),
+ IMX_PINCTRL_PIN(NAND_DATA03),
+ IMX_PINCTRL_PIN(NAND_DATA04),
+ IMX_PINCTRL_PIN(NAND_DATA05),
+ IMX_PINCTRL_PIN(NAND_DATA06),
+ IMX_PINCTRL_PIN(NAND_DATA07),
+ IMX_PINCTRL_PIN(NAND_DQS),
+ IMX_PINCTRL_PIN(NAND_RE_B),
+ IMX_PINCTRL_PIN(NAND_READY_B),
+ IMX_PINCTRL_PIN(NAND_WE_B),
+ IMX_PINCTRL_PIN(NAND_WP_B),
+ IMX_PINCTRL_PIN(SAI5_RXFS),
+ IMX_PINCTRL_PIN(SAI5_RXC),
+ IMX_PINCTRL_PIN(SAI5_RXD0),
+ IMX_PINCTRL_PIN(SAI5_RXD1),
+ IMX_PINCTRL_PIN(SAI5_RXD2),
+ IMX_PINCTRL_PIN(SAI5_RXD3),
+ IMX_PINCTRL_PIN(SAI5_MCLK),
+ IMX_PINCTRL_PIN(SAI1_RXFS),
+ IMX_PINCTRL_PIN(SAI1_RXC),
+ IMX_PINCTRL_PIN(SAI1_RXD0),
+ IMX_PINCTRL_PIN(SAI1_RXD1),
+ IMX_PINCTRL_PIN(SAI1_RXD2),
+ IMX_PINCTRL_PIN(SAI1_RXD3),
+ IMX_PINCTRL_PIN(SAI1_RXD4),
+ IMX_PINCTRL_PIN(SAI1_RXD5),
+ IMX_PINCTRL_PIN(SAI1_RXD6),
+ IMX_PINCTRL_PIN(SAI1_RXD7),
+ IMX_PINCTRL_PIN(SAI1_TXFS),
+ IMX_PINCTRL_PIN(SAI1_TXC),
+ IMX_PINCTRL_PIN(SAI1_TXD0),
+ IMX_PINCTRL_PIN(SAI1_TXD1),
+ IMX_PINCTRL_PIN(SAI1_TXD2),
+ IMX_PINCTRL_PIN(SAI1_TXD3),
+ IMX_PINCTRL_PIN(SAI1_TXD4),
+ IMX_PINCTRL_PIN(SAI1_TXD5),
+ IMX_PINCTRL_PIN(SAI1_TXD6),
+ IMX_PINCTRL_PIN(SAI1_TXD7),
+ IMX_PINCTRL_PIN(SAI1_MCLK),
+ IMX_PINCTRL_PIN(SAI2_RXFS),
+ IMX_PINCTRL_PIN(SAI2_RXC),
+ IMX_PINCTRL_PIN(SAI2_RXD0),
+ IMX_PINCTRL_PIN(SAI2_TXFS),
+ IMX_PINCTRL_PIN(SAI2_TXC),
+ IMX_PINCTRL_PIN(SAI2_TXD0),
+ IMX_PINCTRL_PIN(SAI2_MCLK),
+ IMX_PINCTRL_PIN(SAI3_RXFS),
+ IMX_PINCTRL_PIN(SAI3_RXC),
+ IMX_PINCTRL_PIN(SAI3_RXD),
+ IMX_PINCTRL_PIN(SAI3_TXFS),
+ IMX_PINCTRL_PIN(SAI3_TXC),
+ IMX_PINCTRL_PIN(SAI3_TXD),
+ IMX_PINCTRL_PIN(SAI3_MCLK),
+ IMX_PINCTRL_PIN(SPDIF_TX),
+ IMX_PINCTRL_PIN(SPDIF_RX),
+ IMX_PINCTRL_PIN(SPDIF_EXT_CLK),
+ IMX_PINCTRL_PIN(ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(ECSPI1_MISO),
+ IMX_PINCTRL_PIN(ECSPI1_SS0),
+ IMX_PINCTRL_PIN(ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(ECSPI2_MISO),
+ IMX_PINCTRL_PIN(ECSPI2_SS0),
+ IMX_PINCTRL_PIN(I2C1_SCL),
+ IMX_PINCTRL_PIN(I2C1_SDA),
+ IMX_PINCTRL_PIN(I2C2_SCL),
+ IMX_PINCTRL_PIN(I2C2_SDA),
+ IMX_PINCTRL_PIN(I2C3_SCL),
+ IMX_PINCTRL_PIN(I2C3_SDA),
+ IMX_PINCTRL_PIN(I2C4_SCL),
+ IMX_PINCTRL_PIN(I2C4_SDA),
+ IMX_PINCTRL_PIN(UART1_RXD),
+ IMX_PINCTRL_PIN(UART1_TXD),
+ IMX_PINCTRL_PIN(UART2_RXD),
+ IMX_PINCTRL_PIN(UART2_TXD),
+ IMX_PINCTRL_PIN(UART3_RXD),
+ IMX_PINCTRL_PIN(UART3_TXD),
+ IMX_PINCTRL_PIN(UART4_RXD),
+ IMX_PINCTRL_PIN(UART4_TXD),
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8mn.c b/drivers/pinctrl/nxp/pinctrl-imx8mn.c
new file mode 100644
index 00000000000..a3e22cf72ee
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx8mn.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 NXP
+ */
+
+#include "pinctrl-imx.h"
+
+enum imx8mn_pads {
+ RESERVE0 = 0,
+ RESERVE1 = 1,
+ RESERVE2 = 2,
+ RESERVE3 = 3,
+ RESERVE4 = 4,
+ RESERVE5 = 5,
+ RESERVE6 = 6,
+ RESERVE7 = 7,
+ BOOT_MODE2 = 8,
+ BOOT_MODE3 = 9,
+ GPIO1_IO00 = 10,
+ GPIO1_IO01 = 11,
+ GPIO1_IO02 = 12,
+ GPIO1_IO03 = 13,
+ GPIO1_IO04 = 14,
+ GPIO1_IO05 = 15,
+ GPIO1_IO06 = 16,
+ GPIO1_IO07 = 17,
+ GPIO1_IO08 = 18,
+ GPIO1_IO09 = 19,
+ GPIO1_IO10 = 20,
+ GPIO1_IO11 = 21,
+ GPIO1_IO12 = 22,
+ GPIO1_IO13 = 23,
+ GPIO1_IO14 = 24,
+ GPIO1_IO15 = 25,
+ ENET_MDC = 26,
+ ENET_MDIO = 27,
+ ENET_TD3 = 28,
+ ENET_TD2 = 29,
+ ENET_TD1 = 30,
+ ENET_TD0 = 31,
+ ENET_TX_CTL = 32,
+ ENET_TXC = 33,
+ ENET_RX_CTL = 34,
+ ENET_RXC = 35,
+ ENET_RD0 = 36,
+ ENET_RD1 = 37,
+ ENET_RD2 = 38,
+ ENET_RD3 = 39,
+ SD1_CLK = 40,
+ SD1_CMD = 41,
+ SD1_DATA0 = 42,
+ SD1_DATA1 = 43,
+ SD1_DATA2 = 44,
+ SD1_DATA3 = 45,
+ SD1_DATA4 = 46,
+ SD1_DATA5 = 47,
+ SD1_DATA6 = 48,
+ SD1_DATA7 = 49,
+ SD1_RESET_B = 50,
+ SD1_STROBE = 51,
+ SD2_CD_B = 52,
+ SD2_CLK = 53,
+ SD2_CMD = 54,
+ SD2_DATA0 = 55,
+ SD2_DATA1 = 56,
+ SD2_DATA2 = 57,
+ SD2_DATA3 = 58,
+ SD2_RESET_B = 59,
+ SD2_WP = 60,
+ NAND_ALE = 61,
+ NAND_CE0 = 62,
+ NAND_CE1 = 63,
+ NAND_CE2 = 64,
+ NAND_CE3 = 65,
+ NAND_CLE = 66,
+ NAND_DATA00 = 67,
+ NAND_DATA01 = 68,
+ NAND_DATA02 = 69,
+ NAND_DATA03 = 70,
+ NAND_DATA04 = 71,
+ NAND_DATA05 = 72,
+ NAND_DATA06 = 73,
+ NAND_DATA07 = 74,
+ NAND_DQS = 75,
+ NAND_RE_B = 76,
+ NAND_READY_B = 77,
+ NAND_WE_B = 78,
+ NAND_WP_B = 79,
+ SAI5_RXFS = 80,
+ SAI5_RXC = 81,
+ SAI5_RXD0 = 82,
+ SAI5_RXD1 = 83,
+ SAI5_RXD2 = 84,
+ SAI5_RXD3 = 85,
+ SAI5_MCLK = 86,
+ SAI1_RXFS = 87,
+ SAI1_RXC = 88,
+ SAI1_RXD0 = 89,
+ SAI1_RXD1 = 90,
+ SAI1_RXD2 = 91,
+ SAI1_RXD3 = 92,
+ SAI1_RXD4 = 93,
+ SAI1_RXD5 = 94,
+ SAI1_RXD6 = 95,
+ SAI1_RXD7 = 96,
+ SAI1_TXFS = 97,
+ SAI1_TXC = 98,
+ SAI1_TXD0 = 99,
+ SAI1_TXD1 = 100,
+ SAI1_TXD2 = 101,
+ SAI1_TXD3 = 102,
+ SAI1_TXD4 = 103,
+ SAI1_TXD5 = 104,
+ SAI1_TXD6 = 105,
+ SAI1_TXD7 = 106,
+ SAI1_MCLK = 107,
+ SAI2_RXFS = 108,
+ SAI2_RXC = 109,
+ SAI2_RXD0 = 110,
+ SAI2_TXFS = 111,
+ SAI2_TXC = 112,
+ SAI2_TXD0 = 113,
+ SAI2_MCLK = 114,
+ SAI3_RXFS = 115,
+ SAI3_RXC = 116,
+ SAI3_RXD = 117,
+ SAI3_TXFS = 118,
+ SAI3_TXC = 119,
+ SAI3_TXD = 120,
+ SAI3_MCLK = 121,
+ SPDIF_TX = 122,
+ SPDIF_RX = 123,
+ SPDIF_EXT_CLK = 124,
+ ECSPI1_SCLK = 125,
+ ECSPI1_MOSI = 126,
+ ECSPI1_MISO = 127,
+ ECSPI1_SS0 = 128,
+ ECSPI2_SCLK = 129,
+ ECSPI2_MOSI = 130,
+ ECSPI2_MISO = 131,
+ ECSPI2_SS0 = 132,
+ I2C1_SCL = 133,
+ I2C1_SDA = 134,
+ I2C2_SCL = 135,
+ I2C2_SDA = 136,
+ I2C3_SCL = 137,
+ I2C3_SDA = 138,
+ I2C4_SCL = 139,
+ I2C4_SDA = 140,
+ UART1_RXD = 141,
+ UART1_TXD = 142,
+ UART2_RXD = 143,
+ UART2_TXD = 144,
+ UART3_RXD = 145,
+ UART3_TXD = 146,
+ UART4_RXD = 147,
+ UART4_TXD = 148,
+};
+
+static const struct imx_pinctrl_pin_desc imx8m_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(RESERVE0),
+ IMX_PINCTRL_PIN(RESERVE1),
+ IMX_PINCTRL_PIN(RESERVE2),
+ IMX_PINCTRL_PIN(RESERVE3),
+ IMX_PINCTRL_PIN(RESERVE4),
+ IMX_PINCTRL_PIN(RESERVE5),
+ IMX_PINCTRL_PIN(RESERVE6),
+ IMX_PINCTRL_PIN(RESERVE7),
+ IMX_PINCTRL_PIN(BOOT_MODE2),
+ IMX_PINCTRL_PIN(BOOT_MODE3),
+ IMX_PINCTRL_PIN(GPIO1_IO00),
+ IMX_PINCTRL_PIN(GPIO1_IO01),
+ IMX_PINCTRL_PIN(GPIO1_IO02),
+ IMX_PINCTRL_PIN(GPIO1_IO03),
+ IMX_PINCTRL_PIN(GPIO1_IO04),
+ IMX_PINCTRL_PIN(GPIO1_IO05),
+ IMX_PINCTRL_PIN(GPIO1_IO06),
+ IMX_PINCTRL_PIN(GPIO1_IO07),
+ IMX_PINCTRL_PIN(GPIO1_IO08),
+ IMX_PINCTRL_PIN(GPIO1_IO09),
+ IMX_PINCTRL_PIN(GPIO1_IO10),
+ IMX_PINCTRL_PIN(GPIO1_IO11),
+ IMX_PINCTRL_PIN(GPIO1_IO12),
+ IMX_PINCTRL_PIN(GPIO1_IO13),
+ IMX_PINCTRL_PIN(GPIO1_IO14),
+ IMX_PINCTRL_PIN(GPIO1_IO15),
+ IMX_PINCTRL_PIN(ENET_MDC),
+ IMX_PINCTRL_PIN(ENET_MDIO),
+ IMX_PINCTRL_PIN(ENET_TD3),
+ IMX_PINCTRL_PIN(ENET_TD2),
+ IMX_PINCTRL_PIN(ENET_TD1),
+ IMX_PINCTRL_PIN(ENET_TD0),
+ IMX_PINCTRL_PIN(ENET_TX_CTL),
+ IMX_PINCTRL_PIN(ENET_TXC),
+ IMX_PINCTRL_PIN(ENET_RX_CTL),
+ IMX_PINCTRL_PIN(ENET_RXC),
+ IMX_PINCTRL_PIN(ENET_RD0),
+ IMX_PINCTRL_PIN(ENET_RD1),
+ IMX_PINCTRL_PIN(ENET_RD2),
+ IMX_PINCTRL_PIN(ENET_RD3),
+ IMX_PINCTRL_PIN(SD1_CLK),
+ IMX_PINCTRL_PIN(SD1_CMD),
+ IMX_PINCTRL_PIN(SD1_DATA0),
+ IMX_PINCTRL_PIN(SD1_DATA1),
+ IMX_PINCTRL_PIN(SD1_DATA2),
+ IMX_PINCTRL_PIN(SD1_DATA3),
+ IMX_PINCTRL_PIN(SD1_DATA4),
+ IMX_PINCTRL_PIN(SD1_DATA5),
+ IMX_PINCTRL_PIN(SD1_DATA6),
+ IMX_PINCTRL_PIN(SD1_DATA7),
+ IMX_PINCTRL_PIN(SD1_RESET_B),
+ IMX_PINCTRL_PIN(SD1_STROBE),
+ IMX_PINCTRL_PIN(SD2_CD_B),
+ IMX_PINCTRL_PIN(SD2_CLK),
+ IMX_PINCTRL_PIN(SD2_CMD),
+ IMX_PINCTRL_PIN(SD2_DATA0),
+ IMX_PINCTRL_PIN(SD2_DATA1),
+ IMX_PINCTRL_PIN(SD2_DATA2),
+ IMX_PINCTRL_PIN(SD2_DATA3),
+ IMX_PINCTRL_PIN(SD2_RESET_B),
+ IMX_PINCTRL_PIN(SD2_WP),
+ IMX_PINCTRL_PIN(NAND_ALE),
+ IMX_PINCTRL_PIN(NAND_CE0),
+ IMX_PINCTRL_PIN(NAND_CE1),
+ IMX_PINCTRL_PIN(NAND_CE2),
+ IMX_PINCTRL_PIN(NAND_CE3),
+ IMX_PINCTRL_PIN(NAND_CLE),
+ IMX_PINCTRL_PIN(NAND_DATA00),
+ IMX_PINCTRL_PIN(NAND_DATA01),
+ IMX_PINCTRL_PIN(NAND_DATA02),
+ IMX_PINCTRL_PIN(NAND_DATA03),
+ IMX_PINCTRL_PIN(NAND_DATA04),
+ IMX_PINCTRL_PIN(NAND_DATA05),
+ IMX_PINCTRL_PIN(NAND_DATA06),
+ IMX_PINCTRL_PIN(NAND_DATA07),
+ IMX_PINCTRL_PIN(NAND_DQS),
+ IMX_PINCTRL_PIN(NAND_RE_B),
+ IMX_PINCTRL_PIN(NAND_READY_B),
+ IMX_PINCTRL_PIN(NAND_WE_B),
+ IMX_PINCTRL_PIN(NAND_WP_B),
+ IMX_PINCTRL_PIN(SAI5_RXFS),
+ IMX_PINCTRL_PIN(SAI5_RXC),
+ IMX_PINCTRL_PIN(SAI5_RXD0),
+ IMX_PINCTRL_PIN(SAI5_RXD1),
+ IMX_PINCTRL_PIN(SAI5_RXD2),
+ IMX_PINCTRL_PIN(SAI5_RXD3),
+ IMX_PINCTRL_PIN(SAI5_MCLK),
+ IMX_PINCTRL_PIN(SAI1_RXFS),
+ IMX_PINCTRL_PIN(SAI1_RXC),
+ IMX_PINCTRL_PIN(SAI1_RXD0),
+ IMX_PINCTRL_PIN(SAI1_RXD1),
+ IMX_PINCTRL_PIN(SAI1_RXD2),
+ IMX_PINCTRL_PIN(SAI1_RXD3),
+ IMX_PINCTRL_PIN(SAI1_RXD4),
+ IMX_PINCTRL_PIN(SAI1_RXD5),
+ IMX_PINCTRL_PIN(SAI1_RXD6),
+ IMX_PINCTRL_PIN(SAI1_RXD7),
+ IMX_PINCTRL_PIN(SAI1_TXFS),
+ IMX_PINCTRL_PIN(SAI1_TXC),
+ IMX_PINCTRL_PIN(SAI1_TXD0),
+ IMX_PINCTRL_PIN(SAI1_TXD1),
+ IMX_PINCTRL_PIN(SAI1_TXD2),
+ IMX_PINCTRL_PIN(SAI1_TXD3),
+ IMX_PINCTRL_PIN(SAI1_TXD4),
+ IMX_PINCTRL_PIN(SAI1_TXD5),
+ IMX_PINCTRL_PIN(SAI1_TXD6),
+ IMX_PINCTRL_PIN(SAI1_TXD7),
+ IMX_PINCTRL_PIN(SAI1_MCLK),
+ IMX_PINCTRL_PIN(SAI2_RXFS),
+ IMX_PINCTRL_PIN(SAI2_RXC),
+ IMX_PINCTRL_PIN(SAI2_RXD0),
+ IMX_PINCTRL_PIN(SAI2_TXFS),
+ IMX_PINCTRL_PIN(SAI2_TXC),
+ IMX_PINCTRL_PIN(SAI2_TXD0),
+ IMX_PINCTRL_PIN(SAI2_MCLK),
+ IMX_PINCTRL_PIN(SAI3_RXFS),
+ IMX_PINCTRL_PIN(SAI3_RXC),
+ IMX_PINCTRL_PIN(SAI3_RXD),
+ IMX_PINCTRL_PIN(SAI3_TXFS),
+ IMX_PINCTRL_PIN(SAI3_TXC),
+ IMX_PINCTRL_PIN(SAI3_TXD),
+ IMX_PINCTRL_PIN(SAI3_MCLK),
+ IMX_PINCTRL_PIN(SPDIF_TX),
+ IMX_PINCTRL_PIN(SPDIF_RX),
+ IMX_PINCTRL_PIN(SPDIF_EXT_CLK),
+ IMX_PINCTRL_PIN(ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(ECSPI1_MISO),
+ IMX_PINCTRL_PIN(ECSPI1_SS0),
+ IMX_PINCTRL_PIN(ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(ECSPI2_MISO),
+ IMX_PINCTRL_PIN(ECSPI2_SS0),
+ IMX_PINCTRL_PIN(I2C1_SCL),
+ IMX_PINCTRL_PIN(I2C1_SDA),
+ IMX_PINCTRL_PIN(I2C2_SCL),
+ IMX_PINCTRL_PIN(I2C2_SDA),
+ IMX_PINCTRL_PIN(I2C3_SCL),
+ IMX_PINCTRL_PIN(I2C3_SDA),
+ IMX_PINCTRL_PIN(I2C4_SCL),
+ IMX_PINCTRL_PIN(I2C4_SDA),
+ IMX_PINCTRL_PIN(UART1_RXD),
+ IMX_PINCTRL_PIN(UART1_TXD),
+ IMX_PINCTRL_PIN(UART2_RXD),
+ IMX_PINCTRL_PIN(UART2_TXD),
+ IMX_PINCTRL_PIN(UART3_RXD),
+ IMX_PINCTRL_PIN(UART3_TXD),
+ IMX_PINCTRL_PIN(UART4_RXD),
+ IMX_PINCTRL_PIN(UART4_TXD),
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8mp.c b/drivers/pinctrl/nxp/pinctrl-imx8mp.c
new file mode 100644
index 00000000000..7f02eba5355
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx8mp.c
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 NXP
+ */
+
+#include "pinctrl-imx.h"
+
+enum imx8mp_pads {
+ RESERVE0 = 0,
+ RESERVE1 = 1,
+ RESERVE2 = 2,
+ RESERVE3 = 3,
+ RESERVE4 = 4,
+ GPIO1_IO00 = 5,
+ GPIO1_IO01 = 6,
+ GPIO1_IO02 = 7,
+ GPIO1_IO03 = 8,
+ GPIO1_IO04 = 9,
+ GPIO1_IO05 = 10,
+ GPIO1_IO06 = 11,
+ GPIO1_IO07 = 12,
+ GPIO1_IO08 = 13,
+ GPIO1_IO09 = 14,
+ GPIO1_IO10 = 15,
+ GPIO1_IO11 = 16,
+ GPIO1_IO12 = 17,
+ GPIO1_IO13 = 18,
+ GPIO1_IO14 = 19,
+ GPIO1_IO15 = 20,
+ ENET_MDC = 21,
+ ENET_MDIO = 22,
+ ENET_TD3 = 23,
+ ENET_TD2 = 24,
+ ENET_TD1 = 25,
+ ENET_TD0 = 26,
+ ENET_TX_CTL = 27,
+ ENET_TXC = 28,
+ ENET_RX_CTL = 29,
+ ENET_RXC = 30,
+ ENET_RD0 = 31,
+ ENET_RD1 = 32,
+ ENET_RD2 = 33,
+ ENET_RD3 = 34,
+ SD1_CLK = 35,
+ SD1_CMD = 36,
+ SD1_DATA0 = 37,
+ SD1_DATA1 = 38,
+ SD1_DATA2 = 39,
+ SD1_DATA3 = 40,
+ SD1_DATA4 = 41,
+ SD1_DATA5 = 42,
+ SD1_DATA6 = 43,
+ SD1_DATA7 = 44,
+ SD1_RESET_B = 45,
+ SD1_STROBE = 46,
+ SD2_CD_B = 47,
+ SD2_CLK = 48,
+ SD2_CMD = 49,
+ SD2_DATA0 = 50,
+ SD2_DATA1 = 51,
+ SD2_DATA2 = 52,
+ SD2_DATA3 = 53,
+ SD2_RESET_B = 54,
+ SD2_WP = 55,
+ NAND_ALE = 56,
+ NAND_CE0_B = 57,
+ NAND_CE1_B = 58,
+ NAND_CE2_B = 59,
+ NAND_CE3_B = 60,
+ NAND_CLE = 61,
+ NAND_DATA00 = 62,
+ NAND_DATA01 = 63,
+ NAND_DATA02 = 64,
+ NAND_DATA03 = 65,
+ NAND_DATA04 = 66,
+ NAND_DATA05 = 67,
+ NAND_DATA06 = 68,
+ NAND_DATA07 = 69,
+ NAND_DQS = 70,
+ NAND_RE_B = 71,
+ NAND_READY_B = 72,
+ NAND_WE_B = 73,
+ NAND_WP_B = 74,
+ SAI5_RXFS = 75,
+ SAI5_RXC = 76,
+ SAI5_RXD0 = 77,
+ SAI5_RXD1 = 78,
+ SAI5_RXD2 = 79,
+ SAI5_RXD3 = 80,
+ SAI5_MCLK = 81,
+ SAI1_RXFS = 82,
+ SAI1_RXC = 83,
+ SAI1_RXD0 = 84,
+ SAI1_RXD1 = 85,
+ SAI1_RXD2 = 86,
+ SAI1_RXD3 = 87,
+ SAI1_RXD4 = 88,
+ SAI1_RXD5 = 89,
+ SAI1_RXD6 = 90,
+ SAI1_RXD7 = 91,
+ SAI1_TXFS = 92,
+ SAI1_TXC = 93,
+ SAI1_TXD0 = 94,
+ SAI1_TXD1 = 95,
+ SAI1_TXD2 = 96,
+ SAI1_TXD3 = 97,
+ SAI1_TXD4 = 98,
+ SAI1_TXD5 = 99,
+ SAI1_TXD6 = 100,
+ SAI1_TXD7 = 101,
+ SAI1_MCLK = 102,
+ SAI2_RXFS = 103,
+ SAI2_RXC = 104,
+ SAI2_RXD0 = 105,
+ SAI2_TXFS = 106,
+ SAI2_TXC = 107,
+ SAI2_TXD0 = 108,
+ SAI2_MCLK = 109,
+ SAI3_RXFS = 110,
+ SAI3_RXC = 111,
+ SAI3_RXD = 112,
+ SAI3_TXFS = 113,
+ SAI3_TXC = 114,
+ SAI3_TXD = 115,
+ SAI3_MCLK = 116,
+ SPDIF_TX = 117,
+ SPDIF_RX = 118,
+ SPDIF_EXT_CLK = 119,
+ ECSPI1_SCLK = 120,
+ ECSPI1_MOSI = 121,
+ ECSPI1_MISO = 122,
+ ECSPI1_SS0 = 123,
+ ECSPI2_SCLK = 124,
+ ECSPI2_MOSI = 125,
+ ECSPI2_MISO = 126,
+ ECSPI2_SS0 = 127,
+ I2C1_SCL = 128,
+ I2C1_SDA = 129,
+ I2C2_SCL = 130,
+ I2C2_SDA = 131,
+ I2C3_SCL = 132,
+ I2C3_SDA = 133,
+ I2C4_SCL = 134,
+ I2C4_SDA = 135,
+ UART1_RXD = 136,
+ UART1_TXD = 137,
+ UART2_RXD = 138,
+ UART2_TXD = 139,
+ UART3_RXD = 140,
+ UART3_TXD = 141,
+ UART4_RXD = 142,
+ UART4_TXD = 143,
+ HDMI_DDC_SCL = 144,
+ HDMI_DDC_SDA = 145,
+ HDMI_CEC = 146,
+ HDMI_HPD = 147,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct imx_pinctrl_pin_desc imx8m_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(RESERVE0),
+ IMX_PINCTRL_PIN(RESERVE1),
+ IMX_PINCTRL_PIN(RESERVE2),
+ IMX_PINCTRL_PIN(RESERVE3),
+ IMX_PINCTRL_PIN(RESERVE4),
+ IMX_PINCTRL_PIN(GPIO1_IO00),
+ IMX_PINCTRL_PIN(GPIO1_IO01),
+ IMX_PINCTRL_PIN(GPIO1_IO02),
+ IMX_PINCTRL_PIN(GPIO1_IO03),
+ IMX_PINCTRL_PIN(GPIO1_IO04),
+ IMX_PINCTRL_PIN(GPIO1_IO05),
+ IMX_PINCTRL_PIN(GPIO1_IO06),
+ IMX_PINCTRL_PIN(GPIO1_IO07),
+ IMX_PINCTRL_PIN(GPIO1_IO08),
+ IMX_PINCTRL_PIN(GPIO1_IO09),
+ IMX_PINCTRL_PIN(GPIO1_IO10),
+ IMX_PINCTRL_PIN(GPIO1_IO11),
+ IMX_PINCTRL_PIN(GPIO1_IO12),
+ IMX_PINCTRL_PIN(GPIO1_IO13),
+ IMX_PINCTRL_PIN(GPIO1_IO14),
+ IMX_PINCTRL_PIN(GPIO1_IO15),
+ IMX_PINCTRL_PIN(ENET_MDC),
+ IMX_PINCTRL_PIN(ENET_MDIO),
+ IMX_PINCTRL_PIN(ENET_TD3),
+ IMX_PINCTRL_PIN(ENET_TD2),
+ IMX_PINCTRL_PIN(ENET_TD1),
+ IMX_PINCTRL_PIN(ENET_TD0),
+ IMX_PINCTRL_PIN(ENET_TX_CTL),
+ IMX_PINCTRL_PIN(ENET_TXC),
+ IMX_PINCTRL_PIN(ENET_RX_CTL),
+ IMX_PINCTRL_PIN(ENET_RXC),
+ IMX_PINCTRL_PIN(ENET_RD0),
+ IMX_PINCTRL_PIN(ENET_RD1),
+ IMX_PINCTRL_PIN(ENET_RD2),
+ IMX_PINCTRL_PIN(ENET_RD3),
+ IMX_PINCTRL_PIN(SD1_CLK),
+ IMX_PINCTRL_PIN(SD1_CMD),
+ IMX_PINCTRL_PIN(SD1_DATA0),
+ IMX_PINCTRL_PIN(SD1_DATA1),
+ IMX_PINCTRL_PIN(SD1_DATA2),
+ IMX_PINCTRL_PIN(SD1_DATA3),
+ IMX_PINCTRL_PIN(SD1_DATA4),
+ IMX_PINCTRL_PIN(SD1_DATA5),
+ IMX_PINCTRL_PIN(SD1_DATA6),
+ IMX_PINCTRL_PIN(SD1_DATA7),
+ IMX_PINCTRL_PIN(SD1_RESET_B),
+ IMX_PINCTRL_PIN(SD1_STROBE),
+ IMX_PINCTRL_PIN(SD2_CD_B),
+ IMX_PINCTRL_PIN(SD2_CLK),
+ IMX_PINCTRL_PIN(SD2_CMD),
+ IMX_PINCTRL_PIN(SD2_DATA0),
+ IMX_PINCTRL_PIN(SD2_DATA1),
+ IMX_PINCTRL_PIN(SD2_DATA2),
+ IMX_PINCTRL_PIN(SD2_DATA3),
+ IMX_PINCTRL_PIN(SD2_RESET_B),
+ IMX_PINCTRL_PIN(SD2_WP),
+ IMX_PINCTRL_PIN(NAND_ALE),
+ IMX_PINCTRL_PIN(NAND_CE0_B),
+ IMX_PINCTRL_PIN(NAND_CE1_B),
+ IMX_PINCTRL_PIN(NAND_CE2_B),
+ IMX_PINCTRL_PIN(NAND_CE3_B),
+ IMX_PINCTRL_PIN(NAND_CLE),
+ IMX_PINCTRL_PIN(NAND_DATA00),
+ IMX_PINCTRL_PIN(NAND_DATA01),
+ IMX_PINCTRL_PIN(NAND_DATA02),
+ IMX_PINCTRL_PIN(NAND_DATA03),
+ IMX_PINCTRL_PIN(NAND_DATA04),
+ IMX_PINCTRL_PIN(NAND_DATA05),
+ IMX_PINCTRL_PIN(NAND_DATA06),
+ IMX_PINCTRL_PIN(NAND_DATA07),
+ IMX_PINCTRL_PIN(NAND_DQS),
+ IMX_PINCTRL_PIN(NAND_RE_B),
+ IMX_PINCTRL_PIN(NAND_READY_B),
+ IMX_PINCTRL_PIN(NAND_WE_B),
+ IMX_PINCTRL_PIN(NAND_WP_B),
+ IMX_PINCTRL_PIN(SAI5_RXFS),
+ IMX_PINCTRL_PIN(SAI5_RXC),
+ IMX_PINCTRL_PIN(SAI5_RXD0),
+ IMX_PINCTRL_PIN(SAI5_RXD1),
+ IMX_PINCTRL_PIN(SAI5_RXD2),
+ IMX_PINCTRL_PIN(SAI5_RXD3),
+ IMX_PINCTRL_PIN(SAI5_MCLK),
+ IMX_PINCTRL_PIN(SAI1_RXFS),
+ IMX_PINCTRL_PIN(SAI1_RXC),
+ IMX_PINCTRL_PIN(SAI1_RXD0),
+ IMX_PINCTRL_PIN(SAI1_RXD1),
+ IMX_PINCTRL_PIN(SAI1_RXD2),
+ IMX_PINCTRL_PIN(SAI1_RXD3),
+ IMX_PINCTRL_PIN(SAI1_RXD4),
+ IMX_PINCTRL_PIN(SAI1_RXD5),
+ IMX_PINCTRL_PIN(SAI1_RXD6),
+ IMX_PINCTRL_PIN(SAI1_RXD7),
+ IMX_PINCTRL_PIN(SAI1_TXFS),
+ IMX_PINCTRL_PIN(SAI1_TXC),
+ IMX_PINCTRL_PIN(SAI1_TXD0),
+ IMX_PINCTRL_PIN(SAI1_TXD1),
+ IMX_PINCTRL_PIN(SAI1_TXD2),
+ IMX_PINCTRL_PIN(SAI1_TXD3),
+ IMX_PINCTRL_PIN(SAI1_TXD4),
+ IMX_PINCTRL_PIN(SAI1_TXD5),
+ IMX_PINCTRL_PIN(SAI1_TXD6),
+ IMX_PINCTRL_PIN(SAI1_TXD7),
+ IMX_PINCTRL_PIN(SAI1_MCLK),
+ IMX_PINCTRL_PIN(SAI2_RXFS),
+ IMX_PINCTRL_PIN(SAI2_RXC),
+ IMX_PINCTRL_PIN(SAI2_RXD0),
+ IMX_PINCTRL_PIN(SAI2_TXFS),
+ IMX_PINCTRL_PIN(SAI2_TXC),
+ IMX_PINCTRL_PIN(SAI2_TXD0),
+ IMX_PINCTRL_PIN(SAI2_MCLK),
+ IMX_PINCTRL_PIN(SAI3_RXFS),
+ IMX_PINCTRL_PIN(SAI3_RXC),
+ IMX_PINCTRL_PIN(SAI3_RXD),
+ IMX_PINCTRL_PIN(SAI3_TXFS),
+ IMX_PINCTRL_PIN(SAI3_TXC),
+ IMX_PINCTRL_PIN(SAI3_TXD),
+ IMX_PINCTRL_PIN(SAI3_MCLK),
+ IMX_PINCTRL_PIN(SPDIF_TX),
+ IMX_PINCTRL_PIN(SPDIF_RX),
+ IMX_PINCTRL_PIN(SPDIF_EXT_CLK),
+ IMX_PINCTRL_PIN(ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(ECSPI1_MISO),
+ IMX_PINCTRL_PIN(ECSPI1_SS0),
+ IMX_PINCTRL_PIN(ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(ECSPI2_MISO),
+ IMX_PINCTRL_PIN(ECSPI2_SS0),
+ IMX_PINCTRL_PIN(I2C1_SCL),
+ IMX_PINCTRL_PIN(I2C1_SDA),
+ IMX_PINCTRL_PIN(I2C2_SCL),
+ IMX_PINCTRL_PIN(I2C2_SDA),
+ IMX_PINCTRL_PIN(I2C3_SCL),
+ IMX_PINCTRL_PIN(I2C3_SDA),
+ IMX_PINCTRL_PIN(I2C4_SCL),
+ IMX_PINCTRL_PIN(I2C4_SDA),
+ IMX_PINCTRL_PIN(UART1_RXD),
+ IMX_PINCTRL_PIN(UART1_TXD),
+ IMX_PINCTRL_PIN(UART2_RXD),
+ IMX_PINCTRL_PIN(UART2_TXD),
+ IMX_PINCTRL_PIN(UART3_RXD),
+ IMX_PINCTRL_PIN(UART3_TXD),
+ IMX_PINCTRL_PIN(UART4_RXD),
+ IMX_PINCTRL_PIN(UART4_TXD),
+ IMX_PINCTRL_PIN(HDMI_DDC_SCL),
+ IMX_PINCTRL_PIN(HDMI_DDC_SDA),
+ IMX_PINCTRL_PIN(HDMI_CEC),
+ IMX_PINCTRL_PIN(HDMI_HPD),
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8mq.c b/drivers/pinctrl/nxp/pinctrl-imx8mq.c
new file mode 100644
index 00000000000..bcc3e8ecbcf
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx8mq.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 NXP
+ */
+
+#include "pinctrl-imx.h"
+
+enum imx8mq_pads {
+ RESERVE0 = 0,
+ RESERVE1 = 1,
+ RESERVE2 = 2,
+ RESERVE3 = 3,
+ RESERVE4 = 4,
+ PMIC_STBY_REQ_CCMSRCGPCMIX = 5,
+ PMIC_ON_REQ_SNVSMIX = 6,
+ ONOFF_SNVSMIX = 7,
+ POR_B_SNVSMIX = 8,
+ RTC_RESET_B_SNVSMIX = 9,
+ GPIO1_IO00 = 10,
+ GPIO1_IO01 = 11,
+ GPIO1_IO02 = 12,
+ GPIO1_IO03 = 13,
+ GPIO1_IO04 = 14,
+ GPIO1_IO05 = 15,
+ GPIO1_IO06 = 16,
+ GPIO1_IO07 = 17,
+ GPIO1_IO08 = 18,
+ GPIO1_IO09 = 19,
+ GPIO1_IO10 = 20,
+ GPIO1_IO11 = 21,
+ GPIO1_IO12 = 22,
+ GPIO1_IO13 = 23,
+ GPIO1_IO14 = 24,
+ GPIO1_IO15 = 25,
+ ENET_MDC = 26,
+ ENET_MDIO = 27,
+ ENET_TD3 = 28,
+ ENET_TD2 = 29,
+ ENET_TD1 = 30,
+ ENET_TD0 = 31,
+ ENET_TX_CTL = 32,
+ ENET_TXC = 33,
+ ENET_RX_CTL = 34,
+ ENET_RXC = 35,
+ ENET_RD0 = 36,
+ ENET_RD1 = 37,
+ ENET_RD2 = 38,
+ ENET_RD3 = 39,
+ SD1_CLK = 40,
+ SD1_CMD = 41,
+ SD1_DATA0 = 42,
+ SD1_DATA1 = 43,
+ SD1_DATA2 = 44,
+ SD1_DATA3 = 45,
+ SD1_DATA4 = 46,
+ SD1_DATA5 = 47,
+ SD1_DATA6 = 48,
+ SD1_DATA7 = 49,
+ SD1_RESET_B = 50,
+ SD1_STROBE = 51,
+ SD2_CD_B = 52,
+ SD2_CLK = 53,
+ SD2_CMD = 54,
+ SD2_DATA0 = 55,
+ SD2_DATA1 = 56,
+ SD2_DATA2 = 57,
+ SD2_DATA3 = 58,
+ SD2_RESET_B = 59,
+ SD2_WP = 60,
+ NAND_ALE = 61,
+ NAND_CE0_B = 62,
+ NAND_CE1_B = 63,
+ NAND_CE2_B = 64,
+ NAND_CE3_B = 65,
+ NAND_CLE = 66,
+ NAND_DATA00 = 67,
+ NAND_DATA01 = 68,
+ NAND_DATA02 = 69,
+ NAND_DATA03 = 70,
+ NAND_DATA04 = 71,
+ NAND_DATA05 = 72,
+ NAND_DATA06 = 73,
+ NAND_DATA07 = 74,
+ NAND_DQS = 75,
+ NAND_RE_B = 76,
+ NAND_READY_B = 77,
+ NAND_WE_B = 78,
+ NAND_WP_B = 79,
+ SAI5_RXFS = 80,
+ SAI5_RXC = 81,
+ SAI5_RXD0 = 82,
+ SAI5_RXD1 = 83,
+ SAI5_RXD2 = 84,
+ SAI5_RXD3 = 85,
+ SAI5_MCLK = 86,
+ SAI1_RXFS = 87,
+ SAI1_RXC = 88,
+ SAI1_RXD0 = 89,
+ SAI1_RXD1 = 90,
+ SAI1_RXD2 = 91,
+ SAI1_RXD3 = 92,
+ SAI1_RXD4 = 93,
+ SAI1_RXD5 = 94,
+ SAI1_RXD6 = 95,
+ SAI1_RXD7 = 96,
+ SAI1_TXFS = 97,
+ SAI1_TXC = 98,
+ SAI1_TXD0 = 99,
+ SAI1_TXD1 = 100,
+ SAI1_TXD2 = 101,
+ SAI1_TXD3 = 102,
+ SAI1_TXD4 = 103,
+ SAI1_TXD5 = 104,
+ SAI1_TXD6 = 105,
+ SAI1_TXD7 = 106,
+ SAI1_MCLK = 107,
+ SAI2_RXFS = 108,
+ SAI2_RXC = 109,
+ SAI2_RXD0 = 110,
+ SAI2_TXFS = 111,
+ SAI2_TXC = 112,
+ SAI2_TXD0 = 113,
+ SAI2_MCLK = 114,
+ SAI3_RXFS = 115,
+ SAI3_RXC = 116,
+ SAI3_RXD = 117,
+ SAI3_TXFS = 118,
+ SAI3_TXC = 119,
+ SAI3_TXD = 120,
+ SAI3_MCLK = 121,
+ SPDIF_TX = 122,
+ SPDIF_RX = 123,
+ SPDIF_EXT_CLK = 124,
+ ECSPI1_SCLK = 125,
+ ECSPI1_MOSI = 126,
+ ECSPI1_MISO = 127,
+ ECSPI1_SS0 = 128,
+ ECSPI2_SCLK = 129,
+ ECSPI2_MOSI = 130,
+ ECSPI2_MISO = 131,
+ ECSPI2_SS0 = 132,
+ I2C1_SCL = 133,
+ I2C1_SDA = 134,
+ I2C2_SCL = 135,
+ I2C2_SDA = 136,
+ I2C3_SCL = 137,
+ I2C3_SDA = 138,
+ I2C4_SCL = 139,
+ I2C4_SDA = 140,
+ UART1_RXD = 141,
+ UART1_TXD = 142,
+ UART2_RXD = 143,
+ UART2_TXD = 144,
+ UART3_RXD = 145,
+ UART3_TXD = 146,
+ UART4_RXD = 147,
+ UART4_TXD = 148,
+};
+
+static const struct imx_pinctrl_pin_desc imx8m_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(RESERVE0),
+ IMX_PINCTRL_PIN(RESERVE1),
+ IMX_PINCTRL_PIN(RESERVE2),
+ IMX_PINCTRL_PIN(RESERVE3),
+ IMX_PINCTRL_PIN(RESERVE4),
+ IMX_PINCTRL_PIN(PMIC_STBY_REQ_CCMSRCGPCMIX),
+ IMX_PINCTRL_PIN(PMIC_ON_REQ_SNVSMIX),
+ IMX_PINCTRL_PIN(ONOFF_SNVSMIX),
+ IMX_PINCTRL_PIN(POR_B_SNVSMIX),
+ IMX_PINCTRL_PIN(RTC_RESET_B_SNVSMIX),
+ IMX_PINCTRL_PIN(GPIO1_IO00),
+ IMX_PINCTRL_PIN(GPIO1_IO01),
+ IMX_PINCTRL_PIN(GPIO1_IO02),
+ IMX_PINCTRL_PIN(GPIO1_IO03),
+ IMX_PINCTRL_PIN(GPIO1_IO04),
+ IMX_PINCTRL_PIN(GPIO1_IO05),
+ IMX_PINCTRL_PIN(GPIO1_IO06),
+ IMX_PINCTRL_PIN(GPIO1_IO07),
+ IMX_PINCTRL_PIN(GPIO1_IO08),
+ IMX_PINCTRL_PIN(GPIO1_IO09),
+ IMX_PINCTRL_PIN(GPIO1_IO10),
+ IMX_PINCTRL_PIN(GPIO1_IO11),
+ IMX_PINCTRL_PIN(GPIO1_IO12),
+ IMX_PINCTRL_PIN(GPIO1_IO13),
+ IMX_PINCTRL_PIN(GPIO1_IO14),
+ IMX_PINCTRL_PIN(GPIO1_IO15),
+ IMX_PINCTRL_PIN(ENET_MDC),
+ IMX_PINCTRL_PIN(ENET_MDIO),
+ IMX_PINCTRL_PIN(ENET_TD3),
+ IMX_PINCTRL_PIN(ENET_TD2),
+ IMX_PINCTRL_PIN(ENET_TD1),
+ IMX_PINCTRL_PIN(ENET_TD0),
+ IMX_PINCTRL_PIN(ENET_TX_CTL),
+ IMX_PINCTRL_PIN(ENET_TXC),
+ IMX_PINCTRL_PIN(ENET_RX_CTL),
+ IMX_PINCTRL_PIN(ENET_RXC),
+ IMX_PINCTRL_PIN(ENET_RD0),
+ IMX_PINCTRL_PIN(ENET_RD1),
+ IMX_PINCTRL_PIN(ENET_RD2),
+ IMX_PINCTRL_PIN(ENET_RD3),
+ IMX_PINCTRL_PIN(SD1_CLK),
+ IMX_PINCTRL_PIN(SD1_CMD),
+ IMX_PINCTRL_PIN(SD1_DATA0),
+ IMX_PINCTRL_PIN(SD1_DATA1),
+ IMX_PINCTRL_PIN(SD1_DATA2),
+ IMX_PINCTRL_PIN(SD1_DATA3),
+ IMX_PINCTRL_PIN(SD1_DATA4),
+ IMX_PINCTRL_PIN(SD1_DATA5),
+ IMX_PINCTRL_PIN(SD1_DATA6),
+ IMX_PINCTRL_PIN(SD1_DATA7),
+ IMX_PINCTRL_PIN(SD1_RESET_B),
+ IMX_PINCTRL_PIN(SD1_STROBE),
+ IMX_PINCTRL_PIN(SD2_CD_B),
+ IMX_PINCTRL_PIN(SD2_CLK),
+ IMX_PINCTRL_PIN(SD2_CMD),
+ IMX_PINCTRL_PIN(SD2_DATA0),
+ IMX_PINCTRL_PIN(SD2_DATA1),
+ IMX_PINCTRL_PIN(SD2_DATA2),
+ IMX_PINCTRL_PIN(SD2_DATA3),
+ IMX_PINCTRL_PIN(SD2_RESET_B),
+ IMX_PINCTRL_PIN(SD2_WP),
+ IMX_PINCTRL_PIN(NAND_ALE),
+ IMX_PINCTRL_PIN(NAND_CE0_B),
+ IMX_PINCTRL_PIN(NAND_CE1_B),
+ IMX_PINCTRL_PIN(NAND_CE2_B),
+ IMX_PINCTRL_PIN(NAND_CE3_B),
+ IMX_PINCTRL_PIN(NAND_CLE),
+ IMX_PINCTRL_PIN(NAND_DATA00),
+ IMX_PINCTRL_PIN(NAND_DATA01),
+ IMX_PINCTRL_PIN(NAND_DATA02),
+ IMX_PINCTRL_PIN(NAND_DATA03),
+ IMX_PINCTRL_PIN(NAND_DATA04),
+ IMX_PINCTRL_PIN(NAND_DATA05),
+ IMX_PINCTRL_PIN(NAND_DATA06),
+ IMX_PINCTRL_PIN(NAND_DATA07),
+ IMX_PINCTRL_PIN(NAND_DQS),
+ IMX_PINCTRL_PIN(NAND_RE_B),
+ IMX_PINCTRL_PIN(NAND_READY_B),
+ IMX_PINCTRL_PIN(NAND_WE_B),
+ IMX_PINCTRL_PIN(NAND_WP_B),
+ IMX_PINCTRL_PIN(SAI5_RXFS),
+ IMX_PINCTRL_PIN(SAI5_RXC),
+ IMX_PINCTRL_PIN(SAI5_RXD0),
+ IMX_PINCTRL_PIN(SAI5_RXD1),
+ IMX_PINCTRL_PIN(SAI5_RXD2),
+ IMX_PINCTRL_PIN(SAI5_RXD3),
+ IMX_PINCTRL_PIN(SAI5_MCLK),
+ IMX_PINCTRL_PIN(SAI1_RXFS),
+ IMX_PINCTRL_PIN(SAI1_RXC),
+ IMX_PINCTRL_PIN(SAI1_RXD0),
+ IMX_PINCTRL_PIN(SAI1_RXD1),
+ IMX_PINCTRL_PIN(SAI1_RXD2),
+ IMX_PINCTRL_PIN(SAI1_RXD3),
+ IMX_PINCTRL_PIN(SAI1_RXD4),
+ IMX_PINCTRL_PIN(SAI1_RXD5),
+ IMX_PINCTRL_PIN(SAI1_RXD6),
+ IMX_PINCTRL_PIN(SAI1_RXD7),
+ IMX_PINCTRL_PIN(SAI1_TXFS),
+ IMX_PINCTRL_PIN(SAI1_TXC),
+ IMX_PINCTRL_PIN(SAI1_TXD0),
+ IMX_PINCTRL_PIN(SAI1_TXD1),
+ IMX_PINCTRL_PIN(SAI1_TXD2),
+ IMX_PINCTRL_PIN(SAI1_TXD3),
+ IMX_PINCTRL_PIN(SAI1_TXD4),
+ IMX_PINCTRL_PIN(SAI1_TXD5),
+ IMX_PINCTRL_PIN(SAI1_TXD6),
+ IMX_PINCTRL_PIN(SAI1_TXD7),
+ IMX_PINCTRL_PIN(SAI1_MCLK),
+ IMX_PINCTRL_PIN(SAI2_RXFS),
+ IMX_PINCTRL_PIN(SAI2_RXC),
+ IMX_PINCTRL_PIN(SAI2_RXD0),
+ IMX_PINCTRL_PIN(SAI2_TXFS),
+ IMX_PINCTRL_PIN(SAI2_TXC),
+ IMX_PINCTRL_PIN(SAI2_TXD0),
+ IMX_PINCTRL_PIN(SAI2_MCLK),
+ IMX_PINCTRL_PIN(SAI3_RXFS),
+ IMX_PINCTRL_PIN(SAI3_RXC),
+ IMX_PINCTRL_PIN(SAI3_RXD),
+ IMX_PINCTRL_PIN(SAI3_TXFS),
+ IMX_PINCTRL_PIN(SAI3_TXC),
+ IMX_PINCTRL_PIN(SAI3_TXD),
+ IMX_PINCTRL_PIN(SAI3_MCLK),
+ IMX_PINCTRL_PIN(SPDIF_TX),
+ IMX_PINCTRL_PIN(SPDIF_RX),
+ IMX_PINCTRL_PIN(SPDIF_EXT_CLK),
+ IMX_PINCTRL_PIN(ECSPI1_SCLK),
+ IMX_PINCTRL_PIN(ECSPI1_MOSI),
+ IMX_PINCTRL_PIN(ECSPI1_MISO),
+ IMX_PINCTRL_PIN(ECSPI1_SS0),
+ IMX_PINCTRL_PIN(ECSPI2_SCLK),
+ IMX_PINCTRL_PIN(ECSPI2_MOSI),
+ IMX_PINCTRL_PIN(ECSPI2_MISO),
+ IMX_PINCTRL_PIN(ECSPI2_SS0),
+ IMX_PINCTRL_PIN(I2C1_SCL),
+ IMX_PINCTRL_PIN(I2C1_SDA),
+ IMX_PINCTRL_PIN(I2C2_SCL),
+ IMX_PINCTRL_PIN(I2C2_SDA),
+ IMX_PINCTRL_PIN(I2C3_SCL),
+ IMX_PINCTRL_PIN(I2C3_SDA),
+ IMX_PINCTRL_PIN(I2C4_SCL),
+ IMX_PINCTRL_PIN(I2C4_SDA),
+ IMX_PINCTRL_PIN(UART1_RXD),
+ IMX_PINCTRL_PIN(UART1_TXD),
+ IMX_PINCTRL_PIN(UART2_RXD),
+ IMX_PINCTRL_PIN(UART2_TXD),
+ IMX_PINCTRL_PIN(UART3_RXD),
+ IMX_PINCTRL_PIN(UART3_TXD),
+ IMX_PINCTRL_PIN(UART4_RXD),
+ IMX_PINCTRL_PIN(UART4_TXD),
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx9.c b/drivers/pinctrl/nxp/pinctrl-imx9.c
new file mode 100644
index 00000000000..de22e29e953
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx9.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 NXP
+ */
+
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <asm/io.h>
+
+#include "pinctrl-imx.h"
+
+static struct imx_pinctrl_soc_info imx9_pinctrl_soc_info __section(".data") = {
+ .flags = ZERO_OFFSET_VALID,
+};
+
+static const struct udevice_id imx9_pinctrl_match[] = {
+#if IS_ENABLED(CONFIG_IMX93)
+ { .compatible = "fsl,imx93-iomuxc", .data = (ulong)&imx9_pinctrl_soc_info },
+#endif
+#if IS_ENABLED(CONFIG_IMX91)
+ { .compatible = "fsl,imx91-iomuxc", .data = (ulong)&imx9_pinctrl_soc_info },
+#endif
+ { /* sentinel */ }
+};
+
+#if CONFIG_IS_ENABLED(CMD_PINMUX)
+
+#if IS_ENABLED(CONFIG_IMX93)
+#include "pinctrl-imx93.c"
+#elif IS_ENABLED(CONFIG_IMX91)
+#include "pinctrl-imx91.c"
+#endif
+
+static int imx9_get_pins_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(imx9_pinctrl_pads);
+}
+
+static const char *imx9_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+ /* sanity checking */
+ if (selector != imx9_pinctrl_pads[selector].number) {
+ dev_err(dev,
+ "selector(%u) not match with imx9_pinctrl_pads[selector].number(%u)\n",
+ selector, imx9_pinctrl_pads[selector].number);
+ return NULL;
+ }
+
+ return imx9_pinctrl_pads[selector].name;
+}
+
+static int imx9_get_pin_muxing(struct udevice *dev, unsigned int selector,
+ char *buf, int size)
+{
+ struct imx_pinctrl_priv *priv = dev_get_priv(dev);
+ struct imx_pinctrl_soc_info *info = priv->info;
+ u32 mux_reg = selector << 2;
+ u32 mux_mode = readl(info->base + mux_reg);
+ u32 sion = mux_mode >> 4;
+
+ snprintf(buf, size, "Function(%d) SION(%d) at: 0x%p", mux_mode & 0x7, sion,
+ info->base + mux_reg);
+
+ return 0;
+}
+#endif
+
+static const struct pinctrl_ops imx9_pinctrl_ops = {
+#if CONFIG_IS_ENABLED(CMD_PINMUX)
+ .get_pin_name = imx9_get_pin_name,
+ .get_pins_count = imx9_get_pins_count,
+ .get_pin_muxing = imx9_get_pin_muxing,
+#endif
+ .set_state = imx_pinctrl_set_state_mmio,
+};
+
+U_BOOT_DRIVER(imx9_pinctrl) = {
+ .name = "imx9-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(imx9_pinctrl_match),
+ .probe = imx_pinctrl_probe_mmio,
+ .remove = imx_pinctrl_remove_mmio,
+ .priv_auto = sizeof(struct imx_pinctrl_priv),
+ .ops = &imx9_pinctrl_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx91.c b/drivers/pinctrl/nxp/pinctrl-imx91.c
new file mode 100644
index 00000000000..1dc63cda2fd
--- /dev/null
+++ b/drivers/pinctrl/nxp/pinctrl-imx91.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 NXP
+ */
+
+#include "pinctrl-imx.h"
+
+enum imx91_pads {
+ DAP_TDI = 0,
+ DAP_TMS_SWDIO = 1,
+ DAP_TCLK_SWCLK = 2,
+ DAP_TDO_TRACESWO = 3,
+ GPIO_IO00 = 4,
+ GPIO_IO01 = 5,
+ GPIO_IO02 = 6,
+ GPIO_IO03 = 7,
+ GPIO_IO04 = 8,
+ GPIO_IO05 = 9,
+ GPIO_IO06 = 10,
+ GPIO_IO07 = 11,
+ GPIO_IO08 = 12,
+ GPIO_IO09 = 13,
+ GPIO_IO10 = 14,
+ GPIO_IO11 = 15,
+ GPIO_IO12 = 16,
+ GPIO_IO13 = 17,
+ GPIO_IO14 = 18,
+ GPIO_IO15 = 19,
+ GPIO_IO16 = 20,
+ GPIO_IO17 = 21,
+ GPIO_IO18 = 22,
+ GPIO_IO19 = 23,
+ GPIO_IO20 = 24,
+ GPIO_IO21 = 25,
+ GPIO_IO22 = 26,
+ GPIO_IO23 = 27,
+ GPIO_IO24 = 28,
+ GPIO_IO25 = 29,
+ GPIO_IO26 = 30,
+ GPIO_IO27 = 31,
+ GPIO_IO28 = 32,
+ GPIO_IO29 = 33,
+ CCM_CLKO1 = 34,
+ CCM_CLKO2 = 35,
+ CCM_CLKO3 = 36,
+ CCM_CLKO4 = 37,
+ ENET1_MDC = 38,
+ ENET1_MDIO = 39,
+ ENET1_TD3 = 40,
+ ENET1_TD2 = 41,
+ ENET1_TD1 = 42,
+ ENET1_TD0 = 43,
+ ENET1_TX_CTL = 44,
+ ENET1_TXC = 45,
+ ENET1_RX_CTL = 46,
+ ENET1_RXC = 47,
+ ENET1_RD0 = 48,
+ ENET1_RD1 = 49,
+ ENET1_RD2 = 50,
+ ENET1_RD3 = 51,
+ ENET2_MDC = 52,
+ ENET2_MDIO = 53,
+ ENET2_TD3 = 54,
+ ENET2_TD2 = 55,
+ ENET2_TD1 = 56,
+ ENET2_TD0 = 57,
+ ENET2_TX_CTL = 58,
+ ENET2_TXC = 59,
+ ENET2_RX_CTL = 60,
+ ENET2_RXC = 61,
+ ENET2_RD0 = 62,
+ ENET2_RD1 = 63,
+ ENET2_RD2 = 64,
+ ENET2_RD3 = 65,
+ SD1_CLK = 66,
+ SD1_CMD = 67,
+ SD1_DATA0 = 68,
+ SD1_DATA1 = 69,
+ SD1_DATA2 = 70,
+ SD1_DATA3 = 71,
+ SD1_DATA4 = 72,
+ SD1_DATA5 = 73,
+ SD1_DATA6 = 74,
+ SD1_DATA7 = 75,
+ SD1_STROBE = 76,
+ SD2_VSELECT = 77,
+ SD3_CLK = 78,
+ SD3_CMD = 79,
+ SD3_DATA0 = 80,
+ SD3_DATA1 = 81,
+ SD3_DATA2 = 82,
+ SD3_DATA3 = 83,
+ SD2_CD_B = 84,
+ SD2_CLK = 85,
+ SD2_CMD = 86,
+ SD2_DATA0 = 87,
+ SD2_DATA1 = 88,
+ SD2_DATA2 = 89,
+ SD2_DATA3 = 90,
+ SD2_RESET_B = 91,
+ I2C1_SCL = 92,
+ I2C1_SDA = 93,
+ I2C2_SCL = 94,
+ I2C2_SDA = 95,
+ UART1_RXD = 96,
+ UART1_TXD = 97,
+ UART2_RXD = 98,
+ UART2_TXD = 99,
+ PDM_CLK = 100,
+ PDM_BIT_STREAM0 = 101,
+ PDM_BIT_STREAM1 = 102,
+ SAI1_TXFS = 103,
+ SAI1_TXC = 104,
+ SAI1_TXD0 = 105,
+ SAI1_RXD0 = 106,
+ WDOG_ANY = 107,
+};
+
+static const struct imx_pinctrl_pin_desc imx9_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(DAP_TDI),
+ IMX_PINCTRL_PIN(DAP_TMS_SWDIO),
+ IMX_PINCTRL_PIN(DAP_TCLK_SWCLK),
+ IMX_PINCTRL_PIN(DAP_TDO_TRACESWO),
+ IMX_PINCTRL_PIN(GPIO_IO00),
+ IMX_PINCTRL_PIN(GPIO_IO01),
+ IMX_PINCTRL_PIN(GPIO_IO02),
+ IMX_PINCTRL_PIN(GPIO_IO03),
+ IMX_PINCTRL_PIN(GPIO_IO04),
+ IMX_PINCTRL_PIN(GPIO_IO05),
+ IMX_PINCTRL_PIN(GPIO_IO06),
+ IMX_PINCTRL_PIN(GPIO_IO07),
+ IMX_PINCTRL_PIN(GPIO_IO08),
+ IMX_PINCTRL_PIN(GPIO_IO09),
+ IMX_PINCTRL_PIN(GPIO_IO10),
+ IMX_PINCTRL_PIN(GPIO_IO11),
+ IMX_PINCTRL_PIN(GPIO_IO12),
+ IMX_PINCTRL_PIN(GPIO_IO13),
+ IMX_PINCTRL_PIN(GPIO_IO14),
+ IMX_PINCTRL_PIN(GPIO_IO15),
+ IMX_PINCTRL_PIN(GPIO_IO16),
+ IMX_PINCTRL_PIN(GPIO_IO17),
+ IMX_PINCTRL_PIN(GPIO_IO18),
+ IMX_PINCTRL_PIN(GPIO_IO19),
+ IMX_PINCTRL_PIN(GPIO_IO20),
+ IMX_PINCTRL_PIN(GPIO_IO21),
+ IMX_PINCTRL_PIN(GPIO_IO22),
+ IMX_PINCTRL_PIN(GPIO_IO23),
+ IMX_PINCTRL_PIN(GPIO_IO24),
+ IMX_PINCTRL_PIN(GPIO_IO25),
+ IMX_PINCTRL_PIN(GPIO_IO26),
+ IMX_PINCTRL_PIN(GPIO_IO27),
+ IMX_PINCTRL_PIN(GPIO_IO28),
+ IMX_PINCTRL_PIN(GPIO_IO29),
+ IMX_PINCTRL_PIN(CCM_CLKO1),
+ IMX_PINCTRL_PIN(CCM_CLKO2),
+ IMX_PINCTRL_PIN(CCM_CLKO3),
+ IMX_PINCTRL_PIN(CCM_CLKO4),
+ IMX_PINCTRL_PIN(ENET1_MDC),
+ IMX_PINCTRL_PIN(ENET1_MDIO),
+ IMX_PINCTRL_PIN(ENET1_TD3),
+ IMX_PINCTRL_PIN(ENET1_TD2),
+ IMX_PINCTRL_PIN(ENET1_TD1),
+ IMX_PINCTRL_PIN(ENET1_TD0),
+ IMX_PINCTRL_PIN(ENET1_TX_CTL),
+ IMX_PINCTRL_PIN(ENET1_TXC),
+ IMX_PINCTRL_PIN(ENET1_RX_CTL),
+ IMX_PINCTRL_PIN(ENET1_RXC),
+ IMX_PINCTRL_PIN(ENET1_RD0),
+ IMX_PINCTRL_PIN(ENET1_RD1),
+ IMX_PINCTRL_PIN(ENET1_RD2),
+ IMX_PINCTRL_PIN(ENET1_RD3),
+ IMX_PINCTRL_PIN(ENET2_MDC),
+ IMX_PINCTRL_PIN(ENET2_MDIO),
+ IMX_PINCTRL_PIN(ENET2_TD3),
+ IMX_PINCTRL_PIN(ENET2_TD2),
+ IMX_PINCTRL_PIN(ENET2_TD1),
+ IMX_PINCTRL_PIN(ENET2_TD0),
+ IMX_PINCTRL_PIN(ENET2_TX_CTL),
+ IMX_PINCTRL_PIN(ENET2_TXC),
+ IMX_PINCTRL_PIN(ENET2_RX_CTL),
+ IMX_PINCTRL_PIN(ENET2_RXC),
+ IMX_PINCTRL_PIN(ENET2_RD0),
+ IMX_PINCTRL_PIN(ENET2_RD1),
+ IMX_PINCTRL_PIN(ENET2_RD2),
+ IMX_PINCTRL_PIN(ENET2_RD3),
+ IMX_PINCTRL_PIN(SD1_CLK),
+ IMX_PINCTRL_PIN(SD1_CMD),
+ IMX_PINCTRL_PIN(SD1_DATA0),
+ IMX_PINCTRL_PIN(SD1_DATA1),
+ IMX_PINCTRL_PIN(SD1_DATA2),
+ IMX_PINCTRL_PIN(SD1_DATA3),
+ IMX_PINCTRL_PIN(SD1_DATA4),
+ IMX_PINCTRL_PIN(SD1_DATA5),
+ IMX_PINCTRL_PIN(SD1_DATA6),
+ IMX_PINCTRL_PIN(SD1_DATA7),
+ IMX_PINCTRL_PIN(SD1_STROBE),
+ IMX_PINCTRL_PIN(SD2_VSELECT),
+ IMX_PINCTRL_PIN(SD3_CLK),
+ IMX_PINCTRL_PIN(SD3_CMD),
+ IMX_PINCTRL_PIN(SD3_DATA0),
+ IMX_PINCTRL_PIN(SD3_DATA1),
+ IMX_PINCTRL_PIN(SD3_DATA2),
+ IMX_PINCTRL_PIN(SD3_DATA3),
+ IMX_PINCTRL_PIN(SD2_CD_B),
+ IMX_PINCTRL_PIN(SD2_CLK),
+ IMX_PINCTRL_PIN(SD2_CMD),
+ IMX_PINCTRL_PIN(SD2_DATA0),
+ IMX_PINCTRL_PIN(SD2_DATA1),
+ IMX_PINCTRL_PIN(SD2_DATA2),
+ IMX_PINCTRL_PIN(SD2_DATA3),
+ IMX_PINCTRL_PIN(SD2_RESET_B),
+ IMX_PINCTRL_PIN(I2C1_SCL),
+ IMX_PINCTRL_PIN(I2C1_SDA),
+ IMX_PINCTRL_PIN(I2C2_SCL),
+ IMX_PINCTRL_PIN(I2C2_SDA),
+ IMX_PINCTRL_PIN(UART1_RXD),
+ IMX_PINCTRL_PIN(UART1_TXD),
+ IMX_PINCTRL_PIN(UART2_RXD),
+ IMX_PINCTRL_PIN(UART2_TXD),
+ IMX_PINCTRL_PIN(PDM_CLK),
+ IMX_PINCTRL_PIN(PDM_BIT_STREAM0),
+ IMX_PINCTRL_PIN(PDM_BIT_STREAM1),
+ IMX_PINCTRL_PIN(SAI1_TXFS),
+ IMX_PINCTRL_PIN(SAI1_TXC),
+ IMX_PINCTRL_PIN(SAI1_TXD0),
+ IMX_PINCTRL_PIN(SAI1_RXD0),
+ IMX_PINCTRL_PIN(WDOG_ANY),
+};
diff --git a/drivers/pinctrl/nxp/pinctrl-imx93.c b/drivers/pinctrl/nxp/pinctrl-imx93.c
index 5d250db1081..d13969856f6 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx93.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx93.c
@@ -1,34 +1,228 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2022 NXP
+ * Copyright 2026 NXP
*/
-#include <dm/device.h>
-#include <dm/pinctrl.h>
-
#include "pinctrl-imx.h"
-static struct imx_pinctrl_soc_info imx93_pinctrl_soc_info __section(".data") = {
- .flags = ZERO_OFFSET_VALID,
-};
-
-static const struct udevice_id imx93_pinctrl_match[] = {
- { .compatible = "fsl,imx93-iomuxc", .data = (ulong)&imx93_pinctrl_soc_info },
- { .compatible = "fsl,imx91-iomuxc", .data = (ulong)&imx93_pinctrl_soc_info },
- { /* sentinel */ }
-};
-
-static const struct pinctrl_ops imx93_pinctrl_ops = {
- .set_state = imx_pinctrl_set_state_mmio,
+enum imx93_pads {
+ DAP_TDI = 0,
+ DAP_TMS_SWDIO = 1,
+ DAP_TCLK_SWCLK = 2,
+ DAP_TDO_TRACESWO = 3,
+ GPIO_IO00 = 4,
+ GPIO_IO01 = 5,
+ GPIO_IO02 = 6,
+ GPIO_IO03 = 7,
+ GPIO_IO04 = 8,
+ GPIO_IO05 = 9,
+ GPIO_IO06 = 10,
+ GPIO_IO07 = 11,
+ GPIO_IO08 = 12,
+ GPIO_IO09 = 13,
+ GPIO_IO10 = 14,
+ GPIO_IO11 = 15,
+ GPIO_IO12 = 16,
+ GPIO_IO13 = 17,
+ GPIO_IO14 = 18,
+ GPIO_IO15 = 19,
+ GPIO_IO16 = 20,
+ GPIO_IO17 = 21,
+ GPIO_IO18 = 22,
+ GPIO_IO19 = 23,
+ GPIO_IO20 = 24,
+ GPIO_IO21 = 25,
+ GPIO_IO22 = 26,
+ GPIO_IO23 = 27,
+ GPIO_IO24 = 28,
+ GPIO_IO25 = 29,
+ GPIO_IO26 = 30,
+ GPIO_IO27 = 31,
+ GPIO_IO28 = 32,
+ GPIO_IO29 = 33,
+ CCM_CLKO1 = 34,
+ CCM_CLKO2 = 35,
+ CCM_CLKO3 = 36,
+ CCM_CLKO4 = 37,
+ ENET1_MDC = 38,
+ ENET1_MDIO = 39,
+ ENET1_TD3 = 40,
+ ENET1_TD2 = 41,
+ ENET1_TD1 = 42,
+ ENET1_TD0 = 43,
+ ENET1_TX_CTL = 44,
+ ENET1_TXC = 45,
+ ENET1_RX_CTL = 46,
+ ENET1_RXC = 47,
+ ENET1_RD0 = 48,
+ ENET1_RD1 = 49,
+ ENET1_RD2 = 50,
+ ENET1_RD3 = 51,
+ ENET2_MDC = 52,
+ ENET2_MDIO = 53,
+ ENET2_TD3 = 54,
+ ENET2_TD2 = 55,
+ ENET2_TD1 = 56,
+ ENET2_TD0 = 57,
+ ENET2_TX_CTL = 58,
+ ENET2_TXC = 59,
+ ENET2_RX_CTL = 60,
+ ENET2_RXC = 61,
+ ENET2_RD0 = 62,
+ ENET2_RD1 = 63,
+ ENET2_RD2 = 64,
+ ENET2_RD3 = 65,
+ SD1_CLK = 66,
+ SD1_CMD = 67,
+ SD1_DATA0 = 68,
+ SD1_DATA1 = 69,
+ SD1_DATA2 = 70,
+ SD1_DATA3 = 71,
+ SD1_DATA4 = 72,
+ SD1_DATA5 = 73,
+ SD1_DATA6 = 74,
+ SD1_DATA7 = 75,
+ SD1_STROBE = 76,
+ SD2_VSELECT = 77,
+ SD3_CLK = 78,
+ SD3_CMD = 79,
+ SD3_DATA0 = 80,
+ SD3_DATA1 = 81,
+ SD3_DATA2 = 82,
+ SD3_DATA3 = 83,
+ SD2_CD_B = 84,
+ SD2_CLK = 85,
+ SD2_CMD = 86,
+ SD2_DATA0 = 87,
+ SD2_DATA1 = 88,
+ SD2_DATA2 = 89,
+ SD2_DATA3 = 90,
+ SD2_RESET_B = 91,
+ I2C1_SCL = 92,
+ I2C1_SDA = 93,
+ I2C2_SCL = 94,
+ I2C2_SDA = 95,
+ UART1_RXD = 96,
+ UART1_TXD = 97,
+ UART2_RXD = 98,
+ UART2_TXD = 99,
+ PDM_CLK = 100,
+ PDM_BIT_STREAM0 = 101,
+ PDM_BIT_STREAM1 = 102,
+ SAI1_TXFS = 103,
+ SAI1_TXC = 104,
+ SAI1_TXD0 = 105,
+ SAI1_RXD0 = 106,
+ WDOG_ANY = 107,
};
-U_BOOT_DRIVER(imx93_pinctrl) = {
- .name = "imx93-pinctrl",
- .id = UCLASS_PINCTRL,
- .of_match = of_match_ptr(imx93_pinctrl_match),
- .probe = imx_pinctrl_probe_mmio,
- .remove = imx_pinctrl_remove_mmio,
- .priv_auto = sizeof(struct imx_pinctrl_priv),
- .ops = &imx93_pinctrl_ops,
- .flags = DM_FLAG_PRE_RELOC,
+static const struct imx_pinctrl_pin_desc imx9_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(DAP_TDI),
+ IMX_PINCTRL_PIN(DAP_TMS_SWDIO),
+ IMX_PINCTRL_PIN(DAP_TCLK_SWCLK),
+ IMX_PINCTRL_PIN(DAP_TDO_TRACESWO),
+ IMX_PINCTRL_PIN(GPIO_IO00),
+ IMX_PINCTRL_PIN(GPIO_IO01),
+ IMX_PINCTRL_PIN(GPIO_IO02),
+ IMX_PINCTRL_PIN(GPIO_IO03),
+ IMX_PINCTRL_PIN(GPIO_IO04),
+ IMX_PINCTRL_PIN(GPIO_IO05),
+ IMX_PINCTRL_PIN(GPIO_IO06),
+ IMX_PINCTRL_PIN(GPIO_IO07),
+ IMX_PINCTRL_PIN(GPIO_IO08),
+ IMX_PINCTRL_PIN(GPIO_IO09),
+ IMX_PINCTRL_PIN(GPIO_IO10),
+ IMX_PINCTRL_PIN(GPIO_IO11),
+ IMX_PINCTRL_PIN(GPIO_IO12),
+ IMX_PINCTRL_PIN(GPIO_IO13),
+ IMX_PINCTRL_PIN(GPIO_IO14),
+ IMX_PINCTRL_PIN(GPIO_IO15),
+ IMX_PINCTRL_PIN(GPIO_IO16),
+ IMX_PINCTRL_PIN(GPIO_IO17),
+ IMX_PINCTRL_PIN(GPIO_IO18),
+ IMX_PINCTRL_PIN(GPIO_IO19),
+ IMX_PINCTRL_PIN(GPIO_IO20),
+ IMX_PINCTRL_PIN(GPIO_IO21),
+ IMX_PINCTRL_PIN(GPIO_IO22),
+ IMX_PINCTRL_PIN(GPIO_IO23),
+ IMX_PINCTRL_PIN(GPIO_IO24),
+ IMX_PINCTRL_PIN(GPIO_IO25),
+ IMX_PINCTRL_PIN(GPIO_IO26),
+ IMX_PINCTRL_PIN(GPIO_IO27),
+ IMX_PINCTRL_PIN(GPIO_IO28),
+ IMX_PINCTRL_PIN(GPIO_IO29),
+ IMX_PINCTRL_PIN(CCM_CLKO1),
+ IMX_PINCTRL_PIN(CCM_CLKO2),
+ IMX_PINCTRL_PIN(CCM_CLKO3),
+ IMX_PINCTRL_PIN(CCM_CLKO4),
+ IMX_PINCTRL_PIN(ENET1_MDC),
+ IMX_PINCTRL_PIN(ENET1_MDIO),
+ IMX_PINCTRL_PIN(ENET1_TD3),
+ IMX_PINCTRL_PIN(ENET1_TD2),
+ IMX_PINCTRL_PIN(ENET1_TD1),
+ IMX_PINCTRL_PIN(ENET1_TD0),
+ IMX_PINCTRL_PIN(ENET1_TX_CTL),
+ IMX_PINCTRL_PIN(ENET1_TXC),
+ IMX_PINCTRL_PIN(ENET1_RX_CTL),
+ IMX_PINCTRL_PIN(ENET1_RXC),
+ IMX_PINCTRL_PIN(ENET1_RD0),
+ IMX_PINCTRL_PIN(ENET1_RD1),
+ IMX_PINCTRL_PIN(ENET1_RD2),
+ IMX_PINCTRL_PIN(ENET1_RD3),
+ IMX_PINCTRL_PIN(ENET2_MDC),
+ IMX_PINCTRL_PIN(ENET2_MDIO),
+ IMX_PINCTRL_PIN(ENET2_TD3),
+ IMX_PINCTRL_PIN(ENET2_TD2),
+ IMX_PINCTRL_PIN(ENET2_TD1),
+ IMX_PINCTRL_PIN(ENET2_TD0),
+ IMX_PINCTRL_PIN(ENET2_TX_CTL),
+ IMX_PINCTRL_PIN(ENET2_TXC),
+ IMX_PINCTRL_PIN(ENET2_RX_CTL),
+ IMX_PINCTRL_PIN(ENET2_RXC),
+ IMX_PINCTRL_PIN(ENET2_RD0),
+ IMX_PINCTRL_PIN(ENET2_RD1),
+ IMX_PINCTRL_PIN(ENET2_RD2),
+ IMX_PINCTRL_PIN(ENET2_RD3),
+ IMX_PINCTRL_PIN(SD1_CLK),
+ IMX_PINCTRL_PIN(SD1_CMD),
+ IMX_PINCTRL_PIN(SD1_DATA0),
+ IMX_PINCTRL_PIN(SD1_DATA1),
+ IMX_PINCTRL_PIN(SD1_DATA2),
+ IMX_PINCTRL_PIN(SD1_DATA3),
+ IMX_PINCTRL_PIN(SD1_DATA4),
+ IMX_PINCTRL_PIN(SD1_DATA5),
+ IMX_PINCTRL_PIN(SD1_DATA6),
+ IMX_PINCTRL_PIN(SD1_DATA7),
+ IMX_PINCTRL_PIN(SD1_STROBE),
+ IMX_PINCTRL_PIN(SD2_VSELECT),
+ IMX_PINCTRL_PIN(SD3_CLK),
+ IMX_PINCTRL_PIN(SD3_CMD),
+ IMX_PINCTRL_PIN(SD3_DATA0),
+ IMX_PINCTRL_PIN(SD3_DATA1),
+ IMX_PINCTRL_PIN(SD3_DATA2),
+ IMX_PINCTRL_PIN(SD3_DATA3),
+ IMX_PINCTRL_PIN(SD2_CD_B),
+ IMX_PINCTRL_PIN(SD2_CLK),
+ IMX_PINCTRL_PIN(SD2_CMD),
+ IMX_PINCTRL_PIN(SD2_DATA0),
+ IMX_PINCTRL_PIN(SD2_DATA1),
+ IMX_PINCTRL_PIN(SD2_DATA2),
+ IMX_PINCTRL_PIN(SD2_DATA3),
+ IMX_PINCTRL_PIN(SD2_RESET_B),
+ IMX_PINCTRL_PIN(I2C1_SCL),
+ IMX_PINCTRL_PIN(I2C1_SDA),
+ IMX_PINCTRL_PIN(I2C2_SCL),
+ IMX_PINCTRL_PIN(I2C2_SDA),
+ IMX_PINCTRL_PIN(UART1_RXD),
+ IMX_PINCTRL_PIN(UART1_TXD),
+ IMX_PINCTRL_PIN(UART2_RXD),
+ IMX_PINCTRL_PIN(UART2_TXD),
+ IMX_PINCTRL_PIN(PDM_CLK),
+ IMX_PINCTRL_PIN(PDM_BIT_STREAM0),
+ IMX_PINCTRL_PIN(PDM_BIT_STREAM1),
+ IMX_PINCTRL_PIN(SAI1_TXFS),
+ IMX_PINCTRL_PIN(SAI1_TXC),
+ IMX_PINCTRL_PIN(SAI1_TXD0),
+ IMX_PINCTRL_PIN(SAI1_RXD0),
+ IMX_PINCTRL_PIN(WDOG_ANY),
};
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index bb37b39fa0e..fc5d2a3e5e3 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -232,17 +232,19 @@ static int imx_pwm_of_to_plat(struct udevice *dev)
priv->regs = dev_read_addr_ptr(dev);
- ret = clk_get_by_name(dev, "per", &priv->per_clk);
- if (ret) {
- printf("Failed to get per_clk\n");
- return ret;
- }
+ if (CONFIG_IS_ENABLED(CLK)) {
+ ret = clk_get_by_name(dev, "per", &priv->per_clk);
+ if (ret) {
+ printf("Failed to get per_clk\n");
+ return ret;
+ }
- ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
- if (ret) {
- printf("Failed to get ipg_clk\n");
- return ret;
- }
+ ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
+ if (ret) {
+ printf("Failed to get ipg_clk\n");
+ return ret;
+ }
+ }
return 0;
}
@@ -252,17 +254,19 @@ static int imx_pwm_probe(struct udevice *dev)
int ret;
struct imx_pwm_priv *priv = dev_get_priv(dev);
- ret = clk_enable(&priv->per_clk);
- if (ret) {
- printf("Failed to enable per_clk\n");
- return ret;
- }
+ if (CONFIG_IS_ENABLED(CLK)) {
+ ret = clk_enable(&priv->per_clk);
+ if (ret) {
+ printf("Failed to enable per_clk\n");
+ return ret;
+ }
- ret = clk_enable(&priv->ipg_clk);
- if (ret) {
- printf("Failed to enable ipg_clk\n");
- return ret;
- }
+ ret = clk_enable(&priv->ipg_clk);
+ if (ret) {
+ printf("Failed to enable ipg_clk\n");
+ return ret;
+ }
+ }
return 0;
}
diff --git a/drivers/video/imx/Kconfig b/drivers/video/imx/Kconfig
index b35ba965efc..c25f209629e 100644
--- a/drivers/video/imx/Kconfig
+++ b/drivers/video/imx/Kconfig
@@ -15,6 +15,13 @@ config IMX_HDMI
bool "Enable HDMI support in IPUv3"
depends on VIDEO_IPUV3
+config IPU_CLK_LEGACY
+ bool "Use legacy clock management for IPU"
+ depends on VIDEO_IPUV3 && !CLK
+ default y
+ help
+ Use legacy clock management instead of Common Clock Framework.
+
config IMX_LDB
bool "Freescale i.MX8MP LDB bridge"
depends on VIDEO_BRIDGE
diff --git a/drivers/video/imx/Makefile b/drivers/video/imx/Makefile
index 1edf5a6bdf0..0e7f71a9f93 100644
--- a/drivers/video/imx/Makefile
+++ b/drivers/video/imx/Makefile
@@ -4,5 +4,6 @@
# Wolfgang Denk, DENX Software Engineering, [email protected].
obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o
+obj-$(CONFIG_IPU_CLK_LEGACY) += ipu_clk_legacy.o
obj-$(CONFIG_IMX_LDB) += ldb.o
obj-$(CONFIG_IMX_LCDIF) += lcdif.o
diff --git a/drivers/video/imx/ipu.h b/drivers/video/imx/ipu.h
index 62827dc480d..ae40e20bc28 100644
--- a/drivers/video/imx/ipu.h
+++ b/drivers/video/imx/ipu.h
@@ -18,14 +18,23 @@
#ifndef __ASM_ARCH_IPU_H__
#define __ASM_ARCH_IPU_H__
+#if !CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+#include <clk.h>
+#endif
#include <ipu_pixfmt.h>
#include <linux/types.h>
+#define IPUV3_CLK_MX51 133000000
+#define IPUV3_CLK_MX53 200000000
+#define IPUV3_CLK_MX6Q 264000000
+#define IPUV3_CLK_MX6DL 198000000
+
#define IDMA_CHAN_INVALID 0xFF
#define HIGH_RESOLUTION_WIDTH 1024
struct ipu_ctx;
-struct ipu_di_config;
+
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
struct clk {
const char *name;
@@ -75,6 +84,46 @@ struct clk {
int (*set_parent)(struct clk *clk, struct clk *parent);
};
+/* Legacy clock API functions */
+void clk_enable(struct clk *clk);
+void clk_disable(struct clk *clk);
+int clk_get_usecount(struct clk *clk);
+u32 clk_get_rate(struct clk *clk);
+struct clk *clk_get_parent(struct clk *clk);
+int clk_set_rate(struct clk *clk, unsigned long rate);
+long clk_round_rate(struct clk *clk, unsigned long rate);
+int clk_set_parent(struct clk *clk, struct clk *parent);
+
+/* IPU clock initialization */
+int ipu_clk_init_legacy(struct ipu_ctx *ctx);
+int ipu_ldb_clk_init_legacy(struct ipu_ctx *ctx);
+int ipu_pixel_clk_init_legacy(struct ipu_ctx *ctx, int id);
+
+#else
+
+static inline int clk_get_usecount(struct clk *clk)
+{
+ return clk->enable_count;
+}
+
+/* Stub functions for non-legacy builds */
+static inline int ipu_clk_init_legacy(struct ipu_ctx *ctx)
+{
+ return -ENOSYS;
+}
+
+static inline int ipu_ldb_clk_init_legacy(struct ipu_ctx *ctx)
+{
+ return -ENOSYS;
+}
+
+static inline int ipu_pixel_clk_init_legacy(struct ipu_ctx *ctx, int id)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_IS_ENABLED(IPU_CLK_LEGACY) */
+
struct udevice;
/*
@@ -298,15 +347,6 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
u32 bytes_per_pixel(u32 fmt);
-void clk_enable(struct clk *clk);
-void clk_disable(struct clk *clk);
-u32 clk_get_rate(struct clk *clk);
-int clk_set_rate(struct clk *clk, unsigned long rate);
-long clk_round_rate(struct clk *clk, unsigned long rate);
-int clk_set_parent(struct clk *clk, struct clk *parent);
-int clk_get_usecount(struct clk *clk);
-struct clk *clk_get_parent(struct clk *clk);
-
void ipu_dump_registers(void);
struct ipu_ctx *ipu_probe(struct udevice *dev);
bool ipu_clk_enabled(struct ipu_ctx *ctx);
diff --git a/drivers/video/imx/ipu_clk_legacy.c b/drivers/video/imx/ipu_clk_legacy.c
new file mode 100644
index 00000000000..8aaafa2a080
--- /dev/null
+++ b/drivers/video/imx/ipu_clk_legacy.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Legacy IPU clock management for i.MX5/6 without Common Clock Framework
+ *
+ * (C) Copyright 2026
+ * Brian Ruley, GE HealthCare, [email protected]
+ */
+
+#include "ipu.h"
+#include "ipu_regs.h"
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <div64.h>
+#include <dm/devres.h>
+#include <linux/err.h>
+#include <log.h>
+
+extern struct mxc_ccm_reg *mxc_ccm;
+
+void clk_enable(struct clk *clk)
+{
+ if (clk) {
+ if (clk->usecount++ == 0)
+ clk->enable(clk);
+ }
+}
+
+void clk_disable(struct clk *clk)
+{
+ if (clk) {
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ }
+ }
+}
+
+int clk_get_usecount(struct clk *clk)
+{
+ if (clk == NULL)
+ return 0;
+
+ return clk->usecount;
+}
+
+u32 clk_get_rate(struct clk *clk)
+{
+ if (!clk)
+ return 0;
+
+ return clk->rate;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return 0;
+
+ return clk->parent;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk)
+ return 0;
+
+ if (clk->set_rate)
+ clk->set_rate(clk, rate);
+
+ return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ clk->parent = parent;
+ if (clk->set_parent)
+ return clk->set_parent(clk, parent);
+ return 0;
+}
+
+static int clk_ipu_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+#if CONFIG_IS_ENABLED(MX51) || CONFIG_IS_ENABLED(MX53)
+ reg = __raw_readl(&mxc_ccm->ccdr);
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, &mxc_ccm->ccdr);
+
+ reg = __raw_readl(&mxc_ccm->clpcr);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, &mxc_ccm->clpcr);
+#endif
+ return 0;
+}
+
+static void clk_ipu_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+
+#if CONFIG_IS_ENABLED(MX51) || CONFIG_IS_ENABLED(MX53)
+ reg = __raw_readl(&mxc_ccm->ccdr);
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, &mxc_ccm->ccdr);
+
+ reg = __raw_readl(&mxc_ccm->clpcr);
+ reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, &mxc_ccm->clpcr);
+#endif
+}
+
+static void ipu_pixel_clk_recalc(struct clk *clk)
+{
+ u32 div;
+ u64 final_rate = (unsigned long long)clk->parent->rate * 16;
+
+ div = __raw_readl(DI_BS_CLKGEN0(clk->id));
+ debug("read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n", div,
+ final_rate, clk->parent->rate);
+
+ clk->rate = 0;
+ if (div != 0) {
+ do_div(final_rate, div);
+ clk->rate = final_rate;
+ }
+}
+
+static unsigned long ipu_pixel_clk_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u64 div, final_rate;
+ u32 remainder;
+ u64 parent_rate = (unsigned long long)clk->parent->rate * 16;
+
+ div = parent_rate;
+ remainder = do_div(div, rate);
+ if (remainder > (rate / 2))
+ div++;
+ if (div < 0x10)
+ div = 0x10;
+ if (div & ~0xFEF)
+ div &= 0xFF8;
+ else {
+ if ((div & 0xC) == 0xC) {
+ div += 0x10;
+ div &= ~0xF;
+ }
+ }
+ final_rate = parent_rate;
+ do_div(final_rate, div);
+
+ return final_rate;
+}
+
+static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u64 div, parent_rate;
+ u32 remainder;
+
+ parent_rate = (unsigned long long)clk->parent->rate * 16;
+ div = parent_rate;
+ remainder = do_div(div, rate);
+ if (remainder > (rate / 2))
+ div++;
+
+ if ((div & 0xC) == 0xC) {
+ div += 0x10;
+ div &= ~0xF;
+ }
+ if (div > 0x1000)
+ debug("Overflow, DI_BS_CLKGEN0 div:0x%x\n", (u32)div);
+
+ __raw_writel(div, DI_BS_CLKGEN0(clk->id));
+ __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));
+
+ do_div(parent_rate, div);
+ clk->rate = parent_rate;
+
+ return 0;
+}
+
+static int ipu_pixel_clk_enable(struct clk *clk)
+{
+ u32 disp_gen = __raw_readl(IPU_DISP_GEN);
+ disp_gen |= clk->id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
+ __raw_writel(disp_gen, IPU_DISP_GEN);
+
+ return 0;
+}
+
+static void ipu_pixel_clk_disable(struct clk *clk)
+{
+ u32 disp_gen = __raw_readl(IPU_DISP_GEN);
+ disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
+ __raw_writel(disp_gen, IPU_DISP_GEN);
+}
+
+static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 di_gen = __raw_readl(DI_GENERAL(clk->id));
+ struct ipu_ctx *ctx = clk->ctx;
+
+ if (parent == ctx->ipu_clk)
+ di_gen &= ~DI_GEN_DI_CLK_EXT;
+ else if (!IS_ERR(ctx->di_clk[clk->id]) && parent == ctx->ldb_clk)
+ di_gen |= DI_GEN_DI_CLK_EXT;
+ else
+ return -EINVAL;
+
+ __raw_writel(di_gen, DI_GENERAL(clk->id));
+ ipu_pixel_clk_recalc(clk);
+ return 0;
+}
+
+int ipu_pixel_clk_init_legacy(struct ipu_ctx *ctx, int id)
+{
+ struct clk *pixel_clk;
+
+ pixel_clk = devm_kzalloc(ctx->dev, sizeof(*pixel_clk), GFP_KERNEL);
+ if (!pixel_clk)
+ return -ENOMEM;
+
+ pixel_clk->name = "pixel_clk";
+ pixel_clk->id = id;
+ pixel_clk->ctx = ctx;
+ pixel_clk->recalc = ipu_pixel_clk_recalc;
+ pixel_clk->set_rate = ipu_pixel_clk_set_rate;
+ pixel_clk->round_rate = ipu_pixel_clk_round_rate;
+ pixel_clk->set_parent = ipu_pixel_clk_set_parent;
+ pixel_clk->enable = ipu_pixel_clk_enable;
+ pixel_clk->disable = ipu_pixel_clk_disable;
+ pixel_clk->usecount = 0;
+
+ ctx->pixel_clk[id] = pixel_clk;
+ return 0;
+}
+
+int ipu_clk_init_legacy(struct ipu_ctx *ctx)
+{
+ struct clk *ipu_clk;
+
+ ipu_clk = devm_kzalloc(ctx->dev, sizeof(*ipu_clk), GFP_KERNEL);
+ if (!ipu_clk)
+ return -ENOMEM;
+
+ ipu_clk->name = "ipu_clk";
+ ipu_clk->ctx = ctx;
+#if CONFIG_IS_ENABLED(MX51) || CONFIG_IS_ENABLED(MX53)
+ ipu_clk->enable_reg =
+ (u32 *)(CCM_BASE_ADDR + offsetof(struct mxc_ccm_reg, CCGR5));
+ ipu_clk->enable_shift = MXC_CCM_CCGR5_IPU_OFFSET;
+#else
+ ipu_clk->enable_reg =
+ (u32 *)(CCM_BASE_ADDR + offsetof(struct mxc_ccm_reg, CCGR3));
+ ipu_clk->enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET;
+#endif
+
+ ipu_clk->enable = clk_ipu_enable;
+ ipu_clk->disable = clk_ipu_disable;
+ ipu_clk->usecount = 0;
+
+#if CONFIG_IS_ENABLED(MX51)
+ ipu_clk->rate = IPUV3_CLK_MX51;
+#elif CONFIG_IS_ENABLED(MX53)
+ ipu_clk->rate = IPUV3_CLK_MX53;
+#else
+ ipu_clk->rate = is_mx6sdl() ? IPUV3_CLK_MX6DL : IPUV3_CLK_MX6Q;
+#endif
+
+ ctx->ipu_clk = ipu_clk;
+ return 0;
+}
+
+#if !defined CFG_SYS_LDB_CLOCK
+#define CFG_SYS_LDB_CLOCK 65000000
+#endif
+
+int ipu_ldb_clk_init_legacy(struct ipu_ctx *ctx)
+{
+ struct clk *ldb_clk;
+
+ ldb_clk = devm_kzalloc(ctx->dev, sizeof(*ldb_clk), GFP_KERNEL);
+ if (!ldb_clk)
+ return -ENOMEM;
+
+ ldb_clk->name = "ldb_clk";
+ ldb_clk->ctx = ctx;
+ ldb_clk->rate = CFG_SYS_LDB_CLOCK;
+ ldb_clk->usecount = 0;
+
+ ctx->ldb_clk = ldb_clk;
+ return 0;
+}
diff --git a/drivers/video/imx/ipu_common.c b/drivers/video/imx/ipu_common.c
index e9897ee79d2..8630374a055 100644
--- a/drivers/video/imx/ipu_common.c
+++ b/drivers/video/imx/ipu_common.c
@@ -31,8 +31,8 @@
#include <linux/types.h>
#include <log.h>
-extern struct mxc_ccm_reg *mxc_ccm;
-extern u32 *ipu_cpmem_base;
+u32 *ipu_cpmem_base;
+u32 *ipu_dc_tmpl_reg;
struct ipu_ch_param_word {
u32 data[5];
@@ -92,126 +92,6 @@ struct ipu_ch_param {
#define IPU_SW_RST_TOUT_USEC (10000)
-#define IPUV3_CLK_MX51 133000000
-#define IPUV3_CLK_MX53 200000000
-#define IPUV3_CLK_MX6Q 264000000
-#define IPUV3_CLK_MX6DL 198000000
-
-void clk_enable(struct clk *clk)
-{
- if (clk) {
- if (clk->usecount++ == 0)
- clk->enable(clk);
- }
-}
-
-void clk_disable(struct clk *clk)
-{
- if (clk) {
- if (!(--clk->usecount)) {
- if (clk->disable)
- clk->disable(clk);
- }
- }
-}
-
-int clk_get_usecount(struct clk *clk)
-{
- if (clk == NULL)
- return 0;
-
- return clk->usecount;
-}
-
-u32 clk_get_rate(struct clk *clk)
-{
- if (!clk)
- return 0;
-
- return clk->rate;
-}
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- if (!clk)
- return 0;
-
- return clk->parent;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- if (!clk)
- return 0;
-
- if (clk->set_rate)
- clk->set_rate(clk, rate);
-
- return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (clk == NULL || !clk->round_rate)
- return 0;
-
- return clk->round_rate(clk, rate);
-}
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- clk->parent = parent;
- if (clk->set_parent)
- return clk->set_parent(clk, parent);
- return 0;
-}
-
-static int clk_ipu_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
-#if CONFIG_IS_ENABLED(MX51) || CONFIG_IS_ENABLED(MX53)
- /* Handshake with IPU when certain clock rates are changed. */
- reg = __raw_readl(&mxc_ccm->ccdr);
- reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
- __raw_writel(reg, &mxc_ccm->ccdr);
-
- /* Handshake with IPU when LPM is entered as its enabled. */
- reg = __raw_readl(&mxc_ccm->clpcr);
- reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
- __raw_writel(reg, &mxc_ccm->clpcr);
-#endif
- return 0;
-}
-
-static void clk_ipu_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
-
-#if CONFIG_IS_ENABLED(MX51) || CONFIG_IS_ENABLED(MX53)
- /*
- * No handshake with IPU whe dividers are changed
- * as its not enabled.
- */
- reg = __raw_readl(&mxc_ccm->ccdr);
- reg |= MXC_CCM_CCDR_IPU_HS_MASK;
- __raw_writel(reg, &mxc_ccm->ccdr);
-
- /* No handshake with IPU when LPM is entered as its not enabled. */
- reg = __raw_readl(&mxc_ccm->clpcr);
- reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
- __raw_writel(reg, &mxc_ccm->clpcr);
-#endif
-}
-
/*
* Function to initialize the ipu clock
*
@@ -221,43 +101,19 @@ static void clk_ipu_disable(struct clk *clk)
*/
static int ipu_clk_init(struct ipu_ctx *ctx)
{
- struct clk *ipu_clk;
-
- ipu_clk = devm_kzalloc(ctx->dev, sizeof(*ipu_clk), GFP_KERNEL);
- if (!ipu_clk)
- return -ENOMEM;
-
- ipu_clk->name = "ipu_clk";
- ipu_clk->ctx = ctx;
-#if CONFIG_IS_ENABLED(MX51) || CONFIG_IS_ENABLED(MX53)
- ipu_clk->enable_reg =
- (u32 *)(CCM_BASE_ADDR + offsetof(struct mxc_ccm_reg, CCGR5));
- ipu_clk->enable_shift = MXC_CCM_CCGR5_IPU_OFFSET;
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ return ipu_clk_init_legacy(ctx);
#else
- ipu_clk->enable_reg =
- (u32 *)(CCM_BASE_ADDR + offsetof(struct mxc_ccm_reg, CCGR3));
- ipu_clk->enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET;
-#endif
-
- ipu_clk->enable = clk_ipu_enable;
- ipu_clk->disable = clk_ipu_disable;
- ipu_clk->usecount = 0;
+ struct clk *clk;
-#if CONFIG_IS_ENABLED(MX51)
- ipu_clk->rate = IPUV3_CLK_MX51;
-#elif CONFIG_IS_ENABLED(MX53)
- ipu_clk->rate = IPUV3_CLK_MX53;
-#else
- ipu_clk->rate = is_mx6sdl() ? IPUV3_CLK_MX6DL : IPUV3_CLK_MX6Q;
-#endif
+ clk = devm_clk_get(ctx->dev, "bus");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
- ctx->ipu_clk = ipu_clk;
+ ctx->ipu_clk = clk;
return 0;
-};
-
-#if !defined CFG_SYS_LDB_CLOCK
-#define CFG_SYS_LDB_CLOCK 65000000
#endif
+}
/*
* Function to initialize the ldb dummy clock
@@ -268,23 +124,14 @@ static int ipu_clk_init(struct ipu_ctx *ctx)
*/
static int ipu_ldb_clk_init(struct ipu_ctx *ctx)
{
- struct clk *ldb_clk;
-
- ldb_clk = devm_kzalloc(ctx->dev, sizeof(*ldb_clk), GFP_KERNEL);
- if (!ldb_clk)
- return -ENOMEM;
-
- ldb_clk->name = "ldb_clk";
- ldb_clk->ctx = ctx;
- ldb_clk->rate = CFG_SYS_LDB_CLOCK;
- ldb_clk->usecount = 0;
-
- ctx->ldb_clk = ldb_clk;
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ return ipu_ldb_clk_init_legacy(ctx);
+#else
+ /* Set this in the FB driver where we know the display id */
+ ctx->ldb_clk = NULL;
return 0;
-};
-
-u32 *ipu_cpmem_base;
-u32 *ipu_dc_tmpl_reg;
+#endif
+}
/* Static functions */
@@ -320,124 +167,29 @@ static inline void ipu_ch_param_set_buffer(u32 ch, int buf_num,
#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0)
#define idma_is_set(reg, dma) (__raw_readl(reg(dma)) & idma_mask(dma))
-static void ipu_pixel_clk_recalc(struct clk *clk)
-{
- u32 div;
- u64 final_rate = (unsigned long long)clk->parent->rate * 16;
-
- div = __raw_readl(DI_BS_CLKGEN0(clk->id));
- debug("read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n", div,
- final_rate, clk->parent->rate);
-
- clk->rate = 0;
- if (div != 0) {
- do_div(final_rate, div);
- clk->rate = final_rate;
- }
-}
-
-static unsigned long ipu_pixel_clk_round_rate(struct clk *clk,
- unsigned long rate)
-{
- u64 div, final_rate;
- u32 remainder;
- u64 parent_rate = (unsigned long long)clk->parent->rate * 16;
-
- /*
- * Calculate divider
- * Fractional part is 4 bits,
- * so simply multiply by 2^4 to get fractional part.
- */
- div = parent_rate;
- remainder = do_div(div, rate);
- /* Round the divider value */
- if (remainder > (rate / 2))
- div++;
- if (div < 0x10) /* Min DI disp clock divider is 1 */
- div = 0x10;
- if (div & ~0xFEF)
- div &= 0xFF8;
- else {
- /* Round up divider if it gets us closer to desired pix clk */
- if ((div & 0xC) == 0xC) {
- div += 0x10;
- div &= ~0xF;
- }
- }
- final_rate = parent_rate;
- do_div(final_rate, div);
-
- return final_rate;
-}
-
-static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
-{
- u64 div, parent_rate;
- u32 remainder;
-
- parent_rate = (unsigned long long)clk->parent->rate * 16;
- div = parent_rate;
- remainder = do_div(div, rate);
- /* Round the divider value */
- if (remainder > (rate / 2))
- div++;
-
- /* Round up divider if it gets us closer to desired pix clk */
- if ((div & 0xC) == 0xC) {
- div += 0x10;
- div &= ~0xF;
- }
- if (div > 0x1000)
- debug("Overflow, DI_BS_CLKGEN0 div:0x%x\n", (u32)div);
-
- __raw_writel(div, DI_BS_CLKGEN0(clk->id));
-
- /*
- * Setup pixel clock timing
- * Down time is half of period
- */
- __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));
-
- do_div(parent_rate, div);
-
- clk->rate = parent_rate;
-
- return 0;
-}
-
-static int ipu_pixel_clk_enable(struct clk *clk)
+/*
+ * Function to initialize the display clocks
+ *
+ * @param ctx The ipu context for which the function is called
+ *
+ * Return: Returns 0 on success or negative error code on error
+ */
+static int ipu_di_clk_init(struct ipu_ctx *ctx, int id)
{
- u32 disp_gen = __raw_readl(IPU_DISP_GEN);
- disp_gen |= clk->id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
- __raw_writel(disp_gen, IPU_DISP_GEN);
-
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ ctx->di_clk[id] = NULL;
return 0;
-}
-
-static void ipu_pixel_clk_disable(struct clk *clk)
-{
- u32 disp_gen = __raw_readl(IPU_DISP_GEN);
- disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
- __raw_writel(disp_gen, IPU_DISP_GEN);
-}
-
-static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 di_gen = __raw_readl(DI_GENERAL(clk->id));
- struct ipu_ctx *ctx = clk->ctx;
+#else
+ struct clk *clk;
- if (parent == ctx->ipu_clk)
- di_gen &= ~DI_GEN_DI_CLK_EXT;
- else if (!IS_ERR(ctx->di_clk[clk->id]) && parent == ctx->ldb_clk)
- di_gen |= DI_GEN_DI_CLK_EXT;
- else
- return -EINVAL;
+ clk = devm_clk_get(ctx->dev, id ? "di1" : "di0");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
- __raw_writel(di_gen, DI_GENERAL(clk->id));
- ipu_pixel_clk_recalc(clk);
+ ctx->di_clk[id] = clk;
return 0;
+#endif
}
-
/*
* Function to initialize the pixel clock
*
@@ -447,26 +199,13 @@ static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent)
*/
static int ipu_pixel_clk_init(struct ipu_ctx *ctx, int id)
{
- struct clk *pixel_clk;
-
- pixel_clk = devm_kzalloc(ctx->dev, sizeof(*pixel_clk), GFP_KERNEL);
- if (!pixel_clk)
- return -ENOMEM;
-
- pixel_clk->name = "pixel_clk";
- pixel_clk->id = id;
- pixel_clk->ctx = ctx;
- pixel_clk->recalc = ipu_pixel_clk_recalc;
- pixel_clk->set_rate = ipu_pixel_clk_set_rate;
- pixel_clk->round_rate = ipu_pixel_clk_round_rate;
- pixel_clk->set_parent = ipu_pixel_clk_set_parent;
- pixel_clk->enable = ipu_pixel_clk_enable;
- pixel_clk->disable = ipu_pixel_clk_disable;
- pixel_clk->usecount = 0;
-
- ctx->pixel_clk[id] = pixel_clk;
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ return ipu_pixel_clk_init_legacy(ctx, id);
+#else
+ ctx->pixel_clk[id] = ctx->ipu_clk;
return 0;
-};
+#endif
+}
/*
* This function resets IPU
@@ -536,33 +275,39 @@ struct ipu_ctx *ipu_probe(struct udevice *dev)
ipu_cpmem_base = (u32 *)(ipu_base + IPU_CPMEM_REG_BASE);
ipu_dc_tmpl_reg = (u32 *)(ipu_base + IPU_DC_TMPL_REG_BASE);
- ret = ipu_pixel_clk_init(ctx, 0);
- if (ret)
- goto err;
-
- ret = ipu_pixel_clk_init(ctx, 1);
- if (ret)
- goto err;
+ for (int i = 0; i <= 1; i++) {
+ ret = ipu_pixel_clk_init(ctx, i);
+ if (ret)
+ goto err;
+ }
ret = ipu_clk_init(ctx);
if (ret)
goto err;
- debug("ipu_clk = %u\n", clk_get_rate(ctx->ipu_clk));
+ debug("ipu_clk = %lu\n", (ulong)clk_get_rate(ctx->ipu_clk));
ret = ipu_ldb_clk_init(ctx);
if (ret)
goto err;
- debug("ldb_clk = %u\n", clk_get_rate(ctx->ldb_clk));
+ if (ctx->ldb_clk)
+ debug("ldb_clk = %lu\n", (ulong)clk_get_rate(ctx->ldb_clk));
+
ipu_reset();
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
clk_set_parent(ctx->pixel_clk[0], ctx->ipu_clk);
clk_set_parent(ctx->pixel_clk[1], ctx->ipu_clk);
+
clk_enable(ctx->ipu_clk);
+#endif
- ctx->di_clk[0] = NULL;
- ctx->di_clk[1] = NULL;
+ for (int i = 0; i <= 1; i++) {
+ ret = ipu_di_clk_init(ctx, i);
+ if (ret)
+ goto err;
+ }
__raw_writel(0x807FFFFF, IPU_MEM_RST);
while (__raw_readl(IPU_MEM_RST) & 0x80000000)
@@ -584,7 +329,9 @@ struct ipu_ctx *ipu_probe(struct udevice *dev)
/* Set MCU_T to divide MCU access window into 2 */
__raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN);
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
clk_disable(ctx->ipu_clk);
+#endif
return ctx;
err:
diff --git a/drivers/video/imx/ipu_disp.c b/drivers/video/imx/ipu_disp.c
index 6a337b13af6..5e78574da9b 100644
--- a/drivers/video/imx/ipu_disp.c
+++ b/drivers/video/imx/ipu_disp.c
@@ -612,6 +612,11 @@ void ipu_dp_dc_enable(struct ipu_ctx *ctx, ipu_channel_t channel)
__raw_writel(reg, DC_WR_CH_CONF(dc_chan));
clk_enable(ctx->pixel_clk[di]);
+#if !CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ reg = __raw_readl(IPU_DISP_GEN);
+ reg |= di ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
+ __raw_writel(reg, IPU_DISP_GEN);
+#endif
}
static unsigned char dc_swap;
@@ -702,6 +707,12 @@ void ipu_dp_dc_disable(struct ipu_ctx *ctx, ipu_channel_t channel,
/* Clock is already off because it must be done quickly, but
we need to fix the ref count */
+#if !CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ reg = __raw_readl(IPU_DISP_GEN);
+ reg &= ctx->dc_di_assignment[dc_chan] ? ~DI1_COUNTER_RELEASE :
+ ~DI0_COUNTER_RELEASE;
+ __raw_writel(reg, IPU_DISP_GEN);
+#endif
clk_disable(ctx->pixel_clk[ctx->dc_di_assignment[dc_chan]]);
}
}
@@ -765,40 +776,21 @@ static int ipu_pixfmt_to_map(u32 fmt)
*
* @param sig Bitfield of signal polarities for LCD interface.
*
- * Return: This function returns 0 on success or negative error code on
- * fail.
+ * Return: The integer portion of the divider set for the pixel clock.
*/
-
-int32_t ipu_init_sync_panel(struct ipu_di_config *di, ipu_di_signal_cfg_t sig)
+static u32 ipu_di_clk_config(struct ipu_di_config *di, ipu_di_signal_cfg_t sig)
{
struct ipu_ctx *ctx = di->ctx;
int disp = di->disp;
- u32 reg;
- u32 di_gen, vsync_cnt;
- u32 div, rounded_pixel_clk;
- u32 h_total, v_total;
- int map;
- struct clk *di_parent;
-
- debug("panel size = %d x %d\n", di->width, di->height);
-
- if ((di->v_sync_width == 0) || (di->h_sync_width == 0))
- return -EINVAL;
-
- /* adapt panel to ipu restricitions */
- if (di->v_end_width < 2) {
- di->v_end_width = 2;
- puts("WARNING: v_end_width (lower_margin) must be >= 2, adjusted\n");
- }
-
- h_total = di->width + di->h_sync_width + di->h_start_width +
- di->h_end_width;
- v_total = di->height + di->v_sync_width + di->v_start_width +
- di->v_end_width;
+ u32 div;
/* Init clocking */
debug("pixel clk = %dHz\n", di->pixel_clk_rate);
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ u32 rounded_pixel_clk;
+ struct clk *di_parent;
+
if (sig.ext_clk) {
if (!(g_di1_tvout && (disp == 1))) { /*not round div for tvout*/
/*
@@ -830,13 +822,109 @@ int32_t ipu_init_sync_panel(struct ipu_di_config *di, ipu_di_signal_cfg_t sig)
if (clk_get_usecount(ctx->pixel_clk[disp]) != 0)
clk_set_parent(ctx->pixel_clk[disp], ctx->ipu_clk);
}
+
rounded_pixel_clk =
clk_round_rate(ctx->pixel_clk[disp], di->pixel_clk_rate);
clk_set_rate(ctx->pixel_clk[disp], rounded_pixel_clk);
- udelay(5000);
+
/* Get integer portion of divider */
div = clk_get_rate(clk_get_parent(ctx->pixel_clk[disp])) /
rounded_pixel_clk;
+#else
+ struct clk *clk;
+ u32 clkgen0, di_gen;
+ ulong id;
+
+ if (sig.ext_clk) {
+ /*
+ * Bypass the divider, assuming synchronous mode
+ */
+ clk = ctx->di_clk[disp];
+ div = 1;
+ } else {
+
+ ulong clk_rate = clk_get_rate(ctx->ipu_clk);
+ u32 error;
+
+ div = DIV_ROUND_CLOSEST(clk_rate, di->pixel_clk_rate);
+ div = clamp(div, 1U, 255U);
+
+ error = (clk_rate / div) / (di->pixel_clk_rate / 1000);
+
+ /*
+ * Select IPU if the rate is within 1% of requested pixel
+ * clock, otherwise, use the DI clock
+ */
+ if (990 <= error && error < 1010) {
+ clk = ctx->ipu_clk;
+ } else {
+ clk = ctx->di_clk[disp];
+
+ clk_set_rate(clk, di->pixel_clk_rate);
+ div = DIV_ROUND_CLOSEST(clk_get_rate(clk),
+ di->pixel_clk_rate);
+ div = clamp(div, 1U, 255U);
+ }
+ }
+
+ clkgen0 = div << 4;
+
+ ctx->pixel_clk[disp] = clk;
+ debug("new pixel rate: %lu Hz\n", clk_get_rate(clk));
+
+ id = clk_get_id(clk);
+ __raw_writel(clkgen0, DI_BS_CLKGEN0(id));
+ __raw_writel((clkgen0 & 0xFFF0) << 12, DI_BS_CLKGEN1(id));
+
+ di_gen = __raw_readl(DI_GENERAL(id)) & ~DI_GEN_DI_CLK_EXT;
+ if (clk == ctx->di_clk[disp])
+ di_gen |= DI_GEN_DI_CLK_EXT;
+
+ __raw_writel(di_gen, DI_GENERAL(id));
+#endif
+
+ udelay(5000);
+ return div;
+}
+
+/*
+ * This function is called to initialize a synchronous LCD panel.
+ *
+ * @param di Pointer to display data.
+ *
+ * @param sig Bitfield of signal polarities for LCD interface.
+ *
+ * Return: This function returns 0 on success or negative error code on
+ * fail.
+ */
+int32_t ipu_init_sync_panel(struct ipu_di_config *di, ipu_di_signal_cfg_t sig)
+{
+ int disp = di->disp;
+ u32 reg;
+ u32 di_gen, vsync_cnt;
+ u32 div;
+ u32 h_total, v_total;
+ int map;
+
+ debug("panel size = %d x %d\n", di->width, di->height);
+
+ if ((di->v_sync_width == 0) || (di->h_sync_width == 0))
+ return -EINVAL;
+
+ /* adapt panel to ipu restricitions */
+ if (di->v_end_width < 2) {
+ di->v_end_width = 2;
+ puts("WARNING: v_end_width (lower_margin) must be >= 2, adjusted\n");
+ }
+
+ h_total = di->width + di->h_sync_width + di->h_start_width +
+ di->h_end_width;
+ v_total = di->height + di->v_sync_width + di->v_start_width +
+ di->v_end_width;
+
+ div = ipu_di_clk_config(di, sig);
+ if (div < 0)
+ return div;
ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1);
ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
diff --git a/drivers/video/imx/mxc_ipuv3_fb.c b/drivers/video/imx/mxc_ipuv3_fb.c
index ef5d4faf3b3..3a327b9e97d 100644
--- a/drivers/video/imx/mxc_ipuv3_fb.c
+++ b/drivers/video/imx/mxc_ipuv3_fb.c
@@ -35,6 +35,7 @@
#include <dm.h>
#include <dm/devres.h>
#include <video.h>
+#include <dt-bindings/clock/imx6qdl-clock.h>
static int mxcfb_map_video_memory(struct fb_info *fbi);
static int mxcfb_unmap_video_memory(struct fb_info *fbi);
@@ -599,6 +600,22 @@ static int ipuv3_video_probe(struct udevice *dev)
if (ret < 0)
return ret;
+#if !CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ if (of_machine_is_compatible("fsl,imx6qp"))
+ ret = clk_get_by_id(gdisp ? IMX6QDL_CLK_LDB_DI1_PODF :
+ IMX6QDL_CLK_LDB_DI0_PODF,
+ &ctx->ldb_clk);
+ else
+ ret = clk_get_by_id(gdisp ? IMX6QDL_CLK_LDB_DI1 :
+ IMX6QDL_CLK_LDB_DI0,
+ &ctx->ldb_clk);
+
+ if (ret < 0)
+ return ret;
+
+ debug("ldb_clk = %lu\n", clk_get_rate(ctx->ldb_clk));
+#endif
+
ret = mxcfb_probe(dev, gpixfmt, gdisp, gmode);
if (ret < 0)
return ret;