================
Step 4: Enable LCD's clk.
(Please finish chapter 28, then come back here.)
Power Domain: Peripheral Domain.
Clock Domain: PD_PER_LCD_L3_GCLK (OCP Master Clock)
PD_PER_LCD_L3_GCLK (OCP Slave Clock)
PD_PER_LCD_GCLK (Functional Clock)
l3_clk Master Interface Clock -- 200MHz -- CORE_CLKOUTM4 -- pd_per_lcd_l3_gclk
l4_clk Slave Interface Clock -- 100MHz -- CORE_CLKOUTM4 -- pd_per_lcd_l3_gclk
lcd_clk Functional Clock -- 200MHz -- Display PLL CLKOUT -- pd_per_lcd_gclk
So, add these sentences to in function "board_init" of board.c:
(Note: reference to board/siemens/pxm2)
========
struct dpll_regs dpll_lcd_regs = {
.cm_clkmode_dpll = CM_WKUP + 0x98,
.cm_idlest_dpll = CM_WKUP + 0x48,
.cm_clksel_dpll = CM_WKUP + 0x54,
};
#define PLL_GET_M(v) ((v >> 8) & 0x7FF)
#define PLL_GET_N(v) (v & 0X7F)
int clk_get(int clk)
{
uint32_t val;
uint32_t m, n;
val = readl(dpll_lcd_regs.cm_clksel_dpll);
m = PLL_GET_M(val);
n = PLL_GET_N(val);
printf("clk_get val = 0x%x, m = 0x%x, n = 0x%x\n", val, m, n);
val = m * V_OSCK / n;
printf("clk = 0x%x V_OSCK = %d\n", val, V_OSCK);
return (m * V_OSCK) / n;
}
int board_init(void)
{
/* other execution ...... */
struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER;
struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
struct dpll_params dpll_lcd = {24, 1, -1, -1, -1, -1, -1};
uint32_t *const clk_domains[] = {
&cmper->lcdclkctrl,
0,
};
uint32_t *const clk_modules_explicit_en[] = {
&cmper->lcdclkctrl,
&cmper->lcdcclkstctrl,
0,
};
do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
writel(0x0, &cmdpll->clklcdcpixelclk);
do_setup_dpll(&dpll_lcd_regs, &dpll_lcd);
/* other execution ...... */
}
========
clkget() is called by da8xx-fb.c file. The LCD's clk has to be initialized, otherwise LCD's registers cannot be visited.
================
Step 5: What does hbp, hfp, hsw, vbp, vfp, vsw mean?
========
http://www-mtl.mit.edu/Courses/6.111/labkit/vga.shtml
VGA Video Output
Introduction
VGA is a high-resolution video standard used mostly for computer monitors, where ability to transmit a sharp, detailed image is essential. VGA uses separate wires to transmit the three color compoment signals and vertical and horizontal synchronization signals.
* hbp: Horizontal Back Porch Lowbit Bits 7:0 of the horizontal back pock field.
* hfp: Horizontal Front Porch Lowbits Encoded value (from 1-1024) used to specify the number of pixel clock periods to add to the end of a line transmission before line clock is asserted (programmed value plus 1).
* hsw: Horizontal Sync Pulse Width Lowbits Bits 5:0 of the horizontal sync pulse width field.
* vbp: Vertical Back Porch Value (from 0-255) use to specify the number of line clock periods to add to the beginning of a frame before the first set of pixels is output to the display.
* vfp: Vertical Front Porch Value (from 0-255) used to specify the number of line clock periods to add to the end of each frame.
* vsw: Vertival Sync Width Pulse In active mode (lcdtft = 1), encoded value (from 1-64) used to specify the number of line clock periods to set he lcd_fp pin active at the end of each frame after the (vfp) period elapses.
Note that AT043TN24 does not need HSYNC and VSYNC. But its clock blanking time has to be matched. DEH blanking (hbp + hfp + hsw) is 45 (40-320) CLK, and DEV (vbp + vfp + vsw) blanking is 16 (5-128) H.
================
Step 6: write panel's structures.
struct display_panel display_panel_at043 = {
.panel_type = QVGA,
.max_bpp = 32,
.min_bpp = 24,
.panel_shade = COLOR_ACTIVE,
};
struct da8xx_panel da8xx_panel_at043= {
.name = "QIMEI-AT043TN24",
.width = 480,
.height = 272,
.hbp = 0,
.hfp = 0,
.hsw = 45,
.vbp = 0,
.vfp = 0,
.vsw = 16,
.pxl_clk = 9000000,
.invert_pxl_clk = 0,
};
struct lcd_ctrl_config lcd_ctrl_config_at043 = {
.p_disp_panel = &display_panel_at043,
.ac_bias = 0,
.ac_bias_intrpt = 0,
.dma_burst_sz = 16,
.bpp = 32,
.fdd = 0xFF,
.tft_alt_mode = 0,
.mono_8bit_mode = 0,
.stn_565_mode = 0,
.invert_line_clock = 0,
.invert_frm_clock = 0,
.sync_edge = 0,
.sync_ctrl = 0,
.raster_order = 0,
};
int board_init(void)
{
/* other execution ...... */
/* clock init */
da8xx_video_init(&da8xx_panel_at043, &lcd_ctrl_config_at043,
lcd_ctrl_config_at043.bpp);
/* other execution ...... */
}
================
Step 7: Use the panel.
U-Boot# tftp 0x82000000 123.bmp
U-Boot# bmp info 0x82000000
Image size : 480 x 386
Bits per pixel: 24
Compression : 0
U-Boot# bmp display 0x82000000
================
结论:
啰啰嗦嗦的写了这么多,是因为准备工作很多,但真正需要的步骤很简单:
1. 定义LCD引脚的MUX;
2. 定义CONFIGS;
3. 使能LCD外设的时钟;
4. 定义LCD功能相关的结构体;
5. 使能背光和DISP的GPIO;
存在的问题:
1. 8位红色的[0:7]管脚分别是gpmc_ad[7:0],因此绘制PCB板的时候需要调回来;
2. lcd_data[0:7]代表蓝色,而不是绿色;
3. lcd_data[8:15]代表绿色,而不是蓝色;
4. lcd_ac_bias的定义:
* Active (TFT) mode. This signal acts as an output enable (OE) signal. It is used to signal the external LCD that the data is valide on the data bus (LCD_DATA).
因此AT043TN24屏的DE线,应该和lcd_ac_bias相连。当设置好为Active模式后,这个引脚就会自动在line初始位置和frame初始位置置低。
================
效果:
使用GIMP在电脑上显示的bmp图片:
AT043TN24的显示:
使用GIMP在电脑上显示的bmp图片:
AT043TN24的显示:
用户377235 2015-9-30 18:31
用户377235 2015-9-30 18:30