MLK-23668-2 PCI: imx: add the pcieb for imx8qm
Enable the second PCIe port PCIEB on i.MX8QM platforms. - PCIEB has one more PER clock, since that the PCIEA CSR register would be configuired when PCIEB is initialized. - Use CLKREQ override on i.MX8QM/i.MX8QXP - In the PCIEAX1PCIEBx1SATA usecase, the PHYX2_PCLK[0] is mandatory required by PCIEB. Otherwise PCIEB can't link up when exist from L2 mode when only PCIEB is used. - Regarding to the base board HW limitation(two Disable#) are not connected. Only the standard PCIe EP device is supported on PCIEB port. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> Reviewed-by: Fugang Duan <fugang.duan@nxp.com>
This commit is contained in:
parent
c24b099bb5
commit
8c28614abf
|
@ -106,13 +106,16 @@ struct imx6_pcie {
|
||||||
bool gpio_active_high;
|
bool gpio_active_high;
|
||||||
struct clk *pcie_bus;
|
struct clk *pcie_bus;
|
||||||
struct clk *pcie_phy;
|
struct clk *pcie_phy;
|
||||||
|
struct clk *pcie_phy_pclk;
|
||||||
struct clk *pcie_per;
|
struct clk *pcie_per;
|
||||||
|
struct clk *pciex2_per;
|
||||||
struct clk *pcie_inbound_axi;
|
struct clk *pcie_inbound_axi;
|
||||||
struct clk *pcie;
|
struct clk *pcie;
|
||||||
struct clk *pcie_aux;
|
struct clk *pcie_aux;
|
||||||
struct clk *phy_per;
|
struct clk *phy_per;
|
||||||
struct clk *misc_per;
|
struct clk *misc_per;
|
||||||
struct regmap *iomuxc_gpr;
|
struct regmap *iomuxc_gpr;
|
||||||
|
struct regmap *hsiomix;
|
||||||
u32 controller_id;
|
u32 controller_id;
|
||||||
struct reset_control *pciephy_reset;
|
struct reset_control *pciephy_reset;
|
||||||
struct reset_control *pciephy_perst;
|
struct reset_control *pciephy_perst;
|
||||||
|
@ -136,6 +139,8 @@ struct imx6_pcie {
|
||||||
|
|
||||||
/* power domain for pcie */
|
/* power domain for pcie */
|
||||||
struct device *pd_pcie;
|
struct device *pd_pcie;
|
||||||
|
/* power domain for pcie csr access */
|
||||||
|
struct device *pd_pcie_per;
|
||||||
/* power domain for pcie phy */
|
/* power domain for pcie phy */
|
||||||
struct device *pd_pcie_phy;
|
struct device *pd_pcie_phy;
|
||||||
/* power domain for hsio gpio used by pcie */
|
/* power domain for hsio gpio used by pcie */
|
||||||
|
@ -253,15 +258,18 @@ struct imx6_pcie {
|
||||||
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3)
|
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3)
|
||||||
|
|
||||||
/* iMX8 HSIO registers */
|
/* iMX8 HSIO registers */
|
||||||
#define IMX8QM_CSR_PHYX2_OFFSET 0x00000
|
#define IMX8QM_PHYX2_LPCG_OFFSET 0x00000
|
||||||
#define IMX8QM_CSR_PHYX1_OFFSET 0x10000
|
#define IMX8QM_PHYX2_LPCG_PCLK0_MASK GENMASK(17, 16)
|
||||||
|
#define IMX8QM_PHYX2_LPCG_PCLK1_MASK GENMASK(21, 20)
|
||||||
|
#define IMX8QM_CSR_PHYX2_OFFSET 0x90000
|
||||||
|
#define IMX8QM_CSR_PHYX1_OFFSET 0xA0000
|
||||||
#define IMX8QM_CSR_PHYX_STTS0_OFFSET 0x4
|
#define IMX8QM_CSR_PHYX_STTS0_OFFSET 0x4
|
||||||
#define IMX8QM_CSR_PCIEA_OFFSET 0x20000
|
#define IMX8QM_CSR_PCIEA_OFFSET 0xB0000
|
||||||
#define IMX8QM_CSR_PCIEB_OFFSET 0x30000
|
#define IMX8QM_CSR_PCIEB_OFFSET 0xC0000
|
||||||
#define IMX8QM_CSR_PCIE_CTRL1_OFFSET 0x4
|
#define IMX8QM_CSR_PCIE_CTRL1_OFFSET 0x4
|
||||||
#define IMX8QM_CSR_PCIE_CTRL2_OFFSET 0x8
|
#define IMX8QM_CSR_PCIE_CTRL2_OFFSET 0x8
|
||||||
#define IMX8QM_CSR_PCIE_STTS0_OFFSET 0xC
|
#define IMX8QM_CSR_PCIE_STTS0_OFFSET 0xC
|
||||||
#define IMX8QM_CSR_MISC_OFFSET 0x50000
|
#define IMX8QM_CSR_MISC_OFFSET 0xE0000
|
||||||
|
|
||||||
#define IMX8QM_CTRL_LTSSM_ENABLE BIT(4)
|
#define IMX8QM_CTRL_LTSSM_ENABLE BIT(4)
|
||||||
#define IMX8QM_CTRL_READY_ENTR_L23 BIT(5)
|
#define IMX8QM_CTRL_READY_ENTR_L23 BIT(5)
|
||||||
|
@ -288,6 +296,10 @@ struct imx6_pcie {
|
||||||
#define IMX8QM_CSR_MISC_IOB_A_0_M1M0_2 BIT(4)
|
#define IMX8QM_CSR_MISC_IOB_A_0_M1M0_2 BIT(4)
|
||||||
#define IMX8QM_MISC_PHYX1_EPCS_SEL BIT(12)
|
#define IMX8QM_MISC_PHYX1_EPCS_SEL BIT(12)
|
||||||
#define IMX8QM_MISC_PCIE_AB_SELECT BIT(13)
|
#define IMX8QM_MISC_PCIE_AB_SELECT BIT(13)
|
||||||
|
#define IMX8QM_MISC_CLKREQ_1 BIT(22)
|
||||||
|
#define IMX8QM_MISC_CLKREQ_0 BIT(23)
|
||||||
|
#define IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1 BIT(24)
|
||||||
|
#define IMX8QM_MISC_CLKREQ_OVERRIDE_EN_0 BIT(25)
|
||||||
|
|
||||||
#define IMX8MM_GPR_PCIE_REF_CLK_SEL (0x3 << 24)
|
#define IMX8MM_GPR_PCIE_REF_CLK_SEL (0x3 << 24)
|
||||||
#define IMX8MM_GPR_PCIE_REF_CLK_PLL (0x3 << 24)
|
#define IMX8MM_GPR_PCIE_REF_CLK_PLL (0x3 << 24)
|
||||||
|
@ -332,13 +344,20 @@ static bool imx6_pcie_readable_reg(struct device *dev, unsigned int reg)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
|
case IMX8QM_PHYX2_LPCG_OFFSET:
|
||||||
case IMX8QM_CSR_PHYX2_OFFSET:
|
case IMX8QM_CSR_PHYX2_OFFSET:
|
||||||
|
case IMX8QM_CSR_PHYX1_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET:
|
||||||
case IMX8QM_CSR_MISC_OFFSET:
|
case IMX8QM_CSR_MISC_OFFSET:
|
||||||
case IMX8QM_CSR_PHYX2_OFFSET + IMX8QM_CSR_PHYX_STTS0_OFFSET:
|
case IMX8QM_CSR_PHYX2_OFFSET + IMX8QM_CSR_PHYX_STTS0_OFFSET:
|
||||||
|
case IMX8QM_CSR_PHYX1_OFFSET + IMX8QM_CSR_PHYX_STTS0_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL1_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL1_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_STTS0_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_STTS0_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET + IMX8QM_CSR_PCIE_CTRL1_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET + IMX8QM_CSR_PCIE_STTS0_OFFSET:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -366,11 +385,16 @@ static bool imx6_pcie_writeable_reg(struct device *dev, unsigned int reg)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
|
case IMX8QM_PHYX2_LPCG_OFFSET:
|
||||||
case IMX8QM_CSR_PHYX2_OFFSET:
|
case IMX8QM_CSR_PHYX2_OFFSET:
|
||||||
|
case IMX8QM_CSR_PHYX1_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET:
|
||||||
case IMX8QM_CSR_MISC_OFFSET:
|
case IMX8QM_CSR_MISC_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL1_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL1_OFFSET:
|
||||||
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET:
|
case IMX8QM_CSR_PCIEA_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET + IMX8QM_CSR_PCIE_CTRL1_OFFSET:
|
||||||
|
case IMX8QM_CSR_PCIEB_OFFSET + IMX8QM_CSR_PCIE_CTRL2_OFFSET:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -617,6 +641,17 @@ static int imx6_pcie_attach_pd(struct device *dev)
|
||||||
|
|
||||||
switch (imx6_pcie->drvdata->variant) {
|
switch (imx6_pcie->drvdata->variant) {
|
||||||
case IMX8QM:
|
case IMX8QM:
|
||||||
|
/*
|
||||||
|
* PCIA CSR would be touched during the initialization of the
|
||||||
|
* PCIEB of 8QM.
|
||||||
|
* Enable the PCIEA PD for this case here.
|
||||||
|
*/
|
||||||
|
if (imx6_pcie->controller_id) {
|
||||||
|
imx6_pcie->pd_pcie_per = dev_pm_domain_attach_by_name(dev, "pcie_per");
|
||||||
|
if (IS_ERR(imx6_pcie->pd_pcie_per))
|
||||||
|
return PTR_ERR(imx6_pcie->pd_pcie_per);
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
case IMX8QXP:
|
case IMX8QXP:
|
||||||
imx6_pcie->pd_hsio_gpio = dev_pm_domain_attach_by_name(dev, "hsio_gpio");
|
imx6_pcie->pd_hsio_gpio = dev_pm_domain_attach_by_name(dev, "hsio_gpio");
|
||||||
if (IS_ERR(imx6_pcie->pd_hsio_gpio))
|
if (IS_ERR(imx6_pcie->pd_hsio_gpio))
|
||||||
|
@ -705,31 +740,58 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
|
||||||
ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
|
ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "unable to enable pcie_axi clock\n");
|
dev_err(dev, "unable to enable pcie_axi clock\n");
|
||||||
break;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = clk_prepare_enable(imx6_pcie->pcie_per);
|
ret = clk_prepare_enable(imx6_pcie->pcie_per);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "unable to enable pcie_per clock\n");
|
dev_err(dev, "unable to enable pcie_per clock\n");
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
|
goto err_pcie_per;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = clk_prepare_enable(imx6_pcie->phy_per);
|
ret = clk_prepare_enable(imx6_pcie->phy_per);
|
||||||
if (unlikely(ret)) {
|
if (unlikely(ret)) {
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_per);
|
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
|
|
||||||
dev_err(dev, "unable to enable phy per clock\n");
|
dev_err(dev, "unable to enable phy per clock\n");
|
||||||
|
goto err_phy_per;
|
||||||
}
|
}
|
||||||
ret = clk_prepare_enable(imx6_pcie->misc_per);
|
ret = clk_prepare_enable(imx6_pcie->misc_per);
|
||||||
if (unlikely(ret)) {
|
if (unlikely(ret)) {
|
||||||
clk_disable_unprepare(imx6_pcie->phy_per);
|
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_per);
|
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
|
|
||||||
dev_err(dev, "unable to enable misc per clock\n");
|
dev_err(dev, "unable to enable misc per clock\n");
|
||||||
|
goto err_misc_per;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* PCIA CSR would be touched during the initialization of the
|
||||||
|
* PCIEB of 8QM.
|
||||||
|
* Enable the PCIEA peripheral clock for this case here.
|
||||||
|
*/
|
||||||
|
if (imx6_pcie->drvdata->variant == IMX8QM
|
||||||
|
&& imx6_pcie->controller_id == 1) {
|
||||||
|
ret = clk_prepare_enable(imx6_pcie->pcie_phy_pclk);
|
||||||
|
if (unlikely(ret)) {
|
||||||
|
dev_err(dev, "can't enable pciephyp clock\n");
|
||||||
|
goto err_pcie_phy_pclk;
|
||||||
|
}
|
||||||
|
ret = clk_prepare_enable(imx6_pcie->pciex2_per);
|
||||||
|
if (unlikely(ret)) {
|
||||||
|
dev_err(dev, "can't enable pciex2 per clock\n");
|
||||||
|
goto err_pciex2_per;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
err_pciex2_per:
|
||||||
|
clk_disable_unprepare(imx6_pcie->pcie_phy_pclk);
|
||||||
|
err_pcie_phy_pclk:
|
||||||
|
clk_disable_unprepare(imx6_pcie->misc_per);
|
||||||
|
err_misc_per:
|
||||||
|
clk_disable_unprepare(imx6_pcie->phy_per);
|
||||||
|
err_phy_per:
|
||||||
|
clk_disable_unprepare(imx6_pcie->pcie_per);
|
||||||
|
err_pcie_per:
|
||||||
|
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,6 +877,8 @@ static void imx8_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
|
||||||
|
|
||||||
if (retries >= PHY_PLL_LOCK_WAIT_MAX_RETRIES)
|
if (retries >= PHY_PLL_LOCK_WAIT_MAX_RETRIES)
|
||||||
dev_err(dev, "PCIe PLL lock timeout\n");
|
dev_err(dev, "PCIe PLL lock timeout\n");
|
||||||
|
else
|
||||||
|
dev_info(dev, "PCIe PLL locked after %d us.\n", retries * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
|
static void imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
|
||||||
|
@ -874,8 +938,13 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
|
||||||
case IMX8MM:
|
case IMX8MM:
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_aux);
|
clk_disable_unprepare(imx6_pcie->pcie_aux);
|
||||||
break;
|
break;
|
||||||
case IMX8QXP:
|
|
||||||
case IMX8QM:
|
case IMX8QM:
|
||||||
|
if (imx6_pcie->controller_id == 1) {
|
||||||
|
clk_disable_unprepare(imx6_pcie->pciex2_per);
|
||||||
|
clk_disable_unprepare(imx6_pcie->pcie_phy_pclk);
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case IMX8QXP:
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_per);
|
clk_disable_unprepare(imx6_pcie->pcie_per);
|
||||||
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
|
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
|
||||||
clk_disable_unprepare(imx6_pcie->phy_per);
|
clk_disable_unprepare(imx6_pcie->phy_per);
|
||||||
|
@ -924,6 +993,18 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
|
||||||
break;
|
break;
|
||||||
case IMX8QXP:
|
case IMX8QXP:
|
||||||
imx6_pcie_clk_enable(imx6_pcie);
|
imx6_pcie_clk_enable(imx6_pcie);
|
||||||
|
/*
|
||||||
|
* Set the over ride low and enabled
|
||||||
|
* make sure that REF_CLK is turned on.
|
||||||
|
*/
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_1,
|
||||||
|
0);
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1);
|
||||||
val = IMX8QM_CSR_PCIEB_OFFSET;
|
val = IMX8QM_CSR_PCIEB_OFFSET;
|
||||||
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
|
val + IMX8QM_CSR_PCIE_CTRL2_OFFSET,
|
||||||
|
@ -940,6 +1021,29 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
|
||||||
break;
|
break;
|
||||||
case IMX8QM:
|
case IMX8QM:
|
||||||
imx6_pcie_clk_enable(imx6_pcie);
|
imx6_pcie_clk_enable(imx6_pcie);
|
||||||
|
/*
|
||||||
|
* Set the over ride low and enabled
|
||||||
|
* make sure that REF_CLK is turned on.
|
||||||
|
*/
|
||||||
|
if (imx6_pcie->controller_id) {
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_1,
|
||||||
|
0);
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1);
|
||||||
|
} else {
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_0,
|
||||||
|
0);
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_0,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_0);
|
||||||
|
}
|
||||||
for (i = 0; i <= imx6_pcie->controller_id; i++) {
|
for (i = 0; i <= imx6_pcie->controller_id; i++) {
|
||||||
val = IMX8QM_CSR_PCIEA_OFFSET + i * SZ_64K;
|
val = IMX8QM_CSR_PCIEA_OFFSET + i * SZ_64K;
|
||||||
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
@ -1004,12 +1108,21 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (imx6_pcie->drvdata->variant) {
|
switch (imx6_pcie->drvdata->variant) {
|
||||||
case IMX8QXP:
|
|
||||||
case IMX8QM:
|
case IMX8QM:
|
||||||
|
if (imx6_pcie->controller_id)
|
||||||
|
/* Set the APB clock masks */
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_PHYX2_LPCG_OFFSET,
|
||||||
|
IMX8QM_PHYX2_LPCG_PCLK0_MASK |
|
||||||
|
IMX8QM_PHYX2_LPCG_PCLK1_MASK,
|
||||||
|
IMX8QM_PHYX2_LPCG_PCLK0_MASK |
|
||||||
|
IMX8QM_PHYX2_LPCG_PCLK1_MASK);
|
||||||
|
/* fall through */
|
||||||
|
case IMX8QXP:
|
||||||
val = IMX8QM_CSR_PCIEA_OFFSET
|
val = IMX8QM_CSR_PCIEA_OFFSET
|
||||||
+ imx6_pcie->controller_id * SZ_64K;
|
+ imx6_pcie->controller_id * SZ_64K;
|
||||||
/* bit19 PM_REQ_CORE_RST of pciex#_stts0 should be cleared. */
|
/* bit19 PM_REQ_CORE_RST of pciex#_stts0 should be cleared. */
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < PHY_PLL_LOCK_WAIT_MAX_RETRIES; i++) {
|
||||||
regmap_read(imx6_pcie->iomuxc_gpr,
|
regmap_read(imx6_pcie->iomuxc_gpr,
|
||||||
val + IMX8QM_CSR_PCIE_STTS0_OFFSET,
|
val + IMX8QM_CSR_PCIE_STTS0_OFFSET,
|
||||||
&tmp);
|
&tmp);
|
||||||
|
@ -2194,6 +2307,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
|
||||||
void __iomem *iomem;
|
void __iomem *iomem;
|
||||||
struct regmap_config regconfig = imx6_pcie_regconfig;
|
struct regmap_config regconfig = imx6_pcie_regconfig;
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
|
imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
|
||||||
if (!imx6_pcie)
|
if (!imx6_pcie)
|
||||||
|
@ -2406,20 +2520,36 @@ static int imx6_pcie_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
imx6_pcie->phy_per = devm_clk_get(dev, "phy_per");
|
imx6_pcie->phy_per = devm_clk_get(dev, "phy_per");
|
||||||
if (IS_ERR(imx6_pcie->phy_per)) {
|
if (IS_ERR(imx6_pcie->phy_per)) {
|
||||||
dev_err(dev, "failed to get per clock.\n");
|
dev_err(dev, "failed to get phy per clock.\n");
|
||||||
return PTR_ERR(imx6_pcie->phy_per);
|
return PTR_ERR(imx6_pcie->phy_per);
|
||||||
}
|
}
|
||||||
|
|
||||||
imx6_pcie->misc_per = devm_clk_get(dev, "misc_per");
|
imx6_pcie->misc_per = devm_clk_get(dev, "misc_per");
|
||||||
if (IS_ERR(imx6_pcie->misc_per)) {
|
if (IS_ERR(imx6_pcie->misc_per)) {
|
||||||
dev_err(dev, "failed to get per clock.\n");
|
dev_err(dev, "failed to get misc per clock.\n");
|
||||||
return PTR_ERR(imx6_pcie->misc_per);
|
return PTR_ERR(imx6_pcie->misc_per);
|
||||||
}
|
}
|
||||||
|
if (imx6_pcie->drvdata->variant == IMX8QM
|
||||||
|
&& imx6_pcie->controller_id == 1) {
|
||||||
|
imx6_pcie->pcie_phy_pclk = devm_clk_get(dev,
|
||||||
|
"pcie_phy_pclk");
|
||||||
|
if (IS_ERR(imx6_pcie->pcie_phy_pclk)) {
|
||||||
|
dev_err(dev, "no pcie_phy_pclk clock\n");
|
||||||
|
return PTR_ERR(imx6_pcie->pcie_phy_pclk);
|
||||||
|
}
|
||||||
|
|
||||||
|
imx6_pcie->pciex2_per = devm_clk_get(dev, "pciex2_per");
|
||||||
|
if (IS_ERR(imx6_pcie->pciex2_per)) {
|
||||||
|
dev_err(dev, "can't get pciex2_per.\n");
|
||||||
|
return PTR_ERR(imx6_pcie->pciex2_per);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hsio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
hsio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||||
"hsio");
|
"hsio");
|
||||||
if (hsio_res) {
|
if (hsio_res) {
|
||||||
iomem = devm_ioremap_resource(dev, hsio_res);
|
iomem = devm_ioremap(dev, hsio_res->start,
|
||||||
|
resource_size(hsio_res));
|
||||||
if (IS_ERR(iomem))
|
if (IS_ERR(iomem))
|
||||||
return PTR_ERR(iomem);
|
return PTR_ERR(iomem);
|
||||||
imx6_pcie->iomuxc_gpr =
|
imx6_pcie->iomuxc_gpr =
|
||||||
|
@ -2759,6 +2889,21 @@ static int imx6_pcie_probe(struct platform_device *pdev)
|
||||||
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
|
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
|
||||||
0);
|
0);
|
||||||
break;
|
break;
|
||||||
|
case IMX8QXP:
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1,
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
case IMX8QM:
|
||||||
|
if (imx6_pcie->controller_id)
|
||||||
|
reg = IMX8QM_MISC_CLKREQ_OVERRIDE_EN_1;
|
||||||
|
else
|
||||||
|
reg = IMX8QM_MISC_CLKREQ_OVERRIDE_EN_0;
|
||||||
|
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||||
|
IMX8QM_CSR_MISC_OFFSET,
|
||||||
|
reg, 0);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue