summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@quicinc.com>2016-11-10 16:10:11 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-11-10 16:10:11 -0800
commitdf7f0f85bba2e37c34bda12ea948919a7f70ff50 (patch)
tree41eea5d054e82543b35ea3351c23875e0cbc7a39 /drivers/gpu
parent36cc5dffb56678f6081a98ed5eb54aadb7592bc2 (diff)
parentb8811d64d847539dca50833e9159ec897e01868e (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.c20
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys.h4
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c59
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(