diff options
| author | Dhaval Patel <pdhaval@quicinc.com> | 2016-11-10 16:10:11 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-11-10 16:10:11 -0800 |
| commit | df7f0f85bba2e37c34bda12ea948919a7f70ff50 (patch) | |
| tree | 41eea5d054e82543b35ea3351c23875e0cbc7a39 /drivers/gpu | |
| parent | 36cc5dffb56678f6081a98ed5eb54aadb7592bc2 (diff) | |
| parent | b8811d64d847539dca50833e9159ec897e01868e (diff) | |
Merge "drm/msm/sde: handle pingpong blocks from virtual encoder" into dev/msm-4.4-drm_kms
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder.c | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c | 59 |
3 files changed, 43 insertions, 40 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c index b4757add7dae..37daea0b9f41 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder.c @@ -43,6 +43,8 @@ #define MAX_PHYS_ENCODERS_PER_VIRTUAL \ (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES) +#define MAX_CHANNELS_PER_ENC 2 + /* Wait timeout sized on worst case of 4 60fps frames ~= 67ms */ #define WAIT_TIMEOUT_MSEC 67 @@ -59,6 +61,8 @@ * @phys_encs: Container of physical encoders managed. * @cur_master: Pointer to the current master in this mode. Optimization * Only valid after enable. Cleared as disable. + * @hw_pp Handle to the pingpong blocks used for the display. No. + * pingpong blocks can be different than num_phys_encs. * @crtc_vblank_cb: Callback into the upper layer / CRTC for * notification of the VBLANK * @crtc_vblank_cb_data: Data from upper layer for VBLANK notification @@ -89,6 +93,7 @@ struct sde_encoder_virt { unsigned int num_phys_encs; struct sde_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct sde_encoder_phys *cur_master; + struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; void (*crtc_vblank_cb)(void *); void *crtc_vblank_cb_data; @@ -326,6 +331,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct sde_kms *sde_kms; struct list_head *connector_list; struct drm_connector *conn = NULL, *conn_iter; + struct sde_rm_hw_iter pp_iter; int i = 0, ret; if (!drm_enc) { @@ -363,10 +369,24 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, return; } + sde_rm_init_hw_iter(&pp_iter, drm_enc->base.id, SDE_HW_BLK_PINGPONG); + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + sde_enc->hw_pp[i] = NULL; + if (!sde_rm_get_hw(&sde_kms->rm, &pp_iter)) + break; + sde_enc->hw_pp[i] = (struct sde_hw_pingpong *) pp_iter.hw; + } + for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys) { + if (!sde_enc->hw_pp[i]) { + SDE_ERROR_ENC(sde_enc, + "invalid pingpong block for the encoder\n"); + return; + } + phys->hw_pp = sde_enc->hw_pp[i]; phys->connector = conn->state->connector; if (phys->ops.mode_set) phys->ops.mode_set(phys, mode, adj_mode); diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h index b9761940786f..5dc0b290ef13 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h @@ -154,6 +154,7 @@ enum sde_intr_idx { * @hw_ctl: Hardware interface to the ctl registers * @hw_cdm: Hardware interface to the cdm registers * @cdm_cfg: Chroma-down hardware configuration + * @hw_pp: Hardware interface to the ping pong registers * @sde_kms: Pointer to the sde_kms top level * @cached_mode: DRM mode cached at mode_set time, acted on in enable * @enabled: Whether the encoder has enabled and running a mode @@ -175,6 +176,7 @@ struct sde_encoder_phys { struct sde_hw_ctl *hw_ctl; struct sde_hw_cdm *hw_cdm; struct sde_hw_cdm_cfg cdm_cfg; + struct sde_hw_pingpong *hw_pp; struct sde_kms *sde_kms; struct drm_display_mode cached_mode; enum sde_enc_split_role split_role; @@ -210,7 +212,6 @@ struct sde_encoder_phys_vid { * @base: Baseclass physical encoder structure * @intf_idx: Intf Block index used by this phys encoder * @stream_sel: Stream selection for multi-stream interfaces - * @hw_pp: Hardware interface to the ping pong registers * @pp_rd_ptr_irq_idx: IRQ signifying panel's frame read pointer * For CMD encoders, VBLANK is driven by the PP RD Done IRQ * @pp_tx_done_irq_idx: IRQ signifying frame transmission to panel complete @@ -227,7 +228,6 @@ struct sde_encoder_phys_cmd { struct sde_encoder_phys base; int intf_idx; int stream_sel; - struct sde_hw_pingpong *hw_pp; int irq_idx[INTR_IDX_MAX]; struct sde_irq_callback irq_cb[INTR_IDX_MAX]; wait_queue_head_t pp_tx_done_wq; 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 bdd9239fed95..24e85289fae8 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c @@ -98,23 +98,6 @@ static void sde_encoder_phys_cmd_mode_set( phys_enc->hw_ctl = NULL; return; } - - sde_rm_init_hw_iter(&iter, phys_enc->parent->base.id, - SDE_HW_BLK_PINGPONG); - for (i = 0; i <= instance; i++) { - sde_rm_get_hw(rm, &iter); - if (i == instance) - cmd_enc->hw_pp = (struct sde_hw_pingpong *) iter.hw; - } - - if (IS_ERR_OR_NULL(cmd_enc->hw_pp)) { - SDE_ERROR_CMDENC(cmd_enc, "failed to init pingpong: %ld\n", - PTR_ERR(cmd_enc->hw_pp)); - cmd_enc->hw_pp = NULL; - phys_enc->hw_ctl = NULL; - return; - } - } static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) @@ -128,7 +111,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) phys_enc = &cmd_enc->base; new_pending_cnt = atomic_dec_return(&cmd_enc->pending_cnt); - MSM_EVT(DEV(phys_enc), cmd_enc->hw_pp->idx, new_pending_cnt); + MSM_EVT(DEV(phys_enc), phys_enc->hw_pp->idx, new_pending_cnt); /* Signal any waiting atomic commit thread */ wake_up_all(&cmd_enc->pp_tx_done_wq); @@ -180,12 +163,12 @@ static int sde_encoder_phys_cmd_register_irq(struct sde_encoder_phys *phys_enc, } cmd_enc->irq_idx[idx] = sde_core_irq_idx_lookup(phys_enc->sde_kms, - intr_type, cmd_enc->hw_pp->idx); + intr_type, phys_enc->hw_pp->idx); if (cmd_enc->irq_idx[idx] < 0) { SDE_ERROR_CMDENC(cmd_enc, "failed to lookup IRQ index for %s with pp=%d\n", irq_name, - cmd_enc->hw_pp->idx - PINGPONG_0); + phys_enc->hw_pp->idx - PINGPONG_0); return -EINVAL; } @@ -205,7 +188,7 @@ static int sde_encoder_phys_cmd_register_irq(struct sde_encoder_phys *phys_enc, SDE_ERROR_CMDENC(cmd_enc, "failed to enable IRQ for %s, pp %d, irq_idx %d\n", irq_name, - cmd_enc->hw_pp->idx - PINGPONG_0, + phys_enc->hw_pp->idx - PINGPONG_0, cmd_enc->irq_idx[idx]); cmd_enc->irq_idx[idx] = -EINVAL; @@ -217,7 +200,7 @@ static int sde_encoder_phys_cmd_register_irq(struct sde_encoder_phys *phys_enc, SDE_DEBUG_CMDENC(cmd_enc, "registered IRQ %s for pp %d, irq_idx %d\n", irq_name, - cmd_enc->hw_pp->idx - PINGPONG_0, + phys_enc->hw_pp->idx - PINGPONG_0, cmd_enc->irq_idx[idx]); return ret; @@ -239,7 +222,7 @@ static int sde_encoder_phys_cmd_unregister_irq( cmd_enc->irq_idx[idx], &cmd_enc->irq_cb[idx]); SDE_DEBUG_CMDENC(cmd_enc, "unregistered IRQ for pp %d, irq_idx %d\n", - cmd_enc->hw_pp->idx - PINGPONG_0, + phys_enc->hw_pp->idx - PINGPONG_0, cmd_enc->irq_idx[idx]); return 0; @@ -262,10 +245,10 @@ static void sde_encoder_phys_cmd_tearcheck_config( return; } - SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", cmd_enc->hw_pp->idx - PINGPONG_0); + SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); - if (!cmd_enc->hw_pp->ops.setup_tearcheck || - !cmd_enc->hw_pp->ops.enable_tearcheck) { + if (!phys_enc->hw_pp->ops.setup_tearcheck || + !phys_enc->hw_pp->ops.enable_tearcheck) { SDE_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); return; } @@ -304,23 +287,23 @@ static void sde_encoder_phys_cmd_tearcheck_config( SDE_DEBUG_CMDENC(cmd_enc, "tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n", - cmd_enc->hw_pp->idx - PINGPONG_0, vsync_hz, + phys_enc->hw_pp->idx - PINGPONG_0, vsync_hz, mode->vtotal, mode->vrefresh); SDE_DEBUG_CMDENC(cmd_enc, "tc %d enable %u start_pos %u rd_ptr_irq %u\n", - cmd_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos, + phys_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos, tc_cfg.rd_ptr_irq); SDE_DEBUG_CMDENC(cmd_enc, "tc %d hw_vsync_mode %u vsync_count %u vsync_init_val %u\n", - cmd_enc->hw_pp->idx - PINGPONG_0, tc_cfg.hw_vsync_mode, + phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.hw_vsync_mode, tc_cfg.vsync_count, tc_cfg.vsync_init_val); SDE_DEBUG_CMDENC(cmd_enc, "tc %d cfgheight %u thresh_start %u thresh_cont %u\n", - cmd_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height, + phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height, tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue); - cmd_enc->hw_pp->ops.setup_tearcheck(cmd_enc->hw_pp, &tc_cfg); - cmd_enc->hw_pp->ops.enable_tearcheck(cmd_enc->hw_pp, tc_enable); + phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg); + phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable); } static void sde_encoder_phys_cmd_pingpong_config( @@ -337,7 +320,7 @@ static void sde_encoder_phys_cmd_pingpong_config( } SDE_DEBUG_CMDENC(cmd_enc, "pp %d, enabling mode:\n", - cmd_enc->hw_pp->idx - PINGPONG_0); + phys_enc->hw_pp->idx - PINGPONG_0); drm_mode_debug_printmodeline(&phys_enc->cached_mode); intf_cfg.intf = cmd_enc->intf_idx; @@ -444,7 +427,7 @@ static void sde_encoder_phys_cmd_enable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder\n"); return; } - SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", cmd_enc->hw_pp->idx - PINGPONG_0); + SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); if (WARN_ON(phys_enc->enable_state == SDE_ENC_ENABLED)) return; @@ -506,7 +489,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc) SDE_ERROR("invalid encoder\n"); return; } - SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", cmd_enc->hw_pp->idx - PINGPONG_0); + SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); if (WARN_ON(phys_enc->enable_state == SDE_ENC_DISABLED)) return; @@ -578,7 +561,7 @@ static void sde_encoder_phys_cmd_prepare_for_kickoff( SDE_ERROR("invalid encoder\n"); return; } - SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", cmd_enc->hw_pp->idx - PINGPONG_0); + SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); /* * Mark kickoff request as outstanding. If there are more than one, @@ -590,9 +573,9 @@ static void sde_encoder_phys_cmd_prepare_for_kickoff( if (*need_to_wait) SDE_DEBUG_CMDENC(cmd_enc, "pp %d needs to wait, new_pending_cnt %d", - cmd_enc->hw_pp->idx - PINGPONG_0, + phys_enc->hw_pp->idx - PINGPONG_0, new_pending_cnt); - MSM_EVT(DEV(phys_enc), cmd_enc->hw_pp->idx, new_pending_cnt); + MSM_EVT(DEV(phys_enc), phys_enc->hw_pp->idx, new_pending_cnt); } static void sde_encoder_phys_cmd_init_ops( |
