1. 程式人生 > >AM335x(TQ335x)學習筆記——LCD驅動移植

AM335x(TQ335x)學習筆記——LCD驅動移植

TI的LCD控制器驅動是非常完善的,共通的地方已經由驅動封裝好了,與按鍵一樣,我們可以通過DTS配置完成LCD的顯示。下面,我們來討論下使用DTS方式配置核心完成LCD驅動的思路。

(1)初步分析

由於TQ335x使用的晶片是AM335x,故仍然可以參考am335x-evm.dts。當然,am335x-evmsk.dts、am335x-beagbone.dts都可以。本文以am335x-evm.dts為例。大體上瀏覽下DTS檔案,可以發現兩個醒目的節點:一個是panel,一個是backlight。接下來我們逐個分析。

(2)panel節點資訊分析及配置

從panel節點可以獲得如下資訊:

1. 匹配核心驅動的關鍵詞是:"ti,tilcdc,panel",可以通過這個關鍵字找到相應的驅動。
2. 管腳配置在節點lcd_pins_s0內
3. panel-info中可以配置LCD的硬體資訊,如LCD的解析度等
4. display-times中記錄了LCD刷屏的相關時序。
其中,panel-info和display-times需要去LCD手冊中查詢,管腳配置需要根據AM335x的晶片手冊、資料手冊及TQ335x的原理圖確定,驅動則需要去核心的driver目錄下查詢。下面,我一一解決上述幾個問題:
首先是設定panel-info和display-times。我的TQ335x是用的我除錯TQ210時使用的觸控式螢幕,型號是TN92,這個屏是800*480的解析度,因此,panel-info與evm開發板的配置是相同的,可以不做任何修改。但是,不同螢幕的display-times一般是不相同的,因此,需要查閱觸控式螢幕的手冊來確認display-times。

TN92的水平掃描時序如下表:


垂直掃描時序如下圖:


但是,如果對LCD各引數不怎麼熟悉的話,很難建立這兩個表與DTS中display-times的關係,這時應該去查閱一下linux核心的文件和晶片手冊。在核心文件:”Documentation/devicetree/bindings/video/display-timing.txt"有相關的記載,該檔案中有形象的描述,具體如下:

 +----------+-------------------------------------+----------+-------+
 |          |        ↑                            |          |       |
 |          |        |vback_porch                 |          |       |
 |          |        ↓                            |          |       |
 +----------#######################################----------+-------+
 |          #        ↑                            #          |       |
 |          #        |                            #          |       |
 |  hback   #        |                            #  hfront  | hsync |
 |   porch  #        |       hactive              #  porch   |  len  |
 |<-------->#<-------+--------------------------->#<-------->|<----->|
 |          #        |                            #          |       |
 |          #        |vactive                     #          |       |
 |          #        |                            #          |       |
 |          #        ↓                            #          |       |
 +----------#######################################----------+-------+
 |          |        ↑                            |          |       |
 |          |        |vfront_porch                |          |       |
 |          |        ↓                            |          |       |
 +----------+-------------------------------------+----------+-------+
 |          |        ↑                            |          |       |
 |          |        |vsync_len                   |          |       |
 |          |        ↓                            |          |       |
 +----------+-------------------------------------+----------+-------+
AM335x的技術參考手冊中可以找到相關的暫存器解釋,如下:


綜合這三份資料,很容易確定下LCD的屏的時序引數的範圍(需要強調的是,上述引數不一定精確,還需要使用圖片實機測下效果),經過多次實驗,最終確定下了LCD的時序引數,詳情如下:

panel {
    compatible = "ti,tilcdc,panel";
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&lcd_pins_s0>;
    panel-info {
        ac-bias           = <255>;
        ac-bias-intrpt    = <0>;
        dma-burst-sz      = <16>;
        bpp               = <32>;
        fdd               = <0x80>;
        sync-edge         = <0>;
        sync-ctrl         = <1>;
        raster-order      = <0>;
        fifo-th           = <0>;
    };

    display-timings {
        800x480p62 {
            clock-frequency = <30000000>;
            hactive = <800>;
            vactive = <480>;
            hfront-porch = <214>;
            hback-porch = <40>;
            hsync-len = <4>;
            vback-porch = <20>;
            vfront-porch = <23>;
            vsync-len = <4>;
            hsync-active = <0>;
            vsync-active = <0>;
        };
    };
};
時序確定下來之後需要關注的就是管腳配置,由於am335x集成了LCD控制,該控制器與LCD的連線方式是通過GPIO管腳複用實現的,而evm開發板與TQ335x的LCD都接在了同一個LCD控制器上,因此,直接使用原有的管腳配置即可。這一點也可以通過閱讀TQ335x的原理圖確認,這裡我就不再分析了。

(3)backlight節點分析及配置

從backlight節點中可以獲得如下資訊:

1. 匹配核心驅動的關鍵詞是"pwm-backlight"。
2. 使用的ECAP0進行PWM輸出。
3. 有8個亮度等級。
4. 預設的亮度等級是8,也就是最亮。
瞭解以上資訊後需要查閱TQ335x手冊,弄清楚backlight控制管腳是如何連線的。通過分析TQ335x的原理圖可知,TQ335x的背光控制也是使用PWM方式控制,且該引腳接到AM335x的ECAP2_IN_PWM2_OUT管腳上,而evm開發板是接在ECAP0_IN_PWM0_OUT管腳上的,因此,需要修改DTS配置才能正常使用TQ335x的背光功能。思路是將DTS中的背光配置由EACP0改為EACP2,下面是修改的步驟:
Step1. 將backlight節點中&eacp0改為&eacp2。
Step2. 將&epwmss0改為&epwmss2,並將該節點內的ecap0: [email protected]改成ecap0:[email protected],然後將該節點中的&ecap0_pins改成&ecap2_pins。
Step3. 將ecap0_pins節點改名為ecap2_pins,然後將pinctrl-single,pins內的內容改為:0x19c MUX_MODE4。
最後修改後的DTS相關部分如下:
backlight {
    compatible = "pwm-backlight";
    pwms = <&ecap2 0 50000 0>;
    brightness-levels = <0 51 53 56 62 75 101 152 255>;
    default-brightness-level = <8>;
};

&epwmss2 {
    status = "okay";

    ecap2: [email protected] {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&ecap2_pins>;
    };
};

ecap2_pins: backlight_pins {
    pinctrl-single,pins = <
        0x19c MUX_MODE4 /* MCASP0_AHCLKR.eCAP2_in_PWM2_out MODE4 */
    >;
};
這樣就完成了背光功能的DTS配置。 (4)配置核心驅動 由於evm開發板的程式碼是使用ATAGS方式啟動的,沒有配置pwm-backlight和基於TI LCD控制器的通用panel驅動,需要通過menuconfig開啟相應的配置項。通過DTS中的compatible屬性可以找到pwm-backlight驅動是在drivers/video/backlight/pwm-bl.c中實現的,而panel驅動則是在drivers/gpu/drm/tilcdc/tilcdc_panel.c中實現的,閱讀相應目錄下的Makefile和Kconfig就可以確定出如何配置menuconfig。Makefile和Kconfig的分析過程很簡單,我就不多寫了,下面是通過menuconfig開啟相應功能的步驟。 Step1. 執行menuconfig指令:
make ARCH=arm menuconfig
Step2. 開啟通用pwm-backlight驅動和基於TI LCD控制器的通用panel驅動,配置內容如下:
Graphics support  --->
	[*] Pulse-Width Modulation (PWM) Support  --->
		<*>   ECAP PWM support
		<*>   EHRPWM PWM support
	-*- Backlight & LCD device support  --->
		<*>     Generic PWM based Backlight Driver
Graphics support  --->		
	Direct Rendering Manager  --->
		<*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
		<*> DRM Support for TI LCDC Display Controller
