您的位置:首页 > 其它

I.MX6 U-boot lvds display hacking

2015-10-08 15:02 537 查看
/***********************************************************************************
*                    I.MX6 U-boot lvds display hacking
* 声明:
*   本文主要是为了跟踪I.MX6中的U-boot中显示部分代码,查看是否支持24bit显示。
*
*                                           2015-10-8 晴 深圳 南山平山村 曾剑锋
**********************************************************************************/

cat cpu/arm_cortexa8/start.S
.globl _start
_start: b   reset          ---------------------------+
ldr pc, _undefined_instruction                    |
ldr pc, _software_interrupt                       |
ldr pc, _prefetch_abort                           |
ldr pc, _data_abort                               |
ldr pc, _not_used                                 |
ldr pc, _irq                                      |
ldr pc, _fiq                                      |
|
_undefined_instruction: .word undefined_instruction   |
_software_interrupt:    .word software_interrupt      |
_prefetch_abort:    .word prefetch_abort              |
_data_abort:        .word data_abort                  |
_not_used:      .word not_used                        |
_irq:           .word irq                             |
_fiq:           .word fiq                             |
|
cat cpu/arm_cortexa8/start.S                              |
/*                                                    |
* the actual reset code                              |
*/                                                   |
|
reset:                     <--------------------------+
/*
* set the cpu to SVC32 mode
*/
mrs    r0, cpsr
bic    r0, r0, #0x1f
orr    r0, r0, #0xd3
msr    cpsr,r0

#if (CONFIG_OMAP34XX)
/* Copy vectors to mask ROM indirect addr */
adr    r0, _start        @ r0 <- current position of code
add    r0, r0, #4        @ skip reset vector
mov    r2, #64            @ r2 <- size to copy
add    r2, r0, r2        @ r2 <- source end address
mov    r1, #SRAM_OFFSET0    @ build vect addr
mov    r3, #SRAM_OFFSET1
add    r1, r1, r3
mov    r3, #SRAM_OFFSET2
add    r1, r1, r3
next:
ldmia    r0!, {r3 - r10}        @ copy from source address [r0]
stmia    r1!, {r3 - r10}        @ copy to   target address [r1]
cmp    r0, r2            @ until source end address [r2]
bne    next            @ loop until equal */
#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)
/* No need to copy/exec the clock code - DPLL adjust already done
* in NAND/oneNAND Boot.
*/
bl    cpy_clk_code        @ put dpll adjust code behind vectors
#endif /* NAND Boot */
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl    cpu_init_crit
#endif

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:               @ relocate U-Boot to RAM
adr r0, _start      @ r0 <- current position of code
ldr r1, _TEXT_BASE      @ test if we run from flash or RAM
cmp r0, r1          @ don't reloc during debug
beq stack_setup

ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2      @ r2 <- size of armboot
add r2, r0, r2      @ r2 <- source end address

copy_loop:              @ copy 32 bytes at a time
ldmia   r0!, {r3 - r10}     @ copy from source address [r0]
stmia   r1!, {r3 - r10}     @ copy to   target address [r1]
cmp r0, r2          @ until source end addreee [r2]
ble copy_loop
#endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

stack_setup:
ldr r0, _TEXT_BASE      @ upper 128 KiB: relocated uboot
sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12     @ leave 3 words for abort-stack
and sp, sp, #~7     @ 8 byte alinged for (ldr/str)d

/* Clear BSS (if any). Is below tx (watch load addr - need space) */
clear_bss:
ldr r0, _bss_start      @ find start of bss segment
ldr r1, _bss_end        @ stop here
mov r2, #0x00000000     @ clear value
clbss_l:
str r2, [r0]        @ clear BSS location
cmp r0, r1          @ are we at the end yet
add r0, r0, #4      @ increment clear index pointer
bne clbss_l         @ keep clearing till at end

#ifdef CONFIG_ARCH_MMU
bl board_mmu_init
#endif
ldr pc, _start_armboot  @ jump to C code              -------+
|
_start_armboot: .word start_armboot          ---------+   <------+
|
cat lib_arm/board.c                                       |
void start_armboot (void)                    <--------+
{
init_fnc_t **init_fnc_ptr;
char *s;
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif

/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");

memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));

gd->flags |= GD_FLG_RELOC;

monitor_flash_len = _bss_start - _armboot_start;

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}

/* armboot_start is defined in the board-specific linker script */
mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN);

#ifndef CONFIG_SYS_NO_FLASH
/* configure available FLASH banks */
display_flash_config (flash_init ());
#endif /* CONFIG_SYS_NO_FLASH */

#ifdef CONFIG_VFD
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
/*
* reserve memory for VFD display (always full pages)
*/
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
vfd_setmem (addr);
gd->fb_base = addr;
#endif /* CONFIG_VFD */

#ifdef CONFIG_LCD
/* board init may have inited fb_base */
if (!gd->fb_base) {
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
/*
* reserve memory for LCD display (always full pages)
*/
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
lcd_setmem (addr);
gd->fb_base = addr;
}
#endif /* CONFIG_LCD */

#if defined(CONFIG_CMD_NAND)
puts ("NAND:  ");
nand_init();        /* go init the NAND */
#endif

#if defined(CONFIG_CMD_ONENAND)
onenand_init();
#endif

#ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
#endif

#ifdef CONFIG_GENERIC_MMC
puts ("MMC:   ");
mmc_initialize (gd->bd);
#endif

/* initialize environment */
env_relocate ();

#ifdef CONFIG_VFD
/* must do this after the framebuffer is allocated */
drv_vfd_init();
#endif /* CONFIG_VFD */

#ifdef CONFIG_SERIAL_MULTI
serial_initialize();
#endif

/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

#if defined CONFIG_SPLASH_SCREEN && defined CONFIG_VIDEO_MX5
setup_splash_image();
#endif

stdio_init ();    /* get the devices list going. */   -------------------+
|
jumptable_init ();                                                       |
|
#if defined(CONFIG_API)                                                      |
/* Initialize API */                                                     |
api_init ();                                                             |
#endif                                                                       |
|
console_init_r ();    /* fully init console as a device */               |
|
#if defined(CONFIG_ARCH_MISC_INIT)                                           |
/* miscellaneous arch dependent initialisations */                       |
arch_misc_init ();                                                       |
#endif                                                                       |
#if defined(CONFIG_MISC_INIT_R)                                              |
/* miscellaneous platform dependent initialisations */                   |
misc_init_r ();                                                          |
#endif                                                                       |
|
/* enable exceptions */                                                  |
enable_interrupts ();                                                    |
|
/* Perform network card initialisation if necessary */                   |
#ifdef CONFIG_DRIVER_TI_EMAC                                                 |
/* XXX: this needs to be moved to board init */                          |
extern void davinci_eth_set_mac_addr (const u_int8_t *addr);                 |
if (getenv ("ethaddr")) {                                                |
uchar enetaddr[6];                                                   |
eth_getenv_enetaddr("ethaddr", enetaddr);                            |
davinci_eth_set_mac_addr(enetaddr);                                  |
}                                                                        |
#endif                                                                       |
|
#ifdef CONFIG_DRIVER_CS8900                                                  |
/* XXX: this needs to be moved to board init */                          |
cs8900_get_enetaddr ();                                                  |
#endif                                                                       |
|
#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)      |
/* XXX: this needs to be moved to board init */                          |
if (getenv ("ethaddr")) {                                                |
uchar enetaddr[6];                                                   |
eth_getenv_enetaddr("ethaddr", enetaddr);                            |
smc_set_mac_addr(enetaddr);                                          |
}                                                                        |
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */                |
|
#if defined(CONFIG_ENC28J60_ETH) && !defined(CONFIG_ETHADDR)                 |
extern void enc_set_mac_addr (void);                                     |
enc_set_mac_addr ();                                                     |
#endif /* CONFIG_ENC28J60_ETH && !CONFIG_ETHADDR*/                           |
|
/* Initialize from environment */                                        |
if ((s = getenv ("loadaddr")) != NULL) {                                 |
load_addr = simple_strtoul (s, NULL, 16);                            |
}                                                                        |
#if defined(CONFIG_CMD_NET)                                                  |
if ((s = getenv ("bootfile")) != NULL) {                                 |
copy_filename (BootFile, s, sizeof (BootFile));                      |
}                                                                        |
#endif                                                                       |
|
#ifdef BOARD_LATE_INIT                                                       |
board_late_init ();                                                      |
#endif                                                                       |
|
#ifdef CONFIG_ANDROID_RECOVERY                                               |
check_recovery_mode();                                                   |
#endif                                                                       |
|
#if defined(CONFIG_CMD_NET)                                                  |
#if defined(CONFIG_NET_MULTI)                                                |
puts ("Net:   ");                                                        |
#endif                                                                       |
eth_initialize(gd->bd);                                                  |
#if defined(CONFIG_RESET_PHY_R)                                              |
debug ("Reset Ethernet PHY\n");                                          |
reset_phy();                                                             |
#endif                                                                       |
#endif                                                                       |
#ifdef CONFIG_FASTBOOT                                                       |
check_fastboot_mode();                                                   |
#endif                                                                       |
/* main_loop() can return to retry autoboot, if so just run it again. */ |
for (;;) {                                                               |
main_loop ();                                                        |
}                                                                        |
|
/* NOTREACHED - no way out of command loop except booting */             |
}                                                                            |
|
cat common/stdio.c                                                               |
int stdio_init (void)                    <-----------------------------------+
{
#ifndef CONFIG_ARM    /* already relocated for current ARM implementation */
ulong relocation_offset = gd->reloc_off;
int i;

/* relocate device name pointers */
for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {
stdio_names[i] = (char *) (((ulong) stdio_names[i]) +
relocation_offset);
}
#endif

/* Initialize the list */
INIT_LIST_HEAD(&(devs.list));

#ifdef CONFIG_ARM_DCC_MULTI
drv_arm_dcc_init ();
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
#ifdef CONFIG_LCD
drv_lcd_init ();                     ----------------------------------+
#endif                                                                     |
#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)                   |
drv_video_init ();                                                     |
#endif                                                                     |
#ifdef CONFIG_KEYBOARD                                                     |
drv_keyboard_init ();                                                  |
#endif                                                                     |
#ifdef CONFIG_LOGBUFFER                                                    |
drv_logbuff_init ();                                                   |
#endif                                                                     |
drv_system_init ();                                                    |
#ifdef CONFIG_SERIAL_MULTI                                                 |
serial_stdio_init ();                                                  |
#endif                                                                     |
#ifdef CONFIG_USB_TTY                                                      |
drv_usbtty_init ();                                                    |
#endif                                                                     |
#ifdef CONFIG_NETCONSOLE                                                   |
drv_nc_init ();                                                        |
#endif                                                                     |
#ifdef CONFIG_JTAG_CONSOLE                                                 |
drv_jtag_console_init ();                                              |
#endif                                                                     |
|
return (0);                                                            |
}                                                                          |
|
cat common/stdio.c                                                             |
int drv_lcd_init (void)                    <-------------------------------+
{
struct stdio_dev lcddev;
int rc;

lcd_base = (void *)(gd->fb_base);

lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;

lcd_init (lcd_base);        /* LCD initialization */        ----------+
|
/* Device initialization */                                           |
memset (&lcddev, 0, sizeof (lcddev));                                 |
|
strcpy (lcddev.name, "lcd");                                          |
lcddev.ext   = 0;           /* No extensions */                       |
lcddev.flags = DEV_FLAGS_OUTPUT;    /* Output only */                 |
lcddev.putc  = lcd_putc;        /* 'putc' function */                 |
lcddev.puts  = lcd_puts;        /* 'puts' function */                 |
|
rc = stdio_register (&lcddev);                                        |
|
return (rc == 0) ? 1 : rc;                                            |
}                                                                         |
|
cat common/lcd.c                                                              |
static int lcd_init (void *lcdbase)                   <-------------------+
{
/* Initialize the lcd controller */
debug ("[LCD] Initializing LCD frambuffer at %p\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;                                                      |               |
}                +-------------------------------------------------+               |
|                                                                 |
cat common/lcd.c     V                                                                 |
static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])         |
{                                                                                  |
#if LCD_BPP == LCD_MONOCHROME                                                      |
/* Setting the palette */                                                      |
lcd_initcolregs();                                                             |
|
#elif LCD_BPP == LCD_COLOR8                                                        |
/* Setting the palette */                                                      |
lcd_setcolreg  (CONSOLE_COLOR_BLACK,       0,    0,    0);                     |
lcd_setcolreg  (CONSOLE_COLOR_RED,    0xFF,    0,    0);                       |
lcd_setcolreg  (CONSOLE_COLOR_GREEN,       0, 0xFF,    0);                     |
lcd_setcolreg  (CONSOLE_COLOR_YELLOW,    0xFF, 0xFF,    0);                    |
lcd_setcolreg  (CONSOLE_COLOR_BLUE,        0,    0, 0xFF);                     |
lcd_setcolreg  (CONSOLE_COLOR_MAGENTA,    0xFF,    0, 0xFF);                   |
lcd_setcolreg  (CONSOLE_COLOR_CYAN,       0, 0xFF, 0xFF);                      |
lcd_setcolreg  (CONSOLE_COLOR_GREY,    0xAA, 0xAA, 0xAA);                      |
lcd_setcolreg  (CONSOLE_COLOR_WHITE,    0xFF, 0xFF, 0xFF);                     |
#endif                                                                             |
|
#ifndef CONFIG_SYS_WHITE_ON_BLACK                                                  |
lcd_setfgcolor (CONSOLE_COLOR_BLACK);                                          |
lcd_setbgcolor (CONSOLE_COLOR_WHITE);                                          |
#else                                                                              |
lcd_setfgcolor (CONSOLE_COLOR_WHITE);                                          |
lcd_setbgcolor (CONSOLE_COLOR_BLACK);                                          |
#endif    /* CONFIG_SYS_WHITE_ON_BLACK */                                          |
|
#ifdef    LCD_TEST_PATTERN                                                         |
test_pattern();                                                                |
#else                                                                              |
/* set framebuffer to background color */                                      |
memset ((char *)lcd_base,                                                      |
COLOR_MASK(lcd_getbgcolor()),                                              |
lcd_line_length*panel_info.vl_row);                                        |
#endif                                                                             |
/* Paint the logo and retrieve LCD base address */                             |
debug ("[LCD] Drawing the logo...\n");                                         |
lcd_console_address = lcd_logo ();   --------+                                 |
|                                 |
console_col = 0;                             |                                 |
console_row = 0;                             |                                 |
|                                 |
return (0);                                  |                                 |
}                                                |                                 |
|                                 |
cat common/lcd.c                                     |                                 |
static void *lcd_logo (void)         <-----------+                                 |
{                                                                                  |
#ifdef CONFIG_SPLASH_SCREEN                                                        |
char *s;                                                                       |
ulong addr;                                                                    |
static int do_splash = 1;                                                      |
|
// get the "splashimage=0x30000000\0"                                          |
if (do_splash && (s = getenv("splashimage")) != NULL) {                        |
int x = 0, y = 0;                                                          |
do_splash = 0;                                                             |
|
// get the image address                                                   |
addr = simple_strtoul (s, NULL, 16);                                       |
|
#ifdef CONFIG_SPLASH_SCREEN_ALIGN                                                  |
// get the "splashpos=m,m\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                                                                             |
/**                                                                        |
* We currently offer uboot boot picture size is 800*480,                  |
* so the picture do not need to be offset ,                              |
* just let x and y equal to zero that drawing picture at top left corner  |
*                 write by zengjf    2015/4/8                             |
*/                                                                        |
x = 0;                                                                     |
y = 0;                                                                   |
|
|
if (lcd_display_bitmap (addr, x, y) == 0) {       -------------------+     |
return ((void *)lcd_base);                                       |     |
}                                                                    |     |
}                                                                        |     |
#endif /* CONFIG_SPLASH_SCREEN */                                            |     |
|     |
#ifdef CONFIG_LCD_LOGO                                                       |     |
bitmap_plot (0, 0);                                                      |     |
#endif /* CONFIG_LCD_LOGO */                                                 |     |
|     |
#ifdef CONFIG_LCD_INFO                                                       |     |
console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;                             |     |
console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;                            |     |
lcd_show_board_info();                                                   |     |
#endif /* CONFIG_LCD_INFO */                                                 |     |
|     |
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)         |     |
return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));  |     |
#else                                                                        |     |
return ((void *)lcd_base);                                               |     |
#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */                  |     |
}                                                                            |     |
|     |
cat common/lcd.c                                                                 |     |
int lcd_display_bitmap(ulong bmp_image, int x, int y)     <------------------+     |
{                                                                                  |
#if !defined(CONFIG_MCC200)                                                        |
ushort *cmap = NULL;                                                           |
#endif                                                                             |
ushort *cmap_base = NULL;                                                      |
ushort i, j;                                                                   |
uchar *fb;                                                                     |
bmp_image_t *bmp=(bmp_image_t *)bmp_image;                                     |
uchar *bmap;                                                                   |
ushort padded_line;                                                            |
unsigned long width, height, byte_width;                                       |
unsigned long pwidth = panel_info.vl_col;                                      |
unsigned colors, bpix, bmp_bpix;                                               |
unsigned long compression;                                                     |
#if defined(CONFIG_PXA250)                                                         |
struct pxafb_info *fbi = &panel_info.pxa;                                      |
#elif defined(CONFIG_MPC823)                                                       |
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;                          |
volatile cpm8xx_t *cp = &(immr->im_cpm);                                       |
#endif                                                                             |
|
if (!((bmp->header.signature[0]=='B') &&                                       |
(bmp->header.signature[1]=='M'))) {                                        |
printf ("Error: no valid bmp image at %lx\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<colors; ++i) {                                                 |
bmp_color_table_entry_t cte = bmp->color_table[i];                     |
#if !defined(CONFIG_ATMEL_LCD)                                                     |
ushort colreg =                                                        |
( ((cte.red)   << 8) & 0xf800) |                                   |
( ((cte.green) << 3) & 0x07e0) |                                   |
( ((cte.blue)  >> 3) & 0x001f) ;                                   |
#ifdef CONFIG_SYS_INVERT_COLORS                                                    |
*cmap = 0xffff - colreg;                                               |
#else                                                                              |
*cmap = colreg;                                                        |
#endif                                                                             |
#if defined(CONFIG_MPC823)                                                         |
cmap--;                                                                |
#else                                                                              |
cmap++;                                                                |
#endif                                                                             |
#else /* CONFIG_ATMEL_LCD */                                                       |
lcd_setcolreg(i, cte.red, cte.green, cte.blue);                        |
#endif                                                                             |
}                                                                          |
}                                                                              |
#endif                                                                             |
|
/*                                                                             |
* BMP format for Monochrome assumes that the state of a                       |
* pixel is described on a per Bit basis, not per Byte.                        |
* So, in case of Monochrome BMP we should align widths                        |
* on a byte boundary and convert them from Bit to Byte                        |
* units.                                                                      |
* Probably, PXA250 and MPC823 process 1bpp BMP images in                      |
* their own ways, so make the converting to be MCC200                         |
* specific.                                                                   |
*/                                                                            |
#if defined(CONFIG_MCC200)                                                         |
if (bpix==1)                                                                   |
{                                                                              |
width = ((width + 7) & ~7) >> 3;                                           |
x     = ((x + 7) & ~7) >> 3;                                               |
pwidth= ((pwidth + 7) & ~7) >> 3;                                          |
}                                                                              |
#endif                                                                             |
padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);                        |
#ifdef CONFIG_SPLASH_SCREEN_ALIGN                                                  |
if (x == BMP_ALIGN_CENTER)                                                     |
x = max(0, (pwidth - width) / 2);                                          |
else if (x < 0)                                                                |
x = max(0, pwidth - width + x + 1);                                        |
|
if (y == BMP_ALIGN_CENTER)                                                     |
y = max(0, (panel_info.vl_row - height) / 2);                              |
else if (y < 0)                                                                |
y = max(0, panel_info.vl_row - height + y + 1);                            |
#endif /* CONFIG_SPLASH_SCREEN_ALIGN */                                            |
|
if ((x + width)>pwidth)                                                        |
width = pwidth - x;                                                        |
if ((y + height)>panel_info.vl_row)                                            |
height = panel_info.vl_row - y;                                            |
|
bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset);                   |
fb   = (uchar *) (lcd_base +                                                   |
(y + height - 1) * lcd_line_length + x * bpix / 8);                        |
|
switch (bmp_bpix) {                                                            |
case 1: /* pass through */                                                     |
case 8:                                                                        |
if (bpix != 16)                                                            |
byte_width = width;                                                    |
else                                                                       |
byte_width = width * 2;                                                |
|
for (i = 0; i < height; ++i) {                                             |
WATCHDOG_RESET();                                                      |
for (j = 0; j < width; j++) {                                          |
if (bpix != 16) {                                                  |
#if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)                            |
*(fb++) = *(bmap++);                                           |
#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)                             |
*(fb++) = 255 - *(bmap++);                                     |
#endif                                                                             |
} else {                                                           |
*(uint16_t *)fb = cmap_base[*(bmap++)];                        |
fb += sizeof(uint16_t) / sizeof(*fb);                          |
}                                                                  |
}                                                                      |
bmap += (width - padded_line);                                         |
fb   -= (byte_width + lcd_line_length);                                |
}                                                                          |
break;                                                                     |
|
#if defined(CONFIG_BMP_16BPP)                                                      |
case 16:                                                                       |
for (i = 0; i < height; ++i) {                                             |
WATCHDOG_RESET();                                                      |
for (j = 0; j < width; j++) {                                          |
#if defined(CONFIG_ATMEL_LCD_BGR555)                                               |
*(fb++) = ((bmap[0] & 0x1f) << 2) |                                |
(bmap[1] & 0x03);                                              |
*(fb++) = (bmap[0] & 0xe0) |                                       |
((bmap[1] & 0x7c) >> 2);                                       |
bmap += 2;                                                         |
#else                                                                              |
*(fb++) = *(bmap++);                                               |
*(fb++) = *(bmap++);                                               |
#endif                                                                             |
}                                                                      |
bmap += (padded_line - width) * 2;                                     |
fb   -= (width * 2 + lcd_line_length);                                 |
}                                                                          |
break;                                                                     |
#endif /* CONFIG_BMP_16BPP */                                                      |
#if defined(CONFIG_BMP_24BPP)                                                      |
case 24:                                                                       |
if (bpix != 16) {                                                          |
printf("Error: %d bit/pixel mode,"                                     |
"but BMP has %d bit/pixel\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                                                                             |
|
cat board/freescale/mx6q_sabresd/mx6q_sabresd.c                                        |
......                                                                             |
#ifndef CONFIG_MXC_EPDC                                                            |
#ifdef CONFIG_LCD                                                                  |
void lcd_enable(void)             <------------------------------------------------+
{
char *s;
int ret;
unsigned int reg;

s = getenv("lvds_num");
di = simple_strtol(s, NULL, 10);

/*
* hw_rev 2: IPUV3DEX
* hw_rev 3: IPUV3M
* hw_rev 4: IPUV3H
*/
g_ipu_hw_rev = IPUV3_HW_REV_IPUV3H;

/**
* zengjf modify don't show uboot logo
*/
imx_pwm_config(pwm0, 25000, 50000);
imx_pwm_enable(pwm0);

#if defined CONFIG_MX6Q
/* PWM backlight */
mxc_iomux_v3_setup_pad(MX6Q_PAD_SD1_DAT3__PWM1_PWMO);
/* LVDS panel CABC_EN0 */
//mxc_iomux_v3_setup_pad(MX6Q_PAD_NANDF_CS2__GPIO_6_15);
/* LVDS panel CABC_EN1 */
//mxc_iomux_v3_setup_pad(MX6Q_PAD_NANDF_CS3__GPIO_6_16);
#elif defined CONFIG_MX6DL
/* PWM backlight */
mxc_iomux_v3_setup_pad(MX6DL_PAD_SD1_DAT3__PWM1_PWMO);
/* LVDS panel CABC_EN0 */
//mxc_iomux_v3_setup_pad(MX6DL_PAD_NANDF_CS2__GPIO_6_15);
/* LVDS panel CABC_EN1 */
//mxc_iomux_v3_setup_pad(MX6DL_PAD_NANDF_CS3__GPIO_6_16);
#endif
/*
* Set LVDS panel CABC_EN0 to low to disable
* CABC function. This function will turn backlight
* automatically according to display content, so
* simply disable it to get rid of annoying unstable
* backlight phenomena.
*/
/*
reg = readl(GPIO6_BASE_ADDR + GPIO_GDIR);
reg |= (1 << 15);
writel(reg, GPIO6_BASE_ADDR + GPIO_GDIR);

reg = readl(GPIO6_BASE_ADDR + GPIO_DR);
reg &= ~(1 << 15);
writel(reg, GPIO6_BASE_ADDR + GPIO_DR);
*/

/*
* Set LVDS panel CABC_EN1 to low to disable
* CABC function.
*/
/*
reg = readl(GPIO6_BASE_ADDR + GPIO_GDIR);
reg |= (1 << 16);
writel(reg, GPIO6_BASE_ADDR + GPIO_GDIR);

reg = readl(GPIO6_BASE_ADDR + GPIO_DR);
reg &= ~(1 << 16);
writel(reg, GPIO6_BASE_ADDR + GPIO_DR);
*/

/* Disable ipu1_clk/ipu1_di_clk_x/ldb_dix_clk. */
reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
reg &= ~0xC033;
writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);

#if defined CONFIG_MX6Q
/*
* Align IPU1 HSP clock and IPU1 DIx pixel clock
* with kernel setting to avoid screen flick when
* booting into kernel. Developer should change
* the relevant setting if kernel setting changes.
* IPU1 HSP clock tree:
* osc_clk(24M)->pll2_528_bus_main_clk(528M)->
* periph_clk(528M)->mmdc_ch0_axi_clk(528M)->
* ipu1_clk(264M)
*/
/* pll2_528_bus_main_clk */
/* divider */
writel(0x1, ANATOP_BASE_ADDR + 0x34);

/* periph_clk */
/* source */
reg = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
reg &= ~(0x3 << 18);
writel(reg, CCM_BASE_ADDR + CLKCTL_CBCMR);

reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
reg &= ~(0x1 << 25);
writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);

/*
* Check PERIPH_CLK_SEL_BUSY in
* MXC_CCM_CDHIPR register.
*/
do {
udelay(5);
reg = readl(CCM_BASE_ADDR + CLKCTL_CDHIPR);
} while (reg & (0x1 << 5));

/* mmdc_ch0_axi_clk */
/* divider */
reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
reg &= ~(0x7 << 19);
writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);

/*
* Check MMDC_CH0PODF_BUSY in
* MXC_CCM_CDHIPR register.
*/
do {
udelay(5);
reg = readl(CCM_BASE_ADDR + CLKCTL_CDHIPR);
} while (reg & (0x1 << 4));

/* ipu1_clk */
reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3);
/* source */
reg &= ~(0x3 << 9);
/* divider */
reg &= ~(0x7 << 11);
reg |= (0x1 << 11);
writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR3);

