]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
Merge tag 'u-boot-imx-next-20250922' of https://gitlab.denx.de/u-boot/custodians...
authorTom Rini <trini@konsulko.com>
Mon, 22 Sep 2025 14:23:41 +0000 (08:23 -0600)
committerTom Rini <trini@konsulko.com>
Mon, 22 Sep 2025 15:57:39 +0000 (09:57 -0600)
CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/27684

- Add i.MX8 ahab-commit command.
- Add support for flashing board with UUU on imx93_frdm.
- Fix the acces of PFUZE100 regulator desc.
- Add more i.MX6 PWM clock definitions.
- Enable OP-TEE on phytec-imx8m and update documentation.
- Enable PCI host controller on iMX95 19x19 EVK.

[trini: Fixup spacing issues]
Signed-off-by: Tom Rini <trini@konsulko.com>
1  2 
drivers/clk/imx/clk-imx95-blkctrl.c
drivers/pci/pcie_dw_imx.c

index 0000000000000000000000000000000000000000,3bf6f9415e223493d273d2176448b537d0b8044f..3e6f53b4a1657df811e9a2e9075a501f2a064cc3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,170 +1,183 @@@
 -    [IMX95_CLK_DISPMIX_LVDS_CH0_GATE] = {
+ // SPDX-License-Identifier: GPL-2.0+
+ /*
+  * Copyright 2023-2025 NXP
+  *
+  */
+ #include <asm/io.h>
+ #include <clk-uclass.h>
+ #include <dm.h>
+ #include <dm/device_compat.h>
+ #include <dt-bindings/clock/nxp,imx95-clock.h>
+ #include <linux/clk-provider.h>
+ #include "clk.h"
+ enum {
+       CLK_GATE,
+       CLK_DIVIDER,
+       CLK_MUX,
+ };
+ struct imx95_blk_ctl_clk_dev_data {
+       const char *name;
+       const char * const *parent_names;
+       u32 num_parents;
+       u32 reg;
+       u32 bit_idx;
+       u32 clk_type;
+       u32 flags;
+       u32 flags2;
+       u32 type;
+ };
+ struct imx95_blk_ctl_dev_data {
+       const struct imx95_blk_ctl_clk_dev_data *clk_dev_data;
+       u32 num_clks;
+       u32 clk_reg_offset;
+ };
+ static const struct imx95_blk_ctl_clk_dev_data hsio_blk_ctl_clk_dev_data[] = {
+       [0] = {
+               .name = "hsio_blk_ctl_clk",
+               .parent_names = (const char *[]){ "hsiopll", },
+               .num_parents = 1,
+               .reg = 0,
+               .bit_idx = 6,
+               .type = CLK_GATE,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+ };
+ static const struct imx95_blk_ctl_dev_data hsio_blk_ctl_dev_data = {
+       .num_clks = 1,
+       .clk_dev_data = hsio_blk_ctl_clk_dev_data,
+       .clk_reg_offset = 0,
+ };
+ static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = {
+       [IMX95_CLK_DISPMIX_LVDS_PHY_DIV] = {
+               .name = "ldb_phy_div",
+               .parent_names = (const char *[]){ "ldbpll", },
+               .num_parents = 1,
+               .reg = 0,
+               .bit_idx = 0,
+               .type = CLK_DIVIDER,
+               .flags2 = CLK_DIVIDER_POWER_OF_TWO,
+       },
 -    },
 -    [IMX95_CLK_DISPMIX_LVDS_CH1_GATE] = {
++      [IMX95_CLK_DISPMIX_LVDS_CH0_GATE] = {
+               .name = "lvds_ch0_gate",
+               .parent_names = (const char *[]){ "ldb_phy_div", },
+               .num_parents = 1,
+               .reg = 0,
+               .bit_idx = 1,
+               .type = CLK_GATE,
+               .flags = CLK_SET_RATE_PARENT,
+               .flags2 = CLK_GATE_SET_TO_DISABLE,
 -    },
 -    [IMX95_CLK_DISPMIX_PIX_DI0_GATE] = {
++      },
++      [IMX95_CLK_DISPMIX_LVDS_CH1_GATE] = {
+               .name = "lvds_ch1_gate",
+               .parent_names = (const char *[]){ "ldb_phy_div", },
+               .num_parents = 1,
+               .reg = 0,
+               .bit_idx = 2,
+               .type = CLK_GATE,
+               .flags = CLK_SET_RATE_PARENT,
+               .flags2 = CLK_GATE_SET_TO_DISABLE,
 -    },
 -    [IMX95_CLK_DISPMIX_PIX_DI1_GATE] = {
++      },
++      [IMX95_CLK_DISPMIX_PIX_DI0_GATE] = {
+               .name = "lvds_di0_gate",
+               .parent_names = (const char *[]){ "ldb_pll_div7", },
+               .num_parents = 1,
+               .reg = 0,
+               .bit_idx = 3,
+               .type = CLK_GATE,
+               .flags = CLK_SET_RATE_PARENT,
+               .flags2 = CLK_GATE_SET_TO_DISABLE,
 -    },
++      },
++      [IMX95_CLK_DISPMIX_PIX_DI1_GATE] = {
+               .name = "lvds_di1_gate",
+               .parent_names = (const char *[]){ "ldb_pll_div7", },
+               .num_parents = 1,
+               .reg = 0,
+               .bit_idx = 4,
+               .type = CLK_GATE,
+               .flags = CLK_SET_RATE_PARENT,
+               .flags2 = CLK_GATE_SET_TO_DISABLE,
 -                      dev_clk_dm(dev, i, clk_register_gate(dev, clk_dev_data[i].name, clk_dev_data[i].parent_names[0],
 -                                      clk_dev_data[i].flags, addr + dev_data->clk_reg_offset, clk_dev_data[i].bit_idx,
 -                                      clk_dev_data[i].flags2, NULL));
++      },
+ };
+ static const struct imx95_blk_ctl_dev_data imx95_lvds_csr_dev_data = {
+       .num_clks = ARRAY_SIZE(imx95_lvds_clk_dev_data),
+       .clk_dev_data = imx95_lvds_clk_dev_data,
+       .clk_reg_offset = 0,
+ };
+ static int imx95_blkctrl_clk_probe(struct udevice *dev)
+ {
+       int i;
+       void __iomem *addr;
+       struct imx95_blk_ctl_dev_data *dev_data = (void *)dev_get_driver_data(dev);
+       const struct imx95_blk_ctl_clk_dev_data *clk_dev_data;
+       addr = dev_read_addr_ptr(dev);
+       if (addr == (void *)FDT_ADDR_T_NONE) {
+               dev_err(dev, "No blkctrl register base address\n");
+               return -EINVAL;
+       }
+       if (!dev_data) {
+               dev_err(dev, "driver data is NULL\n");
+               return -EINVAL;
+       }
+       clk_dev_data = dev_data->clk_dev_data;
+       for (i = 0; i < dev_data->num_clks; i++) {
+               if (clk_dev_data[i].clk_type == CLK_GATE) {
 -                              clk_register_divider(dev, clk_dev_data[i].name, clk_dev_data[i].parent_names[0],
 -                                      clk_dev_data[i].flags, addr + dev_data->clk_reg_offset, clk_dev_data[i].bit_idx, 1,
 -                                      clk_dev_data[i].flags2));
++                      dev_clk_dm(dev, i,
++                                 clk_register_gate(dev,
++                                                   clk_dev_data[i].name,
++                                                   clk_dev_data[i].parent_names[0],
++                                                   clk_dev_data[i].flags, addr +
++                                                   dev_data->clk_reg_offset,
++                                                   clk_dev_data[i].bit_idx,
++                                                   clk_dev_data[i].flags2, NULL));
+               } else if (clk_dev_data[i].clk_type == CLK_DIVIDER) {
+                       dev_clk_dm(dev, i,
 -                              clk_register_mux(dev, clk_dev_data[i].name, clk_dev_data[i].parent_names,
 -                                      clk_dev_data[i].num_parents, clk_dev_data[i].flags, addr + dev_data->clk_reg_offset,
 -                                      clk_dev_data[i].bit_idx, 1, clk_dev_data[i].flags2));
++                                 clk_register_divider(dev, clk_dev_data[i].name,
++                                                      clk_dev_data[i].parent_names[0],
++                                                      clk_dev_data[i].flags, addr +
++                                                      dev_data->clk_reg_offset,
++                                                      clk_dev_data[i].bit_idx, 1,
++                                                      clk_dev_data[i].flags2));
+               } else if (clk_dev_data[i].clk_type == CLK_MUX) {
+                       dev_clk_dm(dev, i,
++                                 clk_register_mux(dev,
++                                                  clk_dev_data[i].name,
++                                                  clk_dev_data[i].parent_names,
++                                                  clk_dev_data[i].num_parents,
++                                                  clk_dev_data[i].flags, addr +
++                                                  dev_data->clk_reg_offset,
++                                                  clk_dev_data[i].bit_idx, 1,
++                                                  clk_dev_data[i].flags2));
+               }
+       }
+       return 0;
+ }
+ static const struct udevice_id imx95_blkctrl_clk_ids[] = {
+       { .compatible = "nxp,imx95-lvds-csr", .data = (ulong)&imx95_lvds_csr_dev_data, },
+       { .compatible = "nxp,imx95-hsio-blk-ctl", .data = (ulong)&hsio_blk_ctl_dev_data,  },
+       { },
+ };
+ U_BOOT_DRIVER(imx95_blkctrl_clk) = {
+       .name = "imx95_blkctrl_clk",
+       .id = UCLASS_CLK,
+       .of_match = imx95_blkctrl_clk_ids,
+       .ops = &ccf_clk_ops,
+       .probe = imx95_blkctrl_clk_probe,
+       .flags = DM_FLAG_PRE_RELOC,
+ };
index fdb463710ba19567d67848982c9efa53c7a2390a,f84c7180560a403cfae665f14516090a4029ba15..41d9f3c20b96846ba6580ba206e6b6ac5d5c34e7
@@@ -57,11 -103,159 +103,152 @@@ struct pcie_dw_imx 
  };
  
  struct pcie_chip_info {
+       u32 flags;
+       const u32 ltssm_off;
+       const u32 ltssm_mask;
+       const u32 mode_off[IMX_PCIE_MAX_INSTANCES];
+       const u32 mode_mask[IMX_PCIE_MAX_INSTANCES];
        const char *gpr;
+       void (*init_phy)(struct pcie_dw_imx *priv);
+       int (*enable_ref_clk)(struct pcie_dw_imx *priv, bool enable);
+       int (*core_reset)(struct pcie_dw_imx *priv, bool assert);
+       int (*wait_pll_lock)(struct pcie_dw_imx *priv);
+       void (*post_config)(struct pcie_dw_imx *priv);
  };
  
 -              IMX95_PCIE_SYS_AUX_PWR_DET, IMX95_PCIE_SYS_AUX_PWR_DET);
