From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/soc/rockchip/pm_domains.c | 194 ++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 160 insertions(+), 34 deletions(-) diff --git a/kernel/drivers/soc/rockchip/pm_domains.c b/kernel/drivers/soc/rockchip/pm_domains.c index 04daba2..6e98b2a 100644 --- a/kernel/drivers/soc/rockchip/pm_domains.c +++ b/kernel/drivers/soc/rockchip/pm_domains.c @@ -93,19 +93,26 @@ #define QOS_SATURATION 0x14 #define QOS_EXTCONTROL 0x18 +#define SHAPING_NBPKTMAX0 0x0 + struct rockchip_pm_domain { struct generic_pm_domain genpd; const struct rockchip_domain_info *info; struct rockchip_pmu *pmu; int num_qos; + int num_shaping; struct regmap **qos_regmap; + struct regmap **shaping_regmap; u32 *qos_save_regs[MAX_QOS_REGS_NUM]; + u32 *shaping_save_regs; bool *qos_is_need_init[MAX_QOS_REGS_NUM]; + bool *shaping_is_need_init; int num_clks; struct clk_bulk_data *clks; bool is_ignore_pwr; bool is_qos_saved; bool is_qos_need_init; + bool is_shaping_need_init; struct regulator *supply; }; @@ -124,35 +131,6 @@ module_param_named(always_on, pm_domain_always_on, bool, 0644); MODULE_PARM_DESC(always_on, "Always keep pm domains power on except for system suspend."); - -#ifdef MODULE -static bool keepon_startup = true; -static void rockchip_pd_keepon_do_release(void); - -static int pd_param_set_keepon_startup(const char *val, - const struct kernel_param *kp) -{ - int ret; - - ret = param_set_bool(val, kp); - if (ret) - return ret; - - if (!keepon_startup) - rockchip_pd_keepon_do_release(); - - return 0; -} - -static const struct kernel_param_ops pd_keepon_startup_ops = { - .set = pd_param_set_keepon_startup, - .get = param_get_bool, -}; - -module_param_cb(keepon_startup, &pd_keepon_startup_ops, &keepon_startup, 0644); -MODULE_PARM_DESC(keepon_startup, - "Keep pm domains power on during system startup."); -#endif static void rockchip_pmu_lock(struct rockchip_pm_domain *pd) { @@ -459,6 +437,45 @@ } EXPORT_SYMBOL(rockchip_pmu_idle_request); +static int rockchip_pmu_save_shaping(struct rockchip_pm_domain *pd) +{ + int i; + + for (i = 0; i < pd->num_shaping; i++) + regmap_read(pd->shaping_regmap[i], SHAPING_NBPKTMAX0, + &pd->shaping_save_regs[i]); + + return 0; +} + +static int rockchip_pmu_restore_shaping(struct rockchip_pm_domain *pd) +{ + int i; + + for (i = 0; i < pd->num_shaping; i++) + regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0, + pd->shaping_save_regs[i]); + + return 0; +} + +static void rockchip_pmu_init_shaping(struct rockchip_pm_domain *pd) +{ + int i; + + if (!pd->is_shaping_need_init) + return; + + for (i = 0; i < pd->num_shaping; i++) + if (pd->shaping_is_need_init[i]) + regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0, + pd->shaping_save_regs[i]); + + kfree(pd->shaping_is_need_init); + pd->shaping_is_need_init = NULL; + pd->is_shaping_need_init = false; +} + static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd) { int i; @@ -480,7 +497,8 @@ QOS_EXTCONTROL, &pd->qos_save_regs[4][i]); } - return 0; + + return rockchip_pmu_save_shaping(pd); } static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd) @@ -505,12 +523,14 @@ pd->qos_save_regs[4][i]); } - return 0; + return rockchip_pmu_restore_shaping(pd); } static void rockchip_pmu_init_qos(struct rockchip_pm_domain *pd) { int i; + + rockchip_pmu_init_shaping(pd); if (!pd->is_qos_need_init) return; @@ -809,7 +829,7 @@ if (pd->is_qos_saved) rockchip_pmu_restore_qos(pd); - if (pd->is_qos_need_init) + if (pd->is_qos_need_init || pd->is_shaping_need_init) rockchip_pmu_init_qos(pd); } @@ -949,8 +969,13 @@ if (!pd->is_qos_need_init) { kfree(pd->qos_is_need_init[0]); pd->qos_is_need_init[0] = NULL; - return; } + if (!pd->is_shaping_need_init) { + kfree(pd->shaping_is_need_init); + pd->shaping_is_need_init = NULL; + } + if (!pd->is_qos_need_init && !pd->is_shaping_need_init) + return; is_pd_on = rockchip_pmu_domain_is_on(pd); if (is_pd_on) { @@ -982,6 +1007,79 @@ } return 0; +} + +static int rockchip_pd_of_get_shaping(struct rockchip_pm_domain *pd, + struct device_node *node) +{ + struct rockchip_pmu *pmu = pd->pmu; + struct device_node *shaping_node; + int num_shaping = 0, num_shaping_reg = 0; + int error, i; + u32 val; + + num_shaping = of_count_phandle_with_args(node, "pm_shaping", NULL); + + for (i = 0; i < num_shaping; i++) { + shaping_node = of_parse_phandle(node, "pm_shaping", i); + if (shaping_node && of_device_is_available(shaping_node)) + pd->num_shaping++; + of_node_put(shaping_node); + } + + if (pd->num_shaping > 0) { + pd->shaping_regmap = devm_kcalloc(pmu->dev, pd->num_shaping, + sizeof(*pd->shaping_regmap), + GFP_KERNEL); + if (!pd->shaping_regmap) + return -ENOMEM; + pd->shaping_save_regs = devm_kmalloc(pmu->dev, sizeof(u32) * + pd->num_shaping, + GFP_KERNEL); + if (!pd->shaping_save_regs) + return -ENOMEM; + pd->shaping_is_need_init = kcalloc(pd->num_shaping, sizeof(bool), + GFP_KERNEL); + if (!pd->shaping_is_need_init) + return -ENOMEM; + for (i = 0; i < num_shaping; i++) { + shaping_node = of_parse_phandle(node, "pm_shaping", i); + if (!shaping_node) { + error = -ENODEV; + goto err_free_init; + } + if (of_device_is_available(shaping_node)) { + pd->shaping_regmap[num_shaping_reg] = + syscon_node_to_regmap(shaping_node); + if (IS_ERR(pd->shaping_regmap[num_shaping_reg])) { + of_node_put(shaping_node); + error = -ENODEV; + goto err_free_init; + } + if (!of_property_read_u32(shaping_node, + "shaping-init", + &val)) { + pd->shaping_save_regs[i] = val; + pd->shaping_is_need_init[i] = true; + pd->is_shaping_need_init = true; + } + num_shaping_reg++; + } + of_node_put(shaping_node); + if (num_shaping_reg > pd->num_shaping) { + error = -EINVAL; + goto err_free_init; + } + } + } + + return 0; + +err_free_init: + kfree(pd->shaping_is_need_init); + pd->shaping_is_need_init = NULL; + + return error; } static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, @@ -1160,6 +1258,10 @@ } } + error = rockchip_pd_of_get_shaping(pd, node); + if (error) + goto err_unprepare_clocks; + if (pd->info->name) pd->genpd.name = pd->info->name; else @@ -1309,6 +1411,31 @@ return error; } +#ifdef MODULE +void rockchip_pd_disable_unused(void) +{ + struct generic_pm_domain *genpd; + struct rockchip_pm_domain *pd; + int i; + + if (!g_pmu) + return; + + for (i = 0; i < g_pmu->genpd_data.num_domains; i++) { + genpd = g_pmu->genpd_data.domains[i]; + if (genpd) { + pd = to_rockchip_pd(genpd); + if (pd->info->always_on) + continue; + if (pd->info->keepon_startup && + (genpd->flags & GENPD_FLAG_ALWAYS_ON)) + genpd->flags &= (~GENPD_FLAG_ALWAYS_ON); + queue_work(pm_wq, &genpd->power_off_work); + } + } +} +EXPORT_SYMBOL_GPL(rockchip_pd_disable_unused); +#else static void rockchip_pd_keepon_do_release(void) { struct generic_pm_domain *genpd; @@ -1334,7 +1461,6 @@ } } -#ifndef MODULE static int __init rockchip_pd_keepon_release(void) { rockchip_pd_keepon_do_release(); -- Gitblit v1.6.2