mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-20 17:08:52 +09:00
![Lukasz Majewski](/assets/img/avatar_default.png)
This patch brings the files from Linux kernel (linux-stable/linux-5.1.y SHA1: 5752b50477da)to provide clocks support as it is used on the Linux kernel with Common Clock Framework [CCF] setup. The directory structure has been preserved. The ported code only supports reading information from PLL, MUX, Divider, etc and enabling/disabling the clocks USDHCx/ECSPIx depending on used bus. Moreover, it is agnostic to the alias numbering as the information about the clock is read from the device tree. One needs to pay attention to the comments indicating necessary for U-Boot's driver model changes. If needed, the code can be extended to support the "set" part of the clock management. Signed-off-by: Lukasz Majewski <lukma@denx.de>
81 lines
1.9 KiB
C
81 lines
1.9 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2019 DENX Software Engineering
|
|
* Lukasz Majewski, DENX Software Engineering, lukma@denx.de
|
|
*
|
|
* Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
|
|
*/
|
|
#include <common.h>
|
|
#include <malloc.h>
|
|
#include <clk-uclass.h>
|
|
#include <dm/device.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <div64.h>
|
|
#include <clk.h>
|
|
#include "clk.h"
|
|
|
|
#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
|
|
|
|
static ulong clk_factor_recalc_rate(struct clk *clk)
|
|
{
|
|
struct clk_fixed_factor *fix =
|
|
to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
|
|
unsigned long parent_rate = clk_get_parent_rate(clk);
|
|
unsigned long long int rate;
|
|
|
|
rate = (unsigned long long int)parent_rate * fix->mult;
|
|
do_div(rate, fix->div);
|
|
return (ulong)rate;
|
|
}
|
|
|
|
const struct clk_ops ccf_clk_fixed_factor_ops = {
|
|
.get_rate = clk_factor_recalc_rate,
|
|
};
|
|
|
|
struct clk *clk_hw_register_fixed_factor(struct device *dev,
|
|
const char *name, const char *parent_name, unsigned long flags,
|
|
unsigned int mult, unsigned int div)
|
|
{
|
|
struct clk_fixed_factor *fix;
|
|
struct clk *clk;
|
|
int ret;
|
|
|
|
fix = kzalloc(sizeof(*fix), GFP_KERNEL);
|
|
if (!fix)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
/* struct clk_fixed_factor assignments */
|
|
fix->mult = mult;
|
|
fix->div = div;
|
|
clk = &fix->clk;
|
|
|
|
ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
|
|
parent_name);
|
|
if (ret) {
|
|
kfree(fix);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
return clk;
|
|
}
|
|
|
|
struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
|
|
const char *parent_name, unsigned long flags,
|
|
unsigned int mult, unsigned int div)
|
|
{
|
|
struct clk *clk;
|
|
|
|
clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
|
|
div);
|
|
if (IS_ERR(clk))
|
|
return ERR_CAST(clk);
|
|
return clk;
|
|
}
|
|
|
|
U_BOOT_DRIVER(imx_clk_fixed_factor) = {
|
|
.name = UBOOT_DM_CLK_IMX_FIXED_FACTOR,
|
|
.id = UCLASS_CLK,
|
|
.ops = &ccf_clk_fixed_factor_ops,
|
|
.flags = DM_FLAG_PRE_RELOC,
|
|
};
|