Commit 9224e288 authored by Sunyeal Hong's avatar Sunyeal Hong Committed by Krzysztof Kozlowski
Browse files

clk: samsung: clk-pll: Add support for pll_531x



pll531x PLL is used in Exynos Auto v920 SoC for shared pll.
pll531x: Integer/fractional PLL with mid frequency FVCO (800 to 3120 MHz)

PLL531x
FOUT = (MDIV x FIN)/(PDIV x 2^SDIV) for integer PLL
FOUT = (MDIV + F/2^32-F[31]) x FIN/(PDIV x 2^SDIV) for fractional PLL

Signed-off-by: default avatarSunyeal Hong <sunyeal.hong@samsung.com>
Reviewed-by: default avatarAlim Akhtar <alim.akhtar@samsung.com>
Link: https://lore.kernel.org/r/20240821232652.1077701-4-sunyeal.hong@samsung.com


Signed-off-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
parent c0979bc8
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -1272,6 +1272,47 @@ static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
	.recalc_rate = samsung_pll2650xx_recalc_rate,
};

/*
 * PLL531X Clock Type
 */
/* Maximum lock time can be 500 * PDIV cycles */
#define PLL531X_LOCK_FACTOR		(500)
#define PLL531X_MDIV_MASK		(0x3FF)
#define PLL531X_PDIV_MASK		(0x3F)
#define PLL531X_SDIV_MASK		(0x7)
#define PLL531X_FDIV_MASK		(0xFFFFFFFF)
#define PLL531X_MDIV_SHIFT		(16)
#define PLL531X_PDIV_SHIFT		(8)
#define PLL531X_SDIV_SHIFT		(0)

static unsigned long samsung_pll531x_recalc_rate(struct clk_hw *hw,
						 unsigned long parent_rate)
{
	struct samsung_clk_pll *pll = to_clk_pll(hw);
	u32 pdiv, sdiv, fdiv, pll_con0, pll_con8;
	u64 mdiv, fout = parent_rate;

	pll_con0 = readl_relaxed(pll->con_reg);
	pll_con8 = readl_relaxed(pll->con_reg + 20);
	mdiv = (pll_con0 >> PLL531X_MDIV_SHIFT) & PLL531X_MDIV_MASK;
	pdiv = (pll_con0 >> PLL531X_PDIV_SHIFT) & PLL531X_PDIV_MASK;
	sdiv = (pll_con0 >> PLL531X_SDIV_SHIFT) & PLL531X_SDIV_MASK;
	fdiv = (pll_con8 & PLL531X_FDIV_MASK);

	if (fdiv >> 31)
		mdiv--;

	fout *= (mdiv << 24) + (fdiv >> 8);
	do_div(fout, (pdiv << sdiv));
	fout >>= 24;

	return (unsigned long)fout;
}

static const struct clk_ops samsung_pll531x_clk_ops = {
	.recalc_rate = samsung_pll531x_recalc_rate,
};

static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
				const struct samsung_pll_clock *pll_clk)
{
@@ -1406,6 +1447,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
		else
			init.ops = &samsung_pll2650xx_clk_ops;
		break;
	case pll_531x:
		init.ops = &samsung_pll531x_clk_ops;
		break;
	default:
		pr_warn("%s: Unknown pll type for pll clk %s\n",
			__func__, pll_clk->name);
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ enum samsung_pll_type {
	pll_0516x,
	pll_0517x,
	pll_0518x,
	pll_531x,
};

#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \