LCD驅動移植 Linux 2.6.22.19移植到S3C2410(GEC2410)

來源:互聯網
上載者:User

轉自:http://hi.baidu.com/iblogiam/item/9a608ae2357fbfa8c10d75db

 

limuscle:以下的操作時可行的,實測過。

Linux 2.6.22.19移植到S3C2410(GEC2410)之:LCD驅動移植

Linux 2.6.22.19移植到S3C2410(GEC2410)之:LCD驅動移植

參考文獻:
1. 《移植Linux2.6.22.2到博創2410-S(s3c2410A)(補:LCD驅動移植)》
http://blog.chinaunix.net/u1/34474/showart_410311.html
2. 《2410 移植LCD 驅動LTV350QV》
http://blog.chinaunix.net/u2/83636/showart_1733013.html
3.《S3C2410 下LCD 驅動程式移植及GUI 程式編寫》著作權所有:劉利國,是一篇經典的LCD移植文檔,移植前必看。網上google一下就有(PDF版)。

平台資訊:
目標板 :GEC2410
OS        :Fedora Cor8(FC8)
編譯器 :arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu(4.2.1)
LCD      :SUMSANG 的 LTV350QV_FOE 3.5 寸 320x240

移前注意:
如果你移植的是2.6.24的核心,那我想你就別往下看了,跟2.6.22有很多的區別,主要區別有:
一、在2.6.24核心中有了重大的資料結構變化,首先他把結構拆成了二部分,一個結構是s3c2410fb_display另一個結構是s3c2410fb_mach_info,所以先根據這二個資料結構進行拆分上述結構;
二、2.6.24結構中對寄存器lcdcon1-4全部用函數進行了自動化佈建,我們只需對lcdcon5進行設定,但是並不說明其他的資料不重要,或者不用設定,只是重點在lcdcon5這幾個數值上。
關於2.6.24的LCD驅動移植可以參考:
Linux 2.6.24.4移植到S3C2410(nano2410)之:LCD

移植步驟:
在Linux2.6.22.19下移植LCD驅動還是比較簡單,只要在arch/arm/mach-s3c2410/mach-smdk2410.c裡添加初始化s3c2410的LCD控制器時所需要的參數就好了。(不過LTV350QV的LCD就要另當別論了,下邊會有詳細介紹)!!!
1. 修改/arch/arm/mach-s3c2410/mach-smdk2410.c檔案
     1). 添加標頭檔
            #include <asm/arch/fb.h>

     2). 添加初始化s3c2410的LCD控制器時所需的參數(這些參數可以直接從同級目錄的mach-qt2410.c檔案複製並稍作修改,增快移植速度)。
   static struct s3c2410fb_mach_info S3C2410_lcd_cfg __initdata = {
        .type   =     S3C2410_LCDCON1_TFT, //這話很重要,看下邊特別說明(1)
        .regs   ={ //看特別說明(2)
        .lcdcon1       = S3C2410_LCDCON1_TFT16BPP |
                        S3C2410_LCDCON1_TFT |
                        S3C2410_LCDCON1_CLKVAL(0x04),
        .lcdcon2       = S3C2410_LCDCON2_VBPD(5) |
                        S3C2410_LCDCON2_LINEVAL(239) |
                        S3C2410_LCDCON2_VFPD(4) |
                        S3C2410_LCDCON2_VSPW(3),
        .lcdcon3       = S3C2410_LCDCON3_HBPD(13) |
                        S3C2410_LCDCON3_HOZVAL(319) |
                        S3C2410_LCDCON3_HFPD(20),
        .lcdcon4       = S3C2410_LCDCON4_MVAL(13) |
                        S3C2410_LCDCON4_HSPW(18),
        .lcdcon5       = S3C2410_LCDCON5_FRM565 |
                        S3C2410_LCDCON5_INVVLINE |
                        S3C2410_LCDCON5_INVVFRAME |
                        S3C2410_LCDCON5_PWREN |
                        S3C2410_LCDCON5_INVVCLK |
                        S3C2410_LCDCON5_HWSWP,
    },
    .width          = 320,
    .height         = 240,
    .xres           ={
              .min    = 320,
              .max    = 320,
              .defval = 320,
    },
    .yres           ={
              .min    = 240,
              .max    = 240,
              .defval = 240,
    },
    .bpp            ={
                .min    = 16,
                .max    = 16,
                .defval = 16,
        },
        //下邊設定看特別說明(3)
        .gpcup= 0xffffffff,             //禁止上拉
        .gpcup_mask= 0xffffffff,    //_mask 用於將寄存器清零
        .gpccon= 0xaa9556a9,  
        .gpccon_mask= 0xffffffff,
        .gpdup= 0xffffffff,
        .gpdup_mask= 0xffffffff,
        .gpdcon= 0xaaaaaaaa,
        .gpdcon_mask= 0xffffffff,
        .lpcsel= 0x00,         //LPC3600
};

    3)添加LCD控制器的寄存器參數設定函數
     static void __init smdk2410_init(void)
     {
            s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg);
            platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
           smdk_machine_init();
    }

