1. 程式人生 > >[RK3399][Android7.1] DDR動態頻率調節驅動小結

[RK3399][Android7.1] DDR動態頻率調節驅動小結

OS: Android 7.1
Board: Firefly-RK3399
Kernel: v4.4.55

devfreq介紹:

rk3288平臺上, gpu和ddr有自己的一套dvfs機制,而在rk3399平臺,使用了系統的devfreq框架。

devfreq 是核心開發者定義的一套支援動態調整裝置頻率和電壓的的框架模型。它能有效的降
低該裝置的功耗,同時兼顧其效能。
devfreq 通過不同的變頻策略,選擇一個合適的頻率供裝置使用,目前的核心版本提供了以下
幾種策略:

  • Simple Ondemand :根據負載動態調頻調壓;
  • Userspace:使用者自己設定電壓和頻率,系統不會自動調整;
  • Powersave:功耗優先,始終將頻率設定在最低值;
  • Performance:效能優先,始終將頻率設定為最高值。

devfreq和cpufreq的功能類似,只是前者用於控制device的clock,後者用來控制cpu.

這裡寫圖片描述

dts配置:
dmc, dynamic memory controller

    dmc: dmc {
        compatible = "rockchip,rk3399-dmc";
        devfreq-events = <&dfi>;
        interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0
>; clocks = <&cru SCLK_DDRCLK>; clock-names = "dmc_clk"; ddr_timing = <&ddr_timing>; status = "disabled"; };

dfi,全稱不曉得,用於監控dmc的loading模組

    dfi: dfi@ff630000 {
        reg = <0x00 0xff630000 0x00 0x4000>;
        compatible = "rockchip,rk3399-dfi";
        rockchip,pmu = <&pmugrf>;
        clocks = <&cru PCLK_DDR_MON
>; clock-names = "pclk_ddr_mon"; status = "disabled"; };

ddr timing:

ddr_timing: ddr_timing {
        compatible = "rockchip,ddr-timing";
        ddr3_speed_bin = <21>;
        pd_idle = <0>;
        sr_idle = <0>;
        sr_mc_gate_idle = <0>;
        srpd_lite_idle  = <0>;
        standby_idle = <0>;
        dram_dll_dis_freq = <300>;
        phy_dll_dis_freq = <125>;

        ddr3_odt_dis_freq = <333>;
        ddr3_drv = <DDR3_DS_40ohm>;
        ddr3_odt = <DDR3_ODT_120ohm>;
        phy_ddr3_ca_drv = <PHY_DRV_ODT_40>;
        phy_ddr3_dq_drv = <PHY_DRV_ODT_40>;
        phy_ddr3_odt = <PHY_DRV_ODT_240>;

        lpddr3_odt_dis_freq = <333>;
        lpddr3_drv = <LP3_DS_34ohm>;
        lpddr3_odt = <LP3_ODT_240ohm>;
        phy_lpddr3_ca_drv = <PHY_DRV_ODT_40>;
        phy_lpddr3_dq_drv = <PHY_DRV_ODT_40>;
        phy_lpddr3_odt = <PHY_DRV_ODT_240>;

        lpddr4_odt_dis_freq = <333>;
        lpddr4_drv = <LP4_PDDS_60ohm>;
        lpddr4_dq_odt = <LP4_DQ_ODT_40ohm>;
        lpddr4_ca_odt = <LP4_CA_ODT_40ohm>;
        phy_lpddr4_ca_drv = <PHY_DRV_ODT_40>;
        phy_lpddr4_ck_cs_drv = <PHY_DRV_ODT_80>;
        phy_lpddr4_dq_drv = <PHY_DRV_ODT_80>;
        phy_lpddr4_odt = <PHY_DRV_ODT_60>;
    };

freq table:

    dmc_opp_table: opp-table3 {
        compatible = "operating-points-v2";

        [email protected]200000000 {
            opp-hz = /bits/ 64 <200000000>;
            opp-microvolt = <825000>;
        };
        [email protected]297000000 {
            opp-hz = /bits/ 64 <297000000>;
            opp-microvolt = <850000>;
        };
        [email protected]400000000 {
            opp-hz = /bits/ 64 <400000000>;
            opp-microvolt = <850000>;
        };
        [email protected]594000000 {
            opp-hz = /bits/ 64 <594000000>;
            opp-microvolt = <900000>;
        };
        [email protected]800000000 {
            opp-hz = /bits/ 64 <800000000>;
            opp-microvolt = <900000>;
        };
    };

