zoukankan      html  css  js  c++  java
  • imx6 uboot lcd

    本文记录imx6 uboot中关于lcd初始化的过程。

    uboot中相关的文件:

      cpu/arm_cortexa8/start.S

      lib_arm/board.c

      board/freescale/mx6q_sabresd/mx6q_sabresd.c

      common/stdio.c

      common/lcd.c

      drivers/video/ipu_common.c

    /* 汇编调用C语言 */
    ./cpu/arm_cortexa8/start.S:
    
    ldr    pc, _start_armboot    @ jump to C code         ------+
                                                                |
    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);                     |
                                                                                      |
                                                                                      |
        stdio_init ();    /* get the devices list going. */     ------------------+   |
                                                                                  |   |
        jumptable_init ();                                                        |   |
                                                                                  |   |
        ......                                                                    |   |
                                                                                  |   |
        for (;;) {                                                                |   |
            main_loop ();                                                         |   |
        }                                                                         |   |
                                                                                  |   |
        /* NOTREACHED - no way out of command loop except booting */              |   |
    }                                                                             |   |
                                                                                  |   |
    init_fnc_t *init_sequence[] = {                                       <-------|---+
    #if defined(CONFIG_ARCH_CPU_INIT)                                             |
        arch_cpu_init,        /* basic arch cpu dependent setup */                |
    #endif                                                                        |
        board_init,        /* basic board dependent setup */     -------------+   |
    #if defined(CONFIG_USE_IRQ)                                               |   |
        interrupt_init,        /* set up exceptions */                        |   |
    #endif                                                                    |   |
        timer_init,        /* initialize timer */                             |   |
        env_init,        /* initialize environment */                         |   |
        init_baudrate,        /* initialze baudrate settings */               |   |
        serial_init,        /* serial communications setup */                 |   |
        console_init_f,        /* stage 1 init of console */                  |   |
        display_banner,        /* say that we are here */                     |   |
    #if defined(CONFIG_DISPLAY_CPUINFO)                                       |   |
        print_cpuinfo,        /* display cpu info (and speed) */              |   |
    #endif                                                                    |   |
    #if defined(CONFIG_DISPLAY_BOARDINFO)                                     |   |
        checkboard,        /* display board info */                           |   |
    #endif                                                                    |   |
    #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)                  |   |
        init_func_i2c,                                                        |   |
    #endif                                                                    |   |
        dram_init,        /* configure available RAM banks */                 |   |
    #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)                       |   |
        arm_pci_init,                                                         |   |
    #endif                                                                    |   |
        display_dram_config,                                                  |   |
        NULL,                                                                 |   |
    };                                                                        |   |
                                                                              |   |
    board/freescale/mx6q_sabresd/mx6q_sabresd.c                               |   |
    int board_init(void)                                   <------------------+   |
    {                                                                             |
    /* need set Power Supply Glitch to 0x41736166                                 |
    *and need clear Power supply Glitch Detect bit                                |
    * when POR or reboot or power on Otherwise system                             |
    *could not be power off anymore*/                                             |
        u32 reg;                                                                  |
        writel(0x41736166, SNVS_BASE_ADDR + 0x64);/*set LPPGDR*/                  |
        udelay(10);                                                               |
        reg = readl(SNVS_BASE_ADDR + 0x4c);                                       |
        reg |= (1 << 3);                                                          |
        writel(reg, SNVS_BASE_ADDR + 0x4c);/*clear LPSR*/                         |
                                                                                  |
        mxc_iomux_v3_init((void *)IOMUXC_BASE_ADDR);                              |
        setup_boot_device();                                                      |
        fsl_set_system_rev();                                                     |
                                                                                  |
        /* board id for linux */                                                  |
        gd->bd->bi_arch_number = MACH_TYPE_MX6Q_SABRESD;                          |
                                                                                  |
        /* address of boot parameters */                                          |
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;                            |
                                                                                  |
        setup_uart();                                                             |
    #ifdef CONFIG_DWC_AHSATA                                                      |
        if (cpu_is_mx6q())                                                        |
            setup_sata();                                                         |
    #endif                                                                        |
                                                                                  |
    #ifdef CONFIG_VIDEO_MX5                                                       |
        /* Enable lvds power */                                                   |
    #ifdef UBOOT_SHOW_LOGO                                                        |
        setup_lvds_poweron();                                                     |
    #endif                                                                        |
        panel_info_init();                                                        |
                                                                                  |
        gd->fb_base = CONFIG_FB_BASE;                                             |
    #ifdef CONFIG_ARCH_MMU                                                        |
        gd->fb_base = ioremap_nocache(iomem_to_phys(gd->fb_base), 0);             |
    #endif                                                                        |
    #endif                                                                        |
                                                                                  |
    #ifdef CONFIG_NAND_GPMI                                                       |
    //    setup_gpmi_nand();                                                      |
    #endif                                                                        |
                                                                                  |
    #if defined(CONFIG_ENET_RMII) && !defined(CONFIG_DWC_AHSATA)                  |
        setup_fec();                                                              |
    #endif                                                                        |
                                                                                  |
    #ifdef CONFIG_MXC_EPDC                                                        |
        setup_epdc();                                                             |
    #endif                                                                        |
        return 0;                                                                 |
    }                                                                             |
                                                                                  |
    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);                                               |
    }                                                             |
                                                                  |
    common/lcd.c                                                  |
    int drv_lcd_init (void)               <-----------------------+
    {
        struct stdio_dev lcddev;
        int rc;
        //framebuffer基地址
        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);    //将lcd设备添加到uboot的设备链表中                 |
                                                                                             |
        return (rc == 0) ? 1 : rc;                                                           |
    }                                                                                        |
                                                                                             |
    #define    NBITS(type)    (sizeof(type) * 8)                                             |
                                                                                             |
    board/freescale/mx6q_sabresd/mx6q_sabresd.c                                              |
    vidinfo_t panel_info = {                                                                 |
        .vl_refresh = 85,                                                                    |
        .vl_col = 800,                                                                       |
        .vl_row = 600,                                                                       |
        .vl_pixclock = 26666667,                                                             |
        .vl_left_margin = 8,                                                                 |
        .vl_right_margin = 100,                                                              |
        .vl_upper_margin = 4,                                                                |
        .vl_lower_margin = 8,                                                                |
        .vl_hsync = 4,                                                                       |
        .vl_vsync = 1,                                                                       |
        .vl_sync = 0,                                                                        |
        .vl_mode = 0,                                                                        |
        .vl_flag = 0,                                                                        |
        .vl_bpix = 3,                                                                        |
        cmap:0,                                                                              |
    };                                                                                       |
    typedef struct vidinfo {                                                                 |
        ushort    vl_col;        /* Number of columns (i.e. 640) */                          |
        ushort    vl_row;        /* Number of rows (i.e. 480) */                             |
        ushort    vl_width;    /* Width of display area in millimeters */                    |
        ushort    vl_height;    /* Height of display area in millimeters */                  |
                                                                                             |
        /* LCD configuration register */                                                     |
        u_char    vl_clkp;    /* Clock polarity */                                           |
        u_char    vl_oep;        /* Output Enable polarity */                                |
        u_char    vl_hsp;        /* Horizontal Sync polarity */                              |
        u_char    vl_vsp;        /* Vertical Sync polarity */                                |
        u_char    vl_dp;        /* Data polarity */                                          |
        u_char    vl_bpix;    /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */       |
        u_char    vl_lbw;        /* LCD Bus width, 0 = 4, 1 = 8 */                           |
        u_char    vl_splt;    /* Split display, 0 = single-scan, 1 = dual-scan */            |
        u_char    vl_clor;    /* Color, 0 = mono, 1 = color */                               |
        u_char    vl_tft;        /* 0 = passive, 1 = TFT */                                  |
                                                                                             |
        /* Horizontal control register. Timing from data sheet */                            |
        ushort    vl_hpw;        /* Horz sync pulse width */                                 |
        u_char    vl_blw;        /* Wait before of line */                                   |
        u_char    vl_elw;        /* Wait end of line */                                      |
                                                                                             |
        /* Vertical control register. */                                                     |
        u_char    vl_vpw;        /* Vertical sync pulse width */                             |
        u_char    vl_bfw;        /* Wait before of frame */                                  |
        u_char    vl_efw;        /* Wait end of frame */                                     |
                                                                                             |
        /* PXA LCD controller params */                                                      |
        struct    pxafb_info pxa;                                                            |
    } vidinfo_t;                                                                             |
                                                                                             |
    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;                                                                      |    |
    }                                                                                  |    |
                                                                                       |    |
    void lcd_ctrl_init(void *lcdbase)                                                  |    |
    {                                                                                  |    |
        //计算要使用的framebuffer大小 col*row*bpp/8 字节                               |    |
        u32 mem_len = panel_info.vl_col *                                              |    |
            panel_info.vl_row *                                                        |    |
            NBITS(panel_info.vl_bpix) / 8;                                             |    |
                                                                                       |    |
        /*                                                                             |    |
         * We rely on lcdbase being a physical address, i.e., either MMU off,          |    |
         * or 1-to-1 mapping. Might want to add some virt2phys here.                   |    |
         */                                                                            |    |
        if (!lcdbase)                                                                  |    |
            return;                                                                    |    |
        //将framebuffer清0                                                             |    |
        memset(lcdbase, 0, mem_len);                                                   |    |
    }                                                                                  |    |
                                                                                       |    |
    common/lcd.c                                                                       |    |
    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);                                        |                                |
    }                                                      |                                |
    //显示logo                                             |                                |
    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, 地址转为16进制                                        |
            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                                                                                  |
                                                                                            |
            //显示logo,根据x,y坐标                                                          |
            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 */                  |          |
    }                                                                            |          |
                                                                                 |          |
    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                                                                                  |
                                                                                            |
    #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                                                                                  |
                                                                                            |
    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;
    
    #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
        imx_pwm_config(pwm0, 25000, 50000);
        imx_pwm_enable(pwm0);
    
        mxc_iomux_v3_setup_pad(MX6DL_PAD_SD1_DAT2__GPIO_1_19);
        reg = readl(GPIO1_BASE_ADDR + GPIO_GDIR);
        reg |= (1 << 19);
        writel(reg, GPIO1_BASE_ADDR + GPIO_GDIR);
    
        reg = readl(GPIO1_BASE_ADDR + GPIO_DR);
    #ifdef UBOOT_SHOW_LOGO
        reg |= (1 << 19);
    #else
        reg &= ~(1 << 19);
    #endif
        writel(reg, GPIO1_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);
    
    #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 */
        // 20C_403C
        reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3);
        /* source */
        //ipu1_hsp_clk_sel
        reg |= (0x3 << 9);
        /* divider */
        reg &= ~(0x7 << 11);
        reg |= (0x1 << 11);
        //540M/2 = 270M
        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 */
        writel(0x1, ANATOP_BASE_ADDR + 0x34);
    
        /* pll2_pfd_352M */
        writel(0x1 << 7, ANATOP_BASE_ADDR + 0x104);
        /* divider */
        writel(0x3F, ANATOP_BASE_ADDR + 0x108);
        //This field controls the fractional divide value. The resulting frequency shall be 480*18/PFD0_FRAC where
        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);
        }
        ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB666, DI_PCLK_LDB, 65000000); //18 bit -----+
        //ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB24, DI_PCLK_LDB, 65000000);  //24 bit    |
                                                          |            |                             |
        if (ret)                                          |            |                             |
            puts("LCD cannot be configured 
    ");          +--------------------+                     |
                                                                       |       |                     |
    #ifdef I2C_GPIO_EEPROM_PROCESS        //WRITE process              |       |                     |
                //write singal byte                                    |       |                     |
    #if 1                                                              |       |                     |
            {                                                          |       |                     |
                Load_config_from_mmc();                                |       |                     |
            }                                                          |       |                     |
    #endif                                                             |       |                     |
    #endif                                                             |       |                     |
                                                                       |       |                     |
        /*                                                             |       |                     |
         * LVDS0 mux to IPU1 DI0.                                      |       |                     |
         * LVDS1 mux to IPU1 DI1.                                      |       |                     |
         */                                                            |       |                     |
    #ifdef UBOOT_SHOW_LOGO                                             |       |                     |
        reg = readl(IOMUXC_BASE_ADDR + 0xC);                           |       |                     |
        reg &= ~(0x000003C0);                                          |       |                     |
        reg |= 0x00000100;                                             |       |                     |
        writel(reg, IOMUXC_BASE_ADDR + 0xC);                           |       |                     |
    #endif                                                             |       |                     |
        if (di == 1)                                                   |       |                     |
        {                                                              |       |                     |
            writel(0x40C, IOMUXC_BASE_ADDR + 0x8);//18BIT              |       |                     |
            //writel(0x48C, IOMUXC_BASE_ADDR + 0x8);//24BIT            |       |                     |
        }                                                              |       |                     |
        else                                                           |       |                     |
        {                                                              |       |                     |
            writel(0x201, IOMUXC_BASE_ADDR + 0x8);//18BIT              |       |                     |
            //writel(0x221, IOMUXC_BASE_ADDR + 0x8);//24BIT            |       |                     |
        }                                                              |       |                     |
        ......                                                         |       |
    }                                                                  |       |                     |
    #endif                                                             |       |                     |
                                                                       |       |                     |
                                                                       |       |                     |
    include/ipu.h                                                      |       |                     |
    typedef enum {                                                     |       |                     |
        DI_PCLK_PLL3,                                                  |       |                     |
        DI_PCLK_LDB,                               <-------------------+       |                     |
        DI_PCLK_TVE                                                            |                     |
    } ipu_di_clk_parent_t;                                                     |                     |
                                                                               V                     |
    #define IPU_PIX_FMT_RGB666  fourcc('R', 'G', 'B', '6')    /*< 18  RGB-6-6-6    */                |
    #define IPU_PIX_FMT_RGB24   fourcc('R', 'G', 'B', '3')    /*< 24  RGB-8-8-8    */                |
                                                                                                     |
    #define fourcc(a, b, c, d)                                                                      |
        (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))                          |
                                                                                                     |
    drivers/video/mxc_ipuv3_fb.c                                                                     |
    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;                                                                            |   |
    }                                                                                          |   |
                                                                                               |   |
    drivers/video/ipu_common.c                                                                 |   |
    int ipu_probe(int di, ipu_di_clk_parent_t di_clk_parent, int di_clk_val)          <--------+   |
    {                                                                                              |
        unsigned long ipu_base;                                                                    |
                                                                                                   |
    #if defined(CONFIG_MXC_HSC)                                                                    |
        u32 temp;                                                                                  |
        u32 *reg_hsc_mcd = (u32 *)MIPI_HSC_BASE_ADDR;                                              |
        u32 *reg_hsc_mxt_conf = (u32 *)(MIPI_HSC_BASE_ADDR + 0x800);                               |
                                                                                                   |
         __raw_writel(0xF00, reg_hsc_mcd);                                                         |
                                                                                                   |
        /* CSI mode reserved*/                                                                     |
        temp = __raw_readl(reg_hsc_mxt_conf);                                                      |
         __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf);                                             |
                                                                                                   |
        temp = __raw_readl(reg_hsc_mxt_conf);                                                      |
        __raw_writel(temp | 0x10000, reg_hsc_mxt_conf);                                            |
    #endif                                                                                         |
                                                                                                   |
        ipu_base = IPU_CTRL_BASE_ADDR;                                                             |
        /* base fixup */                                                                           |
        if (g_ipu_hw_rev == IPUV3_HW_REV_IPUV3H)    /* IPUv3H */                                   |
            ipu_base += IPUV3H_REG_BASE;                                                           |
        else if (g_ipu_hw_rev == IPUV3_HW_REV_IPUV3M)    /* IPUv3M */                              |
            ipu_base += IPUV3M_REG_BASE;                                                           |
        else            /* IPUv3D, v3E, v3EX */                                                    |
            ipu_base += IPUV3DEX_REG_BASE;                                                         |
        ipu_cpmem_base = (u32 *)(ipu_base + IPU_CPMEM_REG_BASE);                                   |
        ipu_dc_tmpl_reg = (u32 *)(ipu_base + IPU_DC_TMPL_REG_BASE);                                |
                                                                                                   |
        g_pixel_clk[0] = &pixel_clk[0];                                                            |
        g_pixel_clk[1] = &pixel_clk[1];                                                            |
                                                                                                   |
        g_di_clk[0] = &di_clk[0];                                                                  |
        g_di_clk[1] = &di_clk[1];                                                                  |
        g_di_clk[di]->rate = di_clk_val;                                                           |
                                                                                                   |
        g_ipu_clk = &ipu_clk;                                                                      |
        debug("ipu_clk = %u
    ", clk_get_rate(g_ipu_clk));                                          |
                                                                                                   |
        ipu_reset();                                                                               |
                                                                                                   |
        if (di_clk_parent == DI_PCLK_LDB) {                                                        |
            clk_set_parent(g_pixel_clk[di], g_di_clk[di]);                                         |
        } else {                                                                                   |
            clk_set_parent(g_pixel_clk[0], g_ipu_clk);                                             |
            clk_set_parent(g_pixel_clk[1], g_ipu_clk);                                             |
        }                                                                                          |
                                                                                                   |
        clk_enable(g_ipu_clk);                                                                     |
                                                                                                   |
        __raw_writel(0x807FFFFF, IPU_MEM_RST);                                                     |
        while (__raw_readl(IPU_MEM_RST) & 0x80000000)                                              |
            ;                                                                                      |
                                                                                                   |
        ipu_init_dc_mappings();                                                                    |
                                                                                                   |
        __raw_writel(0, IPU_INT_CTRL(5));                                                          |
        __raw_writel(0, IPU_INT_CTRL(6));                                                          |
        __raw_writel(0, IPU_INT_CTRL(9));                                                          |
        __raw_writel(0, IPU_INT_CTRL(10));                                                         |
                                                                                                   |
        /* DMFC Init */                                                                            |
        ipu_dmfc_init(DMFC_NORMAL, 1);                                                             |
                                                                                                   |
        /* Set sync refresh channels as high priority */                                           |
        __raw_writel(0x18800000L, IDMAC_CHA_PRI(0));                                               |
                                                                                                   |
        /* Set MCU_T to divide MCU access window into 2 */                                         |
        __raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN);                       |
                                                                                                   |
        clk_disable(g_ipu_clk);                                                                    |
                                                                                                   |
        return 0;                                                                                  |
    }                                                                                              |
                                                                                                   |
    /*                                                                                             |
     * Probe routine for the framebuffer driver. It is called during the                           |
     * driver binding process.      The following functions are performed in                       |
     * this routine: Framebuffer initialization, Memory allocation and                             |
     * mapping, Framebuffer registration, IPU initialization.                                      |
     *                                                                                             |
     * @return      Appropriate error code to the kernel common code                               |
     */                                                                                            |
    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;
    
        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;
    
        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;
    }
    
    Author

    Tony Liu

    2016-8-23, Shenzhen

  • 相关阅读:
    Springboot演示小Demo
    快速构建一个 Springboot
    javase练习题--每天写写
    javase练习题
    WebDriver API——延时操作及元素等待
    WebDriver API——javascript的相关操作
    Jenkins安装部署及tomcat的入门介绍
    WebDriver API——鼠标及键盘操作Actions
    sql查询练习
    睡前反省,絮叨絮叨
  • 原文地址:https://www.cnblogs.com/helloworldtoyou/p/5798930.html
Copyright © 2011-2022 走看看