/*
* ipu1_pixel_clk_x clock tree:
* osc_clk(24M)->pll2_528_bus_main_clk(528M)->
* pll2_pfd_352M(452.57M)->ldb_dix_clk(64.65M)->
* ipu1_di_clk_x(64.65M)->ipu1_pixel_clk_x(64.65M)
*/
/* pll2_pfd_352M */
/* disable */
writel(0x1 << 7, ANATOP_BASE_ADDR + 0x104);
/* divider */
writel(0x3F, ANATOP_BASE_ADDR + 0x108);
writel(0x15, ANATOP_BASE_ADDR + 0x104);

/* ldb_dix_clk */
/* source */
reg = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR);
reg &= ~(0x3F << 9);
reg |= (0x9 << 9);
writel(reg, CCM_BASE_ADDR + CLKCTL_CS2CDR);
/* divider */
reg = readl(CCM_BASE_ADDR + CLKCTL_CSCMR2);
reg |= (0x3 << 10);
writel(reg, CCM_BASE_ADDR + CLKCTL_CSCMR2);

/* pll2_pfd_352M */
/* enable after ldb_dix_clk source is set */
writel(0x1 << 7, ANATOP_BASE_ADDR + 0x108);

/* ipu1_di_clk_x */
/* source */
reg = readl(CCM_BASE_ADDR + CLKCTL_CHSCCDR);
reg &= ~0xE07;
reg |= 0x803;
writel(reg, CCM_BASE_ADDR + CLKCTL_CHSCCDR);
#elif defined CONFIG_MX6DL /* CONFIG_MX6Q */
/*
* IPU1 HSP clock tree:
* osc_clk(24M)->pll3_usb_otg_main_clk(480M)->
* pll3_pfd_540M(540M)->ipu1_clk(270M)
*/
/* pll3_usb_otg_main_clk */
/* divider */
writel(0x3, ANATOP_BASE_ADDR + 0x18);