+ static void imx95_pcie_init_phy(struct pcie_dw_imx *priv)
+ {
+ /*
+  * Workaround for ERR051624: The Controller Without Vaux Cannot
+  * Exit L23 Ready Through Beacon or PERST# De-assertion
+  *
+  * When the auxiliary power is not available the controller
+  * cannot exit from L23 Ready with beacon or PERST# de-assertion
+  * when main power is not removed.
+  *
+  * Workaround: Set SS_RW_REG_1[SYS_AUX_PWR_DET] to 1.
+  */
+       regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_1,
 -      regmap_update_bits(priv->iomuxc_gpr,
 -              IMX95_PCIE_SS_RW_REG_0,
 -              IMX95_PCIE_PHY_CR_PARA_SEL,
 -              IMX95_PCIE_PHY_CR_PARA_SEL);
++                         IMX95_PCIE_SYS_AUX_PWR_DET,
++                         IMX95_PCIE_SYS_AUX_PWR_DET);
 -              regmap_update_bits(priv->iomuxc_gpr,
 -                      IMX95_PCIE_PHY_GEN_CTRL,
 -                      IMX95_PCIE_REF_USE_PAD,
 -                      IMX95_PCIE_REF_USE_PAD);
 -              regmap_update_bits(priv->iomuxc_gpr,
 -                      IMX95_PCIE_SS_RW_REG_0,
 -                      IMX95_PCIE_REF_CLKEN, 0);
