summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLloyd Atkinson <latkinso@codeaurora.org>2016-08-16 16:57:46 -0400
committerLloyd Atkinson <latkinso@codeaurora.org>2016-10-27 13:58:25 -0400
commit571ed2aea64bb8174dd67f449afa724df73d25be (patch)
treef719a484bb75261b0bee12e1a62f756d4cf704ea
parent5204ca9e7f3eab41bc5e39227de75acf7551e83e (diff)
drm/msm/sde: dual pipe use case support
Add support for cases with two pipes, merged together via 3D mux into one output display. Change-Id: Ic1e16af72e8cc45a8fd9ad706b37f5b69d30f0ef Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
-rw-r--r--drivers/gpu/drm/msm/sde/sde_connector.h14
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder.c17
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys.h18
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c4
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c8
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c1
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_ctl.c1
7 files changed, 47 insertions, 16 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 403160c85ae2..cca934d52914 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -239,6 +239,20 @@ struct sde_connector_state {
((S) ? to_sde_connector_state((S))->out_fb : 0)
/**
+ * sde_connector_get_topology_name - helper accessor to retrieve topology_name
+ * @connector: pointer to drm connector
+ * Returns: value of the CONNECTOR_PROP_TOPOLOGY_NAME property or 0
+ */
+static inline uint64_t sde_connector_get_topology_name(
+ struct drm_connector *connector)
+{
+ if (!connector || !connector->state)
+ return 0;
+ return sde_connector_get_property(connector->state,
+ CONNECTOR_PROP_TOPOLOGY_NAME);
+}
+
+/**
* sde_connector_init - create drm connector object for a given display
* @dev: Pointer to drm device struct
* @encoder: Pointer to associated encoder
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index bac319ee6889..56eae31da3ad 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -336,6 +336,9 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
if (!conn) {
SDE_ERROR_ENC(sde_enc, "failed to find attached connector\n");
return;
+ } else if (!conn->state) {
+ SDE_ERROR_ENC(sde_enc, "invalid connector state\n");
+ return;
}
/* Reserve dynamic resources now. Indicating non-AtomicTest phase */
@@ -350,8 +353,11 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
for (i = 0; i < sde_enc->num_phys_encs; i++) {
struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
- if (phys && phys->ops.mode_set)
- phys->ops.mode_set(phys, mode, adj_mode);
+ if (phys) {
+ phys->connector = conn->state->connector;
+ if (phys->ops.mode_set)
+ phys->ops.mode_set(phys, mode, adj_mode);
+ }
}
}
@@ -435,8 +441,11 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
for (i = 0; i < sde_enc->num_phys_encs; i++) {
struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
- if (phys && phys->ops.disable && !phys->ops.is_master(phys))
- phys->ops.disable(phys);
+ if (phys) {
+ if (phys->ops.disable && !phys->ops.is_master(phys))
+ phys->ops.disable(phys);
+ phys->connector = NULL;
+ }
}
if (sde_enc->cur_master && sde_enc->cur_master->ops.disable)
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index 4932d503ddbd..3b379aee7dad 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -127,6 +127,7 @@ enum sde_enc_enable_state {
* tied to a specific panel / sub-panel. Abstract type, sub-classed by
* phys_vid or phys_cmd for video mode or command mode encs respectively.
* @parent: Pointer to the containing virtual encoder
+ * @connector: If a mode is set, cached pointer to the active connector
* @ops: Operations exposed to the virtual encoder
* @parent_ops: Callbacks exposed by the parent to the phys_enc
* @hw_mdptop: Hardware interface to the top registers
@@ -139,12 +140,12 @@ enum sde_enc_enable_state {
* @split_role: Role to play in a split-panel configuration
* @intf_mode: Interface mode
* @spin_lock: Lock for IRQ purposes
- * @mode_3d: 3D mux configuration
* @enable_state: Enable state tracking
* @vblank_refcount: Reference count of vblank request
*/
struct sde_encoder_phys {
struct drm_encoder *parent;
+ struct drm_connector *connector;
struct sde_encoder_phys_ops ops;
struct sde_encoder_virt_ops parent_ops;
struct sde_hw_mdp *hw_mdptop;
@@ -156,7 +157,6 @@ struct sde_encoder_phys {
enum sde_enc_split_role split_role;
enum sde_intf_mode intf_mode;
spinlock_t spin_lock;
- enum sde_3d_blend_mode mode_3d;
enum sde_enc_enable_state enable_state;
atomic_t vblank_refcount;
};
@@ -313,4 +313,18 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
*/
void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc);
+
+static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
+ struct sde_encoder_phys *phys_enc)
+{
+ enum sde_rm_topology_name topology;
+
+ topology = sde_connector_get_topology_name(phys_enc->connector);
+ if (phys_enc->split_role == ENC_ROLE_SOLO &&
+ topology == SDE_RM_TOPOLOGY_DUALPIPEMERGE)
+ return BLEND_3D_H_ROW_INT;
+
+ return BLEND_3D_NONE;
+}
+
#endif /* __sde_encoder_phys_H__ */
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 0846e4c02885..139285d66b10 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -327,9 +327,10 @@ static void sde_encoder_phys_cmd_pingpong_config(
drm_mode_debug_printmodeline(&phys_enc->cached_mode);
intf_cfg.intf = cmd_enc->intf_idx;
- intf_cfg.mode_3d = phys_enc->mode_3d;
intf_cfg.intf_mode_sel = SDE_CTL_MODE_SEL_CMD;
intf_cfg.stream_sel = cmd_enc->stream_sel;
+ intf_cfg.mode_3d = sde_encoder_helper_get_3d_blend_mode(phys_enc);
+
phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
sde_encoder_phys_cmd_tearcheck_config(phys_enc);
@@ -611,7 +612,6 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_CMD;
spin_lock_init(&phys_enc->spin_lock);
- phys_enc->mode_3d = BLEND_3D_NONE;
cmd_enc->stream_sel = 0;
phys_enc->enable_state = SDE_ENC_DISABLED;
atomic_set(&cmd_enc->pending_cnt, 0);
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 1b0a74b92fd0..9289d5fa2e33 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -286,10 +286,9 @@ static void sde_encoder_phys_vid_setup_timing_engine(
SDE_DEBUG_VIDENC(vid_enc, "fmt_fourcc 0x%X\n", fmt_fourcc);
intf_cfg.intf = vid_enc->hw_intf->idx;
- intf_cfg.wb = SDE_NONE;
- intf_cfg.mode_3d = phys_enc->mode_3d;
intf_cfg.intf_mode_sel = SDE_CTL_MODE_SEL_VID;
intf_cfg.stream_sel = 0; /* Don't care value for video mode */
+ intf_cfg.mode_3d = sde_encoder_helper_get_3d_blend_mode(phys_enc);
spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
vid_enc->hw_intf->ops.setup_timing_gen(vid_enc->hw_intf,
@@ -762,11 +761,6 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(
spin_lock_init(&phys_enc->spin_lock);
init_completion(&vid_enc->vblank_completion);
atomic_set(&phys_enc->vblank_refcount, 0);
-
- DRM_INFO_ONCE("intf %d: 3d blend modes not yet supported\n",
- vid_enc->hw_intf->idx);
- phys_enc->mode_3d = BLEND_3D_NONE;
-
phys_enc->enable_state = SDE_ENC_DISABLED;
SDE_DEBUG_VIDENC(vid_enc, "created\n");
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
index aa91c2d00d0a..eb77169ac54d 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
@@ -278,6 +278,7 @@ static void sde_encoder_phys_wb_setup_cdp(struct sde_encoder_phys *phys_enc)
intf_cfg->intf = SDE_NONE;
intf_cfg->wb = hw_wb->idx;
+ intf_cfg->mode_3d = sde_encoder_helper_get_3d_blend_mode(phys_enc);
if (phys_enc->hw_ctl && phys_enc->hw_ctl->ops.setup_intf_cfg)
phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl,
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
index 4e8033a0b8f6..2f1bac78b14e 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
@@ -21,7 +21,6 @@
#define CTL_TOP 0x014
#define CTL_FLUSH 0x018
#define CTL_START 0x01C
-#define CTL_PACK_3D 0x020
#define CTL_SW_RESET 0x030
#define CTL_LAYER_EXTN_OFFSET 0x40