Merge "msm: sde: Reduce SDE rotator done signaling time"

This commit is contained in:
Linux Build Service Account 2017-01-13 17:02:54 -08:00 committed by Gerrit - the friendly Code Review server
commit 15cc45eab4
3 changed files with 84 additions and 14 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -1390,6 +1390,14 @@ static void sde_rotator_commit_handler(struct work_struct *work)
entry->item.dst_rect.x, entry->item.dst_rect.y,
entry->item.dst_rect.w, entry->item.dst_rect.h);
ATRACE_INT("sde_smmu_ctrl", 0);
ret = sde_smmu_ctrl(1);
if (IS_ERR_VALUE(ret)) {
SDEROT_ERR("IOMMU attach failed\n");
goto smmu_error;
}
ATRACE_INT("sde_smmu_ctrl", 1);
ret = sde_rotator_map_and_check_data(entry);
if (ret) {
SDEROT_ERR("fail to prepare input/output data %d\n", ret);
@ -1415,6 +1423,8 @@ static void sde_rotator_commit_handler(struct work_struct *work)
sde_rot_mgr_unlock(mgr);
return;
error:
sde_smmu_ctrl(0);
smmu_error:
sde_rotator_put_hw_resource(entry->commitq, entry, hw);
get_hw_res_err:
sde_rotator_signal_output(entry);
@ -1491,6 +1501,7 @@ static void sde_rotator_done_handler(struct work_struct *work)
sde_rot_mgr_lock(mgr);
sde_rotator_put_hw_resource(entry->commitq, entry, entry->commitq->hw);
sde_rotator_signal_output(entry);
ATRACE_INT("sde_rot_done", 1);
sde_rotator_release_entry(mgr, entry);
atomic_dec(&request->pending_count);
if (request->retireq && request->retire_work)
@ -1498,6 +1509,10 @@ static void sde_rotator_done_handler(struct work_struct *work)
if (entry->item.ts)
entry->item.ts[SDE_ROTATOR_TS_RETIRE] = ktime_get();
sde_rot_mgr_unlock(mgr);
ATRACE_INT("sde_smmu_ctrl", 3);
sde_smmu_ctrl(0);
ATRACE_INT("sde_smmu_ctrl", 4);
}
static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -36,6 +36,12 @@
#include "sde_rotator_trace.h"
#include "sde_rotator_debug.h"
#define RES_UHD (3840*2160)
/* traffic shaping clock ticks = finish_time x 19.2MHz */
#define TRAFFIC_SHAPE_CLKTICK_14MS 268800
#define TRAFFIC_SHAPE_CLKTICK_12MS 230400
/* XIN mapping */
#define XIN_SSPP 0
#define XIN_WRITEBACK 1
@ -650,6 +656,20 @@ static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx,
ctx->is_secure = false;
}
/*
* Determine if traffic shaping is required. Only enable traffic
* shaping when content is 4k@30fps. The actual traffic shaping
* bandwidth calculation is done in output setup.
*/
if (((cfg->src_rect->w * cfg->src_rect->h) >= RES_UHD) &&
(cfg->fps <= 30)) {
SDEROT_DBG("Enable Traffic Shaper\n");
ctx->is_traffic_shaping = true;
} else {
SDEROT_DBG("Disable Traffic Shaper\n");
ctx->is_traffic_shaping = false;
}
/* Update command queue write ptr */
sde_hw_rotator_put_regdma_segment(ctx, wrptr);
}
@ -762,6 +782,36 @@ static void sde_hw_rotator_setup_wbengine(struct sde_hw_rotator_context *ctx,
else
SDE_REGDMA_WRITE(wrptr, ROTTOP_OP_MODE, 0x1);
/* setup traffic shaper for 4k 30fps content */
if (ctx->is_traffic_shaping) {
u32 bw;
/*
* Target to finish in 12ms, and we need to set number of bytes
* per clock tick for traffic shaping.
* Each clock tick run @ 19.2MHz, so we need we know total of
* clock ticks in 14ms, i.e. 12ms/(1/19.2MHz) ==> 23040
* Finally, calcualte the byte count per clock tick based on
* resolution, bpp and compression ratio.
*/
bw = cfg->dst_rect->w * cfg->dst_rect->h;
if (fmt->chroma_sample == SDE_MDP_CHROMA_420)
bw = (bw * 3) / 2;
else
bw *= fmt->bpp;
bw /= TRAFFIC_SHAPE_CLKTICK_12MS;
if (bw > 0xFF)
bw = 0xFF;
SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT,
BIT(31) | bw);
SDEROT_DBG("Enable ROT_WB Traffic Shaper:%d\n", bw);
} else {
SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT, 0);
SDEROT_DBG("Disable ROT_WB Traffic Shaper\n");
}
/* Update command queue write ptr */
sde_hw_rotator_put_regdma_segment(ctx, wrptr);
}
@ -1039,6 +1089,7 @@ static u32 sde_hw_rotator_wait_done_regdma(
!sde_hw_rotator_pending_swts(rot, ctx, &swts),
KOFF_TIMEOUT);
ATRACE_INT("sde_rot_done", 0);
spin_lock_irqsave(&rot->rotisr_lock, flags);
last_isr = ctx->last_regdma_isr_status;
@ -1580,6 +1631,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
sspp_cfg.img_width = item->input.width;
sspp_cfg.img_height = item->input.height;
sspp_cfg.fps = entry->perf->config.frame_rate;
sspp_cfg.bw = entry->perf->bw;
sspp_cfg.fmt = sde_get_format_params(item->input.format);
if (!sspp_cfg.fmt) {
SDEROT_ERR("null format\n");
@ -1599,6 +1652,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
wb_cfg.img_width = item->output.width;
wb_cfg.img_height = item->output.height;
wb_cfg.fps = entry->perf->config.frame_rate;
wb_cfg.bw = entry->perf->bw;
wb_cfg.fmt = sde_get_format_params(item->output.format);
wb_cfg.dst_rect = &item->dst_rect;
wb_cfg.data = &entry->dst_buf;
@ -1642,7 +1697,9 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
ot_params.bit_off_mdp_clk_ctrl =
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN0;
ot_params.fmt = entry->perf->config.input.format;
ot_params.fmt = ctx->is_traffic_shaping ?
SDE_PIX_FMT_ABGR_8888 :
entry->perf->config.input.format;
sde_mdp_set_ot_limit(&ot_params);
}
@ -1660,7 +1717,9 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
ot_params.bit_off_mdp_clk_ctrl =
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1;
ot_params.fmt = entry->perf->config.input.format;
ot_params.fmt = ctx->is_traffic_shaping ?
SDE_PIX_FMT_ABGR_8888 :
entry->perf->config.input.format;
sde_mdp_set_ot_limit(&ot_params);
}
@ -1711,7 +1770,6 @@ static int sde_hw_rotator_kickoff(struct sde_rot_hw_resource *hw,
struct sde_hw_rotator *rot;
struct sde_hw_rotator_resource_info *resinfo;
struct sde_hw_rotator_context *ctx;
int ret = 0;
if (!hw || !entry) {
SDEROT_ERR("null hw resource/entry\n");
@ -1729,12 +1787,6 @@ static int sde_hw_rotator_kickoff(struct sde_rot_hw_resource *hw,
return -EINVAL;
}
ret = sde_smmu_ctrl(1);
if (IS_ERR_VALUE(ret)) {
SDEROT_ERR("IOMMU attach failed\n");
return ret;
}
rot->ops.start_rotator(ctx, ctx->q_id);
return 0;
@ -1774,8 +1826,6 @@ static int sde_hw_rotator_wait4done(struct sde_rot_hw_resource *hw,
ret = rot->ops.wait_rotator_done(ctx, ctx->q_id, 0);
sde_smmu_ctrl(0);
if (rot->dbgmem) {
sde_hw_rotator_unmap_vaddr(&ctx->src_dbgbuf);
sde_hw_rotator_unmap_vaddr(&ctx->dst_dbgbuf);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -73,6 +73,8 @@ struct sde_hw_rot_sspp_cfg {
struct sde_mdp_data *data;
u32 img_width;
u32 img_height;
u32 fps;
u64 bw;
};
@ -93,6 +95,8 @@ struct sde_hw_rot_wb_cfg {
u32 img_height;
u32 v_downscale_factor;
u32 h_downscale_factor;
u32 fps;
u64 bw;
};
@ -214,6 +218,7 @@ struct sde_hw_rotator_context {
u32 last_regdma_timestamp;
dma_addr_t ts_addr;
bool is_secure;
bool is_traffic_shaping;
};
/**