sdm: Add interface for QOS calculation.

1. Populate properties for bandwidth/clock calculation and store it
   as a part of hw resource info.
2. Define interface to pass computed bandwidth/clock for each hardware
   interface separately.

Change-Id: I1bd03136e97f77f5fd3b26c7b8aa958238d007ab
CRs-Fixed: 2048927
This commit is contained in:
Ramkumar Radhakrishnan
2017-03-09 18:46:41 -08:00
parent a4af3debeb
commit 9ed1fd8e79
7 changed files with 97 additions and 17 deletions

View File

@@ -39,6 +39,9 @@
#include "xf86drmMode.h" #include "xf86drmMode.h"
namespace sde_drm { namespace sde_drm {
typedef std::map<std::pair<uint32_t, uint64_t>, float> CompRatioMap;
/* /*
* Drm Atomic Operation Codes * Drm Atomic Operation Codes
*/ */
@@ -140,6 +143,24 @@ enum struct DRMOps {
* 1: speculative * 1: speculative
*/ */
CRTC_SET_OUTPUT_FENCE_OFFSET, CRTC_SET_OUTPUT_FENCE_OFFSET,
/*
* Op: Sets overall SDE core clock
* Arg: uint32_t - CRTC ID
* uint32_t - core_clk
*/
CRTC_SET_CORE_CLK,
/*
* Op: Sets overall SDE core average bandwidth
* Arg: uint32_t - CRTC ID
* uint32_t - core_ab
*/
CRTC_SET_CORE_AB,
/*
* Op: Sets overall SDE core instantaneous bandwidth
* Arg: uint32_t - CRTC ID
* uint32_t - core_ib
*/
CRTC_SET_CORE_IB,
/* /*
* Op: Returns release fence for this frame. Should be called after Commit() on * Op: Returns release fence for this frame. Should be called after Commit() on
* DRMAtomicReqInterface. * DRMAtomicReqInterface.
@@ -253,6 +274,21 @@ struct DRMCrtcInfo {
uint32_t max_blend_stages; uint32_t max_blend_stages;
QSEEDVersion qseed_version; QSEEDVersion qseed_version;
SmartDMARevision smart_dma_rev; SmartDMARevision smart_dma_rev;
float ib_fudge_factor;
float clk_fudge_factor;
uint32_t dest_scale_prefill_lines;
uint32_t undersized_prefill_lines;
uint32_t macrotile_prefill_lines;
uint32_t nv12_prefill_lines;
uint32_t linear_prefill_lines;
uint32_t downscale_prefill_lines;
uint32_t extra_prefill_lines;
uint32_t amortized_threshold;
uint64_t max_bandwidth_low;
uint64_t max_bandwidth_high;
uint32_t max_sde_clk;
CompRatioMap comp_ratio_rt_map;
CompRatioMap comp_ratio_nrt_map;
}; };
enum struct DRMPlaneType { enum struct DRMPlaneType {
@@ -277,6 +313,7 @@ struct DRMPlaneTypeInfo {
uint32_t max_downscale; uint32_t max_downscale;
uint32_t max_horizontal_deci; uint32_t max_horizontal_deci;
uint32_t max_vertical_deci; uint32_t max_vertical_deci;
uint64_t max_pipe_bandwidth;
}; };
// All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority // All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
@@ -437,7 +474,7 @@ class DRMManagerInterface {
* Will query post propcessing feature info of a CRTC. * Will query post propcessing feature info of a CRTC.
* [output]: DRMPPFeatureInfo: CRTC post processing feature info * [output]: DRMPPFeatureInfo: CRTC post processing feature info
*/ */
virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0; virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
/* /*
* Register a logical display to receive a token. * Register a logical display to receive a token.
* Each display pipeline in DRM is identified by its CRTC and Connector(s). * Each display pipeline in DRM is identified by its CRTC and Connector(s).

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. * Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@@ -49,6 +49,7 @@ enum DebugTag {
kTagRotator, //!< Debug log is tagged for rotator. kTagRotator, //!< Debug log is tagged for rotator.
kTagScalar, //!< Debug log is tagged for Scalar Helper. kTagScalar, //!< Debug log is tagged for Scalar Helper.
kTagQDCM, //!< Debug log is tagged for display QDCM color managing. kTagQDCM, //!< Debug log is tagged for display QDCM color managing.
kTagQOSClient, //!< Debug log is tagged for Qos client
}; };
/*! @brief Display debug handler class. /*! @brief Display debug handler class.

View File

@@ -111,11 +111,12 @@ enum HWAVRModes {
}; };
typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap; typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
typedef std::map<LayerBufferFormat, float> CompRatioMap;
struct HWDynBwLimitInfo { struct HWDynBwLimitInfo {
uint32_t cur_mode = kBwDefault; uint32_t cur_mode = kBwDefault;
uint32_t total_bw_limit[kBwModeMax] = { 0 }; uint64_t total_bw_limit[kBwModeMax] = { 0 };
uint32_t pipe_bw_limit[kBwModeMax] = { 0 }; uint64_t pipe_bw_limit[kBwModeMax] = { 0 };
}; };
struct HWPipeCaps { struct HWPipeCaps {
@@ -142,6 +143,7 @@ struct HWDestScalarInfo {
uint32_t max_input_width = 0; uint32_t max_input_width = 0;
uint32_t max_output_width = 0; uint32_t max_output_width = 0;
uint32_t max_scale_up = 1; uint32_t max_scale_up = 1;
uint32_t prefill_lines = 4;
}; };
enum SmartDMARevision { enum SmartDMARevision {
@@ -169,7 +171,7 @@ struct HWResourceInfo {
uint32_t max_mixer_width = 2048; uint32_t max_mixer_width = 2048;
uint32_t max_pipe_width = 2048; uint32_t max_pipe_width = 2048;
uint32_t max_cursor_size = 0; uint32_t max_cursor_size = 0;
uint32_t max_pipe_bw = 0; uint64_t max_pipe_bw = 0;
uint32_t max_sde_clk = 0; uint32_t max_sde_clk = 0;
float clk_fudge_factor = 1.0f; float clk_fudge_factor = 1.0f;
uint32_t macrotile_nv12_factor = 0; uint32_t macrotile_nv12_factor = 0;
@@ -185,7 +187,6 @@ struct HWResourceInfo {
bool has_macrotile = false; bool has_macrotile = false;
bool has_non_scalar_rgb = false; bool has_non_scalar_rgb = false;
bool is_src_split = false; bool is_src_split = false;
bool perf_calc = false;
bool has_dyn_bw_support = false; bool has_dyn_bw_support = false;
bool separate_rotator = false; bool separate_rotator = false;
bool has_qseed3 = false; bool has_qseed3 = false;
@@ -200,6 +201,11 @@ struct HWResourceInfo {
bool has_avr = false; bool has_avr = false;
bool has_hdr = false; bool has_hdr = false;
SmartDMARevision smart_dma_rev = SmartDMARevision::V1; SmartDMARevision smart_dma_rev = SmartDMARevision::V1;
float ib_fudge_factor = 1.0f;
uint32_t undersized_prefill_lines = 0;
CompRatioMap comp_ratio_rt_map;
CompRatioMap comp_ratio_nrt_map;
void Reset() { *this = HWResourceInfo(); } void Reset() { *this = HWResourceInfo(); }
}; };
@@ -432,6 +438,7 @@ struct HWAVRInfo {
}; };
struct HWPipeInfo { struct HWPipeInfo {
HWPipeInfo *pair = NULL;
uint8_t rect = 255; uint8_t rect = 255;
uint32_t pipe_id = 0; uint32_t pipe_id = 0;
HWSubBlockType sub_block_type = kHWSubBlockMax; HWSubBlockType sub_block_type = kHWSubBlockMax;
@@ -496,8 +503,9 @@ struct HWLayers {
HWLayersInfo info; HWLayersInfo info;
HWLayerConfig config[kMaxSDELayers]; HWLayerConfig config[kMaxSDELayers];
float output_compression = 1.0f; float output_compression = 1.0f;
uint32_t bandwidth = 0; uint64_t ab_bps = 0;
uint32_t clock = 0; uint64_t ib_bps = 0;
uint32_t clock_hz = 0;
HWAVRInfo hw_avr_info = {}; HWAVRInfo hw_avr_info = {};
}; };

View File

@@ -695,6 +695,13 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
} }
} }
} }
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, hw_layers->clock_hz);
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, hw_layers->ab_bps);
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, hw_layers->ib_bps);
DLOGI_IF(kTagDriverConfig, "System: clock=%d Hz, ab=%llu Bps ib=%llu Bps", hw_layers->clock_hz,
hw_layers->ab_bps, hw_layers->ib_bps);
} }
} }

View File

@@ -135,7 +135,7 @@ HWInfoDRM::~HWInfoDRM() {
DisplayError HWInfoDRM::GetDynamicBWLimits(HWResourceInfo *hw_resource) { DisplayError HWInfoDRM::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info; HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
for (int index = 0; index < kBwModeMax; index++) { for (int index = 0; index < kBwModeMax; index++) {
bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low); bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw; bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
} }
@@ -164,14 +164,13 @@ DisplayError HWInfoDRM::GetHWResourceInfo(HWResourceInfo *hw_resource) {
hw_resource->linear_factor = 1; hw_resource->linear_factor = 1;
hw_resource->scale_factor = 1; hw_resource->scale_factor = 1;
hw_resource->extra_fudge_factor = 2; hw_resource->extra_fudge_factor = 2;
hw_resource->amortizable_threshold = 0; hw_resource->amortizable_threshold = 25;
hw_resource->system_overhead_lines = 0; hw_resource->system_overhead_lines = 0;
hw_resource->hw_dest_scalar_info.count = 0; hw_resource->hw_dest_scalar_info.count = 0;
hw_resource->hw_dest_scalar_info.max_scale_up = 0; hw_resource->hw_dest_scalar_info.max_scale_up = 0;
hw_resource->hw_dest_scalar_info.max_input_width = 0; hw_resource->hw_dest_scalar_info.max_input_width = 0;
hw_resource->hw_dest_scalar_info.max_output_width = 0; hw_resource->hw_dest_scalar_info.max_output_width = 0;
hw_resource->is_src_split = true; hw_resource->is_src_split = true;
hw_resource->perf_calc = false;
hw_resource->has_dyn_bw_support = false; hw_resource->has_dyn_bw_support = false;
hw_resource->has_qseed3 = false; hw_resource->has_qseed3 = false;
hw_resource->has_concurrent_writeback = false; hw_resource->has_concurrent_writeback = false;
@@ -254,6 +253,33 @@ void HWInfoDRM::GetSystemInfo(HWResourceInfo *hw_resource) {
hw_resource->num_blending_stages = info.max_blend_stages; hw_resource->num_blending_stages = info.max_blend_stages;
hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ? hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ?
SmartDMARevision::V2 : SmartDMARevision::V1; SmartDMARevision::V2 : SmartDMARevision::V1;
hw_resource->ib_fudge_factor = info.ib_fudge_factor;
hw_resource->hw_dest_scalar_info.prefill_lines = info.dest_scale_prefill_lines;
hw_resource->undersized_prefill_lines = info.undersized_prefill_lines;
hw_resource->macrotile_factor = info.macrotile_prefill_lines;
hw_resource->macrotile_nv12_factor = info.nv12_prefill_lines;
hw_resource->linear_factor = info.linear_prefill_lines;
hw_resource->scale_factor = info.downscale_prefill_lines;
hw_resource->extra_fudge_factor = info.extra_prefill_lines;
hw_resource->amortizable_threshold = info.amortized_threshold;
hw_resource->max_bandwidth_low = info.max_bandwidth_low / kKiloUnit;
hw_resource->max_bandwidth_high = info.max_bandwidth_high / kKiloUnit;
hw_resource->max_sde_clk = info.max_sde_clk;
std::vector<LayerBufferFormat> sdm_format;
for (auto &it : info.comp_ratio_rt_map) {
std::pair<uint32_t, uint64_t> drm_format = it.first;
GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
sdm_format.clear();
}
for (auto &it : info.comp_ratio_nrt_map) {
std::pair<uint32_t, uint64_t> drm_format = it.first;
GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
sdm_format.clear();
}
} }
void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) { void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) {
@@ -305,6 +331,7 @@ void HWInfoDRM::PopulatePipeCaps(const sde_drm::DRMPlaneTypeInfo &info,
hw_resource->max_scale_down = info.max_downscale; hw_resource->max_scale_down = info.max_downscale;
hw_resource->max_scale_up = info.max_upscale; hw_resource->max_scale_up = info.max_upscale;
hw_resource->has_decimation = info.max_horizontal_deci > 1 && info.max_vertical_deci > 1; hw_resource->has_decimation = info.max_horizontal_deci > 1 && info.max_vertical_deci > 1;
hw_resource->max_pipe_bw = info.max_pipe_bandwidth / kKiloUnit;
} }
void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type, void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type,

View File

@@ -71,6 +71,8 @@ class HWInfoDRM: public HWInfoInterface {
// TODO(user): Read Mdss version from the driver // TODO(user): Read Mdss version from the driver
static const int kHWMdssVersion5 = 500; // MDSS_V5 static const int kHWMdssVersion5 = 500; // MDSS_V5
static const int kMaxStringLength = 1024; static const int kMaxStringLength = 1024;
static const int kKiloUnit = 1000;
static HWResourceInfo *hw_resource_; static HWResourceInfo *hw_resource_;
}; };

View File

@@ -95,7 +95,7 @@ DisplayError HWInfo::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info; HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
for (int index = 0; index < kBwModeMax; index++) { for (int index = 0; index < kBwModeMax; index++) {
bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low); bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw; bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
} }
@@ -169,9 +169,9 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
} else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) { } else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
hw_resource_->max_scale_up = UINT32(atoi(tokens[1])); hw_resource_->max_scale_up = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) { } else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
hw_resource_->max_bandwidth_low = UINT64(atol(tokens[1])); hw_resource_->max_bandwidth_low = std::stoull(tokens[1]);
} else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) { } else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
hw_resource_->max_bandwidth_high = UINT64(atol(tokens[1])); hw_resource_->max_bandwidth_high = std::stoull(tokens[1]);
} else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) { } else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
hw_resource_->max_mixer_width = UINT32(atoi(tokens[1])); hw_resource_->max_mixer_width = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) { } else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) {
@@ -179,7 +179,7 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
} else if (!strncmp(tokens[0], "max_cursor_size", strlen("max_cursor_size"))) { } else if (!strncmp(tokens[0], "max_cursor_size", strlen("max_cursor_size"))) {
hw_resource_->max_cursor_size = UINT32(atoi(tokens[1])); hw_resource_->max_cursor_size = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) { } else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
hw_resource_->max_pipe_bw = UINT32(atoi(tokens[1])); hw_resource_->max_pipe_bw = std::stoull(tokens[1]);
} else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) { } else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
hw_resource_->max_sde_clk = UINT32(atoi(tokens[1])); hw_resource_->max_sde_clk = UINT32(atoi(tokens[1]));
} else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) { } else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
@@ -224,8 +224,6 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
hw_resource_->is_src_split = true; hw_resource_->is_src_split = true;
} else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) { } else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
hw_resource_->has_non_scalar_rgb = true; hw_resource_->has_non_scalar_rgb = true;
} else if (!strncmp(tokens[i], "perf_calc", strlen("perf_calc"))) {
hw_resource_->perf_calc = true;
} else if (!strncmp(tokens[i], "dynamic_bw_limit", strlen("dynamic_bw_limit"))) { } else if (!strncmp(tokens[i], "dynamic_bw_limit", strlen("dynamic_bw_limit"))) {
hw_resource_->has_dyn_bw_support = true; hw_resource_->has_dyn_bw_support = true;
} else if (!strncmp(tokens[i], "separate_rotator", strlen("separate_rotator"))) { } else if (!strncmp(tokens[i], "separate_rotator", strlen("separate_rotator"))) {