summaryrefslogtreecommitdiff
path: root/drivers/mxc/vpu
diff options
context:
space:
mode:
authorHongzhang Yang <Hongzhang.Yang@freescale.com>2013-08-16 10:33:41 +0800
committerJason Liu <r64343@freescale.com>2013-10-30 09:54:55 +0800
commit156f63c769e7beac75f9580b81aab6f46131a45d (patch)
tree023bc4251fa23a96ccdb4cc98a30db5c7f94f5d8 /drivers/mxc/vpu
parent0017873e5e45622ae13453bb5725d42c9cfa12c0 (diff)
ENGR00275473-2 Support PU regulator on/off in VPU driver
Add functions to hide different implemention for different kernel - vpu_power_get: get/put power/regulator - vpu_power_up: enable/disable power/regulator - vpu_reset Implement regulator operations for Linux 3.10 - find regulator from VPU device node property pu-supply Replace printk/pr_xxx with dev_xxx Signed-off-by: Hongzhang Yang <Hongzhang.Yang@freescale.com>
Diffstat (limited to 'drivers/mxc/vpu')
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c205
1 files changed, 101 insertions, 104 deletions
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 9baeeb4e3a51..ecd286b8b825 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -122,9 +122,7 @@ static phys_addr_t top_address_DRAM;
static struct mxc_vpu_platform_data *vpu_plat;
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
-static struct platform_device *vpu_pdev;
-#endif
+static struct device *vpu_dev;
/* IRAM setting */
static struct iram_setting iram;
@@ -143,7 +141,7 @@ static int vpu_jpu_irq;
#endif
static unsigned int regBk[64];
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
static struct regulator *vpu_regulator;
#endif
static unsigned int pc_before_suspend;
@@ -169,16 +167,63 @@ static int cpu_is_mx6q(void)
}
#endif
+static void vpu_reset(void)
+{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
-static void imx_src_reset_vpu(void)
+ device_reset(vpu_dev);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ imx_src_reset_vpu();
+#else
+ if (vpu_plat->reset)
+ vpu_plat->reset();
+#endif
+}
+
+static long vpu_power_get(bool on)
{
- device_reset(&vpu_pdev->dev);
+ long ret = 0;
+
+ if (on) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+ vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
+ ret = IS_ERR(vpu_regulator);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ vpu_regulator = devm_regulator_get(vpu_dev, "pu");
+ ret = IS_ERR(vpu_regulator);
+#endif
+ } else {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ if (!IS_ERR(vpu_regulator))
+ regulator_put(vpu_regulator);
+#endif
+ }
+ return ret;
}
-static void imx_gpc_power_up_pu(int on)
+static void vpu_power_up(bool on)
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ int ret = 0;
+
+ if (on) {
+ if (!IS_ERR(vpu_regulator)) {
+ ret = regulator_enable(vpu_regulator);
+ if (ret)
+ dev_err(vpu_dev, "failed to power up vpu\n");
+ }
+ } else {
+ if (!IS_ERR(vpu_regulator)) {
+ ret = regulator_disable(vpu_regulator);
+ if (ret)
+ dev_err(vpu_dev, "failed to power down vpu\n");
+ }
+ }
+#else
+ imx_gpc_power_up_pu(on);
+#endif
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
static void request_bus_freq(int freq)
{
}
@@ -212,9 +257,9 @@ static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size),
(dma_addr_t *) (&mem->phy_addr),
GFP_DMA | GFP_KERNEL);
- pr_debug("[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
+ dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
if ((void *)(mem->cpu_addr) == NULL) {
- printk(KERN_ERR "Physical memory allocation error!\n");
+ dev_err(vpu_dev, "Physical memory allocation error!\n");
return -1;
}
return 0;
@@ -244,7 +289,7 @@ static int vpu_free_buffers(void)
mem = rec->mem;
if (mem.cpu_addr != 0) {
vpu_free_dma_buffer(&mem);
- pr_debug("[FREE] freed paddr=0x%08X\n", mem.phy_addr);
+ dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08X\n", mem.phy_addr);
/* delete from list */
list_del(&rec->list);
kfree(rec);
@@ -338,19 +383,17 @@ static int vpu_open(struct inode *inode, struct file *filp)
mutex_lock(&vpu_data.lock);
if (open_count++ == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
- if (!IS_ERR(vpu_regulator))
- regulator_enable(vpu_regulator);
-#else
- pm_runtime_get_sync(&vpu_pdev->dev);
- imx_gpc_power_up_pu(true);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ pm_runtime_get_sync(vpu_dev);
#endif
+ vpu_power_up(true);
#ifdef CONFIG_SOC_IMX6Q
clk_prepare(vpu_clk);
clk_enable(vpu_clk);
if (READ_REG(BIT_CUR_PC))
- pr_debug("Not power off before vpu open!\n");
+ dev_dbg(vpu_dev, "Not power off before vpu open!\n");
clk_disable(vpu_clk);
clk_unprepare(vpu_clk);
#endif
@@ -388,14 +431,14 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
return -EFAULT;
}
- pr_debug("[ALLOC] mem alloc size = 0x%x\n",
+ dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n",
rec->mem.size);
ret = vpu_alloc_dma_buffer(&(rec->mem));
if (ret == -1) {
kfree(rec);
- printk(KERN_ERR
- "Physical memory allocation error!\n");
+ dev_err(vpu_dev,
+ "Physical memory allocation error!\n");
break;
}
ret = copy_to_user((void __user *)arg, &(rec->mem),
@@ -423,7 +466,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
if (ret)
return -EACCES;
- pr_debug("[FREE] mem freed cpu_addr = 0x%x\n",
+ dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%x\n",
vpu_mem.cpu_addr);
if ((void *)vpu_mem.cpu_addr != NULL)
vpu_free_dma_buffer(&vpu_mem);
@@ -447,11 +490,10 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
if (!wait_event_interruptible_timeout
(vpu_queue, irq_status != 0,
msecs_to_jiffies(timeout))) {
- printk(KERN_WARNING "VPU blocking: timeout.\n");
+ dev_warn(vpu_dev, "VPU blocking: timeout.\n");
ret = -ETIME;
} else if (signal_pending(current)) {
- printk(KERN_WARNING
- "VPU interrupt received.\n");
+ dev_warn(vpu_dev, "VPU interrupt received.\n");
ret = -ERESTARTSYS;
} else
irq_status = 0;
@@ -590,13 +632,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
}
case VPU_IOC_SYS_SW_RESET:
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
- imx_src_reset_vpu();
-#else
- if (vpu_plat->reset)
- vpu_plat->reset();
-#endif
-
+ vpu_reset();
break;
}
case VPU_IOC_REG_DUMP:
@@ -610,13 +646,13 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
(void __user *)arg,
sizeof(struct vpu_mem_desc));
if (ret != 0) {
- printk(KERN_ERR "copy from user failure:%d\n", ret);
+ dev_err(vpu_dev, "copy from user failure:%d\n", ret);
ret = -EFAULT;
break;
}
ret = vpu_is_valid_phy_memory((u32)check_memory.phy_addr);
- pr_debug("vpu: memory phy:0x%x %s phy memory\n",
+ dev_dbg(vpu_dev, "vpu: memory phy:0x%x %s phy memory\n",
check_memory.phy_addr, (ret ? "is" : "isn't"));
/* borrow .size to pass back the result. */
check_memory.size = ret;
@@ -644,7 +680,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd,
}
default:
{
- printk(KERN_ERR "No such IOCTL, cmd is %d\n", cmd);
+ dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd);
ret = -EINVAL;
break;
}
@@ -674,7 +710,7 @@ static int vpu_release(struct inode *inode, struct file *filp)
while (READ_REG(BIT_BUSY_FLAG)) {
msleep(1);
if (time_after(jiffies, timeout)) {
- printk(KERN_WARNING "VPU timeout during release\n");
+ dev_warn(vpu_dev, "VPU timeout during release\n");
break;
}
}
@@ -691,7 +727,7 @@ static int vpu_release(struct inode *inode, struct file *filp)
if (READ_REG(BIT_BUSY_FLAG)) {
if (cpu_is_mx51() || cpu_is_mx53()) {
- printk(KERN_ERR
+ dev_err(vpu_dev,
"fatal error: can't gate/power off when VPU is busy\n");
clk_disable(vpu_clk);
clk_unprepare(vpu_clk);
@@ -710,21 +746,15 @@ static int vpu_release(struct inode *inode, struct file *filp)
}
if (READ_REG(0x10F4) != 0x77) {
- printk(KERN_ERR
+ dev_err(vpu_dev,
"fatal error: can't gate/power off when VPU is busy\n");
WRITE_REG(0x0, 0x10F0);
clk_disable(vpu_clk);
clk_unprepare(vpu_clk);
mutex_unlock(&vpu_data.lock);
return -EFAULT;
- } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
- imx_src_reset_vpu();
-#else
- if (vpu_plat->reset)
- vpu_plat->reset();
-#endif
- }
+ } else
+ vpu_reset();
}
#endif
}
@@ -747,12 +777,9 @@ static int vpu_release(struct inode *inode, struct file *filp)
atomic_dec(&clk_cnt_from_ioc);
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
- if (!IS_ERR(vpu_regulator))
- regulator_disable(vpu_regulator);
-#else
- imx_gpc_power_up_pu(false);
- pm_runtime_put_sync_suspend(&vpu_pdev->dev);
+ vpu_power_up(false);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ pm_runtime_put_sync_suspend(vpu_dev);
#endif
}
@@ -788,7 +815,7 @@ static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
*/
vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
pfn = phy_vpu_base_addr >> PAGE_SHIFT;
- pr_debug("size=0x%x, page no.=0x%x\n",
+ dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n",
(int)(vm->vm_end - vm->vm_start), (int)pfn);
return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start,
vm->vm_page_prot) ? -EAGAIN : 0;
@@ -803,7 +830,7 @@ static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm)
int request_size;
request_size = vm->vm_end - vm->vm_start;
- pr_debug(" start=0x%x, pgoff=0x%x, size=0x%x\n",
+ dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n",
(unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff),
request_size);
@@ -877,13 +904,13 @@ static int vpu_dev_probe(struct platform_device *pdev)
{
iram_pool = of_get_named_gen_pool(np, "iram", 0);
if (!iram_pool) {
- printk(KERN_ERR "iram pool not available\n");
+ dev_err(&pdev->dev, "iram pool not available\n");
return -ENOMEM;
}
iram_base = gen_pool_alloc(iram_pool, iramsize);
if (!iram_base) {
- printk(KERN_ERR "unable to alloc iram\n");
+ dev_err(&pdev->dev, "unable to alloc iram\n");
return -ENOMEM;
}
@@ -898,8 +925,6 @@ static int vpu_dev_probe(struct platform_device *pdev)
iram.start = addr;
iram.end = addr + iramsize - 1;
}
-
- vpu_pdev = pdev;
#else
vpu_plat = pdev->dev.platform_data;
@@ -914,9 +939,11 @@ static int vpu_dev_probe(struct platform_device *pdev)
}
#endif
+ vpu_dev = &pdev->dev;
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
if (!res) {
- printk(KERN_ERR "vpu: unable to get vpu base addr\n");
+ dev_err(vpu_dev, "vpu: unable to get vpu base addr\n");
return -ENODEV;
}
phy_vpu_base_addr = res->start;
@@ -924,7 +951,7 @@ static int vpu_dev_probe(struct platform_device *pdev)
vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops);
if (vpu_major < 0) {
- printk(KERN_ERR "vpu: unable to get a major for VPU\n");
+ dev_err(vpu_dev, "vpu: unable to get a major for VPU\n");
err = -EBUSY;
goto error;
}
@@ -950,7 +977,7 @@ static int vpu_dev_probe(struct platform_device *pdev)
vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq");
if (vpu_ipi_irq < 0) {
- printk(KERN_ERR "vpu: unable to get vpu interrupt\n");
+ dev_err(vpu_dev, "vpu: unable to get vpu interrupt\n");
err = -ENXIO;
goto err_out_class;
}
@@ -958,26 +985,21 @@ static int vpu_dev_probe(struct platform_device *pdev)
(void *)(&vpu_data));
if (err)
goto err_out_class;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
- vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
- if (IS_ERR(vpu_regulator)) {
+ if (vpu_power_get(true)) {
if (!(cpu_is_mx51() || cpu_is_mx53())) {
- printk(KERN_ERR
- "%s: failed to get vpu regulator\n", __func__);
+ dev_err(vpu_dev, "failed to get vpu power\n");
goto err_out_class;
} else {
/* regulator_get will return error on MX5x,
* just igore it everywhere*/
- printk(KERN_WARNING
- "%s: failed to get vpu regulator\n", __func__);
+ dev_warn(vpu_dev, "failed to get vpu power\n");
}
}
-#endif
#ifdef MXC_VPU_HAS_JPU
vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
if (vpu_jpu_irq < 0) {
- printk(KERN_ERR "vpu: unable to get vpu jpu interrupt\n");
+ dev_err(vpu_dev, "vpu: unable to get vpu jpu interrupt\n");
err = -ENXIO;
free_irq(vpu_ipi_irq, &vpu_data);
goto err_out_class;
@@ -997,7 +1019,7 @@ static int vpu_dev_probe(struct platform_device *pdev)
vpu_data.workqueue = create_workqueue("vpu_wq");
INIT_WORK(&vpu_data.work, vpu_worker_callback);
mutex_init(&vpu_data.lock);
- printk(KERN_INFO "VPU initialized\n");
+ dev_info(vpu_dev, "VPU initialized\n");
goto out;
err_out_class:
@@ -1034,10 +1056,7 @@ static int vpu_dev_remove(struct platform_device *pdev)
iram_free(iram.start, vpu_plat->iram_size);
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
- if (!IS_ERR(vpu_regulator))
- regulator_put(vpu_regulator);
-#endif
+ vpu_power_get(false);
return 0;
}
@@ -1111,12 +1130,7 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
/* If VPU is working before suspend, disable
* regulator to make usecount right. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
- if (!IS_ERR(vpu_regulator))
- regulator_disable(vpu_regulator);
-#else
- imx_gpc_power_up_pu(false);
-#endif
+ vpu_power_up(false);
}
mutex_unlock(&vpu_data.lock);
@@ -1147,16 +1161,12 @@ static int vpu_resume(struct platform_device *pdev)
if (cpu_is_mx53())
goto recover_clk;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
/* If VPU is working before suspend, enable
* regulator to make usecount right. */
- if (!IS_ERR(vpu_regulator))
- regulator_enable(vpu_regulator);
-
+ vpu_power_up(true);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
if (vpu_plat->pg)
vpu_plat->pg(0);
-#else
- imx_gpc_power_up_pu(true);
#endif
if (bitwork_mem.cpu_addr != 0) {
@@ -1170,7 +1180,7 @@ static int vpu_resume(struct platform_device *pdev)
pc = READ_REG(BIT_CUR_PC);
if (pc) {
- printk(KERN_WARNING "Not power off after suspend (PC=0x%x)\n", pc);
+ dev_warn(vpu_dev, "Not power off after suspend (PC=0x%x)\n", pc);
clk_disable(vpu_clk);
clk_unprepare(vpu_clk);
goto recover_clk;
@@ -1214,7 +1224,7 @@ static int vpu_resume(struct platform_device *pdev)
while (READ_REG(BIT_BUSY_FLAG))
;
} else {
- printk(KERN_WARNING "PC=0 before suspend\n");
+ dev_warn(vpu_dev, "PC=0 before suspend\n");
}
clk_disable(vpu_clk);
clk_unprepare(vpu_clk);
@@ -1314,26 +1324,13 @@ static void __exit vpu_exit(void)
vpu_free_dma_buffer(&user_data_mem);
/* reset VPU state */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
- if (!IS_ERR(vpu_regulator))
- regulator_enable(vpu_regulator);
+ vpu_power_up(true);
clk_prepare(vpu_clk);
clk_enable(vpu_clk);
- if (vpu_plat->reset)
- vpu_plat->reset();
+ vpu_reset();
clk_disable(vpu_clk);
clk_unprepare(vpu_clk);
- if (!IS_ERR(vpu_regulator))
- regulator_disable(vpu_regulator);
-#else
- imx_gpc_power_up_pu(true);
- clk_prepare(vpu_clk);
- clk_enable(vpu_clk);
- imx_src_reset_vpu();
- clk_disable(vpu_clk);
- clk_unprepare(vpu_clk);
- imx_gpc_power_up_pu(false);
-#endif
+ vpu_power_up(false);
clk_put(vpu_clk);