標籤:des android cWeb style blog color io os 使用
Platform:Freescale; Android 4.2.2; Kernel-3.0.35
LCD:奇美V500HK1 - 50 inch -
介面:LVDS
板端LVDS介面:
可以看到是30pin的介面,可以支援雙通道(2-channel)。
奇美Datasheet關鍵參數:
關鍵的幾個參數:Pixel clock = 74.25MHz*2 = 148.5MHz ; xres = 960*2 = 1920 ; yres = 1080 ; H-Blank = 140*2 = 180 ; V-Blank = 45
註:
1. 可能是由於雙通道的關係,水平方向的資料都要乘以2。
2. 文檔未定義back、front、uper、lower 的margin,vsync_length 和 hsync_length也未定義。
LVDS關於知識
LVDS:Low Voltage Differential Signal,低壓差分訊號。
差分訊號:一種訊號傳輸的技術,區別於傳統的一根訊號線一根地線的做法,差分傳輸在這兩根線上都傳輸訊號,這兩個訊號的振幅相同,相位相反。在這兩根線上的傳輸的訊號就是差分訊號。訊號接收端比較這兩個電壓的差值來判斷髮送端發送的是邏輯0還是邏輯1。
當LVDS為雙通道傳輸時,通道A和通道B會分別傳輸奇數位的像素點和偶數位的像素點。
LVDS 的每組通道由四組資料線和一組時鐘線組成(24bit以內的像素資料),共10條線。
LVDS 的四組資料線的資料轉送格式有一定的規範,通常分為VESA 和 JEIDA 兩種標準。此處只討論VESA標準。
從LCD的Datasheet中可以看到,根據SELLVDS這根Pin的接法,可以選擇使用哪種標準,這邊我們使用VESA標準。
並且,可以看到四組資料線中,一個像素要傳7位元據,包含了RGB資料和一些控制資料。
LCD相關知識
根據kernel文檔framebuffer.txt,可以得知一些資訊:
電子槍從螢幕的左上方開始,將一個個的像素點依次打倒螢幕上,其順序是從左往右,從上往下。 當掃描到一行的結束回到下一行的開始時,這叫做horizontal retrace;當掃描到右下角(最後一行的最後一個像素),回到左上方掃描下一個frame時,這叫做vertical retrace。
當電子槍掃描到一行的最後一個像素時,我們需要發送一個水平同步脈衝訊號(vsync pulse),來告訴電子槍進行horizontal retrace,同樣,當電子槍要進行vertical retrace之前,我們要發送一個垂直同步脈衝訊號(hsync pulse),如下(timing summarizes):
主要涉及這些參數:xres、yres、left_margin、right_margin、upper_margin、lower_margin、hsync_len、vsync_len、pixel clock
xres、yres:水平和垂直掃描時間
left_margin:行掃描開始前的等待時間,之後開啟Data Enable pin
right_margin:行有效像素掃描完成後的等待時間,之前關閉Data Enable pin
hsync_len:水平同步脈衝寬度,通知掃描槍換行
upper_margin:一個frame掃描開始前的等待時間,之後開啟Data Enable pin
lower_margin:一個frame掃描完成後的等待時間,之前關閉Data Enable pin
hsync_len:水平同步脈衝寬度,通知掃描槍回左上方
pixel clock:打一個像素消耗的時間
horizontal retrace time (h-blank time)= left_margin + right_margin + hsync_length
vertical retrace time (v-blank time) = upper_margin + lower_margin + vsync_len
有些文檔用以下所寫來描述上述參數:
VPW: Vsync Pulse Width
VBP: Vsync Back Porch
VFP: Vsync Front Porch
HBP: Hsync Back Porch
HFP: Hsync Front Porch
有時候,LCD 的 Datasheet對參數描述不詳細時,可以查閱VESA標準,如:
關於晶片內RGB資料的傳輸和控制
IPU:Iamge Process Unit
LDB:LVDS Display Bridge
IPU通過DMA對記憶體中的資料進行讀取,層層處理後,分為ipu_di0 和 ipu_di1 兩個通道交給 LDB Mux&Control,資料經過處理符合LVDS規範後,依據設定分發給LDB Channel 0 和 1,從而傳給LCD。
此處,我的LCD是雙通道,所以LDB Channel 0 和 1分別負責分發奇數位和偶數位的像素。
關於Backlight
背光有兩根pin在控制,一個是enable,控制背光開啟和關閉;一個是pwm,控制背光亮度。
PWM:Pulse Width Modulation,脈衝寬度調製。
當PWM高電平時發光,低電平不發光,通過調整PWM的占空比來調節亮度。
代碼相關
註冊 Backlight device
board-mx6q_dsa2lv.c
mx6_sabresd_pwm_backlight_data.max_brightness = 248;mx6_sabresd_pwm_backlight_data.dft_brightness = 200;mx6_sabresd_pwm_backlight_data.pwm_period_ns = 6250000;mx6_sabresd_pwm_backlight_data.pwm_id = 1;imx6q_add_mxc_pwm_backlight(0, &mx6_sabresd_pwm_backlight_data);
devices-imx6q.h
#define imx6q_add_mxc_pwm_backlight(id, pdata) \ platform_device_register_resndata(NULL, "pwm-backlight", id, NULL, 0, pdata, sizeof(*pdata));
注意註冊裝置傳入的 id=0,對應:/sys/bus/platform/devices/pwm-backlight.0
Backlight 驅動
代碼為pwm_bl.c 和 backlight.c
pwm_bl.c 主要是直接和pwm打交道,而 backlight.c 提供了檔案節點給上層操作。
pwm_bl.c 調用了 backlight.c 的 backlight_device_register方法,又註冊了一個device,這個device 的parent就是之前board-mx6q_dsa2lv.c裡面註冊的device。這麼做的原因可能是出於結構設計的考慮:所有廠商的backlight device都要註冊到backlight.c這個基本架構中,然後提供統一的檔案節點給上層使用。
所以,又有:/sys/devices/platform/pwm-backlight.0/backlight/pwm-backlight.0
TODO:PWM 的研究
添加 LDB 和 IPU 相關裝置
static struct ipuv3_fb_platform_data sabresd_fb_data[] = { { /*fb0*/ .disp_dev = "ldb", .interface_pix_fmt = IPU_PIX_FMT_GBR24, .mode_str = "LDB-1080P60", .default_bpp = 32, .int_clk = false, .late_init = false, }, ... ...};imx6q_add_ipuv3(0, &ipu_data[0]);if (cpu_is_mx6q()) { imx6q_add_ipuv3(1, &ipu_data[1]); for (i = 0; i < 4 && i < ARRAY_SIZE(sabresd_fb_data); i++) imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]);} else for (i = 0; i < 2 && i < ARRAY_SIZE(sabresd_fb_data); i++) imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]);imx6q_add_vdoa();imx6q_add_lcdif(&lcdif_data);imx6q_add_ldb(&ldb_data);imx6q_add_v4l2_output(0);
IPU_PIX_FMT_GBR24:關係到 IPU 給 LDB 傳輸資料的 RGB 格式
在ldb.c中配置fb_videomode結構體,配置lcd參數:
{ "LDB-1080P60B", 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN,},
[Android] LCD Driver Porting