drivers/phy/phy-xgene.c
Source file repositories/reference/linux-study-clean/drivers/phy/phy-xgene.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/phy/phy-xgene.c- Extension
.c- Size
- 60598 bytes
- Lines
- 1724
- Domain
- Driver Families
- Bucket
- drivers/phy
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/module.hlinux/of.hlinux/platform_device.hlinux/io.hlinux/delay.hlinux/phy/phy.hlinux/clk.h
Detected Declarations
struct xgene_sata_override_paramstruct xgene_phy_ctxenum cmu_type_tenum mux_type_tenum clk_type_tenum xgene_phy_modefunction sds_wrfunction sds_rdfunction cmu_wrfunction cmu_rdfunction cmu_toggle1to0function cmu_clrbitsfunction cmu_setbitsfunction serdes_wrfunction serdes_rdfunction serdes_clrbitsfunction serdes_setbitsfunction xgene_phy_cfg_cmu_clk_typefunction xgene_phy_sata_cfg_cmu_corefunction xgene_phy_ssc_enablefunction xgene_phy_sata_cfg_lanesfunction xgene_phy_cal_rdy_chkfunction xgene_phy_pdwn_force_vcofunction xgene_phy_hw_init_satafunction xgene_phy_hw_initializefunction xgene_phy_force_lat_summer_calfunction xgene_phy_reset_rxdfunction xgene_phy_get_avgfunction xgene_phy_gen_avg_valfunction xgene_phy_hw_initfunction xgene_phy_get_paramfunction xgene_phy_probe
Annotated Snippet
struct xgene_sata_override_param {
u32 speed[MAX_LANE]; /* Index for override parameter per lane */
u32 txspeed[3]; /* Tx speed */
u32 txboostgain[MAX_LANE*3]; /* Tx freq boost and gain control */
u32 txeyetuning[MAX_LANE*3]; /* Tx eye tuning */
u32 txeyedirection[MAX_LANE*3]; /* Tx eye tuning direction */
u32 txamplitude[MAX_LANE*3]; /* Tx amplitude control */
u32 txprecursor_cn1[MAX_LANE*3]; /* Tx emphasis taps 1st pre-cursor */
u32 txprecursor_cn2[MAX_LANE*3]; /* Tx emphasis taps 2nd pre-cursor */
u32 txpostcursor_cp1[MAX_LANE*3]; /* Tx emphasis taps post-cursor */
};
struct xgene_phy_ctx {
struct device *dev;
struct phy *phy;
enum xgene_phy_mode mode; /* Mode of operation */
enum clk_type_t clk_type; /* Input clock selection */
void __iomem *sds_base; /* PHY CSR base addr */
struct clk *clk; /* Optional clock */
/* Override Serdes parameters */
struct xgene_sata_override_param sata_param;
};
/*
* For chip earlier than A3 version, enable this flag.
* To enable, pass boot argument phy_xgene.preA3Chip=1
*/
static int preA3Chip;
MODULE_PARM_DESC(preA3Chip, "Enable pre-A3 chip support (1=enable 0=disable)");
module_param_named(preA3Chip, preA3Chip, int, 0444);
static void sds_wr(void __iomem *csr_base, u32 indirect_cmd_reg,
u32 indirect_data_reg, u32 addr, u32 data)
{
unsigned long deadline = jiffies + HZ;
u32 val;
u32 cmd;
cmd = CFG_IND_WR_CMD_MASK | CFG_IND_CMD_DONE_MASK;
cmd = CFG_IND_ADDR_SET(cmd, addr);
writel(data, csr_base + indirect_data_reg);
readl(csr_base + indirect_data_reg); /* Force a barrier */
writel(cmd, csr_base + indirect_cmd_reg);
readl(csr_base + indirect_cmd_reg); /* Force a barrier */
do {
val = readl(csr_base + indirect_cmd_reg);
} while (!(val & CFG_IND_CMD_DONE_MASK) &&
time_before(jiffies, deadline));
if (!(val & CFG_IND_CMD_DONE_MASK))
pr_err("SDS WR timeout at 0x%p offset 0x%08X value 0x%08X\n",
csr_base + indirect_cmd_reg, addr, data);
}
static void sds_rd(void __iomem *csr_base, u32 indirect_cmd_reg,
u32 indirect_data_reg, u32 addr, u32 *data)
{
unsigned long deadline = jiffies + HZ;
u32 val;
u32 cmd;
cmd = CFG_IND_RD_CMD_MASK | CFG_IND_CMD_DONE_MASK;
cmd = CFG_IND_ADDR_SET(cmd, addr);
writel(cmd, csr_base + indirect_cmd_reg);
readl(csr_base + indirect_cmd_reg); /* Force a barrier */
do {
val = readl(csr_base + indirect_cmd_reg);
} while (!(val & CFG_IND_CMD_DONE_MASK) &&
time_before(jiffies, deadline));
*data = readl(csr_base + indirect_data_reg);
if (!(val & CFG_IND_CMD_DONE_MASK))
pr_err("SDS WR timeout at 0x%p offset 0x%08X value 0x%08X\n",
csr_base + indirect_cmd_reg, addr, *data);
}
static void cmu_wr(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type,
u32 reg, u32 data)
{
void __iomem *sds_base = ctx->sds_base;
u32 val;
if (cmu_type == REF_CMU)
reg += SERDES_PLL_REF_INDIRECT_OFFSET;
else
reg += SERDES_PLL_INDIRECT_OFFSET;
sds_wr(sds_base, SATA_ENET_SDS_IND_CMD_REG,
SATA_ENET_SDS_IND_WDATA_REG, reg, data);
sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG,
SATA_ENET_SDS_IND_RDATA_REG, reg, &val);
pr_debug("CMU WR addr 0x%X value 0x%08X <-> 0x%08X\n", reg, data, val);
Annotation
- Immediate include surface: `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/io.h`, `linux/delay.h`, `linux/phy/phy.h`, `linux/clk.h`.
- Detected declarations: `struct xgene_sata_override_param`, `struct xgene_phy_ctx`, `enum cmu_type_t`, `enum mux_type_t`, `enum clk_type_t`, `enum xgene_phy_mode`, `function sds_wr`, `function sds_rd`, `function cmu_wr`, `function cmu_rd`.
- Atlas domain: Driver Families / drivers/phy.
- Implementation status: source implementation candidate.
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.