(5)編譯DTB和核心 執行DTB編譯指令:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- tq335x.dtb
執行核心編譯指令:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8
(6)用新核心啟動開發板
將新編譯好的tq335x.dtb和zImage拷貝到SD卡的boot目錄下,然後用SD啟動開發板到u-boot命令列模式,通過u-boot指令啟動核心(每次都這樣啟動會比較麻煩,可以通過設定u-boot的bootcmd環境變數並儲存來簡化此動作),啟動核心的指令與前一篇文章的命令是相同的:
load mmc 0 0x88000000 /boot/tq335x.dtb
load mmc 0 0x82000000 /boot/zImage
load mmc 0 0x88080000 /boot/ramdisk.img
bootz 0x82000000 0x88080000 0x88000000
這時,可以看到開發板正常啟動並且能看到熟悉的Linux小企鵝Logo,至此,就完成了am335x的LCD驅動移植,實際上是不需要我們寫程式碼的,但需要了解核心的組織方式和DTS配置的方法。

(7)pinmux配置引數的確定方法

相信有些人看完這幾篇文章之後有個疑問,就是配置pinmux的時候offset是如何確定的。配置GPIO管腳複用功能時經常用到pinctrl-single,pins = <offset, function>屬性,核心解析該屬性後根據offset和function配置對應的暫存器,是GPIO管腳配置為指定的複用功能。

講offset的確定方法之前需要指出的是,TI的GPIO控制與三星的晶片不同,三星的晶片管腳複用功能是放在GPIO暫存器中的,而TI的晶片則有個專門的控制模組叫Control Module,該模組可以控制所有的GPIO管腳功能複用;另外,與三星晶片的另外一個不同是TI的晶片分為技術參考手冊和資料手冊,技術參考手冊非常詳細的講述同family的晶片功能及使用方法,資料手冊則用來講述同family中不同晶片特有的屬性。因此,除錯TI晶片時需要結合技術參考手冊和資料手冊,而配置GPIO則需要閱讀技術手冊的GPIO、Control Module兩章和資料手冊中相關的部分。

從am33xx.dtsi中可以看到pinmux的基地址是0x44e10800,我們先來看這個地址是怎麼來的。從技術參考手冊的記憶體對映表可以確定該地址位於L4_WKUP段內,如下圖:


點選L4_WKUP超連結,可以切換到L4_WKUP的地址對映表,從該表中可以確定,該地址位於Control Module,如下圖:


點選Control Module的超連結,可以切換到Control Module的地址對映表,從該表中可以找到0x44e10800地址,實際上就是conf_gpmc_ad0控制暫存器的地址,也就是說,pinmux配置時的offset都基於這個地址的。

以PWM背光控制為例。該功能引腳是接在ECAP2_IN_PWM_OUT上的,實際上就是AM335x的MCASP0_AHCLKR管腳,該管腳的地址也可以在Control Module的地址對映表中找到,該管腳的地址是0x44e1099c(表中是基於Control Module的offset,這個值是計算之後的),因此,在pinmux中配置該引腳時使用的offset應該是0x19c,這樣就確定出了offset。 pinctrl-single,pins的第二項是function,用來指定GPIO管腳是輸入還是輸出,當前處於哪種模式。輸入輸出很容易配置,但是AM335x技術參考手冊中只提到每個管腳有8中模式,即MODE0~MODE7,其中,MODE0是主模式,但是沒有具體講每個引腳的每個MODE是什麼功能,這時,就需要查閱AM335x資料手冊了。在AM335x資料手冊MCASP0_AHCLKR的八種模式的含義,如下圖:
由於我們使用的是eCAP2_in_PWM2_out功能,故使用MUX_MODE4。這就是backlight的pinmux配置時使用pinctrl-single,pins = <0x19c MUX_MODE4>的原因。

(8)效果展示

到這裡LCD的移植工作就算完成了,下面是TQ335x驅動LCD後的效果圖:



(9)總結

使用DTB方式配置核心驅動一般需要以下幾個步驟:

Step1. 設定pinmux,配置的GPIO為相應的功能。
Step2. 設定相應的節點,關聯對應的驅動。
Step3. 檢查核心配置項,確保開啟對應的驅動選項。

本文作者:girlkoo