drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c

Source file repositories/reference/linux-study-clean/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c
Extension
.c
Size
6114 bytes
Lines
198
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 qcom_ipq806x_sata_phy {
	void __iomem *mmio;
	struct clk *cfg_clk;
	struct device *dev;
};

#define __set(v, a, b)	(((v) << (b)) & GENMASK(a, b))

#define SATA_PHY_P0_PARAM0		0x200
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x)	__set(x, 17, 12)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK	GENMASK(17, 12)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x)	__set(x, 11, 6)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK	GENMASK(11, 6)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x)	__set(x, 5, 0)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK	GENMASK(5, 0)

#define SATA_PHY_P0_PARAM1		0x204
#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x)	__set(x, 31, 21)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x)	__set(x, 20, 14)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK	GENMASK(20, 14)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x)	__set(x, 13, 7)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK	GENMASK(13, 7)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x)	__set(x, 6, 0)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK	GENMASK(6, 0)

#define SATA_PHY_P0_PARAM2		0x208
#define SATA_PHY_P0_PARAM2_RX_EQ(x)	__set(x, 20, 18)
#define SATA_PHY_P0_PARAM2_RX_EQ_MASK	GENMASK(20, 18)

#define SATA_PHY_P0_PARAM3		0x20C
#define SATA_PHY_SSC_EN			0x8
#define SATA_PHY_P0_PARAM4		0x210
#define SATA_PHY_REF_SSP_EN		0x2
#define SATA_PHY_RESET			0x1

static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
{
	struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
	u32 reg;

	/* Setting SSC_EN to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
	reg = reg | SATA_PHY_SSC_EN;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);

	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
			~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
	reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);

	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
			~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
	reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);

	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
		~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
	reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);

	/* Setting PHY_RESET to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg | SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	/* Setting REF_SSP_EN to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	/* make sure all changes complete before we let the PHY out of reset */
	mb();

	/* sleep for max. 50us more to combine processor wakeups */
	usleep_range(20, 20 + 50);

	/* Clearing PHY_RESET to 0 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg & ~SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	return 0;
}

Annotation

Implementation Notes