Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9463568
  • 博文数量: 1750
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20091
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1750)

文章存档

2024年(26)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: LINUX

2010-08-05 11:21:24

board.c: start_armboot()

1.lcd frame buffer的保留机理:

#ifdef CONFIG_LCD
#    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);
    size = lcd_setmem (addr);
    gd->fb_base = addr;
#endif /* CONFIG_LCD */

1)==> CONFIG_LCD  in include/configs/smdk6410.h
  ==> PAGE_SIZE same as above
不同的芯片,不同的PAGE_SIZE,不同的LCD有无的配置
 
2)_bss_end
cpu/s3c64xx/start.S:
.globl _bss_start
_bss_start:
    .word __bss_start

.globl _bss_end
_bss_end:
    .word _end
    
3)boarc/samsung/smdk6410/u-boot.lds:
    OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
    ...
    . = ALIGN(4);
    __bss_start = .;
    .bss : { *(.bss) }
    _end = .;
}
 
 4)common/lcd.c: lcd_setmem()
入口参数:addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); see above
     
 /*
 * This is called early in the system initialization to grab memory
 * for the LCD controller.
 * Returns new address for monitor, after reserving LCD buffer memory
 *
 * Note that this is running from ROM, so no write access to global data.
 */
ulong lcd_setmem (ulong addr)
{
    ulong size;
    int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;

    debug ("LCD panel info: %d x %d, %d bit/pix\n",
        panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );

    size = line_length * panel_info.vl_row;

    /* Round up to nearest full page */
    size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

    /* Allocate pages for the frame buffer. */
    addr -= size;

    debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);

    return (addr);
}

===>这里没有支持6410的LCD,故,也无定义s3c6410的控制器的结构,也无初始化   
   
===>panel_info
vidinfo_t panel_info;   

===>vidinfo_t:
include/lcd.h

#if defined CONFIG_MPC823
/*
 * LCD controller stucture for MPC823 CPU
 */
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 */
    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_wbl;        /* Wait between lines */

    /* Vertical control register */
    u_char    vl_vpw;        /* Vertical sync pulse width */
    u_char    vl_lcdac;    /* LCD AC timing */
    u_char    vl_wbf;        /* Wait between frames */
} vidinfo_t;

extern vidinfo_t panel_info;

#elif defined CONFIG_PXA250
/*
 * PXA LCD info
 */
struct pxafb_info {

    /* Misc registers */
    u_long    reg_lccr3;
    u_long    reg_lccr2;
    u_long    reg_lccr1;
    u_long    reg_lccr0;
    u_long    fdadr0;
    u_long    fdadr1;

    /* DMA descriptors */
    struct    pxafb_dma_descriptor *    dmadesc_fblow;
    struct    pxafb_dma_descriptor *    dmadesc_fbhigh;
    struct    pxafb_dma_descriptor *    dmadesc_palette;

    u_long    screen;        /* physical address of frame buffer */
    u_long    palette;    /* physical address of palette memory */
    u_int    palette_size;
};

/*
 * LCD controller stucture for PXA CPU
 */
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;

extern vidinfo_t panel_info;

#elif defined(CONFIG_MCC200)
typedef struct vidinfo {
    ushort    vl_col;        /* Number of columns (i.e. 160) */
    ushort    vl_row;        /* Number of rows (i.e. 100) */

    u_char    vl_bpix;    /* Bits per pixel, 0 = 1 */
} vidinfo_t;
#endif /* CONFIG_MPC823, CONFIG_PXA250 or CONFIG_MCC200 */
common/lcd.c

1.调用流程 :
start_armboot()==>devices_init()==>drv_lcd_init()==>lcd_init()

2.
结构功能:

int drv_lcd_init (void)
{
    device_t 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 = device_register (&lcddev);

    return (rc == 0) ? 1 : rc;
}

==》lcd_init(lcd_base):
    
static int lcd_init (void *lcdbase)
{
    /* Initialize the lcd controller */
    debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);

    lcd_ctrl_init (lcdbase);
    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
    lcd_is_enabled = 1;

    return 0;
}
    
==>lcd_ctrl_init(), lcd_enable ()
由对应的CPU进行专门实现    
    
==>lcd_clear(NULL, 1, 1, NULL)
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 CFG_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    /* CFG_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);
}

依据LCD_BPP为单色,8BPP,等(其余未实现)来设置相应的颜色寄存器

===>
#elif LCD_BPP == LCD_COLOR8

/*
 * 8bpp color definitions
 */
# define CONSOLE_COLOR_BLACK    0
# define CONSOLE_COLOR_RED    1
# define CONSOLE_COLOR_GREEN    2
# define CONSOLE_COLOR_YELLOW    3
# define CONSOLE_COLOR_BLUE    4
# define CONSOLE_COLOR_MAGENTA    5
# define CONSOLE_COLOR_CYAN    6
# define CONSOLE_COLOR_GREY    14
# define CONSOLE_COLOR_WHITE    15    /* Must remain last / highest    */

/************************************************************************/
/**  Small utility to check that you got the colours right        */
/************************************************************************/
#ifdef LCD_TEST_PATTERN

#define    N_BLK_VERT    2
#define    N_BLK_HOR    3

static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
    CONSOLE_COLOR_RED,    CONSOLE_COLOR_GREEN,    CONSOLE_COLOR_YELLOW,
    CONSOLE_COLOR_BLUE,    CONSOLE_COLOR_MAGENTA,    CONSOLE_COLOR_CYAN,
};

static void test_pattern (void)
{
    ushort v_max  = panel_info.vl_row;
    ushort h_max  = panel_info.vl_col;
    ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
    ushort h_step = (h_max + N_BLK_HOR  - 1) / N_BLK_HOR;
    ushort v, h;
    uchar *pix = (uchar *)lcd_base;

    printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n",
        h_max, v_max, h_step, v_step);

    /* WARNING: Code silently assumes 8bit/pixel */
    for (v=0; v        uchar iy = v / v_step;
        for (h=0; h            uchar ix = N_BLK_HOR * iy + (h/h_step);
            *pix++ = test_colors[ix];
        }
    }
}
#endif /* LCD_TEST_PATTERN */

==>
static void lcd_setbgcolor (int color)
{
    lcd_color_bg = color & 0x0F;
}

/*----------------------------------------------------------------------*/

static int lcd_getbgcolor (void)
{
    return lcd_color_bg;
}

==================================
void lcd_putc (const char c)
{
    if (!lcd_is_enabled) {
        serial_putc(c);
        return;
    }

    switch (c) {
    case '\r':    console_col = 0;
            return;

    case '\n':    console_newline();
            return;

    case '\t':    /* Tab (8 chars alignment) */
            console_col |=  8;
            console_col &= ~7;

            if (console_col >= CONSOLE_COLS) {
                console_newline();
            }
            return;

    case '\b':    console_back();
            return;

    default:    lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
                     console_row * VIDEO_FONT_HEIGHT,
                     c);
            if (++console_col >= CONSOLE_COLS) {
                console_newline();
            }
            return;
    }
    /* NOTREACHED */
}

/*----------------------------------------------------------------------*/

void lcd_puts (const char *s)
{
    if (!lcd_is_enabled) {
        serial_puts (s);
        return;
    }

    while (*s) {
        lcd_putc (*s++);
    }
}
阅读(3924) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~