> -----Original Message----- > From: U-Boot <u-boot-boun...@lists.denx.de> On Behalf Of Sam Protsenko > Sent: Wednesday, December 13, 2023 12:17 PM > To: Minkyu Kang <mk7.k...@samsung.com>; Tom Rini <tr...@konsulko.com>; > Lukasz Majewski <lu...@denx.de>; Sean Anderson <sean...@gmail.com> > Cc: Simon Glass <s...@chromium.org>; Heinrich Schuchardt > <xypron.g...@gmx.de>; u-boot@lists.denx.de > Subject: [PATCH 07/13] clk: exynos: Add Samsung clock framework > > Heavily based on Linux kernel Samsung clock framework, with some changes > to accommodate the differences in U-Boot CCF implementation. It's also > quite minimal as compared to the Linux version. > > Signed-off-by: Sam Protsenko <semen.protse...@linaro.org> > --- > drivers/clk/exynos/Makefile | 9 +- > drivers/clk/exynos/clk-pll.c | 167 +++++++++++++++++++++++++ > drivers/clk/exynos/clk-pll.h | 23 ++++ > drivers/clk/exynos/clk.c | 121 +++++++++++++++++++ > drivers/clk/exynos/clk.h | 228 +++++++++++++++++++++++++++++++++++ > 5 files changed, 546 insertions(+), 2 deletions(-) > create mode 100644 drivers/clk/exynos/clk-pll.c > create mode 100644 drivers/clk/exynos/clk-pll.h > create mode 100644 drivers/clk/exynos/clk.c > create mode 100644 drivers/clk/exynos/clk.h > > diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile > index 7faf238571ef..04c5b9a39e16 100644 > --- a/drivers/clk/exynos/Makefile > +++ b/drivers/clk/exynos/Makefile > @@ -1,6 +1,11 @@ > # SPDX-License-Identifier: GPL-2.0+ > # > # Copyright (C) 2016 Samsung Electronics > -# Thomas Abraham <thomas...@samsung.com> > +# Copyright (C) 2023 Linaro Ltd. > +# > +# Authors: > +# Thomas Abraham <thomas...@samsung.com> > +# Sam Protsenko <semen.protse...@linaro.org> > > -obj-$(CONFIG_CLK_EXYNOS7420) += clk-exynos7420.o > +obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk.o clk-pll.o > +obj-$(CONFIG_CLK_EXYNOS7420) += clk-exynos7420.o > diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c > new file mode 100644 > index 000000000000..9e496ff83aaf > --- /dev/null > +++ b/drivers/clk/exynos/clk-pll.c > @@ -0,0 +1,167 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2016 Samsung Electronics > + * Copyright (C) 2023 Linaro Ltd. > + * > + * Authors: > + * Thomas Abraham <thomas...@exynos.com>
Need to correct Thomas's email to samsung.com if you want to keep his original credit even though his e-mail was already stale since he left the company. > + * Sam Protsenko <semen.protse...@linaro.org> > + * > + * This file contains the utility functions to register the pll clocks. > + */ > + > +#include <asm/io.h> > +#include <div64.h> > +#include <malloc.h> > +#include <clk-uclass.h> > +#include <dm/device.h> > +#include <clk.h> > +#include "clk.h" > + > +#define UBOOT_DM_CLK_SAMSUNG_PLL0822X "samsung_clk_pll0822x" > +#define UBOOT_DM_CLK_SAMSUNG_PLL0831X "samsung_clk_pll0831x" > + > +struct samsung_clk_pll { > + struct clk clk; > + void __iomem *con_reg; > + enum samsung_pll_type type; > +}; > + > +#define to_clk_pll(_clk) container_of(_clk, struct samsung_clk_pll, clk) > + > +/* > + * PLL0822x Clock Type > + */ > + > +#define PLL0822X_MDIV_MASK 0x3ff > +#define PLL0822X_PDIV_MASK 0x3f > +#define PLL0822X_SDIV_MASK 0x7 > +#define PLL0822X_MDIV_SHIFT 16 > +#define PLL0822X_PDIV_SHIFT 8 > +#define PLL0822X_SDIV_SHIFT 0 > + > +static unsigned long samsung_pll0822x_recalc_rate(struct clk *clk) > +{ > + struct samsung_clk_pll *pll = to_clk_pll(clk); > + u32 mdiv, pdiv, sdiv, pll_con3; > + u64 fvco = clk_get_parent_rate(clk); > + > + pll_con3 = readl_relaxed(pll->con_reg); > + mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK; > + pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK; > + sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK; > + > + fvco *= mdiv; > + do_div(fvco, (pdiv << sdiv)); > + return (unsigned long)fvco; > +} > + > +static const struct clk_ops samsung_pll0822x_clk_min_ops = { > + .get_rate = samsung_pll0822x_recalc_rate, > +}; > + > +/* > + * PLL0831x Clock Type > + */ > + > +#define PLL0831X_KDIV_MASK 0xffff > +#define PLL0831X_MDIV_MASK 0x1ff > +#define PLL0831X_PDIV_MASK 0x3f > +#define PLL0831X_SDIV_MASK 0x7 > +#define PLL0831X_MDIV_SHIFT 16 > +#define PLL0831X_PDIV_SHIFT 8 > +#define PLL0831X_SDIV_SHIFT 0 > +#define PLL0831X_KDIV_SHIFT 0 > + > +static unsigned long samsung_pll0831x_recalc_rate(struct clk *clk) > +{ > + struct samsung_clk_pll *pll = to_clk_pll(clk); > + u32 mdiv, pdiv, sdiv, pll_con3, pll_con5; > + s16 kdiv; > + u64 fvco = clk_get_parent_rate(clk); > + > + pll_con3 = readl_relaxed(pll->con_reg); > + pll_con5 = readl_relaxed(pll->con_reg + 8); > + mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK; > + pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK; > + sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK; > + kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & > PLL0831X_KDIV_MASK); > + > + fvco *= (mdiv << 16) + kdiv; > + do_div(fvco, (pdiv << sdiv)); > + fvco >>= 16; > + > + return (unsigned long)fvco; > +} > + > +static const struct clk_ops samsung_pll0831x_clk_min_ops = { > + .get_rate = samsung_pll0831x_recalc_rate, > +}; > + > +static struct clk *_samsung_clk_register_pll(void __iomem *base, > + const struct samsung_pll_clock *pll_clk) > +{ > + struct samsung_clk_pll *pll; > + struct clk *clk; > + const char *drv_name; > + int ret; > + > + pll = kzalloc(sizeof(*pll), GFP_KERNEL); > + if (!pll) > + return ERR_PTR(-ENOMEM); > + > + pll->con_reg = base + pll_clk->con_offset; > + pll->type = pll_clk->type; > + clk = &pll->clk; > + clk->flags = pll_clk->flags; > + > + switch (pll_clk->type) { > + case pll_0822x: > + drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X; > + break; > + case pll_0831x: > + drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0831X; > + break; > + default: > + kfree(pll); > + return ERR_PTR(-ENODEV); > + } > + > + ret = clk_register(clk, drv_name, pll_clk->name, pll_clk- > >parent_name); > + if (ret) { > + kfree(pll); > + return ERR_PTR(ret); > + } > + > + return clk; > +} > + > +void samsung_clk_register_pll(void __iomem *base, > + const struct samsung_pll_clock *clk_list, > + unsigned int nr_clk) > +{ > + unsigned int cnt; > + > + for (cnt = 0; cnt < nr_clk; cnt++) { > + struct clk *clk; > + const struct samsung_pll_clock *pll_clk; > + > + pll_clk = &clk_list[cnt]; > + clk = _samsung_clk_register_pll(base, pll_clk); > + clk_dm(pll_clk->id, clk); > + } > +} > + > +U_BOOT_DRIVER(samsung_pll0822x_clk) = { > + .name = UBOOT_DM_CLK_SAMSUNG_PLL0822X, > + .id = UCLASS_CLK, > + .ops = &samsung_pll0822x_clk_min_ops, > + .flags = DM_FLAG_PRE_RELOC, > +}; > + > +U_BOOT_DRIVER(samsung_pll0831x_clk) = { > + .name = UBOOT_DM_CLK_SAMSUNG_PLL0831X, > + .id = UCLASS_CLK, > + .ops = &samsung_pll0831x_clk_min_ops, > + .flags = DM_FLAG_PRE_RELOC, > +}; > diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h > new file mode 100644 > index 000000000000..3b477369aeb8 > --- /dev/null > +++ b/drivers/clk/exynos/clk-pll.h > @@ -0,0 +1,23 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright (C) 2016 Samsung Electronics > + * Copyright (C) 2023 Linaro Ltd. > + * > + * Authors: > + * Thomas Abraham <thomas...@exynos.com> Ditto. Othewise, Reviewed-by: Chanho Park <chanho61.p...@samsung.com>