日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TQ2440平台上LCD驱动的移植

發布時間:2025/5/22 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TQ2440平台上LCD驱动的移植 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考:

http://liu1227787871.blog.163.com/blog/static/205363197201242393031250/

http://blog.csdn.net/cumtgao/article/details/8649006

http://www.360doc.com/content/12/0424/17/9159905_206213245.shtml

http://blog.csdn.net/yj4231/article/details/7878762

?

硬件平臺:TQ2440

LCD型號:WXCAT43,分辨率480*270

U-boot版本:u-boot-2015.04

內核版本:Linux-3.14

?

作者:彭東林

郵箱:pengdonglin137@163.com

?

下面主要完成Linux下面的LCD驅動的移植。

?

首先我們需要知道一些LCD的知識:

我們使用的LCD是TFT類型,下面是S3C2440的LCD控制器的信號引腳:

?

下面是TQ2440的LCD原理圖:

?

下面介紹一下這些引腳的功能:

VCLK:發出lcd時鐘信號,每來一個時鐘,就會在屏幕上顯示一個像素

VLINE:發出lcd行掃描信號

VFRAME:發出lcd楨掃描信號

VM:VDEN,有效時才會在屏幕上顯示象素

LCD_PWREN:發出lcd面板電源使能控制信號

VD[3]——VD[7]?? :lcd數據總線

VD[10]——VD[15] :lcd數據總線

VD[19]——VD[23] :lcd數據總線

?

各信號的含義

VSYNC:幀同步信號

每發出一個脈沖,表示新的一屏圖像數據開始傳送。

HSYNC:行同步信號

每發出一個脈沖,表示新的一行圖像數據開始傳送。

VCLK:像素時鐘信號

每發出一個脈沖,表示新的一個點圖像數據開始傳送。

LEND:行結束信號

?

VBPD:表示在一幀圖像開始時,幀同步信號以后的無效的行數,對應驅動中的upper_margin

VFBD:表示在一幀圖像結束后,幀同步信號以前的無效的行數,對應驅動中的lower_margin

VSPW:表示垂直同步脈沖的寬度,單位是行數

HBPD:表示從水平同步信號開始到一行的有效數據開始之間的vclk的個數,對應驅動中的left_margin;

HFPD:表示一行的有效數據結束到下一個水平同步信號開始之間的vclk的個數,對應驅動中的right_margin;

HSPW:表示水平同步信號的寬度,單位是vclk的個數

?

下面我們結合兩張圖理解一下:

?

下面我們結合TQ2440上的LCD芯片手冊分析:

注意上面這幅圖下面的文字中對CLK和H的說明,其中:CLK表示的是像素時鐘周期,H表示的是行同步時鐘周期。可以發現上面圖中的規律:

525=480+2+41+2?? 他們的單位都是CLK

286=272+2+10+2?? 他們的單位都是H

所以幀率就是: 1/(525*286*像素時鐘周期) Hz

這樣我們也容易理解S3C2440上的兩個公式:

VCLK(Hz) = HCLK/[(CLKVAL+1)x2]?? 像素時鐘頻率(Hz)

Frame Rate = 1/ [ { (VSPW+1) + (VBPD+1) + (LIINEVAL + 1) + (VFPD+1) } x {(HSPW+1) + (HBPD +1)+ (HFPD+1) + (HOZVAL + 1) } x { 2 x ( CLKVAL+1 ) / ( HCLK ) } ] ? 幀率(Hz)

對照上面的兩幅圖,我們采用典型值來填充這個結構體

static struct s3c2410fb_display tq2440_lcd_cfg __initdata = { ? .lcdcon5 = S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_PWREN | S3C2410_LCDCON5_HWSWP, ? .type = S3C2410_LCDCON1_TFT, ? .width = 480, .height = 272, ? .pixclock = 100000, .xres = 480, .yres = 272, .bpp = 16, .left_margin = 2, /* For HBPD+1, 這里我們取的都是典型值 */ .right_margin = 2, /* For HFPD+1 */ .hsync_len = 41, /* For HSPW+1 */ .upper_margin = 2, /* For VBPD+1 */ .lower_margin = 2, /* For VFPD+1 */ .vsync_len = 10, /* For VSPW+1 */ }; ? #define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2)) #define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2)) ? static struct s3c2410fb_mach_info tq2440_fb_info __initdata = { .displays = &tq2440_lcd_cfg, .num_displays = 1, .default_display = 0, ? /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN * and disable the pull down resistors on pins we are using for LCD * data. */ ? .gpcup = (0xf << 1) | (0x3f << 10), ? .gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE | S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM | S3C2410_GPC8_VD0 | S3C2410_GPC9_VD1 | S3C2410_GPC10_VD2 | S3C2410_GPC11_VD3 | S3C2410_GPC12_VD4 | S3C2410_GPC13_VD5 | S3C2410_GPC14_VD6 | S3C2410_GPC15_VD7), ? .gpccon_mask = (S3C2410_GPCCON_MASK(1) | S3C2410_GPCCON_MASK(2) | S3C2410_GPCCON_MASK(3) | S3C2410_GPCCON_MASK(4) | S3C2410_GPCCON_MASK(8) | S3C2410_GPCCON_MASK(9) | S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) | S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) | S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)), ? .gpdup = (0x3f << 2) | (0x3f << 10), ? .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 | S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 | S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 | S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 | S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 | S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23), ? .gpdcon_mask = (S3C2410_GPDCON_MASK(2) | S3C2410_GPDCON_MASK(3) | S3C2410_GPDCON_MASK(4) | S3C2410_GPDCON_MASK(5) | S3C2410_GPDCON_MASK(6) | S3C2410_GPDCON_MASK(7) | S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)| S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)| S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)), ? // .lpcsel = ((0xCE6) & ~7) | 1<<4, // 禁用lpsel,因為如果不是使用三星LPC3600/LCC3600 LCD,必須禁止LPC3600/LCC3600模式(寫入0到TCONSEL)。 }; ?

?

接下來要說的參數是pixclock,他是用來計算像素頻率的。

在driver/video/s3c2410fb.c中:

static void s3c2410fb_activate_var(struct fb_info *info) { struct s3c2410fb_info *fbi = info->par; void __iomem *regs = fbi->io; int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT; struct fb_var_screeninfo *var = &info->var; int clkdiv; ? clkdiv = DIV_ROUND_UP(s3c2410fb_calc_pixclk(fbi, var->pixclock), 2); ? dprintk("%s: var->xres = %d\n", __func__, var->xres); dprintk("%s: var->yres = %d\n", __func__, var->yres); dprintk("%s: var->bpp = %d\n", __func__, var->bits_per_pixel); ? if (type == S3C2410_LCDCON1_TFT) { s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs); --clkdiv; if (clkdiv < 0) clkdiv = 0; } else { s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs); if (clkdiv < 2) clkdiv = 2; } ? fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); ? ...... }

?

上面計算得到的clkdiv就是VCLK(Hz) = HCLK/[(CLKVAL+1)x2] 中的CLKVAL.

static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, unsigned long pixclk) { unsigned long clk = fbi->clk_rate; unsigned long long div; ? /* pixclk is in picoseconds, our clock is in Hz * * Hz -> picoseconds is / 10^-12 */ ? div = (unsigned long long)clk * pixclk; div >>= 12; /* div / 2^12 */ do_div(div, 625 * 625UL * 625); /* div / 5^12 */ ? dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div); return div; }

首先pixclock作為參數傳遞給了s3c2410fb_calc_pixclk函數,當該函數執行完以后

clkdiv? = (clk * pixclk? / 10^12 + (2 - 1))/ 2。

隨后由于是采用TFT模式,將clkdiv-1。最后得:

clkdiv? = (clk * pixclk? / 10^12 + (2 - 1))/ 2 - 1,

這里的clk即為HCLK,LCD模塊使用HCLK作為時鐘源,從內核啟動代碼中可以看到HCLK是100MHz

為方便觀察,將前面datasheet中的計算公式復制在此:CLKVAL = HCLK / VCLK / 2 -1。

我們可以看出1/VCLK = pixclk / 10^12,也就是說pixclk = 10^12 / VCLK。 從LCD的芯片手冊上可以看到VCLK的典型值是9MHz,我們取10MHz。

因此,pixclk=100000。

其實在內核的參考文檔中有這樣一段話:

The speed at which the electron beam paints the pixels is determined by the
dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions
of cycles per second), each pixel is 35242 ps (picoseconds) long:
??? 1/(28.37516E6 Hz) = 35.242E-9 s

也就是說VCLK的倒數,再乘10^12即為pixclk。picoseconds單位表示微微秒,即10^12。

?

完。

轉載于:https://www.cnblogs.com/pengdonglin137/p/4604913.html

總結

以上是生活随笔為你收集整理的TQ2440平台上LCD驱动的移植的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。