summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/disp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/disp')
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c26
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c4
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c27
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c4
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c27
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c154
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h18
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h88
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c56
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h37
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c3
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c11
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h8
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c94
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h68
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h1
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c4
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c22
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h1
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c47
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h2
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c34
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h1
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c2
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c1
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c8
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c7
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c11
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c15
-rw-r--r--drivers/gpu/drm/msm/disp/mdp_kms.h9
33 files changed, 543 insertions, 253 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 393858ef8a83..b6b3bbab0333 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -22,6 +22,7 @@
* @DPU_PERF_MODE_NORMAL: performance controlled by user mode client
* @DPU_PERF_MODE_MINIMUM: performance bounded by minimum setting
* @DPU_PERF_MODE_FIXED: performance bounded by fixed setting
+ * @DPU_PERF_MODE_MAX: maximum value, used for error checking
*/
enum dpu_perf_mode {
DPU_PERF_MODE_NORMAL,
@@ -31,9 +32,9 @@ enum dpu_perf_mode {
};
/**
- * @_dpu_core_perf_calc_bw() - to calculate BW per crtc
- * @kms - pointer to the dpu_kms
- * @crtc - pointer to a crtc
+ * _dpu_core_perf_calc_bw() - to calculate BW per crtc
+ * @kms: pointer to the dpu_kms
+ * @crtc: pointer to a crtc
* Return: returns aggregated BW for all planes in crtc.
*/
static u64 _dpu_core_perf_calc_bw(struct dpu_kms *kms,
@@ -63,9 +64,9 @@ static u64 _dpu_core_perf_calc_bw(struct dpu_kms *kms,
/**
* _dpu_core_perf_calc_clk() - to calculate clock per crtc
- * @kms - pointer to the dpu_kms
- * @crtc - pointer to a crtc
- * @state - pointer to a crtc state
+ * @kms: pointer to the dpu_kms
+ * @crtc: pointer to a crtc
+ * @state: pointer to a crtc state
* Return: returns max clk for all planes in crtc.
*/
static u64 _dpu_core_perf_calc_clk(struct dpu_kms *kms,
@@ -110,14 +111,11 @@ static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms,
struct drm_crtc_state *state,
struct dpu_core_perf_params *perf)
{
- struct dpu_crtc_state *dpu_cstate;
-
if (!kms || !kms->catalog || !crtc || !state || !perf) {
DPU_ERROR("invalid parameters\n");
return;
}
- dpu_cstate = to_dpu_crtc_state(state);
memset(perf, 0, sizeof(struct dpu_core_perf_params));
if (kms->perf.perf_tune.mode == DPU_PERF_MODE_MINIMUM) {
@@ -219,9 +217,6 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
int i, ret = 0;
u64 avg_bw;
- if (!kms->num_paths)
- return -EINVAL;
-
drm_for_each_crtc(tmp_crtc, crtc->dev) {
if (tmp_crtc->enabled &&
curr_client_type ==
@@ -239,6 +234,9 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
}
}
+ if (!kms->num_paths)
+ return 0;
+
avg_bw = perf.bw_ctl;
do_div(avg_bw, (kms->num_paths * 1000)); /*Bps_to_icc*/
@@ -249,8 +247,8 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
}
/**
- * @dpu_core_perf_crtc_release_bw() - request zero bandwidth
- * @crtc - pointer to a crtc
+ * dpu_core_perf_crtc_release_bw() - request zero bandwidth
+ * @crtc: pointer to a crtc
*
* Function checks a state variable for the crtc, if all pending commit
* requests are done, meaning no more bandwidth is needed, release
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e55be2922c2f..56eb22554197 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -845,7 +845,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
}
mode = &crtc_state->adjusted_mode;
- DPU_DEBUG("%s: check", dpu_crtc->name);
+ DPU_DEBUG("%s: check\n", dpu_crtc->name);
/* force a full mode set if active state changed */
if (crtc_state->active_changed)
@@ -953,7 +953,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
}
pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
- DPU_DEBUG("%s: zpos %d", dpu_crtc->name, z_pos);
+ DPU_DEBUG("%s: zpos %d\n", dpu_crtc->name, z_pos);
}
for (i = 0; i < multirect_count; i++) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index f7f5c258b553..288e95ee8e1d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -132,9 +132,10 @@ enum dpu_enc_rc_states {
* @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.
+ * @cur_slave: As above but for the slave encoder.
+ * @hw_pp: Handle to the pingpong blocks used for the display. No.
* pingpong blocks can be different than num_phys_encs.
- * @intfs_swapped Whether or not the phys_enc interfaces have been swapped
+ * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
* for partial update right-only cases, such as pingpong
* split where virtual pingpong does not generate IRQs
* @crtc: Pointer to the currently assigned crtc. Normally you
@@ -973,12 +974,11 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
struct drm_crtc *drm_crtc;
struct dpu_crtc_state *cstate;
struct dpu_global_state *global_state;
- struct msm_display_topology topology;
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
- int num_lm, num_ctl, num_pp, num_dspp;
+ int num_lm, num_ctl, num_pp;
int i, j;
if (!drm_enc) {
@@ -1020,8 +1020,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
if (drm_crtc->state->encoder_mask & drm_encoder_mask(drm_enc))
break;
- topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
-
/* Query resource that have been reserved in atomic check step. */
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp,
@@ -1030,7 +1028,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
- num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
@@ -1096,7 +1094,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc = NULL;
- struct msm_drm_private *priv;
int i;
if (!drm_enc || !drm_enc->dev) {
@@ -1104,8 +1101,6 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
return;
}
- priv = drm_enc->dev->dev_private;
-
dpu_enc = to_dpu_encoder_virt(drm_enc);
if (!dpu_enc || !dpu_enc->cur_master) {
DPU_ERROR("invalid dpu encoder/master\n");
@@ -1207,7 +1202,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc = NULL;
struct msm_drm_private *priv;
- struct dpu_kms *dpu_kms;
int i = 0;
if (!drm_enc) {
@@ -1225,7 +1219,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
dpu_enc->enabled = false;
priv = drm_enc->dev->dev_private;
- dpu_kms = to_dpu_kms(priv->kms);
trace_dpu_enc_disable(DRMID(drm_enc));
@@ -1444,9 +1437,9 @@ static void dpu_encoder_off_work(struct work_struct *work)
/**
* _dpu_encoder_trigger_flush - trigger flush for a physical encoder
- * drm_enc: Pointer to drm encoder structure
- * phys: Pointer to physical encoder structure
- * extra_flush_bits: Additional bit mask to include in flush trigger
+ * @drm_enc: Pointer to drm encoder structure
+ * @phys: Pointer to physical encoder structure
+ * @extra_flush_bits: Additional bit mask to include in flush trigger
*/
static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phys, uint32_t extra_flush_bits)
@@ -1483,7 +1476,7 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc,
/**
* _dpu_encoder_trigger_start - trigger start for a physical encoder
- * phys: Pointer to physical encoder structure
+ * @phys: Pointer to physical encoder structure
*/
static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys)
{
@@ -1566,7 +1559,7 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc)
* encoder rather than the individual physical ones in order to handle
* use cases that require visibility into multiple physical encoders at
* a time.
- * dpu_enc: Pointer to virtual encoder structure
+ * @dpu_enc: Pointer to virtual encoder structure
*/
static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc)
{
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 8493d68ad841..5a056c1191df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -437,7 +437,6 @@ static void dpu_encoder_phys_cmd_enable_helper(
struct dpu_encoder_phys *phys_enc)
{
struct dpu_hw_ctl *ctl;
- u32 flush_mask = 0;
if (!phys_enc->hw_pp) {
DPU_ERROR("invalid arg(s), encoder %d\n", phys_enc != NULL);
@@ -452,8 +451,7 @@ static void dpu_encoder_phys_cmd_enable_helper(
return;
ctl = phys_enc->hw_ctl;
- ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->intf_idx);
- ctl->ops.update_pending_flush(ctl, flush_mask);
+ ctl->ops.update_pending_flush_intf(ctl, phys_enc->intf_idx);
}
static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 805e059b50b7..9a69fad832cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -5,6 +5,7 @@
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
#include "dpu_encoder_phys.h"
#include "dpu_hw_interrupts.h"
+#include "dpu_hw_merge3d.h"
#include "dpu_core_irq.h"
#include "dpu_formats.h"
#include "dpu_trace.h"
@@ -282,6 +283,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
intf_cfg.stream_sel = 0; /* Don't care value for video mode */
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+ if (phys_enc->hw_pp->merge_3d)
+ intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->id;
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
@@ -295,6 +298,12 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
true,
phys_enc->hw_pp->idx);
+ if (phys_enc->hw_pp->merge_3d) {
+ struct dpu_hw_merge_3d *merge_3d = to_dpu_hw_merge_3d(phys_enc->hw_pp->merge_3d);
+
+ merge_3d->ops.setup_3d_mode(merge_3d, intf_cfg.mode_3d);
+ }
+
spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
programmable_fetch_config(phys_enc, &timing_params);
@@ -429,8 +438,6 @@ end:
static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
{
struct dpu_hw_ctl *ctl;
- u32 flush_mask = 0;
- u32 intf_flush_mask = 0;
ctl = phys_enc->hw_ctl;
@@ -452,20 +459,14 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
!dpu_encoder_phys_vid_is_master(phys_enc))
goto skip_flush;
- ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->hw_intf->idx);
- ctl->ops.update_pending_flush(ctl, flush_mask);
-
- if (ctl->ops.get_bitmask_active_intf)
- ctl->ops.get_bitmask_active_intf(ctl, &intf_flush_mask,
- phys_enc->hw_intf->idx);
-
- if (ctl->ops.update_pending_intf_flush)
- ctl->ops.update_pending_intf_flush(ctl, intf_flush_mask);
+ ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
+ if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
+ ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->id);
skip_flush:
DPU_DEBUG_VIDENC(phys_enc,
- "update pending flush ctl %d flush_mask 0%x intf_mask 0x%x\n",
- ctl->idx - CTL_0, flush_mask, intf_flush_mask);
+ "update pending flush ctl %d intf %d\n",
+ ctl->idx - CTL_0, phys_enc->hw_intf->idx);
/* ctl_flush & timing engine enable will be triggered by framework */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index a05282dede91..21ff8f9e5dfd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -22,7 +22,7 @@
#define DPU_MAX_IMG_WIDTH 0x3FFF
#define DPU_MAX_IMG_HEIGHT 0x3FFF
-/**
+/*
* DPU supported format packing, bpp, and other format
* information.
* DPU currently only supports interleaved RGB formats
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c
index ca26666d2af9..819b26e660b9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c
@@ -19,6 +19,7 @@ static LIST_HEAD(dpu_hw_blk_list);
/**
* dpu_hw_blk_init - initialize hw block object
+ * @hw_blk: pointer to hw block object
* @type: hw block type - enum dpu_hw_blk_type
* @id: instance id of the hw block
* @ops: Pointer to block operations
@@ -114,7 +115,6 @@ error_start:
/**
* dpu_hw_blk_put - put hw_blk to free pool if decremented refcount is zero
* @hw_blk: hw block to be freed
- * @free_blk: function to be called when reference count goes to zero
*/
void dpu_hw_blk_put(struct dpu_hw_blk *hw_blk)
{
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 60b304b72b7c..90393fe9e59c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -8,7 +8,6 @@
#include <linux/platform_device.h>
#include "dpu_hw_mdss.h"
#include "dpu_hw_catalog.h"
-#include "dpu_hw_catalog_format.h"
#include "dpu_kms.h"
#define VIG_MASK \
@@ -41,6 +40,8 @@
#define PINGPONG_SDM845_SPLIT_MASK \
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
+#define MERGE_3D_SM8150_MASK (0)
+
#define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
#define INTF_SDM845_MASK (0)
@@ -60,6 +61,79 @@
#define STRCAT(X, Y) (X Y)
+static const uint32_t plane_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_ABGR1555,
+ DRM_FORMAT_RGBA5551,
+ DRM_FORMAT_BGRA5551,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_XBGR1555,
+ DRM_FORMAT_RGBX5551,
+ DRM_FORMAT_BGRX5551,
+ DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_ABGR4444,
+ DRM_FORMAT_RGBA4444,
+ DRM_FORMAT_BGRA4444,
+ DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_XBGR4444,
+ DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_BGRX4444,
+};
+
+static const uint32_t plane_formats_yuv[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_ABGR1555,
+ DRM_FORMAT_RGBA5551,
+ DRM_FORMAT_BGRA5551,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_XBGR1555,
+ DRM_FORMAT_RGBX5551,
+ DRM_FORMAT_BGRX5551,
+ DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_ABGR4444,
+ DRM_FORMAT_RGBA4444,
+ DRM_FORMAT_BGRA4444,
+ DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_XBGR4444,
+ DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_BGRX4444,
+
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_VYUY,
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_YVYU,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YVU420,
+};
+
/*************************************************************
* DPU sub blocks config
*************************************************************/
@@ -111,7 +185,6 @@ static const struct dpu_caps sm8150_dpu_caps = {
static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
- .max_linewidth = 4096,
.qseed_type = DPU_SSPP_SCALER_QSEED3, /* TODO: qseed3 lite */
.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
@@ -433,9 +506,9 @@ static const struct dpu_lm_cfg sc7180_lm[] = {
static const struct dpu_lm_cfg sm8150_lm[] = {
LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
+ &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
- &sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
+ &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1),
LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
&sdm845_lm_sblk, PINGPONG_2, LM_3, 0),
LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK,
@@ -454,16 +527,28 @@ static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = {
.len = 0x90, .version = 0x10000},
};
-#define DSPP_BLK(_name, _id, _base) \
+static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = {
+ .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
+ .len = 0x90, .version = 0x40000},
+};
+
+#define DSPP_BLK(_name, _id, _base, _sblk) \
{\
.name = _name, .id = _id, \
.base = _base, .len = 0x1800, \
.features = DSPP_SC7180_MASK, \
- .sblk = &sc7180_dspp_sblk \
+ .sblk = _sblk \
}
static const struct dpu_dspp_cfg sc7180_dspp[] = {
- DSPP_BLK("dspp_0", DSPP_0, 0x54000),
+ DSPP_BLK("dspp_0", DSPP_0, 0x54000, &sc7180_dspp_sblk),
+};
+
+static const struct dpu_dspp_cfg sm8150_dspp[] = {
+ DSPP_BLK("dspp_0", DSPP_0, 0x54000, &sm8150_dspp_sblk),
+ DSPP_BLK("dspp_1", DSPP_1, 0x56000, &sm8150_dspp_sblk),
+ DSPP_BLK("dspp_2", DSPP_2, 0x58000, &sm8150_dspp_sblk),
+ DSPP_BLK("dspp_3", DSPP_3, 0x5a000, &sm8150_dspp_sblk),
};
/*************************************************************
@@ -481,40 +566,59 @@ static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
.len = 0x20, .version = 0x10000},
};
-#define PP_BLK_TE(_name, _id, _base) \
+#define PP_BLK_TE(_name, _id, _base, _merge_3d) \
{\
.name = _name, .id = _id, \
.base = _base, .len = 0xd4, \
.features = PINGPONG_SDM845_SPLIT_MASK, \
+ .merge_3d = _merge_3d, \
.sblk = &sdm845_pp_sblk_te \
}
-#define PP_BLK(_name, _id, _base) \
+#define PP_BLK(_name, _id, _base, _merge_3d) \
{\
.name = _name, .id = _id, \
.base = _base, .len = 0xd4, \
.features = PINGPONG_SDM845_MASK, \
+ .merge_3d = _merge_3d, \
.sblk = &sdm845_pp_sblk \
}
static const struct dpu_pingpong_cfg sdm845_pp[] = {
- PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
- PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
- PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
- PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0),
};
static struct dpu_pingpong_cfg sc7180_pp[] = {
- PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
- PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0),
};
static const struct dpu_pingpong_cfg sm8150_pp[] = {
- PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
- PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
- PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
- PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
- PP_BLK("pingpong_4", PINGPONG_4, 0x72000),
- PP_BLK("pingpong_5", PINGPONG_5, 0x72800),
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1),
+ PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2),
+ PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2),
+};
+
+/*************************************************************
+ * MERGE_3D sub blocks config
+ *************************************************************/
+#define MERGE_3D_BLK(_name, _id, _base) \
+ {\
+ .name = _name, .id = _id, \
+ .base = _base, .len = 0x100, \
+ .features = MERGE_3D_SM8150_MASK, \
+ .sblk = NULL \
+ }
+
+static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
+ MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x83000),
+ MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x83100),
+ MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200),
};
/*************************************************************
@@ -836,8 +940,12 @@ static void sm8150_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
.sspp = sdm845_sspp,
.mixer_count = ARRAY_SIZE(sm8150_lm),
.mixer = sm8150_lm,
+ .dspp_count = ARRAY_SIZE(sm8150_dspp),
+ .dspp = sm8150_dspp,
.pingpong_count = ARRAY_SIZE(sm8150_pp),
.pingpong = sm8150_pp,
+ .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
+ .merge_3d = sm8150_merge_3d,
.intf_count = ARRAY_SIZE(sm8150_intf),
.intf = sm8150_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
@@ -866,8 +974,12 @@ static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
.sspp = sdm845_sspp,
.mixer_count = ARRAY_SIZE(sm8150_lm),
.mixer = sm8150_lm,
+ .dspp_count = ARRAY_SIZE(sm8150_dspp),
+ .dspp = sm8150_dspp,
.pingpong_count = ARRAY_SIZE(sm8150_pp),
.pingpong = sm8150_pp,
+ .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
+ .merge_3d = sm8150_merge_3d,
.intf_count = ARRAY_SIZE(sm8150_intf),
.intf = sm8150_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 3544af1a45c5..eaef99db2d2f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -524,10 +524,24 @@ struct dpu_dspp_cfg {
*/
struct dpu_pingpong_cfg {
DPU_HW_BLK_INFO;
+ u32 merge_3d;
const struct dpu_pingpong_sub_blks *sblk;
};
/**
+ * struct dpu_merge_3d_cfg - information of DSPP blocks
+ * @id enum identifying this block
+ * @base register offset of this block
+ * @features bit mask identifying sub-blocks/features
+ * supported by this block
+ * @sblk sub-blocks information
+ */
+struct dpu_merge_3d_cfg {
+ DPU_HW_BLK_INFO;
+ const struct dpu_merge_3d_sub_blks *sblk;
+};
+
+/**
* struct dpu_intf_cfg - information of timing engine blocks
* @id enum identifying this block
* @base register offset of this block
@@ -724,6 +738,9 @@ struct dpu_mdss_cfg {
u32 pingpong_count;
const struct dpu_pingpong_cfg *pingpong;
+ u32 merge_3d_count;
+ const struct dpu_merge_3d_cfg *merge_3d;
+
u32 intf_count;
const struct dpu_intf_cfg *intf;
@@ -767,6 +784,7 @@ struct dpu_mdss_hw_cfg_handler {
#define BLK_INTF(s) ((s)->intf)
#define BLK_AD(s) ((s)->ad)
#define BLK_DSPP(s) ((s)->dspp)
+#define BLK_MERGE3d(s) ((s)->merge_3d)
/**
* dpu_hw_catalog_init - dpu hardware catalog init API retrieves
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h
deleted file mode 100644
index 3766f0fd0bf0..000000000000
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- */
-
-#include "dpu_hw_mdss.h"
-
-static const uint32_t qcom_compressed_supported_formats[] = {
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_BGR565,
-
- DRM_FORMAT_NV12,
-};
-
-static const uint32_t plane_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGBX8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_ABGR1555,
- DRM_FORMAT_RGBA5551,
- DRM_FORMAT_BGRA5551,
- DRM_FORMAT_XRGB1555,
- DRM_FORMAT_XBGR1555,
- DRM_FORMAT_RGBX5551,
- DRM_FORMAT_BGRX5551,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_ABGR4444,
- DRM_FORMAT_RGBA4444,
- DRM_FORMAT_BGRA4444,
- DRM_FORMAT_XRGB4444,
- DRM_FORMAT_XBGR4444,
- DRM_FORMAT_RGBX4444,
- DRM_FORMAT_BGRX4444,
-};
-
-static const uint32_t plane_formats_yuv[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGBX8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_ABGR1555,
- DRM_FORMAT_RGBA5551,
- DRM_FORMAT_BGRA5551,
- DRM_FORMAT_XRGB1555,
- DRM_FORMAT_XBGR1555,
- DRM_FORMAT_RGBX5551,
- DRM_FORMAT_BGRX5551,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_ABGR4444,
- DRM_FORMAT_RGBA4444,
- DRM_FORMAT_BGRA4444,
- DRM_FORMAT_XRGB4444,
- DRM_FORMAT_XBGR4444,
- DRM_FORMAT_RGBX4444,
- DRM_FORMAT_BGRX4444,
-
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV61,
- DRM_FORMAT_VYUY,
- DRM_FORMAT_UYVY,
- DRM_FORMAT_YUYV,
- DRM_FORMAT_YVYU,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YVU420,
-};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 758c355b4fd8..8981cfa9dbc3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -22,7 +22,9 @@
#define CTL_PREPARE 0x0d0
#define CTL_SW_RESET 0x030
#define CTL_LAYER_EXTN_OFFSET 0x40
+#define CTL_MERGE_3D_ACTIVE 0x0E4
#define CTL_INTF_ACTIVE 0x0F4
+#define CTL_MERGE_3D_FLUSH 0x100
#define CTL_INTF_FLUSH 0x110
#define CTL_INTF_MASTER 0x134
@@ -30,6 +32,7 @@
#define CTL_FLUSH_MASK_CTL BIT(17)
#define DPU_REG_RESET_TIMEOUT_US 2000
+#define MERGE_3D_IDX 23
#define INTF_IDX 31
static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl,
@@ -104,12 +107,6 @@ static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
ctx->pending_flush_mask |= flushbits;
}
-static inline void dpu_hw_ctl_update_pending_intf_flush(struct dpu_hw_ctl *ctx,
- u32 flushbits)
-{
- ctx->pending_intf_flush_mask |= flushbits;
-}
-
static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
{
return ctx->pending_flush_mask;
@@ -118,6 +115,9 @@ static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
{
+ if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX))
+ DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH,
+ ctx->pending_merge_3d_flush_mask);
if (ctx->pending_flush_mask & BIT(INTF_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH,
ctx->pending_intf_flush_mask);
@@ -220,40 +220,39 @@ static uint32_t dpu_hw_ctl_get_bitmask_mixer(struct dpu_hw_ctl *ctx,
return flushbits;
}
-static int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx,
- u32 *flushbits, enum dpu_intf intf)
+static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
+ enum dpu_intf intf)
{
switch (intf) {
case INTF_0:
- *flushbits |= BIT(31);
+ ctx->pending_flush_mask |= BIT(31);
break;
case INTF_1:
- *flushbits |= BIT(30);
+ ctx->pending_flush_mask |= BIT(30);
break;
case INTF_2:
- *flushbits |= BIT(29);
+ ctx->pending_flush_mask |= BIT(29);
break;
case INTF_3:
- *flushbits |= BIT(28);
+ ctx->pending_flush_mask |= BIT(28);
break;
default:
- return -EINVAL;
+ break;
}
- return 0;
}
-static int dpu_hw_ctl_get_bitmask_intf_v1(struct dpu_hw_ctl *ctx,
- u32 *flushbits, enum dpu_intf intf)
+static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx,
+ enum dpu_intf intf)
{
- *flushbits |= BIT(31);
- return 0;
+ ctx->pending_intf_flush_mask |= BIT(intf - INTF_0);
+ ctx->pending_flush_mask |= BIT(INTF_IDX);
}
-static int dpu_hw_ctl_active_get_bitmask_intf(struct dpu_hw_ctl *ctx,
- u32 *flushbits, enum dpu_intf intf)
+static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
+ enum dpu_merge_3d merge_3d)
{
- *flushbits |= BIT(intf - INTF_0);
- return 0;
+ ctx->pending_merge_3d_flush_mask |= BIT(merge_3d - MERGE_3D_0);
+ ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
}
static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
@@ -497,6 +496,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
DPU_REG_WRITE(c, CTL_TOP, mode_sel);
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
+ DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0));
}
static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
@@ -535,15 +535,15 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
if (cap & BIT(DPU_CTL_ACTIVE_CFG)) {
ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1;
- ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf_v1;
- ops->get_bitmask_active_intf =
- dpu_hw_ctl_active_get_bitmask_intf;
- ops->update_pending_intf_flush =
- dpu_hw_ctl_update_pending_intf_flush;
+ ops->update_pending_flush_intf =
+ dpu_hw_ctl_update_pending_flush_intf_v1;
+ ops->update_pending_flush_merge_3d =
+ dpu_hw_ctl_update_pending_flush_merge_3d_v1;
} else {
ops->trigger_flush = dpu_hw_ctl_trigger_flush;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
- ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf;
+ ops->update_pending_flush_intf =
+ dpu_hw_ctl_update_pending_flush_intf;
}
ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush;
ops->update_pending_flush = dpu_hw_ctl_update_pending_flush;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index ec579b470a80..e93a42ab60b1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -37,12 +37,14 @@ struct dpu_hw_stage_cfg {
* struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface
* @intf : Interface id
* @mode_3d: 3d mux configuration
+ * @merge_3d: 3d merge block used
* @intf_mode_sel: Interface mode, cmd / vid
* @stream_sel: Stream selection for multi-stream interfaces
*/
struct dpu_hw_intf_cfg {
enum dpu_intf intf;
enum dpu_3d_blend_mode mode_3d;
+ enum dpu_merge_3d merge_3d;
enum dpu_ctl_mode_sel intf_mode_sel;
int stream_sel;
};
@@ -91,13 +93,22 @@ struct dpu_hw_ctl_ops {
u32 flushbits);
/**
- * OR in the given flushbits to the cached pending_intf_flush_mask
+ * OR in the given flushbits to the cached pending_(intf_)flush_mask
* No effect on hardware
* @ctx : ctl path ctx pointer
- * @flushbits : module flushmask
+ * @blk : interface block index
*/
- void (*update_pending_intf_flush)(struct dpu_hw_ctl *ctx,
- u32 flushbits);
+ void (*update_pending_flush_intf)(struct dpu_hw_ctl *ctx,
+ enum dpu_intf blk);
+
+ /**
+ * OR in the given flushbits to the cached pending_(merge_3d_)flush_mask
+ * No effect on hardware
+ * @ctx : ctl path ctx pointer
+ * @blk : interface block index
+ */
+ void (*update_pending_flush_merge_3d)(struct dpu_hw_ctl *ctx,
+ enum dpu_merge_3d blk);
/**
* Write the value of the pending_flush_mask to hardware
@@ -143,23 +154,6 @@ struct dpu_hw_ctl_ops {
enum dpu_dspp blk);
/**
- * Query the value of the intf flush mask
- * No effect on hardware
- * @ctx : ctl path ctx pointer
- */
- int (*get_bitmask_intf)(struct dpu_hw_ctl *ctx,
- u32 *flushbits,
- enum dpu_intf blk);
-
- /**
- * Query the value of the intf active flush mask
- * No effect on hardware
- * @ctx : ctl path ctx pointer
- */
- int (*get_bitmask_active_intf)(struct dpu_hw_ctl *ctx,
- u32 *flushbits, enum dpu_intf blk);
-
- /**
* Set all blend stages to disabled
* @ctx : ctl path ctx pointer
*/
@@ -198,6 +192,7 @@ struct dpu_hw_ctl {
const struct dpu_lm_cfg *mixer_hw_caps;
u32 pending_flush_mask;
u32 pending_intf_flush_mask;
+ u32 pending_merge_3d_flush_mask;
/* ops */
struct dpu_hw_ctl_ops ops;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
index a7a24539921f..e42f901a7de5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c
@@ -57,8 +57,7 @@ static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx,
static void _setup_dspp_ops(struct dpu_hw_dspp *c,
unsigned long features)
{
- if (test_bit(DPU_DSPP_PCC, &features) &&
- IS_SC7180_TARGET(c->hw.hwversion))
+ if (test_bit(DPU_DSPP_PCC, &features))
c->ops.setup_pcc = dpu_setup_dspp_pcc;
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index d84a84f7fe1a..5c521de71567 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -189,8 +189,8 @@ struct dpu_irq_type {
u32 reg_idx;
};
-/**
- * List of DPU interrupt registers
+/*
+ * struct dpu_intr_reg - List of DPU interrupt registers
*/
static const struct dpu_intr_reg dpu_intr_set[] = {
{
@@ -245,9 +245,10 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
}
};
-/**
- * IRQ mapping table - use for lookup an irq_idx in this table that have
- * a matching interface type and instance index.
+/*
+ * struct dpu_irq_type - IRQ mapping table use for lookup an irq_idx in this
+ * table that have a matching interface type and
+ * instance index.
*/
static const struct dpu_irq_type dpu_irq_map[] = {
/* BEGIN MAP_RANGE: 0-31, INTR */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c
index 4b8baf71423f..6ac0b5a0e057 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c
@@ -48,7 +48,7 @@ static const struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer,
/**
* _stage_offset(): returns the relative offset of the blend registers
* for the stage to be setup
- * @c: mixer ctx contains the mixer to be programmed
+ * @ctx: mixer ctx contains the mixer to be programmed
* @stage: stage index to setup
*/
static inline int _stage_offset(struct dpu_hw_mixer *ctx, enum dpu_stage stage)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 979fd2c60aa0..09a3fb3e89f5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -96,6 +96,7 @@ enum dpu_hw_blk_type {
DPU_HW_BLK_INTF,
DPU_HW_BLK_WB,
DPU_HW_BLK_DSPP,
+ DPU_HW_BLK_MERGE_3D,
DPU_HW_BLK_MAX,
};
@@ -186,6 +187,13 @@ enum dpu_pingpong {
PINGPONG_MAX
};
+enum dpu_merge_3d {
+ MERGE_3D_0 = 1,
+ MERGE_3D_1,
+ MERGE_3D_2,
+ MERGE_3D_MAX
+};
+
enum dpu_intf {
INTF_0 = 1,
INTF_1,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c
new file mode 100644
index 000000000000..720813e5a8ae
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_kms.h"
+#include "dpu_trace.h"
+
+#define MERGE_3D_MUX 0x000
+#define MERGE_3D_MODE 0x004
+
+static const struct dpu_merge_3d_cfg *_merge_3d_offset(enum dpu_merge_3d idx,
+ const struct dpu_mdss_cfg *m,
+ void __iomem *addr,
+ struct dpu_hw_blk_reg_map *b)
+{
+ int i;
+
+ for (i = 0; i < m->merge_3d_count; i++) {
+ if (idx == m->merge_3d[i].id) {
+ b->base_off = addr;
+ b->blk_off = m->merge_3d[i].base;
+ b->length = m->merge_3d[i].len;
+ b->hwversion = m->hwversion;
+ b->log_mask = DPU_DBG_MASK_PINGPONG;
+ return &m->merge_3d[i];
+ }
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+static void dpu_hw_merge_3d_setup_3d_mode(struct dpu_hw_merge_3d *merge_3d,
+ enum dpu_3d_blend_mode mode_3d)
+{
+ struct dpu_hw_blk_reg_map *c;
+ u32 data;
+
+
+ c = &merge_3d->hw;
+ if (mode_3d == BLEND_3D_NONE) {
+ DPU_REG_WRITE(c, MERGE_3D_MODE, 0);
+ DPU_REG_WRITE(c, MERGE_3D_MUX, 0);
+ } else {
+ data = BIT(0) | ((mode_3d - 1) << 1);
+ DPU_REG_WRITE(c, MERGE_3D_MODE, data);
+ }
+}
+
+static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c,
+ unsigned long features)
+{
+ c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode;
+};
+
+static struct dpu_hw_blk_ops dpu_hw_ops;
+
+struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(enum dpu_merge_3d idx,
+ void __iomem *addr,
+ const struct dpu_mdss_cfg *m)
+{
+ struct dpu_hw_merge_3d *c;
+ const struct dpu_merge_3d_cfg *cfg;
+
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
+ if (!c)
+ return ERR_PTR(-ENOMEM);
+
+ cfg = _merge_3d_offset(idx, m, addr, &c->hw);
+ if (IS_ERR_OR_NULL(cfg)) {
+ kfree(c);
+ return ERR_PTR(-EINVAL);
+ }
+
+ c->idx = idx;
+ c->caps = cfg;
+ _setup_merge_3d_ops(c, c->caps->features);
+
+ dpu_hw_blk_init(&c->base, DPU_HW_BLK_MERGE_3D, idx, &dpu_hw_ops);
+
+ return c;
+}
+
+void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *hw)
+{
+ if (hw)
+ dpu_hw_blk_destroy(&hw->base);
+ kfree(hw);
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h
new file mode 100644
index 000000000000..870bdb14613e
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_MERGE3D_H
+#define _DPU_HW_MERGE3D_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_blk.h"
+
+struct dpu_hw_merge_3d;
+
+/**
+ *
+ * struct dpu_hw_merge_3d_ops : Interface to the merge_3d Hw driver functions
+ * Assumption is these functions will be called after clocks are enabled
+ * @setup_3d_mode : enable 3D merge
+ */
+struct dpu_hw_merge_3d_ops {
+ void (*setup_3d_mode)(struct dpu_hw_merge_3d *merge_3d,
+ enum dpu_3d_blend_mode mode_3d);
+
+};
+
+struct dpu_hw_merge_3d {
+ struct dpu_hw_blk base;
+ struct dpu_hw_blk_reg_map hw;
+
+ /* merge_3d */
+ enum dpu_merge_3d idx;
+ const struct dpu_merge_3d_cfg *caps;
+
+ /* ops */
+ struct dpu_hw_merge_3d_ops ops;
+};
+
+/**
+ * to_dpu_hw_merge_3d - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw)
+{
+ return container_of(hw, struct dpu_hw_merge_3d, base);
+}
+
+/**
+ * dpu_hw_merge_3d_init - initializes the merge_3d driver for the passed
+ * merge_3d idx.
+ * @idx: Pingpong index for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * @m: Pointer to mdss catalog data
+ * Returns: Error code or allocated dpu_hw_merge_3d context
+ */
+struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(enum dpu_merge_3d idx,
+ void __iomem *addr,
+ const struct dpu_mdss_cfg *m);
+
+/**
+ * dpu_hw_merge_3d_destroy - destroys merge_3d driver context
+ * should be called to free the context
+ * @pp: Pointer to PP driver context returned by dpu_hw_merge_3d_init
+ */
+void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *pp);
+
+#endif /*_DPU_HW_MERGE3D_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
index 065996b3ece9..6902b9b95c8e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
@@ -119,6 +119,7 @@ struct dpu_hw_pingpong {
/* pingpong */
enum dpu_pingpong idx;
const struct dpu_pingpong_cfg *caps;
+ struct dpu_hw_blk *merge_3d;
/* ops */
struct dpu_hw_pingpong_ops ops;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index c940b69435e1..2c2ca5335aa8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -231,7 +231,7 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx, opmode);
}
-/**
+/*
* Setup source pixel format, flip,
*/
static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
@@ -437,7 +437,7 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
return dpu_hw_get_scaler3_ver(&ctx->hw, idx);
}
-/**
+/*
* dpu_hw_sspp_setup_rects()
*/
static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index d93c44f6996d..374b0e8471e6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -718,6 +718,8 @@ static void dpu_kms_destroy(struct msm_kms *kms)
dpu_kms = to_dpu_kms(kms);
_dpu_kms_hw_destroy(dpu_kms);
+
+ msm_kms_destroy(&dpu_kms->base);
}
static void _dpu_kms_set_encoder_mode(struct msm_kms *kms,
@@ -1091,12 +1093,9 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(dpu_kms->opp_table);
/* OPP table is optional */
ret = dev_pm_opp_of_add_table(dev);
- if (!ret) {
- dpu_kms->has_opp_table = true;
- } else if (ret != -ENODEV) {
+ if (ret && ret != -ENODEV) {
dev_err(dev, "invalid OPP table in device tree\n");
- dev_pm_opp_put_clkname(dpu_kms->opp_table);
- return ret;
+ goto put_clkname;
}
mp = &dpu_kms->mp;
@@ -1108,7 +1107,11 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
platform_set_drvdata(pdev, dpu_kms);
- msm_kms_init(&dpu_kms->base, &kms_funcs);
+ ret = msm_kms_init(&dpu_kms->base, &kms_funcs);
+ if (ret) {
+ DPU_ERROR("failed to init kms, ret=%d\n", ret);
+ goto err;
+ }
dpu_kms->dev = ddev;
dpu_kms->pdev = pdev;
@@ -1118,8 +1121,8 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
priv->kms = &dpu_kms->base;
return ret;
err:
- if (dpu_kms->has_opp_table)
- dev_pm_opp_of_remove_table(dev);
+ dev_pm_opp_of_remove_table(dev);
+put_clkname:
dev_pm_opp_put_clkname(dpu_kms->opp_table);
return ret;
}
@@ -1137,8 +1140,7 @@ static void dpu_unbind(struct device *dev, struct device *master, void *data)
if (dpu_kms->rpm_enabled)
pm_runtime_disable(&pdev->dev);
- if (dpu_kms->has_opp_table)
- dev_pm_opp_of_remove_table(dev);
+ dev_pm_opp_of_remove_table(dev);
dev_pm_opp_put_clkname(dpu_kms->opp_table);
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 1c0e4c0c9ffb..d6717d6672f7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -131,7 +131,6 @@ struct dpu_kms {
bool rpm_enabled;
struct opp_table *opp_table;
- bool has_opp_table;
struct dss_module_power mp;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 7ea90d25a3b6..bc0231a50132 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -19,7 +19,6 @@
#include "dpu_kms.h"
#include "dpu_formats.h"
#include "dpu_hw_sspp.h"
-#include "dpu_hw_catalog_format.h"
#include "dpu_trace.h"
#include "dpu_crtc.h"
#include "dpu_vbif.h"
@@ -63,6 +62,16 @@ enum {
#define DEFAULT_REFRESH_RATE 60
+static const uint32_t qcom_compressed_supported_formats[] = {
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_BGR565,
+
+ DRM_FORMAT_NV12,
+};
+
/**
* enum dpu_plane_qos - Different qos configurations for each pipe
*
@@ -133,7 +142,8 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
/**
* _dpu_plane_calc_bw - calculate bandwidth required for a plane
- * @Plane: Pointer to drm plane.
+ * @plane: Pointer to drm plane.
+ * @fb: Pointer to framebuffer associated with the given plane
* Result: Updates calculated bandwidth in the plane state.
* BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
* Prefill BW Equation: line src bytes * line_time
@@ -151,7 +161,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
u64 plane_bw;
u32 hw_latency_lines;
u64 scale_factor;
- int vbp, vpw;
+ int vbp, vpw, vfp;
pstate = to_dpu_plane_state(plane->state);
mode = &plane->state->crtc->mode;
@@ -164,6 +174,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
fps = drm_mode_vrefresh(mode);
vbp = mode->vtotal - mode->vsync_end;
vpw = mode->vsync_end - mode->vsync_start;
+ vfp = mode->vsync_start - mode->vdisplay;
hw_latency_lines = dpu_kms->catalog->perf.min_prefill_lines;
scale_factor = src_height > dst_height ?
mult_frac(src_height, 1, dst_height) : 1;
@@ -176,14 +187,20 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
src_width * hw_latency_lines * fps * fmt->bpp *
scale_factor * mode->vtotal;
- do_div(plane_prefill_bw, (vbp+vpw));
+ if ((vbp+vpw) > hw_latency_lines)
+ do_div(plane_prefill_bw, (vbp+vpw));
+ else if ((vbp+vpw+vfp) < hw_latency_lines)
+ do_div(plane_prefill_bw, (vbp+vpw+vfp));
+ else
+ do_div(plane_prefill_bw, hw_latency_lines);
+
pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw);
}
/**
* _dpu_plane_calc_clk - calculate clock required for a plane
- * @Plane: Pointer to drm plane.
+ * @plane: Pointer to drm plane.
* Result: Updates calculated clock in the plane state.
* Clock equation: dst_w * v_total * fps * (src_h / dst_h)
*/
@@ -215,7 +232,7 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane)
* _dpu_plane_calc_fill_level - calculate fill level of the given source format
* @plane: Pointer to drm plane
* @fmt: Pointer to source buffer format
- * @src_wdith: width of source buffer
+ * @src_width: width of source buffer
* Return: fill level corresponding to the source buffer/format or 0 if error
*/
static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
@@ -937,6 +954,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
{
int ret = 0, min_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
+ struct dpu_plane_state *pstate = to_dpu_plane_state(state);
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
struct drm_rect src, dst, fb_rect = { 0 };
@@ -1009,6 +1027,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -E2BIG;
}
+ pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
+
return 0;
}
@@ -1046,6 +1066,7 @@ void dpu_plane_flush(struct drm_plane *plane)
/**
* dpu_plane_set_error: enable/disable error condition
* @plane: pointer to drm_plane structure
+ * @error: error value to set
*/
void dpu_plane_set_error(struct drm_plane *plane, bool error)
{
@@ -1066,6 +1087,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
+ bool is_rt_pipe, update_qos_remap;
const struct dpu_format *fmt =
to_dpu_format(msm_framebuffer_format(fb));
@@ -1075,7 +1097,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
pstate->pending = true;
- pdpu->is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+ is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
_dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL);
DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
@@ -1181,7 +1203,16 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
_dpu_plane_set_ot_limit(plane, crtc);
}
- _dpu_plane_set_qos_remap(plane);
+ update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
+ pstate->needs_qos_remap;
+
+ if (update_qos_remap) {
+ if (is_rt_pipe != pdpu->is_rt_pipe)
+ pdpu->is_rt_pipe = is_rt_pipe;
+ else if (pstate->needs_qos_remap)
+ pstate->needs_qos_remap = false;
+ _dpu_plane_set_qos_remap(plane);
+ }
_dpu_plane_calc_bw(plane, fb);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index ca83b8753d59..13a983fa8213 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -19,6 +19,7 @@
* @base: base drm plane state object
* @aspace: pointer to address space for input/output buffers
* @stage: assigned by crtc blender
+ * @needs_qos_remap: qos remap settings need to be updated
* @multirect_index: index of the rectangle of SSPP
* @multirect_mode: parallel or time multiplex multirect mode
* @pending: whether the current update is still pending
@@ -32,6 +33,7 @@ struct dpu_plane_state {
struct drm_plane_state base;
struct msm_gem_address_space *aspace;
enum dpu_stage stage;
+ bool needs_qos_remap;
uint32_t multirect_index;
uint32_t multirect_mode;
bool pending;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 9b2b5044e8e0..fd2d104f0a91 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -10,6 +10,7 @@
#include "dpu_hw_pingpong.h"
#include "dpu_hw_intf.h"
#include "dpu_hw_dspp.h"
+#include "dpu_hw_merge3d.h"
#include "dpu_encoder.h"
#include "dpu_trace.h"
@@ -42,6 +43,14 @@ int dpu_rm_destroy(struct dpu_rm *rm)
dpu_hw_pingpong_destroy(hw);
}
}
+ for (i = 0; i < ARRAY_SIZE(rm->merge_3d_blks); i++) {
+ struct dpu_hw_merge_3d *hw;
+
+ if (rm->merge_3d_blks[i]) {
+ hw = to_dpu_hw_merge_3d(rm->merge_3d_blks[i]);
+ dpu_hw_merge_3d_destroy(hw);
+ }
+ }
for (i = 0; i < ARRAY_SIZE(rm->mixer_blks); i++) {
struct dpu_hw_mixer *hw;
@@ -119,6 +128,24 @@ int dpu_rm_init(struct dpu_rm *rm,
}
}
+ for (i = 0; i < cat->merge_3d_count; i++) {
+ struct dpu_hw_merge_3d *hw;
+ const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i];
+
+ if (merge_3d->id < MERGE_3D_0 || merge_3d->id >= MERGE_3D_MAX) {
+ DPU_ERROR("skip merge_3d %d with invalid id\n", merge_3d->id);
+ continue;
+ }
+ hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat);
+ if (IS_ERR_OR_NULL(hw)) {
+ rc = PTR_ERR(hw);
+ DPU_ERROR("failed merge_3d object creation: err %d\n",
+ rc);
+ goto fail;
+ }
+ rm->merge_3d_blks[merge_3d->id - MERGE_3D_0] = &hw->base;
+ }
+
for (i = 0; i < cat->pingpong_count; i++) {
struct dpu_hw_pingpong *hw;
const struct dpu_pingpong_cfg *pp = &cat->pingpong[i];
@@ -134,6 +161,8 @@ int dpu_rm_init(struct dpu_rm *rm,
rc);
goto fail;
}
+ if (pp->merge_3d && pp->merge_3d < MERGE_3D_MAX)
+ hw->merge_3d = rm->merge_3d_blks[pp->merge_3d - MERGE_3D_0];
rm->pingpong_blks[pp->id - PINGPONG_0] = &hw->base;
}
@@ -210,7 +239,7 @@ static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top)
* @rm: dpu resource manager handle
* @primary_idx: index of primary mixer in rm->mixer_blks[]
* @peer_idx: index of other mixer in rm->mixer_blks[]
- * @Return: true if rm->mixer_blks[peer_idx] is a peer of
+ * Return: true if rm->mixer_blks[peer_idx] is a peer of
* rm->mixer_blks[primary_idx]
*/
static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx,
@@ -235,6 +264,7 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx,
* proposed use case requirements, incl. hardwired dependent blocks like
* pingpong
* @rm: dpu resource manager handle
+ * @global_state: resources shared across multiple kms objects
* @enc_id: encoder id requesting for allocation
* @lm_idx: index of proposed layer mixer in rm->mixer_blks[], function checks
* if lm, and all other hardwired blocks connected to the lm (pp) is
@@ -245,7 +275,7 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx,
* mixer in rm->dspp_blks[].
* @reqs: input parameter, rm requirements for HW blocks needed in the
* datapath.
- * @Return: true if lm matches all requirements, false otherwise
+ * Return: true if lm matches all requirements, false otherwise
*/
static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
struct dpu_global_state *global_state,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 08726bb1063a..1f12c8d5b8aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -29,6 +29,7 @@ struct dpu_rm {
struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0];
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
+ struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
uint32_t lm_max_width;
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
index 5e8c3f3e6625..7e08f40e7e6f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -140,7 +140,7 @@ exit:
/**
* dpu_vbif_set_ot_limit - set OT based on usecase & configuration parameters
- * @vbif: Pointer to hardware vbif driver
+ * @dpu_kms: DPU handler
* @params: Pointer to usecase parameters
*
* Note this function would block waiting for bus halt.
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index 34e3186e236d..169f9de4a12a 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -11,6 +11,7 @@
#include <drm/drm_vblank.h>
#include "mdp4_kms.h"
+#include "msm_gem.h"
struct mdp4_crtc {
struct drm_crtc base;
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index dbf8d429223e..3d729270bde1 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -175,6 +175,8 @@ static void mdp4_destroy(struct msm_kms *kms)
if (mdp4_kms->rpm_enabled)
pm_runtime_disable(dev);
+ mdp_kms_destroy(&mdp4_kms->base);
+
kfree(mdp4_kms);
}
@@ -427,7 +429,11 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
goto fail;
}
- mdp_kms_init(&mdp4_kms->base, &kms_funcs);
+ ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);
+ if (ret) {
+ DRM_DEV_ERROR(dev->dev, "failed to init kms\n");
+ goto fail;
+ }
kms = &mdp4_kms->base.base;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 4a53d7b42e9c..0c8f9f88301f 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -16,6 +16,7 @@
#include <drm/drm_vblank.h>
#include "mdp5_kms.h"
+#include "msm_gem.h"
#define CURSOR_WIDTH 64
#define CURSOR_HEIGHT 64
@@ -577,9 +578,9 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
mdp5_crtc->enabled = true;
}
-int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc,
- struct drm_crtc_state *new_crtc_state,
- bool need_right_mixer)
+static int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc,
+ struct drm_crtc_state *new_crtc_state,
+ bool need_right_mixer)
{
struct mdp5_crtc_state *mdp5_cstate =
to_mdp5_crtc_state(new_crtc_state);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c
index 030279d7b64b..81b0c7cf954e 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c
@@ -216,7 +216,9 @@ static void send_start_signal(struct mdp5_ctl *ctl)
/**
* mdp5_ctl_set_encoder_state() - set the encoder state
*
- * @enable: true, when encoder is ready for data streaming; false, otherwise.
+ * @ctl: the CTL instance
+ * @pipeline: the encoder's INTF + MIXER configuration
+ * @enabled: true, when encoder is ready for data streaming; false, otherwise.
*
* Note:
* This encoder state is needed to trigger START signal (data path kickoff).
@@ -510,6 +512,13 @@ static void fix_for_single_flush(struct mdp5_ctl *ctl, u32 *flush_mask,
/**
* mdp5_ctl_commit() - Register Flush
*
+ * @ctl: the CTL instance
+ * @pipeline: the encoder's INTF + MIXER configuration
+ * @flush_mask: bitmask of display controller hw blocks to flush
+ * @start: if true, immediately update flush registers and set START
+ * bit, otherwise accumulate flush_mask bits until we are
+ * ready to START
+ *
* The flush register is used to indicate several registers are all
* programmed, and are safe to update to the back copy of the double
* buffered registers.
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index e193865ce9a2..15aed45022bc 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -232,6 +232,8 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
aspace->mmu->funcs->detach(aspace->mmu);
msm_gem_address_space_put(aspace);
}
+
+ mdp_kms_destroy(&mdp5_kms->base);
}
#ifdef CONFIG_DEBUG_FS
@@ -294,7 +296,7 @@ static const struct mdp_kms_funcs kms_funcs = {
.set_irqmask = mdp5_set_irqmask,
};
-int mdp5_disable(struct mdp5_kms *mdp5_kms)
+static int mdp5_disable(struct mdp5_kms *mdp5_kms)
{
DBG("");
@@ -314,7 +316,7 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
return 0;
}
-int mdp5_enable(struct mdp5_kms *mdp5_kms)
+static int mdp5_enable(struct mdp5_kms *mdp5_kms)
{
DBG("");
@@ -592,11 +594,14 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
return NULL;
mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-
- mdp_kms_init(&mdp5_kms->base, &kms_funcs);
-
pdev = mdp5_kms->pdev;
+ ret = mdp_kms_init(&mdp5_kms->base, &kms_funcs);
+ if (ret) {
+ DRM_DEV_ERROR(&pdev->dev, "failed to init kms\n");
+ goto fail;
+ }
+
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
if (irq < 0) {
ret = irq;
diff --git a/drivers/gpu/drm/msm/disp/mdp_kms.h b/drivers/gpu/drm/msm/disp/mdp_kms.h
index 1535c5618491..b0286d5d5130 100644
--- a/drivers/gpu/drm/msm/disp/mdp_kms.h
+++ b/drivers/gpu/drm/msm/disp/mdp_kms.h
@@ -36,12 +36,17 @@ struct mdp_kms {
};
#define to_mdp_kms(x) container_of(x, struct mdp_kms, base)
-static inline void mdp_kms_init(struct mdp_kms *mdp_kms,
+static inline int mdp_kms_init(struct mdp_kms *mdp_kms,
const struct mdp_kms_funcs *funcs)
{
mdp_kms->funcs = funcs;
INIT_LIST_HEAD(&mdp_kms->irq_list);
- msm_kms_init(&mdp_kms->base, &funcs->base);
+ return msm_kms_init(&mdp_kms->base, &funcs->base);
+}
+
+static inline void mdp_kms_destroy(struct mdp_kms *mdp_kms)
+{
+ msm_kms_destroy(&mdp_kms->base);
}
/*