mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
video: rockchip: mpp: deal with issue for px30 264/265 switch
px30 grf switch method:
a) ensure clk on
b) ensure power on
c) disable all iommu
d) switch grf
e) enable current iommu
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: I1015ea9df6d8745f0a4922a1f684082660fac314
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
@@ -388,7 +388,10 @@ static int mpp_dev_reset(struct mpp_dev *mpp)
|
||||
* before running, we have to switch grf ctrl bit to ensure
|
||||
* working in current hardware
|
||||
*/
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
if (mpp->hw_ops->set_grf)
|
||||
mpp->hw_ops->set_grf(mpp);
|
||||
else
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
|
||||
if (mpp->hw_ops->reduce_freq)
|
||||
mpp->hw_ops->reduce_freq(mpp);
|
||||
@@ -457,7 +460,15 @@ static int mpp_task_run(struct mpp_dev *mpp,
|
||||
* before running, we have to switch grf ctrl bit to ensure
|
||||
* working in current hardware
|
||||
*/
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
if (mpp->hw_ops->set_grf) {
|
||||
ret = mpp->hw_ops->set_grf(mpp);
|
||||
if (ret) {
|
||||
dev_err(mpp->dev, "set grf failed\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
}
|
||||
/*
|
||||
* for iommu share hardware, should attach to ensure
|
||||
* working in current device
|
||||
@@ -664,6 +675,7 @@ int mpp_taskqueue_init(struct mpp_taskqueue *queue,
|
||||
mutex_init(&queue->lock);
|
||||
atomic_set(&queue->running, 0);
|
||||
INIT_LIST_HEAD(&queue->pending);
|
||||
INIT_LIST_HEAD(&queue->mmu_link);
|
||||
INIT_WORK(&queue->work, mpp_task_try_run);
|
||||
|
||||
queue->srv = srv;
|
||||
@@ -1469,6 +1481,20 @@ int mpp_safe_unreset(struct reset_control *rst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MPP_GRF_VAL_MASK 0xFFFF
|
||||
|
||||
u32 mpp_get_grf(struct mpp_grf_info *grf_info)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if (grf_info->grf && grf_info->val)
|
||||
regmap_read(grf_info->grf,
|
||||
grf_info->offset,
|
||||
&val);
|
||||
|
||||
return (val & MPP_GRF_VAL_MASK);
|
||||
}
|
||||
|
||||
int mpp_set_grf(struct mpp_grf_info *grf_info)
|
||||
{
|
||||
if (grf_info->grf && grf_info->val)
|
||||
@@ -1525,3 +1551,85 @@ int mpp_read_req(struct mpp_dev *mpp, u32 *regs,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int px30_workaround_combo_init(struct mpp_dev *mpp)
|
||||
{
|
||||
struct mpp_rk_iommu *iommu = NULL, *loop = NULL, *n;
|
||||
struct platform_device *pdev = mpp->iommu_info->pdev;
|
||||
|
||||
/* find whether exist in iommu link */
|
||||
list_for_each_entry_safe(loop, n, &mpp->queue->mmu_link, link) {
|
||||
if (loop->base_addr[0] == pdev->resource[0].start) {
|
||||
iommu = loop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if not exist, add it */
|
||||
if (!iommu) {
|
||||
int i;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
|
||||
iommu = devm_kzalloc(mpp->srv->dev, sizeof(*iommu), GFP_KERNEL);
|
||||
for (i = 0; i < pdev->num_resources; i++) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
|
||||
if (!res)
|
||||
continue;
|
||||
base = devm_ioremap(&pdev->dev,
|
||||
res->start, resource_size(res));
|
||||
if (IS_ERR(base))
|
||||
continue;
|
||||
iommu->base_addr[i] = res->start;
|
||||
iommu->bases[i] = base;
|
||||
iommu->mmu_num++;
|
||||
}
|
||||
iommu->grf_val = mpp->grf_info->val & MPP_GRF_VAL_MASK;
|
||||
iommu->dte_addr = mpp_iommu_get_dte_addr(iommu);
|
||||
INIT_LIST_HEAD(&iommu->link);
|
||||
mutex_lock(&mpp->queue->lock);
|
||||
list_add_tail(&iommu->link, &mpp->queue->mmu_link);
|
||||
mutex_unlock(&mpp->queue->lock);
|
||||
}
|
||||
mpp->iommu_info->iommu = iommu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int px30_workaround_combo_switch_grf(struct mpp_dev *mpp)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 curr_val;
|
||||
u32 next_val;
|
||||
bool pd_is_on;
|
||||
struct mpp_rk_iommu *loop = NULL, *n;
|
||||
|
||||
if (!mpp->grf_info->grf || !mpp->grf_info->val)
|
||||
return 0;
|
||||
|
||||
curr_val = mpp_get_grf(mpp->grf_info);
|
||||
next_val = mpp->grf_info->val & MPP_GRF_VAL_MASK;
|
||||
if (curr_val == next_val)
|
||||
return 0;
|
||||
|
||||
pd_is_on = rockchip_pmu_pd_is_on(mpp->dev);
|
||||
if (!pd_is_on)
|
||||
rockchip_pmu_pd_on(mpp->dev);
|
||||
mpp->hw_ops->power_on(mpp);
|
||||
|
||||
list_for_each_entry_safe(loop, n, &mpp->queue->mmu_link, link) {
|
||||
/* update iommu parameters */
|
||||
if (loop->grf_val == curr_val)
|
||||
loop->is_paged = mpp_iommu_is_paged(loop);
|
||||
/* disable all iommu */
|
||||
mpp_iommu_disable(loop);
|
||||
}
|
||||
mpp_set_grf(mpp->grf_info);
|
||||
/* enable current iommu */
|
||||
ret = mpp_iommu_enable(mpp->iommu_info->iommu);
|
||||
|
||||
mpp->hw_ops->power_off(mpp);
|
||||
if (!pd_is_on)
|
||||
rockchip_pmu_pd_off(mpp->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -254,6 +254,8 @@ struct mpp_taskqueue {
|
||||
atomic_t running;
|
||||
struct mpp_task *cur_task;
|
||||
struct mpp_service *srv;
|
||||
/* link to mmu iommu node */
|
||||
struct list_head mmu_link;
|
||||
};
|
||||
|
||||
struct mpp_reset_clk {
|
||||
@@ -311,6 +313,7 @@ struct mpp_hw_ops {
|
||||
struct mpp_task *mpp_task);
|
||||
int (*reduce_freq)(struct mpp_dev *mpp);
|
||||
int (*reset)(struct mpp_dev *mpp);
|
||||
int (*set_grf)(struct mpp_dev *mpp);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -383,6 +386,7 @@ mpp_reset_control_get(struct mpp_dev *mpp, const char *name);
|
||||
int mpp_safe_reset(struct reset_control *rst);
|
||||
int mpp_safe_unreset(struct reset_control *rst);
|
||||
|
||||
u32 mpp_get_grf(struct mpp_grf_info *grf_info);
|
||||
int mpp_set_grf(struct mpp_grf_info *grf_info);
|
||||
|
||||
int mpp_time_record(struct mpp_task *task);
|
||||
@@ -435,6 +439,10 @@ static inline u32 mpp_read_relaxed(struct mpp_dev *mpp, u32 reg)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* workaround according hardware */
|
||||
int px30_workaround_combo_init(struct mpp_dev *mpp);
|
||||
int px30_workaround_combo_switch_grf(struct mpp_dev *mpp);
|
||||
|
||||
extern const struct file_operations rockchip_mpp_fops;
|
||||
|
||||
extern struct platform_driver rockchip_rkvdec_driver;
|
||||
|
||||
@@ -11,9 +11,12 @@
|
||||
#ifdef CONFIG_ARM_DMA_USE_IOMMU
|
||||
#include <asm/dma-iommu.h>
|
||||
#endif
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-iommu.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@@ -350,17 +353,33 @@ struct mpp_iommu_info *
|
||||
mpp_iommu_probe(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct device_node *np = NULL;
|
||||
struct platform_device *pdev = NULL;
|
||||
struct mpp_iommu_info *info = NULL;
|
||||
#ifdef CONFIG_ARM_DMA_USE_IOMMU
|
||||
struct dma_iommu_mapping *mapping;
|
||||
#endif
|
||||
|
||||
np = of_parse_phandle(dev->of_node, "iommus", 0);
|
||||
if (!np || !of_device_is_available(np)) {
|
||||
mpp_err("failed to get device node\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev) {
|
||||
mpp_err("failed to get platform device\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
info->dev = dev;
|
||||
info->pdev = pdev;
|
||||
|
||||
info->group = iommu_group_get(dev);
|
||||
if (!info->group) {
|
||||
@@ -411,3 +430,126 @@ int mpp_iommu_remove(struct mpp_iommu_info *info)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RK_MMU_DTE_ADDR 0x00 /* Directory table address */
|
||||
#define RK_MMU_STATUS 0x04
|
||||
#define RK_MMU_COMMAND 0x08
|
||||
#define RK_MMU_INT_MASK 0x1C /* IRQ enable */
|
||||
|
||||
/* RK_MMU_COMMAND command values */
|
||||
#define RK_MMU_CMD_ENABLE_PAGING 0 /* Enable memory translation */
|
||||
#define RK_MMU_CMD_DISABLE_PAGING 1 /* Disable memory translation */
|
||||
#define RK_MMU_CMD_ENABLE_STALL 2 /* Stall paging to allow other cmds */
|
||||
#define RK_MMU_CMD_DISABLE_STALL 3 /* Stop stall re-enables paging */
|
||||
#define RK_MMU_CMD_ZAP_CACHE 4 /* Shoot down entire IOTLB */
|
||||
#define RK_MMU_CMD_PAGE_FAULT_DONE 5 /* Clear page fault */
|
||||
#define RK_MMU_CMD_FORCE_RESET 6 /* Reset all registers */
|
||||
|
||||
/* RK_MMU_INT_* register fields */
|
||||
#define RK_MMU_IRQ_MASK 0x03
|
||||
/* RK_MMU_STATUS fields */
|
||||
#define RK_MMU_STATUS_PAGING_ENABLED BIT(0)
|
||||
#define RK_MMU_STATUS_STALL_ACTIVE BIT(2)
|
||||
|
||||
bool mpp_iommu_is_paged(struct mpp_rk_iommu *iommu)
|
||||
{
|
||||
int i;
|
||||
u32 status;
|
||||
bool active = true;
|
||||
|
||||
for (i = 0; i < iommu->mmu_num; i++) {
|
||||
status = readl(iommu->bases[i] + RK_MMU_STATUS);
|
||||
active &= !!(status & RK_MMU_STATUS_PAGING_ENABLED);
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
u32 mpp_iommu_get_dte_addr(struct mpp_rk_iommu *iommu)
|
||||
{
|
||||
return readl(iommu->bases[0] + RK_MMU_DTE_ADDR);
|
||||
}
|
||||
|
||||
int mpp_iommu_enable(struct mpp_rk_iommu *iommu)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* iommu should be paging disable */
|
||||
if (mpp_iommu_is_paged(iommu)) {
|
||||
mpp_err("iommu disable failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* enable stall */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_ENABLE_STALL,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
/* force reset */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_FORCE_RESET,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
|
||||
for (i = 0; i < iommu->mmu_num; i++) {
|
||||
/* restore dte and status */
|
||||
writel(iommu->dte_addr,
|
||||
iommu->bases[i] + RK_MMU_DTE_ADDR);
|
||||
/* zap cache */
|
||||
writel(RK_MMU_CMD_ZAP_CACHE,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
/* irq mask */
|
||||
writel(RK_MMU_IRQ_MASK,
|
||||
iommu->bases[i] + RK_MMU_INT_MASK);
|
||||
}
|
||||
udelay(2);
|
||||
/* enable paging */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_ENABLE_PAGING,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
/* disable stall */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_DISABLE_STALL,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
|
||||
/* iommu should be paging enable */
|
||||
iommu->is_paged = mpp_iommu_is_paged(iommu);
|
||||
if (!iommu->is_paged) {
|
||||
mpp_err("iommu enable failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mpp_iommu_disable(struct mpp_rk_iommu *iommu)
|
||||
{
|
||||
int i;
|
||||
u32 dte;
|
||||
|
||||
if (iommu->is_paged) {
|
||||
dte = readl(iommu->bases[0] + RK_MMU_DTE_ADDR);
|
||||
if (!dte)
|
||||
return -EINVAL;
|
||||
udelay(2);
|
||||
/* enable stall */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_ENABLE_STALL,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
/* disable paging */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_DISABLE_PAGING,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
/* disable stall */
|
||||
for (i = 0; i < iommu->mmu_num; i++)
|
||||
writel(RK_MMU_CMD_DISABLE_STALL,
|
||||
iommu->bases[i] + RK_MMU_COMMAND);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,10 +46,22 @@ struct mpp_dma_session {
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
struct mpp_rk_iommu {
|
||||
struct list_head link;
|
||||
u32 grf_val;
|
||||
int mmu_num;
|
||||
u32 base_addr[2];
|
||||
void __iomem *bases[2];
|
||||
u32 dte_addr;
|
||||
u32 is_paged;
|
||||
};
|
||||
|
||||
struct mpp_iommu_info {
|
||||
struct device *dev;
|
||||
struct device *dev;
|
||||
struct platform_device *pdev;
|
||||
struct iommu_domain *domain;
|
||||
struct iommu_group *group;
|
||||
struct mpp_rk_iommu *iommu;
|
||||
};
|
||||
|
||||
struct mpp_dma_session *
|
||||
@@ -78,4 +90,9 @@ int mpp_iommu_remove(struct mpp_iommu_info *info);
|
||||
int mpp_iommu_attach(struct mpp_iommu_info *info);
|
||||
int mpp_iommu_detach(struct mpp_iommu_info *info);
|
||||
|
||||
bool mpp_iommu_is_paged(struct mpp_rk_iommu *iommu);
|
||||
u32 mpp_iommu_get_dte_addr(struct mpp_rk_iommu *iommu);
|
||||
int mpp_iommu_enable(struct mpp_rk_iommu *iommu);
|
||||
int mpp_iommu_disable(struct mpp_rk_iommu *iommu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1166,6 +1166,12 @@ static int rkvdec_init(struct mpp_dev *mpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvdec_px30_init(struct mpp_dev *mpp)
|
||||
{
|
||||
rkvdec_init(mpp);
|
||||
return px30_workaround_combo_init(mpp);
|
||||
}
|
||||
|
||||
static int rkvdec_3328_iommu_hdl(struct iommu_domain *iommu,
|
||||
struct device *iommu_dev,
|
||||
unsigned long iova,
|
||||
@@ -1522,6 +1528,17 @@ static struct mpp_hw_ops rkvdec_v1_hw_ops = {
|
||||
.reset = rkvdec_reset,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops rkvdec_px30_hw_ops = {
|
||||
.init = rkvdec_px30_init,
|
||||
.power_on = rkvdec_power_on,
|
||||
.power_off = rkvdec_power_off,
|
||||
.get_freq = rkvdec_get_freq,
|
||||
.set_freq = rkvdec_set_freq,
|
||||
.reduce_freq = rkvdec_reduce_freq,
|
||||
.reset = rkvdec_reset,
|
||||
.set_grf = px30_workaround_combo_switch_grf,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops rkvdec_3399_hw_ops = {
|
||||
.init = rkvdec_init,
|
||||
.power_on = rkvdec_power_on,
|
||||
@@ -1573,6 +1590,14 @@ static const struct mpp_dev_var rk_hevcdec_data = {
|
||||
.dev_ops = &rkvdec_v1_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var rk_hevcdec_px30_data = {
|
||||
.device_type = MPP_DEVICE_HEVC_DEC,
|
||||
.hw_info = &rk_hevcdec_hw_info,
|
||||
.trans_info = rk_hevcdec_trans,
|
||||
.hw_ops = &rkvdec_px30_hw_ops,
|
||||
.dev_ops = &rkvdec_v1_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var rkvdec_v1_data = {
|
||||
.device_type = MPP_DEVICE_RKVDEC,
|
||||
.hw_info = &rkvdec_v1_hw_info,
|
||||
@@ -1602,6 +1627,10 @@ static const struct of_device_id mpp_rkvdec_dt_match[] = {
|
||||
.compatible = "rockchip,hevc-decoder",
|
||||
.data = &rk_hevcdec_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,hevc-decoder-px30",
|
||||
.data = &rk_hevcdec_px30_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rkv-decoder-v1",
|
||||
.data = &rkvdec_v1_data,
|
||||
|
||||
@@ -516,6 +516,12 @@ static int vdpu_init(struct mpp_dev *mpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vdpu_px30_init(struct mpp_dev *mpp)
|
||||
{
|
||||
vdpu_init(mpp);
|
||||
return px30_workaround_combo_init(mpp);
|
||||
}
|
||||
|
||||
static int vdpu_power_on(struct mpp_dev *mpp)
|
||||
{
|
||||
struct vdpu_dev *dec = to_vdpu_dev(mpp);
|
||||
@@ -655,6 +661,17 @@ static struct mpp_hw_ops vdpu_v2_hw_ops = {
|
||||
.reset = vdpu_reset,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops vdpu_px30_hw_ops = {
|
||||
.init = vdpu_px30_init,
|
||||
.power_on = vdpu_power_on,
|
||||
.power_off = vdpu_power_off,
|
||||
.get_freq = vdpu_get_freq,
|
||||
.set_freq = vdpu_set_freq,
|
||||
.reduce_freq = vdpu_reduce_freq,
|
||||
.reset = vdpu_reset,
|
||||
.set_grf = px30_workaround_combo_switch_grf,
|
||||
};
|
||||
|
||||
static struct mpp_dev_ops vdpu_v2_dev_ops = {
|
||||
.alloc_task = vdpu_alloc_task,
|
||||
.prepare = vdpu_prepare,
|
||||
@@ -674,11 +691,23 @@ static const struct mpp_dev_var vdpu_v2_data = {
|
||||
.dev_ops = &vdpu_v2_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var vdpu_px30_data = {
|
||||
.device_type = MPP_DEVICE_VDPU2,
|
||||
.hw_info = &vdpu_v2_hw_info,
|
||||
.trans_info = vdpu_v2_trans,
|
||||
.hw_ops = &vdpu_px30_hw_ops,
|
||||
.dev_ops = &vdpu_v2_dev_ops,
|
||||
};
|
||||
|
||||
static const struct of_device_id mpp_vdpu2_dt_match[] = {
|
||||
{
|
||||
.compatible = "rockchip,vpu-decoder-v2",
|
||||
.data = &vdpu_v2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,vpu-decoder-px30",
|
||||
.data = &vdpu_px30_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
@@ -483,6 +483,12 @@ static int vepu_init(struct mpp_dev *mpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vepu_px30_init(struct mpp_dev *mpp)
|
||||
{
|
||||
vepu_init(mpp);
|
||||
return px30_workaround_combo_init(mpp);
|
||||
}
|
||||
|
||||
static int vepu_power_on(struct mpp_dev *mpp)
|
||||
{
|
||||
struct vepu_dev *enc = to_vepu_dev(mpp);
|
||||
@@ -571,6 +577,17 @@ static struct mpp_hw_ops vepu_v2_hw_ops = {
|
||||
.reset = vepu_reset,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops vepu_px30_hw_ops = {
|
||||
.init = vepu_px30_init,
|
||||
.power_on = vepu_power_on,
|
||||
.power_off = vepu_power_off,
|
||||
.get_freq = vepu_get_freq,
|
||||
.set_freq = vepu_set_freq,
|
||||
.reduce_freq = vepu_reduce_freq,
|
||||
.reset = vepu_reset,
|
||||
.set_grf = px30_workaround_combo_switch_grf,
|
||||
};
|
||||
|
||||
static struct mpp_dev_ops vepu_v2_dev_ops = {
|
||||
.alloc_task = vepu_alloc_task,
|
||||
.prepare = vepu_prepare,
|
||||
@@ -590,11 +607,23 @@ static const struct mpp_dev_var vepu_v2_data = {
|
||||
.dev_ops = &vepu_v2_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var vepu_px30_data = {
|
||||
.device_type = MPP_DEVICE_VEPU2,
|
||||
.hw_info = &vepu_v2_hw_info,
|
||||
.trans_info = trans_rk_vepu2,
|
||||
.hw_ops = &vepu_px30_hw_ops,
|
||||
.dev_ops = &vepu_v2_dev_ops,
|
||||
};
|
||||
|
||||
static const struct of_device_id mpp_vepu2_dt_match[] = {
|
||||
{
|
||||
.compatible = "rockchip,vpu-encoder-v2",
|
||||
.data = &vepu_v2_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,vpu-encoder-px30",
|
||||
.data = &vepu_px30_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user