lkml.org 
[lkml]   [2022]   [Apr]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v10, 01/17] media: mediatek: vcodec: Add vdec enable/disable hardware helpers
    Date
    Lock, power and clock are highly coupled operations. Adds vdec
    enable/disable hardware helpers and uses them.

    Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
    Reviewed-by: Tzung-Bi Shih<tzungbi@google.com>
    Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
    ---
    .../mediatek/vcodec/mtk_vcodec_dec_drv.c | 5 -
    .../mediatek/vcodec/mtk_vcodec_dec_pm.c | 166 +++++++++++-------
    .../mediatek/vcodec/mtk_vcodec_dec_pm.h | 6 +-
    .../platform/mediatek/vcodec/vdec_drv_if.c | 20 +--
    .../platform/mediatek/vcodec/vdec_msg_queue.c | 2 +
    5 files changed, 116 insertions(+), 83 deletions(-)

    diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
    index df7b25e9cbc8..a84df6596aaa 100644
    --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
    +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
    @@ -193,9 +193,6 @@ static int fops_vcodec_open(struct file *file)
    mtk_vcodec_dec_set_default_params(ctx);

    if (v4l2_fh_is_singular(&ctx->fh)) {
    - ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
    - if (ret < 0)
    - goto err_load_fw;
    /*
    * Does nothing if firmware was already loaded.
    */
    @@ -252,8 +249,6 @@ static int fops_vcodec_release(struct file *file)
    v4l2_m2m_ctx_release(ctx->m2m_ctx);
    mtk_vcodec_dec_release(ctx);

    - if (v4l2_fh_is_singular(&ctx->fh))
    - mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
    v4l2_fh_del(&ctx->fh);
    v4l2_fh_exit(&ctx->fh);
    v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
    diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c
    index 7e0c2644bf7b..0fb7e5ba635b 100644
    --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c
    +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c
    @@ -57,74 +57,31 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *
    }
    EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);

    -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    +static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
    {
    - struct mtk_vdec_hw_dev *subdev_dev;
    - struct mtk_vcodec_pm *pm;
    int ret;

    - if (vdec_dev->vdec_pdata->is_subdev_supported) {
    - subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
    - if (!subdev_dev) {
    - mtk_v4l2_err("Failed to get hw dev\n");
    - return -EINVAL;
    - }
    - pm = &subdev_dev->pm;
    - } else {
    - pm = &vdec_dev->pm;
    - }
    -
    ret = pm_runtime_resume_and_get(pm->dev);
    if (ret)
    mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);

    return ret;
    }
    -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);

    -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    +static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
    {
    - struct mtk_vdec_hw_dev *subdev_dev;
    - struct mtk_vcodec_pm *pm;
    int ret;

    - if (vdec_dev->vdec_pdata->is_subdev_supported) {
    - subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
    - if (!subdev_dev) {
    - mtk_v4l2_err("Failed to get hw dev\n");
    - return;
    - }
    - pm = &subdev_dev->pm;
    - } else {
    - pm = &vdec_dev->pm;
    - }
    -
    ret = pm_runtime_put_sync(pm->dev);
    if (ret)
    mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
    }
    -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);

    -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    +static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
    {
    - struct mtk_vdec_hw_dev *subdev_dev;
    - struct mtk_vcodec_pm *pm;
    struct mtk_vcodec_clk *dec_clk;
    int ret, i;

    - if (vdec_dev->vdec_pdata->is_subdev_supported) {
    - subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
    - if (!subdev_dev) {
    - mtk_v4l2_err("Failed to get hw dev\n");
    - return;
    - }
    - pm = &subdev_dev->pm;
    - enable_irq(subdev_dev->dec_irq);
    - } else {
    - pm = &vdec_dev->pm;
    - enable_irq(vdec_dev->dec_irq);
    - }
    -
    dec_clk = &pm->vdec_clk;
    for (i = 0; i < dec_clk->clk_num; i++) {
    ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
    @@ -140,30 +97,119 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    for (i -= 1; i >= 0; i--)
    clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
    }
    -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);

    -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    +static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
    {
    - struct mtk_vdec_hw_dev *subdev_dev;
    - struct mtk_vcodec_pm *pm;
    struct mtk_vcodec_clk *dec_clk;
    int i;

    + dec_clk = &pm->vdec_clk;
    + for (i = dec_clk->clk_num - 1; i >= 0; i--)
    + clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
    +}
    +
    +static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    +{
    + struct mtk_vdec_hw_dev *subdev_dev;
    +
    + if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
    + return;
    +
    if (vdec_dev->vdec_pdata->is_subdev_supported) {
    subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
    - if (!subdev_dev) {
    + if (subdev_dev)
    + enable_irq(subdev_dev->dec_irq);
    + else
    + mtk_v4l2_err("Failed to get hw dev\n");
    + } else {
    + enable_irq(vdec_dev->dec_irq);
    + }
    +}
    +
    +static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
    +{
    + struct mtk_vdec_hw_dev *subdev_dev;
    +
    + if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
    + return;
    +
    + if (vdec_dev->vdec_pdata->is_subdev_supported) {
    + subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
    + if (subdev_dev)
    + disable_irq(subdev_dev->dec_irq);
    + else
    mtk_v4l2_err("Failed to get hw dev\n");
    - return;
    - }
    - pm = &subdev_dev->pm;
    - disable_irq(subdev_dev->dec_irq);
    } else {
    - pm = &vdec_dev->pm;
    disable_irq(vdec_dev->dec_irq);
    }
    +}

    - dec_clk = &pm->vdec_clk;
    - for (i = dec_clk->clk_num - 1; i >= 0; i--)
    - clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
    +static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
    + int hw_idx)
    +{
    + struct mtk_vdec_hw_dev *subdev_dev;
    +
    + if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
    + return NULL;
    +
    + if (vdec_dev->vdec_pdata->is_subdev_supported) {
    + subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
    + if (subdev_dev)
    + return &subdev_dev->pm;
    +
    + mtk_v4l2_err("Failed to get hw dev\n");
    + return NULL;
    + }
    +
    + return &vdec_dev->pm;
    +}
    +
    +static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
    + int hw_idx)
    +{
    + struct mtk_vcodec_pm *pm;
    +
    + pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
    + if (pm) {
    + mtk_vcodec_dec_pw_on(pm);
    + mtk_vcodec_dec_clock_on(pm);
    + }
    +}
    +
    +static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
    + int hw_idx)
    +{
    + struct mtk_vcodec_pm *pm;
    +
    + pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
    + if (pm) {
    + mtk_vcodec_dec_clock_off(pm);
    + mtk_vcodec_dec_pw_off(pm);
    + }
    +}
    +
    +void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
    +{
    + mutex_lock(&ctx->dev->dec_mutex[hw_idx]);
    +
    + if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
    + hw_idx == MTK_VDEC_CORE)
    + mtk_vcodec_dec_child_dev_on(ctx->dev, MTK_VDEC_LAT0);
    + mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
    +
    + mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
    +}
    +EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
    +
    +void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
    +{
    + mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
    +
    + mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
    + if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
    + hw_idx == MTK_VDEC_CORE)
    + mtk_vcodec_dec_child_dev_off(ctx->dev, MTK_VDEC_LAT0);
    +
    + mutex_unlock(&ctx->dev->dec_mutex[hw_idx]);
    }
    -EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
    +EXPORT_SYMBOL_GPL(mtk_vcodec_dec_disable_hardware);
    diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h
    index 3cc721bbfaf6..dbcf3cabe6f3 100644
    --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h
    +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.h
    @@ -11,9 +11,7 @@

    int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm);

    -int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
    -void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
    -void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
    -void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
    +void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
    +void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);

    #endif /* _MTK_VCODEC_DEC_PM_H_ */
    diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c
    index 05a5b240e906..c93dd0ea3537 100644
    --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c
    +++ b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c
    @@ -38,11 +38,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
    return -EINVAL;
    }

    - mtk_vdec_lock(ctx);
    - mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
    + mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
    ret = ctx->dec_if->init(ctx);
    - mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
    - mtk_vdec_unlock(ctx);
    + mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);

    return ret;
    }
    @@ -70,15 +68,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
    if (!ctx->drv_handle)
    return -EIO;

    - mtk_vdec_lock(ctx);
    -
    + mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
    mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
    - mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
    ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
    - mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
    mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
    -
    - mtk_vdec_unlock(ctx);
    + mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);

    return ret;
    }
    @@ -103,11 +97,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
    if (!ctx->drv_handle)
    return;

    - mtk_vdec_lock(ctx);
    - mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
    + mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
    ctx->dec_if->deinit(ctx->drv_handle);
    - mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
    - mtk_vdec_unlock(ctx);
    + mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);

    ctx->drv_handle = NULL;
    }
    diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
    index 4b062a8128b4..ae500980ad45 100644
    --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
    +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
    @@ -212,11 +212,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
    return;

    ctx = lat_buf->ctx;
    + mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE);
    mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);

    lat_buf->core_decode(lat_buf);

    mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
    + mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
    vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);

    if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
    --
    2.18.0
    \
     
     \ /
      Last update: 2022-04-26 12:29    [W:4.084 / U:0.152 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site