原创 为AM335x移植Linux内核主线代码(26)U-Boot之LCD(一)

2015-1-26 11:29 3383 11 11 分类: MCU/ 嵌入式 文集: Linux Kernel的DTS

写在前面:关于AT043TN24的背光
背光电路一般是独立的,无论从哪个地方给背光LED供电都可以,不需要AM335x的LCD控制器参与。
AT043TN24需要使用+28V作为液晶背光,因此需要boost芯片,我使用的是LM2733,它体积较小电路简单:

lm2733_sch.jpg



控制背光的GPIO为113,因此需要定义pin_mux:
(Note: 这是LM2733的使能引脚,背光的亮度调节需要PWM,放在第30小节中。)
static struct module_pin_mux blk_pin_mux[] = {
        {OFFSET(mcasp0_ahclkr), MODE(7)},
        {-1},
};

然后执行:
int board_init(void)
{
        /* other actions */
        
        configure_module_pin_mux(blk_pin_mux);
        gpio_request(113, "lcd_light");
        gpio_direction_output(113, 0);
        int i;
        for (i = 0;; i++) {
                gpio_set_value(113, 1);
                mdelay(500);
                gpio_set_value(113, 0);
                mdelay(500);
        }
}

编译之后重新运行u-boot,就可以看到液晶的背光在闪啦~

当然,在实际的使用中,还得注意上电顺序:
 * 首先是LCD的POWER;
 * 然后是signal interface;
 * 其次是display on/off;
 * 最后才是背光。

======================================================
======================================================
使用AT043TN24的准备工作:
驱动AT043TN24需要做两个准备工作,一是阅读AM335x关于LCD控制器的部分,二是阅读AT042TN24用户手册中指令的部分。
准备工作一:"AM335x ARM ® CortexTM-A8 Microprocessors (MPUs) Technical Reference Manual"
-- LCD Controller

13.1 Introduction
13.1.1 Purpose of the Peripheral

The LCD controller consists of two independent controllsers, the Raster and the LCD Interface Display Driver (LIDD) controller. Each controller operates independently from the other and only one of them is active at any given time.

 * The Raster Controller handles the synchronous LCD interface.
 * The LIDD Controller supports the asynchronous LCD interface.

(Raster controller和LCD Interface Display Driver,前者是同步的,后者是异步的。像我这次用的AT043TN24使用的是前者Raster Controller,它的特点是数据在CLK的边沿锁存进去。)

13.1.2 Features
Supports up to 24-bit data output; 8 bit-per-pixel (RGB).
Supports up to WXGA (1366x768) resolution.

13.2 Integration
13.2.1 LCD Controller Connectivily Attributes
13.2.2 LCD Controller Clock and Reset Management
13.3.3 LCD Controller Pin List

 * lcd_cp (O): Pixel Clock in Raster model Read Strobe or Read/Write Strobe in LIDD mode.
 * lcd_pixel_i[15:0] (I): LCD Data Bus input (for LIDD mode only)
 * lcd_pixel_o[23:0] (O): LCD Data Bus output
 * lcd_lp (O): Line Clock or HSYNC in Raster mode; Write Strobe or Direction bit in LIDD mode.
 * lcd_fp (O): Frame Clock or VSYNC in Raster mode; Address Latch Enable in LIDD mode.
 * lcd_ac (O): AC bias or Latch Enable in Raster mode; Primary chip Select/Primary Enable in LIDD MPU Hitachi mode.
 * lcd_mclk (O): N/A in Raster mode; Memory Clock/Secondary chip select/Secondary Enable in LIDD Synchronous/Async MPU/Hitachi mode.
 
(AT043TN24除了使用那24个RGB口之外,不包括背光控制IO还需要三条线,CLK,DISP,DE,分别是时钟、使能显示和数据使能,具体应该怎么和AM335x相连,还得继续往下看。)
 
13.3 Functional Description
13.3.1 Clocking
13.3.1.1 Pixel Clock (LCD_PCLK)
13.3.1.2 Horizontal Clock (LCD_HSYNC)
13.3.1.3 Vertical Clock (LCD_VSYNC)
13.3.1.4 !LCD_AC_BIAS_EN

 * Passive (STN) mode. To prevent a dc charge within the screen pixels, the power and ground supplies of the display are periodically switched. The Raster Controller signal the LCD to switch the polarity by toggling this pin (!LCD_AC_BIAS_EN).
 * Active (TFT). This signal acts as an output enable (OE) signal. It is used to signal the external LCD that the data is valid on the data bus (LCD_DATA).
 
(!LCD_AC_BIAS_EN用来指示数据有效:当它为高电平的时候,意为LCD_DATA上面的数据是可用的;而AT043TN24的DE用来指示数据使能:当它为高电平的时候,LCD_DATA上面的数据被认为是valid,否则就是invalid。可见,AM335x的!LCD_AC_BIAS_EN是要和AT043TN24的DE相连的。)

13.3.2 LCD External I/O Signals

 * LCD_VSYNC:  OUT
  Raster controller: Frame clock the LCD uses to signal the start of a new frame of pixels. Also used by TFT displays as the vertical synchronous signal.
 
 * LCD_HSYNC:  OUT
  Raster controller: Line clock the LCD uses to signal the end of a line of pixels that transfers line data from the shift register to the screen and to increment the line pointer(s). Also used by TFT displays as the horizontal synchronization signal.
    
 * LCD_PCLK:  OUT
  Raster controller: Pixel clock the LCD uses to clock the pixel data into the line shift register. In passive mode, the pixel clock transitions only when valid data is available on the data lines. In active mode, the pixel clock transitions continuously, and the ac-bias pin is used as an output enable to signal when data is available on the LCD pin.
 
(AT043TN24的时钟线只有一根CLK,它用来锁存每个pixel值,所以它应该连接这里的LCD_PCLK。LCD_PCLK在passive模式下,当数据有效时它才有时钟输出;而在active模式下,是一直会输出时钟信号,由!LCD_AC_BIAS_EN告诉液晶哪些时刻的数据是有效的。)
 
 * !LCD_AC_BIAS_EN:  OUT
  Raster controller: ac-bias used to signal the LCD to switch the polarity of the power supplies to the row and column axis of the screen to counteract DC offset. Used in TFT mode as the output enable to signal when data is latched from the data pins using the pixel clock.
 
 * LCD_MCLK: OUT
  Raster controller: not used.
 
 * LCD_D[23:0]:  Raster OUT
  LCD data bus, providing a 4-, 8-, 16- or 24- data path.
  Raster controller: For monochrome displays, each signal represents a pixel; for passive color displays, grouping of three signals represent one pixel (red, green, and blue.)
  LCD_DATA[3:0] is used for monochrome displays of 2, 4, and 8 BPP; LCD_DATA[7:0] is used for color STN displays and LCD_DATA[15:0] or LCD_DATA[23:0] is used for active (TFT) mode.
 
(AT043TN24可以使用LCD_DATA[15:0]做R5/G6/B5驱动,这样可以节省8根数据线;这里采用了R8/G8/B8驱动,LCD_DATA[23:0]都分配给液晶了。)

(AT043TN24还有一个DISP引脚,使能显示,给它分配一个普通的IO口即可。)

13.3.3 DMA Engine
It operates on one or two frame buffers, which are set up during initialization. Using two frame buffers (ping-pong buffers) enables the simultaneous operation of outputting the current video frame to the external display and updating the next video frame. The ping-pong buffering approach is preferred in most applications.

(推荐使用双缓冲。)

13.3.3.1 Interrupts
13.3.3.1.1 LIDD Mode
13.3.3.1.2 Raster Mode

 * Output FIFO under-run
 * Frame synchronization lost
 * Palette loaded
 * AC bias transition
 * Frame transfer completed
 
