Skip to content

Commit

Permalink
drivers: clk: add fixed-clock driver
Browse files Browse the repository at this point in the history
fixed-clock are a really common clock types used in device tree and
when there is a clock hierarchy, they are needed to query the clock
rate. This driver is build by default when CFG_DRIVERS_CLK_DT is
enabled.

Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
  • Loading branch information
clementleger authored and jforissier committed Oct 22, 2021
1 parent dbe94a8 commit 804e32d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
76 changes: 76 additions & 0 deletions core/drivers/clk/fixed_clk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2021, Bootlin
*/

#include <drivers/clk.h>
#include <drivers/clk_dt.h>
#include <libfdt.h>
#include <malloc.h>
#include <stdint.h>

struct fixed_clock_data {
unsigned long rate;
};

static unsigned long fixed_clk_get_rate(struct clk *clk,
unsigned long parent_rate __unused)
{
struct fixed_clock_data *d = clk->priv;

return d->rate;
}

static const struct clk_ops fixed_clk_clk_ops = {
.get_rate = fixed_clk_get_rate,
};

static TEE_Result fixed_clock_setup(const void *fdt, int offs)
{
const uint32_t *freq = NULL;
const char *name = NULL;
struct clk *clk = NULL;
TEE_Result res = TEE_ERROR_GENERIC;
struct fixed_clock_data *fcd = NULL;

name = fdt_get_name(fdt, offs, NULL);
if (!name)
name = "fixed-clock";

clk = clk_alloc(name, &fixed_clk_clk_ops, NULL, 0);
if (!clk)
return TEE_ERROR_OUT_OF_MEMORY;

fcd = calloc(1, sizeof(struct fixed_clock_data));
if (!fcd) {
res = TEE_ERROR_OUT_OF_MEMORY;
goto free_clk;
}

freq = fdt_getprop(fdt, offs, "clock-frequency", NULL);
if (!freq) {
res = TEE_ERROR_BAD_FORMAT;
goto free_fcd;
}

fcd->rate = fdt32_to_cpu(*freq);
clk->priv = fcd;

res = clk_register(clk);
if (res)
goto free_fcd;

res = clk_dt_register_clk_provider(fdt, offs, clk_dt_get_simple_clk,
clk);
if (!res)
return TEE_SUCCESS;

free_fcd:
free(fcd);
free_clk:
clk_free(clk);

return res;
}

CLK_DT_DECLARE(fixed_clock, "fixed-clock", fixed_clock_setup);
3 changes: 2 additions & 1 deletion core/drivers/clk/sub.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
srcs-y += clk.c
srcs-$(CFG_DRIVERS_CLK_DT) += clk_dt.c
srcs-$(CFG_DRIVERS_CLK_DT) += clk_dt.c
srcs-$(CFG_DRIVERS_CLK_FIXED) += fixed_clk.c
3 changes: 3 additions & 0 deletions mk/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,10 @@ CFG_PREALLOC_RPC_CACHE ?= y
# This clock framework allows to describe clock tree and provides functions to
# get and configure the clocks.
# CFG_DRIVERS_CLK_DT embeds devicetree clock parsing support
# CFG_DRIVERS_CLK_FIXED add support for "fixed-clock" compatible clocks
CFG_DRIVERS_CLK ?= n
CFG_DRIVERS_CLK_DT ?= $(call cfg-all-enabled,CFG_DRIVERS_CLK CFG_DT)
CFG_DRIVERS_CLK_FIXED ?= $(CFG_DRIVERS_CLK_DT)

$(eval $(call cfg-depends-all,CFG_DRIVERS_CLK_DT,CFG_DRIVERS_CLK CFG_DT))
$(eval $(call cfg-depends-all,CFG_DRIVERS_CLK_FIXED,CFG_DRIVERS_CLK_DT))

0 comments on commit 804e32d

Please sign in to comment.