summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlan Kwong <akwong@codeaurora.org>2016-07-29 03:33:17 -0400
committerAlan Kwong <akwong@codeaurora.org>2016-08-04 11:39:33 -0400
commit7c49bac9978e73ffc6c4d2aad99a5a562959ae70 (patch)
treef841309cfe82588014c859be3c6208f8d5b78645 /drivers/gpu
parentb05a124d2f5bcdb699adad308a5a90c91faca889 (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.c3
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder.c2
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c2
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c2
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.c15
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.h17
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms_utils.c74
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)