13.3.3.1.3 Interrupt Handling
13.3.4 LIDD Controller
13.3.5 Raster Controller
13.3.5.1 Logical Data Path

 -> Data source (frame buffers)
 -> Input FIFO
 -> TFT (active)
 -> 24 BPP
 -> Output pins

13.3.5.2 Frame Buffer
13.3.5.3 Palette
13.3.5.4 Gray-Scaler/Serializer
13.3.5.4.1 Passive (STN) Mode
13.3.5.4.2 Active (TFT) Mode
 * The gray-scaler/serializer is bypassed.
 
13.3.5.4.3 Summary of Color Depth
13.3.5.5 Output Format
13.3.5.1 Passive (STN) Mode
13.3.5.2 Active (TFT) Mode
13.3.5.6 Subpicture Feature
13.3.6 Interrupt Conditions
13.3.6.1 Highlander 0.8 Interrupts
13.3.6.1.1 Highlander Interrupt Basics
13.3.6.1.2 Raw Status Register
13.3.6.1.3 Masked Status Register
13.3.6.1.4 Interrupt Enable Set Register
13.3.6.1.5 Interrupt Enable Clear Register
13.3.6.1.6 End of Interrupt Register
13.3.6.2 Interrupt Sources
13.3.6.2.1 Overview of Interrupt Sources
13.3.6.2.1.1 DMA End of Frame 0 and End of Frame 1 Interrupt
13.3.6.2.1.2 Palette Loaded Interrupt
13.3.6.2.1.3 FIFO Underflow Interrupt
13.3.6.2.1.4 AC Bias Count Interrupt
13.3.6.2.1.5 Sync Lost Interrupt
13.3.6.2.1.6 Recurrent Frame Done Interrupt
13.3.6.2.1.7 LIDD or Raster Frame Done Interrupt
13.3.7 DMA
13.3.8 Power Management

13.4 Programming Model
13.4.1 LCD Character Displays
13.4.1.1 Configuration Registers, Setup, and Settings
13.4.1.1.1 Configuration Registers
13.4.1.1.2 Defining Panel
13.4.1.2 CPU Initiated Data Bus Transactions
13.4.1.2.1 Initiating Data Bus Transactions
13.4.1.3 DMA Initiated Data Bus Transactions for LIDD
13.4.1.3.1 DMA Overview for MPU Bus Output
13.4.1.3.2 MCU/LIDD DMA Setup: Example Pseudo Code
13.4.1.4 Passive Matrix
13.4.1.4.1 Monochrome Bitrate Awareness
13.4.2 Active Matrix Displays
13.4.2.1 Interfacing to Dual LVDS Transmitters
13.4.3 System Interaction
13.4.3.1 DMA End of Frame Interrupts
13.4.4 Patelle Lookup
13.4.5 Test Logic
13.4.6 Disable and Software Reset Sequence

In Raster Modes, the module must be disabled before applying a software reset. When cfg_lcden is set to '0' to disable the module, the output continues to the end of the current frame.

13.4.7 Precedence Order for Determining Frame Buffer Type
13.5 LCD Registers

======================================================
准备工作二:AT043TN24的用户手册
它的分辨率是480x272;
工作在+3.3V下,背光电压+28V;
信号需要24根RGB线,以及CLK、DISP、DE三根指令线;

======================================================
======================================================
准备工作完成之后,就可以着手开始修改U-Boot了:
(PS:直接用U-Boot的IO口控制方法来驱动AT043TN24不可取,因为AT043TN24要求的CLK在9MHz左右;而使用__raw_writel直接操作GPIO_SETDATAOUT和GPIO_CLEARDATAOUT寄存器,最快也只能达到1us。所以,还是得使用AM335x的LCD外设功能!)
(PS:board/siemens/pxm2,这块西门子的电路板也是使用AM335x为CPU,使用了LCD外设,因此可以以它为参考,编写自己的board.c文件。)

