目前A83T支援單屏顯示,首屏為LCD或者首屏為hdmi,都使用無論使用SCREEN0還是SCREEN1都是使用FB0作為framebuffer,在android下可以實作LCD和HDMI同樣螢幕顯示,而我們需要LCD和HDMI分别顯示。
FrameBuffer采用的是linux下的framebuffer分層驅動,fbmem.c作為通用層,然後驅動層實作對fb操作的可選部分,包括一系列的fb_ops。A83T硬體上有一個DE,然後通過TCON0和TCON1實作對顯示的輸出,其中TCON0控制LCD,實作對lvds,dsi,rgb接口的LCD控制,TCON1實作對HDMI的控制,整體的硬體架構如圖。

從架構上來看是可以實作雙屏異顯的,目前系統無法實作可能還和以前一樣硬體上為了和android配合接下來抽絲剝繭把驅動撸一遍,應該就能找到原因。
驅動層上共注冊了兩個裝置,一個是disp,另一個是hdmi,通過disp的probe對全盤進行初始化,通過hdmi的probe進行hdmi的底層初始化。
[ 0.750562] [dev_disp]disp_module_init
[ 0.750989] [dev_disp]disp probe function
[ 0.751092] [dev_disp]start disp_init
[ 0.751297] [dev_disp]display mode is 0
[ 0.751398] [dev_disp]disp_mode is 0,base=0xf1000000, size=0x400000, irq=0
[ 0.751665] [dev_disp]disp_mode is 1,base=0xf1c0c000, size=0x3fc, irq=118
[ 0.751767] [dev_disp]disp_mode is 2,base=0xf1c0d000, size=0x3fc, irq=119
[ 0.751947] [dev_disp]disp_mode is 3,base=0x0, size=0x0, irq=0
[ 0.752048] [dev_disp]disp_mode is 4,base=0xf1c26000, size=0x2fc, irq=0
[ 0.752227] [dev_disp]disp_mode is 5,base=0x0, size=0x0, irq=0
[ 0.752325] [dev_disp]disp_mode is 6,base=0x0, size=0x0, irq=0
[ 0.752503] [dev_disp]disp_mode is 7,base=0x0, size=0x0, irq=0
[ 0.752692] [dev_disp]boot para type is 1,mode is 0
[ 0.752791] [disp_display]start bsp_disp_init
[ 0.753406] [disp_display]start init hdmi
[ 0.753592] [disp_hdmi]hdmi is used,start disp_init_hdmi
[ 0.753692] [disp_hdmi]disp number is 0
[ 0.753868] [disp_hdmi]disp number is 1
[ 0.753965] [disp_hdmi]disp 1 is output by hdmi
[ 0.754064] [disp_hdmi]mode is 4,irq number is 119
[ 0.754243] [disp_hdmi]start check hdmi is supported and register
[ 0.754429] [disp_hdmi]start hdmi init call clk init
[ 0.754605] [disp_hdmi]start hdmi clk init
[ 0.754710] [disp_hdmi]init hdmi and register
[ 0.754954] [dev_disp]total screens is 2
[ 0.792619] [dev_disp]start work
[ 0.792728] [dev_disp]bsp disp sync with hw
[ 0.793464] [dev_disp]output type is not hdmi or hdmi is registed
[ 1.256339] [dev_hdmi]start hdmi module init
[ 1.261716] [drv_hdmi]start hdmi_init
[ 1.266445] [drv_hdmi]start hdmi thread hdmi_run_thread
[ 1.272615] [dev_disp]start work
[ 1.276419] [dev_disp]output type is not hdmi or hdmi is registed
LCD作為首屏和hdmi作為首屏有兩個不一樣的地方,LCD作為首屏使用的是syn=1,貌似是通過硬體進行顯示同步;hdmi時并不這樣做,差異表現在disp的初始化後的start_work函數。
Start_work函數解析。
首先等待初始化完成,如果50ms還沒初始化完成,則報異常。
然後判斷啟動參數,啟動參數為sync=1時,則根據啟動時對應的螢幕是不是一緻的,不一緻則切換,并且設定硬體sync函數;如果sync不是1時,則分别對不同的螢幕做初始化。啟動時的螢幕配置則從command line中擷取,經過驗證,lcd為主屏是設定為100,hdmi為主屏時設定為00.
進而在start_work中導緻了不同,如果是LCD啟動,則如果輸出類型是hdmi且HDMI沒有注冊(也就是沒有初始化)則退出,否則判斷啟動時對應的disp也就是fb是否和控制器對應,不對應則調用bsp_disp_sync_with_hw
bsp_disp_sync_with_hw函數,在啟動時syn=1并且啟動類型不是DISP_OUTPUT_TYPE_NONE時才可以。先擷取fb對應的控制器,然後調用disp_device_attached,從兩個screen裡找到一個disp_device_attached可以成功的。然後調用控制器,調用控制器對應的裝置的sw_enable。
在sync為0時,如果設定的是使用screen0,id=0或者screen1,id=1時,如果輸出類型是lcd,lcd已經注冊且目前id對應的顯示類型不是lcd,調用bsp_disp_device_switch進行切換,hdmi時也如此操作,如果既不是lcd,也不是hdmi,則直接調用切換。
bsp_disp_device_switch函數就是直接用disp_device_attached函數進行綁定,如果不成功,則從兩個screen裡找一個能綁定成功的。
disp_device_attached,找到id對應的mgr,裝置存在,類型不為0,則表示已經綁定成功了。
對應裝置是enabled同時,enable和disable都存在,disable裝置,unsetmanger函數存在時,unsetmanager。根究disp_dev和output_type找到裝置,裝置具有set_manager時,設定mgr,裝置存在set_mode函數時,設定mode。
Fb_init
首先初始化8個framebuffer,其中有一個fb_num的變量,寫死為1,此處做的操作為從裝置的資訊擷取長寬等資訊,填入fb的結構體資訊。然後調用display_fb_request函數。
display_fb_request函數。
通過fb_id和fb_para設定fb對應的參數,然後調用Fb_map_video_memory,然後擷取mgr并且通過mgr把參數設定到g_fbi的參數内。
Fb_map_video_memory函數
函數會根據傳入的info内容申請記憶體并把記憶體記錄到info的變量内。
把syn=1去掉,換成syn=0;然後在注冊時保證lcd注冊成功;fb_number設定為2,startwork時分别switch一下螢幕,再看日志,再看日志,解決了。
從代碼結構上看,應該是能夠夠實作channel和layer的,但貌似沒怎麼好好弄,反正我們也不用這麼進階的功能,算了,不研究了。