drm/msm/dpu: move hw resource tracking to crtc state
Prep changes for state based resource management. Moves all the hw block tracking for the crtc to the state object. changes in v4: - Serialize crtc state access in debugfs handlers (Sean) - Split the crtc width query as a separate change (Sean) changes in v5: - mode set lock all before crtc state access (Sean) - remove unwanted memset for hw mixer cache (Sean) Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
4233166878
commit
9222cdd27e
@ -155,9 +155,9 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
|
|||||||
crtc_state = to_dpu_crtc_state(crtc->state);
|
crtc_state = to_dpu_crtc_state(crtc->state);
|
||||||
|
|
||||||
lm_horiz_position = 0;
|
lm_horiz_position = 0;
|
||||||
for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) {
|
for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
|
||||||
const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
|
const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
|
||||||
struct dpu_hw_mixer *hw_lm = dpu_crtc->mixers[lm_idx].hw_lm;
|
struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
|
||||||
struct dpu_hw_mixer_cfg cfg;
|
struct dpu_hw_mixer_cfg cfg;
|
||||||
|
|
||||||
if (!lm_roi || !drm_rect_visible(lm_roi))
|
if (!lm_roi || !drm_rect_visible(lm_roi))
|
||||||
@ -238,7 +238,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
|||||||
fb ? fb->modifier : 0);
|
fb ? fb->modifier : 0);
|
||||||
|
|
||||||
/* blend config update */
|
/* blend config update */
|
||||||
for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) {
|
for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
|
||||||
_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
|
_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
|
||||||
pstate, format);
|
pstate, format);
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
|||||||
static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
|
static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct dpu_crtc *dpu_crtc;
|
struct dpu_crtc *dpu_crtc;
|
||||||
struct dpu_crtc_state *dpu_crtc_state;
|
struct dpu_crtc_state *cstate;
|
||||||
struct dpu_crtc_mixer *mixer;
|
struct dpu_crtc_mixer *mixer;
|
||||||
struct dpu_hw_ctl *ctl;
|
struct dpu_hw_ctl *ctl;
|
||||||
struct dpu_hw_mixer *lm;
|
struct dpu_hw_mixer *lm;
|
||||||
@ -273,17 +273,12 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
dpu_crtc = to_dpu_crtc(crtc);
|
dpu_crtc = to_dpu_crtc(crtc);
|
||||||
dpu_crtc_state = to_dpu_crtc_state(crtc->state);
|
cstate = to_dpu_crtc_state(crtc->state);
|
||||||
mixer = dpu_crtc->mixers;
|
mixer = cstate->mixers;
|
||||||
|
|
||||||
DPU_DEBUG("%s\n", dpu_crtc->name);
|
DPU_DEBUG("%s\n", dpu_crtc->name);
|
||||||
|
|
||||||
if (dpu_crtc->num_mixers > CRTC_DUAL_MIXERS) {
|
for (i = 0; i < cstate->num_mixers; i++) {
|
||||||
DPU_ERROR("invalid number mixers: %d\n", dpu_crtc->num_mixers);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < dpu_crtc->num_mixers; i++) {
|
|
||||||
if (!mixer[i].hw_lm || !mixer[i].hw_ctl) {
|
if (!mixer[i].hw_lm || !mixer[i].hw_ctl) {
|
||||||
DPU_ERROR("invalid lm or ctl assigned to mixer\n");
|
DPU_ERROR("invalid lm or ctl assigned to mixer\n");
|
||||||
return;
|
return;
|
||||||
@ -300,7 +295,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer);
|
_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer);
|
||||||
|
|
||||||
for (i = 0; i < dpu_crtc->num_mixers; i++) {
|
for (i = 0; i < cstate->num_mixers; i++) {
|
||||||
ctl = mixer[i].hw_ctl;
|
ctl = mixer[i].hw_ctl;
|
||||||
lm = mixer[i].hw_lm;
|
lm = mixer[i].hw_lm;
|
||||||
|
|
||||||
@ -522,7 +517,7 @@ static void _dpu_crtc_setup_mixer_for_encoder(
|
|||||||
struct drm_crtc *crtc,
|
struct drm_crtc *crtc,
|
||||||
struct drm_encoder *enc)
|
struct drm_encoder *enc)
|
||||||
{
|
{
|
||||||
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
|
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
|
||||||
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
|
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
|
||||||
struct dpu_rm *rm = &dpu_kms->rm;
|
struct dpu_rm *rm = &dpu_kms->rm;
|
||||||
struct dpu_crtc_mixer *mixer;
|
struct dpu_crtc_mixer *mixer;
|
||||||
@ -534,8 +529,8 @@ static void _dpu_crtc_setup_mixer_for_encoder(
|
|||||||
dpu_rm_init_hw_iter(&ctl_iter, enc->base.id, DPU_HW_BLK_CTL);
|
dpu_rm_init_hw_iter(&ctl_iter, enc->base.id, DPU_HW_BLK_CTL);
|
||||||
|
|
||||||
/* Set up all the mixers and ctls reserved by this encoder */
|
/* Set up all the mixers and ctls reserved by this encoder */
|
||||||
for (i = dpu_crtc->num_mixers; i < ARRAY_SIZE(dpu_crtc->mixers); i++) {
|
for (i = cstate->num_mixers; i < ARRAY_SIZE(cstate->mixers); i++) {
|
||||||
mixer = &dpu_crtc->mixers[i];
|
mixer = &cstate->mixers[i];
|
||||||
|
|
||||||
if (!dpu_rm_get_hw(rm, &lm_iter))
|
if (!dpu_rm_get_hw(rm, &lm_iter))
|
||||||
break;
|
break;
|
||||||
@ -560,7 +555,7 @@ static void _dpu_crtc_setup_mixer_for_encoder(
|
|||||||
|
|
||||||
mixer->encoder = enc;
|
mixer->encoder = enc;
|
||||||
|
|
||||||
dpu_crtc->num_mixers++;
|
cstate->num_mixers++;
|
||||||
DPU_DEBUG("setup mixer %d: lm %d\n",
|
DPU_DEBUG("setup mixer %d: lm %d\n",
|
||||||
i, mixer->hw_lm->idx - LM_0);
|
i, mixer->hw_lm->idx - LM_0);
|
||||||
DPU_DEBUG("setup mixer %d: ctl %d\n",
|
DPU_DEBUG("setup mixer %d: ctl %d\n",
|
||||||
@ -573,10 +568,6 @@ static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
|
|||||||
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
|
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
|
||||||
struct drm_encoder *enc;
|
struct drm_encoder *enc;
|
||||||
|
|
||||||
dpu_crtc->num_mixers = 0;
|
|
||||||
dpu_crtc->mixers_swapped = false;
|
|
||||||
memset(dpu_crtc->mixers, 0, sizeof(dpu_crtc->mixers));
|
|
||||||
|
|
||||||
mutex_lock(&dpu_crtc->crtc_lock);
|
mutex_lock(&dpu_crtc->crtc_lock);
|
||||||
/* Check for mixers on all encoders attached to this crtc */
|
/* Check for mixers on all encoders attached to this crtc */
|
||||||
list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) {
|
list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) {
|
||||||
@ -609,7 +600,7 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
|
|||||||
adj_mode = &state->adjusted_mode;
|
adj_mode = &state->adjusted_mode;
|
||||||
crtc_split_width = _dpu_crtc_get_mixer_width(cstate, adj_mode);
|
crtc_split_width = _dpu_crtc_get_mixer_width(cstate, adj_mode);
|
||||||
|
|
||||||
for (i = 0; i < dpu_crtc->num_mixers; i++) {
|
for (i = 0; i < cstate->num_mixers; i++) {
|
||||||
struct drm_rect *r = &cstate->lm_bounds[i];
|
struct drm_rect *r = &cstate->lm_bounds[i];
|
||||||
r->x1 = crtc_split_width * i;
|
r->x1 = crtc_split_width * i;
|
||||||
r->y1 = 0;
|
r->y1 = 0;
|
||||||
@ -626,6 +617,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||||||
struct drm_crtc_state *old_state)
|
struct drm_crtc_state *old_state)
|
||||||
{
|
{
|
||||||
struct dpu_crtc *dpu_crtc;
|
struct dpu_crtc *dpu_crtc;
|
||||||
|
struct dpu_crtc_state *cstate;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -645,10 +637,11 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||||||
DPU_DEBUG("crtc%d\n", crtc->base.id);
|
DPU_DEBUG("crtc%d\n", crtc->base.id);
|
||||||
|
|
||||||
dpu_crtc = to_dpu_crtc(crtc);
|
dpu_crtc = to_dpu_crtc(crtc);
|
||||||
|
cstate = to_dpu_crtc_state(crtc->state);
|
||||||
dev = crtc->dev;
|
dev = crtc->dev;
|
||||||
smmu_state = &dpu_crtc->smmu_state;
|
smmu_state = &dpu_crtc->smmu_state;
|
||||||
|
|
||||||
if (!dpu_crtc->num_mixers) {
|
if (!cstate->num_mixers) {
|
||||||
_dpu_crtc_setup_mixers(crtc);
|
_dpu_crtc_setup_mixers(crtc);
|
||||||
_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
|
_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
|
||||||
}
|
}
|
||||||
@ -675,7 +668,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||||||
* it means we are trying to flush a CRTC whose state is disabled:
|
* it means we are trying to flush a CRTC whose state is disabled:
|
||||||
* nothing else needs to be done.
|
* nothing else needs to be done.
|
||||||
*/
|
*/
|
||||||
if (unlikely(!dpu_crtc->num_mixers))
|
if (unlikely(!cstate->num_mixers))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_dpu_crtc_blend_setup(crtc);
|
_dpu_crtc_blend_setup(crtc);
|
||||||
@ -739,7 +732,7 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
|
|||||||
* it means we are trying to flush a CRTC whose state is disabled:
|
* it means we are trying to flush a CRTC whose state is disabled:
|
||||||
* nothing else needs to be done.
|
* nothing else needs to be done.
|
||||||
*/
|
*/
|
||||||
if (unlikely(!dpu_crtc->num_mixers))
|
if (unlikely(!cstate->num_mixers))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -854,7 +847,7 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
|
|||||||
* it means we are trying to start a CRTC whose state is disabled:
|
* it means we are trying to start a CRTC whose state is disabled:
|
||||||
* nothing else needs to be done.
|
* nothing else needs to be done.
|
||||||
*/
|
*/
|
||||||
if (unlikely(!dpu_crtc->num_mixers))
|
if (unlikely(!cstate->num_mixers))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DPU_ATRACE_BEGIN("crtc_commit");
|
DPU_ATRACE_BEGIN("crtc_commit");
|
||||||
@ -1088,12 +1081,14 @@ static void dpu_crtc_handle_power_event(u32 event_type, void *arg)
|
|||||||
struct drm_crtc *crtc = arg;
|
struct drm_crtc *crtc = arg;
|
||||||
struct dpu_crtc *dpu_crtc;
|
struct dpu_crtc *dpu_crtc;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
|
struct dpu_crtc_state *cstate;
|
||||||
|
|
||||||
if (!crtc) {
|
if (!crtc) {
|
||||||
DPU_ERROR("invalid crtc\n");
|
DPU_ERROR("invalid crtc\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dpu_crtc = to_dpu_crtc(crtc);
|
dpu_crtc = to_dpu_crtc(crtc);
|
||||||
|
cstate = to_dpu_crtc_state(dpu_crtc->base.state);
|
||||||
|
|
||||||
mutex_lock(&dpu_crtc->crtc_lock);
|
mutex_lock(&dpu_crtc->crtc_lock);
|
||||||
|
|
||||||
@ -1174,9 +1169,8 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
|
|||||||
dpu_power_handle_unregister_event(dpu_crtc->phandle,
|
dpu_power_handle_unregister_event(dpu_crtc->phandle,
|
||||||
dpu_crtc->power_event);
|
dpu_crtc->power_event);
|
||||||
|
|
||||||
memset(dpu_crtc->mixers, 0, sizeof(dpu_crtc->mixers));
|
memset(cstate->mixers, 0, sizeof(cstate->mixers));
|
||||||
dpu_crtc->num_mixers = 0;
|
cstate->num_mixers = 0;
|
||||||
dpu_crtc->mixers_swapped = false;
|
|
||||||
|
|
||||||
/* disable clk & bw control until clk & bw properties are set */
|
/* disable clk & bw control until clk & bw properties are set */
|
||||||
cstate->bw_control = false;
|
cstate->bw_control = false;
|
||||||
@ -1521,6 +1515,8 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
|
|||||||
|
|
||||||
dpu_crtc = s->private;
|
dpu_crtc = s->private;
|
||||||
crtc = &dpu_crtc->base;
|
crtc = &dpu_crtc->base;
|
||||||
|
|
||||||
|
drm_modeset_lock_all(crtc->dev);
|
||||||
cstate = to_dpu_crtc_state(crtc->state);
|
cstate = to_dpu_crtc_state(crtc->state);
|
||||||
|
|
||||||
mutex_lock(&dpu_crtc->crtc_lock);
|
mutex_lock(&dpu_crtc->crtc_lock);
|
||||||
@ -1532,8 +1528,8 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
|
|||||||
|
|
||||||
seq_puts(s, "\n");
|
seq_puts(s, "\n");
|
||||||
|
|
||||||
for (i = 0; i < dpu_crtc->num_mixers; ++i) {
|
for (i = 0; i < cstate->num_mixers; ++i) {
|
||||||
m = &dpu_crtc->mixers[i];
|
m = &cstate->mixers[i];
|
||||||
if (!m->hw_lm)
|
if (!m->hw_lm)
|
||||||
seq_printf(s, "\tmixer[%d] has no lm\n", i);
|
seq_printf(s, "\tmixer[%d] has no lm\n", i);
|
||||||
else if (!m->hw_ctl)
|
else if (!m->hw_ctl)
|
||||||
@ -1613,6 +1609,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
|
|||||||
seq_printf(s, "vblank_enable:%d\n", dpu_crtc->vblank_requested);
|
seq_printf(s, "vblank_enable:%d\n", dpu_crtc->vblank_requested);
|
||||||
|
|
||||||
mutex_unlock(&dpu_crtc->crtc_lock);
|
mutex_unlock(&dpu_crtc->crtc_lock);
|
||||||
|
drm_modeset_unlock_all(crtc->dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -121,11 +121,6 @@ struct dpu_crtc_frame_event {
|
|||||||
* struct dpu_crtc - virtualized CRTC data structure
|
* struct dpu_crtc - virtualized CRTC data structure
|
||||||
* @base : Base drm crtc structure
|
* @base : Base drm crtc structure
|
||||||
* @name : ASCII description of this crtc
|
* @name : ASCII description of this crtc
|
||||||
* @num_ctls : Number of ctl paths in use
|
|
||||||
* @num_mixers : Number of mixers in use
|
|
||||||
* @mixers_swapped: Whether the mixers have been swapped for left/right update
|
|
||||||
* especially in the case of DSC Merge.
|
|
||||||
* @mixers : List of active mixers
|
|
||||||
* @event : Pointer to last received drm vblank event. If there is a
|
* @event : Pointer to last received drm vblank event. If there is a
|
||||||
* pending vblank event, this will be non-null.
|
* pending vblank event, this will be non-null.
|
||||||
* @vsync_count : Running count of received vsync events
|
* @vsync_count : Running count of received vsync events
|
||||||
@ -164,12 +159,6 @@ struct dpu_crtc {
|
|||||||
struct drm_crtc base;
|
struct drm_crtc base;
|
||||||
char name[DPU_CRTC_NAME_SIZE];
|
char name[DPU_CRTC_NAME_SIZE];
|
||||||
|
|
||||||
/* HW Resources reserved for the crtc */
|
|
||||||
u32 num_ctls;
|
|
||||||
u32 num_mixers;
|
|
||||||
bool mixers_swapped;
|
|
||||||
struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
|
|
||||||
|
|
||||||
struct drm_pending_vblank_event *event;
|
struct drm_pending_vblank_event *event;
|
||||||
u32 vsync_count;
|
u32 vsync_count;
|
||||||
|
|
||||||
@ -221,6 +210,10 @@ struct dpu_crtc {
|
|||||||
* @property_values: Current crtc property values
|
* @property_values: Current crtc property values
|
||||||
* @input_fence_timeout_ns : Cached input fence timeout, in ns
|
* @input_fence_timeout_ns : Cached input fence timeout, in ns
|
||||||
* @new_perf: new performance state being requested
|
* @new_perf: new performance state being requested
|
||||||
|
* @num_mixers : Number of mixers in use
|
||||||
|
* @mixers : List of active mixers
|
||||||
|
* @num_ctls : Number of ctl paths in use
|
||||||
|
* @hw_ctls : List of active ctl paths
|
||||||
*/
|
*/
|
||||||
struct dpu_crtc_state {
|
struct dpu_crtc_state {
|
||||||
struct drm_crtc_state base;
|
struct drm_crtc_state base;
|
||||||
@ -232,6 +225,13 @@ struct dpu_crtc_state {
|
|||||||
uint64_t input_fence_timeout_ns;
|
uint64_t input_fence_timeout_ns;
|
||||||
|
|
||||||
struct dpu_core_perf_params new_perf;
|
struct dpu_core_perf_params new_perf;
|
||||||
|
|
||||||
|
/* HW Resources reserved for the crtc */
|
||||||
|
u32 num_mixers;
|
||||||
|
struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
|
||||||
|
|
||||||
|
u32 num_ctls;
|
||||||
|
struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_dpu_crtc_state(x) \
|
#define to_dpu_crtc_state(x) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user