Skip to content

Commit

Permalink
media: venus: core, helpers: add two more clocks found in Venus 4xx
Browse files Browse the repository at this point in the history
Add two more clocks for Venus 4xx in core structure and create
a new power enable function to handle it for 3xx/4xx versions.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
Tested-by: Alexandre Courbot <acourbot@chromium.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
  • Loading branch information
Stanimir Varbanov authored and Mauro Carvalho Chehab committed Jul 25, 2018
1 parent 17cd3d1 commit aa3a841
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 16 deletions.
4 changes: 4 additions & 0 deletions drivers/media/platform/qcom/venus/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ struct venus_format {
* @clks: an array of struct clk pointers
* @core0_clk: a struct clk pointer for core0
* @core1_clk: a struct clk pointer for core1
* @core0_bus_clk: a struct clk pointer for core0 bus clock
* @core1_bus_clk: a struct clk pointer for core1 bus clock
* @vdev_dec: a reference to video device structure for decoder instances
* @vdev_enc: a reference to video device structure for encoder instances
* @v4l2_dev: a holder for v4l2 device structure
Expand Down Expand Up @@ -94,6 +96,8 @@ struct venus_core {
struct clk *clks[VIDC_CLKS_NUM_MAX];
struct clk *core0_clk;
struct clk *core1_clk;
struct clk *core0_bus_clk;
struct clk *core1_bus_clk;
struct video_device *vdev_dec;
struct video_device *vdev_enc;
struct v4l2_device v4l2_dev;
Expand Down
51 changes: 51 additions & 0 deletions drivers/media/platform/qcom/venus/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
*/
#include <linux/clk.h>
#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
Expand All @@ -24,6 +25,7 @@
#include "core.h"
#include "helpers.h"
#include "hfi_helper.h"
#include "hfi_venus_io.h"

struct intbuf {
struct list_head list;
Expand Down Expand Up @@ -786,3 +788,52 @@ void venus_helper_init_instance(struct venus_inst *inst)
}
}
EXPORT_SYMBOL_GPL(venus_helper_init_instance);

int venus_helper_power_enable(struct venus_core *core, u32 session_type,
bool enable)
{
void __iomem *ctrl, *stat;
u32 val;
int ret;

if (!IS_V3(core) && !IS_V4(core))
return 0;

if (IS_V3(core)) {
if (session_type == VIDC_SESSION_TYPE_DEC)
ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
else
ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
if (enable)
writel(0, ctrl);
else
writel(1, ctrl);

return 0;
}

if (session_type == VIDC_SESSION_TYPE_DEC) {
ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
} else {
ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
}

if (enable) {
writel(0, ctrl);

ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
if (ret)
return ret;
} else {
writel(1, ctrl);

ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
if (ret)
return ret;
}

return 0;
}
EXPORT_SYMBOL_GPL(venus_helper_power_enable);
2 changes: 2 additions & 0 deletions drivers/media/platform/qcom/venus/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
void venus_helper_init_instance(struct venus_inst *inst);
int venus_helper_power_enable(struct venus_core *core, u32 session_type,
bool enable);
#endif
44 changes: 36 additions & 8 deletions drivers/media/platform/qcom/venus/vdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1079,12 +1079,18 @@ static int vdec_probe(struct platform_device *pdev)
if (!core)
return -EPROBE_DEFER;

if (core->res->hfi_version == HFI_VERSION_3XX) {
if (IS_V3(core) || IS_V4(core)) {
core->core0_clk = devm_clk_get(dev, "core");
if (IS_ERR(core->core0_clk))
return PTR_ERR(core->core0_clk);
}

if (IS_V4(core)) {
core->core0_bus_clk = devm_clk_get(dev, "bus");
if (IS_ERR(core->core0_bus_clk))
return PTR_ERR(core->core0_bus_clk);
}

platform_set_drvdata(pdev, core);

vdev = video_device_alloc();
Expand Down Expand Up @@ -1129,29 +1135,51 @@ static int vdec_remove(struct platform_device *pdev)
static __maybe_unused int vdec_runtime_suspend(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
int ret;

if (core->res->hfi_version == HFI_VERSION_1XX)
if (IS_V1(core))
return 0;

writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
if (ret)
return ret;

if (IS_V4(core))
clk_disable_unprepare(core->core0_bus_clk);

clk_disable_unprepare(core->core0_clk);
writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);

return 0;
return venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
}

static __maybe_unused int vdec_runtime_resume(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
int ret;

if (core->res->hfi_version == HFI_VERSION_1XX)
if (IS_V1(core))
return 0;

writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
if (ret)
return ret;

ret = clk_prepare_enable(core->core0_clk);
writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
if (ret)
goto err_power_disable;

if (IS_V4(core))
ret = clk_prepare_enable(core->core0_bus_clk);

if (ret)
goto err_unprepare_core0;

return venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);

err_unprepare_core0:
clk_disable_unprepare(core->core0_clk);
err_power_disable:
venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
return ret;
}

Expand Down
44 changes: 36 additions & 8 deletions drivers/media/platform/qcom/venus/venc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,12 +1223,18 @@ static int venc_probe(struct platform_device *pdev)
if (!core)
return -EPROBE_DEFER;

if (core->res->hfi_version == HFI_VERSION_3XX) {
if (IS_V3(core) || IS_V4(core)) {
core->core1_clk = devm_clk_get(dev, "core");
if (IS_ERR(core->core1_clk))
return PTR_ERR(core->core1_clk);
}

if (IS_V4(core)) {
core->core1_bus_clk = devm_clk_get(dev, "bus");
if (IS_ERR(core->core1_bus_clk))
return PTR_ERR(core->core1_bus_clk);
}

platform_set_drvdata(pdev, core);

vdev = video_device_alloc();
Expand Down Expand Up @@ -1273,29 +1279,51 @@ static int venc_remove(struct platform_device *pdev)
static __maybe_unused int venc_runtime_suspend(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
int ret;

if (core->res->hfi_version == HFI_VERSION_1XX)
if (IS_V1(core))
return 0;

writel(0, core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL);
ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true);
if (ret)
return ret;

if (IS_V4(core))
clk_disable_unprepare(core->core1_bus_clk);

clk_disable_unprepare(core->core1_clk);
writel(1, core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL);

return 0;
return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false);
}

static __maybe_unused int venc_runtime_resume(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
int ret;

if (core->res->hfi_version == HFI_VERSION_1XX)
if (IS_V1(core))
return 0;

writel(0, core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL);
ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true);
if (ret)
return ret;

ret = clk_prepare_enable(core->core1_clk);
writel(1, core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL);
if (ret)
goto err_power_disable;

if (IS_V4(core))
ret = clk_prepare_enable(core->core1_bus_clk);

if (ret)
goto err_unprepare_core1;

return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false);

err_unprepare_core1:
clk_disable_unprepare(core->core1_clk);
err_power_disable:
venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false);
return ret;
}

Expand Down

0 comments on commit aa3a841

Please sign in to comment.