2022-11-13 20:00:44

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 00/20] PCI: dwc: Add generic resources and Baikal-T1 support

This patchset is a third one in the series created in the framework of
my Baikal-T1 PCIe/eDMA-related work:

[1: Done v5] PCI: dwc: Various fixes and cleanups
Link: https://lore.kernel.org/linux-pci/[email protected]/
Merged: kernel 6.0-rc1
[2: Done v4] PCI: dwc: Add hw version and dma-ranges support
Link: https://lore.kernel.org/linux-pci/[email protected]
Merged: kernel 6.0-rc1
[3: In-review v7] PCI: dwc: Add generic resources and Baikal-T1 support
Link: ---you are looking at it---
[4: Done v6] dmaengine: dw-edma: Add RP/EP local DMA support
Link: https://lore.kernel.org/linux-pci/[email protected]/

Note it is very recommended to merge the patchsets in the same order as
they are listed in the set above in order to have them applied smoothly.
Nothing prevents them from being reviewed synchronously though.

Originally the patches submitted in this patchset were a part of the series:
Link: https://lore.kernel.org/linux-pci/[email protected]/
but due to the reviewers requests the series was expanded to about 30
patches which made it too bulky for a comfortable review. So I decided to
split it up into two patchsets: 2. and 3. in the table above.

Regarding the series content. This patchset is mainly about adding new DW
PCIe platform support - Baikal-T1 PCIe of DW PCIe v4.60a IP-core. But a
set of feature-reach preparations are done first. It starts from
converting the currently available DT-schema into a more flexible schemas
hierarchy with separately defined regs, clocks, resets and interrupts
properties. As a result the common schema can be easily re-used by all the
currently available platforms while the named properties above can be
either re-defined or used as is if the platforms support they. In the
framework of that modification we also suggest to add a set of generic
regs, clocks, resets and interrupts resource names in accordance with what
the DW PCIe hardware reference manual describes and what the DW PCIe core
driver already expects to be specified. Thus the new platform driver will
be able to re-use the common resources infrastructure.

Link: https://lore.kernel.org/linux-pci/[email protected]/
Changelog v2:
- Rename 'syscon' property to 'baikal,bt1-syscon'. (@Rob)
- Move the iATU region selection procedure into a helper function (@Rob).
- Rebase from kernel v5.17 onto v5.18-rc3 since the later kernel has
already DT bindings converted. (@Rob)
- Use 'definitions' property instead of the '$defs' one. It fixes the
dt-validate error: 'X is not of type array.'
- Drop 'interrupts' and 'interrupt-names' property from being required
for the native DW PCIe host.
- Evaluate the 'snps,dw-pcie-common.yaml' schema in the
'socionext,uniphier-pcie-ep.yaml' DT-bindings since the later has
platform-specific names defined.

Link: https://lore.kernel.org/linux-pci/[email protected]
Changelog v3:
- Split up the patch "dt-bindings: PCI: dwc: Define common and native DT
bindings" into a series of modifications. (@Rob)
- Detach this series of the patches into a dedicated patchset.
- Add a new feature patch: "PCI: dwc: Introduce generic controller
capabilities interface".
- Add a new feature patch: "PCI: dwc: Introduce generic resources getter".
- Add a new cleanup patch: "PCI: dwc: Combine iATU detection procedures".
- Add a method to at least request the generic clocks and resets. (@Rob)
- Add GPIO-based PERST# signal support to the core module.
- Redefine Baikal-T1 PCIe host bridge config space accessors with the
pci_generic_config_read32() and pci_generic_config_write32() methods.
(@Rob)
- Drop synonymous from the names list in the common DT-schema since the
device sub-schemas create their own enumerations anyway.
- Rebase onto kernel v5.18.

Link: https://lore.kernel.org/linux-pci/[email protected]/
Changelog v4:
- Drop PCIBIOS_* macros usage. (@Rob)
- Add "static const" to the dw_pcie_ops and dw_pcie_host_ops structure
instances. (@Bjorn)
- Rename bt1_pcie_dw_ops to bt1_pcie_ops. (@Bjorn)
- Rename bt1_pcie_ops to bt1_pci_ops. (@Bjorn)
- Use start_link/stop_link suffixes in the Baikal-T1 PCIe
start/stop link callbacks. (@Bjorn)
- Change the get_res() method suffix to being get_resources(). (@Bjorn)
- Change *_{add,del}_dw_port() method to *_{add,del}_port(). (@Bjorn)
- Drop dma_coerce_mask_and_coherent() applied to the PCI host bridge
kernel device instance. (@Bjorn)
- Add the comment above the dma_set_mask_and_coherent() method usage
regarding the controller eDMA feature. (@Bjorn)
- Fix the comment above the core reset controls assertion. (@Bjorn)
- Replace delays and timeout numeric literals with macros. (@Bjorn)
- Convert the method name from dw_pcie_get_res() to
dw_pcie_get_resources(). (@Bjorn)
- Rebase onto the kernel v5.19-rcX.

Link: https://lore.kernel.org/linux-pci/[email protected]/
Changelog v5:
- Add a note about having line-based PHY phandles order. (@Rob)
- Prefer 'pcie[0-9]+' PHY-names over the rest of the cases. (@Rob)
- Drop generic fallback names from the Baikal-T1 compatible property
constraints. (@Rob)
- Define ordered {reg,interrupt,clock,reset}-names Baikal-T1 PCIe
properties. (@Rob)
- Drop minItems from the Baikal-T1 PCIe clocks and reset properties,
since it equals to the maxItems for them.
- Drop num-ob-windows and num-ib-windows properties constraint from
Baikal-T1 PCIe bindings. (@Rob)
- Add a note about having line-based PHY phandles order. (@Rob)
- Prefer 'pcie[0-9]+' PHY-names over the rest of the cases. (@Rob)
- Add platform-specific reg/interrupt/clock/reset names to the generic
schema, but mark them as deprecated.
- Add new patches:
dt-bindings: visconti-pcie: Fix interrupts array max constraints
dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq
- Move the patch:
PCI: dwc: Introduce dma-ranges property support for RC-host
from the previous patchset in here. (@Bjorn)
- Rebase onto the kernel v6.0-rc2.

Link: https://lore.kernel.org/linux-pci/[email protected]/
Changelog v6:
- Add the Nvidia Tegra194-specific "p2u-[0-7]" phy-names too. (@DT-tbot)
- Drop 'deprecated' keywords from the vendor-specific names. (@Rob)
- Move the common *-names definitions to the RP/EP schemas. Thus drop
the 'definitions' property usage from the DT-schemas. (@Rob)
- Move the DMA-mask setup to the eDMA driver. (@Robin)
- Rebase onto the kernel v6.1-rc3.

Link: https://lore.kernel.org/linux-pci/[email protected]/
Changelog v7:
- Replace if-then-dev_err_probe-return statement with just
return-dev_err_probe one in the pcie-bt1 driver.
- Get back device.of_node pointer to the dw_pcie_ep_init() method.
(@Yoshihiro)
- Drop the dtschema tool 'lib.py' fix chunk from under the '---' pattern.
(@Yoshihiro)
- Move the allOf clause to the bottom of the fsl,imx6q-pcie.yaml bindings.
(@Krzysztof)
- Get back the names to the clock-names property and make sure the
platform-specific cloc-names constraint is applied in the allOf clause
in the fsl,imx6q-pcie.yaml bindings. (@Rob)

Signed-off-by: Serge Semin <[email protected]>
Cc: Alexey Malahov <[email protected]>
Cc: Pavel Parkhomenko <[email protected]>
Cc: "Krzysztof Wilczyński" <[email protected]>
Cc: Frank Li <[email protected]>
Cc: Manivannan Sadhasivam <[email protected]>
Cc: caihuoqing <[email protected]>
Cc: Vinod Koul <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Serge Semin (20):
dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq
dt-bindings: visconti-pcie: Fix interrupts array max constraints
dt-bindings: PCI: dwc: Detach common RP/EP DT bindings
dt-bindings: PCI: dwc: Remove bus node from the examples
dt-bindings: PCI: dwc: Add phys/phy-names common properties
dt-bindings: PCI: dwc: Add max-link-speed common property
dt-bindings: PCI: dwc: Apply generic schema for generic device only
dt-bindings: PCI: dwc: Add max-functions EP property
dt-bindings: PCI: dwc: Add interrupts/interrupt-names common
properties
dt-bindings: PCI: dwc: Add reg/reg-names common properties
dt-bindings: PCI: dwc: Add clocks/resets common properties
dt-bindings: PCI: dwc: Add dma-coherent property
dt-bindings: PCI: dwc: Apply common schema to Rockchip DW PCIe nodes
dt-bindings: PCI: dwc: Add Baikal-T1 PCIe Root Port bindings
PCI: dwc: Introduce dma-ranges property support for RC-host
PCI: dwc: Introduce generic controller capabilities interface
PCI: dwc: Introduce generic resources getter
PCI: dwc: Combine iATU detection procedures
PCI: dwc: Introduce generic platform clocks and resets
PCI: dwc: Add Baikal-T1 PCIe controller support

.../bindings/pci/baikal,bt1-pcie.yaml | 168 +++++
.../bindings/pci/fsl,imx6q-pcie.yaml | 46 +-
.../bindings/pci/rockchip-dw-pcie.yaml | 4 +-
.../bindings/pci/snps,dw-pcie-common.yaml | 266 ++++++++
.../bindings/pci/snps,dw-pcie-ep.yaml | 212 ++++--
.../devicetree/bindings/pci/snps,dw-pcie.yaml | 260 +++++--
.../bindings/pci/toshiba,visconti-pcie.yaml | 7 +-
drivers/pci/controller/dwc/Kconfig | 9 +
drivers/pci/controller/dwc/Makefile | 1 +
drivers/pci/controller/dwc/pcie-bt1.c | 643 ++++++++++++++++++
.../pci/controller/dwc/pcie-designware-ep.c | 29 +-
.../pci/controller/dwc/pcie-designware-host.c | 47 +-
drivers/pci/controller/dwc/pcie-designware.c | 262 +++++--
drivers/pci/controller/dwc/pcie-designware.h | 63 +-
14 files changed, 1796 insertions(+), 221 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/baikal,bt1-pcie.yaml
create mode 100644 Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
create mode 100644 drivers/pci/controller/dwc/pcie-bt1.c

--
2.38.1




2022-11-13 20:02:25

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 09/20] dt-bindings: PCI: dwc: Add interrupts/interrupt-names common properties

Currently the 'interrupts' and 'interrupt-names' properties are defined
being too generic to really describe any actual IRQ interface. Moreover
the DW PCIe End-point devices are left with no IRQ signals. All of that
can be fixed by adding the IRQ-related properties to the common DW PCIe
DT-schemas in accordance with the hardware reference manual. The DW PCIe
common DT-schema will contain the generic properties definitions with just
a number of entries per property, while the DW PCIe RP/EP-specific schemas
will have the particular number of items and the generic resource names
listed.

Note since there are DW PCI-based vendor-specific DT-bindings with the
custom names assigned to the same IRQ resources we have no much choice but
to add them to the generic DT-schemas in order to have the schemas being
applicable for such devices. These names are marked as vendor-specific and
should be avoided being used in new bindings in favor of the generic
names.

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v3:
- This is a new patch unpinned from the next one:
https://lore.kernel.org/linux-pci/[email protected]/
by the Rob' request. (@Rob)

Changelog v5:
- Add platform-specific interrupt names, but mark them as deprecated.

Changelog v6:
- Move the common interrupt-names definitions to the RP/EP schemas.
Thus drop the 'definitions' property. (@Rob)
- Drop the 'deprecated' keywords from the vendor-specific names. (@Rob)

Changelog v7:
- Drop the dtschema tool 'lib.py' fix chunk from under the '---' pattern.
(@Yoshihiro)
---
.../bindings/pci/snps,dw-pcie-common.yaml | 19 ++++
.../bindings/pci/snps,dw-pcie-ep.yaml | 52 +++++++++++
.../devicetree/bindings/pci/snps,dw-pcie.yaml | 90 ++++++++++++++++++-
3 files changed, 158 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
index e63c21783fc1..4646fb14e817 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
@@ -17,6 +17,25 @@ description:
select: false

properties:
+ interrupts:
+ description:
+ There are two main sub-blocks which are normally capable of
+ generating interrupts. It's System Information Interface and MSI
+ interface. While the former one has some common for the Host and
+ Endpoint controllers IRQ-signals, the later interface is obviously
+ Root Complex specific since it's responsible for the incoming MSI
+ messages signalling. The System Information IRQ signals are mainly
+ responsible for reporting the generic PCIe hierarchy and Root
+ Complex events like VPD IO request, general AER, PME, Hot-plug, link
+ bandwidth change, link equalization request, INTx asserted/deasserted
+ Message detection, embedded DMA Tx/Rx/Error.
+ minItems: 1
+ maxItems: 26
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 26
+
phys:
description:
There can be up to the number of possible lanes PHYs specified placed in
diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
index 71dd19ae1060..7d3f8fc8b7b4 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
@@ -41,6 +41,55 @@ properties:
items:
enum: [dbi, dbi2, config, atu, addr_space, link, atu_dma, appl]

+ interrupts:
+ description:
+ There is no mandatory IRQ signals for the normal controller functioning,
+ but in addition to the native set the platforms may have a link- or
+ PM-related IRQs specified.
+ minItems: 1
+ maxItems: 20
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 20
+ items:
+ oneOf:
+ - description:
+ Controller request to read or write virtual product data
+ from/to the VPD capability registers.
+ const: vpd
+ - description:
+ Link Equalization Request flag is set in the Link Status 2
+ register (applicable if the corresponding IRQ is enabled in
+ the Link Control 3 register).
+ const: l_eq
+ - description:
+ Indicates that the eDMA Tx/Rx transfer is complete or that an
+ error has occurred on the corresponding channel. eDMA can have
+ eight Tx (Write) and Rx (Read) eDMA channels thus supporting up
+ to 16 IRQ signals all together. Write eDMA channels shall go
+ first in the ordered row as per default edma_int[*] bus setup.
+ pattern: '^dma([0-9]|1[0-5])?$'
+ - description:
+ PCIe protocol correctable error or a Data Path protection
+ correctable error is detected by the automotive/safety
+ feature.
+ const: sft_ce
+ - description:
+ Indicates that the internal safety mechanism has detected an
+ uncorrectable error.
+ const: sft_ue
+ - description:
+ Application-specific IRQ raised depending on the vendor-specific
+ events basis.
+ const: app
+ - description:
+ Vendor-specific IRQ names. Consider using the generic names above
+ for new bindings.
+ oneOf:
+ - description: See native "app" IRQ for details
+ enum: [ intr ]
+
max-functions:
maximum: 32

@@ -60,6 +109,9 @@ examples:
<0xd0000000 0x2000000>; /* Configuration space */
reg-names = "dbi", "dbi2", "addr_space";

+ interrupts = <23>, <24>;
+ interrupt-names = "dma0", "dma1";
+
phys = <&pcie_phy0>, <&pcie_phy1>, <&pcie_phy2>, <&pcie_phy3>;
phy-names = "pcie0", "pcie1", "pcie2", "pcie3";

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
index 85861b71d9ff..fa1db57b2b97 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
@@ -42,9 +42,92 @@ properties:
enum: [ dbi, dbi2, config, atu, atu_dma, app, appl, elbi, mgmt, ctrl,
parf, cfg, link, ulreg, smu, mpu, apb, phy ]

- interrupts: true
-
- interrupt-names: true
+ interrupts:
+ description:
+ DWC PCIe Root Port/Complex specific IRQ signals. At least MSI interrupt
+ signal is supposed to be specified for the host controller.
+ minItems: 1
+ maxItems: 26
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 26
+ items:
+ oneOf:
+ - description:
+ Controller request to read or write virtual product data
+ from/to the VPD capability registers.
+ const: vpd
+ - description:
+ Link Equalization Request flag is set in the Link Status 2
+ register (applicable if the corresponding IRQ is enabled in
+ the Link Control 3 register).
+ const: l_eq
+ - description:
+ Indicates that the eDMA Tx/Rx transfer is complete or that an
+ error has occurred on the corresponding channel. eDMA can have
+ eight Tx (Write) and Rx (Read) eDMA channels thus supporting up
+ to 16 IRQ signals all together. Write eDMA channels shall go
+ first in the ordered row as per default edma_int[*] bus setup.
+ pattern: '^dma([0-9]|1[0-5])?$'
+ - description:
+ PCIe protocol correctable error or a Data Path protection
+ correctable error is detected by the automotive/safety
+ feature.
+ const: sft_ce
+ - description:
+ Indicates that the internal safety mechanism has detected an
+ uncorrectable error.
+ const: sft_ue
+ - description:
+ Application-specific IRQ raised depending on the vendor-specific
+ events basis.
+ const: app
+ - description:
+ DSP AXI MSI Interrupt detected. It gets de-asserted when there is
+ no more MSI interrupt pending. The interrupt is relevant to the
+ iMSI-RX - Integrated MSI Receiver (AXI bridge).
+ const: msi
+ - description:
+ Legacy A/B/C/D interrupt signal. Basically it's triggered by
+ receiving a Assert_INT{A,B,C,D}/Desassert_INT{A,B,C,D} message
+ from the downstream device.
+ pattern: "^int(a|b|c|d)$"
+ - description:
+ Error condition detected and a flag is set in the Root Error Status
+ register of the AER capability. It's asserted when the RC
+ internally generated an error or an error message is received by
+ the RC.
+ const: aer
+ - description:
+ PME message is received by the port. That means having the PME
+ status bit set in the Root Status register (the event is
+ supposed to be unmasked in the Root Control register).
+ const: pme
+ - description:
+ Hot-plug event is detected. That is a bit has been set in the
+ Slot Status register and the corresponding event is enabled in
+ the Slot Control register.
+ const: hp
+ - description:
+ Link Autonomous Bandwidth Status flag has been set in the Link
+ Status register (the event is supposed to be unmasked in the
+ Link Control register).
+ const: bw_au
+ - description:
+ Bandwidth Management Status flag has been set in the Link
+ Status register (the event is supposed to be unmasked in the
+ Link Control register).
+ const: bw_mg
+ - description:
+ Vendor-specific IRQ names. Consider using the generic names above
+ for new bindings.
+ oneOf:
+ - description: See native "app" IRQ for details
+ enum: [ intr ]
+ allOf:
+ - contains:
+ const: msi

clocks: true

@@ -70,6 +153,7 @@ examples:
bus-range = <0x0 0xff>;

interrupts = <25>, <24>;
+ interrupt-names = "msi", "hp";
#interrupt-cells = <1>;

reset-gpios = <&port0 0 1>;
--
2.38.1



2022-11-13 20:02:28

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 07/20] dt-bindings: PCI: dwc: Apply generic schema for generic device only

Having the generic compatible strings constraints with the 'any'+'generic
string' semantic implicitly encourages either to add new DW PCIe-based
DT-bindings with the generic compatible string attached or just forget
about adding new DT-bindings since the corresponding DT-node will be
evaluated anyway. Moreover having that semantic implemented in the
generic DT-schema causes the DT-validation tool to apply the schema twice:
first by implicit compatible-string-based selection and second by means of
the 'allOf: [ $ref ]' statement. Let's fix all of that by dropping the
compatible property constraints and selecting the generic DT-schema only
for the purely generic DW PCIe DT-nodes. The later is required since there
is a driver for such devices. (Though there are no such DT-nodes currently
defined in the kernel DT sources.)

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v3:
- This is a new patch unpinned from the next one:
https://lore.kernel.org/linux-pci/[email protected]/
by the Rob' request. (@Rob)
- Fix compatible property schema so one would work as expected: string
must contain either generic DW PCIe IP-core name or both generic and
equipped with IP-core version names.

Changelog v5:
- Switch the patch from not-selecting the generic schemas to applying
them to the generic DW PCIe device nodes only.
- Drop the generic compatible string used as fallback. (@Rob)
---
.../devicetree/bindings/pci/snps,dw-pcie-ep.yaml | 16 ++++++++++------
.../devicetree/bindings/pci/snps,dw-pcie.yaml | 16 ++++++++++------
2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
index fc3b5d4ac245..d04001248b53 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
@@ -13,16 +13,20 @@ maintainers:
description: |
Synopsys DesignWare PCIe host controller endpoint

+# Please create a separate DT-schema for your DWC PCIe Endpoint controller
+# and make sure it's assigned with the vendor-specific compatible string.
+select:
+ properties:
+ compatible:
+ const: snps,dw-pcie-ep
+ required:
+ - compatible
+
allOf:
- $ref: /schemas/pci/pci-ep.yaml#
- $ref: /schemas/pci/snps,dw-pcie-common.yaml#

properties:
- compatible:
- anyOf:
- - {}
- - const: snps,dw-pcie-ep
-
reg:
description: |
It should contain Data Bus Interface (dbi) and config registers for all
@@ -38,9 +42,9 @@ properties:
enum: [dbi, dbi2, config, atu, addr_space, link, atu_dma, appl]

required:
+ - compatible
- reg
- reg-names
- - compatible

additionalProperties: true

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
index e787b9727589..85861b71d9ff 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
@@ -13,16 +13,20 @@ maintainers:
description: |
Synopsys DesignWare PCIe host controller

+# Please create a separate DT-schema for your DWC PCIe Root Port controller
+# and make sure it's assigned with the vendor-specific compatible string.
+select:
+ properties:
+ compatible:
+ const: snps,dw-pcie
+ required:
+ - compatible
+
allOf:
- $ref: /schemas/pci/pci-bus.yaml#
- $ref: /schemas/pci/snps,dw-pcie-common.yaml#

properties:
- compatible:
- anyOf:
- - {}
- - const: snps,dw-pcie
-
reg:
description: |
It should contain Data Bus Interface (dbi) and config registers for all
@@ -47,9 +51,9 @@ properties:
additionalProperties: true

required:
+ - compatible
- reg
- reg-names
- - compatible

examples:
- |
--
2.38.1



2022-11-13 20:03:01

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 06/20] dt-bindings: PCI: dwc: Add max-link-speed common property

In accordance with [1] DW PCIe controllers support up to Gen5 link speed.
Let's add the max-link-speed property upper bound to 5 then. The DT
bindings of the particular devices are expected to setup more strict
constraint on that parameter.

[1] Synopsys DesignWare Cores PCI Express Controller Databook, Version
5.40a, March 2019, p. 27

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v3:
- This is a new patch unpinned from the next one:
https://lore.kernel.org/linux-pci/[email protected]/
by the Rob' request. (@Rob)
---
Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml | 3 +++
Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml | 2 ++
Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml | 1 +
3 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
index 91d24e400dfc..e63c21783fc1 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
@@ -54,6 +54,9 @@ properties:
the peripheral devices available on the PCIe bus.
maxItems: 1

+ max-link-speed:
+ maximum: 5
+
num-lanes:
description:
Number of PCIe link lanes to use. Can be omitted if the already brought
diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
index dcd521aed213..fc3b5d4ac245 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
@@ -55,4 +55,6 @@ examples:

phys = <&pcie_phy0>, <&pcie_phy1>, <&pcie_phy2>, <&pcie_phy3>;
phy-names = "pcie0", "pcie1", "pcie2", "pcie3";
+
+ max-link-speed = <3>;
};
diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
index d9512f7f7124..e787b9727589 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
@@ -74,4 +74,5 @@ examples:
phy-names = "pcie";

num-lanes = <1>;
+ max-link-speed = <3>;
};
--
2.38.1



2022-11-13 20:06:20

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in
the separate parts of the DW PCIe core driver. It doesn't really make
sense since the both controller types have identical set of the core CSR
regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host
and EP initialization methods by moving the platform-specific registers
space getting and mapping into a common method. It gets to be even more
justified seeing the CSRs base address pointers are preserved in the
common DW PCIe descriptor. Note all the OF-based common DW PCIe settings
initialization will be moved to the new method too in order to have a
single function for all the generic platform properties handling in single
place.

A nice side-effect of this change is that the pcie-designware-host.c and
pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie
storage modification, which makes the DW PCIe core, Root Port and Endpoint
modules more coherent.

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v3:
- This is a new patch created on v3 lap of the series.

Changelog v4:
- Convert the method name from dw_pcie_get_res() to
dw_pcie_get_resources(). (@Bjorn)

Changelog v7:
- Get back device.of_node pointer to the dw_pcie_ep_init() method.
(@Yoshihiro)
---
.../pci/controller/dwc/pcie-designware-ep.c | 25 +------
.../pci/controller/dwc/pcie-designware-host.c | 15 +---
drivers/pci/controller/dwc/pcie-designware.c | 75 ++++++++++++++-----
drivers/pci/controller/dwc/pcie-designware.h | 3 +
4 files changed, 65 insertions(+), 53 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 237bb01d7852..f68d1ab83bb3 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -13,8 +13,6 @@
#include <linux/pci-epc.h>
#include <linux/pci-epf.h>

-#include "../../pci.h"
-
void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
{
struct pci_epc *epc = ep->epc;
@@ -694,23 +692,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)

INIT_LIST_HEAD(&ep->func_list);

- if (!pci->dbi_base) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
- }
-
- if (!pci->dbi_base2) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
- if (!res) {
- pci->dbi_base2 = pci->dbi_base + SZ_4K;
- } else {
- pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(pci->dbi_base2))
- return PTR_ERR(pci->dbi_base2);
- }
- }
+ ret = dw_pcie_get_resources(pci);
+ if (ret)
+ return ret;

res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
if (!res)
@@ -739,9 +723,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
return -ENOMEM;
ep->outbound_addr = addr;

- if (pci->link_gen < 1)
- pci->link_gen = of_pci_get_max_link_speed(np);
-
epc = devm_pci_epc_create(dev, &epc_ops);
if (IS_ERR(epc)) {
dev_err(dev, "Failed to create epc device\n");
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index ea923c25e12d..3ab6ae3712c4 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -16,7 +16,6 @@
#include <linux/pci_regs.h>
#include <linux/platform_device.h>

-#include "../../pci.h"
#include "pcie-designware.h"

static struct pci_ops dw_pcie_ops;
@@ -395,6 +394,10 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)

raw_spin_lock_init(&pp->lock);

+ ret = dw_pcie_get_resources(pci);
+ if (ret)
+ return ret;
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
if (res) {
pp->cfg0_size = resource_size(res);
@@ -408,13 +411,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
return -ENODEV;
}

- if (!pci->dbi_base) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
- }
-
bridge = devm_pci_alloc_host_bridge(dev, 0);
if (!bridge)
return -ENOMEM;
@@ -429,9 +425,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
pp->io_base = pci_pio_to_address(win->res->start);
}

- if (pci->link_gen < 1)
- pci->link_gen = of_pci_get_max_link_speed(np);
-
/* Set default bus ops */
bridge->ops = &dw_pcie_ops;
bridge->child_ops = &dw_child_pcie_ops;
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 9d78e7ca61e1..a8436027434d 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -11,6 +11,7 @@
#include <linux/align.h>
#include <linux/bitops.h>
#include <linux/delay.h>
+#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/sizes.h>
@@ -19,6 +20,59 @@
#include "../../pci.h"
#include "pcie-designware.h"

+int dw_pcie_get_resources(struct dw_pcie *pci)
+{
+ struct platform_device *pdev = to_platform_device(pci->dev);
+ struct device_node *np = dev_of_node(pci->dev);
+ struct resource *res;
+
+ if (!pci->dbi_base) {
+ 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);
+ }
+
+ /* DBI2 is mainly useful for the endpoint controller */
+ if (!pci->dbi_base2) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
+ if (res) {
+ pci->dbi_base2 = devm_pci_remap_cfg_resource(pci->dev, res);
+ if (IS_ERR(pci->dbi_base2))
+ return PTR_ERR(pci->dbi_base2);
+ } else {
+ pci->dbi_base2 = pci->dbi_base + SZ_4K;
+ }
+ }
+
+ /* For non-unrolled iATU/eDMA platforms this range will be ignored */
+ if (!pci->atu_base) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
+ if (res) {
+ pci->atu_size = resource_size(res);
+ pci->atu_base = devm_ioremap_resource(pci->dev, res);
+ if (IS_ERR(pci->atu_base))
+ return PTR_ERR(pci->atu_base);
+ } else {
+ pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
+ }
+ }
+
+ /* Set a default value suitable for at most 8 in and 8 out windows */
+ if (!pci->atu_size)
+ pci->atu_size = SZ_4K;
+
+ if (pci->link_gen < 1)
+ pci->link_gen = of_pci_get_max_link_speed(np);
+
+ of_property_read_u32(np, "num-lanes", &pci->num_lanes);
+
+ if (of_property_read_bool(np, "snps,enable-cdm-check"))
+ dw_pcie_cap_set(pci, CDM_CHECK);
+
+ return 0;
+}
+
void dw_pcie_version_detect(struct dw_pcie *pci)
{
u32 ver;
@@ -639,25 +693,8 @@ static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci)

