drm/msm/dpu: get INTF blocks directly rather than through RM
INTF blocks are not really handled by resource manager, they are assigned at dpu_encoder_setup_display using dpu_encoder_get_intf(). Then this allocation is passed to RM and then returned to then dpu_encoder. So allocate them outside of RM and use them directly. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com> Link: https://lore.kernel.org/r/20220121210618.3482550-4-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
This commit is contained in:
parent
d5c5e78f21
commit
ef58e0ad34
8 changed files with 16 additions and 134 deletions
|
@ -420,26 +420,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc)
|
||||||
return linecount;
|
return linecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc,
|
|
||||||
struct dpu_encoder_hw_resources *hw_res)
|
|
||||||
{
|
|
||||||
struct dpu_encoder_virt *dpu_enc = NULL;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
dpu_enc = to_dpu_encoder_virt(drm_enc);
|
|
||||||
DPU_DEBUG_ENC(dpu_enc, "\n");
|
|
||||||
|
|
||||||
/* Query resources used by phys encs, expected to be without overlap */
|
|
||||||
memset(hw_res, 0, sizeof(*hw_res));
|
|
||||||
|
|
||||||
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
|
|
||||||
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
|
|
||||||
|
|
||||||
if (phys->ops.get_hw_resources)
|
|
||||||
phys->ops.get_hw_resources(phys, hw_res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
|
static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
|
||||||
{
|
{
|
||||||
struct dpu_encoder_virt *dpu_enc = NULL;
|
struct dpu_encoder_virt *dpu_enc = NULL;
|
||||||
|
@ -973,7 +953,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
|
||||||
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
|
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
|
||||||
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
|
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
|
||||||
int num_lm, num_ctl, num_pp;
|
int num_lm, num_ctl, num_pp;
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
if (!drm_enc) {
|
if (!drm_enc) {
|
||||||
DPU_ERROR("invalid encoder\n");
|
DPU_ERROR("invalid encoder\n");
|
||||||
|
@ -1040,8 +1020,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
|
||||||
cstate->num_mixers = num_lm;
|
cstate->num_mixers = num_lm;
|
||||||
|
|
||||||
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
|
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
|
||||||
int num_blk;
|
|
||||||
struct dpu_hw_blk *hw_blk[MAX_CHANNELS_PER_ENC];
|
|
||||||
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
|
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
|
||||||
|
|
||||||
if (!dpu_enc->hw_pp[i]) {
|
if (!dpu_enc->hw_pp[i]) {
|
||||||
|
@ -1059,16 +1037,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
|
||||||
phys->hw_pp = dpu_enc->hw_pp[i];
|
phys->hw_pp = dpu_enc->hw_pp[i];
|
||||||
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
|
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
|
||||||
|
|
||||||
num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm,
|
if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX)
|
||||||
global_state, drm_enc->base.id, DPU_HW_BLK_INTF,
|
phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx);
|
||||||
hw_blk, ARRAY_SIZE(hw_blk));
|
|
||||||
for (j = 0; j < num_blk; j++) {
|
|
||||||
struct dpu_hw_intf *hw_intf;
|
|
||||||
|
|
||||||
hw_intf = to_dpu_hw_intf(hw_blk[i]);
|
|
||||||
if (hw_intf->idx == phys->intf_idx)
|
|
||||||
phys->hw_intf = hw_intf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!phys->hw_intf) {
|
if (!phys->hw_intf) {
|
||||||
DPU_ERROR_ENC(dpu_enc,
|
DPU_ERROR_ENC(dpu_enc,
|
||||||
|
|
|
@ -18,22 +18,6 @@
|
||||||
|
|
||||||
#define IDLE_TIMEOUT (66 - 16/2)
|
#define IDLE_TIMEOUT (66 - 16/2)
|
||||||
|
|
||||||
/**
|
|
||||||
* Encoder functions and data types
|
|
||||||
* @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused
|
|
||||||
*/
|
|
||||||
struct dpu_encoder_hw_resources {
|
|
||||||
enum dpu_intf_mode intfs[INTF_MAX];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dpu_encoder_get_hw_resources - Populate table of required hardware resources
|
|
||||||
* @encoder: encoder pointer
|
|
||||||
* @hw_res: resource table to populate with encoder required resources
|
|
||||||
*/
|
|
||||||
void dpu_encoder_get_hw_resources(struct drm_encoder *encoder,
|
|
||||||
struct dpu_encoder_hw_resources *hw_res);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to
|
* dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to
|
||||||
* @encoder: encoder pointer
|
* @encoder: encoder pointer
|
||||||
|
|
|
@ -91,9 +91,6 @@ struct dpu_encoder_virt_ops {
|
||||||
* @disable: DRM Call. Disable mode.
|
* @disable: DRM Call. Disable mode.
|
||||||
* @atomic_check: DRM Call. Atomic check new DRM state.
|
* @atomic_check: DRM Call. Atomic check new DRM state.
|
||||||
* @destroy: DRM Call. Destroy and release resources.
|
* @destroy: DRM Call. Destroy and release resources.
|
||||||
* @get_hw_resources: Populate the structure with the hardware
|
|
||||||
* resources that this phys_enc is using.
|
|
||||||
* Expect no overlap between phys_encs.
|
|
||||||
* @control_vblank_irq Register/Deregister for VBLANK IRQ
|
* @control_vblank_irq Register/Deregister for VBLANK IRQ
|
||||||
* @wait_for_commit_done: Wait for hardware to have flushed the
|
* @wait_for_commit_done: Wait for hardware to have flushed the
|
||||||
* current pending frames to hardware
|
* current pending frames to hardware
|
||||||
|
@ -129,8 +126,6 @@ struct dpu_encoder_phys_ops {
|
||||||
struct drm_crtc_state *crtc_state,
|
struct drm_crtc_state *crtc_state,
|
||||||
struct drm_connector_state *conn_state);
|
struct drm_connector_state *conn_state);
|
||||||
void (*destroy)(struct dpu_encoder_phys *encoder);
|
void (*destroy)(struct dpu_encoder_phys *encoder);
|
||||||
void (*get_hw_resources)(struct dpu_encoder_phys *encoder,
|
|
||||||
struct dpu_encoder_hw_resources *hw_res);
|
|
||||||
int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
|
int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
|
||||||
int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
|
int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
|
||||||
int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
|
int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
|
||||||
|
|
|
@ -534,13 +534,6 @@ static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc)
|
||||||
kfree(cmd_enc);
|
kfree(cmd_enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dpu_encoder_phys_cmd_get_hw_resources(
|
|
||||||
struct dpu_encoder_phys *phys_enc,
|
|
||||||
struct dpu_encoder_hw_resources *hw_res)
|
|
||||||
{
|
|
||||||
hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dpu_encoder_phys_cmd_prepare_for_kickoff(
|
static void dpu_encoder_phys_cmd_prepare_for_kickoff(
|
||||||
struct dpu_encoder_phys *phys_enc)
|
struct dpu_encoder_phys *phys_enc)
|
||||||
{
|
{
|
||||||
|
@ -736,7 +729,6 @@ static void dpu_encoder_phys_cmd_init_ops(
|
||||||
ops->enable = dpu_encoder_phys_cmd_enable;
|
ops->enable = dpu_encoder_phys_cmd_enable;
|
||||||
ops->disable = dpu_encoder_phys_cmd_disable;
|
ops->disable = dpu_encoder_phys_cmd_disable;
|
||||||
ops->destroy = dpu_encoder_phys_cmd_destroy;
|
ops->destroy = dpu_encoder_phys_cmd_destroy;
|
||||||
ops->get_hw_resources = dpu_encoder_phys_cmd_get_hw_resources;
|
|
||||||
ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
|
ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
|
||||||
ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
|
ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
|
||||||
ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
|
ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
|
||||||
|
|
|
@ -465,13 +465,6 @@ static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc)
|
||||||
kfree(phys_enc);
|
kfree(phys_enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dpu_encoder_phys_vid_get_hw_resources(
|
|
||||||
struct dpu_encoder_phys *phys_enc,
|
|
||||||
struct dpu_encoder_hw_resources *hw_res)
|
|
||||||
{
|
|
||||||
hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dpu_encoder_phys_vid_wait_for_vblank(
|
static int dpu_encoder_phys_vid_wait_for_vblank(
|
||||||
struct dpu_encoder_phys *phys_enc)
|
struct dpu_encoder_phys *phys_enc)
|
||||||
{
|
{
|
||||||
|
@ -680,7 +673,6 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops)
|
||||||
ops->enable = dpu_encoder_phys_vid_enable;
|
ops->enable = dpu_encoder_phys_vid_enable;
|
||||||
ops->disable = dpu_encoder_phys_vid_disable;
|
ops->disable = dpu_encoder_phys_vid_disable;
|
||||||
ops->destroy = dpu_encoder_phys_vid_destroy;
|
ops->destroy = dpu_encoder_phys_vid_destroy;
|
||||||
ops->get_hw_resources = dpu_encoder_phys_vid_get_hw_resources;
|
|
||||||
ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq;
|
ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq;
|
||||||
ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done;
|
ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done;
|
||||||
ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank;
|
ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank;
|
||||||
|
|
|
@ -144,7 +144,6 @@ struct dpu_global_state {
|
||||||
uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
|
uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
|
||||||
uint32_t mixer_to_enc_id[LM_MAX - LM_0];
|
uint32_t mixer_to_enc_id[LM_MAX - LM_0];
|
||||||
uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
|
uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
|
||||||
uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
|
|
||||||
uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
|
uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ static inline bool reserved_by_other(uint32_t *res_map, int idx,
|
||||||
*/
|
*/
|
||||||
struct dpu_rm_requirements {
|
struct dpu_rm_requirements {
|
||||||
struct msm_display_topology topology;
|
struct msm_display_topology topology;
|
||||||
struct dpu_encoder_hw_resources hw_res;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int dpu_rm_destroy(struct dpu_rm *rm)
|
int dpu_rm_destroy(struct dpu_rm *rm)
|
||||||
|
@ -448,54 +447,6 @@ static int _dpu_rm_reserve_ctls(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dpu_rm_reserve_intf(
|
|
||||||
struct dpu_rm *rm,
|
|
||||||
struct dpu_global_state *global_state,
|
|
||||||
uint32_t enc_id,
|
|
||||||
uint32_t id)
|
|
||||||
{
|
|
||||||
int idx = id - INTF_0;
|
|
||||||
|
|
||||||
if (idx < 0 || idx >= ARRAY_SIZE(rm->intf_blks)) {
|
|
||||||
DPU_ERROR("invalid intf id: %d", id);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rm->intf_blks[idx]) {
|
|
||||||
DPU_ERROR("couldn't find intf id %d\n", id);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reserved_by_other(global_state->intf_to_enc_id, idx, enc_id)) {
|
|
||||||
DPU_ERROR("intf id %d already reserved\n", id);
|
|
||||||
return -ENAVAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
global_state->intf_to_enc_id[idx] = enc_id;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _dpu_rm_reserve_intf_related_hw(
|
|
||||||
struct dpu_rm *rm,
|
|
||||||
struct dpu_global_state *global_state,
|
|
||||||
uint32_t enc_id,
|
|
||||||
struct dpu_encoder_hw_resources *hw_res)
|
|
||||||
{
|
|
||||||
int i, ret = 0;
|
|
||||||
u32 id;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(hw_res->intfs); i++) {
|
|
||||||
if (hw_res->intfs[i] == INTF_MODE_NONE)
|
|
||||||
continue;
|
|
||||||
id = i + INTF_0;
|
|
||||||
ret = _dpu_rm_reserve_intf(rm, global_state, enc_id, id);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _dpu_rm_make_reservation(
|
static int _dpu_rm_make_reservation(
|
||||||
struct dpu_rm *rm,
|
struct dpu_rm *rm,
|
||||||
struct dpu_global_state *global_state,
|
struct dpu_global_state *global_state,
|
||||||
|
@ -517,11 +468,6 @@ static int _dpu_rm_make_reservation(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _dpu_rm_reserve_intf_related_hw(rm, global_state, enc->base.id,
|
|
||||||
&reqs->hw_res);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,8 +476,6 @@ static int _dpu_rm_populate_requirements(
|
||||||
struct dpu_rm_requirements *reqs,
|
struct dpu_rm_requirements *reqs,
|
||||||
struct msm_display_topology req_topology)
|
struct msm_display_topology req_topology)
|
||||||
{
|
{
|
||||||
dpu_encoder_get_hw_resources(enc, &reqs->hw_res);
|
|
||||||
|
|
||||||
reqs->topology = req_topology;
|
reqs->topology = req_topology;
|
||||||
|
|
||||||
DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",
|
DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",
|
||||||
|
@ -561,8 +505,6 @@ void dpu_rm_release(struct dpu_global_state *global_state,
|
||||||
ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id);
|
ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id);
|
||||||
_dpu_rm_clear_mapping(global_state->ctl_to_enc_id,
|
_dpu_rm_clear_mapping(global_state->ctl_to_enc_id,
|
||||||
ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
|
ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
|
||||||
_dpu_rm_clear_mapping(global_state->intf_to_enc_id,
|
|
||||||
ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int dpu_rm_reserve(
|
int dpu_rm_reserve(
|
||||||
|
@ -626,11 +568,6 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
|
||||||
hw_to_enc_id = global_state->ctl_to_enc_id;
|
hw_to_enc_id = global_state->ctl_to_enc_id;
|
||||||
max_blks = ARRAY_SIZE(rm->ctl_blks);
|
max_blks = ARRAY_SIZE(rm->ctl_blks);
|
||||||
break;
|
break;
|
||||||
case DPU_HW_BLK_INTF:
|
|
||||||
hw_blks = rm->intf_blks;
|
|
||||||
hw_to_enc_id = global_state->intf_to_enc_id;
|
|
||||||
max_blks = ARRAY_SIZE(rm->intf_blks);
|
|
||||||
break;
|
|
||||||
case DPU_HW_BLK_DSPP:
|
case DPU_HW_BLK_DSPP:
|
||||||
hw_blks = rm->dspp_blks;
|
hw_blks = rm->dspp_blks;
|
||||||
hw_to_enc_id = global_state->dspp_to_enc_id;
|
hw_to_enc_id = global_state->dspp_to_enc_id;
|
||||||
|
@ -656,3 +593,8 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
|
||||||
|
|
||||||
return num_blks;
|
return num_blks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx)
|
||||||
|
{
|
||||||
|
return to_dpu_hw_intf(rm->intf_blks[intf_idx - INTF_0]);
|
||||||
|
}
|
||||||
|
|
|
@ -84,5 +84,13 @@ void dpu_rm_release(struct dpu_global_state *global_state,
|
||||||
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
|
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
|
||||||
struct dpu_global_state *global_state, uint32_t enc_id,
|
struct dpu_global_state *global_state, uint32_t enc_id,
|
||||||
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
|
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dpu_rm_get_intf - Return a struct dpu_hw_intf instance given it's index.
|
||||||
|
* @rm: DPU Resource Manager handle
|
||||||
|
* @intf_idx: INTF's index
|
||||||
|
*/
|
||||||
|
struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx);
|
||||||
|
|
||||||
#endif /* __DPU_RM_H__ */
|
#endif /* __DPU_RM_H__ */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue