diff options
| author | Lloyd Atkinson <latkinso@codeaurora.org> | 2016-08-16 16:57:46 -0400 |
|---|---|---|
| committer | Lloyd Atkinson <latkinso@codeaurora.org> | 2016-10-27 13:58:25 -0400 |
| commit | 571ed2aea64bb8174dd67f449afa724df73d25be (patch) | |
| tree | f719a484bb75261b0bee12e1a62f756d4cf704ea | |
| parent | 5204ca9e7f3eab41bc5e39227de75acf7551e83e (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.h | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys.h | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_ctl.c | 1 |
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 |
