u32 tx_swing_low;
int link_gen;
struct regmap *reg_src;
+ void __iomem *phy_base;
struct regulator *pcie_phy_regulator;
struct regulator *pcie_bus_regulator;
};
* FIELD: ref_clkdiv2 [0:0]
*/
+/* iMX7 PCIe PHY registers */
+#define PCIE_PHY_CMN_REG15 0x54
+#define PCIE_PHY_CMN_REG15_DLY_4 (1 << 2)
+#define PCIE_PHY_CMN_REG15_PLL_PD (1 << 5)
+#define PCIE_PHY_CMN_REG15_OVRD_PLL_PD (1 << 7)
+
static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
{
struct pcie_port *pp = &imx6_pcie->pp;
udelay(10);
regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), 0);
regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(1), 0);
+
+ /* Add the workaround for ERR010728 */
+ if (unlikely(imx6_pcie->phy_base == NULL)) {
+ pr_err("phy base shouldn't be null.\n");
+ } else {
+ writel(PCIE_PHY_CMN_REG15_DLY_4,
+ imx6_pcie->phy_base + PCIE_PHY_CMN_REG15);
+ writel(PCIE_PHY_CMN_REG15_DLY_4
+ | PCIE_PHY_CMN_REG15_PLL_PD
+ | PCIE_PHY_CMN_REG15_OVRD_PLL_PD,
+ imx6_pcie->phy_base + PCIE_PHY_CMN_REG15);
+ writel(PCIE_PHY_CMN_REG15_DLY_4,
+ imx6_pcie->phy_base + PCIE_PHY_CMN_REG15);
+ }
+
regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(2), 0);
/* wait for phy pll lock firstly. */
struct device *dev = &pdev->dev;
struct imx6_pcie *imx6_pcie;
struct pcie_port *pp;
+ struct device_node *np;
struct resource *dbi_base;
struct device_node *node = dev->of_node;
int ret;
hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
"imprecise external abort");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx-pcie-phy");
+ if (np != NULL) {
+ imx6_pcie->phy_base = of_iomap(np, 0);
+ WARN_ON(!imx6_pcie->phy_base);
+ } else {
+ imx6_pcie->phy_base = NULL;
+ }
+
dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pp->dbi_base = devm_ioremap_resource(dev, dbi_base);
if (IS_ERR(pp->dbi_base))