跟踪uboot代码,了解imx6 splash image的生成过程。
涉及文件:
./cpu/arm_cortexa8/start.S
./board/freescale/mx6q_sabresd/mx6q_sabresd.c
./board/freescale/commom/fsl_bmp_reversed_600x400.c
/* 汇编调用C语言 */./cpu/arm_cortexa8/start.S:ldr pc, _start_armboot @ jump to C code ------+ |lib_arm/board.c <-----+start_armboot(void){ ...... /* 一系列初始化 */ for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { ---+ if ((*init_fnc_ptr)() != 0) { | hang (); | } | } | ...... | |#if defined CONFIG_SPLASH_SCREEN && defined CONFIG_VIDEO_MX5 | setup_splash_image(); --------------------|-+#endif | | ...... | |} | | | |init_fnc_t *init_sequence[] = { <--------+ |#if defined(CONFIG_ARCH_CPU_INIT) | arch_cpu_init, /* basic arch cpu dependent setup */ |#endif | board_init, /* basic board dependent setup */ ------+ |#if defined(CONFIG_USE_IRQ) | | interrupt_init, /* set up exceptions */ | |#endif | | timer_init, /* initialize timer */ | | env_init, /* initialize environment */ | | init_baudrate, /* initialze baudrate settings */ | | serial_init, /* serial communications setup */ | | console_init_f, /* stage 1 init of console */ | | display_banner, /* say that we are here */ | |#if defined(CONFIG_DISPLAY_CPUINFO) | | print_cpuinfo, /* display cpu info (and speed) */ | |#endif | |#if defined(CONFIG_DISPLAY_BOARDINFO) | | checkboard, /* display board info */ | |#endif | |#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) | | init_func_i2c, | |#endif | | dram_init, /* configure available RAM banks */ | |#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) | | arm_pci_init, | |#endif | | display_dram_config, | | NULL, | |}; | | | |/* imx6初始化文件 */ | |board/freescale/mx6q_sabresd/mx6q_sabresd.c | |int board_init(void) <-----+ |{ |/* need set Power Supply Glitch to 0x41736166 |*and need clear Power supply Glitch Detect bit |* when POR or reboot or power on Otherwise system |*could not be power off anymore*/ | u32 reg; | writel(0x41736166, SNVS_BASE_ADDR + 0x64);/*set LPPGDR*/ | udelay(10); | reg = readl(SNVS_BASE_ADDR + 0x4c); | reg |= (1 << 3); | writel(reg, SNVS_BASE_ADDR + 0x4c);/*clear LPSR*/ | | mxc_iomux_v3_init((void *)IOMUXC_BASE_ADDR); | setup_boot_device(); | fsl_set_system_rev(); | | /* board id for linux */ | gd->bd->bi_arch_number = MACH_TYPE_MX6Q_SABRESD; | | /* address of boot parameters */ | gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; | | setup_uart(); |#ifdef CONFIG_DWC_AHSATA | if (cpu_is_mx6q()) | setup_sata(); |#endif | |#ifdef CONFIG_VIDEO_MX5 | /* Enable lvds power */ |// setup_lvds_poweron(); | | panel_info_init(); -------------------+ | | | gd->fb_base = CONFIG_FB_BASE; | |#ifdef CONFIG_ARCH_MMU | | gd->fb_base = ioremap_nocache(iomem_to_phys(gd->fb_base), 0); | |#endif | |#endif | | | |#ifdef CONFIG_NAND_GPMI | |// setup_gpmi_nand(); | |#endif | | | |#if defined(CONFIG_ENET_RMII) && !defined(CONFIG_DWC_AHSATA) | | setup_fec(); | |#endif | | | |#ifdef CONFIG_MXC_EPDC | | setup_epdc(); -------------------+ |#endif | | | return 0; | | |} | | | | | |#ifdef CONFIG_VIDEO_MX5 | | |void panel_info_init(void) <-------+ | |{ | | panel_info.vl_bpix = LCD_BPP; //屏幕颜色深度 | | panel_info.vl_col = lvds_xga.xres; //屏幕尺寸 | | panel_info.vl_row = lvds_xga.yres; //屏幕尺寸 | | panel_info.cmap = colormap; | |} | |#endif | | | |static void setup_epdc(void) <-----------------------+ |{ | unsigned int reg; | | /*** epdc Maxim PMIC settings ***/ | | /* EPDC PWRSTAT - GPIO2[21] for PWR_GOOD status */ | mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A17__GPIO_2_21); | | /* EPDC VCOM0 - GPIO3[17] for VCOM control */ | mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D17__GPIO_3_17); | | /* UART4 TXD - GPIO3[20] for EPD PMIC WAKEUP */ | mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D20__GPIO_3_20); | | /* EIM_A18 - GPIO2[20] for EPD PWR CTL0 */ | mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A18__GPIO_2_20); | | /*** Set pixel clock rates for EPDC ***/ | | /* EPDC AXI clk (IPU2_CLK) from PFD_400M, set to 396/2 = 198MHz */ | reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3); | reg &= ~0x7C000; | reg |= (1 << 16) | (1 << 14); | writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR3); | | /* EPDC AXI clk enable */ | reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3); | reg |= 0x00C0; | writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3); | | /* EPDC PIX clk (IPU2_DI1_CLK) from PLL5, set to 650/4/6 = ~27MHz */ | reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR2); | reg &= ~0x3FE00; | reg |= (2 << 15) | (5 << 12); | writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR2); | | /* PLL5 enable (defaults to 650) */ | reg = readl(ANATOP_BASE_ADDR + ANATOP_PLL_VIDEO); | reg &= ~((1 << 16) | (1 << 12)); | reg |= (1 << 13); | writel(reg, ANATOP_BASE_ADDR + ANATOP_PLL_VIDEO); | | /* EPDC PIX clk enable */ | reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3); | reg |= 0x0C00; | writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3); | | panel_info.epdc_data.working_buf_addr = CONFIG_WORKING_BUF_ADDR; | panel_info.epdc_data.waveform_buf_addr = CONFIG_WAVEFORM_BUF_ADDR; | | panel_info.epdc_data.wv_modes.mode_init = 0; | panel_info.epdc_data.wv_modes.mode_du = 1; | panel_info.epdc_data.wv_modes.mode_gc4 = 3; | panel_info.epdc_data.wv_modes.mode_gc8 = 2; | panel_info.epdc_data.wv_modes.mode_gc16 = 2; | panel_info.epdc_data.wv_modes.mode_gc32 = 2; | | panel_info.epdc_data.epdc_timings = panel_timings; | | setup_epdc_power(); | | /* Assign fb_base */ | gd->fb_base = CONFIG_FB_BASE; |} | |#ifdef CONFIG_SPLASH_SCREEN |void setup_splash_image(void) <-------------------------+{ char *s; ulong addr; s = getenv("splashimage"); if (s != NULL) { addr = simple_strtoul(s, NULL, 16);#if defined(CONFIG_ARCH_MMU) addr = ioremap_nocache(iomem_to_phys(addr), fsl_bmp_reversed_600x400_size);#endif /* 显示uboot图片 */ memcpy((char *)addr, (char *)fsl_bmp_reversed_600x400, ----+ fsl_bmp_reversed_600x400_size); | } |} |#endif |/* bmp文件生成的源文件 */ |board/freescale/commom/fsl_bmp_reversed_600x400.c |const unsigned char fsl_bmp_reversed_600x400[] = { <-----+ ......}
Author
Tony Liu
2016-8-9, Shenzhen