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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

QCom MSM MDP显示驱动一些点的简记

發布時間:2025/4/16 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QCom MSM MDP显示驱动一些点的简记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡要記錄了Qualcom MSM8xxx MDP Framebuffer驅動中的一些點。

Framebuffer設備的sysfs

330static int msm_fb_create_sysfs(struct platform_device *pdev)

331{

332???????? int rc;

333???????? struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);

334

335???????? rc = sysfs_create_group(&mfd->fbi->dev->kobj, &msm_fb_attr_group);

336???????? if (rc)

337???????????????????????? MSM_FB_ERR("%s: sysfs group creation failed, rc=%d\n", __func__,

338???????????????????????????????????????? rc);

339???????? return rc;

340}

?

root@android:/sys/class/graphics/fb0 # ls -al

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 bits_per_pixel

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 blank

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 console

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 cursor

-r--r--r-- root???? root???????? 4096 1970-06-27 09:37 dev

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 mode

-rw-r--r-- root? ???root???????? 4096 1970-06-27 09:37 modes

-r--r--r-- root???? root???????? 4096 1970-06-27 09:37 msm_fb_type

-r--r--r-- root???? root???????? 4096 1970-06-27 09:37 name

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 pan

drwxr-xr-x root???? root? ????????????1970-06-27 08:28 power

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 rotate

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 state

-r--r--r-- root???? root???????? 4096 1970-06-27 09:37 stride

lrwxrwxrwx root???? root??????????? ??1970-06-27 09:37 subsystem -> ../../../../class/graphics

-rw-r--r-- root???? root???????? 4096 1970-06-27 08:28 uevent

-rw-r--r-- root???? root???????? 4096 1970-06-27 09:37 virtual_size

-r--r--r-- root???? root???????? 4096 1970-06-27 08:28 vsync_event

root@android:/sys/class/graphics/fb0 # cat msm_fb_type????????????????????????

mipi dsi cmd panel

root@android:/sys/class/graphics/fb0 # cat bits_per_pixel?????????????????????

32

130|root@android:/sys/class/graphics/fb0 # cat dev

29:0

root@android:/sys/class/graphics/fb0 # cat modes

U:480x854p-0

root@android:/sys/class/graphics/fb0 # cat name

msmfb42_90501

root@android:/sys/class/graphics/fb0 # cat stride

1920

root@android:/sys/class/graphics/fb0 # cat virtual_size?????????????????????

480,2566

?

cont_splash_done?field

Add support for "Continuous Splash Screen" feature.

The image displayed on the screen by the android bootloaderdriver should continue till the android animation shows up.

Delay the display initialization for MDP, display dependent clocksand panel power on functions.

bootloader顯示的image在linux內核啟動過程中保持顯示在屏幕上,知道開機動畫顯示,即linux內核啟動過程中不要出現黑屏。

?

Early suspend & Early resume

Early suspend是有wakelock還占有,系統還不能整體suspend,但是可以關閉屏幕、背光、輸入等;在Early suspended狀態時,重新打開屏幕、背光和輸入,是為對應的early resume。

fb_register中相關設置如下:

1551?????????????????????? mfd->early_suspend.suspend = msmfb_early_suspend;

1552?????????????????????? mfd->early_suspend.resume = msmfb_early_resume;

1553?????????????????????? mfd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;

1554?????????????????????? register_early_suspend(&mfd->early_suspend);

數據結構定義如下:

23/* The early_suspend structure defines suspend and resume hooks to be called

24 * when the user visible sleep state of the system changes, and a level to

25 * control the order. They can be used to turn off the screen and input

26 * devices that are not used for wakeup.

27 * Suspend handlers are called in low to high level order, resume handlers are

28 * called in the opposite order. If, when calling register_early_suspend,

29 * the suspend handlers have already been called without a matching call to the

30 * resume handlers, the suspend handler will be called directly from

31 * register_early_suspend. This direct call can violate the normal level order.

32 */

33enum {

34?????????? EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50,

35?????????? EARLY_SUSPEND_LEVEL_STOP_DRAWING = 100,

36?????????? EARLY_SUSPEND_LEVEL_DISABLE_FB = 150,

37};

38struct early_suspend {

39#ifdef CONFIG_HAS_EARLYSUSPEND

40?????????? struct list_head link;

41?????????? int level;

42?????????? void (*suspend)(struct early_suspend *h);

43?????????? void (*resume)(struct early_suspend *h);

44#endif

45};

?

backlight

msm_fb_set_backlight以后是使用led_trigger調用真正led_classdev "wled"brightnes_set去設置背光。

用戶態ioctl通過msm_fb_set_backlight調用到msm_fb_panel_data::set_backlight

"lcd_backlight".brightness_set -> msm_fb_panel_data::set_backlight -> "bkl_trigger".led_trigger -> "wled".brightness_set。然后找真正操作硬件IC部分。

驅動中設置背光則是繞過"lcd_backlight"設備直接通過backlight_worker工作執行到msm_fb_panel_data::set_backlight,然后-> "bkl_trigger".led_trigger -> "wled".brightness_set。

可以認為"lcd_backlight"是背光抽象設備,通過led_triggerled組映射到不同的led_classdev設備

以三星DSI CMD屏為例:

In mipi_samsung.c

294static void mipi_samsung_set_backlight(struct msm_fb_data_type *mfd)

295{

296???????? if (!cci_fb_UpdateDone){

297???????????????????????? printk("Taylor: No BL before LCM on\n");

298???????????????????????? return;

299???????? }

300

301???????? pr_debug("Taylor: %s : Set BL:%d\n",__func__, mfd->bl_level);

302???????? if ((mipi_samsung_pdata->enable_wled_bl_ctrl)

303???????? ??? && (wled_trigger_initialized)) {

304???????????????????????? led_trigger_event(bkl_led_trigger, mfd->bl_level);

305???????????????????????? return;

306???????? }

307}

?

kernel/drivers/leds/leds-pm8xxx.c

#define PM8XXX_LEDS_DEV_NAME?????? "pm8xxx-led"

2283static struct platform_driver pm8xxx_led_driver = {

2284?????? .probe????????????????? = pm8xxx_led_probe,

2285?????? .remove?????????????????????????????? = __devexit_p(pm8xxx_led_remove),

2286?????? .driver?????????????????? = {

2287?????????????????????? .name?? = PM8XXX_LEDS_DEV_NAME,

2288?????????????????????? .owner = THIS_MODULE,

2289?????? },

2290};

?

pm8xxx_led_probe會對pm8038_led_info數組中的每個led使用設置led_classdev字段,并且初始化work item,然后使用led_classdev_register向系統注冊每個led設備。

2197?????????????????????? INIT_WORK(&led_dat->work, pm8xxx_led_work);

2198?????????????????????? INIT_WORK(&led_dat->modework, pm8xxx_mode_work);

2199?????????????????????? INIT_WORK(&led_dat->testwork, pm8xxx_test_work);

?

每個ledbrightness_set字段設置為pm8xxx_led_set。

1790static void pm8xxx_led_set(struct led_classdev *led_cdev,

1791?????? enum led_brightness value)

1792{

1793?????? struct??? pm8xxx_led_data *led;

1794

1795?????? led = container_of(led_cdev, struct pm8xxx_led_data, cdev);

1796

1797?????? if (value < LED_OFF || value > led->cdev.max_brightness) {

1798?????????????????????? dev_err(led->cdev.dev, "Invalid brightness value exceeds");

1799?????????????????????? return;

1800?????? }

1801

1802?????? led->cdev.brightness = value;

1803?????? schedule_work(&led->work);

1804}

?

1730static void pm8xxx_led_work(struct work_struct *work)

1731{

1732?????? int rc;

1733

1734?????? struct pm8xxx_led_data *led = container_of(work,

1735?????????????????????????????????????????????????????????????????????? struct pm8xxx_led_data, work);

1736

1737?????? if (led->pwm_dev == NULL) {

1738?????????????????????? __pm8xxx_led_work(led, led->cdev.brightness);

1739?????? } else {

1740?????????????????????? rc = pm8xxx_led_pwm_work(led);

1741?????????????????????? if (rc)

1742?????????????????????????????????????? pr_err("could not configure PWM mode for LED:%d\n",

1743?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? led->id);

1744?????? }

1745}

PM8XXX_ID_WLED,是使用__pm8xxx_led_work

1692static void __pm8xxx_led_work(struct pm8xxx_led_data *led,

1693?????????????????????????????????????????????????????????????????????? enum led_brightness level)

1694{

1695?????? int rc;

1696

1697?????? mutex_lock(&led->lock);

1698

1699?????? switch (led->id) {

1700?????? case PM8XXX_ID_LED_KB_LIGHT:

1701?????????????????????? led_kp_set(led, level);

1702?????????????????????? break;

1703?????? case PM8XXX_ID_LED_0:

1704?????? case PM8XXX_ID_LED_1:

1705?????? case PM8XXX_ID_LED_2:

1706?????????????????????? led_lc_set(led, level);

1707?????????????????????? break;

1708?????? case PM8XXX_ID_FLASH_LED_0:

1709?????? case PM8XXX_ID_FLASH_LED_1:

1710?????????????????????? led_flash_set(led, level);

1711?????????????????????? break;

1712??????case PM8XXX_ID_WLED:

1713??????????????????????rc = led_wled_set(led, level);

1714?????????????????????? if (rc < 0)

1715?????????????????????????????????????? pr_err("wled brightness set failed %d\n", rc);

1716?????????????????????? break;

1717?????? case PM8XXX_ID_RGB_LED_RED:

1718?????? case PM8XXX_ID_RGB_LED_GREEN:

1719?????? case PM8XXX_ID_RGB_LED_BLUE:

1720?????????????????????? led_rgb_set(led, level);

1721?????????????????????? break;

1722?????? default:

1723?????????????????????? dev_err(led->cdev.dev, "unknown led id %d", led->id);

1724?????????????????????? break;

1725?????? }

1726

1727?????? mutex_unlock(&led->lock);

1728}

led_wled_set寫電源管理芯片pm8xxx的控制寄存器,控制wled。

?

Framebuffer fb_info::node

registered_fb它是一個數組,它的類型就是struct fb_info,它用于保存我們調用register_framebuffer傳進來的struct fb_info。

num_registered_fb代表注冊幀緩沖設備的個數。

? ?1522 ? ? ? ? for (i = 0; i < FB_MAX; i++)
? ?1523 ? ? ? ? ? ? ? ? if (!registered_fb[i])
? ?1524 ? ? ? ? ? ? ? ? ? ? ? ? break;
? ?1525 ? ? ? ? fb_info->node = i;

相當于找到一個空的次設備號。

?

Framebuffer像素格式

主屏Framebuffer格式?RGBA8888, config時指定;屏格式為RGB565或RGB888,由overlay pipe做轉換。

In mipi_dsi_probe()

481???????? /*

482???????? * get/set panel specific fb info

483???????? */

484???????? mfd->panel_info = pdata->panel_info;

485???????? pinfo = &mfd->panel_info;

486

487???????? if (mfd->panel_info.type == MIPI_VIDEO_PANEL)

488???????????????????????? mfd->dest = DISPLAY_LCDC;

489???????? else

490?????????????????????????mfd->dest = DISPLAY_LCD;

491

492???????? if (mdp_rev == MDP_REV_303 &&

493???????????????????????? mipi_dsi_pdata->get_lane_config) {

494???????????????????????? if (mipi_dsi_pdata->get_lane_config() != 2) {

495???????????????????????????????????????? pr_info("Changing to DSI Single Mode Configuration\n");

496#ifdef CONFIG_FB_MSM_MDP303

497???????????????????????????????????????? update_lane_config(pinfo);

498#endif

499???????????????????????? }

500???????? }

501

502???????? if (mfd->index == 0)

503?????????????????????????mfd->fb_imgType = MSMFB_DEFAULT_TYPE;?? // configed as RGBA8888 for fb0

504???????? else

505???????????????????????? mfd->fb_imgType = MDP_RGB_565;

?

msmfb_update_notify/ msmfb_no_update_notify

用于CABL功能時,統計直方圖使用;

更新屏幕前complete(&msmfb_update_notify)從而在準確時間點啟動直方圖統計;2*HZ后,msmfb_no_update_notify_timer超時,在timer超時回調中complete(&mfd->msmfb_no_update_notify)結束直方圖統計。

?

sw_refresher

使用定時器去觸發mdp_refresh_screen,添加work進行dma_fnc調用。

針對某些接口的VIDEO模式屏且控制器沒有hw_refresh支持時,可以使用sw_refresher。

?

FB_ACTIVATE_VBL標志涵義

fb_var_screeninfo結構體的成員變量activate的值設置FB_ACTIVATE_VBL,表示要等到下一個垂直同步事件出現時,再將當前要渲染的圖形緩沖區的內容繪制出來。這樣做的目的是避免出現屏幕閃爍,即避免前后兩個圖形緩沖區的內容各有一部分同時出現屏幕中。

總結

以上是生活随笔為你收集整理的QCom MSM MDP显示驱动一些点的简记的全部內容,希望文章能夠幫你解決所遇到的問題。

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