video: driver: reduce device_tree dependency for video
Only keep minimal entries in dtsi, which is essential for other drivers usage. Move remaining all data into platform resource file. Remove device_tree dependency and maintain platform_data to initialize resources like regulators, interconnects, clocks, reset_clocks, subcaches and context_banks. Read static data like freq_table, firmware_name, pas_id also from platform_data instead of from dtsi. Change-Id: I73a1df10b92c55e55b23e538aea62598a7250ab4 Signed-off-by: Govindaraj Rajagopal <quic_grajagop@quicinc.com>
This commit is contained in:
@@ -41,6 +41,61 @@ extern u32 vpe_csc_custom_matrix_coeff[MAX_MATRIX_COEFFS];
|
||||
extern u32 vpe_csc_custom_bias_coeff[MAX_BIAS_COEFFS];
|
||||
extern u32 vpe_csc_custom_limit_coeff[MAX_LIMIT_COEFFS];
|
||||
|
||||
struct bw_table {
|
||||
const char *name;
|
||||
u32 min_kbps;
|
||||
u32 max_kbps;
|
||||
};
|
||||
|
||||
struct regulator_table {
|
||||
const char *name;
|
||||
bool hw_trigger;
|
||||
};
|
||||
|
||||
struct clk_table {
|
||||
const char *name;
|
||||
u32 clk_id;
|
||||
bool scaling;
|
||||
};
|
||||
|
||||
struct clk_rst_table {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct subcache_table {
|
||||
const char *name;
|
||||
u32 llcc_id;
|
||||
};
|
||||
|
||||
struct context_bank_table {
|
||||
const char *name;
|
||||
u32 start;
|
||||
u32 size;
|
||||
bool secure;
|
||||
bool dma_coherant;
|
||||
u32 region;
|
||||
};
|
||||
|
||||
struct freq_table {
|
||||
unsigned long freq;
|
||||
};
|
||||
|
||||
struct reg_preset_table {
|
||||
u32 reg;
|
||||
u32 value;
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
struct msm_vidc_ubwc_config_data {
|
||||
u32 max_channels;
|
||||
u32 mal_length;
|
||||
u32 highest_bank_bit;
|
||||
u32 bank_swzl_level;
|
||||
u32 bank_swz2_level;
|
||||
u32 bank_swz3_level;
|
||||
u32 bank_spreading;
|
||||
};
|
||||
|
||||
struct codec_info {
|
||||
u32 v4l2_codec;
|
||||
enum msm_vidc_codec_type vidc_codec;
|
||||
@@ -112,16 +167,6 @@ struct msm_vidc_efuse_data {
|
||||
enum efuse_purpose purpose;
|
||||
};
|
||||
|
||||
struct msm_vidc_ubwc_config_data {
|
||||
u32 max_channels;
|
||||
u32 mal_length;
|
||||
u32 highest_bank_bit;
|
||||
u32 bank_swzl_level;
|
||||
u32 bank_swz2_level;
|
||||
u32 bank_swz3_level;
|
||||
u32 bank_spreading;
|
||||
};
|
||||
|
||||
struct msm_vidc_format_capability {
|
||||
struct codec_info *codec_info;
|
||||
u32 codec_info_size;
|
||||
@@ -136,6 +181,26 @@ struct msm_vidc_format_capability {
|
||||
};
|
||||
|
||||
struct msm_vidc_platform_data {
|
||||
const struct bw_table *bw_tbl;
|
||||
unsigned int bw_tbl_size;
|
||||
const struct regulator_table *regulator_tbl;
|
||||
unsigned int regulator_tbl_size;
|
||||
const struct clk_table *clk_tbl;
|
||||
unsigned int clk_tbl_size;
|
||||
const struct clk_rst_table *clk_rst_tbl;
|
||||
unsigned int clk_rst_tbl_size;
|
||||
const struct subcache_table *subcache_tbl;
|
||||
unsigned int subcache_tbl_size;
|
||||
const struct context_bank_table *context_bank_tbl;
|
||||
unsigned int context_bank_tbl_size;
|
||||
struct freq_table *freq_tbl;
|
||||
unsigned int freq_tbl_size;
|
||||
const struct reg_preset_table *reg_prst_tbl;
|
||||
unsigned int reg_prst_tbl_size;
|
||||
struct msm_vidc_ubwc_config_data *ubwc_config;
|
||||
const char *fwname;
|
||||
u32 pas_id;
|
||||
bool supports_mmrm;
|
||||
struct msm_platform_core_capability *core_data;
|
||||
u32 core_data_size;
|
||||
struct msm_platform_inst_capability *inst_cap_data;
|
||||
@@ -143,7 +208,6 @@ struct msm_vidc_platform_data {
|
||||
struct msm_platform_inst_cap_dependency *inst_cap_dependency_data;
|
||||
u32 inst_cap_dependency_data_size;
|
||||
struct msm_vidc_csc_coeff csc_data;
|
||||
struct msm_vidc_ubwc_config_data *ubwc_config;
|
||||
struct msm_vidc_efuse_data *efuse_data;
|
||||
unsigned int efuse_data_size;
|
||||
unsigned int sku_version;
|
||||
@@ -155,9 +219,18 @@ struct msm_vidc_platform {
|
||||
struct msm_vidc_platform_data data;
|
||||
};
|
||||
|
||||
static inline bool is_sys_cache_present(struct msm_vidc_core *core)
|
||||
{
|
||||
return !!core->platform->data.subcache_tbl_size;
|
||||
}
|
||||
|
||||
static inline bool is_mmrm_supported(struct msm_vidc_core *core)
|
||||
{
|
||||
return !!core->platform->data.supports_mmrm;
|
||||
}
|
||||
|
||||
int msm_vidc_init_platform(struct platform_device *pdev);
|
||||
int msm_vidc_deinit_platform(struct platform_device *pdev);
|
||||
int msm_vidc_read_efuse(struct msm_vidc_core *core);
|
||||
void msm_vidc_sort_table(struct msm_vidc_core *core);
|
||||
|
||||
#endif // _MSM_VIDC_PLATFORM_H_
|
||||
|
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/of.h>
|
||||
#include <soc/qcom/of_common.h>
|
||||
|
||||
#include "msm_vidc_platform.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
@@ -13,7 +14,6 @@
|
||||
#include "msm_vidc_vb2.h"
|
||||
#include "msm_vidc_control.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_internal.h"
|
||||
#if defined(CONFIG_MSM_VIDC_WAIPIO)
|
||||
@@ -25,9 +25,6 @@
|
||||
#if defined(CONFIG_MSM_VIDC_PINEAPPLE)
|
||||
#include "msm_vidc_pineapple.h"
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_PINEAPPLE)
|
||||
#include "msm_vidc_pineapple.h"
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_ANORAK)
|
||||
#include "msm_vidc_anorak.h"
|
||||
#endif
|
||||
@@ -221,7 +218,7 @@ static int msm_vidc_deinit_platform_variant(struct msm_vidc_core *core, struct d
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
|
||||
#if defined(CONFIG_MSM_VIDC_WAIPIO)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-waipio")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8450-vidc")) {
|
||||
rc = msm_vidc_deinit_platform_waipio(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -229,7 +226,8 @@ static int msm_vidc_deinit_platform_variant(struct msm_vidc_core *core, struct d
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_KALAMA)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-kalama")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc-v2")) {
|
||||
rc = msm_vidc_deinit_platform_kalama(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -237,7 +235,7 @@ static int msm_vidc_deinit_platform_variant(struct msm_vidc_core *core, struct d
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_PINEAPPLE)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-pineapple")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8650-vidc")) {
|
||||
rc = msm_vidc_deinit_platform_pineapple(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -245,7 +243,7 @@ static int msm_vidc_deinit_platform_variant(struct msm_vidc_core *core, struct d
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_ANORAK)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-anorak")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sxr2230p-vidc")) {
|
||||
rc = msm_vidc_deinit_platform_anorak(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -268,7 +266,7 @@ static int msm_vidc_init_platform_variant(struct msm_vidc_core *core, struct dev
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
|
||||
#if defined(CONFIG_MSM_VIDC_WAIPIO)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-waipio")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8450-vidc")) {
|
||||
rc = msm_vidc_init_platform_waipio(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -276,7 +274,8 @@ static int msm_vidc_init_platform_variant(struct msm_vidc_core *core, struct dev
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_KALAMA)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-kalama")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc-v2")) {
|
||||
rc = msm_vidc_init_platform_kalama(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -284,7 +283,7 @@ static int msm_vidc_init_platform_variant(struct msm_vidc_core *core, struct dev
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_PINEAPPLE)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-pineapple")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8650-vidc")) {
|
||||
rc = msm_vidc_init_platform_pineapple(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -292,7 +291,7 @@ static int msm_vidc_init_platform_variant(struct msm_vidc_core *core, struct dev
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_ANORAK)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-anorak")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sxr2230p-vidc")) {
|
||||
rc = msm_vidc_init_platform_anorak(core, dev);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -315,7 +314,7 @@ static int msm_vidc_deinit_vpu(struct msm_vidc_core *core, struct device *dev)
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
|
||||
#if defined(CONFIG_MSM_VIDC_IRIS2)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-iris2")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8450-vidc")) {
|
||||
rc = msm_vidc_deinit_iris2(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -323,7 +322,8 @@ static int msm_vidc_deinit_vpu(struct msm_vidc_core *core, struct device *dev)
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_IRIS3)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-iris3")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc-v2")) {
|
||||
rc = msm_vidc_deinit_iris3(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -331,7 +331,7 @@ static int msm_vidc_deinit_vpu(struct msm_vidc_core *core, struct device *dev)
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_IRIS33)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-iris33")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8650-vidc")) {
|
||||
rc = msm_vidc_deinit_iris33(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -351,7 +351,7 @@ static int msm_vidc_init_vpu(struct msm_vidc_core *core, struct device *dev)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MSM_VIDC_IRIS2)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-iris2")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8450-vidc")) {
|
||||
rc = msm_vidc_init_iris2(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -359,7 +359,8 @@ static int msm_vidc_init_vpu(struct msm_vidc_core *core, struct device *dev)
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_IRIS3)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-iris3")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc-v2")) {
|
||||
rc = msm_vidc_init_iris3(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -367,7 +368,7 @@ static int msm_vidc_init_vpu(struct msm_vidc_core *core, struct device *dev)
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_MSM_VIDC_IRIS33)
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc-iris33")) {
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8650-vidc")) {
|
||||
rc = msm_vidc_init_iris33(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed with %d\n", __func__, rc);
|
||||
@@ -494,19 +495,3 @@ int msm_vidc_read_efuse(struct msm_vidc_core *core)
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_vidc_sort_table(struct msm_vidc_core *core)
|
||||
{
|
||||
u32 i = 0;
|
||||
|
||||
if (!core || !core->dt || !core->dt->allowed_clks_tbl) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
sort(core->dt->allowed_clks_tbl, core->dt->allowed_clks_tbl_size,
|
||||
sizeof(*core->dt->allowed_clks_tbl), cmp, NULL);
|
||||
d_vpr_h("Updated allowed clock rates\n");
|
||||
for (i = 0; i < core->dt->allowed_clks_tbl_size; i++)
|
||||
d_vpr_h(" %d\n", core->dt->allowed_clks_tbl[i]);
|
||||
}
|
||||
|
@@ -4,9 +4,13 @@
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <soc/qcom/of_common.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-kalama.h>
|
||||
#include <dt-bindings/clock/qcom,videocc-kalama.h>
|
||||
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
#include <soc/qcom/of_common.h>
|
||||
#include <media/v4l2_vidc_extensions.h>
|
||||
|
||||
#include "msm_vidc_kalama.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
@@ -315,7 +319,6 @@ static struct msm_platform_core_capability core_data_kalama[] = {
|
||||
{AV_SYNC_WINDOW_SIZE, 40},
|
||||
{NON_FATAL_FAULTS, 1},
|
||||
{ENC_AUTO_FRAMERATE, 1},
|
||||
{MMRM, 1},
|
||||
{DEVICE_CAPS, V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_META_CAPTURE |
|
||||
V4L2_CAP_STREAMING},
|
||||
{SUPPORTS_REQUESTS, 1},
|
||||
@@ -2626,7 +2629,128 @@ static struct msm_vidc_format_capability format_data_kalama = {
|
||||
.matrix_coeff_info_size = ARRAY_SIZE(matrix_coeff_data_kalama),
|
||||
};
|
||||
|
||||
/* name, min_kbps, max_kbps */
|
||||
static const struct bw_table kalama_bw_table[] = {
|
||||
{ "venus-cnoc", 1000, 1000 },
|
||||
{ "venus-ddr", 1000, 15000000 },
|
||||
{ "venus-llcc", 1000, 15000000 },
|
||||
};
|
||||
|
||||
/* name, hw_trigger */
|
||||
static const struct regulator_table kalama_regulator_table[] = {
|
||||
{ "iris-ctl", 0 },
|
||||
{ "vcodec", 1 },
|
||||
};
|
||||
|
||||
/* name, clock id, scaling */
|
||||
static const struct clk_table kalama_clk_table[] = {
|
||||
{ "gcc_video_axi0", GCC_VIDEO_AXI0_CLK, 0 },
|
||||
{ "core_clk", VIDEO_CC_MVS0C_CLK, 0 },
|
||||
{ "vcodec_clk", VIDEO_CC_MVS0_CLK, 0 },
|
||||
{ "video_cc_mvs0_clk_src", VIDEO_CC_MVS0_CLK_SRC, 1 },
|
||||
};
|
||||
|
||||
/* name */
|
||||
static const struct clk_rst_table kalama_clk_reset_table[] = {
|
||||
{ "video_axi_reset" },
|
||||
};
|
||||
|
||||
/* name, llcc_id */
|
||||
static const struct subcache_table kalama_subcache_table[] = {
|
||||
{ "vidsc0", LLCC_VIDSC0 },
|
||||
{ "vidvsp", LLCC_VIDVSP },
|
||||
};
|
||||
|
||||
/* name, start, size, secure, dma_coherant, region */
|
||||
const struct context_bank_table kalama_context_bank_table[] = {
|
||||
{"qcom,vidc,cb-ns", 0x25800000, 0xba800000, 0, 1, MSM_VIDC_NON_SECURE },
|
||||
{"qcom,vidc,cb-ns-pxl", 0x00100000, 0xdff00000, 0, 1, MSM_VIDC_NON_SECURE_PIXEL },
|
||||
{"qcom,vidc,cb-sec-pxl", 0x00500000, 0xdfb00000, 1, 0, MSM_VIDC_SECURE_PIXEL },
|
||||
{"qcom,vidc,cb-sec-non-pxl", 0x01000000, 0x24800000, 1, 0, MSM_VIDC_SECURE_NONPIXEL },
|
||||
{"qcom,vidc,cb-sec-bitstream", 0x00500000, 0xdfb00000, 1, 0, MSM_VIDC_SECURE_BITSTREAM },
|
||||
};
|
||||
|
||||
/* freq */
|
||||
static struct freq_table kalama_freq_table[] = {
|
||||
{481000000}, {444000000}, {366000000}, {338000000}, {240000000}
|
||||
};
|
||||
|
||||
static struct freq_table kalama_freq_table_v2[] = {
|
||||
{533333333}, {444000000}, {366000000}, {338000000}, {240000000}
|
||||
};
|
||||
|
||||
/* register, value, mask */
|
||||
static const struct reg_preset_table kalama_reg_preset_table[] = {
|
||||
{ 0xB0088, 0x0, 0x11 },
|
||||
};
|
||||
|
||||
static const struct msm_vidc_platform_data kalama_data = {
|
||||
/* resources dependent on other module */
|
||||
.bw_tbl = kalama_bw_table,
|
||||
.bw_tbl_size = ARRAY_SIZE(kalama_bw_table),
|
||||
.regulator_tbl = kalama_regulator_table,
|
||||
.regulator_tbl_size = ARRAY_SIZE(kalama_regulator_table),
|
||||
.clk_tbl = kalama_clk_table,
|
||||
.clk_tbl_size = ARRAY_SIZE(kalama_clk_table),
|
||||
.clk_rst_tbl = kalama_clk_reset_table,
|
||||
.clk_rst_tbl_size = ARRAY_SIZE(kalama_clk_reset_table),
|
||||
.subcache_tbl = kalama_subcache_table,
|
||||
.subcache_tbl_size = ARRAY_SIZE(kalama_subcache_table),
|
||||
|
||||
/* populate context bank */
|
||||
.context_bank_tbl = kalama_context_bank_table,
|
||||
.context_bank_tbl_size = ARRAY_SIZE(kalama_context_bank_table),
|
||||
|
||||
/* platform specific resources */
|
||||
.freq_tbl = kalama_freq_table,
|
||||
.freq_tbl_size = ARRAY_SIZE(kalama_freq_table),
|
||||
.reg_prst_tbl = kalama_reg_preset_table,
|
||||
.reg_prst_tbl_size = ARRAY_SIZE(kalama_reg_preset_table),
|
||||
.fwname = "vpu30_4v",
|
||||
.pas_id = 9,
|
||||
.supports_mmrm = 1,
|
||||
|
||||
/* caps related resorces */
|
||||
.core_data = core_data_kalama,
|
||||
.core_data_size = ARRAY_SIZE(core_data_kalama),
|
||||
.inst_cap_data = instance_cap_data_kalama,
|
||||
.inst_cap_data_size = ARRAY_SIZE(instance_cap_data_kalama),
|
||||
.inst_cap_dependency_data = instance_cap_dependency_data_kalama,
|
||||
.inst_cap_dependency_data_size = ARRAY_SIZE(instance_cap_dependency_data_kalama),
|
||||
.csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff,
|
||||
.csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff,
|
||||
.csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff,
|
||||
.ubwc_config = ubwc_config_kalama,
|
||||
.format_data = &format_data_kalama,
|
||||
};
|
||||
|
||||
static const struct msm_vidc_platform_data kalama_data_v2 = {
|
||||
/* resources dependent on other module */
|
||||
.bw_tbl = kalama_bw_table,
|
||||
.bw_tbl_size = ARRAY_SIZE(kalama_bw_table),
|
||||
.regulator_tbl = kalama_regulator_table,
|
||||
.regulator_tbl_size = ARRAY_SIZE(kalama_regulator_table),
|
||||
.clk_tbl = kalama_clk_table,
|
||||
.clk_tbl_size = ARRAY_SIZE(kalama_clk_table),
|
||||
.clk_rst_tbl = kalama_clk_reset_table,
|
||||
.clk_rst_tbl_size = ARRAY_SIZE(kalama_clk_reset_table),
|
||||
.subcache_tbl = kalama_subcache_table,
|
||||
.subcache_tbl_size = ARRAY_SIZE(kalama_subcache_table),
|
||||
|
||||
/* populate context bank */
|
||||
.context_bank_tbl = kalama_context_bank_table,
|
||||
.context_bank_tbl_size = ARRAY_SIZE(kalama_context_bank_table),
|
||||
|
||||
/* platform specific resources */
|
||||
.freq_tbl = kalama_freq_table_v2,
|
||||
.freq_tbl_size = ARRAY_SIZE(kalama_freq_table_v2),
|
||||
.reg_prst_tbl = kalama_reg_preset_table,
|
||||
.reg_prst_tbl_size = ARRAY_SIZE(kalama_reg_preset_table),
|
||||
.fwname = "vpu30_4v",
|
||||
.pas_id = 9,
|
||||
.supports_mmrm = 1,
|
||||
|
||||
/* caps related resorces */
|
||||
.core_data = core_data_kalama,
|
||||
.core_data_size = ARRAY_SIZE(core_data_kalama),
|
||||
.inst_cap_data = instance_cap_data_kalama,
|
||||
@@ -2655,17 +2779,21 @@ int msm_vidc_kalama_check_ddr_type(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_init_data(struct msm_vidc_core *core)
|
||||
static int msm_vidc_init_data(struct msm_vidc_core *core, struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !core->platform) {
|
||||
if (!core || !core->platform || !dev) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
d_vpr_h("%s: initialize kalama data\n", __func__);
|
||||
|
||||
core->platform->data = kalama_data;
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc-v2"))
|
||||
core->platform->data = kalama_data_v2;
|
||||
else
|
||||
core->platform->data = kalama_data;
|
||||
|
||||
rc = msm_vidc_kalama_check_ddr_type();
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -2677,7 +2805,7 @@ int msm_vidc_init_platform_kalama(struct msm_vidc_core *core, struct device *dev
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = msm_vidc_init_data(core);
|
||||
rc = msm_vidc_init_data(core, dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@@ -9,8 +9,8 @@
|
||||
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_variant.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
|
||||
static void __fatal_error(bool fatal)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ int __write_register(struct msm_vidc_core *core, u32 reg, u32 value)
|
||||
u8 *base_addr;
|
||||
int rc = 0;
|
||||
|
||||
if (!core) {
|
||||
if (!core || !core->resource) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ int __write_register(struct msm_vidc_core *core, u32 reg, u32 value)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_addr = core->register_base_addr;
|
||||
base_addr = core->resource->register_base_addr;
|
||||
d_vpr_l("regwrite(%pK + %#x) = %#x\n", base_addr, hwiosymaddr, value);
|
||||
base_addr += hwiosymaddr;
|
||||
writel_relaxed(value, base_addr);
|
||||
@@ -74,7 +74,7 @@ int __write_register_masked(struct msm_vidc_core *core, u32 reg, u32 value,
|
||||
u8 *base_addr;
|
||||
int rc = 0;
|
||||
|
||||
if (!core) {
|
||||
if (!core || !core->resource) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ int __write_register_masked(struct msm_vidc_core *core, u32 reg, u32 value,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_addr = core->register_base_addr;
|
||||
base_addr = core->resource->register_base_addr;
|
||||
base_addr += reg;
|
||||
|
||||
prev_val = readl_relaxed(base_addr);
|
||||
@@ -116,7 +116,7 @@ int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value)
|
||||
int rc = 0;
|
||||
u8 *base_addr;
|
||||
|
||||
if (!core || !value) {
|
||||
if (!core || !core->resource || !value) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_addr = core->register_base_addr;
|
||||
base_addr = core->resource->register_base_addr;
|
||||
|
||||
*value = readl_relaxed(base_addr + reg);
|
||||
/*
|
||||
@@ -147,7 +147,7 @@ int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg,
|
||||
u32 val = 0;
|
||||
u8 *addr;
|
||||
|
||||
if (!core) {
|
||||
if (!core || !core->resource) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -157,7 +157,7 @@ int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr = (u8 *)core->register_base_addr + reg;
|
||||
addr = (u8 *)core->resource->register_base_addr + reg;
|
||||
|
||||
rc = readl_relaxed_poll_timeout(addr, val, ((val & mask) == exp_val), sleep_us, timeout_us);
|
||||
/*
|
||||
@@ -167,7 +167,7 @@ int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg,
|
||||
rmb();
|
||||
d_vpr_l(
|
||||
"regread(%pK + %#x) = %#x. rc %d, mask %#x, exp_val %#x, cond %u, sleep %u, timeout %u\n",
|
||||
core->register_base_addr, reg, val, rc, mask, exp_val,
|
||||
core->resource->register_base_addr, reg, val, rc, mask, exp_val,
|
||||
((val & mask) == exp_val), sleep_us, timeout_us);
|
||||
|
||||
return rc;
|
||||
@@ -175,19 +175,25 @@ int __read_register_with_poll_timeout(struct msm_vidc_core *core, u32 reg,
|
||||
|
||||
int __set_registers(struct msm_vidc_core *core)
|
||||
{
|
||||
struct reg_set *reg_set;
|
||||
int i, rc = 0;
|
||||
const struct reg_preset_table *reg_prst;
|
||||
unsigned int prst_count;
|
||||
int cnt, rc = 0;
|
||||
|
||||
if (!core || !core->dt) {
|
||||
if (!core || !core->platform) {
|
||||
d_vpr_e("core resources null, cannot set registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg_set = &core->dt->reg_set;
|
||||
for (i = 0; i < reg_set->count; i++) {
|
||||
rc = __write_register_masked(core, reg_set->reg_tbl[i].reg,
|
||||
reg_set->reg_tbl[i].value,
|
||||
reg_set->reg_tbl[i].mask);
|
||||
reg_prst = core->platform->data.reg_prst_tbl;
|
||||
prst_count = core->platform->data.reg_prst_tbl_size;
|
||||
|
||||
/* skip if there is no preset reg available */
|
||||
if (!reg_prst || !prst_count)
|
||||
return 0;
|
||||
|
||||
for (cnt = 0; cnt < prst_count; cnt++) {
|
||||
rc = __write_register_masked(core, reg_prst->reg,
|
||||
reg_prst->value, reg_prst->mask);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include "msm_vidc_buffer.h"
|
||||
#include "msm_vidc_inst.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_media_info.h"
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_control.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "msm_vidc_buffer.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
@@ -487,7 +486,7 @@ static int __power_off_iris3(struct msm_vidc_core *core)
|
||||
d_vpr_e("%s: failed to unvote buses\n", __func__);
|
||||
|
||||
if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS3))
|
||||
disable_irq_nosync(core->dt->irq);
|
||||
disable_irq_nosync(core->resource->irq);
|
||||
core->intr_status = 0;
|
||||
|
||||
core->power_enabled = false;
|
||||
@@ -551,7 +550,7 @@ fail_regulator:
|
||||
static int __power_on_iris3(struct msm_vidc_core *core)
|
||||
{
|
||||
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||
struct allowed_clock_rates_table *clk_tbl;
|
||||
struct frequency_table *freq_tbl;
|
||||
u32 freq = 0;
|
||||
int rc = 0;
|
||||
|
||||
@@ -579,9 +578,9 @@ static int __power_on_iris3(struct msm_vidc_core *core)
|
||||
/* video controller and hardware powered on successfully */
|
||||
core->power_enabled = true;
|
||||
|
||||
clk_tbl = core->dt->allowed_clks_tbl;
|
||||
freq_tbl = core->resource->freq_set.freq_tbl;
|
||||
freq = core->power.clk_freq ? core->power.clk_freq :
|
||||
clk_tbl[0].clock_rate;
|
||||
freq_tbl[0].freq;
|
||||
|
||||
rc = res_ops->set_clks(core, freq);
|
||||
if (rc) {
|
||||
@@ -596,7 +595,7 @@ static int __power_on_iris3(struct msm_vidc_core *core)
|
||||
|
||||
__interrupt_init_iris3(core);
|
||||
core->intr_status = 0;
|
||||
enable_irq(core->dt->irq);
|
||||
enable_irq(core->resource->irq);
|
||||
|
||||
return rc;
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
|
||||
u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
|
||||
{
|
||||
@@ -27,9 +26,10 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return freq;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
if (!core->dt || !core->dt->allowed_clks_tbl) {
|
||||
|
||||
if (!core->resource || !core->resource->freq_set.freq_tbl ||
|
||||
!core->resource->freq_set.count) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return freq;
|
||||
}
|
||||
@@ -151,8 +151,8 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
|
||||
u32 bitrate_2stage[2] = {130, 120};
|
||||
u32 bitrate_1stage = 100;
|
||||
u32 width, height;
|
||||
u32 bitrate_entry, freq_entry, frequency_table_value;
|
||||
struct allowed_clock_rates_table *allowed_clks_tbl;
|
||||
u32 bitrate_entry, freq_entry, freq_tbl_value;
|
||||
struct frequency_table *freq_tbl;
|
||||
struct v4l2_format *out_f = &inst->fmts[OUTPUT_PORT];
|
||||
|
||||
width = out_f->fmt.pix_mp.width;
|
||||
@@ -165,11 +165,11 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
|
||||
|
||||
freq_entry = bitrate_entry;
|
||||
|
||||
allowed_clks_tbl = core->dt->allowed_clks_tbl;
|
||||
frequency_table_value = allowed_clks_tbl[freq_entry].clock_rate / 1000000;
|
||||
freq_tbl = core->resource->freq_set.freq_tbl;
|
||||
freq_tbl_value = freq_tbl[freq_entry].freq / 1000000;
|
||||
|
||||
input_bitrate_mbps = fps * data_size * 8 / (1024 * 1024);
|
||||
vsp_hw_min_frequency = frequency_table_value * 1000 * input_bitrate_mbps;
|
||||
vsp_hw_min_frequency = freq_tbl_value * 1000 * input_bitrate_mbps;
|
||||
|
||||
if (inst->capabilities->cap[STAGE].value == MSM_VIDC_STAGE_2) {
|
||||
vsp_hw_min_frequency +=
|
||||
@@ -233,9 +233,9 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size)
|
||||
* for non-AV1 codecs limit the frequency to NOM only
|
||||
* index 0 is TURBO, index 1 is NOM clock rate
|
||||
*/
|
||||
if (core->dt->allowed_clks_tbl_size >= 2 &&
|
||||
freq > core->dt->allowed_clks_tbl[1].clock_rate)
|
||||
freq = core->dt->allowed_clks_tbl[1].clock_rate;
|
||||
if (core->resource->freq_set.count >= 2 &&
|
||||
freq > core->resource->freq_set.freq_tbl[1].freq)
|
||||
freq = core->resource->freq_set.freq_tbl[1].freq;
|
||||
}
|
||||
|
||||
i_vpr_p(inst, "%s: filled len %d, required freq %llu, fps %u, mbpf %u\n",
|
||||
|
@@ -74,9 +74,8 @@ struct msm_vidc_core {
|
||||
char fw_version[MAX_NAME_LENGTH];
|
||||
enum msm_vidc_core_state state;
|
||||
struct mutex lock;
|
||||
struct msm_vidc_dt *dt;
|
||||
struct msm_vidc_resource *resource;
|
||||
struct msm_vidc_platform *platform;
|
||||
u8 __iomem *register_base_addr;
|
||||
u32 intr_status;
|
||||
u32 spur_count;
|
||||
u32 reg_count;
|
||||
|
@@ -8,228 +8,5 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
#ifdef CONFIG_MSM_MMRM
|
||||
#include <linux/soc/qcom/msm_mmrm.h>
|
||||
#endif
|
||||
#include "msm_vidc_internal.h"
|
||||
|
||||
/*
|
||||
* These are helper macros to iterate over various lists within
|
||||
* msm_vidc_core->dt. The intention is to cut down on a lot of boiler-plate
|
||||
* code
|
||||
*/
|
||||
|
||||
/* Read as "for each 'thing' in a set of 'thingies'" */
|
||||
#define venus_hfi_for_each_thing(__device, __thing, __thingy) \
|
||||
venus_hfi_for_each_thing_continue(__device, __thing, __thingy, 0)
|
||||
|
||||
#define venus_hfi_for_each_thing_reverse(__device, __thing, __thingy) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
(__device)->dt->__thingy##_set.count - 1)
|
||||
|
||||
/* TODO: the __from parameter technically not required since we can figure it
|
||||
* out with some pointer magic (i.e. __thing - __thing##_tbl[0]). If this macro
|
||||
* sees extensive use, probably worth cleaning it up but for now omitting it
|
||||
* since it introduces unnecessary complexity.
|
||||
*/
|
||||
#define venus_hfi_for_each_thing_continue(__device, __thing, __thingy, __from) \
|
||||
for (__thing = &(__device)->dt->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing < &(__device)->dt->__thingy##_set.__thingy##_tbl[0] + \
|
||||
((__device)->dt->__thingy##_set.count - __from); \
|
||||
++__thing)
|
||||
|
||||
#define venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
__from) \
|
||||
for (__thing = &(__device)->dt->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing >= &(__device)->dt->__thingy##_set.__thingy##_tbl[0]; \
|
||||
--__thing)
|
||||
|
||||
/* Regular set helpers */
|
||||
#define venus_hfi_for_each_regulator(__device, __rinfo) \
|
||||
venus_hfi_for_each_thing(__device, __rinfo, regulator)
|
||||
|
||||
#define venus_hfi_for_each_regulator_reverse(__device, __rinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __rinfo, regulator)
|
||||
|
||||
#define venus_hfi_for_each_regulator_reverse_continue(__device, __rinfo, \
|
||||
__from) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
|
||||
regulator, __from)
|
||||
|
||||
/* Clock set helpers */
|
||||
#define venus_hfi_for_each_clock(__device, __cinfo) \
|
||||
venus_hfi_for_each_thing(__device, __cinfo, clock)
|
||||
|
||||
#define venus_hfi_for_each_clock_reverse(__device, __cinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __cinfo, clock)
|
||||
|
||||
/* Bus set helpers */
|
||||
#define venus_hfi_for_each_bus(__device, __binfo) \
|
||||
venus_hfi_for_each_thing(__device, __binfo, bus)
|
||||
#define venus_hfi_for_each_bus_reverse(__device, __binfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __binfo, bus)
|
||||
|
||||
/* Subcache set helpers */
|
||||
#define venus_hfi_for_each_subcache(__device, __sinfo) \
|
||||
venus_hfi_for_each_thing(__device, __sinfo, subcache)
|
||||
#define venus_hfi_for_each_subcache_reverse(__device, __sinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __sinfo, subcache)
|
||||
|
||||
struct reg_value_pair {
|
||||
u32 reg;
|
||||
u32 value;
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
struct reg_set {
|
||||
struct reg_value_pair *reg_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct addr_range {
|
||||
u32 start;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct addr_set {
|
||||
struct addr_range *addr_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct context_bank_info {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
bool is_secure;
|
||||
struct addr_range addr_range;
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
};
|
||||
|
||||
struct buffer_usage_table {
|
||||
u32 buffer_type;
|
||||
u32 tz_usage;
|
||||
};
|
||||
|
||||
struct buffer_usage_set {
|
||||
struct buffer_usage_table *buffer_usage_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct regulator_info {
|
||||
struct regulator *regulator;
|
||||
bool has_hw_power_collapse;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct regulator_set {
|
||||
struct regulator_info *regulator_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct clock_info {
|
||||
const char *name;
|
||||
u32 clk_id;
|
||||
struct clk *clk;
|
||||
u32 count;
|
||||
bool has_scaling;
|
||||
bool has_mem_retention;
|
||||
u64 prev;
|
||||
#ifdef CONFIG_MSM_MMRM
|
||||
struct mmrm_client *mmrm_client;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct clock_set {
|
||||
struct clock_info *clock_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct bus_info {
|
||||
const char *name;
|
||||
u32 range[2];
|
||||
struct device *dev;
|
||||
struct icc_path *path;
|
||||
};
|
||||
|
||||
struct bus_set {
|
||||
struct bus_info *bus_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct reset_info {
|
||||
struct reset_control *rst;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct reset_set {
|
||||
struct reset_info *reset_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct allowed_clock_rates_table {
|
||||
u32 clock_rate;
|
||||
};
|
||||
|
||||
struct clock_profile_entry {
|
||||
u32 codec_mask;
|
||||
u32 vpp_cycles;
|
||||
u32 vsp_cycles;
|
||||
u32 low_power_cycles;
|
||||
};
|
||||
|
||||
struct clock_freq_table {
|
||||
struct clock_profile_entry *clk_prof_entries;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct subcache_info {
|
||||
const char *name;
|
||||
bool isactive;
|
||||
bool isset;
|
||||
struct llcc_slice_desc *subcache;
|
||||
};
|
||||
|
||||
struct subcache_set {
|
||||
struct subcache_info *subcache_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct msm_vidc_dt {
|
||||
void *core;
|
||||
phys_addr_t register_base;
|
||||
u32 register_size;
|
||||
u32 irq;
|
||||
struct allowed_clock_rates_table *allowed_clks_tbl;
|
||||
u32 allowed_clks_tbl_size;
|
||||
struct clock_freq_table clock_freq_tbl;
|
||||
bool sys_cache_present;
|
||||
bool sys_cache_res_set;
|
||||
struct subcache_set subcache_set;
|
||||
struct reg_set reg_set;
|
||||
struct addr_set qdss_addr_set;
|
||||
struct buffer_usage_set buffer_usage_set;
|
||||
struct regulator_set regulator_set;
|
||||
struct clock_set clock_set;
|
||||
struct bus_set bus_set;
|
||||
struct reset_set reset_set;
|
||||
struct list_head context_banks;
|
||||
struct mutex cb_lock;
|
||||
const char *fw_name;
|
||||
int fw_cookie;
|
||||
};
|
||||
|
||||
int msm_vidc_init_dt(struct platform_device *pdev);
|
||||
int msm_vidc_read_context_bank_resources_from_dt(struct platform_device *pdev);
|
||||
void msm_vidc_deinit_dt(struct platform_device *pdev);
|
||||
|
||||
/* A comparator to compare loads (needed later on) */
|
||||
static inline int cmp(const void *a, const void *b)
|
||||
{
|
||||
/* want to sort in reverse so flip the comparison */
|
||||
return ((struct allowed_clock_rates_table *)b)->clock_rate -
|
||||
((struct allowed_clock_rates_table *)a)->clock_rate;
|
||||
}
|
||||
|
||||
#endif // _MSM_VIDC_DT_H_
|
||||
|
@@ -244,6 +244,7 @@ enum msm_vidc_buffer_region {
|
||||
MSM_VIDC_SECURE_PIXEL,
|
||||
MSM_VIDC_SECURE_NONPIXEL,
|
||||
MSM_VIDC_SECURE_BITSTREAM,
|
||||
MSM_VIDC_REGION_MAX,
|
||||
};
|
||||
|
||||
enum msm_vidc_port_type {
|
||||
@@ -374,7 +375,6 @@ enum msm_vidc_core_capability_type {
|
||||
CLK_FREQ_THRESHOLD,
|
||||
NON_FATAL_FAULTS,
|
||||
ENC_AUTO_FRAMERATE,
|
||||
MMRM,
|
||||
DEVICE_CAPS,
|
||||
SUPPORTS_REQUESTS,
|
||||
CORE_CAP_MAX,
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#define _MSM_VIDC_MEMORY_H_
|
||||
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
|
||||
struct msm_vidc_core;
|
||||
struct msm_vidc_inst;
|
||||
|
@@ -6,11 +6,199 @@
|
||||
#ifndef _MSM_VIDC_RESOURCES_H_
|
||||
#define _MSM_VIDC_RESOURCES_H_
|
||||
|
||||
struct icc_path;
|
||||
struct regulator;
|
||||
struct clk;
|
||||
struct reset_control;
|
||||
struct llcc_slice_desc;
|
||||
struct iommu_domain;
|
||||
struct device;
|
||||
struct msm_vidc_core;
|
||||
|
||||
/*
|
||||
* These are helper macros to iterate over various lists within
|
||||
* msm_vidc_core->resource. The intention is to cut down on a lot of boiler-plate
|
||||
* code
|
||||
*/
|
||||
|
||||
/* Read as "for each 'thing' in a set of 'thingies'" */
|
||||
#define venus_hfi_for_each_thing(__device, __thing, __thingy) \
|
||||
venus_hfi_for_each_thing_continue(__device, __thing, __thingy, 0)
|
||||
|
||||
#define venus_hfi_for_each_thing_reverse(__device, __thing, __thingy) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
(__device)->resource->__thingy##_set.count - 1)
|
||||
|
||||
/* TODO: the __from parameter technically not required since we can figure it
|
||||
* out with some pointer magic (i.e. __thing - __thing##_tbl[0]). If this macro
|
||||
* sees extensive use, probably worth cleaning it up but for now omitting it
|
||||
* since it introduces unnecessary complexity.
|
||||
*/
|
||||
#define venus_hfi_for_each_thing_continue(__device, __thing, __thingy, __from) \
|
||||
for (__thing = &(__device)->resource->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing < &(__device)->resource->__thingy##_set.__thingy##_tbl[0] + \
|
||||
((__device)->resource->__thingy##_set.count - __from); \
|
||||
++__thing)
|
||||
|
||||
#define venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
__from) \
|
||||
for (__thing = &(__device)->resource->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing >= &(__device)->resource->__thingy##_set.__thingy##_tbl[0]; \
|
||||
--__thing)
|
||||
|
||||
/* Bus set helpers */
|
||||
#define venus_hfi_for_each_bus(__device, __binfo) \
|
||||
venus_hfi_for_each_thing(__device, __binfo, bus)
|
||||
#define venus_hfi_for_each_bus_reverse(__device, __binfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __binfo, bus)
|
||||
|
||||
/* Regular set helpers */
|
||||
#define venus_hfi_for_each_regulator(__device, __rinfo) \
|
||||
venus_hfi_for_each_thing(__device, __rinfo, regulator)
|
||||
#define venus_hfi_for_each_regulator_reverse(__device, __rinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __rinfo, regulator)
|
||||
#define venus_hfi_for_each_regulator_reverse_continue(__device, __rinfo, \
|
||||
__from) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
|
||||
regulator, __from)
|
||||
|
||||
/* Clock set helpers */
|
||||
#define venus_hfi_for_each_clock(__device, __cinfo) \
|
||||
venus_hfi_for_each_thing(__device, __cinfo, clock)
|
||||
#define venus_hfi_for_each_clock_reverse(__device, __cinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __cinfo, clock)
|
||||
|
||||
/* Reset clock set helpers */
|
||||
#define venus_hfi_for_each_reset_clock(__device, __rcinfo) \
|
||||
venus_hfi_for_each_thing(__device, __rcinfo, reset)
|
||||
#define venus_hfi_for_each_reset_clock_reverse(__device, __rcinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __rcinfo, reset)
|
||||
#define venus_hfi_for_each_reset_clock_reverse_continue(__device, __rinfo, \
|
||||
__from) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
|
||||
reset, __from)
|
||||
|
||||
/* Subcache set helpers */
|
||||
#define venus_hfi_for_each_subcache(__device, __sinfo) \
|
||||
venus_hfi_for_each_thing(__device, __sinfo, subcache)
|
||||
#define venus_hfi_for_each_subcache_reverse(__device, __sinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __sinfo, subcache)
|
||||
|
||||
/* Contextbank set helpers */
|
||||
#define venus_hfi_for_each_context_bank(__device, __sinfo) \
|
||||
venus_hfi_for_each_thing(__device, __sinfo, context_bank)
|
||||
#define venus_hfi_for_each_context_bank_reverse(__device, __sinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __sinfo, context_bank)
|
||||
|
||||
struct bus_info {
|
||||
struct icc_path *icc;
|
||||
const char *name;
|
||||
u32 min_kbps;
|
||||
u32 max_kbps;
|
||||
};
|
||||
|
||||
struct bus_set {
|
||||
struct bus_info *bus_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct regulator_info {
|
||||
struct regulator *regulator;
|
||||
const char *name;
|
||||
bool hw_power_collapse;
|
||||
};
|
||||
|
||||
struct regulator_set {
|
||||
struct regulator_info *regulator_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct clock_info {
|
||||
struct clk *clk;
|
||||
const char *name;
|
||||
u32 clk_id;
|
||||
bool has_scaling;
|
||||
u64 prev;
|
||||
#ifdef CONFIG_MSM_MMRM
|
||||
struct mmrm_client *mmrm_client;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct clock_set {
|
||||
struct clock_info *clock_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct reset_info {
|
||||
struct reset_control *rst;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct reset_set {
|
||||
struct reset_info *reset_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct subcache_info {
|
||||
struct llcc_slice_desc *subcache;
|
||||
const char *name;
|
||||
u32 llcc_id;
|
||||
bool isactive;
|
||||
};
|
||||
|
||||
struct subcache_set {
|
||||
struct subcache_info *subcache_tbl;
|
||||
u32 count;
|
||||
bool set_to_fw;
|
||||
};
|
||||
|
||||
struct addr_range {
|
||||
u32 start;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct context_bank_info {
|
||||
const char *name;
|
||||
struct addr_range addr_range;
|
||||
bool secure;
|
||||
bool dma_coherant;
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
u32 region;
|
||||
};
|
||||
|
||||
struct context_bank_set {
|
||||
struct context_bank_info *context_bank_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct frequency_table {
|
||||
unsigned long freq;
|
||||
};
|
||||
|
||||
struct freq_set {
|
||||
struct frequency_table *freq_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct msm_vidc_resource {
|
||||
void *core;
|
||||
u8 __iomem *register_base_addr;
|
||||
u32 irq;
|
||||
struct bus_set bus_set;
|
||||
struct regulator_set regulator_set;
|
||||
struct clock_set clock_set;
|
||||
struct reset_set reset_set;
|
||||
struct subcache_set subcache_set;
|
||||
struct context_bank_set context_bank_set;
|
||||
struct freq_set freq_set;
|
||||
int fw_cookie;
|
||||
};
|
||||
|
||||
struct msm_vidc_resources_ops {
|
||||
int (*get)(struct msm_vidc_core *core);
|
||||
void (*put)(struct msm_vidc_core *core);
|
||||
int (*init)(struct msm_vidc_core *core);
|
||||
|
||||
int (*reset_bridge)(struct msm_vidc_core *core);
|
||||
|
||||
|
@@ -12,9 +12,9 @@
|
||||
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_events.h"
|
||||
#include "firmware.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
|
||||
#define MAX_FIRMWARE_NAME_SIZE 128
|
||||
|
||||
@@ -45,15 +45,15 @@ static int protect_cp_mem(struct msm_vidc_core *core)
|
||||
memprot.cp_nonpixel_start = 0x0;
|
||||
memprot.cp_nonpixel_size = 0x0;
|
||||
|
||||
list_for_each_entry(cb, &core->dt->context_banks, list) {
|
||||
if (!strcmp(cb->name, "venus_ns")) {
|
||||
venus_hfi_for_each_context_bank(core, cb) {
|
||||
if (cb->region == MSM_VIDC_NON_SECURE) {
|
||||
memprot.cp_size = cb->addr_range.start;
|
||||
|
||||
d_vpr_h("%s: memprot.cp_size: %#x\n",
|
||||
__func__, memprot.cp_size);
|
||||
}
|
||||
|
||||
if (!strcmp(cb->name, "venus_sec_non_pixel")) {
|
||||
if (cb->region == MSM_VIDC_SECURE_NONPIXEL) {
|
||||
memprot.cp_nonpixel_start = cb->addr_range.start;
|
||||
memprot.cp_nonpixel_size = cb->addr_range.size;
|
||||
|
||||
@@ -65,7 +65,6 @@ static int protect_cp_mem(struct msm_vidc_core *core)
|
||||
|
||||
rc = qcom_scm_mem_protect_video_var(memprot.cp_start, memprot.cp_size,
|
||||
memprot.cp_nonpixel_start, memprot.cp_nonpixel_size);
|
||||
|
||||
if (rc)
|
||||
d_vpr_e("Failed to protect memory(%d)\n", rc);
|
||||
|
||||
@@ -81,6 +80,7 @@ static int __load_fw_to_memory(struct platform_device *pdev,
|
||||
{
|
||||
int rc = 0;
|
||||
const struct firmware *firmware = NULL;
|
||||
struct msm_vidc_core *core;
|
||||
char firmware_name[MAX_FIRMWARE_NAME_SIZE] = { 0 };
|
||||
struct device_node *node = NULL;
|
||||
struct resource res = { 0 };
|
||||
@@ -98,14 +98,16 @@ static int __load_fw_to_memory(struct platform_device *pdev,
|
||||
d_vpr_e("%s: Invalid fw name\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(&pdev->dev);
|
||||
if (!core) {
|
||||
d_vpr_e("%s: core not found in device %s",
|
||||
__func__, dev_name(&pdev->dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
scnprintf(firmware_name, ARRAY_SIZE(firmware_name), "%s.mbn", fw_name);
|
||||
|
||||
rc = of_property_read_u32(pdev->dev.of_node, "pas-id", &pas_id);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: failed to read \"pas-id\". error %d\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
pas_id = core->platform->data.pas_id;
|
||||
|
||||
node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
|
||||
if (!node) {
|
||||
@@ -182,13 +184,13 @@ int fw_load(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!core->dt->fw_cookie) {
|
||||
core->dt->fw_cookie = __load_fw_to_memory(core->pdev,
|
||||
core->dt->fw_name);
|
||||
if (core->dt->fw_cookie <= 0) {
|
||||
if (!core->resource->fw_cookie) {
|
||||
core->resource->fw_cookie = __load_fw_to_memory(core->pdev,
|
||||
core->platform->data.fwname);
|
||||
if (core->resource->fw_cookie <= 0) {
|
||||
d_vpr_e("%s: firmware download failed %d\n",
|
||||
__func__, core->dt->fw_cookie);
|
||||
core->dt->fw_cookie = 0;
|
||||
__func__, core->resource->fw_cookie);
|
||||
core->resource->fw_cookie = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
@@ -202,9 +204,9 @@ int fw_load(struct msm_vidc_core *core)
|
||||
return rc;
|
||||
|
||||
fail_protect_mem:
|
||||
if (core->dt->fw_cookie)
|
||||
qcom_scm_pas_shutdown(core->dt->fw_cookie);
|
||||
core->dt->fw_cookie = 0;
|
||||
if (core->resource->fw_cookie)
|
||||
qcom_scm_pas_shutdown(core->resource->fw_cookie);
|
||||
core->resource->fw_cookie = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -212,14 +214,14 @@ int fw_unload(struct msm_vidc_core *core)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!core->dt->fw_cookie)
|
||||
if (!core->resource->fw_cookie)
|
||||
return -EINVAL;
|
||||
|
||||
ret = qcom_scm_pas_shutdown(core->dt->fw_cookie);
|
||||
ret = qcom_scm_pas_shutdown(core->resource->fw_cookie);
|
||||
if (ret)
|
||||
d_vpr_e("Firmware unload failed rc=%d\n", ret);
|
||||
|
||||
core->dt->fw_cookie = 0;
|
||||
core->resource->fw_cookie = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -5,7 +5,6 @@
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_inst.h"
|
||||
@@ -209,7 +208,7 @@ static ssize_t core_info_read(struct file* file, char __user* buf,
|
||||
ssize_t len = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !core->dt) {
|
||||
if (!core || !core->resource) {
|
||||
d_vpr_e("%s: invalid params %pK\n", __func__, core);
|
||||
return 0;
|
||||
}
|
||||
@@ -226,10 +225,8 @@ static ssize_t core_info_read(struct file* file, char __user* buf,
|
||||
cur += write_str(cur, end - cur,
|
||||
"FW version : %s\n", core->fw_version);
|
||||
cur += write_str(cur, end - cur,
|
||||
"register_base: 0x%x\n", core->dt->register_base);
|
||||
cur += write_str(cur, end - cur,
|
||||
"register_size: %u\n", core->dt->register_size);
|
||||
cur += write_str(cur, end - cur, "irq: %u\n", core->dt->irq);
|
||||
"register_base: 0x%x\n", core->resource->register_base_addr);
|
||||
cur += write_str(cur, end - cur, "irq: %u\n", core->resource->irq);
|
||||
|
||||
len = simple_read_from_buffer(buf, count, ppos,
|
||||
dbuf, cur - dbuf);
|
||||
|
@@ -7,976 +7,3 @@
|
||||
#include <linux/dma-iommu.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
|
||||
static size_t get_u32_array_num_elements(struct device_node *np,
|
||||
char *name)
|
||||
{
|
||||
int len;
|
||||
size_t num_elements = 0;
|
||||
|
||||
if (!of_get_property(np, name, &len)) {
|
||||
d_vpr_e("Failed to read %s from device tree\n", name);
|
||||
goto fail_read;
|
||||
}
|
||||
|
||||
num_elements = len / sizeof(u32);
|
||||
if (num_elements <= 0) {
|
||||
d_vpr_e("%s not specified in device tree\n", name);
|
||||
goto fail_read;
|
||||
}
|
||||
return num_elements;
|
||||
|
||||
fail_read:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* msm_vidc_load_u32_table() - load dtsi table entries
|
||||
* @pdev: A pointer to the platform device.
|
||||
* @of_node: A pointer to the device node.
|
||||
* @table_name: A pointer to the dtsi table entry name.
|
||||
* @struct_size: The size of the structure which is nothing but
|
||||
* a single entry in the dtsi table.
|
||||
* @table: A pointer to the table pointer which needs to be
|
||||
* filled by the dtsi table entries.
|
||||
* @num_elements: Number of elements pointer which needs to be filled
|
||||
* with the number of elements in the table.
|
||||
*
|
||||
* This is a generic implementation to load single or multiple array
|
||||
* table from dtsi. The array elements should be of size equal to u32.
|
||||
*
|
||||
* Return: Return '0' for success else appropriate error value.
|
||||
*/
|
||||
static int msm_vidc_load_u32_table(struct platform_device *pdev,
|
||||
struct device_node *of_node, char *table_name, int struct_size,
|
||||
u32 **table, u32 *num_elements)
|
||||
{
|
||||
int rc = 0, num_elemts = 0;
|
||||
u32 *ptbl = NULL;
|
||||
|
||||
if (!of_find_property(of_node, table_name, NULL)) {
|
||||
d_vpr_h("%s not found\n", table_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
num_elemts = get_u32_array_num_elements(of_node, table_name);
|
||||
if (!num_elemts) {
|
||||
d_vpr_e("no elements in %s\n", table_name);
|
||||
return 0;
|
||||
}
|
||||
num_elemts /= struct_size / sizeof(u32);
|
||||
|
||||
ptbl = devm_kzalloc(&pdev->dev, num_elemts * struct_size, GFP_KERNEL);
|
||||
if (!ptbl) {
|
||||
d_vpr_e("Failed to alloc table %s\n", table_name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (of_property_read_u32_array(of_node, table_name, ptbl,
|
||||
num_elemts * struct_size / sizeof(u32))) {
|
||||
d_vpr_e("Failed to read %s\n", table_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*table = ptbl;
|
||||
if (num_elements)
|
||||
*num_elements = num_elemts;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_allowed_clocks_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
dt->allowed_clks_tbl = NULL;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_reg_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
dt->reg_set.reg_tbl = NULL;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_qdss_addr_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
dt->qdss_addr_set.addr_tbl = NULL;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_bus_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
dt->bus_set.bus_tbl = NULL;
|
||||
dt->bus_set.count = 0;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_buffer_usage_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
dt->buffer_usage_set.buffer_usage_tbl = NULL;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_regulator_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
for (c = 0; c < dt->regulator_set.count; ++c) {
|
||||
struct regulator_info *rinfo =
|
||||
&dt->regulator_set.regulator_tbl[c];
|
||||
|
||||
rinfo->name = NULL;
|
||||
}
|
||||
|
||||
dt->regulator_set.regulator_tbl = NULL;
|
||||
dt->regulator_set.count = 0;
|
||||
}
|
||||
|
||||
static void msm_vidc_free_clock_table(struct msm_vidc_dt *dt)
|
||||
{
|
||||
dt->clock_set.clock_tbl = NULL;
|
||||
dt->clock_set.count = 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_fw_name(struct msm_vidc_core *core)
|
||||
{
|
||||
struct platform_device *pdev = core->pdev;
|
||||
|
||||
return of_property_read_string_index(pdev->dev.of_node,
|
||||
"vidc,firmware-name", 0, &core->dt->fw_name);
|
||||
}
|
||||
|
||||
static int msm_vidc_load_reg_table(struct msm_vidc_core *core)
|
||||
{
|
||||
struct reg_set *reg_set;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
if (!of_find_property(pdev->dev.of_node, "qcom,reg-presets", NULL)) {
|
||||
/*
|
||||
* qcom,reg-presets is an optional property. It likely won't be
|
||||
* present if we don't have any register settings to program
|
||||
*/
|
||||
d_vpr_h("reg-presets not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
reg_set = &dt->reg_set;
|
||||
reg_set->count = get_u32_array_num_elements(pdev->dev.of_node,
|
||||
"qcom,reg-presets");
|
||||
reg_set->count /= sizeof(*reg_set->reg_tbl) / sizeof(u32);
|
||||
|
||||
if (!reg_set->count) {
|
||||
d_vpr_h("no elements in reg set\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
reg_set->reg_tbl = devm_kzalloc(&pdev->dev, reg_set->count *
|
||||
sizeof(*(reg_set->reg_tbl)), GFP_KERNEL);
|
||||
if (!reg_set->reg_tbl) {
|
||||
d_vpr_e("%s: Failed to alloc register table\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets",
|
||||
(u32 *)reg_set->reg_tbl, reg_set->count * 3)) {
|
||||
d_vpr_e("Failed to read register table\n");
|
||||
msm_vidc_free_reg_table(core->dt);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < reg_set->count; i++) {
|
||||
d_vpr_h("reg = %#x, value = %#x, mask = %#x\n",
|
||||
reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value,
|
||||
reg_set->reg_tbl[i].mask);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
static int msm_vidc_load_qdss_table(struct msm_vidc_core *core)
|
||||
{
|
||||
struct addr_set *qdss_addr_set;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
if (!of_find_property(pdev->dev.of_node, "qcom,qdss-presets", NULL)) {
|
||||
/*
|
||||
* qcom,qdss-presets is an optional property. It likely won't be
|
||||
* present if we don't have any register settings to program
|
||||
*/
|
||||
d_vpr_h("qdss-presets not found\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
qdss_addr_set = &dt->qdss_addr_set;
|
||||
qdss_addr_set->count = get_u32_array_num_elements(pdev->dev.of_node,
|
||||
"qcom,qdss-presets");
|
||||
qdss_addr_set->count /= sizeof(*qdss_addr_set->addr_tbl) / sizeof(u32);
|
||||
|
||||
if (!qdss_addr_set->count) {
|
||||
d_vpr_h("no elements in qdss reg set\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
qdss_addr_set->addr_tbl = devm_kzalloc(&pdev->dev,
|
||||
qdss_addr_set->count * sizeof(*qdss_addr_set->addr_tbl),
|
||||
GFP_KERNEL);
|
||||
if (!qdss_addr_set->addr_tbl) {
|
||||
d_vpr_e("%s: Failed to alloc register table\n", __func__);
|
||||
rc = -ENOMEM;
|
||||
goto err_qdss_addr_tbl;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,qdss-presets",
|
||||
(u32 *)qdss_addr_set->addr_tbl, qdss_addr_set->count * 2);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to read qdss address table\n");
|
||||
msm_vidc_free_qdss_addr_table(core->dt);
|
||||
rc = -EINVAL;
|
||||
goto err_qdss_addr_tbl;
|
||||
}
|
||||
|
||||
for (i = 0; i < qdss_addr_set->count; i++) {
|
||||
d_vpr_h("qdss addr = %x, value = %x\n",
|
||||
qdss_addr_set->addr_tbl[i].start,
|
||||
qdss_addr_set->addr_tbl[i].size);
|
||||
}
|
||||
err_qdss_addr_tbl:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_subcache_info(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0, num_subcaches = 0, c;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
struct subcache_set *subcaches = &dt->subcache_set;
|
||||
|
||||
num_subcaches = of_property_count_strings(pdev->dev.of_node,
|
||||
"cache-slice-names");
|
||||
if (num_subcaches <= 0) {
|
||||
d_vpr_h("No subcaches found\n");
|
||||
goto err_load_subcache_table_fail;
|
||||
}
|
||||
|
||||
subcaches->subcache_tbl = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*subcaches->subcache_tbl) * num_subcaches, GFP_KERNEL);
|
||||
if (!subcaches->subcache_tbl) {
|
||||
d_vpr_e("Failed to allocate memory for subcache tbl\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_load_subcache_table_fail;
|
||||
}
|
||||
|
||||
subcaches->count = num_subcaches;
|
||||
d_vpr_h("Found %d subcaches\n", num_subcaches);
|
||||
|
||||
for (c = 0; c < num_subcaches; ++c) {
|
||||
struct subcache_info *vsc = &dt->subcache_set.subcache_tbl[c];
|
||||
|
||||
of_property_read_string_index(pdev->dev.of_node,
|
||||
"cache-slice-names", c, &vsc->name);
|
||||
}
|
||||
|
||||
dt->sys_cache_present = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_load_subcache_table_fail:
|
||||
dt->sys_cache_present = false;
|
||||
subcaches->count = 0;
|
||||
subcaches->subcache_tbl = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_allowed_clocks_table(
|
||||
struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
int i;
|
||||
|
||||
if (!of_find_property(pdev->dev.of_node,
|
||||
"qcom,allowed-clock-rates", NULL)) {
|
||||
d_vpr_h("allowed-clock-rates not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = msm_vidc_load_u32_table(pdev, pdev->dev.of_node,
|
||||
"qcom,allowed-clock-rates",
|
||||
sizeof(*dt->allowed_clks_tbl),
|
||||
(u32 **)&dt->allowed_clks_tbl,
|
||||
&dt->allowed_clks_tbl_size);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: failed to read allowed clocks table\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
sort(dt->allowed_clks_tbl, dt->allowed_clks_tbl_size,
|
||||
sizeof(*dt->allowed_clks_tbl), cmp, NULL);
|
||||
|
||||
d_vpr_h("Found allowed clock rates\n");
|
||||
for (i = 0; i < dt->allowed_clks_tbl_size; i++)
|
||||
d_vpr_h(" %d\n", dt->allowed_clks_tbl[i].clock_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_bus_table(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
struct bus_set *buses = &dt->bus_set;
|
||||
int c = 0, num_buses = 0;
|
||||
u32 *bus_ranges = NULL;
|
||||
|
||||
num_buses = of_property_count_strings(pdev->dev.of_node,
|
||||
"interconnect-names");
|
||||
if (num_buses <= 0) {
|
||||
d_vpr_e("No buses found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buses->count = num_buses;
|
||||
d_vpr_h("Found %d bus interconnects\n", num_buses);
|
||||
|
||||
rc = msm_vidc_vmem_alloc(2 * num_buses * sizeof(*bus_ranges),
|
||||
(void **)&bus_ranges, " for bus ranges");
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = of_property_read_u32_array(pdev->dev.of_node,
|
||||
"qcom,bus-range-kbps", bus_ranges,
|
||||
num_buses * 2);
|
||||
if (rc) {
|
||||
d_vpr_e(
|
||||
"Failed to read bus ranges: defaulting to <0 INT_MAX>\n");
|
||||
for (c = 0; c < num_buses; c++) {
|
||||
bus_ranges[c * 2] = 0;
|
||||
bus_ranges[c * 2 + 1] = INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
buses->bus_tbl = devm_kzalloc(&pdev->dev, num_buses *
|
||||
sizeof(*buses->bus_tbl), GFP_KERNEL);
|
||||
if (!buses->bus_tbl) {
|
||||
d_vpr_e("No memory for bus table\n");
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (c = 0; c < num_buses; c++) {
|
||||
struct bus_info *bus = &dt->bus_set.bus_tbl[c];
|
||||
|
||||
of_property_read_string_index(pdev->dev.of_node,
|
||||
"interconnect-names", c, &bus->name);
|
||||
|
||||
bus->dev = &pdev->dev;
|
||||
bus->range[0] = bus_ranges[c * 2];
|
||||
bus->range[1] = bus_ranges[c * 2 + 1];
|
||||
|
||||
d_vpr_h("Found bus %s, range [%d %d]\n", bus->name,
|
||||
bus->range[0], bus->range[1]);
|
||||
}
|
||||
|
||||
exit:
|
||||
msm_vidc_vmem_free((void **) &bus_ranges);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* TODO: move this to platform data */
|
||||
static int msm_vidc_load_buffer_usage_table(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
struct buffer_usage_set *buffer_usage_set = &dt->buffer_usage_set;
|
||||
|
||||
if (!of_find_property(pdev->dev.of_node,
|
||||
"qcom,buffer-type-tz-usage-table", NULL)) {
|
||||
/*
|
||||
* qcom,buffer-type-tz-usage-table is an optional property. It
|
||||
* likely won't be present if the core doesn't support content
|
||||
* protection
|
||||
*/
|
||||
d_vpr_h("buffer-type-tz-usage-table not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer_usage_set->count = get_u32_array_num_elements(
|
||||
pdev->dev.of_node, "qcom,buffer-type-tz-usage-table");
|
||||
buffer_usage_set->count /=
|
||||
sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32);
|
||||
if (!buffer_usage_set->count) {
|
||||
d_vpr_h("no elements in buffer usage set\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer_usage_set->buffer_usage_tbl = devm_kzalloc(&pdev->dev,
|
||||
buffer_usage_set->count *
|
||||
sizeof(*buffer_usage_set->buffer_usage_tbl),
|
||||
GFP_KERNEL);
|
||||
if (!buffer_usage_set->buffer_usage_tbl) {
|
||||
d_vpr_e("%s: Failed to alloc buffer usage table\n",
|
||||
__func__);
|
||||
rc = -ENOMEM;
|
||||
goto err_load_buf_usage;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(pdev->dev.of_node,
|
||||
"qcom,buffer-type-tz-usage-table",
|
||||
(u32 *)buffer_usage_set->buffer_usage_tbl,
|
||||
buffer_usage_set->count *
|
||||
sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32));
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to read buffer usage table\n");
|
||||
goto err_load_buf_usage;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_load_buf_usage:
|
||||
msm_vidc_free_buffer_usage_table(core->dt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_regulator_table(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
struct regulator_set *regulators = &dt->regulator_set;
|
||||
struct device_node *domains_parent_node = NULL;
|
||||
struct property *domains_property = NULL;
|
||||
int reg_count = 0;
|
||||
|
||||
regulators->count = 0;
|
||||
regulators->regulator_tbl = NULL;
|
||||
|
||||
domains_parent_node = pdev->dev.of_node;
|
||||
for_each_property_of_node(domains_parent_node, domains_property) {
|
||||
const char *search_string = "-supply";
|
||||
char *supply;
|
||||
bool matched = false;
|
||||
|
||||
/* check if current property is possibly a regulator */
|
||||
supply = strnstr(domains_property->name, search_string,
|
||||
strlen(domains_property->name) + 1);
|
||||
matched = supply && (*(supply + strlen(search_string)) == '\0');
|
||||
if (!matched)
|
||||
continue;
|
||||
|
||||
reg_count++;
|
||||
}
|
||||
|
||||
regulators->regulator_tbl = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*regulators->regulator_tbl) *
|
||||
reg_count, GFP_KERNEL);
|
||||
|
||||
if (!regulators->regulator_tbl) {
|
||||
rc = -ENOMEM;
|
||||
d_vpr_e("Failed to alloc memory for regulator table\n");
|
||||
goto err_reg_tbl_alloc;
|
||||
}
|
||||
|
||||
for_each_property_of_node(domains_parent_node, domains_property) {
|
||||
const char *search_string = "-supply";
|
||||
char *supply;
|
||||
bool matched = false;
|
||||
struct device_node *regulator_node = NULL;
|
||||
struct regulator_info *rinfo = NULL;
|
||||
|
||||
/* check if current property is possibly a regulator */
|
||||
supply = strnstr(domains_property->name, search_string,
|
||||
strlen(domains_property->name) + 1);
|
||||
matched = supply && (supply[strlen(search_string)] == '\0');
|
||||
if (!matched)
|
||||
continue;
|
||||
|
||||
/* make sure prop isn't being misused */
|
||||
regulator_node = of_parse_phandle(domains_parent_node,
|
||||
domains_property->name, 0);
|
||||
if (IS_ERR(regulator_node)) {
|
||||
d_vpr_e("%s is not a phandle\n",
|
||||
domains_property->name);
|
||||
continue;
|
||||
}
|
||||
regulators->count++;
|
||||
|
||||
/* populate regulator info */
|
||||
rinfo = ®ulators->regulator_tbl[regulators->count - 1];
|
||||
rinfo->name = devm_kzalloc(&pdev->dev,
|
||||
(supply - domains_property->name) + 1, GFP_KERNEL);
|
||||
if (!rinfo->name) {
|
||||
rc = -ENOMEM;
|
||||
d_vpr_e("Failed to alloc memory for regulator name\n");
|
||||
goto err_reg_name_alloc;
|
||||
}
|
||||
strlcpy(rinfo->name, domains_property->name,
|
||||
(supply - domains_property->name) + 1);
|
||||
|
||||
rinfo->has_hw_power_collapse = of_property_read_bool(
|
||||
regulator_node, "qcom,support-hw-trigger");
|
||||
|
||||
d_vpr_h("Found regulator %s: h/w collapse = %s\n",
|
||||
rinfo->name,
|
||||
rinfo->has_hw_power_collapse ? "yes" : "no");
|
||||
}
|
||||
|
||||
if (!regulators->count)
|
||||
d_vpr_h("No regulators found");
|
||||
|
||||
return 0;
|
||||
|
||||
err_reg_name_alloc:
|
||||
err_reg_tbl_alloc:
|
||||
msm_vidc_free_regulator_table(core->dt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_clock_table(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0, num_clocks = 0, c = 0;
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
int *clock_ids = NULL;
|
||||
int *clock_props = NULL;
|
||||
struct clock_set *clocks = &dt->clock_set;
|
||||
|
||||
num_clocks = of_property_count_strings(pdev->dev.of_node,
|
||||
"clock-names");
|
||||
if (num_clocks <= 0) {
|
||||
d_vpr_h("No clocks found\n");
|
||||
clocks->count = 0;
|
||||
rc = 0;
|
||||
goto err_load_clk_table_fail;
|
||||
}
|
||||
|
||||
clock_ids = devm_kzalloc(&pdev->dev, num_clocks *
|
||||
sizeof(*clock_ids), GFP_KERNEL);
|
||||
if (!clock_ids) {
|
||||
d_vpr_e("No memory to read clock ids\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_load_clk_table_fail;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(pdev->dev.of_node,
|
||||
"clock-ids", clock_ids,
|
||||
num_clocks);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to read clock ids: %d\n", rc);
|
||||
goto err_load_clk_prop_fail;
|
||||
}
|
||||
|
||||
clock_props = devm_kzalloc(&pdev->dev, num_clocks *
|
||||
sizeof(*clock_props), GFP_KERNEL);
|
||||
if (!clock_props) {
|
||||
d_vpr_e("No memory to read clock properties\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_load_clk_table_fail;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(pdev->dev.of_node,
|
||||
"qcom,clock-configs", clock_props,
|
||||
num_clocks);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to read clock properties: %d\n", rc);
|
||||
goto err_load_clk_prop_fail;
|
||||
}
|
||||
|
||||
clocks->clock_tbl = devm_kzalloc(&pdev->dev, sizeof(*clocks->clock_tbl)
|
||||
* num_clocks, GFP_KERNEL);
|
||||
if (!clocks->clock_tbl) {
|
||||
d_vpr_e("Failed to allocate memory for clock tbl\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_load_clk_prop_fail;
|
||||
}
|
||||
|
||||
clocks->count = num_clocks;
|
||||
d_vpr_h("Found %d clocks\n", num_clocks);
|
||||
|
||||
for (c = 0; c < num_clocks; ++c) {
|
||||
struct clock_info *vc = &dt->clock_set.clock_tbl[c];
|
||||
|
||||
of_property_read_string_index(pdev->dev.of_node,
|
||||
"clock-names", c, &vc->name);
|
||||
|
||||
vc->clk_id = clock_ids[c];
|
||||
|
||||
if (clock_props[c] & CLOCK_PROP_HAS_SCALING) {
|
||||
vc->has_scaling = true;
|
||||
} else {
|
||||
vc->has_scaling = false;
|
||||
}
|
||||
|
||||
if (clock_props[c] & CLOCK_PROP_HAS_MEM_RETENTION)
|
||||
vc->has_mem_retention = true;
|
||||
else
|
||||
vc->has_mem_retention = false;
|
||||
|
||||
d_vpr_h("Found clock %s: scale-able = %s\n", vc->name,
|
||||
vc->has_scaling ? "yes" : "no");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
err_load_clk_prop_fail:
|
||||
err_load_clk_table_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_reset_table(struct msm_vidc_core *core)
|
||||
{
|
||||
struct platform_device *pdev = core->pdev;
|
||||
struct msm_vidc_dt *dt = core->dt;
|
||||
struct reset_set *rst = &dt->reset_set;
|
||||
int num_clocks = 0, c = 0;
|
||||
|
||||
num_clocks = of_property_count_strings(pdev->dev.of_node,
|
||||
"reset-names");
|
||||
if (num_clocks <= 0) {
|
||||
d_vpr_h("No reset clocks found\n");
|
||||
rst->count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rst->reset_tbl = devm_kcalloc(&pdev->dev, num_clocks,
|
||||
sizeof(*rst->reset_tbl), GFP_KERNEL);
|
||||
if (!rst->reset_tbl)
|
||||
return -ENOMEM;
|
||||
|
||||
rst->count = num_clocks;
|
||||
d_vpr_h("Found %d reset clocks\n", num_clocks);
|
||||
|
||||
for (c = 0; c < num_clocks; ++c) {
|
||||
struct reset_info *rc = &dt->reset_set.reset_tbl[c];
|
||||
|
||||
of_property_read_string_index(pdev->dev.of_node,
|
||||
"reset-names", c, &rc->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_read_resources_from_dt(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct msm_vidc_dt *dt;
|
||||
struct resource *kres;
|
||||
|
||||
if (!pdev) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(&pdev->dev);
|
||||
if (!core || !core->dt) {
|
||||
d_vpr_e("%s: core not found in device %s",
|
||||
__func__, dev_name(&pdev->dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
dt = core->dt;
|
||||
|
||||
INIT_LIST_HEAD(&dt->context_banks);
|
||||
|
||||
kres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dt->register_base = kres ? kres->start : -1;
|
||||
dt->register_size = kres ? (kres->end + 1 - kres->start) : -1;
|
||||
d_vpr_h("%s: register base %pa, size %#x\n",
|
||||
__func__, &dt->register_base, dt->register_size);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0))
|
||||
dt->irq = platform_get_irq(pdev, 0);
|
||||
#else
|
||||
kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
dt->irq = kres ? kres->start : -1;
|
||||
#endif
|
||||
if (dt->irq < 0)
|
||||
d_vpr_e("%s: get irq failed, %d\n", __func__, dt->irq);
|
||||
|
||||
d_vpr_h("%s: irq %d\n", __func__, dt->irq);
|
||||
|
||||
rc = msm_vidc_load_fw_name(core);
|
||||
if (rc)
|
||||
d_vpr_e("%s: failed to load fw name, rc %d, using default fw\n",
|
||||
__func__, rc);
|
||||
|
||||
rc = msm_vidc_load_subcache_info(core);
|
||||
if (rc)
|
||||
d_vpr_e("Failed to load subcache info: %d\n", rc);
|
||||
|
||||
rc = msm_vidc_load_qdss_table(core);
|
||||
if (rc)
|
||||
d_vpr_e("Failed to load qdss reg table: %d\n", rc);
|
||||
|
||||
rc = msm_vidc_load_reg_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load reg table: %d\n", rc);
|
||||
goto err_load_reg_table;
|
||||
}
|
||||
|
||||
// TODO: move this table to platform
|
||||
rc = msm_vidc_load_buffer_usage_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load buffer usage table: %d\n", rc);
|
||||
goto err_load_buffer_usage_table;
|
||||
}
|
||||
|
||||
rc = msm_vidc_load_regulator_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load list of regulators %d\n", rc);
|
||||
goto err_load_regulator_table;
|
||||
}
|
||||
|
||||
rc = msm_vidc_load_bus_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load bus table: %d\n", rc);
|
||||
goto err_load_bus_table;
|
||||
}
|
||||
|
||||
rc = msm_vidc_load_clock_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load clock table: %d\n", rc);
|
||||
goto err_load_clock_table;
|
||||
}
|
||||
|
||||
// TODO: move this table to platform
|
||||
rc = msm_vidc_load_allowed_clocks_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load allowed clocks table: %d\n", rc);
|
||||
goto err_load_allowed_clocks_table;
|
||||
}
|
||||
|
||||
rc = msm_vidc_load_reset_table(core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to load reset table: %d\n", rc);
|
||||
goto err_load_reset_table;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
err_load_reset_table:
|
||||
msm_vidc_free_allowed_clocks_table(core->dt);
|
||||
err_load_allowed_clocks_table:
|
||||
msm_vidc_free_clock_table(core->dt);
|
||||
err_load_clock_table:
|
||||
msm_vidc_free_bus_table(core->dt);
|
||||
err_load_bus_table:
|
||||
msm_vidc_free_regulator_table(core->dt);
|
||||
err_load_regulator_table:
|
||||
msm_vidc_free_buffer_usage_table(core->dt);
|
||||
err_load_buffer_usage_table:
|
||||
msm_vidc_free_reg_table(core->dt);
|
||||
err_load_reg_table:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_setup_context_bank(struct msm_vidc_core *core,
|
||||
struct context_bank_info *cb, struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct bus_type *bus;
|
||||
|
||||
if (!core || !dev || !cb) {
|
||||
d_vpr_e("%s: Invalid Input params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cb->dev = dev;
|
||||
|
||||
bus = cb->dev->bus;
|
||||
if (IS_ERR_OR_NULL(bus)) {
|
||||
d_vpr_e("%s: failed to get bus type\n", __func__);
|
||||
rc = PTR_ERR(bus) ? PTR_ERR(bus) : -ENODEV;
|
||||
goto remove_cb;
|
||||
}
|
||||
|
||||
cb->domain = iommu_get_domain_for_dev(cb->dev);
|
||||
|
||||
/*
|
||||
* When memory is fragmented, below configuration increases the
|
||||
* possibility to get a mapping for buffer in the configured CB.
|
||||
*/
|
||||
|
||||
/* remove kernel version condition once below api is whitelisted in pineapple */
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0))
|
||||
iommu_dma_enable_best_fit_algo(cb->dev);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* configure device segment size and segment boundary to ensure
|
||||
* iommu mapping returns one mapping (which is required for partial
|
||||
* cache operations)
|
||||
*/
|
||||
if (!dev->dma_parms)
|
||||
dev->dma_parms =
|
||||
devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
|
||||
dma_set_max_seg_size(dev, (unsigned int)DMA_BIT_MASK(32));
|
||||
dma_set_seg_boundary(dev, (unsigned long)DMA_BIT_MASK(64));
|
||||
|
||||
d_vpr_h("Attached %s and created mapping\n", dev_name(dev));
|
||||
d_vpr_h(
|
||||
"Context bank: %s, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, domain: %pK",
|
||||
cb->name, cb->is_secure, cb->addr_range.start,
|
||||
cb->addr_range.size, cb->dev, cb->domain);
|
||||
remove_cb:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_populate_context_bank(struct device *dev,
|
||||
struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
struct context_bank_info *cb = NULL;
|
||||
struct device_node *np = NULL;
|
||||
|
||||
if (!dev || !core || !core->dt) {
|
||||
d_vpr_e("%s: invalid inputs\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
np = dev->of_node;
|
||||
cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL);
|
||||
if (!cb) {
|
||||
d_vpr_e("%s: Failed to allocate cb\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&cb->list);
|
||||
rc = of_property_read_string(np, "label", &cb->name);
|
||||
if (rc) {
|
||||
d_vpr_h("Failed to read cb label from device tree\n");
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
d_vpr_h("%s: context bank has name %s\n", __func__, cb->name);
|
||||
rc = of_property_read_u32_array(np, "virtual-addr-pool",
|
||||
(u32 *)&cb->addr_range, 2);
|
||||
if (rc) {
|
||||
d_vpr_e("Could not read addr pool: context bank: %s %d\n",
|
||||
cb->name, rc);
|
||||
goto err_setup_cb;
|
||||
}
|
||||
|
||||
cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank");
|
||||
d_vpr_h("context bank %s: secure = %d\n",
|
||||
cb->name, cb->is_secure);
|
||||
|
||||
d_vpr_h("context bank %s address start %x size %x\n",
|
||||
cb->name, cb->addr_range.start,
|
||||
cb->addr_range.size);
|
||||
|
||||
rc = msm_vidc_setup_context_bank(core, cb, dev);
|
||||
if (rc) {
|
||||
d_vpr_e("Cannot setup context bank %d\n", rc);
|
||||
goto err_setup_cb;
|
||||
}
|
||||
|
||||
core_lock(core, __func__);
|
||||
list_add_tail(&cb->list, &core->dt->context_banks);
|
||||
core_unlock(core, __func__);
|
||||
|
||||
iommu_set_fault_handler(cb->domain,
|
||||
msm_vidc_smmu_fault_handler, (void *)core);
|
||||
|
||||
return 0;
|
||||
|
||||
err_setup_cb:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_read_context_bank_resources_from_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_vidc_core *core;
|
||||
int rc = 0;
|
||||
|
||||
if (!pdev) {
|
||||
d_vpr_e("Invalid platform device\n");
|
||||
return -EINVAL;
|
||||
} else if (!pdev->dev.parent) {
|
||||
d_vpr_e("Failed to find a parent for %s\n",
|
||||
dev_name(&pdev->dev));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(pdev->dev.parent);
|
||||
if (!core) {
|
||||
d_vpr_e("Failed to find cookie in parent device %s",
|
||||
dev_name(pdev->dev.parent));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vidc_populate_context_bank(&pdev->dev, core);
|
||||
if (rc)
|
||||
d_vpr_e("Failed to probe context bank\n");
|
||||
else
|
||||
d_vpr_h("Successfully probed context bank\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_vidc_deinit_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
if (!pdev) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(&pdev->dev);
|
||||
if (!core) {
|
||||
d_vpr_e("%s: core not found in device %s",
|
||||
__func__, dev_name(&pdev->dev));
|
||||
return;
|
||||
} else if (!core->dt) {
|
||||
d_vpr_e("%s: invalid dt in device %s",
|
||||
__func__, dev_name(&pdev->dev));
|
||||
return;
|
||||
}
|
||||
|
||||
msm_vidc_free_clock_table(core->dt);
|
||||
msm_vidc_free_regulator_table(core->dt);
|
||||
msm_vidc_free_allowed_clocks_table(core->dt);
|
||||
msm_vidc_free_reg_table(core->dt);
|
||||
msm_vidc_free_qdss_addr_table(core->dt);
|
||||
msm_vidc_free_bus_table(core->dt);
|
||||
msm_vidc_free_buffer_usage_table(core->dt);
|
||||
msm_vidc_vmem_free((void **)&core->dt);
|
||||
}
|
||||
|
||||
int msm_vidc_init_dt(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_dt *dt = NULL;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
if (!pdev) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(&pdev->dev);
|
||||
if (!core) {
|
||||
d_vpr_e("%s: core not found in device %s",
|
||||
__func__, dev_name(&pdev->dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vidc_vmem_alloc(sizeof(struct msm_vidc_dt), (void **)&dt, __func__);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
core->dt = dt;
|
||||
dt->core = core;
|
||||
|
||||
rc = msm_vidc_read_resources_from_dt(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_events.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
#include "venus_hfi.h"
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0))
|
||||
@@ -30,27 +31,15 @@ struct msm_vidc_buf_region_name {
|
||||
struct context_bank_info *msm_vidc_get_context_bank(struct msm_vidc_core *core,
|
||||
enum msm_vidc_buffer_region region)
|
||||
{
|
||||
const char *name;
|
||||
struct context_bank_info *cb = NULL, *match = NULL;
|
||||
static const struct msm_vidc_buf_region_name buf_region_name[] = {
|
||||
{MSM_VIDC_REGION_NONE, "none" },
|
||||
{MSM_VIDC_NON_SECURE, "venus_ns" },
|
||||
{MSM_VIDC_NON_SECURE_PIXEL, "venus_ns_pixel" },
|
||||
{MSM_VIDC_SECURE_PIXEL, "venus_sec_pixel" },
|
||||
{MSM_VIDC_SECURE_NONPIXEL, "venus_sec_non_pixel" },
|
||||
{MSM_VIDC_SECURE_BITSTREAM, "venus_sec_bitstream" },
|
||||
};
|
||||
|
||||
if (!region || region > ARRAY_SIZE(buf_region_name))
|
||||
goto exit;
|
||||
if (!region || region >= MSM_VIDC_REGION_MAX) {
|
||||
d_vpr_e("Invalid region %#x\n", region);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buf_region_name[region].region != region)
|
||||
goto exit;
|
||||
|
||||
name = buf_region_name[region].name;
|
||||
|
||||
list_for_each_entry(cb, &core->dt->context_banks, list) {
|
||||
if (!strcmp(cb->name, name)) {
|
||||
venus_hfi_for_each_context_bank(core, cb) {
|
||||
if (cb->region == region) {
|
||||
match = cb;
|
||||
break;
|
||||
}
|
||||
@@ -59,10 +48,6 @@ struct context_bank_info *msm_vidc_get_context_bank(struct msm_vidc_core *core,
|
||||
d_vpr_e("cb not found for region %#x\n", region);
|
||||
|
||||
return match;
|
||||
|
||||
exit:
|
||||
d_vpr_e("Invalid region %#x\n", region);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dma_buf *msm_vidc_memory_get_dmabuf(struct msm_vidc_inst *inst, int fd)
|
||||
@@ -245,7 +230,7 @@ int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
|
||||
* required buffer size
|
||||
*/
|
||||
attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
|
||||
if (core->dt->sys_cache_present)
|
||||
if (is_sys_cache_present(core))
|
||||
attach->dma_map_attrs |=
|
||||
DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "msm_vidc_inst.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
#include "msm_vidc_buffer.h"
|
||||
@@ -92,7 +91,7 @@ void __dump(struct dump dump[], int len)
|
||||
u64 msm_vidc_max_freq(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_core* core;
|
||||
struct allowed_clock_rates_table *allowed_clks_tbl;
|
||||
struct frequency_table *freq_tbl;
|
||||
u64 freq = 0;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
@@ -100,12 +99,14 @@ u64 msm_vidc_max_freq(struct msm_vidc_inst *inst)
|
||||
return freq;
|
||||
}
|
||||
core = inst->core;
|
||||
if (!core->dt || !core->dt->allowed_clks_tbl) {
|
||||
i_vpr_e(inst, "%s: invalid params\n", __func__);
|
||||
|
||||
if (!core->resource || !core->resource->freq_set.freq_tbl ||
|
||||
!core->resource->freq_set.count) {
|
||||
i_vpr_e(inst, "%s: invalid frequency table\n", __func__);
|
||||
return freq;
|
||||
}
|
||||
allowed_clks_tbl = core->dt->allowed_clks_tbl;
|
||||
freq = allowed_clks_tbl[0].clock_rate;
|
||||
freq_tbl = core->resource->freq_set.freq_tbl;
|
||||
freq = freq_tbl[0].freq;
|
||||
|
||||
i_vpr_l(inst, "%s: rate = %llu\n", __func__, freq);
|
||||
return freq;
|
||||
@@ -267,8 +268,8 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
if (!core->dt) {
|
||||
i_vpr_e(inst, "%s: invalid dt params\n", __func__);
|
||||
if (!core->resource) {
|
||||
i_vpr_e(inst, "%s: invalid resource params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
vote_data = &inst->bus_data;
|
||||
@@ -347,7 +348,7 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst)
|
||||
}
|
||||
}
|
||||
vote_data->work_mode = inst->capabilities->cap[STAGE].value;
|
||||
if (core->dt->sys_cache_res_set)
|
||||
if (core->resource->subcache_set.set_to_fw)
|
||||
vote_data->use_sys_cache = true;
|
||||
vote_data->num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value;
|
||||
fill_dynamic_stats(inst, vote_data);
|
||||
@@ -382,8 +383,10 @@ int msm_vidc_set_clocks(struct msm_vidc_inst* inst)
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
if (!core->dt || !core->dt->allowed_clks_tbl) {
|
||||
d_vpr_e("%s: invalid dt params\n", __func__);
|
||||
|
||||
if (!core->resource || !core->resource->freq_set.freq_tbl ||
|
||||
!core->resource->freq_set.count) {
|
||||
d_vpr_e("%s: invalid frequency table\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -422,8 +425,8 @@ int msm_vidc_set_clocks(struct msm_vidc_inst* inst)
|
||||
* keep checking from lowest to highest rate until
|
||||
* table rate >= requested rate
|
||||
*/
|
||||
for (i = core->dt->allowed_clks_tbl_size - 1; i >= 0; i--) {
|
||||
rate = core->dt->allowed_clks_tbl[i].clock_rate;
|
||||
for (i = core->resource->freq_set.count - 1; i >= 0; i--) {
|
||||
rate = core->resource->freq_set.freq_tbl[i].freq;
|
||||
if (rate >= freq)
|
||||
break;
|
||||
}
|
||||
@@ -431,10 +434,10 @@ int msm_vidc_set_clocks(struct msm_vidc_inst* inst)
|
||||
i = 0;
|
||||
if (increment) {
|
||||
if (i > 0)
|
||||
rate = core->dt->allowed_clks_tbl[i - 1].clock_rate;
|
||||
rate = core->resource->freq_set.freq_tbl[i - 1].freq;
|
||||
} else if (decrement) {
|
||||
if (i < (int) (core->dt->allowed_clks_tbl_size - 1))
|
||||
rate = core->dt->allowed_clks_tbl[i + 1].clock_rate;
|
||||
if (i < (int) (core->platform->data.freq_tbl_size - 1))
|
||||
rate = core->resource->freq_set.freq_tbl[i + 1].freq;
|
||||
}
|
||||
core->power.clk_freq = (u32)rate;
|
||||
|
||||
|
@@ -10,11 +10,15 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/dma-iommu.h>
|
||||
#ifdef CONFIG_MSM_MMRM
|
||||
#include <linux/soc/qcom/msm_mmrm.h>
|
||||
#endif
|
||||
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_driver.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
#include "msm_vidc_core.h"
|
||||
#include "msm_vidc_memory.h"
|
||||
@@ -28,62 +32,50 @@ struct msm_vidc_core *g_core;
|
||||
const char video_banner[] = "Video-Banner: (" VIDEO_COMPILE_BY "@"
|
||||
VIDEO_COMPILE_HOST ") (" VIDEO_COMPILE_TIME ")";
|
||||
|
||||
static int msm_vidc_deinit_irq(struct msm_vidc_core *core)
|
||||
static inline bool is_video_device(struct device *dev)
|
||||
{
|
||||
struct msm_vidc_dt *dt;
|
||||
|
||||
if (!core || !core->pdev || !core->dt) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dt = core->dt;
|
||||
d_vpr_h("%s: reg_base = %pa, reg_size = %#x\n",
|
||||
__func__, &dt->register_base, dt->register_size);
|
||||
|
||||
dt->irq = 0;
|
||||
|
||||
if (core->register_base_addr)
|
||||
devm_iounmap(&core->pdev->dev, core->register_base_addr);
|
||||
core->register_base_addr = 0;
|
||||
return 0;
|
||||
return !!(of_device_is_compatible(dev->of_node, "qcom,sm8450-vidc") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8550-vidc-v2") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,sm8650-vidc"));
|
||||
}
|
||||
|
||||
static int msm_vidc_init_irq(struct msm_vidc_core *core)
|
||||
static inline bool is_video_context_bank_device(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_dt *dt;
|
||||
return !!(of_device_is_compatible(dev->of_node, "qcom,vidc,cb-sec-pxl") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,vidc,cb-sec-bitstream") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,vidc,cb-sec-non-pxl") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,vidc,cb-ns") ||
|
||||
of_device_is_compatible(dev->of_node, "qcom,vidc,cb-ns-pxl"));
|
||||
}
|
||||
|
||||
if (!core || !core->pdev || !core->dt) {
|
||||
static int msm_vidc_init_resources(struct msm_vidc_core *core)
|
||||
{
|
||||
const struct msm_vidc_resources_ops *res_ops;
|
||||
struct msm_vidc_resource *res = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dt = core->dt;
|
||||
res_ops = core->res_ops;
|
||||
|
||||
core->register_base_addr = devm_ioremap(&core->pdev->dev,
|
||||
dt->register_base, dt->register_size);
|
||||
if (!core->register_base_addr) {
|
||||
d_vpr_e("could not map reg addr %pa of size %d\n",
|
||||
&dt->register_base, dt->register_size);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
res = devm_kzalloc(&core->pdev->dev, sizeof(*res), GFP_KERNEL);
|
||||
if (!res) {
|
||||
d_vpr_e("%s: failed to alloc memory for resource\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
res->core = core;
|
||||
core->resource = res;
|
||||
|
||||
rc = devm_request_threaded_irq(&core->pdev->dev, dt->irq, venus_hfi_isr,
|
||||
venus_hfi_isr_handler, IRQF_TRIGGER_HIGH, "msm-vidc", core);
|
||||
rc = res_ops->init(core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: Failed to allocate venus IRQ\n", __func__);
|
||||
goto exit;
|
||||
d_vpr_e("%s: Failed to init resources: %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
disable_irq_nosync(dt->irq);
|
||||
|
||||
d_vpr_h("%s: reg_base = %pa, reg_size = %d\n",
|
||||
__func__, &dt->register_base, dt->register_size);
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
msm_vidc_deinit_irq(core);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t sku_version_show(struct device *dev,
|
||||
@@ -95,8 +87,7 @@ static ssize_t sku_version_show(struct device *dev,
|
||||
* Default sku version: 0
|
||||
* driver possibly not probed yet or not the main device.
|
||||
*/
|
||||
if (!dev || !dev->driver ||
|
||||
!of_device_is_compatible(dev->of_node, "qcom,msm-vidc"))
|
||||
if (!dev || !dev->driver)
|
||||
return 0;
|
||||
|
||||
core = dev_get_drvdata(dev);
|
||||
@@ -121,8 +112,15 @@ static struct attribute_group msm_vidc_core_attr_group = {
|
||||
};
|
||||
|
||||
static const struct of_device_id msm_vidc_dt_match[] = {
|
||||
{.compatible = "qcom,msm-vidc"},
|
||||
{.compatible = "qcom,msm-vidc,context-bank"},
|
||||
{.compatible = "qcom,sm8450-vidc"},
|
||||
{.compatible = "qcom,sm8550-vidc"},
|
||||
{.compatible = "qcom,sm8550-vidc-v2"},
|
||||
{.compatible = "qcom,sm8650-vidc"},
|
||||
{.compatible = "qcom,vidc,cb-ns-pxl"},
|
||||
{.compatible = "qcom,vidc,cb-ns"},
|
||||
{.compatible = "qcom,vidc,cb-sec-non-pxl"},
|
||||
{.compatible = "qcom,vidc,cb-sec-bitstream"},
|
||||
{.compatible = "qcom,vidc,cb-sec-pxl"},
|
||||
MSM_VIDC_EMPTY_BRACE
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
|
||||
@@ -137,7 +135,7 @@ static void msm_vidc_unregister_video_device(struct msm_vidc_core *core,
|
||||
{
|
||||
int index;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
d_vpr_h("%s: domain %d\n", __func__, type);
|
||||
|
||||
if (type == MSM_VIDC_DECODER)
|
||||
index = 0;
|
||||
@@ -163,7 +161,7 @@ static int msm_vidc_register_video_device(struct msm_vidc_core *core,
|
||||
int rc = 0;
|
||||
int index, media_index;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
d_vpr_h("%s: domain %d\n", __func__, type);
|
||||
|
||||
if (!core || !core->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -236,32 +234,32 @@ static int msm_vidc_check_mmrm_support(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !core->capabilities) {
|
||||
if (!core || !core->platform) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!core->capabilities[MMRM].value)
|
||||
if (!is_mmrm_supported(core))
|
||||
goto exit;
|
||||
|
||||
if (!mmrm_client_check_scaling_supported(MMRM_CLIENT_CLOCK, 0)) {
|
||||
d_vpr_e("%s: MMRM not supported\n", __func__);
|
||||
core->capabilities[MMRM].value = 0;
|
||||
core->platform->data.supports_mmrm = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
d_vpr_h("%s: %d\n", __func__, core->capabilities[MMRM].value);
|
||||
d_vpr_h("%s: %d\n", __func__, is_mmrm_supported(core));
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static int msm_vidc_check_mmrm_support(struct msm_vidc_core *core)
|
||||
{
|
||||
if (!core || !core->capabilities) {
|
||||
if (!core || !core->platform) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core->capabilities[MMRM].value = 0;
|
||||
core->platform->data.supports_mmrm = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -358,6 +356,83 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct context_bank_info *get_context_bank(
|
||||
struct msm_vidc_core *core, struct device *dev)
|
||||
{
|
||||
struct context_bank_info *cb = NULL, *match = NULL;
|
||||
|
||||
if (!core || !dev) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
venus_hfi_for_each_context_bank(core, cb) {
|
||||
if (of_device_is_compatible(dev->of_node, cb->name)) {
|
||||
match = cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
d_vpr_e("cb not found for dev %s\n", dev_name(dev));
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static int msm_vidc_setup_context_bank(struct msm_vidc_core *core,
|
||||
struct device *dev)
|
||||
{
|
||||
struct context_bank_info *cb = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !dev) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cb = get_context_bank(core, dev);
|
||||
if (!cb) {
|
||||
d_vpr_e("%s: Failed to get context bank device for %s\n",
|
||||
__func__, dev_name(dev));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* populate dev & domain field */
|
||||
cb->dev = dev;
|
||||
cb->domain = iommu_get_domain_for_dev(cb->dev);
|
||||
|
||||
/*
|
||||
* When memory is fragmented, below configuration increases the
|
||||
* possibility to get a mapping for buffer in the configured CB.
|
||||
*/
|
||||
|
||||
/* remove kernel version condition once below api is whitelisted in pineapple */
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))
|
||||
iommu_dma_enable_best_fit_algo(cb->dev);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* configure device segment size and segment boundary to ensure
|
||||
* iommu mapping returns one mapping (which is required for partial
|
||||
* cache operations)
|
||||
*/
|
||||
if (!dev->dma_parms)
|
||||
dev->dma_parms =
|
||||
devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
|
||||
dma_set_max_seg_size(dev, (unsigned int)DMA_BIT_MASK(32));
|
||||
dma_set_seg_boundary(dev, (unsigned long)DMA_BIT_MASK(64));
|
||||
|
||||
iommu_set_fault_handler(cb->domain,
|
||||
msm_vidc_smmu_fault_handler, (void *)core);
|
||||
|
||||
d_vpr_h(
|
||||
"%s: name %s addr start %x size %x secure %d dma_coherant %d region %d dev_name %s domain %pK\n",
|
||||
__func__, cb->name, cb->addr_range.start,
|
||||
cb->addr_range.size, cb->secure, cb->dma_coherant,
|
||||
cb->region, dev_name(cb->dev), cb->domain);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_component_compare_of(struct device *dev, void *data)
|
||||
{
|
||||
return dev->of_node == data;
|
||||
@@ -372,8 +447,35 @@ static void msm_vidc_component_release_of(struct device *dev, void *data)
|
||||
static int msm_vidc_component_cb_bind(struct device *dev,
|
||||
struct device *master, void *data)
|
||||
{
|
||||
d_vpr_h("%s(): %s\n", __func__, dev_name(dev));
|
||||
return 0;
|
||||
struct msm_vidc_core *core;
|
||||
int rc = 0;
|
||||
|
||||
if (!dev) {
|
||||
d_vpr_e("%s: invalid device\n", __func__);
|
||||
return -EINVAL;
|
||||
} else if (!dev->parent) {
|
||||
d_vpr_e("%s: failed to find a parent for %s\n",
|
||||
__func__, dev_name(dev));
|
||||
return -ENODEV;
|
||||
}
|
||||
core = dev_get_drvdata(dev->parent);
|
||||
if (!core) {
|
||||
d_vpr_e("%s: failed to find cookie in parent device %s",
|
||||
__func__, dev_name(dev->parent));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vidc_setup_context_bank(core, dev);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: Failed to probe context bank - %s\n",
|
||||
__func__, dev_name(dev));
|
||||
return rc;
|
||||
}
|
||||
|
||||
d_vpr_h("%s: Successfully probed context bank - %s\n",
|
||||
__func__, dev_name(dev));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void msm_vidc_component_cb_unbind(struct device *dev,
|
||||
@@ -391,7 +493,7 @@ static int msm_vidc_component_bind(struct device *dev)
|
||||
|
||||
rc = component_bind_all(dev, core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: sub-device bind failed\n", __func__);
|
||||
d_vpr_e("%s: sub-device bind failed. rc %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -464,7 +566,7 @@ static int msm_vidc_remove_video_device(struct platform_device *pdev)
|
||||
|
||||
d_vpr_h("depopulating sub devices\n");
|
||||
/*
|
||||
* Trigger remove for each sub-device i.e. qcom,msm-vidc,context-bank.
|
||||
* Trigger remove for each sub-device i.e. qcom,context-bank,xxxx
|
||||
* When msm_vidc_remove is called for each sub-device, destroy
|
||||
* context-bank mappings.
|
||||
*/
|
||||
@@ -488,9 +590,7 @@ static int msm_vidc_remove_video_device(struct platform_device *pdev)
|
||||
msm_vidc_deinit_instance_caps(core);
|
||||
msm_vidc_deinit_core_caps(core);
|
||||
|
||||
msm_vidc_deinit_irq(core);
|
||||
msm_vidc_deinit_platform(pdev);
|
||||
msm_vidc_deinit_dt(pdev);
|
||||
msm_vidc_deinitialize_core(core);
|
||||
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
@@ -504,8 +604,7 @@ static int msm_vidc_remove_video_device(struct platform_device *pdev)
|
||||
|
||||
static int msm_vidc_remove_context_bank(struct platform_device *pdev)
|
||||
{
|
||||
d_vpr_h("%s(): Detached %s and destroyed mapping\n",
|
||||
__func__, dev_name(&pdev->dev));
|
||||
d_vpr_h("%s(): %s\n", __func__, dev_name(&pdev->dev));
|
||||
|
||||
component_del(&pdev->dev, &msm_vidc_component_cb_ops);
|
||||
|
||||
@@ -519,12 +618,10 @@ static int msm_vidc_remove(struct platform_device *pdev)
|
||||
* after core_deinit(). It return immediately after completing
|
||||
* sub-device remove.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-vidc")) {
|
||||
if (is_video_device(&pdev->dev))
|
||||
return msm_vidc_remove_video_device(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-vidc,context-bank")) {
|
||||
else if (is_video_context_bank_device(&pdev->dev))
|
||||
return msm_vidc_remove_context_bank(pdev);
|
||||
}
|
||||
|
||||
/* How did we end up here? */
|
||||
WARN_ON(1);
|
||||
@@ -539,7 +636,7 @@ static int msm_vidc_probe_video_device(struct platform_device *pdev)
|
||||
struct device_node *child = NULL;
|
||||
int sub_device_count = 0, nr = BASE_DEVICE_NUMBER;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
d_vpr_h("%s: %s\n", __func__, dev_name(&pdev->dev));
|
||||
|
||||
rc = msm_vidc_vmem_alloc(sizeof(*core), (void **)&core, __func__);
|
||||
if (rc)
|
||||
@@ -559,13 +656,6 @@ static int msm_vidc_probe_video_device(struct platform_device *pdev)
|
||||
goto init_core_failed;
|
||||
}
|
||||
|
||||
rc = msm_vidc_init_dt(pdev);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: init dt failed with %d\n", __func__, rc);
|
||||
rc = -EINVAL;
|
||||
goto init_dt_failed;
|
||||
}
|
||||
|
||||
rc = msm_vidc_init_platform(pdev);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: init platform failed with %d\n", __func__, rc);
|
||||
@@ -573,16 +663,16 @@ static int msm_vidc_probe_video_device(struct platform_device *pdev)
|
||||
goto init_plat_failed;
|
||||
}
|
||||
|
||||
rc = msm_vidc_init_irq(core);
|
||||
rc = msm_vidc_init_resources(core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: init irq failed with %d\n", __func__, rc);
|
||||
goto init_irq_failed;
|
||||
d_vpr_e("%s: init resource failed with %d\n", __func__, rc);
|
||||
goto init_res_failed;
|
||||
}
|
||||
|
||||
rc = msm_vidc_init_core_caps(core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: init core caps failed with %d\n", __func__, rc);
|
||||
goto init_core_caps_fail;
|
||||
goto init_res_failed;
|
||||
}
|
||||
|
||||
rc = msm_vidc_init_instance_caps(core);
|
||||
@@ -659,8 +749,7 @@ static int msm_vidc_probe_video_device(struct platform_device *pdev)
|
||||
/*
|
||||
* Trigger probe for each sub-device i.e. qcom,msm-vidc,context-bank.
|
||||
* When msm_vidc_probe is called for each sub-device, parse the
|
||||
* context-bank details and store it in core->resources.context_banks
|
||||
* list.
|
||||
* context-bank details.
|
||||
*/
|
||||
rc = of_platform_populate(pdev->dev.of_node, msm_vidc_dt_match, NULL,
|
||||
&pdev->dev);
|
||||
@@ -698,13 +787,9 @@ init_group_failed:
|
||||
msm_vidc_deinit_instance_caps(core);
|
||||
init_inst_caps_fail:
|
||||
msm_vidc_deinit_core_caps(core);
|
||||
init_core_caps_fail:
|
||||
msm_vidc_deinit_irq(core);
|
||||
init_irq_failed:
|
||||
init_res_failed:
|
||||
msm_vidc_deinit_platform(pdev);
|
||||
init_plat_failed:
|
||||
msm_vidc_deinit_dt(pdev);
|
||||
init_dt_failed:
|
||||
msm_vidc_deinitialize_core(core);
|
||||
init_core_failed:
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
@@ -717,13 +802,7 @@ init_core_failed:
|
||||
|
||||
static int msm_vidc_probe_context_bank(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
|
||||
rc = msm_vidc_read_context_bank_resources_from_dt(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
d_vpr_h("%s(): %s\n", __func__, dev_name(&pdev->dev));
|
||||
|
||||
return component_add(&pdev->dev, &msm_vidc_component_cb_ops);
|
||||
}
|
||||
@@ -737,12 +816,10 @@ static int msm_vidc_probe(struct platform_device *pdev)
|
||||
* the end of the probe function after msm-vidc device probe is
|
||||
* completed. Return immediately after completing sub-device probe.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-vidc")) {
|
||||
if (is_video_device(&pdev->dev))
|
||||
return msm_vidc_probe_video_device(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-vidc,context-bank")) {
|
||||
else if (is_video_context_bank_device(&pdev->dev))
|
||||
return msm_vidc_probe_context_bank(pdev);
|
||||
}
|
||||
|
||||
/* How did we end up here? */
|
||||
WARN_ON(1);
|
||||
@@ -760,8 +837,7 @@ static int msm_vidc_pm_suspend(struct device *dev)
|
||||
* - not the main device. We don't support power management on
|
||||
* subdevices (e.g. context banks)
|
||||
*/
|
||||
if (!dev || !dev->driver ||
|
||||
!of_device_is_compatible(dev->of_node, "qcom,msm-vidc"))
|
||||
if (!dev || !dev->driver || !is_video_device(dev))
|
||||
return 0;
|
||||
|
||||
core = dev_get_drvdata(dev);
|
||||
@@ -792,8 +868,7 @@ static int msm_vidc_pm_resume(struct device *dev)
|
||||
* - not the main device. We don't support power management on
|
||||
* subdevices (e.g. context banks)
|
||||
*/
|
||||
if (!dev || !dev->driver ||
|
||||
!of_device_is_compatible(dev->of_node, "qcom,msm-vidc"))
|
||||
if (!dev || !dev->driver || !is_video_device(dev))
|
||||
return 0;
|
||||
|
||||
core = dev_get_drvdata(dev);
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#include "msm_venc.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_control.h"
|
||||
#include "msm_vidc_dt.h"
|
||||
#include "msm_vidc_platform.h"
|
||||
|
||||
extern struct msm_vidc_core *g_core;
|
||||
|
||||
@@ -101,7 +101,7 @@ void *msm_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
|
||||
|
||||
buf->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
|
||||
buf->attach->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP;
|
||||
if (core->dt->sys_cache_present)
|
||||
if (is_sys_cache_present(core))
|
||||
buf->attach->dma_map_attrs |=
|
||||
DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
|
||||
|
||||
|
A különbségek nem kerülnek megjelenítésre, mivel a fájl túl nagy
Load Diff
@@ -12,6 +12,7 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include "venus_hfi.h"
|
||||
@@ -63,11 +64,6 @@ bool __core_in_valid_state(struct msm_vidc_core *core)
|
||||
return core->state != MSM_VIDC_CORE_DEINIT;
|
||||
}
|
||||
|
||||
static bool is_sys_cache_present(struct msm_vidc_core *core)
|
||||
{
|
||||
return core->dt->sys_cache_present;
|
||||
}
|
||||
|
||||
static bool __valdiate_session(struct msm_vidc_core *core,
|
||||
struct msm_vidc_inst *inst, const char *func)
|
||||
{
|
||||
@@ -394,7 +390,7 @@ static int __release_subcaches(struct msm_vidc_core *core)
|
||||
if (msm_vidc_syscache_disable || !is_sys_cache_present(core))
|
||||
return 0;
|
||||
|
||||
if (!core->dt->sys_cache_res_set) {
|
||||
if (!core->resource->subcache_set.set_to_fw) {
|
||||
d_vpr_h("Subcaches not set to Venus\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -409,22 +405,23 @@ static int __release_subcaches(struct msm_vidc_core *core)
|
||||
buf.flags = HFI_BUF_HOST_FLAG_RELEASE;
|
||||
|
||||
venus_hfi_for_each_subcache_reverse(core, sinfo) {
|
||||
if (sinfo->isactive) {
|
||||
buf.index = sinfo->subcache->slice_id;
|
||||
buf.buffer_size = sinfo->subcache->slice_size;
|
||||
if (!sinfo->isactive)
|
||||
continue;
|
||||
|
||||
rc = hfi_create_packet(core->packet,
|
||||
core->packet_size,
|
||||
HFI_CMD_BUFFER,
|
||||
HFI_BUF_HOST_FLAG_NONE,
|
||||
HFI_PAYLOAD_STRUCTURE,
|
||||
HFI_PORT_NONE,
|
||||
core->packet_id++,
|
||||
&buf,
|
||||
sizeof(buf));
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
buf.index = sinfo->subcache->slice_id;
|
||||
buf.buffer_size = sinfo->subcache->slice_size;
|
||||
|
||||
rc = hfi_create_packet(core->packet,
|
||||
core->packet_size,
|
||||
HFI_CMD_BUFFER,
|
||||
HFI_BUF_HOST_FLAG_NONE,
|
||||
HFI_PAYLOAD_STRUCTURE,
|
||||
HFI_PORT_NONE,
|
||||
core->packet_id++,
|
||||
&buf,
|
||||
sizeof(buf));
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set resource to Venus for activated subcaches */
|
||||
@@ -433,15 +430,14 @@ static int __release_subcaches(struct msm_vidc_core *core)
|
||||
return rc;
|
||||
|
||||
venus_hfi_for_each_subcache_reverse(core, sinfo) {
|
||||
if (sinfo->isactive) {
|
||||
sinfo->isset = false;
|
||||
d_vpr_h("Release Subcache id %d size %lu done\n",
|
||||
sinfo->subcache->slice_id,
|
||||
sinfo->subcache->slice_size);
|
||||
}
|
||||
}
|
||||
if (!sinfo->isactive)
|
||||
continue;
|
||||
|
||||
core->dt->sys_cache_res_set = false;
|
||||
d_vpr_h("%s: release Subcache id %d size %lu done\n",
|
||||
__func__, sinfo->subcache->slice_id,
|
||||
sinfo->subcache->slice_size);
|
||||
}
|
||||
core->resource->subcache_set.set_to_fw = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -458,7 +454,7 @@ static int __set_subcaches(struct msm_vidc_core *core)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (core->dt->sys_cache_res_set) {
|
||||
if (core->resource->subcache_set.set_to_fw) {
|
||||
d_vpr_h("Subcaches already set to Venus\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -473,22 +469,22 @@ static int __set_subcaches(struct msm_vidc_core *core)
|
||||
buf.flags = HFI_BUF_HOST_FLAG_NONE;
|
||||
|
||||
venus_hfi_for_each_subcache(core, sinfo) {
|
||||
if (sinfo->isactive) {
|
||||
buf.index = sinfo->subcache->slice_id;
|
||||
buf.buffer_size = sinfo->subcache->slice_size;
|
||||
if (!sinfo->isactive)
|
||||
continue;
|
||||
buf.index = sinfo->subcache->slice_id;
|
||||
buf.buffer_size = sinfo->subcache->slice_size;
|
||||
|
||||
rc = hfi_create_packet(core->packet,
|
||||
core->packet_size,
|
||||
HFI_CMD_BUFFER,
|
||||
HFI_BUF_HOST_FLAG_NONE,
|
||||
HFI_PAYLOAD_STRUCTURE,
|
||||
HFI_PORT_NONE,
|
||||
core->packet_id++,
|
||||
&buf,
|
||||
sizeof(buf));
|
||||
if (rc)
|
||||
goto err_fail_set_subacaches;
|
||||
}
|
||||
rc = hfi_create_packet(core->packet,
|
||||
core->packet_size,
|
||||
HFI_CMD_BUFFER,
|
||||
HFI_BUF_HOST_FLAG_NONE,
|
||||
HFI_PAYLOAD_STRUCTURE,
|
||||
HFI_PORT_NONE,
|
||||
core->packet_id++,
|
||||
&buf,
|
||||
sizeof(buf));
|
||||
if (rc)
|
||||
goto err_fail_set_subacaches;
|
||||
}
|
||||
|
||||
/* Set resource to Venus for activated subcaches */
|
||||
@@ -497,15 +493,13 @@ static int __set_subcaches(struct msm_vidc_core *core)
|
||||
goto err_fail_set_subacaches;
|
||||
|
||||
venus_hfi_for_each_subcache(core, sinfo) {
|
||||
if (sinfo->isactive) {
|
||||
sinfo->isset = true;
|
||||
d_vpr_h("Set Subcache id %d size %lu done\n",
|
||||
sinfo->subcache->slice_id,
|
||||
sinfo->subcache->slice_size);
|
||||
}
|
||||
if (!sinfo->isactive)
|
||||
continue;
|
||||
d_vpr_h("%s: set Subcache id %d size %lu done\n",
|
||||
__func__, sinfo->subcache->slice_id,
|
||||
sinfo->subcache->slice_size);
|
||||
}
|
||||
|
||||
core->dt->sys_cache_res_set = true;
|
||||
core->resource->subcache_set.set_to_fw = true;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -699,16 +693,10 @@ int __load_fw(struct msm_vidc_core *core)
|
||||
core->cpu_watchdog = false;
|
||||
|
||||
trace_msm_v4l2_vidc_fw_load("START");
|
||||
rc = res_ops->get(core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: Failed to get resources: %d\n", __func__, rc);
|
||||
goto fail_init_res;
|
||||
}
|
||||
|
||||
rc = __venus_power_on(core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: power on failed\n", __func__);
|
||||
goto fail_venus_power_on;
|
||||
goto fail_power;
|
||||
}
|
||||
|
||||
rc = fw_load(core);
|
||||
@@ -727,25 +715,21 @@ int __load_fw(struct msm_vidc_core *core)
|
||||
return rc;
|
||||
fail_load_fw:
|
||||
__venus_power_off(core);
|
||||
fail_venus_power_on:
|
||||
res_ops->put(core);
|
||||
fail_init_res:
|
||||
fail_power:
|
||||
trace_msm_v4l2_vidc_fw_load("END");
|
||||
return rc;
|
||||
}
|
||||
|
||||
void __unload_fw(struct msm_vidc_core *core)
|
||||
{
|
||||
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||
int rc = 0;
|
||||
|
||||
if (!core->dt->fw_cookie)
|
||||
if (!core->resource->fw_cookie)
|
||||
return;
|
||||
|
||||
cancel_delayed_work(&core->pm_work);
|
||||
rc = fw_unload(core);
|
||||
__venus_power_off(core);
|
||||
res_ops->put(core);
|
||||
|
||||
core->cpu_watchdog = false;
|
||||
|
||||
|
Reference in New Issue
Block a user