特別說明:
(1)其中的".type    = S3C2410_LCDCON1_TFT,"一定要加,否則Linux會認為LCD是STN屏,出現花屏(像下雨一樣,藍色的)。

(2)這裡的regs設定不同款式的LCD是不同的,需要根據自己的LCD配置進行設定,你可以參考LCD手冊,也可以直接從開發板內建的LCD驅動中COPY過來,開發板內建的驅動一般為 driver/video/s3c2410fp.c 。我就是直接copy的,下邊是我開發板內建驅動該部分內容:
.regs = {
    .lcdcon1 = (5<<8) | (0<<7) | (3<<5) | (12<<1),
    .lcdcon2 = (5<<24) | (239<<14) |(4<<6) | (3),
    .lcdcon3 = (13<<19) | (319<<8) | (20),
    .lcdcon4 = (13<<8) | (18),
    .lcdcon5 = (1<<11) | (1<<10) | (1<<9) | (1<<8) | (0<<6) | (0<<1) | (1),
   },
直接使用數字就可以了,不需要每個都用變數來代替!!!

(3)這裡的設定可以依據LCD原理圖和手冊確定,不過更便捷的方式還是跟設定regs一樣,直接從開發板內建的driver/video/s3c2410fb.c 的LCD驅動中搜尋出來就好了!!!
    其中的*_mask 參數的作用是將要修改的寄存器參數先清零,這樣可以保證後面的設定作業正確。因為設定作業是置位操作,無法清零(參考我的參考資料1)。想瞭解其他各項的作用那就自個兒看手冊吧,那裡夠詳細的了!!!
好,mach-smdk2410.c檔案修改結束。!!!!
________________________________________

2.   如果你想去除10分鐘左右自動關閉LCD顯示的功能,那就進行這第二步吧!

        方法很簡單,注釋掉drivers\char\vt.c 的blank_screen_t(unsigned long dummy)的函數內容即可!!!不過我想對於一般的情況就不要去除這功能了,又能省電還能延長LCD使用壽命,幹嘛要自找麻煩呢!!!
________________________________________

3.   編譯核心,選中所裝驅動
#make menuconfig
Device Drivers >
       Graphics support --->
           <*> Support for frame buffer devices
           <*> S3C2410 LCD framebuffer support
           Console display driver support --->
                 <*> Framebuffer Console support                                                      

                 [*]   Framebuffer Console Rotation                                                   

                 [*] Select compiled-in fonts                                                         

                 [*]   VGA 8x8 font
                 [*]   VGA 8x16 font                                                                  

                 [*]   Mini 4x6 font
                 [*] Sparc console 8x16 font
           [*] Bootup logo --->
                 [*]   Standard 224-color Linux logo
________________________________________              

4.   如果你不是LTV350QV_FOE 這個系列的LCD,那一般你的工作就完成了,直接make zImage編譯核心並燒寫就可以了。
________________________________________

     不過,如果你不幸或有幸用的正好是LTV350QV_FOE這個系列的LCD,呵呵,保持好良好的心態繼續跟我來吧!!!真的,心態很重要!我當時也鬱悶的很,很不情願地繼續移植,結果可想而知,我為此付出了很慘烈的代價,整整浪費了我一整天的時間!!!不過也有點怪我那第二篇參考文獻,幹,寫就寫好點嘛,該寫什麼就把那個寫清楚點吧!總是這湊一點那湊一點,這含一點,那蓄一點,你以為你很含蓄呀!!!!搞什麼鳥子~~~!!!!!
(這個 LTV350QV 比較特殊的是,它的初始化需要通過 spi 匯流排寫 S6F2002 內部的寄存器,有人說,LTV350QV 比較麻煩的一點是還必須要進行 SPI 設定,但這也是它比較靈活的一面。) 這是鳥人說的,我也不知道是不是這樣,你們自個兒來判斷吧!!!!

5. 好,屁話不說,來吧,我們繼續!!!
        其實也很簡單,也就是在driver/video/s3c2410fb.c中加入個LCD的初始函數而已!!!這個函數我是直接參開發板內建的驅動拼接起來的!!如果你想自己寫,那你就自個人蔘考手冊寫吧,我就算了,已經很鬱悶了!!!!
       下邊是我根據開發板內建的s3c2410fb.c 驅動拼接起來的初始化LCD的代碼,並添加到driver/video/s3c2410fb.c中:(注意:一定要根據自己開發板的驅動來,直接用My Code,抱歉,我不敢保證你能移植成功~~~~)
