MTK平台 prelader的插入usb设备开机慢

维护mtk pmic为mt6623的平台过程中,发现接入其他usb设备时会出现开机十分慢的情况,后来查看log发现是在prelaoder阶段出现了类似于flash_tool握手通信下载的情况,但是由于usb设备没有通信协议,导致最后等待十来秒后通讯失败,跳出通讯等待正常启动,重要Log信息如下:

1.代码跟踪分析

(200217_10:02:42.868)[BLDR] seclib_brom_meta_mode:
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.868)step A2 : Standard USB Host!
(200217_10:02:42.868)[PLFM] USB cable in
(200217_10:02:42.868)USB HW reg: index14=0x0
(200217_10:02:42.868)[USBD] USB Full Speed
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.868)hw_set_cc: 450
(200217_10:02:42.868)hw_set_cc: done
(200217_10:02:42.869)hw_set_cc: 450
(200217_10:02:42.869)hw_set_cc: done
(200217_10:02:42.869)hw_set_cc: 450
(200217_10:02:42.869)hw_set_cc: done
(200217_10:02:42.869)hw_set_cc: 450
(200217_10:02:42.869)hw_set_cc: done
(200217_10:02:42.869)hw_set_cc: 450
(200217_10:02:42.869)hw_set_cc: done

后来追踪代码(preloader源目录下面)发现:
代码路径:platrom/xxx/src/core/main.c
代码执行:main–>bldr_handshake()

代码路径:platrom/xxx/src/core/handshake_usb.c
代码执行: bldr_handshake()–>usb_handshake()–>usb_cable_in()

bool usb_handshake(struct bldr_command_handler *handler)
{
    uint32 enum_tmo = CFG_USB_ENUM_TIMEOUT_EN ? USB_ENUM_TIMEOUT : 0;//获取usb连接超时时间
    uint32 handshake_tmo = CFG_USB_HANDSHAKE_TIMEOUT_EN ? USB_SYNC_TIME : 0;
    bool result = FALSE;
    bool force_download = FALSE;

    platform_vusb_on();
	
	//检测是否强制下载
    force_download = platform_com_wait_forever_check();
    if (TRUE == force_download) {
        enum_tmo = 0;
        handshake_tmo = 0;
    } else if (!usb_cable_in()) {//否则检测是否有usb设备插入
         print("%s PMIC not dectect usb cable!\n", MOD);//没有直接返回
         return FALSE;
    }
	
	//如果有usb设备插入则继续往下走
    #if CFG_USB_AUTO_DETECT
    platform_usb_auto_detect_flow();	
	#endif
	
    usbdl_init();
    udelay(1000);
    usb_disconnect();
	
	//等待usb进行连接通讯
    if (usb_connect(enum_tmo) == FALSE) {
    	//如果在等待时间内没有usb进行通讯连接则直接返回,这里的时间就是参数enum_tmo
        print("%s USB enum timeout!\n", MOD);
        /* USB enum fail when connecting to a standby PC, remove ASSERT */
    	/* ASSERT(g_usbphy_ok); */
        goto end;
    }

    udelay(1000);
    //如果连接成功,则进行usb通讯
    if (FALSE == usb_handshake_handler(handler, handshake_tmo)) {
        goto end;
    }

    result = TRUE;

    if (FALSE == usb_port_down(USB_PORT_DOWN_TIME)) {
        print("%s USB port down timeout!\n", MOD);
    }

end:
    usb_service_offline();

#if CFG_USBIF_COMPLIANCE
    /* USB compliance test: 100mA charging current when USB is unconfigured. */
    platform_set_chrg_cur(70);
#endif

    return result;
}

因此根据log来看的,首先进行了usb插入检测,然后再进行usb链接的。
代码路径:preloader/platform/xxx/src/drivers/platform.c