驅動檔案:
目錄:
kernel/drivers/devfreq
檔案:
governor_simpleondemand.c: 策略控制
devfreq.c: devfreq framework
devfreq-event.c:  event驅動,結合dfi
rockchip_dmc.c: rk dmc驅動
rockchip-dfi.c: rk dfi驅動

驅動流程:

  • dmc註冊:
rockchip_dmcfreq_probe ->  rockchip_dmc.c
  devm_regulator_get(dev, "center");  //需要在dts中配置center-supply 屬性
  devfreq_event_get_edev_by_phandle //獲取dfi device
  devfreq_event_enable_edev //使能dfi監測
  of_get_ddr_timings //獲取ddr timing
  rockchip_dmcfreq_init_freq_table //讀取scaling table表
  clk_get_rate(data->dmc_clk); //獲取要設定的預設ddr頻率
  devm_devfreq_add_device //新增到devfreq框架中,預設策略是 "simple_ondemand"。

核心在於profile結構:

static struct devfreq_dev_profile rockchip_devfreq_dmc_profile = {
    .polling_ms = 200, //loading查詢週期
    .target     = rockchip_dmcfreq_target,//設定電壓和頻率
    .get_dev_status = rockchip_dmcfreq_get_dev_status, //獲取loading
    .get_cur_freq   = rockchip_dmcfreq_get_cur_freq, //獲取當前頻率
};
  • dfi註冊:
rockchip_dfi_probe -> rockchip-dfi.c
  devm_devfreq_event_add_edev //作為一個event device新增到devfreq框架中

核心在於event ops:

static const struct devfreq_event_ops rockchip_dfi_ops = {
    .disable = rockchip_dfi_disable,
    .enable = rockchip_dfi_enable,
    .get_event = rockchip_dfi_get_event,
    .set_event = rockchip_dfi_set_event,
};
  • loading獲取及頻率設定:

系統會在polling_ms個週期也就是200ms讀取一次loading,然後決定是否需要調整電壓和頻率。

devfreq_simple_ondemand_handler -> governor_simpleondemand.c
  devfreq_monitor_start -> devfreq.c
    queue_delayed_work -> 
      devfreq_monitor ->    
        update_devfreq -> 
          devfreq->governor->get_target_freq -> 
            devfreq_simple_ondemand_func -> governor_simpleondemand.c
              devfreq_update_stats ->
                df->profile->get_dev_status ->
                  rockchip_dmcfreq_get_dev_status -> rockchip_dmc.c
                    devfreq_event_get_event -> devfreq-event.c
                      edev->desc->ops->get_event ->
                        rockchip_dfi_get_event ->
                          rockchip_dfi_get_busier_ch //獲取dmc每個channel的busy情況,也就是loading
           devfreq->profile->get_cur_freq -> //獲取當前頻率
             rockchip_dmcfreq_get_cur_freq rockchip_dmc.c
           devfreq->profile->target ->  //設定頻率和電壓
             rockchip_dmcfreq_target -> rockchip_dmc.c

相關推薦

[RK3399][Android7.1] DDR動態頻率調節驅動小結

OS: Android 7.1 Board: Firefly-RK3399 Kernel: v4.4.55 devfreq介紹: rk3288平臺上, gpu和ddr有自己的一套dvfs機制,而在rk3399平臺,使用了系統的devfreq框架。

[RK3399][Android7.1] Display中的edp驅動呼叫流程

OS: Android 7.1 Board: Firefly-RK3399 Kernel: v4.4.55 edp驅動被分成兩個檔案,一個是rk驅動檔案: analogix_dp-rockchip.c, 另一個是drm驅動檔案analogix_dp_c

[RK3399][Android7.1] 除錯筆記 --- DDR工作頻率的獲取和設定

OS: Android 7.1 Board: Firefly-RK3399 Kernel: v4.4.55   之前有提到loader中有設定ddr頻率為800MHz,當kernel中開啟了ddr devfreq之後,驅動載入時會獲取ddr預設頻率。

[RK3399][Android7.1] 除錯筆記ADC驅動配置及使用

平臺 核心版本 安卓版本 RK3399 Linux4.4 Android7.1 文章目錄 結構體 配置步驟

[RK3399][Android7.1]Rockchip PWM Backlight 驅動分析

