Skip to content

Commit a524875

Browse files
committed
drivers: firmware: Clock control TISCI driver support
Support added for clock control using TISCI for devices using the binding ti,k2g-sci-clk. This driver relies on the TISCI layer to make calls to the DMSC core to set and get the clock rate and retrieve clock status. Signed-off-by: Dave Joseph <d-joseph@ti.com>
1 parent 99957e1 commit a524875

File tree

6 files changed

+171
-6
lines changed

6 files changed

+171
-6
lines changed

drivers/clock_control/CMakeLists.txt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,15 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL clock_cont
4949
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RTS5912_SCCON clock_control_rts5912_sccon.c)
5050
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL clock_control_nrfs_audiopll.c)
5151
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_IT51XXX clock_control_it51xxx.c)
52-
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF2_COMMON clock_control_nrf2_common.c)
53-
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_FLL16M clock_control_nrf_fll16m.c)
54-
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF54H_HFXO clock_control_nrf54h_hfxo.c)
55-
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_HSFLL_LOCAL clock_control_nrf_hsfll_local.c)
56-
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_LFCLK clock_control_nrf_lfclk.c)
57-
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL60X clock_control_bl60x.c)
52+
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_TISCI clock_control_tisci.c)
53+
54+
if(CONFIG_CLOCK_CONTROL_NRF2)
55+
zephyr_library_sources(clock_control_nrf2_common.c)
56+
zephyr_library_sources(clock_control_nrf2_fll16m.c)
57+
zephyr_library_sources(clock_control_nrf2_hfxo.c)
58+
zephyr_library_sources(clock_control_nrf2_hsfll.c)
59+
zephyr_library_sources(clock_control_nrf2_lfclk.c)
60+
endif()
5861

5962
if(CONFIG_CLOCK_CONTROL_RENESAS_RZA2M_CPG)
6063
zephyr_library_sources(clock_control_renesas_rza2m_cpg.c)

drivers/clock_control/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,6 @@ source "drivers/clock_control/Kconfig.wch_rcc"
116116

117117
source "drivers/clock_control/Kconfig.it51xxx"
118118

119+
source "drivers/clock_control/Kconfig.tisci"
120+
119121
endif # CLOCK_CONTROL

