mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-02 14:23:19 +08:00
[bsp][rockchip] support DVFS for Rockchip
The I2C will timeout in fan53555, fixed it. Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
SOC_DM_ADC_DIR = $(SOC_DM_DIR)/adc
|
||||
SOC_DM_CAN_DIR = $(SOC_DM_DIR)/can
|
||||
SOC_DM_CLK_DIR = $(SOC_DM_DIR)/clk
|
||||
SOC_DM_DVFS_EVENT_DIR = $(SOC_DM_DIR)/dvfs/event
|
||||
SOC_DM_DVFS_CPUFREQ_DIR = $(SOC_DM_DIR)/dvfs/cpufreq
|
||||
SOC_DM_DVFS_DEVFREQ_DIR = $(SOC_DM_DIR)/dvfs/devfreq
|
||||
SOC_DM_HWCRYPTO_DIR = $(SOC_DM_DIR)/hwcrypto
|
||||
SOC_DM_HWSPINLOCK_DIR = $(SOC_DM_DIR)/hwspinlock
|
||||
SOC_DM_CLOCK_TIME_DIR = $(SOC_DM_DIR)/hwtimer
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
|
||||
if not GetDepend(['RT_USING_DVFS']):
|
||||
Return('group')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
list = os.listdir(cwd)
|
||||
CPPPATH = [cwd + '/../include']
|
||||
|
||||
src = []
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
group = group + SConscript(os.path.join(d, 'SConscript'))
|
||||
|
||||
Return('group')
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
config RT_DVFS_ROCKCHIP_CPUFREQ
|
||||
bool "Rockchip CPUfreq driver"
|
||||
depends on RT_USING_DVFS
|
||||
depends on RT_USING_OFW
|
||||
default y
|
||||
help
|
||||
Rockchip CPUfreq with OPP table parsing and optional nvmem
|
||||
bin/leakage voltage selection. Uses SCMI clock and DT cpu-supply
|
||||
regulator (e.g. FAN53555). Thermal throttling uses
|
||||
thermal-cool-dvfs on the cpufreq device.
|
||||
@@ -0,0 +1,13 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
src = []
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd + '/../../include']
|
||||
|
||||
if GetDepend(['RT_DVFS_ROCKCHIP_CPUFREQ']):
|
||||
src += ['dvfs-rockchip-cpufreq.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+10
@@ -0,0 +1,10 @@
|
||||
config RT_DVFS_ROCKCHIP_DMC
|
||||
bool "Rockchip DMC devfreq (DFI event test stub)"
|
||||
depends on RT_USING_DVFS
|
||||
depends on RT_USING_DVFS_EVENT
|
||||
select RT_DVFS_EVENT_ROCKCHIP_DFI
|
||||
default n
|
||||
help
|
||||
Minimal devfreq on the DMC node to bind DFI event and verify
|
||||
devfreq_load_from_event. Does not perform ATF/SIP DDR scaling.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
src = []
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd + '/../../include']
|
||||
|
||||
if GetDepend(['RT_DVFS_ROCKCHIP_DMC']):
|
||||
src += ['dvfs-rockchip-dmc.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-21 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define DBG_TAG "dvfs.rockchip.dmc"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
struct rockchip_dmcfreq
|
||||
{
|
||||
struct rt_dvfs_devfreq devfreq;
|
||||
struct rt_platform_device *pdev;
|
||||
};
|
||||
|
||||
static const struct rt_ofw_node_id dfi_compat_ids[] =
|
||||
{
|
||||
{ .compatible = "rockchip,rk3568-dfi" },
|
||||
{ .compatible = "rockchip,rk3562-dfi" },
|
||||
{ .compatible = "rockchip,px30-dfi" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static rt_err_t rockchip_dmc_bind_dfi_event(struct rockchip_dmcfreq *dmc,
|
||||
struct rt_device *dev)
|
||||
{
|
||||
struct rt_ofw_node *np = dev->ofw_node, *ev_np;
|
||||
|
||||
for (int i = 0; ; ++i)
|
||||
{
|
||||
if (!(ev_np = rt_ofw_parse_phandle(np, "devfreq-events", i)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (rt_ofw_node_match(ev_np, dfi_compat_ids))
|
||||
{
|
||||
dmc->devfreq.ev = rt_ofw_data(ev_np);
|
||||
}
|
||||
|
||||
rt_ofw_node_put(ev_np);
|
||||
|
||||
if (dmc->devfreq.ev)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dmc->devfreq.ev)
|
||||
{
|
||||
LOG_W("%s: no DFI devfreq-event", rt_dm_dev_get_name(dev));
|
||||
return -RT_ENOENT;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rockchip_dmc_probe(struct rt_platform_device *pdev)
|
||||
{
|
||||
rt_err_t err;
|
||||
struct rt_device *dev = &pdev->parent;
|
||||
struct rockchip_dmcfreq *dmc;
|
||||
struct rt_dvfs_scaling *scaling;
|
||||
|
||||
if (!(dmc = rt_calloc(1, sizeof(*dmc))))
|
||||
{
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
dmc->pdev = pdev;
|
||||
scaling = rt_dvfs_devfreq_to_scaling(&dmc->devfreq);
|
||||
|
||||
rt_dm_dev_set_name_auto(dev, "dmc");
|
||||
|
||||
if ((err = rt_device_register(dev, rt_dm_dev_get_name(dev), RT_DEVICE_FLAG_DEACTIVATE)))
|
||||
{
|
||||
rt_free(dmc);
|
||||
return err;
|
||||
}
|
||||
|
||||
scaling->dev = dev;
|
||||
scaling->ops = &rt_dvfs_devfreq_ops;
|
||||
scaling->clk = rt_clk_get_by_index(dev, 0);
|
||||
if (rt_is_err(scaling->clk))
|
||||
{
|
||||
LOG_W("%s: no dmc clk, event test only", rt_dm_dev_get_name(dev));
|
||||
scaling->clk = RT_NULL;
|
||||
}
|
||||
|
||||
scaling->supply = rt_regulator_get(dev, "center");
|
||||
if (rt_is_err(scaling->supply))
|
||||
{
|
||||
scaling->supply = RT_NULL;
|
||||
}
|
||||
|
||||
if ((err = rockchip_dmc_bind_dfi_event(dmc, dev)))
|
||||
{
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
if ((err = rt_dvfs_devfreq_register(&dmc->devfreq)))
|
||||
{
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
if ((err = rt_dvfs_scaling_set_governor(scaling, RT_DVFS_GOVERNOR_TYPE_ONDEMAND)))
|
||||
{
|
||||
LOG_W("%s: ondemand failed: %s", rt_dm_dev_get_name(dev), rt_strerror(err));
|
||||
}
|
||||
|
||||
pdev->priv = dmc;
|
||||
|
||||
LOG_I("%s: event-only devfreq ready, freq %lu-%lu Hz",
|
||||
rt_dm_dev_get_name(dev), scaling->min_freq, scaling->max_freq);
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
_fail:
|
||||
if (scaling->clk)
|
||||
{
|
||||
rt_clk_put(scaling->clk);
|
||||
}
|
||||
if (scaling->supply)
|
||||
{
|
||||
rt_regulator_put(scaling->supply);
|
||||
}
|
||||
rt_device_unregister(dev);
|
||||
rt_free(dmc);
|
||||
return err;
|
||||
}
|
||||
|
||||
static rt_err_t rockchip_dmc_remove(struct rt_platform_device *pdev)
|
||||
{
|
||||
struct rockchip_dmcfreq *dmc = pdev->priv;
|
||||
|
||||
if (!dmc)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_dvfs_devfreq_unregister(&dmc->devfreq);
|
||||
|
||||
struct rt_dvfs_scaling *scaling = rt_dvfs_devfreq_to_scaling(&dmc->devfreq);
|
||||
if (scaling->clk)
|
||||
{
|
||||
rt_clk_put(scaling->clk);
|
||||
}
|
||||
if (scaling->supply)
|
||||
{
|
||||
rt_regulator_put(scaling->supply);
|
||||
}
|
||||
|
||||
rt_device_unregister(&pdev->parent);
|
||||
rt_free(dmc);
|
||||
pdev->priv = RT_NULL;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_ofw_node_id rockchip_dmc_ofw_ids[] =
|
||||
{
|
||||
{ .compatible = "rockchip,rk3568-dmc" },
|
||||
{ .compatible = "rockchip,rk3562-dmc" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct rt_platform_driver rockchip_dmc_driver =
|
||||
{
|
||||
.name = "rockchip-dmc",
|
||||
.ids = rockchip_dmc_ofw_ids,
|
||||
.probe = rockchip_dmc_probe,
|
||||
.remove = rockchip_dmc_remove,
|
||||
};
|
||||
RT_PLATFORM_DRIVER_EXPORT(rockchip_dmc_driver);
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
config RT_DVFS_EVENT_ROCKCHIP_DFI
|
||||
bool "Rockchip DFI Devfreq event driver"
|
||||
depends on RT_USING_DVFS_EVENT
|
||||
default n
|
||||
@@ -0,0 +1,13 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
src = []
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd + '/../../include']
|
||||
|
||||
if GetDepend(['RT_DVFS_EVENT_ROCKCHIP_DFI']):
|
||||
src += ['event-rockchip-dfi.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
+462
File diff suppressed because it is too large
Load Diff
+283
-89
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-21 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#ifndef __OPP_SELECT_H__
|
||||
#define __OPP_SELECT_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
struct opp_info;
|
||||
|
||||
struct volt_rm_table
|
||||
{
|
||||
int volt;
|
||||
int rm;
|
||||
};
|
||||
|
||||
struct opp_data
|
||||
{
|
||||
rt_err_t (*get_soc_info)(struct rt_device *dev, struct rt_ofw_node *np,
|
||||
int *bin, int *process);
|
||||
rt_err_t (*set_soc_info)(struct rt_device *dev, struct rt_ofw_node *np,
|
||||
struct opp_info *info);
|
||||
rt_err_t (*set_read_margin)(struct rt_device *dev,
|
||||
struct opp_info *opp_info, rt_uint32_t rm);
|
||||
rt_err_t (*config_regulators)(struct rt_device *dev,
|
||||
struct rt_dvfs_opp *old_opp, struct rt_dvfs_opp *new_opp,
|
||||
struct opp_info *info);
|
||||
};
|
||||
|
||||
struct opp_info
|
||||
{
|
||||
struct rt_device *dev;
|
||||
struct rt_ofw_node *opp_np;
|
||||
const struct opp_data *data;
|
||||
|
||||
struct rt_clk *clk;
|
||||
struct rt_regulator *supply;
|
||||
struct rt_regulator *mem_supply;
|
||||
|
||||
int bin;
|
||||
int process;
|
||||
int volt_sel;
|
||||
int scale;
|
||||
int leakage;
|
||||
|
||||
rt_bool_t is_runtime_active;
|
||||
|
||||
struct rt_spinlock dvfs_lock;
|
||||
};
|
||||
|
||||
#if defined(RT_DVFS_ROCKCHIP_CPUFREQ)
|
||||
|
||||
void get_opp_data(const struct rt_ofw_node_id *matches, struct opp_info *info);
|
||||
|
||||
rt_err_t nvmem_cell_read_u8(struct rt_ofw_node *np, const char *cell_id,
|
||||
rt_uint8_t *val);
|
||||
|
||||
const char *regulator_name(struct rt_ofw_node *cpu_np);
|
||||
|
||||
rt_err_t opp_table_init(struct rt_device *dev, struct opp_info *info,
|
||||
const char *reg_name);
|
||||
|
||||
void opp_table_uninit(struct rt_device *dev, struct opp_info *info);
|
||||
|
||||
rt_err_t opp_table_adjust(struct rt_device *dev, struct opp_info *info,
|
||||
struct rt_dvfs_scaling *scaling);
|
||||
|
||||
rt_err_t opp_parse(struct rt_dvfs_scaling *dvfs, struct rt_dvfs_opp *opp,
|
||||
struct rt_ofw_node *opp_np, struct opp_info *info);
|
||||
|
||||
rt_err_t cpufreq_set_opp(struct rt_dvfs_scaling *scaling, struct rt_dvfs_opp *opp,
|
||||
struct opp_info *info);
|
||||
|
||||
rt_err_t cpufreq_sync_hw_state(struct rt_dvfs_scaling *scaling);
|
||||
|
||||
void opp_dvfs_lock(struct opp_info *info);
|
||||
void opp_dvfs_unlock(struct opp_info *info);
|
||||
|
||||
#else
|
||||
|
||||
static inline void get_opp_data(const struct rt_ofw_node_id *matches,
|
||||
struct opp_info *info)
|
||||
{
|
||||
RT_UNUSED(matches);
|
||||
RT_UNUSED(info);
|
||||
}
|
||||
|
||||
static inline rt_err_t opp_table_init(struct rt_device *dev,
|
||||
struct opp_info *info, const char *reg_name)
|
||||
{
|
||||
RT_UNUSED(dev);
|
||||
RT_UNUSED(info);
|
||||
RT_UNUSED(reg_name);
|
||||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
#endif /* RT_DVFS_ROCKCHIP_CPUFREQ */
|
||||
|
||||
#endif /* __OPP_SELECT_H__ */
|
||||
@@ -17,6 +17,9 @@ if GetDepend(['RT_SOC_ROCKCHIP_HW_DECOMPRESS']):
|
||||
if GetDepend(['RT_SOC_ROCKCHIP_IODOMAIN']):
|
||||
src += ['io-domain.c']
|
||||
|
||||
if GetDepend(['RT_DVFS_ROCKCHIP_CPUFREQ']):
|
||||
src += ['opp-select.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+45
-51
File diff suppressed because it is too large
Load Diff
@@ -305,7 +305,23 @@
|
||||
#define RT_FIRMWARE_ARM_SCMI
|
||||
#define RT_FIRMWARE_ARM_SCMI_TRANSPORT_MAILBOX
|
||||
#define RT_FIRMWARE_ARM_SCMI_TRANSPORT_SMC
|
||||
#define RT_USING_DVFS
|
||||
#define RT_USING_DVFS_EVENT
|
||||
#define RT_USING_DVFS_OPP_RETRY_MAX 10
|
||||
|
||||
/* DVFS Event Drivers */
|
||||
|
||||
#define RT_DVFS_EVENT_ROCKCHIP_DFI
|
||||
|
||||
/* DVFS CPUfreq Drivers */
|
||||
|
||||
#define RT_DVFS_ROCKCHIP_CPUFREQ
|
||||
|
||||
/* DVFS Devfreq Drivers */
|
||||
|
||||
#define RT_DVFS_ROCKCHIP_DMC
|
||||
#define RT_USING_REGULATOR
|
||||
#define RT_REGULATOR_FAN53555
|
||||
#define RT_REGULATOR_FIXED
|
||||
#define RT_REGULATOR_GPIO
|
||||
#define RT_REGULATOR_SCMI
|
||||
@@ -326,6 +342,7 @@
|
||||
|
||||
/* Thermal Cool Drivers */
|
||||
|
||||
#define RT_THERMAL_COOL_DVFS
|
||||
#define RT_THERMAL_COOL_PWM_FAN
|
||||
#define RT_USING_NVMEM
|
||||
#define RT_NVMEM_ROCKCHIP_OTP
|
||||
@@ -576,10 +593,22 @@
|
||||
|
||||
/* end of File System */
|
||||
|
||||
/* Tmpfs Testcase */
|
||||
|
||||
/* end of Tmpfs Testcase */
|
||||
|
||||
/* CPP11 */
|
||||
|
||||
/* end of CPP11 */
|
||||
|
||||
/* LWP Testcase */
|
||||
|
||||
/* end of LWP Testcase */
|
||||
|
||||
/* Memory Management Subsytem Testcase */
|
||||
|
||||
/* end of Memory Management Subsytem Testcase */
|
||||
|
||||
/* Network */
|
||||
|
||||
/* end of Network */
|
||||
@@ -588,14 +617,6 @@
|
||||
|
||||
/* end of Utest Framework */
|
||||
/* end of Kernel Components */
|
||||
|
||||
/* Memory Management Subsytem Testcase */
|
||||
|
||||
/* end of Memory Management Subsytem Testcase */
|
||||
|
||||
/* Tmpfs Testcase */
|
||||
|
||||
/* end of Tmpfs Testcase */
|
||||
/* end of RT-Thread Utestcases */
|
||||
|
||||
/* RT-Thread online packages */
|
||||
@@ -719,14 +740,6 @@
|
||||
/* GD32 Drivers */
|
||||
|
||||
/* end of GD32 Drivers */
|
||||
|
||||
/* HPMicro SDK */
|
||||
|
||||
/* end of HPMicro SDK */
|
||||
|
||||
/* FT32 HAL & SDK Drivers */
|
||||
|
||||
/* end of FT32 HAL & SDK Drivers */
|
||||
/* end of HAL & SDK Drivers */
|
||||
|
||||
/* sensors drivers */
|
||||
|
||||
@@ -4,6 +4,12 @@ menuconfig RT_USING_REGULATOR
|
||||
select RT_USING_ADT_REF
|
||||
default n
|
||||
|
||||
config RT_REGULATOR_FAN53555
|
||||
bool "Fairchild FAN53555 / TCS4525 Regulator"
|
||||
depends on RT_USING_REGULATOR
|
||||
depends on RT_USING_I2C
|
||||
default n
|
||||
|
||||
config RT_REGULATOR_FIXED
|
||||
bool "Fixed regulator support"
|
||||
depends on RT_USING_REGULATOR
|
||||
|
||||
@@ -10,6 +10,9 @@ CPPPATH = [cwd + '/../include']
|
||||
|
||||
src = ['regulator.c', 'regulator_dm.c', 'regulator_cmd.c']
|
||||
|
||||
if GetDepend(['RT_REGULATOR_FAN53555']):
|
||||
src += ['regulator-fan53555.c']
|
||||
|
||||
if GetDepend(['RT_REGULATOR_FIXED']):
|
||||
src += ['regulator-fixed.c']
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user