int bsp_abb_tv230_init(u32 abb_version, u32 *is_supported) { u32 value = 0; u32 is_timeout = 0; u32 start_stamp = 0; if (COMSTARTV230 != abb_version) return 0; if (is_supported) *is_supported = 1; /* reset VREF*/ bsp_abb_write(0x88C, 0x02); udelay(1); bsp_abb_write(0x88C, 0x00); /* start ABB calibration */ bsp_abb_write(0x88C, 0x00); bsp_abb_write(0x88C, 0x01); start_stamp = bsp_get_slice_value(); do { bsp_abb_read(0x894, &value); if (get_timer_slice_delta(start_stamp, bsp_get_slice_value()) > 6) { is_timeout = 1; break; } }while (!(value & 0x10)); if (is_timeout) value = 0x40; else bsp_abb_read(0x895, &value); bsp_abb_write(0xC5C, value); bsp_abb_write(0xCDC, value); bsp_abb_write(0xD5C, value); bsp_abb_tv230_init_later(); if (!g_abb_inited) { spin_lock_init(&g_abb_tv230_spin_lock); g_abb_ops.abb_suspend = bsp_abb_tv230_suspend; g_abb_ops.abb_resume = bsp_abb_tv230_resume; g_abb_ops.abb_power_up = bsp_abb_tv230_power_up; g_abb_ops.abb_power_down = bsp_abb_tv230_power_down; g_abb_ops.abb_power_status = bsp_abb_tv230_power_status; g_abb_ops.abb_pll_enable = bsp_abb_tv230_pll_enable; g_abb_ops.abb_pll_disable = bsp_abb_tv230_pll_disable; g_abb_ops.abb_pll_status = bsp_abb_tv230_pll_status; } return 0; }
OSL_IRQ_FUNC(static irqreturn_t,ipc_int_handler,irq,arg) { u32 i = 0; u32 u32IntStat = 0,begin = 0,end = 0; u32 u32Date = 0x1; u32 u32BitValue = 0; u32 n = (u32)(unsigned long)arg; u32IntStat=readl(ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_INT_STAT(ipc_ctrl.core_num)); /*清中断*/ writel(u32IntStat,ipc_ctrl.ipc_base[n] + BSP_IPC_CPU_INT_CLR(ipc_ctrl.core_num)); /* 遍历32个中断 */ for (i = n*INTSRC_NUM; i < INTSRC_NUM*(n+1) ; i++) { if(n*INTSRC_NUM!=i) { u32Date <<= 1; } u32BitValue = u32IntStat & u32Date; /* 如果有中断 ,则调用对应中断处理函数 */ if (0 != u32BitValue) { /*调用注册的中断处理函数*/ if (NULL != ipc_ctrl.ipc_int_table[i].routine) { begin = bsp_get_slice_value(); ipc_ctrl.last_int_cb_addr = (unsigned long)(ipc_ctrl.ipc_int_table[i].routine); ipc_ctrl.ipc_int_table[i].routine(ipc_ctrl.ipc_int_table[i].arg); end = bsp_get_slice_value(); ipc_debug.u32IntTimeDelta[i] = get_timer_slice_delta(begin,end); } else { bsp_trace(BSP_LOG_LEVEL_ERROR,BSP_MODU_IPC,"BSP_DRV_IpcIntHandler:No IntConnect,MDRV_ERROR!.int num =%d\n",i); } ipc_debug.u32IntHandleTimes[i]++; } } return IRQ_HANDLED; }
int modem_reset_task(void *arg) { u16 action = 0; unsigned long flags = 0; for( ; ;) { osl_sem_down(&(g_modem_reset_ctrl.task_sem)); action = (u16)g_modem_reset_ctrl.modem_action; reset_print_debug("(%d)has taken task_sem, action=%d\n", ++g_reset_debug.main_stage, action); if (MODEM_POWER_OFF == action) { (void)do_power_off(action); } else if (MODEM_POWER_ON == action) { (void)do_power_on(action); } else if (MODEM_RESET == action) { (void)do_reset(action); reset_print_err("reset count: %d\n", ++g_modem_reset_ctrl.reset_cnt); } if (action == g_modem_reset_ctrl.modem_action) { spin_lock_irqsave(&g_modem_reset_ctrl.action_lock, flags); g_modem_reset_ctrl.modem_action = MODEM_NORMAL; spin_unlock_irqrestore(&g_modem_reset_ctrl.action_lock, flags); } wake_unlock(&(g_modem_reset_ctrl.wake_lock)); g_modem_reset_ctrl.exec_time = get_timer_slice_delta(g_modem_reset_ctrl.exec_time, bsp_get_slice_value()); reset_print_debug("execute done, elapse time %d\n", g_modem_reset_ctrl.exec_time); } }
/* 调频策略 */ static inline u32 cpufreq_calccpu_result_insysint(u32 *next_freq) { u32 ulSleepTime; u32 ulCpuLoad_C; u32 ulProTime; u32 ulEndTime; /*这里是读取时间,暂时大桩*/ ulEndTime = bsp_get_slice_value(); ulProTime = get_timer_slice_delta(g_stDfsCpuControl.ulStartTime, ulEndTime); ulSleepTime = g_ulDfsCcpuIdleTime; g_ulDfsCcpuIdleTime = 0; g_stDfsCpuControl.ulStartTime = ulEndTime; ulCpuLoad_C= (ulProTime == 0) ? (0) : (((ulProTime -ulSleepTime)* 100) / (ulProTime)); /*Calc the Cpu load Value*/ if (ulCpuLoad_C > 100) { ulCpuLoad_C = 100; } g_ulCCpuload = ulCpuLoad_C; if(g_lowpower_shared_addr) { writel(g_ulCCpuload, g_lowpower_shared_addr + 0x20c); } if ((ulCpuLoad_C > g_stDfsCpuConfigInfo.astThresHold[0].usProfileUpLimit) || (ulCpuLoad_C >= g_stDfsSwitch.DFSDdrUpLimit)) { return DFS_PROFILE_UP_TARGET; } else if ((ulCpuLoad_C < g_stDfsCpuConfigInfo.astThresHold[0].usProfileDownLimit) || (ulCpuLoad_C <= g_stDfsSwitch.DFSDdrDownLimit)) { return DFS_PROFILE_DOWN; } else /*The System Load is Normal Value*/ { return DFS_PROFILE_NOCHANGE; } }
/*complete*/ int bsp_rf_complete(struct dpm_device *dev) { int ret = 0; u32 time_stamp = 0; do{ time_stamp = bsp_get_slice_value(); udelay(5); }while(get_timer_slice_delta(rffe_cfg.resume_time_stamp , time_stamp) < 5); ret = balong_rf_config_by_mipi_resume(); if(ret){ rf_print_error("rffe resume mipi config error!ret %d\n",ret); } ret |= balong_rf_anten_resume(); if(ret){ rf_print_error("balong_rf_anten_resume fail!ret %d\n",ret); } rffe_cfg.complete_timestamp = bsp_get_slice_value(); return ret; }
/*find a freq in all table*/ static int cpufreq_frequency_table_target(struct cpufreq_frequency_table *table, unsigned int target_freq, unsigned int relation, unsigned int *index) {/*lint !e578 */ struct cpufreq_frequency_table optimal = { .index = ~0, .frequency = 0, }; struct cpufreq_frequency_table suboptimal = { .index = ~0, .frequency = 0, }; unsigned int i; /*lint --e{744} */ switch (relation) { case DFS_PROFILE_UP: suboptimal.frequency = ~0; break; case DFS_PROFILE_DOWN: optimal.frequency = ~0; break; } for (i = 0; (table[i].frequency != (u32)CPUFREQ_TABLE_END); i++) { unsigned int freq = table[i].frequency; if (freq == (u32)CPUFREQ_ENTRY_INVALID) continue; if ((freq < balong_query_profile_table[BALONG_FREQ_MIN].cpu_frequency) || (freq > balong_query_profile_table[BALONG_FREQ_MAX].cpu_frequency)) continue; switch (relation) { case DFS_PROFILE_UP: if (freq <= target_freq) { if (freq >= optimal.frequency) { optimal.frequency = freq; optimal.index = i; } } else { if (freq <= suboptimal.frequency) { suboptimal.frequency = freq; suboptimal.index = i; } } break; case DFS_PROFILE_DOWN: if (freq >= target_freq) { if (freq <= optimal.frequency) { optimal.frequency = freq; optimal.index = i; } } else { if (freq >= suboptimal.frequency) { suboptimal.frequency = freq; suboptimal.index = i; } } break; } } if (optimal.index > i) { if (suboptimal.index > i) return BSP_ERROR; *index = suboptimal.index; } else *index = optimal.index; return BSP_OK; } /***************************************************************************** Function: PWRCTRL_DfsMgrExcuteVoteResultCpu Description:Handle the Profile Vote Result Input: enResult: The Vote Value Output: None Return: None Others: *****************************************************************************/ static int cpufreq_excute_result_cpu(u32 relation, u32 target_freq) { u32 result = 2; u32 new_index = 0; int cur_profile = 0; struct cpufreq_msg task_msg = {0,0,0,0}; cpufreq_frequency_table_target(balong_clockrate_table, target_freq, relation, &new_index); cpufreq_debug("target_freq %d new_index%d\n", target_freq, new_index); cur_profile = pwrctrl_dfs_get_profile(); if ((DFS_PROFILE_UP == relation) && (BALONG_FREQ_MAX != cur_profile)) { result = DFS_PROFILE_UP_TARGET; } else if ((DFS_PROFILE_DOWN == relation) && (BALONG_FREQ_MIN != cur_profile)) { result = DFS_PROFILE_DOWN_TARGET; } else { cpufreq_err("set target relation %d, cur pro %d\n", relation, cur_profile); return BSP_ERROR; } cpufreq_frequency_target_profile(balong_clockrate_table[new_index].frequency, relation, &new_index); task_msg.msg_type = CPUFREQ_ADJUST_FREQ; task_msg.source = CPUFREQ_CCORE; task_msg.content = result; task_msg.profile = new_index; balong_cpufreq_icc_send(&task_msg); g_stDfsCpuControl.enCurProfile = (u32)cur_profile; return BSP_OK; } unsigned int cpufreq_calccpu_cpuload(void) { u32 end_time = 0; u32 idle_time = 0; u32 wall_time = 0; u32 cpu_load = 0; unsigned long irqlock = 0; local_irq_save(irqlock); end_time = bsp_get_slice_value(); wall_time = get_timer_slice_delta(g_cpufreq_start_time, end_time); idle_time = g_ulDfsCcpuIdleTime_long; g_cpufreq_start_time = end_time; g_ulDfsCcpuIdleTime_long = 0; g_flowctrl_in_interr_times = 0; cpu_load = (wall_time == 0) ? (0) : (((wall_time - idle_time) * 100) / wall_time); local_irq_restore(irqlock); if (cpu_load > 100) { cpu_load = g_ulCCpuload; cpufreq_info("cpuload: %d, wall:%d, idle:%d\n", cpu_load, wall_time, idle_time); } return cpu_load; }
int bsp_modem_memrepair(modem_memrepair_ip module) { int ret = 0; unsigned int timestamp_busbusy; unsigned int timestamp_repairdone; unsigned int slicenew_busbusy = 0; unsigned int slicenew_repairdone = 0; unsigned int bus_stat,done_stat,err_flag = 0; unsigned int bit; if (!bsp_modem_is_need_memrepair(module)) return 0; /*3.配置SYSCTRL中的SCPERCTRL3(0x20c) bit 3 bit4为0*/ set_hi_ap_sctrl_scperctrl3_repair_frm_sram(0); set_hi_ap_sctrl_scperctrl3_repair_frm_efu(0); /*4.配置SYSCTRL中的SCPERCTRL2(0x208)(bit19:0)为1,等待1us*/ set_hi_ap_sctrl_scperctrl2_repair_disable(0xfffff); udelay(1); switch(module){ case MODEM_MEMREPAIR_DSP: bit = MODEM_MEMREPAIR_DSP_BIT; break; case MODEM_MEMREPAIR_IRM: bit = MODEM_MEMREPAIR_IRM_BIT; break; default: ret = -1; goto out; } /*5.使能待修复模块,配置SYSCTRL中的SCPERCTRL2(0x208)bit14为0, 其他bit为1,[31:20] bit 保持不变*/ set_hi_ap_sctrl_scperctrl2_repair_disable(~(1<<bit)&0xfffff); udelay(5); /*6.若首次上电,则配置SYSCTRL中的SCPERCTRL3 (0x20C) bit4为1,指示修复数据来源EFUSE*/ if(*mr_poweron_flag[module] == MR_POWERON_FLAG){ set_hi_ap_sctrl_scperctrl3_repair_frm_efu(1); *mr_poweron_flag[module] = 0; } else if(*mr_poweron_flag[module] == 0){ /*6.非首次上电,则配置SYSCTRL中的SCPERCTRL3 (0x20C)bit3为1,指示修复数据来源sram*/ set_hi_ap_sctrl_scperctrl3_repair_frm_sram(1); } else{/*内存被踩*/ mr_print_error("shared ddr has trampled!module id is %d\n",module);/*内存被踩,后面流程还要继续走吗?*/ } /*k3v3+新增*/ /*8.读取SCTRL中的repair done,SCPERSTATUS3(0x228)bit[14]是否为1.如果为1,执行(9),否则,执行(13)*/ timestamp_repairdone = bsp_get_slice_value(); do{ done_stat = get_hi_ap_sctrl_scperstatus3_efusec_timeout_dbg_info() & (1<<bit); if(done_stat != 0) { /*9.查询SYSCTRL中的SCMRBBUSYSTAT(0x304)bit14,如果其为0,打印修复完成*/ /*10.判断软件是否已经启动倒计时,如果没有启动,软件启动300us倒计时;如果已经启动,进入步骤(11)*/ timestamp_busbusy = bsp_get_slice_value(); do{ bus_stat = get_hi_ap_sctrl_scmrbbusystat_mrb_efuse_busy() & (1<<bit);/*304*/ slicenew_busbusy = bsp_get_slice_value(); }while((bus_stat != 0)&&(get_timer_slice_delta(timestamp_busbusy, slicenew_busbusy) < MEMRAIR_WAIT_TIMEOUT)); /*11.软件判断倒计时是否超时,若没有超时,进入步骤(9);若倒计时超时,打印修复时间不足信息,进入步骤(12)*/ if(bus_stat != 0){ mr_print_error("wait memrepair efuse busy bit timeout,wait slice is 0x%x\n",(slicenew_busbusy - timestamp_busbusy)); /* coverity[no_escape] */ for(;;) ; } else { /*读取errflag*/ err_flag = get_hi_ap_sctrl_scperstatus1_err_flag(); if(!err_flag) goto done; else { mr_print_error("memrepair has errflag,errflag is 0x%x\n",err_flag); /* coverity[no_escape] */ for(;;) ; } } } slicenew_repairdone = bsp_get_slice_value(); /*13.判断是否已经启动30us倒计时,如果没有启动,软件启动30us倒计时,执行(14),如果已经启动,执行(14)*/ }while((done_stat == 0)&&(get_timer_slice_delta(timestamp_repairdone, slicenew_repairdone) < MEMRAIR_DONE_WAIT_TIMEOUT)); /*14.判断是否超时,如果没有超时,执行(8);如果超时,打印修复没有启动错误,软件进入死循环*/ if(done_stat == 0) { mr_print_error("wait memrepair done bit timeout,wait slice is %x\n",(slicenew_repairdone - timestamp_repairdone)); /* coverity[no_escape] */ for(;;) ; } done: /*12. 配置SYSCTRL中的SCPERCTRL3(0x20c)bit 3 bit4为0,退出修复流程*/ set_hi_ap_sctrl_scperctrl3_repair_frm_sram(0);/*bit 3*/ set_hi_ap_sctrl_scperctrl3_repair_frm_efu(0);/*bit 4*/ out: return ret; }