disp: msm: sde: track available hw resources
Track available hw resources using a common data structure in the sde_rm object and pass available hw resource info to interface drivers to make informed decisions in preparing or filtering display modes. Change-Id: I05649623233b0f531582e8c90d1ef92c7fceded4 Signed-off-by: Nilaan Gunabalachandran <ngunabal@codeaurora.org>
This commit is contained in:
@@ -370,6 +370,7 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn,
|
||||
{
|
||||
struct msm_drm_private *priv;
|
||||
struct sde_kms *sde_kms;
|
||||
struct drm_encoder *drm_enc = NULL;
|
||||
|
||||
if (!conn || !conn->dev || !conn->dev->dev_private)
|
||||
return;
|
||||
@@ -380,6 +381,13 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn,
|
||||
if (!sde_kms)
|
||||
return;
|
||||
|
||||
if (conn->state && conn->state->best_encoder)
|
||||
drm_enc = conn->state->best_encoder;
|
||||
else
|
||||
drm_enc = conn->encoder;
|
||||
|
||||
sde_rm_get_resource_info(&sde_kms->rm, drm_enc, avail_res);
|
||||
|
||||
avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width;
|
||||
}
|
||||
|
||||
|
101
msm/sde/sde_rm.c
101
msm/sde/sde_rm.c
@@ -128,6 +128,101 @@ enum sde_rm_dbg_rsvp_stage {
|
||||
SDE_RM_STAGE_FINAL
|
||||
};
|
||||
|
||||
static void _sde_rm_inc_resource_info_lm(struct sde_rm *rm,
|
||||
struct msm_resource_caps_info *avail_res,
|
||||
struct sde_rm_hw_blk *blk)
|
||||
{
|
||||
struct sde_rm_hw_blk *blk2;
|
||||
const struct sde_lm_cfg *lm_cfg, *lm_cfg2;
|
||||
|
||||
avail_res->num_lm++;
|
||||
|
||||
lm_cfg = to_sde_hw_mixer(blk->hw)->cap;
|
||||
/* Check for 3d muxes by comparing paired lms */
|
||||
list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) {
|
||||
lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap;
|
||||
/*
|
||||
* If lm2 is free, or
|
||||
* lm1 & lm2 reserved by same enc, check mask
|
||||
*/
|
||||
if ((!blk2->rsvp || (blk->rsvp &&
|
||||
blk2->rsvp->enc_id == blk->rsvp->enc_id
|
||||
&& lm_cfg->id > lm_cfg2->id)) &&
|
||||
test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask))
|
||||
avail_res->num_3dmux++;
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_rm_dec_resource_info_lm(struct sde_rm *rm,
|
||||
struct msm_resource_caps_info *avail_res,
|
||||
struct sde_rm_hw_blk *blk)
|
||||
{
|
||||
struct sde_rm_hw_blk *blk2;
|
||||
const struct sde_lm_cfg *lm_cfg, *lm_cfg2;
|
||||
|
||||
avail_res->num_lm--;
|
||||
|
||||
lm_cfg = to_sde_hw_mixer(blk->hw)->cap;
|
||||
/* Check for 3d muxes by comparing paired lms */
|
||||
list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) {
|
||||
lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap;
|
||||
/* If lm2 is free and lm1 is now being reserved */
|
||||
if (!blk2->rsvp &&
|
||||
test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask))
|
||||
avail_res->num_3dmux--;
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_rm_inc_resource_info(struct sde_rm *rm,
|
||||
struct msm_resource_caps_info *avail_res,
|
||||
struct sde_rm_hw_blk *blk)
|
||||
{
|
||||
enum sde_hw_blk_type type = blk->type;
|
||||
|
||||
if (type == SDE_HW_BLK_LM)
|
||||
_sde_rm_inc_resource_info_lm(rm, avail_res, blk);
|
||||
else if (type == SDE_HW_BLK_CTL)
|
||||
avail_res->num_ctl++;
|
||||
else if (type == SDE_HW_BLK_DSC)
|
||||
avail_res->num_dsc++;
|
||||
}
|
||||
|
||||
static void _sde_rm_dec_resource_info(struct sde_rm *rm,
|
||||
struct msm_resource_caps_info *avail_res,
|
||||
struct sde_rm_hw_blk *blk)
|
||||
{
|
||||
enum sde_hw_blk_type type = blk->type;
|
||||
|
||||
if (type == SDE_HW_BLK_LM)
|
||||
_sde_rm_dec_resource_info_lm(rm, avail_res, blk);
|
||||
else if (type == SDE_HW_BLK_CTL)
|
||||
avail_res->num_ctl--;
|
||||
else if (type == SDE_HW_BLK_DSC)
|
||||
avail_res->num_dsc--;
|
||||
}
|
||||
|
||||
void sde_rm_get_resource_info(struct sde_rm *rm,
|
||||
struct drm_encoder *drm_enc,
|
||||
struct msm_resource_caps_info *avail_res)
|
||||
{
|
||||
struct sde_rm_hw_blk *blk;
|
||||
enum sde_hw_blk_type type;
|
||||
struct sde_rm_rsvp rsvp;
|
||||
|
||||
memcpy(avail_res, &rm->avail_res,
|
||||
sizeof(rm->avail_res));
|
||||
|
||||
if (!drm_enc)
|
||||
return;
|
||||
|
||||
rsvp.enc_id = drm_enc->base.id;
|
||||
|
||||
for (type = 0; type < SDE_HW_BLK_MAX; type++)
|
||||
list_for_each_entry(blk, &rm->hw_blks[type], list)
|
||||
if (blk->rsvp && blk->rsvp->enc_id == rsvp.enc_id)
|
||||
_sde_rm_inc_resource_info(rm, avail_res, blk);
|
||||
}
|
||||
|
||||
static void _sde_rm_print_rsvps(
|
||||
struct sde_rm *rm,
|
||||
enum sde_rm_dbg_rsvp_stage stage)
|
||||
@@ -444,6 +539,8 @@ static int _sde_rm_hw_blk_create(
|
||||
blk->hw = hw;
|
||||
list_add_tail(&blk->list, &rm->hw_blks[type]);
|
||||
|
||||
_sde_rm_inc_resource_info(rm, &rm->avail_res, blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1744,6 +1841,8 @@ static void _sde_rm_release_rsvp(
|
||||
SDE_DEBUG("rel rsvp %d enc %d %d %d\n",
|
||||
rsvp->seq, rsvp->enc_id,
|
||||
blk->type, blk->id);
|
||||
_sde_rm_inc_resource_info(rm,
|
||||
&rm->avail_res, blk);
|
||||
}
|
||||
if (blk->rsvp_nxt == rsvp) {
|
||||
blk->rsvp_nxt = NULL;
|
||||
@@ -1832,6 +1931,8 @@ static int _sde_rm_commit_rsvp(
|
||||
if (blk->rsvp_nxt) {
|
||||
blk->rsvp = blk->rsvp_nxt;
|
||||
blk->rsvp_nxt = NULL;
|
||||
_sde_rm_dec_resource_info(rm,
|
||||
&rm->avail_res, blk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -101,6 +101,7 @@ struct sde_rm_topology_def {
|
||||
* @lm_max_width: cached layer mixer maximum width
|
||||
* @rsvp_next_seq: sequence number for next reservation for debugging purposes
|
||||
* @rm_lock: resource manager mutex
|
||||
* @avail_res: Pointer with curr available resources
|
||||
*/
|
||||
struct sde_rm {
|
||||
struct drm_device *dev;
|
||||
@@ -111,6 +112,7 @@ struct sde_rm {
|
||||
uint32_t rsvp_next_seq;
|
||||
struct mutex rm_lock;
|
||||
const struct sde_rm_topology_def *topology_tbl;
|
||||
struct msm_resource_caps_info avail_res;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -312,4 +314,14 @@ int sde_rm_ext_blk_create_reserve(struct sde_rm *rm,
|
||||
*/
|
||||
int sde_rm_ext_blk_destroy(struct sde_rm *rm,
|
||||
struct drm_encoder *enc);
|
||||
|
||||
/**
|
||||
* sde_rm_get_resource_info - returns avail hw resource info
|
||||
* @mr: sde rm object
|
||||
* @drm_enc: drm encoder object
|
||||
* @avail_res: out parameter, available resource object
|
||||
*/
|
||||
void sde_rm_get_resource_info(struct sde_rm *rm,
|
||||
struct drm_encoder *drm_enc,
|
||||
struct msm_resource_caps_info *avail_res);
|
||||
#endif /* __SDE_RM_H__ */
|
||||
|
Reference in New Issue
Block a user