int reset_gpio;
bool gpio_active_high;
struct clk *pcie_bus;
- struct clk *pcie_phy;
struct clk *pcie_inbound_axi;
+ struct clk *pcie_phy;
struct clk *pcie;
struct regmap *iomuxc_gpr;
enum imx6_pcie_variants variant;
/* pcie phy ref clock select; 1? internal pll : external osc */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
BIT(5), 0);
- } else {
+ } else if (imx6_pcie->variant == IMX6SX) {
+ /* Force PCIe PHY reset */
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET);
+
+ regulator_set_voltage(imx6_pcie->pcie_phy_regulator,
+ 1100000, 1100000);
+ ret = regulator_enable(imx6_pcie->pcie_phy_regulator);
+ if (ret)
+ dev_err(imx6_pcie->pp.dev,
+ "failed to enable pcie regulator.\n");
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_RX_EQ_MASK,
+ IMX6SX_GPR12_PCIE_RX_EQ_2);
+ }
+
+ if (imx6_pcie->variant != IMX7D) {
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
/* configure constant input signal to the pcie ctrl and phy */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
+ IMX6Q_GPR12_LOS_LEVEL, IMX6Q_GPR12_LOS_LEVEL_9);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
if (imx6_pcie->variant == IMX7D && ddr_test_region == 0)
ddr_test_region = 0xb0000000;
+ else if (imx6_pcie->variant == IMX6SX && ddr_test_region == 0)
+ ddr_test_region = 0xb0000000;
else if (ddr_test_region == 0)
ddr_test_region = 0x40000000;
sscanf(buf, "%x\n", &memw_start);
- if (imx6_pcie->variant == IMX7D) {
+ if (imx6_pcie->variant == IMX7D || imx6_pcie->variant == IMX6SX) {
if (memw_start < 0x80000000 || memw_start > 0xb0000000) {
dev_err(dev, "Invalid memory start addr.\n");
dev_info(dev, "e.x: echo 0xb0000000 > /sys/...");
BIT(11), BIT(11));
regmap_update_bits(imx6_pcie->reg_src, 0x2c,
BIT(11), 0);
+ } else if (imx6_pcie->variant == IMX6SX) {
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_PM_TURN_OFF,
+ IMX6SX_GPR12_PCIE_PM_TURN_OFF);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0);
} else {
pr_info("Info: don't support pm_turn_off yet.\n");
return;
pci_imx_pm_turn_off(imx6_pcie);
- if (imx6_pcie->variant == IMX7D) {
+ if (imx6_pcie->variant == IMX7D || imx6_pcie->variant == IMX6SX) {
/* Disable clks */
clk_disable_unprepare(imx6_pcie->pcie);
clk_disable_unprepare(imx6_pcie->pcie_phy);
clk_disable_unprepare(imx6_pcie->pcie_bus);
- /* turn off external osc input */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- BIT(5), BIT(5));
+ if (imx6_pcie->variant == IMX6SX)
+ clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
+ else
+ /* turn off external osc input */
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ BIT(5), BIT(5));
release_bus_freq(BUS_FREQ_HIGH);
/* Power down PCIe PHY. */
struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
struct pcie_port *pp = &imx6_pcie->pp;
- if (imx6_pcie->variant == IMX7D) {
- regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), 0);
+ if (imx6_pcie->variant == IMX7D || imx6_pcie->variant == IMX6SX) {
+ if (imx6_pcie->variant == IMX7D)
+ regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), 0);
+ else
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_CTL_2, 0);
imx6_pcie_assert_core_reset(imx6_pcie);
if (IS_ENABLED(CONFIG_PCI_MSI))
dw_pcie_msi_cfg_restore(pp);
- /* wait for phy pll lock firstly. */
- pci_imx_phy_pll_locked(imx6_pcie);
- regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), BIT(6));
+ if (imx6_pcie->variant == IMX7D) {
+ /* wait for phy pll lock firstly. */
+ pci_imx_phy_pll_locked(imx6_pcie);
+ regmap_update_bits(imx6_pcie->reg_src, 0x2c,
+ BIT(6), BIT(6));
+ } else {
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_CTL_2,
+ IMX6Q_GPR12_PCIE_CTL_2);
+ }
ret = imx6_pcie_wait_for_link(imx6_pcie);
if (ret < 0)
}
imx6_pcie->pcie_phy_regulator = devm_regulator_get(pp->dev,
"pcie-phy");
+ } else if (imx6_pcie->variant == IMX6SX) {
+ imx6_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev,
+ "pcie_inbound_axi");
+ if (IS_ERR(imx6_pcie->pcie_inbound_axi)) {
+ dev_err(&pdev->dev,
+ "pcie clock source missing or invalid\n");
+ return PTR_ERR(imx6_pcie->pcie_inbound_axi);
+ }
+
+ imx6_pcie->pcie_phy_regulator = devm_regulator_get(pp->dev,
+ "pcie-phy");
+
+ imx6_pcie->iomuxc_gpr =
+ syscon_regmap_lookup_by_compatible
+ ("fsl,imx6sx-iomuxc-gpr");
} else {
imx6_pcie->iomuxc_gpr =
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
imx6_pcie_init_phy(imx6_pcie);
imx6_pcie_deassert_core_reset(imx6_pcie);
+ /*
+ * iMX6SX PCIe has the stand-alone power domain.
+ * refer to the initialization for iMX6SX PCIe,
+ * release the PCIe PHY reset here,
+ * before LTSSM enable is set
+ * .
+ */
+ if (imx6_pcie->variant == IMX6SX)
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ BIT(19), 0 << 19);
+
/* assert LTSSM enable */
if (imx6_pcie->variant == IMX7D) {
regmap_update_bits(imx6_pcie->reg_src, 0x2c,