mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-29 05:18:51 +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>
91 lines
1.9 KiB
C
91 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 2012 Freescale Semiconductor, Inc.
|
|
* Copyright 2012 Linaro Ltd.
|
|
*
|
|
* The code contained herein is licensed under the GNU General Public
|
|
* License. You may obtain a copy of the GNU General Public License
|
|
* Version 2 or later at the following locations:
|
|
*
|
|
* http://www.opensource.org/licenses/gpl-license.html
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/io.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_PFD "imx_clk_pfd"
|
|
|
|
struct clk_pfd {
|
|
struct clk clk;
|
|
void __iomem *reg;
|
|
u8 idx;
|
|
};
|
|
|
|
#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
|
|
|
|
#define SET 0x4
|
|
#define CLR 0x8
|
|
#define OTG 0xc
|
|
|
|
static unsigned long clk_pfd_recalc_rate(struct clk *clk)
|
|
{
|
|
struct clk_pfd *pfd =
|
|
to_clk_pfd(dev_get_clk_ptr(clk->dev));
|
|
unsigned long parent_rate = clk_get_parent_rate(clk);
|
|
u64 tmp = parent_rate;
|
|
u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
|
|
|
|
tmp *= 18;
|
|
do_div(tmp, frac);
|
|
|
|
return tmp;
|
|
}
|
|
|
|
static const struct clk_ops clk_pfd_ops = {
|
|
.get_rate = clk_pfd_recalc_rate,
|
|
};
|
|
|
|
struct clk *imx_clk_pfd(const char *name, const char *parent_name,
|
|
void __iomem *reg, u8 idx)
|
|
{
|
|
struct clk_pfd *pfd;
|
|
struct clk *clk;
|
|
int ret;
|
|
|
|
pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
|
|
if (!pfd)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
pfd->reg = reg;
|
|
pfd->idx = idx;
|
|
|
|
/* register the clock */
|
|
clk = &pfd->clk;
|
|
|
|
ret = clk_register(clk, UBOOT_DM_CLK_IMX_PFD, name, parent_name);
|
|
if (ret) {
|
|
kfree(pfd);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
return clk;
|
|
}
|
|
|
|
U_BOOT_DRIVER(clk_pfd) = {
|
|
.name = UBOOT_DM_CLK_IMX_PFD,
|
|
.id = UCLASS_CLK,
|
|
.ops = &clk_pfd_ops,
|
|
.flags = DM_FLAG_PRE_RELOC,
|
|
};
|