++      regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
++                         IMX95_PCIE_PHY_CR_PARA_SEL,
++                         IMX95_PCIE_PHY_CR_PARA_SEL);
+       if (priv->enable_ext_refclk) {
+               /* External clock is used as reference clock */
 -              regmap_update_bits(priv->iomuxc_gpr,
 -                      IMX95_PCIE_PHY_GEN_CTRL,
 -                      IMX95_PCIE_REF_USE_PAD, 0);
++              regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL,
++                                 IMX95_PCIE_REF_USE_PAD,
++                                 IMX95_PCIE_REF_USE_PAD);
++              regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
++                                 IMX95_PCIE_REF_CLKEN, 0);
+       } else {
 -              regmap_update_bits(priv->iomuxc_gpr,
 -                      IMX95_PCIE_SS_RW_REG_0,
 -                      IMX95_PCIE_REF_CLKEN,
 -                      IMX95_PCIE_REF_CLKEN);
++              regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL,
++                                 IMX95_PCIE_REF_USE_PAD, 0);
 -              regmap_read(priv->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
 -                                   &val);
++              regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
++                                 IMX95_PCIE_REF_CLKEN, IMX95_PCIE_REF_CLKEN);
+       }
+       /* Force CLKREQ# low by override */
+       if (!priv->supports_clkreq)
+               regmap_update_bits(priv->iomuxc_gpr,
+                                  IMX95_PCIE_SS_RW_REG_1,
+                                  IMX95_PCIE_CLKREQ_OVERRIDE_EN |
+                                  IMX95_PCIE_CLKREQ_OVERRIDE_VAL,
+                                  IMX95_PCIE_CLKREQ_OVERRIDE_EN |
+                                  IMX95_PCIE_CLKREQ_OVERRIDE_VAL);
+ }
+ static int imx95_pcie_wait_for_phy_pll_lock(struct pcie_dw_imx *priv)
+ {
+       u32 val;
+       if (regmap_read_poll_timeout(priv->iomuxc_gpr,
+                                    IMX95_PCIE_PHY_MPLLA_CTRL, val,
+                                    val & IMX95_PCIE_PHY_MPLL_STATE,
+                                    PHY_PLL_LOCK_WAIT_USLEEP_MAX,
+                                    PHY_PLL_LOCK_WAIT_TIMEOUT)) {
+               printf("PCIe PLL lock timeout\n");
+               return -ETIMEDOUT;
+       }
+       return 0;
+ }
+ static int imx95_pcie_core_reset(struct pcie_dw_imx *priv, bool assert)
+ {
+       u32 val;
+       if (assert) {
+               /*
+                * From i.MX95 PCIe PHY perspective, the COLD reset toggle
+                * should be complete after power-up by the following sequence.
+                *                 > 10us(at power-up)
+                *                 > 10ns(warm reset)
+                *               |<------------>|
+                *                ______________
+                * phy_reset ____/              \________________
+                *                                   ____________
+                * ref_clk_en_______________________/
+                * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
+                */
+               regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
+                                  IMX95_PCIE_COLD_RST, IMX95_PCIE_COLD_RST);
+               /*
+                * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
+                * hardware by doing a read. Otherwise, there is no guarantee
+                * that the write has reached the hardware before udelay().
+                */
 -                                IMX95_PCIE_COLD_RST, 0);
 -              regmap_read(priv->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
 -                                   &val);
