msm: mdss: add bw requirement calculations for ppp on mdp3
Currently ppp engine adds huge fudge factors for bandwidth calculations. Remove the fudge and add right bw requirement calculations for the same. Change-Id: I798d2bf6ac4c4cff13c82efdd53e5c73fa84b1ff Signed-off-by: Shivaraj Shetty <shivaraj@codeaurora.org>
This commit is contained in:
parent
1dd551da28
commit
1e40a94776
2 changed files with 154 additions and 61 deletions
|
@ -41,6 +41,8 @@
|
|||
#define ENABLE_SOLID_FILL 0x2
|
||||
#define DISABLE_SOLID_FILL 0x0
|
||||
|
||||
struct ppp_resource ppp_res;
|
||||
|
||||
static const bool valid_fmt[MDP_IMGTYPE_LIMIT] = {
|
||||
[MDP_RGB_565] = true,
|
||||
[MDP_BGR_565] = true,
|
||||
|
@ -100,8 +102,8 @@ struct ppp_status {
|
|||
|
||||
struct timer_list free_bw_timer;
|
||||
struct work_struct free_bw_work;
|
||||
bool bw_update;
|
||||
bool bw_on;
|
||||
bool bw_optimal;
|
||||
u32 mdp_clk;
|
||||
};
|
||||
|
||||
|
@ -353,52 +355,149 @@ u32 mdp3_clk_calc(struct msm_fb_data_type *mfd, struct blit_req_list *lreq)
|
|||
return mdp_clk_rate;
|
||||
}
|
||||
|
||||
int mdp3_ppp_vote_update(struct msm_fb_data_type *mfd)
|
||||
struct bpp_info {
|
||||
int bpp_num;
|
||||
int bpp_den;
|
||||
int bpp_pln;
|
||||
};
|
||||
|
||||
int mdp3_get_bpp_info(int format, struct bpp_info *bpp)
|
||||
{
|
||||
struct mdss_panel_info *panel_info = mfd->panel_info;
|
||||
uint64_t req_bw = 0, ab = 0, ib = 0;
|
||||
int rc = 0;
|
||||
if (!ppp_stat->bw_on)
|
||||
pr_err("%s: PPP vote update in wrong state\n", __func__);
|
||||
|
||||
req_bw = panel_info->xres * panel_info->yres *
|
||||
panel_info->mipi.frame_rate *
|
||||
MDP_PPP_MAX_BPP *
|
||||
MDP_PPP_DYNAMIC_FACTOR *
|
||||
MDP_PPP_MAX_READ_WRITE;
|
||||
ib = (req_bw * 3) / 2;
|
||||
|
||||
if (ppp_stat->bw_optimal)
|
||||
ab = ib / 2;
|
||||
else
|
||||
ab = req_bw;
|
||||
rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_PPP, ab, ib);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: scale_set_quota failed\n", __func__);
|
||||
return rc;
|
||||
switch (format) {
|
||||
case MDP_RGB_565:
|
||||
case MDP_BGR_565:
|
||||
bpp->bpp_num = 2;
|
||||
bpp->bpp_den = 1;
|
||||
bpp->bpp_pln = 2;
|
||||
break;
|
||||
case MDP_RGB_888:
|
||||
case MDP_BGR_888:
|
||||
bpp->bpp_num = 3;
|
||||
bpp->bpp_den = 1;
|
||||
bpp->bpp_pln = 3;
|
||||
break;
|
||||
case MDP_BGRA_8888:
|
||||
case MDP_RGBA_8888:
|
||||
case MDP_ARGB_8888:
|
||||
case MDP_XRGB_8888:
|
||||
case MDP_RGBX_8888:
|
||||
case MDP_BGRX_8888:
|
||||
bpp->bpp_num = 4;
|
||||
bpp->bpp_den = 1;
|
||||
bpp->bpp_pln = 4;
|
||||
break;
|
||||
case MDP_Y_CRCB_H2V2:
|
||||
case MDP_Y_CBCR_H2V2:
|
||||
case MDP_Y_CBCR_H2V2_ADRENO:
|
||||
case MDP_Y_CBCR_H2V2_VENUS:
|
||||
bpp->bpp_num = 3;
|
||||
bpp->bpp_den = 2;
|
||||
bpp->bpp_pln = 1;
|
||||
break;
|
||||
case MDP_Y_CBCR_H2V1:
|
||||
case MDP_Y_CRCB_H2V1:
|
||||
bpp->bpp_num = 2;
|
||||
bpp->bpp_den = 1;
|
||||
bpp->bpp_pln = 1;
|
||||
break;
|
||||
case MDP_YCRYCB_H2V1:
|
||||
bpp->bpp_num = 2;
|
||||
bpp->bpp_den = 1;
|
||||
bpp->bpp_pln = 2;
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mdp3_ppp_turnon(struct msm_fb_data_type *mfd, int on_off)
|
||||
u64 mdp3_adjust_scale_factor(struct mdp_blit_req *req, u32 bw_req, int bpp)
|
||||
{
|
||||
int src_h, src_w;
|
||||
int dst_h, dst_w;
|
||||
|
||||
src_h = req->src_rect.h;
|
||||
src_w = req->src_rect.w;
|
||||
|
||||
dst_h = req->dst_rect.h;
|
||||
dst_w = req->dst_rect.w;
|
||||
|
||||
if ((!(req->flags & MDP_ROT_90) && src_h == dst_h && src_w == dst_w) ||
|
||||
((req->flags & MDP_ROT_90) && src_h == dst_w && src_w == dst_h))
|
||||
return bw_req;
|
||||
|
||||
bw_req = (bw_req + (bw_req * dst_h) / (4 * src_h));
|
||||
bw_req = (bw_req + (bw_req * dst_w) / (4 * src_w) +
|
||||
(bw_req * dst_w) / (bpp * src_w));
|
||||
|
||||
return bw_req;
|
||||
}
|
||||
|
||||
int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq)
|
||||
{
|
||||
struct mdss_panel_info *panel_info = mfd->panel_info;
|
||||
uint64_t req_bw = 0, ab = 0, ib = 0;
|
||||
int i, lcount = 0;
|
||||
struct mdp_blit_req *req;
|
||||
struct bpp_info bpp;
|
||||
u32 src_read_bw = 0;
|
||||
u32 dst_read_bw = 0;
|
||||
u32 dst_write_bw = 0;
|
||||
u64 honest_ppp_ab = 0;
|
||||
u32 fps;
|
||||
|
||||
lcount = lreq->count;
|
||||
if (lcount == 0) {
|
||||
pr_err("Blit with request count 0, continue to recover!!!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set FPS to mipi rate as currently there is no way to get this */
|
||||
fps = panel_info->mipi.frame_rate;
|
||||
|
||||
for (i = 0; i < lcount; i++) {
|
||||
req = &(lreq->req_list[i]);
|
||||
|
||||
mdp3_get_bpp_info(req->src.format, &bpp);
|
||||
src_read_bw = req->src_rect.w * req->src_rect.h *
|
||||
bpp.bpp_num / bpp.bpp_den;
|
||||
src_read_bw = mdp3_adjust_scale_factor(req,
|
||||
src_read_bw, bpp.bpp_pln);
|
||||
|
||||
mdp3_get_bpp_info(req->dst.format, &bpp);
|
||||
dst_read_bw = req->dst_rect.w * req->dst_rect.h *
|
||||
bpp.bpp_num / bpp.bpp_den;
|
||||
dst_read_bw = mdp3_adjust_scale_factor(req,
|
||||
dst_read_bw, bpp.bpp_pln);
|
||||
|
||||
dst_write_bw = req->dst_rect.w * req->dst_rect.h *
|
||||
bpp.bpp_num / bpp.bpp_den;
|
||||
honest_ppp_ab += (src_read_bw + dst_read_bw + dst_write_bw);
|
||||
}
|
||||
honest_ppp_ab = honest_ppp_ab * fps;
|
||||
|
||||
if (honest_ppp_ab != ppp_res.next_ab) {
|
||||
pr_debug("bandwidth vote update for ppp: ab = %llx\n",
|
||||
honest_ppp_ab);
|
||||
ppp_res.next_ab = honest_ppp_ab;
|
||||
ppp_res.next_ib = honest_ppp_ab;
|
||||
ppp_stat->bw_update = true;
|
||||
}
|
||||
ppp_res.clk_rate = mdp3_clk_calc(mfd, lreq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp3_ppp_turnon(struct msm_fb_data_type *mfd, int on_off)
|
||||
{
|
||||
uint64_t ab = 0, ib = 0;
|
||||
int rate = 0;
|
||||
int rc;
|
||||
|
||||
if (on_off) {
|
||||
rate = MDP_CORE_CLK_RATE_SVS;
|
||||
req_bw = panel_info->xres * panel_info->yres *
|
||||
panel_info->mipi.frame_rate *
|
||||
MDP_PPP_MAX_BPP *
|
||||
MDP_PPP_DYNAMIC_FACTOR *
|
||||
MDP_PPP_MAX_READ_WRITE;
|
||||
ib = (req_bw * 3) / 2;
|
||||
if (ppp_stat->bw_optimal)
|
||||
ab = ib / 2;
|
||||
else
|
||||
ab = req_bw;
|
||||
rate = ppp_res.clk_rate;
|
||||
ab = ppp_res.next_ab;
|
||||
ib = ppp_res.next_ib;
|
||||
}
|
||||
mdp3_clk_set_rate(MDP3_CLK_MDP_SRC, rate, MDP3_CLIENT_PPP);
|
||||
rc = mdp3_res_update(on_off, 0, MDP3_CLIENT_PPP);
|
||||
|
@ -414,25 +513,10 @@ int mdp3_ppp_turnon(struct msm_fb_data_type *mfd, int on_off)
|
|||
}
|
||||
ppp_stat->bw_on = on_off;
|
||||
ppp_stat->mdp_clk = MDP_CORE_CLK_RATE_SVS;
|
||||
ppp_stat->bw_update = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mdp3_optimal_bw(struct blit_req_list *req)
|
||||
{
|
||||
int i, solid_fill = 0;
|
||||
|
||||
if (!req || (ppp_stat->req_q.count > 1))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < req->count; i++) {
|
||||
if (req->req_list[i].flags & MDP_SOLID_FILL)
|
||||
solid_fill++;
|
||||
}
|
||||
if ((req->count - solid_fill) <= 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void mdp3_start_ppp(struct ppp_blit_op *blit_op)
|
||||
{
|
||||
/* Wait for the pipe to clear */
|
||||
|
@ -1059,7 +1143,6 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
|
|||
struct msm_fb_data_type *mfd = ppp_stat->mfd;
|
||||
struct blit_req_list *req;
|
||||
int i, rc = 0;
|
||||
u32 new_clk_rate;
|
||||
|
||||
mutex_lock(&ppp_stat->config_ppp_mutex);
|
||||
req = mdp3_ppp_next_req(&ppp_stat->req_q);
|
||||
|
@ -1069,7 +1152,6 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
|
|||
}
|
||||
|
||||
if (!ppp_stat->bw_on) {
|
||||
ppp_stat->bw_optimal = mdp3_optimal_bw(req);
|
||||
mdp3_ppp_turnon(mfd, 1);
|
||||
if (rc < 0) {
|
||||
mutex_unlock(&ppp_stat->config_ppp_mutex);
|
||||
|
@ -1079,11 +1161,20 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
|
|||
}
|
||||
while (req) {
|
||||
mdp3_ppp_wait_for_fence(req);
|
||||
new_clk_rate = mdp3_clk_calc(mfd, req);
|
||||
if (new_clk_rate != ppp_stat->mdp_clk) {
|
||||
ppp_stat->mdp_clk = new_clk_rate;
|
||||
mdp3_clk_set_rate(MDP3_CLK_MDP_SRC, new_clk_rate,
|
||||
MDP3_CLIENT_PPP);
|
||||
mdp3_calc_ppp_res(mfd, req);
|
||||
if (ppp_res.clk_rate != ppp_stat->mdp_clk) {
|
||||
ppp_stat->mdp_clk = ppp_res.clk_rate;
|
||||
mdp3_clk_set_rate(MDP3_CLK_MDP_SRC,
|
||||
ppp_stat->mdp_clk, MDP3_CLIENT_PPP);
|
||||
}
|
||||
if (ppp_stat->bw_update) {
|
||||
rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_PPP,
|
||||
ppp_res.next_ab, ppp_res.next_ib);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: bw set quota failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
ppp_stat->bw_update = false;
|
||||
}
|
||||
for (i = 0; i < req->count; i++) {
|
||||
if (!(req->req_list[i].flags & MDP_NO_BLIT)) {
|
||||
|
@ -1106,10 +1197,6 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
|
|||
if (ppp_stat->wait_for_pop)
|
||||
complete(&ppp_stat->pop_q_comp);
|
||||
mutex_unlock(&ppp_stat->req_mutex);
|
||||
if (req && (ppp_stat->bw_optimal != mdp3_optimal_bw(req))) {
|
||||
ppp_stat->bw_optimal = !ppp_stat->bw_optimal;
|
||||
mdp3_ppp_vote_update(mfd);
|
||||
}
|
||||
}
|
||||
mod_timer(&ppp_stat->free_bw_timer, jiffies +
|
||||
msecs_to_jiffies(MDP_RELEASE_BW_TIMEOUT));
|
||||
|
|
|
@ -294,6 +294,12 @@ struct ppp_table {
|
|||
uint32_t val;
|
||||
};
|
||||
|
||||
struct ppp_resource {
|
||||
u64 next_ab;
|
||||
u64 next_ib;
|
||||
u64 clk_rate;
|
||||
};
|
||||
|
||||
struct ppp_csc_table {
|
||||
int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */
|
||||
uint16_t fwd_matrix[MDP_CCS_SIZE]; /* 3x3 color coefficients */
|
||||
|
|
Loading…
Add table
Reference in a new issue