void dw_pcie_iatu_detect(struct dw_pcie *pci)
{
- struct platform_device *pdev = to_platform_device(pci->dev);
-
if (dw_pcie_iatu_unroll_enabled(pci)) {
dw_pcie_cap_set(pci, IATU_UNROLL);
-
- if (!pci->atu_base) {
- struct resource *res =
- platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
- if (res) {
- pci->atu_size = resource_size(res);
- pci->atu_base = devm_ioremap_resource(pci->dev, res);
- }
- if (!pci->atu_base || IS_ERR(pci->atu_base))
- pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
- }
-
- if (!pci->atu_size)
- /* Pick a minimal default, enough for 8 in and 8 out windows */
- pci->atu_size = SZ_4K;
} else {
pci->atu_base = pci->dbi_base + PCIE_ATU_VIEWPORT_BASE;
pci->atu_size = PCIE_ATU_VIEWPORT_SIZE;
@@ -675,7 +712,6 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci)

void dw_pcie_setup(struct dw_pcie *pci)
{
- struct device_node *np = pci->dev->of_node;
u32 val;

if (pci->link_gen > 0)
@@ -703,14 +739,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
val |= PORT_LINK_DLL_LINK_EN;
dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);

- if (of_property_read_bool(np, "snps,enable-cdm-check")) {
+ if (dw_pcie_cap_is(pci, CDM_CHECK)) {
val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
PCIE_PL_CHK_REG_CHK_REG_START;
dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
}

- of_property_read_u32(np, "num-lanes", &pci->num_lanes);
if (!pci->num_lanes) {
dev_dbg(pci->dev, "Using h/w default number of lanes\n");
return;
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index c6dddacee3b1..081f169e6021 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -46,6 +46,7 @@

/* DWC PCIe controller capabilities */
#define DW_PCIE_CAP_IATU_UNROLL 1
+#define DW_PCIE_CAP_CDM_CHECK 2

#define dw_pcie_cap_is(_pci, _cap) \
test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps)
@@ -338,6 +339,8 @@ struct dw_pcie {
#define to_dw_pcie_from_ep(endpoint) \
container_of((endpoint), struct dw_pcie, ep)

+int dw_pcie_get_resources(struct dw_pcie *pci);
+
void dw_pcie_version_detect(struct dw_pcie *pci);

u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
--
2.38.1



2022-11-13 20:06:40

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq

Originally as it was defined the legacy bindings the pcie_inbound_axi and
pcie_aux clock names were supposed to be used in the fsl,imx6sx-pcie and
fsl,imx8mq-pcie devices respectively. But the bindings conversion has been
incorrectly so now the fourth clock name is defined as "pcie_inbound_axi
for imx6sx-pcie, pcie_aux for imx8mq-pcie", which is completely wrong.
Let's fix that by conditionally apply the clock-names constraints based on
the compatible string content.

Fixes: 751ca492f131 ("dt-bindings: PCI: imx6: convert the imx pcie controller to dtschema")
Signed-off-by: Serge Semin <[email protected]>
Acked-by: Alexander Stein <[email protected]>

---

Changelog v5:
- This is a new patch added on the v5 release of the patchset.

Changelog v7:
- Move the allOf clause to the bottom of the bindings. (@Krzysztof)
- Get back the names to the clock-names property and make sure the
platform-specific name constraint is applied in the allOf clause.
(@Rob)
---
.../bindings/pci/fsl,imx6q-pcie.yaml | 46 +++++++++++++++++--
1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
index 376e739bcad4..49b4f7a32e71 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -14,9 +14,6 @@ description: |+
This PCIe host controller is based on the Synopsys DesignWare PCIe IP
and thus inherits all the common properties defined in snps,dw-pcie.yaml.

-allOf:
- - $ref: /schemas/pci/snps,dw-pcie.yaml#
-
properties:
compatible:
enum:
@@ -61,7 +58,7 @@ properties:
- const: pcie
- const: pcie_bus
- const: pcie_phy
- - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie
+ - enum: [ pcie_inbound_axi, pcie_aux ]

num-lanes:
const: 1
@@ -175,6 +172,47 @@ required:
- clocks
- clock-names

+allOf:
+ - $ref: /schemas/pci/snps,dw-pcie.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx6sx-pcie
+ then:
+ properties:
+ clock-names:
+ items:
+ - {}
+ - {}
+ - {}
+ - const: pcie_inbound_axi
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx8mq-pcie
+ then:
+ properties:
+ clock-names:
+ items:
+ - {}
+ - {}
+ - {}
+ - const: pcie_aux
+ - if:
+ properties:
+ compatible:
+ not:
+ contains:
+ enum:
+ - fsl,imx6sx-pcie
+ - fsl,imx8mq-pcie
+ then:
+ properties:
+ clock-names:
+ maxItems: 3
+
unevaluatedProperties: false

examples:
--
2.38.1



2022-11-13 20:07:01

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 02/20] dt-bindings: visconti-pcie: Fix interrupts array max constraints

In accordance with the way the device DT-node is actually defined in
arch/arm64/boot/dts/toshiba/tmpv7708.dtsi and the way the device is probed
by the DW PCIe driver there are two IRQs it actually has. It's MSI IRQ the
DT-bindings lack. Let's extend the interrupts property constraints then
and fix the schema example so one would be acceptable by the actual device
DT-bindings.

Fixes: 17c1b16340f0 ("dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller")
Signed-off-by: Serge Semin <[email protected]>
Acked-by: Rob Herring <[email protected]>
Acked-by: Nobuhiro Iwamatsu <[email protected]>

---

Changelog v5:
- This is a new patch added on the v5 release of the patchset.
---
.../devicetree/bindings/pci/toshiba,visconti-pcie.yaml | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
index 48ed227fc5b9..53da2edd7c9a 100644
--- a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
@@ -36,7 +36,7 @@ properties:
- const: mpu

interrupts:
- maxItems: 1
+ maxItems: 2

clocks:
items:
@@ -94,8 +94,9 @@ examples:
#interrupt-cells = <1>;
ranges = <0x81000000 0 0x40000000 0 0x40000000 0 0x00010000>,
<0x82000000 0 0x50000000 0 0x50000000 0 0x20000000>;
- interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "intr";
+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi", "intr";
interrupt-map-mask = <0 0 0 7>;
interrupt-map =
<0 0 0 1 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH
--
2.38.1



2022-11-13 20:07:34

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 11/20] dt-bindings: PCI: dwc: Add clocks/resets common properties

DW PCIe RP/EP reference manuals explicit define all the clocks and reset
requirements in [1] and [2]. Seeing the DW PCIe vendor-specific
DT-bindings have already started assigning random names to the same set of
the clocks and resets lines, let's define a generic names sets and add
them to the DW PCIe common DT-schema.

Note since there are DW PCI-based vendor-specific DT-bindings with the
custom names assigned to the same clocks and resets resources we have no
much choice but to add them to the generic DT-schemas in order to have the
schemas being applicable for such devices. These names are marked as
vendor-specific and should be avoided being used in new bindings in favor
of the generic names.

[1] Synopsys DesignWare Cores PCI Express Controller Databook - DWC PCIe
Root Port, Version 5.40a, March 2019, p.55 - 78.
[2] Synopsys DesignWare Cores PCI Express Controller Databook - DWC PCIe
Endpoint, Version 5.40a, March 2019, p.58 - 81.

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v3:
- This is a new patch unpinned from the next one:
https://lore.kernel.org/linux-pci/[email protected]/
by the Rob' request. (@Rob)
- Drop synonymous from the names list since the device schemas create
their own enumerations anyway.

Changelog v5:
- Add platform-specific clock/reset names, but mark them as deprecated.

Changelog v6:
- Move the common *-names definitions to the RP/EP schemas. Thus drop
the 'definitions' property. (@Rob)
- Drop the 'deprecated' keywords from the vendor-specific names. (@Rob)
---
.../bindings/pci/snps,dw-pcie-common.yaml | 120 ++++++++++++++++++
.../bindings/pci/snps,dw-pcie-ep.yaml | 6 +
.../devicetree/bindings/pci/snps,dw-pcie.yaml | 2 -
3 files changed, 126 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
index 13c41cd50e54..4d9efcea3859 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-common.yaml
@@ -58,6 +58,126 @@ properties:
minItems: 1
maxItems: 26

+ clocks:
+ description:
+ DWC PCIe reference manual explicitly defines a set of the clocks required
+ to get the controller working correctly. In general all of them can
+ be divided into two groups':' application and core clocks. Note the
+ platforms may have some of the clock sources unspecified in case if the
+ corresponding domains are fed up from a common clock source.
+ minItems: 1
+ maxItems: 7
+
+ clock-names:
+ minItems: 1
+ maxItems: 7
+ items:
+ oneOf:
+ - description:
+ Data Bus Interface (DBI) clock. Clock signal for the AXI-bus
+ interface of the Configuration-Dependent Module, which is
+ basically the set of the controller CSRs.
+ const: dbi
+ - description:
+ Application AXI-bus Master interface clock. Basically this is
+ a clock for the controller DMA interface (PCI-to-CPU).
+ const: mstr
+ - description:
+ Application AXI-bus Slave interface clock. This is a clock for
+ the CPU-to-PCI memory IO interface.
+ const: slv
+ - description:
+ Controller Core-PCS PIPE interface clock. It's normally
+ supplied by an external PCS-PHY.
+ const: pipe
+ - description:
+ Controller Primary clock. It's assumed that all controller input
+ signals (except resets) are synchronous to this clock.
+ const: core
+ - description:
+ Auxiliary clock for the controller PMC domain. The controller
+ partitioning implies having some parts to operate with this
+ clock in some power management states.
+ const: aux
+ - description:
+ Generic reference clock. In case if there are several
+ interfaces fed up with a common clock source it's advisable to
+ define it with this name (for instance pipe, core and aux can
+ be connected to a single source of the periodic signal).
+ const: ref
+ - description:
+ Clock for the PHY registers interface. Originally this is
+ a PHY-viewport-based interface, but some platform may have
+ specifically designed one.
+ const: phy_reg
+ - description:
+ Vendor-specific clock names. Consider using the generic names
+ above for new bindings.
+ oneOf:
+ - description: See native 'dbi' clock for details
+ enum: [ pcie, pcie_apb_sys, aclk_dbi ]
+ - description: See native 'mstr/slv' clock for details
+ enum: [ pcie_bus, pcie_inbound_axi, pcie_aclk, aclk_mst, aclk_slv ]
+ - description: See native 'pipe' clock for details
+ enum: [ pcie_phy, pcie_phy_ref, link ]
+ - description: See native 'aux' clock for details
+ enum: [ pcie_aux ]
+ - description: See native 'ref' clock for details.
+ enum: [ gio ]
+ - description: See nativs 'phy_reg' clock for details
+ enum: [ pcie_apb_phy, pclk ]
+
+ resets:
+ description:
+ DWC PCIe reference manual explicitly defines a set of the reset
+ signals required to be de-asserted to properly activate the controller
+ sub-parts. All of these signals can be divided into two sub-groups':'
+ application and core resets with respect to the main sub-domains they
+ are supposed to reset. Note the platforms may have some of these signals
+ unspecified in case if they are automatically handled or aggregated into
+ a comprehensive control module.
+ minItems: 1
+ maxItems: 10
+
+ reset-names:
+ minItems: 1
+ maxItems: 10
+ items:
+ oneOf:
+ - description: Data Bus Interface (DBI) domain reset
+ const: dbi
+ - description: AXI-bus Master interface reset
+ const: mstr
+ - description: AXI-bus Slave interface reset
+ const: slv
+ - description: Application-dependent interface reset
+ const: app
+ - description: Controller Non-sticky CSR flags reset
+ const: non-sticky
+ - description: Controller sticky CSR flags reset
+ const: sticky
+ - description: PIPE-interface (Core-PCS) logic reset
+ const: pipe
+ - description:
+ Controller primary reset (resets everything except PMC module)
+ const: core
+ - description: PCS/PHY block reset
+ const: phy
+ - description: PMC hot reset signal
+ const: hot
+ - description: Cold reset signal
+ const: pwr
+ - description:
+ Vendor-specific reset names. Consider using the generic names
+ above for new bindings.
+ oneOf:
+ - description: See native 'app' reset for details
+ enum: [ apps, gio, apb ]
+ - description: See native 'phy' reset for details
+ enum: [ pciephy, link ]
+ - description: See native 'pwr' reset for details
+ enum: [ turnoff ]
+
phys:
description:
There can be up to the number of possible lanes PHYs specified placed in
diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
index f4d7eb2dec4d..8fc2151691a4 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
@@ -180,6 +180,12 @@ examples:
interrupts = <23>, <24>;
interrupt-names = "dma0", "dma1";

+ clocks = <&sys_clk 12>, <&sys_clk 24>;
+ clock-names = "dbi", "ref";
+
+ resets = <&sys_rst 12>, <&sys_rst 24>;
+ reset-names = "dbi", "phy";
+
phys = <&pcie_phy0>, <&pcie_phy1>, <&pcie_phy2>, <&pcie_phy3>;
phy-names = "pcie0", "pcie1", "pcie2", "pcie3";

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
index 59d3bbb5883a..c62c8fe517ae 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
@@ -195,8 +195,6 @@ properties:
- contains:
const: msi

- clocks: true
-
additionalProperties: true

required:
--
2.38.1



2022-11-13 20:08:31

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 20/20] PCI: dwc: Add Baikal-T1 PCIe controller support

Baikal-T1 SoC is equipped with DWC PCIe v4.60a host controller. It can be
trained to work up to Gen.3 speed over up to x4 lanes. The host controller
is attached to the DW PCIe 3.0 PCS via the PIPE-4 interface, which in its
turn is connected to the DWC 10G PHY. The whole system is supposed to be
fed up with four clock sources: DBI peripheral clock, AXI application
clocks and external PHY/core reference clock generating the 100MHz signal.
In addition to that the platform provide a way to reset each part of the
controller: sticky/non-sticky bits, host controller core, PIPE interface,
PCS/PHY and Hot/Power reset signal. The driver also provides a way to
handle the GPIO-based PERST# signal.

Note due to the Baikal-T1 MMIO peculiarity we have to implement the DBI
interface accessors which make sure the IO operations are dword-aligned.

Signed-off-by: Serge Semin <[email protected]>

---

Changelog v2:
- Rename 'syscon' property to 'baikal,bt1-syscon'.

Changelog v3:
- Use the clocks/resets handlers defined in the DW PCIe core descriptor.
(@Rob)
- Redefine PCI host bridge config space accessors with the generic
pci_generic_config_read32() and pci_generic_config_write32() methods.
(@Rob)

Changelog v4:
- Drop PCIBIOS_* macros usage. (@Rob)
- Add "static const" to the dw_pcie_ops and dw_pcie_host_ops structure
instances. (@Bjorn)
- Rename bt1_pcie_dw_ops to bt1_pcie_ops. (@Bjorn)
- Rename bt1_pcie_ops to bt1_pci_ops. (@Bjorn)
- Use start_link/stop_link suffixes in the corresponding callbacks.
(@Bjorn)
- Change the get_res() method suffix to being get_resources(). (@Bjorn)
- Change *_{add,del}_dw_port() method to *_{add,del}_port(). (@Bjorn)
- Drop dma_coerce_mask_and_coherent() applied to the PCI host bridge
kernel device instance. (@Bjorn)
- Add the comment above the dma_set_mask_and_coherent() method usage
regarding the controller eDMA feature. (@Bjorn)
- Fix the comment above the core reset controls assertion. (@Bjorn)
- Replace delays and timeout numeric literals with macros. (@Bjorn)

Changelog v6:
- Move the DMA-mask setup to the eDMA driver. (@Robin)

Changelog v7:
- Replace if-then-dev_err_probe-return statement with just
return-dev_err_probe one.
---
drivers/pci/controller/dwc/Kconfig | 9 +
drivers/pci/controller/dwc/Makefile | 1 +
drivers/pci/controller/dwc/pcie-bt1.c | 643 ++++++++++++++++++++++++++
3 files changed, 653 insertions(+)
create mode 100644 drivers/pci/controller/dwc/pcie-bt1.c

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 62ce3abf0f19..771b8b146623 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -222,6 +222,15 @@ config PCIE_ARTPEC6_EP
Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
endpoint mode. This uses the DesignWare core.

+config PCIE_BT1
+ tristate "Baikal-T1 PCIe controller"
+ depends on MIPS_BAIKAL_T1 || COMPILE_TEST
+ depends on PCI_MSI_IRQ_DOMAIN
+ select PCIE_DW_HOST
+ help
+ Enables support for the PCIe controller in the Baikal-T1 SoC to work
+ in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
+
config PCIE_ROCKCHIP_DW_HOST
bool "Rockchip DesignWare PCIe controller"
select PCIE_DW
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index 8ba7b67f5e50..bf5c311875a1 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
+obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
diff --git a/drivers/pci/controller/dwc/pcie-bt1.c b/drivers/pci/controller/dwc/pcie-bt1.c
new file mode 100644
index 000000000000..3346770e6654
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-bt1.c
@@ -0,0 +1,643 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ * Vadim Vlasov <[email protected]>
+ * Serge Semin <[email protected]>
+ *
+ * Baikal-T1 PCIe controller driver
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+
+/* Baikal-T1 System CCU control registers */
+#define BT1_CCU_PCIE_CLKC 0x140
+#define BT1_CCU_PCIE_REQ_PCS_CLK BIT(16)
+#define BT1_CCU_PCIE_REQ_MAC_CLK BIT(17)
+#define BT1_CCU_PCIE_REQ_PIPE_CLK BIT(18)
+
+#define BT1_CCU_PCIE_RSTC 0x144
+#define BT1_CCU_PCIE_REQ_LINK_RST BIT(13)
+#define BT1_CCU_PCIE_REQ_SMLH_RST BIT(14)
+#define BT1_CCU_PCIE_REQ_PHY_RST BIT(16)
+#define BT1_CCU_PCIE_REQ_CORE_RST BIT(24)
+#define BT1_CCU_PCIE_REQ_STICKY_RST BIT(26)
+#define BT1_CCU_PCIE_REQ_NSTICKY_RST BIT(27)
+
+#define BT1_CCU_PCIE_PMSC 0x148
+#define BT1_CCU_PCIE_LTSSM_STATE_MASK GENMASK(5, 0)
+#define BT1_CCU_PCIE_LTSSM_DET_QUIET 0x00
+#define BT1_CCU_PCIE_LTSSM_DET_ACT 0x01
+#define BT1_CCU_PCIE_LTSSM_POLL_ACT 0x02
+#define BT1_CCU_PCIE_LTSSM_POLL_COMP 0x03
+#define BT1_CCU_PCIE_LTSSM_POLL_CONF 0x04
+#define BT1_CCU_PCIE_LTSSM_PRE_DET_QUIET 0x05
+#define BT1_CCU_PCIE_LTSSM_DET_WAIT 0x06
+#define BT1_CCU_PCIE_LTSSM_CFG_LNKWD_START 0x07
+#define BT1_CCU_PCIE_LTSSM_CFG_LNKWD_ACEPT 0x08
+#define BT1_CCU_PCIE_LTSSM_CFG_LNNUM_WAIT 0x09
+#define BT1_CCU_PCIE_LTSSM_CFG_LNNUM_ACEPT 0x0a
+#define BT1_CCU_PCIE_LTSSM_CFG_COMPLETE 0x0b
+#define BT1_CCU_PCIE_LTSSM_CFG_IDLE 0x0c
+#define BT1_CCU_PCIE_LTSSM_RCVR_LOCK 0x0d
+#define BT1_CCU_PCIE_LTSSM_RCVR_SPEED 0x0e
+#define BT1_CCU_PCIE_LTSSM_RCVR_RCVRCFG 0x0f
+#define BT1_CCU_PCIE_LTSSM_RCVR_IDLE 0x10
+#define BT1_CCU_PCIE_LTSSM_L0 0x11
+#define BT1_CCU_PCIE_LTSSM_L0S 0x12
+#define BT1_CCU_PCIE_LTSSM_L123_SEND_IDLE 0x13
+#define BT1_CCU_PCIE_LTSSM_L1_IDLE 0x14
+#define BT1_CCU_PCIE_LTSSM_L2_IDLE 0x15
+#define BT1_CCU_PCIE_LTSSM_L2_WAKE 0x16
+#define BT1_CCU_PCIE_LTSSM_DIS_ENTRY 0x17
+#define BT1_CCU_PCIE_LTSSM_DIS_IDLE 0x18
+#define BT1_CCU_PCIE_LTSSM_DISABLE 0x19
+#define BT1_CCU_PCIE_LTSSM_LPBK_ENTRY 0x1a
+#define BT1_CCU_PCIE_LTSSM_LPBK_ACTIVE 0x1b
+#define BT1_CCU_PCIE_LTSSM_LPBK_EXIT 0x1c
+#define BT1_CCU_PCIE_LTSSM_LPBK_EXIT_TOUT 0x1d
+#define BT1_CCU_PCIE_LTSSM_HOT_RST_ENTRY 0x1e
+#define BT1_CCU_PCIE_LTSSM_HOT_RST 0x1f
+#define BT1_CCU_PCIE_LTSSM_RCVR_EQ0 0x20
+#define BT1_CCU_PCIE_LTSSM_RCVR_EQ1 0x21
+#define BT1_CCU_PCIE_LTSSM_RCVR_EQ2 0x22
+#define BT1_CCU_PCIE_LTSSM_RCVR_EQ3 0x23
+#define BT1_CCU_PCIE_SMLH_LINKUP BIT(6)
+#define BT1_CCU_PCIE_RDLH_LINKUP BIT(7)
+#define BT1_CCU_PCIE_PM_LINKSTATE_L0S BIT(8)
+#define BT1_CCU_PCIE_PM_LINKSTATE_L1 BIT(9)
+#define BT1_CCU_PCIE_PM_LINKSTATE_L2 BIT(10)
+#define BT1_CCU_PCIE_L1_PENDING BIT(12)
+#define BT1_CCU_PCIE_REQ_EXIT_L1 BIT(14)
+#define BT1_CCU_PCIE_LTSSM_RCVR_EQ BIT(15)
+#define BT1_CCU_PCIE_PM_DSTAT_MASK GENMASK(18, 16)
+#define BT1_CCU_PCIE_PM_PME_EN BIT(20)
+#define BT1_CCU_PCIE_PM_PME_STATUS BIT(21)
+#define BT1_CCU_PCIE_AUX_PM_EN BIT(22)
+#define BT1_CCU_PCIE_AUX_PWR_DET BIT(23)
+#define BT1_CCU_PCIE_WAKE_DET BIT(24)
+#define BT1_CCU_PCIE_TURNOFF_REQ BIT(30)
+#define BT1_CCU_PCIE_TURNOFF_ACK BIT(31)
+
+#define BT1_CCU_PCIE_GENC 0x14c
+#define BT1_CCU_PCIE_LTSSM_EN BIT(1)
+#define BT1_CCU_PCIE_DBI2_MODE BIT(2)
+#define BT1_CCU_PCIE_MGMT_EN BIT(3)
+#define BT1_CCU_PCIE_RXLANE_FLIP_EN BIT(16)
+#define BT1_CCU_PCIE_TXLANE_FLIP_EN BIT(17)
+#define BT1_CCU_PCIE_SLV_XFER_PEND BIT(24)
+#define BT1_CCU_PCIE_RCV_XFER_PEND BIT(25)
+#define BT1_CCU_PCIE_DBI_XFER_PEND BIT(26)
+#define BT1_CCU_PCIE_DMA_XFER_PEND BIT(27)
+
+#define BT1_CCU_PCIE_LTSSM_LINKUP(_pmsc) \
+({ \
+ int __state = FIELD_GET(BT1_CCU_PCIE_LTSSM_STATE_MASK, _pmsc); \
+ __state >= BT1_CCU_PCIE_LTSSM_L0 && __state <= BT1_CCU_PCIE_LTSSM_L2_WAKE; \
+})
+
+/* Baikal-T1 PCIe specific control registers */
+#define BT1_PCIE_AXI2MGM_LANENUM 0xd04
+#define BT1_PCIE_AXI2MGM_LANESEL_MASK GENMASK(3, 0)
+
+#define BT1_PCIE_AXI2MGM_ADDRCTL 0xd08
+#define BT1_PCIE_AXI2MGM_PHYREG_ADDR_MASK GENMASK(20, 0)
+#define BT1_PCIE_AXI2MGM_READ_FLAG BIT(29)
+#define BT1_PCIE_AXI2MGM_DONE BIT(30)
+#define BT1_PCIE_AXI2MGM_BUSY BIT(31)
+
+#define BT1_PCIE_AXI2MGM_WRITEDATA 0xd0c
+#define BT1_PCIE_AXI2MGM_WDATA GENMASK(15, 0)
+
+#define BT1_PCIE_AXI2MGM_READDATA 0xd10
+#define BT1_PCIE_AXI2MGM_RDATA GENMASK(15, 0)
+
+/* Generic Baikal-T1 PCIe interface resources */
+#define BT1_PCIE_NUM_APP_CLKS ARRAY_SIZE(bt1_pcie_app_clks)
+#define BT1_PCIE_NUM_CORE_CLKS ARRAY_SIZE(bt1_pcie_core_clks)
+#define BT1_PCIE_NUM_APP_RSTS ARRAY_SIZE(bt1_pcie_app_rsts)
+#define BT1_PCIE_NUM_CORE_RSTS ARRAY_SIZE(bt1_pcie_core_rsts)
+
+/* PCIe bus setup delays and timeouts */
+#define BT1_PCIE_RST_DELAY_MS 100
+#define BT1_PCIE_RUN_DELAY_US 100
+#define BT1_PCIE_REQ_DELAY_US 1
+#define BT1_PCIE_REQ_TIMEOUT_US 1000
+#define BT1_PCIE_LNK_DELAY_US 1000
+#define BT1_PCIE_LNK_TIMEOUT_US 1000000
+
+static const enum dw_pcie_app_clk bt1_pcie_app_clks[] = {
+ DW_PCIE_DBI_CLK, DW_PCIE_MSTR_CLK, DW_PCIE_SLV_CLK,
+};
+
+static const enum dw_pcie_core_clk bt1_pcie_core_clks[] = {
+ DW_PCIE_REF_CLK,
+};
+
+static const enum dw_pcie_app_rst bt1_pcie_app_rsts[] = {
+ DW_PCIE_MSTR_RST, DW_PCIE_SLV_RST,
+};
+
+static const enum dw_pcie_core_rst bt1_pcie_core_rsts[] = {
+ DW_PCIE_NON_STICKY_RST, DW_PCIE_STICKY_RST, DW_PCIE_CORE_RST,
+ DW_PCIE_PIPE_RST, DW_PCIE_PHY_RST, DW_PCIE_HOT_RST, DW_PCIE_PWR_RST,
+};
+
+struct bt1_pcie {
+ struct dw_pcie dw;
+ struct platform_device *pdev;
+ struct regmap *sys_regs;
+};
+#define to_bt1_pcie(_dw) container_of(_dw, struct bt1_pcie, dw)
+
+/*
+ * Baikal-T1 MMIO space must be read/written by the dword-aligned
+ * instructions. Note the methods are optimized to have the dword operations
+ * performed with minimum overhead as the most frequently used ones.
+ */
+static int bt1_pcie_read_mmio(void __iomem *addr, int size, u32 *val)
+{
+ unsigned int ofs = (uintptr_t)addr & 0x3;
+
+ if (!IS_ALIGNED((uintptr_t)addr, size))
+ return -EINVAL;
+
+ *val = readl(addr - ofs) >> ofs * BITS_PER_BYTE;
+ if (size == 4) {
+ return 0;
+ } else if (size == 2) {
+ *val &= 0xffff;
+ return 0;
+ } else if (size == 1) {
+ *val &= 0xff;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int bt1_pcie_write_mmio(void __iomem *addr, int size, u32 val)
+{
+ unsigned int ofs = (uintptr_t)addr & 0x3;
+ u32 tmp, mask;
+
+ if (!IS_ALIGNED((uintptr_t)addr, size))
+ return -EINVAL;
+
+ if (size == 4) {
+ writel(val, addr);
+ return 0;
+ } else if (size == 2 || size == 1) {
+ mask = GENMASK(size * BITS_PER_BYTE - 1, 0);
+ tmp = readl(addr - ofs) & ~(mask << ofs * BITS_PER_BYTE);
+ tmp |= (val & mask) << ofs * BITS_PER_BYTE;
+ writel(tmp, addr - ofs);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static u32 bt1_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
+ size_t size)
+{
+ int ret;
+ u32 val;
+
+ ret = bt1_pcie_read_mmio(base + reg, size, &val);
+ if (ret) {
+ dev_err(pci->dev, "Read DBI address failed\n");
+ return ~0U;
+ }
+
+ return val;
+}
+
+static void bt1_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
+ size_t size, u32 val)
+{
+ int ret;
+
+ ret = bt1_pcie_write_mmio(base + reg, size, val);
+ if (ret)
+ dev_err(pci->dev, "Write DBI address failed\n");
+}
+
+static void bt1_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg,
+ size_t size, u32 val)
+{
+ struct bt1_pcie *btpci = to_bt1_pcie(pci);
+ int ret;
+
+ regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
+ BT1_CCU_PCIE_DBI2_MODE, BT1_CCU_PCIE_DBI2_MODE);
+
+ ret = bt1_pcie_write_mmio(base + reg, size, val);
+ if (ret)
+ dev_err(pci->dev, "Write DBI2 address failed\n");
+
+ regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
+ BT1_CCU_PCIE_DBI2_MODE, 0);
+}
+
+static int bt1_pcie_start_link(struct dw_pcie *pci)
+{
+ struct bt1_pcie *btpci = to_bt1_pcie(pci);
+ u32 val;
+ int ret;
+
+ /*
+ * Enable LTSSM and make sure it was able to establish both PHY and
+ * data links. This procedure shall work fine to reach 2.5 GT/s speed.
+ */
+ regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
+ BT1_CCU_PCIE_LTSSM_EN, BT1_CCU_PCIE_LTSSM_EN);
+
+ ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_PMSC, val,
+ (val & BT1_CCU_PCIE_SMLH_LINKUP),
+ BT1_PCIE_LNK_DELAY_US, BT1_PCIE_LNK_TIMEOUT_US);
+ if (ret) {
+ dev_err(pci->dev, "LTSSM failed to set PHY link up\n");
+ return ret;
+ }
+
+ ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_PMSC, val,
+ (val & BT1_CCU_PCIE_RDLH_LINKUP),
+ BT1_PCIE_LNK_DELAY_US, BT1_PCIE_LNK_TIMEOUT_US);
+ if (ret) {
+ dev_err(pci->dev, "LTSSM failed to set data link up\n");
+ return ret;
+ }
+
+ /*
+ * Activate direct speed change after the link is established in an
+ * attempt to reach a higher bus performance (up to Gen.3 - 8.0 GT/s).
+ * This is required at least to get 8.0 GT/s speed.
+ */
+ val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ val |= PORT_LOGIC_SPEED_CHANGE;
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+
+ ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_PMSC, val,
+ BT1_CCU_PCIE_LTSSM_LINKUP(val),
+ BT1_PCIE_LNK_DELAY_US, BT1_PCIE_LNK_TIMEOUT_US);
+ if (ret)
+ dev_err(pci->dev, "LTSSM failed to get into L0 state\n");
+
+ return ret;
+}
+
+static void bt1_pcie_stop_link(struct dw_pcie *pci)
+{
+ struct bt1_pcie *btpci = to_bt1_pcie(pci);
+
+ regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
+ BT1_CCU_PCIE_LTSSM_EN, 0);
+}
+
+static const struct dw_pcie_ops bt1_pcie_ops = {
+ .read_dbi = bt1_pcie_read_dbi,
+ .write_dbi = bt1_pcie_write_dbi,
+ .write_dbi2 = bt1_pcie_write_dbi2,
+ .start_link = bt1_pcie_start_link,
+ .stop_link = bt1_pcie_stop_link,
+};
+
+static struct pci_ops bt1_pci_ops = {
+ .map_bus = dw_pcie_own_conf_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
+};
+
+static int bt1_pcie_get_resources(struct bt1_pcie *btpci)
+{
+ struct device *dev = btpci->dw.dev;
+ int i;
+
+ /* DBI access is supposed to be performed by the dword-aligned IOs */
+ btpci->dw.pp.bridge->ops = &bt1_pci_ops;
+
+ /* These CSRs are in MMIO so we won't check the regmap-methods status */
+ btpci->sys_regs =
+ syscon_regmap_lookup_by_phandle(dev->of_node, "baikal,bt1-syscon");
+ if (IS_ERR(btpci->sys_regs))
+ return dev_err_probe(dev, PTR_ERR(btpci->sys_regs),
+ "Failed to get syscon\n");
+
+ /* Make sure all the required resources have been specified */
+ for (i = 0; i < BT1_PCIE_NUM_APP_CLKS; i++) {
+ if (!btpci->dw.app_clks[bt1_pcie_app_clks[i]].clk) {
+ dev_err(dev, "App clocks set is incomplete\n");
+ return -ENOENT;
+ }
+ }
+
+ for (i = 0; i < BT1_PCIE_NUM_CORE_CLKS; i++) {
+ if (!btpci->dw.core_clks[bt1_pcie_core_clks[i]].clk) {
+ dev_err(dev, "Core clocks set is incomplete\n");
+ return -ENOENT;
+ }
+ }
+
+ for (i = 0; i < BT1_PCIE_NUM_APP_RSTS; i++) {
+ if (!btpci->dw.app_rsts[bt1_pcie_app_rsts[i]].rstc) {
+ dev_err(dev, "App resets set is incomplete\n");
+ return -ENOENT;
+ }
+ }
+
+ for (i = 0; i < BT1_PCIE_NUM_CORE_RSTS; i++) {
+ if (!btpci->dw.core_rsts[bt1_pcie_core_rsts[i]].rstc) {
+ dev_err(dev, "Core resets set is incomplete\n");
+ return -ENOENT;
+ }
+ }
+
+ return 0;
+}
+
+static void bt1_pcie_full_stop_bus(struct bt1_pcie *btpci, bool init)
+{
+ struct device *dev = btpci->dw.dev;
+ struct dw_pcie *pci = &btpci->dw;
+ int ret;
+
+ /* Disable LTSSM for sure */
+ regmap_update_bits(btpci->sys_regs, BT1_CCU_PCIE_GENC,
+ BT1_CCU_PCIE_LTSSM_EN, 0);
+
+ /*
+ * Application reset controls are trigger-based so assert the core
+ * resets only.
+ */
+ ret = reset_control_bulk_assert(DW_PCIE_NUM_CORE_RSTS, pci->core_rsts);
+ if (ret)
+ dev_err(dev, "Failed to assert core resets\n");
+
+ /*
+ * Clocks are disabled by default at least in accordance with the clk
+ * enable counter value on init stage.
+ */
+ if (!init) {
+ clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
+
+ clk_bulk_disable_unprepare(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
+ }
+
+ /* The peripheral devices are unavailable anyway so reset them too */
+ gpiod_set_value_cansleep(pci->pe_rst, 1);
+
+ /* Make sure all the resets are settled */
+ msleep(BT1_PCIE_RST_DELAY_MS);
+}
+
+/*
+ * Implements the cold reset procedure in accordance with the reference manual
+ * and available PM signals.
+ */
+static int bt1_pcie_cold_start_bus(struct bt1_pcie *btpci)
+{
+ struct device *dev = btpci->dw.dev;
+ struct dw_pcie *pci = &btpci->dw;
+ u32 val;
+ int ret;
+
+ /* First get out of the Power/Hot reset state */
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert PHY reset\n");
+ return ret;
+ }
+
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert hot reset\n");
+ goto err_assert_pwr_rst;
+ }
+
+ /* Wait for the PM-core to stop requesting the PHY reset */
+ ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
+ !(val & BT1_CCU_PCIE_REQ_PHY_RST),
+ BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "Timed out waiting for PM to stop PHY resetting\n");
+ goto err_assert_hot_rst;
+ }
+
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert PHY reset\n");
+ goto err_assert_hot_rst;
+ }
+
+ /* Clocks can be now enabled, but the ref one is crucial at this stage */
+ ret = clk_bulk_prepare_enable(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
+ if (ret) {
+ dev_err(dev, "Failed to enable app clocks\n");
+ goto err_assert_phy_rst;
+ }
+
+ ret = clk_bulk_prepare_enable(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
+ if (ret) {
+ dev_err(dev, "Failed to enable ref clocks\n");
+ goto err_disable_app_clk;
+ }
+
+ /* Wait for the PM to stop requesting the controller core reset */
+ ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
+ !(val & BT1_CCU_PCIE_REQ_CORE_RST),
+ BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "Timed out waiting for PM to stop core resetting\n");
+ goto err_disable_core_clk;
+ }
+
+ /* PCS-PIPE interface and controller core can be now activated */
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert PIPE reset\n");
+ goto err_disable_core_clk;
+ }
+
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert core reset\n");
+ goto err_assert_pipe_rst;
+ }
+
+ /* It's recommended to reset the core and application logic together */
+ ret = reset_control_bulk_reset(DW_PCIE_NUM_APP_RSTS, pci->app_rsts);
+ if (ret) {
+ dev_err(dev, "Failed to reset app domain\n");
+ goto err_assert_core_rst;
+ }
+
+ /* Sticky/Non-sticky CSR flags can be now unreset too */
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert sticky reset\n");
+ goto err_assert_core_rst;
+ }
+
+ ret = reset_control_deassert(pci->core_rsts[DW_PCIE_NON_STICKY_RST].rstc);
+ if (ret) {
+ dev_err(dev, "Failed to deassert non-sticky reset\n");
+ goto err_assert_sticky_rst;
+ }
+
+ /* Activate the PCIe bus peripheral devices */
+ gpiod_set_value_cansleep(pci->pe_rst, 0);
+
+ /* Make sure the state is settled (LTSSM is still disabled though) */
+ usleep_range(BT1_PCIE_RUN_DELAY_US, BT1_PCIE_RUN_DELAY_US + 100);
+
+ return 0;
+
+err_assert_sticky_rst:
+ reset_control_assert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
+
+err_assert_core_rst:
+ reset_control_assert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
+
+err_assert_pipe_rst:
+ reset_control_assert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
+
+err_disable_core_clk:
+ clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
+
+err_disable_app_clk:
+ clk_bulk_disable_unprepare(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
+
+err_assert_phy_rst:
+ reset_control_assert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
+
+err_assert_hot_rst:
+ reset_control_assert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
+
+err_assert_pwr_rst:
+ reset_control_assert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
+
+ return ret;
+}
+
+static int bt1_pcie_host_init(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct bt1_pcie *btpci = to_bt1_pcie(pci);
+ int ret;
+
+ ret = bt1_pcie_get_resources(btpci);
+ if (ret)
+ return ret;
+
+ bt1_pcie_full_stop_bus(btpci, true);
+
+ return bt1_pcie_cold_start_bus(btpci);
+}
+
+static void bt1_pcie_host_deinit(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct bt1_pcie *btpci = to_bt1_pcie(pci);
+
+ bt1_pcie_full_stop_bus(btpci, false);
+}
+
+static const struct dw_pcie_host_ops bt1_pcie_host_ops = {
+ .host_init = bt1_pcie_host_init,
+ .host_deinit = bt1_pcie_host_deinit,
+};
+
+static struct bt1_pcie *bt1_pcie_create_data(struct platform_device *pdev)
+{
+ struct bt1_pcie *btpci;
+
+ btpci = devm_kzalloc(&pdev->dev, sizeof(*btpci), GFP_KERNEL);
+ if (!btpci)
+ return ERR_PTR(-ENOMEM);
+
+ btpci->pdev = pdev;
+
+ platform_set_drvdata(pdev, btpci);
+
+ return btpci;
+}
+
+static int bt1_pcie_add_port(struct bt1_pcie *btpci)
+{
+ struct device *dev = &btpci->pdev->dev;
+ int ret;
+
+ btpci->dw.version = DW_PCIE_VER_460A;
+ btpci->dw.dev = dev;
+ btpci->dw.ops = &bt1_pcie_ops;
+
+ btpci->dw.pp.num_vectors = MAX_MSI_IRQS;
+ btpci->dw.pp.ops = &bt1_pcie_host_ops;
+
+ dw_pcie_cap_set(&btpci->dw, REQ_RES);
+
+ ret = dw_pcie_host_init(&btpci->dw.pp);
+
+ return dev_err_probe(dev, ret, "Failed to initialize DWC PCIe host\n");
+}
+
+static void bt1_pcie_del_port(struct bt1_pcie *btpci)
+{
+ dw_pcie_host_deinit(&btpci->dw.pp);
+}
+
+static int bt1_pcie_probe(struct platform_device *pdev)
+{
+ struct bt1_pcie *btpci;
+
+ btpci = bt1_pcie_create_data(pdev);
+ if (IS_ERR(btpci))
+ return PTR_ERR(btpci);
+
+ return bt1_pcie_add_port(btpci);
+}
+
+static int bt1_pcie_remove(struct platform_device *pdev)
+{
+ struct bt1_pcie *btpci = platform_get_drvdata(pdev);
+
+ bt1_pcie_del_port(btpci);
+
+ return 0;
+}
+
+static const struct of_device_id bt1_pcie_of_match[] = {
+ { .compatible = "baikal,bt1-pcie" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bt1_pcie_of_match);
+
+static struct platform_driver bt1_pcie_driver = {
+ .probe = bt1_pcie_probe,
+ .remove = bt1_pcie_remove,
+ .driver = {
+ .name = "bt1-pcie",
+ .of_match_table = bt1_pcie_of_match,
+ },
+};
+module_platform_driver(bt1_pcie_driver);
+
+MODULE_AUTHOR("Serge Semin <[email protected]>");
+MODULE_DESCRIPTION("Baikal-T1 PCIe driver");
+MODULE_LICENSE("GPL");
--
2.38.1



2022-11-13 20:10:25

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 08/20] dt-bindings: PCI: dwc: Add max-functions EP property

