diff options
| author | Alan Kwong <akwong@codeaurora.org> | 2016-07-29 03:33:17 -0400 |
|---|---|---|
| committer | Alan Kwong <akwong@codeaurora.org> | 2016-08-04 11:39:33 -0400 |
| commit | 7c49bac9978e73ffc6c4d2aad99a5a562959ae70 (patch) | |
| tree | f841309cfe82588014c859be3c6208f8d5b78645 /drivers/gpu | |
| parent | b05a124d2f5bcdb699adad308a5a90c91faca889 (diff) | |
drm/msm/sde: add resource management for writeback and cdm
Add resource management control for writeback and cdm hadware drivers.
This enables sharing of hardware resources among multiple controlling
components.
Change-Id: Ieac1058b4ccb6a59c934c3ad5053dae20ca8c4e5
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_crtc.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.h | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms_utils.c | 74 |
7 files changed, 94 insertions, 21 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index cb8c4e94d2b4..02cd5847c897 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -99,7 +99,8 @@ static int sde_crtc_reserve_hw_resources(struct drm_crtc *crtc, if (enc_hw_res.intfs[i]) { struct sde_crtc_mixer *mixer = &sde_crtc->mixer[sde_crtc->num_mixers]; - plat_hw_res_map = sde_rm_get_res_map(sde_kms, i); + plat_hw_res_map = sde_rm_get_res_map(sde_kms, + i, SDE_NONE); lm_idx = plat_hw_res_map->lm; if (!lm_idx && unused_lm_count) diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index 159be1c990e1..5d4d6ceebad3 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -623,7 +623,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, ret = -EINVAL; } - hw_res_map = sde_rm_get_res_map(sde_kms, intf_idx); + hw_res_map = sde_rm_get_res_map(sde_kms, intf_idx, SDE_NONE); if (IS_ERR_OR_NULL(hw_res_map)) { ret = -EINVAL; } else { diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c index aa75d7782b06..a5c8f739b652 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c @@ -379,7 +379,7 @@ static void sde_encoder_phys_cmd_get_hw_resources( hw_res->intfs[cmd_enc->intf_idx] = INTF_MODE_CMD; hw_res->pingpongs[cmd_enc->hw_pp->idx] = true; hw_res_map = sde_rm_get_res_map(phys_enc->sde_kms, - cmd_enc->intf_idx); + cmd_enc->intf_idx, SDE_NONE); if (IS_ERR_OR_NULL(hw_res_map)) { DRM_ERROR("Failed to get hw_res_map: %ld", PTR_ERR(hw_res_map)); return; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c index 54b6e9720861..48738bd0ab94 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c @@ -504,7 +504,7 @@ static void sde_encoder_phys_vid_get_hw_resources( * otherwise signal/return failure */ hw_res_map = sde_rm_get_res_map(phys_enc->sde_kms, - vid_enc->hw_intf->idx); + vid_enc->hw_intf->idx, SDE_NONE); if (IS_ERR_OR_NULL(hw_res_map)) { DRM_ERROR("Failed to get hw_res_map: %ld", PTR_ERR(hw_res_map)); return; diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 438c42b29c03..67c70af5967f 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -25,12 +25,15 @@ static const char * const iommu_ports[] = { "mdp_0", }; -static const struct sde_hw_res_map res_table[INTF_MAX] = { - { SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE }, - { INTF_0, SDE_NONE, SDE_NONE, SDE_NONE }, - { INTF_1, LM_0, PINGPONG_0, CTL_0 }, - { INTF_2, LM_1, PINGPONG_1, CTL_1 }, - { INTF_3, SDE_NONE, SDE_NONE, CTL_2 }, +static const struct sde_hw_res_map res_table[INTF_MAX + WB_MAX] = { + {SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE}, + {INTF_0, SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE, SDE_NONE}, + {INTF_1, SDE_NONE, LM_0, PINGPONG_0, CTL_0, SDE_NONE}, + {INTF_2, SDE_NONE, LM_1, PINGPONG_1, CTL_1, SDE_NONE }, + {INTF_3, SDE_NONE, SDE_NONE, SDE_NONE, CTL_2, SDE_NONE}, + {SDE_NONE, WB_0, LM_3, SDE_NONE, CTL_3, SDE_NONE}, + {SDE_NONE, WB_1, LM_4, SDE_NONE, CTL_4, SDE_NONE}, + {SDE_NONE, WB_2, LM_2, SDE_NONE, CTL_2, CDM_0}, }; diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index d3999795d80d..f465fef0a6cb 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -21,6 +21,8 @@ #include "sde_hw_ctl.h" #include "sde_hw_lm.h" #include "sde_hw_interrupts.h" +#include "sde_hw_wb.h" +#include "sde_hw_top.h" #include "sde_connector.h" /** @@ -79,9 +81,11 @@ struct sde_irq { */ struct sde_hw_res_map { enum sde_intf intf; + enum sde_wb wb; enum sde_lm lm; enum sde_pingpong pp; enum sde_ctl ctl; + enum sde_cdm cdm; }; /* struct sde_hw_resource_manager : Resource manager maintains the current @@ -89,6 +93,7 @@ struct sde_hw_res_map { * hw resources ex:ctl_path hw driver context * is needed by CRTCs/PLANEs/ENCODERs * @ctl : table of control path hw driver contexts allocated + * @cdm : table of chroma down path hw driver contexts allocated * @mixer : list of mixer hw drivers contexts allocated * @intr : pointer to hw interrupt context * @res_table : pointer to default hw_res table for this platform @@ -97,6 +102,7 @@ struct sde_hw_res_map { */ struct sde_hw_resource_manager { struct sde_hw_ctl *ctl[CTL_MAX]; + struct sde_hw_cdm *cdm[CDM_MAX]; struct sde_hw_mixer *mixer[LM_MAX]; struct sde_hw_intr *intr; const struct sde_hw_res_map *res_table; @@ -411,6 +417,14 @@ struct sde_hw_ctl *sde_rm_get_ctl_path(struct sde_kms *sde_kms, enum sde_ctl idx); void sde_rm_release_ctl_path(struct sde_kms *sde_kms, enum sde_ctl idx); + +struct sde_hw_cdm *sde_rm_acquire_cdm_path(struct sde_kms *sde_kms, + enum sde_cdm idx, struct sde_hw_mdp *hw_mdp); +struct sde_hw_cdm *sde_rm_get_cdm_path(struct sde_kms *sde_kms, + enum sde_cdm idx); +void sde_rm_release_cdm_path(struct sde_kms *sde_kms, + enum sde_cdm idx); + struct sde_hw_mixer *sde_rm_acquire_mixer(struct sde_kms *sde_kms, enum sde_lm idx); struct sde_hw_mixer *sde_rm_get_mixer(struct sde_kms *sde_kms, @@ -421,7 +435,7 @@ struct sde_hw_intr *sde_rm_acquire_intr(struct sde_kms *sde_kms); struct sde_hw_intr *sde_rm_get_intr(struct sde_kms *sde_kms); const struct sde_hw_res_map *sde_rm_get_res_map(struct sde_kms *sde_kms, - enum sde_intf idx); + enum sde_intf intf, enum sde_wb wb); /** * IRQ functions @@ -583,6 +597,7 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc); */ struct sde_encoder_hw_resources { enum sde_intf_mode intfs[INTF_MAX]; + enum sde_intf_mode wbs[WB_MAX]; bool pingpongs[PINGPONG_MAX]; bool ctls[CTL_MAX]; bool pingpongsplit; diff --git a/drivers/gpu/drm/msm/sde/sde_kms_utils.c b/drivers/gpu/drm/msm/sde/sde_kms_utils.c index bd52c8c253a7..c4c9f7601053 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms_utils.c +++ b/drivers/gpu/drm/msm/sde/sde_kms_utils.c @@ -13,6 +13,7 @@ #include "sde_kms.h" #include "sde_hw_lm.h" #include "sde_hw_ctl.h" +#include "sde_hw_cdm.h" struct sde_hw_intr *sde_rm_acquire_intr(struct sde_kms *sde_kms) { @@ -106,6 +107,50 @@ void sde_rm_release_ctl_path(struct sde_kms *sde_kms, enum sde_ctl idx) } } +struct sde_hw_cdm *sde_rm_acquire_cdm_path(struct sde_kms *sde_kms, + enum sde_cdm idx, struct sde_hw_mdp *hw_mdp) +{ + struct sde_hw_cdm *hw_cdm; + + if (!sde_kms) { + DRM_ERROR("Invalid KMS driver"); + return ERR_PTR(-EINVAL); + } else if ((idx == SDE_NONE) || (idx > sde_kms->catalog->cdm_count)) { + DRM_ERROR("Invalid Cdm Path Idx %d", idx); + return ERR_PTR(-EINVAL); + } else if (sde_kms->hw_res.cdm[idx]) { + DRM_ERROR("Cdm path %d already in use ", idx); + return ERR_PTR(-ENODEV); + } + + sde_enable(sde_kms); + hw_cdm = sde_hw_cdm_init(idx, sde_kms->mmio, sde_kms->catalog, hw_mdp); + sde_disable(sde_kms); + + if (!IS_ERR_OR_NULL(hw_cdm)) + sde_kms->hw_res.cdm[idx] = hw_cdm; + + return hw_cdm; +} + +struct sde_hw_cdm *sde_rm_get_cdm_path(struct sde_kms *sde_kms, + enum sde_cdm idx) +{ + if (!sde_kms) { + DRM_ERROR("Invalid KMS Driver"); + return ERR_PTR(-EINVAL); + } else if ((idx == SDE_NONE) || (idx > sde_kms->catalog->cdm_count)) { + DRM_ERROR("Invalid Cdm path Idx %d", idx); + return ERR_PTR(-EINVAL); + } + + return sde_kms->hw_res.cdm[idx]; +} + +void sde_rm_release_cdm_path(struct sde_kms *sde_kms, enum sde_cdm idx) +{ +} + struct sde_hw_mixer *sde_rm_acquire_mixer(struct sde_kms *sde_kms, enum sde_lm idx) { @@ -153,23 +198,32 @@ struct sde_hw_mixer *sde_rm_get_mixer(struct sde_kms *sde_kms, } const struct sde_hw_res_map *sde_rm_get_res_map(struct sde_kms *sde_kms, - enum sde_intf idx) + enum sde_intf intf, enum sde_wb wb) { + int i; + if (!sde_kms) { DRM_ERROR("Invalid KMS Driver"); return ERR_PTR(-EINVAL); } - if ((idx == SDE_NONE) || (idx > sde_kms->catalog->intf_count)) { - DRM_ERROR("Invalid intf id %d", idx); - return ERR_PTR(-EINVAL); + + for (i = 0; i < (INTF_MAX + WB_MAX); i++) { + if ((sde_kms->hw_res.res_table[i].intf == intf) && + (sde_kms->hw_res.res_table[i].wb == wb)) { + DBG( + " Platform Resource map for INTF %d, WB %d -> lm %d, pp %d ctl %d cdm %d", + sde_kms->hw_res.res_table[i].intf, + sde_kms->hw_res.res_table[i].wb, + sde_kms->hw_res.res_table[i].lm, + sde_kms->hw_res.res_table[i].pp, + sde_kms->hw_res.res_table[i].ctl, + sde_kms->hw_res.res_table[i].cdm); + + return &(sde_kms->hw_res.res_table[i]); + } } - DBG(" Platform Resource map for INTF %d -> lm %d, pp %d ctl %d", - sde_kms->hw_res.res_table[idx].intf, - sde_kms->hw_res.res_table[idx].lm, - sde_kms->hw_res.res_table[idx].pp, - sde_kms->hw_res.res_table[idx].ctl); - return &(sde_kms->hw_res.res_table[idx]); + return ERR_PTR(-EINVAL); } void sde_kms_info_reset(struct sde_kms_info *info) |