/* pll3_pfd_540M */
/* divider */
writel(0x3F << 8, ANATOP_BASE_ADDR + 0xF8);
writel(0x10 << 8, ANATOP_BASE_ADDR + 0xF4);
/* enable */
writel(0x1 << 15, ANATOP_BASE_ADDR + 0xF8);

/* ipu1_clk */
reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3);
/* source */
reg |= (0x3 << 9);
/* divider */
reg &= ~(0x7 << 11);
reg |= (0x1 << 11);
writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR3);

/*
* ipu1_pixel_clk_x clock tree:
* osc_clk(24M)->pll2_528_bus_main_clk(528M)->
* pll2_pfd_352M(452.57M)->ldb_dix_clk(64.65M)->
* ipu1_di_clk_x(64.65M)->ipu1_pixel_clk_x(64.65M)
*/
/* pll2_528_bus_main_clk */
/* divider */
writel(0x1, ANATOP_BASE_ADDR + 0x34);

/* pll2_pfd_352M */
/* disable */
writel(0x1 << 7, ANATOP_BASE_ADDR + 0x104);
/* divider */
writel(0x3F, ANATOP_BASE_ADDR + 0x108);
writel(0x15, ANATOP_BASE_ADDR + 0x104);

/* ldb_dix_clk */
/* source */
reg = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR);
reg &= ~(0x3F << 9);
reg |= (0x9 << 9);
writel(reg, CCM_BASE_ADDR + CLKCTL_CS2CDR);
/* divider */
reg = readl(CCM_BASE_ADDR + CLKCTL_CSCMR2);
reg |= (0x3 << 10);
writel(reg, CCM_BASE_ADDR + CLKCTL_CSCMR2);

/* pll2_pfd_352M */
/* enable after ldb_dix_clk source is set */
writel(0x1 << 7, ANATOP_BASE_ADDR + 0x108);

/* ipu1_di_clk_x */
/* source */
reg = readl(CCM_BASE_ADDR + CLKCTL_CHSCCDR);
reg &= ~0xE07;
reg |= 0x803;
writel(reg, CCM_BASE_ADDR + CLKCTL_CHSCCDR);
#endif    /* CONFIG_MX6DL */

/* Enable ipu1/ipu1_dix/ldb_dix clocks. */
if (di == 1) {
reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
reg |= 0xC033;
writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);
} else {
reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
reg |= 0x300F;
writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);
}

/**
* zengjf 2015-7-23 modify to 24bit or 16bit
*
* #define IPU_PIX_FMT_BGR24   fourcc('B', 'G', 'R', '3')    /*< 24  BGR-8-8-8 */
* #define IPU_PIX_FMT_RGB24   fourcc('R', 'G', 'B', '3')    /*< 24  RGB-8-8-8 */
*/
//ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB666,
//ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB24,
ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB24,    ---------+
DI_PCLK_LDB, 65000000);                                   |
if (ret)                                                          |
puts("LCD cannot be configured\n");                           |
|
/*                                                                |
* LVDS0 mux to IPU1 DI0.                                         |
* LVDS1 mux to IPU1 DI1.                                         |
*/                                                               |
reg = readl(IOMUXC_BASE_ADDR + 0xC);                              |
reg &= ~(0x000003C0);                                             |
reg |= 0x00000100;                                                |
writel(reg, IOMUXC_BASE_ADDR + 0xC);                              |
|
if (di == 1)                                                      |
writel(0x40C, IOMUXC_BASE_ADDR + 0x8);                        |
else                                                              |
writel(0x201, IOMUXC_BASE_ADDR + 0x8);                        |
}                                                                     |
#endif                                                                |
|
cat drivers/video/mxc_ipuv3_fb.c                                          V
int ipuv3_fb_init(struct fb_videomode *mode, int di, int interface_pix_fmt,
ipu_di_clk_parent_t di_clk_parent, int di_clk_val)          |
{                                                                     |
int ret;                                                          |
|
ret = ipu_probe(di, di_clk_parent, di_clk_val);                   |
if (ret)                                                          |
puts("Error initializing IPU\n");                             |
|
debug("Framebuffer at 0x%x\n", (unsigned int)lcd_base);           |
ret = mxcfb_probe(interface_pix_fmt, mode, di);                   |
|                               |
return ret;                       |                               |
}                                     +-------------------------------+
|
cat drivers/video/mxc_ipuv3_fb.c          v
static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode, int di)
{                                     |
struct fb_info *fbi;              |
struct mxcfb_info *mxcfbi;        |
int ret = 0;                      |
+----------------------------------+
/*                                                                   |
* Initialize FB structures                                          |
*/                                                                  |
fbi = mxcfb_init_fbinfo();                                           |
if (!fbi) {                                                          |
ret = -ENOMEM;                                                   |
goto err0;                                                       |
}                                                                    |
mxcfbi = (struct mxcfb_info *)fbi->par;                              |
|
if (!g_dp_in_use) {                                                  |
mxcfbi->ipu_ch = MEM_BG_SYNC;                                    |
mxcfbi->blank = FB_BLANK_UNBLANK;                                |
} else {                                                             |
mxcfbi->ipu_ch = MEM_DC_SYNC;                                    |
mxcfbi->blank = FB_BLANK_POWERDOWN;                              |
}                                                                    |
|
mxcfbi->ipu_di = di;                                                 |
|
ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80);                  |
ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0);                        |
strcpy(fbi->fix.id, "DISP3 BG");                                     |
|
g_dp_in_use = 1;                                                     |
|
mxcfb_info[mxcfbi->ipu_di] = fbi;                                    |
|
/* Need dummy values until real panel is configured */               |
fbi->var.xres = 640;                                                 |
fbi->var.yres = 480;                                                 |
/**                                                                  |
* zengjf 2015-8-23 modify to 24bit display, it can't work well      |
*/                                                                  |
fbi->var.bits_per_pixel = 16;                                        |
//fbi->var.bits_per_pixel = 24;                                      |
|
mxcfbi->ipu_di_pix_fmt = interface_pix_fmt;   <----------------------+
fb_videomode_to_var(&fbi->var, mode);