In accordance with [1] the CX_NFUNC IP-core synthesize parameter is
responsible for the number of physical functions to support in the EP
mode. Its upper limit is 32. Let's use it to constrain the number of
PCIe functions the DW PCIe EP DT-nodes can advertise.

[1] Synopsys DesignWare Cores PCI Express Controller Databook - DWC PCIe
Endpoint, Version 5.40a, March 2019, p. 887.

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v3:
- This is a new patch unpinned from the next one:
https://lore.kernel.org/linux-pci/[email protected]/
by the Rob' request. (@Rob)
---
Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
index d04001248b53..71dd19ae1060 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
@@ -41,6 +41,9 @@ properties:
items:
enum: [dbi, dbi2, config, atu, addr_space, link, atu_dma, appl]

+ max-functions:
+ maximum: 32
+
required:
- compatible
- reg
@@ -61,4 +64,5 @@ examples:
phy-names = "pcie0", "pcie1", "pcie2", "pcie3";

max-link-speed = <3>;
+ max-functions = /bits/ 8 <4>;
};
--
2.38.1



2022-11-13 20:35:01

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 14/20] dt-bindings: PCI: dwc: Add Baikal-T1 PCIe Root Port bindings

Baikal-T1 SoC is equipped with DWC PCIe v4.60a Root Port controller, which
link can be trained to work on up to Gen.3 speed over up to x4 lanes. The
controller is supposed to be fed up with four clock sources: DBI
peripheral clock, AXI application Tx/Rx clocks and external PHY/core
reference clock generating the 100MHz signal. In addition to that the
platform provide a way to reset each part of the controller:
sticky/non-sticky bits, host controller core, PIPE interface, PCS/PHY and
Hot/Power reset signal. The Root Port controller is equipped with multiple
IRQ lines like MSI, system AER, PME, HP, Bandwidth change, Link
equalization request and eDMA ones. The registers space is accessed over
the DBI interface. There can be no more than four inbound or outbound iATU
windows configured.

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>

---

Changelog v2:
- Rename 'syscon' property to 'baikal,bt1-syscon'.
- Fix the 'compatible' property definition to being more specific about
what strings are supposed to be used. Due to that we had to add the
select property to evaluate the schema against the Baikal-T1 PCIe DT
nodes only.

Changelog v5:
- Drop generic fallback names from the compatible property constraints.
(@Rob)
- Define ordered {reg,interrupt,clock,reset}-names properties. (@Rob)
- Drop minItems from the clocks and reset properties, since it equals
to the maxItems for them.
- Drop num-ob-windows and num-ib-windows properties constraint. (@Rob)
---
.../bindings/pci/baikal,bt1-pcie.yaml | 168 ++++++++++++++++++
1 file changed, 168 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/baikal,bt1-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/baikal,bt1-pcie.yaml b/Documentation/devicetree/bindings/pci/baikal,bt1-pcie.yaml
new file mode 100644
index 000000000000..8eaa07ae9774
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/baikal,bt1-pcie.yaml
@@ -0,0 +1,168 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/baikal,bt1-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Baikal-T1 PCIe Root Port Controller
+
+maintainers:
+ - Serge Semin <[email protected]>
+
+description:
+ Embedded into Baikal-T1 SoC Root Complex controller with a single port
+ activated. It's based on the DWC RC PCIe v4.60a IP-core, which is configured
+ to have just a single Root Port function and is capable of establishing the
+ link up to Gen.3 speed on x4 lanes. It doesn't have embedded clock and reset
+ control module, so the proper interface initialization is supposed to be
+ performed by software. There four in- and four outbound iATU regions
+ which can be used to emit all required TLP types on the PCIe bus.
+
+allOf:
+ - $ref: /schemas/pci/snps,dw-pcie.yaml#
+
+properties:
+ compatible:
+ const: baikal,bt1-pcie
+
+ reg:
+ description:
+ DBI, DBI2 and at least 4KB outbound iATU-capable region for the
+ peripheral devices CFG-space access.
+ maxItems: 3
+
+ reg-names:
+ items:
+ - const: dbi
+ - const: dbi2
+ - const: config
+
+ interrupts:
+ description:
+ MSI, AER, PME, Hot-plug, Link Bandwidth Management, Link Equalization
+ request and eight Read/Write eDMA IRQ lines are available.
+ maxItems: 14
+
+ interrupt-names:
+ items:
+ - const: dma0
+ - const: dma1
+ - const: dma2
+ - const: dma3
+ - const: dma4
+ - const: dma5
+ - const: dma6
+ - const: dma7
+ - const: msi
+ - const: aer
+ - const: pme
+ - const: hp
+ - const: bw_mg
+ - const: l_eq
+
+ clocks:
+ description:
+ DBI (attached to the APB bus), AXI-bus master and slave interfaces
+ are fed up by the dedicated application clocks. A common reference
+ clock signal is supposed to be attached to the corresponding Ref-pad
+ of the SoC. It will be redistributed amongst the controller core
+ sub-modules (pipe, core, aux, etc).
+ maxItems: 4
+
+ clock-names:
+ items:
+ - const: dbi
+ - const: mstr
+ - const: slv
+ - const: ref
+
+ resets:
+ description:
+ A comprehensive controller reset logic is supposed to be implemented
+ by software, so almost all the possible application and core reset
+ signals are exposed via the system CCU module.
+ maxItems: 9
+
+ reset-names:
+ items:
+ - const: mstr
+ - const: slv
+ - const: pwr
+ - const: hot
+ - const: phy
+ - const: core
+ - const: pipe
+ - const: sticky
+ - const: non-sticky
+
+ baikal,bt1-syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Phandle to the Baikal-T1 System Controller DT node. It's required to
+ access some additional PM, Reset-related and LTSSM signals.
+
+ num-lanes:
+ maximum: 4
+
+ max-link-speed:
+ maximum: 3
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - interrupt-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/mips-gic.h>
+ #include <dt-bindings/gpio/gpio.h>
+
+ pcie@1f052000 {
+ compatible = "baikal,bt1-pcie";
+ device_type = "pci";
+ reg = <0x1f052000 0x1000>, <0x1f053000 0x1000>, <0x1bdbf000 0x1000>;
+ reg-names = "dbi", "dbi2", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x81000000 0 0x00000000 0x1bdb0000 0 0x00008000>,
+ <0x82000000 0 0x20000000 0x08000000 0 0x13db0000>;
+ bus-range = <0x0 0xff>;
+
+ interrupts = <GIC_SHARED 80 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 81 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 82 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 83 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 84 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 85 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 86 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 88 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 90 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 91 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 92 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 93 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "dma0", "dma1", "dma2", "dma3",
+ "dma4", "dma5", "dma6", "dma7",
+ "msi", "aer", "pme", "hp", "bw_mg",
+ "l_eq";
+
+ clocks = <&ccu_sys 1>, <&ccu_axi 6>, <&ccu_axi 7>, <&clk_pcie>;
+ clock-names = "dbi", "mstr", "slv", "ref";
+
+ resets = <&ccu_axi 6>, <&ccu_axi 7>, <&ccu_sys 7>, <&ccu_sys 10>,
+ <&ccu_sys 4>, <&ccu_sys 6>, <&ccu_sys 5>, <&ccu_sys 8>,
+ <&ccu_sys 9>;
+ reset-names = "mstr", "slv", "pwr", "hot", "phy", "core", "pipe",
+ "sticky", "non-sticky";
+
+ reset-gpios = <&port0 0 GPIO_ACTIVE_LOW>;
+
+ num-lanes = <4>;
+ max-link-speed = <3>;
+ };
+...
--
2.38.1



2022-11-13 20:35:01

by Serge Semin

[permalink] [raw]
Subject: [PATCH v7 15/20] PCI: dwc: Introduce dma-ranges property support for RC-host

In accordance with the generic PCIe Root Port DT-bindings the "dma-ranges"
property has the same format as the "ranges" property. The only difference
is in their semantics. The "dma-ranges" property describes the PCIe-to-CPU
memory mapping in opposite to the CPU-to-PCIe mapping of the "ranges"
property. Even though the DW PCIe controllers are normally equipped with
the internal Address Translation Unit which inbound and outbound tables
can be used to implement both properties semantics, it was surprising for
me to discover that the host-related part of the DW PCIe driver currently
supports the "ranges" property only while the "dma-ranges" windows are
just ignored. Having the "dma-ranges" supported in the driver would be
very handy for the platforms, that don't tolerate the 1:1 CPU-PCIe memory
mapping and require a customized PCIe memory layout. So let's fix that by
introducing the "dma-ranges" property support.

First of all we suggest to rename the dw_pcie_prog_inbound_atu() method to
dw_pcie_prog_ep_inbound_atu() and create a new version of the
dw_pcie_prog_inbound_atu() function. Thus we'll have two methods for the
RC and EP controllers respectively in the same way as it has been
developed for the outbound ATU setup methods.

Secondly aside with the memory window index and type the new
dw_pcie_prog_inbound_atu() function will accept CPU address, PCIe address
and size as its arguments. These parameters define the PCIe and CPU memory
ranges which will be used to setup the respective inbound ATU mapping. The
passed parameters need to be verified against the ATU ranges constraints
in the same way as it is done for the outbound ranges.

Finally the DMA-ranges detected for the PCIe controller need to be
converted to the inbound ATU entries during the host controller
initialization procedure. It will be done in the framework of the
dw_pcie_iatu_setup() method. Note before setting the inbound ranges up we
need to disable all the inbound ATU entries in order to prevent unexpected
PCIe TLPs translations defined by some third party software like
bootloaders.

Signed-off-by: Serge Semin <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
Reviewed-by: Manivannan Sadhasivam <[email protected]>

---

Changelog v3:
- Drop inbound iATU window size alignment constraint. (@Manivannan)
---
.../pci/controller/dwc/pcie-designware-ep.c | 4 +-
.../pci/controller/dwc/pcie-designware-host.c | 32 ++++++++++-
drivers/pci/controller/dwc/pcie-designware.c | 56 ++++++++++++++++++-
drivers/pci/controller/dwc/pcie-designware.h | 6 +-
4 files changed, 89 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 83ddb190292e..237bb01d7852 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -171,8 +171,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
return -EINVAL;
}

- ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, type,
- cpu_addr, bar);
+ ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
+ cpu_addr, bar);
if (ret < 0) {
dev_err(pci->dev, "Failed to program IB window\n");
return ret;
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 39f3b37d4033..ea923c25e12d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -643,12 +643,15 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
}

/*
- * Ensure all outbound windows are disabled before proceeding with
- * the MEM/IO ranges setups.
+ * Ensure all out/inbound windows are disabled before proceeding with
+ * the MEM/IO (dma-)ranges setups.
*/
for (i = 0; i < pci->num_ob_windows; i++)
dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, i);

+ for (i = 0; i < pci->num_ib_windows; i++)
+ dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
+
i = 0;
resource_list_for_each_entry(entry, &pp->bridge->windows) {
if (resource_type(entry->res) != IORESOURCE_MEM)
@@ -685,9 +688,32 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
}

if (pci->num_ob_windows <= i)
- dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)\n",
+ dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
pci->num_ob_windows);

+ i = 0;
+ resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
+ if (resource_type(entry->res) != IORESOURCE_MEM)
+ continue;
+
+ if (pci->num_ib_windows <= i)
+ break;
+
+ ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
+ entry->res->start,
+ entry->res->start - entry->offset,
+ resource_size(entry->res));
+ if (ret) {
+ dev_err(pci->dev, "Failed to set DMA range %pr\n",
+ entry->res);
+ return ret;
+ }
+ }
+
+ if (pci->num_ib_windows <= i)
+ dev_warn(pci->dev, "Dma-ranges exceed inbound iATU size (%u)\n",
+ pci->num_ib_windows);
+
return 0;
}

diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index c6725c519a47..ca830ee794a7 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -393,8 +393,60 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
dw_pcie_writel_atu(pci, PCIE_ATU_REGION_DIR_IB, index, reg, val);
}

-int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
- int type, u64 cpu_addr, u8 bar)
+int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
+ u64 cpu_addr, u64 pci_addr, u64 size)
+{
+ u64 limit_addr = pci_addr + size - 1;
+ u32 retries, val;
+
+ if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
+ !IS_ALIGNED(cpu_addr, pci->region_align) ||
+ !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
+ return -EINVAL;
+ }
+
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_BASE,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_BASE,
+ upper_32_bits(pci_addr));
+
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LIMIT,
+ lower_32_bits(limit_addr));
+ if (dw_pcie_ver_is_ge(pci, 460A))
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_LIMIT,
+ upper_32_bits(limit_addr));
+
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
+ upper_32_bits(cpu_addr));
+
+ val = type;
+ if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
+ dw_pcie_ver_is_ge(pci, 460A))
+ val |= PCIE_ATU_INCREASE_REGION_SIZE;
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, val);
+ dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2, PCIE_ATU_ENABLE);
+
+ /*
+ * Make sure ATU enable takes effect before any subsequent config
+ * and I/O accesses.
+ */
+ for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
+ val = dw_pcie_readl_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2);
+ if (val & PCIE_ATU_ENABLE)
+ return 0;
+
+ mdelay(LINK_WAIT_IATU);
+ }
+
+ dev_err(pci->dev, "Inbound iATU is not being enabled\n");
+
+ return -ETIMEDOUT;
+}
+
+int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ int type, u64 cpu_addr, u8 bar)
{
u32 retries, val;

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index a871ae7eb59e..37801bbce854 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -346,8 +346,10 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
u64 cpu_addr, u64 pci_addr, u64 size);
int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
int type, u64 cpu_addr, u64 pci_addr, u64 size);
-int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
- int type, u64 cpu_addr, u8 bar);
+int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
+ u64 cpu_addr, u64 pci_addr, u64 size);
+int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ int type, u64 cpu_addr, u8 bar);
void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
void dw_pcie_setup(struct dw_pcie *pci);
void dw_pcie_iatu_detect(struct dw_pcie *pci);
--
2.38.1



2022-11-14 00:13:59

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v7 01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq


On Sun, 13 Nov 2022 22:12:42 +0300, Serge Semin wrote:
> Originally as it was defined the legacy bindings the pcie_inbound_axi and
> pcie_aux clock names were supposed to be used in the fsl,imx6sx-pcie and
> fsl,imx8mq-pcie devices respectively. But the bindings conversion has been
> incorrectly so now the fourth clock name is defined as "pcie_inbound_axi
> for imx6sx-pcie, pcie_aux for imx8mq-pcie", which is completely wrong.
> Let's fix that by conditionally apply the clock-names constraints based on
> the compatible string content.
>
> Fixes: 751ca492f131 ("dt-bindings: PCI: imx6: convert the imx pcie controller to dtschema")
> Signed-off-by: Serge Semin <[email protected]>
> Acked-by: Alexander Stein <[email protected]>
>
> ---
>
> Changelog v5:
> - This is a new patch added on the v5 release of the patchset.
>
> Changelog v7:
> - Move the allOf clause to the bottom of the bindings. (@Krzysztof)
> - Get back the names to the clock-names property and make sure the
> platform-specific name constraint is applied in the allOf clause.
> (@Rob)
> ---
> .../bindings/pci/fsl,imx6q-pcie.yaml | 46 +++++++++++++++++--
> 1 file changed, 42 insertions(+), 4 deletions(-)
>

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/


pcie@1ffc000: Unevaluated properties are not allowed ('disable-gpio' was unexpected)
arch/arm/boot/dts/imx6dl-emcon-avari.dtb
arch/arm/boot/dts/imx6q-emcon-avari.dtb

pcie@33800000: clock-names:1: 'pcie_bus' was expected
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33800000: clock-names:2: 'pcie_phy' was expected
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb

