From 061f7f873845f7a1c61652e67c6f61b08afedf2b Mon Sep 17 00:00:00 2001 From: Han Gao Date: Wed, 6 Mar 2024 18:30:42 +0800 Subject: [PATCH] sync: vpu-vc8000d-kernel: Linux_SDK_V1.2.1 Signed-off-by: Han Gao --- .../linux/subsys_driver/hantro_dec.c | 26 ++++- .../linux/subsys_driver/hantro_vcmd.c | 106 ++++++++++++++++-- .../linux/subsys_driver/subsys.h | 4 +- 3 files changed, 126 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_dec.c b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_dec.c index fa1c864c9..963018553 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_dec.c +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_dec.c @@ -2135,7 +2135,7 @@ static int check_power_domain(void) dn = of_find_node_by_name(NULL, "vdec"); if (dn != NULL) info = of_find_property(dn, "power-domains", NULL); - pr_debug("%s, %d: power gating is %s\n", __func__, __LINE__, + pr_info("%s, %d: power gating is %s\n", __func__, __LINE__, (info == NULL) ? "disabled" : "enabled"); return (info == NULL) ? 0 : 1; } @@ -2189,7 +2189,7 @@ static int decoder_runtime_resume(struct device *dev) } MMURestore(mmu_hwregs); } - hantrovcmd_reset(); + hantrovcmd_reset(false); } pr_debug("%s, %d: Enabled clock\n", __func__, __LINE__); @@ -2197,6 +2197,27 @@ static int decoder_runtime_resume(struct device *dev) return 0; } +static int decoder_suspend(struct device *dev) +{ + pr_info("%s, %d: enter\n", __func__, __LINE__); + hantrovcmd_suspend_record(); + /*pm_runtime_force_suspend will check current clk state*/ + return pm_runtime_force_suspend(dev); + +} + +static int decoder_resume(struct device *dev) +{ + int ret; + ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret; + + ret = hantrovcmd_resume_start(); + + pr_info("%s, %d: exit resume\n", __func__, __LINE__); + return ret; +} static int decoder_hantrodec_probe(struct platform_device *pdev) { printk("enter %s\n",__func__); @@ -2606,6 +2627,7 @@ static int decoder_hantrodec_remove(struct platform_device *pdev) static const struct dev_pm_ops decoder_runtime_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(decoder_suspend, decoder_resume) SET_RUNTIME_PM_OPS(decoder_runtime_suspend, decoder_runtime_resume, NULL) }; diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_vcmd.c b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_vcmd.c index 5bd2c9691..bd2a1275e 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_vcmd.c +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_vcmd.c @@ -628,6 +628,9 @@ struct hantrovcmd_dev unsigned int mmu_vcmd_reg_mem_busAddress; //start mmu mapping address of vcmd registers memory of CMDBUF. u32 vcmd_reg_mem_size; // size of vcmd registers memory of CMDBUF. struct platform_device *pdev; + bi_list_node* last_linked_cmdbuf_node; + bi_list_node* suspend_running_cmdbuf_node; + bool suspend_entered; } ; /* @@ -1745,6 +1748,8 @@ static long link_and_run_cmdbuf(struct file *filp,struct exchange_parameter* inp last_cmdbuf_node = find_last_linked_cmdbuf(new_cmdbuf_node); record_last_cmdbuf_rdy_num=dev->sw_cmdbuf_rdy_num; vcmd_link_cmdbuf(dev,last_cmdbuf_node); + dev->last_linked_cmdbuf_node = new_cmdbuf_node; //record for resume when pm work + if(dev->working_state==WORKING_STATE_IDLE) { //run @@ -2077,7 +2082,7 @@ long hantrovcmd_ioctl(struct file *filp, long retVal; copy_from_user(&input_para,(struct exchange_parameter*)arg,sizeof(struct exchange_parameter)); - PDEBUG("VCMD link and run cmdbuf\n"); + PDEBUG("filp=%p,VCMD link and run cmdbuf,[%d] \n",(void *)filp, input_para.cmdbuf_id); retVal = pm_runtime_resume_and_get(&hantrovcmd_data[0].pdev->dev); if (retVal < 0) return retVal; @@ -2098,10 +2103,11 @@ long hantrovcmd_ioctl(struct file *filp, __get_user(cmdbuf_id, (u16*)arg); /*high 16 bits are core id, low 16 bits are cmdbuf_id*/ - PDEBUG("VCMD wait for CMDBUF finishing. \n"); + PDEBUG("filp=%p,VCMD wait for CMDBUF finishing. %d,\n",filp,cmdbuf_id); //TODO tmp = wait_cmdbuf_ready(filp,cmdbuf_id,&irq_status_ret); + PDEBUG("filp=%p,VCMD wait for CMDBUF finished. %d,\n",filp,cmdbuf_id); cmdbuf_id=(u16)irq_status_ret; if (tmp==0) { @@ -2122,7 +2128,7 @@ long hantrovcmd_ioctl(struct file *filp, __get_user(cmdbuf_id, (u16*)arg); /*16 bits are cmdbuf_id*/ - PDEBUG("VCMD release CMDBUF\n"); + PDEBUG("filp=%p,VCMD release CMDBUF ,%d\n",filp,cmdbuf_id); pm_runtime_mark_last_busy(&hantrovcmd_data[0].pdev->dev); pm_runtime_put_autosuspend(&hantrovcmd_data[0].pdev->dev); @@ -4020,18 +4026,104 @@ static void printk_vcmd_register_debug(const void *hwregs, char * info) { #endif } -void hantrovcmd_reset(void) +void hantrovcmd_reset(bool only_asic) { if (hantrovcmd_data) { int i; - for(i=0;iworking_state == WORKING_STATE_WORKING ) + dev->suspend_running_cmdbuf_node = dev->last_linked_cmdbuf_node; + else + dev->suspend_running_cmdbuf_node = NULL; + + dev->suspend_entered = true; + if(dev->last_linked_cmdbuf_node) + { + cmdbuf_obj = (struct cmdbuf_obj*)(dev->last_linked_cmdbuf_node->data); + while(timeout--){ + if(cmdbuf_obj->cmdbuf_run_done) + break; + udelay(1000); + } + } + pr_info("%s: core %d working state %s ,node %px \n",__func__,i, + dev->working_state == WORKING_STATE_WORKING ? "working":"idle", + dev->suspend_running_cmdbuf_node); + } +} + +int hantrovcmd_resume_start(void) +{ + if (!hantrovcmd_data) { + return 0; + } + int i; + struct hantrovcmd_dev* dev = NULL; + bi_list_node* last_cmdbuf_node; + int ret; + for(i=0;iworking_state = WORKING_STATE_IDLE; + pr_info("%s: core %d working state working(%d) \n",__func__,i,dev->working_state); + last_cmdbuf_node = dev->suspend_running_cmdbuf_node; + if(last_cmdbuf_node) + { + //run + while (last_cmdbuf_node && + ((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_run_done) + last_cmdbuf_node = last_cmdbuf_node->next; + + if (last_cmdbuf_node && last_cmdbuf_node->data) { + pr_info("vcmd start for cmdbuf id %d, cmdbuf_run_done = %d\n", + ((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_id, + ((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_run_done); + ret = pm_runtime_resume_and_get(&hantrovcmd_data[0].pdev->dev); + if(ret < 0) + return ret; + vcmd_start(dev,last_cmdbuf_node); + } + + } + dev->suspend_entered = false; + dev->suspend_running_cmdbuf_node = NULL; + } + return 0; +} bool hantro_cmdbuf_range(addr_t addr,size_t size){ bool bInRange; diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/subsys.h b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/subsys.h index b74fc2d69..891f774fc 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/subsys.h +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/subsys.h @@ -151,7 +151,9 @@ long hantrovcmd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); int hantrovcmd_init(struct platform_device *pdev); void hantrovcmd_cleanup(struct platform_device *pdev); -void hantrovcmd_reset(void); +void hantrovcmd_reset(bool only_asic); +int hantrovcmd_resume_start(void); +void hantrovcmd_suspend_record(void); bool hantro_cmdbuf_range(addr_t addr,size_t size); /******************************************************************************/