From: ljf Date: Thu, 24 Jul 2014 03:52:00 +0000 (+0800) Subject: rk3036: modify code for iommu enable for the rk3036 new feature X-Git-Tag: firefly_0821_release~4916^2~162 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2ed40eb4d72cad1e9e56329f136fc3de43661ea4;p=firefly-linux-kernel-4.4.55.git rk3036: modify code for iommu enable for the rk3036 new feature --- diff --git a/arch/arm/mach-rockchip/vcodec_service.c b/arch/arm/mach-rockchip/vcodec_service.c index b50712cd7911..34f16367e611 100755 --- a/arch/arm/mach-rockchip/vcodec_service.c +++ b/arch/arm/mach-rockchip/vcodec_service.c @@ -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; }