drivers/phy/broadcom/phy-bcm-sr-pcie.c

Source file repositories/reference/linux-study-clean/drivers/phy/broadcom/phy-bcm-sr-pcie.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/broadcom/phy-bcm-sr-pcie.c
Extension
.c
Size
7480 bytes
Lines
301
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sr_pcie_phy {
	struct sr_pcie_phy_core *core;
	unsigned int index;
	struct phy *phy;
};

/**
 * struct sr_pcie_phy_core - Stingray PCIe PHY core control
 *
 * @dev: pointer to device
 * @base: base register of PCIe SS
 * @cdru: regmap to the CDRU device
 * @mhb: regmap to the MHB device
 * @pipemux: pipemuex strap
 * @phys: array of PCIe PHYs
 */
struct sr_pcie_phy_core {
	struct device *dev;
	void __iomem *base;
	struct regmap *cdru;
	struct regmap *mhb;
	u32 pipemux;
	struct sr_pcie_phy phys[SR_NR_PCIE_PHYS];
};

/*
 * PCIe PIPEMUX lookup table
 *
 * Each array index represents a PIPEMUX strap setting
 * The array element represents a bitmap where a set bit means the PCIe
 * core and associated serdes has been enabled as RC and is available for use
 */
static const u8 pipemux_table[] = {
	/* PIPEMUX = 0, EP 1x16 */
	0x00,
	/* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
	0x80,
	/* PIPEMUX = 2, EP 4x4 */
	0x00,
	/* PIPEMUX = 3, RC 2x8, cores 0, 7 */
	0x81,
	/* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
	0xc3,
	/* PIPEMUX = 5, RC 8x2, all 8 cores */
	0xff,
	/* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
	0xcd,
	/* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
	0xfd,
	/* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
	0xf0,
	/* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
	0xc0,
	/* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
	0x42,
	/* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
	0x3c,
	/* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
	0xfc,
	/* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
	0x4c,
};

/*
 * Return true if the strap setting is valid
 */
static bool pipemux_strap_is_valid(u32 pipemux)
{
	return !!(pipemux < ARRAY_SIZE(pipemux_table));
}

/*
 * Read the PCIe PIPEMUX from strap
 */
static u32 pipemux_strap_read(struct sr_pcie_phy_core *core)
{
	u32 pipemux;

	/*
	 * Read PIPEMUX configuration register to determine the pipemux setting
	 *
	 * In the case when the value indicates using HW strap, fall back to
	 * use HW strap
	 */
	pipemux = readl(core->base + PCIE_PIPEMUX_CFG_OFFSET);
	pipemux &= PCIE_PIPEMUX_MASK;
	if (pipemux == PCIE_PIPEMUX_SELECT_STRAP) {
		regmap_read(core->cdru, CDRU_STRAP_DATA_LSW_OFFSET, &pipemux);
		pipemux >>= PCIE_PIPEMUX_SHIFT;
		pipemux &= PCIE_PIPEMUX_MASK;

Annotation

Implementation Notes