disp: msm: sde: Avoid kcallocs in atomic commit path
To avoid kcalloc for the multirect plane states and plane states will now be stored sde crtc. These states are populated momentarily and accessed in a single context for a handful of functions then are not used. This will clean up parameters passed between functions in the commit path as well. Change-Id: I6a8116a43c140b3f1c0464734032b8db13c1cfb0 Signed-off-by: Samantha Tran <samtran@codeaurora.org>
This commit is contained in:
@@ -42,9 +42,6 @@
|
||||
#include "sde_trace.h"
|
||||
#include "msm_drv.h"
|
||||
|
||||
#define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4)
|
||||
#define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2)
|
||||
|
||||
struct sde_crtc_custom_events {
|
||||
u32 event;
|
||||
int (*func)(struct drm_crtc *crtc, bool en,
|
||||
@@ -1257,13 +1254,6 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
|
||||
sde_cp_crtc_res_change(crtc);
|
||||
}
|
||||
|
||||
struct plane_state {
|
||||
struct sde_plane_state *sde_pstate;
|
||||
const struct drm_plane_state *drm_pstate;
|
||||
int stage;
|
||||
u32 pipe_id;
|
||||
};
|
||||
|
||||
static int pstate_cmp(const void *a, const void *b)
|
||||
{
|
||||
struct plane_state *pa = (struct plane_state *)a;
|
||||
@@ -1297,24 +1287,29 @@ static int pstate_cmp(const void *a, const void *b)
|
||||
* we assume that all pipes are in source split so its valid to compare
|
||||
* without taking into account left/right mixer placement
|
||||
*/
|
||||
static int _sde_crtc_validate_src_split_order(struct drm_crtc *crtc,
|
||||
struct plane_state *pstates, int cnt)
|
||||
static int _sde_crtc_validate_src_split_order(struct drm_crtc *crtc)
|
||||
{
|
||||
struct plane_state *prv_pstate, *cur_pstate;
|
||||
enum sde_layout prev_layout, cur_layout;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_rect left_rect, right_rect;
|
||||
struct sde_kms *sde_kms;
|
||||
struct plane_state *pstates;
|
||||
int32_t left_pid, right_pid;
|
||||
int32_t stage;
|
||||
int i, rc = 0;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
|
||||
sde_kms = _sde_crtc_get_kms(crtc);
|
||||
if (!sde_kms || !sde_kms->catalog) {
|
||||
if (!sde_kms || !sde_kms->catalog || !sde_crtc) {
|
||||
SDE_ERROR("invalid parameters\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 1; i < cnt; i++) {
|
||||
pstates = sde_crtc->pstates;
|
||||
|
||||
for (i = 1; i < sde_crtc->num_pstates; i++) {
|
||||
prv_pstate = &pstates[i - 1];
|
||||
cur_pstate = &pstates[i];
|
||||
prev_layout = prv_pstate->sde_pstate->layout;
|
||||
@@ -1492,7 +1487,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
struct drm_plane_state *state;
|
||||
struct sde_crtc_state *cstate;
|
||||
struct sde_plane_state *pstate = NULL;
|
||||
struct plane_state *pstates = NULL;
|
||||
struct plane_state *pstates;
|
||||
struct sde_format *format;
|
||||
struct sde_hw_ctl *ctl;
|
||||
struct sde_hw_mixer *lm;
|
||||
@@ -1513,11 +1508,9 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
ctl = mixer->hw_ctl;
|
||||
lm = mixer->hw_lm;
|
||||
cstate = to_sde_crtc_state(crtc->state);
|
||||
pstates = kcalloc(SDE_PSTATES_MAX,
|
||||
sizeof(struct plane_state), GFP_KERNEL);
|
||||
if (!pstates)
|
||||
return;
|
||||
pstates = sde_crtc->pstates;
|
||||
|
||||
memset(sde_crtc->pstates, 0, sizeof(sde_crtc->pstates));
|
||||
memset(fetch_active, 0, sizeof(fetch_active));
|
||||
memset(zpos_cnt, 0, sizeof(zpos_cnt));
|
||||
|
||||
@@ -1550,7 +1543,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
format = to_sde_format(msm_framebuffer_format(pstate->base.fb));
|
||||
if (!format) {
|
||||
SDE_ERROR("invalid format\n");
|
||||
goto end;
|
||||
return;
|
||||
}
|
||||
|
||||
blend_type = sde_plane_get_property(pstate,
|
||||
@@ -1641,8 +1634,6 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
kfree(pstates);
|
||||
}
|
||||
|
||||
static void _sde_crtc_swap_mixers_for_right_partial_update(
|
||||
@@ -4523,12 +4514,19 @@ end:
|
||||
}
|
||||
|
||||
static int _sde_crtc_check_secure_blend_config(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state, struct plane_state pstates[],
|
||||
struct sde_crtc_state *cstate, struct sde_kms *sde_kms,
|
||||
int cnt, int secure, int fb_ns, int fb_sec, int fb_sec_dir)
|
||||
struct drm_crtc_state *state, struct sde_crtc_state *cstate,
|
||||
struct sde_kms *sde_kms, int secure, int fb_ns,
|
||||
int fb_sec, int fb_sec_dir)
|
||||
{
|
||||
struct drm_plane *plane;
|
||||
int i;
|
||||
int i, cnt;
|
||||
struct plane_state *pstates;
|
||||
struct sde_crtc *sde_crtc;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
cnt = sde_crtc->num_pstates;
|
||||
pstates = sde_crtc->pstates;
|
||||
|
||||
if (secure == SDE_DRM_SEC_ONLY) {
|
||||
/*
|
||||
* validate planes - only fb_sec_dir is allowed during sec_crtc
|
||||
@@ -4725,8 +4723,7 @@ static int _sde_crtc_check_secure_conn(struct drm_crtc *crtc,
|
||||
}
|
||||
|
||||
static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state, struct plane_state pstates[],
|
||||
int cnt)
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
struct sde_crtc_state *cstate;
|
||||
struct sde_kms *sde_kms;
|
||||
@@ -4754,8 +4751,8 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = _sde_crtc_check_secure_blend_config(crtc, state, pstates, cstate,
|
||||
sde_kms, cnt, secure, fb_ns, fb_sec, fb_sec_dir);
|
||||
rc = _sde_crtc_check_secure_blend_config(crtc, state, cstate,
|
||||
sde_kms, secure, fb_ns, fb_sec, fb_sec_dir);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -4784,10 +4781,7 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
|
||||
static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state,
|
||||
struct drm_display_mode *mode,
|
||||
struct plane_state *pstates,
|
||||
struct drm_plane *plane,
|
||||
struct sde_multirect_plane_states *multirect_plane,
|
||||
int *cnt)
|
||||
struct drm_plane *plane)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_crtc_state *cstate;
|
||||
@@ -4796,6 +4790,9 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
|
||||
int rc = 0, multirect_count = 0, i, mixer_width, mixer_height;
|
||||
int inc_sde_stage = 0;
|
||||
struct sde_kms *kms;
|
||||
int *cnt;
|
||||
struct plane_state *pstates;
|
||||
struct sde_multirect_plane_states *multirect_plane;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
cstate = to_sde_crtc_state(state);
|
||||
@@ -4806,6 +4803,13 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cnt = &sde_crtc->num_pstates;
|
||||
pstates = sde_crtc->pstates;
|
||||
multirect_plane = sde_crtc->multirect;
|
||||
|
||||
*cnt = 0;
|
||||
memset(sde_crtc->pstates, 0, sizeof(sde_crtc->pstates));
|
||||
memset(sde_crtc->multirect, 0, sizeof(sde_crtc->multirect));
|
||||
memset(pipe_staged, 0, sizeof(pipe_staged));
|
||||
|
||||
mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode);
|
||||
@@ -4911,16 +4915,16 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
|
||||
|
||||
static int _sde_crtc_check_zpos(struct drm_crtc_state *state,
|
||||
struct sde_crtc *sde_crtc,
|
||||
struct plane_state *pstates,
|
||||
struct sde_crtc_state *cstate,
|
||||
struct drm_display_mode *mode,
|
||||
int cnt)
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
int rc = 0, i, z_pos;
|
||||
u32 zpos_cnt = 0;
|
||||
struct drm_crtc *crtc;
|
||||
struct sde_kms *kms;
|
||||
enum sde_layout layout;
|
||||
int cnt;
|
||||
struct plane_state *pstates;
|
||||
|
||||
crtc = &sde_crtc->base;
|
||||
kms = _sde_crtc_get_kms(crtc);
|
||||
@@ -4930,6 +4934,9 @@ static int _sde_crtc_check_zpos(struct drm_crtc_state *state,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pstates = sde_crtc->pstates;
|
||||
cnt = sde_crtc->num_pstates;
|
||||
|
||||
sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);
|
||||
|
||||
rc = _sde_crtc_excl_dim_layer_check(state, pstates, cnt);
|
||||
@@ -4983,16 +4990,14 @@ static int _sde_crtc_check_zpos(struct drm_crtc_state *state,
|
||||
}
|
||||
|
||||
static int _sde_crtc_atomic_check_pstates(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state,
|
||||
struct plane_state *pstates,
|
||||
struct sde_multirect_plane_states *multirect_plane)
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_crtc_state *cstate;
|
||||
struct sde_kms *kms;
|
||||
struct drm_plane *plane = NULL;
|
||||
struct drm_display_mode *mode;
|
||||
int rc = 0, cnt = 0;
|
||||
int rc = 0;
|
||||
|
||||
kms = _sde_crtc_get_kms(crtc);
|
||||
|
||||
@@ -5004,19 +5009,19 @@ static int _sde_crtc_atomic_check_pstates(struct drm_crtc *crtc,
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
cstate = to_sde_crtc_state(state);
|
||||
mode = &state->adjusted_mode;
|
||||
sde_crtc->num_pstates = 0;
|
||||
|
||||
/* get plane state for all drm planes associated with crtc state */
|
||||
rc = _sde_crtc_check_get_pstates(crtc, state, mode, pstates,
|
||||
plane, multirect_plane, &cnt);
|
||||
rc = _sde_crtc_check_get_pstates(crtc, state, mode, plane);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* assign mixer stages based on sorted zpos property */
|
||||
rc = _sde_crtc_check_zpos(state, sde_crtc, pstates, cstate, mode, cnt);
|
||||
rc = _sde_crtc_check_zpos(state, sde_crtc, cstate, mode);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = _sde_crtc_check_secure_state(crtc, state, pstates, cnt);
|
||||
rc = _sde_crtc_check_secure_state(crtc, state);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -5026,7 +5031,7 @@ static int _sde_crtc_atomic_check_pstates(struct drm_crtc *crtc,
|
||||
* we assume that all pipes are in source split so its valid to compare
|
||||
* without taking into account left/right mixer placement
|
||||
*/
|
||||
rc = _sde_crtc_validate_src_split_order(crtc, pstates, cnt);
|
||||
rc = _sde_crtc_validate_src_split_order(crtc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -5094,11 +5099,9 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
{
|
||||
struct drm_device *dev;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct plane_state *pstates = NULL;
|
||||
struct sde_crtc_state *cstate;
|
||||
struct drm_display_mode *mode;
|
||||
int rc = 0;
|
||||
struct sde_multirect_plane_states *multirect_plane = NULL;
|
||||
struct drm_connector *conn;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
@@ -5117,18 +5120,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
goto end;
|
||||
}
|
||||
|
||||
pstates = kcalloc(SDE_PSTATES_MAX,
|
||||
sizeof(struct plane_state), GFP_KERNEL);
|
||||
|
||||
multirect_plane = kcalloc(SDE_MULTIRECT_PLANE_MAX,
|
||||
sizeof(struct sde_multirect_plane_states),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!pstates || !multirect_plane) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
mode = &state->adjusted_mode;
|
||||
SDE_DEBUG("%s: check", sde_crtc->name);
|
||||
|
||||
@@ -5164,8 +5155,7 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
_sde_crtc_setup_is_ppsplit(state);
|
||||
_sde_crtc_setup_lm_bounds(crtc, state);
|
||||
|
||||
rc = _sde_crtc_atomic_check_pstates(crtc, state, pstates,
|
||||
multirect_plane);
|
||||
rc = _sde_crtc_atomic_check_pstates(crtc, state);
|
||||
if (rc) {
|
||||
SDE_ERROR("crtc%d failed pstate check %d\n", crtc->base.id, rc);
|
||||
goto end;
|
||||
@@ -5191,8 +5181,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
kfree(pstates);
|
||||
kfree(multirect_plane);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user