Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

112 lines
3.5 KiB

/*
* Copyright (c) 2025 Renesas Electronics Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT renesas_rza2m_cpg
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/clock_control.h>
#include "clock_control_renesas_rza2m_cpg_lld.h"
static int clock_control_renesas_rza2m_on_off(const struct device *dev, clock_control_subsys_t sys,
bool enable)
{
if (!dev || !sys) {
return -EINVAL;
}
int ret = -EINVAL;
uint32_t *clock_id = (uint32_t *)sys;
uint32_t clk_module = RZA2M_GET_MODULE(*clock_id);
ret = rza2m_cpg_mstp_clock_endisable(dev, clk_module, enable);
return ret;
}
static int clock_control_renesas_rza2m_on(const struct device *dev, clock_control_subsys_t sys)
{
/* Enable the specified clock */
return clock_control_renesas_rza2m_on_off(dev, sys, true);
}
static int clock_control_renesas_rza2m_off(const struct device *dev, clock_control_subsys_t sys)
{
/* Disable the specified clock */
return clock_control_renesas_rza2m_on_off(dev, sys, false);
}
static int clock_control_renesas_rza2m_get_rate(const struct device *dev,
clock_control_subsys_t sys, uint32_t *rate)
{
if (!dev || !sys || !rate) {
return -EINVAL;
}
int ret = -EINVAL;
uint32_t *clock_id = (uint32_t *)sys;
enum rza2m_cpg_get_freq_src clk_src = RZA2M_GET_CLOCK_SRC(*clock_id);
ret = rza2m_cpg_get_clock(dev, clk_src, rate);
return ret;
}
static int clock_control_renesas_rza2m_set_rate(const struct device *dev,
clock_control_subsys_t sys,
clock_control_subsys_rate_t rate)
{
int ret;
enum rza2m_cp_sub_clock clock_name = (enum rza2m_cp_sub_clock)sys;
uint32_t clock_rate = (uint32_t)rate;
ret = rza2m_cpg_set_sub_clock_divider(dev, clock_name, clock_rate);
return ret;
}
static int clock_control_renesas_rza2m_init(const struct device *dev)
{
const struct rza2m_cpg_clock_config *config = dev->config;
uint16_t reg_val;
DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
rza2m_cpg_calculate_pll_frequency(dev);
/* Select Bφ Clock output for CLKIO */
sys_write16(0, CPG_REG_ADDR(CPG_CKIOSEL_OFFSET));
/* Enable CLKIO as Low-level output */
reg_val = sys_read16(CPG_REG_ADDR(CPG_FRQCR_OFFSET));
reg_val &= ~(CPG_FRQCR_CKOEN | CPG_FRQCR_CKOEN2);
reg_val |= (1U << CPG_FRQCR_CKOEN_SHIFT) | (1U << CPG_FRQCR_CKOEN2_SHIFT);
sys_write16(reg_val, CPG_REG_ADDR(CPG_FRQCR_OFFSET));
rza2m_cpg_set_sub_clock_divider(dev, CPG_SUB_CLOCK_ICLK, config->cpg_iclk_freq_hz_cfg);
rza2m_cpg_set_sub_clock_divider(dev, CPG_SUB_CLOCK_BCLK, config->cpg_bclk_freq_hz_cfg);
rza2m_cpg_set_sub_clock_divider(dev, CPG_SUB_CLOCK_P1CLK, config->cpg_p1clk_freq_hz_cfg);
return 0;
}
static DEVICE_API(clock_control, rza2m_clock_control_driver_api) = {
.on = clock_control_renesas_rza2m_on,
.off = clock_control_renesas_rza2m_off,
.get_rate = clock_control_renesas_rza2m_get_rate,
.set_rate = clock_control_renesas_rza2m_set_rate,
};
static const struct rza2m_cpg_clock_config g_rza2m_cpg_clock_config = {
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(0)),
.cpg_extal_freq_hz_cfg = DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency),
.cpg_iclk_freq_hz_cfg = DT_PROP(DT_NODELABEL(iclk), clock_frequency),
.cpg_bclk_freq_hz_cfg = DT_PROP(DT_NODELABEL(bclk), clock_frequency),
.cpg_p1clk_freq_hz_cfg = DT_PROP(DT_NODELABEL(p1clk), clock_frequency),
};
static struct rza2m_cpg_clock_data g_rza2m_cpg_clock_data;
DEVICE_DT_INST_DEFINE(0, clock_control_renesas_rza2m_init, NULL, &g_rza2m_cpg_clock_data,
&g_rza2m_cpg_clock_config, PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
&rza2m_clock_control_driver_api);