drivers/phy/mediatek/phy-mtk-ufs.c

Source file repositories/reference/linux-study-clean/drivers/phy/mediatek/phy-mtk-ufs.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/mediatek/phy-mtk-ufs.c
Extension
.c
Size
5282 bytes
Lines
201
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 ufs_mtk_phy {
	struct device *dev;
	void __iomem *mmio;
	struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
};

static struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy)
{
	return (struct ufs_mtk_phy *)phy_get_drvdata(generic_phy);
}

static int ufs_mtk_phy_clk_init(struct ufs_mtk_phy *phy)
{
	struct device *dev = phy->dev;
	struct clk_bulk_data *clks = phy->clks;

	clks[0].id = "unipro";
	clks[1].id = "mp";
	return devm_clk_bulk_get(dev, UFSPHY_CLKS_CNT, clks);
}

static void ufs_mtk_phy_set_active(struct ufs_mtk_phy *phy)
{
	void __iomem *mmio = phy->mmio;

	/* release DA_MP_PLL_PWR_ON */
	mtk_phy_set_bits(mmio + MP_GLB_DIG_8C, PLL_PWR_ON);
	mtk_phy_clear_bits(mmio + MP_GLB_DIG_8C, FRC_FRC_PWR_ON);

	/* release DA_MP_PLL_ISO_EN */
	mtk_phy_clear_bits(mmio + MP_GLB_DIG_8C, PLL_ISO_EN);
	mtk_phy_clear_bits(mmio + MP_GLB_DIG_8C, FRC_PLL_ISO_EN);

	/* release DA_MP_CDR_PWR_ON */
	mtk_phy_set_bits(mmio + MP_LN_RX_44, CDR_PWR_ON);
	mtk_phy_clear_bits(mmio + MP_LN_RX_44, FRC_CDR_PWR_ON);

	/* release DA_MP_CDR_ISO_EN */
	mtk_phy_clear_bits(mmio + MP_LN_RX_44, CDR_ISO_EN);
	mtk_phy_clear_bits(mmio + MP_LN_RX_44, FRC_CDR_ISO_EN);

	/* release DA_MP_RX0_SQ_EN */
	mtk_phy_set_bits(mmio + MP_LN_DIG_RX_AC, RX_SQ_EN);
	mtk_phy_clear_bits(mmio + MP_LN_DIG_RX_AC, FRC_RX_SQ_EN);

	/* delay 1us to wait DIFZ stable */
	udelay(1);

	/* release DIFZ */
	mtk_phy_clear_bits(mmio + MP_LN_DIG_RX_9C, FSM_DIFZ_FRC);
}

static void ufs_mtk_phy_set_deep_hibern(struct ufs_mtk_phy *phy)
{
	void __iomem *mmio = phy->mmio;

	/* force DIFZ */
	mtk_phy_set_bits(mmio + MP_LN_DIG_RX_9C, FSM_DIFZ_FRC);

	/* force DA_MP_RX0_SQ_EN */
	mtk_phy_set_bits(mmio + MP_LN_DIG_RX_AC, FRC_RX_SQ_EN);
	mtk_phy_clear_bits(mmio + MP_LN_DIG_RX_AC, RX_SQ_EN);

	/* force DA_MP_CDR_ISO_EN */
	mtk_phy_set_bits(mmio + MP_LN_RX_44, FRC_CDR_ISO_EN);
	mtk_phy_set_bits(mmio + MP_LN_RX_44, CDR_ISO_EN);

	/* force DA_MP_CDR_PWR_ON */
	mtk_phy_set_bits(mmio + MP_LN_RX_44, FRC_CDR_PWR_ON);
	mtk_phy_clear_bits(mmio + MP_LN_RX_44, CDR_PWR_ON);

	/* force DA_MP_PLL_ISO_EN */
	mtk_phy_set_bits(mmio + MP_GLB_DIG_8C, FRC_PLL_ISO_EN);
	mtk_phy_set_bits(mmio + MP_GLB_DIG_8C, PLL_ISO_EN);

	/* force DA_MP_PLL_PWR_ON */
	mtk_phy_set_bits(mmio + MP_GLB_DIG_8C, FRC_FRC_PWR_ON);
	mtk_phy_clear_bits(mmio + MP_GLB_DIG_8C, PLL_PWR_ON);
}

static int ufs_mtk_phy_power_on(struct phy *generic_phy)
{
	struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
	int ret;

	ret = clk_bulk_prepare_enable(UFSPHY_CLKS_CNT, phy->clks);
	if (ret)
		return ret;

	ufs_mtk_phy_set_active(phy);

Annotation

Implementation Notes