mxcfb_check_var(&fbi->var, fbi);

/* Default Y virtual size is 2x panel size */
fbi->var.yres_virtual = fbi->var.yres * 2;

mxcfb_set_fix(fbi);

/* alocate fb first */
if (mxcfb_map_video_memory(fbi) < 0)
return -ENOMEM;

mxcfb_set_par(fbi);                  -------------------------------------+
|
/* Setting panel_info for lcd */                                          |
panel_info.vl_col = fbi->var.xres;                                        |
panel_info.vl_row = fbi->var.yres;                                        |
panel_info.vl_bpix = LCD_BPP;   // this same can't wake well   ---------+ |
| |
lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;  | |
| |
debug("MXC IPUV3 configured\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;                                                             | |
}                                                                           | |
| |
cat include/configs/mx6dl_sabresd.h                                             | |
#define LCD_BPP        LCD_COLOR16           <------------------------------+ |
|                                              |
cat include/lcd.h                  |                                              |
#define LCD_MONOCHROME    0    +----------+                                   |
#define LCD_COLOR2        1               |                                   |
#define LCD_COLOR4        2               |                                   |
#define LCD_COLOR8        3               |                                   |
#define LCD_COLOR16       4    <----------+                                   |
|
cat drivers/video/mxc_ipuv3_fb.c                                                  |
static int mxcfb_set_par(struct fb_info *fbi)          <----------------------+
{
int retval = 0;
u32 mem_len;
ipu_di_signal_cfg_t sig_cfg;
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
uint32_t out_pixel_fmt;

ipu_disable_channel(mxc_fbi->ipu_ch);
ipu_uninit_channel(mxc_fbi->ipu_ch);
mxcfb_set_fix(fbi);

mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {
if (fbi->fix.smem_start)
mxcfb_unmap_video_memory(fbi);

if (mxcfb_map_video_memory(fbi) < 0)
return -ENOMEM;
}

setup_disp_channel1(fbi);

memset(&sig_cfg, 0, sizeof(sig_cfg));
if (fbi->var.vmode & FB_VMODE_INTERLACED) {
sig_cfg.interlaced = 1;
out_pixel_fmt = IPU_PIX_FMT_YUV444;
} else {
if (mxc_fbi->ipu_di_pix_fmt) {
out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
debug(" zengjf1 %d. \n", out_pixel_fmt);
}
else
{
out_pixel_fmt = IPU_PIX_FMT_RGB666;
debug(" zengjf2 %d. \n", out_pixel_fmt);
}
}
if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
sig_cfg.odd_field_first = 1;
if ((fbi->var.sync & FB_SYNC_EXT) || ext_clk_used)
sig_cfg.ext_clk = 1;
if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
sig_cfg.Hsync_pol = 1;
if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
sig_cfg.Vsync_pol = 1;
if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))
sig_cfg.clk_pol = 1;
if (fbi->var.sync & FB_SYNC_DATA_INVERT)
sig_cfg.data_pol = 1;
if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))
sig_cfg.enable_pol = 1;
if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
sig_cfg.clkidle_en = 1;

