OSDN Git Service

media: venus: Create hfi platform and move vpp/vsp there
authorStanimir Varbanov <stanimir.varbanov@linaro.org>
Wed, 5 Aug 2020 07:36:06 +0000 (09:36 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Wed, 13 Jan 2021 08:11:34 +0000 (09:11 +0100)
Introduce a new hfi platform to cover differences between hfi
versions. As a start move vpp/vsp freq data in that hfi
platform, more platform data will come later.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/qcom/venus/Makefile
drivers/media/platform/qcom/venus/core.c
drivers/media/platform/qcom/venus/core.h
drivers/media/platform/qcom/venus/helpers.c
drivers/media/platform/qcom/venus/helpers.h
drivers/media/platform/qcom/venus/hfi_platform.c [new file with mode: 0644]
drivers/media/platform/qcom/venus/hfi_platform.h [new file with mode: 0644]
drivers/media/platform/qcom/venus/hfi_platform_v4.c [new file with mode: 0644]
drivers/media/platform/qcom/venus/pm_helpers.c
drivers/media/platform/qcom/venus/vdec.c
drivers/media/platform/qcom/venus/venc.c

index dfc6368..09ebf46 100644 (file)
@@ -3,7 +3,8 @@
 
 venus-core-objs += core.o helpers.o firmware.o \
                   hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
-                  hfi_parser.o pm_helpers.o dbgfs.o
+                  hfi_parser.o pm_helpers.o dbgfs.o \
+                  hfi_platform.o hfi_platform_v4.o \
 
 venus-dec-objs += vdec.o vdec_ctrls.o
 venus-enc-objs += venc.o venc_ctrls.o
index bdd293f..6bcd565 100644 (file)
@@ -486,17 +486,6 @@ static const struct freq_tbl sdm845_freq_table[] = {
        {  244800, 100000000 }, /* 1920x1080@30 */
 };
 
-static const struct codec_freq_data sdm845_codec_freq_data[] =  {
-       { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
-       { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
-       { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
-       { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 },
-       { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 },
-       { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 },
-       { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 },
-       { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 },
-};
-
 static const struct bw_tbl sdm845_bw_table_enc[] = {
        { 1944000, 1612000, 0, 2416000, 0 },    /* 3840x2160@60 */
        {  972000,  951000, 0, 1434000, 0 },    /* 3840x2160@30 */
@@ -518,8 +507,6 @@ static const struct venus_resources sdm845_res = {
        .bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
        .bw_tbl_dec = sdm845_bw_table_dec,
        .bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
-       .codec_freq_data = sdm845_codec_freq_data,
-       .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
        .clks = {"core", "iface", "bus" },
        .clks_num = 3,
        .vcodec0_clks = { "core", "bus" },
@@ -541,8 +528,6 @@ static const struct venus_resources sdm845_res_v2 = {
        .bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
        .bw_tbl_dec = sdm845_bw_table_dec,
        .bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
-       .codec_freq_data = sdm845_codec_freq_data,
-       .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
        .clks = {"core", "iface", "bus" },
        .clks_num = 3,
        .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
@@ -592,8 +577,6 @@ static const struct venus_resources sc7180_res = {
        .bw_tbl_enc_size = ARRAY_SIZE(sc7180_bw_table_enc),
        .bw_tbl_dec = sc7180_bw_table_dec,
        .bw_tbl_dec_size = ARRAY_SIZE(sc7180_bw_table_dec),
-       .codec_freq_data = sdm845_codec_freq_data,
-       .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
        .clks = {"core", "iface", "bus" },
        .clks_num = 3,
        .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
index 29f5e25..53187e4 100644 (file)
@@ -36,13 +36,6 @@ struct reg_val {
        u32 value;
 };
 
-struct codec_freq_data {
-       u32 pixfmt;
-       u32 session_type;
-       unsigned long vpp_freq;
-       unsigned long vsp_freq;
-};
-
 struct bw_tbl {
        u32 mbs_per_sec;
        u32 avg;
@@ -61,8 +54,6 @@ struct venus_resources {
        unsigned int bw_tbl_dec_size;
        const struct reg_val *reg_tbl;
        unsigned int reg_tbl_size;
-       const struct codec_freq_data *codec_freq_data;
-       unsigned int codec_freq_data_size;
        const char * const clks[VIDC_CLKS_NUM_MAX];
        unsigned int clks_num;
        const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
@@ -266,7 +257,8 @@ struct venus_buffer {
 struct clock_data {
        u32 core_id;
        unsigned long freq;
-       const struct codec_freq_data *codec_freq_data;
+       unsigned long vpp_freq;
+       unsigned long vsp_freq;
 };
 
 #define to_venus_buffer(ptr)   container_of(ptr, struct venus_buffer, vb)
index 11f35e3..4e2617c 100644 (file)
@@ -15,6 +15,7 @@
 #include "helpers.h"
 #include "hfi_helper.h"
 #include "pm_helpers.h"
+#include "hfi_platform.h"
 
 struct intbuf {
        struct list_head list;
@@ -1042,36 +1043,6 @@ int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
 
-int venus_helper_init_codec_freq_data(struct venus_inst *inst)
-{
-       const struct codec_freq_data *data;
-       unsigned int i, data_size;
-       u32 pixfmt;
-       int ret = 0;
-
-       if (!IS_V4(inst->core))
-               return 0;
-
-       data = inst->core->res->codec_freq_data;
-       data_size = inst->core->res->codec_freq_data_size;
-       pixfmt = inst->session_type == VIDC_SESSION_TYPE_DEC ?
-                       inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
-
-       for (i = 0; i < data_size; i++) {
-               if (data[i].pixfmt == pixfmt &&
-                   data[i].session_type == inst->session_type) {
-                       inst->clk_data.codec_freq_data = &data[i];
-                       break;
-               }
-       }
-
-       if (!inst->clk_data.codec_freq_data)
-               ret = -EINVAL;
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(venus_helper_init_codec_freq_data);
-
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
                              unsigned int output_bufs,
                              unsigned int output2_bufs)
@@ -1527,6 +1498,29 @@ void venus_helper_m2m_job_abort(void *priv)
 }
 EXPORT_SYMBOL_GPL(venus_helper_m2m_job_abort);
 
+int venus_helper_session_init(struct venus_inst *inst)
+{
+       enum hfi_version version = inst->core->res->hfi_version;
+       u32 session_type = inst->session_type;
+       u32 codec;
+       int ret;
+
+       codec = inst->session_type == VIDC_SESSION_TYPE_DEC ?
+                       inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
+
+       ret = hfi_session_init(inst, codec);
+       if (ret)
+               return ret;
+
+       inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec,
+                                                                 session_type);
+       inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec,
+                                                                 session_type);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_session_init);
+
 void venus_helper_init_instance(struct venus_inst *inst)
 {
        if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
index a4a0562..5407979 100644 (file)
@@ -33,7 +33,6 @@ int venus_helper_set_output_resolution(struct venus_inst *inst,
                                       unsigned int width, unsigned int height,
                                       u32 buftype);
 int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
-int venus_helper_init_codec_freq_data(struct venus_inst *inst);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
                              unsigned int output_bufs,
                              unsigned int output2_bufs);
@@ -48,6 +47,7 @@ unsigned int venus_helper_get_opb_size(struct venus_inst *inst);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
+int venus_helper_session_init(struct venus_inst *inst);
 int venus_helper_get_out_fmts(struct venus_inst *inst, u32 fmt, u32 *out_fmt,
                              u32 *out2_fmt, bool ubwc);
 int venus_helper_alloc_dpb_bufs(struct venus_inst *inst);
diff --git a/drivers/media/platform/qcom/venus/hfi_platform.c b/drivers/media/platform/qcom/venus/hfi_platform.c
new file mode 100644 (file)
index 0000000..65559ca
--- /dev/null
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+#include "hfi_platform.h"
+
+const struct hfi_platform *hfi_platform_get(enum hfi_version version)
+{
+       switch (version) {
+       case HFI_VERSION_4XX:
+               return &hfi_plat_v4;
+       default:
+               break;
+       }
+
+       return NULL;
+}
+
+unsigned long
+hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec, u32 session_type)
+{
+       const struct hfi_platform *plat;
+       unsigned long freq = 0;
+
+       plat = hfi_platform_get(version);
+       if (!plat)
+               return 0;
+
+       if (plat->codec_vpp_freq)
+               freq = plat->codec_vpp_freq(session_type, codec);
+
+       return freq;
+}
+
+unsigned long
+hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session_type)
+{
+       const struct hfi_platform *plat;
+       unsigned long freq = 0;
+
+       plat = hfi_platform_get(version);
+       if (!plat)
+               return 0;
+
+       if (plat->codec_vpp_freq)
+               freq = plat->codec_vsp_freq(session_type, codec);
+
+       return freq;
+}
diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h
new file mode 100644 (file)
index 0000000..8b07ecb
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __HFI_PLATFORM_H__
+#define __HFI_PLATFORM_H__
+
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#include "hfi.h"
+#include "hfi_helper.h"
+
+struct hfi_platform_codec_freq_data {
+       u32 pixfmt;
+       u32 session_type;
+       unsigned long vpp_freq;
+       unsigned long vsp_freq;
+};
+
+struct hfi_platform {
+       unsigned long (*codec_vpp_freq)(u32 session_type, u32 codec);
+       unsigned long (*codec_vsp_freq)(u32 session_type, u32 codec);
+};
+
+extern const struct hfi_platform hfi_plat_v4;
+
+const struct hfi_platform *hfi_platform_get(enum hfi_version version);
+unsigned long hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec,
+                                             u32 session_type);
+unsigned long hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec,
+                                             u32 session_type);
+#endif
diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v4.c b/drivers/media/platform/qcom/venus/hfi_platform_v4.c
new file mode 100644 (file)
index 0000000..4fc2fd0
--- /dev/null
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+#include "hfi_platform.h"
+
+static const struct hfi_platform_codec_freq_data codec_freq_data[] =  {
+       { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
+       { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
+       { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
+       { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 },
+       { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 },
+       { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 },
+       { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 },
+       { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 },
+};
+
+static const struct hfi_platform_codec_freq_data *
+get_codec_freq_data(u32 session_type, u32 pixfmt)
+{
+       const struct hfi_platform_codec_freq_data *data = codec_freq_data;
+       unsigned int i, data_size = ARRAY_SIZE(codec_freq_data);
+       const struct hfi_platform_codec_freq_data *found = NULL;
+
+       for (i = 0; i < data_size; i++) {
+               if (data[i].pixfmt == pixfmt && data[i].session_type == session_type) {
+                       found = &data[i];
+                       break;
+               }
+       }
+
+       return found;
+}
+
+static unsigned long codec_vpp_freq(u32 session_type, u32 codec)
+{
+       const struct hfi_platform_codec_freq_data *data;
+
+       data = get_codec_freq_data(session_type, codec);
+       if (data)
+               return data->vpp_freq;
+
+       return 0;
+}
+
+static unsigned long codec_vsp_freq(u32 session_type, u32 codec)
+{
+       const struct hfi_platform_codec_freq_data *data;
+
+       data = get_codec_freq_data(session_type, codec);
+       if (data)
+               return data->vsp_freq;
+
+       return 0;
+}
+
+const struct hfi_platform hfi_plat_v4 = {
+       .codec_vpp_freq = codec_vpp_freq,
+       .codec_vsp_freq = codec_vsp_freq,
+};
index 89f20c2..0011c3a 100644 (file)
@@ -18,6 +18,7 @@
 #include "hfi_parser.h"
 #include "hfi_venus_io.h"
 #include "pm_helpers.h"
+#include "hfi_platform.h"
 
 static bool legacy_binding;
 
@@ -510,7 +511,7 @@ min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load)
                if (inst_pos->state != INST_START)
                        continue;
 
-               vpp_freq = inst_pos->clk_data.codec_freq_data->vpp_freq;
+               vpp_freq = inst_pos->clk_data.vpp_freq;
                coreid = inst_pos->clk_data.core_id;
 
                mbs_per_sec = load_per_instance(inst_pos);
@@ -559,7 +560,7 @@ static int decide_core(struct venus_inst *inst)
                return 0;
 
        inst_load = load_per_instance(inst);
-       inst_load *= inst->clk_data.codec_freq_data->vpp_freq;
+       inst_load *= inst->clk_data.vpp_freq;
        max_freq = core->res->freq_tbl[0].freq;
 
        min_loaded_core(inst, &min_coreid, &min_load);
@@ -942,10 +943,10 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst,
        if (inst->state != INST_START)
                return 0;
 
-       vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
+       vpp_freq = mbs_per_sec * inst->clk_data.vpp_freq;
        /* 21 / 20 is overhead factor */
        vpp_freq += vpp_freq / 20;
-       vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
+       vsp_freq = mbs_per_sec * inst->clk_data.vsp_freq;
 
        /* 10 / 7 is overhead factor */
        if (inst->session_type == VIDC_SESSION_TYPE_ENC)
index 5fe77a7..fd06416 100644 (file)
@@ -760,7 +760,7 @@ static int vdec_session_init(struct venus_inst *inst)
 {
        int ret;
 
-       ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
+       ret = venus_helper_session_init(inst);
        if (ret == -EALREADY)
                return 0;
        else if (ret)
@@ -771,10 +771,6 @@ static int vdec_session_init(struct venus_inst *inst)
        if (ret)
                goto deinit;
 
-       ret = venus_helper_init_codec_freq_data(inst);
-       if (ret)
-               goto deinit;
-
        return 0;
 deinit:
        hfi_session_deinit(inst);
index 8cc0695..6e830fc 100644 (file)
@@ -724,7 +724,7 @@ static int venc_init_session(struct venus_inst *inst)
 {
        int ret;
 
-       ret = hfi_session_init(inst, inst->fmt_cap->pixfmt);
+       ret = venus_helper_session_init(inst);
        if (ret == -EALREADY)
                return 0;
        else if (ret)
@@ -745,10 +745,6 @@ static int venc_init_session(struct venus_inst *inst)
        if (ret)
                goto deinit;
 
-       ret = venus_helper_init_codec_freq_data(inst);
-       if (ret)
-               goto deinit;
-
        ret = venc_set_properties(inst);
        if (ret)
                goto deinit;