diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Android.mk b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Android.mk index 7624ad202..b96130baa 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Android.mk +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Android.mk @@ -5,6 +5,7 @@ include $(CLEAR_VARS) VPU_OUT := $(TARGET_OUT_INTERMEDIATES)/VPU_OBJ HANTRODEC_KO = $(VPU_OUT)/ko/hantrodec.ko HANTRODEC_DIR := $(LOCAL_PATH) +ccflags-y += -DTRACE_INCLUDE_PATH=$(src) $(HANTRODEC_KO): $(MAKE_TOOL) -C $(HANTRODEC_DIR) KDIR=$(KERNEL_DIR) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH); \ diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Makefile b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Makefile index b09967834..b25a2931a 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Makefile +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/Makefile @@ -63,6 +63,12 @@ endif EXTRA_CFLAGS += $(DEBFLAGS) # EXTRA_CFLAGS += -DDYNAMIC_MALLOC_VCMDNODE + #adapt for andriod $src is where this dir. +ifeq ($(CONFIG_ANDROID), y) +ccflags-y += -DTRACE_INCLUDE_PATH=$(src) +else +ccflags-y += -DTRACE_INCLUDE_PATH=$(PWD) +endif ifneq ($(KERNELRELEASE),) # recursive call from kernel build system diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/dec_devfreq.h b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/dec_devfreq.h index 36c42680e..a1a3d1865 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/dec_devfreq.h +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/dec_devfreq.h @@ -7,18 +7,23 @@ struct devfreq; struct opp_table; struct decoder_devfreq { + int busy_count; struct devfreq *df; struct opp_table *clkname_opp_table; bool opp_of_table_added; bool update_freq_flag; unsigned long next_target_freq; unsigned long cur_devfreq; + unsigned long max_freq; wait_queue_head_t target_freq_wait_queue; ktime_t busy_time; ktime_t idle_time; ktime_t time_last_update; - int busy_count; + ktime_t based_maxfreq_busy_time; + ktime_t based_maxfreq_last_busy_t; + int busy_record_count; + /* * Protect busy_time, idle_time, time_last_update and busy_count * because these can be updated concurrently, for example by the GP 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 8d074fe47..c775cc517 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 @@ -109,7 +109,7 @@ # define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) # endif #else -# define PDEBUG(fmt, args...) +# define PDEBUG(fmt, args...) pr_debug("hantrodec: " fmt, ## args) #endif int debug_pr_devfreq_info = 0; @@ -923,11 +923,12 @@ long DecFlushRegs(hantrodec_t *dev, struct core_desc *core) { #ifdef HANTRODEC_DEBUG flush_count++; flush_regs += reg_wr; -#endif + PDEBUG("flushed registers on core %d\n", id); PDEBUG("%d DecFlushRegs: flushed %d/%d registers (dec_mode = %d, avg %d regs per flush)\n", flush_count, reg_wr, flush_regs, dec_regs[id][3]>>27, flush_regs/flush_count); +#endif } else { /* write all regs but the status reg[1] to hardware */ for(i = 0; i < vpu_subsys[id].submodule_iosize[type]/4; i++) { @@ -1881,7 +1882,6 @@ static long hantrodec_ioctl(struct file *filp, unsigned int cmd, static int hantrodec_open(struct inode *inode, struct file *filp) { PDEBUG("dev opened\n"); - pr_debug("==========%s:open!============\n",__func__); if (vcmd) hantrovcmd_open(inode, filp); @@ -2186,7 +2186,7 @@ static int decoder_runtime_suspend(struct device *dev) { hantrodec_t *decdev = &hantrodec_data; - pr_debug("%s, %d: Disable clock\n", __func__, __LINE__); + PDEBUG("%s, %d: Disable clock\n", __func__, __LINE__); clk_disable_unprepare(decdev->cclk); clk_disable_unprepare(decdev->aclk); @@ -2255,7 +2255,7 @@ static int decoder_runtime_resume(struct device *dev) pr_info("%s, %d,hantrovcmd not need reset\n",__func__, __LINE__); } - pr_debug("%s, %d: Enabled clock %d\n", __func__, __LINE__); + PDEBUG("%s, %d: Enabled clock %d\n", __func__, __LINE__); decoder_devfreq_resume(decoder_get_devfreq_priv_data()); return 0; } @@ -2267,7 +2267,7 @@ static int decoder_suspend(struct device *dev) hantrovcmd_suspend_record(); /*pm_runtime_force_suspend will check current clk state*/ - pr_debug(" suspend pm_count %ld\n",atomic_read(&dev->power.usage_count)); + PDEBUG(" suspend pm_count %ld\n",atomic_read(&dev->power.usage_count)); return pm_runtime_force_suspend(dev); } @@ -2295,16 +2295,29 @@ static int decoder_resume(struct device *dev) /******************************************************************************\ ******************************* VPU Devfreq support START*********************** \******************************************************************************/ +unsigned int g_cur_devfreq = 594000000; static void decoder_devfreq_update_utilization(struct decoder_devfreq *devfreq) { ktime_t now, last; - + ktime_t busy; now = ktime_get(); last = devfreq->time_last_update; - if (devfreq->busy_count > 0) - devfreq->busy_time += ktime_sub(now, last); + if (devfreq->busy_count > 0) { + busy = ktime_sub(now, last); + devfreq->busy_time += busy; + #ifndef CONFIG_PM_DEVFREQ + devfreq->based_maxfreq_last_busy_t = busy; + #else + if(devfreq->max_freq) + devfreq->based_maxfreq_last_busy_t = busy/(devfreq->max_freq/devfreq->cur_devfreq); + else + devfreq->based_maxfreq_last_busy_t = busy; + #endif + devfreq->based_maxfreq_busy_time += devfreq->based_maxfreq_last_busy_t; + devfreq->busy_record_count++; + } else { if(devfreq->busy_time > 0) //if first time in not recorded busy time,ignore idle time. @@ -2319,6 +2332,11 @@ static void decoder_devfreq_reset(struct decoder_devfreq *devfreq) devfreq->idle_time = 0; devfreq->time_last_update = ktime_get(); } +void decoder_devfreq_reset_profile_record(struct decoder_devfreq *devfreq) +{ + devfreq->based_maxfreq_busy_time = 0; + devfreq->busy_record_count = 0; +} void decoder_devfreq_record_busy(struct decoder_devfreq *devfreq) { @@ -2326,6 +2344,7 @@ void decoder_devfreq_record_busy(struct decoder_devfreq *devfreq) int busy_count; if (!devfreq) return; + //when devfreq not enabled,need into record time also. decoder_dev_clk_lock(); spin_lock_irqsave(&devfreq->lock, irqflags); busy_count = devfreq->busy_count; @@ -2424,7 +2443,7 @@ void decoder_dev_clk_unlock(void) mutex_unlock(&devfreq->clk_mutex); } -unsigned int g_cur_devfreq = 594000000; + bool hantrovcmd_devfreq_check_state(void); /* set rate need clk disabled,so carefully calling this function @@ -2524,9 +2543,9 @@ static int decoder_devfreq_get_cur_freq(IN struct device *dev, OUT unsigned long *freq = devfreq->cur_devfreq; return 0; } - +#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND struct devfreq_simple_ondemand_data decoder_gov_data; - +#endif static struct devfreq_dev_profile decoder_devfreq_gov_data = { .polling_ms = 100, @@ -2567,6 +2586,7 @@ int decoder_devfreq_init(struct device *dev) init_waitqueue_head(&devfreq->target_freq_wait_queue); mutex_init(&devfreq->clk_mutex); +#ifdef CONFIG_PM_DEVFREQ opp_table = dev_pm_opp_set_clkname(dev,"cclk"); if(IS_ERR(opp_table)) { pr_err("dec set cclk failed\n"); @@ -2588,6 +2608,7 @@ int decoder_devfreq_init(struct device *dev) decoder_devfreq_gov_data.initial_freq = devfreq->cur_devfreq; +#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND decoder_gov_data.upthreshold = 80; decoder_gov_data.downdifferential = 10; @@ -2602,8 +2623,17 @@ int decoder_devfreq_init(struct device *dev) ret = PTR_ERR(df); goto err_fini; } + unsigned long *freq_table = df->profile->freq_table; + if (freq_table[0] < freq_table[df->profile->max_state - 1]) { + devfreq->max_freq = freq_table[df->profile->max_state - 1]; + } else { + devfreq->max_freq = freq_table[0]; + } + pr_info("device max freq %ld\n",devfreq->max_freq); df->suspend_freq = 0; // not set freq when suspend,not suitable for async set rate devfreq->df = df; +#endif +#endif return 0; err_fini: @@ -2614,6 +2644,119 @@ err_fini: /******************************************************************************\ ******************************* VPU Devfreq support END ************************ \******************************************************************************/ +void vdec_vcmd_profile_update(struct work_struct *work); +static DECLARE_DELAYED_WORK(vdec_cmd_profile_work,vdec_vcmd_profile_update); +static ktime_t last_update; +static long update_period_ms = 0; + + +struct vcmd_profile vdec_vcmd_profile; +void vdec_vcmd_profile_update(struct work_struct *work) +{ + //update busy time + ktime_t now,during; + struct decoder_devfreq *devfreq; + devfreq = decoder_get_devfreq_priv_data(); + now = ktime_get(); + during = ktime_sub(now,last_update); + last_update = now; + vdec_vcmd_profile.dev_loading_percent = ktime_to_us(devfreq->based_maxfreq_busy_time) * 100/ktime_to_us(during); + if(vdec_vcmd_profile.dev_loading_percent > vdec_vcmd_profile.dev_loading_max_percent) + vdec_vcmd_profile.dev_loading_max_percent = vdec_vcmd_profile.dev_loading_percent; + pr_debug("based_maxfreq_busy_time %lldms,during period %lld ms",ktime_to_us(devfreq->based_maxfreq_busy_time)/1000,ktime_to_ms(during)); + + if(devfreq->busy_record_count > 0) + vdec_vcmd_profile.avg_hw_proc_us = ktime_to_us(devfreq->based_maxfreq_busy_time)/devfreq->busy_record_count; + else + vdec_vcmd_profile.avg_hw_proc_us = 0; + + vdec_vcmd_profile.last_hw_proc_us = ktime_to_us(devfreq->based_maxfreq_last_busy_t); + vdec_vcmd_profile.proced_count = devfreq->busy_record_count; + decoder_devfreq_reset_profile_record(devfreq); + if(update_period_ms > 0) + schedule_delayed_work(&vdec_cmd_profile_work, msecs_to_jiffies(update_period_ms)); +} + +static ssize_t log_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + ssize_t len = 0; + + const char *module_version = "1.0.0"; + int dev_id = 0; + + + len += scnprintf(buf + len, PAGE_SIZE - len, + "[VDEC] Version: %s q\n" + "----------------------------------------MODULE PARAM-----------------------------\n" + "updatePeriod_ms\n" + " %d\n" + "----------------------------------------MODULE STATUS------------------------------\n" + "DevId DevLoading_%% DevLoadingMax_%%\n" + " %d %d %d\n" + + " avg_hw_proc_us last_hw_proc_us proced_count\n" + " %d %d %d \n" + "cur_submit_vcmd cur_complete_vcmd vcmd_num_share_irq\n" + " %d %d %d \n" + "----------------------------------------EXCEPTION INFO-----------------------------------------\n" + "BusErr Abort Timeout CmdErr\n" + " %d %d %d %d \n", + module_version, update_period_ms, + dev_id, vdec_vcmd_profile.dev_loading_percent, vdec_vcmd_profile.dev_loading_max_percent, + + vdec_vcmd_profile.avg_hw_proc_us, vdec_vcmd_profile.last_hw_proc_us,vdec_vcmd_profile.proced_count, + vdec_vcmd_profile.cur_submit_vcmd_id,vdec_vcmd_profile.cur_complete_vcmd_id,vdec_vcmd_profile.vcmd_num_share_irq, + vdec_vcmd_profile.vcmd_buserr_cnt, vdec_vcmd_profile.vcmd_abort_cnt, vdec_vcmd_profile.vcmd_timeout_cnt, vdec_vcmd_profile.vcmd_cmderr_cnt); + + + return len; +} +static ssize_t log_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + /******************clear *********************/ + vdec_vcmd_profile.vcmd_buserr_cnt = 0; + vdec_vcmd_profile.vcmd_abort_cnt = 0; + vdec_vcmd_profile.vcmd_timeout_cnt = 0; + vdec_vcmd_profile.vcmd_cmderr_cnt = 0; + + vdec_vcmd_profile.dev_loading_max_percent = 0; + vdec_vcmd_profile.last_hw_proc_us = 0; + return count; +} + + +/******************updatePeriod ************************************/ +static ssize_t updatePeriod_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf,"%u\n",update_period_ms); +} + +static ssize_t updatePeriod_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + char *start = (char *)buf; + long old_period = update_period_ms; + update_period_ms = simple_strtoul(start, &start, 0); + if(old_period == 0 && update_period_ms) + schedule_delayed_work(&vdec_cmd_profile_work,msecs_to_jiffies(update_period_ms)); + return count; +} +/******************define log *************************************/ +static struct kobj_attribute log_attr = __ATTR(log, 0664, log_show, log_store); +/******************define updatePeriod_ms*************************************/ +static struct kobj_attribute updatePeriod_attr = __ATTR(updatePeriod_ms, 0664, updatePeriod_show, updatePeriod_store); + + +static struct attribute *attrs[] = { + &log_attr.attr, + &updatePeriod_attr.attr, + NULL, // must be NULL +}; + + +static struct attribute_group vdec_dev_attr_group = { + .name = "info", // dir name + .attrs = attrs, +}; static int decoder_hantrodec_probe(struct platform_device *pdev) @@ -2856,6 +2999,9 @@ static int decoder_hantrodec_probe(struct platform_device *pdev) pr_info("vdec devfreq init ok\n"); } + result = sysfs_create_group(&pdev->dev.kobj, &vdec_dev_attr_group); + if(result) + pr_warn("vdec create sysfs failed\n"); pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_sync_suspend(&pdev->dev); if (result) return result; @@ -2963,6 +3109,7 @@ static int decoder_hantrodec_remove(struct platform_device *pdev) debugfs_remove_recursive(root_debugfs_dir); root_debugfs_dir = NULL; } + cancel_delayed_work_sync(&vdec_cmd_profile_work); pm_runtime_resume_and_get(&pdev->dev); /* When vcmd is true, irq free in hantrovcmd_cleanup! When vcmd is flase, it is not need because in line 2528 freed */ @@ -3028,6 +3175,7 @@ static int decoder_hantrodec_remove(struct platform_device *pdev) device_destroy(hantrodec_class, hantrodec_devt); unregister_chrdev_region(hantrodec_devt, 1); class_destroy(hantrodec_class); + sysfs_remove_group(&pdev->dev.kobj,&vdec_dev_attr_group); pr_info("hantrodec: module removed\n"); return 0; diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_mmu.c b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_mmu.c index 849120356..54b4752da 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_mmu.c +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantro_mmu.c @@ -175,7 +175,7 @@ MODULE_LICENSE("GPL"); # define MMUDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) # endif #else -# define MMUDEBUG(fmt, args...) +# define MMUDEBUG(fmt, args...) pr_debug("hantrommu: " fmt, ## args) #endif #define MMU_ON_ERROR(func) \ @@ -1118,7 +1118,7 @@ enum MMUStatus MMURelease(void *filp, volatile unsigned char *hwregs) { return MMU_STATUS_OK; } - pr_debug(" *****MMU Release*****\n"); + MMUDEBUG(" *****MMU Release*****\n"); AcquireMutex(g_mmu->page_table_mutex, MMU_INFINITE); @@ -1857,8 +1857,8 @@ bool MMU_CheckPowerStayOn(volatile unsigned char *hwregs[MAX_SUBSYS_NUM][2]) address_ext = ((u32)(g_mmu->page_table_array_physical >> 32))&0xff; for (i = 0; i < MAX_SUBSYS_NUM; i++) { if (hwregs[i][0] != NULL) { - pr_debug("software save pg table addr %lx\n",g_mmu->page_table_array_physical); - pr_debug("subsys[%d]: MMU reg LSB %x MSB %x\n",i,ioread32( (void*)(hwregs[i][0] + MMU_REG_ADDRESS)), + MMUDEBUG("software save pg table addr %lx\n",g_mmu->page_table_array_physical); + MMUDEBUG("subsys[%d]: MMU reg LSB %x MSB %x\n",i,ioread32( (void*)(hwregs[i][0] + MMU_REG_ADDRESS)), ioread32( (void *)(hwregs[i][0] + MMU_REG_ADDRESS_MSB))); if(address != ioread32( (void*)(hwregs[i][0] + MMU_REG_ADDRESS) ) 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 085f07c16..fef38f269 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 @@ -97,6 +97,9 @@ #include "hantrovcmd.h" #include "subsys.h" #include "dec_devfreq.h" +#undef linux +#define CREATE_TRACE_POINTS +#include "vdec_trace_point.h" /* * Macros to help debugging */ @@ -112,7 +115,7 @@ # define PDEBUG(fmt, args...) printf(__FILE__ ":%d: " fmt, __LINE__ , ## args) # endif #else -# define PDEBUG(fmt, args...) /* not debugging: nothing */ +# define PDEBUG(fmt, args...) pr_debug("vc8000d_vcmd: " fmt, ## args) #endif /*------------------------------------------------------------------------ @@ -1698,6 +1701,8 @@ static long link_and_run_cmdbuf(struct file *filp,struct exchange_parameter* inp if (down_interruptible(&vcmd_reserve_cmdbuf_sem[cmdbuf_obj->module_type])) return -ERESTARTSYS; + + vdec_vcmd_profile.cur_submit_vcmd_id = input_para->cmdbuf_id; decoder_devfreq_record_busy( decoder_get_devfreq_priv_data() ); return_value=select_vcmd(new_cmdbuf_node); if(return_value) @@ -1705,7 +1710,7 @@ static long link_and_run_cmdbuf(struct file *filp,struct exchange_parameter* inp dev = &hantrovcmd_data[cmdbuf_obj->core_id]; input_para->core_id = cmdbuf_obj->core_id; - pr_debug("filp=%p, VCMD Link CMDBUF [%d] to core [%d]\n", (void *)filp, cmdbuf_id, input_para->core_id); + PDEBUG("filp=%p, VCMD Link CMDBUF [%d] to core [%d]\n", (void *)filp, cmdbuf_id, input_para->core_id); //set ddr address for vcmd registers copy. if(dev->hw_version_id > HW_ID_1_0_C ) { @@ -1952,7 +1957,7 @@ static unsigned int wait_cmdbuf_ready(struct file *filp,u16 cmdbuf_id,u32 *irq_s return -ETIME; } - pr_debug("filp=%p, VCMD Wait CMDBUF [%d]\n", (void *)filp, cmdbuf_id); + PDEBUG("filp=%p, VCMD Wait CMDBUF [%d]\n", (void *)filp, cmdbuf_id); return 0; } else { if (check_mc_cmdbuf_irq(filp, cmdbuf_obj, irq_status_ret)) @@ -2091,7 +2096,7 @@ long hantrovcmd_ioctl(struct file *filp, ret = reserve_cmdbuf(filp,&input_para); if (ret == 0) copy_to_user((struct exchange_parameter*)arg,&input_para,sizeof(struct exchange_parameter)); - pr_debug("filp=%p, VCMD Reserve CMDBUF [%d]\n", (void *)filp, input_para.cmdbuf_id); + PDEBUG("filp=%p, VCMD Reserve CMDBUF [%d]\n", (void *)filp, input_para.cmdbuf_id); return ret; } @@ -3539,6 +3544,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) { //if error,read from register directly. cmdbuf_id = vcmd_get_register_value((const void *)dev->hwregs,dev->reg_mirror,HWIF_VCMD_CMDBUF_EXECUTING_ID); + vdec_vcmd_profile.cur_complete_vcmd_id = cmdbuf_id; if(cmdbuf_id>=TOTAL_DISCRETE_CMDBUF_NUM) { pr_err("hantrovcmd_isr error cmdbuf_id greater than the ceiling !!\n"); @@ -3563,6 +3569,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) #endif cmdbuf_id = *(dev->vcmd_reg_mem_virtualAddress+EXECUTING_CMDBUF_ID_ADDR); + vdec_vcmd_profile.cur_complete_vcmd_id = cmdbuf_id; if(cmdbuf_id>=TOTAL_DISCRETE_CMDBUF_NUM) { pr_err("hantrovcmd_isr error cmdbuf_id greater than the ceiling !!\n"); @@ -3596,6 +3603,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) vcmd_start(dev,base_cmdbuf_node); } handled++; + trace_vdec_interrupt(0xffffffff,irq_status,0); spin_unlock_irqrestore(dev->spinlock, flags); return IRQ_HANDLED; } @@ -3604,6 +3612,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //abort error,don't need to reset new_cmdbuf_node = dev->list_manager.head; dev->working_state = WORKING_STATE_IDLE; + vdec_vcmd_profile.vcmd_abort_cnt++; if(dev->hw_version_id > HW_ID_1_0_C ) { new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id]; @@ -3651,6 +3660,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) } base_cmdbuf_node=base_cmdbuf_node->next; vcmd_delink_cmdbuf(dev,base_cmdbuf_node); + trace_vdec_interrupt(cmdbuf_id,irq_status,cmdbuf_processed_num); spin_unlock_irqrestore(dev->spinlock, flags); if(cmdbuf_processed_num) wake_up_all(dev->wait_queue); @@ -3665,6 +3675,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //bus error, don't need to reset where to record status? new_cmdbuf_node = dev->list_manager.head; dev->working_state = WORKING_STATE_IDLE; + vdec_vcmd_profile.vcmd_buserr_cnt++; if(dev->hw_version_id > HW_ID_1_0_C ) { new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id]; @@ -3724,6 +3735,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //restart new command vcmd_start(dev,base_cmdbuf_node); } + trace_vdec_interrupt(cmdbuf_id,irq_status,cmdbuf_processed_num); spin_unlock_irqrestore(dev->spinlock, flags); if(cmdbuf_processed_num) wake_up_all(dev->wait_queue); @@ -3736,6 +3748,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //time out,need to reset new_cmdbuf_node = dev->list_manager.head; dev->working_state = WORKING_STATE_IDLE; + vdec_vcmd_profile.vcmd_timeout_cnt++; if(dev->hw_version_id > HW_ID_1_0_C ) { new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id]; @@ -3791,6 +3804,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //restart new command vcmd_start(dev,base_cmdbuf_node); } + trace_vdec_interrupt(cmdbuf_id,irq_status,cmdbuf_processed_num); spin_unlock_irqrestore(dev->spinlock, flags); if(cmdbuf_processed_num) wake_up_all(dev->wait_queue); @@ -3803,6 +3817,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //command error,don't need to reset new_cmdbuf_node = dev->list_manager.head; dev->working_state = WORKING_STATE_IDLE; + vdec_vcmd_profile.vcmd_cmderr_cnt++; if(dev->hw_version_id > HW_ID_1_0_C ) { new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id]; @@ -3862,6 +3877,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //restart new command vcmd_start(dev,base_cmdbuf_node); } + trace_vdec_interrupt(cmdbuf_id,irq_status,cmdbuf_processed_num); spin_unlock_irqrestore(dev->spinlock, flags); if(cmdbuf_processed_num) wake_up_all(dev->wait_queue); @@ -3927,6 +3943,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) //restart new command vcmd_start(dev,base_cmdbuf_node); } + trace_vdec_interrupt(cmdbuf_id,irq_status,cmdbuf_processed_num); spin_unlock_irqrestore(dev->spinlock, flags); if(cmdbuf_processed_num) wake_up_all(dev->wait_queue); @@ -3974,6 +3991,8 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id) handled++; } + vdec_vcmd_profile.vcmd_num_share_irq = cmdbuf_processed_num; + trace_vdec_interrupt(cmdbuf_id,irq_status,cmdbuf_processed_num); spin_unlock_irqrestore(dev->spinlock, flags); if(cmdbuf_processed_num) wake_up_all(dev->wait_queue); diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantrovcmd.h b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantrovcmd.h index d431dbb6d..42f67759d 100644 --- a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantrovcmd.h +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/hantrovcmd.h @@ -189,4 +189,22 @@ struct exchange_parameter u16 core_id; //just used for polling. }; +struct vcmd_profile { + int dev_loading_percent; + int dev_loading_max_percent; + + int last_hw_proc_us; + int avg_hw_proc_us; + int proced_count; + int cur_submit_vcmd_id; + int cur_complete_vcmd_id; + int vcmd_num_share_irq; + + //error statistics + u32 vcmd_abort_cnt; + u32 vcmd_buserr_cnt; + u32 vcmd_timeout_cnt; + u32 vcmd_cmderr_cnt; +}; +extern struct vcmd_profile vdec_vcmd_profile; #endif /* !_VC8000_VCMD_DRIVER_H_ */ diff --git a/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/vdec_trace_point.h b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/vdec_trace_point.h new file mode 100644 index 000000000..9f9638435 --- /dev/null +++ b/drivers/staging/media/vpu-vc8000d-kernel/linux/subsys_driver/vdec_trace_point.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vdec_trace_point + +#if !defined(_TRACE_VDEC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_VDEC_H + +#include +#include +#include + +TRACE_EVENT(vdec_interrupt, + + TP_PROTO(unsigned int complete_cmd, unsigned int irq_status, unsigned int processed_vcmd_num), + + TP_ARGS(complete_cmd, irq_status,processed_vcmd_num), + + TP_STRUCT__entry( + __field( unsigned int, complete_cmd ) + __field( unsigned int, irq_status) + __field( unsigned int, processed_vcmd_num) + ), + + TP_fast_assign( + __entry->complete_cmd = complete_cmd; + __entry->irq_status = irq_status; + __entry->processed_vcmd_num = processed_vcmd_num; + ), + + TP_printk("dec irq type complete_cmd %u irq status =%x processed_vcmd_num %d ", __entry->complete_cmd, __entry->irq_status,__entry->processed_vcmd_num) +); + +#endif /* _TRACE_VDEC_H */ + +/* This part must be outside protection */ +#include \ No newline at end of file