1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Arm Ltd
4 * Author: Liviu Dudau <liviu.dudau@foss.arm.com>
9 #include <clk-uclass.h>
11 #include <dm/device_compat.h>
16 #define CLK_FUNCTION BIT(20)
18 struct vexpress_osc_clk_priv
{
24 static ulong
vexpress_osc_clk_get_rate(struct clk
*clk
)
28 struct udevice
*vexpress_cfg
= dev_get_parent(clk
->dev
);
29 struct vexpress_osc_clk_priv
*priv
= dev_get_priv(clk
->dev
);
31 data
= CLK_FUNCTION
| priv
->osc
;
32 err
= misc_read(vexpress_cfg
, 0, &data
, sizeof(data
));
39 #ifndef CONFIG_SPL_BUILD
40 static ulong
vexpress_osc_clk_set_rate(struct clk
*clk
, ulong rate
)
44 struct udevice
*vexpress_cfg
= dev_get_parent(clk
->dev
);
45 struct vexpress_osc_clk_priv
*priv
= dev_get_priv(clk
->dev
);
47 if (rate
< priv
->rate_min
|| rate
> priv
->rate_max
)
51 * we are sending the parent the info about the oscillator
52 * and the value we want to set
54 buffer
[0] = CLK_FUNCTION
| priv
->osc
;
56 err
= misc_write(vexpress_cfg
, 0, buffer
, 2 * sizeof(u32
));
64 static struct clk_ops vexpress_osc_clk_ops
= {
65 .get_rate
= vexpress_osc_clk_get_rate
,
66 #ifndef CONFIG_SPL_BUILD
67 .set_rate
= vexpress_osc_clk_set_rate
,
71 static int vexpress_osc_clk_probe(struct udevice
*dev
)
73 struct vexpress_osc_clk_priv
*priv
= dev_get_priv(dev
);
77 err
= dev_read_u32_array(dev
, "freq-range", values
, 2);
80 priv
->rate_min
= values
[0];
81 priv
->rate_max
= values
[1];
83 err
= dev_read_u32_array(dev
, "arm,vexpress-sysreg,func", values
, 2);
88 dev_err(dev
, "Invalid VExpress function for clock, must be '1'");
91 priv
->osc
= values
[1];
92 debug("clk \"%s%d\", min freq %luHz, max freq %luHz\n", dev
->name
,
93 priv
->osc
, priv
->rate_min
, priv
->rate_max
);
98 static const struct udevice_id vexpress_osc_clk_ids
[] = {
99 { .compatible
= "arm,vexpress-osc", },
103 U_BOOT_DRIVER(vexpress_osc_clk
) = {
104 .name
= "vexpress_osc_clk",
106 .of_match
= vexpress_osc_clk_ids
,
107 .ops
= &vexpress_osc_clk_ops
,
108 .priv_auto_alloc_size
= sizeof(struct vexpress_osc_clk_priv
),
109 .probe
= vexpress_osc_clk_probe
,