目前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的,但貌似沒怎么好好弄,反正我們也不用這么高級的功能,算了,不研究了。
轉載于:https://blog.51cto.com/13558393/2056499