mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 03:06:43 +00:00
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: Sunyeal Hong <sunyeal.hong@samsung.com> Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com> Link: https://lore.kernel.org/r/20240821232652.1077701-4-sunyeal.hong@samsung.com Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
This commit is contained in:
parent
c0979bc884
commit
9224e288f2
@ -1272,6 +1272,47 @@ static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
|
|||||||
.recalc_rate = samsung_pll2650xx_recalc_rate,
|
.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,
|
static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
||||||
const struct samsung_pll_clock *pll_clk)
|
const struct samsung_pll_clock *pll_clk)
|
||||||
{
|
{
|
||||||
@ -1406,6 +1447,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
|||||||
else
|
else
|
||||||
init.ops = &samsung_pll2650xx_clk_ops;
|
init.ops = &samsung_pll2650xx_clk_ops;
|
||||||
break;
|
break;
|
||||||
|
case pll_531x:
|
||||||
|
init.ops = &samsung_pll531x_clk_ops;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_warn("%s: Unknown pll type for pll clk %s\n",
|
pr_warn("%s: Unknown pll type for pll clk %s\n",
|
||||||
__func__, pll_clk->name);
|
__func__, pll_clk->name);
|
||||||
|
@ -42,6 +42,7 @@ enum samsung_pll_type {
|
|||||||
pll_0516x,
|
pll_0516x,
|
||||||
pll_0517x,
|
pll_0517x,
|
||||||
pll_0518x,
|
pll_0518x,
|
||||||
|
pll_531x,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
|
#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user