================
Step 1: 然后来了解几个重要的结构体的概念(随着学习的过程来添加):
 * 在include/video_fb.h里面,定义了struce GraphicDevice:
typedef struct {
    unsigned int isaBase;
    unsigned int pciBase;
    unsigned int dprBase;
    unsigned int vprBase;
    unsigned int cprBase;
    unsigned int frameAdrs;
    unsigned int memSize;
    unsigned int mode;
    unsigned int gdfIndex;
    unsigned int gdfBytesPP;
    unsigned int fg;
    unsigned int bg;
    unsigned int plnSizeX;
    unsigned int plnSizeY;
    unsigned int winSizeX;
    unsigned int winSizeY;
    char modeIdent[80];
} GraphicDevice;

plnSizeX是显示屏的横向分辨率,plnSizeY是显示屏的竖向分辨率。
GraphicDevice描述了一个显示设备。

 * 在include/linux/fb.h里面定义了struct fb_info:
struct fb_info {
        int node;
        int flags;
        struct fb_var_screeninfo var;   /* Current var */
        struct fb_fix_screeninfo fix;   /* Current fix */
        struct fb_monspecs monspecs;    /* Current Monitor specs */
        struct fb_pixmap pixmap;        /* Image hardware mapper */
        struct fb_pixmap sprite;        /* Cursor hardware mapper */
        struct fb_cmap cmap;            /* Current cmap */
        struct list_head modelist;      /* mode list */
        struct fb_videomode *mode;      /* current mode */

        char *screen_base;      /* Virtual address */
        unsigned long screen_size;      /* Amount of ioremapped VRAM or 0 */
        void *pseudo_palette;           /* Fake palette of 16 colors */
#define FBINFO_STATE_RUNNING    0
#define FBINFO_STATE_SUSPENDED  1
        u32 state;                      /* Hardware state i.e suspend */
        void *fbcon_par;                /* fbcon use-only private area */
        /* From here on everything is device dependent */
        void *par;
};

fb的意思是frame buffer,它描述了桢缓冲区的概念。

 * 在include/lcd.h中定义了vidinfo_t:(不同的架构其具体定义也是不同的,AM335x并没有在它的ifdef中被列举,所以会使用这个默认的定义)
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 */

        ushort  *cmap;          /* Pointer to the colormap */

        void    *priv;          /* Pointer to driver-specific data */
} vidinfo_t;

为LCD定义的结构体挺多的,用到什么就grep它的定义。
上面这几个也不一定很重要=_=~

================
Step 2: 为config文件增加lcd相关的宏定义。

#define CONFIG_VIDEO
#define CONFIG_VIDEO_DA8XX
#define CONFIG_CFB_CONSOLE
#define CONFIG_CMD_BMP
#define DA8XX_LCD_CNTL_BASE     0x4830E000
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
#define VIDEO_TSTC_FCT          serial_tstc
#define VIDEO_GETC_FCT          serial_getc
#define VIDEO_KBD_INIT_FCT      0
#define CONFIG_VIDEO_LOGO


 * 使用CONFIG_SYS_CONSOLE_IS_IN_ENV宏,来告诉U-Boot使用env中定义的console;如果不增加它,U-Boot就会搜索LCD作为console输出,而此时我的LCD还未被初始化;使用printenv打印环境变量:“console=ttyO0,115200n8”。
 * 使用CONFIG_CMD_BMP宏,来添加在屏幕上显示bmp图片的功能,从SD卡、USB存储、TFTP服务器等等都可以加载图片放置在内存的相应位置,再使用bmp命令来显示。
 * 使用CONFIG_CFB_CONSOLE宏,意为添加将显示器console的驱动;drv_keyboard_init函数就会被stdio_init函数调用;drv_keyboard_init函数用来设置AM335x的LCD外设,以及执行其他和LCD相关的初始化工作。显示器作为console时,还需要定义输入设备,因此添加VIDEO_TSTC_FCT、VIDEO_GETC_FCT以及VIDEO_KBD_INIT_FCT。

