• I.MX6 U-boot lvds display hacking


    /***********************************************************************************
     *                    I.MX6 U-boot lvds display hacking
     * 声明:
     *   本文主要是为了跟踪I.MX6中的U-boot中显示部分代码,查看是否支持24bit显示。
     *
     *                                           2015-10-8 晴 深圳 南山平山村 曾剑锋
     **********************************************************************************/
                                                                                                        
    cat cpu/arm_cortexa8/start.S                                                                        
        .globl _start                                                                                   
        _start: b   reset          ---------------------------+                                         
            ldr pc, _undefined_instruction                    |                                         
            ldr pc, _software_interrupt                       |                                         
            ldr pc, _prefetch_abort                           |                                         
            ldr pc, _data_abort                               |                                         
            ldr pc, _not_used                                 |                                         
            ldr pc, _irq                                      |                                         
            ldr pc, _fiq                                      |                                         
                                                              |                                         
        _undefined_instruction: .word undefined_instruction   |                                         
        _software_interrupt:    .word software_interrupt      |                                         
        _prefetch_abort:    .word prefetch_abort              |                                         
        _data_abort:        .word data_abort                  |                                         
        _not_used:      .word not_used                        |                                         
        _irq:           .word irq                             |                                         
        _fiq:           .word fiq                             |                                         
                                                              |                                         
    cat cpu/arm_cortexa8/start.S                              |                                         
        /*                                                    |                                         
         * the actual reset code                              |                                         
         */                                                   |                                         
                                                              |                                         
        reset:                     <--------------------------+                                         
            /*                                                                                          
             * set the cpu to SVC32 mode                                                                
             */                                                                                         
            mrs    r0, cpsr                                                                             
            bic    r0, r0, #0x1f                                                                        
            orr    r0, r0, #0xd3                                                                        
            msr    cpsr,r0                                                                              
                                                                                                        
        #if (CONFIG_OMAP34XX)                                                                           
            /* Copy vectors to mask ROM indirect addr */                                                
            adr    r0, _start        @ r0 <- current position of code                                   
            add    r0, r0, #4        @ skip reset vector                                                
            mov    r2, #64            @ r2 <- size to copy                                              
            add    r2, r0, r2        @ r2 <- source end address                                         
            mov    r1, #SRAM_OFFSET0    @ build vect addr                                               
            mov    r3, #SRAM_OFFSET1                                                                    
            add    r1, r1, r3                                                                           
            mov    r3, #SRAM_OFFSET2                                                                    
            add    r1, r1, r3                                                                           
        next:                                                                                           
            ldmia    r0!, {r3 - r10}        @ copy from source address [r0]                             
            stmia    r1!, {r3 - r10}        @ copy to   target address [r1]                             
            cmp    r0, r2            @ until source end address [r2]                                    
            bne    next            @ loop until equal */                                                
        #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)                         
            /* No need to copy/exec the clock code - DPLL adjust already done                           
             * in NAND/oneNAND Boot.                                                                    
             */                                                                                         
            bl    cpy_clk_code        @ put dpll adjust code behind vectors                             
        #endif /* NAND Boot */                                                                          
        #endif                                                                                          
            /* the mask ROM code should have PLL and others stable */                                   
        #ifndef CONFIG_SKIP_LOWLEVEL_INIT                                                               
            bl    cpu_init_crit                                                                         
        #endif                                                                                          
                                                                                                        
        #ifndef CONFIG_SKIP_RELOCATE_UBOOT                                                              
        relocate:               @ relocate U-Boot to RAM                                                
            adr r0, _start      @ r0 <- current position of code                                        
            ldr r1, _TEXT_BASE      @ test if we run from flash or RAM                                  
            cmp r0, r1          @ don't reloc during debug                                              
            beq stack_setup                                                                             
                                                                                                        
            ldr r2, _armboot_start                                                                      
            ldr r3, _bss_start                                                                          
            sub r2, r3, r2      @ r2 <- size of armboot                                                 
            add r2, r0, r2      @ r2 <- source end address                                              
                                                                                                        
        copy_loop:              @ copy 32 bytes at a time                                               
            ldmia   r0!, {r3 - r10}     @ copy from source address [r0]                                 
            stmia   r1!, {r3 - r10}     @ copy to   target address [r1]                                 
            cmp r0, r2          @ until source end addreee [r2]                                         
            ble copy_loop                                                                               
        #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */                                                        
                                                                                                        
        stack_setup:                                                                                    
            ldr r0, _TEXT_BASE      @ upper 128 KiB: relocated uboot                                    
            sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area                                            
            sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo                                              
        #ifdef CONFIG_USE_IRQ                                                                           
            sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)                                  
        #endif                                                                                          
            sub sp, r0, #12     @ leave 3 words for abort-stack                                         
            and sp, sp, #~7     @ 8 byte alinged for (ldr/str)d                                         
                                                                                                        
            /* Clear BSS (if any). Is below tx (watch load addr - need space) */                        
        clear_bss:                                                                                      
            ldr r0, _bss_start      @ find start of bss segment                                         
            ldr r1, _bss_end        @ stop here                                                         
            mov r2, #0x00000000     @ clear value                                                       
        clbss_l:                                                                                        
            str r2, [r0]        @ clear BSS location                                                    
            cmp r0, r1          @ are we at the end yet                                                 
            add r0, r0, #4      @ increment clear index pointer                                         
            bne clbss_l         @ keep clearing till at end                                             
                                                                                                        
        #ifdef CONFIG_ARCH_MMU                                                                          
            bl board_mmu_init                                                                           
        #endif                                                                                          
            ldr pc, _start_armboot  @ jump to C code              -------+                              
                                                                         |                              
        _start_armboot: .word start_armboot          ---------+   <------+                              
                                                              |                                         
    cat lib_arm/board.c                                       |                                         
        void start_armboot (void)                    <--------+                                        
        {                                                                                               
            init_fnc_t **init_fnc_ptr;                                                                  
            char *s;                                                                                    
        #if defined(CONFIG_VFD) || defined(CONFIG_LCD)                                                  
            unsigned long addr;                                                                         
        #endif                                                                                          
                                                                                                        
            /* Pointer is writable since we allocated a register for it */                              
            gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));                        
            /* compiler optimization barrier needed for GCC >= 3.4 */                                   
            __asm__ __volatile__("": : :"memory");                                                      
                                                                                                        
            memset ((void*)gd, 0, sizeof (gd_t));                                                       
            gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));                                                 
            memset (gd->bd, 0, sizeof (bd_t));                                                          
                                                                                                        
            gd->flags |= GD_FLG_RELOC;                                                                  
                                                                                                        
            monitor_flash_len = _bss_start - _armboot_start;                                            
                                                                                                        
            for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {                         
                if ((*init_fnc_ptr)() != 0) {                                                           
                    hang ();                                                                            
                }                                                                                       
            }                                                                                           
                                                                                                        
            /* armboot_start is defined in the board-specific linker script */                          
            mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN);                                   
                                                                                                        
        #ifndef CONFIG_SYS_NO_FLASH                                                                     
            /* configure available FLASH banks */                                                       
            display_flash_config (flash_init ());                                                       
        #endif /* CONFIG_SYS_NO_FLASH */                                                                
                                                                                                        
        #ifdef CONFIG_VFD                                                                               
        #ifndef PAGE_SIZE                                                                               
        #define PAGE_SIZE 4096                                                                          
        #endif                                                                                          
            /*                                                                                          
             * reserve memory for VFD display (always full pages)                                       
             */                                                                                         
            /* bss_end is defined in the board-specific linker script */                                
            addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);                                     
            vfd_setmem (addr);                                                                          
            gd->fb_base = addr;                                                                         
        #endif /* CONFIG_VFD */                                                                         
                                                                                                        
        #ifdef CONFIG_LCD                                                                               
            /* board init may have inited fb_base */                                                    
            if (!gd->fb_base) {                                                                         
        #ifndef PAGE_SIZE                                                                               
        #define PAGE_SIZE 4096                                                                          
        #endif                                                                                          
                /*                                                                                      
                 * reserve memory for LCD display (always full pages)                                   
                 */                                                                                     
                /* bss_end is defined in the board-specific linker script */                            
                addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);                                 
                lcd_setmem (addr);                                                                      
                gd->fb_base = addr;                                                                     
            }                                                                                           
        #endif /* CONFIG_LCD */                                                                         
                                                                                                        
        #if defined(CONFIG_CMD_NAND)                                                                    
            puts ("NAND:  ");                                                                           
            nand_init();        /* go init the NAND */                                                  
        #endif                                                                                          
                                                                                                        
        #if defined(CONFIG_CMD_ONENAND)                                                                 
            onenand_init();                                                                             
        #endif                                                                                          
                                                                                                        
        #ifdef CONFIG_HAS_DATAFLASH                                                                     
            AT91F_DataflashInit();                                                                      
            dataflash_print_info();                                                                     
        #endif                                                                                          
                                                                                                        
        #ifdef CONFIG_GENERIC_MMC                                                                       
            puts ("MMC:   ");                                                                           
            mmc_initialize (gd->bd);                                                                    
        #endif                                                                                          
                                                                                                        
            /* initialize environment */                                                                
            env_relocate ();                                                                            
                                                                                                        
        #ifdef CONFIG_VFD                                                                               
            /* must do this after the framebuffer is allocated */                                       
            drv_vfd_init();                                                                             
        #endif /* CONFIG_VFD */                                                                         
                                                                                                        
        #ifdef CONFIG_SERIAL_MULTI                                                                      
            serial_initialize();                                                                        
        #endif                                                                                          
                                                                                                        
            /* IP Address */                                                                            
            gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");                                              
                                                                                                        
        #if defined CONFIG_SPLASH_SCREEN && defined CONFIG_VIDEO_MX5                                    
            setup_splash_image();                                                                       
        #endif                                                                                          
                                                                                                        
            stdio_init ();    /* get the devices list going. */   -------------------+                  
                                                                                     |                  
            jumptable_init ();                                                       |                  
                                                                                     |                  
        #if defined(CONFIG_API)                                                      |                  
            /* Initialize API */                                                     |                  
            api_init ();                                                             |                  
        #endif                                                                       |                  
                                                                                     |                  
            console_init_r ();    /* fully init console as a device */               |                  
                                                                                     |                  
        #if defined(CONFIG_ARCH_MISC_INIT)                                           |                  
            /* miscellaneous arch dependent initialisations */                       |                  
            arch_misc_init ();                                                       |                  
        #endif                                                                       |                  
        #if defined(CONFIG_MISC_INIT_R)                                              |                  
            /* miscellaneous platform dependent initialisations */                   |                  
            misc_init_r ();                                                          |                  
        #endif                                                                       |                  
                                                                                     |                  
            /* enable exceptions */                                                  |                  
            enable_interrupts ();                                                    |                  
                                                                                     |                  
            /* Perform network card initialisation if necessary */                   |                  
        #ifdef CONFIG_DRIVER_TI_EMAC                                                 |                  
            /* XXX: this needs to be moved to board init */                          |                  
        extern void davinci_eth_set_mac_addr (const u_int8_t *addr);                 |                  
            if (getenv ("ethaddr")) {                                                |                  
                uchar enetaddr[6];                                                   |                  
                eth_getenv_enetaddr("ethaddr", enetaddr);                            |                  
                davinci_eth_set_mac_addr(enetaddr);                                  |                  
            }                                                                        |                  
        #endif                                                                       |                  
                                                                                     |                  
        #ifdef CONFIG_DRIVER_CS8900                                                  |                  
            /* XXX: this needs to be moved to board init */                          |                  
            cs8900_get_enetaddr ();                                                  |                  
        #endif                                                                       |                  
                                                                                     |                  
        #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)      |                  
            /* XXX: this needs to be moved to board init */                          |                  
            if (getenv ("ethaddr")) {                                                |                  
                uchar enetaddr[6];                                                   |                  
                eth_getenv_enetaddr("ethaddr", enetaddr);                            |                  
                smc_set_mac_addr(enetaddr);                                          |                  
            }                                                                        |                  
        #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */                |                  
                                                                                     |                  
        #if defined(CONFIG_ENC28J60_ETH) && !defined(CONFIG_ETHADDR)                 |                  
            extern void enc_set_mac_addr (void);                                     |                  
            enc_set_mac_addr ();                                                     |                  
        #endif /* CONFIG_ENC28J60_ETH && !CONFIG_ETHADDR*/                           |                  
                                                                                     |                  
            /* Initialize from environment */                                        |                  
            if ((s = getenv ("loadaddr")) != NULL) {                                 |                  
                load_addr = simple_strtoul (s, NULL, 16);                            |                  
            }                                                                        |                  
        #if defined(CONFIG_CMD_NET)                                                  |                  
            if ((s = getenv ("bootfile")) != NULL) {                                 |                  
                copy_filename (BootFile, s, sizeof (BootFile));                      |                  
            }                                                                        |                  
        #endif                                                                       |                  
                                                                                     |                  
        #ifdef BOARD_LATE_INIT                                                       |                  
            board_late_init ();                                                      |                  
        #endif                                                                       |                  
                                                                                     |                  
        #ifdef CONFIG_ANDROID_RECOVERY                                               |                  
            check_recovery_mode();                                                   |                  
        #endif                                                                       |                  
                                                                                     |                  
        #if defined(CONFIG_CMD_NET)                                                  |                  
        #if defined(CONFIG_NET_MULTI)                                                |                  
            puts ("Net:   ");                                                        |                  
        #endif                                                                       |                  
            eth_initialize(gd->bd);                                                  |                  
        #if defined(CONFIG_RESET_PHY_R)                                              |                  
            debug ("Reset Ethernet PHY
    ");                                          |                  
            reset_phy();                                                             |                  
        #endif                                                                       |                  
        #endif                                                                       |                  
        #ifdef CONFIG_FASTBOOT                                                       |                  
            check_fastboot_mode();                                                   |                  
        #endif                                                                       |                  
            /* main_loop() can return to retry autoboot, if so just run it again. */ |                  
            for (;;) {                                                               |                  
                main_loop ();                                                        |                  
            }                                                                        |                  
                                                                                     |                  
            /* NOTREACHED - no way out of command loop except booting */             |                  
        }                                                                            |                  
                                                                                     |                  
    cat common/stdio.c                                                               |                  
        int stdio_init (void)                    <-----------------------------------+                  
        {                                                                                               
        #ifndef CONFIG_ARM    /* already relocated for current ARM implementation */                    
            ulong relocation_offset = gd->reloc_off;                                                    
            int i;                                                                                      
                                                                                                        
            /* relocate device name pointers */                                                         
            for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {                            
                stdio_names[i] = (char *) (((ulong) stdio_names[i]) +                                   
                                relocation_offset);                                                     
            }                                                                                           
        #endif                                                                                          
                                                                                                        
            /* Initialize the list */                                                                   
            INIT_LIST_HEAD(&(devs.list));                                                               
                                                                                                        
        #ifdef CONFIG_ARM_DCC_MULTI                                                                     
            drv_arm_dcc_init ();                                                                        
        #endif                                                                                          
        #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)                                        
            i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);                                      
        #endif                                                                                          
        #ifdef CONFIG_LCD                                                                               
            drv_lcd_init ();                     ----------------------------------+                    
        #endif                                                                     |                    
        #if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)                   |                    
            drv_video_init ();                                                     |                    
        #endif                                                                     |                    
        #ifdef CONFIG_KEYBOARD                                                     |                    
            drv_keyboard_init ();                                                  |                    
        #endif                                                                     |                    
        #ifdef CONFIG_LOGBUFFER                                                    |                    
            drv_logbuff_init ();                                                   |                    
        #endif                                                                     |                    
            drv_system_init ();                                                    |                    
        #ifdef CONFIG_SERIAL_MULTI                                                 |                    
            serial_stdio_init ();                                                  |                    
        #endif                                                                     |                    
        #ifdef CONFIG_USB_TTY                                                      |                    
            drv_usbtty_init ();                                                    |                    
        #endif                                                                     |                    
        #ifdef CONFIG_NETCONSOLE                                                   |                    
            drv_nc_init ();                                                        |                    
        #endif                                                                     |                    
        #ifdef CONFIG_JTAG_CONSOLE                                                 |                    
            drv_jtag_console_init ();                                              |                    
        #endif                                                                     |                    
                                                                                   |                    
            return (0);                                                            |                    
        }                                                                          |                    
                                                                                   |                    
    cat common/stdio.c                                                             |                    
        int drv_lcd_init (void)                    <-------------------------------+                    
        {                                                                                               
            struct stdio_dev lcddev;                                                                    
            int rc;                                                                                     
                                                                                                        
            lcd_base = (void *)(gd->fb_base);                                                           
                                                                                                        
            lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;                     
                                                                                                        
            lcd_init (lcd_base);        /* LCD initialization */        ----------+                     
                                                                                  |                     
            /* Device initialization */                                           |                     
            memset (&lcddev, 0, sizeof (lcddev));                                 |                     
                                                                                  |                     
            strcpy (lcddev.name, "lcd");                                          |                     
            lcddev.ext   = 0;           /* No extensions */                       |                     
            lcddev.flags = DEV_FLAGS_OUTPUT;    /* Output only */                 |                     
            lcddev.putc  = lcd_putc;        /* 'putc' function */                 |                     
            lcddev.puts  = lcd_puts;        /* 'puts' function */                 |                     
                                                                                  |                     
            rc = stdio_register (&lcddev);                                        |                     
                                                                                  |                     
            return (rc == 0) ? 1 : rc;                                            |                     
        }                                                                         |                     
                                                                                  |                     
    cat common/lcd.c                                                              |                     
        static int lcd_init (void *lcdbase)                   <-------------------+                     
        {                                                                                               
            /* Initialize the lcd controller */                                                         
            debug ("[LCD] Initializing LCD frambuffer at %p
    ", lcdbase);                               
                                                                                                        
            lcd_ctrl_init (lcdbase);                                                                    
            lcd_is_enabled = 1;                                                                         
            lcd_clear (NULL, 1, 1, NULL);   /* dummy args */  -------------+                            
            lcd_enable ();                                    -------------*---------------+            
                                                                           |               |            
            /* Initialize the console */                                   |               |            
            console_col = 0;                                               |               |            
        #ifdef CONFIG_LCD_INFO_BELOW_LOGO                                  |               |            
            console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;         |               |            
        #else                                                              |               |            
            console_row = 1;    /* leave 1 blank line below logo */        |               |            
        #endif                                                             |               |            
                                                                           |               |            
            return 0;                                                      |               |            
        }                +-------------------------------------------------+               |            
                         |                                                                 |            
    cat common/lcd.c     V                                                                 |            
        static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])         |            
        {                                                                                  |            
        #if LCD_BPP == LCD_MONOCHROME                                                      |            
            /* Setting the palette */                                                      |            
            lcd_initcolregs();                                                             |            
                                                                                           |            
        #elif LCD_BPP == LCD_COLOR8                                                        |            
            /* Setting the palette */                                                      |            
            lcd_setcolreg  (CONSOLE_COLOR_BLACK,       0,    0,    0);                     |            
            lcd_setcolreg  (CONSOLE_COLOR_RED,    0xFF,    0,    0);                       |            
            lcd_setcolreg  (CONSOLE_COLOR_GREEN,       0, 0xFF,    0);                     |            
            lcd_setcolreg  (CONSOLE_COLOR_YELLOW,    0xFF, 0xFF,    0);                    |            
            lcd_setcolreg  (CONSOLE_COLOR_BLUE,        0,    0, 0xFF);                     |            
            lcd_setcolreg  (CONSOLE_COLOR_MAGENTA,    0xFF,    0, 0xFF);                   |            
            lcd_setcolreg  (CONSOLE_COLOR_CYAN,       0, 0xFF, 0xFF);                      |            
            lcd_setcolreg  (CONSOLE_COLOR_GREY,    0xAA, 0xAA, 0xAA);                      |            
            lcd_setcolreg  (CONSOLE_COLOR_WHITE,    0xFF, 0xFF, 0xFF);                     |            
        #endif                                                                             |            
                                                                                           |            
        #ifndef CONFIG_SYS_WHITE_ON_BLACK                                                  |            
            lcd_setfgcolor (CONSOLE_COLOR_BLACK);                                          |            
            lcd_setbgcolor (CONSOLE_COLOR_WHITE);                                          |            
        #else                                                                              |            
            lcd_setfgcolor (CONSOLE_COLOR_WHITE);                                          |            
            lcd_setbgcolor (CONSOLE_COLOR_BLACK);                                          |            
        #endif    /* CONFIG_SYS_WHITE_ON_BLACK */                                          |            
                                                                                           |            
        #ifdef    LCD_TEST_PATTERN                                                         |            
            test_pattern();                                                                |            
        #else                                                                              |            
            /* set framebuffer to background color */                                      |            
            memset ((char *)lcd_base,                                                      |            
                COLOR_MASK(lcd_getbgcolor()),                                              |            
                lcd_line_length*panel_info.vl_row);                                        |            
        #endif                                                                             |            
            /* Paint the logo and retrieve LCD base address */                             |            
            debug ("[LCD] Drawing the logo...
    ");                                         |            
            lcd_console_address = lcd_logo ();   --------+                                 |            
                                                         |                                 |            
            console_col = 0;                             |                                 |            
            console_row = 0;                             |                                 |            
                                                         |                                 |            
            return (0);                                  |                                 |            
        }                                                |                                 |            
                                                         |                                 |            
    cat common/lcd.c                                     |                                 |            
        static void *lcd_logo (void)         <-----------+                                 |            
        {                                                                                  |            
        #ifdef CONFIG_SPLASH_SCREEN                                                        |            
            char *s;                                                                       |            
            ulong addr;                                                                    |            
            static int do_splash = 1;                                                      |            
                                                                                           |            
            // get the "splashimage=0x30000000"                                          |            
            if (do_splash && (s = getenv("splashimage")) != NULL) {                        |            
                int x = 0, y = 0;                                                          |            
                do_splash = 0;                                                             |            
                                                                                           |            
                // get the image address                                                   |            
                addr = simple_strtoul (s, NULL, 16);                                       |            
                                                                                           |            
        #ifdef CONFIG_SPLASH_SCREEN_ALIGN                                                  |            
                // get the "splashpos=m,m"                                               |            
                if ((s = getenv ("splashpos")) != NULL) {                                  |            
                    // the first position x and y, default was center                      |            
                    if (s[0] == 'm')                                                       |            
                        x = BMP_ALIGN_CENTER;                                              |            
                    else                                                                   |            
                        x = simple_strtol (s, NULL, 0);                                    |            
                                                                                           |            
                    if ((s = strchr (s + 1, ',')) != NULL) {                               |            
                        if (s[1] == 'm')                                                   |            
                            y = BMP_ALIGN_CENTER;                                          |            
                        else                                                               |            
                            y = simple_strtol (s + 1, NULL, 0);                            |            
                    }                                                                      |            
                }                                                                          |            
        #endif /* CONFIG_SPLASH_SCREEN_ALIGN */                                            |            
                                                                                           |            
        #ifdef CONFIG_VIDEO_BMP_GZIP                                                       |            
                // get the image struct                                                    |            
                bmp_image_t *bmp = (bmp_image_t *)addr;                                    |            
                unsigned long len;                                                         |            
                                                                                           |            
                if (!((bmp->header.signature[0]=='B') &&                                   |            
                      (bmp->header.signature[1]=='M'))) {                                  |            
                    addr = (ulong)gunzip_bmp(addr, &len);                                  |            
                }                                                                          |            
        #endif                                                                             |            
                /**                                                                        |            
                 * We currently offer uboot boot picture size is 800*480,                  |            
                  * so the picture do not need to be offset ,                              |            
                 * just let x and y equal to zero that drawing picture at top left corner  |            
                 *                 write by zengjf    2015/4/8                             |            
                 */                                                                        |            
                x = 0;                                                                     |            
                  y = 0;                                                                   |            
                                                                                           |            
                                                                                           |            
                if (lcd_display_bitmap (addr, x, y) == 0) {       -------------------+     |            
                    return ((void *)lcd_base);                                       |     |            
                }                                                                    |     |            
            }                                                                        |     |            
        #endif /* CONFIG_SPLASH_SCREEN */                                            |     |            
                                                                                     |     |            
        #ifdef CONFIG_LCD_LOGO                                                       |     |            
            bitmap_plot (0, 0);                                                      |     |            
        #endif /* CONFIG_LCD_LOGO */                                                 |     |            
                                                                                     |     |            
        #ifdef CONFIG_LCD_INFO                                                       |     |            
            console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;                             |     |            
            console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;                            |     |            
            lcd_show_board_info();                                                   |     |            
        #endif /* CONFIG_LCD_INFO */                                                 |     |            
                                                                                     |     |            
        #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)         |     |            
            return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));  |     |            
        #else                                                                        |     |            
            return ((void *)lcd_base);                                               |     |            
        #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */                  |     |            
        }                                                                            |     |            
                                                                                     |     |            
    cat common/lcd.c                                                                 |     |            
        int lcd_display_bitmap(ulong bmp_image, int x, int y)     <------------------+     |            
        {                                                                                  |            
        #if !defined(CONFIG_MCC200)                                                        |            
            ushort *cmap = NULL;                                                           |            
        #endif                                                                             |            
            ushort *cmap_base = NULL;                                                      |            
            ushort i, j;                                                                   |            
            uchar *fb;                                                                     |            
            bmp_image_t *bmp=(bmp_image_t *)bmp_image;                                     |            
            uchar *bmap;                                                                   |            
            ushort padded_line;                                                            |            
            unsigned long width, height, byte_width;                                       |            
            unsigned long pwidth = panel_info.vl_col;                                      |            
            unsigned colors, bpix, bmp_bpix;                                               |            
            unsigned long compression;                                                     |            
        #if defined(CONFIG_PXA250)                                                         |            
            struct pxafb_info *fbi = &panel_info.pxa;                                      |            
        #elif defined(CONFIG_MPC823)                                                       |            
            volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;                          |            
            volatile cpm8xx_t *cp = &(immr->im_cpm);                                       |            
        #endif                                                                             |            
                                                                                           |            
            if (!((bmp->header.signature[0]=='B') &&                                       |            
                (bmp->header.signature[1]=='M'))) {                                        |            
                printf ("Error: no valid bmp image at %lx
    ", bmp_image);                  |            
                return 1;                                                                  |            
            }                                                                              |            
                                                                                           |            
            width = le32_to_cpu (bmp->header.width);                                       |            
            height = le32_to_cpu (bmp->header.height);                                     |            
            bmp_bpix = le16_to_cpu(bmp->header.bit_count);                                 |            
            colors = 1 << bmp_bpix;                                                        |            
            compression = le32_to_cpu (bmp->header.compression);                           |            
                                                                                           |            
            bpix = NBITS(panel_info.vl_bpix);                                              |            
                                                                                           |            
            if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 24)) {              |            
                printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel
    ",            |            
                    bpix, bmp_bpix);                                                       |            
                return 1;                                                                  |            
            }                                                                              |            
                                                                                           |            
        #if defined(CONFIG_BMP_24BPP)                                                      |            
            /* We support displaying 24bpp BMPs on 16bpp LCDs */                           |            
            if (bpix != bmp_bpix && (bmp_bpix != 24 || bpix != 16) &&                      |            
                (bmp_bpix != 8 || bpix != 16)) {                                           |            
        #else                                                                              |            
            /* We support displaying 8bpp BMPs on 16bpp LCDs */                            |            
            if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16)) {                       |            
        #endif                                                                             |            
                printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel
    ",            |            
                    bpix,                                                                  |            
                    le16_to_cpu(bmp->header.bit_count));                                   |            
                return 1;                                                                  |            
            }                                                                              |            
                                                                                           |            
            debug ("Display-bmp: %d x %d  with %d colors
    ",                               |            
                (int)width, (int)height, (int)colors);                                     |            
                                                                                           |            
        #if !defined(CONFIG_MCC200)                                                        |            
            /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */                     |            
            if (bmp_bpix == 8) {                                                           |            
        #if defined(CONFIG_PXA250)                                                         |            
                cmap = (ushort *)fbi->palette;                                             |            
        #elif defined(CONFIG_MPC823)                                                       |            
                cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);                      |            
        #elif !defined(CONFIG_ATMEL_LCD)                                                   |            
                cmap = panel_info.cmap;                                                    |            
        #endif                                                                             |            
                cmap_base = cmap;                                                          |            
                                                                                           |            
                /* Set color map */                                                        |            
                for (i=0; i<colors; ++i) {                                                 |            
                    bmp_color_table_entry_t cte = bmp->color_table[i];                     |            
        #if !defined(CONFIG_ATMEL_LCD)                                                     |            
                    ushort colreg =                                                        |            
                        ( ((cte.red)   << 8) & 0xf800) |                                   |            
                        ( ((cte.green) << 3) & 0x07e0) |                                   |            
                        ( ((cte.blue)  >> 3) & 0x001f) ;                                   |            
        #ifdef CONFIG_SYS_INVERT_COLORS                                                    |            
                    *cmap = 0xffff - colreg;                                               |            
        #else                                                                              |            
                    *cmap = colreg;                                                        |            
        #endif                                                                             |            
        #if defined(CONFIG_MPC823)                                                         |            
                    cmap--;                                                                |            
        #else                                                                              |            
                    cmap++;                                                                |            
        #endif                                                                             |            
        #else /* CONFIG_ATMEL_LCD */                                                       |            
                    lcd_setcolreg(i, cte.red, cte.green, cte.blue);                        |            
        #endif                                                                             |            
                }                                                                          |            
            }                                                                              |            
        #endif                                                                             |            
                                                                                           |            
            /*                                                                             |            
             * BMP format for Monochrome assumes that the state of a                       |            
             * pixel is described on a per Bit basis, not per Byte.                        |            
             * So, in case of Monochrome BMP we should align widths                        |            
             * on a byte boundary and convert them from Bit to Byte                        |            
             * units.                                                                      |            
             * Probably, PXA250 and MPC823 process 1bpp BMP images in                      |            
             * their own ways, so make the converting to be MCC200                         |            
             * specific.                                                                   |            
             */                                                                            |            
        #if defined(CONFIG_MCC200)                                                         |            
            if (bpix==1)                                                                   |            
            {                                                                              |            
                width = ((width + 7) & ~7) >> 3;                                           |            
                x     = ((x + 7) & ~7) >> 3;                                               |            
                pwidth= ((pwidth + 7) & ~7) >> 3;                                          |            
            }                                                                              |            
        #endif                                                                             |            
            padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);                        |            
        #ifdef CONFIG_SPLASH_SCREEN_ALIGN                                                  |            
            if (x == BMP_ALIGN_CENTER)                                                     |            
                x = max(0, (pwidth - width) / 2);                                          |            
            else if (x < 0)                                                                |            
                x = max(0, pwidth - width + x + 1);                                        |            
                                                                                           |            
            if (y == BMP_ALIGN_CENTER)                                                     |            
                y = max(0, (panel_info.vl_row - height) / 2);                              |            
            else if (y < 0)                                                                |            
                y = max(0, panel_info.vl_row - height + y + 1);                            |            
        #endif /* CONFIG_SPLASH_SCREEN_ALIGN */                                            |            
                                                                                           |            
            if ((x + width)>pwidth)                                                        |            
                width = pwidth - x;                                                        |            
            if ((y + height)>panel_info.vl_row)                                            |            
                height = panel_info.vl_row - y;                                            |            
                                                                                           |            
            bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset);                   |            
            fb   = (uchar *) (lcd_base +                                                   |            
                (y + height - 1) * lcd_line_length + x * bpix / 8);                        |            
                                                                                           |            
            switch (bmp_bpix) {                                                            |            
            case 1: /* pass through */                                                     |            
            case 8:                                                                        |            
                if (bpix != 16)                                                            |            
                    byte_width = width;                                                    |            
                else                                                                       |            
                    byte_width = width * 2;                                                |            
                                                                                           |            
                for (i = 0; i < height; ++i) {                                             |            
                    WATCHDOG_RESET();                                                      |            
                    for (j = 0; j < width; j++) {                                          |            
                        if (bpix != 16) {                                                  |            
        #if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)                            |            
                            *(fb++) = *(bmap++);                                           |            
        #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)                             |            
                            *(fb++) = 255 - *(bmap++);                                     |            
        #endif                                                                             |            
                        } else {                                                           |            
                            *(uint16_t *)fb = cmap_base[*(bmap++)];                        |            
                            fb += sizeof(uint16_t) / sizeof(*fb);                          |            
                        }                                                                  |            
                    }                                                                      |            
                    bmap += (width - padded_line);                                         |            
                    fb   -= (byte_width + lcd_line_length);                                |            
                }                                                                          |            
                break;                                                                     |            
                                                                                           |            
        #if defined(CONFIG_BMP_16BPP)                                                      |            
            case 16:                                                                       |            
                for (i = 0; i < height; ++i) {                                             |            
                    WATCHDOG_RESET();                                                      |            
                    for (j = 0; j < width; j++) {                                          |            
        #if defined(CONFIG_ATMEL_LCD_BGR555)                                               |            
                        *(fb++) = ((bmap[0] & 0x1f) << 2) |                                |            
                            (bmap[1] & 0x03);                                              |            
                        *(fb++) = (bmap[0] & 0xe0) |                                       |            
                            ((bmap[1] & 0x7c) >> 2);                                       |            
                        bmap += 2;                                                         |            
        #else                                                                              |            
                        *(fb++) = *(bmap++);                                               |            
                        *(fb++) = *(bmap++);                                               |            
        #endif                                                                             |            
                    }                                                                      |            
                    bmap += (padded_line - width) * 2;                                     |            
                    fb   -= (width * 2 + lcd_line_length);                                 |            
                }                                                                          |            
                break;                                                                     |            
        #endif /* CONFIG_BMP_16BPP */                                                      |            
        #if defined(CONFIG_BMP_24BPP)                                                      |            
            case 24:                                                                       |            
                if (bpix != 16) {                                                          |            
                    printf("Error: %d bit/pixel mode,"                                     |            
                        "but BMP has %d bit/pixel
    ",                                      |            
                        bpix, bmp_bpix);                                                   |            
                    break;                                                                 |            
                }                                                                          |            
                for (i = 0; i < height; ++i) {                                             |            
                    WATCHDOG_RESET();                                                      |            
                    for (j = 0; j < width; j++) {                                          |            
                        *(uint16_t *)fb = ((*(bmap + 2) << 8) & 0xf800)                    |            
                                | ((*(bmap + 1) << 3) & 0x07e0)                            |            
                                | ((*(bmap) >> 3) & 0x001f);                               |            
                        bmap += 3;                                                         |            
                        fb += sizeof(uint16_t) / sizeof(*fb);                              |            
                    }                                                                      |            
                    bmap += (width - padded_line);                                         |            
                    fb   -= ((2*width) + lcd_line_length);                                 |            
                }                                                                          |            
                break;                                                                     |            
        #endif /* CONFIG_BMP_24BPP */                                                      |            
            default:                                                                       |            
                break;                                                                     |            
            };                                                                             |            
                                                                                           |            
            return (0);                                                                    |            
        }                                                                                  |            
        #endif                                                                             |            
                                                                                           |            
    cat board/freescale/mx6q_sabresd/mx6q_sabresd.c                                        |            
        ......                                                                             |            
        #ifndef CONFIG_MXC_EPDC                                                            |            
        #ifdef CONFIG_LCD                                                                  |            
        void lcd_enable(void)             <------------------------------------------------+            
        {                                                                                               
            char *s;                                                                                    
            int ret;                                                                                    
            unsigned int reg;                                                                           
                                                                                                        
            s = getenv("lvds_num");                                                                     
            di = simple_strtol(s, NULL, 10);                                                            
                                                                                                        
            /*                                                                                          
            * hw_rev 2: IPUV3DEX                                                                        
            * hw_rev 3: IPUV3M                                                                          
            * hw_rev 4: IPUV3H                                                                          
            */                                                                                          
            g_ipu_hw_rev = IPUV3_HW_REV_IPUV3H;                                                         
                                                                                                        
            /**                                                                                         
             * zengjf modify don't show uboot logo                                                      
             */                                                                                         
            imx_pwm_config(pwm0, 25000, 50000);                                                         
            imx_pwm_enable(pwm0);                                                                       
                                                                                                        
        #if defined CONFIG_MX6Q                                                                         
            /* PWM backlight */                                                                         
            mxc_iomux_v3_setup_pad(MX6Q_PAD_SD1_DAT3__PWM1_PWMO);                                       
            /* LVDS panel CABC_EN0 */                                                                   
            //mxc_iomux_v3_setup_pad(MX6Q_PAD_NANDF_CS2__GPIO_6_15);                                    
            /* LVDS panel CABC_EN1 */                                                                   
            //mxc_iomux_v3_setup_pad(MX6Q_PAD_NANDF_CS3__GPIO_6_16);                                    
        #elif defined CONFIG_MX6DL                                                                      
            /* PWM backlight */                                                                         
            mxc_iomux_v3_setup_pad(MX6DL_PAD_SD1_DAT3__PWM1_PWMO);                                      
            /* LVDS panel CABC_EN0 */                                                                   
            //mxc_iomux_v3_setup_pad(MX6DL_PAD_NANDF_CS2__GPIO_6_15);                                   
            /* LVDS panel CABC_EN1 */                                                                   
            //mxc_iomux_v3_setup_pad(MX6DL_PAD_NANDF_CS3__GPIO_6_16);                                   
        #endif                                                                                          
            /*                                                                                          
             * Set LVDS panel CABC_EN0 to low to disable                                                
             * CABC function. This function will turn backlight                                         
             * automatically according to display content, so                                           
             * simply disable it to get rid of annoying unstable                                        
             * backlight phenomena.                                                                     
             */                                                                                         
            /*                                                                                          
            reg = readl(GPIO6_BASE_ADDR + GPIO_GDIR);                                                   
            reg |= (1 << 15);                                                                           
            writel(reg, GPIO6_BASE_ADDR + GPIO_GDIR);                                                   
                                                                                                        
            reg = readl(GPIO6_BASE_ADDR + GPIO_DR);                                                     
            reg &= ~(1 << 15);                                                                          
            writel(reg, GPIO6_BASE_ADDR + GPIO_DR);                                                     
            */                                                                                          
                                                                                                        
            /*                                                                                          
             * Set LVDS panel CABC_EN1 to low to disable                                                
             * CABC function.                                                                           
             */                                                                                         
            /*                                                                                          
            reg = readl(GPIO6_BASE_ADDR + GPIO_GDIR);                                                   
            reg |= (1 << 16);                                                                           
            writel(reg, GPIO6_BASE_ADDR + GPIO_GDIR);                                                   
                                                                                                        
            reg = readl(GPIO6_BASE_ADDR + GPIO_DR);                                                     
            reg &= ~(1 << 16);                                                                          
            writel(reg, GPIO6_BASE_ADDR + GPIO_DR);                                                     
            */                                                                                          
                                                                                                        
            /* Disable ipu1_clk/ipu1_di_clk_x/ldb_dix_clk. */                                           
            reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);                                                  
            reg &= ~0xC033;                                                                             
            writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);                                                  
                                                                                                        
        #if defined CONFIG_MX6Q                                                                         
            /*                                                                                          
             * Align IPU1 HSP clock and IPU1 DIx pixel clock                                            
             * with kernel setting to avoid screen flick when                                           
             * booting into kernel. Developer should change                                             
             * the relevant setting if kernel setting changes.                                          
             * IPU1 HSP clock tree:                                                                     
             * osc_clk(24M)->pll2_528_bus_main_clk(528M)->                                              
             * periph_clk(528M)->mmdc_ch0_axi_clk(528M)->                                               
             * ipu1_clk(264M)                                                                           
             */                                                                                         
            /* pll2_528_bus_main_clk */                                                                 
            /* divider */                                                                               
            writel(0x1, ANATOP_BASE_ADDR + 0x34);                                                       
                                                                                                        
            /* periph_clk */                                                                            
            /* source */                                                                                
            reg = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);                                                  
            reg &= ~(0x3 << 18);                                                                        
            writel(reg, CCM_BASE_ADDR + CLKCTL_CBCMR);                                                  
                                                                                                        
            reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);                                                  
            reg &= ~(0x1 << 25);                                                                        
            writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);                                                  
                                                                                                        
            /*                                                                                          
             * Check PERIPH_CLK_SEL_BUSY in                                                             
             * MXC_CCM_CDHIPR register.                                                                 
             */                                                                                         
            do {                                                                                        
                udelay(5);                                                                              
                reg = readl(CCM_BASE_ADDR + CLKCTL_CDHIPR);                                             
            } while (reg & (0x1 << 5));                                                                 
                                                                                                        
            /* mmdc_ch0_axi_clk */                                                                      
            /* divider */                                                                               
            reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);                                                  
            reg &= ~(0x7 << 19);                                                                        
            writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);                                                  
                                                                                                        
            /*                                                                                          
             * Check MMDC_CH0PODF_BUSY in                                                               
             * MXC_CCM_CDHIPR register.                                                                 
             */                                                                                         
            do {                                                                                        
                udelay(5);                                                                              
                reg = readl(CCM_BASE_ADDR + CLKCTL_CDHIPR);                                             
            } while (reg & (0x1 << 4));                                                                 
                                                                                                        
            /* ipu1_clk */                                                                              
            reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3);                                                 
            /* source */                                                                                
            reg &= ~(0x3 << 9);                                                                         
            /* divider */                                                                               
            reg &= ~(0x7 << 11);                                                                        
            reg |= (0x1 << 11);                                                                         
            writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR3);                                                 
                                                                                                        
            /*                                                                                          
             * ipu1_pixel_clk_x clock tree:                                                             
             * osc_clk(24M)->pll2_528_bus_main_clk(528M)->                                              
             * pll2_pfd_352M(452.57M)->ldb_dix_clk(64.65M)->                                            
             * ipu1_di_clk_x(64.65M)->ipu1_pixel_clk_x(64.65M)                                          
             */                                                                                         
            /* pll2_pfd_352M */                                                                         
            /* disable */                                                                               
            writel(0x1 << 7, ANATOP_BASE_ADDR + 0x104);                                                 
            /* divider */                                                                               
            writel(0x3F, ANATOP_BASE_ADDR + 0x108);                                                     
            writel(0x15, ANATOP_BASE_ADDR + 0x104);                                                     
                                                                                                        
            /* ldb_dix_clk */                                                                           
            /* source */                                                                                
            reg = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR);                                                 
            reg &= ~(0x3F << 9);                                                                        
            reg |= (0x9 << 9);                                                                          
            writel(reg, CCM_BASE_ADDR + CLKCTL_CS2CDR);                                                 
            /* divider */                                                                               
            reg = readl(CCM_BASE_ADDR + CLKCTL_CSCMR2);                                                 
            reg |= (0x3 << 10);                                                                         
            writel(reg, CCM_BASE_ADDR + CLKCTL_CSCMR2);                                                 
                                                                                                        
            /* pll2_pfd_352M */                                                                         
            /* enable after ldb_dix_clk source is set */                                                
            writel(0x1 << 7, ANATOP_BASE_ADDR + 0x108);                                                 
                                                                                                        
            /* ipu1_di_clk_x */                                                                         
            /* source */                                                                                
            reg = readl(CCM_BASE_ADDR + CLKCTL_CHSCCDR);                                                
            reg &= ~0xE07;                                                                              
            reg |= 0x803;                                                                               
            writel(reg, CCM_BASE_ADDR + CLKCTL_CHSCCDR);                                                
        #elif defined CONFIG_MX6DL /* CONFIG_MX6Q */                                                    
            /*                                                                                          
             * IPU1 HSP clock tree:                                                                     
             * osc_clk(24M)->pll3_usb_otg_main_clk(480M)->                                              
             * pll3_pfd_540M(540M)->ipu1_clk(270M)                                                      
             */                                                                                         
            /* pll3_usb_otg_main_clk */                                                                 
            /* divider */                                                                               
            writel(0x3, ANATOP_BASE_ADDR + 0x18);                                                       
                                                                                                        
            /* pll3_pfd_540M */                                                                         
            /* divider */                                                                               
            writel(0x3F << 8, ANATOP_BASE_ADDR + 0xF8);                                                 
            writel(0x10 << 8, ANATOP_BASE_ADDR + 0xF4);                                                 
            /* enable */                                                                                
            writel(0x1 << 15, ANATOP_BASE_ADDR + 0xF8);                                                 
                                                                                                        
            /* ipu1_clk */                                                                              
            reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3);                                                 
            /* source */                                                                                
            reg |= (0x3 << 9);                                                                          
            /* divider */                                                                               
            reg &= ~(0x7 << 11);                                                                        
            reg |= (0x1 << 11);                                                                         
            writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR3);                                                 
                                                                                                        
            /*                                                                                          
             * ipu1_pixel_clk_x clock tree:                                                             
             * osc_clk(24M)->pll2_528_bus_main_clk(528M)->                                              
             * pll2_pfd_352M(452.57M)->ldb_dix_clk(64.65M)->                                            
             * ipu1_di_clk_x(64.65M)->ipu1_pixel_clk_x(64.65M)                                          
             */                                                                                         
            /* pll2_528_bus_main_clk */                                                                 
            /* divider */                                                                               
            writel(0x1, ANATOP_BASE_ADDR + 0x34);                                                       
                                                                                                        
            /* pll2_pfd_352M */                                                                         
            /* disable */                                                                               
            writel(0x1 << 7, ANATOP_BASE_ADDR + 0x104);                                                 
            /* divider */                                                                               
            writel(0x3F, ANATOP_BASE_ADDR + 0x108);                                                     
            writel(0x15, ANATOP_BASE_ADDR + 0x104);                                                     
                                                                                                        
            /* ldb_dix_clk */                                                                           
            /* source */                                                                                
            reg = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR);                                                 
            reg &= ~(0x3F << 9);                                                                        
            reg |= (0x9 << 9);                                                                          
            writel(reg, CCM_BASE_ADDR + CLKCTL_CS2CDR);                                                 
            /* divider */                                                                               
            reg = readl(CCM_BASE_ADDR + CLKCTL_CSCMR2);                                                 
            reg |= (0x3 << 10);                                                                         
            writel(reg, CCM_BASE_ADDR + CLKCTL_CSCMR2);                                                 
                                                                                                        
            /* pll2_pfd_352M */                                                                         
            /* enable after ldb_dix_clk source is set */                                                
            writel(0x1 << 7, ANATOP_BASE_ADDR + 0x108);                                                 
                                                                                                        
            /* ipu1_di_clk_x */                                                                         
            /* source */                                                                                
            reg = readl(CCM_BASE_ADDR + CLKCTL_CHSCCDR);                                                
            reg &= ~0xE07;                                                                              
            reg |= 0x803;                                                                               
            writel(reg, CCM_BASE_ADDR + CLKCTL_CHSCCDR);                                                
        #endif    /* CONFIG_MX6DL */                                                                    
                                                                                                        
            /* Enable ipu1/ipu1_dix/ldb_dix clocks. */                                                  
            if (di == 1) {                                                                              
                reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);                                              
                reg |= 0xC033;                                                                          
                writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);                                              
            } else {                                                                                    
                reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);                                              
                reg |= 0x300F;                                                                          
                writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);                                              
            }                                                                                           
                                                                                                        
            /**                                                                                         
             * zengjf 2015-7-23 modify to 24bit or 16bit                                                
             *                                                                                          
             * #define IPU_PIX_FMT_BGR24   fourcc('B', 'G', 'R', '3')    /*< 24  BGR-8-8-8 */           
             * #define IPU_PIX_FMT_RGB24   fourcc('R', 'G', 'B', '3')    /*< 24  RGB-8-8-8 */           
             */                                                                                         
            //ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB666,                                    
            //ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB24,                                     
            ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB24,    ---------+                         
                    DI_PCLK_LDB, 65000000);                                   |                         
            if (ret)                                                          |                         
                puts("LCD cannot be configured
    ");                           |                         
                                                                              |                         
            /*                                                                |                         
             * LVDS0 mux to IPU1 DI0.                                         |                         
             * LVDS1 mux to IPU1 DI1.                                         |                         
             */                                                               |                         
            reg = readl(IOMUXC_BASE_ADDR + 0xC);                              |                         
            reg &= ~(0x000003C0);                                             |                         
            reg |= 0x00000100;                                                |                         
            writel(reg, IOMUXC_BASE_ADDR + 0xC);                              |                         
                                                                              |                         
            if (di == 1)                                                      |                         
                writel(0x40C, IOMUXC_BASE_ADDR + 0x8);                        |                         
            else                                                              |                         
                writel(0x201, IOMUXC_BASE_ADDR + 0x8);                        |                         
        }                                                                     |                         
        #endif                                                                |                         
                                                                              |                         
    cat drivers/video/mxc_ipuv3_fb.c                                          V                         
        int ipuv3_fb_init(struct fb_videomode *mode, int di, int interface_pix_fmt,                     
                  ipu_di_clk_parent_t di_clk_parent, int di_clk_val)          |                         
        {                                                                     |                         
            int ret;                                                          |                         
                                                                              |                         
            ret = ipu_probe(di, di_clk_parent, di_clk_val);                   |                         
            if (ret)                                                          |                         
                puts("Error initializing IPU
    ");                             |                         
                                                                              |                         
            debug("Framebuffer at 0x%x
    ", (unsigned int)lcd_base);           |                         
            ret = mxcfb_probe(interface_pix_fmt, mode, di);                   |                         
                                              |                               |                         
            return ret;                       |                               |                         
        }                                     +-------------------------------+                         
                                              |                                                         
    cat drivers/video/mxc_ipuv3_fb.c          v                                                         
        static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode, int di)                
        {                                     |                                                         
            struct fb_info *fbi;              |                                                         
            struct mxcfb_info *mxcfbi;        |                                                         
            int ret = 0;                      |                                                         
                                              +----------------------------------+                      
            /*                                                                   |                      
             * Initialize FB structures                                          |                      
             */                                                                  |                      
            fbi = mxcfb_init_fbinfo();                                           |                      
            if (!fbi) {                                                          |                      
                ret = -ENOMEM;                                                   |                      
                goto err0;                                                       |                      
            }                                                                    |                      
            mxcfbi = (struct mxcfb_info *)fbi->par;                              |                      
                                                                                 |                      
            if (!g_dp_in_use) {                                                  |                      
                mxcfbi->ipu_ch = MEM_BG_SYNC;                                    |                      
                mxcfbi->blank = FB_BLANK_UNBLANK;                                |                      
            } else {                                                             |                      
                mxcfbi->ipu_ch = MEM_DC_SYNC;                                    |                      
                mxcfbi->blank = FB_BLANK_POWERDOWN;                              |                      
            }                                                                    |                      
                                                                                 |                      
            mxcfbi->ipu_di = di;                                                 |                      
                                                                                 |                      
            ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80);                  |                      
            ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0);                        |                      
            strcpy(fbi->fix.id, "DISP3 BG");                                     |                      
                                                                                 |                      
            g_dp_in_use = 1;                                                     |                      
                                                                                 |                      
            mxcfb_info[mxcfbi->ipu_di] = fbi;                                    |                      
                                                                                 |                      
            /* Need dummy values until real panel is configured */               |                      
            fbi->var.xres = 640;                                                 |                      
            fbi->var.yres = 480;                                                 |                      
            /**                                                                  |                      
             * zengjf 2015-8-23 modify to 24bit display, it can't work well      |                      
             */                                                                  |                      
            fbi->var.bits_per_pixel = 16;                                        |                      
            //fbi->var.bits_per_pixel = 24;                                      |                      
                                                                                 |                      
            mxcfbi->ipu_di_pix_fmt = interface_pix_fmt;   <----------------------+                      
            fb_videomode_to_var(&fbi->var, mode);                                                       
                                                                                                        
            mxcfb_check_var(&fbi->var, fbi);                                                            
                                                                                                        
            /* Default Y virtual size is 2x panel size */                                               
            fbi->var.yres_virtual = fbi->var.yres * 2;                                                  
                                                                                                        
            mxcfb_set_fix(fbi);                                                                         
                                                                                                        
            /* alocate fb first */                                                                      
            if (mxcfb_map_video_memory(fbi) < 0)                                                        
                return -ENOMEM;                                                                         
                                                                                                        
            mxcfb_set_par(fbi);                  -------------------------------------+                 
                                                                                      |                 
            /* Setting panel_info for lcd */                                          |                 
            panel_info.vl_col = fbi->var.xres;                                        |                 
            panel_info.vl_row = fbi->var.yres;                                        |                 
            panel_info.vl_bpix = LCD_BPP;   // this same can't wake well   ---------+ |                 
                                                                                    | |                 
            lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;  | |                 
                                                                                    | |                 
            debug("MXC IPUV3 configured
    "                                          | |                 
                "XRES = %d YRES = %d BitsXpixel = %d
    ",                            | |                 
                panel_info.vl_col,                                                  | |                 
                panel_info.vl_row,                                                  | |                 
                panel_info.vl_bpix);                                                | |                 
                                                                                    | |                 
            ipu_dump_registers();                                                   | |                 
                                                                                    | |                 
            return 0;                                                               | |                 
                                                                                    | |                 
        err0:                                                                       | |                 
            return ret;                                                             | |                 
        }                                                                           | |                 
                                                                                    | |                 
    cat include/configs/mx6dl_sabresd.h                                             | |                 
        #define LCD_BPP        LCD_COLOR16           <------------------------------+ |                 
                                       |                                              |                 
    cat include/lcd.h                  |                                              |                 
        #define LCD_MONOCHROME    0    +----------+                                   |                 
        #define LCD_COLOR2        1               |                                   |                 
        #define LCD_COLOR4        2               |                                   |                 
        #define LCD_COLOR8        3               |                                   |                 
        #define LCD_COLOR16       4    <----------+                                   |                 
                                                                                      |                 
    cat drivers/video/mxc_ipuv3_fb.c                                                  |                 
        static int mxcfb_set_par(struct fb_info *fbi)          <----------------------+                 
        {                                                                                               
            int retval = 0;                                                                             
            u32 mem_len;                                                                                
            ipu_di_signal_cfg_t sig_cfg;                                                                
            struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;                                 
            uint32_t out_pixel_fmt;                                                                     
                                                                                                        
            ipu_disable_channel(mxc_fbi->ipu_ch);                                                       
            ipu_uninit_channel(mxc_fbi->ipu_ch);                                                        
            mxcfb_set_fix(fbi);                                                                         
                                                                                                        
            mem_len = fbi->var.yres_virtual * fbi->fix.line_length;                                     
            if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {                                
                if (fbi->fix.smem_start)                                                                
                    mxcfb_unmap_video_memory(fbi);                                                      
                                                                                                        
                if (mxcfb_map_video_memory(fbi) < 0)                                                    
                    return -ENOMEM;                                                                     
            }                                                                                           
                                                                                                        
            setup_disp_channel1(fbi);                                                                   
                                                                                                        
            memset(&sig_cfg, 0, sizeof(sig_cfg));                                                       
            if (fbi->var.vmode & FB_VMODE_INTERLACED) {                                                 
                sig_cfg.interlaced = 1;                                                                 
                out_pixel_fmt = IPU_PIX_FMT_YUV444;                                                     
            } else {                                                                                    
                if (mxc_fbi->ipu_di_pix_fmt) {                                                          
                    out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;                                            
                    debug(" zengjf1 %d. 
    ", out_pixel_fmt);                                            
                }                                                                                       
                else                                                                                    
                {                                                                                       
                    out_pixel_fmt = IPU_PIX_FMT_RGB666;                                                 
                    debug(" zengjf2 %d. 
    ", out_pixel_fmt);                                            
                }                                                                                       
            }                                                                                           
            if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */                                      
                sig_cfg.odd_field_first = 1;                                                            
            if ((fbi->var.sync & FB_SYNC_EXT) || ext_clk_used)                                          
                sig_cfg.ext_clk = 1;                                                                    
            if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)                                                   
                sig_cfg.Hsync_pol = 1;                                                                  
            if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)                                                  
                sig_cfg.Vsync_pol = 1;                                                                  
            if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))                                                
                sig_cfg.clk_pol = 1;                                                                    
            if (fbi->var.sync & FB_SYNC_DATA_INVERT)                                                    
                sig_cfg.data_pol = 1;                                                                   
            if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))                                                  
                sig_cfg.enable_pol = 1;                                                                 
            if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)                                                    
                sig_cfg.clkidle_en = 1;                                                                 
                                                                                                        
            debug("zengjf pixclock = %d 
    ", fbi->var.pixclock);                                        
            debug("pixclock = %ul Hz
    ", (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));                
            debug("bpp_to_pixfmt: %d
    ", fbi->var.bits_per_pixel);                                      
                                                                                                        
            if (ipu_init_sync_panel(mxc_fbi->ipu_di,                                                    
                        (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,                                        
                        fbi->var.xres, fbi->var.yres,                                                   
                        out_pixel_fmt,                                                                  
                        fbi->var.left_margin,                                                           
                        fbi->var.hsync_len,                                                             
                        fbi->var.right_margin,                                                          
                        fbi->var.upper_margin,                                                          
                        fbi->var.vsync_len,                                                             
                        fbi->var.lower_margin,                                                          
                        0, sig_cfg) != 0) {                                                             
                puts("mxcfb: Error initializing panel.
    ");                                             
                return -EINVAL;                                                                         
            }                                                                                           
                                                                                                        
            retval = setup_disp_channel2(fbi);        --------------------+                             
            if (retval)                                                   |                             
                return retval;                                            |                             
                                                                          |                             
            if (mxc_fbi->blank == FB_BLANK_UNBLANK)                       |                             
                ipu_enable_channel(mxc_fbi->ipu_ch);                      |                             
                                                                          |                             
            return retval;                                                |                             
        }                                                                 |                             
                                                                          |                             
    cat drivers/video/mxc_ipuv3_fb.c                                      |                             
        static int setup_disp_channel2(struct fb_info *fbi)    <----------+                             
        {                                                                                               
            int retval = 0;                                                                             
            struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;                                 
                                                                                                        
            mxc_fbi->cur_ipu_buf = 1;                                                                   
            if (mxc_fbi->alpha_chan_en)                                                                 
                mxc_fbi->cur_ipu_alpha_buf = 1;                                                         
                                                                                                        
            fbi->var.xoffset = fbi->var.yoffset = 0;                                                    
                                                                                                        
            debug("%s: ipu_ch{%x} xres{%d} yres{%d} line_length{%d} smem_start{%lx} smem_end{%lx}
    ",   
                __func__,                                                                               
                mxc_fbi->ipu_ch,                                                                        
                fbi->var.xres,                                                                          
                fbi->var.yres,                                                                          
                fbi->fix.line_length,                                                                   
                fbi->fix.smem_start,                                                                    
                fbi->fix.smem_start +                                                                   
                (fbi->fix.line_length * fbi->var.yres));                                                
                                                                                                        
            retval = ipu_init_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,                         
                             bpp_to_pixfmt(fbi),               --------------------+                    
                             fbi->var.xres, fbi->var.yres,                         |                    
                             fbi->fix.line_length,                                 |                    
                             fbi->fix.smem_start +                                 |                    
                             (fbi->fix.line_length * fbi->var.yres),               |                    
                             fbi->fix.smem_start,                                  |                    
                             0, 0);                                                |                    
            if (retval)                                                            |                    
                printf("ipu_init_channel_buffer error %d
    ", retval);              |                    
                                                                                   |                    
            return retval;                                                         |                    
        }                                                                          |                    
                                                                                   |                    
    cat drivers/video/mxc_ipuv3_fb.c                                               |                    
        static uint32_t bpp_to_pixfmt(struct fb_info *fbi)     <-------------------+                    
        {                                                                                               
            uint32_t pixfmt = 0;                                                                        
                                                                                                        
            debug("bpp_to_pixfmt: %d
    ", fbi->var.bits_per_pixel);                                      
                                                                                                        
            if (fbi->var.nonstd)                                                                        
                return fbi->var.nonstd;                                                                 
                                                                                                        
            switch (fbi->var.bits_per_pixel) {                                                          
            case 24:                                                                                    
                pixfmt = IPU_PIX_FMT_BGR24;                                                             
                break;                                                                                  
            case 32:                                                                                    
                pixfmt = IPU_PIX_FMT_BGR32;                                                             
                break;                                                                                  
            case 16:                                                                                    
                pixfmt = IPU_PIX_FMT_RGB565;                                                            
                break;                                                                                  
            }                                                                                           
            return pixfmt;                                                                              
        }                                                                                               
  • 相关阅读:
    Oracle安装
    自动化测试开发
    Hyperf 接入阿里云ACM应用配置管理中心
    PHP redis有序集合实现分页
    虚拟现实与大数据
    树形数据结构化
    立即执行函数
    jQuery中的显示与隐藏
    jQuery中的HTML
    Django+Nginx配置+前后端交互
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/4861098.html
Copyright © 2020-2023  润新知