Skip to content

Pcie: phytium: update phytium Pcie controller driver support to 6.6.0.4#1677

Open
zhangfuxiang123 wants to merge 10 commits into
deepin-community:linux-6.6.yfrom
zhangfuxiang123:pcie-6.6.y
Open

Pcie: phytium: update phytium Pcie controller driver support to 6.6.0.4#1677
zhangfuxiang123 wants to merge 10 commits into
deepin-community:linux-6.6.yfrom
zhangfuxiang123:pcie-6.6.y

Conversation

@zhangfuxiang123
Copy link
Copy Markdown
Contributor

@zhangfuxiang123 zhangfuxiang123 commented May 9, 2026

These patches updates the support for phytium Pcie controller driver.

Summary by Sourcery

Update Phytium PCIe endpoint and controller support, including new SoC compatibility, DMA support, platform-specific reset/link handling, and configfs controls.

New Features:

  • Add DMA engine support for Phytium PCIe endpoint controllers and expose DMA start/status hooks through the EPC core on Phytium platforms.
  • Support the Phytium PE2201 PCIe endpoint controller variant with dedicated DT binding and per-chip HPB base/limit configuration.
  • Expose an EPC configfs attribute to configure endpoint function number mappings on Phytium platforms.

Bug Fixes:

  • Correct endpoint function numbering usage across the Phytium PCIe endpoint driver to align with hardware expectations.
  • Fix BAR configuration and address translation setup for Phytium PCIe endpoints, including handling of unsupported BARs and BAR window programming.

Enhancements:

  • Replace the Phytium PCIe controller SMC helper with a generic operation interface that supports hot-reset, hot-plug, and link-status queries and reuse it across reset and hotplug paths.
  • Add Phytium-specific secondary bus reset policies for particular CPU types to handle link degradation and preserve device state as needed.
  • Improve Phytium PCIe hotplug link checks by validating link status via firmware when hardware reports unreliable status.
  • Broaden ACS enablement quirks for Phytium-related PCIe devices by matching on specific vendor IDs instead of build-time conditionals.],
  • docs':['Introduce a devicetree binding document for the "phytium,pe2201-pcie-ep" PCIe endpoint controller, including example usage.'],

Some PCI devices have IO space access limit and only supporting
16 bit addresses. We update upper 16 bits of I/O base/limit according
to the bridge and the RC root port.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Xiao Cong <xiaocong1866@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
When the PCIe device is unplugged or under hotreset, the PCIe
controller's protrction mechanism is triggered, which will make the
link inaccessible. This patch disables the protection after the link
is up and makes the PCIe hotplug or hotreset process work well.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Long Shixiang <longshixiang1718@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
The phytium PCIe root ports and X100 switch do not support ACS at this point.
However, the hardware provides isolation and source validation
through the SMMU. The stream ID generated by the PCIe ports contain
both the bus/device/function number as well as the port ID in its 3
most significant bits. Turn on ACS but disable all the peer-to-peer
features.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Xiao Cong <xiaocong1866@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
In the phytium ps2308 platforms, when host PCIe bridge
operate hotreset, then host pcie bridge config register
will restore default value. So before hotreset, it need save
host PCIe bridge config register. Then after hotreset, it need
restore save host PCIe bridge config register.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Xiao Cong <xiaocong1866@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Some Phytium-based systems can come up with reduced PCIe link speed or
lane count after a hotreset. A second reset attempt often restores the
original link characteristics.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Li Tongfeng <litongfeng1497@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
On Phytium 24080 platform, reading the PCIe Link Status (LNKSTA)
register through the standard PCIe capability interface may return
an incorrect value for the Data Link Layer Link Active (DLLLA) bit.
This causes the kernel to report wrong link state after a device
is hot-unplugged.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Li Tongfeng <litongfeng1497@phytium.com.cn>
Add the device tree binding schema for phytium,pe2201-pcie-ep.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Li Tongfeng <litongfeng1497@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Add phytium ep driver DMA Controller support and add
function_num_map to the configfs of EPC.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Li Tongfeng <litongfeng1497@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
On PD2308 platform, it only setup root bridge I/O BAR address,
and don't modify other bridge I/O BAR address after root.

Signed-off-by: Zhang Fuxiang <zhangfuxiang2144@phytium.com.cn>
Signed-off-by: Li Wencheng <liwencheng@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 9, 2026

Reviewer's Guide

