*/\r
typedef struct vpu_reg {\r
VPU_CLIENT_TYPE type;\r
- VPU_FREQ freq;\r
+ VPU_FREQ freq;\r
vpu_session *session;\r
struct list_head session_link; /* link to vpu service session */\r
struct list_head status_link; /* link to register set list */\r
/// global variable\r
//static struct clk *pd_video;\r
static struct dentry *parent; // debugfs root directory for all device (vpu, hevc).\r
+/* mutex for selecting operation registers of vpu or hevc */\r
+static struct mutex g_mode_mutex;\r
\r
#ifdef CONFIG_DEBUG_FS\r
static int vcodec_debugfs_init(void);\r
#define VPU_TIMEOUT_DELAY 2*HZ /* 2s */\r
#define VPU_SIMULATE_DELAY msecs_to_jiffies(15)\r
\r
-static void vcodec_select_mode(enum vcodec_device_id id)\r
+static void vcodec_enter_mode(enum vcodec_device_id id)\r
{\r
if (soc_is_rk3036()) {\r
+ mutex_lock(&g_mode_mutex);\r
#define BIT_VCODEC_SEL (1<<3)\r
if (id == VCODEC_DEVICE_ID_HEVC) {\r
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);\r
}\r
}\r
\r
+static void vcodec_exit_mode(void)\r
+{\r
+ if (soc_is_rk3036())\r
+ mutex_unlock(&g_mode_mutex);\r
+}\r
+\r
static int vpu_get_clk(struct vpu_service_info *pservice)\r
{\r
#if VCODEC_CLOCK_ENABLE\r
\r
mem_region->hdl = hdl;\r
\r
+ vcodec_enter_mode(pservice->dev_id);\r
ret = ion_map_iommu(pservice->dev, pservice->ion_client, mem_region->hdl, &mem_region->iova, &mem_region->len);\r
+ vcodec_exit_mode();\r
if (ret < 0) {\r
dev_err(pservice->dev, "ion map iommu failed\n");\r
kfree(mem_region);\r
// release memory region attach to this registers table.\r
if (pservice->mmu_dev) {\r
list_for_each_entry_safe(mem_region, n, ®->mem_region_list, reg_lnk) {\r
- ion_unmap_iommu(pservice->dev, pservice->ion_client, mem_region->hdl);\r
+ /* do not unmap iommu manually,\r
+ unmap will proccess when memory release */\r
+ /*vcodec_enter_mode(pservice->dev_id);\r
+ ion_unmap_iommu(pservice->dev,\r
+ pservice->ion_client,\r
+ mem_region->hdl);\r
+ vcodec_exit_mode();*/\r
ion_free(pservice->ion_client, mem_region->hdl);\r
list_del_init(&mem_region->reg_lnk);\r
kfree(mem_region);\r
int i;\r
u32 *dst = (u32 *)®->reg[0];\r
\r
- vcodec_select_mode(pservice->dev_id);\r
for (i = 0; i < count; i++)\r
*dst++ = *src++;\r
}\r
list_del_init(®->session_link);\r
list_add_tail(®->session_link, ®->session->done);\r
\r
+ vcodec_enter_mode(pservice->dev_id);\r
switch (reg->type) {\r
case VPU_ENC : {\r
pservice->reg_codec = NULL;\r
pservice->reg_codec = NULL;\r
pservice->reg_pproc = NULL;\r
reg_copy_from_hw(pservice, reg, pservice->dec_dev.hwregs, REG_NUM_9190_DEC_PP);\r
- vcodec_select_mode(pservice->dev_id);\r
pservice->dec_dev.hwregs[PP_INTERRUPT_REGISTER] = 0;\r
break;\r
}\r
break;\r
}\r
}\r
+ vcodec_exit_mode();\r
\r
if (irq_reg != -1) {\r
reg->reg[irq_reg] = pservice->irq_status;\r
if (pservice->auto_freq) {\r
vpu_service_set_freq(pservice, reg);\r
}\r
- \r
- vcodec_select_mode(pservice->dev_id);\r
- \r
+\r
+ vcodec_enter_mode(pservice->dev_id);\r
+\r
switch (reg->type) {\r
case VPU_ENC : {\r
int enc_count = pservice->hw_info->enc_reg_num;\r
}\r
}\r
\r
+ vcodec_exit_mode();\r
+\r
#if HEVC_SIM_ENABLE\r
if (pservice->hw_info->hw_id == HEVC_ID) {\r
simulate_start(pservice);\r
\r
if (strcmp(dev_name(dev), "hevc_service") == 0) {\r
pservice->dev_id = VCODEC_DEVICE_ID_HEVC;\r
- vcodec_select_mode(VCODEC_DEVICE_ID_HEVC);\r
} else if (strcmp(dev_name(dev), "vpu_service") == 0) {\r
pservice->dev_id = VCODEC_DEVICE_ID_VPU;\r
} else {\r
return -1;\r
}\r
\r
+ mutex_init(&g_mode_mutex);\r
+ vcodec_enter_mode(pservice->dev_id);\r
+\r
wake_lock_init(&pservice->wake_lock, WAKE_LOCK_SUSPEND, "vpu");\r
INIT_LIST_HEAD(&pservice->waiting);\r
INIT_LIST_HEAD(&pservice->running);\r
if (soc_is_rk3036()) {\r
if (pservice->dev_id == VCODEC_DEVICE_ID_VPU)\r
offset += 0x400;\r
- vcodec_select_mode(pservice->dev_id);\r
}\r
ret = vpu_service_check_hw(pservice, offset);\r
if (ret < 0) {\r
pservice->dec_dev.iobaseaddr = res->start + pservice->hw_info->dec_offset;\r
pservice->dec_dev.iosize = pservice->hw_info->dec_io_size;\r
\r
- printk("%s %d\n", __func__, __LINE__);\r
-\r
pservice->dec_dev.hwregs = (volatile u32 *)((u8 *)regs + pservice->hw_info->dec_offset);\r
\r
pservice->reg_size = pservice->dec_dev.iosize;\r
\r
- printk("%s %d\n", __func__, __LINE__);\r
-\r
if (pservice->hw_info->hw_id != HEVC_ID && !soc_is_rk3036()) {\r
pservice->enc_dev.iobaseaddr = res->start + pservice->hw_info->enc_offset;\r
pservice->enc_dev.iosize = pservice->hw_info->enc_io_size;\r
#endif\r
\r
vpu_service_power_off(pservice);\r
+ vcodec_exit_mode();\r
+\r
pr_info("init success\n");\r
\r
#if HEVC_SIM_ENABLE\r
dec->refBufSupport = (configReg >> DWL_REF_BUFF_E) & 0x01U;\r
dec->vp6Support = (configReg >> DWL_VP6_E) & 0x01U;\r
\r
- if (!soc_is_rk3190() && !soc_is_rk3288()) {\r
- dec->maxDecPicWidth = configReg & 0x07FFU;\r
- } else {\r
+ if (soc_is_rk3190() || soc_is_rk3288())\r
dec->maxDecPicWidth = 4096;\r
- }\r
+ else if (soc_is_rk3036())\r
+ dec->maxDecPicWidth = 1920;\r
+ else\r
+ dec->maxDecPicWidth = configReg & 0x07FFU;\r
\r
/* 2nd Config register */\r
configReg = pservice->dec_dev.hwregs[VPU_DEC_HWCFG1];\r
\r
pservice->bug_dec_addr = cpu_is_rk30xx();\r
} else {\r
+ if (soc_is_rk3036())\r
+ dec->maxDecPicWidth = 1920;\r
+ else\r
+ dec->maxDecPicWidth = 4096;\r
/* disable frequency switch in hevc.*/\r
pservice->auto_freq = false;\r
}\r
u32 raw_status;\r
u32 irq_status;\r
\r
- vcodec_select_mode(pservice->dev_id);\r
+ vcodec_enter_mode(pservice->dev_id);\r
\r
irq_status = raw_status = readl(dev->hwregs + DEC_INTERRUPT_REGISTER);\r
\r
}\r
\r
pservice->irq_status = raw_status;\r
+ vcodec_exit_mode();\r
\r
return IRQ_WAKE_THREAD;\r
}\r
vpu_device *dev = &pservice->enc_dev;\r
u32 irq_status;\r
\r
- vcodec_select_mode(pservice->dev_id);\r
+ vcodec_enter_mode(pservice->dev_id);\r
irq_status= readl(dev->hwregs + ENC_INTERRUPT_REGISTER);\r
\r
pr_debug("vepu_irq irq status %x\n", irq_status);\r
}\r
\r
pservice->irq_status = irq_status;\r
+ vcodec_exit_mode();\r
\r
return IRQ_WAKE_THREAD;\r
}\r