第一部分(定義):
typedef struct _LTV350qv_spi_data_{
     unsigned char   Device_ID;                     //ID of the device
    unsigned int    Index;                            //index of register
     unsigned long Structure;                      //structure to be writed
}LTV350QV_SPI_Data;

//micro for LTV350QV_POE
#define CS_H            __raw_writel(__raw_readl(S3C2410_GPCDAT)|(1<<8), S3C2410_GPCDAT)   //MAKE_HIGH(LTV350QV_CS)
#define CS_L            __raw_writel(__raw_readl(S3C2410_GPCDAT)&~(1<<8), S3C2410_GPCDAT)   //MAKE_LOW(LTV350QV_CS)
#define SCLK_H __raw_writel(__raw_readl(S3C2410_GPCDAT)|(1<<9), S3C2410_GPCDAT)        //MAKE_HIGH(LTV350QV_SCL)
#define SCLK_L __raw_writel(__raw_readl(S3C2410_GPCDAT)&~(1<<9), S3C2410_GPCDAT)       //MAKE_LOW(LTV350QV_SCL)
#define SDI_H           __raw_writel(__raw_readl(S3C2410_GPCDAT)|(1<<10), S3C2410_GPCDAT)    //MAKE_HIGH(LTV350QV_SDI)
#define SDI_L           __raw_writel(__raw_readl(S3C2410_GPCDAT)&~(1<<10), S3C2410_GPCDAT)    //MAKE_LOW(LTV350QV_SDI)
#define RST_H           __raw_writel(__raw_readl(S3C2410_GPDDAT)|(1<<0), S3C2410_GPDDAT)    //MAKE_HIGH(LTV350QV_RST)
#define RST_L           __raw_writel(__raw_readl(S3C2410_GPDDAT)&~(1<<0), S3C2410_GPDDAT)    //MAKE_LOW(LTV350QV_RST)

第二部分(初始函數):
//***************************************************************
//**********these functions for SUMSUN LTV350QV TFT LCD****************
//***************************************************************
//short delay for about 90*time ns
static void LTV350QV_Short_Delay(u_char time)
{
    //u_char i;
     //for(i=0;i<time*10;i++) ;                 //about 180 ns
      ndelay(150);
}

static void LTV350QV_Rst(void)
{
        RST_L;
        mdelay(1);
        RST_H;
        mdelay(1);
}

static void LTV350QV_Register_Write(LTV350QV_SPI_Data regdata)
{
u_char i,temp1;
u_int temp2;
u_long temp3;
unsigned long flags;           

//write index
temp1=regdata.Device_ID<<2 | 0<<1 | 0<<0;          //register index
temp2=regdata.Index;
temp3=(temp1<<24) | (temp2<<8);

local_irq_save(flags);

CS_L;
LTV350QV_Short_Delay(1);
for(i=0;i<24;i++)
   {
    SCLK_L;
    if(temp3 & (1<<(31-i)) )              //if is H
     SDI_H;
    else
     SDI_L;
    LTV350QV_Short_Delay(1);      //setup time
    SCLK_H;
    LTV350QV_Short_Delay(1);     //hold time
   }
CS_H;

LTV350QV_Short_Delay(5);

//write instruction
temp1=regdata.Device_ID<<2 | 1<<1 | 0<<0;       //instruction
temp2=regdata.Structure;
temp3=(temp1<<24) | (temp2<<8);

CS_L;
LTV350QV_Short_Delay(1);
for(i=0;i<24;i++)
   {
    SCLK_L;
    if(temp3 & (1<<(31-i)) )             //if is H
     SDI_H;
    else
     SDI_L;
    LTV350QV_Short_Delay(1);
    SCLK_H;
    LTV350QV_Short_Delay(1);
   }
CS_H;

local_irq_restore(flags);
}