Updates the Phytium PCIe endpoint controller driver and generic PCI core for Phytium SoCs to 6.6.0.4 by adding endpoint DMA support, refining BAR/ATR handling, introducing SoC‑specific HPB register layouts, centralizing Phytium PCIe SMC handling and link checks, and adding Phytium‑specific EPC configfs and bridge quirks, plus a new DT binding for the PE2201 endpoint controller.

Sequence diagram for starting Phytium endpoint DMA via EPC core

sequenceDiagram
    actor UserSpace
    participant EPF_driver as pci_epf_driver
    participant EPC_core as pci_epc_core_helpers
    participant EPC as pci_epc
    participant EPC_ops as pci_epc_ops
    participant EP_hw as phytium_pcie_ep_driver
    participant DMA_regs as DMA_registers

    UserSpace->>EPF_driver: request DMA transfer(cpu_addr, pci_addr, size, mode)
    EPF_driver->>EPC_core: pci_epc_start_dma(epc, func_no, cpu_addr, pci_addr, size, mode)
    EPC_core->>EPC: validate epc and ops
    alt start_dma not implemented
        EPC_core-->>EPF_driver: return 0
    else start_dma implemented
        EPC_core->>EPC_core: acquire epc_dma_lock
        EPC_core->>EPC_ops: start_dma(epc, func_no, cpu_addr, pci_addr, size, mode)
        activate EP_hw
        EPC_ops->>EP_hw: phytium_pcie_ep_start_dma(epc, func_no, cpu_addr, pci_addr, size, mode)
        EP_hw->>EP_hw: func_no++ and debug log
        EP_hw->>DMA_regs: program HPB window for cpu_addr (upper and lower)
        EP_hw->>DMA_regs: configure DMA_SHARE_ACCESS(mode)
        alt mode == DMA_READ_ENGINE
            EP_hw->>DMA_regs: set DMA_SRCPARAM(mode) to PCIE interface
            EP_hw->>DMA_regs: set DMA_DSTPARAM(mode) to AXI master
            EP_hw->>DMA_regs: set DMA_SRCADDR_LO/UP from pci_addr
            EP_hw->>DMA_regs: set DMA_DESTADDR_LO/UP from cpu_addr
        else mode == DMA_WRITE_ENGINE
            EP_hw->>DMA_regs: set DMA_SRCPARAM(mode) to AXI master
            EP_hw->>DMA_regs: set DMA_DSTPARAM(mode) to PCIE interface
            EP_hw->>DMA_regs: set DMA_SRCADDR_LO/UP from cpu_addr
            EP_hw->>DMA_regs: set DMA_DESTADDR_LO/UP from pci_addr
        end
        EP_hw->>DMA_regs: write DMA_LENGTH(mode)
        EP_hw->>DMA_regs: write DMA_CONTROL(mode) start value
        EP_hw-->>EPC_ops: return 0
        deactivate EP_hw
        EPC_ops-->>EPC_core: return 0
        EPC_core->>EPC_core: release epc_dma_lock
        EPC_core-->>EPF_driver: return 0
    end

    Note over EPF_driver,EPC_core: PCIe EP function may poll pci_epc_dma_status() to read DMA_STATUS(mode)
Loading

Sequence diagram for Phytium PCIe SMC control and link status usage

sequenceDiagram
    participant Core as pci_core_or_pciehp
    participant RP as pci_root_port_dev
    participant FW as firmware_SMC

    Core->>RP: call phytium_pcie_ctrl_smc_op(pdev, op)
    alt device not Phytium root port
        Core-->>Core: return -ENOENT
    else Phytium root port
        Core->>RP: dev_to_node(&pdev->dev)
        alt socket < 0
            Core-->>Core: return -ENOENT
        else valid socket
            Core->>FW: arm_smccc_smc(PHYTIUM_PCIE_CTRL_SMC_FUNC_ID, sbdf_arg, op, ...)
            alt res.a0 != 0
                Core-->>Core: return -ENOENT
            else success
                alt op == PHYTIUM_PCIE_GET_LNKSTA
                    Core->>Core: map res.a1 to link_status bit PCI_EXP_LNKSTA_DLLLA
                    Core-->>Core: return link_status
                else op is PHYTIUM_PCIE_HOTRESET or PHYTIUM_PCIE_HOTPLUG
                    Core-->>Core: return 0
                end
            end
        end
    end

    rect rgb(230,230,250)
        participant HP as pciehp_check_link_active
        participant Port as pciehp_port_pci_dev
        HP->>Port: pci_read_config_word(PCI_EXP_LNKSTA)
        Note over HP,Port: generic link_status read
        HP->>Port: is_ps24080()
        alt Phytium PS24080
            HP->>Port: phytium_pcie_ctrl_smc_op(Port, PHYTIUM_PCIE_GET_LNKSTA)
            HP->>HP: if lnksta >= 0, update DLLLA bit
        end
        HP-->>HP: return !!(lnk_status & PCI_EXP_LNKSTA_DLLLA)
    end
