Linux ARM-MSM sub-architecture
 help / color / mirror / Atom feed
* [PATCH v3 00/14] drm/msm/dp: perform misc cleanups
@ 2024-12-11 23:41 Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it Dmitry Baryshkov
                   ` (14 more replies)
  0 siblings, 15 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel, kernel test robot

- Fix register programming in the dp_audio module
- Rework most of the register programming functions to be local to the
  calling module rather than accessing everything through huge
  dp_catalog monster.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
Changes in v3:
- Fixed falce -> false typo (Abhinav)
- Dropped wrong c&p comment from msm_dp_read_p0() (Stephen)
- Changed msm_dp_aux_clear_hw_interrupts() to return void (Stephen)
- Fixed most of line length warnings
- Link to v2: https://lore.kernel.org/r/20241202-fd-dp-audio-fixup-v2-0-d9187ea96dad@linaro.org

Changes in v2:
- Set safe_to_exit_level before printing it (LKP)
- Keep TPG-related functions (Abhinav)
- Link to v1: https://lore.kernel.org/r/20241108-fd-dp-audio-fixup-v1-0-40c8eeb60cf5@linaro.org

---
Dmitry Baryshkov (14):
      drm/msm/dp: set safe_to_exit_level before printing it
      drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface
      drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs()
      drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
      drm/msm/dp: move I/O functions to global header
      drm/msm/dp: move/inline AUX register functions
      drm/msm/dp: move/inline ctrl register functions
      drm/msm/dp: move/inline panel related functions
      drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
      drm/msm/dp: drop obsolete audio headers access through catalog
      drm/msm/dp: move/inline audio related functions
      drm/msm/dp: move more AUX functions to dp_aux.c
      drm/msm/dp: drop struct msm_dp_panel_in
      drm/msm/dp: move interrupt handling to dp_ctrl

 drivers/gpu/drm/msm/dp/dp_audio.c   |  362 ++++------
 drivers/gpu/drm/msm/dp/dp_aux.c     |  199 +++++-
 drivers/gpu/drm/msm/dp/dp_aux.h     |    9 +-
 drivers/gpu/drm/msm/dp/dp_catalog.c | 1271 +----------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  173 ++---
 drivers/gpu/drm/msm/dp/dp_ctrl.c    |  575 ++++++++++++++--
 drivers/gpu/drm/msm/dp/dp_ctrl.h    |    5 +-
 drivers/gpu/drm/msm/dp/dp_display.c |   36 +-
 drivers/gpu/drm/msm/dp/dp_panel.c   |  234 ++++++-
 drivers/gpu/drm/msm/dp/dp_panel.h   |   14 +-
 drivers/gpu/drm/msm/dp/dp_reg.h     |   17 +
 drivers/gpu/drm/msm/dp/dp_utils.c   |   10 +-
 drivers/gpu/drm/msm/dp/dp_utils.h   |    2 +-
 13 files changed, 1180 insertions(+), 1727 deletions(-)
---
base-commit: 91e71d606356e50f238d7a87aacdee4abc427f07
change-id: 20240615-fd-dp-audio-fixup-a92883ea9e40

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12  1:14   ` Abhinav Kumar
  2024-12-11 23:41 ` [PATCH v3 02/14] drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface Dmitry Baryshkov
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel, kernel test robot

Rather than printing random garbage from stack and pretending that it is
the default safe_to_exit_level, set the variable beforehand.

Fixes: d13e36d7d222 ("drm/msm/dp: add audio support for Display Port on MSM")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202411081748.0PPL9MIj-lkp@intel.com/
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_audio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 74e01a5dd4195d5e0e04250663886f1116f25711..5cbb11986460d1e4ed1890bdf66d0913e013083c 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -329,10 +329,10 @@ static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
 		safe_to_exit_level = 5;
 		break;
 	default:
+		safe_to_exit_level = 14;
 		drm_dbg_dp(audio->drm_dev,
 				"setting the default safe_to_exit_level = %u\n",
 				safe_to_exit_level);
-		safe_to_exit_level = 14;
 		break;
 	}
 

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 02/14] drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12  1:23   ` Abhinav Kumar
  2024-12-11 23:41 ` [PATCH v3 03/14] drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs() Dmitry Baryshkov
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

The msm_dp_utils_pack_sdp_header() accepts an unlimited-size u32 pointer
for the header output, while it expects a two-element array. It performs
a sizeof check which is always true on 64-bit platforms (since
sizeof(u32*) is 8) and is always false on 32-bit platforms. It returns
an error code which nobody actually checks.

Fix the function interface to accept u32[2] and return void, skipping
all the checks.

Fixes: 55fb8ffc1802 ("drm/msm/dp: add VSC SDP support for YUV420 over DP")
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_utils.c | 10 +---------
 drivers/gpu/drm/msm/dp/dp_utils.h |  2 +-
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_utils.c b/drivers/gpu/drm/msm/dp/dp_utils.c
index 2a40f07fe2d5e20114a7692d1269bb8fd5bddbbd..4a5ebb0c33b85e3d55eb974d74c1f54591301b35 100644
--- a/drivers/gpu/drm/msm/dp/dp_utils.c
+++ b/drivers/gpu/drm/msm/dp/dp_utils.c
@@ -74,14 +74,8 @@ u8 msm_dp_utils_calculate_parity(u32 data)
 	return parity_byte;
 }
 
-ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff)
+void msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 header_buff[2])
 {
-	size_t length;
-
-	length = sizeof(header_buff);
-	if (length < DP_SDP_HEADER_SIZE)
-		return -ENOSPC;
-
 	header_buff[0] = FIELD_PREP(HEADER_0_MASK, sdp_header->HB0) |
 		FIELD_PREP(PARITY_0_MASK, msm_dp_utils_calculate_parity(sdp_header->HB0)) |
 		FIELD_PREP(HEADER_1_MASK, sdp_header->HB1) |
@@ -91,6 +85,4 @@ ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *head
 		FIELD_PREP(PARITY_2_MASK, msm_dp_utils_calculate_parity(sdp_header->HB2)) |
 		FIELD_PREP(HEADER_3_MASK, sdp_header->HB3) |
 		FIELD_PREP(PARITY_3_MASK, msm_dp_utils_calculate_parity(sdp_header->HB3));
-
-	return length;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_utils.h b/drivers/gpu/drm/msm/dp/dp_utils.h
index 88d53157f5b59e352a29075e4e8deb044a6de3bd..2e4f98a863c4cb971e621ac24b8b58f035236e73 100644
--- a/drivers/gpu/drm/msm/dp/dp_utils.h
+++ b/drivers/gpu/drm/msm/dp/dp_utils.h
@@ -31,6 +31,6 @@
 u8 msm_dp_utils_get_g0_value(u8 data);
 u8 msm_dp_utils_get_g1_value(u8 data);
 u8 msm_dp_utils_calculate_parity(u32 data);
-ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff);
+void msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 header_buff[2]);
 
 #endif /* _DP_UTILS_H_ */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 03/14] drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs()
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 02/14] drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12  1:13   ` Abhinav Kumar
  2024-12-11 23:41 ` [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private() Dmitry Baryshkov
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

The msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs() are not
called anywhere. If there is a necessity to dump registers, the
snapshotting should be used instead. Drop these two functions.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 37 -------------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  1 -
 drivers/gpu/drm/msm/dp/dp_panel.c   | 11 -----------
 drivers/gpu/drm/msm/dp/dp_panel.h   |  1 -
 4 files changed, 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index b4c8856fb25d01dd1b30c5ec33ce821aafa9551d..0357dec1acd5773f25707e7ebdfca4b1d2b1bb4e 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -276,43 +276,6 @@ int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_
 				min(wait_us, 2000), wait_us);
 }
 
-static void dump_regs(void __iomem *base, int len)
-{
-	int i;
-	u32 x0, x4, x8, xc;
-	u32 addr_off = 0;
-
-	len = DIV_ROUND_UP(len, 16);
-	for (i = 0; i < len; i++) {
-		x0 = readl_relaxed(base + addr_off);
-		x4 = readl_relaxed(base + addr_off + 0x04);
-		x8 = readl_relaxed(base + addr_off + 0x08);
-		xc = readl_relaxed(base + addr_off + 0x0c);
-
-		pr_info("%08x: %08x %08x %08x %08x", addr_off, x0, x4, x8, xc);
-		addr_off += 16;
-	}
-}
-
-void msm_dp_catalog_dump_regs(struct msm_dp_catalog *msm_dp_catalog)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-	struct dss_io_data *io = &catalog->io;
-
-	pr_info("AHB regs\n");
-	dump_regs(io->ahb.base, io->ahb.len);
-
-	pr_info("AUXCLK regs\n");
-	dump_regs(io->aux.base, io->aux.len);
-
-	pr_info("LCLK regs\n");
-	dump_regs(io->link.base, io->link.len);
-
-	pr_info("P0CLK regs\n");
-	dump_regs(io->p0.base, io->p0.len);
-}
-
 u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
 {
 	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index e932b17eecbf514070cd8cd0b98ca0fefbe81ab7..62a401d8f75a6af06445a42af657d65e3fe542c5 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -104,7 +104,6 @@ int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 t
 				u32 sync_start, u32 width_blanking, u32 msm_dp_active);
 void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp);
 void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_dump_regs(struct msm_dp_catalog *msm_dp_catalog);
 void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
 				struct drm_display_mode *drm_mode);
 void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 5d7eaa31bf3176566f40f01ff636bee64e81c64f..7d122496723a32fd591d094269397a9fdd51fe44 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -317,17 +317,6 @@ static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
 	return 0;
 }
 
-void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel)
-{
-	struct msm_dp_catalog *catalog;
-	struct msm_dp_panel_private *panel;
-
-	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
-	catalog = panel->catalog;
-
-	msm_dp_catalog_dump_regs(catalog);
-}
-
 int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
 {
 	u32 data, total_ver, total_hor;
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index 0e944db3adf2f187f313664fe80cf540ec7a19f2..47c1d349be470b60596b64a7bc8c7c39d2e8fdd1 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -55,7 +55,6 @@ struct msm_dp_panel {
 int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel);
 int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
 int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel);
-void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel);
 int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
 		struct drm_connector *connector);
 u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (2 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 03/14] drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs() Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12  2:59   ` Abhinav Kumar
  2024-12-11 23:41 ` [PATCH v3 05/14] drm/msm/dp: move I/O functions to global header Dmitry Baryshkov
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Having I/O regions inside a msm_dp_catalog_private() results in extra
layers of one-line wrappers for accessing the data. Move I/O region base
and size to the globally visible struct msm_dp_catalog.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
 2 files changed, 197 insertions(+), 272 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 0357dec1acd5773f25707e7ebdfca4b1d2b1bb4e..cdb8685924a06e4fc79d70586630ccb9a16a676d 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -63,155 +63,128 @@
 #define DP_DEFAULT_P0_OFFSET	0x1000
 #define DP_DEFAULT_P0_SIZE	0x0400
 
-struct dss_io_region {
-	size_t len;
-	void __iomem *base;
-};
-
-struct dss_io_data {
-	struct dss_io_region ahb;
-	struct dss_io_region aux;
-	struct dss_io_region link;
-	struct dss_io_region p0;
-};
-
 struct msm_dp_catalog_private {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	struct dss_io_data io;
 	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
 	struct msm_dp_catalog msm_dp_catalog;
 };
 
 void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-			struct msm_dp_catalog_private, msm_dp_catalog);
-	struct dss_io_data *dss = &catalog->io;
-
-	msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb");
-	msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux");
-	msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, "dp_link");
-	msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, "dp_p0");
+	msm_disp_snapshot_add_block(disp_state,
+				    msm_dp_catalog->ahb_len, msm_dp_catalog->ahb_base, "dp_ahb");
+	msm_disp_snapshot_add_block(disp_state,
+				    msm_dp_catalog->aux_len, msm_dp_catalog->aux_base, "dp_aux");
+	msm_disp_snapshot_add_block(disp_state,
+				    msm_dp_catalog->link_len, msm_dp_catalog->link_base, "dp_link");
+	msm_disp_snapshot_add_block(disp_state,
+				    msm_dp_catalog->p0_len, msm_dp_catalog->p0_base, "dp_p0");
 }
 
-static inline u32 msm_dp_read_aux(struct msm_dp_catalog_private *catalog, u32 offset)
+static inline u32 msm_dp_read_aux(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
 {
-	return readl_relaxed(catalog->io.aux.base + offset);
+	return readl_relaxed(msm_dp_catalog->aux_base + offset);
 }
 
-static inline void msm_dp_write_aux(struct msm_dp_catalog_private *catalog,
+static inline void msm_dp_write_aux(struct msm_dp_catalog *msm_dp_catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure aux reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io.aux.base + offset);
+	writel(data, msm_dp_catalog->aux_base + offset);
 }
 
-static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog_private *catalog, u32 offset)
+static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog *msm_dp_catalog, u32 offset)
 {
-	return readl_relaxed(catalog->io.ahb.base + offset);
+	return readl_relaxed(msm_dp_catalog->ahb_base + offset);
 }
 
-static inline void msm_dp_write_ahb(struct msm_dp_catalog_private *catalog,
+static inline void msm_dp_write_ahb(struct msm_dp_catalog *msm_dp_catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure phy reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io.ahb.base + offset);
+	writel(data, msm_dp_catalog->ahb_base + offset);
 }
 
-static inline void msm_dp_write_p0(struct msm_dp_catalog_private *catalog,
+static inline void msm_dp_write_p0(struct msm_dp_catalog *msm_dp_catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure interface reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io.p0.base + offset);
+	writel(data, msm_dp_catalog->p0_base + offset);
 }
 
-static inline u32 msm_dp_read_p0(struct msm_dp_catalog_private *catalog,
+static inline u32 msm_dp_read_p0(struct msm_dp_catalog *msm_dp_catalog,
 			       u32 offset)
 {
 	/*
 	 * To make sure interface reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	return readl_relaxed(catalog->io.p0.base + offset);
+	return readl_relaxed(msm_dp_catalog->p0_base + offset);
 }
 
-static inline u32 msm_dp_read_link(struct msm_dp_catalog_private *catalog, u32 offset)
+static inline u32 msm_dp_read_link(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
 {
-	return readl_relaxed(catalog->io.link.base + offset);
+	return readl_relaxed(msm_dp_catalog->link_base + offset);
 }
 
-static inline void msm_dp_write_link(struct msm_dp_catalog_private *catalog,
+static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure link reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io.link.base + offset);
+	writel(data, msm_dp_catalog->link_base + offset);
 }
 
 /* aux related catalog functions */
 u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	return msm_dp_read_aux(catalog, REG_DP_AUX_DATA);
+	return msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_DATA);
 }
 
 int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_write_aux(catalog, REG_DP_AUX_DATA, data);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_DATA, data);
 	return 0;
 }
 
 int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, data);
 	return 0;
 }
 
 int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read)
 {
 	u32 data;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	if (read) {
-		data = msm_dp_read_aux(catalog, REG_DP_AUX_TRANS_CTRL);
+		data = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL);
 		data &= ~DP_AUX_TRANS_CTRL_GO;
-		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
+		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, data);
 	} else {
-		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, 0);
+		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, 0);
 	}
 	return 0;
 }
 
 int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_read_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
-	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
-	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
-	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
+	msm_dp_read_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
 	return 0;
 }
 
@@ -230,47 +203,41 @@ int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog
 void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 aux_ctrl;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
+	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
 
 	aux_ctrl |= DP_AUX_CTRL_RESET;
-	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
 	usleep_range(1000, 1100); /* h/w recommended delay */
 
 	aux_ctrl &= ~DP_AUX_CTRL_RESET;
-	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
 }
 
 void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
 {
 	u32 aux_ctrl;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
+	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
 
 	if (enable) {
-		msm_dp_write_aux(catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
-		msm_dp_write_aux(catalog, REG_DP_AUX_LIMITS, 0xffff);
+		msm_dp_write_aux(msm_dp_catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
+		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_LIMITS, 0xffff);
 		aux_ctrl |= DP_AUX_CTRL_ENABLE;
 	} else {
 		aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
 	}
 
-	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
 }
 
 int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
 					      unsigned long wait_us)
 {
 	u32 state;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	/* poll for hpd connected status every 2ms and timeout after wait_us */
-	return readl_poll_timeout(catalog->io.aux.base +
+	return readl_poll_timeout(msm_dp_catalog->aux_base +
 				REG_DP_DP_HPD_INT_STATUS,
 				state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
 				min(wait_us, 2000), wait_us);
@@ -278,15 +245,13 @@ int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_
 
 u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 intr, intr_ack;
 
-	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS);
+	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS);
 	intr &= ~DP_INTERRUPT_STATUS1_MASK;
 	intr_ack = (intr & DP_INTERRUPT_STATUS1)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, intr_ack |
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, intr_ack |
 			DP_INTERRUPT_STATUS1_MASK);
 
 	return intr;
@@ -298,20 +263,14 @@ void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_cata
 				u32 msm_dp_tu, u32 valid_boundary,
 				u32 valid_boundary2)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
-	msm_dp_write_link(catalog, REG_DP_TU, msm_dp_tu);
-	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_TU, msm_dp_tu);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
 }
 
 void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, state);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, state);
 }
 
 void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 cfg)
@@ -321,13 +280,11 @@ void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32
 
 	drm_dbg_dp(catalog->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", cfg);
 
-	msm_dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_CONFIGURATION_CTRL, cfg);
 }
 
 void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
 	u32 ln_mapping;
 
@@ -336,7 +293,7 @@ void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
 	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
 	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
 
-	msm_dp_write_link(catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
+	msm_dp_write_link(msm_dp_catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
 			ln_mapping);
 }
 
@@ -344,17 +301,15 @@ void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catal
 						bool enable)
 {
 	u32 val;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	val = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+	val = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
 
 	if (enable)
 		val |= DP_MAINLINK_CTRL_ENABLE;
 	else
 		val &= ~DP_MAINLINK_CTRL_ENABLE;
 
-	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, val);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, val);
 }
 
 void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
@@ -370,25 +325,25 @@ void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
 		 * To make sure link reg writes happens before other operation,
 		 * msm_dp_write_link() function uses writel()
 		 */
-		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
 
 		mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
 						DP_MAINLINK_CTRL_ENABLE);
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 
 		mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 
 		mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 
 		mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
 					DP_MAINLINK_FB_BOUNDARY_SEL);
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 	} else {
-		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
 		mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 	}
 }
 
@@ -400,7 +355,7 @@ void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
 	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
 				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	misc_val = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
+	misc_val = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
 
 	/* clear bpp bits */
 	misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
@@ -410,16 +365,14 @@ void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
 	misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
 
 	drm_dbg_dp(catalog->drm_dev, "misc settings = 0x%x\n", misc_val);
-	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc_val);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc_val);
 }
 
 void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 mainlink_ctrl, hw_revision;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+	mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
 
 	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
 	if (hw_revision >= DP_HW_VERSION_1_2)
@@ -427,7 +380,7 @@ void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog
 	else
 		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
 
-	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 }
 
 void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
@@ -485,9 +438,9 @@ void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
 		nvid *= 3;
 
 	drm_dbg_dp(catalog->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
-	msm_dp_write_link(catalog, REG_DP_SOFTWARE_MVID, mvid);
-	msm_dp_write_link(catalog, REG_DP_SOFTWARE_NVID, nvid);
-	msm_dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_SOFTWARE_MVID, mvid);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_SOFTWARE_NVID, nvid);
+	msm_dp_write_p0(msm_dp_catalog, MMSS_DP_DSC_DTO, 0x0);
 }
 
 int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog,
@@ -505,7 +458,7 @@ int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_cata
 	bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
 
 	/* Poll for mainlink ready status */
-	ret = readx_poll_timeout(readl, catalog->io.link.base +
+	ret = readx_poll_timeout(readl, msm_dp_catalog->link_base +
 					REG_DP_MAINLINK_READY,
 					data, data & bit,
 					POLLING_SLEEP_US, POLLING_TIMEOUT_US);
@@ -526,10 +479,7 @@ int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_cata
  */
 u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
 {
-	const struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	return msm_dp_read_ahb(catalog, REG_DP_HW_VERSION);
+	return msm_dp_read_ahb(msm_dp_catalog, REG_DP_HW_VERSION);
 }
 
 /**
@@ -547,28 +497,24 @@ u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
 void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 sw_reset;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	sw_reset = msm_dp_read_ahb(catalog, REG_DP_SW_RESET);
+	sw_reset = msm_dp_read_ahb(msm_dp_catalog, REG_DP_SW_RESET);
 
 	sw_reset |= DP_SW_RESET;
-	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
 	usleep_range(1000, 1100); /* h/w recommended delay */
 
 	sw_reset &= ~DP_SW_RESET;
-	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
 }
 
 bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 data;
 	int ret;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	/* Poll for mainlink ready status */
-	ret = readl_poll_timeout(catalog->io.link.base +
+	ret = readl_poll_timeout(msm_dp_catalog->link_base +
 				REG_DP_MAINLINK_READY,
 				data, data & DP_MAINLINK_READY_FOR_VIDEO,
 				POLLING_SLEEP_US, POLLING_TIMEOUT_US);
@@ -583,17 +529,14 @@ bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
 void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
 						bool enable)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
 	if (enable) {
-		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS,
+		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
 				DP_INTERRUPT_STATUS1_MASK);
-		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
+		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
 				DP_INTERRUPT_STATUS2_MASK);
 	} else {
-		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, 0x00);
-		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 0x00);
+		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, 0x00);
+		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2, 0x00);
 	}
 }
 
@@ -603,73 +546,63 @@ void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
 	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
 				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	u32 config = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
+	u32 config = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
 
 	config = (en ? config | intr_mask : config & ~intr_mask);
 
 	drm_dbg_dp(catalog->drm_dev, "intr_mask=%#x config=%#x\n",
 					intr_mask, config);
-	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK,
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK,
 				config & DP_DP_HPD_INT_MASK);
 }
 
 void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+	u32 reftimer = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
 
 	/* Configure REFTIMER and enable it */
 	reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
-	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
 
 	/* Enable HPD */
-	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
 }
 
 void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+	u32 reftimer = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
 
 	reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
-	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
 
-	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, 0);
 }
 
-static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog_private *catalog)
+static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog *msm_dp_catalog)
 {
 	/* trigger sdp */
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x0);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x0);
 }
 
 void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 config;
 
 	/* enable PSR1 function */
-	config = msm_dp_read_link(catalog, REG_PSR_CONFIG);
+	config = msm_dp_read_link(msm_dp_catalog, REG_PSR_CONFIG);
 	config |= PSR1_SUPPORTED;
-	msm_dp_write_link(catalog, REG_PSR_CONFIG, config);
+	msm_dp_write_link(msm_dp_catalog, REG_PSR_CONFIG, config);
 
-	msm_dp_write_ahb(catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
-	msm_dp_catalog_enable_sdp(catalog);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
+	msm_dp_catalog_enable_sdp(msm_dp_catalog);
 }
 
 void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-			struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 cmd;
 
-	cmd = msm_dp_read_link(catalog, REG_PSR_CMD);
+	cmd = msm_dp_read_link(msm_dp_catalog, REG_PSR_CMD);
 
 	cmd &= ~(PSR_ENTER | PSR_EXIT);
 
@@ -678,8 +611,8 @@ void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool ent
 	else
 		cmd |= PSR_EXIT;
 
-	msm_dp_catalog_enable_sdp(catalog);
-	msm_dp_write_link(catalog, REG_PSR_CMD, cmd);
+	msm_dp_catalog_enable_sdp(msm_dp_catalog);
+	msm_dp_write_link(msm_dp_catalog, REG_PSR_CMD, cmd);
 }
 
 u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
@@ -688,7 +621,7 @@ u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
 				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 status;
 
-	status = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
+	status = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
 	drm_dbg_dp(catalog->drm_dev, "aux status: %#x\n", status);
 	status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
 	status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
@@ -698,14 +631,12 @@ u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
 
 u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	int isr, mask;
 
-	isr = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
-	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK,
+	isr = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_ACK,
 				 (isr & DP_DP_HPD_INT_MASK));
-	mask = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
+	mask = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
 
 	/*
 	 * We only want to return interrupts that are unmasked to the caller.
@@ -719,29 +650,25 @@ u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
 
 u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 intr, intr_ack;
 
-	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS4);
+	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4);
 	intr_ack = (intr & DP_INTERRUPT_STATUS4)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS4, intr_ack);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4, intr_ack);
 
 	return intr;
 }
 
 int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 intr, intr_ack;
 
-	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS2);
+	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2);
 	intr &= ~DP_INTERRUPT_STATUS2_MASK;
 	intr_ack = (intr & DP_INTERRUPT_STATUS2)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
 			intr_ack | DP_INTERRUPT_STATUS2_MASK);
 
 	return intr;
@@ -749,13 +676,10 @@ int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
 
 void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL,
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_PHY_CTRL,
 			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
 	usleep_range(1000, 1100); /* h/w recommended delay */
-	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL, 0x0);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_PHY_CTRL, 0x0);
 }
 
 void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
@@ -766,66 +690,66 @@ void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
 	u32 value = 0x0;
 
 	/* Make sure to clear the current pattern before starting a new one */
-	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, 0x0);
 
 	drm_dbg_dp(catalog->drm_dev, "pattern: %#x\n", pattern);
 	switch (pattern) {
 	case DP_PHY_TEST_PATTERN_D10_2:
-		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
 		break;
 	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
 		value &= ~(1 << 16);
-		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 					value);
 		value |= SCRAMBLER_RESET_COUNT_VALUE;
-		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 					value);
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
 					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
-		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
 					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
 		break;
 	case DP_PHY_TEST_PATTERN_PRBS7:
-		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_PRBS7);
 		break;
 	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
-		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
 		/* 00111110000011111000001111100000 */
-		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
 				0x3E0F83E0);
 		/* 00001111100000111110000011111000 */
-		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
 				0x0F83E0F8);
 		/* 1111100000111110 */
-		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
 				0x0000F83E);
 		break;
 	case DP_PHY_TEST_PATTERN_CP2520:
-		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
 		value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
 
 		value = DP_HBR2_ERM_PATTERN;
-		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 				value);
 		value |= SCRAMBLER_RESET_COUNT_VALUE;
-		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 					value);
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
 					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
-		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
 					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
-		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
 		value |= DP_MAINLINK_CTRL_ENABLE;
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
 		break;
 	case DP_PHY_TEST_PATTERN_SEL_MASK:
-		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL,
 				DP_MAINLINK_CTRL_ENABLE);
-		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
 		break;
 	default:
@@ -837,26 +761,21 @@ void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
 
 u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	return msm_dp_read_link(catalog, REG_DP_MAINLINK_READY);
+	return msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_READY);
 }
 
 /* panel related catalog functions */
 int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
 				u32 sync_start, u32 width_blanking, u32 msm_dp_active)
 {
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 reg;
 
-	msm_dp_write_link(catalog, REG_DP_TOTAL_HOR_VER, total);
-	msm_dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
-	msm_dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
-	msm_dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_TOTAL_HOR_VER, total);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
 
-	reg = msm_dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
+	reg = msm_dp_read_p0(msm_dp_catalog, MMSS_DP_INTF_CONFIG);
 
 	if (msm_dp_catalog->wide_bus_en)
 		reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
@@ -866,42 +785,36 @@ int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 t
 
 	DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", msm_dp_catalog->wide_bus_en, reg);
 
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
+	msm_dp_write_p0(msm_dp_catalog, MMSS_DP_INTF_CONFIG, reg);
 	return 0;
 }
 
 static void msm_dp_catalog_panel_send_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
 {
-	struct msm_dp_catalog_private *catalog;
 	u32 header[2];
 	u32 val;
 	int i;
 
-	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
-
 	msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
 
-	msm_dp_write_link(catalog, MMSS_DP_GENERIC0_0, header[0]);
-	msm_dp_write_link(catalog, MMSS_DP_GENERIC0_1, header[1]);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_0, header[0]);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_1, header[1]);
 
 	for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
 		val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
 		       (vsc_sdp->db[i + 3] << 24));
-		msm_dp_write_link(catalog, MMSS_DP_GENERIC0_2 + i, val);
+		msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_2 + i, val);
 	}
 }
 
 static void msm_dp_catalog_panel_update_sdp(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct msm_dp_catalog_private *catalog;
 	u32 hw_revision;
 
-	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
-
 	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
 	if (hw_revision < DP_HW_VERSION_1_2 && hw_revision >= DP_HW_VERSION_1_0) {
-		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x01);
-		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x00);
+		msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x01);
+		msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x00);
 	}
 }
 
@@ -912,15 +825,15 @@ void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog,
 
 	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
 
-	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
-	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
-	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
+	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
+	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
+	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
 
 	cfg |= GEN0_SDP_EN;
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, cfg);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
 
 	cfg2 |= GENERIC0_SDPSIZE_VALID;
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, cfg2);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
 
 	msm_dp_catalog_panel_send_vsc_sdp(msm_dp_catalog, vsc_sdp);
 
@@ -930,7 +843,7 @@ void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog,
 	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=1\n");
 
 	pr_debug("misc settings = 0x%x\n", misc);
-	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
 
 	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
 }
@@ -942,15 +855,15 @@ void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
 
 	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
 
-	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
-	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
-	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
+	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
+	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
+	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
 
 	cfg &= ~GEN0_SDP_EN;
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, cfg);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
 
 	cfg2 &= ~GENERIC0_SDPSIZE_VALID;
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, cfg2);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
 
 	/* switch back to MSA */
 	misc &= ~DP_MISC1_VSC_SDP;
@@ -958,7 +871,7 @@ void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
 	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=0\n");
 
 	pr_debug("misc settings = 0x%x\n", misc);
-	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
 
 	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
 }
@@ -1055,15 +968,15 @@ static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_
 
 static int msm_dp_catalog_get_io(struct msm_dp_catalog_private *catalog)
 {
+	struct msm_dp_catalog *msm_dp_catalog = &catalog->msm_dp_catalog;
 	struct platform_device *pdev = to_platform_device(catalog->dev);
-	struct dss_io_data *dss = &catalog->io;
 
-	dss->ahb.base = msm_dp_ioremap(pdev, 0, &dss->ahb.len);
-	if (IS_ERR(dss->ahb.base))
-		return PTR_ERR(dss->ahb.base);
+	msm_dp_catalog->ahb_base = msm_dp_ioremap(pdev, 0, &msm_dp_catalog->ahb_len);
+	if (IS_ERR(msm_dp_catalog->ahb_base))
+		return PTR_ERR(msm_dp_catalog->ahb_base);
 
-	dss->aux.base = msm_dp_ioremap(pdev, 1, &dss->aux.len);
-	if (IS_ERR(dss->aux.base)) {
+	msm_dp_catalog->aux_base = msm_dp_ioremap(pdev, 1, &msm_dp_catalog->aux_len);
+	if (IS_ERR(msm_dp_catalog->aux_base)) {
 		/*
 		 * The initial binding had a single reg, but in order to
 		 * support variation in the sub-region sizes this was split.
@@ -1071,34 +984,34 @@ static int msm_dp_catalog_get_io(struct msm_dp_catalog_private *catalog)
 		 * reg is specified, so fill in the sub-region offsets and
 		 * lengths based on this single region.
 		 */
-		if (PTR_ERR(dss->aux.base) == -EINVAL) {
-			if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
+		if (PTR_ERR(msm_dp_catalog->aux_base) == -EINVAL) {
+			if (msm_dp_catalog->ahb_len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
 				DRM_ERROR("legacy memory region not large enough\n");
 				return -EINVAL;
 			}
 
-			dss->ahb.len = DP_DEFAULT_AHB_SIZE;
-			dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
-			dss->aux.len = DP_DEFAULT_AUX_SIZE;
-			dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
-			dss->link.len = DP_DEFAULT_LINK_SIZE;
-			dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
-			dss->p0.len = DP_DEFAULT_P0_SIZE;
+			msm_dp_catalog->ahb_len = DP_DEFAULT_AHB_SIZE;
+			msm_dp_catalog->aux_base = msm_dp_catalog->ahb_base + DP_DEFAULT_AUX_OFFSET;
+			msm_dp_catalog->aux_len = DP_DEFAULT_AUX_SIZE;
+			msm_dp_catalog->link_base = msm_dp_catalog->ahb_base + DP_DEFAULT_LINK_OFFSET;
+			msm_dp_catalog->link_len = DP_DEFAULT_LINK_SIZE;
+			msm_dp_catalog->p0_base = msm_dp_catalog->ahb_base + DP_DEFAULT_P0_OFFSET;
+			msm_dp_catalog->p0_len = DP_DEFAULT_P0_SIZE;
 		} else {
-			DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
-			return PTR_ERR(dss->aux.base);
+			DRM_ERROR("unable to remap aux region: %pe\n", msm_dp_catalog->aux_base);
+			return PTR_ERR(msm_dp_catalog->aux_base);
 		}
 	} else {
-		dss->link.base = msm_dp_ioremap(pdev, 2, &dss->link.len);
-		if (IS_ERR(dss->link.base)) {
-			DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
-			return PTR_ERR(dss->link.base);
+		msm_dp_catalog->link_base = msm_dp_ioremap(pdev, 2, &msm_dp_catalog->link_len);
+		if (IS_ERR(msm_dp_catalog->link_base)) {
+			DRM_ERROR("unable to remap link region: %pe\n", msm_dp_catalog->link_base);
+			return PTR_ERR(msm_dp_catalog->link_base);
 		}
 
-		dss->p0.base = msm_dp_ioremap(pdev, 3, &dss->p0.len);
-		if (IS_ERR(dss->p0.base)) {
-			DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
-			return PTR_ERR(dss->p0.base);
+		msm_dp_catalog->p0_base = msm_dp_ioremap(pdev, 3, &msm_dp_catalog->p0_len);
+		if (IS_ERR(msm_dp_catalog->p0_base)) {
+			DRM_ERROR("unable to remap p0 region: %pe\n", msm_dp_catalog->p0_base);
+			return PTR_ERR(msm_dp_catalog->p0_base);
 		}
 	}
 
@@ -1135,7 +1048,7 @@ u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
 
 	sdp_map = catalog->audio_map;
 
-	return msm_dp_read_link(catalog, sdp_map[sdp][header]);
+	return msm_dp_read_link(msm_dp_catalog, sdp_map[sdp][header]);
 }
 
 void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
@@ -1154,7 +1067,7 @@ void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
 
 	sdp_map = catalog->audio_map;
 
-	msm_dp_write_link(catalog, sdp_map[sdp][header], data);
+	msm_dp_write_link(msm_dp_catalog, sdp_map[sdp][header], data);
 }
 
 void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32 select)
@@ -1173,7 +1086,7 @@ void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32
 	drm_dbg_dp(catalog->drm_dev, "select: %#x, acr_ctrl: %#x\n",
 					select, acr_ctrl);
 
-	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
 }
 
 void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
@@ -1187,7 +1100,7 @@ void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool ena
 	catalog = container_of(msm_dp_catalog,
 		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	audio_ctrl = msm_dp_read_link(catalog, MMSS_DP_AUDIO_CFG);
+	audio_ctrl = msm_dp_read_link(msm_dp_catalog, MMSS_DP_AUDIO_CFG);
 
 	if (enable)
 		audio_ctrl |= BIT(0);
@@ -1196,7 +1109,7 @@ void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool ena
 
 	drm_dbg_dp(catalog->drm_dev, "dp_audio_cfg = 0x%x\n", audio_ctrl);
 
-	msm_dp_write_link(catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
 	/* make sure audio engine is disabled */
 	wmb();
 }
@@ -1213,7 +1126,7 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
 	catalog = container_of(msm_dp_catalog,
 		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	sdp_cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
+	sdp_cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
 	/* AUDIO_TIMESTAMP_SDP_EN */
 	sdp_cfg |= BIT(1);
 	/* AUDIO_STREAM_SDP_EN */
@@ -1227,9 +1140,9 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
 
 	drm_dbg_dp(catalog->drm_dev, "sdp_cfg = 0x%x\n", sdp_cfg);
 
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, sdp_cfg);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, sdp_cfg);
 
-	sdp_cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
+	sdp_cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
 	/* IFRM_REGSRC -> Do not use reg values */
 	sdp_cfg2 &= ~BIT(0);
 	/* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */
@@ -1237,7 +1150,7 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
 
 	drm_dbg_dp(catalog->drm_dev, "sdp_cfg2 = 0x%x\n", sdp_cfg2);
 
-	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
 }
 
 void msm_dp_catalog_audio_init(struct msm_dp_catalog *msm_dp_catalog)
@@ -1292,7 +1205,7 @@ void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 s
 	catalog = container_of(msm_dp_catalog,
 		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	mainlink_levels = msm_dp_read_link(catalog, REG_DP_MAINLINK_LEVELS);
+	mainlink_levels = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS);
 	mainlink_levels &= 0xFE0;
 	mainlink_levels |= safe_to_exit_level;
 
@@ -1300,5 +1213,5 @@ void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 s
 			"mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
 			 mainlink_levels, safe_to_exit_level);
 
-	msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 62a401d8f75a6af06445a42af657d65e3fe542c5..13486c9c8703748e69e846be681951368df0a29e 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -49,6 +49,18 @@ enum msm_dp_catalog_audio_header_type {
 
 struct msm_dp_catalog {
 	bool wide_bus_en;
+
+	void __iomem *ahb_base;
+	size_t ahb_len;
+
+	void __iomem *aux_base;
+	size_t aux_len;
+
+	void __iomem *link_base;
+	size_t link_len;
+
+	void __iomem *p0_base;
+	size_t p0_len;
 };
 
 /* Debug module */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 05/14] drm/msm/dp: move I/O functions to global header
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (3 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private() Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12 20:26   ` Stephen Boyd
  2024-12-11 23:41 ` [PATCH v3 06/14] drm/msm/dp: move/inline AUX register functions Dmitry Baryshkov
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Move msm_dp_read()/msm_write_foo() functions to the dp_catalog.h,
allowing other modules to access the data directly.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 65 -------------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h | 62 +++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index cdb8685924a06e4fc79d70586630ccb9a16a676d..a4ac132d807ea469709de68bc0b65ef41dcdae86 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -82,71 +82,6 @@ void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_d
 				    msm_dp_catalog->p0_len, msm_dp_catalog->p0_base, "dp_p0");
 }
 
-static inline u32 msm_dp_read_aux(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
-{
-	return readl_relaxed(msm_dp_catalog->aux_base + offset);
-}
-
-static inline void msm_dp_write_aux(struct msm_dp_catalog *msm_dp_catalog,
-			       u32 offset, u32 data)
-{
-	/*
-	 * To make sure aux reg writes happens before any other operation,
-	 * this function uses writel() instread of writel_relaxed()
-	 */
-	writel(data, msm_dp_catalog->aux_base + offset);
-}
-
-static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog *msm_dp_catalog, u32 offset)
-{
-	return readl_relaxed(msm_dp_catalog->ahb_base + offset);
-}
-
-static inline void msm_dp_write_ahb(struct msm_dp_catalog *msm_dp_catalog,
-			       u32 offset, u32 data)
-{
-	/*
-	 * To make sure phy reg writes happens before any other operation,
-	 * this function uses writel() instread of writel_relaxed()
-	 */
-	writel(data, msm_dp_catalog->ahb_base + offset);
-}
-
-static inline void msm_dp_write_p0(struct msm_dp_catalog *msm_dp_catalog,
-			       u32 offset, u32 data)
-{
-	/*
-	 * To make sure interface reg writes happens before any other operation,
-	 * this function uses writel() instread of writel_relaxed()
-	 */
-	writel(data, msm_dp_catalog->p0_base + offset);
-}
-
-static inline u32 msm_dp_read_p0(struct msm_dp_catalog *msm_dp_catalog,
-			       u32 offset)
-{
-	/*
-	 * To make sure interface reg writes happens before any other operation,
-	 * this function uses writel() instread of writel_relaxed()
-	 */
-	return readl_relaxed(msm_dp_catalog->p0_base + offset);
-}
-
-static inline u32 msm_dp_read_link(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
-{
-	return readl_relaxed(msm_dp_catalog->link_base + offset);
-}
-
-static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
-			       u32 offset, u32 data)
-{
-	/*
-	 * To make sure link reg writes happens before any other operation,
-	 * this function uses writel() instread of writel_relaxed()
-	 */
-	writel(data, msm_dp_catalog->link_base + offset);
-}
-
 /* aux related catalog functions */
 u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog)
 {
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 13486c9c8703748e69e846be681951368df0a29e..0505b4be61f4e316f03df1d52ea35eb17e66580f 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -63,6 +63,68 @@ struct msm_dp_catalog {
 	size_t p0_len;
 };
 
+/* IO */
+static inline u32 msm_dp_read_aux(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
+{
+	return readl_relaxed(msm_dp_catalog->aux_base + offset);
+}
+
+static inline void msm_dp_write_aux(struct msm_dp_catalog *msm_dp_catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure aux reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, msm_dp_catalog->aux_base + offset);
+}
+
+static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog *msm_dp_catalog, u32 offset)
+{
+	return readl_relaxed(msm_dp_catalog->ahb_base + offset);
+}
+
+static inline void msm_dp_write_ahb(struct msm_dp_catalog *msm_dp_catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure phy reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, msm_dp_catalog->ahb_base + offset);
+}
+
+static inline void msm_dp_write_p0(struct msm_dp_catalog *msm_dp_catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, msm_dp_catalog->p0_base + offset);
+}
+
+static inline u32 msm_dp_read_p0(struct msm_dp_catalog *msm_dp_catalog,
+			       u32 offset)
+{
+	return readl_relaxed(msm_dp_catalog->p0_base + offset);
+}
+
+static inline u32 msm_dp_read_link(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
+{
+	return readl_relaxed(msm_dp_catalog->link_base + offset);
+}
+
+static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure link reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, msm_dp_catalog->link_base + offset);
+}
+
 /* Debug module */
 void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state);
 

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 06/14] drm/msm/dp: move/inline AUX register functions
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (4 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 05/14] drm/msm/dp: move I/O functions to global header Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12 20:26   ` Stephen Boyd
  2024-12-11 23:41 ` [PATCH v3 07/14] drm/msm/dp: move/inline ctrl " Dmitry Baryshkov
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Move all register-level functions to dp_aux.c, inlining one line
wrappers during this process.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_aux.c     | 96 +++++++++++++++++++++++++++++++------
 drivers/gpu/drm/msm/dp/dp_catalog.c | 96 -------------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  9 ----
 3 files changed, 82 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index bc8d46abfc619d669dce339477d58fb0c464a3ea..cdcab948ae7086964d9e913dadadacc333f46231 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/iopoll.h>
 #include <linux/phy/phy.h>
 #include <drm/drm_print.h>
 
@@ -45,6 +46,71 @@ struct msm_dp_aux_private {
 	struct drm_dp_aux msm_dp_aux;
 };
 
+static void msm_dp_aux_clear_hw_interrupts(struct msm_dp_aux_private *aux)
+{
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+
+	msm_dp_read_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
+}
+
+/*
+ * NOTE: resetting AUX controller will also clear any pending HPD related interrupts
+ */
+static void msm_dp_aux_reset(struct msm_dp_aux_private *aux)
+{
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 aux_ctrl;
+
+	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
+
+	aux_ctrl |= DP_AUX_CTRL_RESET;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+
+	aux_ctrl &= ~DP_AUX_CTRL_RESET;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
+}
+
+static void msm_dp_aux_enable(struct msm_dp_aux_private *aux)
+{
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 aux_ctrl;
+
+	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
+
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_LIMITS, 0xffff);
+
+	aux_ctrl |= DP_AUX_CTRL_ENABLE;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
+}
+
+static void msm_dp_aux_disable(struct msm_dp_aux_private *aux)
+{
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 aux_ctrl;
+
+	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
+	aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
+}
+
+static int msm_dp_aux_wait_for_hpd_connect_state(struct msm_dp_aux_private *aux,
+					     unsigned long wait_us)
+{
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 state;
+
+	/* poll for hpd connected status every 2ms and timeout after wait_us */
+	return readl_poll_timeout(msm_dp_catalog->aux_base +
+				  REG_DP_DP_HPD_INT_STATUS,
+				  state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
+				  min(wait_us, 2000), wait_us);
+}
+
 #define MAX_AUX_RETRIES			5
 
 static ssize_t msm_dp_aux_write(struct msm_dp_aux_private *aux,
@@ -88,11 +154,11 @@ static ssize_t msm_dp_aux_write(struct msm_dp_aux_private *aux,
 		/* index = 0, write */
 		if (i == 0)
 			reg |= DP_AUX_DATA_INDEX_WRITE;
-		msm_dp_catalog_aux_write_data(aux->catalog, reg);
+		msm_dp_write_aux(aux->catalog, REG_DP_AUX_DATA, reg);
 	}
 
-	msm_dp_catalog_aux_clear_trans(aux->catalog, false);
-	msm_dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+	msm_dp_write_aux(aux->catalog, REG_DP_AUX_TRANS_CTRL, 0);
+	msm_dp_aux_clear_hw_interrupts(aux);
 
 	reg = 0; /* Transaction number == 1 */
 	if (!aux->native) { /* i2c */
@@ -106,7 +172,7 @@ static ssize_t msm_dp_aux_write(struct msm_dp_aux_private *aux,
 	}
 
 	reg |= DP_AUX_TRANS_CTRL_GO;
-	msm_dp_catalog_aux_write_trans(aux->catalog, reg);
+	msm_dp_write_aux(aux->catalog, REG_DP_AUX_TRANS_CTRL, reg);
 
 	return len;
 }
@@ -139,20 +205,22 @@ static ssize_t msm_dp_aux_cmd_fifo_rx(struct msm_dp_aux_private *aux,
 	u32 i, actual_i;
 	u32 len = msg->size;
 
-	msm_dp_catalog_aux_clear_trans(aux->catalog, true);
+	data = msm_dp_read_aux(aux->catalog, REG_DP_AUX_TRANS_CTRL);
+	data &= ~DP_AUX_TRANS_CTRL_GO;
+	msm_dp_write_aux(aux->catalog, REG_DP_AUX_TRANS_CTRL, data);
 
 	data = DP_AUX_DATA_INDEX_WRITE; /* INDEX_WRITE */
 	data |= DP_AUX_DATA_READ;  /* read */
 
-	msm_dp_catalog_aux_write_data(aux->catalog, data);
+	msm_dp_write_aux(aux->catalog, REG_DP_AUX_DATA, data);
 
 	dp = msg->buffer;
 
 	/* discard first byte */
-	data = msm_dp_catalog_aux_read_data(aux->catalog);
+	data = msm_dp_read_aux(aux->catalog, REG_DP_AUX_DATA);
 
 	for (i = 0; i < len; i++) {
-		data = msm_dp_catalog_aux_read_data(aux->catalog);
+		data = msm_dp_read_aux(aux->catalog, REG_DP_AUX_DATA);
 		*dp++ = (u8)((data >> DP_AUX_DATA_OFFSET) & 0xff);
 
 		actual_i = (data >> DP_AUX_DATA_INDEX_OFFSET) & 0xFF;
@@ -336,7 +404,7 @@ static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux,
 		}
 		/* reset aux if link is in connected state */
 		if (msm_dp_catalog_link_is_connected(aux->catalog))
-			msm_dp_catalog_aux_reset(aux->catalog);
+			msm_dp_aux_reset(aux);
 	} else {
 		aux->retry_cnt = 0;
 		switch (aux->aux_error_num) {
@@ -403,7 +471,7 @@ irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
 
 	if (isr & DP_INTR_AUX_ERROR) {
 		aux->aux_error_num = DP_AUX_ERR_PHY;
-		msm_dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+		msm_dp_aux_clear_hw_interrupts(aux);
 	} else if (isr & DP_INTR_NACK_DEFER) {
 		aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
 	} else if (isr & DP_INTR_WRONG_ADDR) {
@@ -444,7 +512,7 @@ void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux)
 	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
 	phy_calibrate(aux->phy);
-	msm_dp_catalog_aux_reset(aux->catalog);
+	msm_dp_aux_reset(aux);
 }
 
 void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux)
@@ -460,7 +528,7 @@ void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux)
 
 	mutex_lock(&aux->mutex);
 
-	msm_dp_catalog_aux_enable(aux->catalog, true);
+	msm_dp_aux_enable(aux);
 	aux->retry_cnt = 0;
 	aux->initted = true;
 
@@ -476,7 +544,7 @@ void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux)
 	mutex_lock(&aux->mutex);
 
 	aux->initted = false;
-	msm_dp_catalog_aux_enable(aux->catalog, false);
+	msm_dp_aux_disable(aux);
 
 	mutex_unlock(&aux->mutex);
 }
@@ -517,7 +585,7 @@ static int msm_dp_wait_hpd_asserted(struct drm_dp_aux *msm_dp_aux,
 	if (ret)
 		return ret;
 
-	ret = msm_dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog, wait_us);
+	ret = msm_dp_aux_wait_for_hpd_connect_state(aux, wait_us);
 	pm_runtime_put_sync(aux->dev);
 
 	return ret;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index a4ac132d807ea469709de68bc0b65ef41dcdae86..d4ceef78d8c8036dd2d9275a1bb60f47d90c02bb 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -82,102 +82,6 @@ void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_d
 				    msm_dp_catalog->p0_len, msm_dp_catalog->p0_base, "dp_p0");
 }
 
-/* aux related catalog functions */
-u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog)
-{
-	return msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_DATA);
-}
-
-int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data)
-{
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_DATA, data);
-	return 0;
-}
-
-int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data)
-{
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, data);
-	return 0;
-}
-
-int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read)
-{
-	u32 data;
-
-	if (read) {
-		data = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL);
-		data &= ~DP_AUX_TRANS_CTRL_GO;
-		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, data);
-	} else {
-		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, 0);
-	}
-	return 0;
-}
-
-int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog)
-{
-	msm_dp_read_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
-	return 0;
-}
-
-/**
- * msm_dp_catalog_aux_reset() - reset AUX controller
- *
- * @msm_dp_catalog: DP catalog structure
- *
- * return: void
- *
- * This function reset AUX controller
- *
- * NOTE: reset AUX controller will also clear any pending HPD related interrupts
- * 
- */
-void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 aux_ctrl;
-
-	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
-
-	aux_ctrl |= DP_AUX_CTRL_RESET;
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
-	usleep_range(1000, 1100); /* h/w recommended delay */
-
-	aux_ctrl &= ~DP_AUX_CTRL_RESET;
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
-}
-
-void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
-{
-	u32 aux_ctrl;
-
-	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
-
-	if (enable) {
-		msm_dp_write_aux(msm_dp_catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
-		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_LIMITS, 0xffff);
-		aux_ctrl |= DP_AUX_CTRL_ENABLE;
-	} else {
-		aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
-	}
-
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
-}
-
-int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
-					      unsigned long wait_us)
-{
-	u32 state;
-
-	/* poll for hpd connected status every 2ms and timeout after wait_us */
-	return readl_poll_timeout(msm_dp_catalog->aux_base +
-				REG_DP_DP_HPD_INT_STATUS,
-				state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
-				min(wait_us, 2000), wait_us);
-}
-
 u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 intr, intr_ack;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 0505b4be61f4e316f03df1d52ea35eb17e66580f..03e545124bd06d927da35801c1463c0082c3a0b6 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -129,15 +129,6 @@ static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
 void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state);
 
 /* AUX APIs */
-u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog);
-int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data);
-int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data);
-int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read);
-int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable);
-int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
-					      unsigned long wait_us);
 u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
 
 /* DP Controller APIs */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 07/14] drm/msm/dp: move/inline ctrl register functions
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (5 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 06/14] drm/msm/dp: move/inline AUX register functions Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 08/14] drm/msm/dp: move/inline panel related functions Dmitry Baryshkov
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Move CTRL-related functions to dp_ctrl.c, inlining one line wrappers
during this process. The enable/disable functions have been split to the
enable/disable or enter/exit pairs. The IRQ and HPD related functions
are left in dp_catalog.c, pending later cleanup.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 389 +------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  22 +-
 drivers/gpu/drm/msm/dp/dp_ctrl.c    | 447 ++++++++++++++++++++++++++++++++----
 3 files changed, 409 insertions(+), 449 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index d4ceef78d8c8036dd2d9275a1bb60f47d90c02bb..7aa34efdecc48189368b1bb2e37cb9ae98a80dde 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -18,8 +18,6 @@
 #define POLLING_SLEEP_US			1000
 #define POLLING_TIMEOUT_US			10000
 
-#define SCRAMBLER_RESET_COUNT_VALUE		0xFC
-
 #define DP_INTERRUPT_STATUS_ACK_SHIFT	1
 #define DP_INTERRUPT_STATUS_MASK_SHIFT	2
 
@@ -97,217 +95,6 @@ u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
 
 }
 
-/* controller related catalog functions */
-void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_catalog,
-				u32 msm_dp_tu, u32 valid_boundary,
-				u32 valid_boundary2)
-{
-	msm_dp_write_link(msm_dp_catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_TU, msm_dp_tu);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
-}
-
-void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
-{
-	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, state);
-}
-
-void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 cfg)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	drm_dbg_dp(catalog->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", cfg);
-
-	msm_dp_write_link(msm_dp_catalog, REG_DP_CONFIGURATION_CTRL, cfg);
-}
-
-void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
-	u32 ln_mapping;
-
-	ln_mapping = ln_0 << LANE0_MAPPING_SHIFT;
-	ln_mapping |= ln_1 << LANE1_MAPPING_SHIFT;
-	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
-	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
-
-	msm_dp_write_link(msm_dp_catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
-			ln_mapping);
-}
-
-void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catalog,
-						bool enable)
-{
-	u32 val;
-
-	val = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
-
-	if (enable)
-		val |= DP_MAINLINK_CTRL_ENABLE;
-	else
-		val &= ~DP_MAINLINK_CTRL_ENABLE;
-
-	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, val);
-}
-
-void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
-						bool enable)
-{
-	u32 mainlink_ctrl;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	drm_dbg_dp(catalog->drm_dev, "enable=%d\n", enable);
-	if (enable) {
-		/*
-		 * To make sure link reg writes happens before other operation,
-		 * msm_dp_write_link() function uses writel()
-		 */
-		mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
-
-		mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
-						DP_MAINLINK_CTRL_ENABLE);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
-
-		mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
-
-		mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
-
-		mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
-					DP_MAINLINK_FB_BOUNDARY_SEL);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
-	} else {
-		mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
-		mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
-	}
-}
-
-void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
-					u32 colorimetry_cfg,
-					u32 test_bits_depth)
-{
-	u32 misc_val;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	misc_val = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
-
-	/* clear bpp bits */
-	misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
-	misc_val |= colorimetry_cfg << DP_MISC0_COLORIMETRY_CFG_SHIFT;
-	misc_val |= test_bits_depth << DP_MISC0_TEST_BITS_DEPTH_SHIFT;
-	/* Configure clock to synchronous mode */
-	misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
-
-	drm_dbg_dp(catalog->drm_dev, "misc settings = 0x%x\n", misc_val);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc_val);
-}
-
-void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 mainlink_ctrl, hw_revision;
-
-	mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
-
-	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
-	if (hw_revision >= DP_HW_VERSION_1_2)
-		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE;
-	else
-		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
-
-	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
-}
-
-void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
-					u32 rate, u32 stream_rate_khz,
-					bool is_ycbcr_420)
-{
-	u32 pixel_m, pixel_n;
-	u32 mvid, nvid, pixel_div = 0, dispcc_input_rate;
-	u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE;
-	u32 const link_rate_hbr2 = 540000;
-	u32 const link_rate_hbr3 = 810000;
-	unsigned long den, num;
-
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	if (rate == link_rate_hbr3)
-		pixel_div = 6;
-	else if (rate == 162000 || rate == 270000)
-		pixel_div = 2;
-	else if (rate == link_rate_hbr2)
-		pixel_div = 4;
-	else
-		DRM_ERROR("Invalid pixel mux divider\n");
-
-	dispcc_input_rate = (rate * 10) / pixel_div;
-
-	rational_best_approximation(dispcc_input_rate, stream_rate_khz,
-			(unsigned long)(1 << 16) - 1,
-			(unsigned long)(1 << 16) - 1, &den, &num);
-
-	den = ~(den - num);
-	den = den & 0xFFFF;
-	pixel_m = num;
-	pixel_n = den;
-
-	mvid = (pixel_m & 0xFFFF) * 5;
-	nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
-
-	if (nvid < nvid_fixed) {
-		u32 temp;
-
-		temp = (nvid_fixed / nvid) * nvid;
-		mvid = (nvid_fixed / nvid) * mvid;
-		nvid = temp;
-	}
-
-	if (is_ycbcr_420)
-		mvid /= 2;
-
-	if (link_rate_hbr2 == rate)
-		nvid *= 2;
-
-	if (link_rate_hbr3 == rate)
-		nvid *= 3;
-
-	drm_dbg_dp(catalog->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_SOFTWARE_MVID, mvid);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_SOFTWARE_NVID, nvid);
-	msm_dp_write_p0(msm_dp_catalog, MMSS_DP_DSC_DTO, 0x0);
-}
-
-int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog,
-					u32 state_bit)
-{
-	int bit, ret;
-	u32 data;
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	bit = BIT(state_bit - 1);
-	drm_dbg_dp(catalog->drm_dev, "hw: bit=%d train=%d\n", bit, state_bit);
-	msm_dp_catalog_ctrl_state_ctrl(msm_dp_catalog, bit);
-
-	bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
-
-	/* Poll for mainlink ready status */
-	ret = readx_poll_timeout(readl, msm_dp_catalog->link_base +
-					REG_DP_MAINLINK_READY,
-					data, data & bit,
-					POLLING_SLEEP_US, POLLING_TIMEOUT_US);
-	if (ret < 0) {
-		DRM_ERROR("set state_bit for link_train=%d failed\n", state_bit);
-		return ret;
-	}
-	return 0;
-}
-
 /**
  * msm_dp_catalog_hw_revision() - retrieve DP hw revision
  *
@@ -321,50 +108,6 @@ u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
 	return msm_dp_read_ahb(msm_dp_catalog, REG_DP_HW_VERSION);
 }
 
-/**
- * msm_dp_catalog_ctrl_reset() - reset DP controller
- *
- * @msm_dp_catalog: DP catalog structure
- *
- * return: void
- *
- * This function reset the DP controller
- *
- * NOTE: reset DP controller will also clear any pending HPD related interrupts
- * 
- */
-void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 sw_reset;
-
-	sw_reset = msm_dp_read_ahb(msm_dp_catalog, REG_DP_SW_RESET);
-
-	sw_reset |= DP_SW_RESET;
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
-	usleep_range(1000, 1100); /* h/w recommended delay */
-
-	sw_reset &= ~DP_SW_RESET;
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
-}
-
-bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 data;
-	int ret;
-
-	/* Poll for mainlink ready status */
-	ret = readl_poll_timeout(msm_dp_catalog->link_base +
-				REG_DP_MAINLINK_READY,
-				data, data & DP_MAINLINK_READY_FOR_VIDEO,
-				POLLING_SLEEP_US, POLLING_TIMEOUT_US);
-	if (ret < 0) {
-		DRM_ERROR("mainlink not ready\n");
-		return false;
-	}
-
-	return true;
-}
-
 void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
 						bool enable)
 {
@@ -417,43 +160,6 @@ void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog)
 	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, 0);
 }
 
-static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog *msm_dp_catalog)
-{
-	/* trigger sdp */
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x0);
-}
-
-void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 config;
-
-	/* enable PSR1 function */
-	config = msm_dp_read_link(msm_dp_catalog, REG_PSR_CONFIG);
-	config |= PSR1_SUPPORTED;
-	msm_dp_write_link(msm_dp_catalog, REG_PSR_CONFIG, config);
-
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
-	msm_dp_catalog_enable_sdp(msm_dp_catalog);
-}
-
-void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter)
-{
-	u32 cmd;
-
-	cmd = msm_dp_read_link(msm_dp_catalog, REG_PSR_CMD);
-
-	cmd &= ~(PSR_ENTER | PSR_EXIT);
-
-	if (enter)
-		cmd |= PSR_ENTER;
-	else
-		cmd |= PSR_EXIT;
-
-	msm_dp_catalog_enable_sdp(msm_dp_catalog);
-	msm_dp_write_link(msm_dp_catalog, REG_PSR_CMD, cmd);
-}
-
 u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
 {
 	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
@@ -499,6 +205,11 @@ u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_
 	return intr;
 }
 
+void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog)
+{
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
+}
+
 int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 intr, intr_ack;
@@ -513,96 +224,6 @@ int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
 	return intr;
 }
 
-void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog)
-{
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_PHY_CTRL,
-			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
-	usleep_range(1000, 1100); /* h/w recommended delay */
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_PHY_CTRL, 0x0);
-}
-
-void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
-			u32 pattern)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-	u32 value = 0x0;
-
-	/* Make sure to clear the current pattern before starting a new one */
-	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, 0x0);
-
-	drm_dbg_dp(catalog->drm_dev, "pattern: %#x\n", pattern);
-	switch (pattern) {
-	case DP_PHY_TEST_PATTERN_D10_2:
-		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
-				DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
-		break;
-	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
-		value &= ~(1 << 16);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
-					value);
-		value |= SCRAMBLER_RESET_COUNT_VALUE;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
-					value);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
-					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
-					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
-		break;
-	case DP_PHY_TEST_PATTERN_PRBS7:
-		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
-				DP_STATE_CTRL_LINK_PRBS7);
-		break;
-	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
-		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
-				DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
-		/* 00111110000011111000001111100000 */
-		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
-				0x3E0F83E0);
-		/* 00001111100000111110000011111000 */
-		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
-				0x0F83E0F8);
-		/* 1111100000111110 */
-		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
-				0x0000F83E);
-		break;
-	case DP_PHY_TEST_PATTERN_CP2520:
-		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
-		value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
-
-		value = DP_HBR2_ERM_PATTERN;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
-				value);
-		value |= SCRAMBLER_RESET_COUNT_VALUE;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
-					value);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
-					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
-					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
-		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
-		value |= DP_MAINLINK_CTRL_ENABLE;
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
-		break;
-	case DP_PHY_TEST_PATTERN_SEL_MASK:
-		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL,
-				DP_MAINLINK_CTRL_ENABLE);
-		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
-				DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
-		break;
-	default:
-		drm_dbg_dp(catalog->drm_dev,
-				"No valid test pattern requested: %#x\n", pattern);
-		break;
-	}
-}
-
-u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog)
-{
-	return msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_READY);
-}
-
 /* panel related catalog functions */
 int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
 				u32 sync_start, u32 width_blanking, u32 msm_dp_active)
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 03e545124bd06d927da35801c1463c0082c3a0b6..7bf51f804595b165d5e039b332a9358b0c0ca2dc 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -132,37 +132,17 @@ void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_d
 u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
 
 /* DP Controller APIs */
-void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state);
-void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 config);
-void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog, bool enable);
-void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable);
-void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog, u32 cc, u32 tb);
-void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog, u32 rate,
-				u32 stream_rate_khz, bool is_ycbcr_420);
-int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog, u32 pattern);
 u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog);
-bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog);
 void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog, bool enable);
 void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
 			u32 intr_mask, bool en);
 void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog);
 void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter);
 u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog);
 u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog);
 int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog);
 u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_catalog,
-				u32 msm_dp_tu, u32 valid_boundary,
-				u32 valid_boundary2);
-void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
-				u32 pattern);
-u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog);
 
 /* DP Panel APIs */
 int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index bc2ca8133b790fc049e18ab3b37a629558664dd4..6ca2e055717b55c9eb064887948cf095fbfc1c40 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -8,9 +8,11 @@
 #include <linux/types.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/iopoll.h>
 #include <linux/phy/phy.h>
 #include <linux/phy/phy-dp.h>
 #include <linux/pm_opp.h>
+#include <linux/rational.h>
 
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_fixed.h>
@@ -20,6 +22,9 @@
 #include "dp_ctrl.h"
 #include "dp_link.h"
 
+#define POLLING_SLEEP_US			1000
+#define POLLING_TIMEOUT_US			10000
+
 #define DP_KHZ_TO_HZ 1000
 #define IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES	(30 * HZ / 1000) /* 30 ms */
 #define PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES       (300 * HZ / 1000) /* 300 ms */
@@ -118,6 +123,114 @@ static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
 	return 0;
 }
 
+/*
+ * NOTE: resetting DP controller will also clear any pending HPD related interrupts
+ */
+static void msm_dp_ctrl_reset(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 sw_reset;
+
+	sw_reset = msm_dp_read_ahb(msm_dp_catalog, REG_DP_SW_RESET);
+
+	sw_reset |= DP_SW_RESET;
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+
+	sw_reset &= ~DP_SW_RESET;
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
+}
+
+static void msm_dp_ctrl_psr_mainlink_enable(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 val;
+
+	val = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+	val |= DP_MAINLINK_CTRL_ENABLE;
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, val);
+}
+
+static void msm_dp_ctrl_psr_mainlink_disable(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 val;
+
+	val = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+	val &= ~DP_MAINLINK_CTRL_ENABLE;
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, val);
+}
+
+static void msm_dp_ctrl_mainlink_enable(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 mainlink_ctrl;
+
+	drm_dbg_dp(ctrl->drm_dev, "enable\n");
+
+	mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+
+	mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
+					DP_MAINLINK_CTRL_ENABLE);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+
+	mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+
+	mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+
+	mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
+				DP_MAINLINK_FB_BOUNDARY_SEL);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+static void msm_dp_ctrl_mainlink_disable(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 mainlink_ctrl;
+
+	drm_dbg_dp(ctrl->drm_dev, "disable\n");
+
+	mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+	mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+static void msm_dp_setup_peripheral_flush(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 mainlink_ctrl, hw_revision;
+
+	mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+
+	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
+	if (hw_revision >= DP_HW_VERSION_1_2)
+		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE;
+	else
+		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
+
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+static bool msm_dp_ctrl_mainlink_ready(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 data;
+	int ret;
+
+	/* Poll for mainlink ready status */
+	ret = readl_poll_timeout(msm_dp_catalog->link_base + REG_DP_MAINLINK_READY,
+				data, data & DP_MAINLINK_READY_FOR_VIDEO,
+				POLLING_SLEEP_US, POLLING_TIMEOUT_US);
+	if (ret < 0) {
+		DRM_ERROR("mainlink not ready\n");
+		return false;
+	}
+
+	return true;
+}
+
 void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl)
 {
 	struct msm_dp_ctrl_private *ctrl;
@@ -125,7 +238,7 @@ void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	reinit_completion(&ctrl->idle_comp);
-	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_PUSH_IDLE);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, DP_STATE_CTRL_PUSH_IDLE);
 
 	if (!wait_for_completion_timeout(&ctrl->idle_comp,
 			IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
@@ -170,23 +283,51 @@ static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)
 	if (ctrl->panel->psr_cap.version)
 		config |= DP_CONFIGURATION_CTRL_SEND_VSC;
 
-	msm_dp_catalog_ctrl_config_ctrl(ctrl->catalog, config);
+	drm_dbg_dp(ctrl->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", config);
+
+	msm_dp_write_link(ctrl->catalog, REG_DP_CONFIGURATION_CTRL, config);
+}
+
+static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
+	u32 ln_mapping;
+
+	ln_mapping = ln_0 << LANE0_MAPPING_SHIFT;
+	ln_mapping |= ln_1 << LANE1_MAPPING_SHIFT;
+	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
+	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
+
+	msm_dp_write_link(msm_dp_catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
+			ln_mapping);
 }
 
 static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl)
 {
-	u32 cc, tb;
+	u32 colorimetry_cfg, test_bits_depth, misc_val;
 
-	msm_dp_catalog_ctrl_lane_mapping(ctrl->catalog);
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
-	msm_dp_catalog_setup_peripheral_flush(ctrl->catalog);
+	msm_dp_ctrl_lane_mapping(ctrl);
+	msm_dp_ctrl_mainlink_enable(ctrl);
+	msm_dp_setup_peripheral_flush(ctrl);
 
 	msm_dp_ctrl_config_ctrl(ctrl);
 
-	tb = msm_dp_link_get_test_bits_depth(ctrl->link,
-		ctrl->panel->msm_dp_mode.bpp);
-	cc = msm_dp_link_get_colorimetry_config(ctrl->link);
-	msm_dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb);
+	test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link, ctrl->panel->msm_dp_mode.bpp);
+	colorimetry_cfg = msm_dp_link_get_colorimetry_config(ctrl->link);
+
+	misc_val = msm_dp_read_link(ctrl->catalog, REG_DP_MISC1_MISC0);
+
+	/* clear bpp bits */
+	misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
+	misc_val |= colorimetry_cfg << DP_MISC0_COLORIMETRY_CFG_SHIFT;
+	misc_val |= test_bits_depth << DP_MISC0_TEST_BITS_DEPTH_SHIFT;
+	/* Configure clock to synchronous mode */
+	misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
+
+	drm_dbg_dp(ctrl->drm_dev, "misc settings = 0x%x\n", misc_val);
+	msm_dp_write_link(ctrl->catalog, REG_DP_MISC1_MISC0, misc_val);
+
 	msm_dp_panel_timing_cfg(ctrl->panel);
 }
 
@@ -1003,8 +1144,9 @@ static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl)
 	pr_debug("dp_tu=0x%x, valid_boundary=0x%x, valid_boundary2=0x%x\n",
 			msm_dp_tu, valid_boundary, valid_boundary2);
 
-	msm_dp_catalog_ctrl_update_transfer_unit(ctrl->catalog,
-				msm_dp_tu, valid_boundary, valid_boundary2);
+	msm_dp_write_link(ctrl->catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
+	msm_dp_write_link(ctrl->catalog, REG_DP_TU, msm_dp_tu);
+	msm_dp_write_link(ctrl->catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
 }
 
 static int msm_dp_ctrl_wait4video_ready(struct msm_dp_ctrl_private *ctrl)
@@ -1114,6 +1256,30 @@ static int msm_dp_ctrl_read_link_status(struct msm_dp_ctrl_private *ctrl,
 	return ret;
 }
 
+static int msm_dp_ctrl_set_pattern_state_bit(struct msm_dp_ctrl_private *ctrl,
+					 u32 state_bit)
+{
+	int bit, ret;
+	u32 data;
+
+	bit = BIT(state_bit - 1);
+	drm_dbg_dp(ctrl->drm_dev, "hw: bit=%d train=%d\n", bit, state_bit);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, bit);
+
+	bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
+
+	/* Poll for mainlink ready status */
+	ret = readx_poll_timeout(readl, ctrl->catalog->link_base + REG_DP_MAINLINK_READY,
+				 data, data & bit,
+				 POLLING_SLEEP_US, POLLING_TIMEOUT_US);
+	if (ret < 0) {
+		DRM_ERROR("set state_bit for link_train=%d failed\n", state_bit);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
 			int *training_step)
 {
@@ -1121,11 +1287,11 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	int const maximum_retries = 4;
 
-	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, 0);
 
 	*training_step = DP_TRAINING_1;
 
-	ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, 1);
+	ret = msm_dp_ctrl_set_pattern_state_bit(ctrl, 1);
 	if (ret)
 		return ret;
 	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
@@ -1228,7 +1394,7 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
 	int const maximum_retries = 5;
 	u8 link_status[DP_LINK_STATUS_SIZE];
 
-	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, 0);
 
 	*training_step = DP_TRAINING_2;
 
@@ -1243,7 +1409,7 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
 		state_ctrl_bit = 2;
 	}
 
-	ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit);
+	ret = msm_dp_ctrl_set_pattern_state_bit(ctrl, state_ctrl_bit);
 	if (ret)
 		return ret;
 
@@ -1321,7 +1487,7 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
 	drm_dbg_dp(ctrl->drm_dev, "link training #2 successful\n");
 
 end:
-	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, 0);
 
 	return ret;
 }
@@ -1331,7 +1497,7 @@ static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
 {
 	int ret = 0;
 
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
+	msm_dp_ctrl_mainlink_enable(ctrl);
 
 	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
 		return ret;
@@ -1470,7 +1636,7 @@ void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable)
 
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
-	msm_dp_catalog_ctrl_reset(ctrl->catalog);
+	msm_dp_ctrl_reset(ctrl);
 
 	/*
 	 * all dp controller programmable registers will not
@@ -1481,16 +1647,60 @@ void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable)
 	msm_dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
 }
 
+static void msm_dp_ctrl_enable_sdp(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+
+	/* trigger sdp */
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x0);
+}
+
+static void msm_dp_ctrl_psr_enter(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 cmd;
+
+	cmd = msm_dp_read_link(msm_dp_catalog, REG_PSR_CMD);
+
+	cmd &= ~(PSR_ENTER | PSR_EXIT);
+	cmd |= PSR_ENTER;
+
+	msm_dp_ctrl_enable_sdp(ctrl);
+	msm_dp_write_link(msm_dp_catalog, REG_PSR_CMD, cmd);
+}
+
+static void msm_dp_ctrl_psr_exit(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 cmd;
+
+	cmd = msm_dp_read_link(msm_dp_catalog, REG_PSR_CMD);
+
+	cmd &= ~(PSR_ENTER | PSR_EXIT);
+	cmd |= PSR_EXIT;
+
+	msm_dp_ctrl_enable_sdp(ctrl);
+	msm_dp_write_link(msm_dp_catalog, REG_PSR_CMD, cmd);
+}
+
 void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	u8 cfg;
 	struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
 			struct msm_dp_ctrl_private, msm_dp_ctrl);
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 cfg;
 
 	if (!ctrl->panel->psr_cap.version)
 		return;
 
-	msm_dp_catalog_ctrl_config_psr(ctrl->catalog);
+	/* enable PSR1 function */
+	cfg = msm_dp_read_link(msm_dp_catalog, REG_PSR_CONFIG);
+	cfg |= PSR1_SUPPORTED;
+	msm_dp_write_link(msm_dp_catalog, REG_PSR_CONFIG, cfg);
+
+	msm_dp_catalog_ctrl_config_psr_interrupt(msm_dp_catalog);
+	msm_dp_ctrl_enable_sdp(ctrl);
 
 	cfg = DP_PSR_ENABLE;
 	drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
@@ -1516,29 +1726,37 @@ void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enter)
 	 */
 	if (enter) {
 		reinit_completion(&ctrl->psr_op_comp);
-		msm_dp_catalog_ctrl_set_psr(ctrl->catalog, true);
+		msm_dp_ctrl_psr_enter(ctrl);
 
 		if (!wait_for_completion_timeout(&ctrl->psr_op_comp,
 			PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES)) {
 			DRM_ERROR("PSR_ENTRY timedout\n");
-			msm_dp_catalog_ctrl_set_psr(ctrl->catalog, false);
+			msm_dp_ctrl_psr_exit(ctrl);
 			return;
 		}
 
 		msm_dp_ctrl_push_idle(msm_dp_ctrl);
-		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+		msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, 0);
 
-		msm_dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, false);
+		msm_dp_ctrl_psr_mainlink_disable(ctrl);
 	} else {
-		msm_dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, true);
+		msm_dp_ctrl_psr_mainlink_enable(ctrl);
 
-		msm_dp_catalog_ctrl_set_psr(ctrl->catalog, false);
-		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+		msm_dp_ctrl_psr_exit(ctrl);
+		msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
 		msm_dp_ctrl_wait4video_ready(ctrl);
-		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+		msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, 0);
 	}
 }
 
+static void msm_dp_ctrl_phy_reset(struct msm_dp_ctrl_private *ctrl)
+{
+	msm_dp_write_ahb(ctrl->catalog, REG_DP_PHY_CTRL,
+			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+	msm_dp_write_ahb(ctrl->catalog, REG_DP_PHY_CTRL, 0x0);
+}
+
 void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl)
 {
 	struct msm_dp_ctrl_private *ctrl;
@@ -1547,7 +1765,7 @@ void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	phy = ctrl->phy;
 
-	msm_dp_catalog_ctrl_phy_reset(ctrl->catalog);
+	msm_dp_ctrl_phy_reset(ctrl);
 	phy_init(phy);
 
 	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
@@ -1562,7 +1780,7 @@ void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	phy = ctrl->phy;
 
-	msm_dp_catalog_ctrl_phy_reset(ctrl->catalog);
+	msm_dp_ctrl_phy_reset(ctrl);
 	phy_exit(phy);
 	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
 			phy, phy->init_count, phy->power_count);
@@ -1573,7 +1791,7 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
 	struct phy *phy = ctrl->phy;
 	int ret = 0;
 
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_ctrl_mainlink_disable(ctrl);
 	ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
 	phy_configure(phy, &ctrl->phy_opts);
 	/*
@@ -1604,9 +1822,9 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
 
 	phy = ctrl->phy;
 
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_ctrl_mainlink_disable(ctrl);
 
-	msm_dp_catalog_ctrl_reset(ctrl->catalog);
+	msm_dp_ctrl_reset(ctrl);
 
 	dev_pm_opp_set_rate(ctrl->dev, 0);
 	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
@@ -1638,13 +1856,97 @@ static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
 
 	msm_dp_ctrl_clear_training_pattern(ctrl);
 
-	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
 
 	ret = msm_dp_ctrl_wait4video_ready(ctrl);
 end:
 	return ret;
 }
 
+#define SCRAMBLER_RESET_COUNT_VALUE		0xFC
+
+static void msm_dp_ctrl_send_phy_pattern(struct msm_dp_ctrl_private *ctrl,
+				     u32 pattern)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 value = 0x0;
+
+	/* Make sure to clear the current pattern before starting a new one */
+	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, 0x0);
+
+	drm_dbg_dp(ctrl->drm_dev, "pattern: %#x\n", pattern);
+	switch (pattern) {
+	case DP_PHY_TEST_PATTERN_D10_2:
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
+			      DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
+		break;
+
+	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
+		value &= ~(1 << 16);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+			      value);
+		value |= SCRAMBLER_RESET_COUNT_VALUE;
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+			      value);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
+			      DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
+			      DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
+		break;
+
+	case DP_PHY_TEST_PATTERN_PRBS7:
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
+			      DP_STATE_CTRL_LINK_PRBS7);
+		break;
+
+	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
+			      DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
+		/* 00111110000011111000001111100000 */
+		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
+			      0x3E0F83E0);
+		/* 00001111100000111110000011111000 */
+		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
+			      0x0F83E0F8);
+		/* 1111100000111110 */
+		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
+			      0x0000F83E);
+		break;
+
+	case DP_PHY_TEST_PATTERN_CP2520:
+		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+		value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
+
+		value = DP_HBR2_ERM_PATTERN;
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+			      value);
+		value |= SCRAMBLER_RESET_COUNT_VALUE;
+		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+			      value);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
+			      DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
+			      DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
+		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
+		value |= DP_MAINLINK_CTRL_ENABLE;
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
+		break;
+
+	case DP_PHY_TEST_PATTERN_SEL_MASK:
+		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL,
+			      DP_MAINLINK_CTRL_ENABLE);
+		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
+			      DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
+		break;
+
+	default:
+		drm_dbg_dp(ctrl->drm_dev,
+			   "No valid test pattern requested: %#x\n", pattern);
+	break;
+	}
+}
+
 static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
 {
 	bool success = false;
@@ -1659,11 +1961,11 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
 		DRM_ERROR("Failed to set v/p levels\n");
 		return false;
 	}
-	msm_dp_catalog_ctrl_send_phy_pattern(ctrl->catalog, pattern_requested);
+	msm_dp_ctrl_send_phy_pattern(ctrl, pattern_requested);
 	msm_dp_ctrl_update_vx_px(ctrl);
 	msm_dp_link_send_test_response(ctrl->link);
 
-	pattern_sent = msm_dp_catalog_ctrl_read_phy_pattern(ctrl->catalog);
+	pattern_sent = msm_dp_read_link(ctrl->catalog, REG_DP_MAINLINK_READY);
 
 	switch (pattern_sent) {
 	case MR_LINK_TRAINING1:
@@ -1942,6 +2244,63 @@ static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl)
 	return msm_dp_ctrl_setup_main_link(ctrl, &training_step);
 }
 
+static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl,
+			       u32 rate, u32 stream_rate_khz,
+			       bool is_ycbcr_420)
+{
+	u32 pixel_m, pixel_n;
+	u32 mvid, nvid, pixel_div = 0, dispcc_input_rate;
+	u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE;
+	u32 const link_rate_hbr2 = 540000;
+	u32 const link_rate_hbr3 = 810000;
+	unsigned long den, num;
+
+	if (rate == link_rate_hbr3)
+		pixel_div = 6;
+	else if (rate == 162000 || rate == 270000)
+		pixel_div = 2;
+	else if (rate == link_rate_hbr2)
+		pixel_div = 4;
+	else
+		DRM_ERROR("Invalid pixel mux divider\n");
+
+	dispcc_input_rate = (rate * 10) / pixel_div;
+
+	rational_best_approximation(dispcc_input_rate, stream_rate_khz,
+			(unsigned long)(1 << 16) - 1,
+			(unsigned long)(1 << 16) - 1, &den, &num);
+
+	den = ~(den - num);
+	den = den & 0xFFFF;
+	pixel_m = num;
+	pixel_n = den;
+
+	mvid = (pixel_m & 0xFFFF) * 5;
+	nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+
+	if (nvid < nvid_fixed) {
+		u32 temp;
+
+		temp = (nvid_fixed / nvid) * nvid;
+		mvid = (nvid_fixed / nvid) * mvid;
+		nvid = temp;
+	}
+
+	if (is_ycbcr_420)
+		mvid /= 2;
+
+	if (link_rate_hbr2 == rate)
+		nvid *= 2;
+
+	if (link_rate_hbr3 == rate)
+		nvid *= 3;
+
+	drm_dbg_dp(ctrl->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
+	msm_dp_write_link(ctrl->catalog, REG_DP_SOFTWARE_MVID, mvid);
+	msm_dp_write_link(ctrl->catalog, REG_DP_SOFTWARE_NVID, nvid);
+	msm_dp_write_p0(ctrl->catalog, MMSS_DP_DSC_DTO, 0x0);
+}
+
 int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train)
 {
 	int ret = 0;
@@ -2007,20 +2366,20 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train
 
 	msm_dp_ctrl_configure_source_params(ctrl);
 
-	msm_dp_catalog_ctrl_config_msa(ctrl->catalog,
+	msm_dp_ctrl_config_msa(ctrl,
 		ctrl->link->link_params.rate,
 		pixel_rate_orig,
 		ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420);
 
 	msm_dp_ctrl_setup_tr_unit(ctrl);
 
-	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+	msm_dp_write_link(ctrl->catalog, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
 
 	ret = msm_dp_ctrl_wait4video_ready(ctrl);
 	if (ret)
 		return ret;
 
-	mainlink_ready = msm_dp_catalog_ctrl_mainlink_ready(ctrl->catalog);
+	mainlink_ready = msm_dp_ctrl_mainlink_ready(ctrl);
 	drm_dbg_dp(ctrl->drm_dev,
 		"mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
 
@@ -2041,7 +2400,7 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
 	/* set dongle to D3 (power off) mode */
 	msm_dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
 
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_ctrl_mainlink_disable(ctrl);
 
 	if (ctrl->stream_clks_on) {
 		clk_disable_unprepare(ctrl->pixel_clk);
@@ -2069,7 +2428,7 @@ void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	phy = ctrl->phy;
 
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_ctrl_mainlink_disable(ctrl);
 
 	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
 
@@ -2092,9 +2451,9 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
 
 	msm_dp_catalog_panel_disable_vsc_sdp(ctrl->catalog);
 
-	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_ctrl_mainlink_disable(ctrl);
 
-	msm_dp_catalog_ctrl_reset(ctrl->catalog);
+	msm_dp_ctrl_reset(ctrl);
 
 	if (ctrl->stream_clks_on) {
 		clk_disable_unprepare(ctrl->pixel_clk);

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 08/14] drm/msm/dp: move/inline panel related functions
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (6 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 07/14] drm/msm/dp: move/inline ctrl " Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets Dmitry Baryshkov
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Move panel-related functions to dp_panel.c, following up the cleanup
done by the rest of the submodules.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_catalog.c | 192 ---------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |   9 --
 drivers/gpu/drm/msm/dp/dp_ctrl.c    |   4 +-
 drivers/gpu/drm/msm/dp/dp_panel.c   | 206 ++++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/msm/dp/dp_panel.h   |   3 +
 5 files changed, 200 insertions(+), 214 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 7aa34efdecc48189368b1bb2e37cb9ae98a80dde..91c580b1ee312595f3cca886c61ec570069eff03 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -21,8 +21,6 @@
 #define DP_INTERRUPT_STATUS_ACK_SHIFT	1
 #define DP_INTERRUPT_STATUS_MASK_SHIFT	2
 
-#define DP_INTF_CONFIG_DATABUS_WIDEN     BIT(4)
-
 #define DP_INTERRUPT_STATUS1 \
 	(DP_INTR_AUX_XFER_DONE| \
 	DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
@@ -224,196 +222,6 @@ int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
 	return intr;
 }
 
-/* panel related catalog functions */
-int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
-				u32 sync_start, u32 width_blanking, u32 msm_dp_active)
-{
-	u32 reg;
-
-	msm_dp_write_link(msm_dp_catalog, REG_DP_TOTAL_HOR_VER, total);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
-
-	reg = msm_dp_read_p0(msm_dp_catalog, MMSS_DP_INTF_CONFIG);
-
-	if (msm_dp_catalog->wide_bus_en)
-		reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
-	else
-		reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN;
-
-
-	DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", msm_dp_catalog->wide_bus_en, reg);
-
-	msm_dp_write_p0(msm_dp_catalog, MMSS_DP_INTF_CONFIG, reg);
-	return 0;
-}
-
-static void msm_dp_catalog_panel_send_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
-{
-	u32 header[2];
-	u32 val;
-	int i;
-
-	msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
-
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_0, header[0]);
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_1, header[1]);
-
-	for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
-		val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
-		       (vsc_sdp->db[i + 3] << 24));
-		msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_2 + i, val);
-	}
-}
-
-static void msm_dp_catalog_panel_update_sdp(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 hw_revision;
-
-	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
-	if (hw_revision < DP_HW_VERSION_1_2 && hw_revision >= DP_HW_VERSION_1_0) {
-		msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x01);
-		msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x00);
-	}
-}
-
-void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 cfg, cfg2, misc;
-
-	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
-
-	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
-	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
-	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
-
-	cfg |= GEN0_SDP_EN;
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
-
-	cfg2 |= GENERIC0_SDPSIZE_VALID;
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
-
-	msm_dp_catalog_panel_send_vsc_sdp(msm_dp_catalog, vsc_sdp);
-
-	/* indicates presence of VSC (BIT(6) of MISC1) */
-	misc |= DP_MISC1_VSC_SDP;
-
-	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=1\n");
-
-	pr_debug("misc settings = 0x%x\n", misc);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
-
-	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
-}
-
-void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 cfg, cfg2, misc;
-
-	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
-
-	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
-	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
-	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
-
-	cfg &= ~GEN0_SDP_EN;
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
-
-	cfg2 &= ~GENERIC0_SDPSIZE_VALID;
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
-
-	/* switch back to MSA */
-	misc &= ~DP_MISC1_VSC_SDP;
-
-	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=0\n");
-
-	pr_debug("misc settings = 0x%x\n", misc);
-	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
-
-	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
-}
-
-void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
-				struct drm_display_mode *drm_mode)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-	u32 hsync_period, vsync_period;
-	u32 display_v_start, display_v_end;
-	u32 hsync_start_x, hsync_end_x;
-	u32 v_sync_width;
-	u32 hsync_ctl;
-	u32 display_hctl;
-
-	/* TPG config parameters*/
-	hsync_period = drm_mode->htotal;
-	vsync_period = drm_mode->vtotal;
-
-	display_v_start = ((drm_mode->vtotal - drm_mode->vsync_start) *
-					hsync_period);
-	display_v_end = ((vsync_period - (drm_mode->vsync_start -
-					drm_mode->vdisplay))
-					* hsync_period) - 1;
-
-	display_v_start += drm_mode->htotal - drm_mode->hsync_start;
-	display_v_end -= (drm_mode->hsync_start - drm_mode->hdisplay);
-
-	hsync_start_x = drm_mode->htotal - drm_mode->hsync_start;
-	hsync_end_x = hsync_period - (drm_mode->hsync_start -
-					drm_mode->hdisplay) - 1;
-
-	v_sync_width = drm_mode->vsync_end - drm_mode->vsync_start;
-
-	hsync_ctl = (hsync_period << 16) |
-			(drm_mode->hsync_end - drm_mode->hsync_start);
-	display_hctl = (hsync_end_x << 16) | hsync_start_x;
-
-
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0x0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period *
-			hsync_period);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width *
-			hsync_period);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_HCTL, 0);
-	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F0, display_v_start);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end);
-	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F1, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
-	msm_dp_write_p0(catalog, MMSS_DP_INTF_POLARITY_CTL, 0);
-
-	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL,
-				DP_TPG_CHECKERED_RECT_PATTERN);
-	msm_dp_write_p0(catalog, MMSS_DP_TPG_VIDEO_CONFIG,
-				DP_TPG_VIDEO_CONFIG_BPP_8BIT |
-				DP_TPG_VIDEO_CONFIG_RGB);
-	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE,
-				DP_BIST_ENABLE_DPBIST_EN);
-	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN,
-				DP_TIMING_ENGINE_EN_EN);
-	drm_dbg_dp(catalog->drm_dev, "%s: enabled tpg\n", __func__);
-}
-
-void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 0x0);
-	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 0x0);
-	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0);
-}
-
 static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
 {
 	struct resource *res;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 7bf51f804595b165d5e039b332a9358b0c0ca2dc..8dcc029d87315d5777c9c48c0df403be8dd447ce 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -144,15 +144,6 @@ int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
 void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog);
 u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
 
-/* DP Panel APIs */
-int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
-				u32 sync_start, u32 width_blanking, u32 msm_dp_active);
-void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp);
-void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
-				struct drm_display_mode *drm_mode);
-void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog);
-
 struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
 
 /* DP Audio APIs */
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 6ca2e055717b55c9eb064887948cf095fbfc1c40..cde667bf8eeec95035b2feb3661686c99acf5b7d 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -2395,7 +2395,7 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	phy = ctrl->phy;
 
-	msm_dp_catalog_panel_disable_vsc_sdp(ctrl->catalog);
+	msm_dp_panel_disable_vsc_sdp(ctrl->panel);
 
 	/* set dongle to D3 (power off) mode */
 	msm_dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
@@ -2449,7 +2449,7 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	phy = ctrl->phy;
 
-	msm_dp_catalog_panel_disable_vsc_sdp(ctrl->catalog);
+	msm_dp_panel_disable_vsc_sdp(ctrl->panel);
 
 	msm_dp_ctrl_mainlink_disable(ctrl);
 
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 7d122496723a32fd591d094269397a9fdd51fe44..cd91de21c8e658570b8d43251ef815981f801ae4 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -4,6 +4,7 @@
  */
 
 #include "dp_panel.h"
+#include "dp_reg.h"
 #include "dp_utils.h"
 
 #include <drm/drm_connector.h>
@@ -11,6 +12,8 @@
 #include <drm/drm_of.h>
 #include <drm/drm_print.h>
 
+#define DP_INTF_CONFIG_DATABUS_WIDEN     BIT(4)
+
 #define DP_MAX_NUM_DP_LANES	4
 #define DP_LINK_RATE_HBR2	540000 /* kbytes */
 
@@ -242,9 +245,92 @@ void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
 	}
 }
 
-void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
+static void msm_dp_panel_tpg_enable(struct msm_dp_panel *msm_dp_panel,
+				    struct drm_display_mode *drm_mode)
 {
+	struct msm_dp_panel_private *panel;
 	struct msm_dp_catalog *catalog;
+	u32 hsync_period, vsync_period;
+	u32 display_v_start, display_v_end;
+	u32 hsync_start_x, hsync_end_x;
+	u32 v_sync_width;
+	u32 hsync_ctl;
+	u32 display_hctl;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+
+	/* TPG config parameters*/
+	hsync_period = drm_mode->htotal;
+	vsync_period = drm_mode->vtotal;
+
+	display_v_start = ((drm_mode->vtotal - drm_mode->vsync_start) *
+					hsync_period);
+	display_v_end = ((vsync_period - (drm_mode->vsync_start -
+					drm_mode->vdisplay))
+					* hsync_period) - 1;
+
+	display_v_start += drm_mode->htotal - drm_mode->hsync_start;
+	display_v_end -= (drm_mode->hsync_start - drm_mode->hdisplay);
+
+	hsync_start_x = drm_mode->htotal - drm_mode->hsync_start;
+	hsync_end_x = hsync_period - (drm_mode->hsync_start -
+					drm_mode->hdisplay) - 1;
+
+	v_sync_width = drm_mode->vsync_end - drm_mode->vsync_start;
+
+	hsync_ctl = (hsync_period << 16) |
+			(drm_mode->hsync_end - drm_mode->hsync_start);
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period *
+			hsync_period);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width *
+			hsync_period);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_HCTL, 0);
+	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F0, display_v_start);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end);
+	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_POLARITY_CTL, 0);
+
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL,
+				DP_TPG_CHECKERED_RECT_PATTERN);
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_VIDEO_CONFIG,
+				DP_TPG_VIDEO_CONFIG_BPP_8BIT |
+				DP_TPG_VIDEO_CONFIG_RGB);
+	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE,
+				DP_BIST_ENABLE_DPBIST_EN);
+	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN,
+				DP_TIMING_ENGINE_EN_EN);
+	drm_dbg_dp(panel->drm_dev, "%s: enabled tpg\n", __func__);
+}
+
+static void msm_dp_panel_tpg_disable(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_catalog *catalog;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0);
+}
+
+void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
+{
 	struct msm_dp_panel_private *panel;
 
 	if (!msm_dp_panel) {
@@ -253,7 +339,6 @@ void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
 	}
 
 	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
-	catalog = panel->catalog;
 
 	if (!panel->panel_on) {
 		drm_dbg_dp(panel->drm_dev,
@@ -262,18 +347,105 @@ void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
 	}
 
 	if (!enable) {
-		msm_dp_catalog_panel_tpg_disable(catalog);
+		msm_dp_panel_tpg_disable(msm_dp_panel);
 		return;
 	}
 
-	drm_dbg_dp(panel->drm_dev, "calling catalog tpg_enable\n");
-	msm_dp_catalog_panel_tpg_enable(catalog, &panel->msm_dp_panel.msm_dp_mode.drm_mode);
+	drm_dbg_dp(panel->drm_dev, "calling panel's tpg_enable\n");
+	msm_dp_panel_tpg_enable(msm_dp_panel, &panel->msm_dp_panel.msm_dp_mode.drm_mode);
+}
+
+static void msm_dp_panel_send_vsc_sdp(struct msm_dp_panel_private *panel, struct dp_sdp *vsc_sdp)
+{
+	struct msm_dp_catalog *msm_dp_catalog = panel->catalog;
+	u32 header[2];
+	u32 val;
+	int i;
+
+	msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
+
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_0, header[0]);
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_1, header[1]);
+
+	for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
+		val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
+		       (vsc_sdp->db[i + 3] << 24));
+		msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_2 + i, val);
+	}
+}
+
+static void msm_dp_panel_update_sdp(struct msm_dp_panel_private *panel)
+{
+	u32 hw_revision;
+
+	hw_revision = msm_dp_catalog_hw_revision(panel->catalog);
+	if (hw_revision >= DP_HW_VERSION_1_0 &&
+	    hw_revision < DP_HW_VERSION_1_2) {
+		msm_dp_write_link(panel->catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
+		msm_dp_write_link(panel->catalog, MMSS_DP_SDP_CFG3, 0x0);
+	}
+}
+
+void msm_dp_panel_enable_vsc_sdp(struct msm_dp_panel *msm_dp_panel, struct dp_sdp *vsc_sdp)
+{
+	struct msm_dp_panel_private *panel =
+		container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	struct msm_dp_catalog *msm_dp_catalog = panel->catalog;
+	u32 cfg, cfg2, misc;
+
+	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
+	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
+	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
+
+	cfg |= GEN0_SDP_EN;
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
+
+	cfg2 |= GENERIC0_SDPSIZE_VALID;
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
+
+	msm_dp_panel_send_vsc_sdp(panel, vsc_sdp);
+
+	/* indicates presence of VSC (BIT(6) of MISC1) */
+	misc |= DP_MISC1_VSC_SDP;
+
+	drm_dbg_dp(panel->drm_dev, "vsc sdp enable=1\n");
+
+	pr_debug("misc settings = 0x%x\n", misc);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
+
+	msm_dp_panel_update_sdp(panel);
+}
+
+void msm_dp_panel_disable_vsc_sdp(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_panel_private *panel =
+		container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	struct msm_dp_catalog *msm_dp_catalog = panel->catalog;
+	u32 cfg, cfg2, misc;
+
+	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
+	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
+	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
+
+	cfg &= ~GEN0_SDP_EN;
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
+
+	cfg2 &= ~GENERIC0_SDPSIZE_VALID;
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
+
+	/* switch back to MSA */
+	misc &= ~DP_MISC1_VSC_SDP;
+
+	drm_dbg_dp(panel->drm_dev, "vsc sdp enable=0\n");
+
+	pr_debug("misc settings = 0x%x\n", misc);
+	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
+
+	msm_dp_panel_update_sdp(panel);
 }
 
 static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
 {
-	struct msm_dp_catalog *catalog;
-	struct msm_dp_panel_private *panel;
 	struct msm_dp_display_mode *msm_dp_mode;
 	struct drm_dp_vsc_sdp vsc_sdp_data;
 	struct dp_sdp vsc_sdp;
@@ -284,8 +456,6 @@ static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
 		return -EINVAL;
 	}
 
-	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
-	catalog = panel->catalog;
 	msm_dp_mode = &msm_dp_panel->msm_dp_mode;
 
 	memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data));
@@ -312,7 +482,7 @@ static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
 		return len;
 	}
 
-	msm_dp_catalog_panel_enable_vsc_sdp(catalog, &vsc_sdp);
+	msm_dp_panel_enable_vsc_sdp(msm_dp_panel, &vsc_sdp);
 
 	return 0;
 }
@@ -327,6 +497,7 @@ int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
 	u32 sync_start;
 	u32 msm_dp_active;
 	u32 total;
+	u32 reg;
 
 	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 	catalog = panel->catalog;
@@ -372,7 +543,20 @@ int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
 
 	msm_dp_active = data;
 
-	msm_dp_catalog_panel_timing_cfg(catalog, total, sync_start, width_blanking, msm_dp_active);
+	msm_dp_write_link(catalog, REG_DP_TOTAL_HOR_VER, total);
+	msm_dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
+	msm_dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
+	msm_dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
+
+	reg = msm_dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
+	if (catalog->wide_bus_en)
+		reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
+	else
+		reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN;
+
+	drm_dbg_dp(panel->drm_dev, "wide_bus_en=%d reg=%#x\n", catalog->wide_bus_en, reg);
+
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
 
 	if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
 		msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index 47c1d349be470b60596b64a7bc8c7c39d2e8fdd1..f305b1151118b53762368905b70d951a366ba1a8 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -64,6 +64,9 @@ int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
 void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel);
 void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);
 
+void msm_dp_panel_enable_vsc_sdp(struct msm_dp_panel *msm_dp_panel, struct dp_sdp *vsc_sdp);
+void msm_dp_panel_disable_vsc_sdp(struct msm_dp_panel *msm_dp_panel);
+
 /**
  * is_link_rate_valid() - validates the link rate
  * @lane_rate: link rate requested by the sink

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (7 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 08/14] drm/msm/dp: move/inline panel related functions Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12  3:12   ` Abhinav Kumar
  2024-12-12 21:41   ` Abhinav Kumar
  2024-12-11 23:41 ` [PATCH v3 10/14] drm/msm/dp: drop obsolete audio headers access through catalog Dmitry Baryshkov
                   ` (5 subsequent siblings)
  14 siblings, 2 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
to program audio packet data. Use 0 as Packet ID, as it was not
programmed earlier.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
 1 file changed, 66 insertions(+), 222 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 5cbb11986460d1e4ed1890bdf66d0913e013083c..1aa52d5cc08684a49102e45ed6e40ac2b13497c7 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -14,6 +14,7 @@
 #include "dp_catalog.h"
 #include "dp_audio.h"
 #include "dp_panel.h"
+#include "dp_reg.h"
 #include "dp_display.h"
 #include "dp_utils.h"
 
@@ -28,251 +29,94 @@ struct msm_dp_audio_private {
 	struct msm_dp_audio msm_dp_audio;
 };
 
-static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
-		enum msm_dp_catalog_audio_sdp_type sdp,
-		enum msm_dp_catalog_audio_header_type header)
-{
-	return msm_dp_catalog_audio_get_header(catalog, sdp, header);
-}
-
-static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
-		u32 data,
-		enum msm_dp_catalog_audio_sdp_type sdp,
-		enum msm_dp_catalog_audio_header_type header)
-{
-	msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
-}
-
 static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
 {
 	struct msm_dp_catalog *catalog = audio->catalog;
-	u32 value, new_value;
-	u8 parity_byte;
-
-	/* Config header and parity byte 1 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
-
-	new_value = 0x02;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_1_BIT)
-			| (parity_byte << PARITY_BYTE_1_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
-
-	/* Config header and parity byte 2 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
-	new_value = value;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_2_BIT)
-			| (parity_byte << PARITY_BYTE_2_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
-
-	/* Config header and parity byte 3 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
-
-	new_value = audio->channels - 1;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_3_BIT)
-			| (parity_byte << PARITY_BYTE_3_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
-		value, parity_byte);
-
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
+	struct dp_sdp_header sdp_hdr = {
+		.HB0 = 0x00,
+		.HB1 = 0x02,
+		.HB2 = 0x00,
+		.HB3 = audio->channels - 1,
+	};
+	u32 header[2];
+
+	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_0, header[0]);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_1, header[1]);
 }
 
 static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
 {
 	struct msm_dp_catalog *catalog = audio->catalog;
-	u32 value, new_value;
-	u8 parity_byte;
-
-	/* Config header and parity byte 1 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
-
-	new_value = 0x1;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_1_BIT)
-			| (parity_byte << PARITY_BYTE_1_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
-
-	/* Config header and parity byte 2 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
-
-	new_value = 0x17;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_2_BIT)
-			| (parity_byte << PARITY_BYTE_2_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
-
-	/* Config header and parity byte 3 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
-
-	new_value = (0x0 | (0x11 << 2));
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_3_BIT)
-			| (parity_byte << PARITY_BYTE_3_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
+	struct dp_sdp_header sdp_hdr = {
+		.HB0 = 0x00,
+		.HB1 = 0x01,
+		.HB2 = 0x17,
+		.HB3 = 0x0 | (0x11 << 2),
+	};
+	u32 header[2];
+
+	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_0, header[0]);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_1, header[1]);
 }
 
 static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
 {
 	struct msm_dp_catalog *catalog = audio->catalog;
-	u32 value, new_value;
-	u8 parity_byte;
-
-	/* Config header and parity byte 1 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
-
-	new_value = 0x84;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_1_BIT)
-			| (parity_byte << PARITY_BYTE_1_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
-
-	/* Config header and parity byte 2 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
-
-	new_value = 0x1b;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_2_BIT)
-			| (parity_byte << PARITY_BYTE_2_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
-
-	/* Config header and parity byte 3 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
-
-	new_value = (0x0 | (0x11 << 2));
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_3_BIT)
-			| (parity_byte << PARITY_BYTE_3_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
-			new_value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
+	struct dp_sdp_header sdp_hdr = {
+		.HB0 = 0x00,
+		.HB1 = 0x84,
+		.HB2 = 0x1b,
+		.HB3 = 0x0 | (0x11 << 2),
+	};
+	u32 header[2];
+
+	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_0, header[0]);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_1, header[1]);
 }
 
 static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
 {
 	struct msm_dp_catalog *catalog = audio->catalog;
-	u32 value, new_value;
-	u8 parity_byte;
-
-	/* Config header and parity byte 1 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
-
-	new_value = 0x05;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_1_BIT)
-			| (parity_byte << PARITY_BYTE_1_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
-
-	/* Config header and parity byte 2 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
-
-	new_value = 0x0F;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_2_BIT)
-			| (parity_byte << PARITY_BYTE_2_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
-
-	/* Config header and parity byte 3 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
-
-	new_value = 0x0;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_3_BIT)
-			| (parity_byte << PARITY_BYTE_3_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
+	struct dp_sdp_header sdp_hdr = {
+		.HB0 = 0x00,
+		.HB1 = 0x05,
+		.HB2 = 0x0f,
+		.HB3 = 0x00,
+	};
+	u32 header[2];
+
+	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_0, header[0]);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_1, header[1]);
 }
 
 static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
 {
 	struct msm_dp_catalog *catalog = audio->catalog;
-	u32 value, new_value;
-	u8 parity_byte;
-
-	/* Config header and parity byte 1 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
-
-	new_value = 0x06;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_1_BIT)
-			| (parity_byte << PARITY_BYTE_1_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
-
-	/* Config header and parity byte 2 */
-	value = msm_dp_audio_get_header(catalog,
-			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
-
-	new_value = 0x0F;
-	parity_byte = msm_dp_utils_calculate_parity(new_value);
-	value |= ((new_value << HEADER_BYTE_2_BIT)
-			| (parity_byte << PARITY_BYTE_2_BIT));
-	drm_dbg_dp(audio->drm_dev,
-			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
-			value, parity_byte);
-	msm_dp_audio_set_header(catalog, value,
-		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
+	struct dp_sdp_header sdp_hdr = {
+		.HB0 = 0x00,
+		.HB1 = 0x06,
+		.HB2 = 0x0f,
+		.HB3 = 0x00,
+	};
+	u32 header[2];
+	u32 reg;
+
+	/* XXX: is it necessary to preserve this field? */
+	reg = msm_dp_read_link(catalog, MMSS_DP_AUDIO_ISRC_1);
+	sdp_hdr.HB3 = FIELD_GET(HEADER_3_MASK, reg);
+
+	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_0, header[0]);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
 }
 
 static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 10/14] drm/msm/dp: drop obsolete audio headers access through catalog
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (8 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 11/14] drm/msm/dp: move/inline audio related functions Dmitry Baryshkov
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Drop obsolete functions to access audio packet headers. The dp_audio.c
now writes them using msm_dp_write_link() directly.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_audio.c   |  2 -
 drivers/gpu/drm/msm/dp/dp_catalog.c | 76 -------------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h | 24 ------------
 3 files changed, 102 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 1aa52d5cc08684a49102e45ed6e40ac2b13497c7..24b62faa875437e184895c6d03df19884ebb1fd6 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -405,8 +405,6 @@ struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
 
 	msm_dp_audio = &audio->msm_dp_audio;
 
-	msm_dp_catalog_audio_init(catalog);
-
 	return msm_dp_audio;
 error:
 	return ERR_PTR(rc);
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 91c580b1ee312595f3cca886c61ec570069eff03..c1c30da001ed881e1524370be9082d959bdd8bc7 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -62,7 +62,6 @@
 struct msm_dp_catalog_private {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
 	struct msm_dp_catalog msm_dp_catalog;
 };
 
@@ -304,40 +303,6 @@ struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev)
 	return &catalog->msm_dp_catalog;
 }
 
-u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
-				enum msm_dp_catalog_audio_sdp_type sdp,
-				enum msm_dp_catalog_audio_header_type header)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	sdp_map = catalog->audio_map;
-
-	return msm_dp_read_link(msm_dp_catalog, sdp_map[sdp][header]);
-}
-
-void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
-				 enum msm_dp_catalog_audio_sdp_type sdp,
-				 enum msm_dp_catalog_audio_header_type header,
-				 u32 data)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
-
-	if (!msm_dp_catalog)
-		return;
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	sdp_map = catalog->audio_map;
-
-	msm_dp_write_link(msm_dp_catalog, sdp_map[sdp][header], data);
-}
-
 void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32 select)
 {
 	struct msm_dp_catalog_private *catalog;
@@ -421,47 +386,6 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
 	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
 }
 
-void msm_dp_catalog_audio_init(struct msm_dp_catalog *msm_dp_catalog)
-{
-	struct msm_dp_catalog_private *catalog;
-
-	static u32 sdp_map[][DP_AUDIO_SDP_HEADER_MAX] = {
-		{
-			MMSS_DP_AUDIO_STREAM_0,
-			MMSS_DP_AUDIO_STREAM_1,
-			MMSS_DP_AUDIO_STREAM_1,
-		},
-		{
-			MMSS_DP_AUDIO_TIMESTAMP_0,
-			MMSS_DP_AUDIO_TIMESTAMP_1,
-			MMSS_DP_AUDIO_TIMESTAMP_1,
-		},
-		{
-			MMSS_DP_AUDIO_INFOFRAME_0,
-			MMSS_DP_AUDIO_INFOFRAME_1,
-			MMSS_DP_AUDIO_INFOFRAME_1,
-		},
-		{
-			MMSS_DP_AUDIO_COPYMANAGEMENT_0,
-			MMSS_DP_AUDIO_COPYMANAGEMENT_1,
-			MMSS_DP_AUDIO_COPYMANAGEMENT_1,
-		},
-		{
-			MMSS_DP_AUDIO_ISRC_0,
-			MMSS_DP_AUDIO_ISRC_1,
-			MMSS_DP_AUDIO_ISRC_1,
-		},
-	};
-
-	if (!msm_dp_catalog)
-		return;
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	catalog->audio_map = sdp_map;
-}
-
 void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 safe_to_exit_level)
 {
 	struct msm_dp_catalog_private *catalog;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 8dcc029d87315d5777c9c48c0df403be8dd447ce..5ac89a11a503e2abae9f4cc4740b18f2f3b6da5e 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -31,22 +31,6 @@
 #define DP_HW_VERSION_1_0	0x10000000
 #define DP_HW_VERSION_1_2	0x10020000
 
-enum msm_dp_catalog_audio_sdp_type {
-	DP_AUDIO_SDP_STREAM,
-	DP_AUDIO_SDP_TIMESTAMP,
-	DP_AUDIO_SDP_INFOFRAME,
-	DP_AUDIO_SDP_COPYMANAGEMENT,
-	DP_AUDIO_SDP_ISRC,
-	DP_AUDIO_SDP_MAX,
-};
-
-enum msm_dp_catalog_audio_header_type {
-	DP_AUDIO_SDP_HEADER_1,
-	DP_AUDIO_SDP_HEADER_2,
-	DP_AUDIO_SDP_HEADER_3,
-	DP_AUDIO_SDP_HEADER_MAX,
-};
-
 struct msm_dp_catalog {
 	bool wide_bus_en;
 
@@ -147,17 +131,9 @@ u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_
 struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
 
 /* DP Audio APIs */
-u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
-				enum msm_dp_catalog_audio_sdp_type sdp,
-				enum msm_dp_catalog_audio_header_type header);
-void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
-				 enum msm_dp_catalog_audio_sdp_type sdp,
-				 enum msm_dp_catalog_audio_header_type header,
-				 u32 data);
 void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *catalog, u32 select);
 void msm_dp_catalog_audio_enable(struct msm_dp_catalog *catalog, bool enable);
 void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *catalog);
-void msm_dp_catalog_audio_init(struct msm_dp_catalog *catalog);
 void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *catalog, u32 safe_to_exit_level);
 
 #endif /* _DP_CATALOG_H_ */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 11/14] drm/msm/dp: move/inline audio related functions
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (9 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 10/14] drm/msm/dp: drop obsolete audio headers access through catalog Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 12/14] drm/msm/dp: move more AUX functions to dp_aux.c Dmitry Baryshkov
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Move audio-related functions to dp_audio.c, following up the cleanup
done by the rest of the submodules. Inline functions with simple
register access patterns.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_audio.c   |  72 +++++++++++++++++++++----
 drivers/gpu/drm/msm/dp/dp_catalog.c | 105 ------------------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |   6 ---
 3 files changed, 63 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 24b62faa875437e184895c6d03df19884ebb1fd6..4eec0af178cbb190b4e9262dbe9a6e788a57c054 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -119,9 +119,41 @@ static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
 	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
 }
 
+static void msm_dp_audio_config_sdp(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *msm_dp_catalog = audio->catalog;
+	u32 sdp_cfg, sdp_cfg2;
+
+	sdp_cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
+	/* AUDIO_TIMESTAMP_SDP_EN */
+	sdp_cfg |= BIT(1);
+	/* AUDIO_STREAM_SDP_EN */
+	sdp_cfg |= BIT(2);
+	/* AUDIO_COPY_MANAGEMENT_SDP_EN */
+	sdp_cfg |= BIT(5);
+	/* AUDIO_ISRC_SDP_EN  */
+	sdp_cfg |= BIT(6);
+	/* AUDIO_INFOFRAME_SDP_EN  */
+	sdp_cfg |= BIT(20);
+
+	drm_dbg_dp(audio->drm_dev, "sdp_cfg = 0x%x\n", sdp_cfg);
+
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, sdp_cfg);
+
+	sdp_cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
+	/* IFRM_REGSRC -> Do not use reg values */
+	sdp_cfg2 &= ~BIT(0);
+	/* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */
+	sdp_cfg2 &= ~BIT(1);
+
+	drm_dbg_dp(audio->drm_dev, "sdp_cfg2 = 0x%x\n", sdp_cfg2);
+
+	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
+}
+
 static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
 {
-	msm_dp_catalog_audio_config_sdp(audio->catalog);
+	msm_dp_audio_config_sdp(audio);
 
 	msm_dp_audio_stream_sdp(audio);
 	msm_dp_audio_timestamp_sdp(audio);
@@ -132,8 +164,7 @@ static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
 
 static void msm_dp_audio_setup_acr(struct msm_dp_audio_private *audio)
 {
-	u32 select = 0;
-	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 select, acr_ctrl;
 
 	switch (audio->msm_dp_audio.bw_code) {
 	case DP_LINK_BW_1_62:
@@ -154,13 +185,17 @@ static void msm_dp_audio_setup_acr(struct msm_dp_audio_private *audio)
 		break;
 	}
 
-	msm_dp_catalog_audio_config_acr(catalog, select);
+	acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
+
+	drm_dbg_dp(audio->drm_dev, "select: %#x, acr_ctrl: %#x\n",
+		   select, acr_ctrl);
+
+	msm_dp_write_link(audio->catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
 }
 
 static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
 {
-	struct msm_dp_catalog *catalog = audio->catalog;
-	u32 safe_to_exit_level = 0;
+	u32 safe_to_exit_level, mainlink_levels;
 
 	switch (audio->msm_dp_audio.lane_count) {
 	case 1:
@@ -180,14 +215,33 @@ static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
 		break;
 	}
 
-	msm_dp_catalog_audio_sfe_level(catalog, safe_to_exit_level);
+	mainlink_levels = msm_dp_read_link(audio->catalog, REG_DP_MAINLINK_LEVELS);
+	mainlink_levels &= 0xFE0;
+	mainlink_levels |= safe_to_exit_level;
+
+	drm_dbg_dp(audio->drm_dev,
+		   "mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
+		   mainlink_levels, safe_to_exit_level);
+
+	msm_dp_write_link(audio->catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
 }
 
 static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)
 {
-	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 audio_ctrl;
+
+	audio_ctrl = msm_dp_read_link(audio->catalog, MMSS_DP_AUDIO_CFG);
+
+	if (enable)
+		audio_ctrl |= BIT(0);
+	else
+		audio_ctrl &= ~BIT(0);
+
+	drm_dbg_dp(audio->drm_dev, "dp_audio_cfg = 0x%x\n", audio_ctrl);
 
-	msm_dp_catalog_audio_enable(catalog, enable);
+	msm_dp_write_link(audio->catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
+	/* make sure audio engine is disabled */
+	wmb();
 }
 
 static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index c1c30da001ed881e1524370be9082d959bdd8bc7..2eea02fc4cca3f7183e97d0fc086b8d6fa27ad00 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -302,108 +302,3 @@ struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev)
 
 	return &catalog->msm_dp_catalog;
 }
-
-void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32 select)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 acr_ctrl;
-
-	if (!msm_dp_catalog)
-		return;
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
-
-	drm_dbg_dp(catalog->drm_dev, "select: %#x, acr_ctrl: %#x\n",
-					select, acr_ctrl);
-
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
-}
-
-void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 audio_ctrl;
-
-	if (!msm_dp_catalog)
-		return;
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	audio_ctrl = msm_dp_read_link(msm_dp_catalog, MMSS_DP_AUDIO_CFG);
-
-	if (enable)
-		audio_ctrl |= BIT(0);
-	else
-		audio_ctrl &= ~BIT(0);
-
-	drm_dbg_dp(catalog->drm_dev, "dp_audio_cfg = 0x%x\n", audio_ctrl);
-
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
-	/* make sure audio engine is disabled */
-	wmb();
-}
-
-void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 sdp_cfg = 0;
-	u32 sdp_cfg2 = 0;
-
-	if (!msm_dp_catalog)
-		return;
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	sdp_cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
-	/* AUDIO_TIMESTAMP_SDP_EN */
-	sdp_cfg |= BIT(1);
-	/* AUDIO_STREAM_SDP_EN */
-	sdp_cfg |= BIT(2);
-	/* AUDIO_COPY_MANAGEMENT_SDP_EN */
-	sdp_cfg |= BIT(5);
-	/* AUDIO_ISRC_SDP_EN  */
-	sdp_cfg |= BIT(6);
-	/* AUDIO_INFOFRAME_SDP_EN  */
-	sdp_cfg |= BIT(20);
-
-	drm_dbg_dp(catalog->drm_dev, "sdp_cfg = 0x%x\n", sdp_cfg);
-
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, sdp_cfg);
-
-	sdp_cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
-	/* IFRM_REGSRC -> Do not use reg values */
-	sdp_cfg2 &= ~BIT(0);
-	/* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */
-	sdp_cfg2 &= ~BIT(1);
-
-	drm_dbg_dp(catalog->drm_dev, "sdp_cfg2 = 0x%x\n", sdp_cfg2);
-
-	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
-}
-
-void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 safe_to_exit_level)
-{
-	struct msm_dp_catalog_private *catalog;
-	u32 mainlink_levels;
-
-	if (!msm_dp_catalog)
-		return;
-
-	catalog = container_of(msm_dp_catalog,
-		struct msm_dp_catalog_private, msm_dp_catalog);
-
-	mainlink_levels = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS);
-	mainlink_levels &= 0xFE0;
-	mainlink_levels |= safe_to_exit_level;
-
-	drm_dbg_dp(catalog->drm_dev,
-			"mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
-			 mainlink_levels, safe_to_exit_level);
-
-	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
-}
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 5ac89a11a503e2abae9f4cc4740b18f2f3b6da5e..a6d662f5a0d95cdb8f40a9d03be1e7627907b176 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -130,10 +130,4 @@ u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_
 
 struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
 
-/* DP Audio APIs */
-void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *catalog, u32 select);
-void msm_dp_catalog_audio_enable(struct msm_dp_catalog *catalog, bool enable);
-void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *catalog);
-void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *catalog, u32 safe_to_exit_level);
-
 #endif /* _DP_CATALOG_H_ */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 12/14] drm/msm/dp: move more AUX functions to dp_aux.c
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (10 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 11/14] drm/msm/dp: move/inline audio related functions Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-11 23:41 ` [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in Dmitry Baryshkov
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

Move several misnamed functions accessing AUX bus to dp_aux.c, further
cleaning up dp_catalog submodule.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_aux.c     | 94 ++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/msm/dp/dp_aux.h     |  7 +++
 drivers/gpu/drm/msm/dp/dp_catalog.c | 75 +----------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  6 ---
 drivers/gpu/drm/msm/dp/dp_ctrl.c    |  4 +-
 drivers/gpu/drm/msm/dp/dp_display.c | 18 ++++---
 drivers/gpu/drm/msm/dp/dp_panel.c   |  2 +-
 7 files changed, 113 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index cdcab948ae7086964d9e913dadadacc333f46231..f8ea1754665afa37ff9dbaf3f883d94c48bf07b8 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -403,7 +403,7 @@ static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux,
 				phy_calibrate(aux->phy);
 		}
 		/* reset aux if link is in connected state */
-		if (msm_dp_catalog_link_is_connected(aux->catalog))
+		if (msm_dp_aux_is_link_connected(msm_dp_aux))
 			msm_dp_aux_reset(aux);
 	} else {
 		aux->retry_cnt = 0;
@@ -591,6 +591,98 @@ static int msm_dp_wait_hpd_asserted(struct drm_dp_aux *msm_dp_aux,
 	return ret;
 }
 
+void msm_dp_aux_hpd_enable(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux =
+		container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 reg;
+
+	/* Configure REFTIMER and enable it */
+	reg = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
+	reg |= DP_DP_HPD_REFTIMER_ENABLE;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reg);
+
+	/* Enable HPD */
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
+}
+
+void msm_dp_aux_hpd_disable(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux =
+		container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 reg;
+
+	reg = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
+	reg &= ~DP_DP_HPD_REFTIMER_ENABLE;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reg);
+
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, 0);
+}
+
+void msm_dp_aux_hpd_intr_enable(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux =
+		container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 reg;
+
+	reg = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
+	reg |= DP_DP_HPD_INT_MASK;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK,
+		     reg & DP_DP_HPD_INT_MASK);
+}
+
+void msm_dp_aux_hpd_intr_disable(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux =
+		container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 reg;
+
+	reg = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
+	reg &= ~DP_DP_HPD_INT_MASK;
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK,
+		     reg & DP_DP_HPD_INT_MASK);
+}
+
+u32 msm_dp_aux_get_hpd_intr_status(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux =
+		container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	int isr, mask;
+
+	isr = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
+	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_ACK,
+				 (isr & DP_DP_HPD_INT_MASK));
+	mask = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
+
+	/*
+	 * We only want to return interrupts that are unmasked to the caller.
+	 * However, the interrupt status field also contains other
+	 * informational bits about the HPD state status, so we only mask
+	 * out the part of the register that tells us about which interrupts
+	 * are pending.
+	 */
+	return isr & (mask | ~DP_DP_HPD_INT_MASK);
+}
+
+u32 msm_dp_aux_is_link_connected(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux =
+		container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	struct msm_dp_catalog *msm_dp_catalog = aux->catalog;
+	u32 status;
+
+	status = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
+	status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
+	status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
+
+	return status;
+}
+
 struct drm_dp_aux *msm_dp_aux_get(struct device *dev, struct msm_dp_catalog *catalog,
 			      struct phy *phy,
 			      bool is_edp)
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.h b/drivers/gpu/drm/msm/dp/dp_aux.h
index 39c5b4c8596ab28d822493a6b4d479f5f786cdee..624395a41ed0a75ead4826e78d05ca21e8fb8967 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.h
+++ b/drivers/gpu/drm/msm/dp/dp_aux.h
@@ -17,6 +17,13 @@ void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux);
 void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux);
 void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux);
 
+void msm_dp_aux_hpd_enable(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_hpd_disable(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_hpd_intr_enable(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_hpd_intr_disable(struct drm_dp_aux *msm_dp_aux);
+u32 msm_dp_aux_get_hpd_intr_status(struct drm_dp_aux *msm_dp_aux);
+u32 msm_dp_aux_is_link_connected(struct drm_dp_aux *msm_dp_aux);
+
 struct phy;
 struct drm_dp_aux *msm_dp_aux_get(struct device *dev, struct msm_dp_catalog *catalog,
 			      struct phy *phy,
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 2eea02fc4cca3f7183e97d0fc086b8d6fa27ad00..22e2b3147399c0dcce21b9138c24eb699660f21a 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -85,8 +85,8 @@ u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
 	intr &= ~DP_INTERRUPT_STATUS1_MASK;
 	intr_ack = (intr & DP_INTERRUPT_STATUS1)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, intr_ack |
-			DP_INTERRUPT_STATUS1_MASK);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
+		     intr_ack | DP_INTERRUPT_STATUS1_MASK);
 
 	return intr;
 
@@ -119,77 +119,6 @@ void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
 	}
 }
 
-void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
-			u32 intr_mask, bool en)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-
-	u32 config = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
-
-	config = (en ? config | intr_mask : config & ~intr_mask);
-
-	drm_dbg_dp(catalog->drm_dev, "intr_mask=%#x config=%#x\n",
-					intr_mask, config);
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK,
-				config & DP_DP_HPD_INT_MASK);
-}
-
-void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 reftimer = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
-
-	/* Configure REFTIMER and enable it */
-	reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
-
-	/* Enable HPD */
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
-}
-
-void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 reftimer = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
-
-	reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
-
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, 0);
-}
-
-u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
-{
-	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
-				struct msm_dp_catalog_private, msm_dp_catalog);
-	u32 status;
-
-	status = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
-	drm_dbg_dp(catalog->drm_dev, "aux status: %#x\n", status);
-	status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
-	status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
-
-	return status;
-}
-
-u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
-{
-	int isr, mask;
-
-	isr = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
-	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_ACK,
-				 (isr & DP_DP_HPD_INT_MASK));
-	mask = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
-
-	/*
-	 * We only want to return interrupts that are unmasked to the caller.
-	 * However, the interrupt status field also contains other
-	 * informational bits about the HPD state status, so we only mask
-	 * out the part of the register that tells us about which interrupts
-	 * are pending.
-	 */
-	return isr & (mask | ~DP_DP_HPD_INT_MASK);
-}
-
 u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 intr, intr_ack;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index a6d662f5a0d95cdb8f40a9d03be1e7627907b176..789403e332c1a2108ded4f96b049fd00bb34e326 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -118,12 +118,6 @@ u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
 /* DP Controller APIs */
 u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog);
 void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog, bool enable);
-void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
-			u32 intr_mask, bool en);
-void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog);
-u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog);
-u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog);
 int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
 void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog);
 u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index cde667bf8eeec95035b2feb3661686c99acf5b7d..5f32ee2fa0438cd12726540a59ab4849d47ee8c2 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -2162,7 +2162,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
 			break;
 		} else if (training_step == DP_TRAINING_1) {
 			/* link train_1 failed */
-			if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
+			if (!msm_dp_aux_is_link_connected(ctrl->aux))
 				break;
 
 			msm_dp_ctrl_read_link_status(ctrl, link_status);
@@ -2187,7 +2187,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
 			}
 		} else if (training_step == DP_TRAINING_2) {
 			/* link train_2 failed */
-			if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
+			if (!msm_dp_aux_is_link_connected(ctrl->aux))
 				break;
 
 			msm_dp_ctrl_read_link_status(ctrl, link_status);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index aff51bb973ebe0835c96420d16547ebae0c6c0f2..cb02d5d5b404925707c737ed75e9e83fbec34f83 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1145,7 +1145,7 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
 		return IRQ_NONE;
 	}
 
-	hpd_isr_status = msm_dp_catalog_hpd_get_intr_status(dp->catalog);
+	hpd_isr_status = msm_dp_aux_get_hpd_intr_status(dp->aux);
 
 	if (hpd_isr_status & 0x0F) {
 		drm_dbg_dp(dp->drm_dev, "type=%d isr=0x%x\n",
@@ -1360,7 +1360,7 @@ static int msm_dp_pm_runtime_suspend(struct device *dev)
 
 	if (dp->msm_dp_display.is_edp) {
 		msm_dp_display_host_phy_exit(dp);
-		msm_dp_catalog_ctrl_hpd_disable(dp->catalog);
+		msm_dp_aux_hpd_disable(dp->aux);
 	}
 	msm_dp_display_host_deinit(dp);
 
@@ -1381,7 +1381,7 @@ static int msm_dp_pm_runtime_resume(struct device *dev)
 	 */
 	msm_dp_display_host_init(dp);
 	if (dp->msm_dp_display.is_edp) {
-		msm_dp_catalog_ctrl_hpd_enable(dp->catalog);
+		msm_dp_aux_hpd_enable(dp->aux);
 		msm_dp_display_host_phy_init(dp);
 	}
 
@@ -1668,10 +1668,8 @@ void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)
 		return;
 	}
 
-	msm_dp_catalog_ctrl_hpd_enable(dp->catalog);
-
-	/* enable HDP interrupts */
-	msm_dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);
+	msm_dp_aux_hpd_enable(dp->aux);
+	msm_dp_aux_hpd_intr_enable(dp->aux);
 
 	msm_dp_display->internal_hpd = true;
 	mutex_unlock(&dp->event_mutex);
@@ -1684,9 +1682,9 @@ void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
 	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	mutex_lock(&dp->event_mutex);
-	/* disable HDP interrupts */
-	msm_dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
-	msm_dp_catalog_ctrl_hpd_disable(dp->catalog);
+
+	msm_dp_aux_hpd_intr_disable(dp->aux);
+	msm_dp_aux_hpd_disable(dp->aux);
 
 	msm_dp_display->internal_hpd = false;
 
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index cd91de21c8e658570b8d43251ef815981f801ae4..25869e2ac93aba0bffeddae9f95917d81870d8cb 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -165,7 +165,7 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
 	if (!msm_dp_panel->drm_edid) {
 		DRM_ERROR("panel edid read failed\n");
 		/* check edid read fail is due to unplug */
-		if (!msm_dp_catalog_link_is_connected(panel->catalog)) {
+		if (!msm_dp_aux_is_link_connected(panel->aux)) {
 			rc = -ETIMEDOUT;
 			goto end;
 		}

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (11 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 12/14] drm/msm/dp: move more AUX functions to dp_aux.c Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12  3:26   ` Abhinav Kumar
  2024-12-11 23:41 ` [PATCH v3 14/14] drm/msm/dp: move interrupt handling to dp_ctrl Dmitry Baryshkov
  2024-12-12 20:27 ` [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Stephen Boyd
  14 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

All other submodules pass arguments directly. Drop struct
msm_dp_panel_in that is used to wrap dp_panel's submodule args and pass
all data to msm_dp_panel_get() directly.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c |  9 +--------
 drivers/gpu/drm/msm/dp/dp_panel.c   | 15 ++++++++-------
 drivers/gpu/drm/msm/dp/dp_panel.h   | 10 ++--------
 3 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index cb02d5d5b404925707c737ed75e9e83fbec34f83..a2cdcdac042d63a59ff71aefcecb7f8b22f01167 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -722,9 +722,6 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
 {
 	int rc = 0;
 	struct device *dev = &dp->msm_dp_display.pdev->dev;
-	struct msm_dp_panel_in panel_in = {
-		.dev = dev,
-	};
 	struct phy *phy;
 
 	phy = devm_phy_get(dev, "dp");
@@ -765,11 +762,7 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
 		goto error_link;
 	}
 
-	panel_in.aux = dp->aux;
-	panel_in.catalog = dp->catalog;
-	panel_in.link = dp->link;
-
-	dp->panel = msm_dp_panel_get(&panel_in);
+	dp->panel = msm_dp_panel_get(dev, dp->aux, dp->link, dp->catalog);
 	if (IS_ERR(dp->panel)) {
 		rc = PTR_ERR(dp->panel);
 		DRM_ERROR("failed to initialize panel, rc = %d\n", rc);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 25869e2ac93aba0bffeddae9f95917d81870d8cb..49bbcde8cf60ac1b297310a50191135d79b092fb 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -659,25 +659,26 @@ static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
 	return 0;
 }
 
-struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
+struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
+			      struct msm_dp_link *link, struct msm_dp_catalog *catalog)
 {
 	struct msm_dp_panel_private *panel;
 	struct msm_dp_panel *msm_dp_panel;
 	int ret;
 
-	if (!in->dev || !in->catalog || !in->aux || !in->link) {
+	if (!dev || !catalog || !aux || !link) {
 		DRM_ERROR("invalid input\n");
 		return ERR_PTR(-EINVAL);
 	}
 
-	panel = devm_kzalloc(in->dev, sizeof(*panel), GFP_KERNEL);
+	panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
 	if (!panel)
 		return ERR_PTR(-ENOMEM);
 
-	panel->dev = in->dev;
-	panel->aux = in->aux;
-	panel->catalog = in->catalog;
-	panel->link = in->link;
+	panel->dev = dev;
+	panel->aux = aux;
+	panel->catalog = catalog;
+	panel->link = link;
 
 	msm_dp_panel = &panel->msm_dp_panel;
 	msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index f305b1151118b53762368905b70d951a366ba1a8..a4719a3bbbddd18304227a006e82a5ce9ad7bbf3 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -21,13 +21,6 @@ struct msm_dp_display_mode {
 	bool out_fmt_is_yuv_420;
 };
 
-struct msm_dp_panel_in {
-	struct device *dev;
-	struct drm_dp_aux *aux;
-	struct msm_dp_link *link;
-	struct msm_dp_catalog *catalog;
-};
-
 struct msm_dp_panel_psr {
 	u8 version;
 	u8 capabilities;
@@ -94,6 +87,7 @@ static inline bool is_lane_count_valid(u32 lane_count)
 		lane_count == 4);
 }
 
-struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in);
+struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
+			      struct msm_dp_link *link, struct msm_dp_catalog *catalog);
 void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
 #endif /* _DP_PANEL_H_ */

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH v3 14/14] drm/msm/dp: move interrupt handling to dp_ctrl
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (12 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in Dmitry Baryshkov
@ 2024-12-11 23:41 ` Dmitry Baryshkov
  2024-12-12 20:27 ` [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Stephen Boyd
  14 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-11 23:41 UTC (permalink / raw)
  To: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
	Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

It makes it easier to keep all interrupts-related code in dp_ctrl
submodule. Move all functions to dp_ctrl.c.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_aux.c     |   9 +--
 drivers/gpu/drm/msm/dp/dp_aux.h     |   2 +-
 drivers/gpu/drm/msm/dp/dp_catalog.c |  95 ------------------------
 drivers/gpu/drm/msm/dp/dp_catalog.h |  24 ------
 drivers/gpu/drm/msm/dp/dp_ctrl.c    | 142 ++++++++++++++++++++++++++++++------
 drivers/gpu/drm/msm/dp/dp_ctrl.h    |   5 +-
 drivers/gpu/drm/msm/dp/dp_display.c |   9 +--
 drivers/gpu/drm/msm/dp/dp_reg.h     |  17 +++++
 8 files changed, 145 insertions(+), 158 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index f8ea1754665afa37ff9dbaf3f883d94c48bf07b8..d7a38fa5d64d618af463416edf13bef79d6b53ba 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -437,9 +437,8 @@ static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux,
 	return ret;
 }
 
-irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
+irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux, u32 isr)
 {
-	u32 isr;
 	struct msm_dp_aux_private *aux;
 
 	if (!msm_dp_aux) {
@@ -449,12 +448,6 @@ irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
 
 	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
-	isr = msm_dp_catalog_aux_get_irq(aux->catalog);
-
-	/* no interrupts pending, return immediately */
-	if (!isr)
-		return IRQ_NONE;
-
 	if (!aux->cmd_busy) {
 		DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
 		return IRQ_NONE;
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.h b/drivers/gpu/drm/msm/dp/dp_aux.h
index 624395a41ed0a75ead4826e78d05ca21e8fb8967..83908c93b6a1baa6c4eb83a346b4498704008ca5 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.h
+++ b/drivers/gpu/drm/msm/dp/dp_aux.h
@@ -11,7 +11,7 @@
 
 int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux);
 void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux);
-irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux);
+irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux, u32 isr);
 void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled);
 void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux);
 void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux);
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 22e2b3147399c0dcce21b9138c24eb699660f21a..8d90bb0e3fef9cdfc403a4de6a8a0834674d62d5 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -15,41 +15,6 @@
 #include "dp_catalog.h"
 #include "dp_reg.h"
 
-#define POLLING_SLEEP_US			1000
-#define POLLING_TIMEOUT_US			10000
-
-#define DP_INTERRUPT_STATUS_ACK_SHIFT	1
-#define DP_INTERRUPT_STATUS_MASK_SHIFT	2
-
-#define DP_INTERRUPT_STATUS1 \
-	(DP_INTR_AUX_XFER_DONE| \
-	DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
-	DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
-	DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
-	DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
-
-#define DP_INTERRUPT_STATUS1_ACK \
-	(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT)
-#define DP_INTERRUPT_STATUS1_MASK \
-	(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT)
-
-#define DP_INTERRUPT_STATUS2 \
-	(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
-	DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
-
-#define DP_INTERRUPT_STATUS2_ACK \
-	(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT)
-#define DP_INTERRUPT_STATUS2_MASK \
-	(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
-
-#define DP_INTERRUPT_STATUS4 \
-	(PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
-	PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
-
-#define DP_INTERRUPT_MASK4 \
-	(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
-	PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
-
 #define DP_DEFAULT_AHB_OFFSET	0x0000
 #define DP_DEFAULT_AHB_SIZE	0x0200
 #define DP_DEFAULT_AUX_OFFSET	0x0200
@@ -77,21 +42,6 @@ void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_d
 				    msm_dp_catalog->p0_len, msm_dp_catalog->p0_base, "dp_p0");
 }
 
-u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 intr, intr_ack;
-
-	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS);
-	intr &= ~DP_INTERRUPT_STATUS1_MASK;
-	intr_ack = (intr & DP_INTERRUPT_STATUS1)
-			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
-		     intr_ack | DP_INTERRUPT_STATUS1_MASK);
-
-	return intr;
-
-}
-
 /**
  * msm_dp_catalog_hw_revision() - retrieve DP hw revision
  *
@@ -105,51 +55,6 @@ u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
 	return msm_dp_read_ahb(msm_dp_catalog, REG_DP_HW_VERSION);
 }
 
-void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
-						bool enable)
-{
-	if (enable) {
-		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
-				DP_INTERRUPT_STATUS1_MASK);
-		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
-				DP_INTERRUPT_STATUS2_MASK);
-	} else {
-		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, 0x00);
-		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2, 0x00);
-	}
-}
-
-u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 intr, intr_ack;
-
-	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4);
-	intr_ack = (intr & DP_INTERRUPT_STATUS4)
-			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4, intr_ack);
-
-	return intr;
-}
-
-void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog)
-{
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
-}
-
-int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
-{
-	u32 intr, intr_ack;
-
-	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2);
-	intr &= ~DP_INTERRUPT_STATUS2_MASK;
-	intr_ack = (intr & DP_INTERRUPT_STATUS2)
-			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
-			intr_ack | DP_INTERRUPT_STATUS2_MASK);
-
-	return intr;
-}
-
 static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
 {
 	struct resource *res;
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 789403e332c1a2108ded4f96b049fd00bb34e326..310319619242df5fa0d91c89fbcc477f16c130ea 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -11,23 +11,6 @@
 #include "dp_utils.h"
 #include "disp/msm_disp_snapshot.h"
 
-/* interrupts */
-#define DP_INTR_HPD		BIT(0)
-#define DP_INTR_AUX_XFER_DONE	BIT(3)
-#define DP_INTR_WRONG_ADDR	BIT(6)
-#define DP_INTR_TIMEOUT		BIT(9)
-#define DP_INTR_NACK_DEFER	BIT(12)
-#define DP_INTR_WRONG_DATA_CNT	BIT(15)
-#define DP_INTR_I2C_NACK	BIT(18)
-#define DP_INTR_I2C_DEFER	BIT(21)
-#define DP_INTR_PLL_UNLOCKED	BIT(24)
-#define DP_INTR_AUX_ERROR	BIT(27)
-
-#define DP_INTR_READY_FOR_VIDEO		BIT(0)
-#define DP_INTR_IDLE_PATTERN_SENT	BIT(3)
-#define DP_INTR_FRAME_END		BIT(6)
-#define DP_INTR_CRC_UPDATED		BIT(9)
-
 #define DP_HW_VERSION_1_0	0x10000000
 #define DP_HW_VERSION_1_2	0x10020000
 
@@ -112,15 +95,8 @@ static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
 /* Debug module */
 void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state);
 
-/* AUX APIs */
-u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
-
 /* DP Controller APIs */
 u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog, bool enable);
-int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
-void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog);
-u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
 
 struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
 
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 5f32ee2fa0438cd12726540a59ab4849d47ee8c2..f978b599bf14c8fc418f0f2dfe40ca911f8957fe 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -30,6 +30,38 @@
 #define PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES       (300 * HZ / 1000) /* 300 ms */
 #define WAIT_FOR_VIDEO_READY_TIMEOUT_JIFFIES (HZ / 2)
 
+#define DP_INTERRUPT_STATUS_ACK_SHIFT	1
+#define DP_INTERRUPT_STATUS_MASK_SHIFT	2
+
+#define DP_INTERRUPT_STATUS1 \
+	(DP_INTR_AUX_XFER_DONE| \
+	DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
+	DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
+	DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
+	DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
+
+#define DP_INTERRUPT_STATUS1_ACK \
+	(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT)
+#define DP_INTERRUPT_STATUS1_MASK \
+	(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT)
+
+#define DP_INTERRUPT_STATUS2 \
+	(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
+	DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
+
+#define DP_INTERRUPT_STATUS2_ACK \
+	(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT)
+#define DP_INTERRUPT_STATUS2_MASK \
+	(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
+
+#define DP_INTERRUPT_STATUS4 \
+	(PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
+	PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
+
+#define DP_INTERRUPT_MASK4 \
+	(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
+	PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
+
 #define DP_CTRL_INTR_READY_FOR_VIDEO     BIT(0)
 #define DP_CTRL_INTR_IDLE_PATTERN_SENT  BIT(3)
 
@@ -126,8 +158,10 @@ static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
 /*
  * NOTE: resetting DP controller will also clear any pending HPD related interrupts
  */
-static void msm_dp_ctrl_reset(struct msm_dp_ctrl_private *ctrl)
+void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl)
 {
+	struct msm_dp_ctrl_private *ctrl =
+		container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
 	u32 sw_reset;
 
@@ -141,6 +175,79 @@ static void msm_dp_ctrl_reset(struct msm_dp_ctrl_private *ctrl)
 	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
 }
 
+static u32 msm_dp_ctrl_get_aux_interrupt(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS);
+	intr &= ~DP_INTERRUPT_STATUS1_MASK;
+	intr_ack = (intr & DP_INTERRUPT_STATUS1)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
+		     intr_ack | DP_INTERRUPT_STATUS1_MASK);
+
+	return intr;
+
+}
+
+static u32 msm_dp_ctrl_get_interrupt(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2);
+	intr &= ~DP_INTERRUPT_STATUS2_MASK;
+	intr_ack = (intr & DP_INTERRUPT_STATUS2)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
+		     intr_ack | DP_INTERRUPT_STATUS2_MASK);
+
+	return intr;
+}
+
+void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl =
+		container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
+			DP_INTERRUPT_STATUS1_MASK);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
+			DP_INTERRUPT_STATUS2_MASK);
+}
+
+void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl =
+		container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, 0x00);
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2, 0x00);
+}
+
+static u32 msm_dp_ctrl_get_psr_interrupt(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4);
+	intr_ack = (intr & DP_INTERRUPT_STATUS4)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4, intr_ack);
+
+	return intr;
+}
+
+static void msm_dp_ctrl_config_psr_interrupt(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
+
+	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
+}
+
 static void msm_dp_ctrl_psr_mainlink_enable(struct msm_dp_ctrl_private *ctrl)
 {
 	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
@@ -1630,23 +1737,6 @@ static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)
 	return ret;
 }
 
-void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable)
-{
-	struct msm_dp_ctrl_private *ctrl;
-
-	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
-
-	msm_dp_ctrl_reset(ctrl);
-
-	/*
-	 * all dp controller programmable registers will not
-	 * be reset to default value after DP_SW_RESET
-	 * therefore interrupt mask bits have to be updated
-	 * to enable/disable interrupts
-	 */
-	msm_dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
-}
-
 static void msm_dp_ctrl_enable_sdp(struct msm_dp_ctrl_private *ctrl)
 {
 	struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
@@ -1699,7 +1789,7 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
 	cfg |= PSR1_SUPPORTED;
 	msm_dp_write_link(msm_dp_catalog, REG_PSR_CONFIG, cfg);
 
-	msm_dp_catalog_ctrl_config_psr_interrupt(msm_dp_catalog);
+	msm_dp_ctrl_config_psr_interrupt(ctrl);
 	msm_dp_ctrl_enable_sdp(ctrl);
 
 	cfg = DP_PSR_ENABLE;
@@ -1824,7 +1914,7 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
 
 	msm_dp_ctrl_mainlink_disable(ctrl);
 
-	msm_dp_ctrl_reset(ctrl);
+	msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
 
 	dev_pm_opp_set_rate(ctrl->dev, 0);
 	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
@@ -2453,7 +2543,7 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
 
 	msm_dp_ctrl_mainlink_disable(ctrl);
 
-	msm_dp_ctrl_reset(ctrl);
+	msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
 
 	if (ctrl->stream_clks_on) {
 		clk_disable_unprepare(ctrl->pixel_clk);
@@ -2480,7 +2570,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
 	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	if (ctrl->panel->psr_cap.version) {
-		isr = msm_dp_catalog_ctrl_read_psr_interrupt_status(ctrl->catalog);
+		isr = msm_dp_ctrl_get_psr_interrupt(ctrl);
 
 		if (isr)
 			complete(&ctrl->psr_op_comp);
@@ -2495,8 +2585,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
 			drm_dbg_dp(ctrl->drm_dev, "PSR frame capture done\n");
 	}
 
-	isr = msm_dp_catalog_ctrl_get_interrupt(ctrl->catalog);
-
+	isr = msm_dp_ctrl_get_interrupt(ctrl);
 
 	if (isr & DP_CTRL_INTR_READY_FOR_VIDEO) {
 		drm_dbg_dp(ctrl->drm_dev, "dp_video_ready\n");
@@ -2510,6 +2599,11 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
 		ret = IRQ_HANDLED;
 	}
 
+	/* DP aux isr */
+	isr = msm_dp_ctrl_get_aux_interrupt(ctrl);
+	if (isr)
+		ret |= msm_dp_aux_isr(ctrl->aux, isr);
+
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
index b7abfedbf5749c25877a0b8ba3af3d8ed4b23d67..10a4b7cf0335a584b4db67baca882620d7bab74c 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -30,7 +30,7 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link
 			struct msm_dp_catalog *catalog,
 			struct phy *phy);
 
-void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
+void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl);
 void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
 void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
 void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
@@ -41,4 +41,7 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);
 int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
 void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl);
 
+void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
+
 #endif /* _DP_CTRL_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index a2cdcdac042d63a59ff71aefcecb7f8b22f01167..86b2af83301df8206dbe1d0ad1bec091034a6c9c 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -440,7 +440,8 @@ static void msm_dp_display_host_init(struct msm_dp_display_private *dp)
 		dp->phy_initialized);
 
 	msm_dp_ctrl_core_clk_enable(dp->ctrl);
-	msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
+	msm_dp_ctrl_reset(dp->ctrl);
+	msm_dp_ctrl_enable_irq(dp->ctrl);
 	msm_dp_aux_init(dp->aux);
 	dp->core_initialized = true;
 }
@@ -451,7 +452,8 @@ static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp)
 		dp->msm_dp_display.connector_type, dp->core_initialized,
 		dp->phy_initialized);
 
-	msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
+	msm_dp_ctrl_reset(dp->ctrl);
+	msm_dp_ctrl_disable_irq(dp->ctrl);
 	msm_dp_aux_deinit(dp->aux);
 	msm_dp_ctrl_core_clk_disable(dp->ctrl);
 	dp->core_initialized = false;
@@ -1165,9 +1167,6 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
 	/* DP controller isr */
 	ret |= msm_dp_ctrl_isr(dp->ctrl);
 
-	/* DP aux isr */
-	ret |= msm_dp_aux_isr(dp->aux);
-
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h
index 3835c7f5cb984406f8fc52ea765ef2315e0d175b..d17e077ded73251624b5fb1bfbd8f213b4a86d65 100644
--- a/drivers/gpu/drm/msm/dp/dp_reg.h
+++ b/drivers/gpu/drm/msm/dp/dp_reg.h
@@ -21,8 +21,25 @@
 
 #define REG_DP_CLK_CTRL				(0x00000018)
 #define REG_DP_CLK_ACTIVE			(0x0000001C)
+
 #define REG_DP_INTR_STATUS			(0x00000020)
+#define DP_INTR_HPD		BIT(0)
+#define DP_INTR_AUX_XFER_DONE	BIT(3)
+#define DP_INTR_WRONG_ADDR	BIT(6)
+#define DP_INTR_TIMEOUT		BIT(9)
+#define DP_INTR_NACK_DEFER	BIT(12)
+#define DP_INTR_WRONG_DATA_CNT	BIT(15)
+#define DP_INTR_I2C_NACK	BIT(18)
+#define DP_INTR_I2C_DEFER	BIT(21)
+#define DP_INTR_PLL_UNLOCKED	BIT(24)
+#define DP_INTR_AUX_ERROR	BIT(27)
+
 #define REG_DP_INTR_STATUS2			(0x00000024)
+#define DP_INTR_READY_FOR_VIDEO		BIT(0)
+#define DP_INTR_IDLE_PATTERN_SENT	BIT(3)
+#define DP_INTR_FRAME_END		BIT(6)
+#define DP_INTR_CRC_UPDATED		BIT(9)
+
 #define REG_DP_INTR_STATUS3			(0x00000028)
 
 #define REG_DP_INTR_STATUS4			(0x0000002C)

-- 
2.39.5


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 03/14] drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs()
  2024-12-11 23:41 ` [PATCH v3 03/14] drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs() Dmitry Baryshkov
@ 2024-12-12  1:13   ` Abhinav Kumar
  0 siblings, 0 replies; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12  1:13 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> The msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs() are not
> called anywhere. If there is a necessity to dump registers, the
> snapshotting should be used instead. Drop these two functions.
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_catalog.c | 37 -------------------------------------
>   drivers/gpu/drm/msm/dp/dp_catalog.h |  1 -
>   drivers/gpu/drm/msm/dp/dp_panel.c   | 11 -----------
>   drivers/gpu/drm/msm/dp/dp_panel.h   |  1 -
>   4 files changed, 50 deletions(-)
> 

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it
  2024-12-11 23:41 ` [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it Dmitry Baryshkov
@ 2024-12-12  1:14   ` Abhinav Kumar
  2024-12-12  8:58     ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12  1:14 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel, kernel test robot



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> Rather than printing random garbage from stack and pretending that it is
> the default safe_to_exit_level, set the variable beforehand.
> 
> Fixes: d13e36d7d222 ("drm/msm/dp: add audio support for Display Port on MSM")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202411081748.0PPL9MIj-lkp@intel.com/
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_audio.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
> index 74e01a5dd4195d5e0e04250663886f1116f25711..5cbb11986460d1e4ed1890bdf66d0913e013083c 100644
> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
> @@ -329,10 +329,10 @@ static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
>   		safe_to_exit_level = 5;
>   		break;
>   	default:
> +		safe_to_exit_level = 14;
>   		drm_dbg_dp(audio->drm_dev,
>   				"setting the default safe_to_exit_level = %u\n",
>   				safe_to_exit_level);
> -		safe_to_exit_level = 14;
>   		break;
>   	}
>   
> 

This was already picked up in -fixes, so no need to include

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 02/14] drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface
  2024-12-11 23:41 ` [PATCH v3 02/14] drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface Dmitry Baryshkov
@ 2024-12-12  1:23   ` Abhinav Kumar
  0 siblings, 0 replies; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12  1:23 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> The msm_dp_utils_pack_sdp_header() accepts an unlimited-size u32 pointer
> for the header output, while it expects a two-element array. It performs
> a sizeof check which is always true on 64-bit platforms (since
> sizeof(u32*) is 8) and is always false on 32-bit platforms. It returns
> an error code which nobody actually checks.
> 
> Fix the function interface to accept u32[2] and return void, skipping
> all the checks.
> 
> Fixes: 55fb8ffc1802 ("drm/msm/dp: add VSC SDP support for YUV420 over DP")
> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_utils.c | 10 +---------
>   drivers/gpu/drm/msm/dp/dp_utils.h |  2 +-
>   2 files changed, 2 insertions(+), 10 deletions(-)
> 

This was included in -fixes as well. So no need to include.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-11 23:41 ` [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private() Dmitry Baryshkov
@ 2024-12-12  2:59   ` Abhinav Kumar
  2024-12-12  8:52     ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12  2:59 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> Having I/O regions inside a msm_dp_catalog_private() results in extra
> layers of one-line wrappers for accessing the data. Move I/O region base
> and size to the globally visible struct msm_dp_catalog.
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
>   drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
>   2 files changed, 197 insertions(+), 272 deletions(-)
> 


Fundamentally, the whole point of catalog was that it needs to be the 
only place where we want to access the registers. Thats how this really 
started.

This pre-dates my time with the DP driver but as I understand thats what 
it was for.

Basically separating out the logical abstraction vs actual register writes .

If there are hardware sequence differences within the controller reset 
OR any other register offsets which moved around, catalog should have 
been able to absorb it without that spilling over to all the layers.

So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()

Then the reset_ctrl op of the catalog should manage any controller 
version differences within the reset sequence.

We do not use or have catalog ops today so it looks redundant as we just 
call the dp_catalog APIs directly but that was really the intention.

Another reason which was behind this split but not applicable to current 
upstream driver is that the AUX is part of the PHY driver in upstream 
but in downstream, that remains a part of catalog and as we know the AUX 
component keeps changing with chipsets especially the settings. That was 
the reason of keeping catalog separate and the only place which should 
deal with registers and not the entire DP driver.

The second point seems not applicable to this driver but first point 
still is. I do admit there is re-direction like ctrl->catalog
instead of just writing it within dp_ctrl itself but the redirection was 
only because ctrl layers were not really meant to deal with the register 
programming. So for example, now with patch 7 of this series every 
register being written to i exposed in dp_ctrl.c and likewise for other 
files. That seems unnecessary. Because if we do end up with some 
variants which need separate registers written, then we will now have to 
end up touching every file as opposed to only touching dp_catalog.



> diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
> index 0357dec1acd5773f25707e7ebdfca4b1d2b1bb4e..cdb8685924a06e4fc79d70586630ccb9a16a676d 100644
> --- a/drivers/gpu/drm/msm/dp/dp_catalog.c
> +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
> @@ -63,155 +63,128 @@
>   #define DP_DEFAULT_P0_OFFSET	0x1000
>   #define DP_DEFAULT_P0_SIZE	0x0400
>   
> -struct dss_io_region {
> -	size_t len;
> -	void __iomem *base;
> -};
> -
> -struct dss_io_data {
> -	struct dss_io_region ahb;
> -	struct dss_io_region aux;
> -	struct dss_io_region link;
> -	struct dss_io_region p0;
> -};
> -
>   struct msm_dp_catalog_private {
>   	struct device *dev;
>   	struct drm_device *drm_dev;
> -	struct dss_io_data io;
>   	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
>   	struct msm_dp_catalog msm_dp_catalog;
>   };
>   
>   void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -			struct msm_dp_catalog_private, msm_dp_catalog);
> -	struct dss_io_data *dss = &catalog->io;
> -
> -	msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb");
> -	msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux");
> -	msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, "dp_link");
> -	msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, "dp_p0");
> +	msm_disp_snapshot_add_block(disp_state,
> +				    msm_dp_catalog->ahb_len, msm_dp_catalog->ahb_base, "dp_ahb");
> +	msm_disp_snapshot_add_block(disp_state,
> +				    msm_dp_catalog->aux_len, msm_dp_catalog->aux_base, "dp_aux");
> +	msm_disp_snapshot_add_block(disp_state,
> +				    msm_dp_catalog->link_len, msm_dp_catalog->link_base, "dp_link");
> +	msm_disp_snapshot_add_block(disp_state,
> +				    msm_dp_catalog->p0_len, msm_dp_catalog->p0_base, "dp_p0");
>   }
>   
> -static inline u32 msm_dp_read_aux(struct msm_dp_catalog_private *catalog, u32 offset)
> +static inline u32 msm_dp_read_aux(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
>   {
> -	return readl_relaxed(catalog->io.aux.base + offset);
> +	return readl_relaxed(msm_dp_catalog->aux_base + offset);
>   }
>   
> -static inline void msm_dp_write_aux(struct msm_dp_catalog_private *catalog,
> +static inline void msm_dp_write_aux(struct msm_dp_catalog *msm_dp_catalog,
>   			       u32 offset, u32 data)
>   {
>   	/*
>   	 * To make sure aux reg writes happens before any other operation,
>   	 * this function uses writel() instread of writel_relaxed()
>   	 */
> -	writel(data, catalog->io.aux.base + offset);
> +	writel(data, msm_dp_catalog->aux_base + offset);
>   }
>   
> -static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog_private *catalog, u32 offset)
> +static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog *msm_dp_catalog, u32 offset)
>   {
> -	return readl_relaxed(catalog->io.ahb.base + offset);
> +	return readl_relaxed(msm_dp_catalog->ahb_base + offset);
>   }
>   
> -static inline void msm_dp_write_ahb(struct msm_dp_catalog_private *catalog,
> +static inline void msm_dp_write_ahb(struct msm_dp_catalog *msm_dp_catalog,
>   			       u32 offset, u32 data)
>   {
>   	/*
>   	 * To make sure phy reg writes happens before any other operation,
>   	 * this function uses writel() instread of writel_relaxed()
>   	 */
> -	writel(data, catalog->io.ahb.base + offset);
> +	writel(data, msm_dp_catalog->ahb_base + offset);
>   }
>   
> -static inline void msm_dp_write_p0(struct msm_dp_catalog_private *catalog,
> +static inline void msm_dp_write_p0(struct msm_dp_catalog *msm_dp_catalog,
>   			       u32 offset, u32 data)
>   {
>   	/*
>   	 * To make sure interface reg writes happens before any other operation,
>   	 * this function uses writel() instread of writel_relaxed()
>   	 */
> -	writel(data, catalog->io.p0.base + offset);
> +	writel(data, msm_dp_catalog->p0_base + offset);
>   }
>   
> -static inline u32 msm_dp_read_p0(struct msm_dp_catalog_private *catalog,
> +static inline u32 msm_dp_read_p0(struct msm_dp_catalog *msm_dp_catalog,
>   			       u32 offset)
>   {
>   	/*
>   	 * To make sure interface reg writes happens before any other operation,
>   	 * this function uses writel() instread of writel_relaxed()
>   	 */
> -	return readl_relaxed(catalog->io.p0.base + offset);
> +	return readl_relaxed(msm_dp_catalog->p0_base + offset);
>   }
>   
> -static inline u32 msm_dp_read_link(struct msm_dp_catalog_private *catalog, u32 offset)
> +static inline u32 msm_dp_read_link(struct msm_dp_catalog *msm_dp_catalog, u32 offset)
>   {
> -	return readl_relaxed(catalog->io.link.base + offset);
> +	return readl_relaxed(msm_dp_catalog->link_base + offset);
>   }
>   
> -static inline void msm_dp_write_link(struct msm_dp_catalog_private *catalog,
> +static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
>   			       u32 offset, u32 data)
>   {
>   	/*
>   	 * To make sure link reg writes happens before any other operation,
>   	 * this function uses writel() instread of writel_relaxed()
>   	 */
> -	writel(data, catalog->io.link.base + offset);
> +	writel(data, msm_dp_catalog->link_base + offset);
>   }
>   
>   /* aux related catalog functions */
>   u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	return msm_dp_read_aux(catalog, REG_DP_AUX_DATA);
> +	return msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_DATA);
>   }
>   
>   int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	msm_dp_write_aux(catalog, REG_DP_AUX_DATA, data);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_DATA, data);
>   	return 0;
>   }
>   
>   int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, data);
>   	return 0;
>   }
>   
>   int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read)
>   {
>   	u32 data;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
>   	if (read) {
> -		data = msm_dp_read_aux(catalog, REG_DP_AUX_TRANS_CTRL);
> +		data = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL);
>   		data &= ~DP_AUX_TRANS_CTRL_GO;
> -		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
> +		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, data);
>   	} else {
> -		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, 0);
> +		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_TRANS_CTRL, 0);
>   	}
>   	return 0;
>   }
>   
>   int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	msm_dp_read_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
> -	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
> -	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
> -	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
> +	msm_dp_read_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
>   	return 0;
>   }
>   
> @@ -230,47 +203,41 @@ int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog
>   void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog)
>   {
>   	u32 aux_ctrl;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
> +	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
>   
>   	aux_ctrl |= DP_AUX_CTRL_RESET;
> -	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
>   	usleep_range(1000, 1100); /* h/w recommended delay */
>   
>   	aux_ctrl &= ~DP_AUX_CTRL_RESET;
> -	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
>   }
>   
>   void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
>   {
>   	u32 aux_ctrl;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
> +	aux_ctrl = msm_dp_read_aux(msm_dp_catalog, REG_DP_AUX_CTRL);
>   
>   	if (enable) {
> -		msm_dp_write_aux(catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
> -		msm_dp_write_aux(catalog, REG_DP_AUX_LIMITS, 0xffff);
> +		msm_dp_write_aux(msm_dp_catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
> +		msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_LIMITS, 0xffff);
>   		aux_ctrl |= DP_AUX_CTRL_ENABLE;
>   	} else {
>   		aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
>   	}
>   
> -	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_AUX_CTRL, aux_ctrl);
>   }
>   
>   int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
>   					      unsigned long wait_us)
>   {
>   	u32 state;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
>   	/* poll for hpd connected status every 2ms and timeout after wait_us */
> -	return readl_poll_timeout(catalog->io.aux.base +
> +	return readl_poll_timeout(msm_dp_catalog->aux_base +
>   				REG_DP_DP_HPD_INT_STATUS,
>   				state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
>   				min(wait_us, 2000), wait_us);
> @@ -278,15 +245,13 @@ int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_
>   
>   u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 intr, intr_ack;
>   
> -	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS);
> +	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS);
>   	intr &= ~DP_INTERRUPT_STATUS1_MASK;
>   	intr_ack = (intr & DP_INTERRUPT_STATUS1)
>   			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
> -	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, intr_ack |
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, intr_ack |
>   			DP_INTERRUPT_STATUS1_MASK);
>   
>   	return intr;
> @@ -298,20 +263,14 @@ void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_cata
>   				u32 msm_dp_tu, u32 valid_boundary,
>   				u32 valid_boundary2)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
> -	msm_dp_write_link(catalog, REG_DP_TU, msm_dp_tu);
> -	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_TU, msm_dp_tu);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
>   }
>   
>   void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, state);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, state);
>   }
>   
>   void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 cfg)
> @@ -321,13 +280,11 @@ void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32
>   
>   	drm_dbg_dp(catalog->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", cfg);
>   
> -	msm_dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_CONFIGURATION_CTRL, cfg);
>   }
>   
>   void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
>   	u32 ln_mapping;
>   
> @@ -336,7 +293,7 @@ void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
>   	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
>   	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
>   
> -	msm_dp_write_link(catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
>   			ln_mapping);
>   }
>   
> @@ -344,17 +301,15 @@ void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catal
>   						bool enable)
>   {
>   	u32 val;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	val = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
> +	val = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
>   
>   	if (enable)
>   		val |= DP_MAINLINK_CTRL_ENABLE;
>   	else
>   		val &= ~DP_MAINLINK_CTRL_ENABLE;
>   
> -	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, val);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, val);
>   }
>   
>   void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
> @@ -370,25 +325,25 @@ void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
>   		 * To make sure link reg writes happens before other operation,
>   		 * msm_dp_write_link() function uses writel()
>   		 */
> -		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
> +		mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
>   
>   		mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
>   						DP_MAINLINK_CTRL_ENABLE);
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
>   
>   		mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
>   
>   		mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
>   
>   		mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
>   					DP_MAINLINK_FB_BOUNDARY_SEL);
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
>   	} else {
> -		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
> +		mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
>   		mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
>   	}
>   }
>   
> @@ -400,7 +355,7 @@ void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
>   	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
>   				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	misc_val = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
> +	misc_val = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
>   
>   	/* clear bpp bits */
>   	misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
> @@ -410,16 +365,14 @@ void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
>   	misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
>   
>   	drm_dbg_dp(catalog->drm_dev, "misc settings = 0x%x\n", misc_val);
> -	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc_val);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc_val);
>   }
>   
>   void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog)
>   {
>   	u32 mainlink_ctrl, hw_revision;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
> +	mainlink_ctrl = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
>   
>   	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
>   	if (hw_revision >= DP_HW_VERSION_1_2)
> @@ -427,7 +380,7 @@ void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog
>   	else
>   		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
>   
> -	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
>   }
>   
>   void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
> @@ -485,9 +438,9 @@ void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
>   		nvid *= 3;
>   
>   	drm_dbg_dp(catalog->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
> -	msm_dp_write_link(catalog, REG_DP_SOFTWARE_MVID, mvid);
> -	msm_dp_write_link(catalog, REG_DP_SOFTWARE_NVID, nvid);
> -	msm_dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_SOFTWARE_MVID, mvid);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_SOFTWARE_NVID, nvid);
> +	msm_dp_write_p0(msm_dp_catalog, MMSS_DP_DSC_DTO, 0x0);
>   }
>   
>   int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog,
> @@ -505,7 +458,7 @@ int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_cata
>   	bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
>   
>   	/* Poll for mainlink ready status */
> -	ret = readx_poll_timeout(readl, catalog->io.link.base +
> +	ret = readx_poll_timeout(readl, msm_dp_catalog->link_base +
>   					REG_DP_MAINLINK_READY,
>   					data, data & bit,
>   					POLLING_SLEEP_US, POLLING_TIMEOUT_US);
> @@ -526,10 +479,7 @@ int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_cata
>    */
>   u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	const struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	return msm_dp_read_ahb(catalog, REG_DP_HW_VERSION);
> +	return msm_dp_read_ahb(msm_dp_catalog, REG_DP_HW_VERSION);
>   }
>   
>   /**
> @@ -547,28 +497,24 @@ u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
>   void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog)
>   {
>   	u32 sw_reset;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	sw_reset = msm_dp_read_ahb(catalog, REG_DP_SW_RESET);
> +	sw_reset = msm_dp_read_ahb(msm_dp_catalog, REG_DP_SW_RESET);
>   
>   	sw_reset |= DP_SW_RESET;
> -	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
>   	usleep_range(1000, 1100); /* h/w recommended delay */
>   
>   	sw_reset &= ~DP_SW_RESET;
> -	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_SW_RESET, sw_reset);
>   }
>   
>   bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
>   {
>   	u32 data;
>   	int ret;
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   
>   	/* Poll for mainlink ready status */
> -	ret = readl_poll_timeout(catalog->io.link.base +
> +	ret = readl_poll_timeout(msm_dp_catalog->link_base +
>   				REG_DP_MAINLINK_READY,
>   				data, data & DP_MAINLINK_READY_FOR_VIDEO,
>   				POLLING_SLEEP_US, POLLING_TIMEOUT_US);
> @@ -583,17 +529,14 @@ bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
>   void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
>   						bool enable)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
>   	if (enable) {
> -		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS,
> +		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
>   				DP_INTERRUPT_STATUS1_MASK);
> -		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
> +		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
>   				DP_INTERRUPT_STATUS2_MASK);
>   	} else {
> -		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, 0x00);
> -		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 0x00);
> +		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, 0x00);
> +		msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2, 0x00);
>   	}
>   }
>   
> @@ -603,73 +546,63 @@ void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
>   	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
>   				struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	u32 config = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
> +	u32 config = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
>   
>   	config = (en ? config | intr_mask : config & ~intr_mask);
>   
>   	drm_dbg_dp(catalog->drm_dev, "intr_mask=%#x config=%#x\n",
>   					intr_mask, config);
> -	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK,
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK,
>   				config & DP_DP_HPD_INT_MASK);
>   }
>   
>   void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
> +	u32 reftimer = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
>   
>   	/* Configure REFTIMER and enable it */
>   	reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
> -	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
>   
>   	/* Enable HPD */
> -	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
>   }
>   
>   void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
> +	u32 reftimer = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER);
>   
>   	reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
> -	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
>   
> -	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_CTRL, 0);
>   }
>   
> -static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog_private *catalog)
> +static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   {
>   	/* trigger sdp */
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x0);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x0);
>   }
>   
>   void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 config;
>   
>   	/* enable PSR1 function */
> -	config = msm_dp_read_link(catalog, REG_PSR_CONFIG);
> +	config = msm_dp_read_link(msm_dp_catalog, REG_PSR_CONFIG);
>   	config |= PSR1_SUPPORTED;
> -	msm_dp_write_link(catalog, REG_PSR_CONFIG, config);
> +	msm_dp_write_link(msm_dp_catalog, REG_PSR_CONFIG, config);
>   
> -	msm_dp_write_ahb(catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
> -	msm_dp_catalog_enable_sdp(catalog);
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
> +	msm_dp_catalog_enable_sdp(msm_dp_catalog);
>   }
>   
>   void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -			struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 cmd;
>   
> -	cmd = msm_dp_read_link(catalog, REG_PSR_CMD);
> +	cmd = msm_dp_read_link(msm_dp_catalog, REG_PSR_CMD);
>   
>   	cmd &= ~(PSR_ENTER | PSR_EXIT);
>   
> @@ -678,8 +611,8 @@ void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool ent
>   	else
>   		cmd |= PSR_EXIT;
>   
> -	msm_dp_catalog_enable_sdp(catalog);
> -	msm_dp_write_link(catalog, REG_PSR_CMD, cmd);
> +	msm_dp_catalog_enable_sdp(msm_dp_catalog);
> +	msm_dp_write_link(msm_dp_catalog, REG_PSR_CMD, cmd);
>   }
>   
>   u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
> @@ -688,7 +621,7 @@ u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
>   				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 status;
>   
> -	status = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
> +	status = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
>   	drm_dbg_dp(catalog->drm_dev, "aux status: %#x\n", status);
>   	status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
>   	status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
> @@ -698,14 +631,12 @@ u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
>   
>   u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	int isr, mask;
>   
> -	isr = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
> -	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK,
> +	isr = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_STATUS);
> +	msm_dp_write_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_ACK,
>   				 (isr & DP_DP_HPD_INT_MASK));
> -	mask = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
> +	mask = msm_dp_read_aux(msm_dp_catalog, REG_DP_DP_HPD_INT_MASK);
>   
>   	/*
>   	 * We only want to return interrupts that are unmasked to the caller.
> @@ -719,29 +650,25 @@ u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
>   
>   u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 intr, intr_ack;
>   
> -	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS4);
> +	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4);
>   	intr_ack = (intr & DP_INTERRUPT_STATUS4)
>   			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
> -	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS4, intr_ack);
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4, intr_ack);
>   
>   	return intr;
>   }
>   
>   int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 intr, intr_ack;
>   
> -	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS2);
> +	intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2);
>   	intr &= ~DP_INTERRUPT_STATUS2_MASK;
>   	intr_ack = (intr & DP_INTERRUPT_STATUS2)
>   			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
> -	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
>   			intr_ack | DP_INTERRUPT_STATUS2_MASK);
>   
>   	return intr;
> @@ -749,13 +676,10 @@ int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
>   
>   void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL,
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_PHY_CTRL,
>   			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
>   	usleep_range(1000, 1100); /* h/w recommended delay */
> -	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL, 0x0);
> +	msm_dp_write_ahb(msm_dp_catalog, REG_DP_PHY_CTRL, 0x0);
>   }
>   
>   void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
> @@ -766,66 +690,66 @@ void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
>   	u32 value = 0x0;
>   
>   	/* Make sure to clear the current pattern before starting a new one */
> -	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL, 0x0);
>   
>   	drm_dbg_dp(catalog->drm_dev, "pattern: %#x\n", pattern);
>   	switch (pattern) {
>   	case DP_PHY_TEST_PATTERN_D10_2:
> -		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
>   				DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
>   		break;
>   	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
>   		value &= ~(1 << 16);
> -		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
>   					value);
>   		value |= SCRAMBLER_RESET_COUNT_VALUE;
> -		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
>   					value);
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
>   					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
> -		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
>   					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
>   		break;
>   	case DP_PHY_TEST_PATTERN_PRBS7:
> -		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
>   				DP_STATE_CTRL_LINK_PRBS7);
>   		break;
>   	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
> -		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
>   				DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
>   		/* 00111110000011111000001111100000 */
> -		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
>   				0x3E0F83E0);
>   		/* 00001111100000111110000011111000 */
> -		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
>   				0x0F83E0F8);
>   		/* 1111100000111110 */
> -		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
>   				0x0000F83E);
>   		break;
>   	case DP_PHY_TEST_PATTERN_CP2520:
> -		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
> +		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
>   		value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
>   
>   		value = DP_HBR2_ERM_PATTERN;
> -		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
>   				value);
>   		value |= SCRAMBLER_RESET_COUNT_VALUE;
> -		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
>   					value);
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS,
>   					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
> -		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
>   					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
> -		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
> +		value = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL);
>   		value |= DP_MAINLINK_CTRL_ENABLE;
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL, value);
>   		break;
>   	case DP_PHY_TEST_PATTERN_SEL_MASK:
> -		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_CTRL,
>   				DP_MAINLINK_CTRL_ENABLE);
> -		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
> +		msm_dp_write_link(msm_dp_catalog, REG_DP_STATE_CTRL,
>   				DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
>   		break;
>   	default:
> @@ -837,26 +761,21 @@ void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
>   
>   u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
> -
> -	return msm_dp_read_link(catalog, REG_DP_MAINLINK_READY);
> +	return msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_READY);
>   }
>   
>   /* panel related catalog functions */
>   int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
>   				u32 sync_start, u32 width_blanking, u32 msm_dp_active)
>   {
> -	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
> -				struct msm_dp_catalog_private, msm_dp_catalog);
>   	u32 reg;
>   
> -	msm_dp_write_link(catalog, REG_DP_TOTAL_HOR_VER, total);
> -	msm_dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
> -	msm_dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
> -	msm_dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_TOTAL_HOR_VER, total);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
>   
> -	reg = msm_dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
> +	reg = msm_dp_read_p0(msm_dp_catalog, MMSS_DP_INTF_CONFIG);
>   
>   	if (msm_dp_catalog->wide_bus_en)
>   		reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
> @@ -866,42 +785,36 @@ int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 t
>   
>   	DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", msm_dp_catalog->wide_bus_en, reg);
>   
> -	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
> +	msm_dp_write_p0(msm_dp_catalog, MMSS_DP_INTF_CONFIG, reg);
>   	return 0;
>   }
>   
>   static void msm_dp_catalog_panel_send_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
>   {
> -	struct msm_dp_catalog_private *catalog;
>   	u32 header[2];
>   	u32 val;
>   	int i;
>   
> -	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
> -
>   	msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
>   
> -	msm_dp_write_link(catalog, MMSS_DP_GENERIC0_0, header[0]);
> -	msm_dp_write_link(catalog, MMSS_DP_GENERIC0_1, header[1]);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_0, header[0]);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_1, header[1]);
>   
>   	for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
>   		val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
>   		       (vsc_sdp->db[i + 3] << 24));
> -		msm_dp_write_link(catalog, MMSS_DP_GENERIC0_2 + i, val);
> +		msm_dp_write_link(msm_dp_catalog, MMSS_DP_GENERIC0_2 + i, val);
>   	}
>   }
>   
>   static void msm_dp_catalog_panel_update_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   {
> -	struct msm_dp_catalog_private *catalog;
>   	u32 hw_revision;
>   
> -	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
> -
>   	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
>   	if (hw_revision < DP_HW_VERSION_1_2 && hw_revision >= DP_HW_VERSION_1_0) {
> -		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x01);
> -		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x00);
> +		msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x01);
> +		msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG3, 0x00);
>   	}
>   }
>   
> @@ -912,15 +825,15 @@ void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog,
>   
>   	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
> -	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
> -	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
> +	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
> +	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
> +	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
>   
>   	cfg |= GEN0_SDP_EN;
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, cfg);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
>   
>   	cfg2 |= GENERIC0_SDPSIZE_VALID;
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, cfg2);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
>   
>   	msm_dp_catalog_panel_send_vsc_sdp(msm_dp_catalog, vsc_sdp);
>   
> @@ -930,7 +843,7 @@ void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog,
>   	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=1\n");
>   
>   	pr_debug("misc settings = 0x%x\n", misc);
> -	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
>   
>   	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
>   }
> @@ -942,15 +855,15 @@ void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   
>   	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
> -	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
> -	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
> +	cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
> +	cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
> +	misc = msm_dp_read_link(msm_dp_catalog, REG_DP_MISC1_MISC0);
>   
>   	cfg &= ~GEN0_SDP_EN;
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, cfg);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, cfg);
>   
>   	cfg2 &= ~GENERIC0_SDPSIZE_VALID;
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, cfg2);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, cfg2);
>   
>   	/* switch back to MSA */
>   	misc &= ~DP_MISC1_VSC_SDP;
> @@ -958,7 +871,7 @@ void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=0\n");
>   
>   	pr_debug("misc settings = 0x%x\n", misc);
> -	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_MISC1_MISC0, misc);
>   
>   	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
>   }
> @@ -1055,15 +968,15 @@ static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_
>   
>   static int msm_dp_catalog_get_io(struct msm_dp_catalog_private *catalog)
>   {
> +	struct msm_dp_catalog *msm_dp_catalog = &catalog->msm_dp_catalog;
>   	struct platform_device *pdev = to_platform_device(catalog->dev);
> -	struct dss_io_data *dss = &catalog->io;
>   
> -	dss->ahb.base = msm_dp_ioremap(pdev, 0, &dss->ahb.len);
> -	if (IS_ERR(dss->ahb.base))
> -		return PTR_ERR(dss->ahb.base);
> +	msm_dp_catalog->ahb_base = msm_dp_ioremap(pdev, 0, &msm_dp_catalog->ahb_len);
> +	if (IS_ERR(msm_dp_catalog->ahb_base))
> +		return PTR_ERR(msm_dp_catalog->ahb_base);
>   
> -	dss->aux.base = msm_dp_ioremap(pdev, 1, &dss->aux.len);
> -	if (IS_ERR(dss->aux.base)) {
> +	msm_dp_catalog->aux_base = msm_dp_ioremap(pdev, 1, &msm_dp_catalog->aux_len);
> +	if (IS_ERR(msm_dp_catalog->aux_base)) {
>   		/*
>   		 * The initial binding had a single reg, but in order to
>   		 * support variation in the sub-region sizes this was split.
> @@ -1071,34 +984,34 @@ static int msm_dp_catalog_get_io(struct msm_dp_catalog_private *catalog)
>   		 * reg is specified, so fill in the sub-region offsets and
>   		 * lengths based on this single region.
>   		 */
> -		if (PTR_ERR(dss->aux.base) == -EINVAL) {
> -			if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
> +		if (PTR_ERR(msm_dp_catalog->aux_base) == -EINVAL) {
> +			if (msm_dp_catalog->ahb_len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
>   				DRM_ERROR("legacy memory region not large enough\n");
>   				return -EINVAL;
>   			}
>   
> -			dss->ahb.len = DP_DEFAULT_AHB_SIZE;
> -			dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
> -			dss->aux.len = DP_DEFAULT_AUX_SIZE;
> -			dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
> -			dss->link.len = DP_DEFAULT_LINK_SIZE;
> -			dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
> -			dss->p0.len = DP_DEFAULT_P0_SIZE;
> +			msm_dp_catalog->ahb_len = DP_DEFAULT_AHB_SIZE;
> +			msm_dp_catalog->aux_base = msm_dp_catalog->ahb_base + DP_DEFAULT_AUX_OFFSET;
> +			msm_dp_catalog->aux_len = DP_DEFAULT_AUX_SIZE;
> +			msm_dp_catalog->link_base = msm_dp_catalog->ahb_base + DP_DEFAULT_LINK_OFFSET;
> +			msm_dp_catalog->link_len = DP_DEFAULT_LINK_SIZE;
> +			msm_dp_catalog->p0_base = msm_dp_catalog->ahb_base + DP_DEFAULT_P0_OFFSET;
> +			msm_dp_catalog->p0_len = DP_DEFAULT_P0_SIZE;
>   		} else {
> -			DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
> -			return PTR_ERR(dss->aux.base);
> +			DRM_ERROR("unable to remap aux region: %pe\n", msm_dp_catalog->aux_base);
> +			return PTR_ERR(msm_dp_catalog->aux_base);
>   		}
>   	} else {
> -		dss->link.base = msm_dp_ioremap(pdev, 2, &dss->link.len);
> -		if (IS_ERR(dss->link.base)) {
> -			DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
> -			return PTR_ERR(dss->link.base);
> +		msm_dp_catalog->link_base = msm_dp_ioremap(pdev, 2, &msm_dp_catalog->link_len);
> +		if (IS_ERR(msm_dp_catalog->link_base)) {
> +			DRM_ERROR("unable to remap link region: %pe\n", msm_dp_catalog->link_base);
> +			return PTR_ERR(msm_dp_catalog->link_base);
>   		}
>   
> -		dss->p0.base = msm_dp_ioremap(pdev, 3, &dss->p0.len);
> -		if (IS_ERR(dss->p0.base)) {
> -			DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
> -			return PTR_ERR(dss->p0.base);
> +		msm_dp_catalog->p0_base = msm_dp_ioremap(pdev, 3, &msm_dp_catalog->p0_len);
> +		if (IS_ERR(msm_dp_catalog->p0_base)) {
> +			DRM_ERROR("unable to remap p0 region: %pe\n", msm_dp_catalog->p0_base);
> +			return PTR_ERR(msm_dp_catalog->p0_base);
>   		}
>   	}
>   
> @@ -1135,7 +1048,7 @@ u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
>   
>   	sdp_map = catalog->audio_map;
>   
> -	return msm_dp_read_link(catalog, sdp_map[sdp][header]);
> +	return msm_dp_read_link(msm_dp_catalog, sdp_map[sdp][header]);
>   }
>   
>   void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
> @@ -1154,7 +1067,7 @@ void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
>   
>   	sdp_map = catalog->audio_map;
>   
> -	msm_dp_write_link(catalog, sdp_map[sdp][header], data);
> +	msm_dp_write_link(msm_dp_catalog, sdp_map[sdp][header], data);
>   }
>   
>   void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32 select)
> @@ -1173,7 +1086,7 @@ void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32
>   	drm_dbg_dp(catalog->drm_dev, "select: %#x, acr_ctrl: %#x\n",
>   					select, acr_ctrl);
>   
> -	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
>   }
>   
>   void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
> @@ -1187,7 +1100,7 @@ void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool ena
>   	catalog = container_of(msm_dp_catalog,
>   		struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	audio_ctrl = msm_dp_read_link(catalog, MMSS_DP_AUDIO_CFG);
> +	audio_ctrl = msm_dp_read_link(msm_dp_catalog, MMSS_DP_AUDIO_CFG);
>   
>   	if (enable)
>   		audio_ctrl |= BIT(0);
> @@ -1196,7 +1109,7 @@ void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool ena
>   
>   	drm_dbg_dp(catalog->drm_dev, "dp_audio_cfg = 0x%x\n", audio_ctrl);
>   
> -	msm_dp_write_link(catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
>   	/* make sure audio engine is disabled */
>   	wmb();
>   }
> @@ -1213,7 +1126,7 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   	catalog = container_of(msm_dp_catalog,
>   		struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	sdp_cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
> +	sdp_cfg = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG);
>   	/* AUDIO_TIMESTAMP_SDP_EN */
>   	sdp_cfg |= BIT(1);
>   	/* AUDIO_STREAM_SDP_EN */
> @@ -1227,9 +1140,9 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   
>   	drm_dbg_dp(catalog->drm_dev, "sdp_cfg = 0x%x\n", sdp_cfg);
>   
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, sdp_cfg);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG, sdp_cfg);
>   
> -	sdp_cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
> +	sdp_cfg2 = msm_dp_read_link(msm_dp_catalog, MMSS_DP_SDP_CFG2);
>   	/* IFRM_REGSRC -> Do not use reg values */
>   	sdp_cfg2 &= ~BIT(0);
>   	/* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */
> @@ -1237,7 +1150,7 @@ void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
>   
>   	drm_dbg_dp(catalog->drm_dev, "sdp_cfg2 = 0x%x\n", sdp_cfg2);
>   
> -	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
> +	msm_dp_write_link(msm_dp_catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
>   }
>   
>   void msm_dp_catalog_audio_init(struct msm_dp_catalog *msm_dp_catalog)
> @@ -1292,7 +1205,7 @@ void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 s
>   	catalog = container_of(msm_dp_catalog,
>   		struct msm_dp_catalog_private, msm_dp_catalog);
>   
> -	mainlink_levels = msm_dp_read_link(catalog, REG_DP_MAINLINK_LEVELS);
> +	mainlink_levels = msm_dp_read_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS);
>   	mainlink_levels &= 0xFE0;
>   	mainlink_levels |= safe_to_exit_level;
>   
> @@ -1300,5 +1213,5 @@ void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 s
>   			"mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
>   			 mainlink_levels, safe_to_exit_level);
>   
> -	msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
> +	msm_dp_write_link(msm_dp_catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
>   }
> diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
> index 62a401d8f75a6af06445a42af657d65e3fe542c5..13486c9c8703748e69e846be681951368df0a29e 100644
> --- a/drivers/gpu/drm/msm/dp/dp_catalog.h
> +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
> @@ -49,6 +49,18 @@ enum msm_dp_catalog_audio_header_type {
>   
>   struct msm_dp_catalog {
>   	bool wide_bus_en;
> +
> +	void __iomem *ahb_base;
> +	size_t ahb_len;
> +
> +	void __iomem *aux_base;
> +	size_t aux_len;
> +
> +	void __iomem *link_base;
> +	size_t link_len;
> +
> +	void __iomem *p0_base;
> +	size_t p0_len;
>   };
>   
>   /* Debug module */
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-11 23:41 ` [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets Dmitry Baryshkov
@ 2024-12-12  3:12   ` Abhinav Kumar
  2024-12-12  8:53     ` Dmitry Baryshkov
  2024-12-12 21:41   ` Abhinav Kumar
  1 sibling, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12  3:12 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
> to program audio packet data. Use 0 as Packet ID, as it was not
> programmed earlier.
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
>   1 file changed, 66 insertions(+), 222 deletions(-)
> 

Please confirm if dp audio was re-tested after this change. I would 
prefer its retested.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in
  2024-12-11 23:41 ` [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in Dmitry Baryshkov
@ 2024-12-12  3:26   ` Abhinav Kumar
  2024-12-12  8:53     ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12  3:26 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> All other submodules pass arguments directly. Drop struct
> msm_dp_panel_in that is used to wrap dp_panel's submodule args and pass
> all data to msm_dp_panel_get() directly.
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  9 +--------
>   drivers/gpu/drm/msm/dp/dp_panel.c   | 15 ++++++++-------
>   drivers/gpu/drm/msm/dp/dp_panel.h   | 10 ++--------
>   3 files changed, 11 insertions(+), 23 deletions(-)
> 

Change not necessarily tied to catalog cleanup, and can be sent 
independently IMO.

> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index cb02d5d5b404925707c737ed75e9e83fbec34f83..a2cdcdac042d63a59ff71aefcecb7f8b22f01167 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -722,9 +722,6 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
>   {
>   	int rc = 0;
>   	struct device *dev = &dp->msm_dp_display.pdev->dev;
> -	struct msm_dp_panel_in panel_in = {
> -		.dev = dev,
> -	};
>   	struct phy *phy;
>   
>   	phy = devm_phy_get(dev, "dp");
> @@ -765,11 +762,7 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
>   		goto error_link;
>   	}
>   
> -	panel_in.aux = dp->aux;
> -	panel_in.catalog = dp->catalog;
> -	panel_in.link = dp->link;
> -
> -	dp->panel = msm_dp_panel_get(&panel_in);
> +	dp->panel = msm_dp_panel_get(dev, dp->aux, dp->link, dp->catalog);
>   	if (IS_ERR(dp->panel)) {
>   		rc = PTR_ERR(dp->panel);
>   		DRM_ERROR("failed to initialize panel, rc = %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
> index 25869e2ac93aba0bffeddae9f95917d81870d8cb..49bbcde8cf60ac1b297310a50191135d79b092fb 100644
> --- a/drivers/gpu/drm/msm/dp/dp_panel.c
> +++ b/drivers/gpu/drm/msm/dp/dp_panel.c
> @@ -659,25 +659,26 @@ static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
>   	return 0;
>   }
>   
> -struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
> +struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
> +			      struct msm_dp_link *link, struct msm_dp_catalog *catalog)
>   {

so this API, takes a filled input panel, makes a msm_dp_panel out of it 
by filling out more information on top of what was already passed in and 
returns a msm_dp_panel.

So IOW, converts a msm_dp_panel_in to msm_dp_panel.

What is the gain by passing individual params rather than passing them 
as a struct instead? Isnt it better to have it within that struct to 
show the conversion and moreover we dont have to pass in 4 arguments 
instead of 1.


>   	struct msm_dp_panel_private *panel;
>   	struct msm_dp_panel *msm_dp_panel;
>   	int ret;
>   
> -	if (!in->dev || !in->catalog || !in->aux || !in->link) {
> +	if (!dev || !catalog || !aux || !link) {
>   		DRM_ERROR("invalid input\n");
>   		return ERR_PTR(-EINVAL);
>   	}
>   
> -	panel = devm_kzalloc(in->dev, sizeof(*panel), GFP_KERNEL);
> +	panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
>   	if (!panel)
>   		return ERR_PTR(-ENOMEM);
>   
> -	panel->dev = in->dev;
> -	panel->aux = in->aux;
> -	panel->catalog = in->catalog;
> -	panel->link = in->link;
> +	panel->dev = dev;
> +	panel->aux = aux;
> +	panel->catalog = catalog;
> +	panel->link = link;
>   
>   	msm_dp_panel = &panel->msm_dp_panel;
>   	msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
> diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
> index f305b1151118b53762368905b70d951a366ba1a8..a4719a3bbbddd18304227a006e82a5ce9ad7bbf3 100644
> --- a/drivers/gpu/drm/msm/dp/dp_panel.h
> +++ b/drivers/gpu/drm/msm/dp/dp_panel.h
> @@ -21,13 +21,6 @@ struct msm_dp_display_mode {
>   	bool out_fmt_is_yuv_420;
>   };
>   
> -struct msm_dp_panel_in {
> -	struct device *dev;
> -	struct drm_dp_aux *aux;
> -	struct msm_dp_link *link;
> -	struct msm_dp_catalog *catalog;
> -};
> -
>   struct msm_dp_panel_psr {
>   	u8 version;
>   	u8 capabilities;
> @@ -94,6 +87,7 @@ static inline bool is_lane_count_valid(u32 lane_count)
>   		lane_count == 4);
>   }
>   
> -struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in);
> +struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
> +			      struct msm_dp_link *link, struct msm_dp_catalog *catalog);
>   void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
>   #endif /* _DP_PANEL_H_ */
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-12  2:59   ` Abhinav Kumar
@ 2024-12-12  8:52     ` Dmitry Baryshkov
  2024-12-12 19:15       ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12  8:52 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> > Having I/O regions inside a msm_dp_catalog_private() results in extra
> > layers of one-line wrappers for accessing the data. Move I/O region base
> > and size to the globally visible struct msm_dp_catalog.
> >
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
> >   drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
> >   2 files changed, 197 insertions(+), 272 deletions(-)
> >
>
>
> Fundamentally, the whole point of catalog was that it needs to be the
> only place where we want to access the registers. Thats how this really
> started.
>
> This pre-dates my time with the DP driver but as I understand thats what
> it was for.
>
> Basically separating out the logical abstraction vs actual register writes .
>
> If there are hardware sequence differences within the controller reset
> OR any other register offsets which moved around, catalog should have
> been able to absorb it without that spilling over to all the layers.
>
> So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
>
> Then the reset_ctrl op of the catalog should manage any controller
> version differences within the reset sequence.

The problem is that the register-level writes are usually not the best
abstraction. So, instead of designing the code around dp_catalog I'd
prefer to see actual hw / programming changes first.

>
> We do not use or have catalog ops today so it looks redundant as we just
> call the dp_catalog APIs directly but that was really the intention.
>
> Another reason which was behind this split but not applicable to current
> upstream driver is that the AUX is part of the PHY driver in upstream
> but in downstream, that remains a part of catalog and as we know the AUX
> component keeps changing with chipsets especially the settings. That was
> the reason of keeping catalog separate and the only place which should
> deal with registers and not the entire DP driver.
>
> The second point seems not applicable to this driver but first point
> still is. I do admit there is re-direction like ctrl->catalog
> instead of just writing it within dp_ctrl itself but the redirection was
> only because ctrl layers were not really meant to deal with the register
> programming. So for example, now with patch 7 of this series every
> register being written to i exposed in dp_ctrl.c and likewise for other
> files. That seems unnecessary. Because if we do end up with some
> variants which need separate registers written, then we will now have to
> end up touching every file as opposed to only touching dp_catalog.

Yes. I think that it's a bonus, not a problem. We end up touching the
files that are actually changed, so we see what is happening. Quite
frequently register changes are paired with the functionality changes.

For example (a very simple and dumb one), when designing code around
dp_catalog you ended up adding separate _p1 handlers.
Doing that from the data source point of view demands adding a stream_id param.

In the DPU driver we also have version-related conditionals in the HW
modules rather than pushing all data access to dpu_hw_catalog.c &
counterparts.
I think it's better to make DP driver reflect DPU rather than keeping
a separate wrapper for no particular reason (note, DPU has hardware
abstractions, but on a block level, not on a register level).

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in
  2024-12-12  3:26   ` Abhinav Kumar
@ 2024-12-12  8:53     ` Dmitry Baryshkov
  2024-12-12 18:56       ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12  8:53 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Thu, 12 Dec 2024 at 05:26, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> > All other submodules pass arguments directly. Drop struct
> > msm_dp_panel_in that is used to wrap dp_panel's submodule args and pass
> > all data to msm_dp_panel_get() directly.
> >
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_display.c |  9 +--------
> >   drivers/gpu/drm/msm/dp/dp_panel.c   | 15 ++++++++-------
> >   drivers/gpu/drm/msm/dp/dp_panel.h   | 10 ++--------
> >   3 files changed, 11 insertions(+), 23 deletions(-)
> >
>
> Change not necessarily tied to catalog cleanup, and can be sent
> independently IMO.
>
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> > index cb02d5d5b404925707c737ed75e9e83fbec34f83..a2cdcdac042d63a59ff71aefcecb7f8b22f01167 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -722,9 +722,6 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
> >   {
> >       int rc = 0;
> >       struct device *dev = &dp->msm_dp_display.pdev->dev;
> > -     struct msm_dp_panel_in panel_in = {
> > -             .dev = dev,
> > -     };
> >       struct phy *phy;
> >
> >       phy = devm_phy_get(dev, "dp");
> > @@ -765,11 +762,7 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
> >               goto error_link;
> >       }
> >
> > -     panel_in.aux = dp->aux;
> > -     panel_in.catalog = dp->catalog;
> > -     panel_in.link = dp->link;
> > -
> > -     dp->panel = msm_dp_panel_get(&panel_in);
> > +     dp->panel = msm_dp_panel_get(dev, dp->aux, dp->link, dp->catalog);
> >       if (IS_ERR(dp->panel)) {
> >               rc = PTR_ERR(dp->panel);
> >               DRM_ERROR("failed to initialize panel, rc = %d\n", rc);
> > diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
> > index 25869e2ac93aba0bffeddae9f95917d81870d8cb..49bbcde8cf60ac1b297310a50191135d79b092fb 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_panel.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_panel.c
> > @@ -659,25 +659,26 @@ static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
> >       return 0;
> >   }
> >
> > -struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
> > +struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
> > +                           struct msm_dp_link *link, struct msm_dp_catalog *catalog)
> >   {
>
> so this API, takes a filled input panel, makes a msm_dp_panel out of it
> by filling out more information on top of what was already passed in and
> returns a msm_dp_panel.
>
> So IOW, converts a msm_dp_panel_in to msm_dp_panel.
>
> What is the gain by passing individual params rather than passing them
> as a struct instead? Isnt it better to have it within that struct to
> show the conversion and moreover we dont have to pass in 4 arguments
> instead of 1.

We gain uniformity. All other modules use params. And, as pointed out
by Maxime during HDMI Codec reviews, it's easier to handle function
params - it makes it more obvious that one of the params got missing.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-12  3:12   ` Abhinav Kumar
@ 2024-12-12  8:53     ` Dmitry Baryshkov
  0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12  8:53 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Thu, 12 Dec 2024 at 05:12, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> > Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
> > to program audio packet data. Use 0 as Packet ID, as it was not
> > programmed earlier.
> >
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
> >   1 file changed, 66 insertions(+), 222 deletions(-)
> >
>
> Please confirm if dp audio was re-tested after this change. I would
> prefer its retested.

Yes

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it
  2024-12-12  1:14   ` Abhinav Kumar
@ 2024-12-12  8:58     ` Dmitry Baryshkov
  2024-12-12 18:31       ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12  8:58 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel, kernel test robot

On Wed, Dec 11, 2024 at 05:14:18PM -0800, Abhinav Kumar wrote:
> 
> 
> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> > Rather than printing random garbage from stack and pretending that it is
> > the default safe_to_exit_level, set the variable beforehand.
> > 
> > Fixes: d13e36d7d222 ("drm/msm/dp: add audio support for Display Port on MSM")
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes: https://lore.kernel.org/oe-kbuild-all/202411081748.0PPL9MIj-lkp@intel.com/
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_audio.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
> > index 74e01a5dd4195d5e0e04250663886f1116f25711..5cbb11986460d1e4ed1890bdf66d0913e013083c 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_audio.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
> > @@ -329,10 +329,10 @@ static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
> >   		safe_to_exit_level = 5;
> >   		break;
> >   	default:
> > +		safe_to_exit_level = 14;
> >   		drm_dbg_dp(audio->drm_dev,
> >   				"setting the default safe_to_exit_level = %u\n",
> >   				safe_to_exit_level);
> > -		safe_to_exit_level = 14;
> >   		break;
> >   	}
> > 
> 
> This was already picked up in -fixes, so no need to include

I have been rebasing on linux-next. Please make sure that your -fixes
branch is a part of linux-next.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it
  2024-12-12  8:58     ` Dmitry Baryshkov
@ 2024-12-12 18:31       ` Abhinav Kumar
  2024-12-12 18:52         ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12 18:31 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel, kernel test robot



On 12/12/2024 12:58 AM, Dmitry Baryshkov wrote:
> On Wed, Dec 11, 2024 at 05:14:18PM -0800, Abhinav Kumar wrote:
>>
>>
>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>> Rather than printing random garbage from stack and pretending that it is
>>> the default safe_to_exit_level, set the variable beforehand.
>>>
>>> Fixes: d13e36d7d222 ("drm/msm/dp: add audio support for Display Port on MSM")
>>> Reported-by: kernel test robot <lkp@intel.com>
>>> Closes: https://lore.kernel.org/oe-kbuild-all/202411081748.0PPL9MIj-lkp@intel.com/
>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_audio.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
>>> index 74e01a5dd4195d5e0e04250663886f1116f25711..5cbb11986460d1e4ed1890bdf66d0913e013083c 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
>>> @@ -329,10 +329,10 @@ static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
>>>    		safe_to_exit_level = 5;
>>>    		break;
>>>    	default:
>>> +		safe_to_exit_level = 14;
>>>    		drm_dbg_dp(audio->drm_dev,
>>>    				"setting the default safe_to_exit_level = %u\n",
>>>    				safe_to_exit_level);
>>> -		safe_to_exit_level = 14;
>>>    		break;
>>>    	}
>>>
>>
>> This was already picked up in -fixes, so no need to include
> 
> I have been rebasing on linux-next. Please make sure that your -fixes
> branch is a part of linux-next.
> 

Its merged to msm-fixes not just my fixes branch. I am pretty sure 
msm-fixes is part of linux-next.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it
  2024-12-12 18:31       ` Abhinav Kumar
@ 2024-12-12 18:52         ` Abhinav Kumar
  2024-12-12 23:09           ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12 18:52 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel, kernel test robot



On 12/12/2024 10:31 AM, Abhinav Kumar wrote:
> 
> 
> On 12/12/2024 12:58 AM, Dmitry Baryshkov wrote:
>> On Wed, Dec 11, 2024 at 05:14:18PM -0800, Abhinav Kumar wrote:
>>>
>>>
>>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>>> Rather than printing random garbage from stack and pretending that 
>>>> it is
>>>> the default safe_to_exit_level, set the variable beforehand.
>>>>
>>>> Fixes: d13e36d7d222 ("drm/msm/dp: add audio support for Display Port 
>>>> on MSM")
>>>> Reported-by: kernel test robot <lkp@intel.com>
>>>> Closes: 
>>>> https://lore.kernel.org/oe-kbuild-all/202411081748.0PPL9MIj-lkp@intel.com/
>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> ---
>>>>    drivers/gpu/drm/msm/dp/dp_audio.c | 2 +-
>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c 
>>>> b/drivers/gpu/drm/msm/dp/dp_audio.c
>>>> index 
>>>> 74e01a5dd4195d5e0e04250663886f1116f25711..5cbb11986460d1e4ed1890bdf66d0913e013083c 100644
>>>> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
>>>> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
>>>> @@ -329,10 +329,10 @@ static void 
>>>> msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
>>>>            safe_to_exit_level = 5;
>>>>            break;
>>>>        default:
>>>> +        safe_to_exit_level = 14;
>>>>            drm_dbg_dp(audio->drm_dev,
>>>>                    "setting the default safe_to_exit_level = %u\n",
>>>>                    safe_to_exit_level);
>>>> -        safe_to_exit_level = 14;
>>>>            break;
>>>>        }
>>>>
>>>
>>> This was already picked up in -fixes, so no need to include
>>
>> I have been rebasing on linux-next. Please make sure that your -fixes
>> branch is a part of linux-next.
>>
> 
> Its merged to msm-fixes not just my fixes branch. I am pretty sure 
> msm-fixes is part of linux-next.


Actually, I noticed just now that msm-fixes is not part of linux-next. 
So pls ignore my comment. drm-fixes is part of linux-next. We should be 
sending out our PR pretty soon. So you will be able to drop this after that.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in
  2024-12-12  8:53     ` Dmitry Baryshkov
@ 2024-12-12 18:56       ` Abhinav Kumar
  0 siblings, 0 replies; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12 18:56 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel



On 12/12/2024 12:53 AM, Dmitry Baryshkov wrote:
> On Thu, 12 Dec 2024 at 05:26, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>> All other submodules pass arguments directly. Drop struct
>>> msm_dp_panel_in that is used to wrap dp_panel's submodule args and pass
>>> all data to msm_dp_panel_get() directly.
>>>
>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_display.c |  9 +--------
>>>    drivers/gpu/drm/msm/dp/dp_panel.c   | 15 ++++++++-------
>>>    drivers/gpu/drm/msm/dp/dp_panel.h   | 10 ++--------
>>>    3 files changed, 11 insertions(+), 23 deletions(-)
>>>
>>
>> Change not necessarily tied to catalog cleanup, and can be sent
>> independently IMO.
>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
>>> index cb02d5d5b404925707c737ed75e9e83fbec34f83..a2cdcdac042d63a59ff71aefcecb7f8b22f01167 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>>> @@ -722,9 +722,6 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
>>>    {
>>>        int rc = 0;
>>>        struct device *dev = &dp->msm_dp_display.pdev->dev;
>>> -     struct msm_dp_panel_in panel_in = {
>>> -             .dev = dev,
>>> -     };
>>>        struct phy *phy;
>>>
>>>        phy = devm_phy_get(dev, "dp");
>>> @@ -765,11 +762,7 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
>>>                goto error_link;
>>>        }
>>>
>>> -     panel_in.aux = dp->aux;
>>> -     panel_in.catalog = dp->catalog;
>>> -     panel_in.link = dp->link;
>>> -
>>> -     dp->panel = msm_dp_panel_get(&panel_in);
>>> +     dp->panel = msm_dp_panel_get(dev, dp->aux, dp->link, dp->catalog);
>>>        if (IS_ERR(dp->panel)) {
>>>                rc = PTR_ERR(dp->panel);
>>>                DRM_ERROR("failed to initialize panel, rc = %d\n", rc);
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
>>> index 25869e2ac93aba0bffeddae9f95917d81870d8cb..49bbcde8cf60ac1b297310a50191135d79b092fb 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_panel.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_panel.c
>>> @@ -659,25 +659,26 @@ static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
>>>        return 0;
>>>    }
>>>
>>> -struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
>>> +struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
>>> +                           struct msm_dp_link *link, struct msm_dp_catalog *catalog)
>>>    {
>>
>> so this API, takes a filled input panel, makes a msm_dp_panel out of it
>> by filling out more information on top of what was already passed in and
>> returns a msm_dp_panel.
>>
>> So IOW, converts a msm_dp_panel_in to msm_dp_panel.
>>
>> What is the gain by passing individual params rather than passing them
>> as a struct instead? Isnt it better to have it within that struct to
>> show the conversion and moreover we dont have to pass in 4 arguments
>> instead of 1.
> 
> We gain uniformity. All other modules use params. And, as pointed out
> by Maxime during HDMI Codec reviews, it's easier to handle function
> params - it makes it more obvious that one of the params got missing.
> 

Point noted but a very long param list also makes it harder to manage. 
So we should really evaluate on a case-by-case basis and not generalize 
here.

Here its only 4, so i would say its kindof okay. If it goes beyond it, 
then msm_dp_panel_in is probably going to come back.

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-12  8:52     ` Dmitry Baryshkov
@ 2024-12-12 19:15       ` Abhinav Kumar
  2024-12-12 23:09         ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12 19:15 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel



On 12/12/2024 12:52 AM, Dmitry Baryshkov wrote:
> On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>> Having I/O regions inside a msm_dp_catalog_private() results in extra
>>> layers of one-line wrappers for accessing the data. Move I/O region base
>>> and size to the globally visible struct msm_dp_catalog.
>>>
>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
>>>    drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
>>>    2 files changed, 197 insertions(+), 272 deletions(-)
>>>
>>
>>
>> Fundamentally, the whole point of catalog was that it needs to be the
>> only place where we want to access the registers. Thats how this really
>> started.
>>
>> This pre-dates my time with the DP driver but as I understand thats what
>> it was for.
>>
>> Basically separating out the logical abstraction vs actual register writes .
>>
>> If there are hardware sequence differences within the controller reset
>> OR any other register offsets which moved around, catalog should have
>> been able to absorb it without that spilling over to all the layers.
>>
>> So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
>>
>> Then the reset_ctrl op of the catalog should manage any controller
>> version differences within the reset sequence.
> 
> The problem is that the register-level writes are usually not the best
> abstraction. So, instead of designing the code around dp_catalog I'd
> prefer to see actual hw / programming changes first.
> 

So thats the issue here. If we did end up with registers and sequences 
different for controller versions, the ctrl layer was expected to just 
call a reset() op for example similar to the DPU example you gave. And 
as you rightly noted, the dpu_hw_xxx files only expose the ops based on 
version and the upper layers were supposed to just call into the ops 
without knowing the register level details. Thats pretty much what 
dp_ctrl tried to do here. We did not want to expose all the register 
defines in those layers. This series is doing exactly opposite of that.

>>
>> We do not use or have catalog ops today so it looks redundant as we just
>> call the dp_catalog APIs directly but that was really the intention.
>>
>> Another reason which was behind this split but not applicable to current
>> upstream driver is that the AUX is part of the PHY driver in upstream
>> but in downstream, that remains a part of catalog and as we know the AUX
>> component keeps changing with chipsets especially the settings. That was
>> the reason of keeping catalog separate and the only place which should
>> deal with registers and not the entire DP driver.
>>
>> The second point seems not applicable to this driver but first point
>> still is. I do admit there is re-direction like ctrl->catalog
>> instead of just writing it within dp_ctrl itself but the redirection was
>> only because ctrl layers were not really meant to deal with the register
>> programming. So for example, now with patch 7 of this series every
>> register being written to i exposed in dp_ctrl.c and likewise for other
>> files. That seems unnecessary. Because if we do end up with some
>> variants which need separate registers written, then we will now have to
>> end up touching every file as opposed to only touching dp_catalog.
> 
> Yes. I think that it's a bonus, not a problem. We end up touching the
> files that are actually changed, so we see what is happening. Quite
> frequently register changes are paired with the functionality changes.
> 

Not exactly. Why should dp_ctrl really know that some register offset or 
some block shift happened for example. It only needs to know when to 
reset the hardware and not how. Thats the separation getting broken with 
this.

> For example (a very simple and dumb one), when designing code around
> dp_catalog you ended up adding separate _p1 handlers.
> Doing that from the data source point of view demands adding a stream_id param.
> 

I have not checked your comment on that series here but if your concern 
is stream_id should not be stored in the catalog but just passed, thats 
fine, we can change it. stream_id as a param is needed anyway because 
the register programming layer needs to know which offset to use. This 
series is not mitigating that fact.

> In the DPU driver we also have version-related conditionals in the HW
> modules rather than pushing all data access to dpu_hw_catalog.c &
> counterparts.

The dpu_hw_catalog.c and the dp_catalog.c are not the right files to 
compare with each other. dp_catalog.c should be compared with 
dpu_hw_xxx.c and as you noted, DPU version dependencies are handled in 
those files only and not all over the files like what this series is doing.

> I think it's better to make DP driver reflect DPU rather than keeping
> a separate wrapper for no particular reason (note, DPU has hardware
> abstractions, but on a block level, not on a register level).
> 

Thats the issue here. DPU hardware blocks are arranged according to the 
sub-blocks both in the software interface document and hence the code 
matches it file-by-file. DP registers are grouped by clock domains and 
the file separation we have today does not match that anyway. Hence 
grouping link registers writes or pixel clock register writes into 
dp_ctrl is also not correct that way. Let catalog handle that separation 
internally which it already does.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 05/14] drm/msm/dp: move I/O functions to global header
  2024-12-11 23:41 ` [PATCH v3 05/14] drm/msm/dp: move I/O functions to global header Dmitry Baryshkov
@ 2024-12-12 20:26   ` Stephen Boyd
  0 siblings, 0 replies; 43+ messages in thread
From: Stephen Boyd @ 2024-12-12 20:26 UTC (permalink / raw)
  To: Abhinav Kumar, David Airlie, Dmitry Baryshkov, Marijn Suijten,
	Paloma Arellano, Rob Clark, Sean Paul, Simona Vetter
  Cc: Douglas Anderson, linux-arm-msm, dri-devel, freedreno,
	linux-kernel

Quoting Dmitry Baryshkov (2024-12-11 15:41:40)
> Move msm_dp_read()/msm_write_foo() functions to the dp_catalog.h,
> allowing other modules to access the data directly.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 06/14] drm/msm/dp: move/inline AUX register functions
  2024-12-11 23:41 ` [PATCH v3 06/14] drm/msm/dp: move/inline AUX register functions Dmitry Baryshkov
@ 2024-12-12 20:26   ` Stephen Boyd
  0 siblings, 0 replies; 43+ messages in thread
From: Stephen Boyd @ 2024-12-12 20:26 UTC (permalink / raw)
  To: Abhinav Kumar, David Airlie, Dmitry Baryshkov, Marijn Suijten,
	Paloma Arellano, Rob Clark, Sean Paul, Simona Vetter
  Cc: Douglas Anderson, linux-arm-msm, dri-devel, freedreno,
	linux-kernel

Quoting Dmitry Baryshkov (2024-12-11 15:41:41)
> Move all register-level functions to dp_aux.c, inlining one line
> wrappers during this process.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 00/14] drm/msm/dp: perform misc cleanups
  2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
                   ` (13 preceding siblings ...)
  2024-12-11 23:41 ` [PATCH v3 14/14] drm/msm/dp: move interrupt handling to dp_ctrl Dmitry Baryshkov
@ 2024-12-12 20:27 ` Stephen Boyd
  14 siblings, 0 replies; 43+ messages in thread
From: Stephen Boyd @ 2024-12-12 20:27 UTC (permalink / raw)
  To: Abhinav Kumar, David Airlie, Dmitry Baryshkov, Marijn Suijten,
	Paloma Arellano, Rob Clark, Sean Paul, Simona Vetter
  Cc: Douglas Anderson, linux-arm-msm, dri-devel, freedreno,
	linux-kernel, kernel test robot

Quoting Dmitry Baryshkov (2024-12-11 15:41:35)
> - Fix register programming in the dp_audio module
> - Rework most of the register programming functions to be local to the
>   calling module rather than accessing everything through huge
>   dp_catalog monster.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

For the series

Tested-by: Stephen Boyd <swboyd@chromium.org> # sc7180-trogdor

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-11 23:41 ` [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets Dmitry Baryshkov
  2024-12-12  3:12   ` Abhinav Kumar
@ 2024-12-12 21:41   ` Abhinav Kumar
  2024-12-12 22:28     ` Dmitry Baryshkov
  1 sibling, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12 21:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul, Marijn Suijten,
	David Airlie, Simona Vetter, Paloma Arellano
  Cc: Douglas Anderson, Stephen Boyd, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
> to program audio packet data. Use 0 as Packet ID, as it was not
> programmed earlier.
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
>   1 file changed, 66 insertions(+), 222 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
> index 5cbb11986460d1e4ed1890bdf66d0913e013083c..1aa52d5cc08684a49102e45ed6e40ac2b13497c7 100644
> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
> @@ -14,6 +14,7 @@
>   #include "dp_catalog.h"
>   #include "dp_audio.h"
>   #include "dp_panel.h"
> +#include "dp_reg.h"
>   #include "dp_display.h"
>   #include "dp_utils.h"
>   
> @@ -28,251 +29,94 @@ struct msm_dp_audio_private {
>   	struct msm_dp_audio msm_dp_audio;
>   };
>   
> -static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
> -		enum msm_dp_catalog_audio_sdp_type sdp,
> -		enum msm_dp_catalog_audio_header_type header)
> -{
> -	return msm_dp_catalog_audio_get_header(catalog, sdp, header);
> -}
> -
> -static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
> -		u32 data,
> -		enum msm_dp_catalog_audio_sdp_type sdp,
> -		enum msm_dp_catalog_audio_header_type header)
> -{
> -	msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
> -}
> -
>   static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
>   {
>   	struct msm_dp_catalog *catalog = audio->catalog;
> -	u32 value, new_value;
> -	u8 parity_byte;
> -
> -	/* Config header and parity byte 1 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
> -
> -	new_value = 0x02;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_1_BIT)
> -			| (parity_byte << PARITY_BYTE_1_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
> -
> -	/* Config header and parity byte 2 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
> -	new_value = value;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_2_BIT)
> -			| (parity_byte << PARITY_BYTE_2_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
> -
> -	/* Config header and parity byte 3 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
> -
> -	new_value = audio->channels - 1;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_3_BIT)
> -			| (parity_byte << PARITY_BYTE_3_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> -		value, parity_byte);
> -
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
> +	struct dp_sdp_header sdp_hdr = {
> +		.HB0 = 0x00,
> +		.HB1 = 0x02,
> +		.HB2 = 0x00,
> +		.HB3 = audio->channels - 1,
> +	};
> +	u32 header[2];
> +
> +	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> +
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_0, header[0]);
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_1, header[1]);
>   }

This patch is changing the programming behavior.

Earlier it was using a read/modify/write on each register. Now, its just 
  a write. I checked a few chipsets, the reset value of registers was 0, 
so that part is okay.

But, for the MMSS_DP_AUDIO_STREAM_0 register, earlier we were writing 
only the upper nibble, that is bits 15:0 of DP_AUDIO_SDP_HEADER_0 was 
kept as-it-is, but now this patch is changing that to 0. What was the 
reason for that change?

This is true for all the APIs being touched in this file.

I guess the whole point of having that audio map in the catalog was to 
preserve the read values of these registers. I have to check what was 
the reason behind that as once again this was before I worked on this 
driver as well.

So technically there are two parts to this change:

1) dropping read for each header and directly just writing it
2) Writing the registers directly instead of going through catalog

It seems like (1) and (2) are independent. I hope (1) was not the reason 
to have started this whole rework.

>   
>   static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
>   {
>   	struct msm_dp_catalog *catalog = audio->catalog;
> -	u32 value, new_value;
> -	u8 parity_byte;
> -
> -	/* Config header and parity byte 1 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
> -
> -	new_value = 0x1;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_1_BIT)
> -			| (parity_byte << PARITY_BYTE_1_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
> -
> -	/* Config header and parity byte 2 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
> -
> -	new_value = 0x17;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_2_BIT)
> -			| (parity_byte << PARITY_BYTE_2_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
> -
> -	/* Config header and parity byte 3 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
> -
> -	new_value = (0x0 | (0x11 << 2));
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_3_BIT)
> -			| (parity_byte << PARITY_BYTE_3_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
> +	struct dp_sdp_header sdp_hdr = {
> +		.HB0 = 0x00,
> +		.HB1 = 0x01,
> +		.HB2 = 0x17,
> +		.HB3 = 0x0 | (0x11 << 2),
> +	};
> +	u32 header[2];
> +
> +	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> +
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_0, header[0]);
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_1, header[1]);
>   }
>   
>   static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
>   {
>   	struct msm_dp_catalog *catalog = audio->catalog;
> -	u32 value, new_value;
> -	u8 parity_byte;
> -
> -	/* Config header and parity byte 1 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
> -
> -	new_value = 0x84;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_1_BIT)
> -			| (parity_byte << PARITY_BYTE_1_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
> -
> -	/* Config header and parity byte 2 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
> -
> -	new_value = 0x1b;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_2_BIT)
> -			| (parity_byte << PARITY_BYTE_2_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
> -
> -	/* Config header and parity byte 3 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
> -
> -	new_value = (0x0 | (0x11 << 2));
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_3_BIT)
> -			| (parity_byte << PARITY_BYTE_3_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> -			new_value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
> +	struct dp_sdp_header sdp_hdr = {
> +		.HB0 = 0x00,
> +		.HB1 = 0x84,
> +		.HB2 = 0x1b,
> +		.HB3 = 0x0 | (0x11 << 2),
> +	};
> +	u32 header[2];
> +
> +	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> +
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_0, header[0]);
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_1, header[1]);
>   }
>   
>   static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
>   {
>   	struct msm_dp_catalog *catalog = audio->catalog;
> -	u32 value, new_value;
> -	u8 parity_byte;
> -
> -	/* Config header and parity byte 1 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
> -
> -	new_value = 0x05;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_1_BIT)
> -			| (parity_byte << PARITY_BYTE_1_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
> -
> -	/* Config header and parity byte 2 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
> -
> -	new_value = 0x0F;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_2_BIT)
> -			| (parity_byte << PARITY_BYTE_2_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
> -
> -	/* Config header and parity byte 3 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
> -
> -	new_value = 0x0;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_3_BIT)
> -			| (parity_byte << PARITY_BYTE_3_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
> +	struct dp_sdp_header sdp_hdr = {
> +		.HB0 = 0x00,
> +		.HB1 = 0x05,
> +		.HB2 = 0x0f,
> +		.HB3 = 0x00,
> +	};
> +	u32 header[2];
> +
> +	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> +
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_0, header[0]);
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_1, header[1]);
>   }
>   
>   static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
>   {
>   	struct msm_dp_catalog *catalog = audio->catalog;
> -	u32 value, new_value;
> -	u8 parity_byte;
> -
> -	/* Config header and parity byte 1 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
> -
> -	new_value = 0x06;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_1_BIT)
> -			| (parity_byte << PARITY_BYTE_1_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
> -
> -	/* Config header and parity byte 2 */
> -	value = msm_dp_audio_get_header(catalog,
> -			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
> -
> -	new_value = 0x0F;
> -	parity_byte = msm_dp_utils_calculate_parity(new_value);
> -	value |= ((new_value << HEADER_BYTE_2_BIT)
> -			| (parity_byte << PARITY_BYTE_2_BIT));
> -	drm_dbg_dp(audio->drm_dev,
> -			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> -			value, parity_byte);
> -	msm_dp_audio_set_header(catalog, value,
> -		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
> +	struct dp_sdp_header sdp_hdr = {
> +		.HB0 = 0x00,
> +		.HB1 = 0x06,
> +		.HB2 = 0x0f,
> +		.HB3 = 0x00,
> +	};
> +	u32 header[2];
> +	u32 reg;
> +
> +	/* XXX: is it necessary to preserve this field? */
> +	reg = msm_dp_read_link(catalog, MMSS_DP_AUDIO_ISRC_1);
> +	sdp_hdr.HB3 = FIELD_GET(HEADER_3_MASK, reg);
> +
> +	msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> +
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_0, header[0]);
> +	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
>   }
>   
>   static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-12 21:41   ` Abhinav Kumar
@ 2024-12-12 22:28     ` Dmitry Baryshkov
  2024-12-12 23:53       ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12 22:28 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Thu, 12 Dec 2024 at 23:41, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> > Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
> > to program audio packet data. Use 0 as Packet ID, as it was not
> > programmed earlier.
> >
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
> >   1 file changed, 66 insertions(+), 222 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
> > index 5cbb11986460d1e4ed1890bdf66d0913e013083c..1aa52d5cc08684a49102e45ed6e40ac2b13497c7 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_audio.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
> > @@ -14,6 +14,7 @@
> >   #include "dp_catalog.h"
> >   #include "dp_audio.h"
> >   #include "dp_panel.h"
> > +#include "dp_reg.h"
> >   #include "dp_display.h"
> >   #include "dp_utils.h"
> >
> > @@ -28,251 +29,94 @@ struct msm_dp_audio_private {
> >       struct msm_dp_audio msm_dp_audio;
> >   };
> >
> > -static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
> > -             enum msm_dp_catalog_audio_sdp_type sdp,
> > -             enum msm_dp_catalog_audio_header_type header)
> > -{
> > -     return msm_dp_catalog_audio_get_header(catalog, sdp, header);
> > -}
> > -
> > -static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
> > -             u32 data,
> > -             enum msm_dp_catalog_audio_sdp_type sdp,
> > -             enum msm_dp_catalog_audio_header_type header)
> > -{
> > -     msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
> > -}
> > -
> >   static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
> >   {
> >       struct msm_dp_catalog *catalog = audio->catalog;
> > -     u32 value, new_value;
> > -     u8 parity_byte;
> > -
> > -     /* Config header and parity byte 1 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     new_value = 0x02;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_1_BIT)
> > -                     | (parity_byte << PARITY_BYTE_1_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     /* Config header and parity byte 2 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
> > -     new_value = value;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_2_BIT)
> > -                     | (parity_byte << PARITY_BYTE_2_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     /* Config header and parity byte 3 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
> > -
> > -     new_value = audio->channels - 1;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_3_BIT)
> > -                     | (parity_byte << PARITY_BYTE_3_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> > -             value, parity_byte);
> > -
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
> > +     struct dp_sdp_header sdp_hdr = {
> > +             .HB0 = 0x00,
> > +             .HB1 = 0x02,
> > +             .HB2 = 0x00,
> > +             .HB3 = audio->channels - 1,
> > +     };
> > +     u32 header[2];
> > +
> > +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> > +
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_0, header[0]);
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_1, header[1]);
> >   }
>
> This patch is changing the programming behavior.
>
> Earlier it was using a read/modify/write on each register. Now, its just
>   a write. I checked a few chipsets, the reset value of registers was 0,
> so that part is okay.

Except that it was not a correct RMW, it was read, OR new data without
clearing the bitfield, write. So it has been working mostly by a
miracle,

>
> But, for the MMSS_DP_AUDIO_STREAM_0 register, earlier we were writing
> only the upper nibble, that is bits 15:0 of DP_AUDIO_SDP_HEADER_0 was
> kept as-it-is, but now this patch is changing that to 0. What was the
> reason for that change?

It is described in the commit message: "Use 0 as Packet ID, as it was not
programmed earlier."

>
> This is true for all the APIs being touched in this file.
>
> I guess the whole point of having that audio map in the catalog was to
> preserve the read values of these registers. I have to check what was
> the reason behind that as once again this was before I worked on this
> driver as well.
>
> So technically there are two parts to this change:
>
> 1) dropping read for each header and directly just writing it
> 2) Writing the registers directly instead of going through catalog
>
> It seems like (1) and (2) are independent. I hope (1) was not the reason
> to have started this whole rework.

Yes, the driver spends a lot of effort to preserve the data that will
be rewritten when the function is called to write the next header
byte. So it is useless. Only HB0 has been preserved, PacketID. If for
some reason we are generating a stream with the non-zero ID, it should
be explicit, not implicitly 'preserved'.

So, the reasons were:
- fix the RMW cycles to drop old values from the registers
- use new msm_dp_utils_pack_sdp_header()
- get rid of the useless indirection through the catalog and enum
msm_dp_catalog_audio_header_type
- write registers in an efficient way.
- if we ever have a set of functions to handle DP infoframes (like we
do for HDMI), make the MSM DP driver ready to be converted to such
functions.

>
> >
> >   static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
> >   {
> >       struct msm_dp_catalog *catalog = audio->catalog;
> > -     u32 value, new_value;
> > -     u8 parity_byte;
> > -
> > -     /* Config header and parity byte 1 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     new_value = 0x1;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_1_BIT)
> > -                     | (parity_byte << PARITY_BYTE_1_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     /* Config header and parity byte 2 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     new_value = 0x17;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_2_BIT)
> > -                     | (parity_byte << PARITY_BYTE_2_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     /* Config header and parity byte 3 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
> > -
> > -     new_value = (0x0 | (0x11 << 2));
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_3_BIT)
> > -                     | (parity_byte << PARITY_BYTE_3_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
> > +     struct dp_sdp_header sdp_hdr = {
> > +             .HB0 = 0x00,
> > +             .HB1 = 0x01,
> > +             .HB2 = 0x17,
> > +             .HB3 = 0x0 | (0x11 << 2),
> > +     };
> > +     u32 header[2];
> > +
> > +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> > +
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_0, header[0]);
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_1, header[1]);
> >   }
> >
> >   static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
> >   {
> >       struct msm_dp_catalog *catalog = audio->catalog;
> > -     u32 value, new_value;
> > -     u8 parity_byte;
> > -
> > -     /* Config header and parity byte 1 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     new_value = 0x84;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_1_BIT)
> > -                     | (parity_byte << PARITY_BYTE_1_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     /* Config header and parity byte 2 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     new_value = 0x1b;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_2_BIT)
> > -                     | (parity_byte << PARITY_BYTE_2_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     /* Config header and parity byte 3 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
> > -
> > -     new_value = (0x0 | (0x11 << 2));
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_3_BIT)
> > -                     | (parity_byte << PARITY_BYTE_3_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> > -                     new_value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
> > +     struct dp_sdp_header sdp_hdr = {
> > +             .HB0 = 0x00,
> > +             .HB1 = 0x84,
> > +             .HB2 = 0x1b,
> > +             .HB3 = 0x0 | (0x11 << 2),
> > +     };
> > +     u32 header[2];
> > +
> > +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> > +
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_0, header[0]);
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_1, header[1]);
> >   }
> >
> >   static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
> >   {
> >       struct msm_dp_catalog *catalog = audio->catalog;
> > -     u32 value, new_value;
> > -     u8 parity_byte;
> > -
> > -     /* Config header and parity byte 1 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     new_value = 0x05;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_1_BIT)
> > -                     | (parity_byte << PARITY_BYTE_1_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     /* Config header and parity byte 2 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     new_value = 0x0F;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_2_BIT)
> > -                     | (parity_byte << PARITY_BYTE_2_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     /* Config header and parity byte 3 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
> > -
> > -     new_value = 0x0;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_3_BIT)
> > -                     | (parity_byte << PARITY_BYTE_3_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
> > +     struct dp_sdp_header sdp_hdr = {
> > +             .HB0 = 0x00,
> > +             .HB1 = 0x05,
> > +             .HB2 = 0x0f,
> > +             .HB3 = 0x00,
> > +     };
> > +     u32 header[2];
> > +
> > +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> > +
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_0, header[0]);
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_1, header[1]);
> >   }
> >
> >   static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
> >   {
> >       struct msm_dp_catalog *catalog = audio->catalog;
> > -     u32 value, new_value;
> > -     u8 parity_byte;
> > -
> > -     /* Config header and parity byte 1 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     new_value = 0x06;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_1_BIT)
> > -                     | (parity_byte << PARITY_BYTE_1_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
> > -
> > -     /* Config header and parity byte 2 */
> > -     value = msm_dp_audio_get_header(catalog,
> > -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
> > -
> > -     new_value = 0x0F;
> > -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> > -     value |= ((new_value << HEADER_BYTE_2_BIT)
> > -                     | (parity_byte << PARITY_BYTE_2_BIT));
> > -     drm_dbg_dp(audio->drm_dev,
> > -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> > -                     value, parity_byte);
> > -     msm_dp_audio_set_header(catalog, value,
> > -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
> > +     struct dp_sdp_header sdp_hdr = {
> > +             .HB0 = 0x00,
> > +             .HB1 = 0x06,
> > +             .HB2 = 0x0f,
> > +             .HB3 = 0x00,
> > +     };
> > +     u32 header[2];
> > +     u32 reg;
> > +
> > +     /* XXX: is it necessary to preserve this field? */
> > +     reg = msm_dp_read_link(catalog, MMSS_DP_AUDIO_ISRC_1);
> > +     sdp_hdr.HB3 = FIELD_GET(HEADER_3_MASK, reg);
> > +
> > +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> > +
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_0, header[0]);
> > +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
> >   }
> >
> >   static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
> >



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-12 19:15       ` Abhinav Kumar
@ 2024-12-12 23:09         ` Dmitry Baryshkov
  2024-12-14 20:53           ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12 23:09 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Thu, 12 Dec 2024 at 21:15, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/12/2024 12:52 AM, Dmitry Baryshkov wrote:
> > On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> >>> Having I/O regions inside a msm_dp_catalog_private() results in extra
> >>> layers of one-line wrappers for accessing the data. Move I/O region base
> >>> and size to the globally visible struct msm_dp_catalog.
> >>>
> >>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>> ---
> >>>    drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
> >>>    drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
> >>>    2 files changed, 197 insertions(+), 272 deletions(-)
> >>>
> >>
> >>
> >> Fundamentally, the whole point of catalog was that it needs to be the
> >> only place where we want to access the registers. Thats how this really
> >> started.
> >>
> >> This pre-dates my time with the DP driver but as I understand thats what
> >> it was for.
> >>
> >> Basically separating out the logical abstraction vs actual register writes .
> >>
> >> If there are hardware sequence differences within the controller reset
> >> OR any other register offsets which moved around, catalog should have
> >> been able to absorb it without that spilling over to all the layers.
> >>
> >> So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
> >>
> >> Then the reset_ctrl op of the catalog should manage any controller
> >> version differences within the reset sequence.
> >
> > The problem is that the register-level writes are usually not the best
> > abstraction. So, instead of designing the code around dp_catalog I'd
> > prefer to see actual hw / programming changes first.
> >
>
> So thats the issue here. If we did end up with registers and sequences
> different for controller versions, the ctrl layer was expected to just
> call a reset() op for example similar to the DPU example you gave. And
> as you rightly noted, the dpu_hw_xxx files only expose the ops based on
> version and the upper layers were supposed to just call into the ops
> without knowing the register level details. Thats pretty much what
> dp_ctrl tried to do here. We did not want to expose all the register
> defines in those layers. This series is doing exactly opposite of that.

We don't have the issue up to now, even though we support DP
controllers since SDM845 up to SM8650 and X1E80100. The SDE driver has
v200 vs v420 catalog files for PHY programming, the rest of the
functions are common. So, for me it looks like a preparation for the
imaginary case that didn't come to existence up to now.
So, yes. I want to get rid of extra useless indirection and I want to
expose register sequences in those layers.

>
> >>
> >> We do not use or have catalog ops today so it looks redundant as we just
> >> call the dp_catalog APIs directly but that was really the intention.
> >>
> >> Another reason which was behind this split but not applicable to current
> >> upstream driver is that the AUX is part of the PHY driver in upstream
> >> but in downstream, that remains a part of catalog and as we know the AUX
> >> component keeps changing with chipsets especially the settings. That was
> >> the reason of keeping catalog separate and the only place which should
> >> deal with registers and not the entire DP driver.
> >>
> >> The second point seems not applicable to this driver but first point
> >> still is. I do admit there is re-direction like ctrl->catalog
> >> instead of just writing it within dp_ctrl itself but the redirection was
> >> only because ctrl layers were not really meant to deal with the register
> >> programming. So for example, now with patch 7 of this series every
> >> register being written to i exposed in dp_ctrl.c and likewise for other
> >> files. That seems unnecessary. Because if we do end up with some
> >> variants which need separate registers written, then we will now have to
> >> end up touching every file as opposed to only touching dp_catalog.
> >
> > Yes. I think that it's a bonus, not a problem. We end up touching the
> > files that are actually changed, so we see what is happening. Quite
> > frequently register changes are paired with the functionality changes.
> >
>
> Not exactly. Why should dp_ctrl really know that some register offset or
> some block shift happened for example. It only needs to know when to
> reset the hardware and not how. Thats the separation getting broken with
> this.

Yes. And I'm removing that separation very intentionally. If one is
looking for AUX programming, they should be looking into dp_aux only,
not dp_aux & dp_catalog. Likewise all audio code should be in
dp_audio. By using dp_catalog we ended up with a very very very bad
abstraction of msm_dp_catalog_audio_get_header() /
msm_dp_catalog_audio_set_header() / enum
msm_dp_catalog_audio_sdp_type. Just because reads & writes should go
through the catalog.
For dp_panel likewise there is no need to look into some other source
file to follow the register sequences. It can all be contained within
dp_panel.c, helping one to understand the code.

Last, but not least. Code complexity. dp_catalog.c consists of 1340
lines, covering different submodules. It is hard to follow it in this
way.

>
> > For example (a very simple and dumb one), when designing code around
> > dp_catalog you ended up adding separate _p1 handlers.
> > Doing that from the data source point of view demands adding a stream_id param.
> >
>
> I have not checked your comment on that series here but if your concern

This is really a bad cadence. I have provided most of the feedback
almost a week ago.

> is stream_id should not be stored in the catalog but just passed, thats
> fine, we can change it. stream_id as a param is needed anyway because
> the register programming layer needs to know which offset to use. This
> series is not mitigating that fact.

No, my concern was that you have been adding separate _p1() functions
which are a duplicate of _p0() counterparts. When one looks at the
dp_catalog.c it is logical: there are two different register areas, so
there are two distinct sets of functions. If one starts looking from
the dp_panel point of view, it's obvious that there should be a single
msm_dp_write_stream() function which accepts stream_id and then
multiplexes it to go to p0 or p1.

>
> > In the DPU driver we also have version-related conditionals in the HW
> > modules rather than pushing all data access to dpu_hw_catalog.c &
> > counterparts.
>
> The dpu_hw_catalog.c and the dp_catalog.c are not the right files to
> compare with each other. dp_catalog.c should be compared with
> dpu_hw_xxx.c and as you noted, DPU version dependencies are handled in
> those files only and not all over the files like what this series is doing.

Not really. dpu_encoder_phys_cmd_init() checks for the core_major_ver.
Let me see if other files check for the version under the hood.

Also as you wrote, there are multiple dpu_hw_xxx.c files, each
handling register issues on its own. We don't have a single file which
keeps all such differences in one place.

Last, but not least, in the DPU driver there are actual differences
between generations, which require different code paths. In the DP
driver there are none.

>
> > I think it's better to make DP driver reflect DPU rather than keeping
> > a separate wrapper for no particular reason (note, DPU has hardware
> > abstractions, but on a block level, not on a register level).
> >
>
> Thats the issue here. DPU hardware blocks are arranged according to the
> sub-blocks both in the software interface document and hence the code
> matches it file-by-file. DP registers are grouped by clock domains and
> the file separation we have today does not match that anyway. Hence
> grouping link registers writes or pixel clock register writes into
> dp_ctrl is also not correct that way. Let catalog handle that separation
> internally which it already does.

I'd say, dp_panel, dp_audio and dp_link are already pretty
self-contained. I was hoping to look at dp_display vs dp_drm later on,
once the HPD issue gets resolved. Only dp_ctrl is not that logical
from my point of view.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it
  2024-12-12 18:52         ` Abhinav Kumar
@ 2024-12-12 23:09           ` Dmitry Baryshkov
  0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-12 23:09 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel, kernel test robot

On Thu, 12 Dec 2024 at 20:53, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/12/2024 10:31 AM, Abhinav Kumar wrote:
> >
> >
> > On 12/12/2024 12:58 AM, Dmitry Baryshkov wrote:
> >> On Wed, Dec 11, 2024 at 05:14:18PM -0800, Abhinav Kumar wrote:
> >>>
> >>>
> >>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> >>>> Rather than printing random garbage from stack and pretending that
> >>>> it is
> >>>> the default safe_to_exit_level, set the variable beforehand.
> >>>>
> >>>> Fixes: d13e36d7d222 ("drm/msm/dp: add audio support for Display Port
> >>>> on MSM")
> >>>> Reported-by: kernel test robot <lkp@intel.com>
> >>>> Closes:
> >>>> https://lore.kernel.org/oe-kbuild-all/202411081748.0PPL9MIj-lkp@intel.com/
> >>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> >>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>> ---
> >>>>    drivers/gpu/drm/msm/dp/dp_audio.c | 2 +-
> >>>>    1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c
> >>>> b/drivers/gpu/drm/msm/dp/dp_audio.c
> >>>> index
> >>>> 74e01a5dd4195d5e0e04250663886f1116f25711..5cbb11986460d1e4ed1890bdf66d0913e013083c 100644
> >>>> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
> >>>> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
> >>>> @@ -329,10 +329,10 @@ static void
> >>>> msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
> >>>>            safe_to_exit_level = 5;
> >>>>            break;
> >>>>        default:
> >>>> +        safe_to_exit_level = 14;
> >>>>            drm_dbg_dp(audio->drm_dev,
> >>>>                    "setting the default safe_to_exit_level = %u\n",
> >>>>                    safe_to_exit_level);
> >>>> -        safe_to_exit_level = 14;
> >>>>            break;
> >>>>        }
> >>>>
> >>>
> >>> This was already picked up in -fixes, so no need to include
> >>
> >> I have been rebasing on linux-next. Please make sure that your -fixes
> >> branch is a part of linux-next.
> >>
> >
> > Its merged to msm-fixes not just my fixes branch. I am pretty sure
> > msm-fixes is part of linux-next.
>
>
> Actually, I noticed just now that msm-fixes is not part of linux-next.
> So pls ignore my comment. drm-fixes is part of linux-next. We should be
> sending out our PR pretty soon. So you will be able to drop this after that.

Ack. Let's get it to linux-next then.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-12 22:28     ` Dmitry Baryshkov
@ 2024-12-12 23:53       ` Abhinav Kumar
  2024-12-13  0:28         ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-12 23:53 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel



On 12/12/2024 2:28 PM, Dmitry Baryshkov wrote:
> On Thu, 12 Dec 2024 at 23:41, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>> Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
>>> to program audio packet data. Use 0 as Packet ID, as it was not
>>> programmed earlier.
>>>
>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
>>>    1 file changed, 66 insertions(+), 222 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
>>> index 5cbb11986460d1e4ed1890bdf66d0913e013083c..1aa52d5cc08684a49102e45ed6e40ac2b13497c7 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
>>> @@ -14,6 +14,7 @@
>>>    #include "dp_catalog.h"
>>>    #include "dp_audio.h"
>>>    #include "dp_panel.h"
>>> +#include "dp_reg.h"
>>>    #include "dp_display.h"
>>>    #include "dp_utils.h"
>>>
>>> @@ -28,251 +29,94 @@ struct msm_dp_audio_private {
>>>        struct msm_dp_audio msm_dp_audio;
>>>    };
>>>
>>> -static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
>>> -             enum msm_dp_catalog_audio_sdp_type sdp,
>>> -             enum msm_dp_catalog_audio_header_type header)
>>> -{
>>> -     return msm_dp_catalog_audio_get_header(catalog, sdp, header);
>>> -}
>>> -
>>> -static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
>>> -             u32 data,
>>> -             enum msm_dp_catalog_audio_sdp_type sdp,
>>> -             enum msm_dp_catalog_audio_header_type header)
>>> -{
>>> -     msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
>>> -}
>>> -
>>>    static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
>>>    {
>>>        struct msm_dp_catalog *catalog = audio->catalog;
>>> -     u32 value, new_value;
>>> -     u8 parity_byte;
>>> -
>>> -     /* Config header and parity byte 1 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     new_value = 0x02;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     /* Config header and parity byte 2 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
>>> -     new_value = value;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     /* Config header and parity byte 3 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
>>> -
>>> -     new_value = audio->channels - 1;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>> -             value, parity_byte);
>>> -
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
>>> +     struct dp_sdp_header sdp_hdr = {
>>> +             .HB0 = 0x00,
>>> +             .HB1 = 0x02,
>>> +             .HB2 = 0x00,
>>> +             .HB3 = audio->channels - 1,
>>> +     };
>>> +     u32 header[2];
>>> +
>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>> +
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_0, header[0]);
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_1, header[1]);
>>>    }
>>
>> This patch is changing the programming behavior.
>>
>> Earlier it was using a read/modify/write on each register. Now, its just
>>    a write. I checked a few chipsets, the reset value of registers was 0,
>> so that part is okay.
> 
> Except that it was not a correct RMW, it was read, OR new data without
> clearing the bitfield, write. So it has been working mostly by a
> miracle,
> 
>>
>> But, for the MMSS_DP_AUDIO_STREAM_0 register, earlier we were writing
>> only the upper nibble, that is bits 15:0 of DP_AUDIO_SDP_HEADER_0 was
>> kept as-it-is, but now this patch is changing that to 0. What was the
>> reason for that change?
> 
> It is described in the commit message: "Use 0 as Packet ID, as it was not
> programmed earlier."
> 

The part of using 0 as Packet ID is but not the behavior of changing the 
RMW which is also pretty significant. That was all happening under the hood.

>>
>> This is true for all the APIs being touched in this file.
>>
>> I guess the whole point of having that audio map in the catalog was to
>> preserve the read values of these registers. I have to check what was
>> the reason behind that as once again this was before I worked on this
>> driver as well.
>>
>> So technically there are two parts to this change:
>>
>> 1) dropping read for each header and directly just writing it
>> 2) Writing the registers directly instead of going through catalog
>>
>> It seems like (1) and (2) are independent. I hope (1) was not the reason
>> to have started this whole rework.
> 
> Yes, the driver spends a lot of effort to preserve the data that will
> be rewritten when the function is called to write the next header
> byte. So it is useless. Only HB0 has been preserved, PacketID. If for
> some reason we are generating a stream with the non-zero ID, it should
> be explicit, not implicitly 'preserved'.
> 

I am trying to understand why this was being preserved. Audio 
programming is half in DP driver and half in ADSP. I dont know if the 
expectation was that packet ID will be programmed elsewhere and not in 
HLOS code hence it was preserved.

> So, the reasons were:
> - fix the RMW cycles to drop old values from the registers
> - use new msm_dp_utils_pack_sdp_header()
> - get rid of the useless indirection through the catalog and enum
> msm_dp_catalog_audio_header_type
> - write registers in an efficient way.
> - if we ever have a set of functions to handle DP infoframes (like we
> do for HDMI), make the MSM DP driver ready to be converted to such
> functions.


The only reason the current driver needed to go through the catalog map 
was that it was trying to write one header at a time. And in the 
registers, 2 headers are mapped to one register. So a map was needed. I 
do not know the reason for breaking up the writes into one header at a 
time like I already mentioned so I am trying to gather that info. 
Without knowing the reason it might seem useless but its my duty to make 
sure nothing was overlooked.



> 
>>
>>>
>>>    static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
>>>    {
>>>        struct msm_dp_catalog *catalog = audio->catalog;
>>> -     u32 value, new_value;
>>> -     u8 parity_byte;
>>> -
>>> -     /* Config header and parity byte 1 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     new_value = 0x1;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     /* Config header and parity byte 2 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     new_value = 0x17;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     /* Config header and parity byte 3 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
>>> -
>>> -     new_value = (0x0 | (0x11 << 2));
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
>>> +     struct dp_sdp_header sdp_hdr = {
>>> +             .HB0 = 0x00,
>>> +             .HB1 = 0x01,
>>> +             .HB2 = 0x17,
>>> +             .HB3 = 0x0 | (0x11 << 2),
>>> +     };
>>> +     u32 header[2];
>>> +
>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>> +
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_0, header[0]);
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_1, header[1]);
>>>    }
>>>
>>>    static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
>>>    {
>>>        struct msm_dp_catalog *catalog = audio->catalog;
>>> -     u32 value, new_value;
>>> -     u8 parity_byte;
>>> -
>>> -     /* Config header and parity byte 1 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     new_value = 0x84;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     /* Config header and parity byte 2 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     new_value = 0x1b;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     /* Config header and parity byte 3 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
>>> -
>>> -     new_value = (0x0 | (0x11 << 2));
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     new_value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
>>> +     struct dp_sdp_header sdp_hdr = {
>>> +             .HB0 = 0x00,
>>> +             .HB1 = 0x84,
>>> +             .HB2 = 0x1b,
>>> +             .HB3 = 0x0 | (0x11 << 2),
>>> +     };
>>> +     u32 header[2];
>>> +
>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>> +
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_0, header[0]);
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_1, header[1]);
>>>    }
>>>
>>>    static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
>>>    {
>>>        struct msm_dp_catalog *catalog = audio->catalog;
>>> -     u32 value, new_value;
>>> -     u8 parity_byte;
>>> -
>>> -     /* Config header and parity byte 1 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     new_value = 0x05;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     /* Config header and parity byte 2 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     new_value = 0x0F;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     /* Config header and parity byte 3 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
>>> -
>>> -     new_value = 0x0;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
>>> +     struct dp_sdp_header sdp_hdr = {
>>> +             .HB0 = 0x00,
>>> +             .HB1 = 0x05,
>>> +             .HB2 = 0x0f,
>>> +             .HB3 = 0x00,
>>> +     };
>>> +     u32 header[2];
>>> +
>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>> +
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_0, header[0]);
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_1, header[1]);
>>>    }
>>>
>>>    static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
>>>    {
>>>        struct msm_dp_catalog *catalog = audio->catalog;
>>> -     u32 value, new_value;
>>> -     u8 parity_byte;
>>> -
>>> -     /* Config header and parity byte 1 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     new_value = 0x06;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
>>> -
>>> -     /* Config header and parity byte 2 */
>>> -     value = msm_dp_audio_get_header(catalog,
>>> -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
>>> -
>>> -     new_value = 0x0F;
>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>> -     drm_dbg_dp(audio->drm_dev,
>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>> -                     value, parity_byte);
>>> -     msm_dp_audio_set_header(catalog, value,
>>> -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
>>> +     struct dp_sdp_header sdp_hdr = {
>>> +             .HB0 = 0x00,
>>> +             .HB1 = 0x06,
>>> +             .HB2 = 0x0f,
>>> +             .HB3 = 0x00,
>>> +     };
>>> +     u32 header[2];
>>> +     u32 reg;
>>> +
>>> +     /* XXX: is it necessary to preserve this field? */
>>> +     reg = msm_dp_read_link(catalog, MMSS_DP_AUDIO_ISRC_1);
>>> +     sdp_hdr.HB3 = FIELD_GET(HEADER_3_MASK, reg);
>>> +
>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>> +
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_0, header[0]);
>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
>>>    }
>>>
>>>    static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
>>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-12 23:53       ` Abhinav Kumar
@ 2024-12-13  0:28         ` Dmitry Baryshkov
  2024-12-14 18:02           ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-13  0:28 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Fri, 13 Dec 2024 at 01:53, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 12/12/2024 2:28 PM, Dmitry Baryshkov wrote:
> > On Thu, 12 Dec 2024 at 23:41, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> >>> Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
> >>> to program audio packet data. Use 0 as Packet ID, as it was not
> >>> programmed earlier.
> >>>
> >>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>> ---
> >>>    drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
> >>>    1 file changed, 66 insertions(+), 222 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
> >>> index 5cbb11986460d1e4ed1890bdf66d0913e013083c..1aa52d5cc08684a49102e45ed6e40ac2b13497c7 100644
> >>> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
> >>> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
> >>> @@ -14,6 +14,7 @@
> >>>    #include "dp_catalog.h"
> >>>    #include "dp_audio.h"
> >>>    #include "dp_panel.h"
> >>> +#include "dp_reg.h"
> >>>    #include "dp_display.h"
> >>>    #include "dp_utils.h"
> >>>
> >>> @@ -28,251 +29,94 @@ struct msm_dp_audio_private {
> >>>        struct msm_dp_audio msm_dp_audio;
> >>>    };
> >>>
> >>> -static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
> >>> -             enum msm_dp_catalog_audio_sdp_type sdp,
> >>> -             enum msm_dp_catalog_audio_header_type header)
> >>> -{
> >>> -     return msm_dp_catalog_audio_get_header(catalog, sdp, header);
> >>> -}
> >>> -
> >>> -static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
> >>> -             u32 data,
> >>> -             enum msm_dp_catalog_audio_sdp_type sdp,
> >>> -             enum msm_dp_catalog_audio_header_type header)
> >>> -{
> >>> -     msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
> >>> -}
> >>> -
> >>>    static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
> >>>    {
> >>>        struct msm_dp_catalog *catalog = audio->catalog;
> >>> -     u32 value, new_value;
> >>> -     u8 parity_byte;
> >>> -
> >>> -     /* Config header and parity byte 1 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     new_value = 0x02;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     /* Config header and parity byte 2 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
> >>> -     new_value = value;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     /* Config header and parity byte 3 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
> >>> -
> >>> -     new_value = audio->channels - 1;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> >>> -             value, parity_byte);
> >>> -
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
> >>> +     struct dp_sdp_header sdp_hdr = {
> >>> +             .HB0 = 0x00,
> >>> +             .HB1 = 0x02,
> >>> +             .HB2 = 0x00,
> >>> +             .HB3 = audio->channels - 1,
> >>> +     };
> >>> +     u32 header[2];
> >>> +
> >>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> >>> +
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_0, header[0]);
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_1, header[1]);
> >>>    }
> >>
> >> This patch is changing the programming behavior.
> >>
> >> Earlier it was using a read/modify/write on each register. Now, its just
> >>    a write. I checked a few chipsets, the reset value of registers was 0,
> >> so that part is okay.
> >
> > Except that it was not a correct RMW, it was read, OR new data without
> > clearing the bitfield, write. So it has been working mostly by a
> > miracle,
> >
> >>
> >> But, for the MMSS_DP_AUDIO_STREAM_0 register, earlier we were writing
> >> only the upper nibble, that is bits 15:0 of DP_AUDIO_SDP_HEADER_0 was
> >> kept as-it-is, but now this patch is changing that to 0. What was the
> >> reason for that change?
> >
> > It is described in the commit message: "Use 0 as Packet ID, as it was not
> > programmed earlier."
> >
>
> The part of using 0 as Packet ID is but not the behavior of changing the
> RMW which is also pretty significant. That was all happening under the hood.

No. It is explicitly mentioned in the commit message. It's not under the hood.

>
> >>
> >> This is true for all the APIs being touched in this file.
> >>
> >> I guess the whole point of having that audio map in the catalog was to
> >> preserve the read values of these registers. I have to check what was
> >> the reason behind that as once again this was before I worked on this
> >> driver as well.
> >>
> >> So technically there are two parts to this change:
> >>
> >> 1) dropping read for each header and directly just writing it
> >> 2) Writing the registers directly instead of going through catalog
> >>
> >> It seems like (1) and (2) are independent. I hope (1) was not the reason
> >> to have started this whole rework.
> >
> > Yes, the driver spends a lot of effort to preserve the data that will
> > be rewritten when the function is called to write the next header
> > byte. So it is useless. Only HB0 has been preserved, PacketID. If for
> > some reason we are generating a stream with the non-zero ID, it should
> > be explicit, not implicitly 'preserved'.
> >
>
> I am trying to understand why this was being preserved. Audio
> programming is half in DP driver and half in ADSP. I dont know if the
> expectation was that packet ID will be programmed elsewhere and not in
> HLOS code hence it was preserved.
>
> > So, the reasons were:
> > - fix the RMW cycles to drop old values from the registers
> > - use new msm_dp_utils_pack_sdp_header()
> > - get rid of the useless indirection through the catalog and enum
> > msm_dp_catalog_audio_header_type
> > - write registers in an efficient way.
> > - if we ever have a set of functions to handle DP infoframes (like we
> > do for HDMI), make the MSM DP driver ready to be converted to such
> > functions.
>
>
> The only reason the current driver needed to go through the catalog map
> was that it was trying to write one header at a time. And in the
> registers, 2 headers are mapped to one register. So a map was needed. I
> do not know the reason for breaking up the writes into one header at a
> time like I already mentioned so I am trying to gather that info.
> Without knowing the reason it might seem useless but its my duty to make
> sure nothing was overlooked.

Sure!

>
>
>
> >
> >>
> >>>
> >>>    static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
> >>>    {
> >>>        struct msm_dp_catalog *catalog = audio->catalog;
> >>> -     u32 value, new_value;
> >>> -     u8 parity_byte;
> >>> -
> >>> -     /* Config header and parity byte 1 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     new_value = 0x1;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     /* Config header and parity byte 2 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     new_value = 0x17;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     /* Config header and parity byte 3 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
> >>> -
> >>> -     new_value = (0x0 | (0x11 << 2));
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
> >>> +     struct dp_sdp_header sdp_hdr = {
> >>> +             .HB0 = 0x00,
> >>> +             .HB1 = 0x01,
> >>> +             .HB2 = 0x17,
> >>> +             .HB3 = 0x0 | (0x11 << 2),
> >>> +     };
> >>> +     u32 header[2];
> >>> +
> >>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> >>> +
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_0, header[0]);
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_1, header[1]);
> >>>    }
> >>>
> >>>    static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
> >>>    {
> >>>        struct msm_dp_catalog *catalog = audio->catalog;
> >>> -     u32 value, new_value;
> >>> -     u8 parity_byte;
> >>> -
> >>> -     /* Config header and parity byte 1 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     new_value = 0x84;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     /* Config header and parity byte 2 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     new_value = 0x1b;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     /* Config header and parity byte 3 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
> >>> -
> >>> -     new_value = (0x0 | (0x11 << 2));
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     new_value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
> >>> +     struct dp_sdp_header sdp_hdr = {
> >>> +             .HB0 = 0x00,
> >>> +             .HB1 = 0x84,
> >>> +             .HB2 = 0x1b,
> >>> +             .HB3 = 0x0 | (0x11 << 2),
> >>> +     };
> >>> +     u32 header[2];
> >>> +
> >>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> >>> +
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_0, header[0]);
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_1, header[1]);
> >>>    }
> >>>
> >>>    static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
> >>>    {
> >>>        struct msm_dp_catalog *catalog = audio->catalog;
> >>> -     u32 value, new_value;
> >>> -     u8 parity_byte;
> >>> -
> >>> -     /* Config header and parity byte 1 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     new_value = 0x05;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     /* Config header and parity byte 2 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     new_value = 0x0F;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     /* Config header and parity byte 3 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
> >>> -
> >>> -     new_value = 0x0;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
> >>> +     struct dp_sdp_header sdp_hdr = {
> >>> +             .HB0 = 0x00,
> >>> +             .HB1 = 0x05,
> >>> +             .HB2 = 0x0f,
> >>> +             .HB3 = 0x00,
> >>> +     };
> >>> +     u32 header[2];
> >>> +
> >>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> >>> +
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_0, header[0]);
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_1, header[1]);
> >>>    }
> >>>
> >>>    static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
> >>>    {
> >>>        struct msm_dp_catalog *catalog = audio->catalog;
> >>> -     u32 value, new_value;
> >>> -     u8 parity_byte;
> >>> -
> >>> -     /* Config header and parity byte 1 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     new_value = 0x06;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
> >>> -
> >>> -     /* Config header and parity byte 2 */
> >>> -     value = msm_dp_audio_get_header(catalog,
> >>> -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
> >>> -
> >>> -     new_value = 0x0F;
> >>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
> >>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
> >>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
> >>> -     drm_dbg_dp(audio->drm_dev,
> >>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
> >>> -                     value, parity_byte);
> >>> -     msm_dp_audio_set_header(catalog, value,
> >>> -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
> >>> +     struct dp_sdp_header sdp_hdr = {
> >>> +             .HB0 = 0x00,
> >>> +             .HB1 = 0x06,
> >>> +             .HB2 = 0x0f,
> >>> +             .HB3 = 0x00,
> >>> +     };
> >>> +     u32 header[2];
> >>> +     u32 reg;
> >>> +
> >>> +     /* XXX: is it necessary to preserve this field? */
> >>> +     reg = msm_dp_read_link(catalog, MMSS_DP_AUDIO_ISRC_1);
> >>> +     sdp_hdr.HB3 = FIELD_GET(HEADER_3_MASK, reg);
> >>> +
> >>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
> >>> +
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_0, header[0]);
> >>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
> >>>    }
> >>>
> >>>    static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets
  2024-12-13  0:28         ` Dmitry Baryshkov
@ 2024-12-14 18:02           ` Abhinav Kumar
  0 siblings, 0 replies; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-14 18:02 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel



On 12/12/2024 4:28 PM, Dmitry Baryshkov wrote:
> On Fri, 13 Dec 2024 at 01:53, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 12/12/2024 2:28 PM, Dmitry Baryshkov wrote:
>>> On Thu, 12 Dec 2024 at 23:41, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>>>> Use msm_dp_utils_pack_sdp_header() and call msm_dp_write_link() directly
>>>>> to program audio packet data. Use 0 as Packet ID, as it was not
>>>>> programmed earlier.
>>>>>
>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>     drivers/gpu/drm/msm/dp/dp_audio.c | 288 +++++++++-----------------------------
>>>>>     1 file changed, 66 insertions(+), 222 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
>>>>> index 5cbb11986460d1e4ed1890bdf66d0913e013083c..1aa52d5cc08684a49102e45ed6e40ac2b13497c7 100644
>>>>> --- a/drivers/gpu/drm/msm/dp/dp_audio.c
>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_audio.c
>>>>> @@ -14,6 +14,7 @@
>>>>>     #include "dp_catalog.h"
>>>>>     #include "dp_audio.h"
>>>>>     #include "dp_panel.h"
>>>>> +#include "dp_reg.h"
>>>>>     #include "dp_display.h"
>>>>>     #include "dp_utils.h"
>>>>>
>>>>> @@ -28,251 +29,94 @@ struct msm_dp_audio_private {
>>>>>         struct msm_dp_audio msm_dp_audio;
>>>>>     };
>>>>>
>>>>> -static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
>>>>> -             enum msm_dp_catalog_audio_sdp_type sdp,
>>>>> -             enum msm_dp_catalog_audio_header_type header)
>>>>> -{
>>>>> -     return msm_dp_catalog_audio_get_header(catalog, sdp, header);
>>>>> -}
>>>>> -
>>>>> -static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
>>>>> -             u32 data,
>>>>> -             enum msm_dp_catalog_audio_sdp_type sdp,
>>>>> -             enum msm_dp_catalog_audio_header_type header)
>>>>> -{
>>>>> -     msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
>>>>> -}
>>>>> -
>>>>>     static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
>>>>>     {
>>>>>         struct msm_dp_catalog *catalog = audio->catalog;
>>>>> -     u32 value, new_value;
>>>>> -     u8 parity_byte;
>>>>> -
>>>>> -     /* Config header and parity byte 1 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     new_value = 0x02;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     /* Config header and parity byte 2 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
>>>>> -     new_value = value;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     /* Config header and parity byte 3 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
>>>>> -
>>>>> -     new_value = audio->channels - 1;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -             value, parity_byte);
>>>>> -
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
>>>>> +     struct dp_sdp_header sdp_hdr = {
>>>>> +             .HB0 = 0x00,
>>>>> +             .HB1 = 0x02,
>>>>> +             .HB2 = 0x00,
>>>>> +             .HB3 = audio->channels - 1,
>>>>> +     };
>>>>> +     u32 header[2];
>>>>> +
>>>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>>>> +
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_0, header[0]);
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_STREAM_1, header[1]);
>>>>>     }
>>>>
>>>> This patch is changing the programming behavior.
>>>>
>>>> Earlier it was using a read/modify/write on each register. Now, its just
>>>>     a write. I checked a few chipsets, the reset value of registers was 0,
>>>> so that part is okay.
>>>
>>> Except that it was not a correct RMW, it was read, OR new data without
>>> clearing the bitfield, write. So it has been working mostly by a
>>> miracle,
>>>

Yes, we should have added the bitfield clearing long ago and not waited 
for this cleanup. Could have even gone as a separate fix.

>>>>
>>>> But, for the MMSS_DP_AUDIO_STREAM_0 register, earlier we were writing
>>>> only the upper nibble, that is bits 15:0 of DP_AUDIO_SDP_HEADER_0 was
>>>> kept as-it-is, but now this patch is changing that to 0. What was the
>>>> reason for that change?
>>>
>>> It is described in the commit message: "Use 0 as Packet ID, as it was not
>>> programmed earlier."
>>>
>>
>> The part of using 0 as Packet ID is but not the behavior of changing the
>> RMW which is also pretty significant. That was all happening under the hood.
> 
> No. It is explicitly mentioned in the commit message. It's not under the hood.
> 

Which part? "Use msm_dp_utils_pack_sdp_header() and call 
msm_dp_write_link() directly
to program audio packet data" .. this one?

I would prefer to be more explicit.

I would have preferred something like "and drop the existing behavior to 
read every header and write it and write the whole register at once to 
drop the catalog audio map"


>>
>>>>
>>>> This is true for all the APIs being touched in this file.
>>>>
>>>> I guess the whole point of having that audio map in the catalog was to
>>>> preserve the read values of these registers. I have to check what was
>>>> the reason behind that as once again this was before I worked on this
>>>> driver as well.
>>>>
>>>> So technically there are two parts to this change:
>>>>
>>>> 1) dropping read for each header and directly just writing it
>>>> 2) Writing the registers directly instead of going through catalog
>>>>
>>>> It seems like (1) and (2) are independent. I hope (1) was not the reason
>>>> to have started this whole rework.
>>>
>>> Yes, the driver spends a lot of effort to preserve the data that will
>>> be rewritten when the function is called to write the next header
>>> byte. So it is useless. Only HB0 has been preserved, PacketID. If for
>>> some reason we are generating a stream with the non-zero ID, it should
>>> be explicit, not implicitly 'preserved'.
>>>
>>
>> I am trying to understand why this was being preserved. Audio
>> programming is half in DP driver and half in ADSP. I dont know if the
>> expectation was that packet ID will be programmed elsewhere and not in
>> HLOS code hence it was preserved.
>>
>>> So, the reasons were:
>>> - fix the RMW cycles to drop old values from the registers
>>> - use new msm_dp_utils_pack_sdp_header()

This could have been one change by itself rather than an under the 
umbrella of misc cleanups. All you had to do was do the same cleanup, 
but rather than dp audio directly writing the register, it would have 
gone through catalog maybe perhaps with another API.

Then the catalog cleanup could have just replaced that API if required.

Easier to review , easier to land by iself and easier to bisect as well 
if some regression had happened.

>>> - get rid of the useless indirection through the catalog and enum
>>> msm_dp_catalog_audio_header_type
>>> - write registers in an efficient way.

Yes, agreed to this point. It does certainly reduce the number of 
register reads/writes for each DP audio register and yes if we had known 
earlier that this was not needed, would have done it the same way.

>>> - if we ever have a set of functions to handle DP infoframes (like we
>>> do for HDMI), make the MSM DP driver ready to be converted to such
>>> functions.
>>

Yes I get where this change came from. For any infoframe, we have 
similar logic of doing a pack and then writing at once. So I was never 
opposed to this part. I was trying to mostly figure out where the 
read-modify-write came from in the first place and whether there is any 
impact of dropping that.

>>
>> The only reason the current driver needed to go through the catalog map
>> was that it was trying to write one header at a time. And in the
>> registers, 2 headers are mapped to one register. So a map was needed. I
>> do not know the reason for breaking up the writes into one header at a
>> time like I already mentioned so I am trying to gather that info.
>> Without knowing the reason it might seem useless but its my duty to make
>> sure nothing was overlooked.
> 
> Sure!
> 

Ok, so I was finally able to trace down the history of why we did it 
this way and it goes back almost 6 years so took me a while. Its just 
that the pre-silicon validation sequences had a read-modify-write (which 
they do even today) so the current software was just reflecting that.

Functionally however, I have confirmed that we do not need to do that. 
So, I am fine with this change but will first close the discussion on 
patch 5 as this patch tried to do multiple things, so have to close one 
topic and then get to the other to finally ack this change.

>>
>>
>>
>>>
>>>>
>>>>>
>>>>>     static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
>>>>>     {
>>>>>         struct msm_dp_catalog *catalog = audio->catalog;
>>>>> -     u32 value, new_value;
>>>>> -     u8 parity_byte;
>>>>> -
>>>>> -     /* Config header and parity byte 1 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     new_value = 0x1;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     /* Config header and parity byte 2 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     new_value = 0x17;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     /* Config header and parity byte 3 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
>>>>> -
>>>>> -     new_value = (0x0 | (0x11 << 2));
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
>>>>> +     struct dp_sdp_header sdp_hdr = {
>>>>> +             .HB0 = 0x00,
>>>>> +             .HB1 = 0x01,
>>>>> +             .HB2 = 0x17,
>>>>> +             .HB3 = 0x0 | (0x11 << 2),
>>>>> +     };
>>>>> +     u32 header[2];
>>>>> +
>>>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>>>> +
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_0, header[0]);
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_TIMESTAMP_1, header[1]);
>>>>>     }
>>>>>
>>>>>     static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
>>>>>     {
>>>>>         struct msm_dp_catalog *catalog = audio->catalog;
>>>>> -     u32 value, new_value;
>>>>> -     u8 parity_byte;
>>>>> -
>>>>> -     /* Config header and parity byte 1 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     new_value = 0x84;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     /* Config header and parity byte 2 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     new_value = 0x1b;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     /* Config header and parity byte 3 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
>>>>> -
>>>>> -     new_value = (0x0 | (0x11 << 2));
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     new_value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
>>>>> +     struct dp_sdp_header sdp_hdr = {
>>>>> +             .HB0 = 0x00,
>>>>> +             .HB1 = 0x84,
>>>>> +             .HB2 = 0x1b,
>>>>> +             .HB3 = 0x0 | (0x11 << 2),
>>>>> +     };
>>>>> +     u32 header[2];
>>>>> +
>>>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>>>> +
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_0, header[0]);
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_INFOFRAME_1, header[1]);
>>>>>     }
>>>>>
>>>>>     static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
>>>>>     {
>>>>>         struct msm_dp_catalog *catalog = audio->catalog;
>>>>> -     u32 value, new_value;
>>>>> -     u8 parity_byte;
>>>>> -
>>>>> -     /* Config header and parity byte 1 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     new_value = 0x05;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     /* Config header and parity byte 2 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     new_value = 0x0F;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     /* Config header and parity byte 3 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
>>>>> -
>>>>> -     new_value = 0x0;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_3_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_3_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
>>>>> +     struct dp_sdp_header sdp_hdr = {
>>>>> +             .HB0 = 0x00,
>>>>> +             .HB1 = 0x05,
>>>>> +             .HB2 = 0x0f,
>>>>> +             .HB3 = 0x00,
>>>>> +     };
>>>>> +     u32 header[2];
>>>>> +
>>>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>>>> +
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_0, header[0]);
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_COPYMANAGEMENT_1, header[1]);
>>>>>     }
>>>>>
>>>>>     static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
>>>>>     {
>>>>>         struct msm_dp_catalog *catalog = audio->catalog;
>>>>> -     u32 value, new_value;
>>>>> -     u8 parity_byte;
>>>>> -
>>>>> -     /* Config header and parity byte 1 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     new_value = 0x06;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_1_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_1_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
>>>>> -
>>>>> -     /* Config header and parity byte 2 */
>>>>> -     value = msm_dp_audio_get_header(catalog,
>>>>> -                     DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
>>>>> -
>>>>> -     new_value = 0x0F;
>>>>> -     parity_byte = msm_dp_utils_calculate_parity(new_value);
>>>>> -     value |= ((new_value << HEADER_BYTE_2_BIT)
>>>>> -                     | (parity_byte << PARITY_BYTE_2_BIT));
>>>>> -     drm_dbg_dp(audio->drm_dev,
>>>>> -                     "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
>>>>> -                     value, parity_byte);
>>>>> -     msm_dp_audio_set_header(catalog, value,
>>>>> -             DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
>>>>> +     struct dp_sdp_header sdp_hdr = {
>>>>> +             .HB0 = 0x00,
>>>>> +             .HB1 = 0x06,
>>>>> +             .HB2 = 0x0f,
>>>>> +             .HB3 = 0x00,
>>>>> +     };
>>>>> +     u32 header[2];
>>>>> +     u32 reg;
>>>>> +
>>>>> +     /* XXX: is it necessary to preserve this field? */
>>>>> +     reg = msm_dp_read_link(catalog, MMSS_DP_AUDIO_ISRC_1);
>>>>> +     sdp_hdr.HB3 = FIELD_GET(HEADER_3_MASK, reg);
>>>>> +
>>>>> +     msm_dp_utils_pack_sdp_header(&sdp_hdr, header);
>>>>> +
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_0, header[0]);
>>>>> +     msm_dp_write_link(catalog, MMSS_DP_AUDIO_ISRC_1, header[1]);
>>>>>     }
>>>>>
>>>>>     static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
>>>>>
>>>
>>>
>>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-12 23:09         ` Dmitry Baryshkov
@ 2024-12-14 20:53           ` Abhinav Kumar
  2024-12-14 22:05             ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-14 20:53 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

Hi Dmitry

On 12/12/2024 3:09 PM, Dmitry Baryshkov wrote:
> On Thu, 12 Dec 2024 at 21:15, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 12/12/2024 12:52 AM, Dmitry Baryshkov wrote:
>>> On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>>>> Having I/O regions inside a msm_dp_catalog_private() results in extra
>>>>> layers of one-line wrappers for accessing the data. Move I/O region base
>>>>> and size to the globally visible struct msm_dp_catalog.
>>>>>
>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>     drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
>>>>>     drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
>>>>>     2 files changed, 197 insertions(+), 272 deletions(-)
>>>>>
>>>>
>>>>
>>>> Fundamentally, the whole point of catalog was that it needs to be the
>>>> only place where we want to access the registers. Thats how this really
>>>> started.
>>>>
>>>> This pre-dates my time with the DP driver but as I understand thats what
>>>> it was for.
>>>>
>>>> Basically separating out the logical abstraction vs actual register writes .
>>>>
>>>> If there are hardware sequence differences within the controller reset
>>>> OR any other register offsets which moved around, catalog should have
>>>> been able to absorb it without that spilling over to all the layers.
>>>>
>>>> So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
>>>>
>>>> Then the reset_ctrl op of the catalog should manage any controller
>>>> version differences within the reset sequence.
>>>
>>> The problem is that the register-level writes are usually not the best
>>> abstraction. So, instead of designing the code around dp_catalog I'd
>>> prefer to see actual hw / programming changes first.
>>>
>>
>> So thats the issue here. If we did end up with registers and sequences
>> different for controller versions, the ctrl layer was expected to just
>> call a reset() op for example similar to the DPU example you gave. And
>> as you rightly noted, the dpu_hw_xxx files only expose the ops based on
>> version and the upper layers were supposed to just call into the ops
>> without knowing the register level details. Thats pretty much what
>> dp_ctrl tried to do here. We did not want to expose all the register
>> defines in those layers. This series is doing exactly opposite of that.
> 
> We don't have the issue up to now, even though we support DP
> controllers since SDM845 up to SM8650 and X1E80100. The SDE driver has
> v200 vs v420 catalog files for PHY programming, the rest of the
> functions are common. So, for me it looks like a preparation for the
> imaginary case that didn't come to existence up to now.
> So, yes. I want to get rid of extra useless indirection and I want to
> expose register sequences in those layers.
> 

Yes because PHY programming is managed in the PHY driver today and does 
not go through catalog whereas in SDE driver it does, I do not have any 
other concrete example to give you which exists in the current code 
where sequence changes across chipset variants for DP controller and 
since I certainly cannot discuss how things can evolve moving forward, 
as usual, I have to accept it as one of those things which is not used 
today. So yes, I guess the register sequencing point changing across 
chipset variants, does not have a good example which I can really share.

But exposing register sequences within the same file, I am not too sure 
about that. For example, you can take a look at 
dp_catalog_panel_config_hdr in the SDE code OR even 
msm_dp_catalog_panel_enable_vsc_sdp in the current upstream code. Why 
should this entire sequence be exposed to the dp_panel layer?

For smaller functions which are one-liners the redirection seems 
redundant but when the sequence is bigger like in the examples I gave, 
the logical Vs register sequence separation grows. Thats where the 
dp_catalog came from.


>>
>>>>
>>>> We do not use or have catalog ops today so it looks redundant as we just
>>>> call the dp_catalog APIs directly but that was really the intention.
>>>>
>>>> Another reason which was behind this split but not applicable to current
>>>> upstream driver is that the AUX is part of the PHY driver in upstream
>>>> but in downstream, that remains a part of catalog and as we know the AUX
>>>> component keeps changing with chipsets especially the settings. That was
>>>> the reason of keeping catalog separate and the only place which should
>>>> deal with registers and not the entire DP driver.
>>>>
>>>> The second point seems not applicable to this driver but first point
>>>> still is. I do admit there is re-direction like ctrl->catalog
>>>> instead of just writing it within dp_ctrl itself but the redirection was
>>>> only because ctrl layers were not really meant to deal with the register
>>>> programming. So for example, now with patch 7 of this series every
>>>> register being written to i exposed in dp_ctrl.c and likewise for other
>>>> files. That seems unnecessary. Because if we do end up with some
>>>> variants which need separate registers written, then we will now have to
>>>> end up touching every file as opposed to only touching dp_catalog.
>>>
>>> Yes. I think that it's a bonus, not a problem. We end up touching the
>>> files that are actually changed, so we see what is happening. Quite
>>> frequently register changes are paired with the functionality changes.
>>>
>>
>> Not exactly. Why should dp_ctrl really know that some register offset or
>> some block shift happened for example. It only needs to know when to
>> reset the hardware and not how. Thats the separation getting broken with
>> this.
> 
> Yes. And I'm removing that separation very intentionally. If one is
> looking for AUX programming, they should be looking into dp_aux only,
> not dp_aux & dp_catalog. Likewise all audio code should be in
> dp_audio. By using dp_catalog we ended up with a very very very bad
> abstraction of msm_dp_catalog_audio_get_header() /
> msm_dp_catalog_audio_set_header() / enum
> msm_dp_catalog_audio_sdp_type. Just because reads & writes should go
> through the catalog.

No, I think this is where there is some correction needed. the 
get_header() / set_header() was done not because all writes need to go 
through catalog but because the audio headers were thought to be written 
only one header at a time and we had thought that read-modify-write had 
to be done to preserve the bytes. And when we have to do only one header 
at a time and because two headers map to one register, catalog had to 
end up managing an audio_map. Now, after checking where it came from as 
I commented on that patch, this requirement was not a functional one but 
was just trying to preserve the pre-silicon validation scripts sequence, 
this part of it can be dropped. So no need of get_header() / 
set_header() and an audio_map. Now all registers going through catalog 
is another thing which we are still discussing here.

> For dp_panel likewise there is no need to look into some other source
> file to follow the register sequences. It can all be contained within
> dp_panel.c, helping one to understand the code.
> 

> Last, but not least. Code complexity. dp_catalog.c consists of 1340
> lines, covering different submodules. It is hard to follow it in this
> way.
> 

Its just a question of spreading up the functions all over, not reducing 
code complexity. So yes, it reduces the file size of dp_catalog whereas 
increases that of others. Code complexity impact due to that is subjective.

>>
>>> For example (a very simple and dumb one), when designing code around
>>> dp_catalog you ended up adding separate _p1 handlers.
>>> Doing that from the data source point of view demands adding a stream_id param.
>>>
>>
>> I have not checked your comment on that series here but if your concern
> 
> This is really a bad cadence. I have provided most of the feedback
> almost a week ago.
> 

Yes, was a very tight week trying to enable upstream developers to land 
their platforms such as QCS615 by fixing platform specific dpu things 
and had the fixes cycle this week too so as a result my own feature took 
a bit of a hit this week :(

>> is stream_id should not be stored in the catalog but just passed, thats
>> fine, we can change it. stream_id as a param is needed anyway because
>> the register programming layer needs to know which offset to use. This
>> series is not mitigating that fact.
> 
> No, my concern was that you have been adding separate _p1() functions
> which are a duplicate of _p0() counterparts. When one looks at the
> dp_catalog.c it is logical: there are two different register areas, so
> there are two distinct sets of functions. If one starts looking from
> the dp_panel point of view, it's obvious that there should be a single
> msm_dp_write_stream() function which accepts stream_id and then
> multiplexes it to go to p0 or p1.
> 

Your multiplexing suggestion of adding a msm_dp_read_pn/msm_dp_write_pn 
by passing a stream_id can be done even with current dp_catalog intact 
as it will help reduce storing the stream_id in the dp_catalog. So its a 
valid suggestion and can be implemented even in the current code and not 
tied to the fact that register writing is done in dp_catalog or dp_panel.

>>
>>> In the DPU driver we also have version-related conditionals in the HW
>>> modules rather than pushing all data access to dpu_hw_catalog.c &
>>> counterparts.
>>
>> The dpu_hw_catalog.c and the dp_catalog.c are not the right files to
>> compare with each other. dp_catalog.c should be compared with
>> dpu_hw_xxx.c and as you noted, DPU version dependencies are handled in
>> those files only and not all over the files like what this series is doing.
> 
> Not really. dpu_encoder_phys_cmd_init() checks for the core_major_ver.
> Let me see if other files check for the version under the hood.
> 

Well, thats because only cmd mode panel cares about TE. No other files 
from what I checked.

> Also as you wrote, there are multiple dpu_hw_xxx.c files, each
> handling register issues on its own. We don't have a single file which
> keeps all such differences in one place.
> 

Thats because of the way the registers are laid our in the SW interface 
document aligns nicely with the file split we have in the DPU even when 
the first DPU post happened.

But I still dont think its a fair comparison.

If you really had to go deeper into this thought, then even dp_reg.h 
should be broken down into smaller headers because the offsets in 
dpu_hw_*** files are relevant only to those files but after this change 
all DP files must include dp_reg.h even though they will not be using 
all of the offsets. Since current code was already doing that, which it 
didnt have to as dp_Catalog was the only one writing all registers, this 
went unnoticed.


> Last, but not least, in the DPU driver there are actual differences
> between generations, which require different code paths. In the DP
> driver there are none.
> 
>>
>>> I think it's better to make DP driver reflect DPU rather than keeping
>>> a separate wrapper for no particular reason (note, DPU has hardware
>>> abstractions, but on a block level, not on a register level).
>>>
>>
>> Thats the issue here. DPU hardware blocks are arranged according to the
>> sub-blocks both in the software interface document and hence the code
>> matches it file-by-file. DP registers are grouped by clock domains and
>> the file separation we have today does not match that anyway. Hence
>> grouping link registers writes or pixel clock register writes into
>> dp_ctrl is also not correct that way. Let catalog handle that separation
>> internally which it already does.
> 
> I'd say, dp_panel, dp_audio and dp_link are already pretty
> self-contained. I was hoping to look at dp_display vs dp_drm later on,
> once the HPD issue gets resolved. Only dp_ctrl is not that logical
> from my point of view.
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-14 20:53           ` Abhinav Kumar
@ 2024-12-14 22:05             ` Dmitry Baryshkov
  2024-12-16 20:45               ` Abhinav Kumar
  0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-14 22:05 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Sat, 14 Dec 2024 at 22:53, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
> Hi Dmitry
>
> On 12/12/2024 3:09 PM, Dmitry Baryshkov wrote:
> > On Thu, 12 Dec 2024 at 21:15, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 12/12/2024 12:52 AM, Dmitry Baryshkov wrote:
> >>> On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> >>>>> Having I/O regions inside a msm_dp_catalog_private() results in extra
> >>>>> layers of one-line wrappers for accessing the data. Move I/O region base
> >>>>> and size to the globally visible struct msm_dp_catalog.
> >>>>>
> >>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>> ---
> >>>>>     drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
> >>>>>     drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
> >>>>>     2 files changed, 197 insertions(+), 272 deletions(-)
> >>>>>
> >>>>
> >>>>
> >>>> Fundamentally, the whole point of catalog was that it needs to be the
> >>>> only place where we want to access the registers. Thats how this really
> >>>> started.
> >>>>
> >>>> This pre-dates my time with the DP driver but as I understand thats what
> >>>> it was for.
> >>>>
> >>>> Basically separating out the logical abstraction vs actual register writes .
> >>>>
> >>>> If there are hardware sequence differences within the controller reset
> >>>> OR any other register offsets which moved around, catalog should have
> >>>> been able to absorb it without that spilling over to all the layers.
> >>>>
> >>>> So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
> >>>>
> >>>> Then the reset_ctrl op of the catalog should manage any controller
> >>>> version differences within the reset sequence.
> >>>
> >>> The problem is that the register-level writes are usually not the best
> >>> abstraction. So, instead of designing the code around dp_catalog I'd
> >>> prefer to see actual hw / programming changes first.
> >>>
> >>
> >> So thats the issue here. If we did end up with registers and sequences
> >> different for controller versions, the ctrl layer was expected to just
> >> call a reset() op for example similar to the DPU example you gave. And
> >> as you rightly noted, the dpu_hw_xxx files only expose the ops based on
> >> version and the upper layers were supposed to just call into the ops
> >> without knowing the register level details. Thats pretty much what
> >> dp_ctrl tried to do here. We did not want to expose all the register
> >> defines in those layers. This series is doing exactly opposite of that.
> >
> > We don't have the issue up to now, even though we support DP
> > controllers since SDM845 up to SM8650 and X1E80100. The SDE driver has
> > v200 vs v420 catalog files for PHY programming, the rest of the
> > functions are common. So, for me it looks like a preparation for the
> > imaginary case that didn't come to existence up to now.
> > So, yes. I want to get rid of extra useless indirection and I want to
> > expose register sequences in those layers.
> >
>
> Yes because PHY programming is managed in the PHY driver today and does
> not go through catalog whereas in SDE driver it does, I do not have any
> other concrete example to give you which exists in the current code
> where sequence changes across chipset variants for DP controller and
> since I certainly cannot discuss how things can evolve moving forward,
> as usual, I have to accept it as one of those things which is not used
> today. So yes, I guess the register sequencing point changing across
> chipset variants, does not have a good example which I can really share.
>
> But exposing register sequences within the same file, I am not too sure
> about that. For example, you can take a look at
> dp_catalog_panel_config_hdr in the SDE code OR even
> msm_dp_catalog_panel_enable_vsc_sdp in the current upstream code. Why
> should this entire sequence be exposed to the dp_panel layer?

Why not? The dp_catalog_panel_config_hdr() is a bit tough, we don't
implement similar functions currently. For
msm_dp_catalog_panel_enable_vsc_sdp() this is also a logical sequence:
configure GENERIC0, write the package to GENERIC0, indicate presence
of the VSC SDP. I really don't see why this should go to a separate
file.

> For smaller functions which are one-liners the redirection seems
> redundant but when the sequence is bigger like in the examples I gave,
> the logical Vs register sequence separation grows. Thats where the
> dp_catalog came from.
>
>
> >>
> >>>>
> >>>> We do not use or have catalog ops today so it looks redundant as we just
> >>>> call the dp_catalog APIs directly but that was really the intention.
> >>>>
> >>>> Another reason which was behind this split but not applicable to current
> >>>> upstream driver is that the AUX is part of the PHY driver in upstream
> >>>> but in downstream, that remains a part of catalog and as we know the AUX
> >>>> component keeps changing with chipsets especially the settings. That was
> >>>> the reason of keeping catalog separate and the only place which should
> >>>> deal with registers and not the entire DP driver.
> >>>>
> >>>> The second point seems not applicable to this driver but first point
> >>>> still is. I do admit there is re-direction like ctrl->catalog
> >>>> instead of just writing it within dp_ctrl itself but the redirection was
> >>>> only because ctrl layers were not really meant to deal with the register
> >>>> programming. So for example, now with patch 7 of this series every
> >>>> register being written to i exposed in dp_ctrl.c and likewise for other
> >>>> files. That seems unnecessary. Because if we do end up with some
> >>>> variants which need separate registers written, then we will now have to
> >>>> end up touching every file as opposed to only touching dp_catalog.
> >>>
> >>> Yes. I think that it's a bonus, not a problem. We end up touching the
> >>> files that are actually changed, so we see what is happening. Quite
> >>> frequently register changes are paired with the functionality changes.
> >>>
> >>
> >> Not exactly. Why should dp_ctrl really know that some register offset or
> >> some block shift happened for example. It only needs to know when to
> >> reset the hardware and not how. Thats the separation getting broken with
> >> this.
> >
> > Yes. And I'm removing that separation very intentionally. If one is
> > looking for AUX programming, they should be looking into dp_aux only,
> > not dp_aux & dp_catalog. Likewise all audio code should be in
> > dp_audio. By using dp_catalog we ended up with a very very very bad
> > abstraction of msm_dp_catalog_audio_get_header() /
> > msm_dp_catalog_audio_set_header() / enum
> > msm_dp_catalog_audio_sdp_type. Just because reads & writes should go
> > through the catalog.
>
> No, I think this is where there is some correction needed. the
> get_header() / set_header() was done not because all writes need to go
> through catalog but because the audio headers were thought to be written
> only one header at a time and we had thought that read-modify-write had
> to be done to preserve the bytes. And when we have to do only one header
> at a time and because two headers map to one register, catalog had to
> end up managing an audio_map. Now, after checking where it came from as
> I commented on that patch, this requirement was not a functional one but
> was just trying to preserve the pre-silicon validation scripts sequence,
> this part of it can be dropped. So no need of get_header() /
> set_header() and an audio_map. Now all registers going through catalog
> is another thing which we are still discussing here.

You've skipped the msm_dp_catalog_audio_sdp_type enum (which was
explicitly mentioned). It is an abstraction which in my opinion also
isn't required, but it clearly comes from dp_catalog.

>
> > For dp_panel likewise there is no need to look into some other source
> > file to follow the register sequences. It can all be contained within
> > dp_panel.c, helping one to understand the code.
> >
>
> > Last, but not least. Code complexity. dp_catalog.c consists of 1340
> > lines, covering different submodules. It is hard to follow it in this
> > way.
> >
>
> Its just a question of spreading up the functions all over, not reducing
> code complexity. So yes, it reduces the file size of dp_catalog whereas
> increases that of others. Code complexity impact due to that is subjective.

The main issue is that dp_catalog now contains unrelated sets of
functions. That's code complexity.

>
> >>
> >>> For example (a very simple and dumb one), when designing code around
> >>> dp_catalog you ended up adding separate _p1 handlers.
> >>> Doing that from the data source point of view demands adding a stream_id param.
> >>>
> >>
> >> I have not checked your comment on that series here but if your concern
> >
> > This is really a bad cadence. I have provided most of the feedback
> > almost a week ago.
> >
>
> Yes, was a very tight week trying to enable upstream developers to land
> their platforms such as QCS615 by fixing platform specific dpu things
> and had the fixes cycle this week too so as a result my own feature took
> a bit of a hit this week :(
>
> >> is stream_id should not be stored in the catalog but just passed, thats
> >> fine, we can change it. stream_id as a param is needed anyway because
> >> the register programming layer needs to know which offset to use. This
> >> series is not mitigating that fact.
> >
> > No, my concern was that you have been adding separate _p1() functions
> > which are a duplicate of _p0() counterparts. When one looks at the
> > dp_catalog.c it is logical: there are two different register areas, so
> > there are two distinct sets of functions. If one starts looking from
> > the dp_panel point of view, it's obvious that there should be a single
> > msm_dp_write_stream() function which accepts stream_id and then
> > multiplexes it to go to p0 or p1.
> >
>
> Your multiplexing suggestion of adding a msm_dp_read_pn/msm_dp_write_pn
> by passing a stream_id can be done even with current dp_catalog intact
> as it will help reduce storing the stream_id in the dp_catalog. So its a
> valid suggestion and can be implemented even in the current code and not
> tied to the fact that register writing is done in dp_catalog or dp_panel.

It can. The point was about the implementation logic, not about the possibility.

>
> >>
> >>> In the DPU driver we also have version-related conditionals in the HW
> >>> modules rather than pushing all data access to dpu_hw_catalog.c &
> >>> counterparts.
> >>
> >> The dpu_hw_catalog.c and the dp_catalog.c are not the right files to
> >> compare with each other. dp_catalog.c should be compared with
> >> dpu_hw_xxx.c and as you noted, DPU version dependencies are handled in
> >> those files only and not all over the files like what this series is doing.
> >
> > Not really. dpu_encoder_phys_cmd_init() checks for the core_major_ver.
> > Let me see if other files check for the version under the hood.
> >
>
> Well, thats because only cmd mode panel cares about TE. No other files
> from what I checked.

I've sent a series which refactors feature bits into core_major_ver.
Now HW revision is being checked inside dpu_encoder_phys_wb.c,
dpu_kms.c and dpu_rm.c. And I didn't refactor SSPP, which would bring
similar checks to dpu_plane.c and possibly dpu_vbif.c

>
> > Also as you wrote, there are multiple dpu_hw_xxx.c files, each
> > handling register issues on its own. We don't have a single file which
> > keeps all such differences in one place.
> >
>
> Thats because of the way the registers are laid our in the SW interface
> document aligns nicely with the file split we have in the DPU even when
> the first DPU post happened.
>
> But I still dont think its a fair comparison.
>
> If you really had to go deeper into this thought, then even dp_reg.h
> should be broken down into smaller headers because the offsets in
> dpu_hw_*** files are relevant only to those files but after this change
> all DP files must include dp_reg.h even though they will not be using
> all of the offsets. Since current code was already doing that, which it
> didnt have to as dp_Catalog was the only one writing all registers, this
> went unnoticed.

Well... I had a thought about reworking DP into using XML files to
describe registers. It will make it slightly cleaner and
self-documented, but it most likely will be a single file.

>
>
> > Last, but not least, in the DPU driver there are actual differences
> > between generations, which require different code paths. In the DP
> > driver there are none.
> >
> >>
> >>> I think it's better to make DP driver reflect DPU rather than keeping
> >>> a separate wrapper for no particular reason (note, DPU has hardware
> >>> abstractions, but on a block level, not on a register level).
> >>>
> >>
> >> Thats the issue here. DPU hardware blocks are arranged according to the
> >> sub-blocks both in the software interface document and hence the code
> >> matches it file-by-file. DP registers are grouped by clock domains and
> >> the file separation we have today does not match that anyway. Hence
> >> grouping link registers writes or pixel clock register writes into
> >> dp_ctrl is also not correct that way. Let catalog handle that separation
> >> internally which it already does.
> >
> > I'd say, dp_panel, dp_audio and dp_link are already pretty
> > self-contained. I was hoping to look at dp_display vs dp_drm later on,
> > once the HPD issue gets resolved. Only dp_ctrl is not that logical
> > from my point of view.
> >



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-14 22:05             ` Dmitry Baryshkov
@ 2024-12-16 20:45               ` Abhinav Kumar
  2024-12-16 23:24                 ` Dmitry Baryshkov
  0 siblings, 1 reply; 43+ messages in thread
From: Abhinav Kumar @ 2024-12-16 20:45 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel



On 12/14/2024 2:05 PM, Dmitry Baryshkov wrote:
> On Sat, 14 Dec 2024 at 22:53, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>> Hi Dmitry
>>
>> On 12/12/2024 3:09 PM, Dmitry Baryshkov wrote:
>>> On Thu, 12 Dec 2024 at 21:15, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 12/12/2024 12:52 AM, Dmitry Baryshkov wrote:
>>>>> On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
>>>>>>> Having I/O regions inside a msm_dp_catalog_private() results in extra
>>>>>>> layers of one-line wrappers for accessing the data. Move I/O region base
>>>>>>> and size to the globally visible struct msm_dp_catalog.
>>>>>>>
>>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>>> ---
>>>>>>>      drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
>>>>>>>      drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
>>>>>>>      2 files changed, 197 insertions(+), 272 deletions(-)
>>>>>>>
>>>>>>
>>>>>>
>>>>>> Fundamentally, the whole point of catalog was that it needs to be the
>>>>>> only place where we want to access the registers. Thats how this really
>>>>>> started.
>>>>>>
>>>>>> This pre-dates my time with the DP driver but as I understand thats what
>>>>>> it was for.
>>>>>>
>>>>>> Basically separating out the logical abstraction vs actual register writes .
>>>>>>
>>>>>> If there are hardware sequence differences within the controller reset
>>>>>> OR any other register offsets which moved around, catalog should have
>>>>>> been able to absorb it without that spilling over to all the layers.
>>>>>>
>>>>>> So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
>>>>>>
>>>>>> Then the reset_ctrl op of the catalog should manage any controller
>>>>>> version differences within the reset sequence.
>>>>>
>>>>> The problem is that the register-level writes are usually not the best
>>>>> abstraction. So, instead of designing the code around dp_catalog I'd
>>>>> prefer to see actual hw / programming changes first.
>>>>>
>>>>
>>>> So thats the issue here. If we did end up with registers and sequences
>>>> different for controller versions, the ctrl layer was expected to just
>>>> call a reset() op for example similar to the DPU example you gave. And
>>>> as you rightly noted, the dpu_hw_xxx files only expose the ops based on
>>>> version and the upper layers were supposed to just call into the ops
>>>> without knowing the register level details. Thats pretty much what
>>>> dp_ctrl tried to do here. We did not want to expose all the register
>>>> defines in those layers. This series is doing exactly opposite of that.
>>>
>>> We don't have the issue up to now, even though we support DP
>>> controllers since SDM845 up to SM8650 and X1E80100. The SDE driver has
>>> v200 vs v420 catalog files for PHY programming, the rest of the
>>> functions are common. So, for me it looks like a preparation for the
>>> imaginary case that didn't come to existence up to now.
>>> So, yes. I want to get rid of extra useless indirection and I want to
>>> expose register sequences in those layers.
>>>
>>
>> Yes because PHY programming is managed in the PHY driver today and does
>> not go through catalog whereas in SDE driver it does, I do not have any
>> other concrete example to give you which exists in the current code
>> where sequence changes across chipset variants for DP controller and
>> since I certainly cannot discuss how things can evolve moving forward,
>> as usual, I have to accept it as one of those things which is not used
>> today. So yes, I guess the register sequencing point changing across
>> chipset variants, does not have a good example which I can really share.
>>
>> But exposing register sequences within the same file, I am not too sure
>> about that. For example, you can take a look at
>> dp_catalog_panel_config_hdr in the SDE code OR even
>> msm_dp_catalog_panel_enable_vsc_sdp in the current upstream code. Why
>> should this entire sequence be exposed to the dp_panel layer?
> 
> Why not? The dp_catalog_panel_config_hdr() is a bit tough, we don't
> implement similar functions currently. For
> msm_dp_catalog_panel_enable_vsc_sdp() this is also a logical sequence:
> configure GENERIC0, write the package to GENERIC0, indicate presence
> of the VSC SDP. I really don't see why this should go to a separate
> file.
> 

We have to plan for hdr for sure. its not an imaginary use-case.

msm_dp_catalog_panel_enable_vsc_sdp() does a bunch of things, packing 
the size, programming the SDP and triggering the update. dp_panel does 
not need to know all these details.

There are many other examples. Take a look at 
msm_dp_catalog_ctrl_mainlink_ctrl(). from the dp_ctl standpoint, all it 
needs to know is it needs to program the mainlink_Ctrl() at some point, 
it really does not need to know the full sequence of doing that. Thats 
the abstraction getting lost with this.

>> For smaller functions which are one-liners the redirection seems
>> redundant but when the sequence is bigger like in the examples I gave,
>> the logical Vs register sequence separation grows. Thats where the
>> dp_catalog came from.
>>
>>
>>>>
>>>>>>
>>>>>> We do not use or have catalog ops today so it looks redundant as we just
>>>>>> call the dp_catalog APIs directly but that was really the intention.
>>>>>>
>>>>>> Another reason which was behind this split but not applicable to current
>>>>>> upstream driver is that the AUX is part of the PHY driver in upstream
>>>>>> but in downstream, that remains a part of catalog and as we know the AUX
>>>>>> component keeps changing with chipsets especially the settings. That was
>>>>>> the reason of keeping catalog separate and the only place which should
>>>>>> deal with registers and not the entire DP driver.
>>>>>>
>>>>>> The second point seems not applicable to this driver but first point
>>>>>> still is. I do admit there is re-direction like ctrl->catalog
>>>>>> instead of just writing it within dp_ctrl itself but the redirection was
>>>>>> only because ctrl layers were not really meant to deal with the register
>>>>>> programming. So for example, now with patch 7 of this series every
>>>>>> register being written to i exposed in dp_ctrl.c and likewise for other
>>>>>> files. That seems unnecessary. Because if we do end up with some
>>>>>> variants which need separate registers written, then we will now have to
>>>>>> end up touching every file as opposed to only touching dp_catalog.
>>>>>
>>>>> Yes. I think that it's a bonus, not a problem. We end up touching the
>>>>> files that are actually changed, so we see what is happening. Quite
>>>>> frequently register changes are paired with the functionality changes.
>>>>>
>>>>
>>>> Not exactly. Why should dp_ctrl really know that some register offset or
>>>> some block shift happened for example. It only needs to know when to
>>>> reset the hardware and not how. Thats the separation getting broken with
>>>> this.
>>>
>>> Yes. And I'm removing that separation very intentionally. If one is
>>> looking for AUX programming, they should be looking into dp_aux only,
>>> not dp_aux & dp_catalog. Likewise all audio code should be in
>>> dp_audio. By using dp_catalog we ended up with a very very very bad
>>> abstraction of msm_dp_catalog_audio_get_header() /
>>> msm_dp_catalog_audio_set_header() / enum
>>> msm_dp_catalog_audio_sdp_type. Just because reads & writes should go
>>> through the catalog.
>>
>> No, I think this is where there is some correction needed. the
>> get_header() / set_header() was done not because all writes need to go
>> through catalog but because the audio headers were thought to be written
>> only one header at a time and we had thought that read-modify-write had
>> to be done to preserve the bytes. And when we have to do only one header
>> at a time and because two headers map to one register, catalog had to
>> end up managing an audio_map. Now, after checking where it came from as
>> I commented on that patch, this requirement was not a functional one but
>> was just trying to preserve the pre-silicon validation scripts sequence,
>> this part of it can be dropped. So no need of get_header() /
>> set_header() and an audio_map. Now all registers going through catalog
>> is another thing which we are still discussing here.
> 
> You've skipped the msm_dp_catalog_audio_sdp_type enum (which was
> explicitly mentioned). It is an abstraction which in my opinion also
> isn't required, but it clearly comes from dp_catalog.
> 

msm_dp_catalog_audio_sdp_type was needed only till the map was needed as 
it was made with an intention of trying to re-use the sdp_map layout for 
different packets. So its still tied to the fact that we needed a map. 
After dropping the map, this can be dropped too as you already did.


>>
>>> For dp_panel likewise there is no need to look into some other source
>>> file to follow the register sequences. It can all be contained within
>>> dp_panel.c, helping one to understand the code.
>>>
>>
>>> Last, but not least. Code complexity. dp_catalog.c consists of 1340
>>> lines, covering different submodules. It is hard to follow it in this
>>> way.
>>>
>>
>> Its just a question of spreading up the functions all over, not reducing
>> code complexity. So yes, it reduces the file size of dp_catalog whereas
>> increases that of others. Code complexity impact due to that is subjective.
> 
> The main issue is that dp_catalog now contains unrelated sets of
> functions. That's code complexity.
> 

dp_catalog was never meant to be a place where we have related 
functions. It was supposed to provide the register space abstraction and 
hiding away the details from rest of the layers. Going by what you are 
saying even the APIs in dsi_host.c should be related but they are not 
because of the same reason. I think this series went too far in terms of 
what it was trying to achieve trying to clenaup even useful things. 
Audio map removal was a problem tied to the fact that that 
read-modify-write behavior was preserved. That was removed after we 
identified its background. No issues with that. but beyond that, this is 
too much of a rework. I will let other developers chime into this. But I 
am not too fond of this one.

>>
>>>>
>>>>> For example (a very simple and dumb one), when designing code around
>>>>> dp_catalog you ended up adding separate _p1 handlers.
>>>>> Doing that from the data source point of view demands adding a stream_id param.
>>>>>
>>>>
>>>> I have not checked your comment on that series here but if your concern
>>>
>>> This is really a bad cadence. I have provided most of the feedback
>>> almost a week ago.
>>>
>>
>> Yes, was a very tight week trying to enable upstream developers to land
>> their platforms such as QCS615 by fixing platform specific dpu things
>> and had the fixes cycle this week too so as a result my own feature took
>> a bit of a hit this week :(
>>
>>>> is stream_id should not be stored in the catalog but just passed, thats
>>>> fine, we can change it. stream_id as a param is needed anyway because
>>>> the register programming layer needs to know which offset to use. This
>>>> series is not mitigating that fact.
>>>
>>> No, my concern was that you have been adding separate _p1() functions
>>> which are a duplicate of _p0() counterparts. When one looks at the
>>> dp_catalog.c it is logical: there are two different register areas, so
>>> there are two distinct sets of functions. If one starts looking from
>>> the dp_panel point of view, it's obvious that there should be a single
>>> msm_dp_write_stream() function which accepts stream_id and then
>>> multiplexes it to go to p0 or p1.
>>>
>>
>> Your multiplexing suggestion of adding a msm_dp_read_pn/msm_dp_write_pn
>> by passing a stream_id can be done even with current dp_catalog intact
>> as it will help reduce storing the stream_id in the dp_catalog. So its a
>> valid suggestion and can be implemented even in the current code and not
>> tied to the fact that register writing is done in dp_catalog or dp_panel.
> 
> It can. The point was about the implementation logic, not about the possibility.
> 
>>
>>>>
>>>>> In the DPU driver we also have version-related conditionals in the HW
>>>>> modules rather than pushing all data access to dpu_hw_catalog.c &
>>>>> counterparts.
>>>>
>>>> The dpu_hw_catalog.c and the dp_catalog.c are not the right files to
>>>> compare with each other. dp_catalog.c should be compared with
>>>> dpu_hw_xxx.c and as you noted, DPU version dependencies are handled in
>>>> those files only and not all over the files like what this series is doing.
>>>
>>> Not really. dpu_encoder_phys_cmd_init() checks for the core_major_ver.
>>> Let me see if other files check for the version under the hood.
>>>
>>
>> Well, thats because only cmd mode panel cares about TE. No other files
>> from what I checked.
> 
> I've sent a series which refactors feature bits into core_major_ver.
> Now HW revision is being checked inside dpu_encoder_phys_wb.c,
> dpu_kms.c and dpu_rm.c. And I didn't refactor SSPP, which would bring
> similar checks to dpu_plane.c and possibly dpu_vbif.c
> 

We will evaluate it on its merits / demerits as usual and decide.

>>
>>> Also as you wrote, there are multiple dpu_hw_xxx.c files, each
>>> handling register issues on its own. We don't have a single file which
>>> keeps all such differences in one place.
>>>
>>
>> Thats because of the way the registers are laid our in the SW interface
>> document aligns nicely with the file split we have in the DPU even when
>> the first DPU post happened.
>>
>> But I still dont think its a fair comparison.
>>
>> If you really had to go deeper into this thought, then even dp_reg.h
>> should be broken down into smaller headers because the offsets in
>> dpu_hw_*** files are relevant only to those files but after this change
>> all DP files must include dp_reg.h even though they will not be using
>> all of the offsets. Since current code was already doing that, which it
>> didnt have to as dp_Catalog was the only one writing all registers, this
>> went unnoticed.
> 
> Well... I had a thought about reworking DP into using XML files to
> describe registers. It will make it slightly cleaner and
> self-documented, but it most likely will be a single file.
> 

It being in a single file is leaning towards the same model we have 
right now. If dp_regs.h is remaining one unified file, I dont see why 
dp_catalog can stay as well.

>>
>>
>>> Last, but not least, in the DPU driver there are actual differences
>>> between generations, which require different code paths. In the DP
>>> driver there are none.
>>>
>>>>
>>>>> I think it's better to make DP driver reflect DPU rather than keeping
>>>>> a separate wrapper for no particular reason (note, DPU has hardware
>>>>> abstractions, but on a block level, not on a register level).
>>>>>
>>>>
>>>> Thats the issue here. DPU hardware blocks are arranged according to the
>>>> sub-blocks both in the software interface document and hence the code
>>>> matches it file-by-file. DP registers are grouped by clock domains and
>>>> the file separation we have today does not match that anyway. Hence
>>>> grouping link registers writes or pixel clock register writes into
>>>> dp_ctrl is also not correct that way. Let catalog handle that separation
>>>> internally which it already does.
>>>
>>> I'd say, dp_panel, dp_audio and dp_link are already pretty
>>> self-contained. I was hoping to look at dp_display vs dp_drm later on,
>>> once the HPD issue gets resolved. Only dp_ctrl is not that logical
>>> from my point of view.
>>>

Not from the point of view of the register separation of what belongs 
where. Its just a subjective opinion of what belongs where. Different 
developers can view it differently.

> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private()
  2024-12-16 20:45               ` Abhinav Kumar
@ 2024-12-16 23:24                 ` Dmitry Baryshkov
  0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-16 23:24 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
	Paloma Arellano, Douglas Anderson, Stephen Boyd, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Mon, Dec 16, 2024 at 12:45:13PM -0800, Abhinav Kumar wrote:
> 
> 
> On 12/14/2024 2:05 PM, Dmitry Baryshkov wrote:
> > On Sat, 14 Dec 2024 at 22:53, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> > > 
> > > Hi Dmitry
> > > 
> > > On 12/12/2024 3:09 PM, Dmitry Baryshkov wrote:
> > > > On Thu, 12 Dec 2024 at 21:15, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > On 12/12/2024 12:52 AM, Dmitry Baryshkov wrote:
> > > > > > On Thu, 12 Dec 2024 at 04:59, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > On 12/11/2024 3:41 PM, Dmitry Baryshkov wrote:
> > > > > > > > Having I/O regions inside a msm_dp_catalog_private() results in extra
> > > > > > > > layers of one-line wrappers for accessing the data. Move I/O region base
> > > > > > > > and size to the globally visible struct msm_dp_catalog.
> > > > > > > > 
> > > > > > > > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > > > > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > > > > > > ---
> > > > > > > >      drivers/gpu/drm/msm/dp/dp_catalog.c | 457 +++++++++++++++---------------------
> > > > > > > >      drivers/gpu/drm/msm/dp/dp_catalog.h |  12 +
> > > > > > > >      2 files changed, 197 insertions(+), 272 deletions(-)
> > > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > Fundamentally, the whole point of catalog was that it needs to be the
> > > > > > > only place where we want to access the registers. Thats how this really
> > > > > > > started.
> > > > > > > 
> > > > > > > This pre-dates my time with the DP driver but as I understand thats what
> > > > > > > it was for.
> > > > > > > 
> > > > > > > Basically separating out the logical abstraction vs actual register writes .
> > > > > > > 
> > > > > > > If there are hardware sequence differences within the controller reset
> > > > > > > OR any other register offsets which moved around, catalog should have
> > > > > > > been able to absorb it without that spilling over to all the layers.
> > > > > > > 
> > > > > > > So for example, if we call dp_ctrl_reset() --> ctrl->catalog->reset_ctrl()
> > > > > > > 
> > > > > > > Then the reset_ctrl op of the catalog should manage any controller
> > > > > > > version differences within the reset sequence.
> > > > > > 
> > > > > > The problem is that the register-level writes are usually not the best
> > > > > > abstraction. So, instead of designing the code around dp_catalog I'd
> > > > > > prefer to see actual hw / programming changes first.
> > > > > > 
> > > > > 
> > > > > So thats the issue here. If we did end up with registers and sequences
> > > > > different for controller versions, the ctrl layer was expected to just
> > > > > call a reset() op for example similar to the DPU example you gave. And
> > > > > as you rightly noted, the dpu_hw_xxx files only expose the ops based on
> > > > > version and the upper layers were supposed to just call into the ops
> > > > > without knowing the register level details. Thats pretty much what
> > > > > dp_ctrl tried to do here. We did not want to expose all the register
> > > > > defines in those layers. This series is doing exactly opposite of that.
> > > > 
> > > > We don't have the issue up to now, even though we support DP
> > > > controllers since SDM845 up to SM8650 and X1E80100. The SDE driver has
> > > > v200 vs v420 catalog files for PHY programming, the rest of the
> > > > functions are common. So, for me it looks like a preparation for the
> > > > imaginary case that didn't come to existence up to now.
> > > > So, yes. I want to get rid of extra useless indirection and I want to
> > > > expose register sequences in those layers.
> > > > 
> > > 
> > > Yes because PHY programming is managed in the PHY driver today and does
> > > not go through catalog whereas in SDE driver it does, I do not have any
> > > other concrete example to give you which exists in the current code
> > > where sequence changes across chipset variants for DP controller and
> > > since I certainly cannot discuss how things can evolve moving forward,
> > > as usual, I have to accept it as one of those things which is not used
> > > today. So yes, I guess the register sequencing point changing across
> > > chipset variants, does not have a good example which I can really share.
> > > 
> > > But exposing register sequences within the same file, I am not too sure
> > > about that. For example, you can take a look at
> > > dp_catalog_panel_config_hdr in the SDE code OR even
> > > msm_dp_catalog_panel_enable_vsc_sdp in the current upstream code. Why
> > > should this entire sequence be exposed to the dp_panel layer?
> > 
> > Why not? The dp_catalog_panel_config_hdr() is a bit tough, we don't
> > implement similar functions currently. For
> > msm_dp_catalog_panel_enable_vsc_sdp() this is also a logical sequence:
> > configure GENERIC0, write the package to GENERIC0, indicate presence
> > of the VSC SDP. I really don't see why this should go to a separate
> > file.
> > 
> 
> We have to plan for hdr for sure. its not an imaginary use-case.
> 
> msm_dp_catalog_panel_enable_vsc_sdp() does a bunch of things, packing the
> size, programming the SDP and triggering the update. dp_panel does not need
> to know all these details.
> 
> There are many other examples. Take a look at
> msm_dp_catalog_ctrl_mainlink_ctrl(). from the dp_ctl standpoint, all it
> needs to know is it needs to program the mainlink_Ctrl() at some point, it
> really does not need to know the full sequence of doing that. Thats the
> abstraction getting lost with this.
> 
> > > For smaller functions which are one-liners the redirection seems
> > > redundant but when the sequence is bigger like in the examples I gave,
> > > the logical Vs register sequence separation grows. Thats where the
> > > dp_catalog came from.
> > > 
> > > 
> > > > > 
> > > > > > > 
> > > > > > > We do not use or have catalog ops today so it looks redundant as we just
> > > > > > > call the dp_catalog APIs directly but that was really the intention.
> > > > > > > 
> > > > > > > Another reason which was behind this split but not applicable to current
> > > > > > > upstream driver is that the AUX is part of the PHY driver in upstream
> > > > > > > but in downstream, that remains a part of catalog and as we know the AUX
> > > > > > > component keeps changing with chipsets especially the settings. That was
> > > > > > > the reason of keeping catalog separate and the only place which should
> > > > > > > deal with registers and not the entire DP driver.
> > > > > > > 
> > > > > > > The second point seems not applicable to this driver but first point
> > > > > > > still is. I do admit there is re-direction like ctrl->catalog
> > > > > > > instead of just writing it within dp_ctrl itself but the redirection was
> > > > > > > only because ctrl layers were not really meant to deal with the register
> > > > > > > programming. So for example, now with patch 7 of this series every
> > > > > > > register being written to i exposed in dp_ctrl.c and likewise for other
> > > > > > > files. That seems unnecessary. Because if we do end up with some
> > > > > > > variants which need separate registers written, then we will now have to
> > > > > > > end up touching every file as opposed to only touching dp_catalog.
> > > > > > 
> > > > > > Yes. I think that it's a bonus, not a problem. We end up touching the
> > > > > > files that are actually changed, so we see what is happening. Quite
> > > > > > frequently register changes are paired with the functionality changes.
> > > > > > 
> > > > > 
> > > > > Not exactly. Why should dp_ctrl really know that some register offset or
> > > > > some block shift happened for example. It only needs to know when to
> > > > > reset the hardware and not how. Thats the separation getting broken with
> > > > > this.
> > > > 
> > > > Yes. And I'm removing that separation very intentionally. If one is
> > > > looking for AUX programming, they should be looking into dp_aux only,
> > > > not dp_aux & dp_catalog. Likewise all audio code should be in
> > > > dp_audio. By using dp_catalog we ended up with a very very very bad
> > > > abstraction of msm_dp_catalog_audio_get_header() /
> > > > msm_dp_catalog_audio_set_header() / enum
> > > > msm_dp_catalog_audio_sdp_type. Just because reads & writes should go
> > > > through the catalog.
> > > 
> > > No, I think this is where there is some correction needed. the
> > > get_header() / set_header() was done not because all writes need to go
> > > through catalog but because the audio headers were thought to be written
> > > only one header at a time and we had thought that read-modify-write had
> > > to be done to preserve the bytes. And when we have to do only one header
> > > at a time and because two headers map to one register, catalog had to
> > > end up managing an audio_map. Now, after checking where it came from as
> > > I commented on that patch, this requirement was not a functional one but
> > > was just trying to preserve the pre-silicon validation scripts sequence,
> > > this part of it can be dropped. So no need of get_header() /
> > > set_header() and an audio_map. Now all registers going through catalog
> > > is another thing which we are still discussing here.
> > 
> > You've skipped the msm_dp_catalog_audio_sdp_type enum (which was
> > explicitly mentioned). It is an abstraction which in my opinion also
> > isn't required, but it clearly comes from dp_catalog.
> > 
> 
> msm_dp_catalog_audio_sdp_type was needed only till the map was needed as it
> was made with an intention of trying to re-use the sdp_map layout for
> different packets. So its still tied to the fact that we needed a map. After
> dropping the map, this can be dropped too as you already did.

I'm not sure if I understood what you've meant by the sdp_map layout
re-use.

> 
> 
> > > 
> > > > For dp_panel likewise there is no need to look into some other source
> > > > file to follow the register sequences. It can all be contained within
> > > > dp_panel.c, helping one to understand the code.
> > > > 
> > > 
> > > > Last, but not least. Code complexity. dp_catalog.c consists of 1340
> > > > lines, covering different submodules. It is hard to follow it in this
> > > > way.
> > > > 
> > > 
> > > Its just a question of spreading up the functions all over, not reducing
> > > code complexity. So yes, it reduces the file size of dp_catalog whereas
> > > increases that of others. Code complexity impact due to that is subjective.
> > 
> > The main issue is that dp_catalog now contains unrelated sets of
> > functions. That's code complexity.
> > 
> 
> dp_catalog was never meant to be a place where we have related functions. It
> was supposed to provide the register space abstraction and hiding away the
> details from rest of the layers. Going by what you are saying even the APIs
> in dsi_host.c should be related but they are not because of the same reason.
> I think this series went too far in terms of what it was trying to achieve
> trying to clenaup even useful things. Audio map removal was a problem tied
> to the fact that that read-modify-write behavior was preserved. That was
> removed after we identified its background. No issues with that. but beyond
> that, this is too much of a rework. I will let other developers chime into
> this. But I am not too fond of this one.

Sure. It seems the important parts have been reviewed in the next
iteration, so we can land those. Stephen, one of DP reviewers / expers,
seems to like the remaining patches.

> 
> > > 
> > > > > 
> > > > > > For example (a very simple and dumb one), when designing code around
> > > > > > dp_catalog you ended up adding separate _p1 handlers.
> > > > > > Doing that from the data source point of view demands adding a stream_id param.
> > > > > > 
> > > > > 
> > > > > I have not checked your comment on that series here but if your concern
> > > > 
> > > > This is really a bad cadence. I have provided most of the feedback
> > > > almost a week ago.
> > > > 
> > > 
> > > Yes, was a very tight week trying to enable upstream developers to land
> > > their platforms such as QCS615 by fixing platform specific dpu things
> > > and had the fixes cycle this week too so as a result my own feature took
> > > a bit of a hit this week :(
> > > 
> > > > > is stream_id should not be stored in the catalog but just passed, thats
> > > > > fine, we can change it. stream_id as a param is needed anyway because
> > > > > the register programming layer needs to know which offset to use. This
> > > > > series is not mitigating that fact.
> > > > 
> > > > No, my concern was that you have been adding separate _p1() functions
> > > > which are a duplicate of _p0() counterparts. When one looks at the
> > > > dp_catalog.c it is logical: there are two different register areas, so
> > > > there are two distinct sets of functions. If one starts looking from
> > > > the dp_panel point of view, it's obvious that there should be a single
> > > > msm_dp_write_stream() function which accepts stream_id and then
> > > > multiplexes it to go to p0 or p1.
> > > > 
> > > 
> > > Your multiplexing suggestion of adding a msm_dp_read_pn/msm_dp_write_pn
> > > by passing a stream_id can be done even with current dp_catalog intact
> > > as it will help reduce storing the stream_id in the dp_catalog. So its a
> > > valid suggestion and can be implemented even in the current code and not
> > > tied to the fact that register writing is done in dp_catalog or dp_panel.
> > 
> > It can. The point was about the implementation logic, not about the possibility.
> > 
> > > 
> > > > > 
> > > > > > In the DPU driver we also have version-related conditionals in the HW
> > > > > > modules rather than pushing all data access to dpu_hw_catalog.c &
> > > > > > counterparts.
> > > > > 
> > > > > The dpu_hw_catalog.c and the dp_catalog.c are not the right files to
> > > > > compare with each other. dp_catalog.c should be compared with
> > > > > dpu_hw_xxx.c and as you noted, DPU version dependencies are handled in
> > > > > those files only and not all over the files like what this series is doing.
> > > > 
> > > > Not really. dpu_encoder_phys_cmd_init() checks for the core_major_ver.
> > > > Let me see if other files check for the version under the hood.
> > > > 
> > > 
> > > Well, thats because only cmd mode panel cares about TE. No other files
> > > from what I checked.
> > 
> > I've sent a series which refactors feature bits into core_major_ver.
> > Now HW revision is being checked inside dpu_encoder_phys_wb.c,
> > dpu_kms.c and dpu_rm.c. And I didn't refactor SSPP, which would bring
> > similar checks to dpu_plane.c and possibly dpu_vbif.c
> > 
> 
> We will evaluate it on its merits / demerits as usual and decide.

Sure :-)

> 
> > > 
> > > > Also as you wrote, there are multiple dpu_hw_xxx.c files, each
> > > > handling register issues on its own. We don't have a single file which
> > > > keeps all such differences in one place.
> > > > 
> > > 
> > > Thats because of the way the registers are laid our in the SW interface
> > > document aligns nicely with the file split we have in the DPU even when
> > > the first DPU post happened.
> > > 
> > > But I still dont think its a fair comparison.
> > > 
> > > If you really had to go deeper into this thought, then even dp_reg.h
> > > should be broken down into smaller headers because the offsets in
> > > dpu_hw_*** files are relevant only to those files but after this change
> > > all DP files must include dp_reg.h even though they will not be using
> > > all of the offsets. Since current code was already doing that, which it
> > > didnt have to as dp_Catalog was the only one writing all registers, this
> > > went unnoticed.
> > 
> > Well... I had a thought about reworking DP into using XML files to
> > describe registers. It will make it slightly cleaner and
> > self-documented, but it most likely will be a single file.
> > 
> 
> It being in a single file is leaning towards the same model we have right
> now. If dp_regs.h is remaining one unified file, I dont see why dp_catalog
> can stay as well.

It is typical to have a single file with the full register information.
MDP5 for example also has a single register file.

> 
> > > 
> > > 
> > > > Last, but not least, in the DPU driver there are actual differences
> > > > between generations, which require different code paths. In the DP
> > > > driver there are none.
> > > > 
> > > > > 
> > > > > > I think it's better to make DP driver reflect DPU rather than keeping
> > > > > > a separate wrapper for no particular reason (note, DPU has hardware
> > > > > > abstractions, but on a block level, not on a register level).
> > > > > > 
> > > > > 
> > > > > Thats the issue here. DPU hardware blocks are arranged according to the
> > > > > sub-blocks both in the software interface document and hence the code
> > > > > matches it file-by-file. DP registers are grouped by clock domains and
> > > > > the file separation we have today does not match that anyway. Hence
> > > > > grouping link registers writes or pixel clock register writes into
> > > > > dp_ctrl is also not correct that way. Let catalog handle that separation
> > > > > internally which it already does.
> > > > 
> > > > I'd say, dp_panel, dp_audio and dp_link are already pretty
> > > > self-contained. I was hoping to look at dp_display vs dp_drm later on,
> > > > once the HPD issue gets resolved. Only dp_ctrl is not that logical
> > > > from my point of view.
> > > > 
> 
> Not from the point of view of the register separation of what belongs where.
> Its just a subjective opinion of what belongs where. Different developers
> can view it differently.

Even from the register separation point of view: it's better to separate
the AUX and p0/p1 functions rather than keeping them in the dp_catalog.c
together with the rest of the unrelated functions.

Note, that dp_link.c also uses dp_reg.h though it doesn't use dp_catalog
at all.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2024-12-16 23:24 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-11 23:41 [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 01/14] drm/msm/dp: set safe_to_exit_level before printing it Dmitry Baryshkov
2024-12-12  1:14   ` Abhinav Kumar
2024-12-12  8:58     ` Dmitry Baryshkov
2024-12-12 18:31       ` Abhinav Kumar
2024-12-12 18:52         ` Abhinav Kumar
2024-12-12 23:09           ` Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 02/14] drm/msm/dp: fix msm_dp_utils_pack_sdp_header interface Dmitry Baryshkov
2024-12-12  1:23   ` Abhinav Kumar
2024-12-11 23:41 ` [PATCH v3 03/14] drm/msm/dp: drop msm_dp_panel_dump_regs() and msm_dp_catalog_dump_regs() Dmitry Baryshkov
2024-12-12  1:13   ` Abhinav Kumar
2024-12-11 23:41 ` [PATCH v3 04/14] drm/msm/dp: pull I/O data out of msm_dp_catalog_private() Dmitry Baryshkov
2024-12-12  2:59   ` Abhinav Kumar
2024-12-12  8:52     ` Dmitry Baryshkov
2024-12-12 19:15       ` Abhinav Kumar
2024-12-12 23:09         ` Dmitry Baryshkov
2024-12-14 20:53           ` Abhinav Kumar
2024-12-14 22:05             ` Dmitry Baryshkov
2024-12-16 20:45               ` Abhinav Kumar
2024-12-16 23:24                 ` Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 05/14] drm/msm/dp: move I/O functions to global header Dmitry Baryshkov
2024-12-12 20:26   ` Stephen Boyd
2024-12-11 23:41 ` [PATCH v3 06/14] drm/msm/dp: move/inline AUX register functions Dmitry Baryshkov
2024-12-12 20:26   ` Stephen Boyd
2024-12-11 23:41 ` [PATCH v3 07/14] drm/msm/dp: move/inline ctrl " Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 08/14] drm/msm/dp: move/inline panel related functions Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 09/14] drm/msm/dp: use msm_dp_utils_pack_sdp_header() for audio packets Dmitry Baryshkov
2024-12-12  3:12   ` Abhinav Kumar
2024-12-12  8:53     ` Dmitry Baryshkov
2024-12-12 21:41   ` Abhinav Kumar
2024-12-12 22:28     ` Dmitry Baryshkov
2024-12-12 23:53       ` Abhinav Kumar
2024-12-13  0:28         ` Dmitry Baryshkov
2024-12-14 18:02           ` Abhinav Kumar
2024-12-11 23:41 ` [PATCH v3 10/14] drm/msm/dp: drop obsolete audio headers access through catalog Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 11/14] drm/msm/dp: move/inline audio related functions Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 12/14] drm/msm/dp: move more AUX functions to dp_aux.c Dmitry Baryshkov
2024-12-11 23:41 ` [PATCH v3 13/14] drm/msm/dp: drop struct msm_dp_panel_in Dmitry Baryshkov
2024-12-12  3:26   ` Abhinav Kumar
2024-12-12  8:53     ` Dmitry Baryshkov
2024-12-12 18:56       ` Abhinav Kumar
2024-12-11 23:41 ` [PATCH v3 14/14] drm/msm/dp: move interrupt handling to dp_ctrl Dmitry Baryshkov
2024-12-12 20:27 ` [PATCH v3 00/14] drm/msm/dp: perform misc cleanups Stephen Boyd

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox