Hello! Here's v3 (well, kind of v2/v3) I revved the dt-bindings in the meantime. Refer to [1] for all of the gory details on the driver. It's been baking in linux-next for ~week now and the outstanding dt-bindings changes are sorted, so I figured it's time for another try.
Note that I've removed both the dispcc and dts patches from v1. I'll wait for dispcc to land elsewhere and then add the dpu/mdss nodes to dts. For now, the dt-bindings will hopefully suffice.
Thanks,
Sean
[1]- https://lists.freedesktop.org/archives/dri-devel/2018-July/182681.html
Abhinav Kumar (2): drm/msm/dsi: set encoder mode for DRM bridge explicitly drm/msm: higher values of pclk can exceed 32 bits when multiplied by a factor
Chandan Uddaraju (2): drm/msm/dsi: adjust dsi timing for dual dsi mode drm/msm/dsi: Use one connector for dual DSI mode
Jeykumar Sankaran (10): dt-bindings: msm/dsi: Add mdp transfer time to msm dsi binding drm: add msm compressed format modifiers drm/msm: enable zpos normalization drm/msm: #define MDP version numbers drm/msm: Use labels for unwinding in the error path drm/msm: #define MAX_<OBJECT> in msm_drv.h drm/msm: Add .commit() callback to msm_kms functions drm/msm: Add pm_suspend/resume callbacks to msm_kms dt-bindings: msm/disp: Add bindings for Snapdragon 845 DPU drm/msm: Add SDM845 DPU support
Rajesh Yadav (2): drm/msm/dsi: initialize postdiv_lock before use for 10nm pll drm/msm/mdp5: subclass msm_mdss for mdp5
Sean Paul (2): drm/msm: Move wait_for_vblanks into mdp complete_commit() hooks drm/msm: Clean up dangling atomic_wq
vkorjani (1): drm: Add support for pps and compression mode command packet
.../devicetree/bindings/display/msm/dpu.txt | 131 + .../devicetree/bindings/display/msm/dsi.txt | 16 + drivers/gpu/drm/drm_mipi_dsi.c | 2 + drivers/gpu/drm/msm/Makefile | 32 +- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c | 479 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 153 + drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 637 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 133 + drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2504 ++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 484 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c | 2393 +++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h | 103 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2575 +++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 191 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 453 +++ .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 905 ++++++ .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 922 ++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 1276 ++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h | 136 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c | 155 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h | 53 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 511 ++++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 804 +++++ .../drm/msm/disp/dpu1/dpu_hw_catalog_format.h | 182 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c | 323 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h | 139 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 540 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 218 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 1183 ++++++++ .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 257 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 349 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 128 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 261 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 122 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 465 +++ .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 250 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 136 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 753 +++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 424 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 398 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 202 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 452 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 358 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c | 275 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h | 128 + drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h | 56 + drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c | 204 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h | 57 + drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c | 66 + drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h | 59 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1345 +++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 402 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c | 153 + drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 245 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 1963 +++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 175 ++ .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 249 ++ .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 225 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 1079 +++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 199 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 1007 +++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 384 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h | 94 + .../gpu/drm/msm/disp/dpu1/msm_media_info.h | 1376 +++++++++ drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 + drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 + drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 154 +- drivers/gpu/drm/msm/dsi/dsi.c | 3 + drivers/gpu/drm/msm/dsi/dsi.h | 11 +- drivers/gpu/drm/msm/dsi/dsi_cfg.h | 2 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 72 +- drivers/gpu/drm/msm/dsi/dsi_manager.c | 125 +- drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 2 + drivers/gpu/drm/msm/msm_atomic.c | 7 +- drivers/gpu/drm/msm/msm_drv.c | 221 +- drivers/gpu/drm/msm/msm_drv.h | 96 +- drivers/gpu/drm/msm/msm_kms.h | 29 +- include/uapi/drm/drm_fourcc.h | 37 + include/video/mipi_display.h | 3 + 79 files changed, 32453 insertions(+), 242 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/msm/dpu.txt create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h
From: Jeykumar Sankaran jsanka@codeaurora.org
Adds mdp transfer time to msm dsi binding
Changes in v3: - Added Rob's R-b
Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- .../devicetree/bindings/display/msm/dsi.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/msm/dsi.txt b/Documentation/devicetree/bindings/display/msm/dsi.txt index 518e9cdf0d4b..d22237a88eae 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi.txt +++ b/Documentation/devicetree/bindings/display/msm/dsi.txt @@ -121,6 +121,20 @@ Required properties: Optional properties: - qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY regulator is wanted. +- qcom,mdss-mdp-transfer-time-us: Specifies the dsi transfer time for command mode + panels in microseconds. Driver uses this number to adjust + the clock rate according to the expected transfer time. + Increasing this value would slow down the mdp processing + and can result in slower performance. + Decreasing this value can speed up the mdp processing, + but this can also impact power consumption. + As a rule this time should not be higher than the time + that would be expected with the processing at the + dsi link rate since anyways this would be the maximum + transfer time that could be achieved. + If ping pong split is enabled, this time should not be higher + than two times the dsi link rate time. + If the property is not specified, then the default value is 14000 us.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt [2] Documentation/devicetree/bindings/graph.txt @@ -171,6 +185,8 @@ Example: qcom,master-dsi; qcom,sync-dual-dsi;
+ qcom,mdss-mdp-transfer-time-us = <12000>; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&dsi_active>; pinctrl-1 = <&dsi_suspend>;
From: vkorjani vikas.korjani@intel.com
After enabling DSC we need to send compression mode command packet and pps data packet, for which 2 new data types are added 07h Compression Mode Data Type Write , short write, 2 parameters 0Ah PPS Long Write (word count determines number of bytes) This patch adds support to send these packets.
Cc: David Airlie airlied@linux.ie Cc: Jean-Christophe Plagniol-Villard plagnioj@jcrosoft.com Cc: Tomi Valkeinen tomi.valkeinen@ti.com Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: linux-fbdev@vger.kernel.org
Changes in v3: - None
Signed-off-by: vkorjani vikas.korjani@intel.com [seanpaul removed pps_write_buffer fn, added types to packet_format helpers] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/drm_mipi_dsi.c | 2 ++ include/video/mipi_display.h | 3 +++ 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index bc73b7f5b9fc..80b75501f5c6 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -392,6 +392,7 @@ bool mipi_dsi_packet_format_is_short(u8 type) case MIPI_DSI_DCS_SHORT_WRITE: case MIPI_DSI_DCS_SHORT_WRITE_PARAM: case MIPI_DSI_DCS_READ: + case MIPI_DSI_DCS_COMPRESSION_MODE: case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: return true; } @@ -410,6 +411,7 @@ EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); bool mipi_dsi_packet_format_is_long(u8 type) { switch (type) { + case MIPI_DSI_PPS_LONG_WRITE: case MIPI_DSI_NULL_PACKET: case MIPI_DSI_BLANKING_PACKET: case MIPI_DSI_GENERIC_LONG_WRITE: diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h index 19aa65a35546..49a53ef8da96 100644 --- a/include/video/mipi_display.h +++ b/include/video/mipi_display.h @@ -38,6 +38,9 @@ enum {
MIPI_DSI_DCS_READ = 0x06,
+ MIPI_DSI_DCS_COMPRESSION_MODE = 0x07, + MIPI_DSI_PPS_LONG_WRITE = 0x0A, + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37,
MIPI_DSI_END_OF_TRANSMISSION = 0x08,
From: Jeykumar Sankaran jsanka@codeaurora.org
Qualcomm Snapdragon chipsets uses compressed format to optimize BW across multiple IP's. This change adds needed modifier support in drm for a simple 4x4 tile based compressed variants of base formats.
Changes in v3: - Removed duplicate entry for DRM_FORMAT_MOD_QCOM_COMPRESSED (Rob Clark)
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- include/uapi/drm/drm_fourcc.h | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index e04613d30a13..1c9a6bf8c81e 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -298,6 +298,43 @@ extern "C" { */ #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/* + * Qualcomm Compressed Format + * + * Refers to a compressed variant of the base format that is compressed. + * Implementation may be platform and base-format specific. + * + * Each macrotile consists of m x n (mostly 4 x 4) tiles. + * Pixel data pitch/stride is aligned with macrotile width. + * Pixel data height is aligned with macrotile height. + * Entire pixel data buffer is aligned with 4k(bytes). + */ +#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1) + +/* + * QTI DX Format + * + * Refers to a DX variant of the base format. + * Implementation may be platform and base-format specific. + */ +#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2) + +/* + * QTI Tight Format + * + * Refers to a tightly packed variant of the base format. + * Implementation may be platform and base-format specific. + */ +#define DRM_FORMAT_MOD_QCOM_TIGHT fourcc_mod_code(QCOM, 0x4) + +/* + * QTI Tile Format + * + * Refers to a tile variant of the base format. + * Implementation may be platform and base-format specific. + */ +#define DRM_FORMAT_MOD_QCOM_TILE fourcc_mod_code(QCOM, 0x8) + /* Vivante framebuffer modifiers */
/*
Hi,
On 07/20/2018 11:42 PM, Sean Paul wrote:
From: Jeykumar Sankaran jsanka@codeaurora.org
Qualcomm Snapdragon chipsets uses compressed format to optimize BW across multiple IP's. This change adds needed modifier support in drm for a simple 4x4 tile based compressed variants of base formats.
Changes in v3:
- Removed duplicate entry for DRM_FORMAT_MOD_QCOM_COMPRESSED (Rob Clark)
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org
include/uapi/drm/drm_fourcc.h | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index e04613d30a13..1c9a6bf8c81e 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -298,6 +298,43 @@ extern "C" { */ #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/*
- Qualcomm Compressed Format
- Refers to a compressed variant of the base format that is compressed.
- Implementation may be platform and base-format specific.
- Each macrotile consists of m x n (mostly 4 x 4) tiles.
- Pixel data pitch/stride is aligned with macrotile width.
- Pixel data height is aligned with macrotile height.
- Entire pixel data buffer is aligned with 4k(bytes).
- */
+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+/*
- QTI DX Format
- Refers to a DX variant of the base format.
- Implementation may be platform and base-format specific.
- */
+#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
What DX stands for?
On 2018-07-25 07:09, Stanimir Varbanov wrote:
Hi,
On 07/20/2018 11:42 PM, Sean Paul wrote:
From: Jeykumar Sankaran jsanka@codeaurora.org
Qualcomm Snapdragon chipsets uses compressed format to optimize BW across multiple IP's. This change adds needed modifier support in drm for a simple 4x4 tile based compressed variants of base formats.
Changes in v3:
- Removed duplicate entry for DRM_FORMAT_MOD_QCOM_COMPRESSED (Rob
Clark)
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org
include/uapi/drm/drm_fourcc.h | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index e04613d30a13..1c9a6bf8c81e 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -298,6 +298,43 @@ extern "C" { */ #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/*
- Qualcomm Compressed Format
- Refers to a compressed variant of the base format that is
compressed.
- Implementation may be platform and base-format specific.
- Each macrotile consists of m x n (mostly 4 x 4) tiles.
- Pixel data pitch/stride is aligned with macrotile width.
- Pixel data height is aligned with macrotile height.
- Entire pixel data buffer is aligned with 4k(bytes).
- */
+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+/*
- QTI DX Format
- Refers to a DX variant of the base format.
- Implementation may be platform and base-format specific.
- */
+#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
What DX stands for?
_DX is QCOM modifier for identifying 10bit version of NV12 format since there is no fourcc_code for the same.
On 07/26/2018 02:09 AM, Jeykumar Sankaran wrote:
On 2018-07-25 07:09, Stanimir Varbanov wrote:
Hi,
On 07/20/2018 11:42 PM, Sean Paul wrote:
From: Jeykumar Sankaran jsanka@codeaurora.org
Qualcomm Snapdragon chipsets uses compressed format to optimize BW across multiple IP's. This change adds needed modifier support in drm for a simple 4x4 tile based compressed variants of base formats.
Changes in v3:
- Removed duplicate entry for DRM_FORMAT_MOD_QCOM_COMPRESSED (Rob Clark)
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org
include/uapi/drm/drm_fourcc.h | 37 +++++++++++++++++++++++++++++++++++ Â 1 file changed, 37 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index e04613d30a13..1c9a6bf8c81e 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -298,6 +298,43 @@ extern "C" { Â */ Â #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILEÂ Â Â fourcc_mod_code(SAMSUNG, 1)
+/*
- Qualcomm Compressed Format
- Refers to a compressed variant of the base format that is
compressed.
- Implementation may be platform and base-format specific.
- Each macrotile consists of m x n (mostly 4 x 4) tiles.
- Pixel data pitch/stride is aligned with macrotile width.
- Pixel data height is aligned with macrotile height.
- Entire pixel data buffer is aligned with 4k(bytes).
- */
+#define DRM_FORMAT_MOD_QCOM_COMPRESSEDÂ Â Â fourcc_mod_code(QCOM, 1)
+/*
- QTI DX Format
- Refers to a DX variant of the base format.
- Implementation may be platform and base-format specific.
- */
+#define DRM_FORMAT_MOD_QCOM_DXÂ Â Â fourcc_mod_code(QCOM, 0x2)
What DX stands for?
_DX is QCOM modifier for identifying 10bit version of NV12 format since there is no fourcc_code for the same.
Did you mean such as COLOR_FMT_P010? And how DX is translated to ?
On Wed, Jul 25, 2018 at 7:09 PM, Jeykumar Sankaran jsanka@codeaurora.org wrote:
On 2018-07-25 07:09, Stanimir Varbanov wrote:
Hi,
On 07/20/2018 11:42 PM, Sean Paul wrote:
From: Jeykumar Sankaran jsanka@codeaurora.org
Qualcomm Snapdragon chipsets uses compressed format to optimize BW across multiple IP's. This change adds needed modifier support in drm for a simple 4x4 tile based compressed variants of base formats.
Changes in v3:
- Removed duplicate entry for DRM_FORMAT_MOD_QCOM_COMPRESSED (Rob Clark)
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org
include/uapi/drm/drm_fourcc.h | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index e04613d30a13..1c9a6bf8c81e 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -298,6 +298,43 @@ extern "C" { */ #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG,
+/*
- Qualcomm Compressed Format
- Refers to a compressed variant of the base format that is compressed.
- Implementation may be platform and base-format specific.
- Each macrotile consists of m x n (mostly 4 x 4) tiles.
- Pixel data pitch/stride is aligned with macrotile width.
- Pixel data height is aligned with macrotile height.
- Entire pixel data buffer is aligned with 4k(bytes).
- */
+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+/*
- QTI DX Format
- Refers to a DX variant of the base format.
- Implementation may be platform and base-format specific.
- */
+#define DRM_FORMAT_MOD_QCOM_DX fourcc_mod_code(QCOM, 0x2)
What DX stands for?
_DX is QCOM modifier for identifying 10bit version of NV12 format since there is no fourcc_code for the same.
this sounds like it should actually be P010 then.. not a modifier.. I think we should remove the modifier before it ends up in a release..
See: https://patchwork.freedesktop.org/patch/141342/
from a quick look, it seems like we just need a driver that supports it to land the new fourcc's
BR, -R
-- Jeykumar S
From: Jeykumar Sankaran jsanka@codeaurora.org
Qualcomm Snapdragon chipsets uses compressed format to optimize BW across multiple IP's. This change adds needed modifier support in drm for a simple 4x4 tile based compressed variants of base formats.
Changes in v3: - Removed duplicate entry for DRM_FORMAT_MOD_QCOM_COMPRESSED (Rob Clark) Changes in v4: - Remove all modifiers aside from COMPRESSED, this includes tiled and 10-bit
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org Signed-off-by: Rob Clark robdclark@gmail.com --- include/uapi/drm/drm_fourcc.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index d43949b5bb3e..721ab7e54d96 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -299,6 +299,19 @@ extern "C" { */ #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/* + * Qualcomm Compressed Format + * + * Refers to a compressed variant of the base format that is compressed. + * Implementation may be platform and base-format specific. + * + * Each macrotile consists of m x n (mostly 4 x 4) tiles. + * Pixel data pitch/stride is aligned with macrotile width. + * Pixel data height is aligned with macrotile height. + * Entire pixel data buffer is aligned with 4k(bytes). + */ +#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1) + /* Vivante framebuffer modifiers */
/*
From: Chandan Uddaraju chandanu@codeaurora.org
For dual dsi mode, the horizontal timing needs to be divided by half since both the dsi controllers will be driving this panel. Adjust the pixel clock and DSI timing accordingly.
Changes in v3: - Added Archit's R-b - Rebase on dsi cleanup set in msm-next
Cc: Sibi Sankar sibis@codeaurora.org Reviewed-by: Archit Taneja architt@codeaurora.org Signed-off-by: Chandan Uddaraju chandanu@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/dsi/dsi.h | 10 +++-- drivers/gpu/drm/msm/dsi/dsi_cfg.h | 2 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 65 ++++++++++++++++++++++----- drivers/gpu/drm/msm/dsi/dsi_manager.c | 7 +-- 4 files changed, 64 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index dfa049d876bd..d3f613c76ffa 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -163,7 +163,8 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, int msm_dsi_host_enable(struct mipi_dsi_host *host); int msm_dsi_host_disable(struct mipi_dsi_host *host); int msm_dsi_host_power_on(struct mipi_dsi_host *host, - struct msm_dsi_phy_shared_timings *phy_shared_timings); + struct msm_dsi_phy_shared_timings *phy_shared_timings, + bool is_dual_dsi); int msm_dsi_host_power_off(struct mipi_dsi_host *host); int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, struct drm_display_mode *mode); @@ -176,7 +177,8 @@ int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host, struct msm_dsi_pll *src_pll); void msm_dsi_host_reset_phy(struct mipi_dsi_host *host); void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, - struct msm_dsi_phy_clk_request *clk_req); + struct msm_dsi_phy_clk_request *clk_req, + bool is_dual_dsi); void msm_dsi_host_destroy(struct mipi_dsi_host *host); int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, struct drm_device *dev); @@ -196,8 +198,8 @@ int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova); int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova); int dsi_clk_init_v2(struct msm_dsi_host *msm_host); int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host); -int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host); -int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host); +int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi); +int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi);
/* dsi phy */ struct msm_dsi_phy; diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index a795a062b779..16c507911110 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -48,7 +48,7 @@ struct msm_dsi_host_cfg_ops { void* (*tx_buf_get)(struct msm_dsi_host *msm_host); void (*tx_buf_put)(struct msm_dsi_host *msm_host); int (*dma_base_get)(struct msm_dsi_host *msm_host, uint64_t *iova); - int (*calc_clk_rate)(struct msm_dsi_host *msm_host); + int (*calc_clk_rate)(struct msm_dsi_host *msm_host, bool is_dual_dsi); };
struct msm_dsi_cfg_handler { diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index bb00e0f150cb..f6c6eddbcec7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -118,6 +118,7 @@ struct msm_dsi_host { struct clk *byte_intf_clk;
u32 byte_clk_rate; + u32 pixel_clk_rate; u32 esc_clk_rate;
/* DSI v2 specific clocks */ @@ -523,7 +524,7 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) goto error; }
- ret = clk_set_rate(msm_host->pixel_clk, msm_host->mode->clock * 1000); + ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate); if (ret) { pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret); goto error; @@ -604,7 +605,7 @@ int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host) goto error; }
- ret = clk_set_rate(msm_host->pixel_clk, msm_host->mode->clock * 1000); + ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate); if (ret) { pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret); goto error; @@ -663,7 +664,7 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->byte_clk); }
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host) +int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi) { struct drm_display_mode *mode = msm_host->mode; u8 lanes = msm_host->lanes; @@ -671,6 +672,16 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host) u32 pclk_rate;
pclk_rate = mode->clock * 1000; + + /* + * For dual DSI mode, the current DRM mode has the complete width of the + * panel. Since, the complete panel is driven by two DSI controllers, + * theclock rates have to be split between the two dsi controllers. + * Adjust the byte and pixel clock rates for each dsi host accordingly. + */ + if (is_dual_dsi) + pclk_rate /= 2; + if (lanes > 0) { msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes); } else { @@ -685,7 +696,7 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host) return 0; }
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host) +int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi) { struct drm_display_mode *mode = msm_host->mode; u8 lanes = msm_host->lanes; @@ -695,14 +706,26 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host) unsigned long byte_mhz;
pclk_rate = mode->clock * 1000; + + /* + * For dual DSI mode, the current DRM mode has the complete width of the + * panel. Since, the complete panel is driven by two DSI controllers, + * theclock rates have to be split between the two dsi controllers. + * Adjust the byte and pixel clock rates for each dsi host accordingly. + */ + if (is_dual_dsi) + pclk_rate /= 2; + if (lanes > 0) { msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes); } else { pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__); msm_host->byte_clk_rate = (pclk_rate * bpp) / 8; } + msm_host->pixel_clk_rate = pclk_rate;
- DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate); + DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate, + msm_host->byte_clk_rate);
msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
@@ -897,7 +920,7 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, dsi_write(msm_host, REG_DSI_CTRL, data); }
-static void dsi_timing_setup(struct msm_dsi_host *msm_host) +static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_dual_dsi) { struct drm_display_mode *mode = msm_host->mode; u32 hs_start = 0, vs_start = 0; /* take sync start as 0 */ @@ -909,10 +932,26 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host) u32 ha_end = ha_start + mode->hdisplay; u32 va_start = v_total - mode->vsync_start; u32 va_end = va_start + mode->vdisplay; + u32 hdisplay = mode->hdisplay; u32 wc;
DBG("");
+ /* + * For dual DSI mode, the current DRM mode has + * the complete width of the panel. Since, the complete + * panel is driven by two DSI controllers, the horizontal + * timings have to be split between the two dsi controllers. + * Adjust the DSI host timing values accordingly. + */ + if (is_dual_dsi) { + h_total /= 2; + hs_end /= 2; + ha_start /= 2; + ha_end /= 2; + hdisplay /= 2; + } + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { dsi_write(msm_host, REG_DSI_ACTIVE_H, DSI_ACTIVE_H_START(ha_start) | @@ -933,7 +972,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host) DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); } else { /* command mode */ /* image data and 1 byte write_memory_start cmd */ - wc = mode->hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; + wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM_CTRL, DSI_CMD_MDP_STREAM_CTRL_WORD_COUNT(wc) | @@ -943,7 +982,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host) MIPI_DSI_DCS_LONG_WRITE));
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM_TOTAL, - DSI_CMD_MDP_STREAM_TOTAL_H_TOTAL(mode->hdisplay) | + DSI_CMD_MDP_STREAM_TOTAL_H_TOTAL(hdisplay) | DSI_CMD_MDP_STREAM_TOTAL_V_TOTAL(mode->vdisplay)); } } @@ -2217,13 +2256,14 @@ void msm_dsi_host_reset_phy(struct mipi_dsi_host *host) }
void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, - struct msm_dsi_phy_clk_request *clk_req) + struct msm_dsi_phy_clk_request *clk_req, + bool is_dual_dsi) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; int ret;
- ret = cfg_hnd->ops->calc_clk_rate(msm_host); + ret = cfg_hnd->ops->calc_clk_rate(msm_host, is_dual_dsi); if (ret) { pr_err("%s: unable to calc clk rate, %d\n", __func__, ret); return; @@ -2285,7 +2325,8 @@ static void msm_dsi_sfpb_config(struct msm_dsi_host *msm_host, bool enable) }
int msm_dsi_host_power_on(struct mipi_dsi_host *host, - struct msm_dsi_phy_shared_timings *phy_shared_timings) + struct msm_dsi_phy_shared_timings *phy_shared_timings, + bool is_dual_dsi) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; @@ -2321,7 +2362,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, goto fail_disable_clk; }
- dsi_timing_setup(msm_host); + dsi_timing_setup(msm_host, is_dual_dsi); dsi_sw_reset(msm_host); dsi_ctrl_config(msm_host, true, phy_shared_timings);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 4cb1cb68878b..3bb506b44a4b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -134,8 +134,9 @@ static int enable_phy(struct msm_dsi *msm_dsi, int src_pll_id, { struct msm_dsi_phy_clk_request clk_req; int ret; + bool is_dual_dsi = IS_DUAL_DSI();
- msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req); + msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_dual_dsi);
ret = msm_dsi_phy_enable(msm_dsi->phy, src_pll_id, &clk_req); msm_dsi_phy_get_shared_timings(msm_dsi->phy, shared_timings); @@ -458,7 +459,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_dual_dsi && (DSI_1 == id)) return;
- ret = msm_dsi_host_power_on(host, &phy_shared_timings[id]); + ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_dual_dsi); if (ret) { pr_err("%s: power on host %d failed, %d\n", __func__, id, ret); goto host_on_fail; @@ -466,7 +467,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
if (is_dual_dsi && msm_dsi1) { ret = msm_dsi_host_power_on(msm_dsi1->host, - &phy_shared_timings[DSI_1]); + &phy_shared_timings[DSI_1], is_dual_dsi); if (ret) { pr_err("%s: power on host1 failed, %d\n", __func__, ret);
From: Chandan Uddaraju chandanu@codeaurora.org
Current DSI driver uses two connectors for dual DSI case even though we only have one panel. Fix this by implementing one connector/bridge for dual DSI use case. Use master DSI controllers to register one connector/bridge.
Changes in v3: - None
Reviewed-by: Archit Taneja architt@codeaurora.org Signed-off-by: Chandan Uddaraju chandanu@codeaurora.org [seanpaul removed unused local var causing a build warning] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/dsi/dsi.c | 3 + drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi_manager.c | 112 ++++++-------------------- 3 files changed, 30 insertions(+), 86 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index b744bcc7d8ad..ff8164cc6738 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -208,6 +208,9 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, goto fail; }
+ if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) + goto fail; + msm_dsi->encoder = encoder;
msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id); diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index d3f613c76ffa..08f3fc6771b7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -100,6 +100,7 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len); void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags); int msm_dsi_manager_register(struct msm_dsi *msm_dsi); void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi); +bool msm_dsi_manager_validate_current_config(u8 id);
/* msm dsi */ static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi) diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 3bb506b44a4b..000721fe5ab4 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -306,102 +306,25 @@ static void dsi_mgr_connector_destroy(struct drm_connector *connector) kfree(dsi_connector); }
-static void dsi_dual_connector_fix_modes(struct drm_connector *connector) -{ - struct drm_display_mode *mode, *m; - - /* Only support left-right mode */ - list_for_each_entry_safe(mode, m, &connector->probed_modes, head) { - mode->clock >>= 1; - mode->hdisplay >>= 1; - mode->hsync_start >>= 1; - mode->hsync_end >>= 1; - mode->htotal >>= 1; - drm_mode_set_name(mode); - } -} - -static int dsi_dual_connector_tile_init( - struct drm_connector *connector, int id) -{ - struct drm_display_mode *mode; - /* Fake topology id */ - char topo_id[8] = {'M', 'S', 'M', 'D', 'U', 'D', 'S', 'I'}; - - if (connector->tile_group) { - DBG("Tile property has been initialized"); - return 0; - } - - /* Use the first mode only for now */ - mode = list_first_entry(&connector->probed_modes, - struct drm_display_mode, - head); - if (!mode) - return -EINVAL; - - connector->tile_group = drm_mode_get_tile_group( - connector->dev, topo_id); - if (!connector->tile_group) - connector->tile_group = drm_mode_create_tile_group( - connector->dev, topo_id); - if (!connector->tile_group) { - pr_err("%s: failed to create tile group\n", __func__); - return -ENOMEM; - } - - connector->has_tile = true; - connector->tile_is_single_monitor = true; - - /* mode has been fixed */ - connector->tile_h_size = mode->hdisplay; - connector->tile_v_size = mode->vdisplay; - - /* Only support left-right mode */ - connector->num_h_tile = 2; - connector->num_v_tile = 1; - - connector->tile_v_loc = 0; - connector->tile_h_loc = (id == DSI_RIGHT) ? 1 : 0; - - return 0; -} - static int dsi_mgr_connector_get_modes(struct drm_connector *connector) { int id = dsi_mgr_connector_get_id(connector); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct drm_panel *panel = msm_dsi->panel; - int ret, num; + int num;
if (!panel) return 0;
- /* Since we have 2 connectors, but only 1 drm_panel in dual DSI mode, - * panel should not attach to any connector. - * Only temporarily attach panel to the current connector here, - * to let panel set mode to this connector. + /* + * In dual DSI mode, we have one connector that can be + * attached to the drm_panel. */ drm_panel_attach(panel, connector); num = drm_panel_get_modes(panel); - drm_panel_detach(panel); if (!num) return 0;
- if (IS_DUAL_DSI()) { - /* report half resolution to user */ - dsi_dual_connector_fix_modes(connector); - ret = dsi_dual_connector_tile_init(connector, id); - if (ret) - return ret; - ret = drm_mode_connector_set_tile_property(connector); - if (ret) { - pr_err("%s: set tile property failed, %d\n", - __func__, ret); - return ret; - } - } - return num; }
@@ -455,8 +378,8 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (ret) goto phy_en_fail;
- /* Do nothing with the host if it is DSI 1 in case of dual DSI */ - if (is_dual_dsi && (DSI_1 == id)) + /* Do nothing with the host if it is slave-DSI in case of dual DSI */ + if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) return;
ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_dual_dsi); @@ -557,11 +480,11 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) return;
/* - * Do nothing with the host if it is DSI 1 in case of dual DSI. + * Do nothing with the host if it is slave-DSI in case of dual DSI. * It is safe to call dsi_mgr_phy_disable() here because a single PHY * won't be diabled until both PHYs request disable. */ - if (is_dual_dsi && (DSI_1 == id)) + if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) goto disable_phy;
if (panel) { @@ -622,7 +545,7 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, mode->vsync_end, mode->vtotal, mode->type, mode->flags);
- if (is_dual_dsi && (DSI_1 == id)) + if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) return;
msm_dsi_host_set_display_mode(host, adjusted_mode); @@ -690,6 +613,23 @@ struct drm_connector *msm_dsi_manager_connector_init(u8 id) return connector; }
+bool msm_dsi_manager_validate_current_config(u8 id) +{ + bool is_dual_dsi = IS_DUAL_DSI(); + + /* + * For dual DSI, we only have one drm panel. For this + * use case, we register only one bridge/connector. + * Skip bridge/connector initialisation if it is + * slave-DSI for dual DSI configuration. + */ + if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) { + DBG("Skip bridge registration for slave DSI->id: %d\n", id); + return false; + } + return true; +} + /* initialize bridge */ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) {
From: Rajesh Yadav ryadav@codeaurora.org
postdiv_lock spinlock was used before initialization for 10nm pll. It causes following spin_bug: "BUG: spinlock bad magic on CPU#0". Initialize spinlock before its usage.
Changes in v3: - Added Archit's R-b
Reviewed-by: Archit Taneja architt@codeaurora.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c index c4c37a7df637..4c03f0b7343e 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c @@ -798,6 +798,8 @@ struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) return ERR_PTR(-ENOMEM); }
+ spin_lock_init(&pll_10nm->postdiv_lock); + pll = &pll_10nm->base; pll->min_rate = 1000000000UL; pll->max_rate = 3500000000UL;
From: Abhinav Kumar abhinavk@codeaurora.org
Currently, DRM bridge for DPU relies on the default video mode setting to set the encoder mode.
Add an explicit call to set the encoder mode for bridges.
Changes in v3: - None
Reviewed-by: Archit Taneja architt@codeauorora.org Signed-off-by: Abhinav Kumar abhinavk@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 000721fe5ab4..29025d9b7c62 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -777,6 +777,7 @@ void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags) struct msm_drm_private *priv; struct msm_kms *kms; struct drm_encoder *encoder; + bool cmd_mode;
/* * drm_device pointer is assigned to msm_dsi only in the modeset_init @@ -791,10 +792,11 @@ void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags) priv = dev->dev_private; kms = priv->kms; encoder = msm_dsi_get_encoder(msm_dsi); + cmd_mode = !(device_flags & + MIPI_DSI_MODE_VIDEO);
if (encoder && kms->funcs->set_encoder_mode) - if (!(device_flags & MIPI_DSI_MODE_VIDEO)) - kms->funcs->set_encoder_mode(kms, encoder, true); + kms->funcs->set_encoder_mode(kms, encoder, cmd_mode); }
int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
DPU doesn't use this, so push it into the mdp drivers.
Changes in v3: - None
Signed-off-by: Sean Paul seanpaul@chromium.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org --- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 ++ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 ++ drivers/gpu/drm/msm/msm_atomic.c | 2 -- 3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 4b646bf9c214..44d1cda56974 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -125,6 +125,8 @@ static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s struct drm_crtc *crtc; struct drm_crtc_state *crtc_state;
+ drm_atomic_helper_wait_for_vblanks(mdp4_kms->dev, state); + /* see 119ecb7fd */ for_each_new_crtc_in_state(state, crtc, crtc_state, i) drm_crtc_vblank_put(crtc); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 6e12e275deba..bddd625ab91b 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -170,6 +170,8 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s struct device *dev = &mdp5_kms->pdev->dev; struct mdp5_global_state *global_state;
+ drm_atomic_helper_wait_for_vblanks(mdp5_kms->dev, state); + global_state = mdp5_get_existing_global_state(mdp5_kms);
if (mdp5_kms->smp) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index f0635c3da7f4..e6f1e25c60af 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -75,8 +75,6 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
kms->funcs->complete_commit(kms, state);
- drm_atomic_helper_wait_for_vblanks(dev, state); - drm_atomic_helper_commit_hw_done(state);
drm_atomic_helper_cleanup_planes(dev, state);
From: Rajesh Yadav ryadav@codeaurora.org
SoCs having mdp5 or dpu have identical tree like device hierarchy where MDSS top level wrapper manages common power resources for all child devices.
Subclass msm_mdss so that msm_mdss includes common defines and mdp5/dpu mdss derivations to include any extensions.
Add mdss helper interface (msm_mdss_funcs) to msm_mdss base for mdp5/dpu mdss specific implementation calls.
This change subclasses msm_mdss for mdp5, dpu specific changes will be done separately.
Changes in v3: - Added Archit's R-b
Reviewed-by: Archit Taneja architt@codeaurora.org Reviewed-by: Sean Paul seanpaul@chromium.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org [seanpaul rebased on msm-next and resolved conflicts] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 154 ++++++++++++---------- drivers/gpu/drm/msm/msm_drv.c | 22 +++- drivers/gpu/drm/msm/msm_kms.h | 17 ++- 3 files changed, 109 insertions(+), 84 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c index f2a0db7a8a03..1cc4e57f0226 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c @@ -20,12 +20,10 @@ #include "msm_drv.h" #include "mdp5_kms.h"
-/* - * If needed, this can become more specific: something like struct mdp5_mdss, - * which contains a 'struct msm_mdss base' member. - */ -struct msm_mdss { - struct drm_device *dev; +#define to_mdp5_mdss(x) container_of(x, struct mdp5_mdss, base) + +struct mdp5_mdss { + struct msm_mdss base;
void __iomem *mmio, *vbif;
@@ -41,22 +39,22 @@ struct msm_mdss { } irqcontroller; };
-static inline void mdss_write(struct msm_mdss *mdss, u32 reg, u32 data) +static inline void mdss_write(struct mdp5_mdss *mdp5_mdss, u32 reg, u32 data) { - msm_writel(data, mdss->mmio + reg); + msm_writel(data, mdp5_mdss->mmio + reg); }
-static inline u32 mdss_read(struct msm_mdss *mdss, u32 reg) +static inline u32 mdss_read(struct mdp5_mdss *mdp5_mdss, u32 reg) { - return msm_readl(mdss->mmio + reg); + return msm_readl(mdp5_mdss->mmio + reg); }
static irqreturn_t mdss_irq(int irq, void *arg) { - struct msm_mdss *mdss = arg; + struct mdp5_mdss *mdp5_mdss = arg; u32 intr;
- intr = mdss_read(mdss, REG_MDSS_HW_INTR_STATUS); + intr = mdss_read(mdp5_mdss, REG_MDSS_HW_INTR_STATUS);
VERB("intr=%08x", intr);
@@ -64,7 +62,7 @@ static irqreturn_t mdss_irq(int irq, void *arg) irq_hw_number_t hwirq = fls(intr) - 1;
generic_handle_irq(irq_find_mapping( - mdss->irqcontroller.domain, hwirq)); + mdp5_mdss->irqcontroller.domain, hwirq)); intr &= ~(1 << hwirq); }
@@ -84,19 +82,19 @@ static irqreturn_t mdss_irq(int irq, void *arg)
static void mdss_hw_mask_irq(struct irq_data *irqd) { - struct msm_mdss *mdss = irq_data_get_irq_chip_data(irqd); + struct mdp5_mdss *mdp5_mdss = irq_data_get_irq_chip_data(irqd);
smp_mb__before_atomic(); - clear_bit(irqd->hwirq, &mdss->irqcontroller.enabled_mask); + clear_bit(irqd->hwirq, &mdp5_mdss->irqcontroller.enabled_mask); smp_mb__after_atomic(); }
static void mdss_hw_unmask_irq(struct irq_data *irqd) { - struct msm_mdss *mdss = irq_data_get_irq_chip_data(irqd); + struct mdp5_mdss *mdp5_mdss = irq_data_get_irq_chip_data(irqd);
smp_mb__before_atomic(); - set_bit(irqd->hwirq, &mdss->irqcontroller.enabled_mask); + set_bit(irqd->hwirq, &mdp5_mdss->irqcontroller.enabled_mask); smp_mb__after_atomic(); }
@@ -109,13 +107,13 @@ static struct irq_chip mdss_hw_irq_chip = { static int mdss_hw_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { - struct msm_mdss *mdss = d->host_data; + struct mdp5_mdss *mdp5_mdss = d->host_data;
if (!(VALID_IRQS & (1 << hwirq))) return -EPERM;
irq_set_chip_and_handler(irq, &mdss_hw_irq_chip, handle_level_irq); - irq_set_chip_data(irq, mdss); + irq_set_chip_data(irq, mdp5_mdss);
return 0; } @@ -126,90 +124,99 @@ static const struct irq_domain_ops mdss_hw_irqdomain_ops = { };
-static int mdss_irq_domain_init(struct msm_mdss *mdss) +static int mdss_irq_domain_init(struct mdp5_mdss *mdp5_mdss) { - struct device *dev = mdss->dev->dev; + struct device *dev = mdp5_mdss->base.dev->dev; struct irq_domain *d;
d = irq_domain_add_linear(dev->of_node, 32, &mdss_hw_irqdomain_ops, - mdss); + mdp5_mdss); if (!d) { dev_err(dev, "mdss irq domain add failed\n"); return -ENXIO; }
- mdss->irqcontroller.enabled_mask = 0; - mdss->irqcontroller.domain = d; + mdp5_mdss->irqcontroller.enabled_mask = 0; + mdp5_mdss->irqcontroller.domain = d;
return 0; }
-int msm_mdss_enable(struct msm_mdss *mdss) +static int mdp5_mdss_enable(struct msm_mdss *mdss) { + struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss); DBG("");
- clk_prepare_enable(mdss->ahb_clk); - if (mdss->axi_clk) - clk_prepare_enable(mdss->axi_clk); - if (mdss->vsync_clk) - clk_prepare_enable(mdss->vsync_clk); + clk_prepare_enable(mdp5_mdss->ahb_clk); + if (mdp5_mdss->axi_clk) + clk_prepare_enable(mdp5_mdss->axi_clk); + if (mdp5_mdss->vsync_clk) + clk_prepare_enable(mdp5_mdss->vsync_clk);
return 0; }
-int msm_mdss_disable(struct msm_mdss *mdss) +static int mdp5_mdss_disable(struct msm_mdss *mdss) { + struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss); DBG("");
- if (mdss->vsync_clk) - clk_disable_unprepare(mdss->vsync_clk); - if (mdss->axi_clk) - clk_disable_unprepare(mdss->axi_clk); - clk_disable_unprepare(mdss->ahb_clk); + if (mdp5_mdss->vsync_clk) + clk_disable_unprepare(mdp5_mdss->vsync_clk); + if (mdp5_mdss->axi_clk) + clk_disable_unprepare(mdp5_mdss->axi_clk); + clk_disable_unprepare(mdp5_mdss->ahb_clk);
return 0; }
-static int msm_mdss_get_clocks(struct msm_mdss *mdss) +static int msm_mdss_get_clocks(struct mdp5_mdss *mdp5_mdss) { - struct platform_device *pdev = to_platform_device(mdss->dev->dev); + struct platform_device *pdev = + to_platform_device(mdp5_mdss->base.dev->dev);
- mdss->ahb_clk = msm_clk_get(pdev, "iface"); - if (IS_ERR(mdss->ahb_clk)) - mdss->ahb_clk = NULL; + mdp5_mdss->ahb_clk = msm_clk_get(pdev, "iface"); + if (IS_ERR(mdp5_mdss->ahb_clk)) + mdp5_mdss->ahb_clk = NULL;
- mdss->axi_clk = msm_clk_get(pdev, "bus"); - if (IS_ERR(mdss->axi_clk)) - mdss->axi_clk = NULL; + mdp5_mdss->axi_clk = msm_clk_get(pdev, "bus"); + if (IS_ERR(mdp5_mdss->axi_clk)) + mdp5_mdss->axi_clk = NULL;
- mdss->vsync_clk = msm_clk_get(pdev, "vsync"); - if (IS_ERR(mdss->vsync_clk)) - mdss->vsync_clk = NULL; + mdp5_mdss->vsync_clk = msm_clk_get(pdev, "vsync"); + if (IS_ERR(mdp5_mdss->vsync_clk)) + mdp5_mdss->vsync_clk = NULL;
return 0; }
-void msm_mdss_destroy(struct drm_device *dev) +static void mdp5_mdss_destroy(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; - struct msm_mdss *mdss = priv->mdss; + struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(priv->mdss);
- if (!mdss) + if (!mdp5_mdss) return;
- irq_domain_remove(mdss->irqcontroller.domain); - mdss->irqcontroller.domain = NULL; + irq_domain_remove(mdp5_mdss->irqcontroller.domain); + mdp5_mdss->irqcontroller.domain = NULL;
- regulator_disable(mdss->vdd); + regulator_disable(mdp5_mdss->vdd);
pm_runtime_disable(dev->dev); }
-int msm_mdss_init(struct drm_device *dev) +static const struct msm_mdss_funcs mdss_funcs = { + .enable = mdp5_mdss_enable, + .disable = mdp5_mdss_disable, + .destroy = mdp5_mdss_destroy, +}; + +int mdp5_mdss_init(struct drm_device *dev) { struct platform_device *pdev = to_platform_device(dev->dev); struct msm_drm_private *priv = dev->dev_private; - struct msm_mdss *mdss; + struct mdp5_mdss *mdp5_mdss; int ret;
DBG(""); @@ -217,40 +224,40 @@ int msm_mdss_init(struct drm_device *dev) if (!of_device_is_compatible(dev->dev->of_node, "qcom,mdss")) return 0;
- mdss = devm_kzalloc(dev->dev, sizeof(*mdss), GFP_KERNEL); - if (!mdss) { + mdp5_mdss = devm_kzalloc(dev->dev, sizeof(*mdp5_mdss), GFP_KERNEL); + if (!mdp5_mdss) { ret = -ENOMEM; goto fail; }
- mdss->dev = dev; + mdp5_mdss->base.dev = dev;
- mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS"); - if (IS_ERR(mdss->mmio)) { - ret = PTR_ERR(mdss->mmio); + mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS"); + if (IS_ERR(mdp5_mdss->mmio)) { + ret = PTR_ERR(mdp5_mdss->mmio); goto fail; }
- mdss->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF"); - if (IS_ERR(mdss->vbif)) { - ret = PTR_ERR(mdss->vbif); + mdp5_mdss->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF"); + if (IS_ERR(mdp5_mdss->vbif)) { + ret = PTR_ERR(mdp5_mdss->vbif); goto fail; }
- ret = msm_mdss_get_clocks(mdss); + ret = msm_mdss_get_clocks(mdp5_mdss); if (ret) { dev_err(dev->dev, "failed to get clocks: %d\n", ret); goto fail; }
/* Regulator to enable GDSCs in downstream kernels */ - mdss->vdd = devm_regulator_get(dev->dev, "vdd"); - if (IS_ERR(mdss->vdd)) { - ret = PTR_ERR(mdss->vdd); + mdp5_mdss->vdd = devm_regulator_get(dev->dev, "vdd"); + if (IS_ERR(mdp5_mdss->vdd)) { + ret = PTR_ERR(mdp5_mdss->vdd); goto fail; }
- ret = regulator_enable(mdss->vdd); + ret = regulator_enable(mdp5_mdss->vdd); if (ret) { dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret); @@ -258,25 +265,26 @@ int msm_mdss_init(struct drm_device *dev) }
ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0), - mdss_irq, 0, "mdss_isr", mdss); + mdss_irq, 0, "mdss_isr", mdp5_mdss); if (ret) { dev_err(dev->dev, "failed to init irq: %d\n", ret); goto fail_irq; }
- ret = mdss_irq_domain_init(mdss); + ret = mdss_irq_domain_init(mdp5_mdss); if (ret) { dev_err(dev->dev, "failed to init sub-block irqs: %d\n", ret); goto fail_irq; }
- priv->mdss = mdss; + mdp5_mdss->base.funcs = &mdss_funcs; + priv->mdss = &mdp5_mdss->base;
pm_runtime_enable(dev->dev);
return 0; fail_irq: - regulator_disable(mdss->vdd); + regulator_disable(mdp5_mdss->vdd); fail: return ret; } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 7f7321eb5312..2608d3f77956 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -208,6 +208,7 @@ static int msm_drm_uninit(struct device *dev) struct drm_device *ddev = platform_get_drvdata(pdev); struct msm_drm_private *priv = ddev->dev_private; struct msm_kms *kms = priv->kms; + struct msm_mdss *mdss = priv->mdss; struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; struct vblank_event *vbl_ev, *tmp;
@@ -258,7 +259,8 @@ static int msm_drm_uninit(struct device *dev)
component_unbind_all(dev, ddev);
- msm_mdss_destroy(ddev); + if (mdss && mdss->funcs) + mdss->funcs->destroy(ddev);
ddev->dev_private = NULL; drm_dev_unref(ddev); @@ -357,6 +359,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) struct drm_device *ddev; struct msm_drm_private *priv; struct msm_kms *kms; + struct msm_mdss *mdss; int ret;
ddev = drm_dev_alloc(drv, dev); @@ -376,13 +379,15 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ddev->dev_private = priv; priv->dev = ddev;
- ret = msm_mdss_init(ddev); + ret = mdp5_mdss_init(ddev); if (ret) { kfree(priv); drm_dev_unref(ddev); return ret; }
+ mdss = priv->mdss; + priv->wq = alloc_ordered_workqueue("msm", 0); priv->atomic_wq = alloc_ordered_workqueue("msm:atomic", 0);
@@ -396,7 +401,8 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) /* Bind all our sub-components: */ ret = component_bind_all(dev, ddev); if (ret) { - msm_mdss_destroy(ddev); + if (mdss && mdss->funcs) + mdss->funcs->destroy(ddev); kfree(priv); drm_dev_unref(ddev); return ret; @@ -924,11 +930,12 @@ static int msm_runtime_suspend(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct msm_drm_private *priv = ddev->dev_private; + struct msm_mdss *mdss = priv->mdss;
DBG("");
- if (priv->mdss) - return msm_mdss_disable(priv->mdss); + if (mdss && mdss->funcs) + return mdss->funcs->disable(mdss);
return 0; } @@ -937,11 +944,12 @@ static int msm_runtime_resume(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct msm_drm_private *priv = ddev->dev_private; + struct msm_mdss *mdss = priv->mdss;
DBG("");
- if (priv->mdss) - return msm_mdss_enable(priv->mdss); + if (mdss && mdss->funcs) + return mdss->funcs->enable(mdss);
return 0; } diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index dfd92947de2c..76c14221ffdf 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -86,9 +86,18 @@ static inline void msm_kms_init(struct msm_kms *kms,
struct msm_kms *mdp4_kms_init(struct drm_device *dev); struct msm_kms *mdp5_kms_init(struct drm_device *dev); -int msm_mdss_init(struct drm_device *dev); -void msm_mdss_destroy(struct drm_device *dev); -int msm_mdss_enable(struct msm_mdss *mdss); -int msm_mdss_disable(struct msm_mdss *mdss); + +struct msm_mdss_funcs { + int (*enable)(struct msm_mdss *mdss); + int (*disable)(struct msm_mdss *mdss); + void (*destroy)(struct drm_device *dev); +}; + +struct msm_mdss { + struct drm_device *dev; + const struct msm_mdss_funcs *funcs; +}; + +int mdp5_mdss_init(struct drm_device *dev);
#endif /* __MSM_KMS_H__ */
From: Jeykumar Sankaran jsanka@codeaurora.org
Enable drm core zpos normalization for planes.
Changes in v3: - None
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Reviewed-by: Sean Paul seanpaul@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_drv.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 2608d3f77956..9c760cee5156 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -439,6 +439,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) goto fail; }
+ /* Enable normalization of plane zpos */ + ddev->mode_config.normalize_zpos = true; + if (kms) { ret = kms->funcs->hw_init(kms); if (ret) {
From: Abhinav Kumar abhinavk@codeaurora.org
Make the pclk_rate u64 to accommodate higher pixel clock rates.
Changes in v3: - Converted pclk_rate to u32 (Archit) - Rebase on dsi cleanup set in msm-next
Cc: Sibi Sankar sibis@codeaurora.org Cc: Archit Taneja architt@codeaurora.org Signed-off-by: Abhinav Kumar abhinavk@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/dsi/dsi_host.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index f6c6eddbcec7..dff8e88efb66 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -702,6 +702,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi) u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); u32 pclk_rate; + u64 pclk_bpp; unsigned int esc_mhz, esc_div; unsigned long byte_mhz;
@@ -716,13 +717,15 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi) if (is_dual_dsi) pclk_rate /= 2;
+ pclk_bpp = pclk_rate * bpp; if (lanes > 0) { - msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes); + do_div(pclk_bpp, (8 * lanes)); } else { pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__); - msm_host->byte_clk_rate = (pclk_rate * bpp) / 8; + do_div(pclk_bpp, 8); } msm_host->pixel_clk_rate = pclk_rate; + msm_host->byte_clk_rate = pclk_bpp;
DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
I missed this during the atomic conversion
Changes in v3: - None
Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_drv.c | 4 ---- drivers/gpu/drm/msm/msm_drv.h | 1 - 2 files changed, 5 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9c760cee5156..b73acdd52931 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -244,9 +244,6 @@ static int msm_drm_uninit(struct device *dev) flush_workqueue(priv->wq); destroy_workqueue(priv->wq);
- flush_workqueue(priv->atomic_wq); - destroy_workqueue(priv->atomic_wq); - if (kms && kms->funcs) kms->funcs->destroy(kms);
@@ -389,7 +386,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) mdss = priv->mdss;
priv->wq = alloc_ordered_workqueue("msm", 0); - priv->atomic_wq = alloc_ordered_workqueue("msm:atomic", 0);
INIT_LIST_HEAD(&priv->inactive_list); INIT_LIST_HEAD(&priv->vblank_ctrl.event_list); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 17cefca1d566..fa0376b0f42b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -115,7 +115,6 @@ struct msm_drm_private { struct list_head inactive_list;
struct workqueue_struct *wq; - struct workqueue_struct *atomic_wq;
unsigned int num_planes; struct drm_plane *planes[16];
From: Jeykumar Sankaran jsanka@codeaurora.org
Useful for incoming DPU support
Changes in v3: - None
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org [seanpaul split this from the dpu megapatch] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_drv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b73acdd52931..67816543a0d7 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -267,6 +267,9 @@ static int msm_drm_uninit(struct device *dev) return 0; }
+#define KMS_MDP4 4 +#define KMS_MDP5 5 + static int get_mdp_ver(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -411,11 +414,11 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) msm_gem_shrinker_init(ddev);
switch (get_mdp_ver(pdev)) { - case 4: + case KMS_MDP4: kms = mdp4_kms_init(ddev); priv->kms = kms; break; - case 5: + case KMS_MDP5: kms = mdp5_kms_init(ddev); break; default: @@ -1162,8 +1165,8 @@ static int msm_pdev_remove(struct platform_device *pdev) }
static const struct of_device_id dt_match[] = { - { .compatible = "qcom,mdp4", .data = (void *)4 }, /* MDP4 */ - { .compatible = "qcom,mdss", .data = (void *)5 }, /* MDP5 MDSS */ + { .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 }, + { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, {} }; MODULE_DEVICE_TABLE(of, dt_match);
From: Jeykumar Sankaran jsanka@codeaurora.org
This simplifies cleanup, to make sure nothing drops out in case of error.
Changes in v3: - None
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org [seanpaul split out of dpu megapatch and renamed labels] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_drv.c | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 67816543a0d7..8bd9fe831968 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -372,19 +372,16 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { - drm_dev_unref(ddev); - return -ENOMEM; + ret = -ENOMEM; + goto err_unref_drm_dev; }
ddev->dev_private = priv; priv->dev = ddev;
ret = mdp5_mdss_init(ddev); - if (ret) { - kfree(priv); - drm_dev_unref(ddev); - return ret; - } + if (ret) + goto err_free_priv;
mdss = priv->mdss;
@@ -399,17 +396,12 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
/* Bind all our sub-components: */ ret = component_bind_all(dev, ddev); - if (ret) { - if (mdss && mdss->funcs) - mdss->funcs->destroy(ddev); - kfree(priv); - drm_dev_unref(ddev); - return ret; - } + if (ret) + goto err_destroy_mdss;
ret = msm_init_vram(ddev); if (ret) - goto fail; + goto err_msm_uninit;
msm_gem_shrinker_init(ddev);
@@ -435,7 +427,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) */ dev_err(dev, "failed to load kms\n"); ret = PTR_ERR(kms); - goto fail; + goto err_msm_uninit; }
/* Enable normalization of plane zpos */ @@ -445,7 +437,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ret = kms->funcs->hw_init(kms); if (ret) { dev_err(dev, "kms hw init failed: %d\n", ret); - goto fail; + goto err_msm_uninit; } }
@@ -455,7 +447,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ret = drm_vblank_init(ddev, priv->num_crtcs); if (ret < 0) { dev_err(dev, "failed to initialize vblank\n"); - goto fail; + goto err_msm_uninit; }
if (kms) { @@ -464,13 +456,13 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) pm_runtime_put_sync(dev); if (ret < 0) { dev_err(dev, "failed to install IRQ handler\n"); - goto fail; + goto err_msm_uninit; } }
ret = drm_dev_register(ddev, 0); if (ret) - goto fail; + goto err_msm_uninit;
drm_mode_config_reset(ddev);
@@ -481,15 +473,23 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
ret = msm_debugfs_late_init(ddev); if (ret) - goto fail; + goto err_msm_uninit;
drm_kms_helper_poll_init(ddev);
return 0;
-fail: +err_msm_uninit: msm_drm_uninit(dev); return ret; +err_destroy_mdss: + if (mdss && mdss->funcs) + mdss->funcs->destroy(ddev); +err_free_priv: + kfree(priv); +err_unref_drm_dev: + drm_dev_unref(ddev); + return ret; }
/*
From: Jeykumar Sankaran jsanka@codeaurora.org
dpu uses these elsewhere in the driver (in addition to increasing MAX_PLANES, that'll come later), so pull them out into #define.
Changes in v3: - None
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org [seanpaul pulled this out of the dpu megapatch] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_drv.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index fa0376b0f42b..3b206ae6423f 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -54,6 +54,12 @@ struct msm_fence_context; struct msm_gem_address_space; struct msm_gem_vma;
+#define MAX_CRTCS 8 +#define MAX_PLANES 16 +#define MAX_ENCODERS 8 +#define MAX_BRIDGES 8 +#define MAX_CONNECTORS 8 + struct msm_file_private { rwlock_t queuelock; struct list_head submitqueues; @@ -117,19 +123,19 @@ struct msm_drm_private { struct workqueue_struct *wq;
unsigned int num_planes; - struct drm_plane *planes[16]; + struct drm_plane *planes[MAX_PLANES];
unsigned int num_crtcs; - struct drm_crtc *crtcs[8]; + struct drm_crtc *crtcs[MAX_CRTCS];
unsigned int num_encoders; - struct drm_encoder *encoders[8]; + struct drm_encoder *encoders[MAX_ENCODERS];
unsigned int num_bridges; - struct drm_bridge *bridges[8]; + struct drm_bridge *bridges[MAX_BRIDGES];
unsigned int num_connectors; - struct drm_connector *connectors[8]; + struct drm_connector *connectors[MAX_CONNECTORS];
/* Properties */ struct drm_property *plane_property[PLANE_PROP_MAX_NUM];
From: Jeykumar Sankaran jsanka@codeaurora.org
Called right before wait_for_commit_done() to perform kickoff for active crtcs.
Changes in v3: - None
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org [seanpaul split this out of the megapatch] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_atomic.c | 5 +++++ drivers/gpu/drm/msm/msm_kms.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index e6f1e25c60af..c1f1779c980f 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -71,6 +71,11 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_enables(dev, state);
+ if (kms->funcs->commit) { + DRM_DEBUG_ATOMIC("triggering commit\n"); + kms->funcs->commit(kms, state); + } + msm_atomic_wait_for_commit_done(dev, state);
kms->funcs->complete_commit(kms, state); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 76c14221ffdf..761bb07cd7bf 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -42,6 +42,7 @@ struct msm_kms_funcs { void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); /* modeset, bracketing atomic_commit(): */ void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state); + void (*commit)(struct msm_kms *kms, struct drm_atomic_state *state); void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state); /* functions to wait for atomic commit completed on each CRTC */ void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
From: Jeykumar Sankaran jsanka@codeaurora.org
Used by the dpu driver for custom suspend/resume.
Changes in v3: - None
Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org [seanpaul split this out of the megapatch] Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/msm_drv.c | 10 ++++++++++ drivers/gpu/drm/msm/msm_kms.h | 3 +++ 2 files changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 8bd9fe831968..e79ad74ca98c 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -903,6 +903,11 @@ static int msm_pm_suspend(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct msm_drm_private *priv = ddev->dev_private; + struct msm_kms *kms = priv->kms; + + /* TODO: Use atomic helper suspend/resume */ + if (kms && kms->funcs && kms->funcs->pm_suspend) + return kms->funcs->pm_suspend(dev);
drm_kms_helper_poll_disable(ddev);
@@ -919,6 +924,11 @@ static int msm_pm_resume(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct msm_drm_private *priv = ddev->dev_private; + struct msm_kms *kms = priv->kms; + + /* TODO: Use atomic helper suspend/resume */ + if (kms && kms->funcs && kms->funcs->pm_resume) + return kms->funcs->pm_resume(dev);
drm_atomic_helper_resume(ddev, priv->pm_state); drm_kms_helper_poll_enable(ddev); diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 761bb07cd7bf..c15de28ae2dd 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -61,6 +61,9 @@ struct msm_kms_funcs { void (*set_encoder_mode)(struct msm_kms *kms, struct drm_encoder *encoder, bool cmd_mode); + /* pm suspend/resume hooks */ + int (*pm_suspend)(struct device *dev); + int (*pm_resume)(struct device *dev); /* cleanup: */ void (*destroy)(struct msm_kms *kms); #ifdef CONFIG_DEBUG_FS
From: Jeykumar Sankaran jsanka@codeaurora.org
Adds bindings for Snapdragon 845 display processing unit
Changes in v2: - Use SoC specific compatibles for mdss and dpu (Rob Herring) - Use assigned-clocks to set initial clock frequency (Rob Herring)
Changes in v3 (all suggested by Rob Herring): - Rename mdss_phys to mdss - Correct description for clocks/assigned-clocks - Rename mdp_phys to mdp - Rename vbif_phys to vbif - Remove redundant interrupt-parent from mdss_mdp - Fully specify 'ranges' and use relative reg address in mdss_mdp
Cc: Rob Herring robh+dt@kernel.org Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- .../devicetree/bindings/display/msm/dpu.txt | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/msm/dpu.txt
diff --git a/Documentation/devicetree/bindings/display/msm/dpu.txt b/Documentation/devicetree/bindings/display/msm/dpu.txt new file mode 100644 index 000000000000..ad2e8830324e --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/dpu.txt @@ -0,0 +1,131 @@ +Qualcomm Technologies, Inc. DPU KMS + +Description: + +Device tree bindings for MSM Mobile Display Subsytem(MDSS) that encapsulates +sub-blocks like DPU display controller, DSI and DP interfaces etc. +The DPU display controller is found in SDM845 SoC. + +MDSS: +Required properties: +- compatible: "qcom,sdm845-mdss" +- reg: physical base address and length of contoller's registers. +- reg-names: register region names. The following region is required: + * "mdss" +- power-domains: a power domain consumer specifier according to + Documentation/devicetree/bindings/power/power_domain.txt +- clocks: list of clock specifiers for clocks needed by the device. +- clock-names: device clock names, must be in same order as clocks property. + The following clocks are required: + * "iface" + * "bus" + * "core" +- interrupts: interrupt signal from MDSS. +- interrupt-controller: identifies the node as an interrupt controller. +- #interrupt-cells: specifies the number of cells needed to encode an interrupt + source, should be 1. +- iommus: phandle of iommu device node. +- #address-cells: number of address cells for the MDSS children. Should be 1. +- #size-cells: Should be 1. +- ranges: parent bus address space is the same as the child bus address space. + +Optional properties: +- assigned-clocks: list of clock specifiers for clocks needing rate assignment +- assigned-clock-rates: list of clock frequencies sorted in the same order as + the assigned-clocks property. + +MDP: +Required properties: +- compatible: "qcom,sdm845-dpu" +- reg: physical base address and length of controller's registers. +- reg-names : register region names. The following region is required: + * "mdp" + * "vbif" +- clocks: list of clock specifiers for clocks needed by the device. +- clock-names: device clock names, must be in same order as clocks property. + The following clocks are required. + * "bus" + * "iface" + * "core" + * "vsync" +- interrupts: interrupt line from DPU to MDSS. +- ports: contains the list of output ports from DPU device. These ports connect + to interfaces that are external to the DPU hardware, such as DSI, DP etc. + + Each output port contains an endpoint that describes how it is connected to an + external interface. These are described by the standard properties documented + here: + Documentation/devicetree/bindings/graph.txt + Documentation/devicetree/bindings/media/video-interfaces.txt + + Port 0 -> DPU_INTF1 (DSI1) + Port 1 -> DPU_INTF2 (DSI2) + +Optional properties: +- assigned-clocks: list of clock specifiers for clocks needing rate assignment +- assigned-clock-rates: list of clock frequencies sorted in the same order as + the assigned-clocks property. + +Example: + + mdss: mdss@ae00000 { + compatible = "qcom,sdm845-mdss"; + reg = <0xae00000 0x1000>; + reg-names = "mdss"; + + power-domains = <&clock_dispcc 0>; + + clocks = <&gcc GCC_DISP_AHB_CLK>, <&gcc GCC_DISP_AXI_CLK>, + <&clock_dispcc DISP_CC_MDSS_MDP_CLK>; + clock-names = "iface", "bus", "core"; + + assigned-clocks = <&clock_dispcc DISP_CC_MDSS_MDP_CLK>; + assigned-clock-rates = <300000000>; + + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + + iommus = <&apps_iommu 0>; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0xae00000 0xb2008>; + + mdss_mdp: mdp@ae01000 { + compatible = "qcom,sdm845-dpu"; + reg = <0 0x1000 0x8f000>, <0 0xb0000 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>, + <&clock_dispcc DISP_CC_MDSS_AXI_CLK>, + <&clock_dispcc DISP_CC_MDSS_MDP_CLK>, + <&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "iface", "bus", "core", "vsync"; + + assigned-clocks = <&clock_dispcc DISP_CC_MDSS_MDP_CLK>, + <&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <0 0 300000000 19200000>; + + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + + port@1 { + reg = <1>; + dpu_intf2_out: endpoint { + remote-endpoint = <&dsi1_in>; + }; + }; + }; + }; + };
On Fri, Jul 20, 2018 at 04:43:09PM -0400, Sean Paul wrote:
From: Jeykumar Sankaran jsanka@codeaurora.org
Adds bindings for Snapdragon 845 display processing unit
Changes in v2:
- Use SoC specific compatibles for mdss and dpu (Rob Herring)
- Use assigned-clocks to set initial clock frequency (Rob Herring)
Changes in v3 (all suggested by Rob Herring):
- Rename mdss_phys to mdss
- Correct description for clocks/assigned-clocks
- Rename mdp_phys to mdp
- Rename vbif_phys to vbif
- Remove redundant interrupt-parent from mdss_mdp
- Fully specify 'ranges' and use relative reg address in mdss_mdp
Cc: Rob Herring robh+dt@kernel.org Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org
.../devicetree/bindings/display/msm/dpu.txt | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/msm/dpu.txt
Reviewed-by: Rob Herring robh@kernel.org
From: Jeykumar Sankaran jsanka@codeaurora.org
SDM845 SoC includes the Mobile Display Sub System (MDSS) which is a top level wrapper consisting of Display Processing Unit (DPU) and display peripheral modules such as Display Serial Interface (DSI) and DisplayPort (DP).
MDSS functions essentially as a back-end composition engine. It blends video and graphic images stored in the frame buffers and scans out the composed image to a display sink (over DSI/DP).
The following diagram represents hardware blocks for a simple pipeline (two planes are present on a given crtc which is connected to a DSI connector):
MDSS +---------------------------------+ | +-----------------------------+ | | | DPU | | | | +--------+ +--------+ | | | | | SSPP | | SSPP | | | | | +----+---+ +----+---+ | | | | | | | | | | +----v-----------v---+ | | | | | Layer Mixer (LM) | | | | | +--------------------+ | | | | +--------------------+ | | | | | PingPong (PP) | | | | | +--------------------+ | | | | +--------------------+ | | | | | INTERFACE (VIDEO) | | | | | +---+----------------+ | | | +------|----------------------+ | | | | | +------|---------------------+ | | | | DISPLAY PERIPHERALS | | | | +---v-+ +-----+ | | | | | DSI | | DP | | | | | +-----+ +-----+ | | | +----------------------------+ | +---------------------------------+
The number of DPU sub-blocks (i.e. SSPPs, LMs, PP blocks and INTFs) depends on SoC capabilities.
Overview of DPU sub-blocks: --------------------------- * Source Surface Processor (SSPP): Refers to any of hardware pipes like ViG, DMA etc. Only ViG pipes are capable of performing format conversion, scaling and quality improvement for source surfaces.
* Layer Mixer (LM): Blend source surfaces together (in requested zorder)
* PingPong (PP): This block controls frame done interrupt output, EOL and EOF generation, overflow/underflow control.
* Display interface (INTF): Timing generator and interface connecting the display peripherals.
DRM components mapping to DPU architecture: ------------------------------------------ PLANEs maps to SSPPs CRTC maps to LMs Encoder maps to PPs, INTFs
Data flow setup: --------------- MDSS hardware can support various data flows (e.g.): - Dual pipe: Output from two LMs combined to single display. - Split display: Output from two LMs connected to two separate interfaces.
The hardware capabilities determine the number of concurrent data paths possible. Any control path (i.e. pipeline w/i DPU) can be routed to any of the hardware data paths. A given control path can be triggered, flushed and controlled independently.
Changes in v3: - Move msm_media_info.h from uapi to dpu/ subdir - Remove preclose callback dpu (it's handled in core) - Fix kbuild warnings with parent_ops - Remove unused functions from dpu_core_irq - Rename mdss_phys to mdss - Rename mdp_phys address space to mdp - Drop _phys from vbif and regdma binding names
Signed-off-by: Abhinav Kumar abhinavk@codeaurora.org Signed-off-by: Archit Taneja architt@codeaurora.org Signed-off-by: Chandan Uddaraju chandanu@codeaurora.org Signed-off-by: Jeykumar Sankaran jsanka@codeaurora.org Signed-off-by: Jordan Crouse jcrouse@codeaurora.org Signed-off-by: Rajesh Yadav ryadav@codeaurora.org Signed-off-by: Sravanthi Kollukuduru skolluku@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org --- drivers/gpu/drm/msm/Makefile | 32 +- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c | 479 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 153 + drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 637 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 133 + drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2504 ++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 484 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c | 2393 +++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h | 103 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2575 +++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 191 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 453 +++ .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 905 ++++++ .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 922 ++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 1276 ++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h | 136 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c | 155 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h | 53 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 511 ++++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 804 +++++ .../drm/msm/disp/dpu1/dpu_hw_catalog_format.h | 182 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c | 323 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h | 139 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 540 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 218 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 1183 ++++++++ .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 257 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 349 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 128 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 261 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 122 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 465 +++ .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 250 ++ .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 136 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 753 +++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 424 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 398 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 202 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 452 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 358 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c | 275 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h | 128 + drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h | 56 + drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c | 204 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h | 57 + drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c | 66 + drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h | 59 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1345 +++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 402 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c | 153 + drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 245 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 1963 +++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 175 ++ .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 249 ++ .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 225 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 1079 +++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 199 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 1007 +++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 384 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h | 94 + .../gpu/drm/msm/disp/dpu1/msm_media_info.h | 1376 +++++++++ drivers/gpu/drm/msm/msm_drv.c | 135 +- drivers/gpu/drm/msm/msm_drv.h | 81 +- drivers/gpu/drm/msm/msm_kms.h | 8 + 64 files changed, 31989 insertions(+), 15 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h create mode 100644 drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h
The patch is too large for dri-devel, please refer to: https://gitlab.freedesktop.org/seanpaul/dpu-staging/commit/00601828c2959f913...
dri-devel@lists.freedesktop.org