Loading

Class diagram for updated Phytium PCIe endpoint controller and EPC DMA ops

classDiagram
    class phytium_pcie_ep {
        <<struct>>
        void __iomem *reg_base
        void __iomem *hpb_base
        struct resource *mem_res
        unsigned long irq_pci_addr
        u8 irq_pci_fn
        struct pci_epc *epc
        struct platform_device *pdev
    }

    class pci_epc_ops {
        <<struct>>
        int (*write_header)(struct pci_epc *epc, unsigned char fn, u8 vfn, struct pci_epf_header *hdr)
        int (*set_bar)(struct pci_epc *epc, u8 fn, u8 vfn, struct pci_epf_bar *epf_bar)
        void (*clear_bar)(struct pci_epc *epc, u8 fn, u8 vfn, struct pci_epf_bar *epf_bar)
        int (*map_addr)(struct pci_epc *epc, u8 fn, u8 vfn, phys_addr_t phys_addr, u64 pci_addr, size_t size)
        void (*unmap_addr)(struct pci_epc *epc, u8 fn, u8 vfn, phys_addr_t phys_addr)
        int (*set_msi)(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
        int (*get_msi)(struct pci_epc *epc, u8 fn, u8 vfn)
        int (*raise_irq)(struct pci_epc *epc, u8 fn, u8 vfn, enum pci_epc_irq_type type, u16 interrupt_num)
        int (*start)(struct pci_epc *epc)
        void (*stop)(struct pci_epc *epc)
        int (*start_dma)(struct pci_epc *epc, u8 func_no, u64 cpu_addr, u64 pci_addr, size_t size, u8 mode)
        int (*dma_status)(struct pci_epc *epc, u8 func_no, u8 mode)
        const struct pci_epc_features* (*get_features)(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
        struct module *owner
    }

    class pci_epc {
        <<struct>>
        const struct pci_epc_ops *ops
        struct pci_epc_mem *mem
        u8 max_functions
        unsigned long function_num_map
    }

    class pci_epc_core_helpers {
        <<functions>>
        int pci_epc_start(struct pci_epc *epc)
        int pci_epc_start_dma(struct pci_epc *epc, u8 func_no, u64 cpu_addr, u64 pci_addr, size_t size, u8 mode)
        int pci_epc_dma_status(struct pci_epc *epc, u8 func_no, u8 mode)
    }

    class phytium_pcie_ep_driver {
        <<driver>>
        int phytium_pcie_ep_write_header(struct pci_epc *epc, unsigned char fn, u8 vfn, struct pci_epf_header *hdr)
        int phytium_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn, struct pci_epf_bar *epf_bar)
        void phytium_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn, struct pci_epf_bar *epf_bar)
        int phytium_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn, phys_addr_t phys_addr, u64 pci_addr, size_t size)
        void phytium_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn, phys_addr_t phys_addr)
        int phytium_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
        int phytium_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
        int phytium_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn, enum pci_epc_irq_type type, u16 interrupt_num)
        int phytium_pcie_ep_start(struct pci_epc *epc)
        int phytium_pcie_ep_start_dma(struct pci_epc *epc, u8 func_no, u64 cpu_addr, u64 pci_addr, size_t size, u8 mode)
        int phytium_pcie_ep_dma_status(struct pci_epc *epc, u8 func_no, u8 mode)
        int phytium_pcie_ep_probe(struct platform_device *pdev)
        int phytium_pcie_ep_remove(struct platform_device *pdev)
    }

    phytium_pcie_ep_driver --> phytium_pcie_ep : uses
    phytium_pcie_ep_driver --> pci_epc_ops : fills
    pci_epc --> pci_epc_ops : has ops
    pci_epc_core_helpers ..> pci_epc : operates on
    pci_epc_core_helpers ..> pci_epc_ops : calls via ops

    class pci_epc_group {
        <<struct>>
        struct config_group group
        struct pci_epc *epc
        bool start
        unsigned long function_num_map
    }

    pci_epc_group --> pci_epc : references

    class DMA_registers {
        <<macros>>
        int DMA_READ_ENGINE
        int DMA_WRITE_ENGINE
        int DMA_ENGINE0_BASE
        int DMA_SHARE_ACCESS(int engnum)
        int DMA_SRCPARAM(int engnum)
        int DMA_DSTPARAM(int engnum)
        int DMA_SRCADDR_LO(int engnum)
        int DMA_SRCADDR_UP(int engnum)
        int DMA_DESTADDR_LO(int engnum)
        int DMA_DESTADDR_UP(int engnum)
        int DMA_LENGTH(int engnum)
        int DMA_CONTROL(int engnum)
        int DMA_STATUS(int engnum)
    }

    phytium_pcie_ep_driver ..> DMA_registers : programs DMA

    class HPB_register_layouts {
        <<macros>>
        int PHYTIUM_PD2008_HPB_C0_PREF_BASE_LIMIT
        int PHYTIUM_PE2201_HPB_C0_PREF_BASE_LIMIT
        int PHYTIUM_PD2008_HPB_C0_PREF_BASE_LIMIT_UP32
        int PHYTIUM_PE2201_HPB_C0_PREF_BASE_LIMIT_UP32
    }

    phytium_pcie_ep_driver ..> HPB_register_layouts : SoC specific selection
