全志A40i/T3核心板使用的是:AXP221s电源管理芯片。
因此上电起来需要做的工作之一就是初始化这个电源管理芯片。
而主控Arm与该芯片的通讯接口为I2C(这个视每个不同的PMU管理芯片情况而定)。
因此在初始化该芯片前,还需要先初始化Arm的I2C总线。
一. 初始化I2C总线
函数调用路径,从? init_fnc_t * init_sequence[] 开始:
-> init_fnc_t * init_sequence[]????????// uboot的启动初始化函数数组
->?static int init_func_pmubus(void)????????// 初始化i2c总线,为下一步初始化PMU模块做准备
I2C总线相关函数主要集中在“sunxi_i2c.c”文件内,主要是对I2C总线,时钟和寄存器进行初始化。
->?void i2c_init(int speed, int slaveaddr)
->?int sunxi_i2c_init(int bus_num,int speed, int slaveaddr)
-> void sunxi_i2c_bus_setting(int bus_num)????????// 配置i2c总线
->?void i2c_set_clock(int bus_num,int speed)????????// 配置i2c功能时钟????????
至此I2C总线初始化完毕。如果配置成功,则保存读写函数指针。
?? ??? ?i2c_read_pt = sunxi_i2c_read; ?? ??? ?i2c_write_pt = sunxi_i2c_write;
二. 然后就是核心板的PMU模块初始化。
->?int power_source_init(void)
-> // 从sys_config.fex中读取相关配置参数 ?? ?nodeoffset = ?fdt_path_offset(working_fdt,FDT_PATH_POWER_SPLY); ?? ?if(nodeoffset >=0) ?? ?{ ?? ??? ?fdt_getprop_u32(working_fdt, nodeoffset, "dcdc2_vol", &dcdc_vol); ?? ?} ?? ?if(!dcdc_vol) ?? ?{ ?? ??? ?cpu_vol = 900; ?? ?} ?? ?else ?? ?{ ?? ??? ?cpu_vol = dcdc_vol%10000; ?? ?} ?
-> // 初始化CPU电源管理模块(PMU),并配置相关电源参数
? ?axp_exist = ?axp_probe(); ?? ?if(axp_exist) ?? ?{ ?? ??? ?axp_probe_factory_mode(); ?? ??? ?if(!axp_probe_power_supply_condition()) ?? ??? ?{ ?? ??? ??? ?//PMU_SUPPLY_DCDC2 is for cpua ?? ??? ??? ?if(!axp_set_supply_status(0, PMU_SUPPLY_DCDC2, cpu_vol, -1)) ?? ??? ??? ?{ ?? ??? ??? ??? ?tick_printf("PMU: dcdc2 %d\n", cpu_vol); ?? ??? ??? ??? ?sunxi_clock_set_corepll(uboot_spare_head.boot_data.run_clock); ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?printf("axp_set_dcdc2 fail\n"); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else ?? ??? ?{ ?? ??? ??? ?printf("axp_probe_power_supply_condition error\n"); ?? ??? ?} ?? ?} ?? ?else ?? ?{ ?? ??? ?printf("axp_probe error\n"); ?? ?}
-> // 参数获取验证
pll_cpux = sunxi_clock_get_corepll(); ?? ?tick_printf("PMU: cpux %d Mhz,AXI=%d Mhz\n", pll_cpux,sunxi_clock_get_axi()); ?? ?printf("PLL6=%d Mhz,AHB1=%d Mhz, APB1=%dMhz ?MBus=%dMhz\n", sunxi_clock_get_pll6(), ?? ??? ?sunxi_clock_get_ahb(), ?? ??? ?sunxi_clock_get_apb(), ?? ??? ?sunxi_clock_get_mbus());
?? ?if(axp_exist) ?? ?{ ?? ??? ?axp_set_charge_vol_limit(); ?? ??? ?axp_set_all_limit(); ?? ??? ?axp_set_hardware_poweron_vol(); ?? ??? ?axp_set_power_supply_output(); ?? ??? ?//power_config_gpio_bias(); ?? ??? ?power_limit_init(); ?? ?}
主要做的:读取sys_config.fex,初始化一些参数。包括: axp221设备地址(axp221是通过i2c连接到soc上的) 电池容量 电池充电电流 电池充电电压 预充电时间 持续充电时间等。
这个根据Arm主控要求和芯片特性来。
我也没有深入追踪,有兴趣的朋友可以找到这款PMU的芯片手册结合代码看看。
至此对PMU部分的初始化完成~!
|