Merge branch 'remotes/lorenzo/pci/dwc'
- Use dmam_alloc_coherent() instead of dma_map_page() to allocate the MSI target page, which means dwc drivers will work even when ZONE_DMA32 is disabled (Will McVicker) - If we can't allocate an MSI target page with a 32-bit address, try allocating one with a 64-bit address (Will McVicker) - Switch from of_gpio_named_count() to generic gpiod_count() (Andy Shevchenko) - Add support for i.MX8MP PCIe (Richard Zhu) - Fix the Freescale i.MX8 PHY driver, which had interchanged the phy_init() and phy_power_on() interfaces (Richard Zhu) * remotes/lorenzo/pci/dwc: phy: freescale: imx8m-pcie: Fix the wrong order of phy_init() and phy_power_on() PCI: imx6: Add i.MX8MP PCIe support PCI: dwc: Replace of_gpio_named_count() by gpiod_count() PCI: dwc: Drop dependency on ZONE_DMA32
This commit is contained in:
commit
fefb75d842
|
@ -51,6 +51,7 @@ enum imx6_pcie_variants {
|
|||
IMX7D,
|
||||
IMX8MQ,
|
||||
IMX8MM,
|
||||
IMX8MP,
|
||||
};
|
||||
|
||||
#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
|
||||
|
@ -61,6 +62,7 @@ struct imx6_pcie_drvdata {
|
|||
enum imx6_pcie_variants variant;
|
||||
u32 flags;
|
||||
int dbi_length;
|
||||
const char *gpr;
|
||||
};
|
||||
|
||||
struct imx6_pcie {
|
||||
|
@ -150,7 +152,8 @@ struct imx6_pcie {
|
|||
static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
|
||||
{
|
||||
WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ &&
|
||||
imx6_pcie->drvdata->variant != IMX8MM);
|
||||
imx6_pcie->drvdata->variant != IMX8MM &&
|
||||
imx6_pcie->drvdata->variant != IMX8MP);
|
||||
return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
|
||||
}
|
||||
|
||||
|
@ -301,6 +304,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
|
|||
{
|
||||
switch (imx6_pcie->drvdata->variant) {
|
||||
case IMX8MM:
|
||||
case IMX8MP:
|
||||
/*
|
||||
* The PHY initialization had been done in the PHY
|
||||
* driver, break here directly.
|
||||
|
@ -558,6 +562,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
|
|||
break;
|
||||
case IMX8MM:
|
||||
case IMX8MQ:
|
||||
case IMX8MP:
|
||||
ret = clk_prepare_enable(imx6_pcie->pcie_aux);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to enable pcie_aux clock\n");
|
||||
|
@ -602,6 +607,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
|
|||
break;
|
||||
case IMX8MM:
|
||||
case IMX8MQ:
|
||||
case IMX8MP:
|
||||
clk_disable_unprepare(imx6_pcie->pcie_aux);
|
||||
break;
|
||||
default:
|
||||
|
@ -669,6 +675,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
|
|||
reset_control_assert(imx6_pcie->pciephy_reset);
|
||||
fallthrough;
|
||||
case IMX8MM:
|
||||
case IMX8MP:
|
||||
reset_control_assert(imx6_pcie->apps_reset);
|
||||
break;
|
||||
case IMX6SX:
|
||||
|
@ -744,6 +751,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
|
|||
break;
|
||||
case IMX6Q: /* Nothing to do */
|
||||
case IMX8MM:
|
||||
case IMX8MP:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -793,6 +801,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
|
|||
case IMX7D:
|
||||
case IMX8MQ:
|
||||
case IMX8MM:
|
||||
case IMX8MP:
|
||||
reset_control_deassert(imx6_pcie->apps_reset);
|
||||
break;
|
||||
}
|
||||
|
@ -812,6 +821,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
|
|||
case IMX7D:
|
||||
case IMX8MQ:
|
||||
case IMX8MM:
|
||||
case IMX8MP:
|
||||
reset_control_assert(imx6_pcie->apps_reset);
|
||||
break;
|
||||
}
|
||||
|
@ -935,7 +945,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
}
|
||||
|
||||
if (imx6_pcie->phy) {
|
||||
ret = phy_power_on(imx6_pcie->phy);
|
||||
ret = phy_init(imx6_pcie->phy);
|
||||
if (ret) {
|
||||
dev_err(dev, "pcie PHY power up failed\n");
|
||||
goto err_clk_disable;
|
||||
|
@ -949,7 +959,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
}
|
||||
|
||||
if (imx6_pcie->phy) {
|
||||
ret = phy_init(imx6_pcie->phy);
|
||||
ret = phy_power_on(imx6_pcie->phy);
|
||||
if (ret) {
|
||||
dev_err(dev, "waiting for PHY ready timeout!\n");
|
||||
goto err_phy_off;
|
||||
|
@ -961,7 +971,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
|
|||
|
||||
err_phy_off:
|
||||
if (imx6_pcie->phy)
|
||||
phy_power_off(imx6_pcie->phy);
|
||||
phy_exit(imx6_pcie->phy);
|
||||
err_clk_disable:
|
||||
imx6_pcie_clk_disable(imx6_pcie);
|
||||
err_reg_disable:
|
||||
|
@ -1179,6 +1189,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
|
|||
}
|
||||
break;
|
||||
case IMX8MM:
|
||||
case IMX8MP:
|
||||
imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
|
||||
if (IS_ERR(imx6_pcie->pcie_aux))
|
||||
return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
|
||||
|
@ -1216,7 +1227,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
/* Grab GPR config register range */
|
||||
imx6_pcie->iomuxc_gpr =
|
||||
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
|
||||
syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
|
||||
if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
|
||||
dev_err(dev, "unable to find iomuxc registers\n");
|
||||
return PTR_ERR(imx6_pcie->iomuxc_gpr);
|
||||
|
@ -1295,12 +1306,14 @@ static const struct imx6_pcie_drvdata drvdata[] = {
|
|||
.flags = IMX6_PCIE_FLAG_IMX6_PHY |
|
||||
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
|
||||
.dbi_length = 0x200,
|
||||
.gpr = "fsl,imx6q-iomuxc-gpr",
|
||||
},
|
||||
[IMX6SX] = {
|
||||
.variant = IMX6SX,
|
||||
.flags = IMX6_PCIE_FLAG_IMX6_PHY |
|
||||
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
|
||||
IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.gpr = "fsl,imx6q-iomuxc-gpr",
|
||||
},
|
||||
[IMX6QP] = {
|
||||
.variant = IMX6QP,
|
||||
|
@ -1308,17 +1321,26 @@ static const struct imx6_pcie_drvdata drvdata[] = {
|
|||
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
|
||||
IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.dbi_length = 0x200,
|
||||
.gpr = "fsl,imx6q-iomuxc-gpr",
|
||||
},
|
||||
[IMX7D] = {
|
||||
.variant = IMX7D,
|
||||
.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.gpr = "fsl,imx7d-iomuxc-gpr",
|
||||
},
|
||||
[IMX8MQ] = {
|
||||
.variant = IMX8MQ,
|
||||
.gpr = "fsl,imx8mq-iomuxc-gpr",
|
||||
},
|
||||
[IMX8MM] = {
|
||||
.variant = IMX8MM,
|
||||
.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.gpr = "fsl,imx8mm-iomuxc-gpr",
|
||||
},
|
||||
[IMX8MP] = {
|
||||
.variant = IMX8MP,
|
||||
.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.gpr = "fsl,imx8mp-iomuxc-gpr",
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1329,6 +1351,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
|
|||
{ .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], },
|
||||
{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
|
||||
{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
|
||||
{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
@ -267,15 +267,6 @@ static void dw_pcie_free_msi(struct dw_pcie_rp *pp)
|
|||
|
||||
irq_domain_remove(pp->msi_domain);
|
||||
irq_domain_remove(pp->irq_domain);
|
||||
|
||||
if (pp->msi_data) {
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct device *dev = pci->dev;
|
||||
|
||||
dma_unmap_page(dev, pp->msi_data, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
if (pp->msi_page)
|
||||
__free_page(pp->msi_page);
|
||||
}
|
||||
}
|
||||
|
||||
static void dw_pcie_msi_init(struct dw_pcie_rp *pp)
|
||||
|
@ -336,6 +327,7 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
|
|||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct device *dev = pci->dev;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
u64 *msi_vaddr;
|
||||
int ret;
|
||||
u32 ctrl, num_ctrls;
|
||||
|
||||
|
@ -375,22 +367,16 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
|
|||
dw_chained_msi_isr, pp);
|
||||
}
|
||||
|
||||
ret = dma_set_mask(dev, DMA_BIT_MASK(32));
|
||||
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");
|
||||
|
||||
pp->msi_page = alloc_page(GFP_DMA32);
|
||||
pp->msi_data = dma_map_page(dev, pp->msi_page, 0,
|
||||
PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
ret = dma_mapping_error(dev, pp->msi_data);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "Failed to map MSI data\n");
|
||||
__free_page(pp->msi_page);
|
||||
pp->msi_page = NULL;
|
||||
pp->msi_data = 0;
|
||||
msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
|
||||
GFP_KERNEL);
|
||||
if (!msi_vaddr) {
|
||||
dev_err(dev, "Failed to alloc and map MSI data\n");
|
||||
dw_pcie_free_msi(pp);
|
||||
|
||||
return ret;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -243,7 +243,6 @@ struct dw_pcie_rp {
|
|||
struct irq_domain *irq_domain;
|
||||
struct irq_domain *msi_domain;
|
||||
dma_addr_t msi_data;
|
||||
struct page *msi_page;
|
||||
struct irq_chip *msi_irq_chip;
|
||||
u32 num_vectors;
|
||||
u32 irq_mask[MAX_MSI_CTRLS];
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/of_address.h>
|
||||
|
@ -366,12 +367,11 @@ static int kirin_pcie_get_gpio_enable(struct kirin_pcie *pcie,
|
|||
struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
char name[32];
|
||||
int ret, i;
|
||||
|
||||
/* This is an optional property */
|
||||
ret = of_gpio_named_count(np, "hisilicon,clken-gpios");
|
||||
ret = gpiod_count(dev, "hisilicon,clken");
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ struct imx8_pcie_phy {
|
|||
bool clkreq_unused;
|
||||
};
|
||||
|
||||
static int imx8_pcie_phy_init(struct phy *phy)
|
||||
static int imx8_pcie_phy_power_on(struct phy *phy)
|
||||
{
|
||||
int ret;
|
||||
u32 val, pad_mode;
|
||||
|
@ -137,14 +137,14 @@ static int imx8_pcie_phy_init(struct phy *phy)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int imx8_pcie_phy_power_on(struct phy *phy)
|
||||
static int imx8_pcie_phy_init(struct phy *phy)
|
||||
{
|
||||
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
||||
|
||||
return clk_prepare_enable(imx8_phy->clk);
|
||||
}
|
||||
|
||||
static int imx8_pcie_phy_power_off(struct phy *phy)
|
||||
static int imx8_pcie_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
|
||||
|
||||
|
@ -155,8 +155,8 @@ static int imx8_pcie_phy_power_off(struct phy *phy)
|
|||
|
||||
static const struct phy_ops imx8_pcie_phy_ops = {
|
||||
.init = imx8_pcie_phy_init,
|
||||
.exit = imx8_pcie_phy_exit,
|
||||
.power_on = imx8_pcie_phy_power_on,
|
||||
.power_off = imx8_pcie_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue