日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

nano-pc-t1 4412 显示驱动分析

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nano-pc-t1 4412 显示驱动分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 和其它內核代碼類似。

???? 顯示驅動的分析都是由 drivers/video/fbmem.c開始,fbmem.c是顯示驅動的抽象,實際只是一個框架性的東西。

???? fbmem_init 中實現了一個字符設備驅動,并創建了class,但是沒有生成設備文件。

??? 這個字符設備驅動的file_operations里面的函數,實質上都是從struct fb_info *registered_fb[FB_MAX] ? 這個

??? fb_info的結構體數組中去調用 fb_ops 這個結構體中函數指針。數組下標為次設備號。那么這個結構體是如何賦值的

???? 呢?

??? fbmem.c里定義 register_framebuffer這個函數。真正的顯示設備都是調用這個函數來給registered_fb這個數組賦值,

?? 然后再去創建設備文件。


2.? 我們搜索register_framebuffer這個文件,有如下幾處:

???? drivers/gpu/drm/drm_fb_helper.c

???? drivers/video/s3c-fb.c


3. 我們先來看看s3c-fb.c

??? 這個文件注冊了一個平臺總線設備驅動程序,在其probe函數中調用 register_framebuffer。

??? 那么這個驅動的probe的函數什么時候調用呢?

??? 接下來我們看一下內核中實現平臺總線驅動代碼,注意,平臺總線驅動是內核實現的。


4. drivers/base/platform.c

??? 主要看platform_match這個函數,也就是平臺總線設備驅動和平臺總線設備是如何匹配的,知道了匹配規則,我們

??? 就知道如何去需找對應的平臺設備了。

??? 先看這句話

??? if (pdrv->id_table)
?? ??? ?return platform_match_id(pdrv->id_table, pdev) != NULL;

?? return (strcmp(pdev->name, drv->name) == 0);

??? 如何平臺總線設備驅動中有id_table的話,那么調用platform_match_id這個函數。

?? 我們再看一下platform_match_id函數做個什么。

?? while (id->name[0]) {
?? ??? ?if (strcmp(pdev->name, id->name) == 0) {
?? ??? ??? ?pdev->id_entry = id;
?? ??? ??? ?return id;
?? ??? ?}
?? ??? ?id++;
?? ?}

??? 很顯然,就是拿平臺總線設備的name去挨個比較平臺總線設備驅動的id_table,匹配成功測返回id。

??? 如果沒有匹配成功,則再去比較平臺總線設備的名稱和平臺總線驅動的名稱。也就是

???return (strcmp(pdev->name, drv->name) == 0);? 這句。

?? 一旦匹配成功,那么內核會自動調用平臺總線設備驅動的probe函數。


5.? 那么接下來,我們就看看s3c-fb.c這個文件里實現的平臺總線設備驅動程序的name和id_table

??? static struct platform_driver s3c_fb_driver = {
?? ?.probe?? ??? ?= s3c_fb_probe,
?? ?.remove?? ??? ?= s3c_fb_remove,
?? ?.id_table?? ?= s3c_fb_driver_ids,
?? ?.driver?? ??? ?= {
?? ??? ?.name?? ?= "s3c-fb",
?? ??? ?.owner?? ?= THIS_MODULE,
?? ??? ?.pm?? ?= &s3cfb_pm_ops,
?? ?},
};

static struct platform_device_id s3c_fb_driver_ids[] = {
?? ?{
?? ??? ?.name?? ??? ?= "s3c-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_64xx,
?? ?}, {
?? ??? ?.name?? ??? ?= "s5pc100-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_s5pc100,
?? ?}, {
?? ??? ?.name?? ??? ?= "s5pv210-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_s5pv210,
?? ?}, {
?? ??? ?.name?? ??? ?= "exynos4-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_exynos4,
?? ?}, {
?? ??? ?.name?? ??? ?= "exynos5-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_exynos5,
?? ?}, {
?? ??? ?.name?? ??? ?= "s3c2443-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_s3c2443,
?? ?}, {
?? ??? ?.name?? ??? ?= "s5p64x0-fb",
?? ??? ?.driver_data?? ?= (unsigned long)&s3c_fb_data_s5p64x0,
?? ?},
?? ?{},
};

? 有了第4點的分析,我們可以搜索上面紅字部分來查找對應的平臺總線設備了。


6.? 搜索"s3c-fb",找到了

???arch/arm/plat-samsung/devs.c這個文件

??? 搜索"exynos4-fb",找到了

??? arch/arm/mach-exynos/common.c

????? 其它name,我們應該不用理會,都是其它soc名稱。


?? 在devs.c里定義了

?? struct platform_device s3c_device_fb = {
?? ?.name?? ??? ?= "s3c-fb",
?? ?.id?? ??? ?= -1,
?? ?.num_resources?? ?= ARRAY_SIZE(s3c_fb_resource),
?? ?.resource?? ?= s3c_fb_resource,
?? ?.dev?? ??? ?= {
?? ??? ?.dma_mask?? ??? ?= &samsung_device_dma_mask,
?? ??? ?.coherent_dma_mask?? ?= DMA_BIT_MASK(32),
?? ?},
};?

?? 在common.c里是這句 s5p_fb_setname(0,"exynos4-fb");

?? 展開實際是這樣s5p_device_fimd0.name = name;

?? struct platform_device s5p_device_fimd0 = {
?? ?.name?? ??? ?= "s5p-fb",??? 這塊被改為了 "exynos4-fb"
?? ?.id?? ??? ?= 0,
?? ?.num_resources?? ?= ARRAY_SIZE(s5p_fimd0_resource),
?? ?.resource?? ?= s5p_fimd0_resource,
?? ?.dev?? ??? ?= {
?? ??? ?.dma_mask?? ??? ?= &samsung_device_dma_mask,
?? ??? ?.coherent_dma_mask?? ?= DMA_BIT_MASK(32),
?? ?},
};

??? 從以上分析,實際定義了兩個設備,"s3c-fb","exynos4-fb"。


7. 現在,找到了,平臺總線的設備和驅動后,我們要做的主要事情就是去修改lcd的各種參數,主要是fb_info結構體

??? 的fb_var_screeninfo結構體,這里面記錄了lcd的主要9個參數。

?? 行前肩,行后肩,行同步信號脈寬,幀前肩,幀后肩,幀同步信號脈寬,像素時鐘頻率,x軸像素點,y軸像素點。

??? 分析了s3c_fb.c文件后,發現是這句來賦值,fb_videomode_to_var(&fbinfo->var, &initmode);

??? 經過再次分析后,實際數據是來源于平臺總線設備中,pd = pdev->dev.platform_data;


8.? 那么我們再次回到devs.c這個文件,因為上面兩個平臺總線設備均定義在次文件中。

??? 但是查看s3c_device_fb和s5p_device_fimd0這兩個平臺設備結構體后,沒有發現platform_data。那么一定是后面

?? 專門有賦值的地方。查找后,發現

?? void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
{
?? ?s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
?? ??? ??? ? &s3c_device_fb);
}

void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
{
?? ?s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
?? ??? ??? ? &s5p_device_fimd0);
}

?? 經過搜索發現,s5p_fimd0_set_platdata在 下面文件中調用,

??arch/arm/mach-exynos/mach-nanopc-t1.c

?? arch/arm/mach-exynos/mach-smdk4x12.c? 這個文件應該沒用

???s3c_fb_set_platdata沒有被任何地方調用,那么s3c_device_fb這個設備應該沒有用處,我認為應該去掉。


9. 接下來我們主要分析s5p_device_fimd0這個設備。

??? 在mach-nano-t1.c 這句 兩句

??? nanopc_fb_init_pdata(&nanopc_fb_pdata);

??? s5p_fimd0_set_platdata(&nanopc_fb_pdata);

??? 實際真正的數據是在nanopc_fb_pdata中,并且在nanopc_fb_init_pdata中得到的值

??? 再看nanopc_fb_init_pdata這個函數,發現以下幾句

??? lcd = tiny4412_get_lcd();

???? mode->left_margin?? ?= lcd->timing.h_bp;
?? ?mode->right_margin?? ?= lcd->timing.h_fp;
?? ?mode->upper_margin?? ?= lcd->timing.v_bp;
?? ?mode->lower_margin?? ?= lcd->timing.v_fp;
?? ?mode->hsync_len?? ??? ?= lcd->timing.h_sw;
?? ?mode->vsync_len?? ??? ?= lcd->timing.v_sw;
?? ?mode->xres?? ??? ??? ?= lcd->width;
?? ?mode->yres?? ??? ??? ?= lcd->height;

??? 數據實際來源于tiny4412_get_lcd()。

??? tiny4412_get_lcd定義在

??? arch/arm/mach-exynos/tiny4412-lcds.c

???? 到此,我們終于找到各種屏的參數定義,并且還有hdmi參數的定義。

???
??? 待續

???

???

總結

以上是生活随笔為你收集整理的nano-pc-t1 4412 显示驱动分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。