pcie@33800000: clock-names:3: 'pcie_aux' was expected
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33800000: clock-names:3: 'pcie_bus' is not one of ['pcie_inbound_axi', 'pcie_aux']
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33800000: power-domains: [[102, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb

pcie@33800000: power-domains: [[102]] is too short
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb

pcie@33800000: power-domains: [[103]] is too short
arch/arm/boot/dts/imx7d-colibri-emmc-iris.dtb
arch/arm/boot/dts/imx7d-colibri-iris.dtb

pcie@33800000: power-domains: [[104]] is too short
arch/arm/boot/dts/imx7d-colibri-aster.dtb
arch/arm/boot/dts/imx7d-colibri-emmc-aster.dtb
arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dtb
arch/arm/boot/dts/imx7d-colibri-iris-v2.dtb

pcie@33800000: power-domains: [[106]] is too short
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb

pcie@33800000: power-domains: [[107]] is too short
arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dtb
arch/arm/boot/dts/imx7d-colibri-eval-v3.dtb

pcie@33800000: power-domains: [[108]] is too short
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb

pcie@33800000: power-domains: [[125]] is too short
arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb

pcie@33800000: power-domains: [[126]] is too short
arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb

pcie@33800000: power-domains: [[49, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb

pcie@33800000: power-domains: [[55]] is too short
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb

pcie@33800000: power-domains: [[59]] is too short
arch/arm/boot/dts/imx7d-cl-som-imx7.dtb

pcie@33800000: power-domains: [[60, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb

pcie@33800000: power-domains: [[61]] is too short
arch/arm/boot/dts/imx7d-sbc-imx7.dtb

pcie@33800000: power-domains: [[63]] is too short
arch/arm/boot/dts/imx7d-zii-rmu2.dtb

pcie@33800000: power-domains: [[64, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb

pcie@33800000: power-domains: [[64]] is too short
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm/boot/dts/imx7d-remarkable2.dtb

pcie@33800000: power-domains: [[67]] is too short
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb

pcie@33800000: power-domains: [[68]] is too short
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm/boot/dts/imx7d-meerkat96.dtb

pcie@33800000: power-domains: [[70, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb

pcie@33800000: power-domains: [[70]] is too short
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb

pcie@33800000: power-domains: [[72]] is too short
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb

pcie@33800000: power-domains: [[73]] is too short
arch/arm/boot/dts/imx7d-flex-concentrator.dtb
arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dtb
arch/arm/boot/dts/imx7d-smegw01.dtb

pcie@33800000: power-domains: [[75]] is too short
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb

pcie@33800000: power-domains: [[76, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb

pcie@33800000: power-domains: [[76]] is too short
arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb

pcie@33800000: power-domains: [[77]] is too short
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb

pcie@33800000: power-domains: [[78]] is too short
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb

pcie@33800000: power-domains: [[79]] is too short
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb

pcie@33800000: power-domains: [[80]] is too short
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb

pcie@33800000: power-domains: [[81]] is too short
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb

pcie@33800000: power-domains: [[82]] is too short
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb

pcie@33800000: power-domains: [[83, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb

pcie@33800000: power-domains: [[84]] is too short
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb

pcie@33800000: power-domains: [[86, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb

pcie@33800000: power-domains: [[86]] is too short
arch/arm/boot/dts/imx7d-nitrogen7.dtb
arch/arm/boot/dts/imx7d-pico-nymph.dtb

pcie@33800000: power-domains: [[87]] is too short
arch/arm/boot/dts/imx7d-sdb-reva.dtb

pcie@33800000: power-domains: [[88]] is too short
arch/arm/boot/dts/imx7d-pico-dwarf.dtb
arch/arm/boot/dts/imx7d-pico-hobbit.dtb
arch/arm/boot/dts/imx7d-sdb.dtb
arch/arm/boot/dts/imx7d-sdb-sht11.dtb

pcie@33800000: power-domains: [[89]] is too short
arch/arm/boot/dts/imx7d-pico-pi.dtb
arch/arm/boot/dts/imx7d-zii-rpu2.dtb

pcie@33800000: power-domains: [[92]] is too short
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb

pcie@33800000: power-domains: [[96]] is too short
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm/boot/dts/imx7d-mba7.dtb

pcie@33800000: power-domains: [[97, 3]] is too short
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb

pcie@33800000: power-domains: [[97]] is too short
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb

pcie@33800000: power-domains: [[98]] is too short
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33800000: reset-names:0: 'pciephy' was expected
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb

pcie@33800000: reset-names:1: 'apps' was expected
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb

pcie@33800000: reset-names: ['apps', 'turnoff'] is too short
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb

pcie@33800000: resets: [[101, 26], [101, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb

pcie@33800000: resets: [[25, 28], [25, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb

pcie@33800000: resets: [[26, 28], [26, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb

pcie@33800000: resets: [[27, 28], [27, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb

pcie@33800000: resets: [[28, 28], [28, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb

pcie@33800000: resets: [[29, 28], [29, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb

pcie@33800000: resets: [[31, 28], [31, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb

pcie@33800000: resets: [[34, 28], [34, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb

pcie@33800000: resets: [[40, 28], [40, 29]] is too short
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb

pcie@33800000: resets: [[48, 26], [48, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb

pcie@33800000: resets: [[59, 26], [59, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb

pcie@33800000: resets: [[63, 26], [63, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb

pcie@33800000: resets: [[69, 26], [69, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb

pcie@33800000: resets: [[75, 26], [75, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb

pcie@33800000: resets: [[82, 26], [82, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb

pcie@33800000: resets: [[85, 26], [85, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb

pcie@33800000: resets: [[96, 26], [96, 27]] is too short
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb

pcie@33800000: Unevaluated properties are not allowed ('clock-names', 'epdev_on-supply', 'hard-wired', 'power-domains' were unexpected)
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb

pcie@33800000: Unevaluated properties are not allowed ('clock-names', 'power-domains' were unexpected)
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33800000: Unevaluated properties are not allowed ('power-domains', 'reset-names', 'resets' were unexpected)
arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb

pcie@33800000: Unevaluated properties are not allowed ('power-domains' was unexpected)
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb
arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb
arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb
arch/arm/boot/dts/imx7d-cl-som-imx7.dtb
arch/arm/boot/dts/imx7d-colibri-aster.dtb
arch/arm/boot/dts/imx7d-colibri-emmc-aster.dtb
arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dtb
arch/arm/boot/dts/imx7d-colibri-emmc-iris.dtb
arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dtb
arch/arm/boot/dts/imx7d-colibri-eval-v3.dtb
arch/arm/boot/dts/imx7d-colibri-iris.dtb
arch/arm/boot/dts/imx7d-colibri-iris-v2.dtb
arch/arm/boot/dts/imx7d-flex-concentrator.dtb
arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dtb
arch/arm/boot/dts/imx7d-mba7.dtb
arch/arm/boot/dts/imx7d-meerkat96.dtb
arch/arm/boot/dts/imx7d-nitrogen7.dtb
arch/arm/boot/dts/imx7d-pico-dwarf.dtb
arch/arm/boot/dts/imx7d-pico-hobbit.dtb
arch/arm/boot/dts/imx7d-pico-nymph.dtb
arch/arm/boot/dts/imx7d-pico-pi.dtb
arch/arm/boot/dts/imx7d-remarkable2.dtb
arch/arm/boot/dts/imx7d-sbc-imx7.dtb
arch/arm/boot/dts/imx7d-sdb.dtb
arch/arm/boot/dts/imx7d-sdb-reva.dtb
arch/arm/boot/dts/imx7d-sdb-sht11.dtb
arch/arm/boot/dts/imx7d-smegw01.dtb
arch/arm/boot/dts/imx7d-zii-rmu2.dtb
arch/arm/boot/dts/imx7d-zii-rpu2.dtb

pcie@33c00000: 'bus-range' is a required property
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33c00000: clock-names:1: 'pcie_bus' was expected
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33c00000: clock-names:3: 'pcie_aux' was expected
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33c00000: clock-names:3: 'pcie_bus' is not one of ['pcie_inbound_axi', 'pcie_aux']
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33c00000: power-domains: [[102]] is too short
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb

pcie@33c00000: power-domains: [[125]] is too short
arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb

pcie@33c00000: power-domains: [[126]] is too short
arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb

pcie@33c00000: power-domains: [[70]] is too short
arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb

pcie@33c00000: power-domains: [[78]] is too short
arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb

pcie@33c00000: power-domains: [[79]] is too short
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb

pcie@33c00000: power-domains: [[80]] is too short
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb

pcie@33c00000: power-domains: [[81]] is too short
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb

pcie@33c00000: power-domains: [[82]] is too short
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb

pcie@33c00000: power-domains: [[92]] is too short
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb

pcie@33c00000: power-domains: [[97]] is too short
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb

pcie@33c00000: power-domains: [[98]] is too short
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33c00000: Unevaluated properties are not allowed ('clock-names', 'epdev_on-supply', 'hard-wired', 'power-domains' were unexpected)
arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb

pcie@33c00000: Unevaluated properties are not allowed ('clock-names', 'power-domains' were unexpected)
arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb

pcie@33c00000: Unevaluated properties are not allowed ('power-domains' was unexpected)
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb
arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb
arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb
arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb


2022-11-14 07:14:16

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 15/20] PCI: dwc: Introduce dma-ranges property support for RC-host

On Sun, Nov 13, 2022 at 10:12:56PM +0300, Serge Semin wrote:
> In accordance with the generic PCIe Root Port DT-bindings the "dma-ranges"
> property has the same format as the "ranges" property. The only difference
> is in their semantics. The "dma-ranges" property describes the PCIe-to-CPU
> memory mapping in opposite to the CPU-to-PCIe mapping of the "ranges"
> property. Even though the DW PCIe controllers are normally equipped with
> the internal Address Translation Unit which inbound and outbound tables
> can be used to implement both properties semantics, it was surprising for
> me to discover that the host-related part of the DW PCIe driver currently
> supports the "ranges" property only while the "dma-ranges" windows are
> just ignored. Having the "dma-ranges" supported in the driver would be
> very handy for the platforms, that don't tolerate the 1:1 CPU-PCIe memory
> mapping and require a customized PCIe memory layout. So let's fix that by
> introducing the "dma-ranges" property support.
>
> First of all we suggest to rename the dw_pcie_prog_inbound_atu() method to
> dw_pcie_prog_ep_inbound_atu() and create a new version of the
> dw_pcie_prog_inbound_atu() function. Thus we'll have two methods for the
> RC and EP controllers respectively in the same way as it has been
> developed for the outbound ATU setup methods.
>

I think you should split the function renaming part into a separate patch.

> Secondly aside with the memory window index and type the new
> dw_pcie_prog_inbound_atu() function will accept CPU address, PCIe address
> and size as its arguments. These parameters define the PCIe and CPU memory
> ranges which will be used to setup the respective inbound ATU mapping. The
> passed parameters need to be verified against the ATU ranges constraints
> in the same way as it is done for the outbound ranges.
>
> Finally the DMA-ranges detected for the PCIe controller need to be
> converted to the inbound ATU entries during the host controller
> initialization procedure. It will be done in the framework of the
> dw_pcie_iatu_setup() method. Note before setting the inbound ranges up we
> need to disable all the inbound ATU entries in order to prevent unexpected
> PCIe TLPs translations defined by some third party software like
> bootloaders.
>
> Signed-off-by: Serge Semin <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> Reviewed-by: Manivannan Sadhasivam <[email protected]>
>
> ---
>
> Changelog v3:
> - Drop inbound iATU window size alignment constraint. (@Manivannan)
> ---
> .../pci/controller/dwc/pcie-designware-ep.c | 4 +-
> .../pci/controller/dwc/pcie-designware-host.c | 32 ++++++++++-
> drivers/pci/controller/dwc/pcie-designware.c | 56 ++++++++++++++++++-
> drivers/pci/controller/dwc/pcie-designware.h | 6 +-
> 4 files changed, 89 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 83ddb190292e..237bb01d7852 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -171,8 +171,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
> return -EINVAL;
> }
>
> - ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, type,
> - cpu_addr, bar);
> + ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
> + cpu_addr, bar);
> if (ret < 0) {
> dev_err(pci->dev, "Failed to program IB window\n");
> return ret;
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 39f3b37d4033..ea923c25e12d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -643,12 +643,15 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> }
>
> /*
> - * Ensure all outbound windows are disabled before proceeding with
> - * the MEM/IO ranges setups.
> + * Ensure all out/inbound windows are disabled before proceeding with
> + * the MEM/IO (dma-)ranges setups.
> */
> for (i = 0; i < pci->num_ob_windows; i++)
> dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, i);
>
> + for (i = 0; i < pci->num_ib_windows; i++)
> + dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
> +
> i = 0;
> resource_list_for_each_entry(entry, &pp->bridge->windows) {
> if (resource_type(entry->res) != IORESOURCE_MEM)
> @@ -685,9 +688,32 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> }
>
> if (pci->num_ob_windows <= i)
> - dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)\n",
> + dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
> pci->num_ob_windows);
>
> + i = 0;
> + resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
> + if (resource_type(entry->res) != IORESOURCE_MEM)
> + continue;
> +
> + if (pci->num_ib_windows <= i)
> + break;
> +
> + ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
> + entry->res->start,
> + entry->res->start - entry->offset,
> + resource_size(entry->res));
> + if (ret) {
> + dev_err(pci->dev, "Failed to set DMA range %pr\n",
> + entry->res);
> + return ret;
> + }
> + }
> +
> + if (pci->num_ib_windows <= i)
> + dev_warn(pci->dev, "Dma-ranges exceed inbound iATU size (%u)\n",

s/Dma/dma

Thanks,
Mani

> + pci->num_ib_windows);
> +
> return 0;
> }
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index c6725c519a47..ca830ee794a7 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -393,8 +393,60 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
> dw_pcie_writel_atu(pci, PCIE_ATU_REGION_DIR_IB, index, reg, val);
> }
>
> -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> - int type, u64 cpu_addr, u8 bar)
> +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> + u64 cpu_addr, u64 pci_addr, u64 size)
> +{
> + u64 limit_addr = pci_addr + size - 1;
> + u32 retries, val;
> +
> + if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
> + !IS_ALIGNED(cpu_addr, pci->region_align) ||
> + !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
> + return -EINVAL;
> + }
> +
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_BASE,
> + lower_32_bits(pci_addr));
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_BASE,
> + upper_32_bits(pci_addr));
> +
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LIMIT,
> + lower_32_bits(limit_addr));
> + if (dw_pcie_ver_is_ge(pci, 460A))
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_LIMIT,
> + upper_32_bits(limit_addr));
> +
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
> + lower_32_bits(cpu_addr));
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
> + upper_32_bits(cpu_addr));
> +
> + val = type;
> + if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
> + dw_pcie_ver_is_ge(pci, 460A))
> + val |= PCIE_ATU_INCREASE_REGION_SIZE;
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, val);
> + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2, PCIE_ATU_ENABLE);
> +
> + /*
> + * Make sure ATU enable takes effect before any subsequent config
> + * and I/O accesses.
> + */
> + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
> + val = dw_pcie_readl_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2);
> + if (val & PCIE_ATU_ENABLE)
> + return 0;
> +
> + mdelay(LINK_WAIT_IATU);
> + }
> +
> + dev_err(pci->dev, "Inbound iATU is not being enabled\n");
> +
> + return -ETIMEDOUT;
> +}
> +
> +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> + int type, u64 cpu_addr, u8 bar)
> {
> u32 retries, val;
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index a871ae7eb59e..37801bbce854 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -346,8 +346,10 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
> u64 cpu_addr, u64 pci_addr, u64 size);
> int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> int type, u64 cpu_addr, u64 pci_addr, u64 size);
> -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> - int type, u64 cpu_addr, u8 bar);
> +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> + u64 cpu_addr, u64 pci_addr, u64 size);
> +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> + int type, u64 cpu_addr, u8 bar);
> void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> void dw_pcie_setup(struct dw_pcie *pci);
> void dw_pcie_iatu_detect(struct dw_pcie *pci);
> --
> 2.38.1
>
>

--
மணிவண்ணன் சதாசிவம்

2022-11-14 07:36:46

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:
> Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in
> the separate parts of the DW PCIe core driver. It doesn't really make
> sense since the both controller types have identical set of the core CSR
> regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host
> and EP initialization methods by moving the platform-specific registers
> space getting and mapping into a common method. It gets to be even more
> justified seeing the CSRs base address pointers are preserved in the
> common DW PCIe descriptor. Note all the OF-based common DW PCIe settings
> initialization will be moved to the new method too in order to have a
> single function for all the generic platform properties handling in single
> place.
>
> A nice side-effect of this change is that the pcie-designware-host.c and
> pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie
> storage modification, which makes the DW PCIe core, Root Port and Endpoint
> modules more coherent.
>

You have clubbed both generic resource API and introducing CDM_CHECK flag.
Please split them into separate patches.

Thanks,
Mani

> Signed-off-by: Serge Semin <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
>
> ---
>
> Changelog v3:
> - This is a new patch created on v3 lap of the series.
>
> Changelog v4:
> - Convert the method name from dw_pcie_get_res() to
> dw_pcie_get_resources(). (@Bjorn)
>
> Changelog v7:
> - Get back device.of_node pointer to the dw_pcie_ep_init() method.
> (@Yoshihiro)
> ---
> .../pci/controller/dwc/pcie-designware-ep.c | 25 +------
> .../pci/controller/dwc/pcie-designware-host.c | 15 +---
> drivers/pci/controller/dwc/pcie-designware.c | 75 ++++++++++++++-----
> drivers/pci/controller/dwc/pcie-designware.h | 3 +
> 4 files changed, 65 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 237bb01d7852..f68d1ab83bb3 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -13,8 +13,6 @@
> #include <linux/pci-epc.h>
> #include <linux/pci-epf.h>
>
> -#include "../../pci.h"
> -
> void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> {
> struct pci_epc *epc = ep->epc;
> @@ -694,23 +692,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>
> INIT_LIST_HEAD(&ep->func_list);
>
> - if (!pci->dbi_base) {
> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
> - pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
> - if (IS_ERR(pci->dbi_base))
> - return PTR_ERR(pci->dbi_base);
> - }
> -
> - if (!pci->dbi_base2) {
> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
> - if (!res) {
> - pci->dbi_base2 = pci->dbi_base + SZ_4K;
> - } else {
> - pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res);
> - if (IS_ERR(pci->dbi_base2))
> - return PTR_ERR(pci->dbi_base2);
> - }
> - }
> + ret = dw_pcie_get_resources(pci);
> + if (ret)
> + return ret;
>
> res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
> if (!res)
> @@ -739,9 +723,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> return -ENOMEM;
> ep->outbound_addr = addr;
>
> - if (pci->link_gen < 1)
> - pci->link_gen = of_pci_get_max_link_speed(np);
> -
> epc = devm_pci_epc_create(dev, &epc_ops);
> if (IS_ERR(epc)) {
> dev_err(dev, "Failed to create epc device\n");
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index ea923c25e12d..3ab6ae3712c4 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -16,7 +16,6 @@
> #include <linux/pci_regs.h>
> #include <linux/platform_device.h>
>
> -#include "../../pci.h"
> #include "pcie-designware.h"
>
> static struct pci_ops dw_pcie_ops;
> @@ -395,6 +394,10 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>
> raw_spin_lock_init(&pp->lock);
>
> + ret = dw_pcie_get_resources(pci);
> + if (ret)
> + return ret;
> +
> res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> if (res) {
> pp->cfg0_size = resource_size(res);
> @@ -408,13 +411,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> return -ENODEV;
> }
>
> - if (!pci->dbi_base) {
> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
> - pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
> - if (IS_ERR(pci->dbi_base))
> - return PTR_ERR(pci->dbi_base);
> - }
> -
> bridge = devm_pci_alloc_host_bridge(dev, 0);
> if (!bridge)
> return -ENOMEM;
> @@ -429,9 +425,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> pp->io_base = pci_pio_to_address(win->res->start);
> }
>
> - if (pci->link_gen < 1)
> - pci->link_gen = of_pci_get_max_link_speed(np);
> -
> /* Set default bus ops */
> bridge->ops = &dw_pcie_ops;
> bridge->child_ops = &dw_child_pcie_ops;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index 9d78e7ca61e1..a8436027434d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -11,6 +11,7 @@
> #include <linux/align.h>
> #include <linux/bitops.h>
> #include <linux/delay.h>
> +#include <linux/ioport.h>
> #include <linux/of.h>
> #include <linux/of_platform.h>
> #include <linux/sizes.h>
> @@ -19,6 +20,59 @@
> #include "../../pci.h"
> #include "pcie-designware.h"
>
> +int dw_pcie_get_resources(struct dw_pcie *pci)
> +{
> + struct platform_device *pdev = to_platform_device(pci->dev);
> + struct device_node *np = dev_of_node(pci->dev);
> + struct resource *res;
> +
> + if (!pci->dbi_base) {
> + 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);
> + }
> +
> + /* DBI2 is mainly useful for the endpoint controller */
> + if (!pci->dbi_base2) {
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
> + if (res) {
> + pci->dbi_base2 = devm_pci_remap_cfg_resource(pci->dev, res);
> + if (IS_ERR(pci->dbi_base2))
> + return PTR_ERR(pci->dbi_base2);
> + } else {
> + pci->dbi_base2 = pci->dbi_base + SZ_4K;
> + }
> + }
> +
> + /* For non-unrolled iATU/eDMA platforms this range will be ignored */
> + if (!pci->atu_base) {
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
> + if (res) {
> + pci->atu_size = resource_size(res);
> + pci->atu_base = devm_ioremap_resource(pci->dev, res);
> + if (IS_ERR(pci->atu_base))
> + return PTR_ERR(pci->atu_base);
> + } else {
> + pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
> + }
> + }
> +
> + /* Set a default value suitable for at most 8 in and 8 out windows */
> + if (!pci->atu_size)
> + pci->atu_size = SZ_4K;
> +
> + if (pci->link_gen < 1)
> + pci->link_gen = of_pci_get_max_link_speed(np);
> +
> + of_property_read_u32(np, "num-lanes", &pci->num_lanes);
> +
> + if (of_property_read_bool(np, "snps,enable-cdm-check"))
> + dw_pcie_cap_set(pci, CDM_CHECK);
> +
> + return 0;
> +}
> +
> void dw_pcie_version_detect(struct dw_pcie *pci)
> {
> u32 ver;
> @@ -639,25 +693,8 @@ static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci)
>
> void dw_pcie_iatu_detect(struct dw_pcie *pci)
> {
> - struct platform_device *pdev = to_platform_device(pci->dev);
> -
> if (dw_pcie_iatu_unroll_enabled(pci)) {
> dw_pcie_cap_set(pci, IATU_UNROLL);
> -
> - if (!pci->atu_base) {
> - struct resource *res =
> - platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
> - if (res) {
> - pci->atu_size = resource_size(res);
> - pci->atu_base = devm_ioremap_resource(pci->dev, res);
> - }
> - if (!pci->atu_base || IS_ERR(pci->atu_base))
> - pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
> - }
> -
> - if (!pci->atu_size)
> - /* Pick a minimal default, enough for 8 in and 8 out windows */
> - pci->atu_size = SZ_4K;
> } else {
> pci->atu_base = pci->dbi_base + PCIE_ATU_VIEWPORT_BASE;
> pci->atu_size = PCIE_ATU_VIEWPORT_SIZE;
> @@ -675,7 +712,6 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci)
>
> void dw_pcie_setup(struct dw_pcie *pci)
> {
> - struct device_node *np = pci->dev->of_node;
> u32 val;
>
> if (pci->link_gen > 0)
> @@ -703,14 +739,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
> val |= PORT_LINK_DLL_LINK_EN;
> dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
>
> - if (of_property_read_bool(np, "snps,enable-cdm-check")) {
> + if (dw_pcie_cap_is(pci, CDM_CHECK)) {
> val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
> val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
> PCIE_PL_CHK_REG_CHK_REG_START;
> dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
> }
>
> - of_property_read_u32(np, "num-lanes", &pci->num_lanes);
> if (!pci->num_lanes) {
> dev_dbg(pci->dev, "Using h/w default number of lanes\n");
> return;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index c6dddacee3b1..081f169e6021 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -46,6 +46,7 @@
>
> /* DWC PCIe controller capabilities */
> #define DW_PCIE_CAP_IATU_UNROLL 1
> +#define DW_PCIE_CAP_CDM_CHECK 2
>
> #define dw_pcie_cap_is(_pci, _cap) \
> test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps)
> @@ -338,6 +339,8 @@ struct dw_pcie {
> #define to_dw_pcie_from_ep(endpoint) \
> container_of((endpoint), struct dw_pcie, ep)
>
> +int dw_pcie_get_resources(struct dw_pcie *pci);
> +
> void dw_pcie_version_detect(struct dw_pcie *pci);
>
> u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> --
> 2.38.1
>
>

--
மணிவண்ணன் சதாசிவம்

2022-11-14 08:46:29

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 20/20] PCI: dwc: Add Baikal-T1 PCIe controller support

On Sun, Nov 13, 2022 at 10:13:01PM +0300, Serge Semin wrote:
> Baikal-T1 SoC is equipped with DWC PCIe v4.60a host controller. It can be
> trained to work up to Gen.3 speed over up to x4 lanes. The host controller
> is attached to the DW PCIe 3.0 PCS via the PIPE-4 interface, which in its
> turn is connected to the DWC 10G PHY. The whole system is supposed to be
> fed up with four clock sources: DBI peripheral clock, AXI application
> clocks and external PHY/core reference clock generating the 100MHz signal.
> In addition to that the platform provide a way to reset each part of the
> controller: sticky/non-sticky bits, host controller core, PIPE interface,
> PCS/PHY and Hot/Power reset signal. The driver also provides a way to
> handle the GPIO-based PERST# signal.
>
> Note due to the Baikal-T1 MMIO peculiarity we have to implement the DBI
> interface accessors which make sure the IO operations are dword-aligned.
>
> Signed-off-by: Serge Semin <[email protected]>
>
> ---
>
> Changelog v2:
> - Rename 'syscon' property to 'baikal,bt1-syscon'.
>
> Changelog v3:
> - Use the clocks/resets handlers defined in the DW PCIe core descriptor.
> (@Rob)
> - Redefine PCI host bridge config space accessors with the generic
> pci_generic_config_read32() and pci_generic_config_write32() methods.
> (@Rob)
>
> Changelog v4:
> - Drop PCIBIOS_* macros usage. (@Rob)
> - Add "static const" to the dw_pcie_ops and dw_pcie_host_ops structure
> instances. (@Bjorn)
> - Rename bt1_pcie_dw_ops to bt1_pcie_ops. (@Bjorn)
> - Rename bt1_pcie_ops to bt1_pci_ops. (@Bjorn)
> - Use start_link/stop_link suffixes in the corresponding callbacks.
> (@Bjorn)
> - Change the get_res() method suffix to being get_resources(). (@Bjorn)
> - Change *_{add,del}_dw_port() method to *_{add,del}_port(). (@Bjorn)
> - Drop dma_coerce_mask_and_coherent() applied to the PCI host bridge
> kernel device instance. (@Bjorn)
> - Add the comment above the dma_set_mask_and_coherent() method usage
> regarding the controller eDMA feature. (@Bjorn)
> - Fix the comment above the core reset controls assertion. (@Bjorn)
> - Replace delays and timeout numeric literals with macros. (@Bjorn)
>
> Changelog v6:
> - Move the DMA-mask setup to the eDMA driver. (@Robin)
>
> Changelog v7:
> - Replace if-then-dev_err_probe-return statement with just
> return-dev_err_probe one.
> ---
> drivers/pci/controller/dwc/Kconfig | 9 +
> drivers/pci/controller/dwc/Makefile | 1 +
> drivers/pci/controller/dwc/pcie-bt1.c | 643 ++++++++++++++++++++++++++
> 3 files changed, 653 insertions(+)
> create mode 100644 drivers/pci/controller/dwc/pcie-bt1.c
>
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 62ce3abf0f19..771b8b146623 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -222,6 +222,15 @@ config PCIE_ARTPEC6_EP
> Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
> endpoint mode. This uses the DesignWare core.
>
> +config PCIE_BT1
> + tristate "Baikal-T1 PCIe controller"

Wondering why cannot this be "PCIE_BAIKAL"? Are you sure that this same driver
cannot be reused for other Baikal SoCs in future?

> + depends on MIPS_BAIKAL_T1 || COMPILE_TEST
> + depends on PCI_MSI_IRQ_DOMAIN
> + select PCIE_DW_HOST
> + help
> + Enables support for the PCIe controller in the Baikal-T1 SoC to work
> + in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
> +
> config PCIE_ROCKCHIP_DW_HOST
> bool "Rockchip DesignWare PCIe controller"
> select PCIE_DW
> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> index 8ba7b67f5e50..bf5c311875a1 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
> obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
> obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> +obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> diff --git a/drivers/pci/controller/dwc/pcie-bt1.c b/drivers/pci/controller/dwc/pcie-bt1.c
> new file mode 100644
> index 000000000000..3346770e6654
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-bt1.c
> @@ -0,0 +1,643 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC

2022?

> + *
> + * Authors:
> + * Vadim Vlasov <[email protected]>
> + * Serge Semin <[email protected]>
> + *
> + * Baikal-T1 PCIe controller driver
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/types.h>
> +
> +#include "pcie-designware.h"
> +
> +/* Baikal-T1 System CCU control registers */
> +#define BT1_CCU_PCIE_CLKC 0x140
> +#define BT1_CCU_PCIE_REQ_PCS_CLK BIT(16)
> +#define BT1_CCU_PCIE_REQ_MAC_CLK BIT(17)
> +#define BT1_CCU_PCIE_REQ_PIPE_CLK BIT(18)
> +
> +#define BT1_CCU_PCIE_RSTC 0x144
> +#define BT1_CCU_PCIE_REQ_LINK_RST BIT(13)
> +#define BT1_CCU_PCIE_REQ_SMLH_RST BIT(14)
> +#define BT1_CCU_PCIE_REQ_PHY_RST BIT(16)
> +#define BT1_CCU_PCIE_REQ_CORE_RST BIT(24)
> +#define BT1_CCU_PCIE_REQ_STICKY_RST BIT(26)
> +#define BT1_CCU_PCIE_REQ_NSTICKY_RST BIT(27)
> +
> +#define BT1_CCU_PCIE_PMSC 0x148
> +#define BT1_CCU_PCIE_LTSSM_STATE_MASK GENMASK(5, 0)
> +#define BT1_CCU_PCIE_LTSSM_DET_QUIET 0x00
> +#define BT1_CCU_PCIE_LTSSM_DET_ACT 0x01
> +#define BT1_CCU_PCIE_LTSSM_POLL_ACT 0x02
> +#define BT1_CCU_PCIE_LTSSM_POLL_COMP 0x03
> +#define BT1_CCU_PCIE_LTSSM_POLL_CONF 0x04
> +#define BT1_CCU_PCIE_LTSSM_PRE_DET_QUIET 0x05
> +#define BT1_CCU_PCIE_LTSSM_DET_WAIT 0x06
> +#define BT1_CCU_PCIE_LTSSM_CFG_LNKWD_START 0x07
> +#define BT1_CCU_PCIE_LTSSM_CFG_LNKWD_ACEPT 0x08
> +#define BT1_CCU_PCIE_LTSSM_CFG_LNNUM_WAIT 0x09
> +#define BT1_CCU_PCIE_LTSSM_CFG_LNNUM_ACEPT 0x0a
> +#define BT1_CCU_PCIE_LTSSM_CFG_COMPLETE 0x0b
> +#define BT1_CCU_PCIE_LTSSM_CFG_IDLE 0x0c
> +#define BT1_CCU_PCIE_LTSSM_RCVR_LOCK 0x0d
> +#define BT1_CCU_PCIE_LTSSM_RCVR_SPEED 0x0e
> +#define BT1_CCU_PCIE_LTSSM_RCVR_RCVRCFG 0x0f
> +#define BT1_CCU_PCIE_LTSSM_RCVR_IDLE 0x10
> +#define BT1_CCU_PCIE_LTSSM_L0 0x11
> +#define BT1_CCU_PCIE_LTSSM_L0S 0x12
> +#define BT1_CCU_PCIE_LTSSM_L123_SEND_IDLE 0x13
> +#define BT1_CCU_PCIE_LTSSM_L1_IDLE 0x14
> +#define BT1_CCU_PCIE_LTSSM_L2_IDLE 0x15
> +#define BT1_CCU_PCIE_LTSSM_L2_WAKE 0x16
> +#define BT1_CCU_PCIE_LTSSM_DIS_ENTRY 0x17
> +#define BT1_CCU_PCIE_LTSSM_DIS_IDLE 0x18
> +#define BT1_CCU_PCIE_LTSSM_DISABLE 0x19
> +#define BT1_CCU_PCIE_LTSSM_LPBK_ENTRY 0x1a
> +#define BT1_CCU_PCIE_LTSSM_LPBK_ACTIVE 0x1b
> +#define BT1_CCU_PCIE_LTSSM_LPBK_EXIT 0x1c
> +#define BT1_CCU_PCIE_LTSSM_LPBK_EXIT_TOUT 0x1d
> +#define BT1_CCU_PCIE_LTSSM_HOT_RST_ENTRY 0x1e
> +#define BT1_CCU_PCIE_LTSSM_HOT_RST 0x1f
> +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ0 0x20
> +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ1 0x21
> +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ2 0x22
> +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ3 0x23
> +#define BT1_CCU_PCIE_SMLH_LINKUP BIT(6)
> +#define BT1_CCU_PCIE_RDLH_LINKUP BIT(7)
> +#define BT1_CCU_PCIE_PM_LINKSTATE_L0S BIT(8)
> +#define BT1_CCU_PCIE_PM_LINKSTATE_L1 BIT(9)
> +#define BT1_CCU_PCIE_PM_LINKSTATE_L2 BIT(10)
> +#define BT1_CCU_PCIE_L1_PENDING BIT(12)
> +#define BT1_CCU_PCIE_REQ_EXIT_L1 BIT(14)
> +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ BIT(15)
> +#define BT1_CCU_PCIE_PM_DSTAT_MASK GENMASK(18, 16)
> +#define BT1_CCU_PCIE_PM_PME_EN BIT(20)
> +#define BT1_CCU_PCIE_PM_PME_STATUS BIT(21)
> +#define BT1_CCU_PCIE_AUX_PM_EN BIT(22)
> +#define BT1_CCU_PCIE_AUX_PWR_DET BIT(23)
> +#define BT1_CCU_PCIE_WAKE_DET BIT(24)
> +#define BT1_CCU_PCIE_TURNOFF_REQ BIT(30)
> +#define BT1_CCU_PCIE_TURNOFF_ACK BIT(31)
> +
> +#define BT1_CCU_PCIE_GENC 0x14c
> +#define BT1_CCU_PCIE_LTSSM_EN BIT(1)
> +#define BT1_CCU_PCIE_DBI2_MODE BIT(2)
> +#define BT1_CCU_PCIE_MGMT_EN BIT(3)
> +#define BT1_CCU_PCIE_RXLANE_FLIP_EN BIT(16)
> +#define BT1_CCU_PCIE_TXLANE_FLIP_EN BIT(17)
> +#define BT1_CCU_PCIE_SLV_XFER_PEND BIT(24)
> +#define BT1_CCU_PCIE_RCV_XFER_PEND BIT(25)
> +#define BT1_CCU_PCIE_DBI_XFER_PEND BIT(26)
> +#define BT1_CCU_PCIE_DMA_XFER_PEND BIT(27)
> +
> +#define BT1_CCU_PCIE_LTSSM_LINKUP(_pmsc) \
> +({ \
> + int __state = FIELD_GET(BT1_CCU_PCIE_LTSSM_STATE_MASK, _pmsc); \
> + __state >= BT1_CCU_PCIE_LTSSM_L0 && __state <= BT1_CCU_PCIE_LTSSM_L2_WAKE; \
> +})
> +
> +/* Baikal-T1 PCIe specific control registers */
> +#define BT1_PCIE_AXI2MGM_LANENUM 0xd04
> +#define BT1_PCIE_AXI2MGM_LANESEL_MASK GENMASK(3, 0)
> +
> +#define BT1_PCIE_AXI2MGM_ADDRCTL 0xd08
> +#define BT1_PCIE_AXI2MGM_PHYREG_ADDR_MASK GENMASK(20, 0)
> +#define BT1_PCIE_AXI2MGM_READ_FLAG BIT(29)
> +#define BT1_PCIE_AXI2MGM_DONE BIT(30)
> +#define BT1_PCIE_AXI2MGM_BUSY BIT(31)
> +
> +#define BT1_PCIE_AXI2MGM_WRITEDATA 0xd0c
> +#define BT1_PCIE_AXI2MGM_WDATA GENMASK(15, 0)
> +
> +#define BT1_PCIE_AXI2MGM_READDATA 0xd10
> +#define BT1_PCIE_AXI2MGM_RDATA GENMASK(15, 0)
> +
> +/* Generic Baikal-T1 PCIe interface resources */
> +#define BT1_PCIE_NUM_APP_CLKS ARRAY_SIZE(bt1_pcie_app_clks)
> +#define BT1_PCIE_NUM_CORE_CLKS ARRAY_SIZE(bt1_pcie_core_clks)
> +#define BT1_PCIE_NUM_APP_RSTS ARRAY_SIZE(bt1_pcie_app_rsts)
> +#define BT1_PCIE_NUM_CORE_RSTS ARRAY_SIZE(bt1_pcie_core_rsts)
> +
> +/* PCIe bus setup delays and timeouts */
> +#define BT1_PCIE_RST_DELAY_MS 100
> +#define BT1_PCIE_RUN_DELAY_US 100
> +#define BT1_PCIE_REQ_DELAY_US 1
> +#define BT1_PCIE_REQ_TIMEOUT_US 1000
> +#define BT1_PCIE_LNK_DELAY_US 1000
> +#define BT1_PCIE_LNK_TIMEOUT_US 1000000
> +
> +static const enum dw_pcie_app_clk bt1_pcie_app_clks[] = {
> + DW_PCIE_DBI_CLK, DW_PCIE_MSTR_CLK, DW_PCIE_SLV_CLK,
> +};
> +
> +static const enum dw_pcie_core_clk bt1_pcie_core_clks[] = {
> + DW_PCIE_REF_CLK,
> +};
> +
> +static const enum dw_pcie_app_rst bt1_pcie_app_rsts[] = {
> + DW_PCIE_MSTR_RST, DW_PCIE_SLV_RST,
> +};
> +
> +static const enum dw_pcie_core_rst bt1_pcie_core_rsts[] = {
> + DW_PCIE_NON_STICKY_RST, DW_PCIE_STICKY_RST, DW_PCIE_CORE_RST,
> + DW_PCIE_PIPE_RST, DW_PCIE_PHY_RST, DW_PCIE_HOT_RST, DW_PCIE_PWR_RST,
> +};
> +
> +struct bt1_pcie {
> + struct dw_pcie dw;
> + struct platform_device *pdev;
> + struct regmap *sys_regs;
> +};
> +#define to_bt1_pcie(_dw) container_of(_dw, struct bt1_pcie, dw)
> +
> +/*
> + * Baikal-T1 MMIO space must be read/written by the dword-aligned
> + * instructions. Note the methods are optimized to have the dword operations
> + * performed with minimum overhead as the most frequently used ones.
> + */
> +static int bt1_pcie_read_mmio(void __iomem *addr, int size, u32 *val)
> +{
> + unsigned int ofs = (uintptr_t)addr & 0x3;
> +
> + if (!IS_ALIGNED((uintptr_t)addr, size))
> + return -EINVAL;
> +
> + *val = readl(addr - ofs) >> ofs * BITS_PER_BYTE;

Why can't you use the _relaxed variants?

> + if (size == 4) {
> + return 0;
> + } else if (size == 2) {
> + *val &= 0xffff;
> + return 0;
> + } else if (size == 1) {
> + *val &= 0xff;
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +

[...]

> +/*
> + * Implements the cold reset procedure in accordance with the reference manual
> + * and available PM signals.
> + */
> +static int bt1_pcie_cold_start_bus(struct bt1_pcie *btpci)
> +{
> + struct device *dev = btpci->dw.dev;
> + struct dw_pcie *pci = &btpci->dw;
> + u32 val;
> + int ret;
> +
> + /* First get out of the Power/Hot reset state */
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert PHY reset\n");
> + return ret;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert hot reset\n");
> + goto err_assert_pwr_rst;
> + }
> +
> + /* Wait for the PM-core to stop requesting the PHY reset */

What is PM core here? By first look I thought you are referring to Linux PM
core framework.

> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> + !(val & BT1_CCU_PCIE_REQ_PHY_RST),
> + BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
> + if (ret) {
> + dev_err(dev, "Timed out waiting for PM to stop PHY resetting\n");

With relation to my above comment, this log might be confusing.

> + goto err_assert_hot_rst;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert PHY reset\n");
> + goto err_assert_hot_rst;
> + }
> +
> + /* Clocks can be now enabled, but the ref one is crucial at this stage */
> + ret = clk_bulk_prepare_enable(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> + if (ret) {
> + dev_err(dev, "Failed to enable app clocks\n");
> + goto err_assert_phy_rst;
> + }
> +
> + ret = clk_bulk_prepare_enable(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> + if (ret) {
> + dev_err(dev, "Failed to enable ref clocks\n");
> + goto err_disable_app_clk;
> + }
> +
> + /* Wait for the PM to stop requesting the controller core reset */
> + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> + !(val & BT1_CCU_PCIE_REQ_CORE_RST),
> + BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
> + if (ret) {
> + dev_err(dev, "Timed out waiting for PM to stop core resetting\n");
> + goto err_disable_core_clk;
> + }
> +
> + /* PCS-PIPE interface and controller core can be now activated */
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert PIPE reset\n");
> + goto err_disable_core_clk;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert core reset\n");
> + goto err_assert_pipe_rst;
> + }
> +
> + /* It's recommended to reset the core and application logic together */
> + ret = reset_control_bulk_reset(DW_PCIE_NUM_APP_RSTS, pci->app_rsts);
> + if (ret) {
> + dev_err(dev, "Failed to reset app domain\n");
> + goto err_assert_core_rst;
> + }
> +
> + /* Sticky/Non-sticky CSR flags can be now unreset too */
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert sticky reset\n");
> + goto err_assert_core_rst;
> + }
> +
> + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_NON_STICKY_RST].rstc);
> + if (ret) {
> + dev_err(dev, "Failed to deassert non-sticky reset\n");
> + goto err_assert_sticky_rst;
> + }
> +
> + /* Activate the PCIe bus peripheral devices */
> + gpiod_set_value_cansleep(pci->pe_rst, 0);
> +
> + /* Make sure the state is settled (LTSSM is still disabled though) */
> + usleep_range(BT1_PCIE_RUN_DELAY_US, BT1_PCIE_RUN_DELAY_US + 100);
> +
> + return 0;
> +
> +err_assert_sticky_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
> +
> +err_assert_core_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
> +
> +err_assert_pipe_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
> +
> +err_disable_core_clk:
> + clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> +
> +err_disable_app_clk:
> + clk_bulk_disable_unprepare(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> +
> +err_assert_phy_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
> +
> +err_assert_hot_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> +
> +err_assert_pwr_rst:
> + reset_control_assert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> +
> + return ret;
> +}
> +
> +static int bt1_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> + int ret;
> +
> + ret = bt1_pcie_get_resources(btpci);
> + if (ret)
> + return ret;
> +
> + bt1_pcie_full_stop_bus(btpci, true);
> +
> + return bt1_pcie_cold_start_bus(btpci);
> +}
> +
> +static void bt1_pcie_host_deinit(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> +
> + bt1_pcie_full_stop_bus(btpci, false);
> +}
> +
> +static const struct dw_pcie_host_ops bt1_pcie_host_ops = {
> + .host_init = bt1_pcie_host_init,
> + .host_deinit = bt1_pcie_host_deinit,
> +};
> +
> +static struct bt1_pcie *bt1_pcie_create_data(struct platform_device *pdev)
> +{

Since this function is called only from probe, it is better to move it there
itself. It is common for drivers to allocate platform resource in the probe
itself.

> + struct bt1_pcie *btpci;
> +
> + btpci = devm_kzalloc(&pdev->dev, sizeof(*btpci), GFP_KERNEL);
> + if (!btpci)
> + return ERR_PTR(-ENOMEM);
> +
> + btpci->pdev = pdev;
> +
> + platform_set_drvdata(pdev, btpci);
> +
> + return btpci;
> +}
> +
> +static int bt1_pcie_add_port(struct bt1_pcie *btpci)
> +{

This also can be moved to probe.

> + struct device *dev = &btpci->pdev->dev;
> + int ret;
> +
> + btpci->dw.version = DW_PCIE_VER_460A;
> + btpci->dw.dev = dev;
> + btpci->dw.ops = &bt1_pcie_ops;
> +
> + btpci->dw.pp.num_vectors = MAX_MSI_IRQS;
> + btpci->dw.pp.ops = &bt1_pcie_host_ops;
> +
> + dw_pcie_cap_set(&btpci->dw, REQ_RES);
> +
> + ret = dw_pcie_host_init(&btpci->dw.pp);
> +
> + return dev_err_probe(dev, ret, "Failed to initialize DWC PCIe host\n");
> +}
> +
> +static void bt1_pcie_del_port(struct bt1_pcie *btpci)
> +{
> + dw_pcie_host_deinit(&btpci->dw.pp);
> +}
> +
> +static int bt1_pcie_probe(struct platform_device *pdev)
> +{
> + struct bt1_pcie *btpci;
> +
> + btpci = bt1_pcie_create_data(pdev);
> + if (IS_ERR(btpci))
> + return PTR_ERR(btpci);
> +
> + return bt1_pcie_add_port(btpci);
> +}
> +
> +static int bt1_pcie_remove(struct platform_device *pdev)
> +{
> + struct bt1_pcie *btpci = platform_get_drvdata(pdev);
> +
> + bt1_pcie_del_port(btpci);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id bt1_pcie_of_match[] = {
> + { .compatible = "baikal,bt1-pcie" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, bt1_pcie_of_match);
> +
> +static struct platform_driver bt1_pcie_driver = {
> + .probe = bt1_pcie_probe,
> + .remove = bt1_pcie_remove,
> + .driver = {
> + .name = "bt1-pcie",
> + .of_match_table = bt1_pcie_of_match,

You might also want to add PROBE_ASYNCHRONOUS flag to allow parallel probing of
drivers while the dwc core waits for PHY link to be up in dw_pcie_wait_for_link().

Thanks,
Mani

> + },
> +};
> +module_platform_driver(bt1_pcie_driver);
> +
> +MODULE_AUTHOR("Serge Semin <[email protected]>");
> +MODULE_DESCRIPTION("Baikal-T1 PCIe driver");
> +MODULE_LICENSE("GPL");
> --
> 2.38.1
>
>

--
மணிவண்ணன் சதாசிவம்

2022-11-14 08:58:29

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

On Mon, Nov 14, 2022 at 12:16:54PM +0530, Manivannan Sadhasivam wrote:
> On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:
> > Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in
> > the separate parts of the DW PCIe core driver. It doesn't really make
> > sense since the both controller types have identical set of the core CSR
> > regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host
> > and EP initialization methods by moving the platform-specific registers
> > space getting and mapping into a common method. It gets to be even more
> > justified seeing the CSRs base address pointers are preserved in the
> > common DW PCIe descriptor. Note all the OF-based common DW PCIe settings
> > initialization will be moved to the new method too in order to have a
> > single function for all the generic platform properties handling in single
> > place.
> >
> > A nice side-effect of this change is that the pcie-designware-host.c and
> > pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie
> > storage modification, which makes the DW PCIe core, Root Port and Endpoint
> > modules more coherent.
> >
>

> You have clubbed both generic resource API and introducing CDM_CHECK flag.
> Please split them into separate patches.

This modification is a part of the new method dw_pcie_get_resources().
Without that method there is no point in adding the new flag. So no.
It's better to have all of it in a single patch as a part of creating
a coherent resources getter method.

-Sergey

>
> Thanks,
> Mani
>
> > Signed-off-by: Serge Semin <[email protected]>
> > Reviewed-by: Rob Herring <[email protected]>
> >
> > ---
> >
> > Changelog v3:
> > - This is a new patch created on v3 lap of the series.
> >
> > Changelog v4:
> > - Convert the method name from dw_pcie_get_res() to
> > dw_pcie_get_resources(). (@Bjorn)
> >
> > Changelog v7:
> > - Get back device.of_node pointer to the dw_pcie_ep_init() method.
> > (@Yoshihiro)
> > ---
> > .../pci/controller/dwc/pcie-designware-ep.c | 25 +------
> > .../pci/controller/dwc/pcie-designware-host.c | 15 +---
> > drivers/pci/controller/dwc/pcie-designware.c | 75 ++++++++++++++-----
> > drivers/pci/controller/dwc/pcie-designware.h | 3 +
> > 4 files changed, 65 insertions(+), 53 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 237bb01d7852..f68d1ab83bb3 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -13,8 +13,6 @@
> > #include <linux/pci-epc.h>
> > #include <linux/pci-epf.h>
> >
> > -#include "../../pci.h"
> > -
> > void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> > {
> > struct pci_epc *epc = ep->epc;
> > @@ -694,23 +692,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> >
> > INIT_LIST_HEAD(&ep->func_list);
> >
> > - if (!pci->dbi_base) {
> > - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
> > - pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
> > - if (IS_ERR(pci->dbi_base))
> > - return PTR_ERR(pci->dbi_base);
> > - }
> > -
> > - if (!pci->dbi_base2) {
> > - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
> > - if (!res) {
> > - pci->dbi_base2 = pci->dbi_base + SZ_4K;
> > - } else {
> > - pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res);
> > - if (IS_ERR(pci->dbi_base2))
> > - return PTR_ERR(pci->dbi_base2);
> > - }
> > - }
> > + ret = dw_pcie_get_resources(pci);
> > + if (ret)
> > + return ret;
> >
> > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
> > if (!res)
> > @@ -739,9 +723,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> > return -ENOMEM;
> > ep->outbound_addr = addr;
> >
> > - if (pci->link_gen < 1)
> > - pci->link_gen = of_pci_get_max_link_speed(np);
> > -
> > epc = devm_pci_epc_create(dev, &epc_ops);
> > if (IS_ERR(epc)) {
> > dev_err(dev, "Failed to create epc device\n");
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index ea923c25e12d..3ab6ae3712c4 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -16,7 +16,6 @@
> > #include <linux/pci_regs.h>
> > #include <linux/platform_device.h>
> >
> > -#include "../../pci.h"
> > #include "pcie-designware.h"
> >
> > static struct pci_ops dw_pcie_ops;
> > @@ -395,6 +394,10 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> >
> > raw_spin_lock_init(&pp->lock);
> >
> > + ret = dw_pcie_get_resources(pci);
> > + if (ret)
> > + return ret;
> > +
> > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> > if (res) {
> > pp->cfg0_size = resource_size(res);
> > @@ -408,13 +411,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > return -ENODEV;
> > }
> >
> > - if (!pci->dbi_base) {
> > - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
> > - pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
> > - if (IS_ERR(pci->dbi_base))
> > - return PTR_ERR(pci->dbi_base);
> > - }
> > -
> > bridge = devm_pci_alloc_host_bridge(dev, 0);
> > if (!bridge)
> > return -ENOMEM;
> > @@ -429,9 +425,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > pp->io_base = pci_pio_to_address(win->res->start);
> > }
> >
> > - if (pci->link_gen < 1)
> > - pci->link_gen = of_pci_get_max_link_speed(np);
> > -
> > /* Set default bus ops */
> > bridge->ops = &dw_pcie_ops;
> > bridge->child_ops = &dw_child_pcie_ops;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index 9d78e7ca61e1..a8436027434d 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -11,6 +11,7 @@
> > #include <linux/align.h>
> > #include <linux/bitops.h>
> > #include <linux/delay.h>
> > +#include <linux/ioport.h>
> > #include <linux/of.h>
> > #include <linux/of_platform.h>
> > #include <linux/sizes.h>
> > @@ -19,6 +20,59 @@
> > #include "../../pci.h"
> > #include "pcie-designware.h"
> >
> > +int dw_pcie_get_resources(struct dw_pcie *pci)
> > +{
> > + struct platform_device *pdev = to_platform_device(pci->dev);
> > + struct device_node *np = dev_of_node(pci->dev);
> > + struct resource *res;
> > +
> > + if (!pci->dbi_base) {
> > + 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);
> > + }
> > +
> > + /* DBI2 is mainly useful for the endpoint controller */
> > + if (!pci->dbi_base2) {
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
> > + if (res) {
> > + pci->dbi_base2 = devm_pci_remap_cfg_resource(pci->dev, res);
> > + if (IS_ERR(pci->dbi_base2))
> > + return PTR_ERR(pci->dbi_base2);
> > + } else {
> > + pci->dbi_base2 = pci->dbi_base + SZ_4K;
> > + }
> > + }
> > +
> > + /* For non-unrolled iATU/eDMA platforms this range will be ignored */
> > + if (!pci->atu_base) {
> > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
> > + if (res) {
> > + pci->atu_size = resource_size(res);
> > + pci->atu_base = devm_ioremap_resource(pci->dev, res);
> > + if (IS_ERR(pci->atu_base))
> > + return PTR_ERR(pci->atu_base);
> > + } else {
> > + pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
> > + }
> > + }
> > +
> > + /* Set a default value suitable for at most 8 in and 8 out windows */
> > + if (!pci->atu_size)
> > + pci->atu_size = SZ_4K;
> > +
> > + if (pci->link_gen < 1)
> > + pci->link_gen = of_pci_get_max_link_speed(np);
> > +
> > + of_property_read_u32(np, "num-lanes", &pci->num_lanes);
> > +
> > + if (of_property_read_bool(np, "snps,enable-cdm-check"))
> > + dw_pcie_cap_set(pci, CDM_CHECK);
> > +
> > + return 0;
> > +}
> > +
> > void dw_pcie_version_detect(struct dw_pcie *pci)
> > {
> > u32 ver;
> > @@ -639,25 +693,8 @@ static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci)
> >
> > void dw_pcie_iatu_detect(struct dw_pcie *pci)
> > {
> > - struct platform_device *pdev = to_platform_device(pci->dev);
> > -
> > if (dw_pcie_iatu_unroll_enabled(pci)) {
> > dw_pcie_cap_set(pci, IATU_UNROLL);
> > -
> > - if (!pci->atu_base) {
> > - struct resource *res =
> > - platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
> > - if (res) {
> > - pci->atu_size = resource_size(res);
> > - pci->atu_base = devm_ioremap_resource(pci->dev, res);
> > - }
> > - if (!pci->atu_base || IS_ERR(pci->atu_base))
> > - pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
> > - }
> > -
> > - if (!pci->atu_size)
> > - /* Pick a minimal default, enough for 8 in and 8 out windows */
> > - pci->atu_size = SZ_4K;
> > } else {
> > pci->atu_base = pci->dbi_base + PCIE_ATU_VIEWPORT_BASE;
> > pci->atu_size = PCIE_ATU_VIEWPORT_SIZE;
> > @@ -675,7 +712,6 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci)
> >
> > void dw_pcie_setup(struct dw_pcie *pci)
> > {
> > - struct device_node *np = pci->dev->of_node;
> > u32 val;
> >
> > if (pci->link_gen > 0)
> > @@ -703,14 +739,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
> > val |= PORT_LINK_DLL_LINK_EN;
> > dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
> >
> > - if (of_property_read_bool(np, "snps,enable-cdm-check")) {
> > + if (dw_pcie_cap_is(pci, CDM_CHECK)) {
> > val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
> > val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
> > PCIE_PL_CHK_REG_CHK_REG_START;
> > dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
> > }
> >
> > - of_property_read_u32(np, "num-lanes", &pci->num_lanes);
> > if (!pci->num_lanes) {
> > dev_dbg(pci->dev, "Using h/w default number of lanes\n");
> > return;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index c6dddacee3b1..081f169e6021 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -46,6 +46,7 @@
> >
> > /* DWC PCIe controller capabilities */
> > #define DW_PCIE_CAP_IATU_UNROLL 1
> > +#define DW_PCIE_CAP_CDM_CHECK 2
> >
> > #define dw_pcie_cap_is(_pci, _cap) \
> > test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps)
> > @@ -338,6 +339,8 @@ struct dw_pcie {
> > #define to_dw_pcie_from_ep(endpoint) \
> > container_of((endpoint), struct dw_pcie, ep)
> >
> > +int dw_pcie_get_resources(struct dw_pcie *pci);
> > +
> > void dw_pcie_version_detect(struct dw_pcie *pci);
> >
> > u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> > --
> > 2.38.1
> >
> >
>
> --
> மணிவண்ணன் சதாசிவம்

2022-11-14 09:28:41

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 15/20] PCI: dwc: Introduce dma-ranges property support for RC-host

On Mon, Nov 14, 2022 at 12:09:15PM +0530, Manivannan Sadhasivam wrote:
> On Sun, Nov 13, 2022 at 10:12:56PM +0300, Serge Semin wrote:
> > In accordance with the generic PCIe Root Port DT-bindings the "dma-ranges"
> > property has the same format as the "ranges" property. The only difference
> > is in their semantics. The "dma-ranges" property describes the PCIe-to-CPU
> > memory mapping in opposite to the CPU-to-PCIe mapping of the "ranges"
> > property. Even though the DW PCIe controllers are normally equipped with
> > the internal Address Translation Unit which inbound and outbound tables
> > can be used to implement both properties semantics, it was surprising for
> > me to discover that the host-related part of the DW PCIe driver currently
> > supports the "ranges" property only while the "dma-ranges" windows are
> > just ignored. Having the "dma-ranges" supported in the driver would be
> > very handy for the platforms, that don't tolerate the 1:1 CPU-PCIe memory
> > mapping and require a customized PCIe memory layout. So let's fix that by
> > introducing the "dma-ranges" property support.
> >
> > First of all we suggest to rename the dw_pcie_prog_inbound_atu() method to
> > dw_pcie_prog_ep_inbound_atu() and create a new version of the
> > dw_pcie_prog_inbound_atu() function. Thus we'll have two methods for the
> > RC and EP controllers respectively in the same way as it has been
> > developed for the outbound ATU setup methods.
> >
>

> I think you should split the function renaming part into a separate patch.

Don't see this necessary especially at the current stage of the
patchset. Without this modification the renaming isn't required. So
should a revert-patch is applied both of the updates will be undone.

>
> > Secondly aside with the memory window index and type the new
> > dw_pcie_prog_inbound_atu() function will accept CPU address, PCIe address
> > and size as its arguments. These parameters define the PCIe and CPU memory
> > ranges which will be used to setup the respective inbound ATU mapping. The
> > passed parameters need to be verified against the ATU ranges constraints
> > in the same way as it is done for the outbound ranges.
> >
> > Finally the DMA-ranges detected for the PCIe controller need to be
> > converted to the inbound ATU entries during the host controller
> > initialization procedure. It will be done in the framework of the
> > dw_pcie_iatu_setup() method. Note before setting the inbound ranges up we
> > need to disable all the inbound ATU entries in order to prevent unexpected
> > PCIe TLPs translations defined by some third party software like
> > bootloaders.
> >
> > Signed-off-by: Serge Semin <[email protected]>
> > Reviewed-by: Rob Herring <[email protected]>
> > Reviewed-by: Manivannan Sadhasivam <[email protected]>
> >
> > ---
> >
> > Changelog v3:
> > - Drop inbound iATU window size alignment constraint. (@Manivannan)
> > ---
> > .../pci/controller/dwc/pcie-designware-ep.c | 4 +-
> > .../pci/controller/dwc/pcie-designware-host.c | 32 ++++++++++-
> > drivers/pci/controller/dwc/pcie-designware.c | 56 ++++++++++++++++++-
> > drivers/pci/controller/dwc/pcie-designware.h | 6 +-
> > 4 files changed, 89 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 83ddb190292e..237bb01d7852 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -171,8 +171,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
> > return -EINVAL;
> > }
> >
> > - ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, type,
> > - cpu_addr, bar);
> > + ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
> > + cpu_addr, bar);
> > if (ret < 0) {
> > dev_err(pci->dev, "Failed to program IB window\n");
> > return ret;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 39f3b37d4033..ea923c25e12d 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -643,12 +643,15 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > }
> >
> > /*
> > - * Ensure all outbound windows are disabled before proceeding with
> > - * the MEM/IO ranges setups.
> > + * Ensure all out/inbound windows are disabled before proceeding with
> > + * the MEM/IO (dma-)ranges setups.
> > */
> > for (i = 0; i < pci->num_ob_windows; i++)
> > dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, i);
> >
> > + for (i = 0; i < pci->num_ib_windows; i++)
> > + dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
> > +
> > i = 0;
> > resource_list_for_each_entry(entry, &pp->bridge->windows) {
> > if (resource_type(entry->res) != IORESOURCE_MEM)
> > @@ -685,9 +688,32 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > }
> >
> > if (pci->num_ob_windows <= i)
> > - dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)\n",
> > + dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
> > pci->num_ob_windows);
> >
> > + i = 0;
> > + resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
> > + if (resource_type(entry->res) != IORESOURCE_MEM)
> > + continue;
> > +
> > + if (pci->num_ib_windows <= i)
> > + break;
> > +
> > + ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
> > + entry->res->start,
> > + entry->res->start - entry->offset,
> > + resource_size(entry->res));
> > + if (ret) {
> > + dev_err(pci->dev, "Failed to set DMA range %pr\n",
> > + entry->res);
> > + return ret;
> > + }
> > + }
> > +
> > + if (pci->num_ib_windows <= i)
> > + dev_warn(pci->dev, "Dma-ranges exceed inbound iATU size (%u)\n",
>

> s/Dma/dma

Well, I could also make it like DMA-ranges. It depends on what you
imply by the message. I've made it looking like the Ranges-related
counterpart.

-Sergey

>
> Thanks,
> Mani
>
> > + pci->num_ib_windows);
> > +
> > return 0;
> > }
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index c6725c519a47..ca830ee794a7 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -393,8 +393,60 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
> > dw_pcie_writel_atu(pci, PCIE_ATU_REGION_DIR_IB, index, reg, val);
> > }
> >
> > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > - int type, u64 cpu_addr, u8 bar)
> > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> > + u64 cpu_addr, u64 pci_addr, u64 size)
> > +{
> > + u64 limit_addr = pci_addr + size - 1;
> > + u32 retries, val;
> > +
> > + if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
> > + !IS_ALIGNED(cpu_addr, pci->region_align) ||
> > + !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
> > + return -EINVAL;
> > + }
> > +
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_BASE,
> > + lower_32_bits(pci_addr));
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_BASE,
> > + upper_32_bits(pci_addr));
> > +
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LIMIT,
> > + lower_32_bits(limit_addr));
> > + if (dw_pcie_ver_is_ge(pci, 460A))
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_LIMIT,
> > + upper_32_bits(limit_addr));
> > +
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
> > + lower_32_bits(cpu_addr));
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
> > + upper_32_bits(cpu_addr));
> > +
> > + val = type;
> > + if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
> > + dw_pcie_ver_is_ge(pci, 460A))
> > + val |= PCIE_ATU_INCREASE_REGION_SIZE;
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, val);
> > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2, PCIE_ATU_ENABLE);
> > +
> > + /*
> > + * Make sure ATU enable takes effect before any subsequent config
> > + * and I/O accesses.
> > + */
> > + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
> > + val = dw_pcie_readl_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2);
> > + if (val & PCIE_ATU_ENABLE)
> > + return 0;
> > +
> > + mdelay(LINK_WAIT_IATU);
> > + }
> > +
> > + dev_err(pci->dev, "Inbound iATU is not being enabled\n");
> > +
> > + return -ETIMEDOUT;
> > +}
> > +
> > +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > + int type, u64 cpu_addr, u8 bar)
> > {
> > u32 retries, val;
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index a871ae7eb59e..37801bbce854 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -346,8 +346,10 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
> > u64 cpu_addr, u64 pci_addr, u64 size);
> > int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > int type, u64 cpu_addr, u64 pci_addr, u64 size);
> > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > - int type, u64 cpu_addr, u8 bar);
> > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> > + u64 cpu_addr, u64 pci_addr, u64 size);
> > +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > + int type, u64 cpu_addr, u8 bar);
> > void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> > void dw_pcie_setup(struct dw_pcie *pci);
> > void dw_pcie_iatu_detect(struct dw_pcie *pci);
> > --
> > 2.38.1
> >
> >
>
> --
> மணிவண்ணன் சதாசிவம்