Loading

File-Level Changes

Change Details Files
Adjust endpoint function numbering, BAR programming, and address translation setup for the Phytium PCIe EP controller and add SoC‑specific HPB config and DMA engine support.
  • Change EP driver version macro and module version name to PHYTIUM_PCIE_EP_DRIVER_VERSION.
  • Increment hardware function number (fn++) consistently in EP callbacks (header write, BAR ops, MSI, IRQ, map/unmap).
  • Rework BAR sizing/mask calculation to base it on half the requested size, align to EPC window page size, and program HPB window registers for BARs 1/2/4 while skipping unsupported BARs.
  • Special‑case BAR2 to zero the upper BAR register and return without outbound window programming.
  • Update outbound window translation registers so BAR1 maps to the EP physical address and other supported BARs use a barno‑based ID in the upper address.
  • Add EP DMA register definitions and implement phytium_pcie_ep_start_dma/phytium_pcie_ep_dma_status which configure the controller’s DMA engine between EP local memory and RC memory and expose them via pci_epc_ops.
  • Extend EP probe to read the DT compatible string and select PD2008 vs PE2201 HPB C0_PREF_BASE_LIMIT(_UP32) registers accordingly, then use those when programming HPB windows, and store struct platform_device *pdev in the EP private data.
  • Register new OF compatible "phytium,pe2201-pcie-ep" and provide a YAML DT binding example for the PE2201 endpoint controller.
drivers/pci/controller/pcie-phytium-ep.c
drivers/pci/controller/pcie-phytium-ep.h
drivers/pci/controller/pcie-phytium-register.h
Documentation/devicetree/bindings/pci/phytium,pe2201-pcie-ep.yaml
Add Phytium‑specific EPC DMA start/status helpers and a configfs attribute to control EP function number mapping.
  • Introduce arch‑guarded pci_epc_start_dma() and pci_epc_dma_status() in the EPC core, serialized by a new epc_dma_lock and wired to new pci_epc_ops callbacks.
  • Add a Phytium‑only function_num_map attribute in the EPC configfs group so userspace can configure and expose a function number bitmap to the EPC driver.
drivers/pci/endpoint/pci-epc-core.c
drivers/pci/endpoint/pci-ep-cfs.c
include/linux/pci-epc.h
Consolidate Phytium PCIe controller firmware SMC handling, extend it with link‑status queries, and use it from reset and hotplug paths.
  • Replace phytium_clear_ctrl_prot() with a generalized phytium_pcie_ctrl_smc_op() that handles hotreset, hotplug, and get‑link‑status operations via a single SMC function ID and returns PCIe link status when requested.
  • Switch callers in pci_reset_secondary_bus() and pciehp hotplug handling to use phytium_pcie_ctrl_smc_op() instead of the old helper.
  • Use phytium_pcie_ctrl_smc_op() from pciehp_check_link_active() on PS24080 systems to override possibly stale DLLLA bits with firmware‑reported link state.
