diff options
| author | Tom Rini <[email protected]> | 2026-03-02 13:44:46 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-03-02 13:44:46 -0600 |
| commit | c0ca147ac6228949a6d6497531c9f2f4a0dc6c67 (patch) | |
| tree | 203dffa4165dbe5c98fb0e2a4594185782d53dbb | |
| parent | f6963fc232603007c661411fb31c57f1a9678a87 (diff) | |
| parent | 56e5f5290f2daf886bf6306f426cbb1171deac01 (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.
40 files changed, 3072 insertions, 559 deletions
diff --git a/arch/arm/dts/imx8-capricorn-cxg3.dts b/arch/arm/dts/imx8-capricorn-cxg3.dts index 2f8597579f3..b40410b2b6f 100644 --- a/arch/arm/dts/imx8-capricorn-cxg3.dts +++ b/arch/arm/dts/imx8-capricorn-cxg3.dts @@ -102,6 +102,26 @@ pinctrl-0 = <&pinctrl_gpio_keys>; muxcgrp: imx8qxp-som { + pinctrl_fec2: fec2grp { + fsl,pins = < + SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0 + SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD 0x000014a0 + SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0 + + SC_P_ENET0_MDC_CONN_ENET1_MDC 0x00000060 + SC_P_ENET0_MDIO_CONN_ENET1_MDIO 0x00000060 + + SC_P_ESAI0_FSR_CONN_ENET1_RCLK50M_IN 0x00000060 + SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x00000060 + SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x00000060 + SC_P_ESAI0_TX2_RX3_CONN_ENET1_RMII_RX_ER 0x00000060 + SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x00000060 + SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x00000060 + SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x00000060 + SC_P_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x00000060 + >; + }; + pinctrl_gpio_leds: gpioledsgrp { fsl,pins = < SC_P_ESAI0_FST_LSIO_GPIO0_IO01 0x06000021 @@ -127,3 +147,27 @@ >; }; }; + +&fec2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec2>; + phy-mode = "rmii"; + + phy-handle = <ðphy1>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + }; +}; diff --git a/arch/arm/dts/imx8-capricorn.dtsi b/arch/arm/dts/imx8-capricorn.dtsi index 3734a9d21f1..f640daa775f 100644 --- a/arch/arm/dts/imx8-capricorn.dtsi +++ b/arch/arm/dts/imx8-capricorn.dtsi @@ -63,41 +63,6 @@ SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021 SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041 SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021 - SC_P_ENET0_RGMII_TXC_LSIO_GPIO4_IO29 0x06000021 - >; - }; - - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - SC_P_ENET0_RGMII_RXC_CONN_USDHC1_CLK 0x06000041 - SC_P_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD 0x00000021 - SC_P_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0 0x00000021 - SC_P_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1 0x00000021 - SC_P_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2 0x00000021 - SC_P_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3 0x00000021 - SC_P_ENET0_RGMII_TXD2_CONN_USDHC1_CD_B 0x06000021 - //SC_P_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01 0x06000021 - SC_P_ENET0_RGMII_TX_CTL_LSIO_GPIO4_IO30 0x06000021 - >; - }; - - pinctrl_fec2: fec2grp { - fsl,pins = < - SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0 - SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD 0x000014a0 - SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD 0x000514a0 - - SC_P_ENET0_MDC_CONN_ENET1_MDC 0x00000060 - SC_P_ENET0_MDIO_CONN_ENET1_MDIO 0x00000060 - - SC_P_ESAI0_FSR_CONN_ENET1_RCLK50M_IN 0x00000060 - SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x00000060 - SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x00000060 - SC_P_ESAI0_TX2_RX3_CONN_ENET1_RMII_RX_ER 0x00000060 - SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x00000060 - SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x00000060 - SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x00000060 - SC_P_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x00000060 /* ERST: Reset pin */ >; }; }; @@ -126,6 +91,7 @@ &usdhc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc1>; + max-frequency = <52000000>; clock-frequency=<52000000>; no-1-8-v; bus-width = <8>; @@ -160,27 +126,3 @@ &fec1 { status ="disabled"; }; - -&fec2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_fec2>; - phy-mode = "rmii"; - - phy-handle = <ðphy1>; - fsl,magic-packet; - status = "okay"; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - ethphy0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; - }; - ethphy1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; - }; -}; diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 20c741283cd..8af45e14707 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -310,7 +310,8 @@ void arch_preboot_os(void) /* disable video before launching O/S */ rc = uclass_find_first_device(UCLASS_VIDEO, &dev); while (!rc && dev) { - ipuv3_fb_shutdown(dev); + if (device_active(dev)) + ipuv3_fb_shutdown(dev); uclass_find_next_device(&dev); } #endif diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c index c77104d0338..22d6959f74f 100644 --- a/arch/arm/mach-imx/imx8/misc.c +++ b/arch/arm/mach-imx/imx8/misc.c @@ -1,4 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ +#include <command.h> +#include <env.h> #include <log.h> #include <firmware/imx/sci/sci.h> #include <asm/mach-imx/sys_proto.h> @@ -62,3 +64,34 @@ void build_info(void) printf("Build: SCFW %08x, SECO-FW %08x, ATF %s\n", sc_commit, seco_commit, (char *)&atf_commit); } + +int do_boottype(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + sc_misc_bt_t boot_type; + + if (argc > 2) + return CMD_RET_USAGE; + + if (sc_misc_get_boot_type(-1, &boot_type) != 0) { + puts("boottype cannot be retrieved\n"); + return CMD_RET_FAILURE; + } + + if (argc > 1) + printf("Boottype: %d\n", boot_type); + + env_set_ulong("boottype", boot_type); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(boottype, CONFIG_SYS_MAXARGS, 2, do_boottype, + "save current boot-container in env variable 'boottype'", + "possible values for boottype:\n" + "0: SC_MISC_BT_PRIMARY\n" + "1: SC_MISC_BT_SECONDARY\n" + "2: SC_MISC_BT_RECOVERY\n" + "3: SC_MISC_BT_MANUFACTURE\n" + "4: SC_MISC_BT_SERIAL\n" + "[print] - print current boottype" +); diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c index c1458ccca3c..17269ddd2fc 100644 --- a/arch/arm/mach-imx/imx9/scmi/soc.c +++ b/arch/arm/mach-imx/imx9/scmi/soc.c @@ -820,7 +820,7 @@ int timer_init(void) return 0; } -enum env_location env_get_location(enum env_operation op, int prio) +enum env_location arch_env_get_location(enum env_operation op, int prio) { enum boot_device dev = get_boot_device(); enum env_location env_loc = ENVL_UNKNOWN; diff --git a/board/nxp/imx8mm_evk/spl.c b/board/nxp/imx8mm_evk/spl.c index 5c588046ff4..50bae3a2bcc 100644 --- a/board/nxp/imx8mm_evk/spl.c +++ b/board/nxp/imx8mm_evk/spl.c @@ -106,8 +106,6 @@ void board_init_f(ulong dummy) arch_cpu_init(); - init_uart_clk(1); - timer_init(); /* Clear the BSS. */ diff --git a/board/nxp/imx8mp_evk/imx8mp_evk.c b/board/nxp/imx8mp_evk/imx8mp_evk.c index 489e5ad4d43..e17100e51ec 100644 --- a/board/nxp/imx8mp_evk/imx8mp_evk.c +++ b/board/nxp/imx8mp_evk/imx8mp_evk.c @@ -28,6 +28,13 @@ struct efi_capsule_update_info update_info = { }; #endif /* EFI_HAVE_CAPSULE_SUPPORT */ +#if CONFIG_IS_ENABLED(ENV_IS_IN_MMC) +int board_mmc_get_env_dev(int devno) +{ + return devno; +} +#endif + int board_late_init(void) { #if CONFIG_IS_ENABLED(ENV_IS_IN_MMC) diff --git a/board/nxp/imx8mp_evk/spl.c b/board/nxp/imx8mp_evk/spl.c index 5b4aac42830..27cd82e745a 100644 --- a/board/nxp/imx8mp_evk/spl.c +++ b/board/nxp/imx8mp_evk/spl.c @@ -102,8 +102,6 @@ void board_init_f(ulong dummy) arch_cpu_init(); - init_uart_clk(1); - ret = spl_early_init(); if (ret) { debug("spl_init() failed: %d\n", ret); diff --git a/board/phytec/phycore_imx93/phycore-imx93.c b/board/phytec/phycore_imx93/phycore-imx93.c index cdaedd52c14..036c9f5de7e 100644 --- a/board/phytec/phycore_imx93/phycore-imx93.c +++ b/board/phytec/phycore_imx93/phycore-imx93.c @@ -41,6 +41,11 @@ int board_late_init(void) case MMC1_BOOT: env_set_ulong("mmcdev", 0); break; + case USB_BOOT: + printf("Detect USB boot. Will enter fastboot mode!\n"); + if (!strcmp(env_get("bootcmd"), env_get_default("bootcmd"))) + env_set("bootcmd", "fastboot 0; bootflow scan -lb;"); + break; default: break; } diff --git a/board/siemens/capricorn/Kconfig b/board/siemens/capricorn/Kconfig index fe230971e97..d6d1aad75b2 100644 --- a/board/siemens/capricorn/Kconfig +++ b/board/siemens/capricorn/Kconfig @@ -1,5 +1,7 @@ if TARGET_CAPRICORN +config HUSH_INIT_VAR + def_bool y config SYS_BOARD default "capricorn" diff --git a/board/siemens/capricorn/board.c b/board/siemens/capricorn/board.c index 390a7b0d841..ba6c96a409c 100644 --- a/board/siemens/capricorn/board.c +++ b/board/siemens/capricorn/board.c @@ -5,6 +5,7 @@ * Copyright 2019 Siemens AG * */ +#include <cli_hush.h> #include <command.h> #include <dm.h> #include <env.h> @@ -29,6 +30,7 @@ #include "../common/board.h" #include "../common/eeprom.h" #include "../common/factoryset.h" +#include <firmware/imx/sci/sci.h> #define GPIO_PAD_CTRL \ ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ @@ -355,16 +357,6 @@ int board_mmc_get_env_dev(int devno) return devno; } -static int check_mmc_autodetect(void) -{ - char *autodetect_str = env_get("mmcautodetect"); - - if (autodetect_str && (strcmp(autodetect_str, "yes") == 0)) - return 1; - - return 0; -} - /* This should be defined for each board */ __weak int mmc_map_to_kernel_blk(int dev_no) { @@ -373,23 +365,45 @@ __weak int mmc_map_to_kernel_blk(int dev_no) void board_late_mmc_env_init(void) { - char cmd[32]; - char mmcblk[32]; u32 dev_no = mmc_get_env_dev(); - if (!check_mmc_autodetect()) - return; - env_set_ulong("mmcdev", dev_no); +} - /* Set mmcblk env */ - sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", - mmc_map_to_kernel_blk(dev_no)); - env_set("mmcroot", mmcblk); +#if defined(CONFIG_HUSH_INIT_VAR) +int hush_init_var(void) +{ + sc_misc_bt_t boot_type; - sprintf(cmd, "mmc dev %d", dev_no); - run_command(cmd, 0); + if (sc_misc_get_boot_type(-1, &boot_type) != 0) { + puts("boottype cannot be retrieved\n"); + return 0; + } + + /* + * Set here explicitly a hush shell variable, so if a saveenv + * happens, this variable is *not* saved in U-Boot environment. + * + * This is for devices which are already in the field essential, + * as if such a device breaks, the cutsomer gets a new device + * with a new U-Boot version (and so a new U-Boot environment). + * + * But the customer makes a downgrade to an older U-Boot version, + * which does not have this code in, and runs now with a new + * U-Boot Environment (yes, protected Environment is not enabled + * there) and the old U-Boot must still work with the new U-Boot + * Environment. So we cannot store this variable in U-Boot + * Environment as a stored value will in this case never be over- + * written. + */ + if (boot_type == 1) { + printf("boot-container fallback ocured\n"); + set_local_var("fallback=1", 0); + } + + return 0; } +#endif #ifndef CONFIG_XPL_BUILD static int load_parameters_from_factoryset(void) diff --git a/board/siemens/capricorn/capricorn_default.env b/board/siemens/capricorn/capricorn_default.env index c8b5b3d7da3..10d612b04fe 100644 --- a/board/siemens/capricorn/capricorn_default.env +++ b/board/siemens/capricorn/capricorn_default.env @@ -1,17 +1,23 @@ -altbootcmd=run bootcmd +terminate_upgrade=bootcount reset; setenv upgrade_available 0 +altbootcmd=run terminate_upgrade; run toggle_partition baudrate=115200 bootcmd=run flash_self;reset; bootdelay=3 bootdir=targetdir/rootfs/boot bootlimit=3 -check_upgrade=if test ${upgrade_available} -eq 1; then echo upgrade_available is set; if test ${bootcount} -gt ${bootlimit}; then setenv upgrade_available 0;echo toggle partition;run toggle_partition;fi;fi; cntr_addr=0x88000000 cntr_file=os_cntr_signed.bin console=ttyLP2 dtb_name_default=default ethprime=eth1 fdt_addr=0x83000000 -flash_self=run mmc_boot +flash_self=if test -n "$fallback";then + echo "fallback: $fallback"; + run terminate_upgrade; + run toggle_partition; + else + run mmc_boot; + fi flash_self_test=setenv testargs test loglevel=3 systemd.unit=test.target; run mmc_boot hostname=capricorn initrd_addr=0x83100000 @@ -19,30 +25,88 @@ initrd_high=0xffffffffffffffff ip_method=none kernel_name=Image loadaddr=0x80400000 -mmc_boot=run set_bootargs;run check_upgrade; run set_partition;run set_bootargs_mmc;run mmc_load_bootfiles -mmc_boot_fit=ext4load mmc 0:${mmc_part_nr} 0x88000000 boot/fitImage;if test -n ${A};then setenv bootargs ${bootargs} rootfs_sig=${sig_a};fi;if test -n ${B};then setenv bootargs ${bootargs} rootfs_sig=${sig_b};fi;bootm 0x88000000#conf-${dtb_name}.dtb;bootm -mmc_boot_image=ext4load mmc 0:${mmc_part_nr} ${fdt_addr} boot/${dtb_name}.dtb;if test $? -eq 1;then ext4load mmc 0:${mmc_part_nr} ${fdt_addr} boot/${dtb_name_default}.dtb;fi; ext4load mmc 0:${mmc_part_nr} ${loadaddr} boot/${kernel_name}; booti ${loadaddr} - ${fdt_addr} -mmc_load_bootfiles=echo -n Loading from eMMC ...; if test -e mmc 0:${mmc_part_nr} boot/fitImage; then echo fit; setenv fdt_high; setenv initrd_high; run mmc_boot_fit; else echo image; run mmc_boot_image; fi -net_nfs=wdt dev scu-wdt; wdt stop; echo Booting from network ...; run set_bootargs_net; tftpboot ${loadaddr} ${bootdir}/${kernel_name}; printenv bootargs; if test ${kernel_name} = fitImage; then setenv fdt_high; setenv initrd_high; bootm ${loadaddr}#conf-${dtb_name}.dtb; else tftpboot ${fdt_addr} ${serverip}:${bootdir}/${dtb_name}.dtb; if test $? -eq 1; then echo Loading default.dtb!; tftpboot ${fdt_addr} ${serverip}:${bootdir}/${dtb_name_default}.dtb; fi; booti ${loadaddr} - ${fdt_addr}; fi -net_unfs=setenv nfsopts vers=3,udp,rsize=4096,wsize=4096,nolock,port=3049,mountport=3048 rw; run net_nfs -netdev=lan0 +mmc_boot=run set_bootargs; run set_partition;run set_bootargs_mmc;run mmc_load_bootfiles +mmc_boot_fit=ext4load mmc 0:${mmc_part_nr} 0x88000000 boot/fitImage; + if test -n ${A};then + setenv bootargs ${bootargs} rootfs_sig=${sig_a}; + fi; + if test -n ${B};then + setenv bootargs ${bootargs} rootfs_sig=${sig_b}; + fi; + bootm 0x88000000#conf-${dtb_name}.dtb;bootm 0x88000000 +mmc_boot_image=ext4load mmc 0:${mmc_part_nr} ${fdt_addr} boot/${dtb_name}.dtb; + if test $? -eq 1;then + ext4load mmc 0:${mmc_part_nr} ${fdt_addr} boot/${dtb_name_default}.dtb; + fi; + ext4load mmc 0:${mmc_part_nr} ${loadaddr} boot/${kernel_name}; + booti ${loadaddr} - ${fdt_addr} +mmc_load_bootfiles=echo -n Loading from eMMC ...; + if test -e mmc 0:${mmc_part_nr} boot/fitImage; then + echo fit; setenv fdt_high; setenv initrd_high; run mmc_boot_fit; + else + echo image; run mmc_boot_image; + fi +net_nfs=wdt dev scu-wdt; wdt stop; echo Booting from network ...; + run set_bootargs_net; tftpboot ${loadaddr} ${bootdir}/${kernel_name}; + printenv bootargs; + if test ${kernel_name} = fitImage; then + setenv fdt_high; setenv initrd_high; + bootm ${loadaddr}#conf-${dtb_name}.dtb; + else + tftpboot ${fdt_addr} ${serverip}:${bootdir}/${dtb_name}.dtb; + if test $? -eq 1; then + echo Loading default.dtb!; + tftpboot ${fdt_addr} ${serverip}:${bootdir}/${dtb_name_default}.dtb; + fi; + booti ${loadaddr} - ${fdt_addr}; + fi +net_unfs=setenv nfsopts vers=3,udp,rsize=4096,wsize=4096,nolock,port=3049,mountport=3048 rw; + run net_nfs +netdev=eth0 nfsopts=vers=3,udp,rsize=4096,wsize=4096,nolock rw partitionset_active=A rootfs_name=/dev/mmcblk0 rootpath=/home/projects/targetdir/rootfs script_file=u-boot-commands.img -set_bootargs_mmc=setenv bootargs ${bootargs} root=${mmc_active_vol} ro rootdelay=1 rootwait rootfstype=ext4 ip=${ip_method} -set_bootargs_net=run set_bootargs; if test ${kernel_name} = fitImage; then setenv loadaddr 0x88000000; fi; setenv bootargs ${bootargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off -set_bootargs=setenv bootargs console=${console},${baudrate} target_env=${target_env} ${testargs} ${optargs} -set_partition=setenv ${partitionset_active} true;if test -n ${A}; then setenv mmc_part_nr 1;fi;if test -n ${B}; then setenv mmc_part_nr 2;fi;setenv mmc_active_vol ${rootfs_name}p${mmc_part_nr} -tftp_run_script=tftpboot ${kernel_loadaddr} ${serverip}:${script_file};if test $? -eq 0;then source ${kernel_loadaddr};fi -toggle_partition=setenv ${partitionset_active} true; if test -n ${A}; then setenv partitionset_active B; mmc partconf 0 1 2 0; env delete A; fi; if test -n ${B}; then setenv partitionset_active A; mmc partconf 0 1 1 0; env delete B; fi;saveenv; reset +set_bootargs_mmc=setenv bootargs ${bootargs} root=${mmc_active_vol} ro rootdelay=1 + rootwait rootfstype=ext4 ip=${ip_method} +set_bootargs_net=run set_bootargs; + if test ${kernel_name} = fitImage; then + setenv loadaddr 0x88000000; + fi; + setenv bootargs ${bootargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} + ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off +set_bootargs=setenv bootargs console=${console},${baudrate} target_env=${target_env} ${testargs} + ${optargs} +set_partition=mmc partconf 0 v_mmc_part_nr; setenv mmc_part_nr $v_mmc_part_nr; + setenv mmc_active_vol ${rootfs_name}p$v_mmc_part_nr +tftp_run_script=tftpboot ${kernel_loadaddr} ${serverip}:${script_file}; + if test $? -eq 0;then + source ${kernel_loadaddr}; + fi +toggle_partition=mmc partconf 0 v_mmc_part_nr; + if test $v_mmc_part_nr -eq 1;then + mmc partconf 0 1 2 0; setenv partitionset_active B; + elif test $v_mmc_part_nr -eq 2;then + mmc partconf 0 1 1 0; setenv partitionset_active A; + else + echo error mmc_part_nr $v_mmc_part_nr; + fi; + saveenv;reset upgrade_available=0 emmc_dev=0 sd_dev=1 mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused kboot=booti -bootcmd_mfg=run mfgtool_args; if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else booti ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot usb auto; fi; +bootcmd_mfg=run mfgtool_args; + if iminfo ${initrd_addr}; then + if test ${tee} = yes; then + bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; + else + booti ${loadaddr} ${initrd_addr} ${fdt_addr}; + fi; + else + echo "Run fastboot ..."; fastboot usb auto; + fi; fastboot_bytes=124c00 fastboot_dev=mmc -mmcautodetect=yes diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig index 5c3c8a2ca57..d5b01939f2d 100644 --- a/configs/imx8mp_evk_defconfig +++ b/configs/imx8mp_evk_defconfig @@ -87,6 +87,7 @@ CONFIG_ETHPRIME="eth1" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_SPL_CLK_IMX8MP=y CONFIG_CLK_IMX8MP=y CONFIG_DFU_MMC=y CONFIG_USB_FUNCTION_FASTBOOT=y diff --git a/configs/imx8qxp_capricorn.config b/configs/imx8qxp_capricorn.config index 62babf2626f..2bae5b1a862 100644 --- a/configs/imx8qxp_capricorn.config +++ b/configs/imx8qxp_capricorn.config @@ -12,6 +12,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80200000 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_REDUNDANT=y CONFIG_ENV_MMC_EMMC_HW_PARTITION=2 +CONFIG_ENV_WRITEABLE_LIST=y CONFIG_DM_GPIO=y CONFIG_AHAB_BOOT=y @@ -73,6 +74,8 @@ CONFIG_CMD_CPU=y # CONFIG_CMD_CRC32 is not set # CONFIG_CMD_BIND is not set CONFIG_CMD_WDT=y +CONFIG_CMD_WGET=y +CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_CLK=y CONFIG_CMD_DM=y CONFIG_CMD_FUSE=y diff --git a/configs/toradex-smarc-imx95_defconfig b/configs/toradex-smarc-imx95_defconfig index 77b355c12d6..ad908949b59 100644 --- a/configs/toradex-smarc-imx95_defconfig +++ b/configs/toradex-smarc-imx95_defconfig @@ -74,6 +74,7 @@ CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_PCI=y CONFIG_CMD_READ=y +CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_USB=y CONFIG_CMD_USB_SDP=y CONFIG_CMD_USB_MASS_STORAGE=y @@ -122,6 +123,8 @@ CONFIG_FASTBOOT_UUU_SUPPORT=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_SPL_FIRMWARE=y # CONFIG_SCMI_AGENT_SMCCC is not set +CONFIG_IMX_SM_CPU=y +CONFIG_IMX_SM_LMM=y CONFIG_IMX_RGPIO2P=y CONFIG_DM_PCA953X=y CONFIG_SPL_DM_PCA953X=y @@ -152,6 +155,7 @@ CONFIG_SPL_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_SPL_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y +CONFIG_REMOTEPROC_IMX=y CONFIG_DM_RNG=y CONFIG_DM_SERIAL=y CONFIG_FSL_LPUART=y 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; diff --git a/include/configs/capricorn-common.h b/include/configs/capricorn-common.h index 7120a44d186..ee13d2ab950 100644 --- a/include/configs/capricorn-common.h +++ b/include/configs/capricorn-common.h @@ -38,6 +38,19 @@ #define CFG_EXTRA_ENV_SETTINGS \ AHAB_ENV +#ifdef CONFIG_ENV_WRITEABLE_LIST +#define CFG_ENV_FLAGS_LIST_STATIC \ + "bootcount:dw," \ + "bootdelay:sw," \ + "bootlimit:dw," \ + "partitionset_active:sw," \ + "rastate:dw," \ + "sig_a:sw,sig_b:sw," \ + "target_env:sw," \ + "upgrade_available:dw," \ + "ustate:dw" +#endif + /* Default location for tftp and bootm */ /* On CCP board, USDHC1 is for eMMC */ diff --git a/include/firmware/imx/sci/sci.h b/include/firmware/imx/sci/sci.h index 876d52cac35..7f4ca735663 100644 --- a/include/firmware/imx/sci/sci.h +++ b/include/firmware/imx/sci/sci.h @@ -86,6 +86,7 @@ int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl, u32 *val); void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev); void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status); +int sc_misc_get_boot_type(sc_ipc_t ipc, sc_misc_bt_t *type); int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx); void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit); int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val); |
