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;
}
Ejemplo n.º 7
0
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;
}