debug("zengjf pixclock = %d \n", fbi->var.pixclock);
debug("pixclock = %ul Hz\n", (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
debug("bpp_to_pixfmt: %d\n", fbi->var.bits_per_pixel);

if (ipu_init_sync_panel(mxc_fbi->ipu_di,
(PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
fbi->var.xres, fbi->var.yres,
out_pixel_fmt,
fbi->var.left_margin,
fbi->var.hsync_len,
fbi->var.right_margin,
fbi->var.upper_margin,
fbi->var.vsync_len,
fbi->var.lower_margin,
0, sig_cfg) != 0) {
puts("mxcfb: Error initializing panel.\n");
return -EINVAL;
}

retval = setup_disp_channel2(fbi);        --------------------+
if (retval)                                                   |
return retval;                                            |
|
if (mxc_fbi->blank == FB_BLANK_UNBLANK)                       |
ipu_enable_channel(mxc_fbi->ipu_ch);                      |
|
return retval;                                                |
}                                                                 |
|
cat drivers/video/mxc_ipuv3_fb.c                                      |
static int setup_disp_channel2(struct fb_info *fbi)    <----------+
{
int retval = 0;
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;

mxc_fbi->cur_ipu_buf = 1;
if (mxc_fbi->alpha_chan_en)
mxc_fbi->cur_ipu_alpha_buf = 1;

fbi->var.xoffset = fbi->var.yoffset = 0;

debug("%s: ipu_ch{%x} xres{%d} yres{%d} line_length{%d} smem_start{%lx} smem_end{%lx}\n",
__func__,
mxc_fbi->ipu_ch,
fbi->var.xres,
fbi->var.yres,
fbi->fix.line_length,
fbi->fix.smem_start,
fbi->fix.smem_start +
(fbi->fix.line_length * fbi->var.yres));

retval = ipu_init_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
bpp_to_pixfmt(fbi),               --------------------+
fbi->var.xres, fbi->var.yres,                         |
fbi->fix.line_length,                                 |
fbi->fix.smem_start +                                 |
(fbi->fix.line_length * fbi->var.yres),               |
fbi->fix.smem_start,                                  |
0, 0);                                                |
if (retval)                                                            |
printf("ipu_init_channel_buffer error %d\n", retval);              |
|
return retval;                                                         |
}                                                                          |
|
cat drivers/video/mxc_ipuv3_fb.c                                               |
static uint32_t bpp_to_pixfmt(struct fb_info *fbi)     <-------------------+
{
uint32_t pixfmt = 0;

debug("bpp_to_pixfmt: %d\n", fbi->var.bits_per_pixel);

if (fbi->var.nonstd)
return fbi->var.nonstd;

switch (fbi->var.bits_per_pixel) {
case 24:
pixfmt = IPU_PIX_FMT_BGR24;
break;
case 32:
pixfmt = IPU_PIX_FMT_BGR32;
break;
case 16:
pixfmt = IPU_PIX_FMT_RGB565;
break;
}
return pixfmt;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: