mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'pci-v6.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull pci updates from Bjorn Helgaas:
"Resource management:
- Distribute spare resources to unconfigured hotplug bridges at
boot-time (not just when hot-adding such a bridge), which makes
hot-adding devices to docks work better.
- Revert to a BAR assignment inherited from firmware only when the
address is actually reachable via any upstream bridges, which fixes
some cases where firmware doesn't configure all devices.
- Add a sysfs interface to resize BARs so this can be done before
assigning devices to a VM through VFIO.
Power management:
- Disable Precision Time Management for all devices on suspend to
enable lower-power PM state. We previously did this just for Root
Ports, which isn't enough because downstream devices can still
generate PTM messages, which cause errors if it's disabled in the
Root Port.
- Save and restore the ASPM L1 PM Substates configuration for
suspend/ resume. Previously this configuration was lost, so L1.x
states likely stopped working after resume.
- Check whether the L1 PM Substates Capability exists. If it didn't
exist, we previously read junk and tried to configure L1 Substates
based on that.
- Fix the LTR_L1.2_THRESHOLD computation, which previously set a
threshold for entering L1.2 that was too low in some cases.
- Reduce the delay after transitions to or from D3cold by using
usleep_range() rather than msleep(), which often slept for ~19ms
instead of the 10ms normally required. The spec says 10ms is
enough, but it's possible we could trip over devices that need a
little more.
Error handling:
- Work around a BIOS bug that caused Intel Root Ports to advertise a
Root Port Programmed I/O (RP PIO) log size of zero, which caused
annoying warnings and prevented the kernel from dumping log
registers for DPC errors.
Qualcomm PCIe controller driver:
- Add support for SC8280XP and SA8540P host controllers and SM8450
endpoint controller.
- Disable Master AXI clock on endpoint controllers to save power when
link is idle or in L1.x.
- Expose link state transition counts via debugfs to help debug
issues with low-power states.
- Add auto-loading module support.
Synopsys DesignWare PCIe controller driver:
- Remove a dependency on ZONE_DMA32 by allocating the MSI target page
differently. There's more work to do related to eDMA controllers,
so it's not completely settled"
* tag 'pci-v6.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (71 commits)
PCI: qcom-ep: Check platform_get_resource_byname() return value
PCI: qcom-ep: Add support for SM8450 SoC
dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC
dt-bindings: PCI: qcom-ep: Define clocks per platform
PCI: qcom-ep: Make PERST separation optional
dt-bindings: PCI: qcom-ep: Make PERST separation optional
PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic
PCI: Expose PCIe Resizable BAR support via sysfs
PCI/ASPM: Correct LTR_L1.2_THRESHOLD computation
PCI/ASPM: Ignore L1 PM Substates if device lacks capability
PCI/ASPM: Factor out L1 PM Substates configuration
PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS
PCI: qcom-ep: Expose link transition counts via debugfs
PCI: qcom-ep: Disable IRQs during driver remove
PCI/ASPM: Save L1 PM Substates Capability for suspend/resume
PCI/ASPM: Refactor L1 PM Substates Control Register programming
PCI: qcom-ep: Make use of the cached dev pointer
PCI: qcom-ep: Rely on the clocks supplied by devicetree
PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure
phy: freescale: imx8m-pcie: Fix the wrong order of phy_init() and phy_power_on()
...
This commit is contained in:
@@ -457,3 +457,36 @@ Description:
|
||||
|
||||
The file is writable if the PF is bound to a driver that
|
||||
implements ->sriov_set_msix_vec_count().
|
||||
|
||||
What: /sys/bus/pci/devices/.../resourceN_resize
|
||||
Date: September 2022
|
||||
Contact: Alex Williamson <alex.williamson@redhat.com>
|
||||
Description:
|
||||
These files provide an interface to PCIe Resizable BAR support.
|
||||
A file is created for each BAR resource (N) supported by the
|
||||
PCIe Resizable BAR extended capability of the device. Reading
|
||||
each file exposes the bitmap of available resource sizes:
|
||||
|
||||
# cat resource1_resize
|
||||
00000000000001c0
|
||||
|
||||
The bitmap represents supported resource sizes for the BAR,
|
||||
where bit0 = 1MB, bit1 = 2MB, bit2 = 4MB, etc. In the above
|
||||
example the device supports 64MB, 128MB, and 256MB BAR sizes.
|
||||
|
||||
When writing the file, the user provides the bit position of
|
||||
the desired resource size, for example:
|
||||
|
||||
# echo 7 > resource1_resize
|
||||
|
||||
This indicates to set the size value corresponding to bit 7,
|
||||
128MB. The resulting size is 2 ^ (bit# + 20). This definition
|
||||
matches the PCIe specification of this capability.
|
||||
|
||||
In order to make use of resource resizing, all PCI drivers must
|
||||
be unbound from the device and peer devices under the same
|
||||
parent bridge may need to be soft removed. In the case of
|
||||
VGA devices, writing a resize value will remove low level
|
||||
console drivers from the device. Raw users of pci-sysfs
|
||||
resourceN attributes must be terminated prior to resizing.
|
||||
Success of the resizing operation is not guaranteed.
|
||||
|
||||
@@ -48,7 +48,13 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8192-pcie
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8188-pcie
|
||||
- mediatek,mt8195-pcie
|
||||
- const: mediatek,mt8192-pcie
|
||||
- const: mediatek,mt8192-pcie
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -84,7 +90,9 @@ properties:
|
||||
- const: tl_96m
|
||||
- const: tl_32k
|
||||
- const: peri_26m
|
||||
- const: top_133m
|
||||
- enum:
|
||||
- top_133m # for MT8192
|
||||
- peri_mem # for MT8188/MT8195
|
||||
|
||||
assigned-clocks:
|
||||
maxItems: 1
|
||||
@@ -126,6 +134,7 @@ required:
|
||||
- interrupts
|
||||
- ranges
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#interrupt-cells'
|
||||
- interrupt-controller
|
||||
|
||||
|
||||
@@ -25,6 +25,33 @@ properties:
|
||||
- const: cfg
|
||||
- const: apb
|
||||
|
||||
clocks:
|
||||
description:
|
||||
Fabric Interface Controllers, FICs, are the interface between the FPGA
|
||||
fabric and the core complex on PolarFire SoC. The FICs require two clocks,
|
||||
one from each side of the interface. The "FIC clocks" described by this
|
||||
property are on the core complex side & communication through a FIC is not
|
||||
possible unless it's corresponding clock is enabled. A clock must be
|
||||
enabled for each of the interfaces the root port is connected through.
|
||||
This could in theory be all 4 interfaces, one interface or any combination
|
||||
in between.
|
||||
minItems: 1
|
||||
items:
|
||||
- description: FIC0's clock
|
||||
- description: FIC1's clock
|
||||
- description: FIC2's clock
|
||||
- description: FIC3's clock
|
||||
|
||||
clock-names:
|
||||
description:
|
||||
As any FIC connection combination is possible, the names should match the
|
||||
order in the clocks property and take the form "ficN" where N is a number
|
||||
0-3
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
pattern: '^fic[0-3]$'
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
items:
|
||||
@@ -40,6 +67,10 @@ properties:
|
||||
ranges:
|
||||
maxItems: 1
|
||||
|
||||
dma-ranges:
|
||||
minItems: 1
|
||||
maxItems: 6
|
||||
|
||||
msi-controller:
|
||||
description: Identifies the node as an MSI controller.
|
||||
|
||||
|
||||
@@ -9,12 +9,11 @@ title: Qualcomm PCIe Endpoint Controller binding
|
||||
maintainers:
|
||||
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: "pci-ep.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sdx55-pcie-ep
|
||||
enum:
|
||||
- qcom,sdx55-pcie-ep
|
||||
- qcom,sm8450-pcie-ep
|
||||
|
||||
reg:
|
||||
items:
|
||||
@@ -35,24 +34,12 @@ properties:
|
||||
- const: mmio
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: PCIe Auxiliary clock
|
||||
- description: PCIe CFG AHB clock
|
||||
- description: PCIe Master AXI clock
|
||||
- description: PCIe Slave AXI clock
|
||||
- description: PCIe Slave Q2A AXI clock
|
||||
- description: PCIe Sleep clock
|
||||
- description: PCIe Reference clock
|
||||
minItems: 7
|
||||
maxItems: 8
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg
|
||||
- const: bus_master
|
||||
- const: bus_slave
|
||||
- const: slave_q2a
|
||||
- const: sleep
|
||||
- const: ref
|
||||
minItems: 7
|
||||
maxItems: 8
|
||||
|
||||
qcom,perst-regs:
|
||||
description: Reference to a syscon representing TCSR followed by the two
|
||||
@@ -105,7 +92,6 @@ required:
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- qcom,perst-regs
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- reset-gpios
|
||||
@@ -113,6 +99,64 @@ required:
|
||||
- reset-names
|
||||
- power-domains
|
||||
|
||||
allOf:
|
||||
- $ref: pci-ep.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sdx55-pcie-ep
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: PCIe Auxiliary clock
|
||||
- description: PCIe CFG AHB clock
|
||||
- description: PCIe Master AXI clock
|
||||
- description: PCIe Slave AXI clock
|
||||
- description: PCIe Slave Q2A AXI clock
|
||||
- description: PCIe Sleep clock
|
||||
- description: PCIe Reference clock
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg
|
||||
- const: bus_master
|
||||
- const: bus_slave
|
||||
- const: slave_q2a
|
||||
- const: sleep
|
||||
- const: ref
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8450-pcie-ep
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: PCIe Auxiliary clock
|
||||
- description: PCIe CFG AHB clock
|
||||
- description: PCIe Master AXI clock
|
||||
- description: PCIe Slave AXI clock
|
||||
- description: PCIe Slave Q2A AXI clock
|
||||
- description: PCIe Reference clock
|
||||
- description: PCIe DDRSS SF TBU clock
|
||||
- description: PCIe AGGRE NOC AXI clock
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg
|
||||
- const: bus_master
|
||||
- const: bus_slave
|
||||
- const: slave_q2a
|
||||
- const: ref
|
||||
- const: ddrss_sf_tbu
|
||||
- const: aggre_noc_axi
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -25,8 +25,10 @@ properties:
|
||||
- qcom,pcie-ipq4019
|
||||
- qcom,pcie-ipq8074
|
||||
- qcom,pcie-qcs404
|
||||
- qcom,pcie-sa8540p
|
||||
- qcom,pcie-sc7280
|
||||
- qcom,pcie-sc8180x
|
||||
- qcom,pcie-sc8280xp
|
||||
- qcom,pcie-sdm845
|
||||
- qcom,pcie-sm8150
|
||||
- qcom,pcie-sm8250
|
||||
@@ -181,6 +183,7 @@ allOf:
|
||||
enum:
|
||||
- qcom,pcie-sc7280
|
||||
- qcom,pcie-sc8180x
|
||||
- qcom,pcie-sc8280xp
|
||||
- qcom,pcie-sm8250
|
||||
- qcom,pcie-sm8450-pcie0
|
||||
- qcom,pcie-sm8450-pcie1
|
||||
@@ -598,6 +601,36 @@ allOf:
|
||||
items:
|
||||
- const: pci # PCIe core reset
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pcie-sa8540p
|
||||
- qcom,pcie-sc8280xp
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 8
|
||||
maxItems: 9
|
||||
clock-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: aux # Auxiliary clock
|
||||
- const: cfg # Configuration clock
|
||||
- const: bus_master # Master AXI clock
|
||||
- const: bus_slave # Slave AXI clock
|
||||
- const: slave_q2a # Slave Q2A clock
|
||||
- const: ddrss_sf_tbu # PCIe SF TBU clock
|
||||
- const: noc_aggr_4 # NoC aggregate 4 clock
|
||||
- const: noc_aggr_south_sf # NoC aggregate South SF clock
|
||||
- const: cnoc_qx # Configuration NoC QX clock
|
||||
resets:
|
||||
maxItems: 1
|
||||
reset-names:
|
||||
items:
|
||||
- const: pci # PCIe core reset
|
||||
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
@@ -626,8 +659,6 @@ allOf:
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
# Newer chipsets support either 1 or 8 MSI vectors
|
||||
# On older chipsets it's always 1 MSI vector
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@@ -662,7 +693,40 @@ allOf:
|
||||
- const: msi5
|
||||
- const: msi6
|
||||
- const: msi7
|
||||
else:
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pcie-sc8280xp
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: msi0
|
||||
- const: msi1
|
||||
- const: msi2
|
||||
- const: msi3
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,pcie-apq8064
|
||||
- qcom,pcie-apq8084
|
||||
- qcom,pcie-ipq4019
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8064
|
||||
- qcom,pcie-ipq8064-v2
|
||||
- qcom,pcie-ipq8074
|
||||
- qcom,pcie-qcs404
|
||||
- qcom,pcie-sa8540p
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
@@ -51,6 +51,12 @@ properties:
|
||||
description: A phandle to the PCIe power up reset line.
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: pcie_aux
|
||||
|
||||
pwren-gpios:
|
||||
description: Should specify the GPIO for controlling the PCI bus device power on.
|
||||
maxItems: 1
|
||||
@@ -66,6 +72,7 @@ required:
|
||||
- interrupt-map-mask
|
||||
- interrupt-map
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- pwren-gpios
|
||||
- reset-gpios
|
||||
@@ -104,6 +111,7 @@ examples:
|
||||
<0x0 0x0 0x0 0x2 &plic0 58>,
|
||||
<0x0 0x0 0x0 0x3 &plic0 59>,
|
||||
<0x0 0x0 0x0 0x4 &plic0 60>;
|
||||
clock-names = "pcie_aux";
|
||||
clocks = <&prci FU740_PRCI_CLK_PCIE_AUX>;
|
||||
resets = <&prci 4>;
|
||||
pwren-gpios = <&gpio 5 0>;
|
||||
|
||||
@@ -15865,6 +15865,7 @@ PCI ENDPOINT SUBSYSTEM
|
||||
M: Kishon Vijay Abraham I <kishon@ti.com>
|
||||
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
R: Krzysztof Wilczyński <kw@linux.com>
|
||||
R: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
Q: https://patchwork.kernel.org/project/linux-pci/list/
|
||||
@@ -15878,8 +15879,8 @@ F: drivers/pci/endpoint/
|
||||
F: tools/pci/
|
||||
|
||||
PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
|
||||
M: Russell Currey <ruscur@russell.cc>
|
||||
M: Oliver O'Halloran <oohall@gmail.com>
|
||||
M: Mahesh J Salgaonkar <mahesh@linux.ibm.com>
|
||||
R: Oliver O'Halloran <oohall@gmail.com>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Supported
|
||||
F: Documentation/PCI/pci-error-recovery.rst
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
@@ -26,6 +27,7 @@
|
||||
#define PARF_SYS_CTRL 0x00
|
||||
#define PARF_DB_CTRL 0x10
|
||||
#define PARF_PM_CTRL 0x20
|
||||
#define PARF_MHI_CLOCK_RESET_CTRL 0x174
|
||||
#define PARF_MHI_BASE_ADDR_LOWER 0x178
|
||||
#define PARF_MHI_BASE_ADDR_UPPER 0x17c
|
||||
#define PARF_DEBUG_INT_EN 0x190
|
||||
@@ -45,6 +47,11 @@
|
||||
#define PARF_ATU_BASE_ADDR 0x634
|
||||
#define PARF_ATU_BASE_ADDR_HI 0x638
|
||||
#define PARF_SRIS_MODE 0x644
|
||||
#define PARF_DEBUG_CNT_PM_LINKST_IN_L2 0xc04
|
||||
#define PARF_DEBUG_CNT_PM_LINKST_IN_L1 0xc0c
|
||||
#define PARF_DEBUG_CNT_PM_LINKST_IN_L0S 0xc10
|
||||
#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1 0xc84
|
||||
#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2 0xc88
|
||||
#define PARF_DEVICE_TYPE 0x1000
|
||||
#define PARF_BDF_TO_SID_CFG 0x2c00
|
||||
|
||||
@@ -83,6 +90,9 @@
|
||||
#define PARF_PM_CTRL_READY_ENTR_L23 BIT(2)
|
||||
#define PARF_PM_CTRL_REQ_NOT_ENTR_L1 BIT(5)
|
||||
|
||||
/* PARF_MHI_CLOCK_RESET_CTRL fields */
|
||||
#define PARF_MSTR_AXI_CLK_EN BIT(1)
|
||||
|
||||
/* PARF_AXI_MSTR_RD_HALT_NO_WRITES register fields */
|
||||
#define PARF_AXI_MSTR_RD_HALT_NO_WRITE_EN BIT(0)
|
||||
|
||||
@@ -95,6 +105,7 @@
|
||||
/* PARF_SYS_CTRL register fields */
|
||||
#define PARF_SYS_CTRL_AUX_PWR_DET BIT(4)
|
||||
#define PARF_SYS_CTRL_CORE_CLK_CGC_DIS BIT(6)
|
||||
#define PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS BIT(10)
|
||||
#define PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE BIT(11)
|
||||
|
||||
/* PARF_DB_CTRL register fields */
|
||||
@@ -130,21 +141,33 @@ enum qcom_pcie_ep_link_status {
|
||||
QCOM_PCIE_EP_LINK_DOWN,
|
||||
};
|
||||
|
||||
static struct clk_bulk_data qcom_pcie_ep_clks[] = {
|
||||
{ .id = "cfg" },
|
||||
{ .id = "aux" },
|
||||
{ .id = "bus_master" },
|
||||
{ .id = "bus_slave" },
|
||||
{ .id = "ref" },
|
||||
{ .id = "sleep" },
|
||||
{ .id = "slave_q2a" },
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller
|
||||
* @pci: Designware PCIe controller struct
|
||||
* @parf: Qualcomm PCIe specific PARF register base
|
||||
* @elbi: Designware PCIe specific ELBI register base
|
||||
* @mmio: MMIO register base
|
||||
* @perst_map: PERST regmap
|
||||
* @mmio_res: MMIO region resource
|
||||
* @core_reset: PCIe Endpoint core reset
|
||||
* @reset: PERST# GPIO
|
||||
* @wake: WAKE# GPIO
|
||||
* @phy: PHY controller block
|
||||
* @debugfs: PCIe Endpoint Debugfs directory
|
||||
* @clks: PCIe clocks
|
||||
* @num_clks: PCIe clocks count
|
||||
* @perst_en: Flag for PERST enable
|
||||
* @perst_sep_en: Flag for PERST separation enable
|
||||
* @link_status: PCIe Link status
|
||||
* @global_irq: Qualcomm PCIe specific Global IRQ
|
||||
* @perst_irq: PERST# IRQ
|
||||
*/
|
||||
struct qcom_pcie_ep {
|
||||
struct dw_pcie pci;
|
||||
|
||||
void __iomem *parf;
|
||||
void __iomem *elbi;
|
||||
void __iomem *mmio;
|
||||
struct regmap *perst_map;
|
||||
struct resource *mmio_res;
|
||||
|
||||
@@ -152,6 +175,10 @@ struct qcom_pcie_ep {
|
||||
struct gpio_desc *reset;
|
||||
struct gpio_desc *wake;
|
||||
struct phy *phy;
|
||||
struct dentry *debugfs;
|
||||
|
||||
struct clk_bulk_data *clks;
|
||||
int num_clks;
|
||||
|
||||
u32 perst_en;
|
||||
u32 perst_sep_en;
|
||||
@@ -193,8 +220,10 @@ static int qcom_pcie_ep_core_reset(struct qcom_pcie_ep *pcie_ep)
|
||||
*/
|
||||
static void qcom_pcie_ep_configure_tcsr(struct qcom_pcie_ep *pcie_ep)
|
||||
{
|
||||
regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0);
|
||||
regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0);
|
||||
if (pcie_ep->perst_map) {
|
||||
regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0);
|
||||
regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int qcom_pcie_dw_link_up(struct dw_pcie *pci)
|
||||
@@ -227,8 +256,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_bulk_prepare_enable(ARRAY_SIZE(qcom_pcie_ep_clks),
|
||||
qcom_pcie_ep_clks);
|
||||
ret = clk_bulk_prepare_enable(pcie_ep->num_clks, pcie_ep->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -249,8 +277,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep)
|
||||
err_phy_exit:
|
||||
phy_exit(pcie_ep->phy);
|
||||
err_disable_clk:
|
||||
clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks),
|
||||
qcom_pcie_ep_clks);
|
||||
clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -259,8 +286,7 @@ static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep)
|
||||
{
|
||||
phy_power_off(pcie_ep->phy);
|
||||
phy_exit(pcie_ep->phy);
|
||||
clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks),
|
||||
qcom_pcie_ep_clks);
|
||||
clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks);
|
||||
}
|
||||
|
||||
static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
|
||||
@@ -318,8 +344,14 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
|
||||
val &= ~PARF_Q2A_FLUSH_EN;
|
||||
writel_relaxed(val, pcie_ep->parf + PARF_Q2A_FLUSH);
|
||||
|
||||
/* Disable DBI Wakeup, core clock CGC and enable AUX power */
|
||||
/*
|
||||
* Disable Master AXI clock during idle. Do not allow DBI access
|
||||
* to take the core out of L1. Disable core clock gating that
|
||||
* gates PIPE clock from propagating to core clock. Report to the
|
||||
* host that Vaux is present.
|
||||
*/
|
||||
val = readl_relaxed(pcie_ep->parf + PARF_SYS_CTRL);
|
||||
val &= ~PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS;
|
||||
val |= PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE |
|
||||
PARF_SYS_CTRL_CORE_CLK_CGC_DIS |
|
||||
PARF_SYS_CTRL_AUX_PWR_DET;
|
||||
@@ -375,6 +407,11 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
|
||||
pcie_ep->parf + PARF_MHI_BASE_ADDR_LOWER);
|
||||
writel_relaxed(0, pcie_ep->parf + PARF_MHI_BASE_ADDR_UPPER);
|
||||
|
||||
/* Gate Master AXI clock to MHI bus during L1SS */
|
||||
val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
|
||||
val &= ~PARF_MSTR_AXI_CLK_EN;
|
||||
val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL);
|
||||
|
||||
dw_pcie_ep_init_notify(&pcie_ep->pci.ep);
|
||||
|
||||
/* Enable LTSSM */
|
||||
@@ -437,11 +474,19 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,
|
||||
|
||||
pcie_ep->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"mmio");
|
||||
if (!pcie_ep->mmio_res) {
|
||||
dev_err(dev, "Failed to get mmio resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pcie_ep->mmio = devm_pci_remap_cfg_resource(dev, pcie_ep->mmio_res);
|
||||
if (IS_ERR(pcie_ep->mmio))
|
||||
return PTR_ERR(pcie_ep->mmio);
|
||||
|
||||
syscon = of_parse_phandle(dev->of_node, "qcom,perst-regs", 0);
|
||||
if (!syscon) {
|
||||
dev_err(dev, "Failed to parse qcom,perst-regs\n");
|
||||
return -EINVAL;
|
||||
dev_dbg(dev, "PERST separation not available\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcie_ep->perst_map = syscon_node_to_regmap(syscon);
|
||||
@@ -474,14 +519,15 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
|
||||
|
||||
ret = qcom_pcie_ep_get_io_resources(pdev, pcie_ep);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to get io resources %d\n", ret);
|
||||
dev_err(dev, "Failed to get io resources %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_clk_bulk_get(dev, ARRAY_SIZE(qcom_pcie_ep_clks),
|
||||
qcom_pcie_ep_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
pcie_ep->num_clks = devm_clk_bulk_get_all(dev, &pcie_ep->clks);
|
||||
if (pcie_ep->num_clks < 0) {
|
||||
dev_err(dev, "Failed to get clocks\n");
|
||||
return pcie_ep->num_clks;
|
||||
}
|
||||
|
||||
pcie_ep->core_reset = devm_reset_control_get_exclusive(dev, "core");
|
||||
if (IS_ERR(pcie_ep->core_reset))
|
||||
@@ -495,7 +541,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev,
|
||||
if (IS_ERR(pcie_ep->wake))
|
||||
return PTR_ERR(pcie_ep->wake);
|
||||
|
||||
pcie_ep->phy = devm_phy_optional_get(&pdev->dev, "pciephy");
|
||||
pcie_ep->phy = devm_phy_optional_get(dev, "pciephy");
|
||||
if (IS_ERR(pcie_ep->phy))
|
||||
ret = PTR_ERR(pcie_ep->phy);
|
||||
|
||||
@@ -571,13 +617,13 @@ static irqreturn_t qcom_pcie_ep_perst_irq_thread(int irq, void *data)
|
||||
static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev,
|
||||
struct qcom_pcie_ep *pcie_ep)
|
||||
{
|
||||
int irq, ret;
|
||||
int ret;
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "global");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
pcie_ep->global_irq = platform_get_irq_byname(pdev, "global");
|
||||
if (pcie_ep->global_irq < 0)
|
||||
return pcie_ep->global_irq;
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
ret = devm_request_threaded_irq(&pdev->dev, pcie_ep->global_irq, NULL,
|
||||
qcom_pcie_ep_global_irq_thread,
|
||||
IRQF_ONESHOT,
|
||||
"global_irq", pcie_ep);
|
||||
@@ -594,7 +640,7 @@ static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev,
|
||||
"perst_irq", pcie_ep);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to request PERST IRQ\n");
|
||||
disable_irq(irq);
|
||||
disable_irq(pcie_ep->global_irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -617,6 +663,37 @@ static int qcom_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
|
||||
}
|
||||
}
|
||||
|
||||
static int qcom_pcie_ep_link_transition_count(struct seq_file *s, void *data)
|
||||
{
|
||||
struct qcom_pcie_ep *pcie_ep = (struct qcom_pcie_ep *)
|
||||
dev_get_drvdata(s->private);
|
||||
|
||||
seq_printf(s, "L0s transition count: %u\n",
|
||||
readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L0S));
|
||||
|
||||
seq_printf(s, "L1 transition count: %u\n",
|
||||
readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L1));
|
||||
|
||||
seq_printf(s, "L1.1 transition count: %u\n",
|
||||
readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1));
|
||||
|
||||
seq_printf(s, "L1.2 transition count: %u\n",
|
||||
readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2));
|
||||
|
||||
seq_printf(s, "L2 transition count: %u\n",
|
||||
readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep)
|
||||
{
|
||||
struct dw_pcie *pci = &pcie_ep->pci;
|
||||
|
||||
debugfs_create_devm_seqfile(pci->dev, "link_transition_count", pcie_ep->debugfs,
|
||||
qcom_pcie_ep_link_transition_count);
|
||||
}
|
||||
|
||||
static const struct pci_epc_features qcom_pcie_epc_features = {
|
||||
.linkup_notifier = true,
|
||||
.core_init_notifier = true,
|
||||
@@ -649,6 +726,7 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct qcom_pcie_ep *pcie_ep;
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
pcie_ep = devm_kzalloc(dev, sizeof(*pcie_ep), GFP_KERNEL);
|
||||
@@ -680,8 +758,21 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_disable_resources;
|
||||
|
||||
name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
|
||||
if (!name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_disable_irqs;
|
||||
}
|
||||
|
||||
pcie_ep->debugfs = debugfs_create_dir(name, NULL);
|
||||
qcom_pcie_ep_init_debugfs(pcie_ep);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_irqs:
|
||||
disable_irq(pcie_ep->global_irq);
|
||||
disable_irq(pcie_ep->perst_irq);
|
||||
|
||||
err_disable_resources:
|
||||
qcom_pcie_disable_resources(pcie_ep);
|
||||
|
||||
@@ -692,6 +783,11 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_pcie_ep *pcie_ep = platform_get_drvdata(pdev);
|
||||
|
||||
disable_irq(pcie_ep->global_irq);
|
||||
disable_irq(pcie_ep->perst_irq);
|
||||
|
||||
debugfs_remove_recursive(pcie_ep->debugfs);
|
||||
|
||||
if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED)
|
||||
return 0;
|
||||
|
||||
@@ -702,8 +798,10 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id qcom_pcie_ep_match[] = {
|
||||
{ .compatible = "qcom,sdx55-pcie-ep", },
|
||||
{ .compatible = "qcom,sm8450-pcie-ep", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_pcie_ep_match);
|
||||
|
||||
static struct platform_driver qcom_pcie_ep_driver = {
|
||||
.probe = qcom_pcie_ep_probe,
|
||||
|
||||
@@ -180,7 +180,7 @@ struct qcom_pcie_resources_2_3_3 {
|
||||
|
||||
/* 6 clocks typically, 7 for sm8250 */
|
||||
struct qcom_pcie_resources_2_7_0 {
|
||||
struct clk_bulk_data clks[9];
|
||||
struct clk_bulk_data clks[12];
|
||||
int num_clks;
|
||||
struct regulator_bulk_data supplies[2];
|
||||
struct reset_control *pci_reset;
|
||||
@@ -208,17 +208,12 @@ struct qcom_pcie_ops {
|
||||
int (*init)(struct qcom_pcie *pcie);
|
||||
int (*post_init)(struct qcom_pcie *pcie);
|
||||
void (*deinit)(struct qcom_pcie *pcie);
|
||||
void (*post_deinit)(struct qcom_pcie *pcie);
|
||||
void (*ltssm_enable)(struct qcom_pcie *pcie);
|
||||
int (*config_sid)(struct qcom_pcie *pcie);
|
||||
};
|
||||
|
||||
struct qcom_pcie_cfg {
|
||||
const struct qcom_pcie_ops *ops;
|
||||
unsigned int has_tbu_clk:1;
|
||||
unsigned int has_ddrss_sf_tbu_clk:1;
|
||||
unsigned int has_aggre0_clk:1;
|
||||
unsigned int has_aggre1_clk:1;
|
||||
};
|
||||
|
||||
struct qcom_pcie {
|
||||
@@ -1175,6 +1170,7 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
|
||||
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
|
||||
struct dw_pcie *pci = pcie->pci;
|
||||
struct device *dev = pci->dev;
|
||||
unsigned int num_clks, num_opt_clks;
|
||||
unsigned int idx;
|
||||
int ret;
|
||||
|
||||
@@ -1195,18 +1191,25 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
|
||||
res->clks[idx++].id = "bus_master";
|
||||
res->clks[idx++].id = "bus_slave";
|
||||
res->clks[idx++].id = "slave_q2a";
|
||||
if (pcie->cfg->has_tbu_clk)
|
||||
res->clks[idx++].id = "tbu";
|
||||
if (pcie->cfg->has_ddrss_sf_tbu_clk)
|
||||
res->clks[idx++].id = "ddrss_sf_tbu";
|
||||
if (pcie->cfg->has_aggre0_clk)
|
||||
res->clks[idx++].id = "aggre0";
|
||||
if (pcie->cfg->has_aggre1_clk)
|
||||
res->clks[idx++].id = "aggre1";
|
||||
|
||||
num_clks = idx;
|
||||
|
||||
ret = devm_clk_bulk_get(dev, num_clks, res->clks);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
res->clks[idx++].id = "tbu";
|
||||
res->clks[idx++].id = "ddrss_sf_tbu";
|
||||
res->clks[idx++].id = "aggre0";
|
||||
res->clks[idx++].id = "aggre1";
|
||||
res->clks[idx++].id = "noc_aggr_4";
|
||||
res->clks[idx++].id = "noc_aggr_south_sf";
|
||||
res->clks[idx++].id = "cnoc_qx";
|
||||
|
||||
num_opt_clks = idx - num_clks;
|
||||
res->num_clks = idx;
|
||||
|
||||
ret = devm_clk_bulk_get(dev, res->num_clks, res->clks);
|
||||
ret = devm_clk_bulk_get_optional(dev, num_opt_clks, res->clks + num_clks);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1509,15 +1512,13 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
|
||||
if (pcie->cfg->ops->config_sid) {
|
||||
ret = pcie->cfg->ops->config_sid(pcie);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
err_assert_reset:
|
||||
qcom_ep_reset_assert(pcie);
|
||||
if (pcie->cfg->ops->post_deinit)
|
||||
pcie->cfg->ops->post_deinit(pcie);
|
||||
err_disable_phy:
|
||||
phy_power_off(pcie->phy);
|
||||
err_deinit:
|
||||
@@ -1601,68 +1602,35 @@ static const struct qcom_pcie_ops ops_2_9_0 = {
|
||||
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg apq8084_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_1_0_0 = {
|
||||
.ops = &ops_1_0_0,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg ipq8064_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_1_9_0 = {
|
||||
.ops = &ops_1_9_0,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg cfg_2_1_0 = {
|
||||
.ops = &ops_2_1_0,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg msm8996_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_2_3_2 = {
|
||||
.ops = &ops_2_3_2,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg ipq8074_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_2_3_3 = {
|
||||
.ops = &ops_2_3_3,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg ipq4019_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_2_4_0 = {
|
||||
.ops = &ops_2_4_0,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sdm845_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_2_7_0 = {
|
||||
.ops = &ops_2_7_0,
|
||||
.has_tbu_clk = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sm8150_cfg = {
|
||||
/* sm8150 has qcom IP rev 1.5.0. However 1.5.0 ops are same as
|
||||
* 1.9.0, so reuse the same.
|
||||
*/
|
||||
.ops = &ops_1_9_0,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sm8250_cfg = {
|
||||
.ops = &ops_1_9_0,
|
||||
.has_tbu_clk = true,
|
||||
.has_ddrss_sf_tbu_clk = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sm8450_pcie0_cfg = {
|
||||
.ops = &ops_1_9_0,
|
||||
.has_ddrss_sf_tbu_clk = true,
|
||||
.has_aggre0_clk = true,
|
||||
.has_aggre1_clk = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sm8450_pcie1_cfg = {
|
||||
.ops = &ops_1_9_0,
|
||||
.has_ddrss_sf_tbu_clk = true,
|
||||
.has_aggre1_clk = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sc7280_cfg = {
|
||||
.ops = &ops_1_9_0,
|
||||
.has_tbu_clk = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg sc8180x_cfg = {
|
||||
.ops = &ops_1_9_0,
|
||||
.has_tbu_clk = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pcie_cfg ipq6018_cfg = {
|
||||
static const struct qcom_pcie_cfg cfg_2_9_0 = {
|
||||
.ops = &ops_2_9_0,
|
||||
};
|
||||
|
||||
@@ -1761,22 +1729,24 @@ err_pm_runtime_put:
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_pcie_match[] = {
|
||||
{ .compatible = "qcom,pcie-apq8084", .data = &apq8084_cfg },
|
||||
{ .compatible = "qcom,pcie-ipq8064", .data = &ipq8064_cfg },
|
||||
{ .compatible = "qcom,pcie-ipq8064-v2", .data = &ipq8064_cfg },
|
||||
{ .compatible = "qcom,pcie-apq8064", .data = &ipq8064_cfg },
|
||||
{ .compatible = "qcom,pcie-msm8996", .data = &msm8996_cfg },
|
||||
{ .compatible = "qcom,pcie-ipq8074", .data = &ipq8074_cfg },
|
||||
{ .compatible = "qcom,pcie-ipq4019", .data = &ipq4019_cfg },
|
||||
{ .compatible = "qcom,pcie-qcs404", .data = &ipq4019_cfg },
|
||||
{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
|
||||
{ .compatible = "qcom,pcie-sm8150", .data = &sm8150_cfg },
|
||||
{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
|
||||
{ .compatible = "qcom,pcie-sc8180x", .data = &sc8180x_cfg },
|
||||
{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &sm8450_pcie0_cfg },
|
||||
{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &sm8450_pcie1_cfg },
|
||||
{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
|
||||
{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
|
||||
{ .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
|
||||
{ .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 },
|
||||
{ .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8074", .data = &cfg_2_3_3 },
|
||||
{ .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 },
|
||||
{ .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 },
|
||||
{ .compatible = "qcom,pcie-sa8540p", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sdm845", .data = &cfg_2_7_0 },
|
||||
{ .compatible = "qcom,pcie-sm8150", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sm8250", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
|
||||
{ .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define PCIE_CORE_DEV_ID_REG 0x0
|
||||
#define PCIE_CORE_CMD_STATUS_REG 0x4
|
||||
#define PCIE_CORE_DEV_REV_REG 0x8
|
||||
#define PCIE_CORE_SSDEV_ID_REG 0x2c
|
||||
#define PCIE_CORE_PCIEXP_CAP 0xc0
|
||||
#define PCIE_CORE_PCIERR_CAP 0x100
|
||||
#define PCIE_CORE_ERR_CAPCTL_REG 0x118
|
||||
@@ -1077,7 +1078,10 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
|
||||
/* Indicates supports for Completion Retry Status */
|
||||
bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS);
|
||||
|
||||
bridge->subsystem_vendor_id = advk_readl(pcie, PCIE_CORE_SSDEV_ID_REG) & 0xffff;
|
||||
bridge->subsystem_id = advk_readl(pcie, PCIE_CORE_SSDEV_ID_REG) >> 16;
|
||||
bridge->has_pcie = true;
|
||||
bridge->pcie_start = PCIE_CORE_PCIEXP_CAP;
|
||||
bridge->data = pcie;
|
||||
bridge->ops = &advk_pci_bridge_emul_ops;
|
||||
|
||||
|
||||
@@ -103,13 +103,6 @@
|
||||
#define FARADAY_PCI_DMA_MEM2_BASE 0x00000000
|
||||
#define FARADAY_PCI_DMA_MEM3_BASE 0x00000000
|
||||
|
||||
/* Defines for PCI configuration command register */
|
||||
#define PCI_CONF_ENABLE BIT(31)
|
||||
#define PCI_CONF_WHERE(r) ((r) & 0xFC)
|
||||
#define PCI_CONF_BUS(b) (((b) & 0xFF) << 16)
|
||||
#define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11)
|
||||
#define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8)
|
||||
|
||||
/**
|
||||
* struct faraday_pci_variant - encodes IP block differences
|
||||
* @cascaded_irq: this host has cascaded IRQs from an interrupt controller
|
||||
@@ -190,11 +183,8 @@ static int faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number,
|
||||
unsigned int fn, int config, int size,
|
||||
u32 *value)
|
||||
{
|
||||
writel(PCI_CONF_BUS(bus_number) |
|
||||
PCI_CONF_DEVICE(PCI_SLOT(fn)) |
|
||||
PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
|
||||
PCI_CONF_WHERE(config) |
|
||||
PCI_CONF_ENABLE,
|
||||
writel(PCI_CONF1_ADDRESS(bus_number, PCI_SLOT(fn),
|
||||
PCI_FUNC(fn), config),
|
||||
p->base + FTPCI_CONFIG);
|
||||
|
||||
*value = readl(p->base + FTPCI_DATA);
|
||||
@@ -225,11 +215,8 @@ static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number,
|
||||
{
|
||||
int ret = PCIBIOS_SUCCESSFUL;
|
||||
|
||||
writel(PCI_CONF_BUS(bus_number) |
|
||||
PCI_CONF_DEVICE(PCI_SLOT(fn)) |
|
||||
PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
|
||||
PCI_CONF_WHERE(config) |
|
||||
PCI_CONF_ENABLE,
|
||||
writel(PCI_CONF1_ADDRESS(bus_number, PCI_SLOT(fn),
|
||||
PCI_FUNC(fn), config),
|
||||
p->base + FTPCI_CONFIG);
|
||||
|
||||
switch (size) {
|
||||
|
||||
@@ -523,7 +523,7 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
|
||||
|
||||
/* Are the new iobase/iolimit values invalid? */
|
||||
if (conf->iolimit < conf->iobase ||
|
||||
conf->iolimitupper < conf->iobaseupper)
|
||||
le16_to_cpu(conf->iolimitupper) < le16_to_cpu(conf->iobaseupper))
|
||||
return mvebu_pcie_set_window(port, port->io_target, port->io_attr,
|
||||
&desired, &port->iowin);
|
||||
|
||||
@@ -535,10 +535,10 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
|
||||
* is the CPU address.
|
||||
*/
|
||||
desired.remap = ((conf->iobase & 0xF0) << 8) |
|
||||
(conf->iobaseupper << 16);
|
||||
(le16_to_cpu(conf->iobaseupper) << 16);
|
||||
desired.base = port->pcie->io.start + desired.remap;
|
||||
desired.size = ((0xFFF | ((conf->iolimit & 0xF0) << 8) |
|
||||
(conf->iolimitupper << 16)) -
|
||||
(le16_to_cpu(conf->iolimitupper) << 16)) -
|
||||
desired.remap) +
|
||||
1;
|
||||
|
||||
@@ -552,7 +552,7 @@ static int mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
|
||||
struct pci_bridge_emul_conf *conf = &port->bridge.conf;
|
||||
|
||||
/* Are the new membase/memlimit values invalid? */
|
||||
if (conf->memlimit < conf->membase)
|
||||
if (le16_to_cpu(conf->memlimit) < le16_to_cpu(conf->membase))
|
||||
return mvebu_pcie_set_window(port, port->mem_target, port->mem_attr,
|
||||
&desired, &port->memwin);
|
||||
|
||||
@@ -562,8 +562,8 @@ static int mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
|
||||
* window to setup, according to the PCI-to-PCI bridge
|
||||
* specifications.
|
||||
*/
|
||||
desired.base = ((conf->membase & 0xFFF0) << 16);
|
||||
desired.size = (((conf->memlimit & 0xFFF0) << 16) | 0xFFFFF) -
|
||||
desired.base = ((le16_to_cpu(conf->membase) & 0xFFF0) << 16);
|
||||
desired.size = (((le16_to_cpu(conf->memlimit) & 0xFFF0) << 16) | 0xFFFFF) -
|
||||
desired.base + 1;
|
||||
|
||||
return mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired,
|
||||
@@ -946,6 +946,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
|
||||
bridge->subsystem_vendor_id = ssdev_id & 0xffff;
|
||||
bridge->subsystem_id = ssdev_id >> 16;
|
||||
bridge->has_pcie = true;
|
||||
bridge->pcie_start = PCIE_CAP_PCIEXP;
|
||||
bridge->data = port;
|
||||
bridge->ops = &mvebu_pci_bridge_emul_ops;
|
||||
|
||||
|
||||
@@ -415,13 +415,6 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
|
||||
* address (access to which generates correct config transaction) falls in
|
||||
* this 4 KiB region.
|
||||
*/
|
||||
static unsigned int tegra_pcie_conf_offset(u8 bus, unsigned int devfn,
|
||||
unsigned int where)
|
||||
{
|
||||
return ((where & 0xf00) << 16) | (bus << 16) | (PCI_SLOT(devfn) << 11) |
|
||||
(PCI_FUNC(devfn) << 8) | (where & 0xff);
|
||||
}
|
||||
|
||||
static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
|
||||
unsigned int devfn,
|
||||
int where)
|
||||
@@ -443,7 +436,9 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
|
||||
unsigned int offset;
|
||||
u32 base;
|
||||
|
||||
offset = tegra_pcie_conf_offset(bus->number, devfn, where);
|
||||
offset = PCI_CONF1_EXT_ADDRESS(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where) &
|
||||
~PCI_CONF1_ENABLE;
|
||||
|
||||
/* move 4 KiB window to offset within the FPCI region */
|
||||
base = 0xfe100000 + ((offset & ~(SZ_4K - 1)) >> 8);
|
||||
|
||||
@@ -516,8 +516,8 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
|
||||
u32 stat, idx;
|
||||
int ret, i;
|
||||
|
||||
reset = gpiod_get_from_of_node(np, "reset-gpios", 0,
|
||||
GPIOD_OUT_LOW, "PERST#");
|
||||
reset = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "reset",
|
||||
GPIOD_OUT_LOW, "PERST#");
|
||||
if (IS_ERR(reset))
|
||||
return PTR_ERR(reset);
|
||||
|
||||
|
||||
@@ -1071,7 +1071,7 @@ static struct platform_driver mtk_pcie_driver = {
|
||||
.probe = mtk_pcie_probe,
|
||||
.remove = mtk_pcie_remove,
|
||||
.driver = {
|
||||
.name = "mtk-pcie",
|
||||
.name = "mtk-pcie-gen3",
|
||||
.of_match_table = mtk_pcie_of_match,
|
||||
.pm = &mtk_pcie_pm_ops,
|
||||
},
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <linux/reset.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
#include "../pci.h"
|
||||
|
||||
/* MediaTek-specific configuration registers */
|
||||
#define PCIE_FTS_NUM 0x70c
|
||||
#define PCIE_FTS_NUM_MASK GENMASK(15, 8)
|
||||
@@ -120,19 +122,12 @@ static inline void pcie_port_write(struct mt7621_pcie_port *port,
|
||||
writel_relaxed(val, port->base + reg);
|
||||
}
|
||||
|
||||
static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot,
|
||||
unsigned int func, unsigned int where)
|
||||
{
|
||||
return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) |
|
||||
(func << 8) | (where & 0xfc) | 0x80000000;
|
||||
}
|
||||
|
||||
static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus,
|
||||
unsigned int devfn, int where)
|
||||
{
|
||||
struct mt7621_pcie *pcie = bus->sysdata;
|
||||
u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where);
|
||||
u32 address = PCI_CONF1_EXT_ADDRESS(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where);
|
||||
|
||||
writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR);
|
||||
|
||||
@@ -147,7 +142,7 @@ static struct pci_ops mt7621_pcie_ops = {
|
||||
|
||||
static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg)
|
||||
{
|
||||
u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg);
|
||||
u32 address = PCI_CONF1_EXT_ADDRESS(0, dev, 0, reg);
|
||||
|
||||
pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR);
|
||||
return pcie_read(pcie, RALINK_PCI_CONFIG_DATA);
|
||||
@@ -156,7 +151,7 @@ static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg)
|
||||
static void write_config(struct mt7621_pcie *pcie, unsigned int dev,
|
||||
u32 reg, u32 val)
|
||||
{
|
||||
u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg);
|
||||
u32 address = PCI_CONF1_EXT_ADDRESS(0, dev, 0, reg);
|
||||
|
||||
pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR);
|
||||
pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user