drivers/pci/controller/dwc/pcie-nxp-s32g.c
Source file repositories/reference/linux-study-clean/drivers/pci/controller/dwc/pcie-nxp-s32g.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/controller/dwc/pcie-nxp-s32g.c- Extension
.c- Size
- 10023 bytes
- Lines
- 407
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: implementation source
- Status
- source implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/interrupt.hlinux/io.hlinux/module.hlinux/of_device.hlinux/of_address.hlinux/pci.hlinux/phy/phy.hlinux/platform_device.hlinux/pm_runtime.hlinux/sizes.hlinux/types.hpcie-designware.h
Detected Declarations
struct s32g_pcie_portstruct s32g_pciefunction s32g_pcie_writel_ctrlfunction s32g_pcie_readl_ctrlfunction s32g_pcie_enable_ltssmfunction s32g_pcie_disable_ltssmfunction s32g_pcie_start_linkfunction s32g_pcie_stop_linkfunction s32g_pcie_reset_mstr_acefunction s32g_init_pcie_controllerfunction s32g_init_pcie_phyfunction list_for_each_entryfunction s32g_deinit_pcie_phyfunction list_for_each_entry_safefunction s32g_pcie_initfunction s32g_pcie_deinitfunction s32g_pcie_parse_portfunction s32g_pcie_parse_portsfunction for_each_available_child_of_node_scopedfunction s32g_pcie_get_resourcesfunction s32g_pcie_probefunction s32g_pcie_suspend_noirqfunction s32g_pcie_resume_noirq
Annotated Snippet
struct s32g_pcie_port {
struct list_head list;
struct phy *phy;
};
struct s32g_pcie {
struct dw_pcie pci;
void __iomem *ctrl_base;
struct list_head ports;
};
#define to_s32g_from_dw_pcie(x) \
container_of(x, struct s32g_pcie, pci)
static void s32g_pcie_writel_ctrl(struct s32g_pcie *s32g_pp, u32 reg, u32 val)
{
writel(val, s32g_pp->ctrl_base + reg);
}
static u32 s32g_pcie_readl_ctrl(struct s32g_pcie *s32g_pp, u32 reg)
{
return readl(s32g_pp->ctrl_base + reg);
}
static void s32g_pcie_enable_ltssm(struct s32g_pcie *s32g_pp)
{
u32 reg;
reg = s32g_pcie_readl_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3);
reg |= LTSSM_EN;
s32g_pcie_writel_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3, reg);
}
static void s32g_pcie_disable_ltssm(struct s32g_pcie *s32g_pp)
{
u32 reg;
reg = s32g_pcie_readl_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3);
reg &= ~LTSSM_EN;
s32g_pcie_writel_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3, reg);
}
static int s32g_pcie_start_link(struct dw_pcie *pci)
{
struct s32g_pcie *s32g_pp = to_s32g_from_dw_pcie(pci);
s32g_pcie_enable_ltssm(s32g_pp);
return 0;
}
static void s32g_pcie_stop_link(struct dw_pcie *pci)
{
struct s32g_pcie *s32g_pp = to_s32g_from_dw_pcie(pci);
s32g_pcie_disable_ltssm(s32g_pp);
}
static struct dw_pcie_ops s32g_pcie_ops = {
.start_link = s32g_pcie_start_link,
.stop_link = s32g_pcie_stop_link,
};
/* Configure the AMBA AXI Coherency Extensions (ACE) interface */
static void s32g_pcie_reset_mstr_ace(struct dw_pcie *pci)
{
u32 ddr_base_low = lower_32_bits(S32G_MEMORY_BOUNDARY_ADDR);
u32 ddr_base_high = upper_32_bits(S32G_MEMORY_BOUNDARY_ADDR);
dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writel_dbi(pci, COHERENCY_CONTROL_3_OFF, 0x0);
/*
* Ncore is a cache-coherent interconnect module that enables the
* integration of heterogeneous coherent and non-coherent agents in
* the chip. Ncore transactions to peripheral should be non-coherent
* or it might drop them.
*
* One example where this is needed are PCIe MSIs, which use NoSnoop=0
* and might end up routed to Ncore. PCIe coherent traffic (e.g. MSIs)
* that targets peripheral space will be dropped by Ncore because
* peripherals on S32G are not coherent as slaves. We add a hard
* boundary in the PCIe controller coherency control registers to
* separate physical memory space from peripheral space.
*
* Define the start of DDR as seen by Linux as this boundary between
* "memory" and "peripherals", with peripherals being below.
*/
dw_pcie_writel_dbi(pci, COHERENCY_CONTROL_1_OFF,
(ddr_base_low & CFG_MEMTYPE_BOUNDARY_LOW_ADDR_MASK));
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/io.h`, `linux/module.h`, `linux/of_device.h`, `linux/of_address.h`, `linux/pci.h`, `linux/phy/phy.h`, `linux/platform_device.h`.
- Detected declarations: `struct s32g_pcie_port`, `struct s32g_pcie`, `function s32g_pcie_writel_ctrl`, `function s32g_pcie_readl_ctrl`, `function s32g_pcie_enable_ltssm`, `function s32g_pcie_disable_ltssm`, `function s32g_pcie_start_link`, `function s32g_pcie_stop_link`, `function s32g_pcie_reset_mstr_ace`, `function s32g_init_pcie_controller`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.