Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'pci/controller/dwc-imx6'

- Add DT binding and driver support for an optional external refclock in
addition to the refclock from the internal PLL (Richard Zhu)

- Apply i.MX95 ERR051586 erratum workaround (release CLKREQ# so endpoint
can assert it when required) during resume (Richard Zhu)

- Enable i.MX95 REFCLK by overriding CLKREQ# so it's driven by default
(Richard Zhu)

- Clear CLKREQ# override if link is up and DT says 'supports-clkreq' so
endpoints can use CLKREQ# to exit the L1.2 state (Richard Zhu)

* pci/controller/dwc-imx6:
PCI: imx6: Clear CLKREQ# override if 'supports-clkreq' DT property is available
PCI: imx6: Add CLKREQ# override to enable REFCLK for i.MX95 PCIe
PCI: dwc: Invoke post_init in dw_pcie_resume_noirq()
PCI: imx6: Add external reference clock input mode support
dt-bindings: PCI: pci-imx6: Add external reference clock input
dt-bindings: PCI: dwc: Add external reference clock input

+75 -10
+5 -2
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
··· 44 44 45 45 clock-names: 46 46 minItems: 3 47 - maxItems: 5 47 + maxItems: 6 48 48 49 49 interrupts: 50 50 minItems: 1 ··· 212 212 then: 213 213 properties: 214 214 clocks: 215 - maxItems: 5 215 + minItems: 5 216 + maxItems: 6 216 217 clock-names: 218 + minItems: 5 217 219 items: 218 220 - const: pcie 219 221 - const: pcie_bus 220 222 - const: pcie_phy 221 223 - const: pcie_aux 222 224 - const: ref 225 + - const: extref # Optional 223 226 224 227 unevaluatedProperties: false 225 228
+6
Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
··· 106 106 be connected to a single source of the periodic signal). 107 107 const: ref 108 108 - description: 109 + Some dwc wrappers (like i.MX95 PCIes) have two reference clock 110 + inputs, one from an internal PLL, the other from an off-chip crystal 111 + oscillator. If present, 'extref' refers to a reference clock from 112 + an external oscillator. 113 + const: extref 114 + - description: 109 115 Clock for the PHY registers interface. Originally this is 110 116 a PHY-viewport-based interface, but some platform may have 111 117 specifically designed one.
+61 -8
drivers/pci/controller/dwc/pci-imx6.c
··· 52 52 #define IMX95_PCIE_REF_CLKEN BIT(23) 53 53 #define IMX95_PCIE_PHY_CR_PARA_SEL BIT(9) 54 54 #define IMX95_PCIE_SS_RW_REG_1 0xf4 55 + #define IMX95_PCIE_CLKREQ_OVERRIDE_EN BIT(8) 56 + #define IMX95_PCIE_CLKREQ_OVERRIDE_VAL BIT(9) 55 57 #define IMX95_PCIE_SYS_AUX_PWR_DET BIT(31) 56 58 57 59 #define IMX95_PE0_GEN_CTRL_1 0x1050 ··· 139 137 int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable); 140 138 int (*core_reset)(struct imx_pcie *pcie, bool assert); 141 139 int (*wait_pll_lock)(struct imx_pcie *pcie); 140 + void (*clr_clkreq_override)(struct imx_pcie *pcie); 142 141 const struct dw_pcie_host_ops *ops; 143 142 }; 144 143 ··· 153 150 struct gpio_desc *reset_gpiod; 154 151 struct clk_bulk_data *clks; 155 152 int num_clks; 153 + bool supports_clkreq; 154 + bool enable_ext_refclk; 156 155 struct regmap *iomuxc_gpr; 157 156 u16 msi_ctrl; 158 157 u32 controller_id; ··· 247 242 248 243 static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) 249 244 { 245 + bool ext = imx_pcie->enable_ext_refclk; 246 + 250 247 /* 251 248 * ERR051624: The Controller Without Vaux Cannot Exit L23 Ready 252 249 * Through Beacon or PERST# De-assertion ··· 267 260 IMX95_PCIE_PHY_CR_PARA_SEL, 268 261 IMX95_PCIE_PHY_CR_PARA_SEL); 269 262 270 - regmap_update_bits(imx_pcie->iomuxc_gpr, 271 - IMX95_PCIE_PHY_GEN_CTRL, 272 - IMX95_PCIE_REF_USE_PAD, 0); 273 - regmap_update_bits(imx_pcie->iomuxc_gpr, 274 - IMX95_PCIE_SS_RW_REG_0, 263 + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL, 264 + ext ? IMX95_PCIE_REF_USE_PAD : 0, 265 + IMX95_PCIE_REF_USE_PAD); 266 + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0, 275 267 IMX95_PCIE_REF_CLKEN, 276 - IMX95_PCIE_REF_CLKEN); 268 + ext ? 0 : IMX95_PCIE_REF_CLKEN); 277 269 278 270 return 0; 279 271 } ··· 692 686 return 0; 693 687 } 694 688 695 - static int imx8mm_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable) 689 + static void imx8mm_pcie_clkreq_override(struct imx_pcie *imx_pcie, bool enable) 696 690 { 697 691 int offset = imx_pcie_grp_offset(imx_pcie); 698 692 ··· 702 696 regmap_update_bits(imx_pcie->iomuxc_gpr, offset, 703 697 IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, 704 698 enable ? IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN : 0); 699 + } 700 + 701 + static int imx8mm_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable) 702 + { 703 + imx8mm_pcie_clkreq_override(imx_pcie, enable); 705 704 return 0; 706 705 } 707 706 ··· 716 705 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 717 706 enable ? 0 : IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); 718 707 return 0; 708 + } 709 + 710 + static void imx95_pcie_clkreq_override(struct imx_pcie *imx_pcie, bool enable) 711 + { 712 + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_1, 713 + IMX95_PCIE_CLKREQ_OVERRIDE_EN, 714 + enable ? IMX95_PCIE_CLKREQ_OVERRIDE_EN : 0); 715 + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_1, 716 + IMX95_PCIE_CLKREQ_OVERRIDE_VAL, 717 + enable ? IMX95_PCIE_CLKREQ_OVERRIDE_VAL : 0); 718 + } 719 + 720 + static int imx95_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable) 721 + { 722 + imx95_pcie_clkreq_override(imx_pcie, enable); 723 + return 0; 724 + } 725 + 726 + static void imx8mm_pcie_clr_clkreq_override(struct imx_pcie *imx_pcie) 727 + { 728 + imx8mm_pcie_clkreq_override(imx_pcie, false); 729 + } 730 + 731 + static void imx95_pcie_clr_clkreq_override(struct imx_pcie *imx_pcie) 732 + { 733 + imx95_pcie_clkreq_override(imx_pcie, false); 719 734 } 720 735 721 736 static int imx_pcie_clk_enable(struct imx_pcie *imx_pcie) ··· 1360 1323 dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val); 1361 1324 dw_pcie_dbi_ro_wr_dis(pci); 1362 1325 } 1326 + 1327 + /* Clear CLKREQ# override if supports_clkreq is true and link is up */ 1328 + if (dw_pcie_link_up(pci) && imx_pcie->supports_clkreq) { 1329 + if (imx_pcie->drvdata->clr_clkreq_override) 1330 + imx_pcie->drvdata->clr_clkreq_override(imx_pcie); 1331 + } 1363 1332 } 1364 1333 1365 1334 /* ··· 1649 1606 struct imx_pcie *imx_pcie; 1650 1607 struct device_node *np; 1651 1608 struct device_node *node = dev->of_node; 1652 - int ret, domain; 1609 + int i, ret, domain; 1653 1610 u16 val; 1654 1611 1655 1612 imx_pcie = devm_kzalloc(dev, sizeof(*imx_pcie), GFP_KERNEL); ··· 1700 1657 if (imx_pcie->num_clks < 0) 1701 1658 return dev_err_probe(dev, imx_pcie->num_clks, 1702 1659 "failed to get clocks\n"); 1660 + for (i = 0; i < imx_pcie->num_clks; i++) 1661 + if (strncmp(imx_pcie->clks[i].id, "extref", 6) == 0) 1662 + imx_pcie->enable_ext_refclk = true; 1703 1663 1704 1664 if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_PHYDRV)) { 1705 1665 imx_pcie->phy = devm_phy_get(dev, "pcie-phy"); ··· 1790 1744 /* Limit link speed */ 1791 1745 pci->max_link_speed = 1; 1792 1746 of_property_read_u32(node, "fsl,max-link-speed", &pci->max_link_speed); 1747 + imx_pcie->supports_clkreq = of_property_read_bool(node, "supports-clkreq"); 1793 1748 1794 1749 ret = devm_regulator_get_enable_optional(&pdev->dev, "vpcie3v3aux"); 1795 1750 if (ret < 0 && ret != -ENODEV) ··· 1928 1881 .mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, 1929 1882 .init_phy = imx8mq_pcie_init_phy, 1930 1883 .enable_ref_clk = imx8mm_pcie_enable_ref_clk, 1884 + .clr_clkreq_override = imx8mm_pcie_clr_clkreq_override, 1931 1885 }, 1932 1886 [IMX8MM] = { 1933 1887 .variant = IMX8MM, ··· 1939 1891 .mode_off[0] = IOMUXC_GPR12, 1940 1892 .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, 1941 1893 .enable_ref_clk = imx8mm_pcie_enable_ref_clk, 1894 + .clr_clkreq_override = imx8mm_pcie_clr_clkreq_override, 1942 1895 }, 1943 1896 [IMX8MP] = { 1944 1897 .variant = IMX8MP, ··· 1950 1901 .mode_off[0] = IOMUXC_GPR12, 1951 1902 .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, 1952 1903 .enable_ref_clk = imx8mm_pcie_enable_ref_clk, 1904 + .clr_clkreq_override = imx8mm_pcie_clr_clkreq_override, 1953 1905 }, 1954 1906 [IMX8Q] = { 1955 1907 .variant = IMX8Q, ··· 1971 1921 .core_reset = imx95_pcie_core_reset, 1972 1922 .init_phy = imx95_pcie_init_phy, 1973 1923 .wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock, 1924 + .enable_ref_clk = imx95_pcie_enable_ref_clk, 1925 + .clr_clkreq_override = imx95_pcie_clr_clkreq_override, 1974 1926 }, 1975 1927 [IMX8MQ_EP] = { 1976 1928 .variant = IMX8MQ_EP, ··· 2029 1977 .core_reset = imx95_pcie_core_reset, 2030 1978 .wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock, 2031 1979 .epc_features = &imx95_pcie_epc_features, 1980 + .enable_ref_clk = imx95_pcie_enable_ref_clk, 2032 1981 .mode = DW_PCIE_EP_TYPE, 2033 1982 }, 2034 1983 };
+3
drivers/pci/controller/dwc/pcie-designware-host.c
··· 1317 1317 if (ret) 1318 1318 return ret; 1319 1319 1320 + if (pci->pp.ops->post_init) 1321 + pci->pp.ops->post_init(&pci->pp); 1322 + 1320 1323 return ret; 1321 1324 } 1322 1325 EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);