Merge branches 'pci/host', 'pci/host-designware', 'pci/host-hisi', 'pci/host-qcom' and 'pci/host-rcar' into next
* pci/host: PCI: host: Add of_pci_get_host_bridge_resources() stub PCI: host: Mark PCIe/PCI (MSI) IRQ cascade handlers as IRQF_NO_THREAD * pci/host-designware: PCI: designware: Make config accessor override checking symmetric PCI: designware: Simplify control flow * pci/host-hisi: PCI: hisi: Add support for HiSilicon Hip06 PCIe host controllers * pci/host-qcom: ARM: dts: ifc6410: enable PCIe DT node for this board ARM: dts: apq8064: add PCIe devicetree node PCI: qcom: Add Qualcomm PCIe controller driver PCI: qcom: Document PCIe devicetree bindings PCI: designware: Ensure ATU is enabled before IO/conf space accesses * pci/host-rcar: PCI: rcar: Add Gen2 PHY setup to pcie-rcar PCI: rcar: Add runtime PM support to pcie-rcar PCI: rcar: Remove unused pci_sys_data struct from pcie-rcar
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define DRV_NAME "rcar-pcie"
|
||||
@@ -94,6 +95,11 @@
|
||||
#define H1_PCIEPHYDOUTR 0x040014
|
||||
#define H1_PCIEPHYSR 0x040018
|
||||
|
||||
/* R-Car Gen2 PHY */
|
||||
#define GEN2_PCIEPHYADDR 0x780
|
||||
#define GEN2_PCIEPHYDATA 0x784
|
||||
#define GEN2_PCIEPHYCTRL 0x78c
|
||||
|
||||
#define INT_PCI_MSI_NR 32
|
||||
|
||||
#define RCONF(x) (PCICONF(0)+(x))
|
||||
@@ -124,16 +130,7 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip)
|
||||
}
|
||||
|
||||
/* Structure representing the PCIe interface */
|
||||
/*
|
||||
* ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
|
||||
* sysdata. Add pci_sys_data as the first element in struct gen_pci so
|
||||
* that when we use a gen_pci pointer as sysdata, it is also a pointer to
|
||||
* a struct pci_sys_data.
|
||||
*/
|
||||
struct rcar_pcie {
|
||||
#ifdef CONFIG_ARM
|
||||
struct pci_sys_data sys;
|
||||
#endif
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
struct list_head resources;
|
||||
@@ -576,6 +573,26 @@ static int rcar_pcie_hw_init_h1(struct rcar_pcie *pcie)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int rcar_pcie_hw_init_gen2(struct rcar_pcie *pcie)
|
||||
{
|
||||
/*
|
||||
* These settings come from the R-Car Series, 2nd Generation User's
|
||||
* Manual, section 50.3.1 (2) Initialization of the physical layer.
|
||||
*/
|
||||
rcar_pci_write_reg(pcie, 0x000f0030, GEN2_PCIEPHYADDR);
|
||||
rcar_pci_write_reg(pcie, 0x00381203, GEN2_PCIEPHYDATA);
|
||||
rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
|
||||
rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
|
||||
|
||||
rcar_pci_write_reg(pcie, 0x000f0054, GEN2_PCIEPHYADDR);
|
||||
/* The following value is for DC connection, no termination resistor */
|
||||
rcar_pci_write_reg(pcie, 0x13802007, GEN2_PCIEPHYDATA);
|
||||
rcar_pci_write_reg(pcie, 0x00000001, GEN2_PCIEPHYCTRL);
|
||||
rcar_pci_write_reg(pcie, 0x00000006, GEN2_PCIEPHYCTRL);
|
||||
|
||||
return rcar_pcie_hw_init(pcie);
|
||||
}
|
||||
|
||||
static int rcar_msi_alloc(struct rcar_msi *chip)
|
||||
{
|
||||
int msi;
|
||||
@@ -718,14 +735,16 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
|
||||
|
||||
/* Two irqs are for MSI, but they are also used for non-MSI irqs */
|
||||
err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
|
||||
IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
rcar_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
|
||||
IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
rcar_msi_irq_chip.name, pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
|
||||
goto err;
|
||||
@@ -915,9 +934,9 @@ static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie *pcie,
|
||||
|
||||
static const struct of_device_id rcar_pcie_of_match[] = {
|
||||
{ .compatible = "renesas,pcie-r8a7779", .data = rcar_pcie_hw_init_h1 },
|
||||
{ .compatible = "renesas,pcie-rcar-gen2", .data = rcar_pcie_hw_init },
|
||||
{ .compatible = "renesas,pcie-r8a7790", .data = rcar_pcie_hw_init },
|
||||
{ .compatible = "renesas,pcie-r8a7791", .data = rcar_pcie_hw_init },
|
||||
{ .compatible = "renesas,pcie-rcar-gen2", .data = rcar_pcie_hw_init_gen2 },
|
||||
{ .compatible = "renesas,pcie-r8a7790", .data = rcar_pcie_hw_init_gen2 },
|
||||
{ .compatible = "renesas,pcie-r8a7791", .data = rcar_pcie_hw_init_gen2 },
|
||||
{ .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init },
|
||||
{},
|
||||
};
|
||||
@@ -1003,32 +1022,51 @@ static int rcar_pcie_probe(struct platform_device *pdev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
of_id = of_match_device(rcar_pcie_of_match, pcie->dev);
|
||||
if (!of_id || !of_id->data)
|
||||
return -EINVAL;
|
||||
hw_init_fn = of_id->data;
|
||||
|
||||
pm_runtime_enable(pcie->dev);
|
||||
err = pm_runtime_get_sync(pcie->dev);
|
||||
if (err < 0) {
|
||||
dev_err(pcie->dev, "pm_runtime_get_sync failed\n");
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
/* Failure to get a link might just be that no cards are inserted */
|
||||
err = hw_init_fn(pcie);
|
||||
if (err) {
|
||||
dev_info(&pdev->dev, "PCIe link down\n");
|
||||
err = 0;
|
||||
goto err_pm_put;
|
||||
}
|
||||
|
||||
data = rcar_pci_read_reg(pcie, MACSR);
|
||||
dev_info(&pdev->dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
|
||||
|
||||
if (IS_ENABLED(CONFIG_PCI_MSI)) {
|
||||
err = rcar_pcie_enable_msi(pcie);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to enable MSI support: %d\n",
|
||||
err);
|
||||
return err;
|
||||
goto err_pm_put;
|
||||
}
|
||||
}
|
||||
|
||||
of_id = of_match_device(rcar_pcie_of_match, pcie->dev);
|
||||
if (!of_id || !of_id->data)
|
||||
return -EINVAL;
|
||||
hw_init_fn = of_id->data;
|
||||
err = rcar_pcie_enable(pcie);
|
||||
if (err)
|
||||
goto err_pm_put;
|
||||
|
||||
/* Failure to get a link might just be that no cards are inserted */
|
||||
err = hw_init_fn(pcie);
|
||||
if (err) {
|
||||
dev_info(&pdev->dev, "PCIe link down\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
data = rcar_pci_read_reg(pcie, MACSR);
|
||||
dev_info(&pdev->dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
|
||||
err_pm_put:
|
||||
pm_runtime_put(pcie->dev);
|
||||
|
||||
return rcar_pcie_enable(pcie);
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(pcie->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct platform_driver rcar_pcie_driver = {
|
||||
|
Reference in New Issue
Block a user