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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 亮屏速度分析

發布時間:2023/12/20 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 亮屏速度分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.



前面聊的

最近在調試項目的亮屏速度,我們希望在按下power鍵后到亮屏這個時間能達到500MS以內,在Rockchip 3399和3288上面的時間都不能達到要求,因此引發了一系列的調試之路。

計算按下power鍵到亮屏的時間

Android 喚醒時間統計
剛開始的時候,我只在android階段統計時間,也能看到時間的差異,但是不是最準確的,我統計的時間日志如下

01-18?09:13:40.992?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?743ms
01-18?09:13:45.304?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?757ms
01-18?09:13:49.559?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?725ms
01-18?09:18:27.461?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?741ms
01-18?09:18:32.766?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?743ms
01-18?09:18:35.861?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?745ms
01-18?09:18:38.345?683?772?D?SurfaceControl:?Excessive?delay?in?setPowerMode():?733ms

Kernel從Power到亮屏的時間統計
后來同事中的精英古總在他的代碼上加入了從按下Power鍵到亮屏的時間,直接通過printk打印,代碼如下

diff?--git?a/drivers/gpu/drm/panel/panel-simple.c?b/drivers/gpu/drm/panel/panel-simple.c
old?mode?100644
new?mode?100755
index?17c3b94..2b39662
---?a/drivers/gpu/drm/panel/panel-simple.c
+++?b/drivers/gpu/drm/panel/panel-simple.c
@@?-504,6?+504,7?@@?static?int?panel_simple_enable(struct?drm_panel?*panel)
????????}

????????p->enabled?=?true;
+???????printk("%s?exit\n",?__func__);

????????return?0;
?}
diff?--git?a/drivers/input/keyboard/rk_keys.c?b/drivers/input/keyboard/rk_keys.c
old?mode?100644
new?mode?100755
index?fed5ced..537b599
---?a/drivers/input/keyboard/rk_keys.c
+++?b/drivers/input/keyboard/rk_keys.c
@@?-134,6?+134,10?@@?static?void?keys_timer(unsigned?long?_data)
????????????????key_dbg(pdata,?"%skey[%s]:?report?event[%d]?state[%d]\n",
????????????????????????button->type?==?TYPE_ADC???"adc"?:?"gpio",
????????????????????????button->desc,?button->code,?button->state);
+???????????????if(strcmp(button->desc,?"power")?==?0)
+???????????????printk("%skey[%s]:?report?event[%d]?state[%d]\n",
+???????????????????????button->type?==?TYPE_ADC???"adc"?:?"gpio",
+???????????????????????button->desc,?button->code,?button->state);
????????????????input_event(input,?EV_KEY,?button->code,?button->state);
????????????????input_sync(input);
????????}

統計每個驅動的resume函數調用時間

上面的時間對我們調試非常有用,然后就需要細分到每個驅動的resume函數執行的時間,用的方法是我之前寫過的,大概統計了下TP,LCD,sensor的resume時間,發現TP和LCD占用的時間非常多,然后跟同事一起看了下,同事把TP resume里面的代碼用工作隊列實現后速度明顯有了提升。
然后有很長一段時間不知道干嘛,想打印其他每個驅動的resume時間,一直沒找到方法,后面看到一個代碼,非常有用。
kernel/drivers/base/power/main.c

static?void?dpm_show_time(ktime_t?starttime,?pm_message_t?state,?char?*info)???????????????????????????????????????????????????????
{????????????????
????ktime_t?calltime;
????u64?usecs64;
????int?usecs;

????calltime?=?ktime_get();
????usecs64?=?ktime_to_ns(ktime_sub(calltime,?starttime));
????do_div(usecs64,?NSEC_PER_USEC);
????usecs?=?usecs64;
????if?(usecs?==?0)
????????usecs?=?1;?
????pr_info("PM:?%s%s%s?of?devices?complete?after?%ld.%03ld?msecs\n",
????????info??:?"",?info???"?"?:?"",?pm_verb(state.event),
????????usecs?/?USEC_PER_MSEC,?usecs?%?USEC_PER_MSEC);
}???