平臺 核心版本 安卓版本 RK3399 Linux4.4 Android7.1 文章目錄 DTS 驅動分析

[RK3399][Android7.1] 學習筆記 DRM驅動程式開發(介紹)

平臺 核心版本 安卓版本 rk Linux4.4 Android7.1 1. 簡介 DRM 全稱是 Direct Rendering Mana

[RK3399][Android7.1] 除錯筆記 --- DDR中clock相關配置

OS: Android 7.1 Board: Firefly-RK3399 Kernel: v4.4.55 把這個拎出來說是因為在除錯ddr default rate的時候對這部分有些誤區。 dmc中clock相關的配置有: dmc:

[RK3399][Android7.1] 除錯筆記 --- 模組編譯32位動態

Platform: RK3399 OS: Android 7.1 Board: Firefly-RK3399 需求: 系統HAL的camera庫camera.rk30board.so使用的是

[RK3399][Android7.1]開發環境搭建

最後還是安裝了雙系統,在Ubuntu16.04下編譯的,以下的解決方法依然後效;/(ㄒoㄒ)/~~ ######################黃金分割線########################### Virtual Machine:Vmware 14, Linux:Ubuntu16

[RK3399][Android7.1] Vmware虛擬機器裡的Ubuntu硬碟空間越來越大

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 背景: Vmware裡的Ubuntu系統隨著使用會越來越大,比如編譯了Android系統,即使編譯後刪除了也是佔虛擬硬碟空間, 最終會吃掉物理硬碟空間。 解決方法: 使

[RK3399][Android7.1] 除錯筆記 --- OTA diff升級輸入法異常

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 現象: 之前因為版權的原因替換了輸入法。請參考:[RK3399][Android7.1] 除錯筆記 —谷歌拼音替換搜狗輸入法 但是再做OTA升級的時候發現輸入法升級異常。

[RK3399][Android7.1] 除錯筆記 --- 解決開關按鍵時產生的Pop聲

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 背景: 按鍵音在開啟和關閉的時候,會有pop聲。 原因: audio codec後面有個功放,功放一直開啟著,當codec開啟和關閉的時候,會有噪聲帶進到功放中。

[RK3399][Android7.1] 除錯筆記 --- Sending non-protected broadcast ...

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 使用自定義的廣播,然後用命令列測試的時候出現如下warning: 1300 D AndroidRuntime: Calling main entry com.android.com

[RK3399][Android7.1] 除錯筆記 --- USB:device descriptor read/64, error -32

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 現象: 由於rk3399四個usb口不能滿足數量需求,對其中的usb3.0(非OTG口)進行外接Hub(用的是GL850)做擴充套件。 插上U盤後出現如下error: [

[RK3399][Android7.1] 除錯筆記 --- USB:no configuration chosen from 1 choice

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 背景: 由於rk3399四個usb口不能滿足數量需求,對其中的usb3.0(非OTG口)進行外接Hub做擴充套件成3個USB2.0+1一個USB3.0。 原理圖如下: 現象

[RK3399][Android7.1] 除錯筆記 --- Android7.1 Launcher選擇位置

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 一開始沒找到在哪選擇切換Launcher,記錄下。 步驟: 1. 進入Settings app 2. Apps 3. Settings 4. Home app

[RK3399][Android7.1] 除錯筆記 --- I2S1工作輸出是12MHz問題

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 現象: 使用I2S1通道,測量到的I2S MCLK是12MHz. 理論上應該是11.288MHz. 原因: rk3399平臺有三路I2S(其中一路內部使用,可以不管),

[RK3399][Android7.1] 除錯筆記 --- SD卡升級不會清除data

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 現象: 使用update.img製作sd卡升級完成後發現不會清除data分割槽 原因: 像rk3288 android6.0上會在recovery中設定misc分割槽,

RK3399 android7.1 DTS 電壓域的配置

     RK3399的CPU採用big.LITTLE大小核架構,雙Cortex-A72大核+四Cortex-A53小核結構,對整數、浮點、記憶體等作了大幅優化,在整體效能、功耗及核心面積三個方面都具革命性提升。 RK3399的GPU採用四核ARM新一代高階影象處理器Mali

[RK3399][Android7.1] 除錯筆記 --- 預編譯呼叫第三方庫

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 背景: 現在在Framework層及以下經常會呼叫到第三方的C++演算法庫,比如語音識別,人臉識別等等。