================
Step 3: 理解U-Boot关于驱动文件da8xx-fb.c和da8xx-fb.h。
====
http://processors.wiki.ti.com/index.php/DA8xx_LCDC_Linux_FB_FAQs?keyMatch=DA8xx&tisearch=Search-EN
====
DA8xx LCDC Linux FB FAQs
1. About this page
This page describes the flicker/tearing issue faced on AM335x when graphics(SGX)/Android comes up. Also describes root cause and its solution.

2. Introduction
AM335x LCD controller is based LCDC IP of DA8xx which has 2 DMA channels(channel 0 and channel 1), controller ping pongs between them in dual frame buffer mode on every other frame done interrupt. Linux frame buffer driver uses 2 DDR frame buffers as ping pong buffers. And it is expected to feed the filled buffer on every frame done callback.

3. DMA channel 0/1 ping ponging
4. Recommended Ping Pong usage
5. Host CPU Keep Out Regions
6. Issue with Linux FB use case
7. Solution or work around for issue
8. Limitation with above solution
9. Other solution
10. Backup section
11. Flicker due to underflow error

好吧,上面的帖子主要是讲ping pong是怎么工作的,那再来看看下面这个:
====
http://processors.wiki.ti.com/index.php/AM335x_LCD_Controller_Driver%27s_Guide
AM335x LCD Controller Driver's Guide
1. Introduction
LCD controller(LCDC) on AM335x is an updated version of LCDC that is found on OMAP-L138 SoC. It has following updates in comparision with OMAP-L138
 * Interrupt configuration and status registers are different.
 * Increased resolution of 2048*2048.
 * 24 bits per pixel active TFT raster configuration.
So da8xx-fb LCD driver can be used by having enhancements under LCD_VERSION2 code. This update in LCDC version can be detected by reading PID register.

(由于要通过lcd_ctrl_init为外设LCD进行初始化之后,video_hw_init函数才能进行LCD_VERSION的读取,所以这里先认为它就是LCD_VERSION2。)

2. LCDC on AM335x Soc
 * LCDC has 2 interface clocks, L3 peripheral and L4LS peripherial.
 * LCDC functional clock can be mux selected among DISPLAY PLL CLKOUTM2, CORE PLLCLOCKM5 OR PER PLLCLKOUTM2. Supports MAX pixel clock of ~126MHz, configure DISPLAY PLL for 600MHz.
 * LCD_DATA[0-15] pins are in mode0 and LCD_DATA[16-23] are in mode1.
 * LCD is enabled on General Purpose EVM operating in profile 0/1/2 and on IP-Phone.
 * Backlight is through eCAP0_in_PWM0_out pin, controls brightness via eCAP0 module. LCD EVM also has alternative backlight control via TLC59108 power control chip. This is via do not implement(DNI) R23 register on non-alpha boards, only populated in-case of non-availability of eCAP0_in_PWM0_out pin.
 
(由da8xx-fb.c中调用的clk_get(2)可知,它的LCDC时钟由sysclk2获得,但是clk_get函数并没有在AM335x中被定义,所以需要自己编写,可以直接返回CLKPM2的值192MHz,也可以参考下面的帖子:)
(http://patchwork.ozlabs.org/patch/264389/)
(为了控制LM2733,需要两个IO,一个做shutdown的使能,一个做负载的PWM波切换。)

3. Driver Configuration
3.1 Building as Loadable Kernel Module
4. Usage and Verification
(上面这几个小节的内容是基于Linux系统的,而不是U-Boot。)

通过这两个帖子,可以知道,要成功驱动LCD,就需要知道如何配置da8xx-fb.c和da8xx-fb.h的结构体参数,以及调用其中的函数。
 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /3 下一条