video-driver: Abstract platform resources
Move clocks, gdsc, bandwidth resources out of venus_hfi and use the ops in variant and venus_hfi code. Change-Id: I1be77c9d384f4eef2cb8085b75c39dc3fd3eeb86 Signed-off-by: Stanimir Varbanov <quic_c_svarba@quicinc.com>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

szülő
a558b04808
commit
8b003fb153
1
Kbuild
1
Kbuild
@@ -67,6 +67,7 @@ msm_video-objs += driver/vidc/src/msm_vidc_v4l2.o \
|
|||||||
driver/vidc/src/msm_vidc_power.o \
|
driver/vidc/src/msm_vidc_power.o \
|
||||||
driver/vidc/src/msm_vidc_probe.o \
|
driver/vidc/src/msm_vidc_probe.o \
|
||||||
driver/vidc/src/msm_vidc_dt.o \
|
driver/vidc/src/msm_vidc_dt.o \
|
||||||
|
driver/vidc/src/resources.o \
|
||||||
driver/vidc/src/msm_vidc_debug.o \
|
driver/vidc/src/msm_vidc_debug.o \
|
||||||
driver/vidc/src/msm_vidc_memory.o \
|
driver/vidc/src/msm_vidc_memory.o \
|
||||||
driver/vidc/src/msm_vidc_fence.o \
|
driver/vidc/src/msm_vidc_fence.o \
|
||||||
|
@@ -170,202 +170,6 @@
|
|||||||
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
|
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
|
||||||
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
|
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
|
||||||
|
|
||||||
|
|
||||||
static int __disable_unprepare_clock_iris2(struct msm_vidc_core *core,
|
|
||||||
const char *clk_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct clock_info *cl;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
if (!core || !clk_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_clock(core, cl) {
|
|
||||||
if (!cl->clk) {
|
|
||||||
d_vpr_e("%s: invalid clock %s\n", __func__, cl->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(cl->name, clk_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
clk_disable_unprepare(cl->clk);
|
|
||||||
if (cl->has_scaling)
|
|
||||||
__set_clk_rate(core, cl, 0);
|
|
||||||
cl->prev = 0;
|
|
||||||
d_vpr_h("%s: clock %s disable unprepared\n", __func__, cl->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: clock %s not found\n", __func__, clk_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __prepare_enable_clock_iris2(struct msm_vidc_core *core,
|
|
||||||
const char *clk_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct clock_info *cl;
|
|
||||||
bool found;
|
|
||||||
u64 rate = 0;
|
|
||||||
|
|
||||||
if (!core || !clk_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_clock(core, cl) {
|
|
||||||
if (!cl->clk) {
|
|
||||||
d_vpr_e("%s: invalid clock\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(cl->name, clk_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
/*
|
|
||||||
* For the clocks we control, set the rate prior to preparing
|
|
||||||
* them. Since we don't really have a load at this point, scale
|
|
||||||
* it to the lowest frequency possible
|
|
||||||
*/
|
|
||||||
if (cl->has_scaling) {
|
|
||||||
rate = clk_round_rate(cl->clk, 0);
|
|
||||||
/**
|
|
||||||
* source clock is already multipled with scaling ratio and __set_clk_rate
|
|
||||||
* attempts to multiply again. So divide scaling ratio before calling
|
|
||||||
* __set_clk_rate.
|
|
||||||
*/
|
|
||||||
rate = rate / MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO;
|
|
||||||
__set_clk_rate(core, cl, rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = clk_prepare_enable(cl->clk);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to enable clock %s\n",
|
|
||||||
__func__, cl->name);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
if (!__clk_is_enabled(cl->clk)) {
|
|
||||||
d_vpr_e("%s: clock %s not enabled\n",
|
|
||||||
__func__, cl->name);
|
|
||||||
clk_disable_unprepare(cl->clk);
|
|
||||||
if (cl->has_scaling)
|
|
||||||
__set_clk_rate(core, cl, 0);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
d_vpr_h("%s: clock %s prepare enabled\n", __func__, cl->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: clock %s not found\n", __func__, clk_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __disable_regulator_iris2(struct msm_vidc_core *core,
|
|
||||||
const char *reg_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct regulator_info *rinfo;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
if (!core || !reg_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_regulator(core, rinfo) {
|
|
||||||
if (!rinfo->regulator) {
|
|
||||||
d_vpr_e("%s: invalid regulator %s\n",
|
|
||||||
__func__, rinfo->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(rinfo->name, reg_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
rc = __acquire_regulator(core, rinfo);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to acquire %s, rc = %d\n",
|
|
||||||
__func__, rinfo->name, rc);
|
|
||||||
/* Bring attention to this issue */
|
|
||||||
WARN_ON(true);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
core->handoff_done = false;
|
|
||||||
|
|
||||||
rc = regulator_disable(rinfo->regulator);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to disable %s, rc = %d\n",
|
|
||||||
__func__, rinfo->name, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
d_vpr_h("%s: disabled regulator %s\n", __func__, rinfo->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: regulator %s not found\n", __func__, reg_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __enable_regulator_iris2(struct msm_vidc_core *core,
|
|
||||||
const char *reg_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct regulator_info *rinfo;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
if (!core || !reg_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_regulator(core, rinfo) {
|
|
||||||
if (!rinfo->regulator) {
|
|
||||||
d_vpr_e("%s: invalid regulator %s\n",
|
|
||||||
__func__, rinfo->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(rinfo->name, reg_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
rc = regulator_enable(rinfo->regulator);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to enable %s, rc = %d\n",
|
|
||||||
__func__, rinfo->name, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
if (!regulator_is_enabled(rinfo->regulator)) {
|
|
||||||
d_vpr_e("%s: regulator %s not enabled\n",
|
|
||||||
__func__, rinfo->name);
|
|
||||||
regulator_disable(rinfo->regulator);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
d_vpr_h("%s: enabled regulator %s\n", __func__, rinfo->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: regulator %s not found\n", __func__, reg_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __interrupt_init_iris2(struct msm_vidc_core *vidc_core)
|
static int __interrupt_init_iris2(struct msm_vidc_core *vidc_core)
|
||||||
{
|
{
|
||||||
struct msm_vidc_core *core = vidc_core;
|
struct msm_vidc_core *core = vidc_core;
|
||||||
@@ -445,6 +249,7 @@ static int __setup_ucregion_memory_map_iris2(struct msm_vidc_core *vidc_core)
|
|||||||
|
|
||||||
static int __power_off_iris2_hardware(struct msm_vidc_core *core)
|
static int __power_off_iris2_hardware(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0, i;
|
int rc = 0, i;
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
|
|
||||||
@@ -517,12 +322,12 @@ static int __power_off_iris2_hardware(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
disable_power:
|
disable_power:
|
||||||
/* power down process */
|
/* power down process */
|
||||||
rc = __disable_regulator_iris2(core, "vcodec");
|
rc = res_ops->gdsc_off(core, "vcodec");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable regulator vcodec failed\n", __func__);
|
d_vpr_e("%s: disable regulator vcodec failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
rc = __disable_unprepare_clock_iris2(core, "vcodec_clk");
|
rc = res_ops->clk_disable(core, "vcodec_clk");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable unprepare vcodec_clk failed\n", __func__);
|
d_vpr_e("%s: disable unprepare vcodec_clk failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@@ -533,6 +338,7 @@ disable_power:
|
|||||||
|
|
||||||
static int __power_off_iris2_controller(struct msm_vidc_core *core)
|
static int __power_off_iris2_controller(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -575,27 +381,27 @@ static int __power_off_iris2_controller(struct msm_vidc_core *core)
|
|||||||
d_vpr_h("%s: debug bridge release failed\n", __func__);
|
d_vpr_h("%s: debug bridge release failed\n", __func__);
|
||||||
|
|
||||||
/* Turn off MVP MVS0C core clock */
|
/* Turn off MVP MVS0C core clock */
|
||||||
rc = __disable_unprepare_clock_iris2(core, "core_clk");
|
rc = res_ops->clk_disable(core, "core_clk");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
|
d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable GCC_VIDEO_AXI0_CLK clock */
|
/* Disable GCC_VIDEO_AXI0_CLK clock */
|
||||||
rc = __disable_unprepare_clock_iris2(core, "gcc_video_axi0");
|
rc = res_ops->clk_disable(core, "gcc_video_axi0");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable unprepare gcc_video_axi0 failed\n", __func__);
|
d_vpr_e("%s: disable unprepare gcc_video_axi0 failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = call_venus_op(core, reset_ahb2axi_bridge, core);
|
rc = res_ops->reset_bridge(core);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: reset ahb2axi bridge failed\n", __func__);
|
d_vpr_e("%s: reset bridge failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* power down process */
|
/* power down process */
|
||||||
rc = __disable_regulator_iris2(core, "iris-ctl");
|
rc = res_ops->gdsc_off(core, "iris-ctl");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable regulator iris-ctl failed\n", __func__);
|
d_vpr_e("%s: disable regulator iris-ctl failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@@ -606,6 +412,7 @@ static int __power_off_iris2_controller(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
static int __power_off_iris2(struct msm_vidc_core *core)
|
static int __power_off_iris2(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (!core || !core->capabilities) {
|
if (!core || !core->capabilities) {
|
||||||
@@ -620,7 +427,7 @@ static int __power_off_iris2(struct msm_vidc_core *core)
|
|||||||
* Reset video_cc_mvs0_clk_src value to resolve MMRM high video
|
* Reset video_cc_mvs0_clk_src value to resolve MMRM high video
|
||||||
* clock projection issue.
|
* clock projection issue.
|
||||||
*/
|
*/
|
||||||
rc = __set_clocks(core, 0);
|
rc = res_ops->set_clks(core, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
d_vpr_e("%s: resetting clocks failed\n", __func__);
|
d_vpr_e("%s: resetting clocks failed\n", __func__);
|
||||||
|
|
||||||
@@ -630,7 +437,7 @@ static int __power_off_iris2(struct msm_vidc_core *core)
|
|||||||
if (__power_off_iris2_controller(core))
|
if (__power_off_iris2_controller(core))
|
||||||
d_vpr_e("%s: failed to power off controller\n", __func__);
|
d_vpr_e("%s: failed to power off controller\n", __func__);
|
||||||
|
|
||||||
if (__unvote_buses(core))
|
if (res_ops->set_bw(core, 0, 0))
|
||||||
d_vpr_e("%s: failed to unvote buses\n", __func__);
|
d_vpr_e("%s: failed to unvote buses\n", __func__);
|
||||||
|
|
||||||
if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2))
|
if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2))
|
||||||
@@ -644,64 +451,69 @@ static int __power_off_iris2(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
static int __power_on_iris2_controller(struct msm_vidc_core *core)
|
static int __power_on_iris2_controller(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = __enable_regulator_iris2(core, "iris-ctl");
|
rc = res_ops->gdsc_on(core, "iris-ctl");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_regulator;
|
goto fail_regulator;
|
||||||
|
|
||||||
rc = call_venus_op(core, reset_ahb2axi_bridge, core);
|
rc = res_ops->reset_bridge(core);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_reset_ahb2axi;
|
goto fail_reset_ahb2axi;
|
||||||
|
|
||||||
rc = __prepare_enable_clock_iris2(core, "gcc_video_axi0");
|
rc = res_ops->clk_enable(core, "gcc_video_axi0");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_clk_axi;
|
goto fail_clk_axi;
|
||||||
|
|
||||||
rc = __prepare_enable_clock_iris2(core, "core_clk");
|
rc = res_ops->clk_enable(core, "core_clk");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_clk_controller;
|
goto fail_clk_controller;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_clk_controller:
|
fail_clk_controller:
|
||||||
__disable_unprepare_clock_iris2(core, "gcc_video_axi0");
|
res_ops->clk_disable(core, "gcc_video_axi0");
|
||||||
fail_clk_axi:
|
fail_clk_axi:
|
||||||
fail_reset_ahb2axi:
|
fail_reset_ahb2axi:
|
||||||
__disable_regulator_iris2(core, "iris-ctl");
|
res_ops->gdsc_off(core, "iris-ctl");
|
||||||
fail_regulator:
|
fail_regulator:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __power_on_iris2_hardware(struct msm_vidc_core *core)
|
static int __power_on_iris2_hardware(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = __enable_regulator_iris2(core, "vcodec");
|
rc = res_ops->gdsc_on(core, "vcodec");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_regulator;
|
goto fail_regulator;
|
||||||
|
|
||||||
rc = __prepare_enable_clock_iris2(core, "vcodec_clk");
|
rc = res_ops->clk_enable(core, "vcodec_clk");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_clk_controller;
|
goto fail_clk_controller;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_clk_controller:
|
fail_clk_controller:
|
||||||
__disable_regulator_iris2(core, "vcodec");
|
res_ops->gdsc_off(core, "vcodec");
|
||||||
fail_regulator:
|
fail_regulator:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __power_on_iris2(struct msm_vidc_core *core)
|
static int __power_on_iris2(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
|
struct allowed_clock_rates_table *clk_tbl;
|
||||||
|
u32 freq = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (core->power_enabled)
|
if (core->power_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Vote for all hardware resources */
|
/* Vote for all hardware resources */
|
||||||
rc = __vote_buses(core, INT_MAX, INT_MAX);
|
rc = res_ops->set_bw(core, INT_MAX, INT_MAX);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: failed to vote buses, rc %d\n", __func__, rc);
|
d_vpr_e("%s: failed to vote buses, rc %d\n", __func__, rc);
|
||||||
goto fail_vote_buses;
|
goto fail_vote_buses;
|
||||||
@@ -721,16 +533,23 @@ static int __power_on_iris2(struct msm_vidc_core *core)
|
|||||||
/* video controller and hardware powered on successfully */
|
/* video controller and hardware powered on successfully */
|
||||||
core->power_enabled = true;
|
core->power_enabled = true;
|
||||||
|
|
||||||
rc = __scale_clocks(core);
|
clk_tbl = core->dt->allowed_clks_tbl;
|
||||||
|
freq = core->power.clk_freq ? core->power.clk_freq :
|
||||||
|
clk_tbl[0].clock_rate;
|
||||||
|
|
||||||
|
rc = res_ops->set_clks(core, freq);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: failed to scale clocks\n", __func__);
|
d_vpr_e("%s: failed to scale clocks\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core->power.clk_freq = freq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Re-program all of the registers that get reset as a result of
|
* Re-program all of the registers that get reset as a result of
|
||||||
* regulator_disable() and _enable()
|
* regulator_disable() and _enable()
|
||||||
*/
|
*/
|
||||||
__set_registers(core);
|
res_ops->set_regs(core);
|
||||||
|
|
||||||
__interrupt_init_iris2(core);
|
__interrupt_init_iris2(core);
|
||||||
core->intr_status = 0;
|
core->intr_status = 0;
|
||||||
@@ -741,7 +560,7 @@ static int __power_on_iris2(struct msm_vidc_core *core)
|
|||||||
fail_power_on_hardware:
|
fail_power_on_hardware:
|
||||||
__power_off_iris2_controller(core);
|
__power_off_iris2_controller(core);
|
||||||
fail_power_on_controller:
|
fail_power_on_controller:
|
||||||
__unvote_buses(core);
|
res_ops->set_bw(core, 0, 0);
|
||||||
fail_vote_buses:
|
fail_vote_buses:
|
||||||
core->power_enabled = false;
|
core->power_enabled = false;
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1185,7 +1004,6 @@ static struct msm_vidc_venus_ops iris2_ops = {
|
|||||||
.boot_firmware = __boot_firmware_iris2,
|
.boot_firmware = __boot_firmware_iris2,
|
||||||
.raise_interrupt = __raise_interrupt_iris2,
|
.raise_interrupt = __raise_interrupt_iris2,
|
||||||
.clear_interrupt = __clear_interrupt_iris2,
|
.clear_interrupt = __clear_interrupt_iris2,
|
||||||
.reset_ahb2axi_bridge = __reset_ahb2axi_bridge,
|
|
||||||
.power_on = __power_on_iris2,
|
.power_on = __power_on_iris2,
|
||||||
.power_off = __power_off_iris2,
|
.power_off = __power_off_iris2,
|
||||||
.prepare_pc = __prepare_pc_iris2,
|
.prepare_pc = __prepare_pc_iris2,
|
||||||
@@ -1214,6 +1032,7 @@ int msm_vidc_init_iris2(struct msm_vidc_core *core)
|
|||||||
d_vpr_h("%s()\n", __func__);
|
d_vpr_h("%s()\n", __func__);
|
||||||
core->venus_ops = &iris2_ops;
|
core->venus_ops = &iris2_ops;
|
||||||
core->session_ops = &msm_session_ops;
|
core->session_ops = &msm_session_ops;
|
||||||
|
core->res_ops = get_resources_ops();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -176,202 +176,6 @@
|
|||||||
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
|
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_LOW 0x00011238
|
||||||
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
|
#define VCODEC_NOC_ERL_MAIN_ERRLOG3_HIGH 0x0001123C
|
||||||
|
|
||||||
|
|
||||||
static int __disable_unprepare_clock_iris3(struct msm_vidc_core *core,
|
|
||||||
const char *clk_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct clock_info *cl;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
if (!core || !clk_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_clock(core, cl) {
|
|
||||||
if (!cl->clk) {
|
|
||||||
d_vpr_e("%s: invalid clock %s\n", __func__, cl->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(cl->name, clk_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
clk_disable_unprepare(cl->clk);
|
|
||||||
if (cl->has_scaling)
|
|
||||||
__set_clk_rate(core, cl, 0);
|
|
||||||
cl->prev = 0;
|
|
||||||
d_vpr_h("%s: clock %s disable unprepared\n", __func__, cl->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: clock %s not found\n", __func__, clk_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __prepare_enable_clock_iris3(struct msm_vidc_core *core,
|
|
||||||
const char *clk_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct clock_info *cl;
|
|
||||||
bool found;
|
|
||||||
u64 rate = 0;
|
|
||||||
|
|
||||||
if (!core || !clk_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_clock(core, cl) {
|
|
||||||
if (!cl->clk) {
|
|
||||||
d_vpr_e("%s: invalid clock\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(cl->name, clk_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
/*
|
|
||||||
* For the clocks we control, set the rate prior to preparing
|
|
||||||
* them. Since we don't really have a load at this point, scale
|
|
||||||
* it to the lowest frequency possible
|
|
||||||
*/
|
|
||||||
if (cl->has_scaling) {
|
|
||||||
rate = clk_round_rate(cl->clk, 0);
|
|
||||||
/**
|
|
||||||
* source clock is already multipled with scaling ratio and __set_clk_rate
|
|
||||||
* attempts to multiply again. So divide scaling ratio before calling
|
|
||||||
* __set_clk_rate.
|
|
||||||
*/
|
|
||||||
rate = rate / MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO;
|
|
||||||
__set_clk_rate(core, cl, rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = clk_prepare_enable(cl->clk);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to enable clock %s\n",
|
|
||||||
__func__, cl->name);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
if (!__clk_is_enabled(cl->clk)) {
|
|
||||||
d_vpr_e("%s: clock %s not enabled\n",
|
|
||||||
__func__, cl->name);
|
|
||||||
clk_disable_unprepare(cl->clk);
|
|
||||||
if (cl->has_scaling)
|
|
||||||
__set_clk_rate(core, cl, 0);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
d_vpr_h("%s: clock %s prepare enabled\n", __func__, cl->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: clock %s not found\n", __func__, clk_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __disable_regulator_iris3(struct msm_vidc_core *core,
|
|
||||||
const char *reg_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct regulator_info *rinfo;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
if (!core || !reg_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_regulator(core, rinfo) {
|
|
||||||
if (!rinfo->regulator) {
|
|
||||||
d_vpr_e("%s: invalid regulator %s\n",
|
|
||||||
__func__, rinfo->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(rinfo->name, reg_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
rc = __acquire_regulator(core, rinfo);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to acquire %s, rc = %d\n",
|
|
||||||
__func__, rinfo->name, rc);
|
|
||||||
/* Bring attention to this issue */
|
|
||||||
WARN_ON(true);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
core->handoff_done = false;
|
|
||||||
|
|
||||||
rc = regulator_disable(rinfo->regulator);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to disable %s, rc = %d\n",
|
|
||||||
__func__, rinfo->name, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
d_vpr_h("%s: disabled regulator %s\n", __func__, rinfo->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: regulator %s not found\n", __func__, reg_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __enable_regulator_iris3(struct msm_vidc_core *core,
|
|
||||||
const char *reg_name)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
struct regulator_info *rinfo;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
if (!core || !reg_name) {
|
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
venus_hfi_for_each_regulator(core, rinfo) {
|
|
||||||
if (!rinfo->regulator) {
|
|
||||||
d_vpr_e("%s: invalid regulator %s\n",
|
|
||||||
__func__, rinfo->name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (strcmp(rinfo->name, reg_name))
|
|
||||||
continue;
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
rc = regulator_enable(rinfo->regulator);
|
|
||||||
if (rc) {
|
|
||||||
d_vpr_e("%s: failed to enable %s, rc = %d\n",
|
|
||||||
__func__, rinfo->name, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
if (!regulator_is_enabled(rinfo->regulator)) {
|
|
||||||
d_vpr_e("%s: regulator %s not enabled\n",
|
|
||||||
__func__, rinfo->name);
|
|
||||||
regulator_disable(rinfo->regulator);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
d_vpr_h("%s: enabled regulator %s\n", __func__, rinfo->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
d_vpr_e("%s: regulator %s not found\n", __func__, reg_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __interrupt_init_iris3(struct msm_vidc_core *vidc_core)
|
static int __interrupt_init_iris3(struct msm_vidc_core *vidc_core)
|
||||||
{
|
{
|
||||||
struct msm_vidc_core *core = vidc_core;
|
struct msm_vidc_core *core = vidc_core;
|
||||||
@@ -465,6 +269,7 @@ static bool is_iris3_hw_power_collapsed(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
static int __power_off_iris3_hardware(struct msm_vidc_core *core)
|
static int __power_off_iris3_hardware(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0, i;
|
int rc = 0, i;
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
bool pwr_collapsed = false;
|
bool pwr_collapsed = false;
|
||||||
@@ -556,12 +361,13 @@ static int __power_off_iris3_hardware(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
disable_power:
|
disable_power:
|
||||||
/* power down process */
|
/* power down process */
|
||||||
rc = __disable_regulator_iris3(core, "vcodec");
|
rc = res_ops->gdsc_off(core, "vcodec");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable regulator vcodec failed\n", __func__);
|
d_vpr_e("%s: disable regulator vcodec failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
rc = __disable_unprepare_clock_iris3(core, "vcodec_clk");
|
|
||||||
|
rc = res_ops->clk_disable(core, "vcodec_clk");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable unprepare vcodec_clk failed\n", __func__);
|
d_vpr_e("%s: disable unprepare vcodec_clk failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@@ -572,6 +378,7 @@ disable_power:
|
|||||||
|
|
||||||
static int __power_off_iris3_controller(struct msm_vidc_core *core)
|
static int __power_off_iris3_controller(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -632,14 +439,14 @@ static int __power_off_iris3_controller(struct msm_vidc_core *core)
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Turn off MVP MVS0C core clock */
|
/* Turn off MVP MVS0C core clock */
|
||||||
rc = __disable_unprepare_clock_iris3(core, "core_clk");
|
rc = res_ops->clk_disable(core, "core_clk");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
|
d_vpr_e("%s: disable unprepare core_clk failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* power down process */
|
/* power down process */
|
||||||
rc = __disable_regulator_iris3(core, "iris-ctl");
|
rc = res_ops->gdsc_off(core, "iris-ctl");
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: disable regulator iris-ctl failed\n", __func__);
|
d_vpr_e("%s: disable regulator iris-ctl failed\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@@ -650,6 +457,7 @@ static int __power_off_iris3_controller(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
static int __power_off_iris3(struct msm_vidc_core *core)
|
static int __power_off_iris3(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (!core || !core->capabilities) {
|
if (!core || !core->capabilities) {
|
||||||
@@ -664,7 +472,7 @@ static int __power_off_iris3(struct msm_vidc_core *core)
|
|||||||
* Reset video_cc_mvs0_clk_src value to resolve MMRM high video
|
* Reset video_cc_mvs0_clk_src value to resolve MMRM high video
|
||||||
* clock projection issue.
|
* clock projection issue.
|
||||||
*/
|
*/
|
||||||
rc = __set_clocks(core, 0);
|
rc = res_ops->set_clks(core, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
d_vpr_e("%s: resetting clocks failed\n", __func__);
|
d_vpr_e("%s: resetting clocks failed\n", __func__);
|
||||||
|
|
||||||
@@ -674,7 +482,7 @@ static int __power_off_iris3(struct msm_vidc_core *core)
|
|||||||
if (__power_off_iris3_controller(core))
|
if (__power_off_iris3_controller(core))
|
||||||
d_vpr_e("%s: failed to power off controller\n", __func__);
|
d_vpr_e("%s: failed to power off controller\n", __func__);
|
||||||
|
|
||||||
if (__unvote_buses(core))
|
if (res_ops->set_bw(core, 0, 0))
|
||||||
d_vpr_e("%s: failed to unvote buses\n", __func__);
|
d_vpr_e("%s: failed to unvote buses\n", __func__);
|
||||||
|
|
||||||
if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS3))
|
if (!(core->intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS3))
|
||||||
@@ -688,64 +496,69 @@ static int __power_off_iris3(struct msm_vidc_core *core)
|
|||||||
|
|
||||||
static int __power_on_iris3_controller(struct msm_vidc_core *core)
|
static int __power_on_iris3_controller(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = __enable_regulator_iris3(core, "iris-ctl");
|
rc = res_ops->gdsc_on(core, "iris-ctl");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_regulator;
|
goto fail_regulator;
|
||||||
|
|
||||||
rc = call_venus_op(core, reset_ahb2axi_bridge, core);
|
rc = res_ops->reset_bridge(core);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_reset_ahb2axi;
|
goto fail_reset_ahb2axi;
|
||||||
|
|
||||||
rc = __prepare_enable_clock_iris3(core, "gcc_video_axi0");
|
rc = res_ops->clk_enable(core, "gcc_video_axi0");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_clk_axi;
|
goto fail_clk_axi;
|
||||||
|
|
||||||
rc = __prepare_enable_clock_iris3(core, "core_clk");
|
rc = res_ops->clk_enable(core, "core_clk");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_clk_controller;
|
goto fail_clk_controller;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_clk_controller:
|
fail_clk_controller:
|
||||||
__disable_unprepare_clock_iris3(core, "gcc_video_axi0");
|
res_ops->clk_disable(core, "gcc_video_axi0");
|
||||||
fail_clk_axi:
|
fail_clk_axi:
|
||||||
fail_reset_ahb2axi:
|
fail_reset_ahb2axi:
|
||||||
__disable_regulator_iris3(core, "iris-ctl");
|
res_ops->gdsc_off(core, "iris-ctl");
|
||||||
fail_regulator:
|
fail_regulator:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __power_on_iris3_hardware(struct msm_vidc_core *core)
|
static int __power_on_iris3_hardware(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
const struct msm_vidc_resources_ops *res_ops = core->res_ops;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = __enable_regulator_iris3(core, "vcodec");
|
rc = res_ops->gdsc_on(core, "vcodec");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_regulator;
|
goto fail_regulator;
|
||||||
|
|
||||||
rc = __prepare_enable_clock_iris3(core, "vcodec_clk");
|
rc = res_ops->clk_enable(core, "vcodec_clk");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail_clk_controller;
|
goto fail_clk_controller;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_clk_controller:
|
fail_clk_controller:
|
||||||
__disable_regulator_iris3(core, "vcodec");
|
res_ops->gdsc_off(core, "vcodec");
|
||||||
fail_regulator:
|
fail_regulator:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __power_on_iris3(struct msm_vidc_core *core)
|
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;
|
||||||
|
u32 freq = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (core->power_enabled)
|
if (core->power_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Vote for all hardware resources */
|
/* Vote for all hardware resources */
|
||||||
rc = __vote_buses(core, INT_MAX, INT_MAX);
|
rc = res_ops->set_bw(core, INT_MAX, INT_MAX);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: failed to vote buses, rc %d\n", __func__, rc);
|
d_vpr_e("%s: failed to vote buses, rc %d\n", __func__, rc);
|
||||||
goto fail_vote_buses;
|
goto fail_vote_buses;
|
||||||
@@ -765,7 +578,11 @@ static int __power_on_iris3(struct msm_vidc_core *core)
|
|||||||
/* video controller and hardware powered on successfully */
|
/* video controller and hardware powered on successfully */
|
||||||
core->power_enabled = true;
|
core->power_enabled = true;
|
||||||
|
|
||||||
rc = __scale_clocks(core);
|
clk_tbl = core->dt->allowed_clks_tbl;
|
||||||
|
freq = core->power.clk_freq ? core->power.clk_freq :
|
||||||
|
clk_tbl[0].clock_rate;
|
||||||
|
|
||||||
|
rc = res_ops->set_clks(core, freq);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
d_vpr_e("%s: failed to scale clocks\n", __func__);
|
d_vpr_e("%s: failed to scale clocks\n", __func__);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@@ -774,7 +591,7 @@ static int __power_on_iris3(struct msm_vidc_core *core)
|
|||||||
* Re-program all of the registers that get reset as a result of
|
* Re-program all of the registers that get reset as a result of
|
||||||
* regulator_disable() and _enable()
|
* regulator_disable() and _enable()
|
||||||
*/
|
*/
|
||||||
__set_registers(core);
|
res_ops->set_regs(core);
|
||||||
|
|
||||||
__interrupt_init_iris3(core);
|
__interrupt_init_iris3(core);
|
||||||
core->intr_status = 0;
|
core->intr_status = 0;
|
||||||
@@ -785,7 +602,7 @@ static int __power_on_iris3(struct msm_vidc_core *core)
|
|||||||
fail_power_on_hardware:
|
fail_power_on_hardware:
|
||||||
__power_off_iris3_controller(core);
|
__power_off_iris3_controller(core);
|
||||||
fail_power_on_controller:
|
fail_power_on_controller:
|
||||||
__unvote_buses(core);
|
res_ops->set_bw(core, 0, 0);
|
||||||
fail_vote_buses:
|
fail_vote_buses:
|
||||||
core->power_enabled = false;
|
core->power_enabled = false;
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1263,7 +1080,6 @@ static struct msm_vidc_venus_ops iris3_ops = {
|
|||||||
.boot_firmware = __boot_firmware_iris3,
|
.boot_firmware = __boot_firmware_iris3,
|
||||||
.raise_interrupt = __raise_interrupt_iris3,
|
.raise_interrupt = __raise_interrupt_iris3,
|
||||||
.clear_interrupt = __clear_interrupt_iris3,
|
.clear_interrupt = __clear_interrupt_iris3,
|
||||||
.reset_ahb2axi_bridge = __reset_ahb2axi_bridge,
|
|
||||||
.power_on = __power_on_iris3,
|
.power_on = __power_on_iris3,
|
||||||
.power_off = __power_off_iris3,
|
.power_off = __power_off_iris3,
|
||||||
.prepare_pc = __prepare_pc_iris3,
|
.prepare_pc = __prepare_pc_iris3,
|
||||||
@@ -1292,6 +1108,7 @@ int msm_vidc_init_iris3(struct msm_vidc_core *core)
|
|||||||
d_vpr_h("%s()\n", __func__);
|
d_vpr_h("%s()\n", __func__);
|
||||||
core->venus_ops = &iris3_ops;
|
core->venus_ops = &iris3_ops;
|
||||||
core->session_ops = &msm_session_ops;
|
core->session_ops = &msm_session_ops;
|
||||||
|
core->res_ops = get_resources_ops();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "msm_vidc_internal.h"
|
#include "msm_vidc_internal.h"
|
||||||
#include "venus_hfi_queue.h"
|
#include "venus_hfi_queue.h"
|
||||||
|
#include "resources.h"
|
||||||
|
|
||||||
struct msm_vidc_core;
|
struct msm_vidc_core;
|
||||||
|
|
||||||
@@ -21,7 +22,6 @@ struct msm_vidc_core;
|
|||||||
|
|
||||||
struct msm_vidc_venus_ops {
|
struct msm_vidc_venus_ops {
|
||||||
int (*boot_firmware)(struct msm_vidc_core *core);
|
int (*boot_firmware)(struct msm_vidc_core *core);
|
||||||
int (*reset_ahb2axi_bridge)(struct msm_vidc_core *core);
|
|
||||||
int (*raise_interrupt)(struct msm_vidc_core *core);
|
int (*raise_interrupt)(struct msm_vidc_core *core);
|
||||||
int (*clear_interrupt)(struct msm_vidc_core *core);
|
int (*clear_interrupt)(struct msm_vidc_core *core);
|
||||||
int (*prepare_pc)(struct msm_vidc_core *core);
|
int (*prepare_pc)(struct msm_vidc_core *core);
|
||||||
@@ -108,6 +108,7 @@ struct msm_vidc_core {
|
|||||||
struct vb2_mem_ops *vb2_mem_ops;
|
struct vb2_mem_ops *vb2_mem_ops;
|
||||||
struct v4l2_m2m_ops *v4l2_m2m_ops;
|
struct v4l2_m2m_ops *v4l2_m2m_ops;
|
||||||
struct msm_vidc_venus_ops *venus_ops;
|
struct msm_vidc_venus_ops *venus_ops;
|
||||||
|
const struct msm_vidc_resources_ops *res_ops;
|
||||||
struct msm_vidc_session_ops *session_ops;
|
struct msm_vidc_session_ops *session_ops;
|
||||||
struct msm_vidc_memory_ops *mem_ops;
|
struct msm_vidc_memory_ops *mem_ops;
|
||||||
struct media_device_ops *media_device_ops;
|
struct media_device_ops *media_device_ops;
|
||||||
|
@@ -135,7 +135,9 @@ struct clock_info {
|
|||||||
bool has_scaling;
|
bool has_scaling;
|
||||||
bool has_mem_retention;
|
bool has_mem_retention;
|
||||||
u64 prev;
|
u64 prev;
|
||||||
|
#ifdef CONFIG_MSM_MMRM
|
||||||
struct mmrm_client *mmrm_client;
|
struct mmrm_client *mmrm_client;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clock_set {
|
struct clock_set {
|
||||||
|
35
driver/vidc/inc/resources.h
Normal file
35
driver/vidc/inc/resources.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2022, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MSM_VIDC_RESOURCES_H_
|
||||||
|
#define _MSM_VIDC_RESOURCES_H_
|
||||||
|
|
||||||
|
struct msm_vidc_core;
|
||||||
|
|
||||||
|
struct msm_vidc_resources_ops {
|
||||||
|
int (*get)(struct msm_vidc_core *core);
|
||||||
|
void (*put)(struct msm_vidc_core *core);
|
||||||
|
|
||||||
|
int (*reset_bridge)(struct msm_vidc_core *core);
|
||||||
|
|
||||||
|
int (*gdsc_on)(struct msm_vidc_core *core, const char *name);
|
||||||
|
int (*gdsc_off)(struct msm_vidc_core *core, const char *name);
|
||||||
|
int (*gdsc_hw_ctrl)(struct msm_vidc_core *core);
|
||||||
|
int (*gdsc_sw_ctrl)(struct msm_vidc_core *core);
|
||||||
|
|
||||||
|
int (*llcc)(struct msm_vidc_core *core, bool enable);
|
||||||
|
int (*set_bw)(struct msm_vidc_core *core, unsigned long bw_ddr,
|
||||||
|
unsigned long bw_llcc);
|
||||||
|
int (*set_clks)(struct msm_vidc_core *core, u64 rate);
|
||||||
|
|
||||||
|
int (*clk_disable)(struct msm_vidc_core *core, const char *name);
|
||||||
|
int (*clk_enable)(struct msm_vidc_core *core, const char *name);
|
||||||
|
|
||||||
|
int (*set_regs)(struct msm_vidc_core *core);
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct msm_vidc_resources_ops *get_resources_ops(void);
|
||||||
|
|
||||||
|
#endif
|
@@ -80,27 +80,7 @@ int __write_register(struct msm_vidc_core *core,
|
|||||||
int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value);
|
int __read_register(struct msm_vidc_core *core, u32 reg, u32 *value);
|
||||||
int __read_register_with_poll_timeout(struct msm_vidc_core *core,
|
int __read_register_with_poll_timeout(struct msm_vidc_core *core,
|
||||||
u32 reg, u32 mask, u32 exp_val, u32 sleep_us, u32 timeout_us);
|
u32 reg, u32 mask, u32 exp_val, u32 sleep_us, u32 timeout_us);
|
||||||
int __set_clocks(struct msm_vidc_core *core, u32 freq);
|
|
||||||
int __scale_clocks(struct msm_vidc_core *core);
|
|
||||||
int __set_clk_rate(struct msm_vidc_core *core,
|
|
||||||
struct clock_info *cl, u64 rate);
|
|
||||||
int __acquire_regulator(struct msm_vidc_core *core,
|
|
||||||
struct regulator_info *rinfo);
|
|
||||||
int __unvote_buses(struct msm_vidc_core *core);
|
|
||||||
int __vote_buses(struct msm_vidc_core *core, unsigned long bw_ddr,
|
|
||||||
unsigned long bw_llcc);
|
|
||||||
int __prepare_pc(struct msm_vidc_core *core);
|
int __prepare_pc(struct msm_vidc_core *core);
|
||||||
int __set_registers(struct msm_vidc_core *core);
|
|
||||||
|
|
||||||
int __reset_ahb2axi_bridge(struct msm_vidc_core *core);
|
|
||||||
int __clock_config_on_enable(struct msm_vidc_core *core);
|
|
||||||
int __interrupt_init(struct msm_vidc_core *core);
|
|
||||||
int __setup_ucregion_memmap(struct msm_vidc_core *core);
|
|
||||||
int __raise_interrupt(struct msm_vidc_core *core);
|
|
||||||
int __power_on(struct msm_vidc_core *core);
|
|
||||||
int __power_off(struct msm_vidc_core *core);
|
|
||||||
bool __core_in_valid_state(struct msm_vidc_core *core);
|
bool __core_in_valid_state(struct msm_vidc_core *core);
|
||||||
int __load_fw(struct msm_vidc_core *core);
|
|
||||||
void __unload_fw(struct msm_vidc_core *core);
|
|
||||||
|
|
||||||
#endif // _VENUS_HFI_H_
|
#endif // _VENUS_HFI_H_
|
||||||
|
@@ -229,6 +229,7 @@ video_reg_failed:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MSM_MMRM
|
||||||
static int msm_vidc_check_mmrm_support(struct msm_vidc_core *core)
|
static int msm_vidc_check_mmrm_support(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -250,6 +251,19 @@ exit:
|
|||||||
d_vpr_h("%s: %d\n", __func__, core->capabilities[MMRM].value);
|
d_vpr_h("%s: %d\n", __func__, core->capabilities[MMRM].value);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static int msm_vidc_check_mmrm_support(struct msm_vidc_core *core)
|
||||||
|
{
|
||||||
|
if (!core || !core->capabilities) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
core->capabilities[MMRM].value = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int msm_vidc_deinitialize_core(struct msm_vidc_core *core)
|
static int msm_vidc_deinitialize_core(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
|
1148
driver/vidc/src/resources.c
Normal file
1148
driver/vidc/src/resources.c
Normal file
A különbségek nem kerülnek megjelenítésre, mivel a fájl túl nagy
Load Diff
A különbségek nem kerülnek megjelenítésre, mivel a fájl túl nagy
Load Diff
Reference in New Issue
Block a user