mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-23 22:38:20 -04:00
Merge branch 'pci/controller/dwc-intel-gw'
- Enable clock before PHY init for correct ordering (Florian Eckert) - Add .start_link() callback so the driver works again (Florian Eckert) - Stop overwriting the ATU base address discovered by dw_pcie_get_resources() (Florian Eckert) - Add DT 'atu' region since this is hardware-specific, and fall back to driver default if lacking (Florian Eckert) * pci/controller/dwc-intel-gw: dt-bindings: PCI: intel,lgm-pcie: Add 'atu' resource PCI: intel-gw: Fix ATU base address setup and add optional DT 'atu' region PCI: intel-gw: Add .start_link() callback PCI: intel-gw: Enable clock before PHY init PCI: intel-gw: Move interrupt enable to own function PCI: intel-gw: Remove unused PCIE_APP_INTX_OFST definition
This commit is contained in:
@@ -27,16 +27,20 @@ properties:
|
||||
- const: snps,dw-pcie
|
||||
|
||||
reg:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: Controller control and status registers.
|
||||
- description: PCIe configuration registers.
|
||||
- description: Controller application registers.
|
||||
- description: Internal Address Translation Unit (iATU) registers.
|
||||
|
||||
reg-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: dbi
|
||||
- const: config
|
||||
- const: app
|
||||
- const: atu
|
||||
|
||||
ranges:
|
||||
maxItems: 1
|
||||
@@ -95,8 +99,9 @@ examples:
|
||||
#size-cells = <2>;
|
||||
reg = <0xd0e00000 0x1000>,
|
||||
<0xd2000000 0x800000>,
|
||||
<0xd0a41000 0x1000>;
|
||||
reg-names = "dbi", "config", "app";
|
||||
<0xd0a41000 0x1000>,
|
||||
<0xd0ec0000 0x1000>;
|
||||
reg-names = "dbi", "config", "app", "atu";
|
||||
linux,pci-domain = <0>;
|
||||
max-link-speed = <4>;
|
||||
bus-range = <0x00 0x08>;
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#define PCIE_APP_IRN_INTD BIT(16)
|
||||
#define PCIE_APP_IRN_MSG_LTR BIT(18)
|
||||
#define PCIE_APP_IRN_SYS_ERR_RC BIT(29)
|
||||
#define PCIE_APP_INTX_OFST 12
|
||||
|
||||
#define PCIE_APP_IRN_INT \
|
||||
(PCIE_APP_IRN_AER_REPORT | PCIE_APP_IRN_PME | \
|
||||
@@ -196,6 +195,13 @@ static void intel_pcie_device_rst_deassert(struct intel_pcie *pcie)
|
||||
gpiod_set_value_cansleep(pcie->reset_gpio, 0);
|
||||
}
|
||||
|
||||
static void intel_pcie_core_irq_enable(struct intel_pcie *pcie)
|
||||
{
|
||||
pcie_app_wr(pcie, PCIE_APP_IRNEN, 0);
|
||||
pcie_app_wr(pcie, PCIE_APP_IRNCR, PCIE_APP_IRN_INT);
|
||||
pcie_app_wr(pcie, PCIE_APP_IRNEN, PCIE_APP_IRN_INT);
|
||||
}
|
||||
|
||||
static void intel_pcie_core_irq_disable(struct intel_pcie *pcie)
|
||||
{
|
||||
pcie_app_wr(pcie, PCIE_APP_IRNEN, 0);
|
||||
@@ -278,6 +284,16 @@ static void intel_pcie_turn_off(struct intel_pcie *pcie)
|
||||
pcie_rc_cfg_wr_mask(pcie, PCI_COMMAND, PCI_COMMAND_MEMORY, 0);
|
||||
}
|
||||
|
||||
static int intel_pcie_start_link(struct dw_pcie *pci)
|
||||
{
|
||||
struct intel_pcie *pcie = dev_get_drvdata(pci->dev);
|
||||
|
||||
intel_pcie_device_rst_deassert(pcie);
|
||||
intel_pcie_ltssm_enable(pcie);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_pcie_host_setup(struct intel_pcie *pcie)
|
||||
{
|
||||
int ret;
|
||||
@@ -285,49 +301,33 @@ static int intel_pcie_host_setup(struct intel_pcie *pcie)
|
||||
|
||||
intel_pcie_core_rst_assert(pcie);
|
||||
intel_pcie_device_rst_assert(pcie);
|
||||
|
||||
ret = phy_init(pcie->phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_pcie_core_rst_deassert(pcie);
|
||||
|
||||
/* Controller clock must be provided earlier than PHY */
|
||||
ret = clk_prepare_enable(pcie->core_clk);
|
||||
if (ret) {
|
||||
dev_err(pcie->pci.dev, "Core clock enable failed: %d\n", ret);
|
||||
goto clk_err;
|
||||
}
|
||||
|
||||
pci->atu_base = pci->dbi_base + 0xC0000;
|
||||
ret = phy_init(pcie->phy);
|
||||
if (ret)
|
||||
goto phy_err;
|
||||
|
||||
intel_pcie_ltssm_disable(pcie);
|
||||
intel_pcie_link_setup(pcie);
|
||||
intel_pcie_init_n_fts(pci);
|
||||
|
||||
ret = dw_pcie_setup_rc(&pci->pp);
|
||||
if (ret)
|
||||
goto app_init_err;
|
||||
|
||||
dw_pcie_upconfig_setup(pci);
|
||||
|
||||
intel_pcie_device_rst_deassert(pcie);
|
||||
intel_pcie_ltssm_enable(pcie);
|
||||
|
||||
ret = dw_pcie_wait_for_link(pci);
|
||||
if (ret)
|
||||
goto app_init_err;
|
||||
|
||||
/* Enable integrated interrupts */
|
||||
pcie_app_wr_mask(pcie, PCIE_APP_IRNEN, PCIE_APP_IRN_INT,
|
||||
PCIE_APP_IRN_INT);
|
||||
intel_pcie_core_irq_enable(pcie);
|
||||
|
||||
return 0;
|
||||
|
||||
app_init_err:
|
||||
phy_err:
|
||||
clk_disable_unprepare(pcie->core_clk);
|
||||
clk_err:
|
||||
intel_pcie_core_rst_assert(pcie);
|
||||
phy_exit(pcie->phy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -381,6 +381,7 @@ static int intel_pcie_rc_init(struct dw_pcie_rp *pp)
|
||||
}
|
||||
|
||||
static const struct dw_pcie_ops intel_pcie_ops = {
|
||||
.start_link = intel_pcie_start_link,
|
||||
};
|
||||
|
||||
static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
|
||||
@@ -392,6 +393,7 @@ static int intel_pcie_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct intel_pcie *pcie;
|
||||
struct dw_pcie_rp *pp;
|
||||
struct resource *res;
|
||||
struct dw_pcie *pci;
|
||||
int ret;
|
||||
|
||||
@@ -416,6 +418,32 @@ static int intel_pcie_probe(struct platform_device *pdev)
|
||||
pci->ops = &intel_pcie_ops;
|
||||
pp->ops = &intel_pcie_dw_ops;
|
||||
|
||||
/*
|
||||
* If the 'atu' region is not available in the devicetree, use the
|
||||
* default offset from DBI region for backwards compatibility. The
|
||||
* 'atu' region should always be specified in the devicetree, as
|
||||
* this is a hardware-specific address that should not be defined
|
||||
* in the driver.
|
||||
*/
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
|
||||
if (!res) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
|
||||
pci->dbi_base = devm_pci_remap_cfg_resource(pci->dev, res);
|
||||
if (IS_ERR(pci->dbi_base))
|
||||
return PTR_ERR(pci->dbi_base);
|
||||
|
||||
pci->dbi_phys_addr = res->start;
|
||||
pci->atu_base = devm_ioremap(dev, res->start + 0xC0000, SZ_4K);
|
||||
if (!pci->atu_base) {
|
||||
dev_err(dev, "failed to remap ATU space\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pci->atu_size = SZ_4K;
|
||||
pci->atu_phys_addr = res->start + 0xC0000;
|
||||
dev_warn(dev, "ATU region not specified in DT. Using default offset\n");
|
||||
}
|
||||
|
||||
ret = dw_pcie_host_init(pp);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot initialize host\n");
|
||||
|
||||
Reference in New Issue
Block a user