mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
rk3036: modify code for iommu enable for the rk3036 new feature
This commit is contained in:
@@ -281,7 +281,7 @@ typedef struct vpu_session {
|
||||
*/
|
||||
typedef struct vpu_reg {
|
||||
VPU_CLIENT_TYPE type;
|
||||
VPU_FREQ freq;
|
||||
VPU_FREQ freq;
|
||||
vpu_session *session;
|
||||
struct list_head session_link; /* link to vpu service session */
|
||||
struct list_head status_link; /* link to register set list */
|
||||
@@ -378,6 +378,8 @@ typedef struct vpu_request
|
||||
/// global variable
|
||||
//static struct clk *pd_video;
|
||||
static struct dentry *parent; // debugfs root directory for all device (vpu, hevc).
|
||||
/* mutex for selecting operation registers of vpu or hevc */
|
||||
static struct mutex g_mode_mutex;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int vcodec_debugfs_init(void);
|
||||
@@ -397,9 +399,10 @@ static const struct file_operations debug_vcodec_fops = {
|
||||
#define VPU_TIMEOUT_DELAY 2*HZ /* 2s */
|
||||
#define VPU_SIMULATE_DELAY msecs_to_jiffies(15)
|
||||
|
||||
static void vcodec_select_mode(enum vcodec_device_id id)
|
||||
static void vcodec_enter_mode(enum vcodec_device_id id)
|
||||
{
|
||||
if (soc_is_rk3036()) {
|
||||
mutex_lock(&g_mode_mutex);
|
||||
#define BIT_VCODEC_SEL (1<<3)
|
||||
if (id == VCODEC_DEVICE_ID_HEVC) {
|
||||
writel_relaxed(readl_relaxed(RK_GRF_VIRT + RK3036_GRF_SOC_CON1) | (BIT_VCODEC_SEL) | (BIT_VCODEC_SEL << 16), RK_GRF_VIRT + RK3036_GRF_SOC_CON1);
|
||||
@@ -409,6 +412,12 @@ static void vcodec_select_mode(enum vcodec_device_id id)
|
||||
}
|
||||
}
|
||||
|
||||
static void vcodec_exit_mode(void)
|
||||
{
|
||||
if (soc_is_rk3036())
|
||||
mutex_unlock(&g_mode_mutex);
|
||||
}
|
||||
|
||||
static int vpu_get_clk(struct vpu_service_info *pservice)
|
||||
{
|
||||
#if VCODEC_CLOCK_ENABLE
|
||||
@@ -753,7 +762,9 @@ static int vcodec_bufid_to_iova(struct vpu_service_info *pservice, u8 *tbl, int
|
||||
|
||||
mem_region->hdl = hdl;
|
||||
|
||||
vcodec_enter_mode(pservice->dev_id);
|
||||
ret = ion_map_iommu(pservice->dev, pservice->ion_client, mem_region->hdl, &mem_region->iova, &mem_region->len);
|
||||
vcodec_exit_mode();
|
||||
if (ret < 0) {
|
||||
dev_err(pservice->dev, "ion map iommu failed\n");
|
||||
kfree(mem_region);
|
||||
@@ -920,7 +931,13 @@ static void reg_deinit(struct vpu_service_info *pservice, vpu_reg *reg)
|
||||
// release memory region attach to this registers table.
|
||||
if (pservice->mmu_dev) {
|
||||
list_for_each_entry_safe(mem_region, n, ®->mem_region_list, reg_lnk) {
|
||||
ion_unmap_iommu(pservice->dev, pservice->ion_client, mem_region->hdl);
|
||||
/* do not unmap iommu manually,
|
||||
unmap will proccess when memory release */
|
||||
/*vcodec_enter_mode(pservice->dev_id);
|
||||
ion_unmap_iommu(pservice->dev,
|
||||
pservice->ion_client,
|
||||
mem_region->hdl);
|
||||
vcodec_exit_mode();*/
|
||||
ion_free(pservice->ion_client, mem_region->hdl);
|
||||
list_del_init(&mem_region->reg_lnk);
|
||||
kfree(mem_region);
|
||||
@@ -945,7 +962,6 @@ static void reg_copy_from_hw(struct vpu_service_info *pservice, vpu_reg *reg, vo
|
||||
int i;
|
||||
u32 *dst = (u32 *)®->reg[0];
|
||||
|
||||
vcodec_select_mode(pservice->dev_id);
|
||||
for (i = 0; i < count; i++)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
@@ -959,6 +975,7 @@ static void reg_from_run_to_done(struct vpu_service_info *pservice, vpu_reg *reg
|
||||
list_del_init(®->session_link);
|
||||
list_add_tail(®->session_link, ®->session->done);
|
||||
|
||||
vcodec_enter_mode(pservice->dev_id);
|
||||
switch (reg->type) {
|
||||
case VPU_ENC : {
|
||||
pservice->reg_codec = NULL;
|
||||
@@ -983,7 +1000,6 @@ static void reg_from_run_to_done(struct vpu_service_info *pservice, vpu_reg *reg
|
||||
pservice->reg_codec = NULL;
|
||||
pservice->reg_pproc = NULL;
|
||||
reg_copy_from_hw(pservice, reg, pservice->dec_dev.hwregs, REG_NUM_9190_DEC_PP);
|
||||
vcodec_select_mode(pservice->dev_id);
|
||||
pservice->dec_dev.hwregs[PP_INTERRUPT_REGISTER] = 0;
|
||||
break;
|
||||
}
|
||||
@@ -992,6 +1008,7 @@ static void reg_from_run_to_done(struct vpu_service_info *pservice, vpu_reg *reg
|
||||
break;
|
||||
}
|
||||
}
|
||||
vcodec_exit_mode();
|
||||
|
||||
if (irq_reg != -1) {
|
||||
reg->reg[irq_reg] = pservice->irq_status;
|
||||
@@ -1055,9 +1072,9 @@ static void reg_copy_to_hw(struct vpu_service_info *pservice, vpu_reg *reg)
|
||||
if (pservice->auto_freq) {
|
||||
vpu_service_set_freq(pservice, reg);
|
||||
}
|
||||
|
||||
vcodec_select_mode(pservice->dev_id);
|
||||
|
||||
|
||||
vcodec_enter_mode(pservice->dev_id);
|
||||
|
||||
switch (reg->type) {
|
||||
case VPU_ENC : {
|
||||
int enc_count = pservice->hw_info->enc_reg_num;
|
||||
@@ -1160,6 +1177,8 @@ static void reg_copy_to_hw(struct vpu_service_info *pservice, vpu_reg *reg)
|
||||
}
|
||||
}
|
||||
|
||||
vcodec_exit_mode();
|
||||
|
||||
#if HEVC_SIM_ENABLE
|
||||
if (pservice->hw_info->hw_id == HEVC_ID) {
|
||||
simulate_start(pservice);
|
||||
@@ -1516,7 +1535,6 @@ static int vcodec_probe(struct platform_device *pdev)
|
||||
|
||||
if (strcmp(dev_name(dev), "hevc_service") == 0) {
|
||||
pservice->dev_id = VCODEC_DEVICE_ID_HEVC;
|
||||
vcodec_select_mode(VCODEC_DEVICE_ID_HEVC);
|
||||
} else if (strcmp(dev_name(dev), "vpu_service") == 0) {
|
||||
pservice->dev_id = VCODEC_DEVICE_ID_VPU;
|
||||
} else {
|
||||
@@ -1524,6 +1542,9 @@ static int vcodec_probe(struct platform_device *pdev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex_init(&g_mode_mutex);
|
||||
vcodec_enter_mode(pservice->dev_id);
|
||||
|
||||
wake_lock_init(&pservice->wake_lock, WAKE_LOCK_SUSPEND, "vpu");
|
||||
INIT_LIST_HEAD(&pservice->waiting);
|
||||
INIT_LIST_HEAD(&pservice->running);
|
||||
@@ -1563,7 +1584,6 @@ static int vcodec_probe(struct platform_device *pdev)
|
||||
if (soc_is_rk3036()) {
|
||||
if (pservice->dev_id == VCODEC_DEVICE_ID_VPU)
|
||||
offset += 0x400;
|
||||
vcodec_select_mode(pservice->dev_id);
|
||||
}
|
||||
ret = vpu_service_check_hw(pservice, offset);
|
||||
if (ret < 0) {
|
||||
@@ -1576,14 +1596,10 @@ static int vcodec_probe(struct platform_device *pdev)
|
||||
pservice->dec_dev.iobaseaddr = res->start + pservice->hw_info->dec_offset;
|
||||
pservice->dec_dev.iosize = pservice->hw_info->dec_io_size;
|
||||
|
||||
printk("%s %d\n", __func__, __LINE__);
|
||||
|
||||
pservice->dec_dev.hwregs = (volatile u32 *)((u8 *)regs + pservice->hw_info->dec_offset);
|
||||
|
||||
pservice->reg_size = pservice->dec_dev.iosize;
|
||||
|
||||
printk("%s %d\n", __func__, __LINE__);
|
||||
|
||||
if (pservice->hw_info->hw_id != HEVC_ID && !soc_is_rk3036()) {
|
||||
pservice->enc_dev.iobaseaddr = res->start + pservice->hw_info->enc_offset;
|
||||
pservice->enc_dev.iosize = pservice->hw_info->enc_io_size;
|
||||
@@ -1692,6 +1708,8 @@ static int vcodec_probe(struct platform_device *pdev)
|
||||
#endif
|
||||
|
||||
vpu_service_power_off(pservice);
|
||||
vcodec_exit_mode();
|
||||
|
||||
pr_info("init success\n");
|
||||
|
||||
#if HEVC_SIM_ENABLE
|
||||
@@ -1795,11 +1813,12 @@ static void get_hw_info(struct vpu_service_info *pservice)
|
||||
dec->refBufSupport = (configReg >> DWL_REF_BUFF_E) & 0x01U;
|
||||
dec->vp6Support = (configReg >> DWL_VP6_E) & 0x01U;
|
||||
|
||||
if (!soc_is_rk3190() && !soc_is_rk3288()) {
|
||||
dec->maxDecPicWidth = configReg & 0x07FFU;
|
||||
} else {
|
||||
if (soc_is_rk3190() || soc_is_rk3288())
|
||||
dec->maxDecPicWidth = 4096;
|
||||
}
|
||||
else if (soc_is_rk3036())
|
||||
dec->maxDecPicWidth = 1920;
|
||||
else
|
||||
dec->maxDecPicWidth = configReg & 0x07FFU;
|
||||
|
||||
/* 2nd Config register */
|
||||
configReg = pservice->dec_dev.hwregs[VPU_DEC_HWCFG1];
|
||||
@@ -1970,6 +1989,10 @@ static void get_hw_info(struct vpu_service_info *pservice)
|
||||
|
||||
pservice->bug_dec_addr = cpu_is_rk30xx();
|
||||
} else {
|
||||
if (soc_is_rk3036())
|
||||
dec->maxDecPicWidth = 1920;
|
||||
else
|
||||
dec->maxDecPicWidth = 4096;
|
||||
/* disable frequency switch in hevc.*/
|
||||
pservice->auto_freq = false;
|
||||
}
|
||||
@@ -1982,7 +2005,7 @@ static irqreturn_t vdpu_irq(int irq, void *dev_id)
|
||||
u32 raw_status;
|
||||
u32 irq_status;
|
||||
|
||||
vcodec_select_mode(pservice->dev_id);
|
||||
vcodec_enter_mode(pservice->dev_id);
|
||||
|
||||
irq_status = raw_status = readl(dev->hwregs + DEC_INTERRUPT_REGISTER);
|
||||
|
||||
@@ -2016,6 +2039,7 @@ static irqreturn_t vdpu_irq(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
pservice->irq_status = raw_status;
|
||||
vcodec_exit_mode();
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
@@ -2068,7 +2092,7 @@ static irqreturn_t vepu_irq(int irq, void *dev_id)
|
||||
vpu_device *dev = &pservice->enc_dev;
|
||||
u32 irq_status;
|
||||
|
||||
vcodec_select_mode(pservice->dev_id);
|
||||
vcodec_enter_mode(pservice->dev_id);
|
||||
irq_status= readl(dev->hwregs + ENC_INTERRUPT_REGISTER);
|
||||
|
||||
pr_debug("vepu_irq irq status %x\n", irq_status);
|
||||
@@ -2086,6 +2110,7 @@ static irqreturn_t vepu_irq(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
pservice->irq_status = irq_status;
|
||||
vcodec_exit_mode();
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user