xref: /rk3399_ARM-atf/drivers/ti/clk/ti_clk_dev.c (revision a28114d66a6d43db4accef5fd5d6dab6c059e584)
1*cd88365fSKamlesh Gurudasani /*
2*cd88365fSKamlesh Gurudasani  * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com
3*cd88365fSKamlesh Gurudasani  *
4*cd88365fSKamlesh Gurudasani  * SPDX-License-Identifier: BSD-3-Clause
5*cd88365fSKamlesh Gurudasani  */
6*cd88365fSKamlesh Gurudasani 
7*cd88365fSKamlesh Gurudasani /*
8*cd88365fSKamlesh Gurudasani  * TI Device Clock Driver
9*cd88365fSKamlesh Gurudasani  *
10*cd88365fSKamlesh Gurudasani  * This driver provides clock nodes that are derived from device states,
11*cd88365fSKamlesh Gurudasani  * allowing the clock framework to query and track device power states.
12*cd88365fSKamlesh Gurudasani  * It implements a clock driver that reports frequency and state based on
13*cd88365fSKamlesh Gurudasani  * the associated device's power state, enabling clock tree dependencies
14*cd88365fSKamlesh Gurudasani  * on device power domains.
15*cd88365fSKamlesh Gurudasani  */
16*cd88365fSKamlesh Gurudasani 
17*cd88365fSKamlesh Gurudasani #include <assert.h>
18*cd88365fSKamlesh Gurudasani 
19*cd88365fSKamlesh Gurudasani #include <ti_clk.h>
20*cd88365fSKamlesh Gurudasani #include <ti_clk_dev.h>
21*cd88365fSKamlesh Gurudasani #include <ti_container_of.h>
22*cd88365fSKamlesh Gurudasani #include <ti_device.h>
23*cd88365fSKamlesh Gurudasani #include <ti_device_clk.h>
24*cd88365fSKamlesh Gurudasani #include <ti_device_pm.h>
25*cd88365fSKamlesh Gurudasani 
26*cd88365fSKamlesh Gurudasani /**
27*cd88365fSKamlesh Gurudasani  * ti_clk_from_device_set_state() - Set the state of a device-derived clock.
28*cd88365fSKamlesh Gurudasani  * @clkp: The clock instance (unused).
29*cd88365fSKamlesh Gurudasani  * @enabled: True to enable, false to disable (unused).
30*cd88365fSKamlesh Gurudasani  *
31*cd88365fSKamlesh Gurudasani  * This clock's state is derived from the associated device's power domain
32*cd88365fSKamlesh Gurudasani  * and cannot be directly controlled via the clock framework; the device
33*cd88365fSKamlesh Gurudasani  * power state drives enablement, so always return success.
34*cd88365fSKamlesh Gurudasani  *
35*cd88365fSKamlesh Gurudasani  * Return: Always true.
36*cd88365fSKamlesh Gurudasani  */
ti_clk_from_device_set_state(struct ti_clk * clkp __maybe_unused,bool enabled __maybe_unused)37*cd88365fSKamlesh Gurudasani static bool ti_clk_from_device_set_state(struct ti_clk *clkp __maybe_unused,
38*cd88365fSKamlesh Gurudasani 					 bool enabled __maybe_unused)
39*cd88365fSKamlesh Gurudasani {
40*cd88365fSKamlesh Gurudasani 	assert(clkp != NULL);
41*cd88365fSKamlesh Gurudasani 
42*cd88365fSKamlesh Gurudasani 	return true;
43*cd88365fSKamlesh Gurudasani }
44*cd88365fSKamlesh Gurudasani 
ti_clk_from_device_get_state(struct ti_clk * clkp)45*cd88365fSKamlesh Gurudasani static uint32_t ti_clk_from_device_get_state(struct ti_clk *clkp)
46*cd88365fSKamlesh Gurudasani {
47*cd88365fSKamlesh Gurudasani 	const struct ti_clk_data_from_dev *from_device;
48*cd88365fSKamlesh Gurudasani 	struct ti_dev_clk *dev_clkp;
49*cd88365fSKamlesh Gurudasani 	struct ti_device *dev;
50*cd88365fSKamlesh Gurudasani 	uint32_t state;
51*cd88365fSKamlesh Gurudasani 
52*cd88365fSKamlesh Gurudasani 	assert(clkp != NULL);
53*cd88365fSKamlesh Gurudasani 
54*cd88365fSKamlesh Gurudasani 	from_device = ti_container_of((const struct ti_clk_drv_data *)clkp->data,
55*cd88365fSKamlesh Gurudasani 				      const struct ti_clk_data_from_dev, data);
56*cd88365fSKamlesh Gurudasani 
57*cd88365fSKamlesh Gurudasani 	dev = ti_device_lookup(from_device->dev);
58*cd88365fSKamlesh Gurudasani 	if ((dev == NULL) || (dev->initialized == 0U)) {
59*cd88365fSKamlesh Gurudasani 		return TI_CLK_HW_STATE_DISABLED;
60*cd88365fSKamlesh Gurudasani 	}
61*cd88365fSKamlesh Gurudasani 
62*cd88365fSKamlesh Gurudasani 	state = ti_device_get_state(dev);
63*cd88365fSKamlesh Gurudasani 	if (state == TI_DEVICE_STATE_DISABLED) {
64*cd88365fSKamlesh Gurudasani 		return TI_CLK_HW_STATE_DISABLED;
65*cd88365fSKamlesh Gurudasani 	}
66*cd88365fSKamlesh Gurudasani 
67*cd88365fSKamlesh Gurudasani 	if (state == TI_DEVICE_STATE_TRANSITIONING) {
68*cd88365fSKamlesh Gurudasani 		return TI_CLK_HW_STATE_TRANSITION;
69*cd88365fSKamlesh Gurudasani 	}
70*cd88365fSKamlesh Gurudasani 
71*cd88365fSKamlesh Gurudasani 	dev_clkp = ti_get_dev_clk(dev, from_device->clk_idx);
72*cd88365fSKamlesh Gurudasani 	if ((dev_clkp == NULL) || ((dev_clkp->flags & TI_DEV_CLK_FLAG_DISABLE) != 0U)) {
73*cd88365fSKamlesh Gurudasani 		return TI_CLK_HW_STATE_DISABLED;
74*cd88365fSKamlesh Gurudasani 	}
75*cd88365fSKamlesh Gurudasani 
76*cd88365fSKamlesh Gurudasani 	return TI_CLK_HW_STATE_ENABLED;
77*cd88365fSKamlesh Gurudasani }
78*cd88365fSKamlesh Gurudasani 
79*cd88365fSKamlesh Gurudasani const struct ti_clk_drv ti_clk_drv_from_device = {
80*cd88365fSKamlesh Gurudasani 	.get_freq = ti_clk_value_get_freq,
81*cd88365fSKamlesh Gurudasani 	.set_state = ti_clk_from_device_set_state,
82*cd88365fSKamlesh Gurudasani 	.get_state = ti_clk_from_device_get_state,
83*cd88365fSKamlesh Gurudasani };
84