Re: [PATCH v2 07/34] media: iris: initialize power resources

From: Konrad Dybcio
Date: Mon Dec 18 2023 - 10:09:29 EST


On 18.12.2023 12:32, Dikshita Agarwal wrote:
> Add support for initializing Iris "resources", which are clocks,
> interconnects, power domains, reset clocks, and clock frequencies
> used for Iris hardware.
>
> Signed-off-by: Dikshita Agarwal <quic_dikshita@xxxxxxxxxxx>
> ---
[...]

> + ret = init_resources(core);
> + if (ret) {
> + dev_err_probe(core->dev, ret,
> + "%s: init resource failed with %d\n", __func__, ret);
> + return ret;
You're supposed to return dev_err_probe, it propagates the errors
this way

Also, I think __func__ is excessive, throughout the code. You can
very quickly grep for the error messages, which are quite unique.

[...]

> +
> +static const struct bus_info plat_bus_table[] = {
> + { NULL, "iris-cnoc", 1000, 1000 },
> + { NULL, "iris-ddr", 1000, 15000000 },
> +};
> +
> +static const char * const plat_pd_table[] = { "iris-ctl", "vcodec", NULL };
> +#define PD_COUNT 2
> +
> +static const char * const plat_opp_pd_table[] = { "mxc", "mmcx", NULL };
> +#define OPP_PD_COUNT 2
> +
> +static const struct clock_info plat_clk_table[] = {
> + { NULL, "gcc_video_axi0", GCC_VIDEO_AXI0_CLK, 0, 0 },
> + { NULL, "core_clk", VIDEO_CC_MVS0C_CLK, 0, 0 },
> + { NULL, "vcodec_core", VIDEO_CC_MVS0_CLK, 1, 0 },
> +};
> +
> +static const char * const plat_clk_reset_table[] = { "video_axi_reset", NULL };
> +#define RESET_COUNT 1
Are you sure this won't change between platforms?
[...]

> +static int init_bus(struct iris_core *core)
> +{
> + struct bus_info *binfo = NULL;
> + u32 i = 0;
no need to initialize

[...]

> +static int init_clocks(struct iris_core *core)
> +{
> + struct clock_info *cinfo = NULL;
> + u32 i;
> +
> + core->clk_count = ARRAY_SIZE(plat_clk_table);
> + core->clock_tbl = devm_kzalloc(core->dev,
> + sizeof(struct clock_info) * core->clk_count,
> + GFP_KERNEL);
> + if (!core->clock_tbl)
> + return -ENOMEM;
> +
> + for (i = 0; i < core->clk_count; i++) {
> + cinfo = &core->clock_tbl[i];
> + cinfo->name = plat_clk_table[i].name;
> + cinfo->clk_id = plat_clk_table[i].clk_id;
> + cinfo->has_scaling = plat_clk_table[i].has_scaling;
> + cinfo->clk = devm_clk_get(core->dev, cinfo->name);
> + if (IS_ERR(cinfo->clk)) {
> + dev_err(core->dev,
> + "%s: failed to get clock: %s\n", __func__, cinfo->name);
> + return PTR_ERR(cinfo->clk);
> + }
> + }
Are you not going to use OPP for scaling the main RPMhPD with the core
clock?

> +
> + return 0;
> +}
> +
> +static int init_reset_clocks(struct iris_core *core)
init_resets

'reset clocks' is an old downstream concept

> +{
> + struct reset_info *rinfo = NULL;
> + u32 i = 0;
unnecessary initializations

[...]

> +
> +int init_resources(struct iris_core *core)
> +{
> + int ret;
> +
> + ret = init_bus(core);
> + if (ret)
> + return ret;
> +
> + ret = init_power_domains(core);
> + if (ret)
> + return ret;
> +
> + ret = init_clocks(core);
> + if (ret)
> + return ret;
> +
> + ret = init_reset_clocks(core);
> +
> + return ret;
return init_reset_clocks(core);

> +}
> diff --git a/drivers/media/platform/qcom/vcodec/iris/resources.h b/drivers/media/platform/qcom/vcodec/iris/resources.h
> new file mode 100644
> index 0000000..d21bcc7e
> --- /dev/null
> +++ b/drivers/media/platform/qcom/vcodec/iris/resources.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef _RESOURCES_H_
> +#define _RESOURCES_H_
> +
> +struct bus_info {
> + struct icc_path *icc;
> + const char *name;
> + u32 bw_min_kbps;
> + u32 bw_max_kbps;
u64?

> +};
> +
> +struct power_domain_info {
> + struct device *genpd_dev;
> + const char *name;
> +};
> +
> +struct clock_info {
> + struct clk *clk;
> + const char *name;
I'm not sure why you need it

> + u32 clk_id;
Or this

> + bool has_scaling;
Or this

you could probably do something like this:

struct big_iris_struct {
[...]
struct clk *core_clk;
struct clk *memory_clk;
struct clk *some_important_scaled_clock;
struct clk_bulk_data less_important_nonscaling_clocks[X]
}

and then make use of all of the great common upstream APIs to manage
them!

> + u64 prev;
> +};
> +
> +struct reset_info {
> + struct reset_control *rst;
> + const char *name;
this seems a bit excessive as well

Konrad