mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-10-17 19:44:37 +00:00
0d47bc7056
Add initial clock driver for Allwinner A64. Implement USB clock enable and disable functions for OHCI, EHCI, OTG and USBPHY gate and clock registers via ccu clk gate table. Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
74 lines
1.5 KiB
C
74 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2018 Amarula Solutions.
|
|
* Author: Jagan Teki <jagan@amarulasolutions.com>
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <clk-uclass.h>
|
|
#include <dm.h>
|
|
#include <errno.h>
|
|
#include <asm/io.h>
|
|
#include <asm/arch/ccu.h>
|
|
#include <linux/log2.h>
|
|
|
|
static const struct ccu_clk_gate *priv_to_gate(struct ccu_priv *priv,
|
|
unsigned long id)
|
|
{
|
|
return &priv->desc->gates[id];
|
|
}
|
|
|
|
static int sunxi_set_gate(struct clk *clk, bool on)
|
|
{
|
|
struct ccu_priv *priv = dev_get_priv(clk->dev);
|
|
const struct ccu_clk_gate *gate = priv_to_gate(priv, clk->id);
|
|
u32 reg;
|
|
|
|
if (!(gate->flags & CCU_CLK_F_IS_VALID)) {
|
|
printf("%s: (CLK#%ld) unhandled\n", __func__, clk->id);
|
|
return 0;
|
|
}
|
|
|
|
debug("%s: (CLK#%ld) off#0x%x, BIT(%d)\n", __func__,
|
|
clk->id, gate->off, ilog2(gate->bit));
|
|
|
|
reg = readl(priv->base + gate->off);
|
|
if (on)
|
|
reg |= gate->bit;
|
|
else
|
|
reg &= ~gate->bit;
|
|
|
|
writel(reg, priv->base + gate->off);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sunxi_clk_enable(struct clk *clk)
|
|
{
|
|
return sunxi_set_gate(clk, true);
|
|
}
|
|
|
|
static int sunxi_clk_disable(struct clk *clk)
|
|
{
|
|
return sunxi_set_gate(clk, false);
|
|
}
|
|
|
|
struct clk_ops sunxi_clk_ops = {
|
|
.enable = sunxi_clk_enable,
|
|
.disable = sunxi_clk_disable,
|
|
};
|
|
|
|
int sunxi_clk_probe(struct udevice *dev)
|
|
{
|
|
struct ccu_priv *priv = dev_get_priv(dev);
|
|
|
|
priv->base = dev_read_addr_ptr(dev);
|
|
if (!priv->base)
|
|
return -ENOMEM;
|
|
|
|
priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
|
|
if (!priv->desc)
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
}
|