msm: vidc: Enhance bus scaling algorithm
Enhance current bus scaling algorithm to make use of run time
UBWC stats of compression ratios(CR) and complexity factor(CF).
CRs-Fixed: 2012520
Change-Id: I3d2f61ab7e49b8fa9f953e3fb381261fde34c42a
Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c b/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
index f7ce757..d329a8b 100644
--- a/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
+++ b/drivers/media/platform/msm/vidc/governors/msm_vidc_dyn_gov.c
@@ -16,6 +16,7 @@
#include "msm_vidc_internal.h"
#include "msm_vidc_debug.h"
#include "vidc_hfi_api.h"
+#define COMPRESSION_RATIO_MAX 5
static bool debug;
module_param(debug, bool, 0644);
@@ -30,13 +31,6 @@
struct devfreq_governor devfreq_gov;
};
-enum scenario {
- SCENARIO_WORST,
- SCENARIO_SUSTAINED_WORST,
- SCENARIO_AVERAGE,
- SCENARIO_MAX,
-};
-
/*
* Minimum dimensions that the governor is willing to calculate
* bandwidth for. This means that anything bandwidth(0, 0) ==
@@ -62,15 +56,9 @@
#define kbps(__mbps) ((__mbps) * 1000)
#define bps(__mbps) (kbps(__mbps) * 1000)
-#define GENERATE_SCENARIO_PROFILE(__average, __worst) { \
- [SCENARIO_AVERAGE] = (__average), \
- [SCENARIO_WORST] = (__worst), \
- [SCENARIO_SUSTAINED_WORST] = (__worst), \
-}
-
-#define GENERATE_COMPRESSION_PROFILE(__bpp, __average, __worst) { \
+#define GENERATE_COMPRESSION_PROFILE(__bpp, __worst) { \
.bpp = __bpp, \
- .ratio = GENERATE_SCENARIO_PROFILE(__average, __worst), \
+ .ratio = __worst, \
}
/*
@@ -85,109 +73,168 @@
* 4096 2160| 44 88| 2.2 1.26 1.97 1.22|
* 4096 2304| 48 96| 2.2 1.26 1.97 1.22|
*/
-#define COMPRESSION_RATIO_MAX 2
static struct lut {
int frame_size; /* width x height */
- unsigned long bitrate[SCENARIO_MAX];
+ int frame_rate;
+ unsigned long bitrate;
struct {
int bpp;
- fp_t ratio[SCENARIO_MAX];
+ fp_t ratio;
} compression_ratio[COMPRESSION_RATIO_MAX];
} const LUT[] = {
{
.frame_size = 1280 * 720,
- .bitrate = GENERATE_SCENARIO_PROFILE(7, 14),
+ .frame_rate = 30,
+ .bitrate = 14,
.compression_ratio = {
GENERATE_COMPRESSION_PROFILE(8,
- FP(1, 69, 100),
FP(1, 28, 100)),
GENERATE_COMPRESSION_PROFILE(10,
- FP(1, 49, 100),
+ FP(1, 23, 100)),
+ }
+ },
+ {
+ .frame_size = 1280 * 720,
+ .frame_rate = 60,
+ .bitrate = 22,
+ .compression_ratio = {
+ GENERATE_COMPRESSION_PROFILE(8,
+ FP(1, 28, 100)),
+ GENERATE_COMPRESSION_PROFILE(10,
FP(1, 23, 100)),
}
},
{
.frame_size = 1920 * 1088,
- .bitrate = GENERATE_SCENARIO_PROFILE(20, 40),
+ .frame_rate = 30,
+ .bitrate = 40,
.compression_ratio = {
GENERATE_COMPRESSION_PROFILE(8,
- FP(1, 69, 100),
FP(1, 28, 100)),
GENERATE_COMPRESSION_PROFILE(10,
- FP(1, 49, 100),
+ FP(1, 23, 100)),
+ }
+ },
+ {
+ .frame_size = 1920 * 1088,
+ .frame_rate = 60,
+ .bitrate = 64,
+ .compression_ratio = {
+ GENERATE_COMPRESSION_PROFILE(8,
+ FP(1, 28, 100)),
+ GENERATE_COMPRESSION_PROFILE(10,
FP(1, 23, 100)),
}
},
{
.frame_size = 2560 * 1440,
- .bitrate = GENERATE_SCENARIO_PROFILE(32, 64),
+ .frame_rate = 30,
+ .bitrate = 64,
.compression_ratio = {
GENERATE_COMPRESSION_PROFILE(8,
- FP(2, 20, 100),
FP(1, 26, 100)),
GENERATE_COMPRESSION_PROFILE(10,
- FP(1, 97, 100),
+ FP(1, 22, 100)),
+ }
+ },
+ {
+ .frame_size = 2560 * 1440,
+ .frame_rate = 60,
+ .bitrate = 102,
+ .compression_ratio = {
+ GENERATE_COMPRESSION_PROFILE(8,
+ FP(1, 26, 100)),
+ GENERATE_COMPRESSION_PROFILE(10,
FP(1, 22, 100)),
}
},
{
.frame_size = 3840 * 2160,
- .bitrate = GENERATE_SCENARIO_PROFILE(42, 84),
+ .frame_rate = 30,
+ .bitrate = 84,
.compression_ratio = {
GENERATE_COMPRESSION_PROFILE(8,
- FP(2, 20, 100),
FP(1, 26, 100)),
GENERATE_COMPRESSION_PROFILE(10,
- FP(1, 97, 100),
+ FP(1, 22, 100)),
+ }
+ },
+ {
+ .frame_size = 3840 * 2160,
+ .frame_rate = 60,
+ .bitrate = 134,
+ .compression_ratio = {
+ GENERATE_COMPRESSION_PROFILE(8,
+ FP(1, 26, 100)),
+ GENERATE_COMPRESSION_PROFILE(10,
FP(1, 22, 100)),
}
},
{
.frame_size = 4096 * 2160,
- .bitrate = GENERATE_SCENARIO_PROFILE(44, 88),
+ .frame_rate = 30,
+ .bitrate = 88,
.compression_ratio = {
GENERATE_COMPRESSION_PROFILE(8,
- FP(2, 20, 100),
FP(1, 26, 100)),
GENERATE_COMPRESSION_PROFILE(10,
- FP(1, 97, 100),
+ FP(1, 22, 100)),
+ }
+ },
+ {
+ .frame_size = 4096 * 2160,
+ .frame_rate = 60,
+ .bitrate = 141,
+ .compression_ratio = {
+ GENERATE_COMPRESSION_PROFILE(8,
+ FP(1, 26, 100)),
+ GENERATE_COMPRESSION_PROFILE(10,
FP(1, 22, 100)),
}
},
{
.frame_size = 4096 * 2304,
- .bitrate = GENERATE_SCENARIO_PROFILE(48, 96),
+ .frame_rate = 30,
+ .bitrate = 96,
.compression_ratio = {
GENERATE_COMPRESSION_PROFILE(8,
- FP(2, 20, 100),
FP(1, 26, 100)),
GENERATE_COMPRESSION_PROFILE(10,
- FP(1, 97, 100),
+ FP(1, 22, 100)),
+ }
+ },
+ {
+ .frame_size = 4096 * 2304,
+ .frame_rate = 60,
+ .bitrate = 154,
+ .compression_ratio = {
+ GENERATE_COMPRESSION_PROFILE(8,
+ FP(1, 26, 100)),
+ GENERATE_COMPRESSION_PROFILE(10,
FP(1, 22, 100)),
}
},
};
-static struct lut const *__lut(int width, int height)
+static struct lut const *__lut(int width, int height, int fps)
{
int frame_size = height * width, c = 0;
do {
- if (LUT[c].frame_size >= frame_size)
+ if (LUT[c].frame_size >= frame_size && LUT[c].frame_rate >= fps)
return &LUT[c];
} while (++c < ARRAY_SIZE(LUT));
return &LUT[ARRAY_SIZE(LUT) - 1];
}
-static fp_t __compression_ratio(struct lut const *entry, int bpp,
- enum scenario s)
+static fp_t __compression_ratio(struct lut const *entry, int bpp)
{
int c = 0;
for (c = 0; c < COMPRESSION_RATIO_MAX; ++c) {
if (entry->compression_ratio[c].bpp == bpp)
- return entry->compression_ratio[c].ratio[s];
+ return entry->compression_ratio[c].ratio;
}
WARN(true, "Shouldn't be here, LUT possibly corrupted?\n");
@@ -282,23 +329,20 @@
* measured heuristics and hardcoded numbers taken from the firmware.
*/
/* Decoder parameters */
- enum scenario scenario;
- int width, height, lcu_size, dpb_bpp, opb_bpp, fps;
+ int width, height, lcu_size, dpb_bpp, opb_bpp, fps, opb_factor;
bool unified_dpb_opb, dpb_compression_enabled, opb_compression_enabled;
- fp_t dpb_opb_scaling_ratio, dpb_compression_factor,
- opb_compression_factor, qsmmu_bw_overhead_factor;
- int vmem_size; /* in kB */
+ fp_t dpb_opb_scaling_ratio, dpb_read_compression_factor,
+ dpb_write_compression_factor, opb_compression_factor,
+ qsmmu_bw_overhead_factor, height_ratio;
/* Derived parameters */
- int lcu_per_frame, tnbr_per_lcu_10bpc, tnbr_per_lcu_8bpc, tnbr_per_lcu,
- colocated_bytes_per_lcu, vmem_line_buffer, vmem_chroma_cache,
- vmem_luma_cache, vmem_chroma_luma_cache;
+ int lcu_per_frame, tnbr_per_lcu, colocated_bytes_per_lcu;
unsigned long bitrate;
+
fp_t bins_to_bit_factor, dpb_write_factor, ten_bpc_packing_factor,
ten_bpc_bpp_factor, vsp_read_factor, vsp_write_factor,
- ocmem_usage_lcu_factor, ref_ocmem_bw_factor_read,
- ref_ocmem_bw_factor_write, bw_for_1x_8bpc, dpb_bw_for_1x,
- motion_vector_complexity, row_cache_penalty, opb_bw;
+ bw_for_1x_8bpc, dpb_bw_for_1x,
+ motion_vector_complexity = 0, row_cache_penalty = 0, opb_bw = 0;
/* Output parameters */
struct {
@@ -306,17 +350,15 @@
line_buffer_read, line_buffer_write, recon_read,
recon_write, opb_read, opb_write, dpb_read, dpb_write,
total;
- } ddr, vmem;
+ } ddr = {0};
unsigned long ret = 0;
+ unsigned int integer_part, frac_part;
- /* Decoder parameters setup */
- scenario = SCENARIO_WORST;
+ width = max(d->input_width, BASELINE_DIMENSIONS.width);
+ height = max(d->input_height, BASELINE_DIMENSIONS.height);
- width = max(d->width, BASELINE_DIMENSIONS.width);
- height = max(d->height, BASELINE_DIMENSIONS.height);
-
- lcu_size = 32;
+ lcu_size = d->lcu_size;
dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX;
opb_bpp = d->num_formats >= 2 ? __bpp(d->color_formats[1]) : dpb_bpp;
@@ -325,134 +367,61 @@
unified_dpb_opb = d->num_formats == 1;
- dpb_opb_scaling_ratio = FP_ONE;
+ dpb_opb_scaling_ratio = fp_div(FP_INT(d->input_width * d->input_height),
+ FP_INT(d->output_width * d->output_height));
+ height_ratio = fp_div(d->input_height, d->output_height);
dpb_compression_enabled = d->num_formats >= 1 &&
__ubwc(d->color_formats[0]);
opb_compression_enabled = d->num_formats >= 2 &&
__ubwc(d->color_formats[1]);
- dpb_compression_factor = !dpb_compression_enabled ? FP_ONE :
- __compression_ratio(__lut(width, height), dpb_bpp, scenario);
+ /*
+ * Convert Q16 number into Integer and Fractional part upto 2 places.
+ * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752;
+ * Integer part = 105752 / 65536 = 1;
+ * Reminder = 105752 - 1 * 65536 = 40216;
+ * Fractional part = 40216 * 100 / 65536 = 61;
+ * Now converto to FP(1, 61, 100) for below code.
+ */
+
+ integer_part = d->compression_ratio >> 16;
+ frac_part =
+ ((d->compression_ratio - (integer_part * 65536)) * 100) >> 16;
+
+ dpb_read_compression_factor = FP(integer_part, frac_part, 100);
+
+ dpb_write_compression_factor = !dpb_compression_enabled ? FP_ONE :
+ __compression_ratio(__lut(width, height, fps), opb_bpp);
opb_compression_factor = !opb_compression_enabled ? FP_ONE :
- __compression_ratio(__lut(width, height), opb_bpp, scenario);
+ __compression_ratio(__lut(width, height, fps), opb_bpp);
- vmem_size = 512; /* in kB */
/* Derived parameters setup */
lcu_per_frame = DIV_ROUND_UP(width, lcu_size) *
DIV_ROUND_UP(height, lcu_size);
- bitrate = __lut(width, height)->bitrate[scenario];
+ bitrate = __lut(width, height, fps)->bitrate;
- bins_to_bit_factor = FP(1, 60, 100);
+ bins_to_bit_factor = d->work_mode == VIDC_WORK_MODE_1 ?
+ FP_INT(0) : FP_INT(4);
- dpb_write_factor = scenario == SCENARIO_AVERAGE ?
- FP_ONE : FP(1, 5, 100);
+ vsp_read_factor = bins_to_bit_factor + FP_INT(2);
+
+ dpb_write_factor = FP(1, 5, 100);
ten_bpc_packing_factor = FP(1, 67, 1000);
ten_bpc_bpp_factor = FP(1, 1, 4);
- vsp_read_factor = bins_to_bit_factor + FP_INT(2);
vsp_write_factor = bins_to_bit_factor;
- tnbr_per_lcu_10bpc = lcu_size == 16 ? 384 + 192 :
- lcu_size == 32 ? 640 + 256 :
- 1280 + 384;
- tnbr_per_lcu_8bpc = lcu_size == 16 ? 256 + 192 :
- lcu_size == 32 ? 512 + 256 :
- 1024 + 384;
- tnbr_per_lcu = dpb_bpp == 10 ? tnbr_per_lcu_10bpc : tnbr_per_lcu_8bpc;
+ tnbr_per_lcu = lcu_size == 16 ? 128 :
+ lcu_size == 32 ? 64 : 128;
colocated_bytes_per_lcu = lcu_size == 16 ? 16 :
lcu_size == 32 ? 64 : 256;
- ocmem_usage_lcu_factor = lcu_size == 16 ? FP(1, 8, 10) :
- lcu_size == 32 ? FP(1, 2, 10) :
- FP_ONE;
- ref_ocmem_bw_factor_read = vmem_size < 296 ? FP_ZERO :
- vmem_size < 648 ? FP(0, 1, 4) :
- FP(0, 55, 100);
- ref_ocmem_bw_factor_write = vmem_size < 296 ? FP_ZERO :
- vmem_size < 648 ? FP(0, 7, 10) :
- FP(1, 4, 10);
-
- /* Prelim b/w calculation */
- bw_for_1x_8bpc = fp_mult(FP_INT(width * height * fps),
- fp_mult(FP(1, 50, 100), dpb_write_factor));
- bw_for_1x_8bpc = fp_div(bw_for_1x_8bpc, FP_INT(bps(1)));
-
- dpb_bw_for_1x = dpb_bpp == 8 ? bw_for_1x_8bpc :
- fp_mult(bw_for_1x_8bpc, fp_mult(ten_bpc_packing_factor,
- ten_bpc_bpp_factor));
- /* VMEM adjustments */
- vmem_line_buffer = tnbr_per_lcu * DIV_ROUND_UP(width, lcu_size) / 1024;
- vmem_chroma_cache = dpb_bpp == 10 ? 176 : 128;
- vmem_luma_cache = dpb_bpp == 10 ? 353 : 256;
- vmem_chroma_luma_cache = vmem_chroma_cache + vmem_luma_cache;
-
- motion_vector_complexity = scenario == SCENARIO_AVERAGE ?
- FP(2, 66, 100) : FP_INT(4);
-
- row_cache_penalty = FP_ZERO;
- if (vmem_size < vmem_line_buffer + vmem_chroma_cache)
- row_cache_penalty = fp_mult(FP(0, 5, 100),
- motion_vector_complexity);
- else if (vmem_size < vmem_line_buffer + vmem_luma_cache)
- row_cache_penalty = fp_mult(FP(0, 7, 100),
- motion_vector_complexity);
- else if (vmem_size < vmem_line_buffer + vmem_chroma_cache
- + vmem_luma_cache)
- row_cache_penalty = fp_mult(FP(0, 3, 100),
- motion_vector_complexity);
- else
- row_cache_penalty = FP_ZERO;
-
-
- opb_bw = unified_dpb_opb ? FP_ZERO :
- fp_div(fp_div(bw_for_1x_8bpc, dpb_opb_scaling_ratio),
- opb_compression_factor);
-
- /* B/W breakdown on a per buffer type basis for VMEM */
- vmem.vsp_read = FP_ZERO;
- vmem.vsp_write = FP_ZERO;
-
- vmem.collocated_read = FP_ZERO;
- vmem.collocated_write = FP_ZERO;
-
- vmem.line_buffer_read = FP_INT(tnbr_per_lcu *
- lcu_per_frame * fps / bps(1));
- vmem.line_buffer_write = vmem.line_buffer_read;
-
- vmem.recon_read = FP_ZERO;
- vmem.recon_write = FP_ZERO;
-
- vmem.opb_read = FP_ZERO;
- vmem.opb_write = FP_ZERO;
-
- vmem.dpb_read = fp_mult(ocmem_usage_lcu_factor, fp_mult(
- ref_ocmem_bw_factor_read,
- dpb_bw_for_1x));
- vmem.dpb_write = fp_mult(ocmem_usage_lcu_factor, fp_mult(
- ref_ocmem_bw_factor_write,
- dpb_bw_for_1x));
-
- vmem.total = vmem.vsp_read + vmem.vsp_write +
- vmem.collocated_read + vmem.collocated_write +
- vmem.line_buffer_read + vmem.line_buffer_write +
- vmem.recon_read + vmem.recon_write +
- vmem.opb_read + vmem.opb_write +
- vmem.dpb_read + vmem.dpb_write;
-
- /*
- * Attempt to force VMEM to a certain frequency for 4K
- */
- if (width * height * fps >= 3840 * 2160 * 60)
- vmem.total = FP_INT(NOMINAL_BW_MBPS);
- else if (width * height * fps >= 3840 * 2160 * 30)
- vmem.total = FP_INT(SVS_BW_MBPS);
-
/* ........................................ for DDR */
ddr.vsp_read = fp_div(fp_mult(FP_INT(bitrate),
vsp_read_factor), FP_INT(8));
@@ -464,35 +433,51 @@
ddr.collocated_write = FP_INT(lcu_per_frame *
colocated_bytes_per_lcu * fps / bps(1));
- ddr.line_buffer_read = vmem_size ? FP_ZERO : vmem.line_buffer_read;
- ddr.line_buffer_write = vmem_size ? FP_ZERO : vmem.line_buffer_write;
+ ddr.line_buffer_read = FP_INT(tnbr_per_lcu *
+ lcu_per_frame * fps / bps(1));
+ ddr.line_buffer_write = ddr.line_buffer_read;
- ddr.recon_read = FP_ZERO;
- ddr.recon_write = fp_div(dpb_bw_for_1x, dpb_compression_factor);
+ motion_vector_complexity = FP_INT(4);
- ddr.opb_read = FP_ZERO;
- ddr.opb_write = opb_bw;
+ bw_for_1x_8bpc = fp_div(FP_INT(width * height), FP_INT(32 * 8));
- ddr.dpb_read = fp_div(fp_mult(dpb_bw_for_1x,
- motion_vector_complexity + row_cache_penalty),
- dpb_compression_factor);
- ddr.dpb_write = FP_ZERO;
+ bw_for_1x_8bpc = fp_mult(bw_for_1x_8bpc,
+ fp_div(FP_INT(256 * 30), FP_INT(1000 * 1000)));
+
+ dpb_bw_for_1x = dpb_bpp == 8 ? bw_for_1x_8bpc :
+ fp_mult(bw_for_1x_8bpc, fp_mult(ten_bpc_packing_factor,
+ ten_bpc_bpp_factor));
+
+ ddr.dpb_read = fp_div(fp_mult(fp_mult(dpb_bw_for_1x,
+ motion_vector_complexity), dpb_write_factor),
+ dpb_read_compression_factor);
+
+ ddr.dpb_write = fp_div(fp_mult(dpb_bw_for_1x, dpb_write_factor),
+ dpb_write_compression_factor);
+
+ opb_factor = dpb_bpp == 8 ? 8 : 4;
+
+ ddr.opb_read = unified_dpb_opb ? 0 : opb_compression_enabled ?
+ fp_div(fp_mult(fp_div(dpb_bw_for_1x, dpb_opb_scaling_ratio),
+ FP_INT(opb_factor)), height_ratio) : 0;
+ ddr.opb_write = unified_dpb_opb ? 0 : opb_compression_enabled ?
+ ddr.dpb_read : fp_div(fp_div(fp_mult(dpb_bw_for_1x,
+ FP(1, 50, 100)), dpb_opb_scaling_ratio),
+ opb_compression_factor);
ddr.total = ddr.vsp_read + ddr.vsp_write +
ddr.collocated_read + ddr.collocated_write +
- ddr.line_buffer_read + ddr.line_buffer_write +
- ddr.recon_read + ddr.recon_write +
ddr.opb_read + ddr.opb_write +
ddr.dpb_read + ddr.dpb_write;
qsmmu_bw_overhead_factor = FP(1, 3, 100);
+
ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor);
/* Dump all the variables for easier debugging */
if (debug) {
struct dump dump[] = {
{"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC},
- {"content", "%d", scenario},
{"LCU size", "%d", lcu_size},
{"DPB bitdepth", "%d", dpb_bpp},
{"frame rate", "%d", fps},
@@ -501,11 +486,12 @@
dpb_opb_scaling_ratio},
{"DPB compression", "%d", dpb_compression_enabled},
{"OPB compression", "%d", opb_compression_enabled},
- {"DPB compression factor", DUMP_FP_FMT,
- dpb_compression_factor},
+ {"DPB Read compression factor", DUMP_FP_FMT,
+ dpb_read_compression_factor},
+ {"DPB Write compression factor", DUMP_FP_FMT,
+ dpb_write_compression_factor},
{"OPB compression factor", DUMP_FP_FMT,
opb_compression_factor},
- {"VMEM size", "%dkB", vmem_size},
{"frame width", "%d", width},
{"frame height", "%d", height},
@@ -519,25 +505,11 @@
{"10bpc,BPP factor", DUMP_FP_FMT, ten_bpc_bpp_factor},
{"VSP read factor", DUMP_FP_FMT, vsp_read_factor},
{"VSP write factor", DUMP_FP_FMT, vsp_write_factor},
- {"TNBR/LCU_10bpc", "%d", tnbr_per_lcu_10bpc},
- {"TNBR/LCU_8bpc", "%d", tnbr_per_lcu_8bpc},
{"TNBR/LCU", "%d", tnbr_per_lcu},
{"colocated bytes/LCU", "%d", colocated_bytes_per_lcu},
- {"OCMEM usage LCU factor", DUMP_FP_FMT,
- ocmem_usage_lcu_factor},
- {"ref OCMEM b/w factor (read)", DUMP_FP_FMT,
- ref_ocmem_bw_factor_read},
- {"ref OCMEM b/w factor (write)", DUMP_FP_FMT,
- ref_ocmem_bw_factor_write},
{"B/W for 1x (NV12 8bpc)", DUMP_FP_FMT, bw_for_1x_8bpc},
{"DPB B/W For 1x (NV12)", DUMP_FP_FMT, dpb_bw_for_1x},
- {"VMEM", "", DUMP_HEADER_MAGIC},
- {"line buffer", "%d", vmem_line_buffer},
- {"chroma cache", "%d", vmem_chroma_cache},
- {"luma cache", "%d", vmem_luma_cache},
- {"luma & chroma cache", "%d", vmem_chroma_luma_cache},
-
{"DERIVED PARAMETERS (2)", "", DUMP_HEADER_MAGIC},
{"MV complexity", DUMP_FP_FMT, motion_vector_complexity},
{"row cache penalty", DUMP_FP_FMT, row_cache_penalty},
@@ -557,19 +529,6 @@
{"DPB read", DUMP_FP_FMT, ddr.dpb_read},
{"DPB write", DUMP_FP_FMT, ddr.dpb_write},
- {"INTERMEDIATE VMEM B/W", "", DUMP_HEADER_MAGIC},
- {"VSP read", "%d", vmem.vsp_read},
- {"VSP write", DUMP_FP_FMT, vmem.vsp_write},
- {"collocated read", DUMP_FP_FMT, vmem.collocated_read},
- {"collocated write", DUMP_FP_FMT, vmem.collocated_write},
- {"line buffer read", DUMP_FP_FMT, vmem.line_buffer_read},
- {"line buffer write", DUMP_FP_FMT, vmem.line_buffer_write},
- {"recon read", DUMP_FP_FMT, vmem.recon_read},
- {"recon write", DUMP_FP_FMT, vmem.recon_write},
- {"OPB read", DUMP_FP_FMT, vmem.opb_read},
- {"OPB write", DUMP_FP_FMT, vmem.opb_write},
- {"DPB read", DUMP_FP_FMT, vmem.dpb_read},
- {"DPB write", DUMP_FP_FMT, vmem.dpb_write},
};
__dump(dump, ARRAY_SIZE(dump));
}
@@ -579,7 +538,7 @@
ret = kbps(fp_round(ddr.total));
break;
case GOVERNOR_LLCC:
- ret = kbps(fp_round(vmem.total));
+ dprintk(VIDC_PROF, "LLCC Voting not supported yet\n");
break;
default:
dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__);
@@ -597,9 +556,9 @@
* measured heuristics and hardcoded numbers taken from the firmware.
*/
/* Encoder Parameters */
- enum scenario scenario, bitrate_scenario;
+
enum hal_video_codec standard;
- int width, height, fps, vmem_size;
+ int width, height, fps;
enum hal_uncompressed_format dpb_color_format;
enum hal_uncompressed_format original_color_format;
bool dpb_compression_enabled, original_compression_enabled,
@@ -618,35 +577,34 @@
fp_t bins_to_bit_factor, chroma_luma_factor_dpb, one_frame_bw_dpb,
chroma_luma_factor_original, one_frame_bw_original,
line_buffer_size_per_lcu, line_buffer_size, line_buffer_bw,
- original_vmem_requirement, bw_increase_p, bw_increase_b;
+ bw_increase_p, bw_increase_b;
int collocated_mv_per_lcu, max_transaction_size,
search_window_size_vertical_p, search_window_factor_p,
- search_window_factor_bw_p, vmem_size_p, available_vmem_p,
+ search_window_factor_bw_p,
search_window_size_vertical_b, search_window_factor_b,
- search_window_factor_bw_b, vmem_size_b, available_vmem_b;
+ search_window_factor_bw_b;
/* Output paramaters */
struct {
fp_t vsp_read, vsp_write, collocated_read, collocated_write,
line_buffer_read, line_buffer_write, original_read,
original_write, dpb_read, dpb_write, total;
- } ddr, vmem;
+ } ddr = {0};
unsigned long ret = 0;
+ fp_t integer_part, frac_part;
/* Encoder Parameters setup */
- scenario = SCENARIO_WORST;
standard = d->codec;
- width = max(d->width, BASELINE_DIMENSIONS.width);
- height = max(d->height, BASELINE_DIMENSIONS.height);
+ width = max(d->input_width, BASELINE_DIMENSIONS.width);
+ height = max(d->input_height, BASELINE_DIMENSIONS.height);
dpb_color_format = HAL_COLOR_FORMAT_NV12_UBWC;
original_color_format = d->num_formats >= 1 ?
d->color_formats[0] : HAL_UNUSED_COLOR;
fps = d->fps;
- bitrate_scenario = SCENARIO_WORST;
dpb_compression_enabled = __ubwc(dpb_color_format);
original_compression_enabled = __ubwc(original_color_format);
@@ -655,21 +613,30 @@
low_power = d->power_mode == VIDC_POWER_LOW;
b_frames_enabled = false;
- dpb_compression_factor = !dpb_compression_enabled ? FP_ONE :
- __compression_ratio(__lut(width, height),
- __bpp(dpb_color_format), scenario);
- original_compression_factor = !original_compression_enabled ? FP_ONE :
- __compression_ratio(__lut(width, height),
- __bpp(original_color_format), scenario);
+ /*
+ * Convert Q16 number into Integer and Fractional part upto 2 places.
+ * Ex : 105752 / 65536 = 1.61; 1.61 in Q16 = 105752;
+ * Integer part = 105752 / 65536 = 1;
+ * Reminder = 105752 - 1 * 65536 = 40216;
+ * Fractional part = 40216 * 100 / 65536 = 61;
+ * Now converto to FP(1, 61, 100) for below code.
+ */
+
+ integer_part = d->compression_ratio >> 16;
+ frac_part =
+ ((d->compression_ratio - (integer_part * 65536)) * 100) >> 16;
+
+ dpb_compression_factor = FP(integer_part, frac_part, 100);
+
+ original_compression_factor = dpb_compression_factor;
rotation = false;
cropping_or_scaling = false;
- vmem_size = 512; /* in kB */
/* Derived Parameters */
lcu_size = 16;
gop = b_frames_enabled ? GOP_IBBP : GOP_IPPP;
- bitrate = __lut(width, height)->bitrate[bitrate_scenario];
+ bitrate = __lut(width, height, fps)->bitrate;
bins_to_bit_factor = FP(1, 6, 10);
/*
@@ -713,16 +680,6 @@
collocated_mv_per_lcu = lcu_size == 16 ? 16 : 64;
max_transaction_size = 256;
- original_vmem_requirement = FP_INT(3 *
- (two_stage_encoding ? 2 : 1) * lcu_size);
- original_vmem_requirement = fp_mult(original_vmem_requirement,
- (FP_ONE + chroma_luma_factor_original));
- original_vmem_requirement += FP_INT((cropping_or_scaling ? 3 : 0) * 2);
- original_vmem_requirement = fp_mult(original_vmem_requirement,
- FP_INT(max_transaction_size));
- original_vmem_requirement = fp_div(original_vmem_requirement,
- FP_INT(1024));
-
search_window_size_vertical_p = low_power ? 32 :
b_frames_enabled ? 80 :
width > 2048 ? 64 : 48;
@@ -730,24 +687,16 @@
search_window_factor_bw_p = !two_stage_encoding ?
search_window_size_vertical_p * 2 / lcu_size + 1 :
(search_window_size_vertical_p * 2 / lcu_size + 2) / 2;
- vmem_size_p = (search_window_factor_p * width + 128 * 2) *
- lcu_size / 2 / 1024; /* XXX: CF hack */
bw_increase_p = fp_mult(one_frame_bw_dpb,
FP_INT(search_window_factor_bw_p - 1) / 3);
- available_vmem_p = min_t(int, 3, (vmem_size - fp_int(line_buffer_size) -
- fp_int(original_vmem_requirement)) / vmem_size_p);
search_window_size_vertical_b = 48;
search_window_factor_b = search_window_size_vertical_b * 2 / lcu_size;
search_window_factor_bw_b = !two_stage_encoding ?
search_window_size_vertical_b * 2 / lcu_size + 1 :
(search_window_size_vertical_b * 2 / lcu_size + 2) / 2;
- vmem_size_b = (search_window_factor_b * width + 128 * 2) * lcu_size /
- 2 / 1024;
bw_increase_b = fp_mult(one_frame_bw_dpb,
FP_INT((search_window_factor_bw_b - 1) / 3));
- available_vmem_b = min_t(int, 6, (vmem_size - fp_int(line_buffer_size) -
- fp_int(original_vmem_requirement)) / vmem_size_b);
/* Output parameters for DDR */
ddr.vsp_read = fp_mult(fp_div(FP_INT(bitrate), FP_INT(8)),
@@ -759,8 +708,6 @@
collocated_mv_per_lcu * fps), FP_INT(1000 * 1000));
ddr.collocated_write = ddr.collocated_read;
- ddr.line_buffer_read = (FP_INT(vmem_size) >= line_buffer_size +
- original_vmem_requirement) ? FP_ZERO : line_buffer_bw;
ddr.line_buffer_write = ddr.line_buffer_read;
ddr.original_read = fp_div(one_frame_bw_original,
@@ -768,27 +715,6 @@
ddr.original_write = FP_ZERO;
ddr.dpb_read = FP_ZERO;
- if (gop == GOP_IPPP) {
- ddr.dpb_read = one_frame_bw_dpb + fp_mult(bw_increase_p,
- FP_INT(3 - available_vmem_p));
- } else if (scenario == SCENARIO_WORST ||
- scenario == SCENARIO_SUSTAINED_WORST) {
- ddr.dpb_read = fp_mult(one_frame_bw_dpb, FP_INT(2));
- ddr.dpb_read += fp_mult(FP_INT(6 - available_vmem_b),
- bw_increase_b);
- } else {
- fp_t part_p, part_b;
-
- part_p = one_frame_bw_dpb + fp_mult(bw_increase_p,
- FP_INT(3 - available_vmem_p));
- part_p = fp_div(part_p, FP_INT(3));
-
- part_b = fp_mult(one_frame_bw_dpb, 2) +
- fp_mult(FP_INT(6 - available_vmem_b), bw_increase_b);
- part_b = fp_mult(part_b, FP(0, 2, 3));
-
- ddr.dpb_read = part_p + part_b;
- }
ddr.dpb_read = fp_div(ddr.dpb_read, dpb_compression_factor);
ddr.dpb_write = fp_div(one_frame_bw_dpb, dpb_compression_factor);
@@ -802,103 +728,15 @@
qsmmu_bw_overhead_factor = FP(1, 3, 100);
ddr.total = fp_mult(ddr.total, qsmmu_bw_overhead_factor);
- /* ................. for VMEM */
- vmem.vsp_read = FP_ZERO;
- vmem.vsp_write = FP_ZERO;
-
- vmem.collocated_read = FP_ZERO;
- vmem.collocated_write = FP_ZERO;
-
- vmem.line_buffer_read = line_buffer_bw - ddr.line_buffer_read;
- vmem.line_buffer_write = vmem.line_buffer_read;
-
- vmem.original_read = FP_INT(vmem_size) >= original_vmem_requirement ?
- ddr.original_read : FP_ZERO;
- vmem.original_write = vmem.original_read;
-
- vmem.dpb_read = FP_ZERO;
- if (gop == GOP_IPPP) {
- fp_t temp = fp_mult(one_frame_bw_dpb,
- FP_INT(search_window_factor_bw_p * available_vmem_p));
- temp = fp_div(temp, FP_INT(3));
-
- vmem.dpb_read = temp;
- } else if (scenario != SCENARIO_AVERAGE) {
- fp_t temp = fp_mult(one_frame_bw_dpb, FP_INT(2));
-
- temp = fp_mult(temp, FP_INT(search_window_factor_bw_b *
- available_vmem_b));
- temp = fp_div(temp, FP_INT(6));
-
- vmem.dpb_read = temp;
- } else {
- fp_t part_p, part_b;
-
- part_p = fp_mult(one_frame_bw_dpb, FP_INT(
- search_window_factor_bw_p *
- available_vmem_p));
- part_p = fp_div(part_p, FP_INT(3 * 3));
-
- part_b = fp_mult(one_frame_bw_dpb, FP_INT(2 *
- search_window_factor_bw_b *
- available_vmem_b));
- part_b = fp_div(part_b, FP_INT(6));
- part_b = fp_mult(part_b, FP(0, 2, 3));
-
- vmem.dpb_read = part_p + part_b;
- }
-
- vmem.dpb_write = FP_ZERO;
- if (gop == GOP_IPPP) {
- fp_t temp = fp_mult(one_frame_bw_dpb,
- FP_INT(available_vmem_p));
- temp = fp_div(temp, FP_INT(3));
-
- vmem.dpb_write = temp;
- } else if (scenario != SCENARIO_AVERAGE) {
- fp_t temp = fp_mult(one_frame_bw_dpb,
- FP_INT(2 * available_vmem_b));
- temp = fp_div(temp, FP_INT(6));
-
- vmem.dpb_write = temp;
- } else {
- fp_t part_b, part_p;
-
- part_b = fp_mult(one_frame_bw_dpb, FP_INT(available_vmem_p));
- part_b = fp_div(part_b, FP_INT(9));
-
- part_p = fp_mult(one_frame_bw_dpb, FP_INT(
- 2 * available_vmem_b));
- part_p = fp_div(part_p, FP_INT(6));
- part_b = fp_mult(part_b, FP(0, 2, 3));
-
- vmem.dpb_write = part_p + part_b;
- }
-
- vmem.total = vmem.vsp_read + vmem.vsp_write +
- vmem.collocated_read + vmem.collocated_write +
- vmem.line_buffer_read + vmem.line_buffer_write +
- vmem.original_read + vmem.original_write +
- vmem.dpb_read + vmem.dpb_write;
-
- /*
- * When in low power mode, attempt to force the VMEM clocks a certain
- * frequency that DCVS would prefer
- */
- if (width * height >= 3840 * 2160 && low_power)
- vmem.total = FP_INT(NOMINAL_BW_MBPS);
-
if (debug) {
struct dump dump[] = {
{"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC},
- {"scenario", "%d", scenario},
{"standard", "%#x", standard},
{"width", "%d", width},
{"height", "%d", height},
{"DPB format", "%#x", dpb_color_format},
{"original frame format", "%#x", original_color_format},
{"fps", "%d", fps},
- {"target bitrate", "%d", bitrate_scenario},
{"DPB compression enable", "%d", dpb_compression_enabled},
{"original compression enable", "%d",
original_compression_enabled},
@@ -910,7 +748,6 @@
original_compression_factor},
{"rotation", "%d", rotation},
{"cropping or scaling", "%d", cropping_or_scaling},
- {"VMEM size (KB)", "%d", vmem_size},
{"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC},
{"LCU size", "%d", lcu_size},
@@ -923,17 +760,13 @@
{"search window factor (B)", "%d", search_window_factor_b},
{"search window factor BW (B)", "%d",
search_window_factor_bw_b},
- {"VMEM size (B)", "%d", vmem_size_b},
{"bw increase (MB/s) (B)", DUMP_FP_FMT, bw_increase_b},
- {"available VMEM (B)", "%d", available_vmem_b},
{"search window size vertical (P)", "%d",
search_window_size_vertical_p},
{"search window factor (P)", "%d", search_window_factor_p},
{"search window factor BW (P)", "%d",
search_window_factor_bw_p},
- {"VMEM size (P)", "%d", vmem_size_p},
{"bw increase (MB/s) (P)", DUMP_FP_FMT, bw_increase_p},
- {"available VMEM (P)", "%d", available_vmem_p},
{"chroma/luma factor DPB", DUMP_FP_FMT,
chroma_luma_factor_dpb},
{"one frame BW DPB (MB/s)", DUMP_FP_FMT, one_frame_bw_dpb},
@@ -946,8 +779,6 @@
{"line buffer size (KB)", DUMP_FP_FMT, line_buffer_size},
{"line buffer BW (MB/s)", DUMP_FP_FMT, line_buffer_bw},
{"collocated MVs per LCU", "%d", collocated_mv_per_lcu},
- {"original VMEM requirement (KB)", DUMP_FP_FMT,
- original_vmem_requirement},
{"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC},
{"VSP read", DUMP_FP_FMT, ddr.vsp_read},
@@ -960,18 +791,6 @@
{"original read", DUMP_FP_FMT, ddr.original_write},
{"DPB read", DUMP_FP_FMT, ddr.dpb_read},
{"DPB write", DUMP_FP_FMT, ddr.dpb_write},
-
- {"INTERMEDIATE B/W VMEM", "", DUMP_HEADER_MAGIC},
- {"VSP read", DUMP_FP_FMT, vmem.vsp_read},
- {"VSP read", DUMP_FP_FMT, vmem.vsp_write},
- {"collocated read", DUMP_FP_FMT, vmem.collocated_read},
- {"collocated read", DUMP_FP_FMT, vmem.collocated_write},
- {"line buffer read", DUMP_FP_FMT, vmem.line_buffer_read},
- {"line buffer read", DUMP_FP_FMT, vmem.line_buffer_write},
- {"original read", DUMP_FP_FMT, vmem.original_read},
- {"original read", DUMP_FP_FMT, vmem.original_write},
- {"DPB read", DUMP_FP_FMT, vmem.dpb_read},
- {"DPB write", DUMP_FP_FMT, vmem.dpb_write},
};
__dump(dump, ARRAY_SIZE(dump));
}
@@ -981,7 +800,7 @@
ret = kbps(fp_round(ddr.total));
break;
case GOVERNOR_LLCC:
- ret = kbps(fp_round(vmem.total));
+ dprintk(VIDC_PROF, "LLCC Voting not supported yet\n");
break;
default:
dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__);
@@ -1023,18 +842,21 @@
dev->profile->get_dev_status(dev->dev.parent, &stats);
vidc_data = (struct msm_vidc_gov_data *)stats.private_data;
+ if (!vidc_data || !vidc_data->data_count)
+ goto exit;
+
for (c = 0; c < vidc_data->data_count; ++c) {
if (vidc_data->data->power_mode == VIDC_POWER_TURBO) {
- *freq = INT_MAX;
goto exit;
}
}
+ ab_kbps = 0;
for (c = 0; c < vidc_data->data_count; ++c)
ab_kbps += __calculate(&vidc_data->data[c], gov->mode);
- *freq = clamp(ab_kbps, dev->min_freq, dev->max_freq ?: UINT_MAX);
exit:
+ *freq = clamp(ab_kbps, dev->min_freq, dev->max_freq ?: UINT_MAX);
return 0;
}
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index f678f56..08cb055 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1320,6 +1320,13 @@
data_done.status = hfi_map_err_status(pkt->error_type);
data_done.size = sizeof(struct msm_vidc_cb_data_done);
data_done.clnt_data = pkt->input_tag;
+ data_done.input_done.recon_stats.buffer_index =
+ pkt->ubwc_cr_stats.frame_index;
+ memcpy(&data_done.input_done.recon_stats.ubwc_stats_info,
+ &pkt->ubwc_cr_stats.ubwc_stats_info,
+ sizeof(data_done.input_done.recon_stats.ubwc_stats_info));
+ data_done.input_done.recon_stats.complexity_number =
+ pkt->ubwc_cr_stats.complexity_number;
data_done.input_done.offset = pkt->offset;
data_done.input_done.filled_len = pkt->filled_len;
data_done.input_done.packet_buffer =
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 5c34f28..12a4e86 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -710,6 +710,7 @@
v4l2_device_unregister(&core->v4l2_dev);
msm_vidc_free_platform_resources(&core->resources);
+ kfree(core->vote_data);
sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group);
dev_set_drvdata(&pdev->dev, NULL);
mutex_destroy(&core->lock);
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 053d748..f31c11b 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -513,6 +513,7 @@
msm_comm_get_hal_output_buffer(inst),
f->fmt.pix_mp.pixelformat);
+ inst->clk_data.opb_fourcc = f->fmt.pix_mp.pixelformat;
if (msm_comm_get_stream_output_mode(inst) ==
HAL_VIDEO_DECODER_SECONDARY) {
frame_sz.buffer_type = HAL_BUFFER_OUTPUT2;
@@ -1056,6 +1057,7 @@
"%s Failed to get buffer requirements : %d\n",
__func__, rc);
}
+ inst->clk_data.dpb_fourcc = fourcc;
break;
default:
dprintk(VIDC_ERR,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 2e952a3..ede51b6 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1482,6 +1482,13 @@
goto fail_start;
}
+ rc = msm_comm_set_recon_buffers(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to set recon buffers: %d\n", rc);
+ goto fail_start;
+ }
+
if (msm_comm_get_stream_output_mode(inst) ==
HAL_VIDEO_DECODER_SECONDARY) {
rc = msm_comm_set_output_buffers(inst);
@@ -2085,6 +2092,7 @@
INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
INIT_MSM_VIDC_LIST(&inst->outputbufs);
INIT_MSM_VIDC_LIST(&inst->registeredbufs);
+ INIT_MSM_VIDC_LIST(&inst->reconbufs);
kref_init(&inst->kref);
@@ -2219,6 +2227,11 @@
"Failed to release scratch buffers\n");
}
+ if (msm_comm_release_recon_buffers(inst)) {
+ dprintk(VIDC_ERR,
+ "Failed to release recon buffers\n");
+ }
+
if (msm_comm_release_persist_buffers(inst)) {
dprintk(VIDC_ERR,
"Failed to release persist buffers\n");
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 05af186..6935a76 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -16,6 +16,94 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_clocks.h"
+static inline unsigned long int get_ubwc_compression_ratio(
+ struct ubwc_cr_stats_info_type ubwc_stats_info)
+{
+ unsigned long int sum = 0, weighted_sum = 0;
+ unsigned long int compression_ratio = 1 << 16;
+
+ weighted_sum =
+ 32 * ubwc_stats_info.cr_stats_info0 +
+ 64 * ubwc_stats_info.cr_stats_info1 +
+ 96 * ubwc_stats_info.cr_stats_info2 +
+ 128 * ubwc_stats_info.cr_stats_info3 +
+ 160 * ubwc_stats_info.cr_stats_info4 +
+ 192 * ubwc_stats_info.cr_stats_info5 +
+ 256 * ubwc_stats_info.cr_stats_info6;
+
+ sum =
+ ubwc_stats_info.cr_stats_info0 +
+ ubwc_stats_info.cr_stats_info1 +
+ ubwc_stats_info.cr_stats_info2 +
+ ubwc_stats_info.cr_stats_info3 +
+ ubwc_stats_info.cr_stats_info4 +
+ ubwc_stats_info.cr_stats_info5 +
+ ubwc_stats_info.cr_stats_info6;
+
+ compression_ratio = (weighted_sum && sum) ?
+ ((256 * sum) << 16) / weighted_sum : compression_ratio;
+
+ return compression_ratio;
+}
+
+static inline int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst)
+{
+ int height, width;
+
+ if (!inst->in_reconfig) {
+ height = max(inst->prop.height[CAPTURE_PORT],
+ inst->prop.height[OUTPUT_PORT]);
+ width = max(inst->prop.width[CAPTURE_PORT],
+ inst->prop.width[OUTPUT_PORT]);
+ } else {
+ height = inst->reconfig_height;
+ width = inst->reconfig_width;
+ }
+
+ return NUM_MBS_PER_FRAME(height, width);
+}
+
+void update_recon_stats(struct msm_vidc_inst *inst,
+ struct recon_stats_type *recon_stats)
+{
+ struct recon_buf *binfo;
+ u32 CR = 0, CF = 0;
+ u32 frame_size;
+
+ CR = get_ubwc_compression_ratio(recon_stats->ubwc_stats_info);
+
+ frame_size = (msm_vidc_get_mbs_per_frame(inst) / (32 * 8) * 3) / 2;
+
+ CF = recon_stats->complexity_number / frame_size;
+
+ mutex_lock(&inst->reconbufs.lock);
+ list_for_each_entry(binfo, &inst->reconbufs.list, list) {
+ if (binfo->buffer_index ==
+ recon_stats->buffer_index) {
+ binfo->CR = CR;
+ binfo->CF = CF;
+ }
+ }
+ mutex_unlock(&inst->reconbufs.lock);
+}
+
+static int fill_recon_stats(struct msm_vidc_inst *inst,
+ struct vidc_bus_vote_data *vote_data)
+{
+ struct recon_buf *binfo;
+ u32 CR = 0, CF = 0;
+
+ mutex_lock(&inst->reconbufs.lock);
+ list_for_each_entry(binfo, &inst->reconbufs.list, list) {
+ CR = max(CR, binfo->CR);
+ CF = max(CF, binfo->CF);
+ }
+ mutex_unlock(&inst->reconbufs.lock);
+ vote_data->complexity_factor = CF;
+ vote_data->compression_ratio = CR;
+ return 0;
+}
+
int msm_comm_vote_bus(struct msm_vidc_core *core)
{
int rc = 0, vote_data_count = 0, i = 0;
@@ -30,35 +118,36 @@
hdev = core->device;
- mutex_lock(&core->lock);
- list_for_each_entry(inst, &core->instances, list)
- ++vote_data_count;
-
- vote_data = kcalloc(vote_data_count, sizeof(*vote_data),
- GFP_TEMPORARY);
+ vote_data = core->vote_data;
if (!vote_data) {
- dprintk(VIDC_ERR, "%s: failed to allocate memory\n", __func__);
- rc = -ENOMEM;
- goto fail_alloc;
+ dprintk(VIDC_PROF,
+ "Failed to get vote_data for inst %pK\n",
+ inst);
+ return -EINVAL;
}
+ mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
- int codec = 0, yuv = 0;
+ int codec = 0;
+
+ ++vote_data_count;
codec = inst->session_type == MSM_VIDC_DECODER ?
inst->fmts[OUTPUT_PORT].fourcc :
inst->fmts[CAPTURE_PORT].fourcc;
- yuv = inst->session_type == MSM_VIDC_DECODER ?
- inst->fmts[CAPTURE_PORT].fourcc :
- inst->fmts[OUTPUT_PORT].fourcc;
-
vote_data[i].domain = get_hal_domain(inst->session_type);
vote_data[i].codec = get_hal_codec(codec);
- vote_data[i].width = max(inst->prop.width[CAPTURE_PORT],
+ vote_data[i].input_width = max(inst->prop.width[OUTPUT_PORT],
inst->prop.width[OUTPUT_PORT]);
- vote_data[i].height = max(inst->prop.height[CAPTURE_PORT],
+ vote_data[i].input_height = max(inst->prop.height[OUTPUT_PORT],
inst->prop.height[OUTPUT_PORT]);
+ vote_data[i].output_width = max(inst->prop.width[CAPTURE_PORT],
+ inst->prop.width[OUTPUT_PORT]);
+ vote_data[i].output_height =
+ max(inst->prop.height[CAPTURE_PORT],
+ inst->prop.height[OUTPUT_PORT]);
+ vote_data[i].lcu_size = codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
if (inst->clk_data.operating_rate)
vote_data[i].fps =
@@ -67,32 +156,35 @@
else
vote_data[i].fps = inst->prop.fps;
+ vote_data[i].power_mode = 0;
if (!msm_vidc_clock_scaling ||
inst->clk_data.buffer_counter < DCVS_FTB_WINDOW)
vote_data[i].power_mode = VIDC_POWER_TURBO;
- /*
- * TODO: support for OBP-DBP split mode hasn't been yet
- * implemented, once it is, this part of code needs to be
- * revisited since passing in accurate information to the bus
- * governor will drastically reduce bandwidth
- */
- //vote_data[i].color_formats[0] = get_hal_uncompressed(yuv);
- vote_data[i].num_formats = 1;
+ if (msm_comm_get_stream_output_mode(inst) ==
+ HAL_VIDEO_DECODER_PRIMARY) {
+ vote_data[i].color_formats[0] =
+ msm_comm_get_hal_uncompressed(
+ inst->clk_data.opb_fourcc);
+ vote_data[i].num_formats = 1;
+ } else {
+ vote_data[i].color_formats[0] =
+ msm_comm_get_hal_uncompressed(
+ inst->clk_data.dpb_fourcc);
+ vote_data[i].color_formats[1] =
+ msm_comm_get_hal_uncompressed(
+ inst->clk_data.opb_fourcc);
+ vote_data[i].num_formats = 2;
+ }
+ vote_data[i].work_mode = inst->clk_data.work_mode;
+ fill_recon_stats(inst, &vote_data[i]);
i++;
}
mutex_unlock(&core->lock);
+ if (vote_data_count)
+ rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data,
+ vote_data, vote_data_count);
- rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, vote_data,
- vote_data_count);
- if (rc)
- dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
-
- kfree(vote_data);
- return rc;
-
-fail_alloc:
- mutex_unlock(&core->lock);
return rc;
}
@@ -252,24 +344,6 @@
mutex_unlock(&inst->freqs.lock);
}
-
-static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
-{
- int height, width;
-
- if (!inst->in_reconfig) {
- height = max(inst->prop.height[CAPTURE_PORT],
- inst->prop.height[OUTPUT_PORT]);
- width = max(inst->prop.width[CAPTURE_PORT],
- inst->prop.width[OUTPUT_PORT]);
- } else {
- height = inst->reconfig_height;
- width = inst->reconfig_width;
- }
-
- return NUM_MBS_PER_FRAME(height, width);
-}
-
static unsigned long msm_vidc_calc_freq(struct msm_vidc_inst *inst,
u32 filled_len)
{
@@ -783,7 +857,7 @@
__func__);
return 0;
}
- mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
+ mbs_per_frame = msm_vidc_get_mbs_per_frame(inst);
if (mbs_per_frame >= inst->core->resources.max_hq_mbs_per_frame ||
inst->prop.fps >= inst->core->resources.max_hq_fps) {
enable = true;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.h b/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
index fe4822b..db57647 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
@@ -43,5 +43,6 @@
int msm_vidc_decide_core_and_power_mode(struct msm_vidc_inst *inst);
void msm_vidc_clear_freq_entry(struct msm_vidc_inst *inst,
ion_phys_addr_t device_addr);
-
+void update_recon_stats(struct msm_vidc_inst *inst,
+ struct recon_stats_type *recon_stats);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index fe61e6f..45992a7 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -817,7 +817,7 @@
return codec;
}
-static enum hal_uncompressed_format get_hal_uncompressed(int fourcc)
+enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc)
{
enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
@@ -976,6 +976,11 @@
__func__, core->codec_count, core->enc_codec_supported,
core->dec_codec_supported);
+ core->vote_data = kcalloc(MAX_SUPPORTED_INSTANCES,
+ sizeof(core->vote_data), GFP_KERNEL);
+ if (!core->vote_data)
+ dprintk(VIDC_ERR, "%s: failed to allocate memory\n", __func__);
+
complete(&(core->completions[index]));
}
@@ -2231,6 +2236,9 @@
V4L2_QCOM_BUF_FLAG_IDRFRAME |
V4L2_BUF_FLAG_KEYFRAME;
}
+
+ update_recon_stats(inst, &empty_buf_done->recon_stats);
+
dprintk(VIDC_DBG,
"Got ebd from hal: device_addr: %pa, alloc: %d, status: %#x, pic_type: %#x, flags: %#x\n",
&empty_buf_done->packet_buffer,
@@ -4504,6 +4512,27 @@
return rc;
}
+int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst)
+{
+ struct recon_buf *buf, *next;
+
+ if (!inst) {
+ dprintk(VIDC_ERR,
+ "Invalid instance pointer = %pK\n", inst);
+ return -EINVAL;
+ }
+
+ mutex_lock(&inst->reconbufs.lock);
+ list_for_each_entry_safe(buf, next, &inst->reconbufs.list, list) {
+ list_del(&buf->list);
+ kfree(buf);
+ }
+ INIT_LIST_HEAD(&inst->reconbufs.list);
+ mutex_unlock(&inst->reconbufs.lock);
+
+ return 0;
+}
+
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
{
struct msm_smem *handle;
@@ -4657,6 +4686,54 @@
return rc;
}
+int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst)
+{
+ int rc = 0, i = 0;
+ struct hal_buffer_requirements *internal_buf;
+ struct recon_buf *binfo;
+ struct msm_vidc_list *buf_list = &inst->reconbufs;
+
+ if (!inst) {
+ dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ if (inst->session_type == MSM_VIDC_ENCODER)
+ internal_buf = get_buff_req_buffer(inst,
+ HAL_BUFFER_INTERNAL_RECON);
+ else if (inst->session_type == MSM_VIDC_DECODER)
+ internal_buf = get_buff_req_buffer(inst,
+ msm_comm_get_hal_output_buffer(inst));
+ else
+ return -EINVAL;
+
+ if (!internal_buf || !internal_buf->buffer_count_actual) {
+ dprintk(VIDC_DBG, "Inst : %pK Recon buffers not required\n",
+ inst);
+ return 0;
+ }
+
+ if (!list_empty(&inst->reconbufs.list))
+ msm_comm_release_recon_buffers(inst);
+
+ for (i = 0; i < internal_buf->buffer_count_actual; i++) {
+ binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
+ if (!binfo) {
+ dprintk(VIDC_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto fail_kzalloc;
+ }
+
+ binfo->buffer_index = i;
+ mutex_lock(&buf_list->lock);
+ list_add_tail(&binfo->list, &buf_list->list);
+ mutex_unlock(&buf_list->lock);
+ }
+
+fail_kzalloc:
+ return rc;
+}
+
int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -5395,7 +5472,7 @@
hdev = inst->core->device;
- format = get_hal_uncompressed(fourcc);
+ format = msm_comm_get_hal_uncompressed(fourcc);
if (format == HAL_UNUSED_COLOR) {
dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
fourcc);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 7534593..52925eb 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -41,6 +41,7 @@
enum hal_property ptype, void *pdata);
int msm_comm_try_get_prop(struct msm_vidc_inst *inst,
enum hal_property ptype, union hal_get_property *hprop);
+int msm_comm_set_recon_buffers(struct msm_vidc_inst *inst);
int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst);
int msm_comm_set_output_buffers(struct msm_vidc_inst *inst);
@@ -51,6 +52,7 @@
int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
bool check_for_reuse);
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
+int msm_comm_release_recon_buffers(struct msm_vidc_inst *inst);
int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
bool force_release);
void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst);
@@ -98,6 +100,7 @@
int msm_comm_v4l2_to_hal(int id, int value);
int msm_comm_hal_to_v4l2(int id, int value);
int msm_comm_session_continue(void *instance);
+enum hal_uncompressed_format msm_comm_get_hal_uncompressed(int fourcc);
u32 get_frame_size_nv12(int plane, u32 height, u32 width);
u32 get_frame_size_nv12_ubwc(int plane, u32 height, u32 width);
u32 get_frame_size_rgba(int plane, u32 height, u32 width);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 5edd3d5..769a94d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -145,6 +145,13 @@
unsigned long freq;
};
+struct recon_buf {
+ struct list_head list;
+ u32 buffer_index;
+ u32 CR;
+ u32 CF;
+};
+
struct internal_buf {
struct list_head list;
enum hal_buffer buffer_type;
@@ -230,6 +237,8 @@
u32 operating_rate;
struct clock_profile_entry *entry;
u32 core_id;
+ u32 dpb_fourcc;
+ u32 opb_fourcc;
enum hal_work_mode work_mode;
bool low_latency_mode;
};
@@ -278,6 +287,7 @@
bool smmu_fault_handled;
unsigned long min_freq;
unsigned long curr_freq;
+ struct vidc_bus_vote_data *vote_data;
};
struct msm_vidc_inst {
@@ -296,6 +306,7 @@
struct msm_vidc_list persistbufs;
struct msm_vidc_list pending_getpropq;
struct msm_vidc_list outputbufs;
+ struct msm_vidc_list reconbufs;
struct msm_vidc_list registeredbufs;
struct buffer_requirements buff_req;
void *mem_client;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 86e4f42..695c563 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1082,6 +1082,22 @@
HAL_RESPONSE_UNUSED = 0x10000000,
};
+struct ubwc_cr_stats_info_type {
+ u32 cr_stats_info0;
+ u32 cr_stats_info1;
+ u32 cr_stats_info2;
+ u32 cr_stats_info3;
+ u32 cr_stats_info4;
+ u32 cr_stats_info5;
+ u32 cr_stats_info6;
+};
+
+struct recon_stats_type {
+ u32 buffer_index;
+ u32 complexity_number;
+ struct ubwc_cr_stats_info_type ubwc_stats_info;
+};
+
struct vidc_hal_ebd {
u32 timestamp_hi;
u32 timestamp_lo;
@@ -1094,6 +1110,7 @@
u32 alloc_len;
u32 filled_len;
enum hal_picture picture_type;
+ struct recon_stats_type recon_stats;
ion_phys_addr_t packet_buffer;
ion_phys_addr_t extra_data_buffer;
};
@@ -1315,8 +1332,16 @@
enum hal_video_codec codec;
enum hal_uncompressed_format color_formats[2];
int num_formats; /* 1 = DPB-OPB unified; 2 = split */
- int height, width, fps;
+ int input_height, input_width, fps;
+ int output_height, output_width;
+ int compression_ratio;
+ int complexity_factor;
+ unsigned int lcu_size;
enum msm_vidc_power_mode power_mode;
+ struct imem_ab_table *imem_ab_tbl;
+ enum hal_work_mode work_mode;
+ unsigned long bitrate;
+ u32 imem_ab_tbl_size;
};
struct vidc_clk_scale_data {