int usb_cable_in(void)
{
#if !CFG_FPGA_PLATFORM && !defined MTK_ALPS_BOX_SUPPORT
    int exist = 0;
    CHARGER_TYPE ret;

    if ((g_boot_reason == BR_USB) || usb_accessory_in()) {//检测usb插入
        ret = mt_charger_type_detection();//如果有usb插入,检测类型
        if (ret == STANDARD_HOST || ret == CHARGING_HOST) {//根据类型进行相关设置
            print("\n%s USB cable in\n", MOD);
            mt_usb_phy_poweron();
            mt_usb_phy_savecurrent();

            /* enable pmic hw charger detection */
            #if CFG_BATTERY_DETECT
            if (hw_check_battery())
                pl_hw_ulc_det();
            #endif

            exist = 1;
        } else if (ret == NONSTANDARD_CHARGER || ret == STANDARD_CHARGER) {
            print("\n%s USB cable in - NONSTANDARD CHARGER or STANDARD CHARGER\n", MOD);
            #if CFG_USBIF_COMPLIANCE
            platform_set_chrg_cur(450);
            #endif

            #if (CFG_USB_UART_SWITCH)
            if (uart_mode) {
                print("\n%s Switch back to USB Mode\n", MOD);
                set_to_usb_mode();
            }
            #endif
        }
    }

    return exist;
#else
    int exist = 0;
    u8  u1_reg =0; 

    /* enable BG current, this ensure phy can work normal  */
    USBPHY_CLR8(0x00, 0x20);
    USBPHY_SET8(0x00, 0x11);
    /* set OTG_VBUSTG = 1.445 v */
    USBPHY_SET8(0x06, 0x04);
    /* set OTG enable */
    USBPHY_SET8(0x1a, 0x10);
    
    /*close vbus by GPIO16 control VBAT.*/
    mt_set_gpio_mode(GPIO16, GPIO_MODE_00);
    mt_set_gpio_dir(GPIO16, GPIO_DIR_OUT);
    mt_set_gpio_pull_enable(GPIO16, GPIO_PULL_ENABLE);
    mt_set_gpio_pull_select(GPIO16, GPIO_PULL_UP);
    mdelay(100);

    /* read vbusvalid bit, when input vbus 5v, phy will modify this bit.*/
    u1_reg = usb_readb(0x630);   
    if((u1_reg &= 0x10) == 0x10)
    {
        exist = 1;
    }
    
    if(exist)
    {
        print("\n%s USB cable in\n", MOD);
        mt_usb_phy_poweron();
        mt_usb_phy_savecurrent();
    }
    return exist;
#endif
}

从上面的代码看出
代码执行: usb_cable_in–>if((g_boot_reason == BR_USB) || usb_accessory_in())–>mt_charger_type_detection
usb_accessory_in–>if(PMIC_CHRDET_EXIST == pmic_IsUsbCableIn())//检测usb插入。

源码路径:preloader/platform/ac8227l/src/drivers/pmic_6323.c
代码执行:mt_charger_type_detection-->hw_charger_type_detection–>hw_charger_type_detection–>
else(1hw_bc11_DCD())–>else(1hw_bc11_stepA2())—>upmu_get_rgs_bc11_cmp_out—>
pmic_read_interface//获取充电类型

usb等待连接:传进来的参数u32 tmo是连接的超时时间
代码路径:platrom/xxx/src/core/handshake_usb.c

static bool usb_connect(u32 tmo)
{
    ulong start_time = get_timer(0);
    bool result = FALSE;
    u32 i = 1;

    mt_usb_disconnect_internal();
    mt_usb_connect_internal();

#if CFG_USBIF_COMPLIANCE
    /* USB compliance test: 100mA charging current when USB is unconfigured. */
    platform_set_chrg_cur(70);
#endif

    print("%s Enumeration(Start)\n", MOD);
	
	//在这里进行检测usb连接,如果在规定时间tmo内
    do {
        /* kick wdt to avoid cpu reset during usb driver installation if not present */
        platform_wdt_all_kick();
        service_interrupts();
		
		//usb连接成功就退出
        if (usbdl_configured()) {
            #if CFG_USBIF_COMPLIANCE
            /* USB compliance test: 500mA charging current when USB is configured but
             * we set the charging current to 450mA since 500mA doesn't support in the
             * platform.
             */
            //usb连接成功则退出循环
            platform_set_chrg_cur(450);
            #endif
            result = TRUE;
            break;
        }

        if (tmo) {
            /* enable timeout mechanism */
            //检测是否超过超时连接时间,超过便跳出while
            if (get_timer(start_time) > tmo)
                break;
                
            #if !CFG_FPGA_PLATFORM
            /* cable plugged-out and power key detection each 1 second */
            //隔1000ms进行一次usb插入检测
            if (get_timer(start_time) > i * 1000) {
                if (!usb_accessory_in() && !pmic_detect_powerkey())
                    pl_power_off();

		#if !CFG_EVB_PLATFORM
                /* check bypass power key from the 2nd second */
                if (i > 1 && pmic_detect_powerkey()) {
                    print("%s Enumeration(Skip): powerkey pressed\n", MOD);
                    break;
                }
                i++;
		#endif
            }
            #endif
        }
    } while(1);

    print("%s Enumeration(End): %s %dms \n", MOD, result == TRUE ? "OK" : "TMO",
        get_timer(start_time));
    return result;

从上面的代码看出,usb连接过程中如果连接成功就马上退出,否则就不断等待usb连接,等待超过时间tmo就跳出等待。从上面的代码看出tmo的时间来自USB_ENUM_TIMEOUT,

   uint32 enum_tmo = CFG_USB_ENUM_TIMEOUT_EN ? USB_ENUM_TIMEOUT : 0;//获取usb连接超时时间

USB_ENUM_TIMEOUT在代码:platform/ac8227l/src/drivers/inc/platform.h中定义。

#define CFG_USB_ENUM_TIMEOUT            (8000)           /* 8000ms */

因此这就能解析为何会插入异常usb设备后,usb设备错误的被当做充电设备,然后进行在usb连接的时候一直没有连接成功,等待超时时间超过8秒后直接退出。这就造成了开机延迟了很久。

2.解决方案

直接把超时时间改为2秒
#define CFG_USB_ENUM_TIMEOUT (2000) /* 2000ms */

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值