drivers/pci/pci.h
drivers/pci/pci.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/pciehp_ctrl.c
Add Phytium‑specific workarounds for bridge secondary‑bus resets and IO base/limit programming, plus refine ACS quirks.
  • Implement phytium_pci_bridge_secondary_bus_reset() that retries secondary bus reset when link speed/width are degraded, and select different reset strategies for PD2308 vs PS24080 in pci_bridge_secondary_bus_reset().
  • In pci_setup_bridge_io(), optionally override the IO_BASE_UPPER16 register from a parent fwnode "io-upper" property on Phytium architectures.
  • Adjust the ACS‑enabled quirk table to list explicit vendor IDs (PLX 0x10b5, Cadence 0x17cd, Phytium 0x1db7) instead of conditional macros for Phytium, so these devices share the X-Gene ACS quirk unconditionally.
drivers/pci/pci.c
drivers/pci/setup-bus.c
drivers/pci/quirks.c

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign avenger-285714 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot
Copy link
Copy Markdown

Hi @zhangfuxiang123. Thanks for your PR.

I'm waiting for a deepin-community member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In pciehp_check_link_active(), the Phytium-specific path stores the return value of phytium_pcie_ctrl_smc_op() (which can be negative) into a u16 and then tests lnksta >= 0, which will always be true for an unsigned type; consider using a signed type for the return, checking for errors explicitly, and only updating lnk_status when the SMC call succeeds.
  • The new pci_epc_start_dma() and pci_epc_dma_status() helpers in pci-epc-core.c use IS_ERR(epc) to validate the epc pointer even though epc is a normal struct pointer, not an ERR_PTR; changing this to a simple if (!epc) (or removing the check if callers guarantee non-NULL) would be more appropriate and avoid misleading error handling.
  • In phytium_pcie_ep_probe(), using of_get_property(np, "compatible", NULL) and strcmp() assumes a single, null-terminated compatible string and ignores the standard multi-string semantics; it would be more robust to rely on the OF match table (e.g. of_device_get_match_data() or of_device_is_compatible()) to select the SoC-specific hpb_c0_pref_base_limit values.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `pciehp_check_link_active()`, the Phytium-specific path stores the return value of `phytium_pcie_ctrl_smc_op()` (which can be negative) into a `u16` and then tests `lnksta >= 0`, which will always be true for an unsigned type; consider using a signed type for the return, checking for errors explicitly, and only updating `lnk_status` when the SMC call succeeds.
- The new `pci_epc_start_dma()` and `pci_epc_dma_status()` helpers in `pci-epc-core.c` use `IS_ERR(epc)` to validate the `epc` pointer even though `epc` is a normal struct pointer, not an ERR_PTR; changing this to a simple `if (!epc)` (or removing the check if callers guarantee non-NULL) would be more appropriate and avoid misleading error handling.
- In `phytium_pcie_ep_probe()`, using `of_get_property(np, "compatible", NULL)` and `strcmp()` assumes a single, null-terminated compatible string and ignores the standard multi-string semantics; it would be more robust to rely on the OF match table (e.g. `of_device_get_match_data()` or `of_device_is_compatible()`) to select the SoC-specific `hpb_c0_pref_base_limit` values.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Phytium PCIe root-port and endpoint support by extending the PCIe endpoint controller (EPC) core with Phytium-specific DMA and function mapping controls, adding a new PE2201 endpoint variant, and refining Phytium platform reset/hotplug/link handling in the generic PCI hotplug/reset paths.

Changes:

  • Add Phytium-specific EPC DMA hooks and a configfs knob for EPC function bitmap handling.
  • Extend Phytium PCIe endpoint controller driver for PE2201 (incl. HPB base/limit offsets) and add a new DT binding.
  • Adjust Phytium platform behavior in core PCI code (ACS quirks, bridge resets, hotplug link-status overrides, IO window programming quirk).

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 27 comments.