++              regmap_read(priv->iomuxc_gpr, IMX95_PCIE_RST_CTRL, &val);
+               udelay(15);
+               regmap_update_bits(priv->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
++                                 IMX95_PCIE_COLD_RST, 0);
++              regmap_read(priv->iomuxc_gpr, IMX95_PCIE_RST_CTRL, &val);
+               udelay(10);
+       }
+       return 0;
+ }
+ static void imx95_pcie_post_config(struct pcie_dw_imx *priv)
+ {
+       u32 val;
+       /*
+        * Workaround for ERR051586: Compliance with 8GT/s Receiver
+        * Impedance ECN
+        *
+        * The default value of GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] is
+        * 1 which makes receiver non-compliant with the ZRX-DC
+        * parameter for 2.5 GT/s when operating at 8 GT/s or higher. It
+        * causes unnecessary timeout in L1.
+        *
+        * Workaround: Program GEN3_RELATED_OFF[GEN3_ZRXDC_NONCOMPL] to 0.
+        */
+       dw_pcie_dbi_write_enable(&priv->dw, true);
+       val = readl(priv->dw.dbi_base + GEN3_RELATED_OFF);
+       val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
+       writel(val, priv->dw.dbi_base + GEN3_RELATED_OFF);
+       dw_pcie_dbi_write_enable(&priv->dw, false);
+ }
+ static int imx8mm_pcie_enable_ref_clk(struct pcie_dw_imx *priv, bool enable)
+ {
+       regmap_update_bits(priv->iomuxc_gpr, IOMUXC_GPR14_OFFSET,
+                          IMX8M_GPR_PCIE_CLK_REQ_OVERRIDE,
+                          enable ? 0 : IMX8M_GPR_PCIE_CLK_REQ_OVERRIDE);
+       regmap_update_bits(priv->iomuxc_gpr, IOMUXC_GPR14_OFFSET,
+                          IMX8M_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
+                          enable ? IMX8M_GPR_PCIE_CLK_REQ_OVERRIDE_EN : 0);
+       return 0;
+ }
  static const struct pcie_chip_info imx8mm_chip_info = {
+       .flags = IMX_PCIE_FLAG_HAS_APP_RESET | IMX_PCIE_FLAG_HAS_PHYDRV,
        .gpr = "fsl,imx8mm-iomuxc-gpr",
+       .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
  };
  
  static const struct pcie_chip_info imx8mp_chip_info = {