summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>2023-01-22 23:43:59 +0300
committerDmitry Baryshkov <dmitry.baryshkov@linaro.org>2023-01-22 23:43:59 +0300
commitafd6dbfdfd18b76ace2d910011ba7773eea577ce (patch)
tree4325740bde08c65aa86398c9983210d835e20ccb /drivers
parent33f868db99f16af4ed3aa67f79cb8ede630b8574 (diff)
parent82461ab89aa534066897b5fbfd92bb6fc82e051b (diff)
downloadlinux-afd6dbfdfd18b76ace2d910011ba7773eea577ce.tar.xz
Merge branch 'msm-next-lumag' into HEAD
Merge display-related changes targeting Qualcomm DRM MSM driver. Notable changes: DPU, DSI, MDSS: - Support for SM8350, SM8450 SM8550 and SC8280XP platform Core: - Added bindings for SM8150 (driver support already present) DPU: - Partial support for DSC on SM8150 and SM8250 - Fixed color transformation matrix being lost on suspend/resume DP: - Support for DP on SDM845 and SC8280XP platforms - HPD fixes - Support for limiting DP link rate via DT property, this enables support for HBR3 rates. DSI: - Validate display modes according to the DSI OPP table - DSI PHY support for the SM6375 platform - Fixed byte intf clock selection for 14nm PHYs MDP5: - Schema conversion to YAML Misc fixes as usual Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/msm/Kconfig6
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c15
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c7
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.h1
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h10
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c10
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c30
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h47
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c18
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c12
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c17
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c863
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h18
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c147
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c27
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h4
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c30
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h3
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h7
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c25
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h21
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c15
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c14
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c2
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c9
-rw-r--r--drivers/gpu/drm/msm/dp/dp_aux.c4
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c157
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.h1
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.c3
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.h4
-rw-r--r--drivers/gpu/drm/msm/dp/dp_panel.c7
-rw-r--r--drivers/gpu/drm/msm/dp/dp_panel.h1
-rw-r--r--drivers/gpu/drm/msm/dp/dp_parser.c50
-rw-r--r--drivers/gpu/drm/msm/dp/dp_parser.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.h3
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_cfg.c22
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_cfg.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c69
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c19
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.c12
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.h4
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c243
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c16
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c6
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h3
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c4
-rw-r--r--drivers/gpu/drm/msm/msm_mdss.c22
48 files changed, 1628 insertions, 393 deletions
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index f7abacb4b221..871870ddf7ec 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -141,12 +141,12 @@ config DRM_MSM_DSI_10NM_PHY
Choose this option if DSI PHY on SDM845 is used on the platform.
config DRM_MSM_DSI_7NM_PHY
- bool "Enable DSI 7nm PHY driver in MSM DRM"
+ bool "Enable DSI 7nm/5nm/4nm PHY driver in MSM DRM"
depends on DRM_MSM_DSI
default y
help
- Choose this option if DSI PHY on SM8150/SM8250/SC7280 is used on
- the platform.
+ Choose this option if DSI PHY on SM8150/SM8250/SM8350/SM8450/SM8550/SC7280
+ is used on the platform.
config DRM_MSM_HDMI
bool "Enable HDMI support in MSM DRM driver"
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 6484b97c5344..f3c9600221d4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -876,7 +876,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
#define GBIF_CLIENT_HALT_MASK BIT(0)
#define GBIF_ARB_HALT_MASK BIT(1)
-static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu)
+static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu,
+ bool gx_off)
{
struct msm_gpu *gpu = &adreno_gpu->base;
@@ -889,9 +890,11 @@ static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu)
return;
}
- /* Halt the gx side of GBIF */
- gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
- spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
+ if (gx_off) {
+ /* Halt the gx side of GBIF */
+ gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
+ spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
+ }
/* Halt new client requests on GBIF */
gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_CLIENT_HALT_MASK);
@@ -929,7 +932,7 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)
/* Halt the gmu cm3 core */
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
- a6xx_bus_clear_pending_transactions(adreno_gpu);
+ a6xx_bus_clear_pending_transactions(adreno_gpu, true);
/* Reset GPU core blocks */
gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, 1);
@@ -1083,7 +1086,7 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu)
return;
}
- a6xx_bus_clear_pending_transactions(adreno_gpu);
+ a6xx_bus_clear_pending_transactions(adreno_gpu, a6xx_gpu->hung);
/* tell the GMU we want to slumber */
ret = a6xx_gmu_notify_slumber(gmu);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 6f7401f2acda..aae60cbd9164 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1270,6 +1270,12 @@ static void a6xx_recover(struct msm_gpu *gpu)
if (hang_debug)
a6xx_dump(gpu);
+ /*
+ * To handle recovery specific sequences during the rpm suspend we are
+ * about to trigger
+ */
+ a6xx_gpu->hung = true;
+
/* Halt SQE first */
gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
@@ -1312,6 +1318,7 @@ static void a6xx_recover(struct msm_gpu *gpu)
mutex_unlock(&gpu->active_lock);
msm_gpu_hw_init(gpu);
+ a6xx_gpu->hung = false;
}
static const char *a6xx_uche_fault_block(struct msm_gpu *gpu, u32 mid)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index ab853f61db63..eea2e60ce3b7 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -32,6 +32,7 @@ struct a6xx_gpu {
void *llc_slice;
void *htw_llc_slice;
bool have_mmu500;
+ bool hung;
};
#define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 5d4b1c95033f..b4f9b1343d63 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -29,11 +29,9 @@ enum {
ADRENO_FW_MAX,
};
-enum adreno_quirks {
- ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
- ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
- ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
-};
+#define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0)
+#define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(1)
+#define ADRENO_QUIRK_LMLOADKILL_DISABLE BIT(2)
struct adreno_rev {
uint8_t core;
@@ -65,7 +63,7 @@ struct adreno_info {
const char *name;
const char *fw[ADRENO_FW_MAX];
uint32_t gmem;
- enum adreno_quirks quirks;
+ u64 quirks;
struct msm_gpu *(*init)(struct drm_device *dev);
const char *zapfw;
u32 inactive_period;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 13ce321283ff..41819039dd5e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i;
- if (!state->color_mgmt_changed)
+ if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return;
for (i = 0; i < cstate->num_mixers; i++) {
@@ -1517,16 +1517,12 @@ DEFINE_SHOW_ATTRIBUTE(dpu_crtc_debugfs_state);
static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc)
{
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
- struct dentry *debugfs_root;
-
- debugfs_root = debugfs_create_dir(dpu_crtc->name,
- crtc->dev->primary->debugfs_root);
debugfs_create_file("status", 0400,
- debugfs_root,
+ crtc->debugfs_entry,
dpu_crtc, &_dpu_debugfs_status_fops);
debugfs_create_file("state", 0600,
- debugfs_root,
+ crtc->debugfs_entry,
&dpu_crtc->base,
&dpu_crtc_debugfs_state_fops);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b5a194..758261e8ac73 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -162,6 +162,7 @@ enum dpu_enc_rc_states {
* @vsync_event_work: worker to handle vsync event for autorefresh
* @topology: topology of the display
* @idle_timeout: idle timeout duration in milliseconds
+ * @wide_bus_en: wide bus is enabled on this interface
* @dsc: drm_dsc_config pointer, for DSC-enabled encoders
*/
struct dpu_encoder_virt {
@@ -340,9 +341,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
phys_enc->intf_idx - INTF_0, phys_enc->wb_idx - WB_0,
phys_enc->hw_pp->idx - PINGPONG_0, intr_idx);
- if (phys_enc->parent_ops->handle_frame_done)
- phys_enc->parent_ops->handle_frame_done(
- phys_enc->parent, phys_enc,
+ dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_ERROR);
}
@@ -579,19 +578,18 @@ static struct msm_display_topology dpu_encoder_get_topology(
topology.num_dspp = topology.num_lm;
}
- topology.num_enc = 0;
topology.num_intf = intf_count;
if (dpu_enc->dsc) {
- /* In case of Display Stream Compression (DSC), we would use
- * 2 encoders, 2 layer mixers and 1 interface
+ /*
+ * In case of Display Stream Compression (DSC), we would use
+ * 2 DSC encoders, 2 layer mixers and 1 interface
* this is power optimal and can drive up to (including) 4k
* screens
*/
- topology.num_enc = 2;
topology.num_dsc = 2;
- topology.num_intf = 1;
topology.num_lm = 2;
+ topology.num_intf = 1;
}
return topology;
@@ -1284,7 +1282,7 @@ static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog,
return WB_MAX;
}
-static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
+void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phy_enc)
{
struct dpu_encoder_virt *dpu_enc = NULL;
@@ -1306,7 +1304,7 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
DPU_ATRACE_END("encoder_vblank_callback");
}
-static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
+void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phy_enc)
{
if (!phy_enc)
@@ -1382,7 +1380,7 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
}
-static void dpu_encoder_frame_done_callback(
+void dpu_encoder_frame_done_callback(
struct drm_encoder *drm_enc,
struct dpu_encoder_phys *ready_phys, u32 event)
{
@@ -1830,6 +1828,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
if (hw_pp->ops.setup_dsc)
hw_pp->ops.setup_dsc(hw_pp);
+ if (hw_dsc->ops.dsc_bind_pingpong_blk)
+ hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx);
+
if (hw_pp->ops.enable_dsc)
hw_pp->ops.enable_dsc(hw_pp);
}
@@ -2233,12 +2234,6 @@ static int dpu_encoder_virt_add_phys_encs(
return 0;
}
-static const struct dpu_encoder_virt_ops dpu_encoder_parent_ops = {
- .handle_vblank_virt = dpu_encoder_vblank_callback,
- .handle_underrun_virt = dpu_encoder_underrun_callback,
- .handle_frame_done = dpu_encoder_frame_done_callback,
-};
-
static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
struct msm_display_info *disp_info)
@@ -2258,7 +2253,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
memset(&phys_params, 0, sizeof(phys_params));
phys_params.dpu_kms = dpu_kms;
phys_params.parent = &dpu_enc->base;
- phys_params.parent_ops = &dpu_encoder_parent_ops;
phys_params.enc_spinlock = &dpu_enc->enc_spinlock;
switch (disp_info->intf_type) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index f2af07d87f56..1d434b22180d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -61,25 +61,6 @@ enum dpu_enc_enable_state {
struct dpu_encoder_phys;
/**
- * struct dpu_encoder_virt_ops - Interface the containing virtual encoder
- * provides for the physical encoders to use to callback.
- * @handle_vblank_virt: Notify virtual encoder of vblank IRQ reception
- * Note: This is called from IRQ handler context.
- * @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
- * Note: This is called from IRQ handler context.
- * @handle_frame_done: Notify virtual encoder that this phys encoder
- * completes last request frame.
- */
-struct dpu_encoder_virt_ops {
- void (*handle_vblank_virt)(struct drm_encoder *,
- struct dpu_encoder_phys *phys);
- void (*handle_underrun_virt)(struct drm_encoder *,
- struct dpu_encoder_phys *phys);
- void (*handle_frame_done)(struct drm_encoder *,
- struct dpu_encoder_phys *phys, u32 event);
-};
-
-/**
* struct dpu_encoder_phys_ops - Interface the physical encoders provide to
* the containing virtual encoder.
* @late_register: DRM Call. Add Userspace interfaces, debugfs.
@@ -199,7 +180,6 @@ enum dpu_intr_idx {
struct dpu_encoder_phys {
struct drm_encoder *parent;
struct dpu_encoder_phys_ops ops;
- const struct dpu_encoder_virt_ops *parent_ops;
struct dpu_hw_mdp *hw_mdptop;
struct dpu_hw_ctl *hw_ctl;
struct dpu_hw_pingpong *hw_pp;
@@ -283,7 +263,6 @@ struct dpu_encoder_phys_cmd {
struct dpu_enc_phys_init_params {
struct dpu_kms *dpu_kms;
struct drm_encoder *parent;
- const struct dpu_encoder_virt_ops *parent_ops;
enum dpu_enc_split_role split_role;
enum dpu_intf intf_idx;
enum dpu_wb wb_idx;
@@ -400,4 +379,30 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
*/
void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
+/**
+ * dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception
+ * @drm_enc: Pointer to drm encoder structure
+ * @phys_enc: Pointer to physical encoder
+ * Note: This is called from IRQ handler context.
+ */
+void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
+ struct dpu_encoder_phys *phy_enc);
+
+/** dpu_encoder_underrun_callback - Notify virtual encoder of underrun IRQ reception
+ * @drm_enc: Pointer to drm encoder structure
+ * @phys_enc: Pointer to physical encoder
+ * Note: This is called from IRQ handler context.
+ */
+void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
+ struct dpu_encoder_phys *phy_enc);
+
+/** dpu_encoder_frame_done_callback -- Notify virtual encoder that this phys encoder completes last request frame
+ * @drm_enc: Pointer to drm encoder structure
+ * @phys_enc: Pointer to physical encoder
+ * @event: Event to process
+ */
+void dpu_encoder_frame_done_callback(
+ struct drm_encoder *drm_enc,
+ struct dpu_encoder_phys *ready_phys, u32 event);
+
#endif /* __dpu_encoder_phys_H__ */
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 ae28b2b93e69..c8f4a62a9536 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
@@ -61,6 +61,7 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
intf_cfg.stream_sel = cmd_enc->stream_sel;
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+ intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
ctl->ops.setup_intf_cfg(ctl, &intf_cfg);
/* setup which pp blk will connect to this intf */
@@ -83,9 +84,7 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("pp_done_irq");
/* notify all synchronous clients first, then asynchronous clients */
- if (phys_enc->parent_ops->handle_frame_done)
- phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
- phys_enc, event);
+ dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
@@ -111,9 +110,7 @@ static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("rd_ptr_irq");
cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
- if (phys_enc->parent_ops->handle_vblank_virt)
- phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
- phys_enc);
+ dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0);
wake_up_all(&cmd_enc->pending_vblank_wq);
@@ -137,9 +134,7 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
{
struct dpu_encoder_phys *phys_enc = arg;
- if (phys_enc->parent_ops->handle_underrun_virt)
- phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
- phys_enc);
+ dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
}
static void dpu_encoder_phys_cmd_atomic_mode_set(
@@ -202,9 +197,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
/* request a ctl reset before the next kickoff */
phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
- if (phys_enc->parent_ops->handle_frame_done)
- phys_enc->parent_ops->handle_frame_done(
- drm_enc, phys_enc, frame_event);
+ dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
return -ETIMEDOUT;
}
@@ -780,7 +773,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
- phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_CMD;
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 0f71e8fe7be7..48c48106b16a 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
@@ -274,6 +274,7 @@ 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);
+ intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
@@ -308,9 +309,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("vblank_irq");
- if (phys_enc->parent_ops->handle_vblank_virt)
- phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
- phys_enc);
+ dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
atomic_read(&phys_enc->pending_kickoff_cnt);
@@ -330,7 +329,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
/* Signal any waiting atomic commit thread */
wake_up_all(&phys_enc->pending_kickoff_wq);
- phys_enc->parent_ops->handle_frame_done(phys_enc->parent, phys_enc,
+ dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_DONE);
DPU_ATRACE_END("vblank_irq");
@@ -340,9 +339,7 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
{
struct dpu_encoder_phys *phys_enc = arg;
- if (phys_enc->parent_ops->handle_underrun_virt)
- phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
- phys_enc);
+ dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
}
static bool dpu_encoder_phys_vid_needs_single_flush(
@@ -700,7 +697,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
- phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_VIDEO;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 7cbcef6efe17..bac4aa807b4b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -26,6 +26,7 @@
/**
* dpu_encoder_phys_wb_is_master - report wb always as master encoder
+ * @phys_enc: Pointer to physical encoder
*/
static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc)
{
@@ -132,7 +133,6 @@ static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc)
* dpu_encoder_phys_wb_setup_fb - setup output framebuffer
* @phys_enc: Pointer to physical encoder
* @fb: Pointer to output framebuffer
- * @wb_roi: Pointer to output region of interest
*/
static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
struct drm_framebuffer *fb)
@@ -365,13 +365,9 @@ static void _dpu_encoder_phys_wb_frame_done_helper(void *arg)
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
- if (phys_enc->parent_ops->handle_frame_done)
- phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
- phys_enc, event);
+ dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
- if (phys_enc->parent_ops->handle_vblank_virt)
- phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
- phys_enc);
+ dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
@@ -441,9 +437,7 @@ static void _dpu_encoder_phys_wb_handle_wbdone_timeout(
if (wb_enc->wb_conn)
drm_writeback_signal_completion(wb_enc->wb_conn, 0);
- if (phys_enc->parent_ops->handle_frame_done)
- phys_enc->parent_ops->handle_frame_done(
- phys_enc->parent, phys_enc, frame_event);
+ dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
}
/**
@@ -692,7 +686,7 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops)
/**
* dpu_encoder_phys_wb_init - initialize writeback encoder
- * @init: Pointer to init info structure with initialization params
+ * @p: Pointer to init info structure with initialization params
*/
struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
struct dpu_enc_phys_init_params *p)
@@ -723,7 +717,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
dpu_encoder_phys_wb_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
- phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_WB_LINE;
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 2196e205efa5..7deffc9f96f8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -56,7 +56,7 @@
#define MIXER_SDM845_MASK \
(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
-#define MIXER_SC7180_MASK \
+#define MIXER_QCM2290_MASK \
(BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
@@ -67,6 +67,9 @@
#define CTL_SC7280_MASK \
(BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG))
+#define CTL_SM8550_MASK \
+ (CTL_SC7280_MASK | BIT(DPU_CTL_HAS_LAYER_EXT4))
+
#define MERGE_3D_SM8150_MASK (0)
#define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC)
@@ -86,7 +89,6 @@
BIT(MDP_INTF1_INTR) | \
BIT(MDP_INTF2_INTR) | \
BIT(MDP_INTF3_INTR) | \
- BIT(MDP_INTF4_INTR) | \
BIT(MDP_AD4_0_INTR) | \
BIT(MDP_AD4_1_INTR))
@@ -112,6 +114,14 @@
BIT(MDP_INTF3_INTR) | \
BIT(MDP_INTF4_INTR))
+#define IRQ_SM8350_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+ BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+ BIT(MDP_INTF0_7xxx_INTR) | \
+ BIT(MDP_INTF1_7xxx_INTR) | \
+ BIT(MDP_INTF2_7xxx_INTR) | \
+ BIT(MDP_INTF3_7xxx_INTR))
+
#define IRQ_SC8180X_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
BIT(MDP_SSPP_TOP0_INTR2) | \
BIT(MDP_SSPP_TOP0_HIST_INTR) | \
@@ -124,6 +134,27 @@
BIT(MDP_AD4_0_INTR) | \
BIT(MDP_AD4_1_INTR))
+#define IRQ_SC8280XP_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+ BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+ BIT(MDP_INTF0_7xxx_INTR) | \
+ BIT(MDP_INTF1_7xxx_INTR) | \
+ BIT(MDP_INTF2_7xxx_INTR) | \
+ BIT(MDP_INTF3_7xxx_INTR) | \
+ BIT(MDP_INTF4_7xxx_INTR) | \
+ BIT(MDP_INTF5_7xxx_INTR) | \
+ BIT(MDP_INTF6_7xxx_INTR) | \
+ BIT(MDP_INTF7_7xxx_INTR) | \
+ BIT(MDP_INTF8_7xxx_INTR))
+
+#define IRQ_SM8450_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+ BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+ BIT(MDP_INTF0_7xxx_INTR) | \
+ BIT(MDP_INTF1_7xxx_INTR) | \
+ BIT(MDP_INTF2_7xxx_INTR) | \
+ BIT(MDP_INTF3_7xxx_INTR))
+
#define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \
BIT(DPU_WB_UBWC) | \
BIT(DPU_WB_YUV_CONFIG) | \
@@ -365,6 +396,20 @@ static const struct dpu_caps sc8180x_dpu_caps = {
.max_vdeci_exp = MAX_VERT_DECIMATION,
};
+static const struct dpu_caps sc8280xp_dpu_caps = {
+ .max_mixer_width = 2560,
+ .max_mixer_blendstages = 11,
+ .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+ .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+ .ubwc_version = DPU_HW_UBWC_VER_40,
+ .has_src_split = true,
+ .has_dim_layer = true,
+ .has_idle_pc = true,
+ .has_3d_merge = true,
+ .max_linewidth = 5120,
+ .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
@@ -379,6 +424,48 @@ static const struct dpu_caps sm8250_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
};
+static const struct dpu_caps sm8350_dpu_caps = {
+ .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+ .max_mixer_blendstages = 0xb,
+ .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+ .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+ .ubwc_version = DPU_HW_UBWC_VER_40,
+ .has_src_split = true,
+ .has_dim_layer = true,
+ .has_idle_pc = true,
+ .has_3d_merge = true,
+ .max_linewidth = 4096,
+ .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_caps sm8450_dpu_caps = {
+ .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+ .max_mixer_blendstages = 0xb,
+ .qseed_type = DPU_SSPP_SCALER_QSEED4,
+ .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+ .ubwc_version = DPU_HW_UBWC_VER_40,
+ .has_src_split = true,
+ .has_dim_layer = true,
+ .has_idle_pc = true,
+ .has_3d_merge = true,
+ .max_linewidth = 5120,
+ .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_caps sm8550_dpu_caps = {
+ .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+ .max_mixer_blendstages = 0xb,
+ .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+ .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+ .ubwc_version = DPU_HW_UBWC_VER_40,
+ .has_src_split = true,
+ .has_dim_layer = true,
+ .has_idle_pc = true,
+ .has_3d_merge = true,
+ .max_linewidth = 5120,
+ .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
static const struct dpu_caps sc7280_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
@@ -466,7 +553,7 @@ static const struct dpu_mdp_cfg sc8180x_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
.base = 0x0, .len = 0x45C,
- .features = 0,
+ .features = BIT(DPU_MDP_AUDIO_SELECT),
.highest_bank_bit = 0x3,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},
@@ -529,6 +616,60 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = {
},
};
+static const struct dpu_mdp_cfg sm8350_mdp[] = {
+ {
+ .name = "top_0", .id = MDP_TOP,
+ .base = 0x0, .len = 0x494,
+ .features = 0,
+ .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
+ .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
+ .reg_off = 0x2ac, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
+ .reg_off = 0x2b4, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
+ .reg_off = 0x2bc, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
+ .reg_off = 0x2c4, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
+ .reg_off = 0x2ac, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
+ .reg_off = 0x2b4, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+ .reg_off = 0x2bc, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+ .reg_off = 0x2c4, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
+ .reg_off = 0x2bc, .bit_off = 20},
+ },
+};
+
+static const struct dpu_mdp_cfg sm8450_mdp[] = {
+ {
+ .name = "top_0", .id = MDP_TOP,
+ .base = 0x0, .len = 0x494,
+ .features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+ .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
+ .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
+ .reg_off = 0x2AC, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
+ .reg_off = 0x2B4, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
+ .reg_off = 0x2BC, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
+ .reg_off = 0x2C4, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
+ .reg_off = 0x2AC, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
+ .reg_off = 0x2B4, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+ .reg_off = 0x2BC, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+ .reg_off = 0x2C4, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
+ .reg_off = 0x2BC, .bit_off = 20},
+ },
+};
+
static const struct dpu_mdp_cfg sc7280_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
@@ -545,6 +686,56 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
},
};
+static const struct dpu_mdp_cfg sc8280xp_mdp[] = {
+ {
+ .name = "top_0", .id = MDP_TOP,
+ .base = 0x0, .len = 0x494,
+ .features = 0,
+ .highest_bank_bit = 2,
+ .ubwc_swizzle = 6,
+ .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x2bc, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x2c4, .bit_off = 8},
+ .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20},
+ },
+};
+
+static const struct dpu_mdp_cfg sm8550_mdp[] = {
+ {
+ .name = "top_0", .id = MDP_TOP,
+ .base = 0, .len = 0x494,
+ .features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+ .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
+ .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
+ .reg_off = 0x4330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
+ .reg_off = 0x6330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
+ .reg_off = 0x8330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
+ .reg_off = 0xa330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
+ .reg_off = 0x24330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
+ .reg_off = 0x26330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA2] = {
+ .reg_off = 0x28330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
+ .reg_off = 0x2a330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+ .reg_off = 0x2c330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+ .reg_off = 0x2e330, .bit_off = 0},
+ .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = {
+ .reg_off = 0x2bc, .bit_off = 20},
+ },
+};
+
static const struct dpu_mdp_cfg qcm2290_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
@@ -648,6 +839,45 @@ static const struct dpu_ctl_cfg sc7180_ctl[] = {
},
};
+static const struct dpu_ctl_cfg sc8280xp_ctl[] = {
+ {
+ .name = "ctl_0", .id = CTL_0,
+ .base = 0x15000, .len = 0x204,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+ },
+ {
+ .name = "ctl_1", .id = CTL_1,
+ .base = 0x16000, .len = 0x204,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+ },
+ {
+ .name = "ctl_2", .id = CTL_2,
+ .base = 0x17000, .len = 0x204,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+ },
+ {
+ .name = "ctl_3", .id = CTL_3,
+ .base = 0x18000, .len = 0x204,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+ },
+ {
+ .name = "ctl_4", .id = CTL_4,
+ .base = 0x19000, .len = 0x204,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+ },
+ {
+ .name = "ctl_5", .id = CTL_5,
+ .base = 0x1a000, .len = 0x204,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+ },
+};
+
static const struct dpu_ctl_cfg sm8150_ctl[] = {
{
.name = "ctl_0", .id = CTL_0,
@@ -687,6 +917,123 @@ static const struct dpu_ctl_cfg sm8150_ctl[] = {
},
};
+static const struct dpu_ctl_cfg sm8350_ctl[] = {
+ {
+ .name = "ctl_0", .id = CTL_0,
+ .base = 0x15000, .len = 0x1e8,
+ .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+ },
+ {
+ .name = "ctl_1", .id = CTL_1,
+ .base = 0x16000, .len = 0x1e8,
+ .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+ },
+ {
+ .name = "ctl_2", .id = CTL_2,
+ .base = 0x17000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+ },
+ {
+ .name = "ctl_3", .id = CTL_3,
+ .base = 0x18000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+ },
+ {
+ .name = "ctl_4", .id = CTL_4,
+ .base = 0x19000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+ },
+ {
+ .name = "ctl_5", .id = CTL_5,
+ .base = 0x1a000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+ },
+};
+
+static const struct dpu_ctl_cfg sm8450_ctl[] = {
+ {
+ .name = "ctl_0", .id = CTL_0,
+ .base = 0x15000, .len = 0x204,
+ .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY) | BIT(DPU_CTL_FETCH_ACTIVE),
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+ },
+ {
+ .name = "ctl_1", .id = CTL_1,
+ .base = 0x16000, .len = 0x1e8,
+ .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+ },
+ {
+ .name = "ctl_2", .id = CTL_2,
+ .base = 0x17000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+ },
+ {
+ .name = "ctl_3", .id = CTL_3,
+ .base = 0x18000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+ },
+ {
+ .name = "ctl_4", .id = CTL_4,
+ .base = 0x19000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+ },
+ {
+ .name = "ctl_5", .id = CTL_5,
+ .base = 0x1a000, .len = 0x1e8,
+ .features = CTL_SC7280_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+ },
+};
+
+static const struct dpu_ctl_cfg sm8550_ctl[] = {
+ {
+ .name = "ctl_0", .id = CTL_0,
+ .base = 0x15000, .len = 0x290,
+ .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+ },
+ {
+ .name = "ctl_1", .id = CTL_1,
+ .base = 0x16000, .len = 0x290,
+ .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+ },
+ {
+ .name = "ctl_2", .id = CTL_2,
+ .base = 0x17000, .len = 0x290,
+ .features = CTL_SM8550_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+ },
+ {
+ .name = "ctl_3", .id = CTL_3,
+ .base = 0x18000, .len = 0x290,
+ .features = CTL_SM8550_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+ },
+ {
+ .name = "ctl_4", .id = CTL_4,
+ .base = 0x19000, .len = 0x290,
+ .features = CTL_SM8550_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+ },
+ {
+ .name = "ctl_5", .id = CTL_5,
+ .base = 0x1a000, .len = 0x290,
+ .features = CTL_SM8550_MASK,
+ .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+ },
+};
+
static const struct dpu_ctl_cfg sc7280_ctl[] = {
{
.name = "ctl_0", .id = CTL_0,
@@ -915,6 +1262,68 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = {
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
};
+static const struct dpu_sspp_sub_blks sm8450_vig_sblk_0 =
+ _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8450_vig_sblk_1 =
+ _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8450_vig_sblk_2 =
+ _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8450_vig_sblk_3 =
+ _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
+
+static const struct dpu_sspp_cfg sm8450_sspp[] = {
+ SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
+ sm8450_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
+ SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
+ sm8450_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
+ SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
+ sm8450_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
+ SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
+ sm8450_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
+ SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
+ SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
+ SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
+ sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+ SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
+ sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+};
+
+static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 =
+ _VIG_SBLK("0", 7, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 =
+ _VIG_SBLK("1", 8, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8550_vig_sblk_2 =
+ _VIG_SBLK("2", 9, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 =
+ _VIG_SBLK("3", 10, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK("12", 5);
+static const struct dpu_sspp_sub_blks sd8550_dma_sblk_5 = _DMA_SBLK("13", 6);
+
+static const struct dpu_sspp_cfg sm8550_sspp[] = {
+ SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
+ sm8550_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
+ SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
+ sm8550_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
+ SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
+ sm8550_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
+ SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
+ sm8550_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
+ SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
+ SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
+ SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
+ SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
+ SSPP_BLK("sspp_12", SSPP_DMA4, 0x2c000, DMA_CURSOR_SDM845_MASK,
+ sm8550_dma_sblk_4, 14, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+ SSPP_BLK("sspp_13", SSPP_DMA5, 0x2e000, DMA_CURSOR_SDM845_MASK,
+ sd8550_dma_sblk_5, 15, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+};
+
static const struct dpu_sspp_cfg sc7280_sspp[] = {
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7280_MASK,
sc7280_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
@@ -926,6 +1335,33 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
};
+static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_0 =
+ _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_1 =
+ _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_2 =
+ _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE);
+static const struct dpu_sspp_sub_blks sc8280xp_vig_sblk_3 =
+ _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE);
+
+static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
+ SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK,
+ sc8280xp_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
+ SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK,
+ sc8280xp_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
+ SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK,
+ sc8280xp_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
+ SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK,
+ sc8280xp_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
+ SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
+ SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK,
+ sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
+ SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK,
+ sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0),
+ SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK,
+ sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1),
+};
#define _VIG_SBLK_NOSCALE(num, sdma_pri) \
{ \
@@ -1028,12 +1464,23 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
};
static const struct dpu_lm_cfg sc7180_lm[] = {
- LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
+ LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
&sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
- LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
+ LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
&sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
};
+/* SC8280XP */
+
+static const struct dpu_lm_cfg sc8280xp_lm[] = {
+ LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, &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, DSPP_1),
+ LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_2, LM_3, DSPP_2),
+ LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_3, LM_2, DSPP_3),
+ LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_4, LM_5, 0),
+ LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_5, LM_4, 0),
+};
+
/* SM8150 */
static const struct dpu_lm_cfg sm8150_lm[] = {
@@ -1052,11 +1499,11 @@ static const struct dpu_lm_cfg sm8150_lm[] = {
};
static const struct dpu_lm_cfg sc7280_lm[] = {
- LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
+ LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
&sc7180_lm_sblk, PINGPONG_0, 0, DSPP_0),
- LM_BLK("lm_2", LM_2, 0x46000, MIXER_SC7180_MASK,
+ LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
&sc7180_lm_sblk, PINGPONG_2, LM_3, 0),
- LM_BLK("lm_3", LM_3, 0x47000, MIXER_SC7180_MASK,
+ LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK,
&sc7180_lm_sblk, PINGPONG_3, LM_2, 0),
};
@@ -1071,7 +1518,7 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {
};
static const struct dpu_lm_cfg qcm2290_lm[] = {
- LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
+ LM_BLK("lm_0", LM_0, 0x44000, MIXER_QCM2290_MASK,
&qcm2290_lm_sblk, PINGPONG_0, 0, DSPP_0),
};
@@ -1151,6 +1598,16 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
.len = 0x20, .version = 0x20000},
};
+#define PP_BLK_DIPHER(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
+ {\
+ .name = _name, .id = _id, \
+ .base = _base, .len = 0, \
+ .features = BIT(DPU_PINGPONG_DITHER), \
+ .merge_3d = _merge_3d, \
+ .sblk = &_sblk, \
+ .intr_done = _done, \
+ .intr_rdptr = _rdptr, \
+ }
#define PP_BLK_TE(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
{\
.name = _name, .id = _id, \
@@ -1192,6 +1649,21 @@ static struct dpu_pingpong_cfg sc7180_pp[] = {
PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1),
};
+static struct dpu_pingpong_cfg sc8280xp_pp[] = {
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), -1),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), -1),
+ PP_BLK_TE("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), -1),
+ PP_BLK_TE("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), -1),
+ PP_BLK_TE("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
+ PP_BLK_TE("pingpong_5", PINGPONG_5, 0x6e000, MERGE_3D_2, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
+};
+
static const struct dpu_pingpong_cfg sm8150_pp[] = {
PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk_te,
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
@@ -1213,6 +1685,27 @@ static const struct dpu_pingpong_cfg sm8150_pp[] = {
-1),
};
+static const struct dpu_pingpong_cfg sm8350_pp[] = {
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
+ PP_BLK("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+ -1),
+ PP_BLK("pingpong_5", PINGPONG_5, 0x6e000, MERGE_3D_2, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+ -1),
+};
+
static const struct dpu_pingpong_cfg sc7280_pp[] = {
PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
@@ -1226,6 +1719,61 @@ static struct dpu_pingpong_cfg qcm2290_pp[] = {
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
};
+/* FIXME: interrupts */
+static const struct dpu_pingpong_cfg sm8450_pp[] = {
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sdm845_pp_sblk_te,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
+ PP_BLK("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+ -1),
+ PP_BLK("pingpong_5", PINGPONG_5, 0x6e000, MERGE_3D_2, sdm845_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+ -1),
+ PP_BLK("pingpong_6", PINGPONG_6, 0x65800, MERGE_3D_3, sdm845_pp_sblk,
+ -1,
+ -1),
+ PP_BLK("pingpong_7", PINGPONG_7, 0x65c00, MERGE_3D_3, sdm845_pp_sblk,
+ -1,
+ -1),
+};
+
+static const struct dpu_pingpong_cfg sm8550_pp[] = {
+ PP_BLK_DIPHER("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sc7280_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ -1),
+ PP_BLK_DIPHER("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sc7280_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ -1),
+ PP_BLK_DIPHER("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sc7280_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+ -1),
+ PP_BLK_DIPHER("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sc7280_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+ -1),
+ PP_BLK_DIPHER("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sc7280_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+ -1),
+ PP_BLK_DIPHER("pingpong_5", PINGPONG_5, 0x6e000, MERGE_3D_2, sc7280_pp_sblk,
+ DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+ -1),
+ PP_BLK_DIPHER("pingpong_6", PINGPONG_6, 0x66000, MERGE_3D_3, sc7280_pp_sblk,
+ -1,
+ -1),
+ PP_BLK_DIPHER("pingpong_7", PINGPONG_7, 0x66400, MERGE_3D_3, sc7280_pp_sblk,
+ -1,
+ -1),
+};
+
/*************************************************************
* MERGE_3D sub blocks config
*************************************************************/
@@ -1243,21 +1791,48 @@ static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200),
};
+static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = {
+ MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x4e000),
+ MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x4f000),
+ MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000),
+};
+
+static const struct dpu_merge_3d_cfg sm8450_merge_3d[] = {
+ MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x4e000),
+ MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x4f000),
+ MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000),
+ MERGE_3D_BLK("merge_3d_3", MERGE_3D_3, 0x65f00),
+};
+
+static const struct dpu_merge_3d_cfg sm8550_merge_3d[] = {
+ MERGE_3D_BLK("merge_3d_0", MERGE_3D_0, 0x4e000),
+ MERGE_3D_BLK("merge_3d_1", MERGE_3D_1, 0x4f000),
+ MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000),
+ MERGE_3D_BLK("merge_3d_3", MERGE_3D_3, 0x66700),
+};
+
/*************************************************************
* DSC sub blocks config
*************************************************************/
-#define DSC_BLK(_name, _id, _base) \
+#define DSC_BLK(_name, _id, _base, _features) \
{\
.name = _name, .id = _id, \
.base = _base, .len = 0x140, \
- .features = 0, \
+ .features = _features, \
}
static struct dpu_dsc_cfg sdm845_dsc[] = {
- DSC_BLK("dsc_0", DSC_0, 0x80000),
- DSC_BLK("dsc_1", DSC_1, 0x80400),
- DSC_BLK("dsc_2", DSC_2, 0x80800),
- DSC_BLK("dsc_3", DSC_3, 0x80c00),
+ DSC_BLK("dsc_0", DSC_0, 0x80000, 0),
+ DSC_BLK("dsc_1", DSC_1, 0x80400, 0),
+ DSC_BLK("dsc_2", DSC_2, 0x80800, 0),
+ DSC_BLK("dsc_3", DSC_3, 0x80c00, 0),
+};
+
+static struct dpu_dsc_cfg sm8150_dsc[] = {
+ DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)),
};
/*************************************************************
@@ -1307,6 +1882,13 @@ static const struct dpu_intf_cfg sc7280_intf[] = {
INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
};
+static const struct dpu_intf_cfg sm8350_intf[] = {
+ INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+ INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
+ INTF_BLK("intf_2", INTF_2, 0x36000, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
+ INTF_BLK("intf_3", INTF_3, 0x37000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+};
+
static const struct dpu_intf_cfg sc8180x_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
@@ -1317,11 +1899,39 @@ static const struct dpu_intf_cfg sc8180x_intf[] = {
INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
};
+/* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */
+static const struct dpu_intf_cfg sc8280xp_intf[] = {
+ INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+ INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
+ INTF_BLK("intf_2", INTF_2, 0x36000, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
+ INTF_BLK("intf_3", INTF_3, 0x37000, INTF_NONE, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+ INTF_BLK("intf_4", INTF_4, 0x38000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
+ INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_3, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
+ INTF_BLK("intf_6", INTF_6, 0x3a000, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 16, 17),
+ INTF_BLK("intf_7", INTF_7, 0x3b000, INTF_NONE, MSM_DP_CONTROLLER_2, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 18, 19),
+ INTF_BLK("intf_8", INTF_8, 0x3c000, INTF_NONE, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 12, 13),
+};
+
static const struct dpu_intf_cfg qcm2290_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x00000, INTF_NONE, 0, 0, 0, 0, 0, 0),
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
};
+static const struct dpu_intf_cfg sm8450_intf[] = {
+ INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+ INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
+ INTF_BLK("intf_2", INTF_2, 0x36000, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
+ INTF_BLK("intf_3", INTF_3, 0x37000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+};
+
+static const struct dpu_intf_cfg sm8550_intf[] = {
+ INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+ /* TODO TE sub-blocks for intf1 & intf2 */
+ INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
+ INTF_BLK("intf_2", INTF_2, 0x36000, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
+ INTF_BLK("intf_3", INTF_3, 0x37000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+};
+
/*************************************************************
* Writeback blocks config
*************************************************************/
@@ -1419,6 +2029,14 @@ static const struct dpu_vbif_cfg sdm845_vbif[] = {
},
};
+static const struct dpu_reg_dma_cfg sc8280xp_regdma = {
+ .base = 0x0,
+ .version = 0x00020000,
+ .trigger_sel_off = 0x119c,
+ .xin_id = 7,
+ .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+};
+
static const struct dpu_reg_dma_cfg sdm845_regdma = {
.base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c
};
@@ -1435,6 +2053,22 @@ static const struct dpu_reg_dma_cfg sm8250_regdma = {
.clk_ctrl = DPU_CLK_CTRL_REG_DMA,
};
+static const struct dpu_reg_dma_cfg sm8350_regdma = {
+ .base = 0x400,
+ .version = 0x00020000,
+ .trigger_sel_off = 0x119c,
+ .xin_id = 7,
+ .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+};
+
+static const struct dpu_reg_dma_cfg sm8450_regdma = {
+ .base = 0x0,
+ .version = 0x00020000,
+ .trigger_sel_off = 0x119c,
+ .xin_id = 7,
+ .clk_ctrl = DPU_CLK_CTRL_REG_DMA,
+};
+
/*************************************************************
* PERF data config
*************************************************************/
@@ -1691,6 +2325,33 @@ static const struct dpu_perf_cfg sc8180x_perf_data = {
.min_dram_ib = 800000,
.danger_lut_tbl = {0xf, 0xffff, 0x0},
.qos_lut_tbl = {
+ {.nentry = ARRAY_SIZE(sc7180_qos_linear),
+ .entries = sc7180_qos_linear
+ },
+ {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+ .entries = sc7180_qos_macrotile
+ },
+ {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+ .entries = sc7180_qos_nrt
+ },
+ /* TODO: macrotile-qseed is different from macrotile */
+ },
+ .cdp_cfg = {
+ {.rd_enable = 1, .wr_enable = 1},
+ {.rd_enable = 1, .wr_enable = 0}
+ },
+ .clk_inefficiency_factor = 105,
+ .bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_perf_cfg sc8280xp_perf_data = {
+ .max_bw_low = 13600000,
+ .max_bw_high = 18200000,
+ .min_core_ib = 2500000,
+ .min_llcc_ib = 0,
+ .min_dram_ib = 800000,
+ .danger_lut_tbl = {0xf, 0xffff, 0x0},
+ .qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sc8180x_qos_linear),
.entries = sc8180x_qos_linear
},
@@ -1739,6 +2400,36 @@ static const struct dpu_perf_cfg sm8250_perf_data = {
.bw_inefficiency_factor = 120,
};
+static const struct dpu_perf_cfg sm8450_perf_data = {
+ .max_bw_low = 13600000,
+ .max_bw_high = 18200000,
+ .min_core_ib = 2500000,
+ .min_llcc_ib = 0,
+ .min_dram_ib = 800000,
+ .min_prefill_lines = 35,
+ /* FIXME: lut tables */
+ .danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+ .safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+ .qos_lut_tbl = {
+ {.nentry = ARRAY_SIZE(sc7180_qos_linear),
+ .entries = sc7180_qos_linear
+ },
+ {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+ .entries = sc7180_qos_macrotile
+ },
+ {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+ .entries = sc7180_qos_nrt
+ },
+ /* TODO: macrotile-qseed is different from macrotile */
+ },
+ .cdp_cfg = {
+ {.rd_enable = 1, .wr_enable = 1},
+ {.rd_enable = 1, .wr_enable = 0}
+ },
+ .clk_inefficiency_factor = 105,
+ .bw_inefficiency_factor = 120,
+};
+
static const struct dpu_perf_cfg sc7280_perf_data = {
.max_bw_low = 4700000,
.max_bw_high = 8800000,
@@ -1767,6 +2458,36 @@ static const struct dpu_perf_cfg sc7280_perf_data = {
.bw_inefficiency_factor = 120,
};
+static const struct dpu_perf_cfg sm8350_perf_data = {
+ .max_bw_low = 11800000,
+ .max_bw_high = 15500000,
+ .min_core_ib = 2500000,
+ .min_llcc_ib = 0,
+ .min_dram_ib = 800000,
+ .min_prefill_lines = 40,
+ /* FIXME: lut tables */
+ .danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+ .safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+ .qos_lut_tbl = {
+ {.nentry = ARRAY_SIZE(sc7180_qos_linear),
+ .entries = sc7180_qos_linear
+ },
+ {.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+ .entries = sc7180_qos_macrotile
+ },
+ {.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+ .entries = sc7180_qos_nrt
+ },
+ /* TODO: macrotile-qseed is different from macrotile */
+ },
+ .cdp_cfg = {
+ {.rd_enable = 1, .wr_enable = 1},
+ {.rd_enable = 1, .wr_enable = 0}
+ },
+ .clk_inefficiency_factor = 105,
+ .bw_inefficiency_factor = 120,
+};
+
static const struct dpu_perf_cfg qcm2290_perf_data = {
.max_bw_low = 2700000,
.max_bw_high = 2700000,
@@ -1899,6 +2620,8 @@ static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
.mixer = sm8150_lm,
.dspp_count = ARRAY_SIZE(sm8150_dspp),
.dspp = sm8150_dspp,
+ .dsc_count = ARRAY_SIZE(sm8150_dsc),
+ .dsc = sm8150_dsc,
.pingpong_count = ARRAY_SIZE(sm8150_pp),
.pingpong = sm8150_pp,
.merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
@@ -1937,6 +2660,32 @@ static const struct dpu_mdss_cfg sc8180x_dpu_cfg = {
.mdss_irqs = IRQ_SC8180X_MASK,
};
+static const struct dpu_mdss_cfg sc8280xp_dpu_cfg = {
+ .caps = &sc8280xp_dpu_caps,
+ .mdp_count = ARRAY_SIZE(sc8280xp_mdp),
+ .mdp = sc8280xp_mdp,
+ .ctl_count = ARRAY_SIZE(sc8280xp_ctl),
+ .ctl = sc8280xp_ctl,
+ .sspp_count = ARRAY_SIZE(sc8280xp_sspp),
+ .sspp = sc8280xp_sspp,
+ .mixer_count = ARRAY_SIZE(sc8280xp_lm),
+ .mixer = sc8280xp_lm,
+ .dspp_count = ARRAY_SIZE(sm8150_dspp),
+ .dspp = sm8150_dspp,
+ .pingpong_count = ARRAY_SIZE(sc8280xp_pp),
+ .pingpong = sc8280xp_pp,
+ .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d),
+ .merge_3d = sm8350_merge_3d,
+ .intf_count = ARRAY_SIZE(sc8280xp_intf),
+ .intf = sc8280xp_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+ .reg_dma_count = 1,
+ .dma_cfg = &sc8280xp_regdma,
+ .perf = &sc8280xp_perf_data,
+ .mdss_irqs = IRQ_SC8280XP_MASK,
+};
+
static const struct dpu_mdss_cfg sm8250_dpu_cfg = {
.caps = &sm8250_dpu_caps,
.mdp_count = ARRAY_SIZE(sm8250_mdp),
@@ -1949,6 +2698,8 @@ static const struct dpu_mdss_cfg sm8250_dpu_cfg = {
.mixer = sm8150_lm,
.dspp_count = ARRAY_SIZE(sm8150_dspp),
.dspp = sm8150_dspp,
+ .dsc_count = ARRAY_SIZE(sm8150_dsc),
+ .dsc = sm8150_dsc,
.pingpong_count = ARRAY_SIZE(sm8150_pp),
.pingpong = sm8150_pp,
.merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
@@ -1965,6 +2716,84 @@ static const struct dpu_mdss_cfg sm8250_dpu_cfg = {
.mdss_irqs = IRQ_SM8250_MASK,
};
+static const struct dpu_mdss_cfg sm8350_dpu_cfg = {
+ .caps = &sm8350_dpu_caps,
+ .mdp_count = ARRAY_SIZE(sm8350_mdp),
+ .mdp = sm8350_mdp,
+ .ctl_count = ARRAY_SIZE(sm8350_ctl),
+ .ctl = sm8350_ctl,
+ .sspp_count = ARRAY_SIZE(sm8250_sspp),
+ .sspp = sm8250_sspp,
+ .mixer_count = ARRAY_SIZE(sm8150_lm),
+ .mixer = sm8150_lm,
+ .dspp_count = ARRAY_SIZE(sm8150_dspp),
+ .dspp = sm8150_dspp,
+ .pingpong_count = ARRAY_SIZE(sm8350_pp),
+ .pingpong = sm8350_pp,
+ .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d),
+ .merge_3d = sm8350_merge_3d,
+ .intf_count = ARRAY_SIZE(sm8350_intf),
+ .intf = sm8350_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+ .reg_dma_count = 1,
+ .dma_cfg = &sm8350_regdma,
+ .perf = &sm8350_perf_data,
+ .mdss_irqs = IRQ_SM8350_MASK,
+};
+
+static const struct dpu_mdss_cfg sm8450_dpu_cfg = {
+ .caps = &sm8450_dpu_caps,
+ .mdp_count = ARRAY_SIZE(sm8450_mdp),
+ .mdp = sm8450_mdp,
+ .ctl_count = ARRAY_SIZE(sm8450_ctl),
+ .ctl = sm8450_ctl,
+ .sspp_count = ARRAY_SIZE(sm8450_sspp),
+ .sspp = sm8450_sspp,
+ .mixer_count = ARRAY_SIZE(sm8150_lm),
+ .mixer = sm8150_lm,
+ .dspp_count = ARRAY_SIZE(sm8150_dspp),
+ .dspp = sm8150_dspp,
+ .pingpong_count = ARRAY_SIZE(sm8450_pp),
+ .pingpong = sm8450_pp,
+ .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d),
+ .merge_3d = sm8450_merge_3d,
+ .intf_count = ARRAY_SIZE(sm8450_intf),
+ .intf = sm8450_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+ .reg_dma_count = 1,
+ .dma_cfg = &sm8450_regdma,
+ .perf = &sm8450_perf_data,
+ .mdss_irqs = IRQ_SM8450_MASK,
+};
+
+static const struct dpu_mdss_cfg sm8550_dpu_cfg = {
+ .caps = &sm8550_dpu_caps,
+ .mdp_count = ARRAY_SIZE(sm8550_mdp),
+ .mdp = sm8550_mdp,
+ .ctl_count = ARRAY_SIZE(sm8550_ctl),
+ .ctl = sm8550_ctl,
+ .sspp_count = ARRAY_SIZE(sm8550_sspp),
+ .sspp = sm8550_sspp,
+ .mixer_count = ARRAY_SIZE(sm8150_lm),
+ .mixer = sm8150_lm,
+ .dspp_count = ARRAY_SIZE(sm8150_dspp),
+ .dspp = sm8150_dspp,
+ .pingpong_count = ARRAY_SIZE(sm8550_pp),
+ .pingpong = sm8550_pp,
+ .merge_3d_count = ARRAY_SIZE(sm8550_merge_3d),
+ .merge_3d = sm8550_merge_3d,
+ .intf_count = ARRAY_SIZE(sm8550_intf),
+ .intf = sm8550_intf,
+ .vbif_count = ARRAY_SIZE(sdm845_vbif),
+ .vbif = sdm845_vbif,
+ .reg_dma_count = 1,
+ .dma_cfg = &sm8450_regdma,
+ .perf = &sm8450_perf_data,
+ .mdss_irqs = IRQ_SM8450_MASK,
+};
+
static const struct dpu_mdss_cfg sc7280_dpu_cfg = {
.caps = &sc7280_dpu_caps,
.mdp_count = ARRAY_SIZE(sc7280_mdp),
@@ -2023,7 +2852,11 @@ static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
{ .hw_rev = DPU_HW_VER_620, .dpu_cfg = &sc7180_dpu_cfg},
{ .hw_rev = DPU_HW_VER_630, .dpu_cfg = &sm6115_dpu_cfg},
{ .hw_rev = DPU_HW_VER_650, .dpu_cfg = &qcm2290_dpu_cfg},
+ { .hw_rev = DPU_HW_VER_700, .dpu_cfg = &sm8350_dpu_cfg},
{ .hw_rev = DPU_HW_VER_720, .dpu_cfg = &sc7280_dpu_cfg},
+ { .hw_rev = DPU_HW_VER_800, .dpu_cfg = &sc8280xp_dpu_cfg},
+ { .hw_rev = DPU_HW_VER_810, .dpu_cfg = &sm8450_dpu_cfg},
+ { .hw_rev = DPU_HW_VER_900, .dpu_cfg = &sm8550_dpu_cfg},
};
const struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev)
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 3b645d5aa9aa..978e3bd145f0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -46,7 +46,11 @@
#define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */
#define DPU_HW_VER_630 DPU_HW_VER(6, 3, 0) /* sm6115|sm4250 */
#define DPU_HW_VER_650 DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */
+#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350 */
#define DPU_HW_VER_720 DPU_HW_VER(7, 2, 0) /* sc7280 */
+#define DPU_HW_VER_800 DPU_HW_VER(8, 0, 0) /* sc8280xp */
+#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450 */
+#define DPU_HW_VER_900 DPU_HW_VER(9, 0, 0) /* sm8550 */
#define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170)
#define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300)
@@ -83,6 +87,8 @@ enum {
* @DPU_MDP_UBWC_1_0, This chipsets supports Universal Bandwidth
* compression initial revision
* @DPU_MDP_UBWC_1_5, Universal Bandwidth compression version 1.5
+ * @DPU_MDP_PERIPH_0_REMOVED Indicates that access to periph top0 block results
+ * in a failure
* @DPU_MDP_MAX Maximum value
*/
@@ -93,6 +99,7 @@ enum {
DPU_MDP_UBWC_1_0,
DPU_MDP_UBWC_1_5,
DPU_MDP_AUDIO_SELECT,
+ DPU_MDP_PERIPH_0_REMOVED,
DPU_MDP_MAX
};
@@ -192,6 +199,7 @@ enum {
* @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs
+ * @DPU_CTL_HAS_LAYER_EXT4: CTL has the CTL_LAYER_EXT4 register
* @DPU_CTL_MAX
*/
enum {
@@ -199,6 +207,7 @@ enum {
DPU_CTL_ACTIVE_CFG,
DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG,
+ DPU_CTL_HAS_LAYER_EXT4,
DPU_CTL_MAX
};
@@ -267,6 +276,15 @@ enum {
};
/**
+ * DSC features
+ * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets
+ * the pixel output from this DSC.
+ */
+enum {
+ DPU_DSC_OUTPUT_CTRL = 0x1,
+};
+
+/**
* MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU
* @name: string name for debug purposes
* @id: enum identifying this block
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 a35ecb6676c8..b88a2f3724e6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -17,6 +17,8 @@
(0x70 + (((lm) - LM_0) * 0x004))
#define CTL_LAYER_EXT3(lm) \
(0xA0 + (((lm) - LM_0) * 0x004))
+#define CTL_LAYER_EXT4(lm) \
+ (0xB8 + (((lm) - LM_0) * 0x004))
#define CTL_TOP 0x014
#define CTL_FLUSH 0x018
#define CTL_START 0x01C
@@ -377,12 +379,37 @@ static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx)
DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
}
+struct ctl_blend_config {
+ int idx, shift, ext_shift;
+};
+
+static const struct ctl_blend_config ctl_blend_config[][2] = {
+ [SSPP_NONE] = { { -1 }, { -1 } },
+ [SSPP_MAX] = { { -1 }, { -1 } },
+ [SSPP_VIG0] = { { 0, 0, 0 }, { 3, 0 } },
+ [SSPP_VIG1] = { { 0, 3, 2 }, { 3, 4 } },
+ [SSPP_VIG2] = { { 0, 6, 4 }, { 3, 8 } },
+ [SSPP_VIG3] = { { 0, 26, 6 }, { 3, 12 } },
+ [SSPP_RGB0] = { { 0, 9, 8 }, { -1 } },
+ [SSPP_RGB1] = { { 0, 12, 10 }, { -1 } },
+ [SSPP_RGB2] = { { 0, 15, 12 }, { -1 } },
+ [SSPP_RGB3] = { { 0, 29, 14 }, { -1 } },
+ [SSPP_DMA0] = { { 0, 18, 16 }, { 2, 8 } },
+ [SSPP_DMA1] = { { 0, 21, 18 }, { 2, 12 } },
+ [SSPP_DMA2] = { { 2, 0 }, { 2, 16 } },
+ [SSPP_DMA3] = { { 2, 4 }, { 2, 20 } },
+ [SSPP_DMA4] = { { 4, 0 }, { 4, 8 } },
+ [SSPP_DMA5] = { { 4, 4 }, { 4, 12 } },
+ [SSPP_CURSOR0] = { { 1, 20 }, { -1 } },
+ [SSPP_CURSOR1] = { { 1, 26 }, { -1 } },
+};
+
static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
- u32 mixercfg = 0, mixercfg_ext = 0, mix, ext;
- u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0;
+ u32 mix, ext, mix_ext;
+ u32 mixercfg[5] = { 0 };
int i, j;
int stages;
int pipes_per_stage;
@@ -397,7 +424,7 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
else
pipes_per_stage = 1;
- mixercfg = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
+ mixercfg[0] = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
if (!stage_cfg)
goto exit;
@@ -406,109 +433,35 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
/* overflow to ext register if 'i + 1 > 7' */
mix = (i + 1) & 0x7;
ext = i >= 7;
+ mix_ext = (i + 1) & 0xf;
for (j = 0 ; j < pipes_per_stage; j++) {
enum dpu_sspp_multirect_index rect_index =
stage_cfg->multirect_index[i][j];
-
- switch (stage_cfg->stage[i][j]) {
- case SSPP_VIG0:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext3 |= ((i + 1) & 0xF) << 0;
- } else {
- mixercfg |= mix << 0;
- mixercfg_ext |= ext << 0;
- }
- break;
- case SSPP_VIG1:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext3 |= ((i + 1) & 0xF) << 4;
- } else {
- mixercfg |= mix << 3;
- mixercfg_ext |= ext << 2;
- }
- break;
- case SSPP_VIG2:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext3 |= ((i + 1) & 0xF) << 8;
- } else {
- mixercfg |= mix << 6;
- mixercfg_ext |= ext << 4;
- }
- break;
- case SSPP_VIG3:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext3 |= ((i + 1) & 0xF) << 12;
- } else {
- mixercfg |= mix << 26;
- mixercfg_ext |= ext << 6;
- }
- break;
- case SSPP_RGB0:
- mixercfg |= mix << 9;
- mixercfg_ext |= ext << 8;
- break;
- case SSPP_RGB1:
- mixercfg |= mix << 12;
- mixercfg_ext |= ext << 10;
- break;
- case SSPP_RGB2:
- mixercfg |= mix << 15;
- mixercfg_ext |= ext << 12;
- break;
- case SSPP_RGB3:
- mixercfg |= mix << 29;
- mixercfg_ext |= ext << 14;
- break;
- case SSPP_DMA0:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext2 |= ((i + 1) & 0xF) << 8;
- } else {
- mixercfg |= mix << 18;
- mixercfg_ext |= ext << 16;
- }
- break;
- case SSPP_DMA1:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext2 |= ((i + 1) & 0xF) << 12;
- } else {
- mixercfg |= mix << 21;
- mixercfg_ext |= ext << 18;
- }
- break;
- case SSPP_DMA2:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext2 |= ((i + 1) & 0xF) << 16;
- } else {
- mix |= (i + 1) & 0xF;
- mixercfg_ext2 |= mix << 0;
- }
- break;
- case SSPP_DMA3:
- if (rect_index == DPU_SSPP_RECT_1) {
- mixercfg_ext2 |= ((i + 1) & 0xF) << 20;
- } else {
- mix |= (i + 1) & 0xF;
- mixercfg_ext2 |= mix << 4;
- }
- break;
- case SSPP_CURSOR0:
- mixercfg_ext |= ((i + 1) & 0xF) << 20;
- break;
- case SSPP_CURSOR1:
- mixercfg_ext |= ((i + 1) & 0xF) << 26;
- break;
- default:
- break;
+ enum dpu_sspp pipe = stage_cfg->stage[i][j];
+ const struct ctl_blend_config *cfg =
+ &ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1];
+
+ /*
+ * CTL_LAYER has 3-bit field (and extra bits in EXT register),
+ * all EXT registers has 4-bit fields.
+ */
+ if (cfg->idx == 0) {
+ mixercfg[0] |= mix << cfg->shift;
+ mixercfg[1] |= ext << cfg->ext_shift;
+ } else {
+ mixercfg[cfg->idx] |= mix_ext << cfg->shift;
}
}
}
exit:
- DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg);
- DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext);
- DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2);
- DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3);
+ DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]);
+ DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]);
+ DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]);
+ DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]);
+ if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features)))
+ DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]);
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
index 3662df698dae..619926da1441 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
@@ -29,6 +29,8 @@
#define DSC_RANGE_MAX_QP 0x0B0
#define DSC_RANGE_BPG_OFFSET 0x0EC
+#define DSC_CTL(m) (0x1800 - 0x3FC * (m - DSC_0))
+
static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
{
struct dpu_hw_blk_reg_map *c = &dsc->hw;
@@ -150,6 +152,29 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc,
}
}
+static void dpu_hw_dsc_bind_pingpong_blk(
+ struct dpu_hw_dsc *hw_dsc,
+ bool enable,
+ const enum dpu_pingpong pp)
+{
+ struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+ int mux_cfg = 0xF;
+ u32 dsc_ctl_offset;
+
+ dsc_ctl_offset = DSC_CTL(hw_dsc->idx);
+
+ if (enable)
+ mux_cfg = (pp - PINGPONG_0) & 0x7;
+
+ DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n",
+ enable ? "Binding" : "Unbinding",
+ hw_dsc->idx - DSC_0,
+ enable ? "to" : "from",
+ pp - PINGPONG_0);
+
+ DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg);
+}
+
static struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc,
const struct dpu_mdss_cfg *m,
void __iomem *addr,
@@ -174,6 +199,8 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops,
ops->dsc_disable = dpu_hw_dsc_disable;
ops->dsc_config = dpu_hw_dsc_config;
ops->dsc_config_thresh = dpu_hw_dsc_config_thresh;
+ if (cap & BIT(DPU_DSC_OUTPUT_CTRL))
+ ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk;
};
struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
index c0b77fe1a696..ae9b5db53d7f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
@@ -42,6 +42,10 @@ struct dpu_hw_dsc_ops {
*/
void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
struct drm_dsc_config *dsc);
+
+ void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc,
+ bool enable,
+ enum dpu_pingpong pp);
};
struct dpu_hw_dsc {
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 cf1b6d84c18a..53326f25e40e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -35,6 +35,9 @@
#define MDP_INTF_3_OFF_REV_7xxx 0x37000
#define MDP_INTF_4_OFF_REV_7xxx 0x38000
#define MDP_INTF_5_OFF_REV_7xxx 0x39000
+#define MDP_INTF_6_OFF_REV_7xxx 0x3a000
+#define MDP_INTF_7_OFF_REV_7xxx 0x3b000
+#define MDP_INTF_8_OFF_REV_7xxx 0x3c000
/**
* struct dpu_intr_reg - array of DPU register sets
@@ -139,6 +142,21 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_EN,
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_STATUS
},
+ [MDP_INTF6_7xxx_INTR] = {
+ MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_CLEAR,
+ MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_EN,
+ MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_STATUS
+ },
+ [MDP_INTF7_7xxx_INTR] = {
+ MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_CLEAR,
+ MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_EN,
+ MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_STATUS
+ },
+ [MDP_INTF8_7xxx_INTR] = {
+ MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_CLEAR,
+ MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_EN,
+ MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_STATUS
+ },
};
#define DPU_IRQ_REG(irq_idx) (irq_idx / 32)
@@ -252,9 +270,9 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
cache_irq_mask = intr->cache_irq_mask[reg_idx];
if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) {
- dbgstr = "DPU IRQ already set:";
+ dbgstr = "already ";
} else {
- dbgstr = "DPU IRQ enabled:";
+ dbgstr = "";
cache_irq_mask |= DPU_IRQ_MASK(irq_idx);
/* Cleaning any pending interrupt */
@@ -268,7 +286,7 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
}
- pr_debug("%s MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", dbgstr,
+ pr_debug("DPU IRQ %d %senabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", irq_idx, dbgstr,
DPU_IRQ_MASK(irq_idx), cache_irq_mask);
return 0;
@@ -301,9 +319,9 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
cache_irq_mask = intr->cache_irq_mask[reg_idx];
if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) {
- dbgstr = "DPU IRQ is already cleared:";
+ dbgstr = "already ";
} else {
- dbgstr = "DPU IRQ mask disable:";
+ dbgstr = "";
cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx);
/* Disable interrupts based on the new mask */
@@ -317,7 +335,7 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
}
- pr_debug("%s MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", dbgstr,
+ pr_debug("DPU IRQ %d %sdisabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", irq_idx, dbgstr,
DPU_IRQ_MASK(irq_idx), cache_irq_mask);
return 0;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
index 46443955443c..425465011c80 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
@@ -31,6 +31,9 @@ enum dpu_hw_intr_reg {
MDP_INTF3_7xxx_INTR,
MDP_INTF4_7xxx_INTR,
MDP_INTF5_7xxx_INTR,
+ MDP_INTF6_7xxx_INTR,
+ MDP_INTF7_7xxx_INTR,
+ MDP_INTF8_7xxx_INTR,
MDP_INTR_MAX,
};
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 d3b0ed0a9c6c..2d9192a6ce00 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -120,6 +120,8 @@ enum dpu_sspp {
SSPP_DMA1,
SSPP_DMA2,
SSPP_DMA3,
+ SSPP_DMA4,
+ SSPP_DMA5,
SSPP_CURSOR0,
SSPP_CURSOR1,
SSPP_MAX
@@ -195,6 +197,8 @@ enum dpu_pingpong {
PINGPONG_3,
PINGPONG_4,
PINGPONG_5,
+ PINGPONG_6,
+ PINGPONG_7,
PINGPONG_S0,
PINGPONG_MAX
};
@@ -203,6 +207,7 @@ enum dpu_merge_3d {
MERGE_3D_0 = 1,
MERGE_3D_1,
MERGE_3D_2,
+ MERGE_3D_3,
MERGE_3D_MAX
};
@@ -214,6 +219,8 @@ enum dpu_intf {
INTF_4,
INTF_5,
INTF_6,
+ INTF_7,
+ INTF_8,
INTF_MAX
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index c3110a25a30d..2bb02e17ee52 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -7,40 +7,17 @@
#include "dpu_hw_top.h"
#include "dpu_kms.h"
-#define SSPP_SPARE 0x28
-
#define FLD_SPLIT_DISPLAY_CMD BIT(1)
#define FLD_SMART_PANEL_FREE_RUN BIT(2)
#define FLD_INTF_1_SW_TRG_MUX BIT(4)
#define FLD_INTF_2_SW_TRG_MUX BIT(8)
#define FLD_TE_LINE_INTER_WATERLEVEL_MASK 0xFFFF
-#define DANGER_STATUS 0x360
-#define SAFE_STATUS 0x364
-
-#define TE_LINE_INTERVAL 0x3F4
-
#define TRAFFIC_SHAPER_EN BIT(31)
#define TRAFFIC_SHAPER_RD_CLIENT(num) (0x030 + (num * 4))
#define TRAFFIC_SHAPER_WR_CLIENT(num) (0x060 + (num * 4))
#define TRAFFIC_SHAPER_FIXPOINT_FACTOR 4
-#define MDP_WD_TIMER_0_CTL 0x380
-#define MDP_WD_TIMER_0_CTL2 0x384
-#define MDP_WD_TIMER_0_LOAD_VALUE 0x388
-#define MDP_WD_TIMER_1_CTL 0x390
-#define MDP_WD_TIMER_1_CTL2 0x394
-#define MDP_WD_TIMER_1_LOAD_VALUE 0x398
-#define MDP_WD_TIMER_2_CTL 0x420
-#define MDP_WD_TIMER_2_CTL2 0x424
-#define MDP_WD_TIMER_2_LOAD_VALUE 0x428
-#define MDP_WD_TIMER_3_CTL 0x430
-#define MDP_WD_TIMER_3_CTL2 0x434
-#define MDP_WD_TIMER_3_LOAD_VALUE 0x438
-#define MDP_WD_TIMER_4_CTL 0x440
-#define MDP_WD_TIMER_4_CTL2 0x444
-#define MDP_WD_TIMER_4_LOAD_VALUE 0x448
-
#define MDP_TICK_COUNT 16
#define XO_CLK_RATE 19200
#define MS_TICKS_IN_SEC 1000
@@ -48,8 +25,6 @@
#define CALCULATE_WD_LOAD_VALUE(fps) \
((uint32_t)((MS_TICKS_IN_SEC * XO_CLK_RATE)/(MDP_TICK_COUNT * fps)))
-#define DCE_SEL 0x450
-
static void dpu_hw_setup_split_pipe(struct dpu_hw_mdp *mdp,
struct split_pipe_cfg *cfg)
{
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
index c8156ed4b7fb..feb9a729844a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
@@ -16,6 +16,7 @@
#define INTR_CLEAR 0x018
#define INTR2_EN 0x008
#define INTR2_STATUS 0x00c
+#define SSPP_SPARE 0x028
#define INTR2_CLEAR 0x02c
#define HIST_INTR_EN 0x01c
#define HIST_INTR_STATUS 0x020
@@ -28,7 +29,15 @@
#define DSPP_IGC_COLOR0_RAM_LUTN 0x300
#define DSPP_IGC_COLOR1_RAM_LUTN 0x304
#define DSPP_IGC_COLOR2_RAM_LUTN 0x308
+#define DANGER_STATUS 0x360
+#define SAFE_STATUS 0x364
#define HW_EVENTS_CTL 0x37C
+#define MDP_WD_TIMER_0_CTL 0x380
+#define MDP_WD_TIMER_0_CTL2 0x384
+#define MDP_WD_TIMER_0_LOAD_VALUE 0x388
+#define MDP_WD_TIMER_1_CTL 0x390
+#define MDP_WD_TIMER_1_CTL2 0x394
+#define MDP_WD_TIMER_1_LOAD_VALUE 0x398
#define CLK_CTRL3 0x3A8
#define CLK_STATUS3 0x3AC
#define CLK_CTRL4 0x3B0
@@ -43,6 +52,18 @@
#define HDMI_DP_CORE_SELECT 0x408
#define MDP_OUT_CTL_0 0x410
#define MDP_VSYNC_SEL 0x414
+#define MDP_WD_TIMER_2_CTL 0x420
+#define MDP_WD_TIMER_2_CTL2 0x424
+#define MDP_WD_TIMER_2_LOAD_VALUE 0x428
+#define MDP_WD_TIMER_3_CTL 0x430
+#define MDP_WD_TIMER_3_CTL2 0x434
+#define MDP_WD_TIMER_3_LOAD_VALUE 0x438
+#define MDP_WD_TIMER_4_CTL 0x440
+#define MDP_WD_TIMER_4_CTL2 0x444
+#define MDP_WD_TIMER_4_LOAD_VALUE 0x448
#define DCE_SEL 0x450
+#define MDP_PERIPH_TOP0 MDP_WD_TIMER_0_CTL
+#define MDP_PERIPH_TOP0_END CLK_CTRL3
+
#endif /*_DPU_HWIO_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index b71199511a52..d612419118a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -927,8 +927,15 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k
msm_disp_snapshot_add_block(disp_state, cat->wb[i].len,
dpu_kms->mmio + cat->wb[i].base, "wb_%d", i);
- msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
- dpu_kms->mmio + cat->mdp[0].base, "top");
+ if (cat->mdp[0].features & BIT(DPU_MDP_PERIPH_0_REMOVED)) {
+ msm_disp_snapshot_add_block(disp_state, MDP_PERIPH_TOP0,
+ dpu_kms->mmio + cat->mdp[0].base, "top");
+ msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len - MDP_PERIPH_TOP0_END,
+ dpu_kms->mmio + cat->mdp[0].base + MDP_PERIPH_TOP0_END, "top_2");
+ } else {
+ msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
+ dpu_kms->mmio + cat->mdp[0].base, "top");
+ }
pm_runtime_put_sync(&dpu_kms->pdev->dev);
}
@@ -1292,9 +1299,13 @@ static const struct of_device_id dpu_dt_match[] = {
{ .compatible = "qcom,sc7180-dpu", },
{ .compatible = "qcom,sc7280-dpu", },
{ .compatible = "qcom,sc8180x-dpu", },
+ { .compatible = "qcom,sc8280xp-dpu", },
{ .compatible = "qcom,sm6115-dpu", },
{ .compatible = "qcom,sm8150-dpu", },
{ .compatible = "qcom,sm8250-dpu", },
+ { .compatible = "qcom,sm8350-dpu", },
+ { .compatible = "qcom,sm8450-dpu", },
+ { .compatible = "qcom,sm8550-dpu", },
{}
};
MODULE_DEVICE_TABLE(of, dpu_dt_match);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 73b3442e7467..396429e63756 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -496,6 +496,11 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
/* check if DSC required are allocated or not */
for (i = 0; i < num_dsc; i++) {
+ if (!rm->dsc_blks[i]) {
+ DPU_ERROR("DSC %d does not exist\n", i);
+ return -EIO;
+ }
+
if (global_state->dsc_to_enc_id[i]) {
DPU_ERROR("DSC %d is already allocated\n", i);
return -EIO;
@@ -543,8 +548,8 @@ static int _dpu_rm_populate_requirements(
{
reqs->topology = req_topology;
- DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",
- reqs->topology.num_lm, reqs->topology.num_enc,
+ DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
+ reqs->topology.num_lm, reqs->topology.num_dsc,
reqs->topology.num_intf);
return 0;
@@ -660,6 +665,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
blks_size, enc_id);
break;
}
+ if (!hw_blks[i]) {
+ DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
+ type, enc_id);
+ break;
+ }
blks[num_blks++] = hw_blks[i];
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
index 088ec990a2f2..2a5a68366582 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
@@ -70,6 +70,8 @@ int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
int rc = 0;
dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL);
+ if (!dpu_wb_conn)
+ return -ENOMEM;
drm_connector_helper_add(&dpu_wb_conn->base.base, &dpu_wb_conn_helper_funcs);
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c
index 4d49f3ba6a96..ddcdd5e87853 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c
@@ -69,8 +69,7 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
struct drm_device *dev = mdp4_kms->dev;
- struct msm_drm_private *priv = dev->dev_private;
- unsigned int id;
+ struct drm_crtc *crtc;
uint32_t status, enable;
enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE);
@@ -81,9 +80,9 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
mdp_dispatch_irqs(mdp_kms, status);
- for (id = 0; id < priv->num_crtcs; id++)
- if (status & mdp4_crtc_vblank(priv->crtcs[id]))
- drm_handle_vblank(dev, id);
+ drm_for_each_crtc(crtc, dev)
+ if (status & mdp4_crtc_vblank(crtc))
+ drm_crtc_handle_vblank(crtc);
return IRQ_HANDLED;
}
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c
index 9b4c8d92ff32..43443a435d59 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c
@@ -82,8 +82,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
struct drm_device *dev = mdp5_kms->dev;
- struct msm_drm_private *priv = dev->dev_private;
- unsigned int id;
+ struct drm_crtc *crtc;
uint32_t status, enable;
enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN);
@@ -94,9 +93,9 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
mdp_dispatch_irqs(mdp_kms, status);
- for (id = 0; id < priv->num_crtcs; id++)
- if (status & mdp5_crtc_vblank(priv->crtcs[id]))
- drm_handle_vblank(dev, id);
+ drm_for_each_crtc(crtc, dev)
+ if (status & mdp5_crtc_vblank(crtc))
+ drm_crtc_handle_vblank(crtc);
return IRQ_HANDLED;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index d030a93a08c3..cc3efed593aa 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -423,6 +423,10 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
isr = dp_catalog_aux_get_irq(aux->catalog);
+ /* no interrupts pending, return immediately */
+ if (!isr)
+ return;
+
if (!aux->cmd_busy)
return;
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 7ff60e5ff325..bde1a7ce442f 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -122,61 +122,64 @@ struct dp_display_private {
struct msm_dp_desc {
phys_addr_t io_start;
+ unsigned int id;
unsigned int connector_type;
bool wide_bus_en;
};
-struct msm_dp_config {
- const struct msm_dp_desc *descs;
- size_t num_descs;
-};
-
static const struct msm_dp_desc sc7180_dp_descs[] = {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
-};
-
-static const struct msm_dp_config sc7180_dp_cfg = {
- .descs = sc7180_dp_descs,
- .num_descs = ARRAY_SIZE(sc7180_dp_descs),
+ { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ {}
};
static const struct msm_dp_desc sc7280_dp_descs[] = {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
- [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
-};
-
-static const struct msm_dp_config sc7280_dp_cfg = {
- .descs = sc7280_dp_descs,
- .num_descs = ARRAY_SIZE(sc7280_dp_descs),
+ { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+ {}
};
static const struct msm_dp_desc sc8180x_dp_descs[] = {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
- [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
- [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP },
+ { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP },
+ {}
};
-static const struct msm_dp_config sc8180x_dp_cfg = {
- .descs = sc8180x_dp_descs,
- .num_descs = ARRAY_SIZE(sc8180x_dp_descs),
+static const struct msm_dp_desc sc8280xp_dp_descs[] = {
+ { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ { .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ {}
};
-static const struct msm_dp_desc sm8350_dp_descs[] = {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+static const struct msm_dp_desc sc8280xp_edp_descs[] = {
+ { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+ { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+ { .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+ { .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+ {}
};
-static const struct msm_dp_config sm8350_dp_cfg = {
- .descs = sm8350_dp_descs,
- .num_descs = ARRAY_SIZE(sm8350_dp_descs),
+static const struct msm_dp_desc sm8350_dp_descs[] = {
+ { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ {}
};
static const struct of_device_id dp_dt_match[] = {
- { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg },
- { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_cfg },
- { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_cfg },
- { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg },
- { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg },
- { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_cfg },
+ { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
+ { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
+ { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
+ { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_descs },
+ { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_descs },
+ { .compatible = "qcom,sc8280xp-dp", .data = &sc8280xp_dp_descs },
+ { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs },
+ { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
+ { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
{}
};
@@ -390,6 +393,10 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
struct edid *edid;
dp->panel->max_dp_lanes = dp->parser->max_dp_lanes;
+ dp->panel->max_dp_link_rate = dp->parser->max_dp_link_rate;
+
+ drm_dbg_dp(dp->drm_dev, "max_lanes=%d max_link_rate=%d\n",
+ dp->panel->max_dp_lanes, dp->panel->max_dp_link_rate);
rc = dp_panel_read_sink_caps(dp->panel, dp->dp_display.connector);
if (rc)
@@ -607,8 +614,10 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
}
/* enable HDP irq_hpd/replug interrupt */
- dp_catalog_hpd_config_intr(dp->catalog,
- DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true);
+ if (dp->dp_display.internal_hpd)
+ dp_catalog_hpd_config_intr(dp->catalog,
+ DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
+ true);
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state);
@@ -648,8 +657,10 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
dp->dp_display.connector_type, state);
/* disable irq_hpd/replug interrupts */
- dp_catalog_hpd_config_intr(dp->catalog,
- DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false);
+ if (dp->dp_display.internal_hpd)
+ dp_catalog_hpd_config_intr(dp->catalog,
+ DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
+ false);
/* unplugged, no more irq_hpd handle */
dp_del_event(dp, EV_IRQ_HPD_INT);
@@ -675,7 +686,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
}
/* disable HPD plug interrupts */
- dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
+ if (dp->dp_display.internal_hpd)
+ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
/*
* We don't need separate work for disconnect as
@@ -693,7 +705,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
dp_display_handle_plugged_change(&dp->dp_display, false);
/* enable HDP plug interrupt to prepare for next plugin */
- if (!dp->dp_display.is_edp)
+ if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
@@ -1078,8 +1090,8 @@ static void dp_display_config_hpd(struct dp_display_private *dp)
dp_display_host_init(dp);
dp_catalog_ctrl_hpd_config(dp->catalog);
- /* Enable plug and unplug interrupts only for external DisplayPort */
- if (!dp->dp_display.is_edp)
+ /* Enable plug and unplug interrupts only if requested */
+ if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog,
DP_DP_HPD_PLUG_INT_MASK |
DP_DP_HPD_UNPLUG_INT_MASK,
@@ -1262,10 +1274,9 @@ int dp_display_request_irq(struct msm_dp *dp_display)
return 0;
}
-static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev,
- unsigned int *id)
+static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev)
{
- const struct msm_dp_config *cfg = of_device_get_match_data(&pdev->dev);
+ const struct msm_dp_desc *descs = of_device_get_match_data(&pdev->dev);
struct resource *res;
int i;
@@ -1273,11 +1284,9 @@ static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pde
if (!res)
return NULL;
- for (i = 0; i < cfg->num_descs; i++) {
- if (cfg->descs[i].io_start == res->start) {
- *id = i;
- return &cfg->descs[i];
- }
+ for (i = 0; i < descs[i].io_start; i++) {
+ if (descs[i].io_start == res->start)
+ return &descs[i];
}
dev_err(&pdev->dev, "unknown displayport instance\n");
@@ -1299,12 +1308,13 @@ static int dp_display_probe(struct platform_device *pdev)
if (!dp)
return -ENOMEM;
- desc = dp_display_get_desc(pdev, &dp->id);
+ desc = dp_display_get_desc(pdev);
if (!desc)
return -EINVAL;
dp->pdev = pdev;
dp->name = "drm_dp";
+ dp->id = desc->id;
dp->dp_display.connector_type = desc->connector_type;
dp->wide_bus_en = desc->wide_bus_en;
dp->dp_display.is_edp =
@@ -1373,8 +1383,7 @@ static int dp_pm_resume(struct device *dev)
dp_catalog_ctrl_hpd_config(dp->catalog);
-
- if (!dp->dp_display.is_edp)
+ if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog,
DP_DP_HPD_PLUG_INT_MASK |
DP_DP_HPD_UNPLUG_INT_MASK,
@@ -1497,7 +1506,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
dp = container_of(dp_display, struct dp_display_private, dp_display);
if (!dp_display->is_edp)
- dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
+ dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
}
bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
@@ -1771,3 +1780,41 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
dp_display->dp_mode.h_active_low =
!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
}
+
+void dp_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
+ struct msm_dp *dp_display = dp_bridge->dp_display;
+
+ dp_display->internal_hpd = true;
+}
+
+void dp_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
+ struct msm_dp *dp_display = dp_bridge->dp_display;
+
+ dp_display->internal_hpd = false;
+}
+
+void dp_bridge_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
+ struct msm_dp *dp_display = dp_bridge->dp_display;
+ struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+ /* Without next_bridge interrupts are handled by the DP core directly */
+ if (dp_display->internal_hpd)
+ return;
+
+ if (!dp->core_initialized) {
+ drm_dbg_dp(dp->drm_dev, "not initialized\n");
+ return;
+ }
+
+ if (!dp_display->is_connected && status == connector_status_connected)
+ dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+ else if (dp_display->is_connected && status == connector_status_disconnected)
+ dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+}
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index dcedf021f7fe..371337d0fae2 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -21,6 +21,7 @@ struct msm_dp {
bool power_on;
unsigned int connector_type;
bool is_edp;
+ bool internal_hpd;
hdmi_codec_plugged_cb plugged_cb;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 6db82f9b03af..275370f21115 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -102,6 +102,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
.get_modes = dp_bridge_get_modes,
.detect = dp_bridge_detect,
.atomic_check = dp_bridge_atomic_check,
+ .hpd_enable = dp_bridge_hpd_enable,
+ .hpd_disable = dp_bridge_hpd_disable,
+ .hpd_notify = dp_bridge_hpd_notify,
};
struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 82035dbb0578..250f7c66201f 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -32,5 +32,9 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode);
+void dp_bridge_hpd_enable(struct drm_bridge *bridge);
+void dp_bridge_hpd_disable(struct drm_bridge *bridge);
+void dp_bridge_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status);
#endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 5149cebc93f6..1800d8963f8a 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -75,12 +75,13 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
link_info->rate = drm_dp_bw_code_to_link_rate(dpcd[DP_MAX_LINK_RATE]);
link_info->num_lanes = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+ /* Limit data lanes from data-lanes of endpoint property of dtsi */
if (link_info->num_lanes > dp_panel->max_dp_lanes)
link_info->num_lanes = dp_panel->max_dp_lanes;
- /* Limit support upto HBR2 until HBR3 support is added */
- if (link_info->rate >= (drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4)))
- link_info->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
+ /* Limit link rate from link-frequencies of endpoint property of dtsi */
+ if (link_info->rate > dp_panel->max_dp_link_rate)
+ link_info->rate = dp_panel->max_dp_link_rate;
drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index d861197ac1c8..f04d0210b5cd 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -50,6 +50,7 @@ struct dp_panel {
u32 vic;
u32 max_dp_lanes;
+ u32 max_dp_link_rate;
u32 max_bw_code;
};
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index dcbe893d66d7..7032dcc8842b 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -91,19 +91,53 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
return 0;
}
+static u32 dp_parser_link_frequencies(struct device_node *of_node)
+{
+ struct device_node *endpoint;
+ u64 frequency = 0;
+ int cnt;
+
+ endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
+ if (!endpoint)
+ return 0;
+
+ cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
+
+ if (cnt > 0)
+ of_property_read_u64_index(endpoint, "link-frequencies",
+ cnt - 1, &frequency);
+ of_node_put(endpoint);
+
+ do_div(frequency,
+ 10 * /* from symbol rate to link rate */
+ 1000); /* kbytes */
+
+ return frequency;
+}
+
static int dp_parser_misc(struct dp_parser *parser)
{
struct device_node *of_node = parser->pdev->dev.of_node;
- int len;
-
- len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
- if (len < 0) {
- DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n",
- DP_MAX_NUM_DP_LANES);
- len = DP_MAX_NUM_DP_LANES;
+ int cnt;
+
+ /*
+ * data-lanes is the property of dp_out endpoint
+ */
+ cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
+ if (cnt < 0) {
+ /* legacy code, data-lanes is the property of mdss_dp node */
+ cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
}
- parser->max_dp_lanes = len;
+ if (cnt > 0)
+ parser->max_dp_lanes = cnt;
+ else
+ parser->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
+
+ parser->max_dp_link_rate = dp_parser_link_frequencies(of_node);
+ if (!parser->max_dp_link_rate)
+ parser->max_dp_link_rate = DP_LINK_RATE_HBR2;
+
return 0;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index d30ab773db46..1f068626d445 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -15,6 +15,7 @@
#define DP_LABEL "MDSS DP DISPLAY"
#define DP_MAX_PIXEL_CLK_KHZ 675000
#define DP_MAX_NUM_DP_LANES 4
+#define DP_LINK_RATE_HBR2 540000 /* kbytes */
enum dp_pm_type {
DP_CORE_PM,
@@ -119,6 +120,7 @@ struct dp_parser {
struct dp_io io;
struct dp_display_data disp_data;
u32 max_dp_lanes;
+ u32 max_dp_link_rate;
struct drm_bridge *next_bridge;
int (*parse)(struct dp_parser *parser);
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 2a96b4fe7839..bd3763a5d723 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -118,6 +118,8 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
+unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
+ const struct drm_display_mode *mode);
int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
@@ -139,6 +141,7 @@ struct msm_dsi_phy_shared_timings {
u32 clk_post;
u32 clk_pre;
bool clk_pre_inc_by_2;
+ bool byte_intf_clk_div_2;
};
struct msm_dsi_phy_clk_request {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 7e97c239ed48..6d21f0b33411 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -181,6 +181,20 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.num_dsi = 2,
};
+static const struct regulator_bulk_data sm8550_dsi_regulators[] = {
+ { .supply = "vdda", .init_load_uA = 16800 }, /* 1.2 V */
+};
+
+static const struct msm_dsi_config sm8550_dsi_cfg = {
+ .io_offset = DSI_6G_REG_SHIFT,
+ .regulator_data = sm8550_dsi_regulators,
+ .num_regulators = ARRAY_SIZE(sm8550_dsi_regulators),
+ .bus_clk_names = dsi_sdm845_bus_clk_names,
+ .num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
+ .io_start = { 0xae94000, 0xae96000 },
+ .num_dsi = 2,
+};
+
static const struct regulator_bulk_data sc7180_dsi_regulators[] = {
{ .supply = "vdda", .init_load_uA = 21800 }, /* 1.2 V */
};
@@ -209,8 +223,8 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
.num_regulators = ARRAY_SIZE(sc7280_dsi_regulators),
.bus_clk_names = dsi_sc7280_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sc7280_bus_clk_names),
- .io_start = { 0xae94000 },
- .num_dsi = 1,
+ .io_start = { 0xae94000, 0xae96000 },
+ .num_dsi = 2,
};
static const char * const dsi_qcm2290_bus_clk_names[] = {
@@ -300,6 +314,10 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
&sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,
&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+ {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,
+ &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+ {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0,
+ &sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops},
};
const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index 8f04e685a74e..44be4a88aa83 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -25,6 +25,8 @@
#define MSM_DSI_6G_VER_MINOR_V2_4_0 0x20040000
#define MSM_DSI_6G_VER_MINOR_V2_4_1 0x20040001
#define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000
+#define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000
+#define MSM_DSI_6G_VER_MINOR_V2_7_0 0x20070000
#define MSM_DSI_V2_VER_MINOR_8064 0x0
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 89aadd3b3202..18fa30e1e858 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -122,6 +122,7 @@ struct msm_dsi_host {
struct clk *byte_intf_clk;
unsigned long byte_clk_rate;
+ unsigned long byte_intf_clk_rate;
unsigned long pixel_clk_rate;
unsigned long esc_clk_rate;
@@ -398,7 +399,6 @@ int msm_dsi_runtime_resume(struct device *dev)
int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
{
- unsigned long byte_intf_rate;
int ret;
DBG("Set clk rates: pclk=%d, byteclk=%lu",
@@ -418,13 +418,7 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
}
if (msm_host->byte_intf_clk) {
- /* For CPHY, byte_intf_clk is same as byte_clk */
- if (msm_host->cphy_mode)
- byte_intf_rate = msm_host->byte_clk_rate;
- else
- byte_intf_rate = msm_host->byte_clk_rate / 2;
-
- ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_rate);
+ ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n",
__func__, ret);
@@ -570,9 +564,8 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
clk_disable_unprepare(msm_host->byte_clk);
}
-static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi)
{
- struct drm_display_mode *mode = msm_host->mode;
unsigned long pclk_rate;
pclk_rate = mode->clock * 1000;
@@ -589,11 +582,13 @@ static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bo
return pclk_rate;
}
-static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
+ const struct drm_display_mode *mode)
{
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
u8 lanes = msm_host->lanes;
u32 bpp = dsi_get_bpp(msm_host->format);
- unsigned long pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi);
+ unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi);
u64 pclk_bpp = (u64)pclk_rate * bpp;
if (lanes == 0) {
@@ -607,8 +602,14 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
else
do_div(pclk_bpp, (8 * lanes));
- msm_host->pixel_clk_rate = pclk_rate;
- msm_host->byte_clk_rate = pclk_bpp;
+ return pclk_bpp;
+}
+
+static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+{
+ msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi);
+ msm_host->byte_clk_rate = dsi_byte_clk_get_rate(&msm_host->base, is_bonded_dsi,
+ msm_host->mode);
DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate,
msm_host->byte_clk_rate);
@@ -636,7 +637,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
dsi_calc_pclk(msm_host, is_bonded_dsi);
- pclk_bpp = (u64)dsi_get_pclk_rate(msm_host, is_bonded_dsi) * bpp;
+ pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp;
do_div(pclk_bpp, 8);
msm_host->src_clk_rate = pclk_bpp;
@@ -853,11 +854,12 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
*/
slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
- /* If slice_per_pkt is greater than slice_per_intf
+ /*
+ * If slice_count is greater than slice_per_intf
* then default to 1. This can happen during partial
* update.
*/
- if (slice_per_intf > dsc->slice_count)
+ if (dsc->slice_count > slice_per_intf)
dsc->slice_count = 1;
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
@@ -987,7 +989,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
if (!msm_host->dsc)
wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
else
- wc = mode->hdisplay / 2 + 1;
+ wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1;
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
@@ -1883,8 +1885,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
if (!msm_host) {
- ret = -ENOMEM;
- goto fail;
+ return -ENOMEM;
}
msm_host->pdev = pdev;
@@ -1893,31 +1894,28 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
ret = dsi_host_parse_dt(msm_host);
if (ret) {
pr_err("%s: failed to parse dt\n", __func__);
- goto fail;
+ return ret;
}
msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size);
if (IS_ERR(msm_host->ctrl_base)) {
pr_err("%s: unable to map Dsi ctrl base\n", __func__);
- ret = PTR_ERR(msm_host->ctrl_base);
- goto fail;
+ return PTR_ERR(msm_host->ctrl_base);
}
pm_runtime_enable(&pdev->dev);
msm_host->cfg_hnd = dsi_get_config(msm_host);
if (!msm_host->cfg_hnd) {
- ret = -EINVAL;
pr_err("%s: get config failed\n", __func__);
- goto fail;
+ return -EINVAL;
}
cfg = msm_host->cfg_hnd->cfg;
msm_host->id = dsi_host_get_id(msm_host);
if (msm_host->id < 0) {
- ret = msm_host->id;
pr_err("%s: unable to identify DSI host index\n", __func__);
- goto fail;
+ return msm_host->id;
}
/* fixup base address by io offset */
@@ -1927,19 +1925,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
cfg->regulator_data,
&msm_host->supplies);
if (ret)
- goto fail;
+ return ret;
ret = dsi_clk_init(msm_host);
if (ret) {
pr_err("%s: unable to initialize dsi clks\n", __func__);
- goto fail;
+ return ret;
}
msm_host->rx_buf = devm_kzalloc(&pdev->dev, SZ_4K, GFP_KERNEL);
if (!msm_host->rx_buf) {
- ret = -ENOMEM;
pr_err("%s: alloc rx temp buf failed\n", __func__);
- goto fail;
+ return -ENOMEM;
}
ret = devm_pm_opp_set_clkname(&pdev->dev, "byte");
@@ -1977,15 +1974,15 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
/* setup workqueue */
msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
+ if (!msm_host->workqueue)
+ return -ENOMEM;
+
INIT_WORK(&msm_host->err_work, dsi_err_worker);
msm_dsi->id = msm_host->id;
DBG("Dsi Host %d initialized", msm_host->id);
return 0;
-
-fail:
- return ret;
}
void msm_dsi_host_destroy(struct mipi_dsi_host *host)
@@ -2391,6 +2388,10 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret;
}
+ msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
+ if (phy_shared_timings->byte_intf_clk_div_2)
+ msm_host->byte_intf_clk_rate /= 2;
+
msm_dsi_sfpb_config(msm_host, true);
ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 3a1417397283..b20fddb534a7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -450,6 +450,25 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
int id = dsi_mgr_bridge_get_id(bridge);
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
struct mipi_dsi_host *host = msm_dsi->host;
+ struct platform_device *pdev = msm_dsi->pdev;
+ struct dev_pm_opp *opp;
+ unsigned long byte_clk_rate;
+
+ byte_clk_rate = dsi_byte_clk_get_rate(host, IS_BONDED_DSI(), mode);
+
+ /*
+ * fail all errors except -ENODEV as that could mean that opp
+ * table is not yet implemented
+ */
+ opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &byte_clk_rate);
+ if (IS_ERR(opp)) {
+ if (PTR_ERR(opp) == -ERANGE)
+ return MODE_CLOCK_RANGE;
+ else if (PTR_ERR(opp) != -ENODEV)
+ return MODE_ERROR;
+ } else {
+ dev_pm_opp_put(opp);
+ }
return msm_dsi_host_check_dsc(host, mode);
}
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index ee6051367679..bb09cbe8ff86 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -350,6 +350,8 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
timing->shared_timings.clk_pre_inc_by_2 = 0;
}
+ timing->shared_timings.byte_intf_clk_div_2 = true;
+
timing->ta_go = 3;
timing->ta_sure = 0;
timing->ta_get = 4;
@@ -454,6 +456,8 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
tmax = 255;
timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 10000) + tmin;
+ timing->shared_timings.byte_intf_clk_div_2 = true;
+
DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
timing->clk_zero, timing->clk_trail, timing->clk_prepare, timing->hs_exit,
@@ -569,6 +573,14 @@ static const struct of_device_id dsi_phy_dt_match[] = {
.data = &dsi_phy_7nm_8150_cfgs },
{ .compatible = "qcom,sc7280-dsi-phy-7nm",
.data = &dsi_phy_7nm_7280_cfgs },
+ { .compatible = "qcom,sm6375-dsi-phy-7nm",
+ .data = &dsi_phy_7nm_6375_cfgs },
+ { .compatible = "qcom,sm8350-dsi-phy-5nm",
+ .data = &dsi_phy_5nm_8350_cfgs },
+ { .compatible = "qcom,sm8450-dsi-phy-5nm",
+ .data = &dsi_phy_5nm_8450_cfgs },
+ { .compatible = "qcom,sm8550-dsi-phy-4nm",
+ .data = &dsi_phy_4nm_8550_cfgs },
#endif
{}
};
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
index 1096afedd616..7137a17ae523 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
@@ -55,8 +55,12 @@ extern const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;
struct msm_dsi_dphy_timing {
u32 clk_zero;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
index 9e7fa7d88ead..3b1ed02f644d 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
@@ -39,8 +39,16 @@
#define VCO_REF_CLK_RATE 19200000
#define FRAC_BITS 18
+/* Hardware is pre V4.1 */
+#define DSI_PHY_7NM_QUIRK_PRE_V4_1 BIT(0)
/* Hardware is V4.1 */
-#define DSI_PHY_7NM_QUIRK_V4_1 BIT(0)
+#define DSI_PHY_7NM_QUIRK_V4_1 BIT(1)
+/* Hardware is V4.2 */
+#define DSI_PHY_7NM_QUIRK_V4_2 BIT(2)
+/* Hardware is V4.3 */
+#define DSI_PHY_7NM_QUIRK_V4_3 BIT(3)
+/* Hardware is V5.2 */
+#define DSI_PHY_7NM_QUIRK_V5_2 BIT(4)
struct dsi_pll_config {
bool enable_ssc;
@@ -116,16 +124,27 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config
dec_multiple = div_u64(pll_freq * multiplier, divider);
dec = div_u64_rem(dec_multiple, multiplier, &frac);
- if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
+ if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)
config->pll_clock_inverters = 0x28;
- else if (pll_freq <= 1000000000ULL)
- config->pll_clock_inverters = 0xa0;
- else if (pll_freq <= 2500000000ULL)
- config->pll_clock_inverters = 0x20;
- else if (pll_freq <= 3020000000ULL)
- config->pll_clock_inverters = 0x00;
- else
- config->pll_clock_inverters = 0x40;
+ else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+ if (pll_freq <= 1300000000ULL)
+ config->pll_clock_inverters = 0xa0;
+ else if (pll_freq <= 2500000000ULL)
+ config->pll_clock_inverters = 0x20;
+ else if (pll_freq <= 4000000000ULL)
+ config->pll_clock_inverters = 0x00;
+ else
+ config->pll_clock_inverters = 0x40;
+ } else {
+ if (pll_freq <= 1000000000ULL)
+ config->pll_clock_inverters = 0xa0;
+ else if (pll_freq <= 2500000000ULL)
+ config->pll_clock_inverters = 0x20;
+ else if (pll_freq <= 3020000000ULL)
+ config->pll_clock_inverters = 0x00;
+ else
+ config->pll_clock_inverters = 0x40;
+ }
config->decimal_div_start = dec;
config->frac_div_start = frac;
@@ -197,16 +216,32 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
void __iomem *base = pll->phy->pll_base;
u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
- if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+ if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))
if (pll->vco_current_rate >= 3100000000ULL)
analog_controls_five_1 = 0x03;
+ if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
if (pll->vco_current_rate < 1520000000ULL)
vco_config_1 = 0x08;
else if (pll->vco_current_rate < 2990000000ULL)
vco_config_1 = 0x01;
}
+ if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) ||
+ (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {
+ if (pll->vco_current_rate < 1520000000ULL)
+ vco_config_1 = 0x08;
+ else if (pll->vco_current_rate >= 2990000000ULL)
+ vco_config_1 = 0x01;
+ }
+
+ if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+ if (pll->vco_current_rate < 1557000000ULL)
+ vco_config_1 = 0x08;
+ else
+ vco_config_1 = 0x01;
+ }
+
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
analog_controls_five_1);
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
@@ -231,9 +266,9 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
- pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22);
+ !(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) ? 0x3f : 0x22);
- if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+ if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)) {
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
if (pll->slave)
dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
@@ -788,7 +823,7 @@ static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)
const u8 *tx_dctrl = tx_dctrl_0;
void __iomem *lane_base = phy->lane_base;
- if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)
+ if (!(phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))
tx_dctrl = tx_dctrl_1;
/* Strength ctrl settings */
@@ -844,6 +879,13 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
if (dsi_phy_hw_v4_0_is_pll_on(phy))
pr_warn("PLL turned on before configuring PHY\n");
+ /* Request for REFGEN READY */
+ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||
+ (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+ dsi_phy_write(phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x1);
+ udelay(500);
+ }
+
/* wait for REFGEN READY */
ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,
status, (status & BIT(0)),
@@ -858,23 +900,64 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
/* Alter PHY configurations if data rate less than 1.5GHZ*/
less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);
- if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+ glbl_str_swi_cal_sel_ctrl = 0x00;
+ if (phy->cphy_mode) {
+ vreg_ctrl_0 = 0x51;
+ vreg_ctrl_1 = 0x55;
+ glbl_hstx_str_ctrl_0 = 0x00;
+ glbl_pemph_ctrl_0 = 0x11;
+ lane_ctrl0 = 0x17;
+ } else {
vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
+ vreg_ctrl_1 = 0x5c;
+ glbl_hstx_str_ctrl_0 = 0x88;
+ glbl_pemph_ctrl_0 = 0x00;
+ lane_ctrl0 = 0x1f;
+ }
+
+ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
if (phy->cphy_mode) {
+ vreg_ctrl_0 = 0x45;
+ vreg_ctrl_1 = 0x45;
+ glbl_rescode_top_ctrl = 0x00;
+ glbl_rescode_bot_ctrl = 0x00;
+ } else {
+ vreg_ctrl_0 = 0x44;
+ vreg_ctrl_1 = 0x19;
+ glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c : 0x03;
+ glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x3c;
+ }
+ } else if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {
+ if (phy->cphy_mode) {
+ glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01;
+ glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x3b;
+ } else {
+ glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01;
+ glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x39;
+ }
+ } else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) {
+ if (phy->cphy_mode) {
+ glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01;
+ glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x3b;
+ } else {
+ glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c : 0x00;
+ glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x39;
+ }
+ } else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+ if (phy->cphy_mode) {
+ glbl_hstx_str_ctrl_0 = 0x88;
glbl_rescode_top_ctrl = 0x00;
glbl_rescode_bot_ctrl = 0x3c;
} else {
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00;
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c;
}
- glbl_str_swi_cal_sel_ctrl = 0x00;
- glbl_hstx_str_ctrl_0 = 0x88;
} else {
- vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
if (phy->cphy_mode) {
glbl_str_swi_cal_sel_ctrl = 0x03;
glbl_hstx_str_ctrl_0 = 0x66;
} else {
+ vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;
}
@@ -882,17 +965,6 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
glbl_rescode_bot_ctrl = 0x3c;
}
- if (phy->cphy_mode) {
- vreg_ctrl_0 = 0x51;
- vreg_ctrl_1 = 0x55;
- glbl_pemph_ctrl_0 = 0x11;
- lane_ctrl0 = 0x17;
- } else {
- vreg_ctrl_1 = 0x5c;
- glbl_pemph_ctrl_0 = 0x00;
- lane_ctrl0 = 0x1f;
- }
-
/* de-assert digital and pll power down */
data = BIT(6) | BIT(5);
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
@@ -904,9 +976,8 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00);
/* program CMN_CTRL_4 for minor_ver 2 chipsets*/
- data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0);
- data = data & (0xf0);
- if (data == 0x20)
+ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) ||
+ (dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20)
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04);
/* Configure PHY lane swap (TODO: we need to calculate this) */
@@ -1017,6 +1088,16 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
pr_warn("Turning OFF PHY while PLL is on\n");
dsi_phy_hw_v4_0_config_lpcdrx(phy, false);
+
+ /* Turn off REFGEN Vote */
+ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||
+ (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+ dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x0);
+ wmb();
+ /* Delay to ensure HW removes vote before PHY shut down */
+ udelay(2);
+ }
+
data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_CTRL_0);
/* disable all lanes */
@@ -1040,6 +1121,14 @@ static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = {
{ .supply = "vdds", .init_load_uA = 37550 },
};
+static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = {
+ { .supply = "vdds", .init_load_uA = 97800 },
+};
+
+static const struct regulator_bulk_data dsi_phy_7nm_98400uA_regulators[] = {
+ { .supply = "vdds", .init_load_uA = 98400 },
+};
+
const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
.has_phy_lane = true,
.regulator_data = dsi_phy_7nm_36mA_regulators,
@@ -1063,6 +1152,26 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
.quirks = DSI_PHY_7NM_QUIRK_V4_1,
};
+const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs = {
+ .has_phy_lane = true,
+ .ops = {
+ .enable = dsi_7nm_phy_enable,
+ .disable = dsi_7nm_phy_disable,
+ .pll_init = dsi_pll_7nm_init,
+ .save_pll_state = dsi_7nm_pll_save_state,
+ .restore_pll_state = dsi_7nm_pll_restore_state,
+ },
+ .min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+ .max_pll_rate = 5000000000ULL,
+#else
+ .max_pll_rate = ULONG_MAX,
+#endif
+ .io_start = { 0x5e94400 },
+ .num_dsi_phy = 1,
+ .quirks = DSI_PHY_7NM_QUIRK_V4_1,
+};
+
const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
.has_phy_lane = true,
.regulator_data = dsi_phy_7nm_36mA_regulators,
@@ -1079,6 +1188,7 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
.max_pll_rate = 3500000000UL,
.io_start = { 0xae94400, 0xae96400 },
.num_dsi_phy = 2,
+ .quirks = DSI_PHY_7NM_QUIRK_PRE_V4_1,
};
const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
@@ -1102,3 +1212,72 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
.num_dsi_phy = 1,
.quirks = DSI_PHY_7NM_QUIRK_V4_1,
};
+
+const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs = {
+ .has_phy_lane = true,
+ .regulator_data = dsi_phy_7nm_37750uA_regulators,
+ .num_regulators = ARRAY_SIZE(dsi_phy_7nm_37750uA_regulators),
+ .ops = {
+ .enable = dsi_7nm_phy_enable,
+ .disable = dsi_7nm_phy_disable,
+ .pll_init = dsi_pll_7nm_init,
+ .save_pll_state = dsi_7nm_pll_save_state,
+ .restore_pll_state = dsi_7nm_pll_restore_state,
+ .set_continuous_clock = dsi_7nm_set_continuous_clock,
+ },
+ .min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+ .max_pll_rate = 5000000000UL,
+#else
+ .max_pll_rate = ULONG_MAX,
+#endif
+ .io_start = { 0xae94400, 0xae96400 },
+ .num_dsi_phy = 2,
+ .quirks = DSI_PHY_7NM_QUIRK_V4_2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {
+ .has_phy_lane = true,
+ .regulator_data = dsi_phy_7nm_97800uA_regulators,
+ .num_regulators = ARRAY_SIZE(dsi_phy_7nm_97800uA_regulators),
+ .ops = {
+ .enable = dsi_7nm_phy_enable,
+ .disable = dsi_7nm_phy_disable,
+ .pll_init = dsi_pll_7nm_init,
+ .save_pll_state = dsi_7nm_pll_save_state,
+ .restore_pll_state = dsi_7nm_pll_restore_state,
+ .set_continuous_clock = dsi_7nm_set_continuous_clock,
+ },
+ .min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+ .max_pll_rate = 5000000000UL,
+#else
+ .max_pll_rate = ULONG_MAX,
+#endif
+ .io_start = { 0xae94400, 0xae96400 },
+ .num_dsi_phy = 2,
+ .quirks = DSI_PHY_7NM_QUIRK_V4_3,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {
+ .has_phy_lane = true,
+ .regulator_data = dsi_phy_7nm_98400uA_regulators,
+ .num_regulators = ARRAY_SIZE(dsi_phy_7nm_98400uA_regulators),
+ .ops = {
+ .enable = dsi_7nm_phy_enable,
+ .disable = dsi_7nm_phy_disable,
+ .pll_init = dsi_pll_7nm_init,
+ .save_pll_state = dsi_7nm_pll_save_state,
+ .restore_pll_state = dsi_7nm_pll_restore_state,
+ .set_continuous_clock = dsi_7nm_set_continuous_clock,
+ },
+ .min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+ .max_pll_rate = 5000000000UL,
+#else
+ .max_pll_rate = ULONG_MAX,
+#endif
+ .io_start = { 0xae95000, 0xae97000 },
+ .num_dsi_phy = 2,
+ .quirks = DSI_PHY_7NM_QUIRK_V5_2,
+};
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 4d3fdc806bef..4ad36bc8fe5e 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -120,6 +120,10 @@ static int msm_hdmi_init(struct hdmi *hdmi)
int ret;
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
+ if (!hdmi->workq) {
+ ret = -ENOMEM;
+ goto fail;
+ }
hdmi->i2c = msm_hdmi_i2c_init(hdmi);
if (IS_ERR(hdmi->i2c)) {
@@ -532,11 +536,19 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
ret = devm_pm_runtime_enable(&pdev->dev);
if (ret)
- return ret;
+ goto err_put_phy;
platform_set_drvdata(pdev, hdmi);
- return component_add(&pdev->dev, &msm_hdmi_ops);
+ ret = component_add(&pdev->dev, &msm_hdmi_ops);
+ if (ret)
+ goto err_put_phy;
+
+ return 0;
+
+err_put_phy:
+ msm_hdmi_put_phy(hdmi);
+ return ret;
}
static int msm_hdmi_dev_remove(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ff3a1ff423fc..aca48c868c14 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -420,6 +420,8 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
priv->dev = ddev;
priv->wq = alloc_ordered_workqueue("msm", 0);
+ if (!priv->wq)
+ return -ENOMEM;
INIT_LIST_HEAD(&priv->objects);
mutex_init(&priv->obj_lock);
@@ -493,7 +495,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
if (IS_ERR(priv->event_thread[i].worker)) {
ret = PTR_ERR(priv->event_thread[i].worker);
DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n");
- ret = PTR_ERR(priv->event_thread[i].worker);
+ priv->event_thread[i].worker = NULL;
goto err_msm_uninit;
}
@@ -1282,7 +1284,7 @@ void msm_drv_shutdown(struct platform_device *pdev)
* msm_drm_init, drm_dev->registered is used as an indicator that the
* shutdown will be successful.
*/
- if (drm && drm->registered)
+ if (drm && drm->registered && priv->kms)
drm_atomic_helper_shutdown(drm);
}
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 81deb112ea44..9f0c184b02a0 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -62,6 +62,7 @@ enum msm_dp_controller {
MSM_DP_CONTROLLER_0,
MSM_DP_CONTROLLER_1,
MSM_DP_CONTROLLER_2,
+ MSM_DP_CONTROLLER_3,
MSM_DP_CONTROLLER_COUNT,
};
@@ -83,14 +84,12 @@ enum msm_event_wait {
/**
* struct msm_display_topology - defines a display topology pipeline
* @num_lm: number of layer mixers used
- * @num_enc: number of compression encoder blocks used
* @num_intf: number of interfaces the panel is mounted on
* @num_dspp: number of dspp blocks used
* @num_dsc: number of Display Stream Compression (DSC) blocks used
*/
struct msm_display_topology {
u32 num_lm;
- u32 num_enc;
u32 num_intf;
u32 num_dspp;
u32 num_dsc;
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 1af7e7c613a6..be4bf77103cd 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -209,6 +209,10 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit,
goto out;
}
submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL);
+ if (!submit->cmd[i].relocs) {
+ ret = -ENOMEM;
+ goto out;
+ }
ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);
if (ret) {
ret = -EFAULT;
diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 86b28add1fff..02646e4bb4cd 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -47,15 +47,17 @@ struct msm_mdss {
static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
struct msm_mdss *msm_mdss)
{
- struct icc_path *path0 = of_icc_get(dev, "mdp0-mem");
- struct icc_path *path1 = of_icc_get(dev, "mdp1-mem");
+ struct icc_path *path0;
+ struct icc_path *path1;
+ path0 = of_icc_get(dev, "mdp0-mem");
if (IS_ERR_OR_NULL(path0))
return PTR_ERR_OR_ZERO(path0);
msm_mdss->path[0] = path0;
msm_mdss->num_paths = 1;
+ path1 = of_icc_get(dev, "mdp1-mem");
if (!IS_ERR_OR_NULL(path1)) {
msm_mdss->path[1] = path1;
msm_mdss->num_paths++;
@@ -284,9 +286,21 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)
/* UBWC_2_0 */
msm_mdss_setup_ubwc_dec_20(msm_mdss, 0x11f);
break;
+ case DPU_HW_VER_700:
+ /* TODO: highest_bank_bit = 2 for LP_DDR4 */
+ msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 3, 1);
+ break;
case DPU_HW_VER_720:
msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_3_0, 6, 1, 1, 1);
break;
+ case DPU_HW_VER_800:
+ msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 2, 1);
+ break;
+ case DPU_HW_VER_810:
+ case DPU_HW_VER_900:
+ /* TODO: highest_bank_bit = 2 for LP_DDR4 */
+ msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 3, 1);
+ break;
}
return ret;
@@ -513,9 +527,13 @@ static const struct of_device_id mdss_dt_match[] = {
{ .compatible = "qcom,sc7180-mdss" },
{ .compatible = "qcom,sc7280-mdss" },
{ .compatible = "qcom,sc8180x-mdss" },
+ { .compatible = "qcom,sc8280xp-mdss" },
{ .compatible = "qcom,sm6115-mdss" },
{ .compatible = "qcom,sm8150-mdss" },
{ .compatible = "qcom,sm8250-mdss" },
+ { .compatible = "qcom,sm8350-mdss" },
+ { .compatible = "qcom,sm8450-mdss" },
+ { .compatible = "qcom,sm8550-mdss" },
{}
};
MODULE_DEVICE_TABLE(of, mdss_dt_match);