drivers/clock_control/Kconfig.tisci

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright 2024 Texas Instruments Incorporated.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config CLOCK_CONTROL_TISCI
5+
bool "TI SCI Clock Control driver"
6+
default y
7+
depends on DT_HAS_TI_K2G_SCI_CLK_ENABLED
8+
help
9+
Driver for TISCI based clock control.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2025, Texas Instruments
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT ti_k2g_sci_clk
8+
9+
#include <zephyr/device.h>
10+
#include <zephyr/drivers/firmware/tisci/tisci.h>
11+
#include <zephyr/drivers/clock_control.h>
12+
#include <zephyr/drivers/clock_control/tisci_clock_control.h>
13+
#include <zephyr/devicetree.h>
14+
#include <zephyr/logging/log.h>
15+
16+
LOG_MODULE_REGISTER(ti_k2g_sci_clk, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
17+
18+
const struct device *dmsc = DEVICE_DT_GET(DT_NODELABEL(dmsc));
19+
20+
static int tisci_get_rate(const struct device *dev, clock_control_subsys_t sys, uint32_t *rate)
21+
{
22+
struct tisci_clock_config *req = (struct tisci_clock_config *)sys;
23+
uint64_t temp_rate;
24+
int ret = tisci_cmd_clk_get_freq(dmsc, req->dev_id, req->clk_id, &temp_rate);
25+
26+
if (ret) {
27+
LOG_ERR("Failed to get clock freq: dev_id=%u clk_id=%u err=%d", req->dev_id,
28+
req->clk_id, ret);
29+
return ret;
30+
}
31+
32+
*rate = (uint32_t)temp_rate;
33+
return 0;
34+
}
35+
36+
static int tisci_set_rate(const struct device *dev, void *sys, void *rate)
37+
{
38+
struct tisci_clock_config *req = (struct tisci_clock_config *)sys;
39+
uint64_t freq = *((uint64_t *)rate);
40+
int ret = tisci_cmd_clk_set_freq(dmsc, req->dev_id, req->clk_id, freq, freq, freq);
41+
42+
if (ret) {
43+
LOG_ERR("Failed to set clock freq: dev_id=%u clk_id=%u freq=%llu err=%d",
44+
req->dev_id, req->clk_id, freq, ret);
45+
}
46+
return ret;
47+
}
48+
49+
static inline enum clock_control_status tisci_get_status(const struct device *dev,
50+
clock_control_subsys_t sys)
51+
{
52+
enum clock_control_status state = CLOCK_CONTROL_STATUS_UNKNOWN;
53+
struct tisci_clock_config *req = (struct tisci_clock_config *)sys;
54+
bool req_state = true;
55+
bool curr_state = true;
56+
int ret;
57+
58+
ret = tisci_cmd_clk_is_on(dmsc, req->clk_id, req->dev_id, &req_state, &curr_state);
59+
if (ret) {
60+
LOG_ERR("Failed to get clock ON status: dev_id=%u clk_id=%u err=%d", req->dev_id,
61+
req->clk_id, ret);
62+
return CLOCK_CONTROL_STATUS_UNKNOWN;
63+
}
64+
if (curr_state) {
65+
return CLOCK_CONTROL_STATUS_ON;
66+
}
67+
if (req_state && !curr_state) {
68+
return CLOCK_CONTROL_STATUS_STARTING;
69+
}
70+
curr_state = true;
71+
ret = tisci_cmd_clk_is_off(dmsc, req->clk_id, req->dev_id, NULL, &curr_state);
72+
if (ret) {
73+
LOG_ERR("Failed to get clock OFF status: dev_id=%u clk_id=%u err=%d", req->dev_id,
74+
req->clk_id, ret);
75+
return CLOCK_CONTROL_STATUS_UNKNOWN;
76+
}
77+
if (curr_state) {
78+
return CLOCK_CONTROL_STATUS_OFF;
79+
}
80+
return state;
81+
}
82+
83+
static DEVICE_API(clock_control, tisci_clock_driver_api) = {
84+
.get_rate = tisci_get_rate, .set_rate = tisci_set_rate, .get_status = tisci_get_status};
85+
86+
#define TI_K2G_SCI_CLK_INIT(_n) \
87+
DEVICE_DT_INST_DEFINE(_n, NULL, NULL, NULL, NULL, PRE_KERNEL_1, \
88+
CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &tisci_clock_driver_api);
89+
90+
DT_INST_FOREACH_STATUS_OKAY(TI_K2G_SCI_CLK_INIT)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2025 Texas Instruments Incorporated.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: TI-SCI clock controller
5+
6+
compatible: "ti,k2g-sci-clk"
7+
8+
include:
9+
- clock-controller.yaml
10+
- base.yaml
11+
12+
properties:
13+
"#clock-cells":
14+
type: int
15+
required: true
16+
description: >
17+
Number of cells required to specify a clock provided by this controller.
18+
const: 2
19+
20+
clock-cells:
21+
- devid
22+
- clkid
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2025 Texas Instruments
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_DRIVERS_CLOCK_CONTROL_TISCI_CLOCK_CONTROL_H_
8+
#define ZEPHYR_DRIVERS_CLOCK_CONTROL_TISCI_CLOCK_CONTROL_H_
9+
10+
/**
11+
* @struct tisci_clock_config
12+
* @brief Clock configuration structure
13+
*
14+
* This structure is used to define the configuration for a clock, including
15+
* the device ID and clock ID.
16+
*
17+
* @param tisci_clock_config::dev_id
18+
* Device ID associated with the clock.
19+
*
20+
* @param tisci_clock_config::clk_id
21+
* Clock ID within the device.
22+
*/
23+
#include <stdint.h>
24+
struct tisci_clock_config {
25+
uint32_t dev_id;
26+
uint32_t clk_id;
27+
};
28+
29+
#define TISCI_GET_CLOCK(_dev) DEVICE_DT_GET(DT_PHANDLE(DT_NODELABEL(_dev), clocks))
30+
31+
#define TISCI_GET_CLOCK_DETAILS(_dev) \
32+
{.dev_id = DT_CLOCKS_CELL(DT_NODELABEL(_dev), devid), \
33+
.clk_id = DT_CLOCKS_CELL(DT_NODELABEL(_dev), clkid)}
34+
35+
#define TISCI_GET_CLOCK_BY_INST(inst) DEVICE_DT_INST_GET(inst)
36+
37+
#define TISCI_GET_CLOCK_DETAILS_BY_INST(inst) \
38+
{.dev_id = DT_INST_CLOCKS_CELL(inst, devid), .clk_id = DT_INST_CLOCKS_CELL(inst, clkid)}
39+
#endif

0 commit comments

Comments
 (0)