博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
imx6 uboot lcd
阅读量:6483 次
发布时间:2019-06-23

本文共 70265 字,大约阅读时间需要 234 分钟。

本文记录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\n", 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...\n");                                              |    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\0"                                               |    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\0"                                                    |        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\n", 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\n",                 |            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\n",                 |            bpix,                                                                       |            le16_to_cpu(bmp->header.bit_count));                                        |        return 1;                                                                       |    }                                                                                   |                                                                                        |    debug ("Display-bmp: %d x %d  with %d colors\n",                                    |        (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
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\n", | 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 \n"); +--------------------+ | | | |#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\n"); | | debug("Framebuffer at 0x%x\n", (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\n", 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\n" "XRES = %d YRES = %d BitsXpixel = %d\n", 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

转载地址:http://gafuo.baihongyu.com/

你可能感兴趣的文章
memcache数据库和redis数据库的区别(理论)
查看>>
第三十九天
查看>>
论程序员加班的害处
查看>>
基于HTML5的WebGL设计汉诺塔3D游戏
查看>>
WPF资料链接
查看>>
再次更新
查看>>
利用Windows自带的Certutil查看文件MD5
查看>>
开篇,博客的申请理由
查看>>
[JSOI2008]星球大战starwar BZOJ1015
查看>>
IntelliJ IDEA 注册码
查看>>
String字符串的截取
查看>>
Shell编程-环境变量配置文件
查看>>
Struts2和Spring MVC的区别
查看>>
git代码冲突
查看>>
git bash 风格调整
查看>>
HDOJ-1010 Tempter of the Bone
查看>>
日本开设无人机专业,打造无人机“人才市场”
查看>>
190行代码实现mvvm模式
查看>>
兼容几乎所有浏览器的透明背景效果
查看>>
Linux VNC server的安装及简单配置使用
查看>>