(转)Tiny210v2( S5PV210 ) 平台下 FIMD 对应 的 framebuffer 驱动中,关于 video buffer 的理解...
生活随笔
收集整理的這篇文章主要介紹了
(转)Tiny210v2( S5PV210 ) 平台下 FIMD 对应 的 framebuffer 驱动中,关于 video buffer 的理解...
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
原文:http://www.arm9home.net/read.php?tid-25938.html
管理提醒:?本帖被 xoom 執(zhí)行加亮操作(2012-12-13)如之前所說,一直想知道顯示數(shù)據(jù)都在哪個(gè)地方,通常的數(shù)據(jù),比如 framebuffer 中的顯示數(shù)據(jù),和OpenGL 處理的數(shù)據(jù)有啥關(guān)系。
目前為止我還沒有弄明白 OpenGL 這塊,但是 framebuffer 這部分差不多了。這篇文章記錄了 framebuffer 的顯示數(shù)據(jù)相關(guān)內(nèi)容。
1. 關(guān)于FIMD
????Tiny210v2 開發(fā)板屬于 s5pv210 的一種,在這塊開發(fā)板上,顯示部分又被叫做 FIMD,我不知道FIMD是什么的縮寫,但D應(yīng)該和Display Controller有關(guān)系吧。
????FIMD 的主要功能就是獲取顯示數(shù)據(jù),并將數(shù)據(jù)輸出到顯示屏。當(dāng)然期間會(huì)對(duì)顯示數(shù)據(jù)進(jìn)行處理:
?????????
?
????FIMD一共支持5個(gè)layer,在SoC用戶手冊(cè)中,將layer成為window,源代碼中也叫做window。
?????????
?
????FIMD可以通過AXI總線從內(nèi)存或者Camera哪里獲取到顯示數(shù)據(jù),并進(jìn)行合成。
?????????
?
????
2. 內(nèi)核配置 framebuffer
????通過 make menuconfig 可以配置 framebuffer 相關(guān)的內(nèi)容。
????
?????????
?
????保存以后,在 .config 文件中可以找到相關(guān)配置內(nèi)容。
????
????????.config
????????--------------------------------------------------
| 復(fù)制代碼 |
????同樣也會(huì)在頭文件中生成宏定義:
????????include/generated/autoconf.h
????????--------------------------------------------------
| 復(fù)制代碼 |
????
????CONFIG_FB_S3C_DEFAULT_WINDOW 是指 默認(rèn)的 window, 0-4。
????CONFIG_FB_S3C_NR_BUFFERS 是指 window 的buffer數(shù),3個(gè)就是 trebble-buffer,2個(gè)就是double-buffer。
????其中第一個(gè)是正在顯示的數(shù)據(jù),又叫onscreen,其他幾個(gè)是后臺(tái)描畫的數(shù)據(jù),又叫offscreen,通過 flip 操作可以將 onscreen 數(shù)據(jù)和offscreen 數(shù)據(jù)交換。
????CONFIG_FB_S3C_NUM_OVLY_WIN 是 OVERLAY window, 0-4。
????CONFIG_FB_S3C_NUM_BUF_OVLY_WIN 是指 OVERLAY window 的buffer數(shù),和 CONFIG_FB_S3C_NR_BUFFERS 一個(gè)意思。
????????
3. 顯示數(shù)據(jù)buffer
????內(nèi)核初始話過程中,為這些window 的 buffer 預(yù)留了一部分內(nèi)存。
????具體看下面的代碼:
????初始化函數(shù)會(huì)首先映射內(nèi)存空間:
????????
| 復(fù)制代碼 |
????
????在映射內(nèi)存空間中,保留了一部分內(nèi)存,保留的大小就和window 以及 buffer數(shù)有關(guān)系:
????大小是 800 x 480 x 2個(gè)window x 3個(gè)buffer x RGBA的4字節(jié),這是給通常顯示數(shù)據(jù)的,
????除此之外,還預(yù)留了 YUV 的數(shù)據(jù)區(qū)域,1280 x 720 x 3個(gè)buffer x Y的一個(gè)字節(jié)數(shù)據(jù) + 1280 x 720 x 3個(gè)buffer x UV的一個(gè)字節(jié)數(shù)據(jù)。
????另外還有一個(gè) 4096 字節(jié)大小的 數(shù)據(jù)。
????這些數(shù)據(jù)我只理解了 RGBA 數(shù)據(jù), YUV 的數(shù)據(jù)不知道是干啥的? 難道是給 HDMI 輸出用的?
????????
????????arch/arm/mach-sp5v210/Mach-mini210.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????這些內(nèi)存是PAGE對(duì)齊的,對(duì)齊的部分參考下面的算法。
????PAGE_SIZE 大小是 4096。
????????include/linux/Const.h
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
????????arch/arm/include/asm/Page.h
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
????????include/linux/Kernel.h
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
4. 內(nèi)核關(guān)于FIMD內(nèi)存預(yù)留的相關(guān)debug log
????在內(nèi)核的 boot log 中,我們可以找到關(guān)于內(nèi)存預(yù)留的log:
????????dmesg log :
????????--------------------------------------------------
????????[????0.000000] s5p: 13060 kbytes system memory reserved for fimd at 0x3c330000, 1-bank base(0x3c330000)?
????????
????????[????0.648804] fimd at 0x3c330000
5. 物理內(nèi)存視圖
????畫了一個(gè)簡(jiǎn)單的物理內(nèi)存布局圖,可以看到 RGBA 部分的數(shù)據(jù),其實(shí)一共給 2 個(gè) window 預(yù)留了。
????????|??????????????|
????????|--------------|
????????|??????????????|0x3CFF0000 -- 0x3CFF0FFF || ????
????????|--------------|
????????|??????????????|0x3CF7F000 -- 0x3CFEFFFF ||
????????|--------------|???????????????????????? ||
????????|??????????????|0x3CF0E000 -- 0x3CF7EFFF || treble-buffer YUV( UV ) framebuffer : 1280 x 360 x 1 byte
????????|--------------|???????????????????????? ||
????????|??????????????|0x3CE9D000 -- 0x3CF0DFFF ||
????????|--------------|???????????????????????????
????????|??????????????|0x3CDBC000 -- 0x3CE9EFFF ||
????????|--------------|???????????????????????? ||
????????|??????????????|0x3CCDB000 -- 0x3CDBBFFF || treble-buffer YUV(??Y ) framebuffer : 1280 x 720 x 1 byte
????????|--------------|???????????????????????? ||
????????|??????????????|0x3CBFA000 -- 0x3CCDAFFF ||
????????|--------------|???????????????????????????
????????|??????????????|0x3CA83000 -- 0x3CBF9FFF ||
????????|--------------|???????????????????????? ||
????????|??????????????|0x3C90C000 -- 0x3CA82FFF || treble-buffer RGBA framebuffer : 800 x 480 x 4 bytes
????????|--------------|???????????????????????? ||
????????|??????????????|0x3C795000 -- 0x3C90BFFF ||
????????|--------------|???????????????????????????
????????|??????????????|0x3C61E000 -- 0x3C794FFF ||
????????|--------------|???????????????????????? ||
????????|??????????????|0x3C4A7000 -- 0x3C61DFFF || treble-buffer RGBA framebuffer : 800 x 480 x 4 byte
????????|--------------|???????????????????????? ||
????????|??????????????|0x3C330000 -- 0x3C4A6FFF ||
????????|--------------|
????????|??????????????|
6. 將預(yù)留的物理內(nèi)存記錄到platform信息中
????這些預(yù)留的物理內(nèi)存,在 platform 初始化過程中,會(huì)映射到內(nèi)存空間。
????在開發(fā)板初始化過程中,會(huì)進(jìn)行 machine init, 而 machine init 過程中會(huì)調(diào)用 s3c_fb_set_platdata 初始化 platform 信息。
????????
????????arch/arm/mach-sp5v210/Mach-mini210.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????
????在platform初始化過程中,就會(huì)通過 pmem_start 和 pmem_size 分別記錄這5個(gè)window 的物理內(nèi)存地址和大小。????
????注意的是 platform 初始化,相當(dāng)于是記錄系統(tǒng)都有哪些資源。而設(shè)備驅(qū)動(dòng)初始化過程中,比如s3cfb這個(gè)fb驅(qū)動(dòng),則會(huì)來使用這些資源。
????????arch/arm/plat-s5p/include/plat/Fb.h
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
????????arch/arm/plat-samsung/Dev-fb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????
????我們需要留意一下上面這段代碼,????
????因?yàn)?num_overlay_win 是 CONFIG_FB_S3C_NUM_OVLY_WIN=1,所以 for 循環(huán)只執(zhí)行了一次,那么 window 0 的物理內(nèi)存地址初始化了。
????然后又手工為 default_win 也就是 CONFIG_FB_S3C_DEFAULT_WINDOW=2 進(jìn)行了初始化。
????也就是說: window 0 和 window 2 在platform初始化中記錄了數(shù)據(jù)buffer的物理內(nèi)存地址。
????雖然是 for 循環(huán)做的,我認(rèn)為這個(gè)for循環(huán)寫得不好。
7. 在s3cfb初始化過程中,為window 關(guān)聯(lián)這些內(nèi)存
????在初始化過程中,會(huì)分配fb設(shè)備相關(guān)數(shù)據(jù)結(jié)構(gòu),并注冊(cè)fb設(shè)備。
????????drivers/video/samsung/s3cfb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????但是我們發(fā)現(xiàn),只有當(dāng) fb 設(shè)備對(duì)應(yīng)的 window 是 default window ,也就是 window 2 的時(shí)候,
????才會(huì)將 window 2 對(duì)應(yīng)的內(nèi)存映射到內(nèi)存空間。
????雖然預(yù)留的物理內(nèi)存是 window 0 和 window 2 的,但這個(gè)時(shí)候 window 0 的物理內(nèi)存是沒有被映射的。
????????drivers/video/samsung/s3cfb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????
????這是注冊(cè) fb 設(shè)備的地方,只要注冊(cè)成功,/dev 目錄下就會(huì)有一個(gè) fb 文件。
????雖然只給 window 2 映射了顯示數(shù)據(jù)的內(nèi)存,但是 for 循環(huán)還是將所有的 window 都注冊(cè)設(shè)備文件了。
????這就是為什么 /dev 目錄下有 fb0 - fb4 5個(gè)fb設(shè)備。其實(shí)每一個(gè) fb 設(shè)備對(duì)應(yīng)一個(gè) window。
????
????另外需要注意的是,第一個(gè)注冊(cè)的 fb 是 fb0,然后依次 ++。
????下面的代碼在注冊(cè)的時(shí)候, 首先注冊(cè)的是 default window 2,然后是 3, 4, 0, 1。
????也就是說 :
????fb0 -> window 2
????fb1 -> window 3
????fb2 -> window 4
????fb3 -> window 0
????fb4 -> window 1
????另外還需要注意的是,如果你直接去 cat??/dev/fbX ,只有 fb0 是成功的,其他全部失敗,
????因?yàn)榈侥壳拔恢?#xff0c;只有 fb0 也就是 default window 2,映射了顯示數(shù)據(jù)的內(nèi)存。
????????
????????drivers/video/samsung/s3cfb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
8. 內(nèi)核關(guān)于顯示內(nèi)存映射的相關(guān)debug log
????需要注意一下,部分log中寫的是fb2,但這個(gè)log是boot階段的,真正有效的是fb0,
????代碼中l(wèi)og寫錯(cuò)了,fb 很多應(yīng)該是 window。fb0 -> window 2
????????dmesg log :
????????--------------------------------------------------
????????[??507.316250] [s3cfb]win 2: pmem_start=0x3c795000
????????[??507.316292] [s3cfb][fb2] dma: 0x3c795000, cpu: 0xe1000000, size: 0x0085c000
????????
????????[??507.333888] PA FB = 0x3C795000, bits per pixel = 32
????????[??507.333933] screen width=800 height=480 va=0xdc795000 pa=0x3c795000
????????[??507.333987] xres_virtual = 800, yres_virtual = 1440, xoffset = 0, yoffset = 0
????????[??507.336543] fb_size=8765440?
????????[??507.339351] Back frameBuffer[0].VAddr=dc90c000 PAddr=3c90c000 size=1536000?
????????[??507.346146] Back frameBuffer[1].VAddr=dca83000 PAddr=3ca83000 size=1536000?
????????[??507.353014] Video Y Buffer[0].VAddr=dcbfa000 PAddr=3cbfa000 size=921600
????????[??507.359576] Video Y Buffer[1].VAddr=dccdb000 PAddr=3ccdb000 size=921600?
????????[??507.366161] Video Y Buffer[2].VAddr=dcdbc000 PAddr=3cdbc000 size=921600
????????[??507.372750] Video UV Buffer[0].VAddr=dce9d000 PAddr=3ce9d000 size=462848
????????[??507.379418] Video UV Buffer[1].VAddr=dcf0e000 PAddr=3cf0e000 size=462848
????????[??507.386093] Video UV Buffer[2].VAddr=dcf7f000 PAddr=3cf7f000 size=462848
9. 顯示數(shù)據(jù)使用內(nèi)存映射的一些細(xì)節(jié)
????s3cfb_map_video_memory 這個(gè)函數(shù)用于映射顯示數(shù)據(jù)的內(nèi)存地址,
????如果是 platform 初始化過程中預(yù)留過物理內(nèi)存,則會(huì)使用這個(gè)物理內(nèi)存。
????否則就會(huì)臨時(shí)申請(qǐng)一塊內(nèi)存。
????也就是說 window 0 和 window 2 會(huì)使用預(yù)留的物理內(nèi)存。
????window 1 / window 3 / window 4 會(huì)使用新申請(qǐng)的內(nèi)存。
????????drivers/video/samsung/s3cfb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????除了在初始化的時(shí)候會(huì)映射以外,
????還可一通過 ioctl 來調(diào)用 s3cfb_map_video_memory。
????傳遞的參數(shù)是 FBIOPUT_VSCREENINFO。
????????drivers/video/samsung/s3cfb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
10. 在s3cfb初始化過程中映射FIMD的控制寄存器,用于控制硬件
????FIMD的控制寄存器和內(nèi)存是統(tǒng)一編址的,因此可以像使用內(nèi)存一樣訪問他們,但前提是需要將他們映射到內(nèi)存空間。
????內(nèi)核代碼中的寄存器地址定義都能和 SoC 用戶手冊(cè)對(duì)應(yīng)上,我們看看下面的截圖,很一致吧。
????但是在看代碼的過程中,我發(fā)現(xiàn)代碼使用的寄存器的一些信息,Soc 用戶手冊(cè)沒有,是不是用戶手冊(cè)比較老了?
????
?????????
?
?????????
?
????在 s3cfb 模塊初始化的過程中,就會(huì)將控制寄存器映射到內(nèi)存中。
????????arch/arm/mach-sp5v210/include/mach/map.h
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
????????
????????arch/arm/plat-samsung/dev-fb.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
????s3cfb_fimd6x.c這個(gè)文件將讀寫 FIMD 的控制寄存器相關(guān)功能都集中在這里了。
????我理解 6x 可能是對(duì)應(yīng)硬件版本號(hào),因?yàn)橛∠笾锌吹接布姹咎?hào)好象是 0x62。
????通過設(shè)定這些控制寄存器,就能控制比如 window 是否顯示啊,顯示數(shù)據(jù)格式是啥啊,顯示數(shù)據(jù)地址在哪里啊,等等。
????????drivers/video/samsung/s3cfb_fimd6x.c
????????--------------------------------------------------
| 復(fù)制代碼 |
11. 用戶空間的測(cè)試用例
????這個(gè)用例其實(shí)是用來確認(rèn) /dev 目錄下的 fb0 - fb4 是否好用的,以及 window 之間的alpha透過是否正確。
????關(guān)于 window 之間的層次關(guān)系可以參考:
?????????
?
????下面的代碼,大概意思是:
????* 打開 window 0 - window 4 對(duì)應(yīng)的 fb 設(shè)備文件。
????* 設(shè)置這些 window 都是 800 x 480 x RGBA
????* 設(shè)置這些 window 內(nèi)部的顯示數(shù)據(jù),是從 window 0 - window 4 開始的,分別畫 500x480, 400x480, 300x480, 200x480, 100x480 這么大塊數(shù)據(jù)。
????* 讓window 的顯示數(shù)據(jù)顯示出來。
????????s3cfb_test.c
????????--------------------------------------------------
| 復(fù)制代碼 |
????????
????下面是屏幕截圖,其實(shí)我對(duì) RGB 不太了解,不知到什么值應(yīng)該是什么顏色,但 只描畫了紅/綠/藍(lán) 三種顏色,而屏幕上不是這三種顏色。
????說明 alpha blending 應(yīng)該是正常工作了的。
?????????
?
END
總結(jié)
以上是生活随笔為你收集整理的(转)Tiny210v2( S5PV210 ) 平台下 FIMD 对应 的 framebuffer 驱动中,关于 video buffer 的理解...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到棺材和血是什么意思
- 下一篇: C链表反转(时间复杂度O(n))