2022-11-14 12:14:18

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq

On Sun, Nov 13, 2022 at 06:06:28PM -0600, Rob Herring wrote:
>
> On Sun, 13 Nov 2022 22:12:42 +0300, Serge Semin wrote:
> > Originally as it was defined the legacy bindings the pcie_inbound_axi and
> > pcie_aux clock names were supposed to be used in the fsl,imx6sx-pcie and
> > fsl,imx8mq-pcie devices respectively. But the bindings conversion has been
> > incorrectly so now the fourth clock name is defined as "pcie_inbound_axi
> > for imx6sx-pcie, pcie_aux for imx8mq-pcie", which is completely wrong.
> > Let's fix that by conditionally apply the clock-names constraints based on
> > the compatible string content.
> >
> > Fixes: 751ca492f131 ("dt-bindings: PCI: imx6: convert the imx pcie controller to dtschema")
> > Signed-off-by: Serge Semin <[email protected]>
> > Acked-by: Alexander Stein <[email protected]>
> >
> > ---
> >
> > Changelog v5:
> > - This is a new patch added on the v5 release of the patchset.
> >
> > Changelog v7:
> > - Move the allOf clause to the bottom of the bindings. (@Krzysztof)
> > - Get back the names to the clock-names property and make sure the
> > platform-specific name constraint is applied in the allOf clause.
> > (@Rob)
> > ---
> > .../bindings/pci/fsl,imx6q-pcie.yaml | 46 +++++++++++++++++--
> > 1 file changed, 42 insertions(+), 4 deletions(-)
> >
>

> Running 'make dtbs_check' with the schema in this patch gives the
> following warnings. Consider if they are expected or the schema is
> incorrect. These may not be new warnings.

Yeah, these are the old warnings. No semantic change causing them
provided in this patch.

-Sergey

