uboot/drivers/clk/clk-fixed-factor.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2019 DENX Software Engineering
   4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
   5 *
   6 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
   7 */
   8#include <common.h>
   9#include <malloc.h>
  10#include <clk-uclass.h>
  11#include <dm/device.h>
  12#include <linux/clk-provider.h>
  13#include <div64.h>
  14#include <clk.h>
  15#include "clk.h"
  16
  17#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
  18
  19static ulong clk_factor_recalc_rate(struct clk *clk)
  20{
  21        struct clk_fixed_factor *fix =
  22                to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
  23        unsigned long parent_rate = clk_get_parent_rate(clk);
  24        unsigned long long int rate;
  25
  26        rate = (unsigned long long int)parent_rate * fix->mult;
  27        do_div(rate, fix->div);
  28        return (ulong)rate;
  29}
  30
  31const struct clk_ops ccf_clk_fixed_factor_ops = {
  32        .get_rate = clk_factor_recalc_rate,
  33};
  34
  35struct clk *clk_hw_register_fixed_factor(struct device *dev,
  36                const char *name, const char *parent_name, unsigned long flags,
  37                unsigned int mult, unsigned int div)
  38{
  39        struct clk_fixed_factor *fix;
  40        struct clk *clk;
  41        int ret;
  42
  43        fix = kzalloc(sizeof(*fix), GFP_KERNEL);
  44        if (!fix)
  45                return ERR_PTR(-ENOMEM);
  46
  47        /* struct clk_fixed_factor assignments */
  48        fix->mult = mult;
  49        fix->div = div;
  50        clk = &fix->clk;
  51
  52        ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
  53                           parent_name);
  54        if (ret) {
  55                kfree(fix);
  56                return ERR_PTR(ret);
  57        }
  58
  59        return clk;
  60}
  61
  62struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
  63                const char *parent_name, unsigned long flags,
  64                unsigned int mult, unsigned int div)
  65{
  66        struct clk *clk;
  67
  68        clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
  69                                          div);
  70        if (IS_ERR(clk))
  71                return ERR_CAST(clk);
  72        return clk;
  73}
  74
  75U_BOOT_DRIVER(imx_clk_fixed_factor) = {
  76        .name   = UBOOT_DM_CLK_IMX_FIXED_FACTOR,
  77        .id     = UCLASS_CLK,
  78        .ops    = &ccf_clk_fixed_factor_ops,
  79        .flags = DM_FLAG_PRE_RELOC,
  80};
  81