diff --git a/lichee/brandy/u-boot-2014.07/board/sunxi/sun8iw15p1/sun8iw15p1.c b/lichee/brandy/u-boot-2014.07/board/sunxi/sun8iw15p1/sun8iw15p1.c index 0667d4549..c00112217 100755 --- a/lichee/brandy/u-boot-2014.07/board/sunxi/sun8iw15p1/sun8iw15p1.c +++ b/lichee/brandy/u-boot-2014.07/board/sunxi/sun8iw15p1/sun8iw15p1.c @@ -29,6 +29,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -42,6 +43,195 @@ int enable_smp(void) return 0; } +__s32 boot_set_gpio(void *user_gpio_list, __u32 group_count_max, __s32 set_gpio) +{ + normal_gpio_set_t *tmp_user_gpio_data, *gpio_list; + __u32 first_port; //保存真正有效的GPIO的个数 + __u32 tmp_group_func_data; + __u32 tmp_group_pull_data; + __u32 tmp_group_dlevel_data; + __u32 tmp_group_data_data; + __u32 data_change = 0; +// __u32 *tmp_group_port_addr; + volatile __u32 *tmp_group_func_addr, *tmp_group_pull_addr; + volatile __u32 *tmp_group_dlevel_addr, *tmp_group_data_addr; + __u32 port, port_num, port_num_func, port_num_pull; + __u32 pre_port, pre_port_num_func; + __u32 pre_port_num_pull; + __s32 i, tmp_val; + + + gpio_list = (normal_gpio_set_t *)user_gpio_list; + + for(first_port = 0; first_port < group_count_max; first_port++) + { + tmp_user_gpio_data = gpio_list + first_port; + port = tmp_user_gpio_data->port; //读出端口数值 + port_num = tmp_user_gpio_data->port_num; //读出端口中的某一个GPIO + if(!port) + { + continue; + } + port_num_func = (port_num >> 3); + port_num_pull = (port_num >> 4); + + tmp_group_func_addr = PIO_REG_CFG(port, port_num_func); //更新功能寄存器地址 + tmp_group_pull_addr = PIO_REG_PULL(port, port_num_pull); //更新pull寄存器 + tmp_group_dlevel_addr = PIO_REG_DLEVEL(port, port_num_pull);//更新level寄存器 + tmp_group_data_addr = PIO_REG_DATA(port); //更新data寄存器 + + tmp_group_func_data = GPIO_REG_READ(tmp_group_func_addr); + tmp_group_pull_data = GPIO_REG_READ(tmp_group_pull_addr); + tmp_group_dlevel_data = GPIO_REG_READ(tmp_group_dlevel_addr); + tmp_group_data_data = GPIO_REG_READ(tmp_group_data_addr); + + pre_port = port; + pre_port_num_func = port_num_func; + pre_port_num_pull = port_num_pull; + //更新功能寄存器 + tmp_val = (port_num - (port_num_func << 3)) << 2; + tmp_group_func_data &= ~(0x07 << tmp_val); + if(set_gpio) + { + tmp_group_func_data |= (tmp_user_gpio_data->mul_sel & 0x07) << tmp_val; + } + //根据pull的值决定是否更新pull寄存器 + tmp_val = (port_num - (port_num_pull << 4)) << 1; + if(tmp_user_gpio_data->pull >= 0) + { + tmp_group_pull_data &= ~( 0x03 << tmp_val); + tmp_group_pull_data |= (tmp_user_gpio_data->pull & 0x03) << tmp_val; + } + //根据driver level的值决定是否更新driver level寄存器 + if(tmp_user_gpio_data->drv_level >= 0) + { + tmp_group_dlevel_data &= ~( 0x03 << tmp_val); + tmp_group_dlevel_data |= (tmp_user_gpio_data->drv_level & 0x03) << tmp_val; + } + //根据用户输入,以及功能分配决定是否更新data寄存器 + if(tmp_user_gpio_data->mul_sel == 1) + { + if(tmp_user_gpio_data->data >= 0) + { + tmp_val = tmp_user_gpio_data->data & 1; + tmp_group_data_data &= ~(1 << port_num); + tmp_group_data_data |= tmp_val << port_num; + data_change = 1; + } + } + + break; + } + //检查是否有数据存在 + if(first_port >= group_count_max) + { + return -1; + } + //保存用户数据 + for(i = first_port + 1; i < group_count_max; i++) + { + tmp_user_gpio_data = gpio_list + i; //gpio_set依次指向用户的每个GPIO数组成员 + port = tmp_user_gpio_data->port; //读出端口数值 + port_num = tmp_user_gpio_data->port_num; //读出端口中的某一个GPIO + if(!port) + { + break; + } + port_num_func = (port_num >> 3); + port_num_pull = (port_num >> 4); + + if((port_num_pull != pre_port_num_pull) || (port != pre_port)) //如果发现当前引脚的端口不一致,或者所在的pull寄存器不一致 + { + GPIO_REG_WRITE(tmp_group_func_addr, tmp_group_func_data); //回写功能寄存器 + GPIO_REG_WRITE(tmp_group_pull_addr, tmp_group_pull_data); //回写pull寄存器 + GPIO_REG_WRITE(tmp_group_dlevel_addr, tmp_group_dlevel_data); //回写driver level寄存器 + if(data_change) + { + data_change = 0; + GPIO_REG_WRITE(tmp_group_data_addr, tmp_group_data_data); //回写data寄存器 + } + + tmp_group_func_addr = PIO_REG_CFG(port, port_num_func); //更新功能寄存器地址 + tmp_group_pull_addr = PIO_REG_PULL(port, port_num_pull); //更新pull寄存器 + tmp_group_dlevel_addr = PIO_REG_DLEVEL(port, port_num_pull);//更新level寄存器 + tmp_group_data_addr = PIO_REG_DATA(port); //更新data寄存器 + + tmp_group_func_data = GPIO_REG_READ(tmp_group_func_addr); + tmp_group_pull_data = GPIO_REG_READ(tmp_group_pull_addr); + tmp_group_dlevel_data = GPIO_REG_READ(tmp_group_dlevel_addr); + tmp_group_data_data = GPIO_REG_READ(tmp_group_data_addr); + } + else if(pre_port_num_func != port_num_func) //如果发现当前引脚的功能寄存器不一致 + { + GPIO_REG_WRITE(tmp_group_func_addr, tmp_group_func_data); //则只回写功能寄存器 + tmp_group_func_addr = PIO_REG_CFG(port, port_num_func); //更新功能寄存器地址 + + tmp_group_func_data = GPIO_REG_READ(tmp_group_func_addr); + } + //保存当前硬件寄存器数据 + pre_port_num_pull = port_num_pull; //设置当前GPIO成为前一个GPIO + pre_port_num_func = port_num_func; + pre_port = port; + + //更新功能寄存器 + tmp_val = (port_num - (port_num_func << 3)) << 2; + if(tmp_user_gpio_data->mul_sel >= 0) + { + tmp_group_func_data &= ~( 0x07 << tmp_val); + if(set_gpio) + { + tmp_group_func_data |= (tmp_user_gpio_data->mul_sel & 0x07) << tmp_val; + } + } + //根据pull的值决定是否更新pull寄存器 + tmp_val = (port_num - (port_num_pull << 4)) << 1; + if(tmp_user_gpio_data->pull >= 0) + { + tmp_group_pull_data &= ~( 0x03 << tmp_val); + tmp_group_pull_data |= (tmp_user_gpio_data->pull & 0x03) << tmp_val; + } + //根据driver level的值决定是否更新driver level寄存器 + if(tmp_user_gpio_data->drv_level >= 0) + { + tmp_group_dlevel_data &= ~( 0x03 << tmp_val); + tmp_group_dlevel_data |= (tmp_user_gpio_data->drv_level & 0x03) << tmp_val; + } + //根据用户输入,以及功能分配决定是否更新data寄存器 + if(tmp_user_gpio_data->mul_sel == 1) + { + if(tmp_user_gpio_data->data >= 0) + { + tmp_val = tmp_user_gpio_data->data & 1; + tmp_group_data_data &= ~(1 << port_num); + tmp_group_data_data |= tmp_val << port_num; + data_change = 1; + } + } + } + //for循环结束,如果存在还没有回写的寄存器,这里写回到硬件当中 + if(tmp_group_func_addr) //只要更新过寄存器地址,就可以对硬件赋值 + { //那么把所有的值全部回写到硬件寄存器 + GPIO_REG_WRITE(tmp_group_func_addr, tmp_group_func_data); //回写功能寄存器 + GPIO_REG_WRITE(tmp_group_pull_addr, tmp_group_pull_data); //回写pull寄存器 + GPIO_REG_WRITE(tmp_group_dlevel_addr, tmp_group_dlevel_data); //回写driver level寄存器 + if(data_change) + { + GPIO_REG_WRITE(tmp_group_data_addr, tmp_group_data_data); //回写data寄存器 + } + } + + return 0; +} + +void Netease_gpio_init(void) { + normal_gpio_set_t ldo_gpio[2] = + { + { 8, 4, 1, -1, -1, 1, {0}},//4v5_ldo_en = port:PH04<1><0> + { 8, 5, 1, -1, -1, 1, {0}} //3v_ldo_en = port:PH05<1><0> + }; + boot_set_gpio(ldo_gpio,2,1); +} + int board_init(void) { //asm volatile("b ."); @@ -71,6 +261,9 @@ int board_init(void) writel(reg_val, CCMU_VE_BGR_REG); } + printf("Enable GPIO PH04 PH05, by Netease!\n"); + Netease_gpio_init(); + return 0; } diff --git a/target/allwinner/mandolin-common/bin/u-boot-sun8iw15p1.bin b/target/allwinner/mandolin-common/bin/u-boot-sun8iw15p1.bin index 92eed82fb..f7d49acda 100755 Binary files a/target/allwinner/mandolin-common/bin/u-boot-sun8iw15p1.bin and b/target/allwinner/mandolin-common/bin/u-boot-sun8iw15p1.bin differ