[RK3399][Android7.1] DDR动态频率调节驱动小结
2018-01-22 19:16
1261 查看
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的功能类似,只是前者用来控制cpu,后者用于控制device的clock.
dts配置:
dmc, dynamic memory controller
dfi,全称不晓得,用于监控dmc的loading模块
ddr timing:
freq table:
功能开启参见:
[RK3399][Android7.1] 调试笔记 — DDR动态调节功能开启
驱动文件:
目录:
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注册:
核心在于profile结构:
dfi注册:
核心在于event ops:
loading获取及频率设置:
系统会在polling_ms个周期也就是200ms读取一次loading,然后决定是否需要调整电压和频率。
Board: Firefly-RK3399
Kernel: v4.4.55
devfreq介绍:
rk3288平台上, gpu和ddr有自己的一套dvfs机制,而在rk3399平台,使用了系统的devfreq框架。
devfreq 是内核开发者定义的一套支持动态调整设备频率和电压的的框架模型。它能有效的降
低该设备的功耗,同时兼顾其性能。
devfreq 通过不同的变频策略,选择一个合适的频率供设备使用,目前的内核版本提供了以下
几种策略:
Simple Ondemand :根据负载动态调频调压;
Userspace:用户自己设置电压和频率,系统不会自动调整;
Powersave:功耗优先,始终将频率设置在最低值;
Performance:性能优先,始终将频率设置为最高值。
devfreq和cpufreq的功能类似,只是前者用来控制cpu,后者用于控制device的clock.
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"; opp@200000000 { opp-hz = /bits/ 64 <200000000>; opp-microvolt = <825000>; }; opp@297000000 { opp-hz = /bits/ 64 <297000000>; opp-microvolt = <850000>; }; opp@400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <850000>; }; opp@594000000 { opp-hz = /bits/ 64 <594000000>; opp-microvolt = <900000>; }; opp@800000000 { opp-hz = /bits/ 64 <800000000>; opp-microvolt = <900000>; }; };
功能开启参见:
[RK3399][Android7.1] 调试笔记 — DDR动态调节功能开启
驱动文件:
目录:
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动态调节功能开启
- [RK3399][Android7.1] 调试笔记 --- 查看当前DDR的工作频率
- [RK3399][Android7.1] 调试笔记 --- DDR工作频率的获取和设置
- [RK3399][Android7.1] 调试笔记 --- 提高DDR频率到933MHz
- [RK3399][Android7.1] 调试笔记 --- DDR的开机频率和大小
- [RK3399][Android7.1] Uboot display 加载过程小结
- [RK3399][Android7.1] Uboot启动过程小结
- [RK3399][Android7.1] Display中的edp驱动调用流程
- [RK3399][Android7.1] 调试笔记 --- DDR中的freq table
- [RK3399][Android7.1] 调试笔记 --- DDR中clock相关配置
- RK3399 Android上面调试IMX291 Camera驱动
- [RK3399][Android7.1] Ubuntu编译环境内存要求
- [RK3399][Android7.1] Uboot重要文件及目录
- [RK3399][Android7.1] DRM中的Component System
- [RK3399][Android7.1] 调试笔记 --- 系统使用的init.rc
- [RK3399][Android7.1] 调试笔记 --- 系统默认时钟配置
- [RK3399][Android7.1] Ubuntu 编译环境安装依赖包失败
- [RK3399][Android7.1] Android Ninja编译系统介绍
- [RK3399][Android7.1] Camera HAL初始化流程
- [RK3399][Android7.1] 调试笔记 --- tablet版本sdk下载