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
   9#define LOG_CATEGORY UCLASS_CLK
  10
  11#include <common.h>
  12#include <clk.h>
  13#include <clk-uclass.h>
  14#include <div64.h>
  15#include <log.h>
  16#include <malloc.h>
  17#include <dm/device.h>
  18#include <dm/devres.h>
  19#include <linux/clk-provider.h>
  20#include <linux/err.h>
  21
  22#include "clk.h"
  23
  24#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
  25
  26static ulong clk_factor_recalc_rate(struct clk *clk)
  27{
  28        struct clk_fixed_factor *fix = to_clk_fixed_factor(clk);
  29        unsigned long parent_rate = clk_get_parent_rate(clk);
  30        unsigned long long int rate;
  31
  32        rate = (unsigned long long int)parent_rate * fix->mult;
  33        do_div(rate, fix->div);
  34        return (ulong)rate;
  35}
  36
  37const struct clk_ops ccf_clk_fixed_factor_ops = {
  38        .get_rate = clk_factor_recalc_rate,
  39};
  40
  41struct clk *clk_hw_register_fixed_factor(struct device *dev,
  42                const char *name, const char *parent_name, unsigned long flags,
  43                unsigned int mult, unsigned int div)
  44{
  45        struct clk_fixed_factor *fix;
  46        struct clk *clk;
  47        int ret;
  48
  49        fix = kzalloc(sizeof(*fix), GFP_KERNEL);
  50        if (!fix)
  51                return ERR_PTR(-ENOMEM);
  52
  53        /* struct clk_fixed_factor assignments */
  54        fix->mult = mult;
  55        fix->div = div;
  56        clk = &fix->clk;
  57        clk->flags = flags;
  58
  59        ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
  60                           parent_name);
  61        if (ret) {
  62                kfree(fix);
  63                return ERR_PTR(ret);
  64        }
  65
  66        return clk;
  67}
  68
  69struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
  70                const char *parent_name, unsigned long flags,
  71                unsigned int mult, unsigned int div)
  72{
  73        struct clk *clk;
  74
  75        clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
  76                                          div);
  77        if (IS_ERR(clk))
  78                return ERR_CAST(clk);
  79        return clk;
  80}
  81
  82U_BOOT_DRIVER(imx_clk_fixed_factor) = {
  83        .name   = UBOOT_DM_CLK_IMX_FIXED_FACTOR,
  84        .id     = UCLASS_CLK,
  85        .ops    = &ccf_clk_fixed_factor_ops,
  86        .flags = DM_FLAG_PRE_RELOC,
  87};
  88