>
> Note that it is not yet a requirement to have 0 warnings for dtbs_check.
> This will change in the future.
>
> Full log is available here: https://patchwork.ozlabs.org/patch/
>
>
> pcie@1ffc000: Unevaluated properties are not allowed ('disable-gpio' was unexpected)
> arch/arm/boot/dts/imx6dl-emcon-avari.dtb
> arch/arm/boot/dts/imx6q-emcon-avari.dtb
>
> pcie@33800000: clock-names:1: 'pcie_bus' was expected
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33800000: clock-names:2: 'pcie_phy' was expected
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
>
> pcie@33800000: clock-names:3: 'pcie_aux' was expected
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33800000: clock-names:3: 'pcie_bus' is not one of ['pcie_inbound_axi', 'pcie_aux']
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33800000: power-domains: [[102, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb
>
> pcie@33800000: power-domains: [[102]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
>
> pcie@33800000: power-domains: [[103]] is too short
> arch/arm/boot/dts/imx7d-colibri-emmc-iris.dtb
> arch/arm/boot/dts/imx7d-colibri-iris.dtb
>
> pcie@33800000: power-domains: [[104]] is too short
> arch/arm/boot/dts/imx7d-colibri-aster.dtb
> arch/arm/boot/dts/imx7d-colibri-emmc-aster.dtb
> arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dtb
> arch/arm/boot/dts/imx7d-colibri-iris-v2.dtb
>
> pcie@33800000: power-domains: [[106]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
>
> pcie@33800000: power-domains: [[107]] is too short
> arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dtb
> arch/arm/boot/dts/imx7d-colibri-eval-v3.dtb
>
> pcie@33800000: power-domains: [[108]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
>
> pcie@33800000: power-domains: [[125]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb
>
> pcie@33800000: power-domains: [[126]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb
>
> pcie@33800000: power-domains: [[49, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
>
> pcie@33800000: power-domains: [[55]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
>
> pcie@33800000: power-domains: [[59]] is too short
> arch/arm/boot/dts/imx7d-cl-som-imx7.dtb
>
> pcie@33800000: power-domains: [[60, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
>
> pcie@33800000: power-domains: [[61]] is too short
> arch/arm/boot/dts/imx7d-sbc-imx7.dtb
>
> pcie@33800000: power-domains: [[63]] is too short
> arch/arm/boot/dts/imx7d-zii-rmu2.dtb
>
> pcie@33800000: power-domains: [[64, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
>
> pcie@33800000: power-domains: [[64]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm/boot/dts/imx7d-remarkable2.dtb
>
> pcie@33800000: power-domains: [[67]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
>
> pcie@33800000: power-domains: [[68]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm/boot/dts/imx7d-meerkat96.dtb
>
> pcie@33800000: power-domains: [[70, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
>
> pcie@33800000: power-domains: [[70]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
> arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb
>
> pcie@33800000: power-domains: [[72]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
>
> pcie@33800000: power-domains: [[73]] is too short
> arch/arm/boot/dts/imx7d-flex-concentrator.dtb
> arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dtb
> arch/arm/boot/dts/imx7d-smegw01.dtb
>
> pcie@33800000: power-domains: [[75]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
>
> pcie@33800000: power-domains: [[76, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
>
> pcie@33800000: power-domains: [[76]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
> arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
>
> pcie@33800000: power-domains: [[77]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
>
> pcie@33800000: power-domains: [[78]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb
>
> pcie@33800000: power-domains: [[79]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb
>
> pcie@33800000: power-domains: [[80]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
>
> pcie@33800000: power-domains: [[81]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
>
> pcie@33800000: power-domains: [[82]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb
>
> pcie@33800000: power-domains: [[83, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
>
> pcie@33800000: power-domains: [[84]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
>
> pcie@33800000: power-domains: [[86, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
>
> pcie@33800000: power-domains: [[86]] is too short
> arch/arm/boot/dts/imx7d-nitrogen7.dtb
> arch/arm/boot/dts/imx7d-pico-nymph.dtb
>
> pcie@33800000: power-domains: [[87]] is too short
> arch/arm/boot/dts/imx7d-sdb-reva.dtb
>
> pcie@33800000: power-domains: [[88]] is too short
> arch/arm/boot/dts/imx7d-pico-dwarf.dtb
> arch/arm/boot/dts/imx7d-pico-hobbit.dtb
> arch/arm/boot/dts/imx7d-sdb.dtb
> arch/arm/boot/dts/imx7d-sdb-sht11.dtb
>
> pcie@33800000: power-domains: [[89]] is too short
> arch/arm/boot/dts/imx7d-pico-pi.dtb
> arch/arm/boot/dts/imx7d-zii-rpu2.dtb
>
> pcie@33800000: power-domains: [[92]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
>
> pcie@33800000: power-domains: [[96]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm/boot/dts/imx7d-mba7.dtb
>
> pcie@33800000: power-domains: [[97, 3]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
>
> pcie@33800000: power-domains: [[97]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
>
> pcie@33800000: power-domains: [[98]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33800000: reset-names:0: 'pciephy' was expected
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
> arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb
>
> pcie@33800000: reset-names:1: 'apps' was expected
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
> arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb
>
> pcie@33800000: reset-names: ['apps', 'turnoff'] is too short
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
> arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb
>
> pcie@33800000: resets: [[101, 26], [101, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb
>
> pcie@33800000: resets: [[25, 28], [25, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
>
> pcie@33800000: resets: [[26, 28], [26, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
>
> pcie@33800000: resets: [[27, 28], [27, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
>
> pcie@33800000: resets: [[28, 28], [28, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
>
> pcie@33800000: resets: [[29, 28], [29, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
>
> pcie@33800000: resets: [[31, 28], [31, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
>
> pcie@33800000: resets: [[34, 28], [34, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
>
> pcie@33800000: resets: [[40, 28], [40, 29]] is too short
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
>
> pcie@33800000: resets: [[48, 26], [48, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
>
> pcie@33800000: resets: [[59, 26], [59, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
>
> pcie@33800000: resets: [[63, 26], [63, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
>
> pcie@33800000: resets: [[69, 26], [69, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
>
> pcie@33800000: resets: [[75, 26], [75, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
>
> pcie@33800000: resets: [[82, 26], [82, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
>
> pcie@33800000: resets: [[85, 26], [85, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
>
> pcie@33800000: resets: [[96, 26], [96, 27]] is too short
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
>
> pcie@33800000: Unevaluated properties are not allowed ('clock-names', 'epdev_on-supply', 'hard-wired', 'power-domains' were unexpected)
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
>
> pcie@33800000: Unevaluated properties are not allowed ('clock-names', 'power-domains' were unexpected)
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33800000: Unevaluated properties are not allowed ('power-domains', 'reset-names', 'resets' were unexpected)
> arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dtb
> arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dtb
> arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-emcon-avari.dtb
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-ctouch2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-icore-mx8mm-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dtb
> arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dtb
> arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dtb
> arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dtb
> arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s-ep1.dtb
> arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb
> arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dtb
> arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-nonwifi-dev.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dahlia.dtb
> arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-dev.dtb
>
> pcie@33800000: Unevaluated properties are not allowed ('power-domains' was unexpected)
> arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb
> arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
> arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb
> arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb
> arch/arm/boot/dts/imx7d-cl-som-imx7.dtb
> arch/arm/boot/dts/imx7d-colibri-aster.dtb
> arch/arm/boot/dts/imx7d-colibri-emmc-aster.dtb
> arch/arm/boot/dts/imx7d-colibri-emmc-eval-v3.dtb
> arch/arm/boot/dts/imx7d-colibri-emmc-iris.dtb
> arch/arm/boot/dts/imx7d-colibri-emmc-iris-v2.dtb
> arch/arm/boot/dts/imx7d-colibri-eval-v3.dtb
> arch/arm/boot/dts/imx7d-colibri-iris.dtb
> arch/arm/boot/dts/imx7d-colibri-iris-v2.dtb
> arch/arm/boot/dts/imx7d-flex-concentrator.dtb
> arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dtb
> arch/arm/boot/dts/imx7d-mba7.dtb
> arch/arm/boot/dts/imx7d-meerkat96.dtb
> arch/arm/boot/dts/imx7d-nitrogen7.dtb
> arch/arm/boot/dts/imx7d-pico-dwarf.dtb
> arch/arm/boot/dts/imx7d-pico-hobbit.dtb
> arch/arm/boot/dts/imx7d-pico-nymph.dtb
> arch/arm/boot/dts/imx7d-pico-pi.dtb
> arch/arm/boot/dts/imx7d-remarkable2.dtb
> arch/arm/boot/dts/imx7d-sbc-imx7.dtb
> arch/arm/boot/dts/imx7d-sdb.dtb
> arch/arm/boot/dts/imx7d-sdb-reva.dtb
> arch/arm/boot/dts/imx7d-sdb-sht11.dtb
> arch/arm/boot/dts/imx7d-smegw01.dtb
> arch/arm/boot/dts/imx7d-zii-rmu2.dtb
> arch/arm/boot/dts/imx7d-zii-rpu2.dtb
>
> pcie@33c00000: 'bus-range' is a required property
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33c00000: clock-names:1: 'pcie_bus' was expected
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33c00000: clock-names:3: 'pcie_aux' was expected
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33c00000: clock-names:3: 'pcie_bus' is not one of ['pcie_inbound_axi', 'pcie_aux']
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33c00000: power-domains: [[102]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
>
> pcie@33c00000: power-domains: [[125]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb
>
> pcie@33c00000: power-domains: [[126]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb
>
> pcie@33c00000: power-domains: [[70]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
> arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb
>
> pcie@33c00000: power-domains: [[78]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb
>
> pcie@33c00000: power-domains: [[79]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb
>
> pcie@33c00000: power-domains: [[80]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
>
> pcie@33c00000: power-domains: [[81]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
>
> pcie@33c00000: power-domains: [[82]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb
>
> pcie@33c00000: power-domains: [[92]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
>
> pcie@33c00000: power-domains: [[97]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
>
> pcie@33c00000: power-domains: [[98]] is too short
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33c00000: Unevaluated properties are not allowed ('clock-names', 'epdev_on-supply', 'hard-wired', 'power-domains' were unexpected)
> arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dtb
>
> pcie@33c00000: Unevaluated properties are not allowed ('clock-names', 'power-domains' were unexpected)
> arch/arm64/boot/dts/freescale/imx8mq-evk.dtb
> arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dtb
> arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dtb
>
> pcie@33c00000: Unevaluated properties are not allowed ('power-domains' was unexpected)
> arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dtb
> arch/arm64/boot/dts/freescale/imx8mq-librem5-r4.dtb
> arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dtb
> arch/arm64/boot/dts/freescale/imx8mq-phanbell.dtb
> arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dtb
> arch/arm64/boot/dts/freescale/imx8mq-thor96.dtb
>

2022-11-14 13:29:34

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 20/20] PCI: dwc: Add Baikal-T1 PCIe controller support

On Mon, Nov 14, 2022 at 01:01:35PM +0530, Manivannan Sadhasivam wrote:
> On Sun, Nov 13, 2022 at 10:13:01PM +0300, Serge Semin wrote:
> > Baikal-T1 SoC is equipped with DWC PCIe v4.60a host controller. It can be
> > trained to work up to Gen.3 speed over up to x4 lanes. The host controller
> > is attached to the DW PCIe 3.0 PCS via the PIPE-4 interface, which in its
> > turn is connected to the DWC 10G PHY. The whole system is supposed to be
> > fed up with four clock sources: DBI peripheral clock, AXI application
> > clocks and external PHY/core reference clock generating the 100MHz signal.
> > In addition to that the platform provide a way to reset each part of the
> > controller: sticky/non-sticky bits, host controller core, PIPE interface,
> > PCS/PHY and Hot/Power reset signal. The driver also provides a way to
> > handle the GPIO-based PERST# signal.
> >
> > Note due to the Baikal-T1 MMIO peculiarity we have to implement the DBI
> > interface accessors which make sure the IO operations are dword-aligned.
> >
> > Signed-off-by: Serge Semin <[email protected]>
> >
> > ---
> >
> > Changelog v2:
> > - Rename 'syscon' property to 'baikal,bt1-syscon'.
> >
> > Changelog v3:
> > - Use the clocks/resets handlers defined in the DW PCIe core descriptor.
> > (@Rob)
> > - Redefine PCI host bridge config space accessors with the generic
> > pci_generic_config_read32() and pci_generic_config_write32() methods.
> > (@Rob)
> >
> > Changelog v4:
> > - Drop PCIBIOS_* macros usage. (@Rob)
> > - Add "static const" to the dw_pcie_ops and dw_pcie_host_ops structure
> > instances. (@Bjorn)
> > - Rename bt1_pcie_dw_ops to bt1_pcie_ops. (@Bjorn)
> > - Rename bt1_pcie_ops to bt1_pci_ops. (@Bjorn)
> > - Use start_link/stop_link suffixes in the corresponding callbacks.
> > (@Bjorn)
> > - Change the get_res() method suffix to being get_resources(). (@Bjorn)
> > - Change *_{add,del}_dw_port() method to *_{add,del}_port(). (@Bjorn)
> > - Drop dma_coerce_mask_and_coherent() applied to the PCI host bridge
> > kernel device instance. (@Bjorn)
> > - Add the comment above the dma_set_mask_and_coherent() method usage
> > regarding the controller eDMA feature. (@Bjorn)
> > - Fix the comment above the core reset controls assertion. (@Bjorn)
> > - Replace delays and timeout numeric literals with macros. (@Bjorn)
> >
> > Changelog v6:
> > - Move the DMA-mask setup to the eDMA driver. (@Robin)
> >
> > Changelog v7:
> > - Replace if-then-dev_err_probe-return statement with just
> > return-dev_err_probe one.
> > ---
> > drivers/pci/controller/dwc/Kconfig | 9 +
> > drivers/pci/controller/dwc/Makefile | 1 +
> > drivers/pci/controller/dwc/pcie-bt1.c | 643 ++++++++++++++++++++++++++
> > 3 files changed, 653 insertions(+)
> > create mode 100644 drivers/pci/controller/dwc/pcie-bt1.c
> >
> > diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> > index 62ce3abf0f19..771b8b146623 100644
> > --- a/drivers/pci/controller/dwc/Kconfig
> > +++ b/drivers/pci/controller/dwc/Kconfig
> > @@ -222,6 +222,15 @@ config PCIE_ARTPEC6_EP
> > Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
> > endpoint mode. This uses the DesignWare core.
> >
> > +config PCIE_BT1
> > + tristate "Baikal-T1 PCIe controller"
>

> Wondering why cannot this be "PCIE_BAIKAL"? Are you sure that this same driver
> cannot be reused for other Baikal SoCs in future?

Well, there are at least two SoCs: Baikal-M1 and Baikal-S1, which
comprise the Synopsys DW PCIe Host IP-core on boards. But both of them
have different versions of the controller (4.70a and 5.40a, meanwhile
Baikal-T1 has 4.60a) and the clocks/reset/link
enable/disable/establish procedures are also different. So I have much
doubt we should be adding a support for all of them in a single driver
because the only common part for them most likely will be just the
probe and remove methods.) Thus having a generic driver name in the
kernel will cause a confusion (or will require so submit a pre-requisite
config/driver renaming patch) should we decide to submit the drivers
for the new controllers.

>
> > + depends on MIPS_BAIKAL_T1 || COMPILE_TEST
> > + depends on PCI_MSI_IRQ_DOMAIN
> > + select PCIE_DW_HOST
> > + help
> > + Enables support for the PCIe controller in the Baikal-T1 SoC to work
> > + in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
> > +
> > config PCIE_ROCKCHIP_DW_HOST
> > bool "Rockchip DesignWare PCIe controller"
> > select PCIE_DW
> > diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> > index 8ba7b67f5e50..bf5c311875a1 100644
> > --- a/drivers/pci/controller/dwc/Makefile
> > +++ b/drivers/pci/controller/dwc/Makefile
> > @@ -3,6 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
> > obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
> > obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> > obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> > +obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> > obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> > obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> > obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> > diff --git a/drivers/pci/controller/dwc/pcie-bt1.c b/drivers/pci/controller/dwc/pcie-bt1.c
> > new file mode 100644
> > index 000000000000..3346770e6654
> > --- /dev/null
> > +++ b/drivers/pci/controller/dwc/pcie-bt1.c
> > @@ -0,0 +1,643 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
>

> 2022?

Why not. I'll update this if v8 is required.

>
> > + *
> > + * Authors:
> > + * Vadim Vlasov <[email protected]>
> > + * Serge Semin <[email protected]>
> > + *
> > + * Baikal-T1 PCIe controller driver
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/bits.h>
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/kernel.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/module.h>
> > +#include <linux/pci.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/reset.h>
> > +#include <linux/types.h>
> > +
> > +#include "pcie-designware.h"
> > +
> > +/* Baikal-T1 System CCU control registers */
> > +#define BT1_CCU_PCIE_CLKC 0x140
> > +#define BT1_CCU_PCIE_REQ_PCS_CLK BIT(16)
> > +#define BT1_CCU_PCIE_REQ_MAC_CLK BIT(17)
> > +#define BT1_CCU_PCIE_REQ_PIPE_CLK BIT(18)
> > +
> > +#define BT1_CCU_PCIE_RSTC 0x144
> > +#define BT1_CCU_PCIE_REQ_LINK_RST BIT(13)
> > +#define BT1_CCU_PCIE_REQ_SMLH_RST BIT(14)
> > +#define BT1_CCU_PCIE_REQ_PHY_RST BIT(16)
> > +#define BT1_CCU_PCIE_REQ_CORE_RST BIT(24)
> > +#define BT1_CCU_PCIE_REQ_STICKY_RST BIT(26)
> > +#define BT1_CCU_PCIE_REQ_NSTICKY_RST BIT(27)
> > +
> > +#define BT1_CCU_PCIE_PMSC 0x148
> > +#define BT1_CCU_PCIE_LTSSM_STATE_MASK GENMASK(5, 0)
> > +#define BT1_CCU_PCIE_LTSSM_DET_QUIET 0x00
> > +#define BT1_CCU_PCIE_LTSSM_DET_ACT 0x01
> > +#define BT1_CCU_PCIE_LTSSM_POLL_ACT 0x02
> > +#define BT1_CCU_PCIE_LTSSM_POLL_COMP 0x03
> > +#define BT1_CCU_PCIE_LTSSM_POLL_CONF 0x04
> > +#define BT1_CCU_PCIE_LTSSM_PRE_DET_QUIET 0x05
> > +#define BT1_CCU_PCIE_LTSSM_DET_WAIT 0x06
> > +#define BT1_CCU_PCIE_LTSSM_CFG_LNKWD_START 0x07
> > +#define BT1_CCU_PCIE_LTSSM_CFG_LNKWD_ACEPT 0x08
> > +#define BT1_CCU_PCIE_LTSSM_CFG_LNNUM_WAIT 0x09
> > +#define BT1_CCU_PCIE_LTSSM_CFG_LNNUM_ACEPT 0x0a
> > +#define BT1_CCU_PCIE_LTSSM_CFG_COMPLETE 0x0b
> > +#define BT1_CCU_PCIE_LTSSM_CFG_IDLE 0x0c
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_LOCK 0x0d
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_SPEED 0x0e
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_RCVRCFG 0x0f
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_IDLE 0x10
> > +#define BT1_CCU_PCIE_LTSSM_L0 0x11
> > +#define BT1_CCU_PCIE_LTSSM_L0S 0x12
> > +#define BT1_CCU_PCIE_LTSSM_L123_SEND_IDLE 0x13
> > +#define BT1_CCU_PCIE_LTSSM_L1_IDLE 0x14
> > +#define BT1_CCU_PCIE_LTSSM_L2_IDLE 0x15
> > +#define BT1_CCU_PCIE_LTSSM_L2_WAKE 0x16
> > +#define BT1_CCU_PCIE_LTSSM_DIS_ENTRY 0x17
> > +#define BT1_CCU_PCIE_LTSSM_DIS_IDLE 0x18
> > +#define BT1_CCU_PCIE_LTSSM_DISABLE 0x19
> > +#define BT1_CCU_PCIE_LTSSM_LPBK_ENTRY 0x1a
> > +#define BT1_CCU_PCIE_LTSSM_LPBK_ACTIVE 0x1b
> > +#define BT1_CCU_PCIE_LTSSM_LPBK_EXIT 0x1c
> > +#define BT1_CCU_PCIE_LTSSM_LPBK_EXIT_TOUT 0x1d
> > +#define BT1_CCU_PCIE_LTSSM_HOT_RST_ENTRY 0x1e
> > +#define BT1_CCU_PCIE_LTSSM_HOT_RST 0x1f
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ0 0x20
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ1 0x21
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ2 0x22
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ3 0x23
> > +#define BT1_CCU_PCIE_SMLH_LINKUP BIT(6)
> > +#define BT1_CCU_PCIE_RDLH_LINKUP BIT(7)
> > +#define BT1_CCU_PCIE_PM_LINKSTATE_L0S BIT(8)
> > +#define BT1_CCU_PCIE_PM_LINKSTATE_L1 BIT(9)
> > +#define BT1_CCU_PCIE_PM_LINKSTATE_L2 BIT(10)
> > +#define BT1_CCU_PCIE_L1_PENDING BIT(12)
> > +#define BT1_CCU_PCIE_REQ_EXIT_L1 BIT(14)
> > +#define BT1_CCU_PCIE_LTSSM_RCVR_EQ BIT(15)
> > +#define BT1_CCU_PCIE_PM_DSTAT_MASK GENMASK(18, 16)
> > +#define BT1_CCU_PCIE_PM_PME_EN BIT(20)
> > +#define BT1_CCU_PCIE_PM_PME_STATUS BIT(21)
> > +#define BT1_CCU_PCIE_AUX_PM_EN BIT(22)
> > +#define BT1_CCU_PCIE_AUX_PWR_DET BIT(23)
> > +#define BT1_CCU_PCIE_WAKE_DET BIT(24)
> > +#define BT1_CCU_PCIE_TURNOFF_REQ BIT(30)
> > +#define BT1_CCU_PCIE_TURNOFF_ACK BIT(31)
> > +
> > +#define BT1_CCU_PCIE_GENC 0x14c
> > +#define BT1_CCU_PCIE_LTSSM_EN BIT(1)
> > +#define BT1_CCU_PCIE_DBI2_MODE BIT(2)
> > +#define BT1_CCU_PCIE_MGMT_EN BIT(3)
> > +#define BT1_CCU_PCIE_RXLANE_FLIP_EN BIT(16)
> > +#define BT1_CCU_PCIE_TXLANE_FLIP_EN BIT(17)
> > +#define BT1_CCU_PCIE_SLV_XFER_PEND BIT(24)
> > +#define BT1_CCU_PCIE_RCV_XFER_PEND BIT(25)
> > +#define BT1_CCU_PCIE_DBI_XFER_PEND BIT(26)
> > +#define BT1_CCU_PCIE_DMA_XFER_PEND BIT(27)
> > +
> > +#define BT1_CCU_PCIE_LTSSM_LINKUP(_pmsc) \
> > +({ \
> > + int __state = FIELD_GET(BT1_CCU_PCIE_LTSSM_STATE_MASK, _pmsc); \
> > + __state >= BT1_CCU_PCIE_LTSSM_L0 && __state <= BT1_CCU_PCIE_LTSSM_L2_WAKE; \
> > +})
> > +
> > +/* Baikal-T1 PCIe specific control registers */
> > +#define BT1_PCIE_AXI2MGM_LANENUM 0xd04
> > +#define BT1_PCIE_AXI2MGM_LANESEL_MASK GENMASK(3, 0)
> > +
> > +#define BT1_PCIE_AXI2MGM_ADDRCTL 0xd08
> > +#define BT1_PCIE_AXI2MGM_PHYREG_ADDR_MASK GENMASK(20, 0)
> > +#define BT1_PCIE_AXI2MGM_READ_FLAG BIT(29)
> > +#define BT1_PCIE_AXI2MGM_DONE BIT(30)
> > +#define BT1_PCIE_AXI2MGM_BUSY BIT(31)
> > +
> > +#define BT1_PCIE_AXI2MGM_WRITEDATA 0xd0c
> > +#define BT1_PCIE_AXI2MGM_WDATA GENMASK(15, 0)
> > +
> > +#define BT1_PCIE_AXI2MGM_READDATA 0xd10
> > +#define BT1_PCIE_AXI2MGM_RDATA GENMASK(15, 0)
> > +
> > +/* Generic Baikal-T1 PCIe interface resources */
> > +#define BT1_PCIE_NUM_APP_CLKS ARRAY_SIZE(bt1_pcie_app_clks)
> > +#define BT1_PCIE_NUM_CORE_CLKS ARRAY_SIZE(bt1_pcie_core_clks)
> > +#define BT1_PCIE_NUM_APP_RSTS ARRAY_SIZE(bt1_pcie_app_rsts)
> > +#define BT1_PCIE_NUM_CORE_RSTS ARRAY_SIZE(bt1_pcie_core_rsts)
> > +
> > +/* PCIe bus setup delays and timeouts */
> > +#define BT1_PCIE_RST_DELAY_MS 100
> > +#define BT1_PCIE_RUN_DELAY_US 100
> > +#define BT1_PCIE_REQ_DELAY_US 1
> > +#define BT1_PCIE_REQ_TIMEOUT_US 1000
> > +#define BT1_PCIE_LNK_DELAY_US 1000
> > +#define BT1_PCIE_LNK_TIMEOUT_US 1000000
> > +
> > +static const enum dw_pcie_app_clk bt1_pcie_app_clks[] = {
> > + DW_PCIE_DBI_CLK, DW_PCIE_MSTR_CLK, DW_PCIE_SLV_CLK,
> > +};
> > +
> > +static const enum dw_pcie_core_clk bt1_pcie_core_clks[] = {
> > + DW_PCIE_REF_CLK,
> > +};
> > +
> > +static const enum dw_pcie_app_rst bt1_pcie_app_rsts[] = {
> > + DW_PCIE_MSTR_RST, DW_PCIE_SLV_RST,
> > +};
> > +
> > +static const enum dw_pcie_core_rst bt1_pcie_core_rsts[] = {
> > + DW_PCIE_NON_STICKY_RST, DW_PCIE_STICKY_RST, DW_PCIE_CORE_RST,
> > + DW_PCIE_PIPE_RST, DW_PCIE_PHY_RST, DW_PCIE_HOT_RST, DW_PCIE_PWR_RST,
> > +};
> > +
> > +struct bt1_pcie {
> > + struct dw_pcie dw;
> > + struct platform_device *pdev;
> > + struct regmap *sys_regs;
> > +};
> > +#define to_bt1_pcie(_dw) container_of(_dw, struct bt1_pcie, dw)
> > +
> > +/*
> > + * Baikal-T1 MMIO space must be read/written by the dword-aligned
> > + * instructions. Note the methods are optimized to have the dword operations
> > + * performed with minimum overhead as the most frequently used ones.
> > + */
> > +static int bt1_pcie_read_mmio(void __iomem *addr, int size, u32 *val)
> > +{
> > + unsigned int ofs = (uintptr_t)addr & 0x3;
> > +
> > + if (!IS_ALIGNED((uintptr_t)addr, size))
> > + return -EINVAL;
> > +
> > + *val = readl(addr - ofs) >> ofs * BITS_PER_BYTE;
>

> Why can't you use the _relaxed variants?

As a part of a nitpick fix I could, but in this case I don't think
it's very much necessary and IMO it still can be dangerous, since the
IO-accessors utilization is hidden behind the wrapper, which then is
used not only in the LLDD, but in the generic driver too. So depending
on the DW PCIe core driver implementation the strong ordering might be
required if not at the current stage, but in future. So I'd rather be on
the safe side in this case especially seeing it won't give us much
performance gain at runtime since the method is mainly used during the
probe/initialization process.

>
> > + if (size == 4) {
> > + return 0;
> > + } else if (size == 2) {
> > + *val &= 0xffff;
> > + return 0;
> > + } else if (size == 1) {
> > + *val &= 0xff;
> > + return 0;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
>
> [...]
>
> > +/*
> > + * Implements the cold reset procedure in accordance with the reference manual
> > + * and available PM signals.
> > + */
> > +static int bt1_pcie_cold_start_bus(struct bt1_pcie *btpci)
> > +{
> > + struct device *dev = btpci->dw.dev;
> > + struct dw_pcie *pci = &btpci->dw;
> > + u32 val;
> > + int ret;
> > +
> > + /* First get out of the Power/Hot reset state */
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert PHY reset\n");
> > + return ret;
> > + }
> > +
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert hot reset\n");
> > + goto err_assert_pwr_rst;
> > + }
> > +
> > + /* Wait for the PM-core to stop requesting the PHY reset */
>

> What is PM core here? By first look I thought you are referring to Linux PM
> core framework.

See the DW PCIe HW-manual. The IP-core has it's own PM-controller.

>
> > + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> > + !(val & BT1_CCU_PCIE_REQ_PHY_RST),
> > + BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
> > + if (ret) {
> > + dev_err(dev, "Timed out waiting for PM to stop PHY resetting\n");
>
> With relation to my above comment, this log might be confusing.

See above.

>
> > + goto err_assert_hot_rst;
> > + }
> > +
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert PHY reset\n");
> > + goto err_assert_hot_rst;
> > + }
> > +
> > + /* Clocks can be now enabled, but the ref one is crucial at this stage */
> > + ret = clk_bulk_prepare_enable(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> > + if (ret) {
> > + dev_err(dev, "Failed to enable app clocks\n");
> > + goto err_assert_phy_rst;
> > + }
> > +
> > + ret = clk_bulk_prepare_enable(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> > + if (ret) {
> > + dev_err(dev, "Failed to enable ref clocks\n");
> > + goto err_disable_app_clk;
> > + }
> > +
> > + /* Wait for the PM to stop requesting the controller core reset */
> > + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> > + !(val & BT1_CCU_PCIE_REQ_CORE_RST),
> > + BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
> > + if (ret) {
> > + dev_err(dev, "Timed out waiting for PM to stop core resetting\n");
> > + goto err_disable_core_clk;
> > + }
> > +
> > + /* PCS-PIPE interface and controller core can be now activated */
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert PIPE reset\n");
> > + goto err_disable_core_clk;
> > + }
> > +
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert core reset\n");
> > + goto err_assert_pipe_rst;
> > + }
> > +
> > + /* It's recommended to reset the core and application logic together */
> > + ret = reset_control_bulk_reset(DW_PCIE_NUM_APP_RSTS, pci->app_rsts);
> > + if (ret) {
> > + dev_err(dev, "Failed to reset app domain\n");
> > + goto err_assert_core_rst;
> > + }
> > +
> > + /* Sticky/Non-sticky CSR flags can be now unreset too */
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert sticky reset\n");
> > + goto err_assert_core_rst;
> > + }
> > +
> > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_NON_STICKY_RST].rstc);
> > + if (ret) {
> > + dev_err(dev, "Failed to deassert non-sticky reset\n");
> > + goto err_assert_sticky_rst;
> > + }
> > +
> > + /* Activate the PCIe bus peripheral devices */
> > + gpiod_set_value_cansleep(pci->pe_rst, 0);
> > +
> > + /* Make sure the state is settled (LTSSM is still disabled though) */
> > + usleep_range(BT1_PCIE_RUN_DELAY_US, BT1_PCIE_RUN_DELAY_US + 100);
> > +
> > + return 0;
> > +
> > +err_assert_sticky_rst:
> > + reset_control_assert(pci->core_rsts[DW_PCIE_STICKY_RST].rstc);
> > +
> > +err_assert_core_rst:
> > + reset_control_assert(pci->core_rsts[DW_PCIE_CORE_RST].rstc);
> > +
> > +err_assert_pipe_rst:
> > + reset_control_assert(pci->core_rsts[DW_PCIE_PIPE_RST].rstc);
> > +
> > +err_disable_core_clk:
> > + clk_bulk_disable_unprepare(DW_PCIE_NUM_CORE_CLKS, pci->core_clks);
> > +
> > +err_disable_app_clk:
> > + clk_bulk_disable_unprepare(DW_PCIE_NUM_APP_CLKS, pci->app_clks);
> > +
> > +err_assert_phy_rst:
> > + reset_control_assert(pci->core_rsts[DW_PCIE_PHY_RST].rstc);
> > +
> > +err_assert_hot_rst:
> > + reset_control_assert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> > +
> > +err_assert_pwr_rst:
> > + reset_control_assert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> > +
> > + return ret;
> > +}
> > +
> > +static int bt1_pcie_host_init(struct dw_pcie_rp *pp)
> > +{
> > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> > + int ret;
> > +
> > + ret = bt1_pcie_get_resources(btpci);
> > + if (ret)
> > + return ret;
> > +
> > + bt1_pcie_full_stop_bus(btpci, true);
> > +
> > + return bt1_pcie_cold_start_bus(btpci);
> > +}
> > +
> > +static void bt1_pcie_host_deinit(struct dw_pcie_rp *pp)
> > +{
> > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > + struct bt1_pcie *btpci = to_bt1_pcie(pci);
> > +
> > + bt1_pcie_full_stop_bus(btpci, false);
> > +}
> > +
> > +static const struct dw_pcie_host_ops bt1_pcie_host_ops = {
> > + .host_init = bt1_pcie_host_init,
> > + .host_deinit = bt1_pcie_host_deinit,
> > +};
> > +
> > +static struct bt1_pcie *bt1_pcie_create_data(struct platform_device *pdev)
> > +{
>

> Since this function is called only from probe, it is better to move it there
> itself. It is common for drivers to allocate platform resource in the probe
> itself.

Already discussed this with Bjorn. One more time. I find it more
readable to leave the probe method as coherent as possible not bulking
everything in there especially seeing the compiler will embed the
static code in there anyway. So no.

>
> > + struct bt1_pcie *btpci;
> > +
> > + btpci = devm_kzalloc(&pdev->dev, sizeof(*btpci), GFP_KERNEL);
> > + if (!btpci)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + btpci->pdev = pdev;
> > +
> > + platform_set_drvdata(pdev, btpci);
> > +
> > + return btpci;
> > +}
> > +
> > +static int bt1_pcie_add_port(struct bt1_pcie *btpci)
> > +{
>

> This also can be moved to probe.

See above.

>
> > + struct device *dev = &btpci->pdev->dev;
> > + int ret;
> > +
> > + btpci->dw.version = DW_PCIE_VER_460A;
> > + btpci->dw.dev = dev;
> > + btpci->dw.ops = &bt1_pcie_ops;
> > +
> > + btpci->dw.pp.num_vectors = MAX_MSI_IRQS;
> > + btpci->dw.pp.ops = &bt1_pcie_host_ops;
> > +
> > + dw_pcie_cap_set(&btpci->dw, REQ_RES);
> > +
> > + ret = dw_pcie_host_init(&btpci->dw.pp);
> > +
> > + return dev_err_probe(dev, ret, "Failed to initialize DWC PCIe host\n");
> > +}
> > +
> > +static void bt1_pcie_del_port(struct bt1_pcie *btpci)
> > +{
> > + dw_pcie_host_deinit(&btpci->dw.pp);
> > +}
> > +
> > +static int bt1_pcie_probe(struct platform_device *pdev)
> > +{
> > + struct bt1_pcie *btpci;
> > +
> > + btpci = bt1_pcie_create_data(pdev);
> > + if (IS_ERR(btpci))
> > + return PTR_ERR(btpci);
> > +
> > + return bt1_pcie_add_port(btpci);
> > +}
> > +
> > +static int bt1_pcie_remove(struct platform_device *pdev)
> > +{
> > + struct bt1_pcie *btpci = platform_get_drvdata(pdev);
> > +
> > + bt1_pcie_del_port(btpci);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id bt1_pcie_of_match[] = {
> > + { .compatible = "baikal,bt1-pcie" },
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, bt1_pcie_of_match);
> > +
> > +static struct platform_driver bt1_pcie_driver = {
> > + .probe = bt1_pcie_probe,
> > + .remove = bt1_pcie_remove,
> > + .driver = {
> > + .name = "bt1-pcie",
> > + .of_match_table = bt1_pcie_of_match,
>

> You might also want to add PROBE_ASYNCHRONOUS flag to allow parallel probing of
> drivers while the dwc core waits for PHY link to be up in dw_pcie_wait_for_link().

Thanks for reminding me about that flag (though it's
PROBE_PREFER_ASYNCHRONOUS). I was thinking to add it after getting
read the Rob' comment here
https://patchwork.kernel.org/project/linux-pci/patch/[email protected]/#25035943
But then successfully forgot about it. It works well on our platform
and even saves us of 0.5 seconds of the bootup time if no device is
attached to the PCIe controller. No kidding, it's indeed good
suggestion since the whole bootup time is of about 3 seconds. So we'll
be able to reduce it for about 13%. I'll provide this update on v8.

-Sergey

>
> Thanks,
> Mani
>
> > + },
> > +};
> > +module_platform_driver(bt1_pcie_driver);
> > +
> > +MODULE_AUTHOR("Serge Semin <[email protected]>");
> > +MODULE_DESCRIPTION("Baikal-T1 PCIe driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.38.1
> >
> >
>
> --
> மணிவண்ணன் சதாசிவம்

2022-11-14 18:15:50

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 15/20] PCI: dwc: Introduce dma-ranges property support for RC-host

On Mon, Nov 14, 2022 at 11:32:27AM +0300, Serge Semin wrote:
> On Mon, Nov 14, 2022 at 12:09:15PM +0530, Manivannan Sadhasivam wrote:
> > On Sun, Nov 13, 2022 at 10:12:56PM +0300, Serge Semin wrote:
> > > In accordance with the generic PCIe Root Port DT-bindings the "dma-ranges"
> > > property has the same format as the "ranges" property. The only difference
> > > is in their semantics. The "dma-ranges" property describes the PCIe-to-CPU
> > > memory mapping in opposite to the CPU-to-PCIe mapping of the "ranges"
> > > property. Even though the DW PCIe controllers are normally equipped with
> > > the internal Address Translation Unit which inbound and outbound tables
> > > can be used to implement both properties semantics, it was surprising for
> > > me to discover that the host-related part of the DW PCIe driver currently
> > > supports the "ranges" property only while the "dma-ranges" windows are
> > > just ignored. Having the "dma-ranges" supported in the driver would be
> > > very handy for the platforms, that don't tolerate the 1:1 CPU-PCIe memory
> > > mapping and require a customized PCIe memory layout. So let's fix that by
> > > introducing the "dma-ranges" property support.
> > >
> > > First of all we suggest to rename the dw_pcie_prog_inbound_atu() method to
> > > dw_pcie_prog_ep_inbound_atu() and create a new version of the
> > > dw_pcie_prog_inbound_atu() function. Thus we'll have two methods for the
> > > RC and EP controllers respectively in the same way as it has been
> > > developed for the outbound ATU setup methods.
> > >
> >
>
> > I think you should split the function renaming part into a separate patch.
>
> Don't see this necessary especially at the current stage of the
> patchset. Without this modification the renaming isn't required. So
> should a revert-patch is applied both of the updates will be undone.
>

There is no necessity for both API renaming and dma-ranges implementation to be
in the same patch as long as first one is functionally independent. But I'll
defer it to you.

> >
> > > Secondly aside with the memory window index and type the new
> > > dw_pcie_prog_inbound_atu() function will accept CPU address, PCIe address
> > > and size as its arguments. These parameters define the PCIe and CPU memory
> > > ranges which will be used to setup the respective inbound ATU mapping. The
> > > passed parameters need to be verified against the ATU ranges constraints
> > > in the same way as it is done for the outbound ranges.
> > >
> > > Finally the DMA-ranges detected for the PCIe controller need to be
> > > converted to the inbound ATU entries during the host controller
> > > initialization procedure. It will be done in the framework of the
> > > dw_pcie_iatu_setup() method. Note before setting the inbound ranges up we
> > > need to disable all the inbound ATU entries in order to prevent unexpected
> > > PCIe TLPs translations defined by some third party software like
> > > bootloaders.
> > >
> > > Signed-off-by: Serge Semin <[email protected]>
> > > Reviewed-by: Rob Herring <[email protected]>
> > > Reviewed-by: Manivannan Sadhasivam <[email protected]>
> > >
> > > ---
> > >
> > > Changelog v3:
> > > - Drop inbound iATU window size alignment constraint. (@Manivannan)
> > > ---
> > > .../pci/controller/dwc/pcie-designware-ep.c | 4 +-
> > > .../pci/controller/dwc/pcie-designware-host.c | 32 ++++++++++-
> > > drivers/pci/controller/dwc/pcie-designware.c | 56 ++++++++++++++++++-
> > > drivers/pci/controller/dwc/pcie-designware.h | 6 +-
> > > 4 files changed, 89 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > index 83ddb190292e..237bb01d7852 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > @@ -171,8 +171,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
> > > return -EINVAL;
> > > }
> > >
> > > - ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, type,
> > > - cpu_addr, bar);
> > > + ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
> > > + cpu_addr, bar);
> > > if (ret < 0) {
> > > dev_err(pci->dev, "Failed to program IB window\n");
> > > return ret;
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index 39f3b37d4033..ea923c25e12d 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -643,12 +643,15 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > > }
> > >
> > > /*
> > > - * Ensure all outbound windows are disabled before proceeding with
> > > - * the MEM/IO ranges setups.
> > > + * Ensure all out/inbound windows are disabled before proceeding with
> > > + * the MEM/IO (dma-)ranges setups.
> > > */
> > > for (i = 0; i < pci->num_ob_windows; i++)
> > > dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, i);
> > >
> > > + for (i = 0; i < pci->num_ib_windows; i++)
> > > + dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
> > > +
> > > i = 0;
> > > resource_list_for_each_entry(entry, &pp->bridge->windows) {
> > > if (resource_type(entry->res) != IORESOURCE_MEM)
> > > @@ -685,9 +688,32 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > > }
> > >
> > > if (pci->num_ob_windows <= i)
> > > - dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)\n",
> > > + dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
> > > pci->num_ob_windows);
> > >
> > > + i = 0;
> > > + resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
> > > + if (resource_type(entry->res) != IORESOURCE_MEM)
> > > + continue;
> > > +
> > > + if (pci->num_ib_windows <= i)
> > > + break;
> > > +
> > > + ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
> > > + entry->res->start,
> > > + entry->res->start - entry->offset,
> > > + resource_size(entry->res));
> > > + if (ret) {
> > > + dev_err(pci->dev, "Failed to set DMA range %pr\n",
> > > + entry->res);
> > > + return ret;
> > > + }
> > > + }
> > > +
> > > + if (pci->num_ib_windows <= i)
> > > + dev_warn(pci->dev, "Dma-ranges exceed inbound iATU size (%u)\n",
> >
>
> > s/Dma/dma
>
> Well, I could also make it like DMA-ranges. It depends on what you
> imply by the message. I've made it looking like the Ranges-related
> counterpart.
>

Either "DMA" or "dma" looks good. I haven't seen "Dma" mostly.

Thanks,
Mani

> -Sergey
>
> >
> > Thanks,
> > Mani
> >
> > > + pci->num_ib_windows);
> > > +
> > > return 0;
> > > }
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > > index c6725c519a47..ca830ee794a7 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > > @@ -393,8 +393,60 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
> > > dw_pcie_writel_atu(pci, PCIE_ATU_REGION_DIR_IB, index, reg, val);
> > > }
> > >
> > > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > - int type, u64 cpu_addr, u8 bar)
> > > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> > > + u64 cpu_addr, u64 pci_addr, u64 size)
> > > +{
> > > + u64 limit_addr = pci_addr + size - 1;
> > > + u32 retries, val;
> > > +
> > > + if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
> > > + !IS_ALIGNED(cpu_addr, pci->region_align) ||
> > > + !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
> > > + return -EINVAL;
> > > + }
> > > +
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_BASE,
> > > + lower_32_bits(pci_addr));
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_BASE,
> > > + upper_32_bits(pci_addr));
> > > +
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LIMIT,
> > > + lower_32_bits(limit_addr));
> > > + if (dw_pcie_ver_is_ge(pci, 460A))
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_LIMIT,
> > > + upper_32_bits(limit_addr));
> > > +
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
> > > + lower_32_bits(cpu_addr));
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
> > > + upper_32_bits(cpu_addr));
> > > +
> > > + val = type;
> > > + if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
> > > + dw_pcie_ver_is_ge(pci, 460A))
> > > + val |= PCIE_ATU_INCREASE_REGION_SIZE;
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, val);
> > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2, PCIE_ATU_ENABLE);
> > > +
> > > + /*
> > > + * Make sure ATU enable takes effect before any subsequent config
> > > + * and I/O accesses.
> > > + */
> > > + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
> > > + val = dw_pcie_readl_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2);
> > > + if (val & PCIE_ATU_ENABLE)
> > > + return 0;
> > > +
> > > + mdelay(LINK_WAIT_IATU);
> > > + }
> > > +
> > > + dev_err(pci->dev, "Inbound iATU is not being enabled\n");
> > > +
> > > + return -ETIMEDOUT;
> > > +}
> > > +
> > > +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > + int type, u64 cpu_addr, u8 bar)
> > > {
> > > u32 retries, val;
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > > index a871ae7eb59e..37801bbce854 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > > @@ -346,8 +346,10 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
> > > u64 cpu_addr, u64 pci_addr, u64 size);
> > > int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > int type, u64 cpu_addr, u64 pci_addr, u64 size);
> > > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > - int type, u64 cpu_addr, u8 bar);
> > > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> > > + u64 cpu_addr, u64 pci_addr, u64 size);
> > > +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > + int type, u64 cpu_addr, u8 bar);
> > > void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> > > void dw_pcie_setup(struct dw_pcie *pci);
> > > void dw_pcie_iatu_detect(struct dw_pcie *pci);
> > > --
> > > 2.38.1
> > >
> > >
> >
> > --
> > மணிவண்ணன் சதாசிவம்

--
மணிவண்ணன் சதாசிவம்

2022-11-14 18:21:02

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 20/20] PCI: dwc: Add Baikal-T1 PCIe controller support

On Mon, Nov 14, 2022 at 02:20:59PM +0300, Serge Semin wrote:
> On Mon, Nov 14, 2022 at 01:01:35PM +0530, Manivannan Sadhasivam wrote:
> > On Sun, Nov 13, 2022 at 10:13:01PM +0300, Serge Semin wrote:
> > > Baikal-T1 SoC is equipped with DWC PCIe v4.60a host controller. It can be
> > > trained to work up to Gen.3 speed over up to x4 lanes. The host controller
> > > is attached to the DW PCIe 3.0 PCS via the PIPE-4 interface, which in its
> > > turn is connected to the DWC 10G PHY. The whole system is supposed to be
> > > fed up with four clock sources: DBI peripheral clock, AXI application
> > > clocks and external PHY/core reference clock generating the 100MHz signal.
> > > In addition to that the platform provide a way to reset each part of the
> > > controller: sticky/non-sticky bits, host controller core, PIPE interface,
> > > PCS/PHY and Hot/Power reset signal. The driver also provides a way to
> > > handle the GPIO-based PERST# signal.
> > >
> > > Note due to the Baikal-T1 MMIO peculiarity we have to implement the DBI
> > > interface accessors which make sure the IO operations are dword-aligned.
> > >
> > > Signed-off-by: Serge Semin <[email protected]>
> > >
> > > ---
> > >
> > > Changelog v2:
> > > - Rename 'syscon' property to 'baikal,bt1-syscon'.
> > >
> > > Changelog v3:
> > > - Use the clocks/resets handlers defined in the DW PCIe core descriptor.
> > > (@Rob)
> > > - Redefine PCI host bridge config space accessors with the generic
> > > pci_generic_config_read32() and pci_generic_config_write32() methods.
> > > (@Rob)
> > >
> > > Changelog v4:
> > > - Drop PCIBIOS_* macros usage. (@Rob)
> > > - Add "static const" to the dw_pcie_ops and dw_pcie_host_ops structure
> > > instances. (@Bjorn)
> > > - Rename bt1_pcie_dw_ops to bt1_pcie_ops. (@Bjorn)
> > > - Rename bt1_pcie_ops to bt1_pci_ops. (@Bjorn)
> > > - Use start_link/stop_link suffixes in the corresponding callbacks.
> > > (@Bjorn)
> > > - Change the get_res() method suffix to being get_resources(). (@Bjorn)
> > > - Change *_{add,del}_dw_port() method to *_{add,del}_port(). (@Bjorn)
> > > - Drop dma_coerce_mask_and_coherent() applied to the PCI host bridge
> > > kernel device instance. (@Bjorn)
> > > - Add the comment above the dma_set_mask_and_coherent() method usage
> > > regarding the controller eDMA feature. (@Bjorn)
> > > - Fix the comment above the core reset controls assertion. (@Bjorn)
> > > - Replace delays and timeout numeric literals with macros. (@Bjorn)
> > >
> > > Changelog v6:
> > > - Move the DMA-mask setup to the eDMA driver. (@Robin)
> > >
> > > Changelog v7:
> > > - Replace if-then-dev_err_probe-return statement with just
> > > return-dev_err_probe one.
> > > ---
> > > drivers/pci/controller/dwc/Kconfig | 9 +
> > > drivers/pci/controller/dwc/Makefile | 1 +
> > > drivers/pci/controller/dwc/pcie-bt1.c | 643 ++++++++++++++++++++++++++
> > > 3 files changed, 653 insertions(+)
> > > create mode 100644 drivers/pci/controller/dwc/pcie-bt1.c
> > >
> > > diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> > > index 62ce3abf0f19..771b8b146623 100644
> > > --- a/drivers/pci/controller/dwc/Kconfig
> > > +++ b/drivers/pci/controller/dwc/Kconfig
> > > @@ -222,6 +222,15 @@ config PCIE_ARTPEC6_EP
> > > Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
> > > endpoint mode. This uses the DesignWare core.
> > >
> > > +config PCIE_BT1
> > > + tristate "Baikal-T1 PCIe controller"
> >
>
> > Wondering why cannot this be "PCIE_BAIKAL"? Are you sure that this same driver
> > cannot be reused for other Baikal SoCs in future?
>
> Well, there are at least two SoCs: Baikal-M1 and Baikal-S1, which
> comprise the Synopsys DW PCIe Host IP-core on boards. But both of them
> have different versions of the controller (4.70a and 5.40a, meanwhile
> Baikal-T1 has 4.60a) and the clocks/reset/link
> enable/disable/establish procedures are also different. So I have much
> doubt we should be adding a support for all of them in a single driver
> because the only common part for them most likely will be just the
> probe and remove methods.) Thus having a generic driver name in the
> kernel will cause a confusion (or will require so submit a pre-requisite
> config/driver renaming patch) should we decide to submit the drivers
> for the new controllers.
>

Most of the PCIe IPs out there have a single driver for a family/manufacturer.
Unless the IP changes drastically (like a different core), we add a separate
driver for that.

If you look at the Qcom driver, we have clubbed the support for dozens of SoCs
that differ by clock/resets/link and each will be identified by a separate
devicetree compatible. Here all the SoCs have synopsys based IP but only their
resources are different, so grouping them together in a single driver makes
sense.

> >
> > > + depends on MIPS_BAIKAL_T1 || COMPILE_TEST
> > > + depends on PCI_MSI_IRQ_DOMAIN
> > > + select PCIE_DW_HOST
> > > + help
> > > + Enables support for the PCIe controller in the Baikal-T1 SoC to work
> > > + in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
> > > +
> > > config PCIE_ROCKCHIP_DW_HOST
> > > bool "Rockchip DesignWare PCIe controller"
> > > select PCIE_DW
> > > diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> > > index 8ba7b67f5e50..bf5c311875a1 100644
> > > --- a/drivers/pci/controller/dwc/Makefile
> > > +++ b/drivers/pci/controller/dwc/Makefile
> > > @@ -3,6 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
> > > obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
> > > obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> > > obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> > > +obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> > > obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> > > obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> > > obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> > > diff --git a/drivers/pci/controller/dwc/pcie-bt1.c b/drivers/pci/controller/dwc/pcie-bt1.c
> > > new file mode 100644
> > > index 000000000000..3346770e6654
> > > --- /dev/null
> > > +++ b/drivers/pci/controller/dwc/pcie-bt1.c
> > > @@ -0,0 +1,643 @@

[...]

> > > +/*
> > > + * Baikal-T1 MMIO space must be read/written by the dword-aligned
> > > + * instructions. Note the methods are optimized to have the dword operations
> > > + * performed with minimum overhead as the most frequently used ones.
> > > + */
> > > +static int bt1_pcie_read_mmio(void __iomem *addr, int size, u32 *val)
> > > +{
> > > + unsigned int ofs = (uintptr_t)addr & 0x3;
> > > +
> > > + if (!IS_ALIGNED((uintptr_t)addr, size))
> > > + return -EINVAL;
> > > +
> > > + *val = readl(addr - ofs) >> ofs * BITS_PER_BYTE;
> >
>
> > Why can't you use the _relaxed variants?
>
> As a part of a nitpick fix I could, but in this case I don't think
> it's very much necessary and IMO it still can be dangerous, since the
> IO-accessors utilization is hidden behind the wrapper, which then is
> used not only in the LLDD, but in the generic driver too. So depending
> on the DW PCIe core driver implementation the strong ordering might be
> required if not at the current stage, but in future. So I'd rather be on
> the safe side in this case especially seeing it won't give us much
> performance gain at runtime since the method is mainly used during the
> probe/initialization process.
>

Well, I don't see any danger in making this as the relaxed version and that's
why asked. For the safe side of things, we could always use the non-relaxed
version everywhere ;)

> >
> > > + if (size == 4) {
> > > + return 0;
> > > + } else if (size == 2) {
> > > + *val &= 0xffff;
> > > + return 0;
> > > + } else if (size == 1) {
> > > + *val &= 0xff;
> > > + return 0;
> > > + }
> > > +
> > > + return -EINVAL;
> > > +}
> > > +
> >
> > [...]
> >
> > > +/*
> > > + * Implements the cold reset procedure in accordance with the reference manual
> > > + * and available PM signals.
> > > + */
> > > +static int bt1_pcie_cold_start_bus(struct bt1_pcie *btpci)
> > > +{
> > > + struct device *dev = btpci->dw.dev;
> > > + struct dw_pcie *pci = &btpci->dw;
> > > + u32 val;
> > > + int ret;
> > > +
> > > + /* First get out of the Power/Hot reset state */
> > > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> > > + if (ret) {
> > > + dev_err(dev, "Failed to deassert PHY reset\n");
> > > + return ret;
> > > + }
> > > +
> > > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> > > + if (ret) {
> > > + dev_err(dev, "Failed to deassert hot reset\n");
> > > + goto err_assert_pwr_rst;
> > > + }
> > > +
> > > + /* Wait for the PM-core to stop requesting the PHY reset */
> >
>
> > What is PM core here? By first look I thought you are referring to Linux PM
> > core framework.
>
> See the DW PCIe HW-manual. The IP-core has it's own PM-controller.
>

Oh, I was not aware of that...

> >
> > > + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> > > + !(val & BT1_CCU_PCIE_REQ_PHY_RST),
> > > + BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
> > > + if (ret) {
> > > + dev_err(dev, "Timed out waiting for PM to stop PHY resetting\n");
> >
> > With relation to my above comment, this log might be confusing.
>
> See above.

[...]

> > > +static const struct of_device_id bt1_pcie_of_match[] = {
> > > + { .compatible = "baikal,bt1-pcie" },
> > > + {},
> > > +};
> > > +MODULE_DEVICE_TABLE(of, bt1_pcie_of_match);
> > > +
> > > +static struct platform_driver bt1_pcie_driver = {
> > > + .probe = bt1_pcie_probe,
> > > + .remove = bt1_pcie_remove,
> > > + .driver = {
> > > + .name = "bt1-pcie",
> > > + .of_match_table = bt1_pcie_of_match,
> >
>
> > You might also want to add PROBE_ASYNCHRONOUS flag to allow parallel probing of
> > drivers while the dwc core waits for PHY link to be up in dw_pcie_wait_for_link().
>
> Thanks for reminding me about that flag (though it's
> PROBE_PREFER_ASYNCHRONOUS).

Ah, yes!

> I was thinking to add it after getting
> read the Rob' comment here
> https://patchwork.kernel.org/project/linux-pci/patch/[email protected]/#25035943
> But then successfully forgot about it. It works well on our platform
> and even saves us of 0.5 seconds of the bootup time if no device is
> attached to the PCIe controller. No kidding, it's indeed good
> suggestion since the whole bootup time is of about 3 seconds. So we'll
> be able to reduce it for about 13%. I'll provide this update on v8.
>

Cool!

Thanks,
Mani

> -Sergey
>
> >
> > Thanks,
> > Mani
> >
> > > + },
> > > +};
> > > +module_platform_driver(bt1_pcie_driver);
> > > +
> > > +MODULE_AUTHOR("Serge Semin <[email protected]>");
> > > +MODULE_DESCRIPTION("Baikal-T1 PCIe driver");
> > > +MODULE_LICENSE("GPL");
> > > --
> > > 2.38.1
> > >
> > >
> >
> > --
> > மணிவண்ணன் சதாசிவம்

--
மணிவண்ணன் சதாசிவம்

2022-11-14 18:36:24

by Manivannan Sadhasivam

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

On Mon, Nov 14, 2022 at 11:39:03AM +0300, Serge Semin wrote:
> On Mon, Nov 14, 2022 at 12:16:54PM +0530, Manivannan Sadhasivam wrote:
> > On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:
> > > Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in
> > > the separate parts of the DW PCIe core driver. It doesn't really make
> > > sense since the both controller types have identical set of the core CSR
> > > regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host
> > > and EP initialization methods by moving the platform-specific registers
> > > space getting and mapping into a common method. It gets to be even more
> > > justified seeing the CSRs base address pointers are preserved in the
> > > common DW PCIe descriptor. Note all the OF-based common DW PCIe settings
> > > initialization will be moved to the new method too in order to have a
> > > single function for all the generic platform properties handling in single
> > > place.
> > >
> > > A nice side-effect of this change is that the pcie-designware-host.c and
> > > pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie
> > > storage modification, which makes the DW PCIe core, Root Port and Endpoint
> > > modules more coherent.
> > >
> >
>
> > You have clubbed both generic resource API and introducing CDM_CHECK flag.
> > Please split them into separate patches.
>
> This modification is a part of the new method dw_pcie_get_resources().
> Without that method there is no point in adding the new flag. So no.
> It's better to have all of it in a single patch as a part of creating
> a coherent resources getter method.
>

Same comment as previous patch. I'll defer it to you.

Thanks,
Mani

> -Sergey
>
> >
> > Thanks,
> > Mani
> >
> > > Signed-off-by: Serge Semin <[email protected]>
> > > Reviewed-by: Rob Herring <[email protected]>
> > >
> > > ---
> > >
> > > Changelog v3:
> > > - This is a new patch created on v3 lap of the series.
> > >
> > > Changelog v4:
> > > - Convert the method name from dw_pcie_get_res() to
> > > dw_pcie_get_resources(). (@Bjorn)
> > >
> > > Changelog v7:
> > > - Get back device.of_node pointer to the dw_pcie_ep_init() method.
> > > (@Yoshihiro)
> > > ---
> > > .../pci/controller/dwc/pcie-designware-ep.c | 25 +------
> > > .../pci/controller/dwc/pcie-designware-host.c | 15 +---
> > > drivers/pci/controller/dwc/pcie-designware.c | 75 ++++++++++++++-----
> > > drivers/pci/controller/dwc/pcie-designware.h | 3 +
> > > 4 files changed, 65 insertions(+), 53 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > index 237bb01d7852..f68d1ab83bb3 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > @@ -13,8 +13,6 @@
> > > #include <linux/pci-epc.h>
> > > #include <linux/pci-epf.h>
> > >
> > > -#include "../../pci.h"
> > > -
> > > void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> > > {
> > > struct pci_epc *epc = ep->epc;
> > > @@ -694,23 +692,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> > >
> > > INIT_LIST_HEAD(&ep->func_list);
> > >
> > > - if (!pci->dbi_base) {
> > > - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
> > > - pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
> > > - if (IS_ERR(pci->dbi_base))
> > > - return PTR_ERR(pci->dbi_base);
> > > - }
> > > -
> > > - if (!pci->dbi_base2) {
> > > - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
> > > - if (!res) {
> > > - pci->dbi_base2 = pci->dbi_base + SZ_4K;
> > > - } else {
> > > - pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res);
> > > - if (IS_ERR(pci->dbi_base2))
> > > - return PTR_ERR(pci->dbi_base2);
> > > - }
> > > - }
> > > + ret = dw_pcie_get_resources(pci);
> > > + if (ret)
> > > + return ret;
> > >
> > > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
> > > if (!res)
> > > @@ -739,9 +723,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> > > return -ENOMEM;
> > > ep->outbound_addr = addr;
> > >
> > > - if (pci->link_gen < 1)
> > > - pci->link_gen = of_pci_get_max_link_speed(np);
> > > -
> > > epc = devm_pci_epc_create(dev, &epc_ops);
> > > if (IS_ERR(epc)) {
> > > dev_err(dev, "Failed to create epc device\n");
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index ea923c25e12d..3ab6ae3712c4 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -16,7 +16,6 @@
> > > #include <linux/pci_regs.h>
> > > #include <linux/platform_device.h>
> > >
> > > -#include "../../pci.h"
> > > #include "pcie-designware.h"
> > >
> > > static struct pci_ops dw_pcie_ops;
> > > @@ -395,6 +394,10 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > >
> > > raw_spin_lock_init(&pp->lock);
> > >
> > > + ret = dw_pcie_get_resources(pci);
> > > + if (ret)
> > > + return ret;
> > > +
> > > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> > > if (res) {
> > > pp->cfg0_size = resource_size(res);
> > > @@ -408,13 +411,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > > return -ENODEV;
> > > }
> > >
> > > - if (!pci->dbi_base) {
> > > - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
> > > - pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
> > > - if (IS_ERR(pci->dbi_base))
> > > - return PTR_ERR(pci->dbi_base);
> > > - }
> > > -
> > > bridge = devm_pci_alloc_host_bridge(dev, 0);
> > > if (!bridge)
> > > return -ENOMEM;
> > > @@ -429,9 +425,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > > pp->io_base = pci_pio_to_address(win->res->start);
> > > }
> > >
> > > - if (pci->link_gen < 1)
> > > - pci->link_gen = of_pci_get_max_link_speed(np);
> > > -
> > > /* Set default bus ops */
> > > bridge->ops = &dw_pcie_ops;
> > > bridge->child_ops = &dw_child_pcie_ops;
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > > index 9d78e7ca61e1..a8436027434d 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > > @@ -11,6 +11,7 @@
> > > #include <linux/align.h>
> > > #include <linux/bitops.h>
> > > #include <linux/delay.h>
> > > +#include <linux/ioport.h>
> > > #include <linux/of.h>
> > > #include <linux/of_platform.h>
> > > #include <linux/sizes.h>
> > > @@ -19,6 +20,59 @@
> > > #include "../../pci.h"
> > > #include "pcie-designware.h"
> > >
> > > +int dw_pcie_get_resources(struct dw_pcie *pci)
> > > +{
> > > + struct platform_device *pdev = to_platform_device(pci->dev);
> > > + struct device_node *np = dev_of_node(pci->dev);
> > > + struct resource *res;
> > > +
> > > + if (!pci->dbi_base) {
> > > + 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);
> > > + }
> > > +
> > > + /* DBI2 is mainly useful for the endpoint controller */
> > > + if (!pci->dbi_base2) {
> > > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
> > > + if (res) {
> > > + pci->dbi_base2 = devm_pci_remap_cfg_resource(pci->dev, res);
> > > + if (IS_ERR(pci->dbi_base2))
> > > + return PTR_ERR(pci->dbi_base2);
> > > + } else {
> > > + pci->dbi_base2 = pci->dbi_base + SZ_4K;
> > > + }
> > > + }
> > > +
> > > + /* For non-unrolled iATU/eDMA platforms this range will be ignored */
> > > + if (!pci->atu_base) {
> > > + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
> > > + if (res) {
> > > + pci->atu_size = resource_size(res);
> > > + pci->atu_base = devm_ioremap_resource(pci->dev, res);
> > > + if (IS_ERR(pci->atu_base))
> > > + return PTR_ERR(pci->atu_base);
> > > + } else {
> > > + pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
> > > + }
> > > + }
> > > +
> > > + /* Set a default value suitable for at most 8 in and 8 out windows */
> > > + if (!pci->atu_size)
> > > + pci->atu_size = SZ_4K;
> > > +
> > > + if (pci->link_gen < 1)
> > > + pci->link_gen = of_pci_get_max_link_speed(np);
> > > +
> > > + of_property_read_u32(np, "num-lanes", &pci->num_lanes);
> > > +
> > > + if (of_property_read_bool(np, "snps,enable-cdm-check"))
> > > + dw_pcie_cap_set(pci, CDM_CHECK);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > void dw_pcie_version_detect(struct dw_pcie *pci)
> > > {
> > > u32 ver;
> > > @@ -639,25 +693,8 @@ static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci)
> > >
> > > void dw_pcie_iatu_detect(struct dw_pcie *pci)
> > > {
> > > - struct platform_device *pdev = to_platform_device(pci->dev);
> > > -
> > > if (dw_pcie_iatu_unroll_enabled(pci)) {
> > > dw_pcie_cap_set(pci, IATU_UNROLL);
> > > -
> > > - if (!pci->atu_base) {
> > > - struct resource *res =
> > > - platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
> > > - if (res) {
> > > - pci->atu_size = resource_size(res);
> > > - pci->atu_base = devm_ioremap_resource(pci->dev, res);
> > > - }
> > > - if (!pci->atu_base || IS_ERR(pci->atu_base))
> > > - pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
> > > - }
> > > -
> > > - if (!pci->atu_size)
> > > - /* Pick a minimal default, enough for 8 in and 8 out windows */
> > > - pci->atu_size = SZ_4K;
> > > } else {
> > > pci->atu_base = pci->dbi_base + PCIE_ATU_VIEWPORT_BASE;
> > > pci->atu_size = PCIE_ATU_VIEWPORT_SIZE;
> > > @@ -675,7 +712,6 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci)
> > >
> > > void dw_pcie_setup(struct dw_pcie *pci)
> > > {
> > > - struct device_node *np = pci->dev->of_node;
> > > u32 val;
> > >
> > > if (pci->link_gen > 0)
> > > @@ -703,14 +739,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
> > > val |= PORT_LINK_DLL_LINK_EN;
> > > dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
> > >
> > > - if (of_property_read_bool(np, "snps,enable-cdm-check")) {
> > > + if (dw_pcie_cap_is(pci, CDM_CHECK)) {
> > > val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
> > > val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
> > > PCIE_PL_CHK_REG_CHK_REG_START;
> > > dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
> > > }
> > >
> > > - of_property_read_u32(np, "num-lanes", &pci->num_lanes);
> > > if (!pci->num_lanes) {
> > > dev_dbg(pci->dev, "Using h/w default number of lanes\n");
> > > return;
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > > index c6dddacee3b1..081f169e6021 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > > @@ -46,6 +46,7 @@
> > >
> > > /* DWC PCIe controller capabilities */
> > > #define DW_PCIE_CAP_IATU_UNROLL 1
> > > +#define DW_PCIE_CAP_CDM_CHECK 2
> > >
> > > #define dw_pcie_cap_is(_pci, _cap) \
> > > test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps)
> > > @@ -338,6 +339,8 @@ struct dw_pcie {
> > > #define to_dw_pcie_from_ep(endpoint) \
> > > container_of((endpoint), struct dw_pcie, ep)
> > >
> > > +int dw_pcie_get_resources(struct dw_pcie *pci);
> > > +
> > > void dw_pcie_version_detect(struct dw_pcie *pci);
> > >
> > > u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> > > --
> > > 2.38.1
> > >
> > >
> >
> > --
> > மணிவண்ணன் சதாசிவம்

--
மணிவண்ணன் சதாசிவம்

2022-11-15 14:53:18

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 15/20] PCI: dwc: Introduce dma-ranges property support for RC-host

On Mon, Nov 14, 2022 at 11:27:21PM +0530, Manivannan Sadhasivam wrote:
> On Mon, Nov 14, 2022 at 11:32:27AM +0300, Serge Semin wrote:
> > On Mon, Nov 14, 2022 at 12:09:15PM +0530, Manivannan Sadhasivam wrote:
> > > On Sun, Nov 13, 2022 at 10:12:56PM +0300, Serge Semin wrote:
> > > > In accordance with the generic PCIe Root Port DT-bindings the "dma-ranges"
> > > > property has the same format as the "ranges" property. The only difference
> > > > is in their semantics. The "dma-ranges" property describes the PCIe-to-CPU
> > > > memory mapping in opposite to the CPU-to-PCIe mapping of the "ranges"
> > > > property. Even though the DW PCIe controllers are normally equipped with
> > > > the internal Address Translation Unit which inbound and outbound tables
> > > > can be used to implement both properties semantics, it was surprising for
> > > > me to discover that the host-related part of the DW PCIe driver currently
> > > > supports the "ranges" property only while the "dma-ranges" windows are
> > > > just ignored. Having the "dma-ranges" supported in the driver would be
> > > > very handy for the platforms, that don't tolerate the 1:1 CPU-PCIe memory
> > > > mapping and require a customized PCIe memory layout. So let's fix that by
> > > > introducing the "dma-ranges" property support.
> > > >
> > > > First of all we suggest to rename the dw_pcie_prog_inbound_atu() method to
> > > > dw_pcie_prog_ep_inbound_atu() and create a new version of the
> > > > dw_pcie_prog_inbound_atu() function. Thus we'll have two methods for the
> > > > RC and EP controllers respectively in the same way as it has been
> > > > developed for the outbound ATU setup methods.
> > > >
> > >
> >
> > > I think you should split the function renaming part into a separate patch.
> >
> > Don't see this necessary especially at the current stage of the
> > patchset. Without this modification the renaming isn't required. So
> > should a revert-patch is applied both of the updates will be undone.
> >
>
> There is no necessity for both API renaming and dma-ranges implementation to be
> in the same patch as long as first one is functionally independent. But I'll
> defer it to you.
>
> > >
> > > > Secondly aside with the memory window index and type the new
> > > > dw_pcie_prog_inbound_atu() function will accept CPU address, PCIe address
> > > > and size as its arguments. These parameters define the PCIe and CPU memory
> > > > ranges which will be used to setup the respective inbound ATU mapping. The
> > > > passed parameters need to be verified against the ATU ranges constraints
> > > > in the same way as it is done for the outbound ranges.
> > > >
> > > > Finally the DMA-ranges detected for the PCIe controller need to be
> > > > converted to the inbound ATU entries during the host controller
> > > > initialization procedure. It will be done in the framework of the
> > > > dw_pcie_iatu_setup() method. Note before setting the inbound ranges up we
> > > > need to disable all the inbound ATU entries in order to prevent unexpected
> > > > PCIe TLPs translations defined by some third party software like
> > > > bootloaders.
> > > >
> > > > Signed-off-by: Serge Semin <[email protected]>
> > > > Reviewed-by: Rob Herring <[email protected]>
> > > > Reviewed-by: Manivannan Sadhasivam <[email protected]>
> > > >
> > > > ---
> > > >
> > > > Changelog v3:
> > > > - Drop inbound iATU window size alignment constraint. (@Manivannan)
> > > > ---
> > > > .../pci/controller/dwc/pcie-designware-ep.c | 4 +-
> > > > .../pci/controller/dwc/pcie-designware-host.c | 32 ++++++++++-
> > > > drivers/pci/controller/dwc/pcie-designware.c | 56 ++++++++++++++++++-
> > > > drivers/pci/controller/dwc/pcie-designware.h | 6 +-
> > > > 4 files changed, 89 insertions(+), 9 deletions(-)
> > > >
> > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > > index 83ddb190292e..237bb01d7852 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > > @@ -171,8 +171,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
> > > > return -EINVAL;
> > > > }
> > > >
> > > > - ret = dw_pcie_prog_inbound_atu(pci, func_no, free_win, type,
> > > > - cpu_addr, bar);
> > > > + ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
> > > > + cpu_addr, bar);
> > > > if (ret < 0) {
> > > > dev_err(pci->dev, "Failed to program IB window\n");
> > > > return ret;
> > > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > index 39f3b37d4033..ea923c25e12d 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > @@ -643,12 +643,15 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > > > }
> > > >
> > > > /*
> > > > - * Ensure all outbound windows are disabled before proceeding with
> > > > - * the MEM/IO ranges setups.
> > > > + * Ensure all out/inbound windows are disabled before proceeding with
> > > > + * the MEM/IO (dma-)ranges setups.
> > > > */
> > > > for (i = 0; i < pci->num_ob_windows; i++)
> > > > dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, i);
> > > >
> > > > + for (i = 0; i < pci->num_ib_windows; i++)
> > > > + dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
> > > > +
> > > > i = 0;
> > > > resource_list_for_each_entry(entry, &pp->bridge->windows) {
> > > > if (resource_type(entry->res) != IORESOURCE_MEM)
> > > > @@ -685,9 +688,32 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > > > }
> > > >
> > > > if (pci->num_ob_windows <= i)
> > > > - dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)\n",
> > > > + dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
> > > > pci->num_ob_windows);
> > > >
> > > > + i = 0;
> > > > + resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
> > > > + if (resource_type(entry->res) != IORESOURCE_MEM)
> > > > + continue;
> > > > +
> > > > + if (pci->num_ib_windows <= i)
> > > > + break;
> > > > +
> > > > + ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
> > > > + entry->res->start,
> > > > + entry->res->start - entry->offset,
> > > > + resource_size(entry->res));
> > > > + if (ret) {
> > > > + dev_err(pci->dev, "Failed to set DMA range %pr\n",
> > > > + entry->res);
> > > > + return ret;
> > > > + }
> > > > + }
> > > > +
> > > > + if (pci->num_ib_windows <= i)
> > > > + dev_warn(pci->dev, "Dma-ranges exceed inbound iATU size (%u)\n",
> > >
> >
> > > s/Dma/dma
> >
> > Well, I could also make it like DMA-ranges. It depends on what you
> > imply by the message. I've made it looking like the Ranges-related
> > counterpart.
> >
>

> Either "DMA" or "dma" looks good. I haven't seen "Dma" mostly.

"DMA" it's then. So it would look more like the just "ranges"-related
warning.

-Sergey

>
> Thanks,
> Mani
>
> > -Sergey
> >
> > >
> > > Thanks,
> > > Mani
> > >
> > > > + pci->num_ib_windows);
> > > > +
> > > > return 0;
> > > > }
> > > >
> > > > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > > > index c6725c519a47..ca830ee794a7 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > > > @@ -393,8 +393,60 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
> > > > dw_pcie_writel_atu(pci, PCIE_ATU_REGION_DIR_IB, index, reg, val);
> > > > }
> > > >
> > > > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > > - int type, u64 cpu_addr, u8 bar)
> > > > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> > > > + u64 cpu_addr, u64 pci_addr, u64 size)
> > > > +{
> > > > + u64 limit_addr = pci_addr + size - 1;
> > > > + u32 retries, val;
> > > > +
> > > > + if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
> > > > + !IS_ALIGNED(cpu_addr, pci->region_align) ||
> > > > + !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
> > > > + return -EINVAL;
> > > > + }
> > > > +
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_BASE,
> > > > + lower_32_bits(pci_addr));
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_BASE,
> > > > + upper_32_bits(pci_addr));
> > > > +
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LIMIT,
> > > > + lower_32_bits(limit_addr));
> > > > + if (dw_pcie_ver_is_ge(pci, 460A))
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_LIMIT,
> > > > + upper_32_bits(limit_addr));
> > > > +
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
> > > > + lower_32_bits(cpu_addr));
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
> > > > + upper_32_bits(cpu_addr));
> > > > +
> > > > + val = type;
> > > > + if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
> > > > + dw_pcie_ver_is_ge(pci, 460A))
> > > > + val |= PCIE_ATU_INCREASE_REGION_SIZE;
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, val);
> > > > + dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2, PCIE_ATU_ENABLE);
> > > > +
> > > > + /*
> > > > + * Make sure ATU enable takes effect before any subsequent config
> > > > + * and I/O accesses.
> > > > + */
> > > > + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
> > > > + val = dw_pcie_readl_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2);
> > > > + if (val & PCIE_ATU_ENABLE)
> > > > + return 0;
> > > > +
> > > > + mdelay(LINK_WAIT_IATU);
> > > > + }
> > > > +
> > > > + dev_err(pci->dev, "Inbound iATU is not being enabled\n");
> > > > +
> > > > + return -ETIMEDOUT;
> > > > +}
> > > > +
> > > > +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > > + int type, u64 cpu_addr, u8 bar)
> > > > {
> > > > u32 retries, val;
> > > >
> > > > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > > > index a871ae7eb59e..37801bbce854 100644
> > > > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > > > @@ -346,8 +346,10 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
> > > > u64 cpu_addr, u64 pci_addr, u64 size);
> > > > int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > > int type, u64 cpu_addr, u64 pci_addr, u64 size);
> > > > -int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > > - int type, u64 cpu_addr, u8 bar);
> > > > +int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
> > > > + u64 cpu_addr, u64 pci_addr, u64 size);
> > > > +int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> > > > + int type, u64 cpu_addr, u8 bar);
> > > > void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> > > > void dw_pcie_setup(struct dw_pcie *pci);
> > > > void dw_pcie_iatu_detect(struct dw_pcie *pci);
> > > > --
> > > > 2.38.1
> > > >
> > > >
> > >
> > > --
> > > மணிவண்ணன் சதாசிவம்
>
> --
> மணிவண்ணன் சதாசிவம்

2022-11-15 16:46:22

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 20/20] PCI: dwc: Add Baikal-T1 PCIe controller support

On Mon, Nov 14, 2022 at 11:41:55PM +0530, Manivannan Sadhasivam wrote:
> On Mon, Nov 14, 2022 at 02:20:59PM +0300, Serge Semin wrote:
> > On Mon, Nov 14, 2022 at 01:01:35PM +0530, Manivannan Sadhasivam wrote:
> > > On Sun, Nov 13, 2022 at 10:13:01PM +0300, Serge Semin wrote:
> > > > Baikal-T1 SoC is equipped with DWC PCIe v4.60a host controller. It can be
> > > > trained to work up to Gen.3 speed over up to x4 lanes. The host controller
> > > > is attached to the DW PCIe 3.0 PCS via the PIPE-4 interface, which in its
> > > > turn is connected to the DWC 10G PHY. The whole system is supposed to be
> > > > fed up with four clock sources: DBI peripheral clock, AXI application
> > > > clocks and external PHY/core reference clock generating the 100MHz signal.
> > > > In addition to that the platform provide a way to reset each part of the
> > > > controller: sticky/non-sticky bits, host controller core, PIPE interface,
> > > > PCS/PHY and Hot/Power reset signal. The driver also provides a way to
> > > > handle the GPIO-based PERST# signal.
> > > >
> > > > Note due to the Baikal-T1 MMIO peculiarity we have to implement the DBI
> > > > interface accessors which make sure the IO operations are dword-aligned.
> > > >
> > > > Signed-off-by: Serge Semin <[email protected]>
> > > >
> > > > ---
> > > >
> > > > Changelog v2:
> > > > - Rename 'syscon' property to 'baikal,bt1-syscon'.
> > > >
> > > > Changelog v3:
> > > > - Use the clocks/resets handlers defined in the DW PCIe core descriptor.
> > > > (@Rob)
> > > > - Redefine PCI host bridge config space accessors with the generic
> > > > pci_generic_config_read32() and pci_generic_config_write32() methods.
> > > > (@Rob)
> > > >
> > > > Changelog v4:
> > > > - Drop PCIBIOS_* macros usage. (@Rob)
> > > > - Add "static const" to the dw_pcie_ops and dw_pcie_host_ops structure
> > > > instances. (@Bjorn)
> > > > - Rename bt1_pcie_dw_ops to bt1_pcie_ops. (@Bjorn)
> > > > - Rename bt1_pcie_ops to bt1_pci_ops. (@Bjorn)
> > > > - Use start_link/stop_link suffixes in the corresponding callbacks.
> > > > (@Bjorn)
> > > > - Change the get_res() method suffix to being get_resources(). (@Bjorn)
> > > > - Change *_{add,del}_dw_port() method to *_{add,del}_port(). (@Bjorn)
> > > > - Drop dma_coerce_mask_and_coherent() applied to the PCI host bridge
> > > > kernel device instance. (@Bjorn)
> > > > - Add the comment above the dma_set_mask_and_coherent() method usage
> > > > regarding the controller eDMA feature. (@Bjorn)
> > > > - Fix the comment above the core reset controls assertion. (@Bjorn)
> > > > - Replace delays and timeout numeric literals with macros. (@Bjorn)
> > > >
> > > > Changelog v6:
> > > > - Move the DMA-mask setup to the eDMA driver. (@Robin)
> > > >
> > > > Changelog v7:
> > > > - Replace if-then-dev_err_probe-return statement with just
> > > > return-dev_err_probe one.
> > > > ---
> > > > drivers/pci/controller/dwc/Kconfig | 9 +
> > > > drivers/pci/controller/dwc/Makefile | 1 +
> > > > drivers/pci/controller/dwc/pcie-bt1.c | 643 ++++++++++++++++++++++++++
> > > > 3 files changed, 653 insertions(+)
> > > > create mode 100644 drivers/pci/controller/dwc/pcie-bt1.c
> > > >
> > > > diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> > > > index 62ce3abf0f19..771b8b146623 100644
> > > > --- a/drivers/pci/controller/dwc/Kconfig
> > > > +++ b/drivers/pci/controller/dwc/Kconfig
> > > > @@ -222,6 +222,15 @@ config PCIE_ARTPEC6_EP
> > > > Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
> > > > endpoint mode. This uses the DesignWare core.
> > > >
> > > > +config PCIE_BT1
> > > > + tristate "Baikal-T1 PCIe controller"
> > >
> >
> > > Wondering why cannot this be "PCIE_BAIKAL"? Are you sure that this same driver
> > > cannot be reused for other Baikal SoCs in future?
> >
> > Well, there are at least two SoCs: Baikal-M1 and Baikal-S1, which
> > comprise the Synopsys DW PCIe Host IP-core on boards. But both of them
> > have different versions of the controller (4.70a and 5.40a, meanwhile
> > Baikal-T1 has 4.60a) and the clocks/reset/link
> > enable/disable/establish procedures are also different. So I have much
> > doubt we should be adding a support for all of them in a single driver
> > because the only common part for them most likely will be just the
> > probe and remove methods.) Thus having a generic driver name in the
> > kernel will cause a confusion (or will require so submit a pre-requisite
> > config/driver renaming patch) should we decide to submit the drivers
> > for the new controllers.
> >
>

> Most of the PCIe IPs out there have a single driver for a family/manufacturer.
> Unless the IP changes drastically (like a different core), we add a separate
> driver for that.

You say 'most', which means not all of them. In anyway I have much
doubt that the "single driver per family/manufacture" rule should be
followed all the time. The fact that it works in a lot of cases
doesn't mean it gets to be general. In fact it depends on the
platform/device implementation. Even if two devices have an interface
synthesized from the same IP-core the synthesize parameters can be
very much different, the platform-setting can differ too. In that case
there is no point in having those two devices handled by the same
driver, because that would just needlessly overcomplicate the code
with a sophisticated abstraction layer (like a full HAL). So it's
better to just split the code up following the KISS principal. It will
cause having simpler individual drivers, make them more readable and
better maintainable, will simplify the parallel development process.
IMO of course.

>
> If you look at the Qcom driver, we have clubbed the support for dozens of SoCs
> that differ by clock/resets/link and each will be identified by a separate
> devicetree compatible. Here all the SoCs have synopsys based IP but only their
> resources are different, so grouping them together in a single driver makes
> sense.

Not only the resource, but the initialization procedures too.
Basically all DW PCIe LLDD contains: request resources,
platform-related inits, device-specific inits, and some of them even
IRQs handling. If all of that is absolutely different, then I don't
see much reason in having the combined driver even if the device is
produced by the same manufacturer.

Anyway I'd suggest to leave the driver in subject as is for now. If at
the moment of the other Baikal-* SoCs PCIe controller drivers
open-sourcing we discover that some part of this driver can be reused,
then we'll make sure this driver is converted to a more generic
version (Kconfig name, driver name, functions/data names) and submit
an update-patch with the new controller support. Currently I'd rather
have a more coherent driver in the kernel than a driver with generic
names but working with only one version of the controller.

>
> > >
> > > > + depends on MIPS_BAIKAL_T1 || COMPILE_TEST
> > > > + depends on PCI_MSI_IRQ_DOMAIN
> > > > + select PCIE_DW_HOST
> > > > + help
> > > > + Enables support for the PCIe controller in the Baikal-T1 SoC to work
> > > > + in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
> > > > +
> > > > config PCIE_ROCKCHIP_DW_HOST
> > > > bool "Rockchip DesignWare PCIe controller"
> > > > select PCIE_DW
> > > > diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> > > > index 8ba7b67f5e50..bf5c311875a1 100644
> > > > --- a/drivers/pci/controller/dwc/Makefile
> > > > +++ b/drivers/pci/controller/dwc/Makefile
> > > > @@ -3,6 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
> > > > obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
> > > > obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
> > > > obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> > > > +obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
> > > > obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> > > > obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> > > > obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
> > > > diff --git a/drivers/pci/controller/dwc/pcie-bt1.c b/drivers/pci/controller/dwc/pcie-bt1.c
> > > > new file mode 100644
> > > > index 000000000000..3346770e6654
> > > > --- /dev/null
> > > > +++ b/drivers/pci/controller/dwc/pcie-bt1.c
> > > > @@ -0,0 +1,643 @@
>
> [...]
>
> > > > +/*
> > > > + * Baikal-T1 MMIO space must be read/written by the dword-aligned
> > > > + * instructions. Note the methods are optimized to have the dword operations
> > > > + * performed with minimum overhead as the most frequently used ones.
> > > > + */
> > > > +static int bt1_pcie_read_mmio(void __iomem *addr, int size, u32 *val)
> > > > +{
> > > > + unsigned int ofs = (uintptr_t)addr & 0x3;
> > > > +
> > > > + if (!IS_ALIGNED((uintptr_t)addr, size))
> > > > + return -EINVAL;
> > > > +
> > > > + *val = readl(addr - ofs) >> ofs * BITS_PER_BYTE;
> > >
> >
> > > Why can't you use the _relaxed variants?
> >
> > As a part of a nitpick fix I could, but in this case I don't think
> > it's very much necessary and IMO it still can be dangerous, since the
> > IO-accessors utilization is hidden behind the wrapper, which then is
> > used not only in the LLDD, but in the generic driver too. So depending
> > on the DW PCIe core driver implementation the strong ordering might be
> > required if not at the current stage, but in future. So I'd rather be on
> > the safe side in this case especially seeing it won't give us much
> > performance gain at runtime since the method is mainly used during the
> > probe/initialization process.
> >
>

> Well, I don't see any danger in making this as the relaxed version and that's
> why asked. For the safe side of things, we could always use the non-relaxed
> version everywhere ;)

There are in general many nasty and hard to fix bugs might be caused
due to using the relaxed-version of the accessors. Let's take the DW
PCIe driver for instance. The DW PCIe host driver performs the
DBI-access protected by the spin-lock in the methods
dw_pci_bottom_mask()/dw_pci_bottom_unmask(). In accordance with
"Documentation/memory-barriers.txt" the "relaxed" method don't
guarantee the ordering with respect to locking. It doesn't guarantee
an ordering of the parallel accesses to the same IO-address either. It
means the actual IO may be completed after the lock is released, due
to which a concurrent code may see an outdated value if it
reads/writes from/to the same IO-address in the framework of the
critical section. Such code may work most of the time until at some
point you see that some IRQ line isn't masked/unmasked even after the
corresponding mask/unmask method is executed. Moreover absolutely the
same code using the relaxed-version can work on one platform and fail
on another due to many things: IO-bus implementation,
platform-specific locks design, relaxed IO-accessors implementation,
etc (though in this context we are talking about a single platform).

In this particular case you suggest to update the method which is
utilized exactly for the DBI-accesses. Thus if we did as you say at
some random point it might work not as expected depending on the
context like described above. So on the second thought answering to
your original question, no, I can't use the "relaxed"-version here at
the very least due to the reason described above and taking into
account that the driver core methods dw_pcie_read()/dw_pcie_write()
don't use them too.

Please also note all the DW PCIe LLDD (histb, exynos, kirin) defining
the custom DBI-accessors use the strictest IO-accessors version in the
same way as the DW PCIe core driver.

-Sergey

>
> > >
> > > > + if (size == 4) {
> > > > + return 0;
> > > > + } else if (size == 2) {
> > > > + *val &= 0xffff;
> > > > + return 0;
> > > > + } else if (size == 1) {
> > > > + *val &= 0xff;
> > > > + return 0;
> > > > + }
> > > > +
> > > > + return -EINVAL;
> > > > +}
> > > > +
> > >
> > > [...]
> > >
> > > > +/*
> > > > + * Implements the cold reset procedure in accordance with the reference manual
> > > > + * and available PM signals.
> > > > + */
> > > > +static int bt1_pcie_cold_start_bus(struct bt1_pcie *btpci)
> > > > +{
> > > > + struct device *dev = btpci->dw.dev;
> > > > + struct dw_pcie *pci = &btpci->dw;
> > > > + u32 val;
> > > > + int ret;
> > > > +
> > > > + /* First get out of the Power/Hot reset state */
> > > > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_PWR_RST].rstc);
> > > > + if (ret) {
> > > > + dev_err(dev, "Failed to deassert PHY reset\n");
> > > > + return ret;
> > > > + }
> > > > +
> > > > + ret = reset_control_deassert(pci->core_rsts[DW_PCIE_HOT_RST].rstc);
> > > > + if (ret) {
> > > > + dev_err(dev, "Failed to deassert hot reset\n");
> > > > + goto err_assert_pwr_rst;
> > > > + }
> > > > +
> > > > + /* Wait for the PM-core to stop requesting the PHY reset */
> > >
> >
> > > What is PM core here? By first look I thought you are referring to Linux PM
> > > core framework.
> >
> > See the DW PCIe HW-manual. The IP-core has it's own PM-controller.
> >
>
> Oh, I was not aware of that...
>
> > >
> > > > + ret = regmap_read_poll_timeout(btpci->sys_regs, BT1_CCU_PCIE_RSTC, val,
> > > > + !(val & BT1_CCU_PCIE_REQ_PHY_RST),
> > > > + BT1_PCIE_REQ_DELAY_US, BT1_PCIE_REQ_TIMEOUT_US);
> > > > + if (ret) {
> > > > + dev_err(dev, "Timed out waiting for PM to stop PHY resetting\n");
> > >
> > > With relation to my above comment, this log might be confusing.
> >
> > See above.
>
> [...]
>
> > > > +static const struct of_device_id bt1_pcie_of_match[] = {
> > > > + { .compatible = "baikal,bt1-pcie" },
> > > > + {},
> > > > +};
> > > > +MODULE_DEVICE_TABLE(of, bt1_pcie_of_match);
> > > > +
> > > > +static struct platform_driver bt1_pcie_driver = {
> > > > + .probe = bt1_pcie_probe,
> > > > + .remove = bt1_pcie_remove,
> > > > + .driver = {
> > > > + .name = "bt1-pcie",
> > > > + .of_match_table = bt1_pcie_of_match,
> > >
> >
> > > You might also want to add PROBE_ASYNCHRONOUS flag to allow parallel probing of
> > > drivers while the dwc core waits for PHY link to be up in dw_pcie_wait_for_link().
> >
> > Thanks for reminding me about that flag (though it's
> > PROBE_PREFER_ASYNCHRONOUS).
>
> Ah, yes!
>
> > I was thinking to add it after getting
> > read the Rob' comment here
> > https://patchwork.kernel.org/project/linux-pci/patch/[email protected]/#25035943
> > But then successfully forgot about it. It works well on our platform
> > and even saves us of 0.5 seconds of the bootup time if no device is
> > attached to the PCIe controller. No kidding, it's indeed good
> > suggestion since the whole bootup time is of about 3 seconds. So we'll
> > be able to reduce it for about 13%. I'll provide this update on v8.
> >
>
> Cool!
>
> Thanks,
> Mani
>
> > -Sergey
> >
> > >
> > > Thanks,
> > > Mani
> > >
> > > > + },
> > > > +};
> > > > +module_platform_driver(bt1_pcie_driver);
> > > > +
> > > > +MODULE_AUTHOR("Serge Semin <[email protected]>");
> > > > +MODULE_DESCRIPTION("Baikal-T1 PCIe driver");
> > > > +MODULE_LICENSE("GPL");
> > > > --
> > > > 2.38.1
> > > >
> > > >
> > >
> > > --
> > > மணிவண்ணன் சதாசிவம்
>
> --
> மணிவண்ணன் சதாசிவம்

2022-11-16 20:39:51

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH v7 01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq

On Sun, Nov 13, 2022 at 10:12:42PM +0300, Serge Semin wrote:
> Originally as it was defined the legacy bindings the pcie_inbound_axi and
> pcie_aux clock names were supposed to be used in the fsl,imx6sx-pcie and
> fsl,imx8mq-pcie devices respectively. But the bindings conversion has been
> incorrectly so now the fourth clock name is defined as "pcie_inbound_axi
> for imx6sx-pcie, pcie_aux for imx8mq-pcie", which is completely wrong.
> Let's fix that by conditionally apply the clock-names constraints based on
> the compatible string content.
>
> Fixes: 751ca492f131 ("dt-bindings: PCI: imx6: convert the imx pcie controller to dtschema")
> Signed-off-by: Serge Semin <[email protected]>
> Acked-by: Alexander Stein <[email protected]>
>
> ---
>
> Changelog v5:
> - This is a new patch added on the v5 release of the patchset.
>
> Changelog v7:
> - Move the allOf clause to the bottom of the bindings. (@Krzysztof)
> - Get back the names to the clock-names property and make sure the
> platform-specific name constraint is applied in the allOf clause.
> (@Rob)
> ---
> .../bindings/pci/fsl,imx6q-pcie.yaml | 46 +++++++++++++++++--
> 1 file changed, 42 insertions(+), 4 deletions(-)

We have 2 patches doing the same thing:

https://lore.kernel.org/all/[email protected]/

Please hash out which one you all want. Both seem to have clock
warnings still...

Reviewed-by: Rob Herring <[email protected]>

2022-11-17 08:05:25

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq

On Thu, Nov 17, 2022 at 10:43:22AM +0300, Serge Semin wrote:
> On Wed, Nov 16, 2022 at 02:38:12PM -0600, Rob Herring wrote:
> > On Sun, Nov 13, 2022 at 10:12:42PM +0300, Serge Semin wrote:
> > > Originally as it was defined the legacy bindings the pcie_inbound_axi and
> > > pcie_aux clock names were supposed to be used in the fsl,imx6sx-pcie and
> > > fsl,imx8mq-pcie devices respectively. But the bindings conversion has been
> > > incorrectly so now the fourth clock name is defined as "pcie_inbound_axi
> > > for imx6sx-pcie, pcie_aux for imx8mq-pcie", which is completely wrong.
> > > Let's fix that by conditionally apply the clock-names constraints based on
> > > the compatible string content.
> > >
> > > Fixes: 751ca492f131 ("dt-bindings: PCI: imx6: convert the imx pcie controller to dtschema")
> > > Signed-off-by: Serge Semin <[email protected]>
> > > Acked-by: Alexander Stein <[email protected]>
> > >
> > > ---
> > >
> > > Changelog v5:
> > > - This is a new patch added on the v5 release of the patchset.
> > >
> > > Changelog v7:
> > > - Move the allOf clause to the bottom of the bindings. (@Krzysztof)
> > > - Get back the names to the clock-names property and make sure the
> > > platform-specific name constraint is applied in the allOf clause.
> > > (@Rob)
> > > ---
> > > .../bindings/pci/fsl,imx6q-pcie.yaml | 46 +++++++++++++++++--
> > > 1 file changed, 42 insertions(+), 4 deletions(-)
> >
> > We have 2 patches doing the same thing:
> >
> > https://lore.kernel.org/all/[email protected]/
>

> It seems to me that that patch does two things at a time:
> 1. Fixes invalid fourth clock-names entry.
> 2. Fixes the fsl,imx8mm-pcie device having the "pcie_aux" clock name
> required instead of "pcie_phy".
>
> My patch does only the first part. What about moving my patch to that
> series and converting the Marek' patch to being applicable on top of
> it and fixing the imx8mm part only? That seems reasonable.

BTW, if this patch is moved from here the series will fail the
dt_binding_check procedure.

-Sergey

>
> -Sergey
>
> >
> > Please hash out which one you all want. Both seem to have clock
> > warnings still...
> >
> > Reviewed-by: Rob Herring <[email protected]>

2022-11-17 08:43:17

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq

On Wed, Nov 16, 2022 at 02:38:12PM -0600, Rob Herring wrote:
> On Sun, Nov 13, 2022 at 10:12:42PM +0300, Serge Semin wrote:
> > Originally as it was defined the legacy bindings the pcie_inbound_axi and
> > pcie_aux clock names were supposed to be used in the fsl,imx6sx-pcie and
> > fsl,imx8mq-pcie devices respectively. But the bindings conversion has been
> > incorrectly so now the fourth clock name is defined as "pcie_inbound_axi
> > for imx6sx-pcie, pcie_aux for imx8mq-pcie", which is completely wrong.
> > Let's fix that by conditionally apply the clock-names constraints based on
> > the compatible string content.
> >
> > Fixes: 751ca492f131 ("dt-bindings: PCI: imx6: convert the imx pcie controller to dtschema")
> > Signed-off-by: Serge Semin <[email protected]>
> > Acked-by: Alexander Stein <[email protected]>
> >
> > ---
> >
> > Changelog v5:
> > - This is a new patch added on the v5 release of the patchset.
> >
> > Changelog v7:
> > - Move the allOf clause to the bottom of the bindings. (@Krzysztof)
> > - Get back the names to the clock-names property and make sure the
> > platform-specific name constraint is applied in the allOf clause.
> > (@Rob)
> > ---
> > .../bindings/pci/fsl,imx6q-pcie.yaml | 46 +++++++++++++++++--
> > 1 file changed, 42 insertions(+), 4 deletions(-)
>
> We have 2 patches doing the same thing:
>
> https://lore.kernel.org/all/[email protected]/

It seems to me that that patch does two things at a time:
1. Fixes invalid fourth clock-names entry.
2. Fixes the fsl,imx8mm-pcie device having the "pcie_aux" clock name
required instead of "pcie_phy".

My patch does only the first part. What about moving my patch to that
series and converting the Marek' patch to being applicable on top of
it and fixing the imx8mm part only? That seems reasonable.

-Sergey

>
> Please hash out which one you all want. Both seem to have clock
> warnings still...
>
> Reviewed-by: Rob Herring <[email protected]>

2022-11-23 15:24:03

by Lorenzo Pieralisi

[permalink] [raw]
Subject: Re: [PATCH v7 00/20] PCI: dwc: Add generic resources and Baikal-T1 support

On Sun, 13 Nov 2022 22:12:41 +0300, Serge Semin wrote:
> This patchset is a third one in the series created in the framework of
> my Baikal-T1 PCIe/eDMA-related work:
>
> [1: Done v5] PCI: dwc: Various fixes and cleanups
> Link: https://lore.kernel.org/linux-pci/[email protected]/
> Merged: kernel 6.0-rc1
> [2: Done v4] PCI: dwc: Add hw version and dma-ranges support
> Link: https://lore.kernel.org/linux-pci/[email protected]
> Merged: kernel 6.0-rc1
> [3: In-review v7] PCI: dwc: Add generic resources and Baikal-T1 support
> Link: ---you are looking at it---
> [4: Done v6] dmaengine: dw-edma: Add RP/EP local DMA support
> Link: https://lore.kernel.org/linux-pci/[email protected]/
>
> [...]

I think it is time we merged this series - we went through
several rounds of reviews and it should be ready for
mainline (in particular wrt using the generic infrastructure
it puts in place).

Applied to pci/dwc, thank you.

[01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq
https://git.kernel.org/lpieralisi/pci/c/b8a83e600bdd
[02/20] dt-bindings: visconti-pcie: Fix interrupts array max constraints
https://git.kernel.org/lpieralisi/pci/c/4cf4b9b70ab2
[03/20] dt-bindings: PCI: dwc: Detach common RP/EP DT bindings
https://git.kernel.org/lpieralisi/pci/c/057646a5db2f
[04/20] dt-bindings: PCI: dwc: Remove bus node from the examples
https://git.kernel.org/lpieralisi/pci/c/b9fe9985aee2
[05/20] dt-bindings: PCI: dwc: Add phys/phy-names common properties
https://git.kernel.org/lpieralisi/pci/c/875596361910
[06/20] dt-bindings: PCI: dwc: Add max-link-speed common property
https://git.kernel.org/lpieralisi/pci/c/eaa9d8865287
[07/20] dt-bindings: PCI: dwc: Apply generic schema for generic device only
https://git.kernel.org/lpieralisi/pci/c/f133396e2d00
[08/20] dt-bindings: PCI: dwc: Add max-functions EP property
https://git.kernel.org/lpieralisi/pci/c/12f7936c7a0e
[09/20] dt-bindings: PCI: dwc: Add interrupts/interrupt-names common properties
https://git.kernel.org/lpieralisi/pci/c/35486813c41b
[10/20] dt-bindings: PCI: dwc: Add reg/reg-names common properties
https://git.kernel.org/lpieralisi/pci/c/4cc13eedb892
[11/20] dt-bindings: PCI: dwc: Add clocks/resets common properties
https://git.kernel.org/lpieralisi/pci/c/bd9504af9169
[12/20] dt-bindings: PCI: dwc: Add dma-coherent property
https://git.kernel.org/lpieralisi/pci/c/4a8972542a6d
[13/20] dt-bindings: PCI: dwc: Apply common schema to Rockchip DW PCIe nodes
https://git.kernel.org/lpieralisi/pci/c/98b59129cb9f
[14/20] dt-bindings: PCI: dwc: Add Baikal-T1 PCIe Root Port bindings
https://git.kernel.org/lpieralisi/pci/c/ce27c4e61f2d
[15/20] PCI: dwc: Introduce dma-ranges property support for RC-host
https://git.kernel.org/lpieralisi/pci/c/8522e17d4cab
[16/20] PCI: dwc: Introduce generic controller capabilities interface
https://git.kernel.org/lpieralisi/pci/c/7f9e982dc4fc
[17/20] PCI: dwc: Introduce generic resources getter
https://git.kernel.org/lpieralisi/pci/c/ef8c58877fe7
[18/20] PCI: dwc: Combine iATU detection procedures
https://git.kernel.org/lpieralisi/pci/c/9f67ecdd9579
[19/20] PCI: dwc: Introduce generic platform clocks and resets
https://git.kernel.org/lpieralisi/pci/c/ef69f852a978
[20/20] PCI: dwc: Add Baikal-T1 PCIe controller support
https://git.kernel.org/lpieralisi/pci/c/ba6ed462dcf4

Thanks,
Lorenzo

2022-11-23 19:53:54

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

Hi Serge,

On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:
> Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in
> the separate parts of the DW PCIe core driver. It doesn't really make
> sense since the both controller types have identical set of the core CSR
> regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host
> and EP initialization methods by moving the platform-specific registers
> space getting and mapping into a common method. It gets to be even more
> justified seeing the CSRs base address pointers are preserved in the
> common DW PCIe descriptor. Note all the OF-based common DW PCIe settings
> initialization will be moved to the new method too in order to have a
> single function for all the generic platform properties handling in single
> place.
>
> A nice side-effect of this change is that the pcie-designware-host.c and
> pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie
> storage modification, which makes the DW PCIe core, Root Port and Endpoint
> modules more coherent.

Thanks for these new generic interfaces in the DWC core! And thanks
for the changes in this patch to take advantage of them in the
pcie-designware drivers.

Do you plan similar changes to other drivers to take advantage of
these DWC-generic data and interfaces? If you add generic things to
the DWC core but only take advantage of them in your driver, I don't
think they are really usefully generic.

Bjorn

2022-11-25 13:10:46

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 00/20] PCI: dwc: Add generic resources and Baikal-T1 support

On Wed, Nov 23, 2022 at 04:09:12PM +0100, Lorenzo Pieralisi wrote:
> On Sun, 13 Nov 2022 22:12:41 +0300, Serge Semin wrote:
> > This patchset is a third one in the series created in the framework of
> > my Baikal-T1 PCIe/eDMA-related work:
> >
> > [1: Done v5] PCI: dwc: Various fixes and cleanups
> > Link: https://lore.kernel.org/linux-pci/[email protected]/
> > Merged: kernel 6.0-rc1
> > [2: Done v4] PCI: dwc: Add hw version and dma-ranges support
> > Link: https://lore.kernel.org/linux-pci/[email protected]
> > Merged: kernel 6.0-rc1
> > [3: In-review v7] PCI: dwc: Add generic resources and Baikal-T1 support
> > Link: ---you are looking at it---
> > [4: Done v6] dmaengine: dw-edma: Add RP/EP local DMA support
> > Link: https://lore.kernel.org/linux-pci/[email protected]/
> >
> > [...]
>
> I think it is time we merged this series - we went through
> several rounds of reviews and it should be ready for
> mainline (in particular wrt using the generic infrastructure
> it puts in place).
>
> Applied to pci/dwc, thank you.

Thanks. We've finally done that!

Could you please merge the DW eDMA part in too?
Link: https://lore.kernel.org/linux-pci/[email protected]/
Due to the dependencies we agreed to hold it on for until the last DW
PCIe patchset is merged in. See discussion here:
https://lore.kernel.org/dmaengine/20220616183900.ww7ora37kmve7av2@mobilestation/
and here (Vinod ab-tag):
https://lore.kernel.org/linux-pci/YuKFnjrxnyNa+98X@matsya/
and here (the last thread mentioned the dependencies):
https://lore.kernel.org/linux-pci/20220825112843.4pbh37x6wemsdmmp@mobilestation/

The eDMA series has got all the ab/rb/tb-tags from @Vinod and @Mani side.
The only tiny exception is
[PATCH v6 22/24] dmaengine: dw-edma: Bypass dma-ranges mapping for the local setup
for which I had to drop the tags due to an update per the @Robin request
in the framework of the dma-ranges/DMA-mask discussion:
https://lore.kernel.org/linux-pci/20220927104831.bovlzl74osb4t5d3@mobilestation/
https://lore.kernel.org/linux-pci/20221007224515.sseyabdfa2phcsdz@mobilestation/

I failed to reach @Robin since November 8, 2022. If you are able to
effectively draw his attention so he looked at the updated patch, that
would be great. Other than that I see no barrier to merge the DW eDMA
series in too.

-Serge(y)

>
> [01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq
> https://git.kernel.org/lpieralisi/pci/c/b8a83e600bdd
> [02/20] dt-bindings: visconti-pcie: Fix interrupts array max constraints
> https://git.kernel.org/lpieralisi/pci/c/4cf4b9b70ab2
> [03/20] dt-bindings: PCI: dwc: Detach common RP/EP DT bindings
> https://git.kernel.org/lpieralisi/pci/c/057646a5db2f
> [04/20] dt-bindings: PCI: dwc: Remove bus node from the examples
> https://git.kernel.org/lpieralisi/pci/c/b9fe9985aee2
> [05/20] dt-bindings: PCI: dwc: Add phys/phy-names common properties
> https://git.kernel.org/lpieralisi/pci/c/875596361910
> [06/20] dt-bindings: PCI: dwc: Add max-link-speed common property
> https://git.kernel.org/lpieralisi/pci/c/eaa9d8865287
> [07/20] dt-bindings: PCI: dwc: Apply generic schema for generic device only
> https://git.kernel.org/lpieralisi/pci/c/f133396e2d00
> [08/20] dt-bindings: PCI: dwc: Add max-functions EP property
> https://git.kernel.org/lpieralisi/pci/c/12f7936c7a0e
> [09/20] dt-bindings: PCI: dwc: Add interrupts/interrupt-names common properties
> https://git.kernel.org/lpieralisi/pci/c/35486813c41b
> [10/20] dt-bindings: PCI: dwc: Add reg/reg-names common properties
> https://git.kernel.org/lpieralisi/pci/c/4cc13eedb892
> [11/20] dt-bindings: PCI: dwc: Add clocks/resets common properties
> https://git.kernel.org/lpieralisi/pci/c/bd9504af9169
> [12/20] dt-bindings: PCI: dwc: Add dma-coherent property
> https://git.kernel.org/lpieralisi/pci/c/4a8972542a6d
> [13/20] dt-bindings: PCI: dwc: Apply common schema to Rockchip DW PCIe nodes
> https://git.kernel.org/lpieralisi/pci/c/98b59129cb9f
> [14/20] dt-bindings: PCI: dwc: Add Baikal-T1 PCIe Root Port bindings
> https://git.kernel.org/lpieralisi/pci/c/ce27c4e61f2d
> [15/20] PCI: dwc: Introduce dma-ranges property support for RC-host
> https://git.kernel.org/lpieralisi/pci/c/8522e17d4cab
> [16/20] PCI: dwc: Introduce generic controller capabilities interface
> https://git.kernel.org/lpieralisi/pci/c/7f9e982dc4fc
> [17/20] PCI: dwc: Introduce generic resources getter
> https://git.kernel.org/lpieralisi/pci/c/ef8c58877fe7
> [18/20] PCI: dwc: Combine iATU detection procedures
> https://git.kernel.org/lpieralisi/pci/c/9f67ecdd9579
> [19/20] PCI: dwc: Introduce generic platform clocks and resets
> https://git.kernel.org/lpieralisi/pci/c/ef69f852a978
> [20/20] PCI: dwc: Add Baikal-T1 PCIe controller support
> https://git.kernel.org/lpieralisi/pci/c/ba6ed462dcf4
>
> Thanks,
> Lorenzo

2022-11-25 20:44:35

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 00/20] PCI: dwc: Add generic resources and Baikal-T1 support

On Fri, Nov 25, 2022 at 03:58:55PM +0300, Serge Semin wrote:
> On Wed, Nov 23, 2022 at 04:09:12PM +0100, Lorenzo Pieralisi wrote:
> > On Sun, 13 Nov 2022 22:12:41 +0300, Serge Semin wrote:
> > > This patchset is a third one in the series created in the framework of
> > > my Baikal-T1 PCIe/eDMA-related work:
> > >
> > > [1: Done v5] PCI: dwc: Various fixes and cleanups
> > > Link: https://lore.kernel.org/linux-pci/[email protected]/
> > > Merged: kernel 6.0-rc1
> > > [2: Done v4] PCI: dwc: Add hw version and dma-ranges support
> > > Link: https://lore.kernel.org/linux-pci/[email protected]
> > > Merged: kernel 6.0-rc1
> > > [3: In-review v7] PCI: dwc: Add generic resources and Baikal-T1 support
> > > Link: ---you are looking at it---
> > > [4: Done v6] dmaengine: dw-edma: Add RP/EP local DMA support
> > > Link: https://lore.kernel.org/linux-pci/[email protected]/
> > >
> > > [...]
> >
> > I think it is time we merged this series - we went through
> > several rounds of reviews and it should be ready for
> > mainline (in particular wrt using the generic infrastructure
> > it puts in place).
> >
> > Applied to pci/dwc, thank you.
>
> Thanks. We've finally done that!
>

> Could you please merge the DW eDMA part in too?

@Lorenzo, hold on with this for sometime. @Robin submitted some comments
there.

-Serge(y)

> Link: https://lore.kernel.org/linux-pci/[email protected]/
> Due to the dependencies we agreed to hold it on for until the last DW
> PCIe patchset is merged in. See discussion here:
> https://lore.kernel.org/dmaengine/20220616183900.ww7ora37kmve7av2@mobilestation/
> and here (Vinod ab-tag):
> https://lore.kernel.org/linux-pci/YuKFnjrxnyNa+98X@matsya/
> and here (the last thread mentioned the dependencies):
> https://lore.kernel.org/linux-pci/20220825112843.4pbh37x6wemsdmmp@mobilestation/
>
> The eDMA series has got all the ab/rb/tb-tags from @Vinod and @Mani side.
> The only tiny exception is
> [PATCH v6 22/24] dmaengine: dw-edma: Bypass dma-ranges mapping for the local setup
> for which I had to drop the tags due to an update per the @Robin request
> in the framework of the dma-ranges/DMA-mask discussion:
> https://lore.kernel.org/linux-pci/20220927104831.bovlzl74osb4t5d3@mobilestation/
> https://lore.kernel.org/linux-pci/20221007224515.sseyabdfa2phcsdz@mobilestation/
>
> I failed to reach @Robin since November 8, 2022. If you are able to
> effectively draw his attention so he looked at the updated patch, that
> would be great. Other than that I see no barrier to merge the DW eDMA
> series in too.
>
> -Serge(y)
>
> >
> > [01/20] dt-bindings: imx6q-pcie: Fix clock names for imx6sx and imx8mq
> > https://git.kernel.org/lpieralisi/pci/c/b8a83e600bdd
> > [02/20] dt-bindings: visconti-pcie: Fix interrupts array max constraints
> > https://git.kernel.org/lpieralisi/pci/c/4cf4b9b70ab2
> > [03/20] dt-bindings: PCI: dwc: Detach common RP/EP DT bindings
> > https://git.kernel.org/lpieralisi/pci/c/057646a5db2f
> > [04/20] dt-bindings: PCI: dwc: Remove bus node from the examples
> > https://git.kernel.org/lpieralisi/pci/c/b9fe9985aee2
> > [05/20] dt-bindings: PCI: dwc: Add phys/phy-names common properties
> > https://git.kernel.org/lpieralisi/pci/c/875596361910
> > [06/20] dt-bindings: PCI: dwc: Add max-link-speed common property
> > https://git.kernel.org/lpieralisi/pci/c/eaa9d8865287
> > [07/20] dt-bindings: PCI: dwc: Apply generic schema for generic device only
> > https://git.kernel.org/lpieralisi/pci/c/f133396e2d00
> > [08/20] dt-bindings: PCI: dwc: Add max-functions EP property
> > https://git.kernel.org/lpieralisi/pci/c/12f7936c7a0e
> > [09/20] dt-bindings: PCI: dwc: Add interrupts/interrupt-names common properties
> > https://git.kernel.org/lpieralisi/pci/c/35486813c41b
> > [10/20] dt-bindings: PCI: dwc: Add reg/reg-names common properties
> > https://git.kernel.org/lpieralisi/pci/c/4cc13eedb892
> > [11/20] dt-bindings: PCI: dwc: Add clocks/resets common properties
> > https://git.kernel.org/lpieralisi/pci/c/bd9504af9169
> > [12/20] dt-bindings: PCI: dwc: Add dma-coherent property
> > https://git.kernel.org/lpieralisi/pci/c/4a8972542a6d
> > [13/20] dt-bindings: PCI: dwc: Apply common schema to Rockchip DW PCIe nodes
> > https://git.kernel.org/lpieralisi/pci/c/98b59129cb9f
> > [14/20] dt-bindings: PCI: dwc: Add Baikal-T1 PCIe Root Port bindings
> > https://git.kernel.org/lpieralisi/pci/c/ce27c4e61f2d
> > [15/20] PCI: dwc: Introduce dma-ranges property support for RC-host
> > https://git.kernel.org/lpieralisi/pci/c/8522e17d4cab
> > [16/20] PCI: dwc: Introduce generic controller capabilities interface
> > https://git.kernel.org/lpieralisi/pci/c/7f9e982dc4fc
> > [17/20] PCI: dwc: Introduce generic resources getter
> > https://git.kernel.org/lpieralisi/pci/c/ef8c58877fe7
> > [18/20] PCI: dwc: Combine iATU detection procedures
> > https://git.kernel.org/lpieralisi/pci/c/9f67ecdd9579
> > [19/20] PCI: dwc: Introduce generic platform clocks and resets
> > https://git.kernel.org/lpieralisi/pci/c/ef69f852a978
> > [20/20] PCI: dwc: Add Baikal-T1 PCIe controller support
> > https://git.kernel.org/lpieralisi/pci/c/ba6ed462dcf4
> >
> > Thanks,
> > Lorenzo

2022-11-27 01:29:45

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

Hi Bjorn,

On Wed, Nov 23, 2022 at 01:44:36PM -0600, Bjorn Helgaas wrote:
> Hi Serge,
>
> On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:
> > Currently the DW PCIe Root Port and Endpoint CSR spaces are retrieved in
> > the separate parts of the DW PCIe core driver. It doesn't really make
> > sense since the both controller types have identical set of the core CSR
> > regions: DBI, DBI CS2 and iATU/eDMA. Thus we can simplify the DW PCIe Host
> > and EP initialization methods by moving the platform-specific registers
> > space getting and mapping into a common method. It gets to be even more
> > justified seeing the CSRs base address pointers are preserved in the
> > common DW PCIe descriptor. Note all the OF-based common DW PCIe settings
> > initialization will be moved to the new method too in order to have a
> > single function for all the generic platform properties handling in single
> > place.
> >
> > A nice side-effect of this change is that the pcie-designware-host.c and
> > pcie-designware-ep.c drivers are cleaned up from all the direct dw_pcie
> > storage modification, which makes the DW PCIe core, Root Port and Endpoint
> > modules more coherent.
>

> Thanks for these new generic interfaces in the DWC core! And thanks
> for the changes in this patch to take advantage of them in the
> pcie-designware drivers.
>
> Do you plan similar changes to other drivers to take advantage of
> these DWC-generic data and interfaces? If you add generic things to
> the DWC core but only take advantage of them in your driver, I don't
> think they are really usefully generic.

Could you be more specific what generic things you are referring to? I
am asking because the only part of the changes which is used in my
low-level driver only is introduced in another patch of this series.
It's
< [PATCH v7 19/20] PCI: dwc: Introduce generic platform clocks and resets
The new clock/reset request interface has been implemented the way it
is due to reasons I in details described to Rob here:
Link: https://lore.kernel.org/linux-pci/20220520160246.guczq52v2ycfgc6c@mobilestation
To cut it short it can't be used by the most of the already available
low-level drivers since they already have their own versions of the
names for the clock and reset resources (or don't have any name
defined at all). The only driver for which the interface could be
utilized is Toshiba Visconti PCIe host controller driver. The device
DT-bindings defines the clock names matching the generic names
introduced in the patches of this series. If you find it appropriate
enough I can provide a patch for that driver.

Note the main goal of the patch
[PATCH v7 19/20] PCI: dwc: Introduce generic platform clocks and resets
was to create some interface to stop the developers of the new drivers
from creating the platform-specific DT-bindings to the same clock and
reset resources. Since the already defined DT-bindings can't be
changed anyway I don't think it would worth risking to catch
regressions on an attempt to provide a more complicated interface
utilized in the old drivers too.

-Serge(y)

>
> Bjorn

2022-11-29 18:42:30

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

On Sun, Nov 27, 2022 at 04:10:05AM +0300, Serge Semin wrote:
> On Wed, Nov 23, 2022 at 01:44:36PM -0600, Bjorn Helgaas wrote:
> > On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:

> > Thanks for these new generic interfaces in the DWC core! And thanks
> > for the changes in this patch to take advantage of them in the
> > pcie-designware drivers.
> >
> > Do you plan similar changes to other drivers to take advantage of
> > these DWC-generic data and interfaces? If you add generic things to
> > the DWC core but only take advantage of them in your driver, I don't
> > think they are really usefully generic.
>
> Could you be more specific what generic things you are referring to? I
> am asking because the only part of the changes which is used in my
> low-level driver only is introduced in another patch of this series.

I asked because three of your patches mention "generic" things, but I
didn't see any changes to drivers except pcie-designware:

PCI: dwc: Introduce generic platform clocks and reset
PCI: dwc: Introduce generic resources getter
PCI: dwc: Introduce generic controller capabilities interface

I hoped that we would be able to use these to remove some code from
existing drivers, but if they only improve maintainability of future
drivers, that's useful, too.

Bjorn

2022-11-30 00:36:50

by Serge Semin

[permalink] [raw]
Subject: Re: [PATCH v7 17/20] PCI: dwc: Introduce generic resources getter

On Tue, Nov 29, 2022 at 12:35:43PM -0600, Bjorn Helgaas wrote:
> On Sun, Nov 27, 2022 at 04:10:05AM +0300, Serge Semin wrote:
> > On Wed, Nov 23, 2022 at 01:44:36PM -0600, Bjorn Helgaas wrote:
> > > On Sun, Nov 13, 2022 at 10:12:58PM +0300, Serge Semin wrote:
>
> > > Thanks for these new generic interfaces in the DWC core! And thanks
> > > for the changes in this patch to take advantage of them in the
> > > pcie-designware drivers.
> > >
> > > Do you plan similar changes to other drivers to take advantage of
> > > these DWC-generic data and interfaces? If you add generic things to
> > > the DWC core but only take advantage of them in your driver, I don't
> > > think they are really usefully generic.
> >
> > Could you be more specific what generic things you are referring to? I
> > am asking because the only part of the changes which is used in my
> > low-level driver only is introduced in another patch of this series.
>
> I asked because three of your patches mention "generic" things, but I
> didn't see any changes to drivers except pcie-designware:
>

> PCI: dwc: Introduce generic platform clocks and reset

This patch introduces a method to request a generic platform clocks
and resets by their names. As I already said these names are defined
by the DT-bindings, which are platform-specific. That's why the most
of the currently available drivers can't be converted to using it.
Instead the new drivers are supposed to be encouraged to use the
generic names (in accordance with the generic DW PCIe DT-schema) and
the resources request interface (based on the generic DT-bindings) if
it suits their design.

Anyway I honestly tried to come up with an even more generic
interface, which could be used by all the low-level drivers. But due
to too much variations of the resource names and their sometimes too
complex utilization in the drivers any solution looked too complex.
After all of thoughts I decided to keep things simpler.

> PCI: dwc: Introduce generic resources getter

This patch defines a generic resource getter for the DW PCIe host and
end-point drivers. That's why it's called generic.

> PCI: dwc: Introduce generic controller capabilities interface

This patch introduces an interface to set the device-specific
capabilities. Since these capabilities can be marked as available by
both the core driver (at least two of them already defined within this
patchset) and low-level platform drivers the interface is called
as generic.

>
> I hoped that we would be able to use these to remove some code from
> existing drivers, but if they only improve maintainability of future
> drivers, that's useful, too.

Removing some code is possible for instance from the pcie-visconti.c
driver by using the new generic clocks and resets request interface.
I've scheduled to create a small patchset which would do that after
the rest of my patches pass the review process.

-Serge(y)

>
> Bjorn