這個函數用來打印resume的函數消耗的時間,但是如何去觸發打印這個函數呢?

  • 一定保證設備進入深度睡眠,串口也進入深度睡眠,沒有任何打印后。

  • 執行以下命令

echo?N?>?/sys/module/printk/parameters/console_suspend
//使控制臺在suspend最后才關閉,這樣可以打印出休眠過程完整信息
echo?1?>?/sys/power/pm_print_times
//使能調試變量

打印的LOG類似下面的

[?37.031413]?bcmsdh_sdmmc_resume?Exit
[?37.082174]?PM:?resume?of?devices?complete?after?78.589?msecs
[?37.085277]?[BT_RFKILL]:?**?disable?irq
[?37.087645]?Restarting?tasks?...?

修改Lcd配置減小resume時間

古總在調試過程中展現了非常厲害的功底,第一步就是修改了LCD的參數,讓亮屏時間加快。修改如下

---?a/arch/arm/boot/dts/rk3288-pad.dts
+++?b/arch/arm/boot/dts/rk3288-pad.dts
@@?-169,10?+169,10?@@
????????????????dsi,lanes?=?<4>;

????????????????prepare-delay-ms?=?<20>;
-???????????????init-delay-ms?=?<20>;
-???????????????enable-delay-ms?=?<100>;
-???????????????disable-delay-ms?=?<20>;
-???????????????unprepare-delay-ms?=?<20>;
+???????????????//init-delay-ms?=?<20>;
+???????????????enable-delay-ms?=?<1>;
+???????????????disable-delay-ms?=?<1>;
+???????????????unprepare-delay-ms?=?<1>;
????????????????panel-init-sequence?=?[
????????????????????????15?32?02?8F?A5
????????????????????????15?01?02?83?00

修改DRM 超時時間減小喚醒時間

這是最關鍵的,DRM框架非常復雜,RK也是從開源的DRM移植過來使用,在DRM部分有個時間超時導致問題,最終跟RK拿到最新的patch讓喚醒時間直接加速500MS.
我們在日志下發現問題,并給詢問了RK,最終發現這部分代碼沒有更新到最新的部分。

hi rk:
為什么亮屏的時候有時候會打印這句VOP等待超時?請問下這是什么意思。
[ 1211.293492] rockchip-vop ff930000.vop: wait win close timeout
[ 1211.293514] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 1200*1920, close all win
有時候卻不會打印。

[ 1216.423283] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 12001920, close all win [ 1223.899741] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 12001920, close all win
[ 1234.386252] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 1200*1920, close all win

patch代碼如下

---?a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++?b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@?-139,6?+139,9?@@
?#define?to_vop_win(x)?container_of(x,?struct?vop_win,?base)
?#define?to_vop_plane_state(x)?container_of(x,?struct?vop_plane_state,?base)

+/*add?by?VENDOR_PATCH?for?seep?up?the?drm?vop?driver?at?2018/1/18?for?RK?Defect?#191554,?VENDOR_PATCH?PAD100-193*/
+#define?VENDOR_PATCH
+
?struct?vop_zpos?{
????????int?win_id;
????????int?zpos;
@@?-868,9?+871,15?@@?static?void?vop_disable_all_planes(struct?vop?*vop)

????????vop_disable_allwin(vop)
;
????????vop_cfg_done(vop);
+#ifdef?VENDOR_PATCH
????????ret?=?readx_poll_timeout_atomic(vop_is_allwin_disabled,
????????????????????????????????????????vop,?active,?active,
+???????????????????????????????????????0,?100?*?1000);
+#else
+???????ret?=?readx_poll_timeout_atomic(vop_is_allwin_disabled,
+???????????????????????????????vop,?active,?active,
????????????????????????????????????????0,?500?*?1000);
+#endif
????????if?(ret)
????????????????dev_err(vop->dev,?"wait?win?close?timeout\n");
?}
@@?-2215,20?+2224,36?@@?static?size_t?vop_crtc_bandwidth(struct?drm_crtc?*crtc,
????????u16?htotal?=?adjusted_mode->crtc_htotal;
????????u16?vdisplay?=?adjusted_mode->crtc_vdisplay;
????????int?clock?=?adjusted_mode->crtc_clock;
+#ifndef?VENDOR_PATCH
????????struct?vop?*vop?=?to_vop(crtc
)
;
????????const?struct?vop_data?*vop_data?=?vop->data;
+#endif
????????struct?vop_plane_state?*vop_plane_state;
????????struct?drm_plane_state?*pstate;
????????struct?vop_bandwidth?*pbandwidth;
????????struct?drm_plane?*plane;
????????u64?bandwidth;
????????int?i,?cnt?=?0;
+#ifdef?VENDOR_PATCH
+???????int?plane_num?=?0;
+#endif

????????if?(!htotal?||?!vdisplay)
????????????????return?0;

+#ifndef?VENDOR_PATCH
????????pbandwidth?=?kmalloc_array(vop_data->win_size,?sizeof(*pbandwidth),
???????????????????????????????????GFP_KERNEL);
+#else
+???????for_each_plane_in_state(state,?plane,?pstate,?i)?{
+???????????????if?(pstate->crtc?!=?crtc?||?!pstate->fb)
+???????????????????????continue;
+???????????????plane_num++;
+???????}
+???????pbandwidth?=?kmalloc_array(plane_num,?sizeof(*pbandwidth),
+??????????????????????????????????GFP_KERNEL);
+#endif
+
????????if?(!pbandwidth)
????????????????return?-ENOMEM;

@@?-2421,7?+2446,10?@@?static?void?vop_crtc_enable(struct?drm_crtc?*crtc)
????????rockchip_set_system_status(sys_status)
;
????????mutex_lock(&vop->vop_lock);
????????vop_initial(crtc);
-
+#ifdef?VENDOR_PATCH
+???????vop_disable_allwin(vop);
+???????VOP_CTRL_SET(vop,?standby,?0);
+#endif
????????VOP_CTRL_SET(vop,?dclk_pol,?1);
????????val?=?(adjusted_mode->flags?&?DRM_MODE_FLAG_NHSYNC)??
???????????????????0?:?BIT(HSYNC_POSITIVE);
@@?-2549,8?+2577,9?@@?static?void?vop_crtc_enable(struct?drm_crtc?*crtc)
????????/*
?????????*?enable?vop,?all?the?register?would?take?effect?when?vop?exit?standby
?????????*/

+#ifndef?VENDOR_PATCH
????????VOP_CTRL_SET(vop,?standby,?0)
;
-
+#endif
????????enable_irq(vop->irq);
????????drm_crtc_vblank_on(crtc);
????????mutex_unlock(&vop->vop_lock);


修改QOS相關代碼

QOS為Quality Of Service(服務質量)的簡稱,對PM QoS而言,表示Linux kernel電源管理相關的服務質量。那到底什么是服務質量呢?

我們知道,Linux PM的主要功能,是節省功耗,但同時,會付出一定的性能代價,例如延遲(latency)增加、吞吐量(throughput)下降。可以把PM當作一種服務,把它對性能的影響,類比為服務的質量(QoS)。對性能的影響越大,QoS越低,反之越高。

我們可以這么認為,我們在某個時候需要增加代碼的執行速度,就通過這個去控制CPU的運行策略,這樣確保代碼可以快速執行。

不過這個方法沒有使用到,如果對某個resume時間不是十分滿意,可以嘗試這個方法。

休眠喚醒流程圖

從網上拷貝了個休眠喚醒的流程圖,如果以后有問題需要分析的話,可以跟進這個流程去排查。

參考

https://www.spinics.net/lists/linux-pm/msg24063.html
http://eeepage.info/pm-failed-suspend-wakeup_event/
https://blog.csdn.net/qq_695538007/article/details/41208135
https://blog.csdn.net/jacobywu/article/details/24735521


當你看到這里的時候,說明你已經閱讀完上面的內容,不管怎樣,感謝您有心或者無意的關注和支持,

覺得不錯,請幫忙轉發點好看,您的每一次支持,我都將銘記于心

公眾號接入了AI功能,隨意回復任意消息哦(比如笑話,天氣

想獲取學習資料,請點擊狀態欄公眾號福利按鈕






總結

以上是生活随笔為你收集整理的Android 亮屏速度分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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