/*验证irmbbpmem空间*/
void irmbbp_memrepair_test(void)
{
    int iret = 0;
    u32 addr = 0xe1c10000;
    u32 value= 0;
    u32 len = 0x8000;

    /*bbp irm memory*/
    /*先检测是否有坏点*/
    iret = bad_mem_check(addr,value,len);
    if(!iret)
    {
        mr_print_error("bbp irm memory have no bad mem.\n");
    }
    else
    {
        /*执行memrepair*/
        iret = bsp_modem_memrepair(MODEM_MEMREPAIR_IRM);
        if(iret)
        {
            mr_print_error("repair error!\n");
        }
        /*重新检测坏点*/
        iret = bad_mem_check(addr,value,len);
        if(iret)
        {
            mr_print_error("repair failed!\n");
        }
        else
        {
            mr_print_error("repair ok!\n");
        }
    }
}
/*检测是否有坏点*/
int bad_mem_check(u32 addr, u32 value, u32 len)
{
    u32 reg_value = 0;
    int iret = 0;
    u32 i = 0;

    memset((void *)addr,value,len);
    for(i = 0;i < len;i++)
    {
        reg_value = (u32)readl(addr++);
        if(reg_value != value)
        {
            mr_print_error("bad mem addr 0x%x,value is 0x%x,should be 0x%x. \n",addr,reg_value,value);
            iret = -1;
        }
    }
    /*对value取反,再检测一次*/
    value = ~value;

    memset((void *)addr,value,len);
    for(i = 0;i < len;i++)
    {
        reg_value = (u32)readl(addr++);
        if(reg_value != value)
        {
            mr_print_error("bad mem addr 0x%x,value is 0x%x,should be 0x%x. \n",addr,reg_value,value);
            iret = -1;
        }
    }

    mr_print_error("mem check finsh.\n");

    return iret;
}
int bsp_modem_memrepair_test(void)
{
    int iret = 0;

    irmbbp_memrepair_test();
    bbe_memrepair_test();
    mr_print_error("test finsh.\n");

    return iret;
}
/*验证bbemem空间*/
void bbe_memrepair_test(void)
{
    int iret = 0;
    u32 value= 0x0;
    u32 addr1 = 0xe2840000;
    u32 addr2 = 0xe2740000;
    u32 len1 = 0xc0000;
    u32 len2 = 0xc0000;

    /*bbp irm memory*/
    /*先检测是否有坏点*/
    iret = bad_mem_check(addr1,value,len1);
    iret |= bad_mem_check(addr2,value,len2);
    if(!iret)
    {
        mr_print_error("bbe memory have no bad mem.\n");
    }
    else
    {
        /*执行memrepair*/
        iret = bsp_modem_memrepair(MODEM_MEMREPAIR_DSP);
        if(iret)
        {
            mr_print_error("repair error!\n");
        }
        /*重新检测坏点*/
        iret = bad_mem_check(addr1,value,len1);
        iret |= bad_mem_check(addr2,value,len2);
        if(iret)
        {
            mr_print_error("repair failed!\n");
        }
        else
        {
            mr_print_error("repair ok!\n");
        }
    }
}
int bsp_modem_memrepair_test(void)
{
    int iret = 0;

#if 0
    /**/
    iret = module_memrepair_test(MODEM_MEMREPAIR_DSP,);
    iret |= module_memrepair_test(MODEM_MEMREPAIR_BBPIRM,);
    iret |= module_memrepair_test(MODEM_MEMREPAIR_BBPCOM,);
    iret |= module_memrepair_test(MODEM_MEMREPAIR_BBPCS,);
    mr_print_error("test finsh.\n");
#endif
    return iret;
}
Esempio n. 6
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;
}