/****************************************
* *
****************************************/
static void LTV350QV_Write(u_int index, u_int regdata)
{
LTV350QV_SPI_Data WriteData;

WriteData.Device_ID=LTV350QV_POE; //0x1d
WriteData.Index=index;                     //
WriteData.Structure=regdata;

LTV350QV_Register_Write(WriteData);
}
/****************************************
* *power ON sequence
****************************************/
static void LTV350QV_Power_ON(void) //粉色部分的代碼請參考內建驅動的pxafb_setup_gpio部分,或者你就跟蹤LTV350QV_Power_ON這函數,也能找到具體實現的代碼!!!
{
__raw_writel(0xaa9556a9, S3C2410_GPCCON); //Initialize VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND
                                                                                     //LCDVF[0],[1],[2]---output;VD[0],[1],[2]----output.            

__raw_writel(0xffffffff, S3C2410_GPCUP);   // Disable Pull-up register

//DPRINTK("%s()\n", __FUNCTION__);

   LTV350QV_Write(9, 0x0000);
   mdelay(150);
   LTV350QV_Write(9, 0x4000);
   LTV350QV_Write(10, 0x2000);
   LTV350QV_Write(9, 0x4055);
   mdelay(550);
   LTV350QV_Write(1, 0x409d);
   LTV350QV_Write(2, 0x0204);
LTV350QV_Write(3, 0x0100);
   LTV350QV_Write(4, 0x3000);
   LTV350QV_Write(5, 0x4003);
   LTV350QV_Write(6, 0x000a);
   LTV350QV_Write(7, 0x0021);
   LTV350QV_Write(8, 0x0c00);
   LTV350QV_Write(10, 0x0103);
LTV350QV_Write(11, 0x0301);
   LTV350QV_Write(12, 0x1f0f);
   LTV350QV_Write(13, 0x1f0f);
   LTV350QV_Write(14, 0x0707);
   LTV350QV_Write(15, 0x0307);
   LTV350QV_Write(16, 0x0707);
   LTV350QV_Write(17, 0x0000);
   LTV350QV_Write(18, 0x0004);
   LTV350QV_Write(19, 0x0000);

   mdelay(200);
   LTV350QV_Write(9, 0x4a55);
   LTV350QV_Write(5, 0x5003);

__raw_writel(0xaaaaaaaa, S3C2410_GPDCON);
__raw_writel(0xffffffff, S3C2410_GPDUP);
__raw_writel(3, S3C2410_LCDINTMSK);    // MASK LCD Sub Interrupt
__raw_writel(0, S3C2410_TPAL);    // Disable Temp Palette
__raw_writel(0, S3C2410_LPCSEL);    // Disable LPC3600
}

/**********************************
* *power OFF sequence
**********************************/
static void LTV350QV_Powen_OFF(void) //沒用到
{

/* GON -> 0, POC -> 0 */
LTV350QV_Write(9, 0x4055);
/* DSC -> 0 */
LTV350QV_Write(5, 0x4003);
   /* VCOMG -> 0 */
   LTV350QV_Write(10, 0x0000);

   mdelay(20);

/* AP[2:0] -> 000 */
LTV350QV_Write(9, 0x4000);
}
//------------------------------------------------------end LTV350-POE

第三部分(把上邊的LTV350QV_Power_ON函數加入執行):
      加入位置為static int __init s3c2410fb_probe(struct platform_device *pdev),具體位置我是加在:
    ret = s3c2410fb_init_registers(info);
    ret = s3c2410fb_check_var(&fbinfo->var, fbinfo);
   ret = register_framebuffer(fbinfo);
    if (ret < 0) {
               printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret);
              goto free_video_memory;
    }
    LTV350QV_Power_ON();
其他位置是否可以呢?SORRY,我也不知道,一般可以吧!!!呵呵,如果你興趣,可以試過!!!!

6. 呵呵,怎麼樣,這第五步夠嗆的吧!!!不過沒事,也就這些了!!!忘記配置核心的就去配置下,選項跟上邊的一樣!接著編譯核心,燒寫開發板,啟動。。。。。你是否看見了LCD上顯示的可愛的企鵝映像呢???看見了?哈哈。。。那恭喜你!如果沒看見,那就請你重新檢查下是否哪裡漏掉了,但一定要保持好良好心態哦,這個很重要!!!!
啟動資訊有:
       Console: switching to colour frame buffer device 80x40
        fb0: s3c2410fb frame buffer device

7. 但你如果想在LCD上顯示自己的Logo,那下面我介紹一下自訂Logo的方法:
    (1)進入linux的kde圖形介面,使用The GIMP 影像編輯器(其他也可以)開啟你想要的影像檔,依次選擇映像->模式->索引顏色,將顏色改為224色;至於圖片大小,不要大於你的顯示器解析度就好,最後將檔案儲存為ppm格式(ASCii碼),檔案名稱為:logo_linux_clut224.ppm。
    (2)將logo_linux_clut224.ppm拷貝到/drivers/video/logo檔案夾下,替換原有的檔案(記得備份啊,以防萬一)。
    (3)重新編譯核心,燒寫開發板啟動。

8. 好文章分享(網上自己找)

1.
Linux-2.6.20的LCD驅動分析

2. LCD移植過程

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.