Show a summary per file
File Description
MAINTAINERS Add DT binding file entry for the new PE2201 EP binding.
include/linux/pci-epc.h Extend EPC ops/API with Phytium-only DMA hooks.
drivers/pci/setup-bus.c Add Phytium-specific override for bridge I/O upper bits via firmware node property.
drivers/pci/quirks.c Expand ACS quirks matching by vendor IDs (Phytium-related devices).
drivers/pci/pci.h Replace Phytium PCIe SMC helper with a more general op helper, add link-status query op.
drivers/pci/pci.c Add Phytium CPU-specific secondary bus reset policies and switch to new SMC helper.
drivers/pci/hotplug/pciehp_hpc.c Add Phytium platform link-status validation via firmware for hotplug.
drivers/pci/hotplug/pciehp_ctrl.c Switch hotplug protection-clear path to new SMC helper.
drivers/pci/endpoint/pci-epc-core.c Add EPC-core exported DMA wrappers (Phytium-gated).
drivers/pci/endpoint/pci-ep-cfs.c Add Phytium-gated configfs attribute to set EPC function bitmap.
drivers/pci/controller/pcie-phytium-register.h Add PE2201 HPB offsets and define EP DMA register macros.
drivers/pci/controller/pcie-phytium-ep.h Track platform device pointer in EP private data.
drivers/pci/controller/pcie-phytium-ep.c Add PE2201 compatible, BAR/ATR programming changes, and EP DMA engine ops.
drivers/pci/controller/Kconfig Restrict Phytium EP controller driver to ARCH_PHYTIUM.
Documentation/devicetree/bindings/pci/phytium,pe2201-pcie-ep.yaml Introduce DT binding for PE2201 EP controller.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +234 to +235
return sprintf(page, "%ld\n",
to_pci_epc_group(item)->function_num_map);
#include "../pci.h"
#include "pciehp.h"
#ifdef CONFIG_ARCH_PHYTIUM
#include <asm/phytium_cputype.h>
Comment thread drivers/pci/pci.c
EXPORT_SYMBOL(isa_dma_bridge_buggy);
#endif
#ifdef CONFIG_ARCH_PHYTIUM
#include <asm/phytium_cputype.h>
Comment thread drivers/pci/quirks.c
Comment on lines +5394 to +5396
{ 0x10b5, PCI_ANY_ID, pci_quirk_xgene_acs },
{ 0x17cd, PCI_ANY_ID, pci_quirk_xgene_acs },
{ 0x1db7, PCI_ANY_ID, pci_quirk_xgene_acs },
Comment thread include/linux/pci-epc.h
Comment on lines +89 to +94

#ifdef CONFIG_ARCH_PHYTIUM
int (*start_dma)(struct pci_epc *epc, u8 func_no, u64 cpu_addr, u64 pci_addr,
size_t size, u8 mode);
int (*dma_status)(struct pci_epc *epc, u8 func_no, u8 mode);
#endif
Comment on lines +351 to +354
phytium_hpb_writel(priv, base, upper_32_bits(cpu_addr));
phytium_hpb_writel(priv, (base + 0x4),
(lower_32_bits(cpu_addr) & (~0x3f)) | (fls64(size - 1)));
cpu_addr = 0x40000000000 | (cpu_addr & 0x3f);
Comment on lines +356 to +358
phytium_pcie_writel(priv, func_no, DMA_SHARE_ACCESS(mode),
PHYTIUM_PCIE_EP_DMA_SHARE_ACCESS);
if (mode == DMA_READ_ENGINE) {
Comment on lines +431 to +435
compatible = of_get_property(np, "compatible", NULL);
if (!compatible) {
dev_err(dev, "Compatible property not found\n");
return -EINVAL;
}
#define C0_PREF_BASE_MASK 0xfff
#define C0_PREF_BASE_SHIFT 4
#define C0_PREF_VALUE_SHIFT 20
#define PHYTIUM_HPB_C0_PREF_BASE_LIMIT_UP32 0xa34
Comment on lines +87 to +96
#define DMA_SHARE_ACCESS(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x28) // 0x468
#define DMA_SRCPARAM(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x0) // 0x440
#define DMA_DSTPARAM(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x4) // 0x444
#define DMA_SRCADDR_LO(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x8) // 0x448
#define DMA_SRCADDR_UP(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0xc) // 0x44C
#define DMA_DESTADDR_LO(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x10) // 0x450
#define DMA_DESTADDR_UP(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x14) // 0x454
#define DMA_LENGTH(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x18) // 0x458
#define DMA_CONTROL(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x1c) // 0x45C
#define DMA_STATUS(engnum) (DMA_ENGINE0_BASE + 0x40 * engnum + 0x20) // 0x460
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants