media: venus: pm_helpers: use opp-table for the frequency

Some platforms (such as qcs615 and sc7180) use the same core but have
different frequency tables. Using the opp-table allows us to separate
the core description from the frequency data and supports the use of
fallback compatibles.

Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Renjiang Han <quic_renjiang@quicinc.com>
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
Renjiang Han 2025-06-12 07:53:51 +05:30 committed by Hans Verkuil
parent c056064a20
commit b179234b5e

View File

@ -41,16 +41,14 @@ static int core_clks_get(struct venus_core *core)
static int core_clks_enable(struct venus_core *core) static int core_clks_enable(struct venus_core *core)
{ {
const struct venus_resources *res = core->res; const struct venus_resources *res = core->res;
const struct freq_tbl *freq_tbl = core->res->freq_tbl; struct device *dev = core->dev;
unsigned int freq_tbl_size = core->res->freq_tbl_size; unsigned long freq = 0;
unsigned long freq; struct dev_pm_opp *opp;
unsigned int i; unsigned int i;
int ret; int ret;
if (!freq_tbl) opp = dev_pm_opp_find_freq_ceil(dev, &freq);
return -EINVAL; dev_pm_opp_put(opp);
freq = freq_tbl[freq_tbl_size - 1].freq;
for (i = 0; i < res->clks_num; i++) { for (i = 0; i < res->clks_num; i++) {
if (IS_V6(core)) { if (IS_V6(core)) {
@ -636,7 +634,9 @@ static int decide_core(struct venus_inst *inst)
u32 min_coreid, min_load, cur_inst_load; u32 min_coreid, min_load, cur_inst_load;
u32 min_lp_coreid, min_lp_load, cur_inst_lp_load; u32 min_lp_coreid, min_lp_load, cur_inst_lp_load;
struct hfi_videocores_usage_type cu; struct hfi_videocores_usage_type cu;
unsigned long max_freq; unsigned long max_freq = ULONG_MAX;
struct device *dev = core->dev;
struct dev_pm_opp *opp;
int ret = 0; int ret = 0;
if (legacy_binding) { if (legacy_binding) {
@ -659,7 +659,8 @@ static int decide_core(struct venus_inst *inst)
cur_inst_lp_load *= inst->clk_data.low_power_freq; cur_inst_lp_load *= inst->clk_data.low_power_freq;
/*TODO : divide this inst->load by work_route */ /*TODO : divide this inst->load by work_route */
max_freq = core->res->freq_tbl[0].freq; opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
dev_pm_opp_put(opp);
min_loaded_core(inst, &min_coreid, &min_load, false); min_loaded_core(inst, &min_coreid, &min_load, false);
min_loaded_core(inst, &min_lp_coreid, &min_lp_load, true); min_loaded_core(inst, &min_lp_coreid, &min_lp_load, true);
@ -949,7 +950,10 @@ static int core_resets_get(struct venus_core *core)
static int core_get_v4(struct venus_core *core) static int core_get_v4(struct venus_core *core)
{ {
struct device *dev = core->dev; struct device *dev = core->dev;
const struct freq_tbl *freq_tbl = core->res->freq_tbl;
unsigned int num_rows = core->res->freq_tbl_size;
const struct venus_resources *res = core->res; const struct venus_resources *res = core->res;
unsigned int i;
int ret; int ret;
ret = core_clks_get(core); ret = core_clks_get(core);
@ -986,9 +990,17 @@ static int core_get_v4(struct venus_core *core)
if (core->res->opp_pmdomain) { if (core->res->opp_pmdomain) {
ret = devm_pm_opp_of_add_table(dev); ret = devm_pm_opp_of_add_table(dev);
if (ret && ret != -ENODEV) { if (ret) {
dev_err(dev, "invalid OPP table in device tree\n"); if (ret == -ENODEV) {
return ret; for (i = 0; i < num_rows; i++) {
ret = dev_pm_opp_add(dev, freq_tbl[i].freq, 0);
if (ret)
return ret;
}
} else {
dev_err(dev, "invalid OPP table in device tree\n");
return ret;
}
} }
} }
@ -1078,11 +1090,11 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst,
static int load_scale_v4(struct venus_inst *inst) static int load_scale_v4(struct venus_inst *inst)
{ {
struct venus_core *core = inst->core; struct venus_core *core = inst->core;
const struct freq_tbl *table = core->res->freq_tbl;
unsigned int num_rows = core->res->freq_tbl_size;
struct device *dev = core->dev; struct device *dev = core->dev;
unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0; unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
unsigned long max_freq = ULONG_MAX;
unsigned long filled_len = 0; unsigned long filled_len = 0;
struct dev_pm_opp *opp;
int i, ret = 0; int i, ret = 0;
for (i = 0; i < inst->num_input_bufs; i++) for (i = 0; i < inst->num_input_bufs; i++)
@ -1108,20 +1120,18 @@ static int load_scale_v4(struct venus_inst *inst)
freq = max(freq_core1, freq_core2); freq = max(freq_core1, freq_core2);
if (freq > table[0].freq) { opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
dev_dbg(dev, VDBGL "requested clock rate: %lu scaling clock rate : %lu\n", dev_pm_opp_put(opp);
freq, table[0].freq);
freq = table[0].freq; if (freq > max_freq) {
dev_dbg(dev, VDBGL "requested clock rate: %lu scaling clock rate : %lu\n",
freq, max_freq);
freq = max_freq;
goto set_freq; goto set_freq;
} }
for (i = num_rows - 1 ; i >= 0; i--) { opp = dev_pm_opp_find_freq_ceil(dev, &freq);
if (freq <= table[i].freq) { dev_pm_opp_put(opp);
freq = table[i].freq;
break;
}
}
set_freq: set_freq: