mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
video: rockchip: mpp: workaround for rk3036 hevc & vdpu combo
Signed-off-by: Chandler Chen <chandler.chen@rock-chips.com> Change-Id: I42844249859f3a3dad8013f6ca7dc0f4e9a4e743
This commit is contained in:
@@ -1029,6 +1029,7 @@ struct mpp_taskqueue *mpp_taskqueue_init(struct device *dev)
|
||||
atomic_set(&queue->reset_request, 0);
|
||||
atomic_set(&queue->detach_count, 0);
|
||||
atomic_set(&queue->task_id, 0);
|
||||
queue->dev_active_flags = 0;
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
@@ -540,6 +540,7 @@ struct mpp_taskqueue {
|
||||
unsigned long core_idle;
|
||||
u32 core_id_max;
|
||||
u32 core_count;
|
||||
unsigned long dev_active_flags;
|
||||
};
|
||||
|
||||
struct mpp_reset_group {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_iommu.h"
|
||||
#include <soc/rockchip/rockchip_iommu.h>
|
||||
|
||||
#include "hack/mpp_hack_px30.h"
|
||||
|
||||
@@ -1280,6 +1281,13 @@ static int rkvdec_px30_init(struct mpp_dev *mpp)
|
||||
return px30_workaround_combo_init(mpp);
|
||||
}
|
||||
|
||||
static int rkvdec_3036_init(struct mpp_dev *mpp)
|
||||
{
|
||||
rkvdec_init(mpp);
|
||||
set_bit(mpp->var->device_type, &mpp->queue->dev_active_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvdec_3328_iommu_hdl(struct iommu_domain *iommu,
|
||||
struct device *iommu_dev,
|
||||
unsigned long iova,
|
||||
@@ -1533,6 +1541,47 @@ static int rkvdec_3368_set_grf(struct mpp_dev *mpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvdec_3036_set_grf(struct mpp_dev *mpp)
|
||||
{
|
||||
int grf_changed;
|
||||
struct mpp_dev *loop = NULL, *n;
|
||||
struct mpp_taskqueue *queue = mpp->queue;
|
||||
bool pd_is_on;
|
||||
|
||||
grf_changed = mpp_grf_is_changed(mpp->grf_info);
|
||||
if (grf_changed) {
|
||||
|
||||
/*
|
||||
* in this case, devices share the queue also share the same pd&clk,
|
||||
* so use mpp->dev's pd to control all the process is okay
|
||||
*/
|
||||
pd_is_on = rockchip_pmu_pd_is_on(mpp->dev);
|
||||
if (!pd_is_on)
|
||||
rockchip_pmu_pd_on(mpp->dev);
|
||||
mpp->hw_ops->clk_on(mpp);
|
||||
|
||||
list_for_each_entry_safe(loop, n, &queue->dev_list, queue_link) {
|
||||
if (test_bit(loop->var->device_type, &queue->dev_active_flags)) {
|
||||
if (loop->hw_ops->reset)
|
||||
loop->hw_ops->reset(loop);
|
||||
rockchip_iommu_disable(loop->dev);
|
||||
clear_bit(loop->var->device_type, &queue->dev_active_flags);
|
||||
}
|
||||
}
|
||||
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
rockchip_iommu_enable(mpp->dev);
|
||||
set_bit(mpp->var->device_type, &queue->dev_active_flags);
|
||||
|
||||
mpp->hw_ops->clk_off(mpp);
|
||||
if (!pd_is_on)
|
||||
rockchip_pmu_pd_off(mpp->dev);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvdec_set_freq(struct mpp_dev *mpp,
|
||||
struct mpp_task *mpp_task)
|
||||
{
|
||||
@@ -1708,6 +1757,17 @@ static struct mpp_hw_ops rkvdec_px30_hw_ops = {
|
||||
.set_grf = px30_workaround_combo_switch_grf,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops rkvdec_3036_hw_ops = {
|
||||
.init = rkvdec_3036_init,
|
||||
.clk_on = rkvdec_clk_on,
|
||||
.clk_off = rkvdec_clk_off,
|
||||
.get_freq = rkvdec_get_freq,
|
||||
.set_freq = rkvdec_set_freq,
|
||||
.reduce_freq = rkvdec_reduce_freq,
|
||||
.reset = rkvdec_reset,
|
||||
.set_grf = rkvdec_3036_set_grf,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops rkvdec_3399_hw_ops = {
|
||||
.init = rkvdec_init,
|
||||
.clk_on = rkvdec_clk_on,
|
||||
@@ -1798,6 +1858,14 @@ static const struct mpp_dev_var rk_hevcdec_data = {
|
||||
.dev_ops = &rkvdec_v1_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var rk_hevcdec_3036_data = {
|
||||
.device_type = MPP_DEVICE_HEVC_DEC,
|
||||
.hw_info = &rk_hevcdec_hw_info,
|
||||
.trans_info = rk_hevcdec_trans,
|
||||
.hw_ops = &rkvdec_3036_hw_ops,
|
||||
.dev_ops = &rkvdec_v1_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var rk_hevcdec_3368_data = {
|
||||
.device_type = MPP_DEVICE_HEVC_DEC,
|
||||
.hw_info = &rk_hevcdec_hw_info,
|
||||
@@ -1857,6 +1925,12 @@ static const struct of_device_id mpp_rkvdec_dt_match[] = {
|
||||
.data = &rk_hevcdec_px30_data,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_RK3036
|
||||
{
|
||||
.compatible = "rockchip,hevc-decoder-rk3036",
|
||||
.data = &rk_hevcdec_3036_data,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_RK3368
|
||||
{
|
||||
.compatible = "rockchip,hevc-decoder-rk3368",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_iommu.h"
|
||||
#include <soc/rockchip/rockchip_iommu.h>
|
||||
|
||||
#define VDPU1_DRIVER_NAME "mpp_vdpu1"
|
||||
|
||||
@@ -563,6 +564,13 @@ static int vdpu_init(struct mpp_dev *mpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vdpu_3036_init(struct mpp_dev *mpp)
|
||||
{
|
||||
vdpu_init(mpp);
|
||||
set_bit(mpp->var->device_type, &mpp->queue->dev_active_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vdpu_clk_on(struct mpp_dev *mpp)
|
||||
{
|
||||
struct vdpu_dev *dec = to_vdpu_dev(mpp);
|
||||
@@ -699,6 +707,46 @@ static int vdpu_reset(struct mpp_dev *mpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vdpu_3036_set_grf(struct mpp_dev *mpp)
|
||||
{
|
||||
int grf_changed;
|
||||
struct mpp_dev *loop = NULL, *n;
|
||||
struct mpp_taskqueue *queue = mpp->queue;
|
||||
bool pd_is_on;
|
||||
|
||||
grf_changed = mpp_grf_is_changed(mpp->grf_info);
|
||||
if (grf_changed) {
|
||||
|
||||
/*
|
||||
* in this case, devices share the queue also share the same pd&clk,
|
||||
* so use mpp->dev's pd to control all the process is okay
|
||||
*/
|
||||
pd_is_on = rockchip_pmu_pd_is_on(mpp->dev);
|
||||
if (!pd_is_on)
|
||||
rockchip_pmu_pd_on(mpp->dev);
|
||||
mpp->hw_ops->clk_on(mpp);
|
||||
|
||||
list_for_each_entry_safe(loop, n, &queue->dev_list, queue_link) {
|
||||
if (test_bit(loop->var->device_type, &queue->dev_active_flags)) {
|
||||
if (loop->hw_ops->reset)
|
||||
loop->hw_ops->reset(loop);
|
||||
rockchip_iommu_disable(loop->dev);
|
||||
clear_bit(loop->var->device_type, &queue->dev_active_flags);
|
||||
}
|
||||
}
|
||||
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
rockchip_iommu_enable(mpp->dev);
|
||||
set_bit(mpp->var->device_type, &queue->dev_active_flags);
|
||||
|
||||
mpp->hw_ops->clk_off(mpp);
|
||||
if (!pd_is_on)
|
||||
rockchip_pmu_pd_off(mpp->dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mpp_hw_ops vdpu_v1_hw_ops = {
|
||||
.init = vdpu_init,
|
||||
.clk_on = vdpu_clk_on,
|
||||
@@ -706,6 +754,17 @@ static struct mpp_hw_ops vdpu_v1_hw_ops = {
|
||||
.set_freq = vdpu_set_freq,
|
||||
.reduce_freq = vdpu_reduce_freq,
|
||||
.reset = vdpu_reset,
|
||||
.set_grf = vdpu_3036_set_grf,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops vdpu_3036_hw_ops = {
|
||||
.init = vdpu_3036_init,
|
||||
.clk_on = vdpu_clk_on,
|
||||
.clk_off = vdpu_clk_off,
|
||||
.set_freq = vdpu_set_freq,
|
||||
.reduce_freq = vdpu_reduce_freq,
|
||||
.reset = vdpu_reset,
|
||||
.set_grf = vdpu_3036_set_grf,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops vdpu_3288_hw_ops = {
|
||||
@@ -746,6 +805,14 @@ static const struct mpp_dev_var vdpu_v1_data = {
|
||||
.dev_ops = &vdpu_v1_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var vdpu_3036_data = {
|
||||
.device_type = MPP_DEVICE_VDPU1,
|
||||
.hw_info = &vdpu_v1_hw_info,
|
||||
.trans_info = vdpu_v1_trans,
|
||||
.hw_ops = &vdpu_3036_hw_ops,
|
||||
.dev_ops = &vdpu_v1_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var vdpu_3288_data = {
|
||||
.device_type = MPP_DEVICE_VDPU1,
|
||||
.hw_info = &vdpu_v1_hw_info,
|
||||
@@ -781,6 +848,12 @@ static const struct of_device_id mpp_vdpu1_dt_match[] = {
|
||||
.data = &vdpu_3288_data,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_RK3036
|
||||
{
|
||||
.compatible = "rockchip,vpu-decoder-rk3036",
|
||||
.data = &vdpu_3036_data,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_RK3368
|
||||
{
|
||||
.compatible = "rockchip,vpu-decoder-rk3368",
|
||||
|
||||
Reference in New Issue
Block a user