^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Rockchip Generic power domain support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2015 ROCKCHIP, Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pm_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pm_domain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/rockchip/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <soc/rockchip/pm_domains.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <soc/rockchip/rockchip_dmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <dt-bindings/power/px30-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <dt-bindings/power/rv1126-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <dt-bindings/power/rk1808-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <dt-bindings/power/rk3036-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <dt-bindings/power/rk3066-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <dt-bindings/power/rk3128-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <dt-bindings/power/rk3188-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <dt-bindings/power/rk3228-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <dt-bindings/power/rk3288-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <dt-bindings/power/rk3328-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <dt-bindings/power/rk3366-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <dt-bindings/power/rk3368-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <dt-bindings/power/rk3399-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <dt-bindings/power/rk3568-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <dt-bindings/power/rk3588-power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct rockchip_domain_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int pwr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int req_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int idle_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int ack_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) bool active_wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int pwr_w_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int req_w_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int mem_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int repair_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) bool keepon_startup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) bool always_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 pwr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 mem_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 req_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct rockchip_pmu_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 pwr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 status_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u32 req_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u32 idle_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u32 ack_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 mem_pwr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u32 chain_status_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u32 mem_status_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u32 repair_status_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u32 core_pwrcnt_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u32 gpu_pwrcnt_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int core_power_transition_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int gpu_power_transition_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int num_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) const struct rockchip_domain_info *domain_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define MAX_QOS_REGS_NUM 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define QOS_PRIORITY 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define QOS_MODE 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define QOS_BANDWIDTH 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define QOS_SATURATION 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define QOS_EXTCONTROL 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct rockchip_pm_domain {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct generic_pm_domain genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) const struct rockchip_domain_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct rockchip_pmu *pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int num_qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct regmap **qos_regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 *qos_save_regs[MAX_QOS_REGS_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bool *qos_is_need_init[MAX_QOS_REGS_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct clk_bulk_data *clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bool is_ignore_pwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bool is_qos_saved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bool is_qos_need_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct regulator *supply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct rockchip_pmu {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) const struct rockchip_pmu_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct mutex mutex; /* mutex lock for pmu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct genpd_onecell_data genpd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct generic_pm_domain *domains[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct rockchip_pmu *g_pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static bool pm_domain_always_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) module_param_named(always_on, pm_domain_always_on, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) MODULE_PARM_DESC(always_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) "Always keep pm domains power on except for system suspend.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void rockchip_pmu_lock(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mutex_lock(&pd->pmu->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rockchip_dmcfreq_lock_nested();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void rockchip_pmu_unlock(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) rockchip_dmcfreq_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mutex_unlock(&pd->pmu->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define DOMAIN(_name, pwr, status, req, idle, ack, wakeup, keepon) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .pwr_mask = (pwr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .status_mask = (status), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .req_mask = (req), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .idle_mask = (idle), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .ack_mask = (ack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .active_wakeup = (wakeup), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .keepon_startup = (keepon), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define DOMAIN_M(_name, pwr, status, req, idle, ack, wakeup, keepon) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .pwr_w_mask = (pwr) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .pwr_mask = (pwr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .status_mask = (status), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .req_w_mask = (req) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .req_mask = (req), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .idle_mask = (idle), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .ack_mask = (ack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .active_wakeup = wakeup, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .keepon_startup = keepon, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define DOMAIN_M_O(_name, pwr, status, p_offset, req, idle, ack, r_offset, wakeup, keepon) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .pwr_w_mask = (pwr) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .pwr_mask = (pwr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .status_mask = (status), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .req_w_mask = (req) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .req_mask = (req), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .idle_mask = (idle), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .ack_mask = (ack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .active_wakeup = wakeup, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .keepon_startup = keepon, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .pwr_offset = p_offset, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .req_offset = r_offset, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define DOMAIN_M_O_R(_name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, ack, wakeup, keepon) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .pwr_offset = p_offset, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .pwr_w_mask = (pwr) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .pwr_mask = (pwr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .status_mask = (status), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .mem_offset = m_offset, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .mem_status_mask = (m_status), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .repair_status_mask = (r_status), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .req_offset = r_offset, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .req_w_mask = (req) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .req_mask = (req), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .idle_mask = (idle), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .ack_mask = (ack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .active_wakeup = wakeup, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .keepon_startup = keepon, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define DOMAIN_RK3036(_name, req, ack, idle, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .req_mask = (req), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .req_w_mask = (req) << 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .ack_mask = (ack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .idle_mask = (idle), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .active_wakeup = wakeup, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define DOMAIN_PX30(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define DOMAIN_PX30_PROTECT(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define DOMAIN_RV1126(name, pwr, req, idle, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) DOMAIN_M(name, pwr, pwr, req, idle, idle, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define DOMAIN_RV1126_PROTECT(name, pwr, req, idle, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) DOMAIN_M(name, pwr, pwr, req, idle, idle, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define DOMAIN_RV1126_O(name, pwr, req, idle, r_offset, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) DOMAIN_M_O(name, pwr, pwr, 0, req, idle, idle, r_offset, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define DOMAIN_RK3288(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define DOMAIN_RK3288_PROTECT(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define DOMAIN_RK3328(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) DOMAIN_M(name, pwr, pwr, req, (req) << 10, req, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define DOMAIN_RK3368(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) DOMAIN(name, pwr, status, req, (req) << 16, req, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define DOMAIN_RK3368_PROTECT(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) DOMAIN(name, pwr, status, req, (req) << 16, req, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define DOMAIN_RK3399(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) DOMAIN(name, pwr, status, req, req, req, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define DOMAIN_RK3399_PROTECT(name, pwr, status, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) DOMAIN(name, pwr, status, req, req, req, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define DOMAIN_RK3568(name, pwr, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) DOMAIN_M(name, pwr, pwr, req, req, req, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define DOMAIN_RK3568_PROTECT(name, pwr, req, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) DOMAIN_M(name, pwr, pwr, req, req, req, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define DOMAIN_RK3588(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup, false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define DOMAIN_RK3588_P(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup, true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) const struct rockchip_domain_info *pd_info = pd->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return (val & pd_info->idle_mask) == pd_info->idle_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) bool idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) const struct rockchip_domain_info *pd_info = pd->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct generic_pm_domain *genpd = &pd->genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 pd_req_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned int target_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) bool is_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (pd_info->req_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) pd_req_offset = pd_info->req_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (pd_info->req_mask == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) else if (pd_info->req_w_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) regmap_write(pmu->regmap, pmu->info->req_offset + pd_req_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) idle ? (pd_info->req_mask | pd_info->req_w_mask) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pd_info->req_w_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) regmap_update_bits(pmu->regmap, pmu->info->req_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) pd_req_offset, pd_info->req_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) idle ? -1U : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dsb(sy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Wait util idle_ack = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) target_ack = idle ? pd_info->ack_mask : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) (val & pd_info->ack_mask) == target_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 0, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) "failed to get ack on domain '%s', target_idle = %d, target_ack = %d, val=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) genpd->name, idle, target_ack, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_idle, pd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) is_idle, is_idle == idle, 0, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) "failed to set idle on domain '%s', target_idle = %d, val=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) genpd->name, idle, is_idle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) panic("panic_on_set_idle set ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int rockchip_pmu_idle_request(struct device *dev, bool idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (IS_ERR_OR_NULL(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (IS_ERR_OR_NULL(dev->pm_domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) genpd = pd_to_genpd(dev->pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rockchip_pmu_lock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = rockchip_pmu_set_idle_request(pd, idle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) EXPORT_SYMBOL(rockchip_pmu_idle_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) for (i = 0; i < pd->num_qos; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) regmap_read(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) QOS_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) &pd->qos_save_regs[0][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regmap_read(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) QOS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) &pd->qos_save_regs[1][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) regmap_read(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) QOS_BANDWIDTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) &pd->qos_save_regs[2][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) regmap_read(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) QOS_SATURATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) &pd->qos_save_regs[3][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) regmap_read(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) QOS_EXTCONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) &pd->qos_save_regs[4][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) for (i = 0; i < pd->num_qos; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) QOS_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) pd->qos_save_regs[0][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) QOS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) pd->qos_save_regs[1][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) QOS_BANDWIDTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) pd->qos_save_regs[2][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) QOS_SATURATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pd->qos_save_regs[3][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) QOS_EXTCONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pd->qos_save_regs[4][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void rockchip_pmu_init_qos(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!pd->is_qos_need_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) for (i = 0; i < pd->num_qos; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (pd->qos_is_need_init[0][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) QOS_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pd->qos_save_regs[0][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (pd->qos_is_need_init[1][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) QOS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pd->qos_save_regs[1][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (pd->qos_is_need_init[2][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) QOS_BANDWIDTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) pd->qos_save_regs[2][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (pd->qos_is_need_init[3][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) QOS_SATURATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) pd->qos_save_regs[3][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (pd->qos_is_need_init[4][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) regmap_write(pd->qos_regmap[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) QOS_EXTCONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pd->qos_save_regs[4][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) kfree(pd->qos_is_need_init[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) pd->qos_is_need_init[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pd->is_qos_need_init = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int rockchip_save_qos(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (IS_ERR_OR_NULL(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (IS_ERR_OR_NULL(dev->pm_domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) genpd = pd_to_genpd(dev->pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) rockchip_pmu_lock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = rockchip_pmu_save_qos(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) EXPORT_SYMBOL(rockchip_save_qos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int rockchip_restore_qos(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (IS_ERR_OR_NULL(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (IS_ERR_OR_NULL(dev->pm_domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) genpd = pd_to_genpd(dev->pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) rockchip_pmu_lock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ret = rockchip_pmu_restore_qos(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) EXPORT_SYMBOL(rockchip_restore_qos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static bool rockchip_pmu_domain_is_mem_on(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) regmap_read(pmu->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) pmu->info->mem_status_offset + pd->info->mem_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* 1'b0: power on, 1'b1: power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return !(val & pd->info->mem_status_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static bool rockchip_pmu_domain_is_chain_on(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) regmap_read(pmu->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) pmu->info->chain_status_offset + pd->info->mem_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* 1'b1: power on, 1'b0: power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return val & pd->info->mem_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static int rockchip_pmu_domain_mem_reset(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct generic_pm_domain *genpd = &pd->genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) bool is_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_chain_on, pd, is_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) is_on == true, 0, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) "failed to get chain status '%s', target_on=1, val=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) genpd->name, is_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) udelay(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) regmap_write(pmu->regmap, pmu->info->mem_pwr_offset + pd->info->pwr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) (pd->info->pwr_mask | pd->info->pwr_w_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) dsb(sy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_mem_on, pd, is_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) is_on == false, 0, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) "failed to get mem status '%s', target_on=0, val=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) genpd->name, is_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) regmap_write(pmu->regmap, pmu->info->mem_pwr_offset + pd->info->pwr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) pd->info->pwr_w_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dsb(sy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_mem_on, pd, is_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) is_on == true, 0, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) "failed to get mem status '%s', target_on=1, val=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) genpd->name, is_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (pd->info->repair_status_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) regmap_read(pmu->regmap, pmu->info->repair_status_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* 1'b1: power on, 1'b0: power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return val & pd->info->repair_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* check idle status for idle-only domains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (pd->info->status_mask == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return !rockchip_pmu_domain_is_idle(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) regmap_read(pmu->regmap, pmu->info->status_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* 1'b0: power on, 1'b1: power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return !(val & pd->info->status_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct generic_pm_domain *genpd = &pd->genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) u32 pd_pwr_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) bool is_on, is_mem_on = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (pd->info->pwr_mask == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (on && pd->info->mem_status_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) is_mem_on = rockchip_pmu_domain_is_mem_on(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (pd->info->pwr_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) pd_pwr_offset = pd->info->pwr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (pd->info->pwr_w_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) on ? pd->info->pwr_w_mask :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) (pd->info->pwr_mask | pd->info->pwr_w_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) regmap_update_bits(pmu->regmap, pmu->info->pwr_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pd_pwr_offset, pd->info->pwr_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) on ? 0 : -1U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dsb(sy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (is_mem_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = rockchip_pmu_domain_mem_reset(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) is_on == on, 0, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) "failed to set domain '%s', target_on= %d, val=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) genpd->name, on, is_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) panic("panic_on_set_domain set ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct rockchip_pmu *pmu = pd->pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct generic_pm_domain *genpd = &pd->genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (pm_domain_always_on && !power_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!power_on && soc_is_px30s()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (genpd->name && !strcmp(genpd->name, "gpu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) rockchip_pmu_lock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (rockchip_pmu_domain_is_on(pd) != power_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (IS_ERR_OR_NULL(pd->supply) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) PTR_ERR(pd->supply) != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pd->supply = devm_regulator_get_optional(pd->pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) genpd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (power_on && !IS_ERR(pd->supply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ret = regulator_enable(pd->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dev_err(pd->pmu->dev, "failed to set vdd supply enable '%s',\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) genpd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) ret = clk_bulk_enable(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dev_err(pmu->dev, "failed to enable clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (!power_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) rockchip_pmu_save_qos(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) pd->is_qos_saved = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /* if powering down, idle request to NIU first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ret = rockchip_pmu_set_idle_request(pd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dev_err(pd->pmu->dev, "failed to set idle request '%s',\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) genpd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = rockchip_do_pmu_set_power_domain(pd, power_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dev_err(pd->pmu->dev, "failed to set power '%s' = %d,\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) genpd->name, power_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (power_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* if powering up, leave idle mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = rockchip_pmu_set_idle_request(pd, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dev_err(pd->pmu->dev, "failed to set deidle request '%s',\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) genpd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (pd->is_qos_saved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) rockchip_pmu_restore_qos(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (pd->is_qos_need_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) rockchip_pmu_init_qos(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) clk_bulk_disable(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (!power_on && !IS_ERR(pd->supply))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ret = regulator_disable(pd->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static int rockchip_pd_power_on(struct generic_pm_domain *domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (pd->is_ignore_pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return rockchip_pd_power(pd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static int rockchip_pd_power_off(struct generic_pm_domain *domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (pd->is_ignore_pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return rockchip_pd_power(pd, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int rockchip_pmu_pd_on(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (IS_ERR_OR_NULL(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (IS_ERR_OR_NULL(dev->pm_domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) genpd = pd_to_genpd(dev->pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return rockchip_pd_power(pd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) EXPORT_SYMBOL(rockchip_pmu_pd_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int rockchip_pmu_pd_off(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (IS_ERR_OR_NULL(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (IS_ERR_OR_NULL(dev->pm_domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) genpd = pd_to_genpd(dev->pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return rockchip_pd_power(pd, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) EXPORT_SYMBOL(rockchip_pmu_pd_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) bool rockchip_pmu_pd_is_on(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) bool is_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (IS_ERR_OR_NULL(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (IS_ERR_OR_NULL(dev->pm_domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) genpd = pd_to_genpd(dev->pm_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) rockchip_pmu_lock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) is_on = rockchip_pmu_domain_is_on(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return is_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) EXPORT_SYMBOL(rockchip_pmu_pd_is_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) error = pm_clk_create(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dev_err(dev, "pm_clk_create failed %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) error = pm_clk_add_clk(dev, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dev_err(dev, "pm_clk_add_clk failed %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) clk_put(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pm_clk_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) pm_clk_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static void rockchip_pd_qos_init(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int is_pd_on, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!pd->is_qos_need_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) kfree(pd->qos_is_need_init[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) pd->qos_is_need_init[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) is_pd_on = rockchip_pmu_domain_is_on(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (is_pd_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ret = clk_bulk_enable(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) dev_err(pd->pmu->dev, "failed to enable clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) rockchip_pmu_init_qos(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) clk_bulk_disable(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static int rockchip_pd_add_alwasy_on_flag(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (pd->genpd.flags & GENPD_FLAG_ALWAYS_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (!rockchip_pmu_domain_is_on(pd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) error = rockchip_pd_power(pd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) dev_err(pd->pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) "failed to power on domain '%s': %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) pd->genpd.name, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) const struct rockchip_domain_info *pd_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct device_node *qos_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) int num_qos = 0, num_qos_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) u32 id, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) error = of_property_read_u32(node, "reg", &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) "%pOFn: failed to retrieve domain id (reg): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) node, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (id >= pmu->info->num_domains) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) dev_err(pmu->dev, "%pOFn: invalid domain id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) node, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (pmu->genpd_data.domains[id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) pd_info = &pmu->info->domain_info[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!pd_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_err(pmu->dev, "%pOFn: undefined domain id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) node, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (!pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) pd->info = pd_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) pd->pmu = pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (!pd_info->pwr_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) pd->is_ignore_pwr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) pd->num_clks = of_clk_get_parent_count(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (pd->num_clks > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) sizeof(*pd->clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!pd->clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) dev_dbg(pmu->dev, "%pOFn: doesn't have clocks: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) node, pd->num_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) pd->num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) for (i = 0; i < pd->num_clks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) pd->clks[i].clk = of_clk_get(node, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (IS_ERR(pd->clks[i].clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) error = PTR_ERR(pd->clks[i].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) "%pOFn: failed to get clk at index %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) node, i, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) error = clk_bulk_prepare(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) goto err_put_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) num_qos = of_count_phandle_with_args(node, "pm_qos", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) for (j = 0; j < num_qos; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) qos_node = of_parse_phandle(node, "pm_qos", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (qos_node && of_device_is_available(qos_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pd->num_qos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) of_node_put(qos_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (pd->num_qos > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) sizeof(*pd->qos_regmap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (!pd->qos_regmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) pd->qos_save_regs[0] = (u32 *)devm_kmalloc(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) sizeof(u32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) MAX_QOS_REGS_NUM *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) pd->num_qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!pd->qos_save_regs[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) pd->qos_is_need_init[0] = kzalloc(sizeof(bool) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) MAX_QOS_REGS_NUM *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) pd->num_qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (!pd->qos_is_need_init[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) for (i = 1; i < MAX_QOS_REGS_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) pd->qos_save_regs[i] = pd->qos_save_regs[i - 1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) num_qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pd->qos_is_need_init[i] = pd->qos_is_need_init[i - 1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) num_qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) for (j = 0; j < num_qos; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) qos_node = of_parse_phandle(node, "pm_qos", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!qos_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (of_device_is_available(qos_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) pd->qos_regmap[num_qos_reg] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) syscon_node_to_regmap(qos_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (IS_ERR(pd->qos_regmap[num_qos_reg])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) of_node_put(qos_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (!of_property_read_u32(qos_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) "priority-init",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) pd->qos_save_regs[0][j] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) pd->qos_is_need_init[0][j] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) pd->is_qos_need_init = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (!of_property_read_u32(qos_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) "mode-init",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) pd->qos_save_regs[1][j] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) pd->qos_is_need_init[1][j] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) pd->is_qos_need_init = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (!of_property_read_u32(qos_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) "bandwidth-init",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) pd->qos_save_regs[2][j] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) pd->qos_is_need_init[2][j] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) pd->is_qos_need_init = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (!of_property_read_u32(qos_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) "saturation-init",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) pd->qos_save_regs[3][j] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) pd->qos_is_need_init[3][j] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) pd->is_qos_need_init = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (!of_property_read_u32(qos_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) "extcontrol-init",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) pd->qos_save_regs[4][j] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) pd->qos_is_need_init[4][j] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) pd->is_qos_need_init = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) num_qos_reg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) of_node_put(qos_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (num_qos_reg > pd->num_qos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (pd->info->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pd->genpd.name = pd->info->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) pd->genpd.name = kbasename(node->full_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) pd->genpd.power_off = rockchip_pd_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) pd->genpd.power_on = rockchip_pd_power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) pd->genpd.attach_dev = rockchip_pd_attach_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) pd->genpd.detach_dev = rockchip_pd_detach_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (pd_info->active_wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (pd_info->always_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) error = rockchip_pd_add_alwasy_on_flag(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (pd_info->keepon_startup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) error = rockchip_pd_add_alwasy_on_flag(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) goto err_unprepare_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) rockchip_pd_qos_init(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) pmu->genpd_data.domains[id] = &pd->genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) err_unprepare_clocks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) kfree(pd->qos_is_need_init[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) pd->qos_is_need_init[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) clk_bulk_unprepare(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) err_put_clocks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) clk_bulk_put(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * We're in the error cleanup already, so we only complain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * but won't emit another error on top of the original one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) ret = pm_genpd_remove(&pd->genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) pd->genpd.name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) clk_bulk_unprepare(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) clk_bulk_put(pd->num_clks, pd->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /* protect the zeroing of pm->num_clks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) rockchip_pmu_lock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) pd->num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) rockchip_pmu_unlock(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* devm will free our memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) for (i = 0; i < pmu->genpd_data.num_domains; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) genpd = pmu->genpd_data.domains[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (genpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) rockchip_pm_remove_one_domain(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* devm will free our memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) u32 domain_reg_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) /* First configure domain power down transition count ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) regmap_write(pmu->regmap, domain_reg_offset, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* ... and then power up count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) regmap_write(pmu->regmap, domain_reg_offset + 4, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct generic_pm_domain *child_domain, *parent_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct rockchip_pm_domain *child_pd, *parent_pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) for_each_child_of_node(parent, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) error = of_property_read_u32(parent, "reg", &idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) "%pOFn: failed to retrieve domain id (reg): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) parent, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) parent_domain = pmu->genpd_data.domains[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) error = rockchip_pm_add_one_domain(pmu, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev_err(pmu->dev, "failed to handle node %pOFn: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) np, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) error = of_property_read_u32(np, "reg", &idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) dev_err(pmu->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) "%pOFn: failed to retrieve domain id (reg): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) np, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) child_domain = pmu->genpd_data.domains[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) error = pm_genpd_add_subdomain(parent_domain, child_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) dev_err(pmu->dev, "%s failed to add subdomain %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) parent_domain->name, child_domain->name, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) dev_dbg(pmu->dev, "%s add subdomain: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) parent_domain->name, child_domain->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * If child_pd doesn't do idle request or power on/off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * parent_pd may fail to do power on/off, so if parent_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * need to power on/off, child_pd can't ignore to do idle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * request and power on/off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) child_pd = to_rockchip_pd(child_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) parent_pd = to_rockchip_pd(parent_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!parent_pd->is_ignore_pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) child_pd->is_ignore_pwr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) rockchip_pm_add_subdomain(pmu, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static int __init rockchip_pd_keepon_release(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) struct rockchip_pm_domain *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (!g_pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) for (i = 0; i < g_pmu->genpd_data.num_domains; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) genpd = g_pmu->genpd_data.domains[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (genpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) pd = to_rockchip_pd(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (pd->info->always_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (!pd->info->keepon_startup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) genpd->flags &= (~GENPD_FLAG_ALWAYS_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) queue_work(pm_wq, &genpd->power_off_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) late_initcall_sync(rockchip_pd_keepon_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static void __iomem *pd_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) void rockchip_dump_pmu(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (pd_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) pr_warn("PMU:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 32, 4, pd_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 0x100, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) EXPORT_SYMBOL_GPL(rockchip_dump_pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static int rockchip_pmu_panic(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) unsigned long ev, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) rockchip_dump_pmu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static struct notifier_block pmu_panic_block = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .notifier_call = rockchip_pmu_panic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static int rockchip_pm_domain_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct device *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct rockchip_pmu *pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) const struct rockchip_pmu_info *pmu_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) dev_err(dev, "device tree node not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) match = of_match_device(dev->driver->of_match_table, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (!match || !match->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) dev_err(dev, "missing pmu data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) pmu_info = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) pmu = devm_kzalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct_size(pmu, domains, pmu_info->num_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (!pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) pmu->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) mutex_init(&pmu->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) pmu->info = pmu_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) pmu->genpd_data.domains = pmu->domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) pmu->genpd_data.num_domains = pmu_info->num_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) parent = dev->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (!parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) dev_err(dev, "no parent for syscon devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) pmu->regmap = syscon_node_to_regmap(parent->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (IS_ERR(pmu->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) dev_err(dev, "no regmap available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return PTR_ERR(pmu->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) reg_base = of_iomap(parent->of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (!reg_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) dev_err(dev, "%s: could not map pmu region\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) pd_base = reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) * Configure power up and down transition delays for CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * and GPU domains.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (pmu_info->core_power_transition_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) pmu_info->core_power_transition_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (pmu_info->gpu_pwrcnt_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) pmu_info->gpu_power_transition_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) for_each_available_child_of_node(np, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) error = rockchip_pm_add_one_domain(pmu, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) dev_err(dev, "failed to handle node %pOFn: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) node, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) error = rockchip_pm_add_subdomain(pmu, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) dev_err(dev, "failed to handle subdomain node %pOFn: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) node, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) dev_dbg(dev, "no power domains defined\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) error = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) dev_err(dev, "failed to add provider: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) atomic_notifier_chain_register(&panic_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) &pmu_panic_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) g_pmu = pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) rockchip_pm_domain_cleanup(pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) static const struct rockchip_domain_info px30_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) [PX30_PD_USB] = DOMAIN_PX30("usb", BIT(5), BIT(5), BIT(10), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) [PX30_PD_SDCARD] = DOMAIN_PX30("sdcard", BIT(8), BIT(8), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) [PX30_PD_GMAC] = DOMAIN_PX30("gmac", BIT(10), BIT(10), BIT(6), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) [PX30_PD_MMC_NAND] = DOMAIN_PX30("mmc_nand", BIT(11), BIT(11), BIT(5), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) [PX30_PD_VPU] = DOMAIN_PX30("vpu", BIT(12), BIT(12), BIT(14), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) [PX30_PD_VO] = DOMAIN_PX30_PROTECT("vo", BIT(13), BIT(13), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) [PX30_PD_VI] = DOMAIN_PX30_PROTECT("vi", BIT(14), BIT(14), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) [PX30_PD_GPU] = DOMAIN_PX30("gpu", BIT(15), BIT(15), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) static const struct rockchip_domain_info rv1126_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) [RV1126_PD_CRYPTO] = DOMAIN_RV1126_O("crypto", BIT(10), BIT(4), BIT(20), 0x4, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) [RV1126_PD_VEPU] = DOMAIN_RV1126("vepu", BIT(2), BIT(9), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) [RV1126_PD_VI] = DOMAIN_RV1126("vi", BIT(4), BIT(6), BIT(6), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) [RV1126_PD_VO] = DOMAIN_RV1126_PROTECT("vo", BIT(5), BIT(7), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) [RV1126_PD_ISPP] = DOMAIN_RV1126("ispp", BIT(1), BIT(8), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) [RV1126_PD_VDPU] = DOMAIN_RV1126("vdpu", BIT(3), BIT(10), BIT(10), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) [RV1126_PD_NVM] = DOMAIN_RV1126("nvm", BIT(7), BIT(11), BIT(11), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) [RV1126_PD_SDIO] = DOMAIN_RV1126("sdio", BIT(8), BIT(13), BIT(13), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) [RV1126_PD_USB] = DOMAIN_RV1126("usb", BIT(9), BIT(15), BIT(15), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) [RV1126_PD_NPU] = DOMAIN_RV1126_O("npu", BIT(0), BIT(2), BIT(18), 0x4, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) static const struct rockchip_domain_info rk1808_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) [RK1808_VD_NPU] = DOMAIN_PX30("npu", BIT(15), BIT(15), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) [RK1808_PD_PCIE] = DOMAIN_PX30("pcie", BIT(9), BIT(9), BIT(4), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) [RK1808_PD_VPU] = DOMAIN_PX30("vpu", BIT(13), BIT(13), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) [RK1808_PD_VIO] = DOMAIN_PX30_PROTECT("vio", BIT(14), BIT(14), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static const struct rockchip_domain_info rk3036_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) [RK3036_PD_MSCH] = DOMAIN_RK3036("msch", BIT(14), BIT(23), BIT(30), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) [RK3036_PD_CORE] = DOMAIN_RK3036("core", BIT(13), BIT(17), BIT(24), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) [RK3036_PD_PERI] = DOMAIN_RK3036("peri", BIT(12), BIT(18), BIT(25), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) [RK3036_PD_VIO] = DOMAIN_RK3036("vio", BIT(11), BIT(19), BIT(26), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) [RK3036_PD_VPU] = DOMAIN_RK3036("vpu", BIT(10), BIT(20), BIT(27), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) [RK3036_PD_GPU] = DOMAIN_RK3036("gpu", BIT(9), BIT(21), BIT(28), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) [RK3036_PD_SYS] = DOMAIN_RK3036("sys", BIT(8), BIT(22), BIT(29), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) static const struct rockchip_domain_info rk3066_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) [RK3066_PD_GPU] = DOMAIN("gpu", BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) [RK3066_PD_VIDEO] = DOMAIN("video", BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) [RK3066_PD_VIO] = DOMAIN("vio", BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) [RK3066_PD_PERI] = DOMAIN("peri", BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) [RK3066_PD_CPU] = DOMAIN("cpu", 0, BIT(5), BIT(1), BIT(26), BIT(31), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static const struct rockchip_domain_info rk3128_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) [RK3128_PD_CORE] = DOMAIN_RK3288("core", BIT(0), BIT(0), BIT(4), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) [RK3128_PD_MSCH] = DOMAIN_RK3288("msch", 0, 0, BIT(6), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) [RK3128_PD_VIO] = DOMAIN_RK3288_PROTECT("vio", BIT(3), BIT(3), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) [RK3128_PD_VIDEO] = DOMAIN_RK3288("video", BIT(2), BIT(2), BIT(1), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) [RK3128_PD_GPU] = DOMAIN_RK3288("gpu", BIT(1), BIT(1), BIT(3), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) static const struct rockchip_domain_info rk3188_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) [RK3188_PD_GPU] = DOMAIN("gpu", BIT(9), BIT(9), BIT(3), BIT(24), BIT(29), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) [RK3188_PD_VIDEO] = DOMAIN("video", BIT(8), BIT(8), BIT(4), BIT(23), BIT(28), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) [RK3188_PD_VIO] = DOMAIN("vio", BIT(7), BIT(7), BIT(5), BIT(22), BIT(27), false, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) [RK3188_PD_PERI] = DOMAIN("peri", BIT(6), BIT(6), BIT(2), BIT(25), BIT(30), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) [RK3188_PD_CPU] = DOMAIN("cpu", BIT(5), BIT(5), BIT(1), BIT(26), BIT(31), false, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static const struct rockchip_domain_info rk3228_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) [RK3228_PD_CORE] = DOMAIN_RK3036("core", BIT(0), BIT(0), BIT(16), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) [RK3228_PD_MSCH] = DOMAIN_RK3036("msch", BIT(1), BIT(1), BIT(17), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) [RK3228_PD_BUS] = DOMAIN_RK3036("bus", BIT(2), BIT(2), BIT(18), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) [RK3228_PD_SYS] = DOMAIN_RK3036("sys", BIT(3), BIT(3), BIT(19), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) [RK3228_PD_VIO] = DOMAIN_RK3036("vio", BIT(4), BIT(4), BIT(20), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) [RK3228_PD_VOP] = DOMAIN_RK3036("vop", BIT(5), BIT(5), BIT(21), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) [RK3228_PD_VPU] = DOMAIN_RK3036("vpu", BIT(6), BIT(6), BIT(22), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) [RK3228_PD_RKVDEC] = DOMAIN_RK3036("vdec", BIT(7), BIT(7), BIT(23), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) [RK3228_PD_GPU] = DOMAIN_RK3036("gpu", BIT(8), BIT(8), BIT(24), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) [RK3228_PD_PERI] = DOMAIN_RK3036("peri", BIT(9), BIT(9), BIT(25), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) [RK3228_PD_GMAC] = DOMAIN_RK3036("gmac", BIT(10), BIT(10), BIT(26), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) static const struct rockchip_domain_info rk3288_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) [RK3288_PD_VIO] = DOMAIN_RK3288_PROTECT("vio", BIT(7), BIT(7), BIT(4), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) [RK3288_PD_HEVC] = DOMAIN_RK3288("hevc", BIT(14), BIT(10), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) [RK3288_PD_VIDEO] = DOMAIN_RK3288("video", BIT(8), BIT(8), BIT(3), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) [RK3288_PD_GPU] = DOMAIN_RK3288("gpu", BIT(9), BIT(9), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static const struct rockchip_domain_info rk3328_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) [RK3328_PD_CORE] = DOMAIN_RK3328("core", 0, BIT(0), BIT(0), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) [RK3328_PD_GPU] = DOMAIN_RK3328("gpu", 0, BIT(1), BIT(1), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) [RK3328_PD_BUS] = DOMAIN_RK3328("bus", 0, BIT(2), BIT(2), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) [RK3328_PD_MSCH] = DOMAIN_RK3328("msch", 0, BIT(3), BIT(3), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) [RK3328_PD_PERI] = DOMAIN_RK3328("peri", 0, BIT(4), BIT(4), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) [RK3328_PD_VIDEO] = DOMAIN_RK3328("video", 0, BIT(5), BIT(5), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) [RK3328_PD_HEVC] = DOMAIN_RK3328("hevc", 0, BIT(6), BIT(6), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) [RK3328_PD_VIO] = DOMAIN_RK3328("vio", 0, BIT(8), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) [RK3328_PD_VPU] = DOMAIN_RK3328("vpu", 0, BIT(9), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static const struct rockchip_domain_info rk3366_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) [RK3366_PD_PERI] = DOMAIN_RK3368("peri", BIT(10), BIT(10), BIT(6), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) [RK3366_PD_VIO] = DOMAIN_RK3368_PROTECT("vio", BIT(14), BIT(14), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) [RK3366_PD_VIDEO] = DOMAIN_RK3368("video", BIT(13), BIT(13), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) [RK3366_PD_RKVDEC] = DOMAIN_RK3368("rkvdec", BIT(11), BIT(11), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) [RK3366_PD_WIFIBT] = DOMAIN_RK3368("wifibt", BIT(8), BIT(8), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) [RK3366_PD_VPU] = DOMAIN_RK3368("vpu", BIT(12), BIT(12), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) [RK3366_PD_GPU] = DOMAIN_RK3368("gpu", BIT(15), BIT(15), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) static const struct rockchip_domain_info rk3368_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) [RK3368_PD_PERI] = DOMAIN_RK3368("peri", BIT(13), BIT(12), BIT(6), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) [RK3368_PD_VIO] = DOMAIN_RK3368_PROTECT("vio", BIT(15), BIT(14), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) [RK3368_PD_VIDEO] = DOMAIN_RK3368("video", BIT(14), BIT(13), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) [RK3368_PD_GPU_0] = DOMAIN_RK3368("gpu_0", BIT(16), BIT(15), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) [RK3368_PD_GPU_1] = DOMAIN_RK3368("gpu_1", BIT(17), BIT(16), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static const struct rockchip_domain_info rk3399_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) [RK3399_PD_TCPD0] = DOMAIN_RK3399("tcpd0", BIT(8), BIT(8), 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) [RK3399_PD_TCPD1] = DOMAIN_RK3399("tcpd1", BIT(9), BIT(9), 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) [RK3399_PD_CCI] = DOMAIN_RK3399("cci", BIT(10), BIT(10), 0, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) [RK3399_PD_CCI0] = DOMAIN_RK3399("cci0", 0, 0, BIT(15), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) [RK3399_PD_CCI1] = DOMAIN_RK3399("cci1", 0, 0, BIT(16), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) [RK3399_PD_PERILP] = DOMAIN_RK3399("perilp", BIT(11), BIT(11), BIT(1), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) [RK3399_PD_PERIHP] = DOMAIN_RK3399("perihp", BIT(12), BIT(12), BIT(2), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) [RK3399_PD_CENTER] = DOMAIN_RK3399("center", BIT(13), BIT(13), BIT(14), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) [RK3399_PD_VIO] = DOMAIN_RK3399_PROTECT("vio", BIT(14), BIT(14), BIT(17), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) [RK3399_PD_GPU] = DOMAIN_RK3399("gpu", BIT(15), BIT(15), BIT(0), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) [RK3399_PD_VCODEC] = DOMAIN_RK3399("vcodec", BIT(16), BIT(16), BIT(3), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) [RK3399_PD_VDU] = DOMAIN_RK3399("vdu", BIT(17), BIT(17), BIT(4), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) [RK3399_PD_RGA] = DOMAIN_RK3399("rga", BIT(18), BIT(18), BIT(5), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) [RK3399_PD_IEP] = DOMAIN_RK3399("iep", BIT(19), BIT(19), BIT(6), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) [RK3399_PD_VO] = DOMAIN_RK3399_PROTECT("vo", BIT(20), BIT(20), 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) [RK3399_PD_VOPB] = DOMAIN_RK3399_PROTECT("vopb", 0, 0, BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) [RK3399_PD_VOPL] = DOMAIN_RK3399_PROTECT("vopl", 0, 0, BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) [RK3399_PD_ISP0] = DOMAIN_RK3399("isp0", BIT(22), BIT(22), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) [RK3399_PD_ISP1] = DOMAIN_RK3399("isp1", BIT(23), BIT(23), BIT(10), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) [RK3399_PD_HDCP] = DOMAIN_RK3399_PROTECT("hdcp", BIT(24), BIT(24), BIT(11), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) [RK3399_PD_GMAC] = DOMAIN_RK3399("gmac", BIT(25), BIT(25), BIT(23), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) [RK3399_PD_EMMC] = DOMAIN_RK3399("emmc", BIT(26), BIT(26), BIT(24), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) [RK3399_PD_USB3] = DOMAIN_RK3399("usb3", BIT(27), BIT(27), BIT(12), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) [RK3399_PD_EDP] = DOMAIN_RK3399_PROTECT("edp", BIT(28), BIT(28), BIT(22), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) [RK3399_PD_GIC] = DOMAIN_RK3399("gic", BIT(29), BIT(29), BIT(27), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) [RK3399_PD_SD] = DOMAIN_RK3399("sd", BIT(30), BIT(30), BIT(28), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399("sdioaudio", BIT(31), BIT(31), BIT(29), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static const struct rockchip_domain_info rk3568_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) [RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) [RK3568_PD_VI] = DOMAIN_RK3568("vi", BIT(6), BIT(3), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) [RK3568_PD_VO] = DOMAIN_RK3568_PROTECT("vo", BIT(7), BIT(4), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) [RK3568_PD_RGA] = DOMAIN_RK3568("rga", BIT(5), BIT(5), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) [RK3568_PD_VPU] = DOMAIN_RK3568("vpu", BIT(2), BIT(6), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) [RK3568_PD_RKVDEC] = DOMAIN_RK3568("rkvdec", BIT(4), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) [RK3568_PD_RKVENC] = DOMAIN_RK3568("rkvenc", BIT(3), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) static const struct rockchip_domain_info rk3588_pm_domains[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) /* name p_offset pwr status m_offset m_status r_status r_offset req idle wakeup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, 0x0, 0, BIT(1), 0x0, BIT(0), BIT(0), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0x0, 0, 0, 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0x0, 0, 0, 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, 0x0, BIT(11), BIT(2), 0x0, BIT(1), BIT(1), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, 0x0, BIT(12), BIT(3), 0x0, BIT(2), BIT(2), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, 0x0, BIT(13), BIT(4), 0x0, BIT(3), BIT(3), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, BIT(6), 0, 0x0, BIT(14), BIT(5), 0x0, BIT(4), BIT(4), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, BIT(7), 0, 0x0, BIT(15), BIT(6), 0x0, BIT(5), BIT(5), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, BIT(8), 0, 0x0, BIT(16), BIT(7), 0x0, BIT(6), BIT(6), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, BIT(9), 0, 0x0, BIT(17), BIT(8), 0x0, BIT(7), BIT(7), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, BIT(10), 0, 0x0, BIT(18), BIT(9), 0x0, BIT(8), BIT(8), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, BIT(11), 0, 0x0, BIT(19), BIT(10), 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, BIT(12), 0, 0x0, BIT(20), BIT(11), 0x0, BIT(9), BIT(9), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, BIT(13), 0, 0x0, BIT(21), BIT(12), 0x0, BIT(10), BIT(10), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, BIT(14), 0, 0x0, BIT(22), BIT(13), 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, BIT(15), 0, 0x0, BIT(23), BIT(14), 0x0, BIT(11), BIT(11), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, BIT(0), 0, 0x0, BIT(24), BIT(15), 0x0, BIT(12), BIT(12), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) [RK3588_PD_VOP] = DOMAIN_RK3588_P("vop", 0x4, BIT(1), 0, 0x0, BIT(25), BIT(16), 0x0, BIT(13) | BIT(14), BIT(13) | BIT(14), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) [RK3588_PD_VO0] = DOMAIN_RK3588_P("vo0", 0x4, BIT(2), 0, 0x0, BIT(26), BIT(17), 0x0, BIT(15), BIT(15), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) [RK3588_PD_VO1] = DOMAIN_RK3588_P("vo1", 0x4, BIT(3), 0, 0x0, BIT(27), BIT(18), 0x4, BIT(0), BIT(16), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, BIT(4), 0, 0x0, BIT(28), BIT(19), 0x4, BIT(1), BIT(17), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, BIT(5), 0, 0x0, BIT(29), BIT(20), 0x4, BIT(5), BIT(21), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, BIT(6), 0, 0x0, BIT(30), BIT(21), 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, BIT(7), 0, 0x0, BIT(31), BIT(22), 0x0, 0, 0, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, BIT(8), BIT(24), 0x4, 0, 0, 0x4, BIT(2), BIT(18), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, BIT(9), 0, 0x4, BIT(1), BIT(23), 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, BIT(10), 0, 0x4, BIT(2), BIT(24), 0x4, BIT(3), BIT(19), false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, BIT(11), 0, 0x4, BIT(3), BIT(25), 0x4, BIT(4), BIT(20), true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, BIT(13), 0, 0x4, BIT(5), BIT(26), 0x0, 0, 0, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) static const struct rockchip_pmu_info px30_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) .pwr_offset = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) .status_offset = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .req_offset = 0x64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) .idle_offset = 0x6c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) .ack_offset = 0x6c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) .num_domains = ARRAY_SIZE(px30_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .domain_info = px30_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static const struct rockchip_pmu_info rv1126_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .pwr_offset = 0x110,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) .status_offset = 0x108,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) .req_offset = 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) .idle_offset = 0xd8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .ack_offset = 0xd0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) .num_domains = ARRAY_SIZE(rv1126_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) .domain_info = rv1126_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) static const struct rockchip_pmu_info rk1808_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .pwr_offset = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .status_offset = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) .req_offset = 0x64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .idle_offset = 0x6c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) .ack_offset = 0x6c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .num_domains = ARRAY_SIZE(rk1808_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .domain_info = rk1808_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static const struct rockchip_pmu_info rk3036_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) .req_offset = 0x148,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) .idle_offset = 0x14c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) .ack_offset = 0x14c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) .num_domains = ARRAY_SIZE(rk3036_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) .domain_info = rk3036_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) static const struct rockchip_pmu_info rk3066_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) .pwr_offset = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) .status_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) .req_offset = 0x38, /* PMU_MISC_CON1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) .idle_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) .ack_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .num_domains = ARRAY_SIZE(rk3066_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .domain_info = rk3066_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static const struct rockchip_pmu_info rk3128_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) .pwr_offset = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .status_offset = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .req_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .idle_offset = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .ack_offset = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .num_domains = ARRAY_SIZE(rk3128_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) .domain_info = rk3128_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) static const struct rockchip_pmu_info rk3188_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .pwr_offset = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .status_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .req_offset = 0x38, /* PMU_MISC_CON1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .idle_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .ack_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) .num_domains = ARRAY_SIZE(rk3188_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .domain_info = rk3188_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static const struct rockchip_pmu_info rk3228_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) .req_offset = 0x40c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) .idle_offset = 0x488,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) .ack_offset = 0x488,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) .num_domains = ARRAY_SIZE(rk3228_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) .domain_info = rk3228_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) static const struct rockchip_pmu_info rk3288_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) .pwr_offset = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) .status_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) .req_offset = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) .idle_offset = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .ack_offset = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .core_pwrcnt_offset = 0x34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .gpu_pwrcnt_offset = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) .core_power_transition_time = 24, /* 1us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) .gpu_power_transition_time = 24, /* 1us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) .num_domains = ARRAY_SIZE(rk3288_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) .domain_info = rk3288_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) static const struct rockchip_pmu_info rk3328_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) .req_offset = 0x414,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .idle_offset = 0x484,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) .ack_offset = 0x484,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .num_domains = ARRAY_SIZE(rk3328_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .domain_info = rk3328_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) static const struct rockchip_pmu_info rk3366_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) .pwr_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) .status_offset = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .req_offset = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .idle_offset = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) .ack_offset = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .core_pwrcnt_offset = 0x48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) .gpu_pwrcnt_offset = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) .core_power_transition_time = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) .gpu_power_transition_time = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) .num_domains = ARRAY_SIZE(rk3366_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) .domain_info = rk3366_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) static const struct rockchip_pmu_info rk3368_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) .pwr_offset = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) .status_offset = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) .req_offset = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) .idle_offset = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) .ack_offset = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) .core_pwrcnt_offset = 0x48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) .gpu_pwrcnt_offset = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) .core_power_transition_time = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) .gpu_power_transition_time = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) .num_domains = ARRAY_SIZE(rk3368_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) .domain_info = rk3368_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) static const struct rockchip_pmu_info rk3399_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) .pwr_offset = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) .status_offset = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) .req_offset = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) .idle_offset = 0x64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) .ack_offset = 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) /* ARM Trusted Firmware manages power transition times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) .num_domains = ARRAY_SIZE(rk3399_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) .domain_info = rk3399_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) static const struct rockchip_pmu_info rk3568_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) .pwr_offset = 0xa0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) .status_offset = 0x98,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) .req_offset = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) .idle_offset = 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) .ack_offset = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) .num_domains = ARRAY_SIZE(rk3568_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) .domain_info = rk3568_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) static const struct rockchip_pmu_info rk3588_pmu = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) .pwr_offset = 0x14c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) .status_offset = 0x180,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) .req_offset = 0x10c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) .idle_offset = 0x120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) .ack_offset = 0x118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) .mem_pwr_offset = 0x1a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) .chain_status_offset = 0x1f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) .mem_status_offset = 0x1f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) .repair_status_offset = 0x290,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) .num_domains = ARRAY_SIZE(rk3588_pm_domains),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) .domain_info = rk3588_pm_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) static const struct of_device_id rockchip_pm_domain_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) .compatible = "rockchip,px30-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) .data = (void *)&px30_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .compatible = "rockchip,rv1126-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) .data = (void *)&rv1126_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) .compatible = "rockchip,rk1808-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) .data = (void *)&rk1808_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) .compatible = "rockchip,rk3036-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) .data = (void *)&rk3036_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) .compatible = "rockchip,rk3066-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) .data = (void *)&rk3066_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) .compatible = "rockchip,rk3128-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) .data = (void *)&rk3128_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) .compatible = "rockchip,rk3188-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .data = (void *)&rk3188_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .compatible = "rockchip,rk3228-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .data = (void *)&rk3228_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) .compatible = "rockchip,rk3288-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) .data = (void *)&rk3288_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) .compatible = "rockchip,rk3328-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) .data = (void *)&rk3328_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .compatible = "rockchip,rk3366-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .data = (void *)&rk3366_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .compatible = "rockchip,rk3368-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) .data = (void *)&rk3368_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) .compatible = "rockchip,rk3399-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) .data = (void *)&rk3399_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) .compatible = "rockchip,rk3568-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) .data = (void *)&rk3568_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) .compatible = "rockchip,rk3588-power-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) .data = (void *)&rk3588_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) MODULE_DEVICE_TABLE(of, rockchip_pm_domain_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) static struct platform_driver rockchip_pm_domain_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) .probe = rockchip_pm_domain_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) .name = "rockchip-pm-domain",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) .of_match_table = rockchip_pm_domain_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) * We can't forcibly eject devices form power domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) * so we can't really remove power domains once they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) * were added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) static int __init rockchip_pm_domain_drv_register(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) return platform_driver_register(&rockchip_pm_domain_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) postcore_initcall(rockchip_pm_domain_drv_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) static void __exit rockchip_pm_domain_drv_unregister(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) platform_driver_unregister(&rockchip_pm_domain_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) module_exit(rockchip_pm_domain_drv_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) MODULE_DESCRIPTION("ROCKCHIP PM Domain Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) MODULE_LICENSE("GPL");