blob: 2a446788e191dc4b62db4d4b64ef8fb567b4217c [file] [log] [blame]
Lukasz Majewski4de44bb2019-06-24 15:50:45 +02001// 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 */
Patrick Delaunay8767e792021-11-19 15:12:07 +01008
9#define LOG_CATEGORY UCLASS_CLK
10
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020011#include <common.h>
Patrick Delaunay283dadf2021-11-19 15:12:06 +010012#include <clk.h>
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020013#include <clk-uclass.h>
Patrick Delaunay283dadf2021-11-19 15:12:06 +010014#include <div64.h>
Patrick Delaunay8767e792021-11-19 15:12:07 +010015#include <log.h>
Patrick Delaunay283dadf2021-11-19 15:12:06 +010016#include <malloc.h>
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020017#include <dm/device.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070018#include <dm/devres.h>
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020019#include <linux/clk-provider.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070020#include <linux/err.h>
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020021
Patrick Delaunay283dadf2021-11-19 15:12:06 +010022#include "clk.h"
23
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020024#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
25
26static ulong clk_factor_recalc_rate(struct clk *clk)
27{
Sean Andersoncfc2f022020-06-24 06:41:06 -040028 struct clk_fixed_factor *fix = to_clk_fixed_factor(clk);
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020029 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;
Dario Binacchi1a62dc12020-04-13 14:36:27 +020057 clk->flags = flags;
Lukasz Majewski4de44bb2019-06-24 15:50:45 +020058
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};