> -----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>

Reply via email to