Skip to contentSkip to conversation

Add support for DisplayPort driver on SnapDragon 845

PATCH In review Chandan Uddaraju 8 participants 20 messages Oct 10, 2018 – Mar 10, 2019 6 messages not in the archive Page 2 of 3

Subsystems (5)
lore
Share & tools
lore
#12 lore raw

Re: [DPU PATCH 2/3] drm/msm/dp: add displayPort driver support

In reply to Sean Paul
Quoted 9 lines · Sean Paul
Quoted 7 lines · Chandan Uddaraju

Add the needed displayPort files to enable DP driver on msm target.

"dp_display" module is the main module that calls into other sub-modules. "dp_drm" file represents the interface between DRM framework and DP driver.

Hello Sean,
I had few queries regarding your comments. Shared my queries below. Please share your feedback.

Quoted 540 lines

Hi Chandan,
A few themes which I've pointed out below, but want to call out at the top so it's obvious.

- Please remove all superfluous NULL checks at the beginning of functions.
Included in this is reflowing initialization of variables and
checking that
return types still make sense (ie: if a function's only error path is
the NULL
check, make it void).
- Please remove all of the new callbacks and just call functions directly. This
should also get rid of the _get/_put functions that allocate/set them
up
- Please consolidate state structs into one struct with a few substructs,
there's too much state right now.
- Please #define hardcoded values
- Instead of sprinkling wmb() everywhere, use readl/writel instead of *_relaxed
- There are a bunch of races that I found, please audit the code and remove
races with locks as necessary
- I tried to catch as much dead code as possible, please audit the rest for
unused structs/variables/functions/etc
- Use drm dp helper structs for link parameter storage

Quoted 67 lines
---
 drivers/gpu/drm/msm/Kconfig                 |    9 +
 drivers/gpu/drm/msm/Makefile                |   15 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c |  206 ++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h |   44 +
 drivers/gpu/drm/msm/dp/dp_aux.c             |  570 ++++++++++
 drivers/gpu/drm/msm/dp/dp_aux.h             |   44 +
 drivers/gpu/drm/msm/dp/dp_catalog.c         | 1188 
++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_catalog.h         |  144 +++
 drivers/gpu/drm/msm/dp/dp_ctrl.c            | 1475 
+++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_ctrl.h            |   50 +
 drivers/gpu/drm/msm/dp/dp_debug.c           |  507 +++++++++
 drivers/gpu/drm/msm/dp/dp_debug.h           |   81 ++
 drivers/gpu/drm/msm/dp/dp_display.c         |  977 +++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_display.h         |   55 +
 drivers/gpu/drm/msm/dp/dp_drm.c             |  542 ++++++++++
 drivers/gpu/drm/msm/dp/dp_drm.h             |   52 +
 drivers/gpu/drm/msm/dp/dp_extcon.c          |  400 +++++++
 drivers/gpu/drm/msm/dp/dp_extcon.h          |  111 ++
 drivers/gpu/drm/msm/dp/dp_link.c            | 1549 
+++++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_link.h            |  184 ++++
 drivers/gpu/drm/msm/dp/dp_panel.c           |  624 +++++++++++
 drivers/gpu/drm/msm/dp/dp_panel.h           |  121 +++
 drivers/gpu/drm/msm/dp/dp_parser.c          |  679 ++++++++++++
 drivers/gpu/drm/msm/dp/dp_parser.h          |  205 ++++
 drivers/gpu/drm/msm/dp/dp_power.c           |  599 +++++++++++
 drivers/gpu/drm/msm/dp/dp_power.h           |   57 +
 drivers/gpu/drm/msm/dp/dp_reg.h             |  357 ++++++
 drivers/gpu/drm/msm/msm_drv.c               |    2 +
 drivers/gpu/drm/msm/msm_drv.h               |   22 +
 include/drm/drm_dp_helper.h                 |   19 +
 30 files changed, 10887 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_display.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_display.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_drm.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_drm.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_extcon.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_extcon.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_link.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_link.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_panel.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_panel.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_parser.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_parser.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_power.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_power.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_reg.h
drivers/gpu/drm/msm/Kconfig +0 -0
index 843a9d4..c363f24 100644
@@ -49,6 +49,15 @@ config DRM_MSM_HDMI_HDCP
 	help
 	  Choose this option to enable HDCP state machine

drivers/gpu/drm/msm/Kconfig config DRM_MSM_HDMI_HDCP · line 60

Quoted 10 lines
drivers/gpu/drm/msm/Kconfig +9 -0
 
+config DRM_MSM_DP
+	bool "Enable DP support in MSM DRM driver"
+	depends on DRM_MSM
+	default n
+	help
+	  Compile in support for DP driver in msm drm
+	  driver. DP external display support is enabled
+	  through this config option. It can be primary or
+	  secondary display on device.

Why are these line lengths so short? You can go to 80 columns. Please also add an empty line here.

Quoted 16 lines
drivers/gpu/drm/msm/Kconfig +0 -0
 config DRM_MSM_DSI
 	bool "Enable DSI support in MSM DRM driver"
 	depends on DRM_MSM
drivers/gpu/drm/msm/Makefile +1 -0
index 19ab521..765a8d8 100644
@@ -2,6 +2,7 @@
 ccflags-y := -Idrivers/gpu/drm/msm
 ccflags-y += -Idrivers/gpu/drm/msm/disp/dpu1
 ccflags-$(CONFIG_DRM_MSM_DSI) += -Idrivers/gpu/drm/msm/dsi
+ccflags-$(CONFIG_DRM_MSM_DP) += -Idrivers/gpu/drm/msm/dp
 
 msm-y := \
 	adreno/adreno_device.o \

drivers/gpu/drm/msm/Makefile msm-y := \ · line 98

Quoted 6 lines
drivers/gpu/drm/msm/Makefile +2 -1
@@ -93,7 +94,19 @@ msm-y := \
 	msm_submitqueue.o
 
 msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
-			  disp/dpu1/dpu_dbg.o
+			  disp/dpu1/dpu_dbg.o \
+			  dp/dp_debug.o

Does this compile if CONFIG_DEBUG_FS is selected, but not CONFIG_DRM_MSM_DP?

drivers/gpu/drm/msm/Makefile msm-y := \ · line 109

Quoted 11 lines
drivers/gpu/drm/msm/Makefile +11 -0
+
+msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_extcon.o \
+	dp/dp_parser.o \
+	dp/dp_power.o \
+	dp/dp_catalog.o \
+	dp/dp_aux.o \
+	dp/dp_panel.o \
+	dp/dp_link.o \
+	dp/dp_ctrl.o \
+	dp/dp_display.o \
+	dp/dp_drm.o

The rest of the file has files in alphabetical order, this should too.

Quoted 20 lines
drivers/gpu/drm/msm/Makefile +0 -0
 msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
 msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +4 -0
index 790d39f..0f53a15 100644
@@ -14,10 +14,216 @@
 #include <linux/clk.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
 #include <linux/delay.h>
 
 #include "dpu_io_util.h"
 
+static struct resource *msm_dss_get_res_byname(struct platform_device 
 *pdev,
+					       unsigned int type,

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 35

Quoted 10 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +10 -0
+					       const char *name)
+{
+	struct resource *res = NULL;
+
+	res = platform_get_resource_byname(pdev, type, name);
+	if (!res)
+		DEV_ERR("%s: '%s' resource not found\n", __func__, name);
+
+	return res;
+} /* msm_dss_get_res_byname */

Why don't you just call platform_get_resource_byname directly?

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 41

Quoted 7 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +7 -0
+
+int msm_dss_ioremap_byname(struct platform_device *pdev,
+			   struct dss_io_data *io_data, const char *name)
+{
+	struct resource *res = NULL;
+
+	if (!pdev || !io_data) {

Given that we've been aggressively trying to get rid of these superfluous checks, I'm not thrilled that they're being re-introduced. Can you please go through the patch and remove all of the unnecessary checks?

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 50

Quoted 9 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +9 -0
+		DEV_ERR("%pS->%s: invalid input\n",
+			__builtin_return_address(0), __func__);
+		return -EINVAL;
+	}
+
+	res = msm_dss_get_res_byname(pdev, IORESOURCE_MEM, name);
+	if (!res) {
+		DEV_ERR("%pS->%s: '%s' msm_dss_get_res_byname failed\n",
+			__builtin_return_address(0), __func__, name);

Yet another error format :) Could we please stick with one of DPU_ERROR, DRM_ERROR, or DRM_DEV_ERROR?

Quoted 18 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +18 -0
+		return -ENODEV;
+	}
+
+	io_data->len = (u32)resource_size(res);
+	io_data->base = ioremap(res->start, io_data->len);
+	if (!io_data->base) {
+		DEV_ERR("%pS->%s: '%s' ioremap failed\n",
+			__builtin_return_address(0), __func__, name);
+		return -EIO;
+	}
+
+	return 0;
+} /* msm_dss_ioremap_byname */
+
+void msm_dss_iounmap(struct dss_io_data *io_data)
+{
+	if (!io_data) {
+		DEV_ERR("%pS->%s: invalid input\n",

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 78

Quoted 10 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +10 -0
+			__builtin_return_address(0), __func__);
+		return;
+	}
+
+	if (io_data->base) {
+		iounmap(io_data->base);
+		io_data->base = NULL;
+	}
+	io_data->len = 0;
+} /* msm_dss_iounmap */

These two functions are only used in dp_parser.c, why not just make them static functions there?

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 81

Quoted 3 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +3 -0
+
+int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
+			int num_vreg, int config)

This should be 2 functions, one for initialization and one for deinitializing, the 2 paths don't share any code, so there's no need to combine them.

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 93

Quoted 12 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +12 -0
+{
+	int i = 0, rc = 0;
+	struct dss_vreg *curr_vreg = NULL;
+	enum dss_vreg_type type;
+
+	if (!in_vreg || !num_vreg)
+		return rc;
+
+	if (config) {
+		for (i = 0; i < num_vreg; i++) {
+			curr_vreg = &in_vreg[i];
+			curr_vreg->vreg = regulator_get(dev,

Use devm_* please

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 95

Quoted 2 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +2 -0
+				curr_vreg->vreg_name);
+			rc = PTR_RET(curr_vreg->vreg);

PTR_RET is deprecated. The pattern for this is usually:

                        ptr = some_func();
                        if (IS_ERR_OR_NULL(ptr)) {
                                ...
                                rc = PTR_ERR(ptr);
                                goto fail_label:
                        }
Quoted 121 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +120 -0
+			if (rc) {
+				DEV_ERR("%pS->%s: %s get failed. rc=%d\n",
+					 __builtin_return_address(0), __func__,
+					 curr_vreg->vreg_name, rc);
+				curr_vreg->vreg = NULL;
+				goto vreg_get_fail;
+			}
+			type = (regulator_count_voltages(curr_vreg->vreg) > 0)
+					? DSS_REG_LDO : DSS_REG_VS;
+			if (type == DSS_REG_LDO) {
+				rc = regulator_set_voltage(
+					curr_vreg->vreg,
+					curr_vreg->min_voltage,
+					curr_vreg->max_voltage);
+				if (rc < 0) {
+					DEV_ERR("%pS->%s: %s set vltg fail\n",
+						__builtin_return_address(0),
+						__func__,
+						curr_vreg->vreg_name);
+					goto vreg_set_voltage_fail;
+				}
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--) {
+			curr_vreg = &in_vreg[i];
+			if (curr_vreg->vreg) {
+				type = (regulator_count_voltages(
+					curr_vreg->vreg) > 0)
+					? DSS_REG_LDO : DSS_REG_VS;
+				if (type == DSS_REG_LDO) {
+					regulator_set_voltage(curr_vreg->vreg,
+						0, curr_vreg->max_voltage);
+				}
+				regulator_put(curr_vreg->vreg);
+				curr_vreg->vreg = NULL;
+			}
+		}
+	}
+	return 0;
+
+vreg_unconfig:
+if (type == DSS_REG_LDO)
+	regulator_set_load(curr_vreg->vreg, 0);
+
+vreg_set_voltage_fail:
+	regulator_put(curr_vreg->vreg);
+	curr_vreg->vreg = NULL;
+
+vreg_get_fail:
+	for (i--; i >= 0; i--) {
+		curr_vreg = &in_vreg[i];
+		type = (regulator_count_voltages(curr_vreg->vreg) > 0)
+			? DSS_REG_LDO : DSS_REG_VS;
+		goto vreg_unconfig;
+	}
+	return rc;
+} /* msm_dss_config_vreg */
+
+int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int 
 enable)
+{
+	int i = 0, rc = 0;
+	bool need_sleep;
+
+	if (enable) {
+		for (i = 0; i < num_vreg; i++) {
+			rc = PTR_RET(in_vreg[i].vreg);
+			if (rc) {
+				DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
+					__builtin_return_address(0), __func__,
+					in_vreg[i].vreg_name, rc);
+				goto vreg_set_opt_mode_fail;
+			}
+			need_sleep = !regulator_is_enabled(in_vreg[i].vreg);
+			if (in_vreg[i].pre_on_sleep && need_sleep)
+				usleep_range(in_vreg[i].pre_on_sleep * 1000,
+					in_vreg[i].pre_on_sleep * 1000);
+			rc = regulator_set_load(in_vreg[i].vreg,
+				in_vreg[i].enable_load);
+			if (rc < 0) {
+				DEV_ERR("%pS->%s: %s set opt m fail\n",
+					__builtin_return_address(0), __func__,
+					in_vreg[i].vreg_name);
+				goto vreg_set_opt_mode_fail;
+			}
+			rc = regulator_enable(in_vreg[i].vreg);
+			if (in_vreg[i].post_on_sleep && need_sleep)
+				usleep_range(in_vreg[i].post_on_sleep * 1000,
+					in_vreg[i].post_on_sleep * 1000);
+			if (rc < 0) {
+				DEV_ERR("%pS->%s: %s enable failed\n",
+					__builtin_return_address(0), __func__,
+					in_vreg[i].vreg_name);
+				goto disable_vreg;
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--) {
+			if (in_vreg[i].pre_off_sleep)
+				usleep_range(in_vreg[i].pre_off_sleep * 1000,
+					in_vreg[i].pre_off_sleep * 1000);
+			regulator_set_load(in_vreg[i].vreg,
+				in_vreg[i].disable_load);
+			regulator_disable(in_vreg[i].vreg);
+			if (in_vreg[i].post_off_sleep)
+				usleep_range(in_vreg[i].post_off_sleep * 1000,
+					in_vreg[i].post_off_sleep * 1000);
+		}
+	}
+	return rc;
+
+disable_vreg:
+	regulator_set_load(in_vreg[i].vreg, in_vreg[i].disable_load);
+
+vreg_set_opt_mode_fail:
+	for (i--; i >= 0; i--) {
+		if (in_vreg[i].pre_off_sleep)
+			usleep_range(in_vreg[i].pre_off_sleep * 1000,
+				in_vreg[i].pre_off_sleep * 1000);
+		regulator_set_load(in_vreg[i].vreg,

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 225

Quoted 10 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +10 -0
+			in_vreg[i].disable_load);
+		regulator_disable(in_vreg[i].vreg);
+		if (in_vreg[i].post_off_sleep)
+			usleep_range(in_vreg[i].post_off_sleep * 1000,
+				in_vreg[i].post_off_sleep * 1000);
+	}
+
+	return rc;
+} /* msm_dss_enable_vreg */
+

Same question here, but with dp_power.

Quoted 17 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +1 -0
+
 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk)

{

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +0 -0
 	int i;
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +1 -0
index bc07381..524b394 100644
@@ -15,6 +15,7 @@
 
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/types.h>
 
 #define DEV_DBG(fmt, args...)   pr_debug(fmt, ##args)

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 29

Quoted 7 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
@@ -22,6 +23,39 @@
 #define DEV_WARN(fmt, args...)  pr_warn(fmt, ##args)
 #define DEV_ERR(fmt, args...)   pr_err(fmt, ##args)
 
+struct dss_io_data {
+	u32 len;
+	void __iomem *base;
+};

len isn't used anywhere, so this struct can go away. If the struct goes away, you can really simplify (or eliminate msm_dss_ioremap_byname())

Quoted 12 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +8 -0
+
+/*
+void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 
 debug);
+u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug);
+void dss_reg_dump(void __iomem *base, u32 len, const char *prefix, 
 u32 debug);
+
+#define DSS_REG_W_ND(io, offset, val)  dss_reg_w(io, offset, val, 
 false)
+#define DSS_REG_W(io, offset, val)     dss_reg_w(io, offset, val, 

true)

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 40

Quoted 3 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +3 -0
+#define DSS_REG_R_ND(io, offset)       dss_reg_r(io, offset, false)
+#define DSS_REG_R(io, offset)          dss_reg_r(io, offset, true)
+*/

None of the dss_reg_*/DSS_REG_* functions/macros are used. Please remove.

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 44

Quoted 4 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
+enum dss_vreg_type {
+	DSS_REG_LDO,
+	DSS_REG_VS,
+};

These are only used in msm_dss_config_vreg(). Please remove.

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 50

Quoted 6 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +6 -0
+
+struct dss_vreg {
+	struct regulator *vreg; /* vreg handle */
+	char vreg_name[32];
+	int min_voltage;
+	int max_voltage;

Can't we deduce these from the regulator subsystem with regulator_list_voltage()?

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 52

Quoted 2 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +2 -0
+	int enable_load;
+	int disable_load;

These are really a function of the dp device than the regulator.

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 56

Quoted 4 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
+	int pre_on_sleep;
+	int post_on_sleep;
+	int pre_off_sleep;
+	int post_off_sleep;

None of these sleep values are set? Also, shouldn't these constraints usually expressed/acted upon in the regulator driver?

Quoted 1 line

+};

So if we can remove all of the extra goop around the regulator, then we can get rid of dss_vreg.

Quoted 27 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +11 -0
+
 struct dss_gpio {
 	unsigned int gpio;
 	unsigned int value;
@@ -42,12 +76,22 @@ struct dss_clk {
 };
 
 struct dss_module_power {
+	unsigned int num_vreg;
+	struct dss_vreg *vreg_config;
 	unsigned int num_gpio;
 	struct dss_gpio *gpio_config;
 	unsigned int num_clk;
 	struct dss_clk *clk_config;
 };
 
+int msm_dss_ioremap_byname(struct platform_device *pdev,
+			   struct dss_io_data *io_data, const char *name);
+void msm_dss_iounmap(struct dss_io_data *io_data);
+
+int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
+			int num_vreg, int config);
+int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg,	int 
 enable);
+
 int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int 
 num_clk);
Quoted 1 line

void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);

Why are these msm_dss* functions in dpu_io_util.h?

drivers/gpu/drm/msm/dp/dp_aux.c

Quoted 7 lines

int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);

drivers/gpu/drm/msm/dp/dp_aux.c new file +0 -0
new file mode 100644
index 0000000..00b82c2
@@ -0,0 +1,570 @@

/snip

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +0 -0
new file mode 100644
index 0000000..0c300ed

/snip

Quoted 3 lines

I didn't really review the dp_aux.* files as-is. Please convert to using drm_dp_aux and I'll take another look.

Please correct me if I am wrong. Looks like you are suggesting to use most of the drm_dp_aux struct variable instead of what we have defined locally.

Quoted 1,411 lines
Quoted 23 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
new file mode 100644
index 0000000..5818612
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 24

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <drm/drm_dp_helper.h>
+
+#include "dp_catalog.h"
+#include "dp_reg.h"
+
+#define DP_GET_MSB(x)	(x >> 8)
+#define DP_GET_LSB(x)	(x & 0xff)

These aren't used anywhere

drivers/gpu/drm/msm/dp/dp_catalog.c line 27

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+
+#define dp_read(offset) readl_relaxed((offset))
+#define dp_write(offset, data) writel_relaxed((data), (offset))

These macros aren't useful. I think you'd be much better having a read_/write_ for the different io types, ie:

static inline u32 dp_read_audio(struct dp_catalog *catalog, u32 offset)

{
        return readl_relaxed(catalog->io->dp_link.base + offset);
}

Then you can remove a ton of boilerplate code below getting base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 29

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+#define dp_catalog_get_priv(x) { \

static inline struct dp_catalog_private *dp_catalog_get_priv(...)

{
        ...
}
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	struct dp_catalog *dp_catalog; \
+	dp_catalog = container_of(x, struct dp_catalog, x); \
+	catalog = container_of(dp_catalog, struct dp_catalog_private, \
+				dp_catalog); \
+}
+
+#define DP_INTERRUPT_STATUS1 \
+	(DP_INTR_AUX_I2C_DONE| \
+	DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
+	DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \

drivers/gpu/drm/msm/dp/dp_catalog.c line 49

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
+	DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
+
+#define DP_INTR_MASK1		(DP_INTERRUPT_STATUS1 << 2)
+
+#define DP_INTERRUPT_STATUS2 \
+	(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
+	DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
+
+#define DP_INTR_MASK2		(DP_INTERRUPT_STATUS2 << 2)

Can you please rename these to be consistent with each other? DP_INTERRUPT_STATUS2_MASK perhaps?

Quoted 23 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +23 -0
+
+static u8 const vm_pre_emphasis[4][4] = {
+	{0x00, 0x0B, 0x12, 0xFF},       /* pe0, 0 db */
+	{0x00, 0x0A, 0x12, 0xFF},       /* pe1, 3.5 db */
+	{0x00, 0x0C, 0xFF, 0xFF},       /* pe2, 6.0 db */
+	{0xFF, 0xFF, 0xFF, 0xFF}        /* pe3, 9.5 db */
+};
+
+/* voltage swing, 0.2v and 1.0v are not support */
+static u8 const vm_voltage_swing[4][4] = {
+	{0x07, 0x0F, 0x14, 0xFF}, /* sw0, 0.4v  */
+	{0x11, 0x1D, 0x1F, 0xFF}, /* sw1, 0.6 v */
+	{0x18, 0x1F, 0xFF, 0xFF}, /* sw1, 0.8 v */
+	{0xFF, 0xFF, 0xFF, 0xFF}  /* sw1, 1.2 v, optional */
+};
+
+/* audio related catalog functions */
+struct dp_catalog_private {
+	struct device *dev;
+	struct dp_io *io;
+
+	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
+	struct dp_catalog dp_catalog;

drivers/gpu/drm/msm/dp/dp_catalog.c line 82

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+};
+
+/* aux related catalog functions */
+static u32 dp_catalog_aux_read_data(struct dp_catalog_aux *aux)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");

And another logging type, please remove pr_* and use a DPU_/DRM_/DRM_DEV_ variant.

drivers/gpu/drm/msm/dp/dp_catalog.c line 91

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	return dp_read(base + DP_AUX_DATA);
+end:
+	return 0;

... or you could just return directly in the if above and remove the label :) Same comment applies below.

Also, probably shouldn't return 0 in an error case.

Then again, I'm guessing hitting the NULL case is likely impossible, so you can probably remove all of the machinery around checking !aux.

Quoted 77 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +43 -0
+}
+
+static int dp_catalog_aux_write_data(struct dp_catalog_aux *aux)
+{
+	int rc = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	dp_write(base + DP_AUX_DATA, aux->data);
+end:
+	return rc;
+}
+
+static int dp_catalog_aux_write_trans(struct dp_catalog_aux *aux)
+{
+	int rc = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	dp_write(base + DP_AUX_TRANS_CTRL, aux->data);
+end:
+	return rc;
+}
+
+static int dp_catalog_aux_clear_trans(struct dp_catalog_aux *aux, 

bool read)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +33 -0
+{
+	int rc = 0;
+	u32 data = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	if (read) {
+		data = dp_read(base + DP_AUX_TRANS_CTRL);
+		data &= ~BIT(9);
+		dp_write(base + DP_AUX_TRANS_CTRL, data);
+	} else {
+		dp_write(base + DP_AUX_TRANS_CTRL, 0);
+	}
+end:
+	return rc;
+}
+
+static void dp_catalog_aux_reset(struct dp_catalog_aux *aux)
+{
+	u32 aux_ctrl;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {

drivers/gpu/drm/msm/dp/dp_catalog.c line 177

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	aux_ctrl = dp_read(base + DP_AUX_CTRL);
+
+	aux_ctrl |= BIT(1);

What's BIT(1)? Can you please #define it?

drivers/gpu/drm/msm/dp/dp_catalog.c line 179

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_AUX_CTRL, aux_ctrl);
+	usleep_range(1000, 1010); /* h/w recommended delay */

10us diff is right on the line of enough delay to make usleep_range worth it. I'd recommend increasing to 100us to increase the chance of the scheduler being able to batch this wakeup with another.

drivers/gpu/drm/msm/dp/dp_catalog.c line 183

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+
+	aux_ctrl &= ~BIT(1);
+	dp_write(base + DP_AUX_CTRL, aux_ctrl);
+	wmb();

Can you just use writel for these cases instead of using _relaxed and then wmb()? This applies elsewhere too.

Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_aux_enable(struct dp_catalog_aux *aux, bool 

enable)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+{
+	u32 aux_ctrl;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		return;
+	}

drivers/gpu/drm/msm/dp/dp_catalog.c line 205

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	aux_ctrl = dp_read(base + DP_AUX_CTRL);
+
+	if (enable) {
+		dp_write(base + DP_TIMEOUT_COUNT, 0xffff);
+		dp_write(base + DP_AUX_LIMITS, 0xffff);
+		aux_ctrl |= BIT(0);

Please #define BIT(0)

Quoted 35 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +35 -0
+	} else {
+		aux_ctrl &= ~BIT(0);
+	}
+
+	dp_write(base + DP_AUX_CTRL, aux_ctrl);
+}
+
+static void dp_catalog_aux_update_cfg(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type)
+{
+	struct dp_catalog_private *catalog;
+	u32 new_index = 0, current_index = 0;
+
+	if (!aux || !cfg || (type >= PHY_AUX_CFG_MAX)) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+
+	current_index = cfg[type].current_index;
+	new_index = (current_index + 1) % cfg[type].cfg_cnt;
+	pr_debug("Updating %s from 0x%08x to 0x%08x\n",
+		dp_phy_aux_config_type_to_string(type),
+	cfg[type].lut[current_index], cfg[type].lut[new_index]);
+
+	dp_write(catalog->io->phy_io.base + cfg[type].offset,
+			cfg[type].lut[new_index]);
+	cfg[type].current_index = new_index;
+}
+
+static void dp_catalog_aux_setup(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg)
+{
+	struct dp_catalog_private *catalog;

drivers/gpu/drm/msm/dp/dp_catalog.c line 250

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	int i = 0;
+
+	if (!aux || !cfg) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+
+	dp_write(catalog->io->phy_io.base + DP_PHY_PD_CTL, 0x65);

What's 0x65? Please #define

drivers/gpu/drm/msm/dp/dp_catalog.c line 255

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	wmb(); /* make sure PD programming happened */
+
+	/* Turn on BIAS current for PHY/PLL */
+	dp_write(catalog->io->dp_pll_io.base +
+		QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1b);

Same here for 0x1b. I'm going to stop mentioning this, please audit the driver for other instances of hardcoded values (like this and the one at the end of this function) and break them out into meaningful #defines.

Quoted 125 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +11 -0
+
+	/* DP AUX CFG register programming */
+	for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
+		pr_debug("%s: offset=0x%08x, value=0x%08x\n",
+			dp_phy_aux_config_type_to_string(i),
+			cfg[i].offset, cfg[i].lut[cfg[i].current_index]);
+		dp_write(catalog->io->phy_io.base + cfg[i].offset,
+			cfg[i].lut[cfg[i].current_index]);
+	}
+
+	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_INTERRUPT_MASK, 

0x1F);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_aux_get_irq(struct dp_catalog_aux *aux, bool 

cmd_busy)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +23 -0
+{
+	u32 ack;
+	struct dp_catalog_private *catalog;
+	void __iomem *ahb_base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+	ahb_base = catalog->io->dp_ahb.base;
+
+	aux->isr = dp_read(ahb_base + DP_INTR_STATUS);
+	aux->isr &= ~DP_INTR_MASK1;
+	ack = aux->isr & DP_INTERRUPT_STATUS1;
+	ack <<= 1;
+	ack |= DP_INTR_MASK1;
+	dp_write(ahb_base + DP_INTR_STATUS, ack);
+}
+
+/* controller related catalog functions */
+static void dp_catalog_ctrl_update_transfer_unit(struct 

dp_catalog_ctrl *ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +18 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_VALID_BOUNDARY, ctrl->valid_boundary);
+	dp_write(base + DP_TU, ctrl->dp_tu);
+	dp_write(base + DP_VALID_BOUNDARY_2, ctrl->valid_boundary2);
+}
+
+static void dp_catalog_ctrl_state_ctrl(struct dp_catalog_ctrl *ctrl, 

u32 state)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_STATE_CTRL, state);
+}
+
+static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl, 

u32 cfg)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +18 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *link_base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	link_base = catalog->io->dp_link.base;
+
+	pr_debug("DP_CONFIGURATION_CTRL=0x%x\n", cfg);
+
+	dp_write(link_base + DP_CONFIGURATION_CTRL, cfg);
+}
+
+static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_LOGICAL2PHYSICAL_LANE_MAPPING, 0xe4);
+}
+
+static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +13 -0
+						bool enable)
+{
+	u32 mainlink_ctrl;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 383

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	if (enable) {
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000000);
+		wmb(); /* make sure mainlink is turned off before reset */
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000002);
+		wmb(); /* make sure mainlink entered reset */
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000000);
+		wmb(); /* make sure mainlink reset done */
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000001);
+		wmb(); /* make sure mainlink turned on */

Same comments here re: readl vs readl_relaxed + wmb

Please #define the bits you're setting.

Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +14 -0
+	} else {
+		mainlink_ctrl = dp_read(base + DP_MAINLINK_CTRL);
+		mainlink_ctrl &= ~BIT(0);
+		dp_write(base + DP_MAINLINK_CTRL, mainlink_ctrl);
+	}
+}
+
+static void dp_catalog_ctrl_config_misc(struct dp_catalog_ctrl *ctrl,
+					u32 cc, u32 tb)
+{
+	u32 misc_val;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 407

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	misc_val = dp_read(base + DP_MISC1_MISC0);
+	misc_val |= cc;

Should you mask this so it doesn't stomp areas it shouldn't?

drivers/gpu/drm/msm/dp/dp_catalog.c line 408

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	misc_val |= (tb << 5);

Parentheses are unnecessary

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	misc_val |= BIT(0); /* Configure clock to synchronous mode */
+
+	pr_debug("misc settings = 0x%x\n", misc_val);
+	dp_write(base + DP_MISC1_MISC0, misc_val);

drivers/gpu/drm/msm/dp/dp_catalog.c line 422

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+}
+
+static void dp_catalog_ctrl_config_msa(struct dp_catalog_ctrl *ctrl,
+					u32 rate, u32 stream_rate_khz,
+					bool fixed_nvid)
+{
+	u32 pixel_m, pixel_n;
+	u32 mvid, nvid;
+	u64 mvid_calc;
+	u32 const nvid_fixed = 0x8000;

You should pull this out into a #define in drm_dp_helper.h and use the new define in the i915 driver (in a separate patch) as well as here.

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +37 -0
+	u32 const link_rate_hbr2 = 540000;
+	u32 const link_rate_hbr3 = 810000;
+	struct dp_catalog_private *catalog;
+	void __iomem *base_cc, *base_ctrl;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	if (fixed_nvid) {
+		pr_debug("use fixed NVID=0x%x\n", nvid_fixed);
+		nvid = nvid_fixed;
+
+		pr_debug("link rate=%dkbps, stream_rate_khz=%uKhz",
+			rate, stream_rate_khz);
+
+		/*
+		 * For intermediate results, use 64 bit arithmetic to avoid
+		 * loss of precision.
+		 */
+		mvid_calc = (u64) stream_rate_khz * nvid;
+		mvid_calc = div_u64(mvid_calc, rate);
+
+		/*
+		 * truncate back to 32 bits as this final divided value will
+		 * always be within the range of a 32 bit unsigned int.
+		 */
+		mvid = (u32) mvid_calc;
+	} else {
+		base_cc = catalog->io->dp_cc_io.base;
+
+		pixel_m = dp_read(base_cc + MMSS_DP_PIXEL_M);
+		pixel_n = dp_read(base_cc + MMSS_DP_PIXEL_N);
+		pr_debug("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 469

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		mvid = (pixel_m & 0xFFFF) * 5;
+		nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+
+		pr_debug("rate = %d\n", rate);
+
+		if (link_rate_hbr2 == rate)
+			nvid *= 2;
+
+		if (link_rate_hbr3 == rate)
+			nvid *= 3;
                switch (drm_dp_bw_code_to_link_rate(rate)) {
                case DP_LINK_BW_5_4:
                        nvid *= 2;
                        break;
                case DP_LINK_BW_8_1:
                        nvid *= 3;
                        break;
                default:
                        break;
                }

And remove link_rate_hbr* above.

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+	}
+
+	base_ctrl = catalog->io->dp_link.base;
+	pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
+	dp_write(base_ctrl + DP_SOFTWARE_MVID, mvid);
+	dp_write(base_ctrl + DP_SOFTWARE_NVID, nvid);
+}
+
+static void dp_catalog_ctrl_set_pattern(struct dp_catalog_ctrl *ctrl,
+					u32 pattern)
+{
+	int bit, cnt = 10;
+	u32 data;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 495

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	bit = 1;
+	bit <<= (pattern - 1);
        bit = BIT(pattern - 1);

drivers/gpu/drm/msm/dp/dp_catalog.c line 500

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	pr_debug("hw: bit=%d train=%d\n", bit, pattern);
+	dp_write(base + DP_STATE_CTRL, bit);
+
+	bit = 8;
+	bit <<= (pattern - 1);
        bit = BIT(pattern - 1) << 3;

drivers/gpu/drm/msm/dp/dp_catalog.c line 505

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+
+	while (cnt--) {
+		data = dp_read(base + DP_MAINLINK_READY);
+		if (data & bit)
+			break;

Should there be a sleep in here? Also, consider using readx_poll_timeout instead of rolling your own polling.

drivers/gpu/drm/msm/dp/dp_catalog.c line 509

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	}
+
+	if (cnt == 0)
+		pr_err("set link_train=%d failed\n", pattern);

This function should return an int and report this failure instead of ignoring it.

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_ctrl_usb_reset(struct dp_catalog_ctrl *ctrl, 

bool flip)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 526

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->usb3_dp_com.base;
+
+	dp_write(base + USB3_DP_COM_RESET_OVRD_CTRL, 0x0a);

Again, all of these magic values need to be pulled out into #defines so we know what the values mean.

drivers/gpu/drm/msm/dp/dp_catalog.c line 530

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	dp_write(base + USB3_DP_COM_PHY_MODE_CTRL, 0x02);
+	dp_write(base + USB3_DP_COM_SW_RESET, 0x01);
+	/* make sure usb3 com phy software reset is done */
+	wmb();

Same comments here wrt wmb()

drivers/gpu/drm/msm/dp/dp_catalog.c line 535

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+
+	if (!flip) /* CC1 */
+		dp_write(base + USB3_DP_COM_TYPEC_CTRL, 0x02);
+	else /* CC2 */
+		dp_write(base + USB3_DP_COM_TYPEC_CTRL, 0x03);
        u32 val;
        ...
        val = SOME_DEFINE_THAT_MAKES_SENSE;
        if (flip)
                val |= ANOTHER_DEFINE_THAT_MEANS_FLIP;

        dp_io_write(USB3_DP_COM_TYPEC_CTRL, val);
Quoted 24 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +24 -0
+
+	dp_write(base + USB3_DP_COM_SWI_CTRL, 0x00);
+	dp_write(base + USB3_DP_COM_SW_RESET, 0x00);
+	/* make sure the software reset is done */
+	wmb();
+
+	dp_write(base + USB3_DP_COM_POWER_DOWN_CTRL, 0x01);
+	dp_write(base + USB3_DP_COM_RESET_OVRD_CTRL, 0x00);
+	/* make sure phy is brought out of reset */
+	wmb();
+
+}
+
+static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel,
+	bool enable)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!panel) {
+		pr_err("invalid input\n");
+		return;
+	}
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 569

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	dp_catalog_get_priv(panel);
+	base = catalog->io->dp_p0.base;
+
+	if (!enable) {
+		dp_write(base + MMSS_DP_TPG_MAIN_CONTROL, 0x0);
+		dp_write(base + MMSS_DP_BIST_ENABLE, 0x0);
+		dp_write(base + MMSS_DP_TIMING_ENGINE_EN, 0x0);
+		wmb(); /* ensure Timing generator is turned off */
+		return;
+	}

There's really no reason to have both the enable + disable path in the same function, they don't share any code (aside from writing a few different values to the same registers). Could you please split this function into a timing_generator_disable and timing_generator_enable?

Quoted 41 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	dp_write(base + MMSS_DP_INTF_CONFIG, 0x0);
+	dp_write(base + MMSS_DP_INTF_HSYNC_CTL, panel->hsync_ctl);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PERIOD_F0, panel->vsync_period *
+			panel->hsync_period);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, 

panel->v_sync_width *

drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+			panel->hsync_period);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
+	dp_write(base + MMSS_DP_INTF_DISPLAY_HCTL, panel->display_hctl);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_HCTL, 0);
+	dp_write(base + MMSS_INTF_DISPLAY_V_START_F0, 

panel->display_v_start);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	dp_write(base + MMSS_DP_INTF_DISPLAY_V_END_F0, 

panel->display_v_end);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +25 -0
+	dp_write(base + MMSS_INTF_DISPLAY_V_START_F1, 0);
+	dp_write(base + MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
+	dp_write(base + MMSS_DP_INTF_POLARITY_CTL, 0);
+	wmb(); /* ensure TPG registers are programmed */
+
+	dp_write(base + MMSS_DP_TPG_MAIN_CONTROL, 0x100);
+	dp_write(base + MMSS_DP_TPG_VIDEO_CONFIG, 0x5);
+	wmb(); /* ensure TPG config is programmed */
+	dp_write(base + MMSS_DP_BIST_ENABLE, 0x1);
+	dp_write(base + MMSS_DP_TIMING_ENGINE_EN, 0x1);
+	wmb(); /* ensure Timing generator is turned on */
+	pr_debug("%s: enabled tpg\n", __func__);
+}
+
+static void dp_catalog_ctrl_reset(struct dp_catalog_ctrl *ctrl)
+{
+	u32 sw_reset;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {

drivers/gpu/drm/msm/dp/dp_catalog.c line 617

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	sw_reset = dp_read(base + DP_SW_RESET);
+
+	sw_reset |= BIT(0);

Should be a #define

drivers/gpu/drm/msm/dp/dp_catalog.c line 619

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_SW_RESET, sw_reset);
+	usleep_range(1000, 1010); /* h/w recommended delay */

Same comment here regarding the 10us range

Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	sw_reset &= ~BIT(0);
+	dp_write(base + DP_SW_RESET, sw_reset);
+}
+
+static bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +11 -0
+{
+	u32 data;
+	int cnt = 10;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		goto end;
+	}
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 646

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	while (--cnt) {
+		/* DP_MAINLINK_READY */
+		data = dp_read(base + DP_MAINLINK_READY);
+		if (data & BIT(0))
+			return true;
+
+		usleep_range(1000, 1010); /* 1ms wait before next reg read */

Same comment here regarding using readx_poll_timeout wrapped in a helper, also 10us comment.

Quoted 41 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +30 -0
+	}
+	pr_err("mainlink not ready\n");
+end:
+	return false;
+}
+
+static void dp_catalog_ctrl_enable_irq(struct dp_catalog_ctrl *ctrl,
+						bool enable)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	if (enable) {
+		dp_write(base + DP_INTR_STATUS, DP_INTR_MASK1);
+		dp_write(base + DP_INTR_STATUS2, DP_INTR_MASK2);
+	} else {
+		dp_write(base + DP_INTR_STATUS, 0x00);
+		dp_write(base + DP_INTR_STATUS2, 0x00);
+	}
+}
+
+static void dp_catalog_ctrl_hpd_config(struct dp_catalog_ctrl *ctrl, 

bool en)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);

drivers/gpu/drm/msm/dp/dp_catalog.c line 696

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	base = catalog->io->dp_aux.base;
+
+	if (en) {
+		u32 reftimer = dp_read(base + DP_DP_HPD_REFTIMER);
+
+		dp_write(base + DP_DP_HPD_INT_ACK, 0xF);
+		dp_write(base + DP_DP_HPD_INT_MASK, 0xF);
+
+		/* Enabling REFTIMER */
+		reftimer |= BIT(16);

You don't use this anywhere?

drivers/gpu/drm/msm/dp/dp_catalog.c line 701

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		dp_write(base + DP_DP_HPD_REFTIMER, 0xF);
+		/* Enable HPD */
+		dp_write(base + DP_DP_HPD_CTRL, 0x1);
+	} else {
+		/*Disable HPD */

Space after *

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		dp_write(base + DP_DP_HPD_CTRL, 0x0);
+	}
+}
+
+static void dp_catalog_ctrl_get_interrupt(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+{
+	u32 ack = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 720

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	ctrl->isr = dp_read(base + DP_INTR_STATUS2);

This value should just get returned instead of being stored.

drivers/gpu/drm/msm/dp/dp_catalog.c line 721

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	ctrl->isr &= ~DP_INTR_MASK2;

Unmasking the interrupts should not be returned from this function, it should be part of the ack below.

drivers/gpu/drm/msm/dp/dp_catalog.c line 722

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	ack = ctrl->isr & DP_INTERRUPT_STATUS2;

And this does the above unmask already, so you can just turf it.

drivers/gpu/drm/msm/dp/dp_catalog.c line 724

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	ack <<= 1;
+	ack |= DP_INTR_MASK2;

Instead of rolling the ack code yourself, I'd prefer what you did with _MASK, where you define DP_INTERRUPT_STATUS2_ACK above and just do a bitwise-OR to add the acks here. Without the register map in front of me, it would take a while to figure out what you're trying to accomplish.

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +7 -0
+	dp_write(base + DP_INTR_STATUS2, ack);
+}
+
+static void dp_catalog_ctrl_phy_reset(struct dp_catalog_ctrl *ctrl)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 741

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	dp_write(base + DP_PHY_CTRL, 0x5); /* bit 0 & 2 */

The comment doesn't help here, please #define these bits

drivers/gpu/drm/msm/dp/dp_catalog.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	usleep_range(1000, 1010); /* h/w recommended delay */

Same comment re: delay range

drivers/gpu/drm/msm/dp/dp_catalog.c line 744

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_PHY_CTRL, 0x0);
+	wmb(); /* make sure PHY reset done */

Same comment re: wmb

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_ctrl_phy_lane_cfg(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+		bool flipped, u8 ln_cnt)
+{
+	u32 info = 0x0;
+	struct dp_catalog_private *catalog;

drivers/gpu/drm/msm/dp/dp_catalog.c line 761

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	u8 orientation = BIT(!!flipped);
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+
+	info |= (ln_cnt & 0x0F);

Remove the | and just make this an assignment (and you can remove the initialization to 0 above)

drivers/gpu/drm/msm/dp/dp_catalog.c line 773

Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +7 -0
+	info |= ((orientation & 0x0F) << 4);
+	pr_debug("Shared Info = 0x%x\n", info);
+
+	dp_write(catalog->io->phy_io.base + DP_PHY_SPARE0, info);
+}
+
+static void dp_catalog_ctrl_update_vx_px(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		u8 v_level, u8 p_level)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base0, *base1;
+	u8 value0, value1;

Can we please pick better names for these?!

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 789

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	dp_catalog_get_priv(ctrl);
+	base0 = catalog->io->ln_tx0_io.base;
+	base1 = catalog->io->ln_tx1_io.base;
+
+	pr_debug("hw: v=%d p=%d\n", v_level, p_level);
+
+	value0 = vm_voltage_swing[v_level][p_level];
+	value1 = vm_pre_emphasis[v_level][p_level];
+
+	/* program default setting first */

Why do you need to do this?

drivers/gpu/drm/msm/dp/dp_catalog.c line 793

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	dp_write(base0 + TXn_TX_DRV_LVL, 0x2A);
+	dp_write(base1 + TXn_TX_DRV_LVL, 0x2A);
+	dp_write(base0 + TXn_TX_EMP_POST1_LVL, 0x20);
+	dp_write(base1 + TXn_TX_EMP_POST1_LVL, 0x20);

#define these magic values

drivers/gpu/drm/msm/dp/dp_catalog.c line 797

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+
+	/* Enable MUX to use Cursor values from these registers */
+	value0 |= BIT(5);
+	value1 |= BIT(5);

#define these bits please

drivers/gpu/drm/msm/dp/dp_catalog.c line 800

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+
+	/* Configure host and panel only if both values are allowed */
+	if (value0 != 0xFF && value1 != 0xFF) {

You can check this a lot earlier in the function.

drivers/gpu/drm/msm/dp/dp_catalog.c line 810

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		dp_write(base0 + TXn_TX_DRV_LVL, value0);
+		dp_write(base1 + TXn_TX_DRV_LVL, value0);
+		dp_write(base0 + TXn_TX_EMP_POST1_LVL, value1);
+		dp_write(base1 + TXn_TX_EMP_POST1_LVL, value1);
+
+		pr_debug("hw: vx_value=0x%x px_value=0x%x\n",
+			value0, value1);
+	} else {
+		pr_err("invalid vx (0x%x=0x%x), px (0x%x=0x%x\n",
+			v_level, value0, p_level, value1);

Seems like returning an error in this case would be useful

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	}
+}
+
+static void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+			u32 pattern)
+{
+	struct dp_catalog_private *catalog;
+	u32 value = 0x0;
+	void __iomem *base = NULL;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 830

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_STATE_CTRL, 0x0);

Do you really need to do this?

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +22 -0
+
+	switch (pattern) {
+	case DP_TEST_PHY_PATTERN_D10_2_NO_SCRAMBLING:
+		dp_write(base + DP_STATE_CTRL, 0x1);
+		break;
+	case DP_TEST_PHY_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT:
+		value &= ~(1 << 16);
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		value |= 0xFC;
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		dp_write(base + DP_MAINLINK_LEVELS, 0x2);
+		dp_write(base + DP_STATE_CTRL, 0x10);
+		break;
+	case DP_TEST_PHY_PATTERN_PRBS7:
+		dp_write(base + DP_STATE_CTRL, 0x20);
+		break;
+	case DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN:
+		dp_write(base + DP_STATE_CTRL, 0x40);
+		/* 00111110000011111000001111100000 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG0, 0x3E0F83E0);
+		/* 00001111100000111110000011111000 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG1, 0x0F83E0F8);

drivers/gpu/drm/msm/dp/dp_catalog.c line 862

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		/* 1111100000111110 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG2, 0x0000F83E);
+		break;
+	case DP_TEST_PHY_PATTERN_HBR2_CTS_EYE_PATTERN:
+		value = BIT(16);
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		value |= 0xFC;
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		dp_write(base + DP_MAINLINK_LEVELS, 0x2);
+		dp_write(base + DP_STATE_CTRL, 0x10);

This code is the exact same as the case for DP_TEST_PHY_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT, aside from BIT(16) vs ~BIT(16). Can you please combine these cases
and share code?

drivers/gpu/drm/msm/dp/dp_catalog.c line 867

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		break;
+	default:
+		pr_debug("No valid test pattern requested: 0x%x\n", pattern);
+		return;
+	}

All of the DP_STATE_CTRL values should be #defined, and you can move the write down here instead of duplicating it everywhere (with DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN writing a 0).

Quoted 42 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	/* Make sure the test pattern is programmed in the hardware */
+	wmb();
+}
+
+static u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +18 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base = NULL;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return 0;
+	}
+
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->dp_link.base;
+
+	return dp_read(base + DP_MAINLINK_READY);
+}
+
+/* panel related catalog functions */
+static int dp_catalog_panel_timing_cfg(struct dp_catalog_panel 

*panel)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +15 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!panel) {
+		pr_err("invalid input\n");
+		goto end;
+	}
+
+	dp_catalog_get_priv(panel);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_TOTAL_HOR_VER, panel->total);
+	dp_write(base + DP_START_HOR_VER_FROM_SYNC, panel->sync_start);
+	dp_write(base + DP_HSYNC_VSYNC_WIDTH_POLARITY, 

panel->width_blanking);

drivers/gpu/drm/msm/dp/dp_catalog.c line 908

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_ACTIVE_HOR_VER, panel->dp_active);
+end:

useless label, but it'll probably go away when you strip out all of the unnecessary NULL checks from the driver.

Quoted 30 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +30 -0
+	return 0;
+}
+
+static void dp_catalog_audio_init(struct dp_catalog_audio *audio)
+{
+	struct 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,

drivers/gpu/drm/msm/dp/dp_catalog.c line 948

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+			MMSS_DP_AUDIO_ISRC_1,
+		},
+	};
+
+	if (!audio)
+		return;
+
+	dp_catalog_get_priv(audio);
+
+	catalog->audio_map = sdp_map;

Hmm, this is a bit spooky, we're storing a (non-const) pointer to a static stack variable. Fortunately this looks like it'll be easy to fix since this data is only accessed in this file. So move the map into a static const global and reference it directly when needed (and drop audio_map).

Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_audio_config_sdp(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +14 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	u32 sdp_cfg = 0;
+	u32 sdp_cfg2 = 0;
+
+	if (!audio)
+		return;
+
+	dp_catalog_get_priv(audio);
+	base = catalog->io->dp_link.base;
+
+	sdp_cfg = dp_read(base + MMSS_DP_SDP_CFG);
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 975

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	/* 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);

#define the values and combine the assignment

drivers/gpu/drm/msm/dp/dp_catalog.c line 984

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+
+	pr_debug("sdp_cfg = 0x%x\n", sdp_cfg);
+	dp_write(base + MMSS_DP_SDP_CFG, sdp_cfg);
+
+	sdp_cfg2 = dp_read(base + 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);

The reset value of this register is 0x4, so how can the bits in position 0/1 get flipped? We shouldn't need this code, afaict.

If we do, the same comments regarding #define and combination as above.

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	pr_debug("sdp_cfg2 = 0x%x\n", sdp_cfg2);
+	dp_write(base + MMSS_DP_SDP_CFG2, sdp_cfg2);
+}
+
+static void dp_catalog_audio_get_header(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+{
+	struct dp_catalog_private *catalog;
+	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
+	void __iomem *base;
+	enum dp_catalog_audio_sdp_type sdp;
+	enum dp_catalog_audio_header_type header;
+
+	if (!audio)
+		return;

drivers/gpu/drm/msm/dp/dp_catalog.c line 1009

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	dp_catalog_get_priv(audio);
+
+	base    = catalog->io->dp_link.base;
+	sdp_map = catalog->audio_map;
+	sdp     = audio->sdp_type;
+	header  = audio->sdp_header;
+
+	audio->data = dp_read(base + sdp_map[sdp][header]);
+}

This function is unused, please remove.

Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_audio_set_header(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +11 -0
+{
+	struct dp_catalog_private *catalog;
+	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
+	void __iomem *base;
+	enum dp_catalog_audio_sdp_type sdp;
+	enum dp_catalog_audio_header_type header;
+	u32 data;
+
+	if (!audio)
+		return;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 1032

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	dp_catalog_get_priv(audio);
+
+	base    = catalog->io->dp_link.base;
+	sdp_map = catalog->audio_map;
+	sdp     = audio->sdp_type;
+	header  = audio->sdp_header;
+	data    = audio->data;
+
+	dp_write(base + sdp_map[sdp][header], data);
+}

This function is unused, please remove.

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_audio_config_acr(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	u32 acr_ctrl, select;
+
+	dp_catalog_get_priv(audio);

drivers/gpu/drm/msm/dp/dp_catalog.c line 1050

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	select = audio->data;
+	base   = catalog->io->dp_link.base;
+
+	acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
+
+	pr_debug("select = 0x%x, acr_ctrl = 0x%x\n", select, acr_ctrl);
+
+	dp_write(base + MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
+}

This function is unused, please remove.

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_audio_safe_to_exit_level(struct 

dp_catalog_audio *audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	u32 mainlink_levels, safe_to_exit_level;
+
+	dp_catalog_get_priv(audio);
+
+	base   = catalog->io->dp_link.base;
+	safe_to_exit_level = audio->data;

drivers/gpu/drm/msm/dp/dp_catalog.c line 1071

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	mainlink_levels = dp_read(base + DP_MAINLINK_LEVELS);
+	mainlink_levels &= 0xFE0;
+	mainlink_levels |= safe_to_exit_level;
+
+	pr_debug("mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
+			mainlink_levels, safe_to_exit_level);
+
+	dp_write(base + DP_MAINLINK_LEVELS, mainlink_levels);
+}

This function is unused, please remove.

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+
+static void dp_catalog_audio_enable(struct dp_catalog_audio *audio)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	bool enable;
+	u32 audio_ctrl;
+
+	dp_catalog_get_priv(audio);
+
+	base   = catalog->io->dp_link.base;
+	enable = !!audio->data;
+
+	audio_ctrl = dp_read(base + MMSS_DP_AUDIO_CFG);
+
+	if (enable)

drivers/gpu/drm/msm/dp/dp_catalog.c line 1097

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		audio_ctrl |= BIT(0);
+	else
+		audio_ctrl &= ~BIT(0);
+
+	pr_debug("dp_audio_cfg = 0x%x\n", audio_ctrl);
+	dp_write(base + MMSS_DP_AUDIO_CFG, audio_ctrl);
+
+	/* make sure audio engine is disabled */
+	wmb();
+}

This function is unused, please remove.

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io 

*io)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+{
+	int rc = 0;
+	struct dp_catalog *dp_catalog;
+	struct dp_catalog_private *catalog;

drivers/gpu/drm/msm/dp/dp_catalog.c line 1113

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	struct dp_catalog_aux aux = {
+		.read_data     = dp_catalog_aux_read_data,
+		.write_data    = dp_catalog_aux_write_data,
+		.write_trans   = dp_catalog_aux_write_trans,
+		.clear_trans   = dp_catalog_aux_clear_trans,
+		.reset         = dp_catalog_aux_reset,
+		.update_aux_cfg = dp_catalog_aux_update_cfg,
+		.enable        = dp_catalog_aux_enable,
+		.setup         = dp_catalog_aux_setup,
+		.get_irq       = dp_catalog_aux_get_irq,

Out of these, it seems like write_trans, clear_trans, update_aux_cfg, setup and get_irq are all unused. Please remove them.

Please also check the other functions to ensure they're used.

Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +17 -0
+	};
+	struct dp_catalog_ctrl ctrl = {
+		.state_ctrl     = dp_catalog_ctrl_state_ctrl,
+		.config_ctrl    = dp_catalog_ctrl_config_ctrl,
+		.lane_mapping   = dp_catalog_ctrl_lane_mapping,
+		.mainlink_ctrl  = dp_catalog_ctrl_mainlink_ctrl,
+		.config_misc    = dp_catalog_ctrl_config_misc,
+		.config_msa     = dp_catalog_ctrl_config_msa,
+		.set_pattern    = dp_catalog_ctrl_set_pattern,
+		.reset          = dp_catalog_ctrl_reset,
+		.usb_reset      = dp_catalog_ctrl_usb_reset,
+		.mainlink_ready = dp_catalog_ctrl_mainlink_ready,
+		.enable_irq     = dp_catalog_ctrl_enable_irq,
+		.hpd_config     = dp_catalog_ctrl_hpd_config,
+		.phy_reset      = dp_catalog_ctrl_phy_reset,
+		.phy_lane_cfg   = dp_catalog_ctrl_phy_lane_cfg,
+		.update_vx_px   = dp_catalog_ctrl_update_vx_px,
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 1134

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+		.get_interrupt  = dp_catalog_ctrl_get_interrupt,
+		.update_transfer_unit = dp_catalog_ctrl_update_transfer_unit,
+		.send_phy_pattern    = dp_catalog_ctrl_send_phy_pattern,
+		.read_phy_pattern = dp_catalog_ctrl_read_phy_pattern,

So, what's the benefit of adding the catalog abstractions? Do you ever have multiple/alternate implementations of a catalog? It doesn't seem like it. You should just remove all of the catalog overhead and call the functions directly.

We use catalog abstractions for two different reasons:
1. To support multiple hardware since these implementations are hardware specific.
2. To virtualize DP hardware.

Our internal hardware already supports multiple chips. We want to keep these abstractions to make the code consistent between upstream and internal implementation.

Quoted 660 lines
Quoted 165 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +54 -0
+	};
+	struct dp_catalog_audio audio = {
+		.init       = dp_catalog_audio_init,
+		.config_acr = dp_catalog_audio_config_acr,
+		.enable     = dp_catalog_audio_enable,
+		.config_sdp = dp_catalog_audio_config_sdp,
+		.set_header = dp_catalog_audio_set_header,
+		.get_header = dp_catalog_audio_get_header,
+		.safe_to_exit_level = dp_catalog_audio_safe_to_exit_level,
+	};
+	struct dp_catalog_panel panel = {
+		.timing_cfg = dp_catalog_panel_timing_cfg,
+		.tpg_config = dp_catalog_panel_tpg_cfg,
+	};
+
+	if (!io) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto error;
+	}
+
+	catalog  = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL);
+	if (!catalog) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	catalog->dev = dev;
+	catalog->io = io;
+
+	dp_catalog = &catalog->dp_catalog;
+
+	dp_catalog->aux   = aux;
+	dp_catalog->ctrl  = ctrl;
+	dp_catalog->audio = audio;
+	dp_catalog->panel = panel;
+
+	return dp_catalog;
+error:
+	return ERR_PTR(rc);
+}
+
+void dp_catalog_put(struct dp_catalog *dp_catalog)
+{
+	struct dp_catalog_private *catalog;
+
+	if (!dp_catalog)
+		return;
+
+	catalog = container_of(dp_catalog, struct dp_catalog_private,
+				dp_catalog);
+
+	devm_kfree(catalog->dev, catalog);
+}
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
new file mode 100644
index 0000000..58951df
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_catalog.h new file +89 -0
+
+#ifndef _DP_CATALOG_H_
+#define _DP_CATALOG_H_
+
+#include "dp_parser.h"
+
+/* interrupts */
+#define DP_INTR_HPD		BIT(0)
+#define DP_INTR_AUX_I2C_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)
+
+struct dp_catalog_aux {
+	u32 data;
+	u32 isr;
+
+	u32 (*read_data)(struct dp_catalog_aux *aux);
+	int (*write_data)(struct dp_catalog_aux *aux);
+	int (*write_trans)(struct dp_catalog_aux *aux);
+	int (*clear_trans)(struct dp_catalog_aux *aux, bool read);
+	void (*reset)(struct dp_catalog_aux *aux);
+	void (*enable)(struct dp_catalog_aux *aux, bool enable);
+	void (*update_aux_cfg)(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type);
+	void (*setup)(struct dp_catalog_aux *aux,
+			struct dp_aux_cfg *aux_cfg);
+	void (*get_irq)(struct dp_catalog_aux *aux, bool cmd_busy);
+};
+
+struct dp_catalog_ctrl {
+	u32 dp_tu;
+	u32 valid_boundary;
+	u32 valid_boundary2;
+	u32 isr;
+
+	void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state);
+	void (*config_ctrl)(struct dp_catalog_ctrl *ctrl, u32 config);
+	void (*lane_mapping)(struct dp_catalog_ctrl *ctrl);
+	void (*mainlink_ctrl)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*config_misc)(struct dp_catalog_ctrl *ctrl, u32 cc, u32 tb);
+	void (*config_msa)(struct dp_catalog_ctrl *ctrl, u32 rate,
+				u32 stream_rate_khz, bool fixed_nvid);
+	void (*set_pattern)(struct dp_catalog_ctrl *ctrl, u32 pattern);
+	void (*reset)(struct dp_catalog_ctrl *ctrl);
+	void (*usb_reset)(struct dp_catalog_ctrl *ctrl, bool flip);
+	bool (*mainlink_ready)(struct dp_catalog_ctrl *ctrl);
+	void (*enable_irq)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*hpd_config)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*phy_reset)(struct dp_catalog_ctrl *ctrl);
+	void (*phy_lane_cfg)(struct dp_catalog_ctrl *ctrl, bool flipped,
+				u8 lane_cnt);
+	void (*update_vx_px)(struct dp_catalog_ctrl *ctrl, u8 v_level,
+				u8 p_level);
+	void (*get_interrupt)(struct dp_catalog_ctrl *ctrl);
+	void (*update_transfer_unit)(struct dp_catalog_ctrl *ctrl);
+	void (*send_phy_pattern)(struct dp_catalog_ctrl *ctrl,
+			u32 pattern);
+	u32 (*read_phy_pattern)(struct dp_catalog_ctrl *ctrl);
+};
+
+enum 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 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 dp_catalog_audio {
+	enum dp_catalog_audio_sdp_type sdp_type;

drivers/gpu/drm/msm/dp/dp_catalog.h line 112

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+	enum dp_catalog_audio_header_type sdp_header;
+	u32 data;
+
+	void (*init)(struct dp_catalog_audio *audio);
+	void (*enable)(struct dp_catalog_audio *audio);
+	void (*config_acr)(struct dp_catalog_audio *audio);
+	void (*config_sdp)(struct dp_catalog_audio *audio);
+	void (*set_header)(struct dp_catalog_audio *audio);
+	void (*get_header)(struct dp_catalog_audio *audio);
+	void (*safe_to_exit_level)(struct dp_catalog_audio *audio);

None of these are called? So get rid of this entire structure, the functions that aren't called, and the audio enums above.

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+};
+
+struct dp_catalog_panel {
+	u32 total;
+	u32 sync_start;
+	u32 width_blanking;

drivers/gpu/drm/msm/dp/dp_catalog.h line 128

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+	u32 dp_active;
+
+	/* TPG */
+	u32 hsync_period;
+	u32 vsync_period;
+	u32 display_v_start;
+	u32 display_v_end;
+	u32 v_sync_width;
+	u32 hsync_ctl;
+	u32 display_hctl;

All of this information is already available from drm core, so it can go.

drivers/gpu/drm/msm/dp/dp_catalog.h line 131

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +3 -0
+
+	int (*timing_cfg)(struct dp_catalog_panel *panel);
+	void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);

As suggested elsewhere, these functions should just be called directly wherever applicable. So we can get rid of this struct.

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+};
+
+struct dp_catalog {
+	struct dp_catalog_aux aux;
+	struct dp_catalog_ctrl ctrl;
+	struct dp_catalog_audio audio;
+	struct dp_catalog_panel panel;
+};
+
+struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io 
Quoted 2 lines

*io);
+void dp_catalog_put(struct dp_catalog *catalog);

As mentioned above, all of this should be removed. We can just call the functions directly.

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
+
+#endif /* _DP_CATALOG_H_ */
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
new file mode 100644
index 0000000..08a52f5
@@ -0,0 +1,1475 @@
+/*
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +14 -0
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+
+#include "dp_ctrl.h"
+
+#define DP_KHZ_TO_HZ 1000
+
+#define DP_CTRL_INTR_READY_FOR_VIDEO     BIT(0)
+#define DP_CTRL_INTR_IDLE_PATTERN_SENT  BIT(3)
+

drivers/gpu/drm/msm/dp/dp_ctrl.c line 37

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+/* dp state ctrl */
+#define ST_TRAIN_PATTERN_1		BIT(0)
+#define ST_TRAIN_PATTERN_2		BIT(1)
+#define ST_TRAIN_PATTERN_3		BIT(2)
+#define ST_TRAIN_PATTERN_4		BIT(3)
+#define ST_SYMBOL_ERR_RATE_MEASUREMENT	BIT(4)
+#define ST_PRBS7			BIT(5)
+#define ST_CUSTOM_80_BIT_PATTERN	BIT(6)
+#define ST_SEND_VIDEO			BIT(7)
+#define ST_PUSH_IDLE			BIT(8)

I'd like to see these defined with DP_STATE_CTRL (and s/ST/DP_STATE_CTRL/).

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +8 -0
+
+#define MR_LINK_TRAINING1  0x8
+#define MR_LINK_SYMBOL_ERM 0x80
+#define MR_LINK_PRBS7 0x100
+#define MR_LINK_CUSTOM80 0x200
+
+struct dp_vc_tu_mapping_table {
+	u32 vic;

drivers/gpu/drm/msm/dp/dp_ctrl.c line 55

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+	u8 lanes;
+	u8 lrate; /* DP_LINK_RATE -> 162(6), 270(10), 540(20), 810 (30) */
+	u8 bpp;
+	u8 valid_boundary_link;
+	u16 delay_start_link;
+	bool boundary_moderation_en;
+	u8 valid_lower_boundary_link;
+	u8 upper_boundary_count;
+	u8 lower_boundary_count;
+	u8 tu_size_minus1;

Please check this struct for unused members, there are at least a couple.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 67

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0
+};
+
+struct dp_ctrl_private {
+	struct dp_ctrl dp_ctrl;
+
+	struct device *dev;
+	struct dp_aux *aux;
+	struct dp_panel *panel;
+	struct dp_link *link;
+	struct dp_power *power;
+	struct dp_parser *parser;
+	struct dp_catalog_ctrl *catalog;

Once you remove struct dp_ctrl and call the functions directly, I suspect you can get rid of all of these.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 76

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0
+
+	struct completion idle_comp;
+	struct completion video_comp;
+
+	bool orientation;
+	atomic_t aborted;
+
+	u32 pixel_rate;
+	u32 vic;

'u32 vic' shows up in 3 places in this driver, but there is not one use of any vic :) Please remove from here and elsewhere.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 85

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0
+};
+
+enum notification_status {
+	NOTIFY_UNKNOWN,
+	NOTIFY_CONNECT,
+	NOTIFY_DISCONNECT,
+	NOTIFY_CONNECT_IRQ_HPD,
+	NOTIFY_DISCONNECT_IRQ_HPD,
+};

Unused, please remove.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 97

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0
+
+static void dp_ctrl_idle_patterns_sent(struct dp_ctrl_private *ctrl)
+{
+	pr_debug("idle_patterns_sent\n");
+	complete(&ctrl->idle_comp);
+}
+
+static void dp_ctrl_video_ready(struct dp_ctrl_private *ctrl)
+{
+	pr_debug("dp_video_ready\n");
+	complete(&ctrl->video_comp);
+}

These functions don't provide value, please remove and just call complete() directly.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 108

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +11 -0
+
+static void dp_ctrl_abort(struct dp_ctrl *dp_ctrl)
+{
+	struct dp_ctrl_private *ctrl;
+
+	if (!dp_ctrl) {
+		pr_err("Invalid input data\n");
+		return;
+	}
+
+	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

JFYI, this is sprinkled everywhere, would be a good candidate for an inline function. Since dp_ctrl can be removed, it's kind of a moot point now.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 115

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+
+	atomic_set(&ctrl->aborted, 1);
+}
+
+static void dp_ctrl_state_ctrl(struct dp_ctrl_private *ctrl, u32 

state)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
+{
+	ctrl->catalog->state_ctrl(ctrl->catalog, state);

No need to wrap this in a function

drivers/gpu/drm/msm/dp/dp_ctrl.c line 120

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+}
+
+static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl)
+{
+	int const idle_pattern_completion_timeout_ms = 3 * HZ / 100;

This should be #define'd outside of the functioninstead. Also, why the '_ms_' suffix? The units are in jiffies.

I think something like

#define IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES (30 * HZ / 1000) /* 30 ms */

would be clearer.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 130

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+	struct dp_ctrl_private *ctrl;
+
+	if (!dp_ctrl) {
+		pr_err("Invalid input data\n");
+		return;
+	}
+
+	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+
+	reinit_completion(&ctrl->idle_comp);

This function is called from a bunch of places, and idle_comp is also used in a bunch of places. Are you certain this is thread-safe if you have concurrent callers or users of idle_comp?

drivers/gpu/drm/msm/dp/dp_ctrl.c line 135

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+	dp_ctrl_state_ctrl(ctrl, ST_PUSH_IDLE);
+
+	if (!wait_for_completion_timeout(&ctrl->idle_comp,
+			idle_pattern_completion_timeout_ms))
+		pr_warn("PUSH_IDLE pattern timedout\n");

Return an error?

drivers/gpu/drm/msm/dp/dp_ctrl.c line 145

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+
+	pr_debug("mainlink off done\n");
+}
+
+static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl)
+{
+	u32 config = 0, tbd;
+	u8 *dpcd = ctrl->panel->dpcd;
+
+	config |= (2 << 13); /* Default-> LSCLK DIV: 1/4 LCLK  */

#define value

drivers/gpu/drm/msm/dp/dp_ctrl.c line 146

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0
+	config |= (0 << 11); /* RGB */

This is a no-op, can be removed

drivers/gpu/drm/msm/dp/dp_ctrl.c line 155

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+
+	/* Scrambler reset enable */
+	if (dpcd[DP_EDP_CONFIGURATION_CAP] & 

DP_ALTERNATE_SCRAMBLER_RESET_CAP)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+		config |= (1 << 10);
+
+	tbd = ctrl->link->get_test_bits_depth(ctrl->link,
+			ctrl->panel->pinfo.bpp);
+
+	if (tbd == DP_TEST_BIT_DEPTH_UNKNOWN)

Should we print a debug message here?

drivers/gpu/drm/msm/dp/dp_ctrl.c line 161

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+		tbd = DP_TEST_BIT_DEPTH_8;
+
+	config |= tbd << 8;
+
+	/* Num of Lanes */
+	config |= ((ctrl->link->link_params.lane_count - 1) << 4);

These shift values should be #defined

drivers/gpu/drm/msm/dp/dp_ctrl.c line 164

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+
+	if (drm_dp_enhanced_frame_cap(dpcd))
+		config |= 0x40;

#define 0x40

drivers/gpu/drm/msm/dp/dp_ctrl.c line 168

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+
+	config |= 0x04; /* progressive video */
+
+	config |= 0x03;	/* sycn clock & static Mvid */

And these, plus s/sycn/sync/

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+
+	ctrl->catalog->config_ctrl(ctrl->catalog, config);
+}
+
+/**
+ * dp_ctrl_configure_source_params() - configures DP transmitter 

source params
+ * @ctrl: Display Port Driver data
+ *
+ * Configures the DP transmitter source params including details such as lane
+ * configuration, output format and sink/panel timing information.
+ */
+static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c line 185

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+{
+	u32 cc, tb;
+
+	ctrl->catalog->lane_mapping(ctrl->catalog);
+	ctrl->catalog->mainlink_ctrl(ctrl->catalog, true);

We go through ctrl->catalog->callback_hook to call a function that is specific to ctrl and only called in this file. It could easily just be a static function without having to go through 2 structs and a callback hook.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 192

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0
+
+	dp_ctrl_config_ctrl(ctrl);
+
+	tb = ctrl->link->get_test_bits_depth(ctrl->link,
+		ctrl->panel->pinfo.bpp);
+	cc = ctrl->link->get_colorimetry_config(ctrl->link);
+	ctrl->catalog->config_misc(ctrl->catalog, cc, tb);

Same comments with these hooks, they're only called from this file. I'll stop harping on this, but could we please remove the layers of indirection and just embed and call functions as appropriate?

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +22 -0
+	ctrl->panel->timing_cfg(ctrl->panel);
+}
+
+static void dp_ctrl_get_extra_req_bytes(u64 result_valid,
+					int valid_bdary_link,
+					u64 value1, u64 value2,
+					bool *negative, u64 *result,
+					u64 compare)
+{
+	*negative = false;
+	if (result_valid >= compare) {
+		if (valid_bdary_link
+				>= compare)
+			*result = value1 + value2;
+		else {
+			if (value1 < value2)
+				*negative = true;
+			*result = (value1 >= value2) ?
+				(value1 - value2) : (value2 - value1);
+		}
+	} else {
+		if (valid_bdary_link

drivers/gpu/drm/msm/dp/dp_ctrl.c line 224

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+				>= compare) {
+			if (value1 >= value2)
+				*negative = true;
+			*result = (value1 >= value2) ?
+				(value1 - value2) : (value2 - value1);
+		} else {
+			*result = value1 + value2;
+			*negative = true;
+		}
+	}

I think this can be simplified to the following, it's still super hard to follow, but I'm not sure if that can be helped.

        bool result_bigger = result_valid >= compare;
        bool valid_bdary_bigger = valid_bdary_link >= compare;

	if (result_bigger && valid_bdary_bigger ||
            !result_bigger && !valid_bdary_bigger) {
                *negative = !valid_bdary_bigger;
                return value1 + value2;
        }

        *negative = (result_bigger && !valid_bdary_bigger && value1 < 
value2) ||
                    (!result_bigger && valid_bdary_bigger && value1 >= 
value2);
        return max(value1, value2) - min(value1, value2);

I don't know. The more I stare at this the less convinced I become that it's better. So take it or leave it. At the very least you can collapse the

if (cond)

        *negative = true;

to

*negative = cond;

and do the max(v,v) - min(v,v) trick to shave off some of the conditionals in the original.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 231

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0
+}
+
+static u64 roundup_u64(u64 x, u64 y)
+{
+	x += (y - 1);
+	return (div64_ul(x, y) * y);
+}

Please replace all usage with DIV_ROUND_UP_ULL

drivers/gpu/drm/msm/dp/dp_ctrl.c line 239

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +8 -0
+
+static u64 rounddown_u64(u64 x, u64 y)
+{
+	u64 rem;
+
+	div64_u64_rem(x, y, &rem);
+	return (x - rem);
+}

Please replace all usage with DIV_ROUND_DOWN_ULL

Quoted 58 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +58 -0
+
+static void dp_ctrl_calc_tu_parameters(struct dp_ctrl_private *ctrl,
+				       struct dp_vc_tu_mapping_table *tu_table)
+{
+	u32 multiplier = 1000000;
+	u64 pclk, lclk;
+	u8 bpp, ln_cnt;
+	int run_idx = 0;
+	u32 lwidth, h_blank;
+	u32 fifo_empty = 0;
+	u32 ratio_scale = 1001;
+	u64 temp, ratio, original_ratio;
+	u64 temp2, reminder;
+	u64 temp3, temp4, result = 0;
+
+	u64 err = multiplier;
+	u64 n_err = 0, n_n_err = 0;
+	bool n_err_neg, nn_err_neg;
+	u8 hblank_margin = 16;
+
+	u8 tu_size, tu_size_desired = 0, tu_size_minus1;
+	int valid_boundary_link;
+	u64 resulting_valid;
+	u64 total_valid;
+	u64 effective_valid;
+	u64 effective_valid_recorded;
+	int n_tus;
+	int n_tus_per_lane;
+	int paired_tus;
+	int remainder_tus;
+	int remainder_tus_upper, remainder_tus_lower;
+	int extra_bytes;
+	int filler_size;
+	int delay_start_link;
+	int boundary_moderation_en = 0;
+	int upper_bdry_cnt = 0;
+	int lower_bdry_cnt = 0;
+	int i_upper_bdry_cnt = 0;
+	int i_lower_bdry_cnt = 0;
+	int valid_lower_boundary_link = 0;
+	int even_distribution_bf = 0;
+	int even_distribution_legacy = 0;
+	int even_distribution = 0;
+	int min_hblank = 0;
+	int extra_pclk_cycles;
+	u8 extra_pclk_cycle_delay = 4;
+	int extra_pclk_cycles_in_link_clk;
+	u64 ratio_by_tu;
+	u64 average_valid2;
+	u64 extra_buffer_margin;
+	int new_valid_boundary_link;
+
+	u64 resulting_valid_tmp;
+	u64 ratio_by_tu_tmp;
+	int n_tus_tmp;
+	int extra_pclk_cycles_tmp;
+	int extra_pclk_cycles_in_lclk_tmp;
+	int extra_req_bytes_new_tmp;

drivers/gpu/drm/msm/dp/dp_ctrl.c line 307

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+	int filler_size_tmp;
+	int lower_filler_size_tmp;
+	int delay_start_link_tmp;
+	int min_hblank_tmp = 0;
+	bool extra_req_bytes_is_neg = false;
+	struct dp_panel_info *pinfo = &ctrl->panel->pinfo;
+
+	u8 dp_brute_force = 1;
+	u64 brute_force_threshold = 10;
+	u64 diff_abs;

76 stack vars and ~450 lines must be a new record somewhere :)

Quoted 2 lines

I'm going to skip reviewing this function and let you split/simplify/reduce it. Please just make it more readable (comments, docs, helper functions, etc).

Yes, will try to split this function as modular as possible.
JFYI, this function is IP/hardware specific implementation. It might not be possible to provide lot of comments to make is understandable.

Quoted 3,155 lines
Quoted 408 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +58 -0
+
+	ln_cnt =  ctrl->link->link_params.lane_count;
+
+	bpp = pinfo->bpp;
+	lwidth = pinfo->h_active;
+	h_blank = pinfo->h_back_porch + pinfo->h_front_porch +
+				pinfo->h_sync_width;
+	pclk = pinfo->pixel_clk_khz * 1000;
+
+	boundary_moderation_en = 0;
+	upper_bdry_cnt = 0;
+	lower_bdry_cnt = 0;
+	i_upper_bdry_cnt = 0;
+	i_lower_bdry_cnt = 0;
+	valid_lower_boundary_link = 0;
+	even_distribution_bf = 0;
+	even_distribution_legacy = 0;
+	even_distribution = 0;
+	min_hblank = 0;
+
+	lclk = drm_dp_bw_code_to_link_rate(
+		ctrl->link->link_params.bw_code) * DP_KHZ_TO_HZ;
+
+	pr_debug("pclk=%lld, active_width=%d, h_blank=%d\n",
+						pclk, lwidth, h_blank);
+	pr_debug("lclk = %lld, ln_cnt = %d\n", lclk, ln_cnt);
+	ratio = div64_u64_rem(pclk * bpp * multiplier,
+				8 * ln_cnt * lclk, &reminder);
+	ratio = div64_u64((pclk * bpp * multiplier), (8 * ln_cnt * lclk));
+	original_ratio = ratio;
+
+	extra_buffer_margin = roundup_u64(div64_u64(extra_pclk_cycle_delay
+				* lclk * multiplier, pclk), multiplier);
+	extra_buffer_margin = div64_u64(extra_buffer_margin, multiplier);
+
+	/* To deal with cases where lines are not distributable */
+	if (((lwidth % ln_cnt) != 0) && ratio < multiplier) {
+		ratio = ratio * ratio_scale;
+		ratio = ratio < (1000 * multiplier)
+				? ratio : (1000 * multiplier);
+	}
+	pr_debug("ratio = %lld\n", ratio);
+
+	for (tu_size = 32; tu_size <= 64; tu_size++) {
+		temp = ratio * tu_size;
+		temp2 = ((temp / multiplier) + 1) * multiplier;
+		n_err = roundup_u64(temp, multiplier) - temp;
+
+		if (n_err < err) {
+			err = n_err;
+			tu_size_desired = tu_size;
+		}
+	}
+	pr_debug("Info: tu_size_desired = %d\n", tu_size_desired);
+
+	tu_size_minus1 = tu_size_desired - 1;
+
+	valid_boundary_link = roundup_u64(ratio * tu_size_desired, 

multiplier);

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +15 -0
+	valid_boundary_link /= multiplier;
+	n_tus = rounddown((lwidth * bpp * multiplier)
+			/ (8 * valid_boundary_link), multiplier) / multiplier;
+	even_distribution_legacy = n_tus % ln_cnt == 0 ? 1 : 0;
+	pr_debug("Info: n_symbol_per_tu=%d, number_of_tus=%d\n",
+					valid_boundary_link, n_tus);
+
+	extra_bytes = roundup_u64((n_tus + 1)
+			* ((valid_boundary_link * multiplier)
+			- (original_ratio * tu_size_desired)), multiplier);
+	extra_bytes /= multiplier;
+	extra_pclk_cycles = roundup(extra_bytes * 8 * multiplier / bpp,
+			multiplier);
+	extra_pclk_cycles /= multiplier;
+	extra_pclk_cycles_in_link_clk = 

roundup_u64(div64_u64(extra_pclk_cycles

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +256 -0
+				* lclk * multiplier, pclk), multiplier);
+	extra_pclk_cycles_in_link_clk /= multiplier;
+	filler_size = roundup_u64((tu_size_desired - valid_boundary_link)
+						* multiplier, multiplier);
+	filler_size /= multiplier;
+	ratio_by_tu = div64_u64(ratio * tu_size_desired, multiplier);
+
+	pr_debug("extra_pclk_cycles_in_link_clk=%d, extra_bytes=%d\n",
+				extra_pclk_cycles_in_link_clk, extra_bytes);
+	pr_debug("extra_pclk_cycles_in_link_clk=%d\n",
+				extra_pclk_cycles_in_link_clk);
+	pr_debug("filler_size=%d, extra_buffer_margin=%lld\n",
+				filler_size, extra_buffer_margin);
+
+	delay_start_link = ((extra_bytes > extra_pclk_cycles_in_link_clk)
+			? extra_bytes
+			: extra_pclk_cycles_in_link_clk)
+				+ filler_size + extra_buffer_margin;
+	resulting_valid = valid_boundary_link;
+	pr_debug("Info: delay_start_link=%d, filler_size=%d\n",
+				delay_start_link, filler_size);
+	pr_debug("valid_boundary_link=%d ratio_by_tu=%lld\n",
+				valid_boundary_link, ratio_by_tu);
+
+	diff_abs = (resulting_valid >= ratio_by_tu)
+				? (resulting_valid - ratio_by_tu)
+				: (ratio_by_tu - resulting_valid);
+
+	if (err != 0 && ((diff_abs > brute_force_threshold)
+			|| (even_distribution_legacy == 0)
+			|| (dp_brute_force == 1))) {
+		err = multiplier;
+		for (tu_size = 32; tu_size <= 64; tu_size++) {
+			for (i_upper_bdry_cnt = 1; i_upper_bdry_cnt <= 15;
+						i_upper_bdry_cnt++) {
+				for (i_lower_bdry_cnt = 1;
+					i_lower_bdry_cnt <= 15;
+					i_lower_bdry_cnt++) {
+					new_valid_boundary_link =
+						roundup_u64(ratio
+						* tu_size, multiplier);
+					average_valid2 = (i_upper_bdry_cnt
+						* new_valid_boundary_link
+						+ i_lower_bdry_cnt
+						* (new_valid_boundary_link
+							- multiplier))
+						/ (i_upper_bdry_cnt
+							+ i_lower_bdry_cnt);
+					n_tus = rounddown_u64(div64_u64(lwidth
+						* multiplier * multiplier
+						* (bpp / 8), average_valid2),
+							multiplier);
+					n_tus /= multiplier;
+					n_tus_per_lane
+						= rounddown(n_tus
+							* multiplier
+							/ ln_cnt, multiplier);
+					n_tus_per_lane /= multiplier;
+					paired_tus =
+						rounddown((n_tus_per_lane)
+							* multiplier
+							/ (i_upper_bdry_cnt
+							+ i_lower_bdry_cnt),
+							multiplier);
+					paired_tus /= multiplier;
+					remainder_tus = n_tus_per_lane
+							- paired_tus
+						* (i_upper_bdry_cnt
+							+ i_lower_bdry_cnt);
+					if ((remainder_tus
+						- i_upper_bdry_cnt) > 0) {
+						remainder_tus_upper
+							= i_upper_bdry_cnt;
+						remainder_tus_lower =
+							remainder_tus
+							- i_upper_bdry_cnt;
+					} else {
+						remainder_tus_upper
+							= remainder_tus;
+						remainder_tus_lower = 0;
+					}
+					total_valid = paired_tus
+						* (i_upper_bdry_cnt
+						* new_valid_boundary_link
+							+ i_lower_bdry_cnt
+						* (new_valid_boundary_link
+							- multiplier))
+						+ (remainder_tus_upper
+						* new_valid_boundary_link)
+						+ (remainder_tus_lower
+						* (new_valid_boundary_link
+							- multiplier));
+					n_err_neg = nn_err_neg = false;
+					effective_valid
+						= div_u64(total_valid,
+							n_tus_per_lane);
+					n_n_err = (effective_valid
+							>= (ratio * tu_size))
+						? (effective_valid
+							- (ratio * tu_size))
+						: ((ratio * tu_size)
+							- effective_valid);
+					if (effective_valid < (ratio * tu_size))
+						nn_err_neg = true;
+					n_err = (average_valid2
+						>= (ratio * tu_size))
+						? (average_valid2
+							- (ratio * tu_size))
+						: ((ratio * tu_size)
+							- average_valid2);
+					if (average_valid2 < (ratio * tu_size))
+						n_err_neg = true;
+					even_distribution =
+						n_tus % ln_cnt == 0 ? 1 : 0;
+					diff_abs =
+						resulting_valid >= ratio_by_tu
+						? (resulting_valid
+							- ratio_by_tu)
+						: (ratio_by_tu
+							- resulting_valid);
+
+					resulting_valid_tmp = div64_u64(
+						(i_upper_bdry_cnt
+						* new_valid_boundary_link
+						+ i_lower_bdry_cnt
+						* (new_valid_boundary_link
+							- multiplier)),
+						(i_upper_bdry_cnt
+							+ i_lower_bdry_cnt));
+					ratio_by_tu_tmp =
+						original_ratio * tu_size;
+					ratio_by_tu_tmp /= multiplier;
+					n_tus_tmp = rounddown_u64(
+						div64_u64(lwidth
+						* multiplier * multiplier
+						* bpp / 8,
+						resulting_valid_tmp),
+						multiplier);
+					n_tus_tmp /= multiplier;
+
+					temp3 = (resulting_valid_tmp
+						>= (original_ratio * tu_size))
+						? (resulting_valid_tmp
+						- original_ratio * tu_size)
+						: (original_ratio * tu_size)
+						- resulting_valid_tmp;
+					temp3 = (n_tus_tmp + 1) * temp3;
+					temp4 = (new_valid_boundary_link
+						>= (original_ratio * tu_size))
+						? (new_valid_boundary_link
+							- original_ratio
+							* tu_size)
+						: (original_ratio * tu_size)
+						- new_valid_boundary_link;
+					temp4 = (i_upper_bdry_cnt
+							* ln_cnt * temp4);
+
+					temp3 = roundup_u64(temp3, multiplier);
+					temp4 = roundup_u64(temp4, multiplier);
+					dp_ctrl_get_extra_req_bytes
+						(resulting_valid_tmp,
+						new_valid_boundary_link,
+						temp3, temp4,
+						&extra_req_bytes_is_neg,
+						&result,
+						(original_ratio * tu_size));
+					extra_req_bytes_new_tmp
+						= div64_ul(result, multiplier);
+					if ((extra_req_bytes_is_neg)
+						&& (extra_req_bytes_new_tmp
+							> 1))
+						extra_req_bytes_new_tmp
+						= extra_req_bytes_new_tmp - 1;
+					if (extra_req_bytes_new_tmp == 0)
+						extra_req_bytes_new_tmp = 1;
+					extra_pclk_cycles_tmp =
+						(u64)(extra_req_bytes_new_tmp
+						      * 8 * multiplier) / bpp;
+					extra_pclk_cycles_tmp /= multiplier;
+
+					if (extra_pclk_cycles_tmp <= 0)
+						extra_pclk_cycles_tmp = 1;
+					extra_pclk_cycles_in_lclk_tmp =
+						roundup_u64(div64_u64(
+							extra_pclk_cycles_tmp
+							* lclk * multiplier,
+							pclk), multiplier);
+					extra_pclk_cycles_in_lclk_tmp
+						/= multiplier;
+					filler_size_tmp = roundup_u64(
+						(tu_size * multiplier *
+						new_valid_boundary_link),
+						multiplier);
+					filler_size_tmp /= multiplier;
+					lower_filler_size_tmp =
+						filler_size_tmp + 1;
+					if (extra_req_bytes_is_neg)
+						temp3 = (extra_req_bytes_new_tmp
+						> extra_pclk_cycles_in_lclk_tmp
+						? extra_pclk_cycles_in_lclk_tmp
+						: extra_req_bytes_new_tmp);
+					else
+						temp3 = (extra_req_bytes_new_tmp
+						> extra_pclk_cycles_in_lclk_tmp
+						? extra_req_bytes_new_tmp :
+						extra_pclk_cycles_in_lclk_tmp);
+
+					temp4 = lower_filler_size_tmp
+						+ extra_buffer_margin;
+					if (extra_req_bytes_is_neg)
+						delay_start_link_tmp
+							= (temp3 >= temp4)
+							? (temp3 - temp4)
+							: (temp4 - temp3);
+					else
+						delay_start_link_tmp
+							= temp3 + temp4;
+
+					min_hblank_tmp = (int)div64_u64(
+						roundup_u64(
+						div64_u64(delay_start_link_tmp
+						* pclk * multiplier, lclk),
+						multiplier), multiplier)
+						+ hblank_margin;
+
+					if (((even_distribution == 1)
+						|| ((even_distribution_bf == 0)
+						&& (even_distribution_legacy
+								== 0)))
+						&& !n_err_neg && !nn_err_neg
+						&& n_n_err < err
+						&& (n_n_err < diff_abs
+						|| (dp_brute_force == 1))
+						&& (new_valid_boundary_link
+									- 1) > 0
+						&& (h_blank >=
+							(u32)min_hblank_tmp)) {
+						upper_bdry_cnt =
+							i_upper_bdry_cnt;
+						lower_bdry_cnt =
+							i_lower_bdry_cnt;
+						err = n_n_err;
+						boundary_moderation_en = 1;
+						tu_size_desired = tu_size;
+						valid_boundary_link =
+							new_valid_boundary_link;
+						effective_valid_recorded
+							= effective_valid;
+						delay_start_link
+							= delay_start_link_tmp;
+						filler_size = filler_size_tmp;
+						min_hblank = min_hblank_tmp;
+						n_tus = n_tus_tmp;
+						even_distribution_bf = 1;
+
+						pr_debug("upper_bdry_cnt=%d, lower_boundary_cnt=%d, err=%lld, 

tu_size_desired=%d, valid_boundary_link=%d, effective_valid=%lld\n",

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +31 -0
+							upper_bdry_cnt,
+							lower_bdry_cnt, err,
+							tu_size_desired,
+							valid_boundary_link,
+							effective_valid);
+					}
+				}
+			}
+		}
+
+		if (boundary_moderation_en == 1) {
+			resulting_valid = (u64)(upper_bdry_cnt
+					*valid_boundary_link + lower_bdry_cnt
+					* (valid_boundary_link - 1))
+					/ (upper_bdry_cnt + lower_bdry_cnt);
+			ratio_by_tu = original_ratio * tu_size_desired;
+			valid_lower_boundary_link =
+				(valid_boundary_link / multiplier) - 1;
+
+			tu_size_minus1 = tu_size_desired - 1;
+			even_distribution_bf = 1;
+			valid_boundary_link /= multiplier;
+			pr_debug("Info: Boundary_moderation enabled\n");
+		}
+	}
+
+	min_hblank = ((int) roundup_u64(div64_u64(delay_start_link * pclk
+			* multiplier, lclk), multiplier))
+			/ multiplier + hblank_margin;
+	if (h_blank < (u32)min_hblank) {
+		pr_debug(" WARNING: run_idx=%d Programmed h_blank %d is smaller 

than the min_hblank %d supported.\n",

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +11 -0
+					run_idx, h_blank, min_hblank);
+	}
+
+	if (fifo_empty)	{
+		tu_size_minus1 = 31;
+		valid_boundary_link = 32;
+		delay_start_link = 0;
+		boundary_moderation_en = 0;
+	}
+
+	pr_debug("tu_size_minus1=%d valid_boundary_link=%d 

delay_start_link=%d boundary_moderation_en=%d\n upper_boundary_cnt=%d lower_boundary_cnt=%d valid_lower_boundary_link=%d min_hblank=%d\n",

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +31 -0
+		tu_size_minus1, valid_boundary_link, delay_start_link,
+		boundary_moderation_en, upper_bdry_cnt, lower_bdry_cnt,
+		valid_lower_boundary_link, min_hblank);
+
+	tu_table->valid_boundary_link = valid_boundary_link;
+	tu_table->delay_start_link = delay_start_link;
+	tu_table->boundary_moderation_en = boundary_moderation_en;
+	tu_table->valid_lower_boundary_link = valid_lower_boundary_link;
+	tu_table->upper_boundary_count = upper_bdry_cnt;
+	tu_table->lower_boundary_count = lower_bdry_cnt;
+	tu_table->tu_size_minus1 = tu_size_minus1;
+}
+
+static void dp_ctrl_setup_tr_unit(struct dp_ctrl_private *ctrl)
+{
+	u32 dp_tu = 0x0;
+	u32 valid_boundary = 0x0;
+	u32 valid_boundary2 = 0x0;
+	struct dp_vc_tu_mapping_table tu_calc_table;
+
+	dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
+
+	dp_tu |= tu_calc_table.tu_size_minus1;
+	valid_boundary |= tu_calc_table.valid_boundary_link;
+	valid_boundary |= (tu_calc_table.delay_start_link << 16);
+
+	valid_boundary2 |= (tu_calc_table.valid_lower_boundary_link << 1);
+	valid_boundary2 |= (tu_calc_table.upper_boundary_count << 16);
+	valid_boundary2 |= (tu_calc_table.lower_boundary_count << 20);
+
+	if (tu_calc_table.boundary_moderation_en)

drivers/gpu/drm/msm/dp/dp_ctrl.c line 719

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+		valid_boundary2 |= BIT(0);
+
+	pr_debug("dp_tu=0x%x, valid_boundary=0x%x, valid_boundary2=0x%x\n",
+			dp_tu, valid_boundary, valid_boundary2);
+
+	ctrl->catalog->dp_tu = dp_tu;
+	ctrl->catalog->valid_boundary = valid_boundary;
+	ctrl->catalog->valid_boundary2 = valid_boundary2;
+
+	ctrl->catalog->update_transfer_unit(ctrl->catalog);

Again here, if you just call the function directly, you can avoid the callback. If you add function arguments, you can avoid having to store dp_tu/valid_boundary/
valid_boundary2 entirely.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 726

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0
+}
+
+static int dp_ctrl_wait4video_ready(struct dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+
+	ret = wait_for_completion_timeout(&ctrl->video_comp, HZ / 2);

Break out the timeout into a #define

drivers/gpu/drm/msm/dp/dp_ctrl.c line 732

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+	if (ret <= 0) {
+		pr_err("Link Train timedout\n");
+		ret = -EINVAL;
+	}
+
+	return ret;

You're not checking the return value at the callsite.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 736

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+}
+
+static int dp_ctrl_update_sink_vx_px(struct dp_ctrl_private *ctrl,
+				     u32 voltage_level, u32 pre_emphasis_level)

I don't think this needs to be a function, just move it all into dp_ctrl_update_vx_px.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 745

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0
+{
+	int i;
+	u8 buf[4];
+	u32 max_level_reached = 0;
+
+	if (voltage_level == DP_LINK_VOLTAGE_MAX) {
+		pr_debug("max. voltage swing level reached %d\n",
+				voltage_level);
+		max_level_reached |= BIT(2);

DP_TRAIN_MAX_SWING_REACHED

drivers/gpu/drm/msm/dp/dp_ctrl.c line 751

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+	}
+
+	if (pre_emphasis_level == DP_LINK_PRE_EMPHASIS_MAX) {
+		pr_debug("max. pre-emphasis level reached %d\n",
+				pre_emphasis_level);
+		max_level_reached  |= BIT(5);

DP_TRAIN_MAX_PRE_EMPHASIS_REACHED

drivers/gpu/drm/msm/dp/dp_ctrl.c line 754

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+	}
+
+	pre_emphasis_level <<= 3;

This is DP_TRAIN_PRE_EMPHASIS_SHIFT, but I'm guessing you aren't using the DP_TRAIN_PRE_EMPH_LEVEL_* values when you set p_level. So the right way to fix this is to use those #defines and get rid of this shift.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 756

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
+
+	for (i = 0; i < 4; i++)

You shouldn't assume 4 lanes here, use drm_dp_link->num_lanes

drivers/gpu/drm/msm/dp/dp_ctrl.c line 760

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+		buf[i] = voltage_level | pre_emphasis_level | max_level_reached;
+
+	pr_debug("sink: p|v=0x%x\n", voltage_level | pre_emphasis_level);
+	return drm_dp_dpcd_write(ctrl->aux->drm_aux, 0x103, buf, 4);

s/0x103/DP_TRAINING_LANE0_SET/ and s/4/drm_dp_link->num_lanes/

Also, this will return number of bytes transmitted, not (0 || -errno).

drivers/gpu/drm/msm/dp/dp_ctrl.c line 771

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +11 -0
+}
+
+static void dp_ctrl_update_vx_px(struct dp_ctrl_private *ctrl)
+{
+	struct dp_link *link = ctrl->link;
+
+	ctrl->catalog->update_vx_px(ctrl->catalog,
+		link->phy_params.v_level, link->phy_params.p_level);
+
+	dp_ctrl_update_sink_vx_px(ctrl, link->phy_params.v_level,
+		link->phy_params.p_level);

Fortunately (or unfortunately), the return value isn't checked. So please check the return value.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 777

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+}
+
+static void dp_ctrl_train_pattern_set(struct dp_ctrl_private *ctrl,
+		u8 pattern)
+{
+	u8 buf[4];

Why 4?

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+
+	pr_debug("sink: pattern=%x\n", pattern);
+
+	buf[0] = pattern;
+	drm_dp_dpcd_write(ctrl->aux->drm_aux, DP_TRAINING_PATTERN_SET, buf, 

1);

Check the return value of this and alll drm_dp_dpcd_(read|write) calls.

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+}
+
+static int dp_ctrl_read_link_status(struct dp_ctrl_private *ctrl,
+				    u8 *link_status)
+{
+	int ret = 0, len;

drivers/gpu/drm/msm/dp/dp_ctrl.c line 798

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+	u32 const offset = DP_LANE_ALIGN_STATUS_UPDATED - DP_LANE0_1_STATUS;
+	u32 link_status_read_max_retries = 100;
+
+	while (--link_status_read_max_retries) {
+		len = drm_dp_dpcd_read_link_status(ctrl->aux->drm_aux,
+			link_status);
+		if (len != DP_LINK_STATUS_SIZE) {
+			pr_err("DP link status read failed, err: %d\n", len);
+			ret = len;
+			break;

Just return directly here. You can also just drop len and use ret (or drop ret and use len).

drivers/gpu/drm/msm/dp/dp_ctrl.c line 802

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+		}
+
+		if (!(link_status[offset] & DP_LINK_STATUS_UPDATED))
+			break;

And return 0 directly here

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+	}
+
+	return ret;

Here you're returning successful in the timeout case :( Once you convert the above
to direct returns, this can become return -ETIMEDOUT;

I think you should also drop the number of retries drastically.

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+}
+
+static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl)
+{
+	int tries, old_v_level, ret = 0;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	int const maximum_retries = 5;
+
+	dp_ctrl_state_ctrl(ctrl, 0);
+	/* Make sure to clear the current pattern before starting a new one 

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c line 818

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+	wmb();
+
+	ctrl->catalog->set_pattern(ctrl->catalog, 0x01);

#define that bit please

drivers/gpu/drm/msm/dp/dp_ctrl.c line 820

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
+	dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
+		DP_LINK_SCRAMBLING_DISABLE); /* train_1 */

the train_1 comment isn't needed.

drivers/gpu/drm/msm/dp/dp_ctrl.c line 825

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+	dp_ctrl_update_vx_px(ctrl);
+
+	tries = 0;
+	old_v_level = ctrl->link->phy_params.v_level;
+	while (1) {

Instead of unbounded, this should be:

        for (tries = 0; tries < maximum_retries; tries++) {

You'll need to s/break/return ret/ in the rest of the loop and move the timeout error to the bottom of the function

drivers/gpu/drm/msm/dp/dp_ctrl.c line 829

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0
+		drm_dp_link_train_clock_recovery_delay(ctrl->panel->dpcd);
+
+		ret = dp_ctrl_read_link_status(ctrl, link_status);
+		if (ret)
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Since DP_LINK_VOLTAGE_MAX == DP_LINK_VOLTAGE_LEVEL_2, you'll end up not retrying LEVEL_2 at all.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 56 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +53 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TRAINING_PATTERN_DISABLE

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 26 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_RECOVERED_CLOCK_OUT_EN);

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

for (tries = 0; tries < maximum_retries; tries++)

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_SET_ANSI_8B10B

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Drop the hand-rolled ctrl->panel->link_info and use drm_dp_link_probe to fill in drm_dp_link.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_MAIN_LINK_CHANNEL_CODING_SET,

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print ret

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

this should be debug loglevel

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print ret

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

debug loglevel

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comments re: wmb

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

train)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This can fit on one line

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

All of the "goto end"'s can be replaced with "return ret", then delete the end label.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You should really protect sink_request with a lock, it's racy. I'm trying to catch the race conditions while I review, but I'd urge you to audit the driver for other places that need locking.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of adding the label, just wrap the reset and train calls in an if (train) {} block.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

"we have to first _do_ a..."

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value please

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 24 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of doing all of this work, just store pointers to the link and pixel clock when you parse the dt. That way you can just access them directly in dp_ctrl_enable_mainlink_clocks.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function isn't necesary (even less so when all of the catalog abstractions are gone).

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 63 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +63 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

For this, you should use the DP_DPCD_QUIRK_CONSTANT_N quirk and drm_dp_has_quirk() instead.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Return value should be checked

Below you have:

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Between the disable and enable, so you should probably have that here too?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Do you really want to continue here? Seems like you could get into an infinite loop pretty easily in the -EINVAL case.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Are you guaranteed that this doesn't race with other idle_comp uses?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

The do/while is a bit awkward, especially since it starts with a conditional block that can't possibly be true on the first iteration. How about:

	for (tries = 0; tries < max_tries; tries++) {
		ctrl->catalog->phy_lane_cfg(ctrl->catalog,
			ctrl->orientation, ctrl->link->link_params.lane_count);

		/*
		 * Disable and re-enable the mainlink clock since the
		 * link clock might have been adjusted as part of the
		 * link maintenance.
		 */
		ret = dp_ctrl_disable_mainlink_clocks(ctrl);
                if (ret)
                        return ret;

		ret = dp_ctrl_enable_mainlink_clocks(ctrl);
		if (ret)
			return ret;

		dp_ctrl_configure_source_params(ctrl);

		ctrl->catalog->config_msa(ctrl->catalog,
			drm_dp_bw_code_to_link_rate(
			ctrl->link->link_params.bw_code),
			ctrl->pixel_rate, dp_ctrl_use_fixed_nvid(ctrl));

		reinit_completion(&ctrl->idle_comp);

		ret = dp_ctrl_setup_main_link(ctrl, true);
		if (ret != -EAGAIN)
                        return ret;

                /* try with lower link rate */
                dp_ctrl_link_rate_down_shift(ctrl);

                ctrl->catalog->mainlink_ctrl(ctrl->catalog, false);
	}

        return -ETIMEDOUT;

There's a lot of similarity between this code and dp_ctrl_on. If the code were shared, we wouldn't have the missing 20ms delay above. So can you please pull the common bits which [re-]initialize the link into a helper function that you call from both functions?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

It's nice that we return a value here, but it's never checked by our callers :(

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This and the "end" debug statements should be removed

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

s/related/ralated/

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please propagate errors instead of swallowing them.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

success = pattern_requested == DP_LINK_QUAL_PATTERN_11_D10_2;

Same can be done below.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 21 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I feel like you should return success (or a ret). As it is, this doesn't do much.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Downgrade to DEBUG level please

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +15 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think this function goes away with all of the catalog stuff removed.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This amount is excessive, 5 times should suffice (unless you have data that suggests otherwise).

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Should this be a #define in drm_dp_helper?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why is this needed over is_connected? It seems like if you had proper locking around is_connected (which I think is necessary), you could just acquire the lock
and try the training. If it fails b/c someone unplugged the cable, that's quite Ok.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +29 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Are you guaranteed that this doesn't race with other idle_comp uses (or other dp_ctrl_on callers)?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 19 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return code

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return code

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comment here as in dp_ctrl_link_maintenance(), we should pull out the common code and put it in a helper.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is racy, sink_request could change between the check above and here.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please remove

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 19 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

readl/wmb nit

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check and propagate return value

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This should return the isr instead of store it in ctrl->catalog->isr, since that could potentially be overwritten after this function acks the current interrupts.

(Also, it's only used in this function, so there's no need to store it). One you remove the catalog indirection, hopefully there will be a bunch of these cases that become clear.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

As mentioned above, just call the completions directly.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 62 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +62 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Once again, these functions can be deleted. Just store the _necessary_ data in a central struct (with substructs as necessary) and call functions directly.

drivers/gpu/drm/msm/dp/dp_ctrl.h

Quoted 43 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +2 -0
new file mode 100644
index 0000000..6ab221a

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_ctrl.h new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comment as catalog, these should just be functions to be called directly.

drivers/gpu/drm/msm/dp/dp_ctrl.h

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This struct is not needed, function arguments work just as well.

drivers/gpu/drm/msm/dp/dp_debug.c

Quoted 391 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +5 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_debug.c new file +2 -0
new file mode 100644
index 0000000..5c0a8ce

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_debug.c new file +180 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*len)

drivers/gpu/drm/msm/dp/dp_debug.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*user_buff,

drivers/gpu/drm/msm/dp/dp_debug.c new file +171 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

edid, hpd, and connected can all be deleted. They're provided by core.

AFAICT, you can also infer the information from dp_debug, so I think you can just drop this entire file.

drivers/gpu/drm/msm/dp/dp_debug.h

Quoted 222 lines
drivers/gpu/drm/msm/dp/dp_debug.c new file +62 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*panel,

drivers/gpu/drm/msm/dp/dp_debug.c new file +69 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_debug.h new file +2 -0
new file mode 100644
index 0000000..a6480e1

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_debug.h new file +28 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

data
+ *
+ * @dev: device instance of the caller
+ * @panel: instance of panel module
+ * @usbpd: instance of usbpd module
+ * @link: instance of link module
+ * @connector: double pointer to display connector
+ * return: pointer to allocated debug module data
+ *
+ * This function sets up the debug module and provides a way
+ * for debugfs input to be communicated with existing modules
+ */
+struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,

drivers/gpu/drm/msm/dp/dp_debug.h new file +15 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*panel,

drivers/gpu/drm/msm/dp/dp_debug.h new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Drop this too

drivers/gpu/drm/msm/dp/dp_display.c

Quoted 220 lines
drivers/gpu/drm/msm/dp/dp_debug.h new file +2 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_display.c new file +2 -0
new file mode 100644
index 0000000..8c98399

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_display.c new file +131 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*master,

drivers/gpu/drm/msm/dp/dp_display.c new file +35 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp)

drivers/gpu/drm/msm/dp/dp_display.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp,

drivers/gpu/drm/msm/dp/dp_display.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function is called from a few different threads with no locking. It seems like there's good opportunity for is_connected and notification_comp to get out of sync.

Additionally, is_connected is set to true before the function returns (and enable has been completed). So is that going to cause problems when we call detect/get_modes where is_connected == true and the hw is not up?

Perhaps I'm misreading this function, but it seems like the plan is to block until userspace has been notified and does a full modeset (ie: enable)? If that is the case, we usually don't want to have the hardware lit up until it's actually going to be used. In these cases, we'll wrap get_modes in enable/disable (with proper locking), and wait for modeset to leave it on.

drivers/gpu/drm/msm/dp/dp_display.c

Quoted 700 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +168 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp)

drivers/gpu/drm/msm/dp/dp_display.c new file +70 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp)

drivers/gpu/drm/msm/dp/dp_display.c new file +135 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +30 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

mode_pclk_khz)

drivers/gpu/drm/msm/dp/dp_display.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +30 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +18 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +80 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These 2 functions are never used, and as such g_dp_display is never used. AFAICT, the callback hooks linked from g_dp_display also aren't called from anywhere else. So can you just dump these functions, the struct, and all of the unused callback hooks?

Quoted 42 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +42 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_display.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dev,

drivers/gpu/drm/msm/dp/dp_display.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called?

This is called from dpu_kms.c. The changes from DPU will be dependent on these changes.

Quoted 401 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 232 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +38 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_display.h new file +2 -0
new file mode 100644
index 0000000..ca5eae5

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_display.h new file +42 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0
new file mode 100644
index 0000000..64d6449

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_drm.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*drm_mode,

drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_mode->hsync_end;

drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_mode->vsync_end;

drivers/gpu/drm/msm/dp/dp_drm.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp_mode,

drivers/gpu/drm/msm/dp/dp_drm.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_mode->timing.h_back_porch;

drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_mode->timing.v_back_porch;

drivers/gpu/drm/msm/dp/dp_drm.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use the drm modes directly and delete these functions.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 160 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_drm.c new file +143 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I'm not convinced you need any of this. The only advantage a bridge gets you is to be involved in modeset. However the only thing you do in modeset is save the mode (which is only used in enable). So why not just use the mode from the crtc's state when encoder->enable is called?

Quoted 2 lines

That allows you to delete all of the bridge stuff here.

Will keep enable, disable and mode_set func ops and remove the remaining ops. Please let me know if you still have concerns with these func ops.

Quoted 4,707 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*display)

drivers/gpu/drm/msm/dp/dp_drm.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This isn't called from anything?

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

connected
+ * @connector: Pointer to drm connector structure
+ * @force: Force detect setting from drm framework
+ * Returns: Connector 'is connected' status
+ */
+static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,

drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

connector_status_unknown;

drivers/gpu/drm/msm/dp/dp_drm.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

no need for dp_conn, just do

        dp = to_dp_connector(conn)->dp_display;

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is always true.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

detect() should never do work, please remove.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why?

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Once dp_conn is devm managed, you can just remove this function and set .destroy to drm_connector_cleanup

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called?

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_mode_probed_add()
+ * @connector: Pointer to drm connector structure
+ * Returns: Number of modes added
+ */

drivers/gpu/drm/msm/dp/dp_drm.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

When you get rid of dp_display_mode, please use the stack for the new drm_display_mode

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why is only one mode returned?

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_drm.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This can also return -errno, you should check for that too.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_drm.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why continue if you know you failed?

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You shouldn't overwrite these.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This shouldn't be an error

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 88 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +63 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

is valid
+ * @connector: Pointer to drm connector structure
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+static enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector,

drivers/gpu/drm/msm/dp/dp_drm.c new file +18 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think the value of max_pclk_khz is racy, you'll probably want to audit its use.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please drop this.

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

So I guess I was wrong when I said none of the g_dp_display functions are being used. I'm still unsure where they're set, perhaps there's some missing code. At any rate, what's the benefit of sticking all of that work into an abstract callback hook when it only has one implementation and one callsite.

All of that code can move in here (and the same goes for the other callbacks (move the code where it's used).

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_atomic_helper_connector_duplicate_state,

drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_connector_helper_funcs = {

drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp_display)

drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Use devm_kzalloc (you've already got a memory leak if drm_connector_init fails below).

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

&dp_connector_funcs,

drivers/gpu/drm/msm/dp/dp_drm.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These lines don't extend to 80 chars

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These are already false by virtue of kzalloc

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 122 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_drm.h new file +2 -0
new file mode 100644
index 0000000..efbc1be

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_drm.h new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

initialization steps
+ * @connector: Pointer to drm connector structure
+ * @display: Pointer to private display handle
+ * Returns: Zero on success
+ */
+int dp_connector_post_init(struct drm_connector *connector, void *display);

drivers/gpu/drm/msm/dp/dp_drm.h new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp_display);

drivers/gpu/drm/msm/dp/dp_drm.h new file +3 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0
new file mode 100644
index 0000000..635c13b

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_extcon.c new file +33 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this used?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 26 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +26 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

No need to have this just for one debug statement, just print the enum value with %d below.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 23 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +23 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called from?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please #define hardcoded values

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

All of the values in cap->port seem to be hardcoded, so why not just use the #define's directly where applicable?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only multi_func, hpd_high, and hpd_irq are used out of this struct. Can you cull the values down? hpd_irq is also only set to its hardcoded value, so just use that value directly where applicable.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function is also unused

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 44 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +44 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just return -EINVAL and get rid of the error label and rc.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If forced_disconnect is always !dp_usbpd->hpd_high, why not just use !dp_usbpd->hpd_high directly?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Do you need locking in this function/file?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

        return (property.intval) ? 2 : 4;

and delete lanes

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Can fit on 1 line

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Can fit on 1 line, plus remove all () from this, they're not needed.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This part is a bit confusing, you add a helper function to get the lanes, and interpret the USB_SS property to return 2 vs. 4, but then immediately convert that back into what the USB_SS property returns. Instead, remove the helper function and read USB_SS directly here.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I feel like this can never be false anyways, but you're not using either of these members in the conditional block. So why not just call dp_extcon_connect unconditionally?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*extcon_priv)

drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

create_singlethread_workqueue("drm_dp_extcon");

What's the benefit of using a dedicated workqueue instead of the system wq?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function can't fail, so it should return void. In fact, this really doesn't need to be a separate function, roll it into dp_extcon_register().

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 23 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +23 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Yikes, this doesn't look like an error!

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_usbpd);

drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

extcon_priv->extcon,

drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why keep going and create the workqueue if we have no notifier? This should probably be a return.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

return ret?

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_usbpd);

drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

extcon_priv->extcon,

drivers/gpu/drm/msm/dp/dp_extcon.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*cb)

drivers/gpu/drm/msm/dp/dp_extcon.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 21 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This label isn't useful, return directly where applicable.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 168 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +16 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_extcon.h new file +2 -0
new file mode 100644
index 0000000..1f83a18

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_extcon.h new file +91 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*cb);

drivers/gpu/drm/msm/dp/dp_extcon.h new file +7 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0
new file mode 100644
index 0000000..5ab1efc

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These should be in drm_dp_helper.h

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 335 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +67 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

addr)

drivers/gpu/drm/msm/dp/dp_link.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +65 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +80 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

from DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the audio link pattern parameters.
+ */
+static int dp_link_parse_audio_pattern_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +81 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

No need for this, just print the value in the debug statement.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 34 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +34 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same thing here, just remove this and print the enum value.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

pass-by-value doesn't need const same comment applies elsewhere, please sweep the code for other instances.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If you're going to check len < 2, you should probably also check len > 2 to prevent overflow. At this point, len can really only be 2, so you can just remove
it entirely as an argument.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comment here rt bounds checking

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 31 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Putting aside the uninformative names, these dp_link_parse_timing_params* can be combined into one pretty easily, like:

static int dp_link_read_u32(struct dp_link_private *link, unsigned int offset,
u32 *val, int num_bytes)

{
        int i;
        ssize_t ret;
        __be32 tmp_val;

        for (i = 0; num_bytes > 0; i += sizeof(*val)) {
                int to_read = min(sizeof(tmp_val), num_bytes);

                tmp_val = 0;
                ret = drm_dp_dpcd_read(link->aux->drm_aux, offset + i, 
&tmp_val,
                                       to_read);
                if (rlen < 0) {
                        /* print error message here */
                        return rlen;
                }
                val[i] = be32_to_cpu(tmp_val);
                num_bytes -= to_read;
        }
        return 0;
}

If you need to strip off the first bit, do it from the caller.

I didn't compile or test this, so it might need tweaking, but you get the idea.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

from DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the video link pattern and the link
+ * bit depth requested by the sink and, and if the values parsed are valid.
+ */
+static int dp_link_parse_video_pattern_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why do you need data and bp? I think you only need one.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +25 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_link.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This mask isolates one bit from data

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

and this function returns true if the input is 0 || 1

So remove this code, and remove dp_link_is_dynamic_range_valid.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

And now you can just assign this directly. You should probably stay consistent and store the value shifted like the other values you're storing.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 118 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_h_total);

drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_v_total);

drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_h_start);

drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_v_start);

drivers/gpu/drm/msm/dp/dp_link.c new file +32 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_h_width);

drivers/gpu/drm/msm/dp/dp_link.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TEST_REFRESH_RATE_NUMERATOR,

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

(DP_TEST_REFRESH_RATE_NUMERATOR)\n");

drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of sprinkling all of these pr_debug messages around, just have one big debug at the end to print everything.

Quoted 1 line

+exit:

This label isn't useful, just return directly above

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

parameters from
+ * DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
+ * count (Byte 0x220), and if these values parse are valid.
+ */
+static int dp_link_parse_link_training_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You don't need both bp and data

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use 1 directly below.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 28 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +28 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_MAX_LANE_COUNT_MASK

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You might also want to data against max lanes

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

return directly above and remove exit + ret;

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 31 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

phy_test_pattern_sel)

drivers/gpu/drm/msm/dp/dp_link.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

being
+ * requested.
+ */
+static int dp_link_parse_phy_test_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only need one of these.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use 1 below

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

FWIW, drm_dp_dpcd_read will return either len or an -errno. Partial reads return -EPROTO. So instead of checking that rlen < param_len, you can just do rlen < 0.

Please also change all of the 1-byte reads over to using drm_dp_dpcd_readb().

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print and return rlen.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just embed that code here.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove label/ret and return directly

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove this and just print the enum.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link request
+ * @link: link requested by the sink
+ *
+ * Returns true if the requested link is a permitted audio/video link.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Should you be masking link to isolate these bits?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

And once you mask the value, just check if any of the bits are set instead of enumerating all possible values.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

supported
+ * @test_requested: link requested by the sink
+ *
+ * Returns true if the requested link is supported.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think this all equates to:

	return test_requested != DP_TEST_LINK_FAUX_PATTERN;

and in that case, you can just remove this function and insert that condition in the if statement below.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This doesn't warrant its own function. Also, should this be & instead of ==?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

sink
+ * @link: Display Port Driver data
+ *
+ * Parses the DPCD to check if an automated link is requested (Byte 0x201),
+ * and what type of link automation is being requested (Byte 0x218).
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only need 1 of bp/data

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Not needed, use drm_dp_dpcd_readb()

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Print error. This goes for other failure messages in this file.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 35 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +33 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

data);

drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If test_requested is only used in the scope of this function, just use a local and pass it around. If test_requested is used outside the scope of this function, you need locking.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check the return here or it could get stomped

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check the return here or it could get stomped

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Should fit on 1 line, I think

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check the return here or it could get stomped

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

/*

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

send

drivers/gpu/drm/msm/dp/dp_link.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Content
+ * Protection enabled.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_dp_dpcd_readb

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print ret

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

return ret

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

cp_ready is only used in this function, please don't store stuff like this beyond its scope.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Don't need this comment

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

No need for dedicated function

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 30 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

requests
+ * @link: Display Port link data
+ *
+ * This function will handle new link training requests that are initiated by
+ * the sink. In particular, it will update the requested lane count and link
+ * link rate, and then trigger the link retraining procedure.
+ *
+ * The function will return 0 if a link training request has been processed,
+ * otherwise it will return -EINVAL.
+ */
+static int dp_link_process_link_training_request(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->request.test_lane_count;

drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Should be using dp helper structs for this stuff

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +18 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I strongly suspect you should have locking protecting test_response.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is another racy function where you could be simultaneously powering up and powering down the link. So you might want some locking.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 19 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

unneeded (). You could probably reword to fit on one line too

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

checksum)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_dp_dpcd_readb. I'll stop commenting on these, just please go through and convert all 1-byte reads/writes

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check and return the result

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only need one of these

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_dp_dpcd_readb

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_ADJUST_REQUEST_LANE0_1,

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print error

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 40 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_ADJUST_REQUEST_LANE2_3,

drivers/gpu/drm/msm/dp/dp_link.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think you can use drm_dp_get_adjust_request_voltage() for all of this.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove

Quoted 1 line

+end:

return directly everywhere and remove end & ret

Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

requests
+ * @link: Display Port Driver data
+ *
+ * This function will handle new phy link pattern requests that are initiated
+ * by the sink. The function will return 0 if a phy link pattern has been
+ * processed, otherwise it will return -EINVAL.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 1 line

{

Is test_requested always expected to have this value populated when dp_link_process_request()?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use these values directly instead of adding more locals.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These should be debug level prints

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->request.test_lane_count;

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value and propagate it.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

int r)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I don't think you're really supposed to reach into the link_status like this. How about adding a new helper to check for DP_LINK_STATUS_UPDATED and one for DP_DOWNSTREAM_PORT_STATUS_CHANGED?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

updates
+ * @link: Display Port link module data
+ *
+ * This function will check for changes in the link status, e.g. clock
+ * recovery done on all lanes, and trigger link training if there is a
+ * failure/error on the link.
+ *
+ * The function will return 0 if the a link status update has been processed,
+ * otherwise it will return -EINVAL.
+ */
+static int dp_link_process_link_status_update(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_LANE_ALIGN_STATUS_UPDATED) &

drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Can you please fix the alignment here, it's tough to read.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

&

drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

It seems like this is running in a separate thread from where prev_sink_count is set, potential race here?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

	return link->prev_sink_count != link->dp_link.sink_count.count;

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

status changes
+ * @link: Display Port Driver data
+ *
+ * This function will handle downstream port updates that are initiated by
+ * the sink. If the downstream port status has changed, the EDID is read via
+ * AUX.
+ *
+ * The function will return 0 if a downstream port update has been
+ * processed, otherwise it will return -EINVAL.
+ */
+static int dp_link_process_ds_port_status_change(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just embed the contents of is_ds_port_status_changed here, no need for 2 funcs

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 41 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

pattern request
+ * @link: Display Port link module's data
+ *
+ * This function will handle a new video pattern request that are initiated by
+ * the sink. This is acheieved by first sending a disconnect notification to
+ * the sink followed by a subsequent connect notification to the user modules,
+ * where it is expected that the user modules would draw the required link
+ * pattern.
+ */
+static int dp_link_process_video_pattern_request(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just do this directly in dp_link_process_request and get rid of this function

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 33 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

pattern request
+ * @link: Display Port link module data
+ *
+ * This function will handle a new audio pattern request that is initiated by
+ * the sink. This is acheieved by sending the necessary secondary data packets
+ * to the sink. It is expected that any simulatenous requests for video
+ * patterns will be handled before the audio pattern is sent to the sink.
+ */
+static int dp_link_process_audio_pattern_request(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 33 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +33 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

memset?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 73 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

to HIGH
+ * (including cases when there are back to back HPD IRQ HIGH) indicating
+ * the start of a new link training request or sink status update.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +61 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove exit & ret, just return values directly

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

s/CEA_VESA/RGB_VESA?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

s/nd/and/

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If you store the value shifted like I suggested, you don't have to do this switch (which really should be an if anyways since the range is 0:1).

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link_status)

drivers/gpu/drm/msm/dp/dp_link.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You can combine these loops and do the work at once (check out intel_get_adjust_train)

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 45 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

within

drivers/gpu/drm/msm/dp/dp_link.c new file +29 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

req)

drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is a stub, why do this?

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Further, why have a stub at all? The hook is never called, so delete it all please.

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

bpp)

drivers/gpu/drm/msm/dp/dp_link.c new file +25 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

AFAICT tbd corresponds to a SoC register value, as opposed to the DPCD value. It's a happy coincidence that they're the same, however I think you should use a separate msm-specific #define instead of the drm_dp_helper values.

drivers/gpu/drm/msm/dp/dp_link.h

Quoted 89 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +52 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_link.h new file +2 -0
new file mode 100644
index 0000000..6d6ef43

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_link.h new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TRAIN_VOLTAGE_SWING_*

drivers/gpu/drm/msm/dp/dp_link.h

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_link.h new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TRAIN_PRE_EMPH*

drivers/gpu/drm/msm/dp/dp_link.h

Quoted 48 lines
drivers/gpu/drm/msm/dp/dp_link.h new file +48 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Use drm_dp_link

drivers/gpu/drm/msm/dp/dp_link.h

Quoted 47 lines
drivers/gpu/drm/msm/dp/dp_link.h new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

phy_test_pattern_sel)

drivers/gpu/drm/msm/dp/dp_link.h new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is only used for debug statements, just remove it and print the enum as an int. This will let you remove DP_LINK_ENUM_STR as well.

drivers/gpu/drm/msm/dp/dp_link.h

Quoted 35 lines
drivers/gpu/drm/msm/dp/dp_link.h new file +35 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just return directly from each case.

drivers/gpu/drm/msm/dp/dp_panel.c

Quoted 49 lines
drivers/gpu/drm/msm/dp/dp_link.h new file +19 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_panel.c new file +2 -0
new file mode 100644
index 0000000..e497b44

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

13 lines not shown · raw message

drivers/gpu/drm/msm/dp/dp_panel.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

1,335 lines not shown · raw message

Quoted 2 lines

2 lines not shown · raw message

1,722 lines not shown · raw message

Parts of this message are not shown here. View the raw message.

A message that is not in the archive (sent off-list or not yet received): 84612eefebedc1eae1756505d6639b01-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

#14 lore raw

Re: [DPU PATCH 2/3] drm/msm/dp: add displayPort driver support

Quoted 11 lines · On Mon, Nov 19, 2018 at 02:34:53PM -0800, [email protected] wrote:
Quoted 9 lines · Sean Paul
Quoted 7 lines · Chandan Uddaraju

Add the needed displayPort files to enable DP driver on msm target.

"dp_display" module is the main module that calls into other sub-modules. "dp_drm" file represents the interface between DRM framework and DP driver.

Quoted 3 lines

Hello Sean,
I had few queries regarding your comments. Shared my queries below. Please share your feedback.

/snip

Quoted 19 lines
Quoted 19 lines

drivers/gpu/drm/msm/dp/dp_aux.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_aux.c new file +0 -0
new file mode 100644
index 0000000..00b82c2
@@ -0,0 +1,570 @@

/snip

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +0 -0
new file mode 100644
index 0000000..0c300ed

/snip

Quoted 8 lines
Quoted 3 lines

I didn't really review the dp_aux.* files as-is. Please convert to using drm_dp_aux and I'll take another look.

Please correct me if I am wrong. Looks like you are suggesting to use most of the drm_dp_aux struct variable
instead of what we have defined locally.

Correct

/snip

Quoted 28 lines
Quoted 19 lines
Quoted 19 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +19 -0
+	struct dp_catalog_ctrl ctrl = {
+		.state_ctrl     = dp_catalog_ctrl_state_ctrl,
+		.config_ctrl    = dp_catalog_ctrl_config_ctrl,
+		.lane_mapping   = dp_catalog_ctrl_lane_mapping,
+		.mainlink_ctrl  = dp_catalog_ctrl_mainlink_ctrl,
+		.config_misc    = dp_catalog_ctrl_config_misc,
+		.config_msa     = dp_catalog_ctrl_config_msa,
+		.set_pattern    = dp_catalog_ctrl_set_pattern,
+		.reset          = dp_catalog_ctrl_reset,
+		.usb_reset      = dp_catalog_ctrl_usb_reset,
+		.mainlink_ready = dp_catalog_ctrl_mainlink_ready,
+		.enable_irq     = dp_catalog_ctrl_enable_irq,
+		.hpd_config     = dp_catalog_ctrl_hpd_config,
+		.phy_reset      = dp_catalog_ctrl_phy_reset,
+		.phy_lane_cfg   = dp_catalog_ctrl_phy_lane_cfg,
+		.update_vx_px   = dp_catalog_ctrl_update_vx_px,
+		.get_interrupt  = dp_catalog_ctrl_get_interrupt,
+		.update_transfer_unit = dp_catalog_ctrl_update_transfer_unit,
+		.send_phy_pattern    = dp_catalog_ctrl_send_phy_pattern,
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_aux.h new file +1 -0
+		.read_phy_pattern = dp_catalog_ctrl_read_phy_pattern,

So, what's the benefit of adding the catalog abstractions? Do you ever have
multiple/alternate implementations of a catalog? It doesn't seem like it. You
should just remove all of the catalog overhead and call the functions directly.

Quoted 9 lines

We use catalog abstractions for two different reasons:
1. To support multiple hardware since these implementations are hardware specific.
2. To virtualize DP hardware.

Our internal hardware already supports multiple chips. We want to keep these abstractions to
make the code consistent between upstream and internal implementation.

I'm not sure how this differs from having a common header/function declarations and multiple definitions in a .c gated by CONFIG_*? Ideally even this wouldn't be necessary since hw changes are either incremental and can be done more precisely than wholesale changing the implementation.

If you want to virtualize, you can do the CONFIG_* thing. However since that's not going upstream, you can carry the Kconfig/Makefile change in your downstream.

All of these abstractions add thousands of lines of code, extra files, and multiple levels of indirection. IMO, I don't think the benefits outweigh the costs.

/snip

Quoted 76 lines
Quoted 71 lines
Quoted 57 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +57 -0
+static void dp_ctrl_calc_tu_parameters(struct dp_ctrl_private *ctrl,
+				       struct dp_vc_tu_mapping_table *tu_table)
+{
+	u32 multiplier = 1000000;
+	u64 pclk, lclk;
+	u8 bpp, ln_cnt;
+	int run_idx = 0;
+	u32 lwidth, h_blank;
+	u32 fifo_empty = 0;
+	u32 ratio_scale = 1001;
+	u64 temp, ratio, original_ratio;
+	u64 temp2, reminder;
+	u64 temp3, temp4, result = 0;
+
+	u64 err = multiplier;
+	u64 n_err = 0, n_n_err = 0;
+	bool n_err_neg, nn_err_neg;
+	u8 hblank_margin = 16;
+
+	u8 tu_size, tu_size_desired = 0, tu_size_minus1;
+	int valid_boundary_link;
+	u64 resulting_valid;
+	u64 total_valid;
+	u64 effective_valid;
+	u64 effective_valid_recorded;
+	int n_tus;
+	int n_tus_per_lane;
+	int paired_tus;
+	int remainder_tus;
+	int remainder_tus_upper, remainder_tus_lower;
+	int extra_bytes;
+	int filler_size;
+	int delay_start_link;
+	int boundary_moderation_en = 0;
+	int upper_bdry_cnt = 0;
+	int lower_bdry_cnt = 0;
+	int i_upper_bdry_cnt = 0;
+	int i_lower_bdry_cnt = 0;
+	int valid_lower_boundary_link = 0;
+	int even_distribution_bf = 0;
+	int even_distribution_legacy = 0;
+	int even_distribution = 0;
+	int min_hblank = 0;
+	int extra_pclk_cycles;
+	u8 extra_pclk_cycle_delay = 4;
+	int extra_pclk_cycles_in_link_clk;
+	u64 ratio_by_tu;
+	u64 average_valid2;
+	u64 extra_buffer_margin;
+	int new_valid_boundary_link;
+
+	u64 resulting_valid_tmp;
+	u64 ratio_by_tu_tmp;
+	int n_tus_tmp;
+	int extra_pclk_cycles_tmp;
+	int extra_pclk_cycles_in_lclk_tmp;
+	int extra_req_bytes_new_tmp;

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +10 -0
+	int filler_size_tmp;
+	int lower_filler_size_tmp;
+	int delay_start_link_tmp;
+	int min_hblank_tmp = 0;
+	bool extra_req_bytes_is_neg = false;
+	struct dp_panel_info *pinfo = &ctrl->panel->pinfo;
+
+	u8 dp_brute_force = 1;
+	u64 brute_force_threshold = 10;
+	u64 diff_abs;

76 stack vars and ~450 lines must be a new record somewhere :)

Quoted 4 lines

I'm going to skip reviewing this function and let you split/simplify/reduce it.
Please just make it more readable (comments, docs, helper functions, etc).

Quoted 4 lines

Yes, will try to split this function as modular as possible. JFYI, this function is IP/hardware specific implementation. It might not be possible
to provide lot of comments to make is understandable.

Ok, please do what you can to simplify/split and add a comment that this is magic from the HW team.

/snip

Quoted 9 lines
Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 3 lines

+int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,

drivers/gpu/drm/msm/dp/dp_aux.h new file +1 -0
+			struct drm_encoder *encoder)

Where is this called?

This is called from dpu_kms.c. The changes from DPU will be dependent on these changes.

Hmm, is that code missing? I don't see this function being called anywhere in this patch.

/snip

Quoted 17 lines
Quoted 17 lines

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +8 -0
+static const struct drm_bridge_funcs dp_bridge_ops = {
+	.mode_fixup   = dp_bridge_mode_fixup,
+	.pre_enable   = dp_bridge_pre_enable,
+	.enable       = dp_bridge_enable,
+	.disable      = dp_bridge_disable,
+	.post_disable = dp_bridge_post_disable,
+	.mode_set     = dp_bridge_mode_set,
+};

I'm not convinced you need any of this. The only advantage a bridge gets you is
to be involved in modeset. However the only thing you do in modeset is save the
mode (which is only used in enable). So why not just use the mode from the
crtc's state when encoder->enable is called?

Quoted 6 lines
Quoted 2 lines

That allows you to delete all of the bridge stuff here.

Will keep enable, disable and mode_set func ops and remove the remaining ops.
Please let me know if you still have concerns with these func ops.

Why not remove all of it and call this code from the encoder's enable function? You shouldn't need a bridge at all.

/snip

Quoted 33 lines
Quoted 33 lines
Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +11 -0
+static int dp_parser_init_clk_data(struct dp_parser *parser)
+{
+	int num_clk = 0, i = 0, rc = 0;
+	int core_clk_count = 0, ctrl_clk_count = 0;
+	const char *core_clk = "core";
+	const char *ctrl_clk = "ctrl";
+	const char *clk_name;
+	struct device *dev = &parser->pdev->dev;
+	struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
+	struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
+

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +10 -0
+	num_clk = of_property_count_strings(dev->of_node, "clock-names");
+	if (num_clk <= 0) {
+		pr_err("no clocks are defined\n");
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	for (i = 0; i < num_clk; i++) {
+		of_property_read_string_index(dev->of_node,
+				"clock-names", i, &clk_name);

Check return value

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +6 -0
+
+		if (dp_parser_check_prefix(core_clk, clk_name))
+			core_clk_count++;
+
+		if (dp_parser_check_prefix(ctrl_clk, clk_name))
+			ctrl_clk_count++;

Just use "core"/"ctrl" directly here.

Quoted 7 lines
Quoted 3 lines

Have you considered just having 2 clock lists? That would avoid having to do
this.

I am not clear on what you are suggesting? We currently have two clock-lists (core & ctrl).

I meant in the dt bindings. Instead of one clocks list, could you split into core and ctrl? That way you wouldn't have to parse based on name.

/snip

Quoted 13 lines
Quoted 2 lines

---- START hmmmm

I didn't understand, can you please provide more details regarding "START" and "END".

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +5 -0
+	struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
+	struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
+
+	core_power = &parser->mp[DP_CORE_PM];
+	ctrl_power = &parser->mp[DP_CTRL_PM];

---- END hmmmm

You assign core_power and ctrl_power in the declaration and then immediately assign the value again.

/snip

Signature · 5 lines
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#15 lore raw

Re: [DPU PATCH 2/3] drm/msm/dp: add displayPort driver support

In reply to Sean Paul
Quoted 9 lines · Sean Paul
Quoted 7 lines · Chandan Uddaraju

Add the needed displayPort files to enable DP driver on msm target.

"dp_display" module is the main module that calls into other sub-modules. "dp_drm" file represents the interface between DRM framework and DP driver.

Hello Sean,
I have responded to all of your comments and queries. I have specified the comments addressed in V2 patch series and what I have missed that will be fixed in V3.

Quoted 98 lines

Hi Chandan,
A few themes which I've pointed out below, but want to call out at the top so it's obvious.

- Please remove all superfluous NULL checks at the beginning of functions.
Included in this is reflowing initialization of variables and
checking that
return types still make sense (ie: if a function's only error path is
the NULL
check, make it void).
- Please remove all of the new callbacks and just call functions directly. This
should also get rid of the _get/_put functions that allocate/set them
up
- Please consolidate state structs into one struct with a few substructs,
there's too much state right now.
- Please #define hardcoded values
- Instead of sprinkling wmb() everywhere, use readl/writel instead of *_relaxed
- There are a bunch of races that I found, please audit the code and remove
races with locks as necessary
- I tried to catch as much dead code as possible, please audit the rest for
unused structs/variables/functions/etc
- Use drm dp helper structs for link parameter storage

Quoted 68 lines
---
 drivers/gpu/drm/msm/Kconfig                 |    9 +
 drivers/gpu/drm/msm/Makefile                |   15 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c |  206 ++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h |   44 +
 drivers/gpu/drm/msm/dp/dp_aux.c             |  570 ++++++++++
 drivers/gpu/drm/msm/dp/dp_aux.h             |   44 +
 drivers/gpu/drm/msm/dp/dp_catalog.c         | 1188 
++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_catalog.h         |  144 +++
 drivers/gpu/drm/msm/dp/dp_ctrl.c            | 1475 
+++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_ctrl.h            |   50 +
 drivers/gpu/drm/msm/dp/dp_debug.c           |  507 +++++++++
 drivers/gpu/drm/msm/dp/dp_debug.h           |   81 ++
 drivers/gpu/drm/msm/dp/dp_display.c         |  977 +++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_display.h         |   55 +
 drivers/gpu/drm/msm/dp/dp_drm.c             |  542 ++++++++++
 drivers/gpu/drm/msm/dp/dp_drm.h             |   52 +
 drivers/gpu/drm/msm/dp/dp_extcon.c          |  400 +++++++
 drivers/gpu/drm/msm/dp/dp_extcon.h          |  111 ++
 drivers/gpu/drm/msm/dp/dp_link.c            | 1549 
+++++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_link.h            |  184 ++++
 drivers/gpu/drm/msm/dp/dp_panel.c           |  624 +++++++++++
 drivers/gpu/drm/msm/dp/dp_panel.h           |  121 +++
 drivers/gpu/drm/msm/dp/dp_parser.c          |  679 ++++++++++++
 drivers/gpu/drm/msm/dp/dp_parser.h          |  205 ++++
 drivers/gpu/drm/msm/dp/dp_power.c           |  599 +++++++++++
 drivers/gpu/drm/msm/dp/dp_power.h           |   57 +
 drivers/gpu/drm/msm/dp/dp_reg.h             |  357 ++++++
 drivers/gpu/drm/msm/msm_drv.c               |    2 +
 drivers/gpu/drm/msm/msm_drv.h               |   22 +
 include/drm/drm_dp_helper.h                 |   19 +
 30 files changed, 10887 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_display.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_display.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_drm.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_drm.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_extcon.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_extcon.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_link.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_link.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_panel.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_panel.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_parser.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_parser.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_power.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_power.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_reg.h
drivers/gpu/drm/msm/Kconfig +0 -0
index 843a9d4..c363f24 100644
@@ -49,6 +49,15 @@ config DRM_MSM_HDMI_HDCP
 	help
 	  Choose this option to enable HDCP state machine
 
Quoted 12 lines

drivers/gpu/drm/msm/Kconfig config DRM_MSM_HDMI_HDCP · line 60

Quoted 9 lines
drivers/gpu/drm/msm/Kconfig +9 -0
+config DRM_MSM_DP
+	bool "Enable DP support in MSM DRM driver"
+	depends on DRM_MSM
+	default n
+	help
+	  Compile in support for DP driver in msm drm
+	  driver. DP external display support is enabled
+	  through this config option. It can be primary or
+	  secondary display on device.

Why are these line lengths so short? You can go to 80 columns. Please also add an empty line here.

Fixed this in V2.

Quoted 19 lines
Quoted 19 lines
drivers/gpu/drm/msm/Kconfig +0 -0
 config DRM_MSM_DSI
 	bool "Enable DSI support in MSM DRM driver"
 	depends on DRM_MSM
drivers/gpu/drm/msm/Makefile +1 -0
index 19ab521..765a8d8 100644
@@ -2,6 +2,7 @@
 ccflags-y := -Idrivers/gpu/drm/msm
 ccflags-y += -Idrivers/gpu/drm/msm/disp/dpu1
 ccflags-$(CONFIG_DRM_MSM_DSI) += -Idrivers/gpu/drm/msm/dsi
+ccflags-$(CONFIG_DRM_MSM_DP) += -Idrivers/gpu/drm/msm/dp
 
 msm-y := \
 	adreno/adreno_device.o \
@@ -93,7 +94,19 @@ msm-y := \
 	msm_submitqueue.o
 
Quoted 7 lines

drivers/gpu/drm/msm/Makefile msm-y := \ · line 98

Quoted 4 lines
drivers/gpu/drm/msm/Makefile +2 -1
 msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
-			  disp/dpu1/dpu_dbg.o
+			  disp/dpu1/dpu_dbg.o \
+			  dp/dp_debug.o

Does this compile if CONFIG_DEBUG_FS is selected, but not CONFIG_DRM_MSM_DP?

Fixed this in V2. DEBUG file is removed in V2.

Quoted 5 lines
Quoted 5 lines
drivers/gpu/drm/msm/Makefile +5 -0
+
+msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_extcon.o \
+	dp/dp_parser.o \
+	dp/dp_power.o \
+	dp/dp_catalog.o \
Quoted 9 lines

drivers/gpu/drm/msm/Makefile msm-y := \ · line 109

Quoted 6 lines
drivers/gpu/drm/msm/Makefile +6 -0
+	dp/dp_aux.o \
+	dp/dp_panel.o \
+	dp/dp_link.o \
+	dp/dp_ctrl.o \
+	dp/dp_display.o \
+	dp/dp_drm.o

The rest of the file has files in alphabetical order, this should too.

Fixed this in V2.

Quoted 17 lines
Quoted 17 lines
drivers/gpu/drm/msm/Makefile +0 -0
 msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
 msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +2 -0
index 790d39f..0f53a15 100644
@@ -14,10 +14,216 @@
 #include <linux/clk.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
 #include <linux/delay.h>
 
 #include "dpu_io_util.h"
 
Quoted 16 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 34

Quoted 13 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +12 -0
+static struct resource *msm_dss_get_res_byname(struct platform_device 
 *pdev,
+					       unsigned int type,
+					       const char *name)
+{
+	struct resource *res = NULL;
+
+	res = platform_get_resource_byname(pdev, type, name);
+	if (!res)
+		DEV_ERR("%s: '%s' resource not found\n", __func__, name);
+
+	return res;
+} /* msm_dss_get_res_byname */

Why don't you just call platform_get_resource_byname directly?

Fixed this in V2.

Quoted 12 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 41

Quoted 7 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +7 -0
+
+int msm_dss_ioremap_byname(struct platform_device *pdev,
+			   struct dss_io_data *io_data, const char *name)
+{
+	struct resource *res = NULL;
+
+	if (!pdev || !io_data) {

Given that we've been aggressively trying to get rid of these superfluous checks, I'm not thrilled that they're being re-introduced. Can you please go through the patch and remove all of the unnecessary checks?

Most of them have been removed in V2 patch. Only kept the checks where necessary. Will go through the files again and see if I have missed anything. (For V3)

Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +4 -0
+		DEV_ERR("%pS->%s: invalid input\n",
+			__builtin_return_address(0), __func__);
+		return -EINVAL;
+	}
Quoted 9 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 50

Quoted 5 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +5 -0
+
+	res = msm_dss_get_res_byname(pdev, IORESOURCE_MEM, name);
+	if (!res) {
+		DEV_ERR("%pS->%s: '%s' msm_dss_get_res_byname failed\n",
+			__builtin_return_address(0), __func__, name);

Yet another error format :) Could we please stick with one of DPU_ERROR, DRM_ERROR, or DRM_DEV_ERROR?

All of the error formats has been move to DRM_ERROR in v2.

Quoted 23 lines
Quoted 23 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +23 -0
+		return -ENODEV;
+	}
+
+	io_data->len = (u32)resource_size(res);
+	io_data->base = ioremap(res->start, io_data->len);
+	if (!io_data->base) {
+		DEV_ERR("%pS->%s: '%s' ioremap failed\n",
+			__builtin_return_address(0), __func__, name);
+		return -EIO;
+	}
+
+	return 0;
+} /* msm_dss_ioremap_byname */
+
+void msm_dss_iounmap(struct dss_io_data *io_data)
+{
+	if (!io_data) {
+		DEV_ERR("%pS->%s: invalid input\n",
+			__builtin_return_address(0), __func__);
+		return;
+	}
+
+	if (io_data->base) {
Quoted 9 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 78

Quoted 5 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +5 -0
+		iounmap(io_data->base);
+		io_data->base = NULL;
+	}
+	io_data->len = 0;
+} /* msm_dss_iounmap */

These two functions are only used in dp_parser.c, why not just make them static functions there?

These two functions are moved to dp_parser.c in V2.

Quoted 7 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 81

Quoted 3 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +3 -0
+
+int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
+			int num_vreg, int config)

This should be 2 functions, one for initialization and one for deinitializing, the 2 paths don't share any code, so there's no need to combine them.

Added 2 functions in V2 patch. (The functions are moved to dp_power.c file)

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +6 -0
+{
+	int i = 0, rc = 0;
+	struct dss_vreg *curr_vreg = NULL;
+	enum dss_vreg_type type;
+
+	if (!in_vreg || !num_vreg)
Quoted 8 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 93

Quoted 6 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +6 -0
+		return rc;
+
+	if (config) {
+		for (i = 0; i < num_vreg; i++) {
+			curr_vreg = &in_vreg[i];
+			curr_vreg->vreg = regulator_get(dev,

Use devm_* please

Fixed in V2.

Quoted 6 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 95

Quoted 3 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +2 -0
+				curr_vreg->vreg_name);
+			rc = PTR_RET(curr_vreg->vreg);

PTR_RET is deprecated. The pattern for this is usually:

Quoted 7 lines
                        ptr = some_func();
                        if (IS_ERR_OR_NULL(ptr)) {
                                ...
                                rc = PTR_ERR(ptr);
                                goto fail_label:
                        }

Didn't address this comment. Will fix this in V3 patch.

Quoted 125 lines
Quoted 125 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +124 -0
+			if (rc) {
+				DEV_ERR("%pS->%s: %s get failed. rc=%d\n",
+					 __builtin_return_address(0), __func__,
+					 curr_vreg->vreg_name, rc);
+				curr_vreg->vreg = NULL;
+				goto vreg_get_fail;
+			}
+			type = (regulator_count_voltages(curr_vreg->vreg) > 0)
+					? DSS_REG_LDO : DSS_REG_VS;
+			if (type == DSS_REG_LDO) {
+				rc = regulator_set_voltage(
+					curr_vreg->vreg,
+					curr_vreg->min_voltage,
+					curr_vreg->max_voltage);
+				if (rc < 0) {
+					DEV_ERR("%pS->%s: %s set vltg fail\n",
+						__builtin_return_address(0),
+						__func__,
+						curr_vreg->vreg_name);
+					goto vreg_set_voltage_fail;
+				}
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--) {
+			curr_vreg = &in_vreg[i];
+			if (curr_vreg->vreg) {
+				type = (regulator_count_voltages(
+					curr_vreg->vreg) > 0)
+					? DSS_REG_LDO : DSS_REG_VS;
+				if (type == DSS_REG_LDO) {
+					regulator_set_voltage(curr_vreg->vreg,
+						0, curr_vreg->max_voltage);
+				}
+				regulator_put(curr_vreg->vreg);
+				curr_vreg->vreg = NULL;
+			}
+		}
+	}
+	return 0;
+
+vreg_unconfig:
+if (type == DSS_REG_LDO)
+	regulator_set_load(curr_vreg->vreg, 0);
+
+vreg_set_voltage_fail:
+	regulator_put(curr_vreg->vreg);
+	curr_vreg->vreg = NULL;
+
+vreg_get_fail:
+	for (i--; i >= 0; i--) {
+		curr_vreg = &in_vreg[i];
+		type = (regulator_count_voltages(curr_vreg->vreg) > 0)
+			? DSS_REG_LDO : DSS_REG_VS;
+		goto vreg_unconfig;
+	}
+	return rc;
+} /* msm_dss_config_vreg */
+
+int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int 
 enable)
+{
+	int i = 0, rc = 0;
+	bool need_sleep;
+
+	if (enable) {
+		for (i = 0; i < num_vreg; i++) {
+			rc = PTR_RET(in_vreg[i].vreg);
+			if (rc) {
+				DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
+					__builtin_return_address(0), __func__,
+					in_vreg[i].vreg_name, rc);
+				goto vreg_set_opt_mode_fail;
+			}
+			need_sleep = !regulator_is_enabled(in_vreg[i].vreg);
+			if (in_vreg[i].pre_on_sleep && need_sleep)
+				usleep_range(in_vreg[i].pre_on_sleep * 1000,
+					in_vreg[i].pre_on_sleep * 1000);
+			rc = regulator_set_load(in_vreg[i].vreg,
+				in_vreg[i].enable_load);
+			if (rc < 0) {
+				DEV_ERR("%pS->%s: %s set opt m fail\n",
+					__builtin_return_address(0), __func__,
+					in_vreg[i].vreg_name);
+				goto vreg_set_opt_mode_fail;
+			}
+			rc = regulator_enable(in_vreg[i].vreg);
+			if (in_vreg[i].post_on_sleep && need_sleep)
+				usleep_range(in_vreg[i].post_on_sleep * 1000,
+					in_vreg[i].post_on_sleep * 1000);
+			if (rc < 0) {
+				DEV_ERR("%pS->%s: %s enable failed\n",
+					__builtin_return_address(0), __func__,
+					in_vreg[i].vreg_name);
+				goto disable_vreg;
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--) {
+			if (in_vreg[i].pre_off_sleep)
+				usleep_range(in_vreg[i].pre_off_sleep * 1000,
+					in_vreg[i].pre_off_sleep * 1000);
+			regulator_set_load(in_vreg[i].vreg,
+				in_vreg[i].disable_load);
+			regulator_disable(in_vreg[i].vreg);
+			if (in_vreg[i].post_off_sleep)
+				usleep_range(in_vreg[i].post_off_sleep * 1000,
+					in_vreg[i].post_off_sleep * 1000);
+		}
+	}
+	return rc;
+
+disable_vreg:
+	regulator_set_load(in_vreg[i].vreg, in_vreg[i].disable_load);
+
+vreg_set_opt_mode_fail:
+	for (i--; i >= 0; i--) {
+		if (in_vreg[i].pre_off_sleep)
+			usleep_range(in_vreg[i].pre_off_sleep * 1000,
+				in_vreg[i].pre_off_sleep * 1000);
+		regulator_set_load(in_vreg[i].vreg,
+			in_vreg[i].disable_load);
+		regulator_disable(in_vreg[i].vreg);
+		if (in_vreg[i].post_off_sleep)
+			usleep_range(in_vreg[i].post_off_sleep * 1000,
Quoted 9 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c line 225

Quoted 6 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +6 -0
+				in_vreg[i].post_off_sleep * 1000);
+	}
+
+	return rc;
+} /* msm_dss_enable_vreg */
+

Same question here, but with dp_power.

Fixed this in V2.

Quoted 20 lines
Quoted 20 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +1 -0
+
 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk)

{

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +0 -0
 	int i;
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +1 -0
index bc07381..524b394 100644
@@ -15,6 +15,7 @@
 
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/types.h>
 
 #define DEV_DBG(fmt, args...)   pr_debug(fmt, ##args)
@@ -22,6 +23,39 @@
 #define DEV_WARN(fmt, args...)  pr_warn(fmt, ##args)
 #define DEV_ERR(fmt, args...)   pr_err(fmt, ##args)
 
Quoted 8 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 29

Quoted 4 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
+struct dss_io_data {
+	u32 len;
+	void __iomem *base;
+};

len isn't used anywhere, so this struct can go away. If the struct goes away, you can really simplify (or eliminate msm_dss_ioremap_byname())

We want to keep this since we use len for our internal unit level testing and in simulation mode.

Quoted 9 lines
Quoted 9 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +7 -0
+
+/*
+void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 
 debug);
+u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug);
+void dss_reg_dump(void __iomem *base, u32 len, const char *prefix, 
 u32 debug);
+
+#define DSS_REG_W_ND(io, offset, val)  dss_reg_w(io, offset, val, 
Quoted 9 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 40

Quoted 6 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +1 -0
 false)
+#define DSS_REG_W(io, offset, val)     dss_reg_w(io, offset, val, 

true)

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +3 -0
+#define DSS_REG_R_ND(io, offset)       dss_reg_r(io, offset, false)
+#define DSS_REG_R(io, offset)          dss_reg_r(io, offset, true)
+*/

None of the dss_reg_*/DSS_REG_* functions/macros are used. Please remove.

Removed this in V2.

Quoted 8 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 44

Quoted 5 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
+enum dss_vreg_type {
+	DSS_REG_LDO,
+	DSS_REG_VS,
+};

These are only used in msm_dss_config_vreg(). Please remove.

Will fix this in V3.

Quoted 15 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 50

Quoted 6 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +6 -0
+
+struct dss_vreg {
+	struct regulator *vreg; /* vreg handle */
+	char vreg_name[32];
+	int min_voltage;
+	int max_voltage;

Can't we deduce these from the regulator subsystem with regulator_list_voltage()?

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 52

Quoted 2 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +2 -0
+	int enable_load;
+	int disable_load;

These are really a function of the dp device than the regulator.

Quoted 9 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 56

Quoted 4 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
+	int pre_on_sleep;
+	int post_on_sleep;
+	int pre_off_sleep;
+	int post_off_sleep;

None of these sleep values are set? Also, shouldn't these constraints usually expressed/acted upon in the regulator driver?

Quoted 1 line

+};

Will remove them in V3. These were added as a generic implementation for io_utils. Since we are not going to use them, will remove them for now.

Quoted 4 lines

So if we can remove all of the extra goop around the regulator, then we can get rid of dss_vreg.

Will follow up on vreg APIs and fix them in V3.

Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +3 -0
+
 struct dss_gpio {
 	unsigned int gpio;
 	unsigned int value;
@@ -42,12 +76,22 @@ struct dss_clk {
 };
 
 struct dss_module_power {
+	unsigned int num_vreg;
+	struct dss_vreg *vreg_config;
 	unsigned int num_gpio;
 	struct dss_gpio *gpio_config;
 	unsigned int num_clk;
 	struct dss_clk *clk_config;
 };
 
Quoted 15 lines
Quoted 11 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +8 -0
+int msm_dss_ioremap_byname(struct platform_device *pdev,
+			   struct dss_io_data *io_data, const char *name);
+void msm_dss_iounmap(struct dss_io_data *io_data);
+
+int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
+			int num_vreg, int config);
+int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg,	int 
 enable);
+
 int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int 
 num_clk);
Quoted 1 line

void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);

Why are these msm_dss* functions in dpu_io_util.h?

These functions are moved to specific files in V2.

Quoted 19 lines

drivers/gpu/drm/msm/dp/dp_aux.c

Quoted 8 lines

int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);

drivers/gpu/drm/msm/dp/dp_aux.c new file +0 -0
new file mode 100644
index 0000000..00b82c2
@@ -0,0 +1,570 @@

/snip

drivers/gpu/drm/msm/dp/dp_aux.h

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_aux.h new file +0 -0
new file mode 100644
index 0000000..0c300ed

/snip

Quoted 3 lines

I didn't really review the dp_aux.* files as-is. Please convert to using drm_dp_aux and I'll take another look.

Most of the aux interface already uses drm_dp_aux. We register with drm framework for aux traffic and transfer->call back gets called.

I see that I have missed fixing the hard coded values for register operations for aux transfers. Will fix that in V3.

Quoted 27 lines
Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
new file mode 100644
index 0000000..5818612
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <drm/drm_dp_helper.h>
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 24

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+#include "dp_catalog.h"
+#include "dp_reg.h"
+
+#define DP_GET_MSB(x)	(x >> 8)
+#define DP_GET_LSB(x)	(x & 0xff)

These aren't used anywhere

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 27

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+
+#define dp_read(offset) readl_relaxed((offset))
+#define dp_write(offset, data) writel_relaxed((data), (offset))

These macros aren't useful. I think you'd be much better having a read_/write_ for the different io types, ie:

Quoted 6 lines

static inline u32 dp_read_audio(struct dp_catalog *catalog, u32 offset)

{
        return readl_relaxed(catalog->io->dp_link.base + offset);
}

Then you can remove a ton of boilerplate code below getting base;

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 29

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+#define dp_catalog_get_priv(x) { \

static inline struct dp_catalog_private *dp_catalog_get_priv(...)

{
        ...
}

For inline, we have to use 3 different functions (one each for aux, ctrl and panel). Looking at "type-checking" w.r.t macro, container_of will through an error if its not valid pointer. Please let me know if you still want to change this macro to inline func.

Quoted 15 lines
Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +15 -0
+	struct dp_catalog *dp_catalog; \
+	dp_catalog = container_of(x, struct dp_catalog, x); \
+	catalog = container_of(dp_catalog, struct dp_catalog_private, \
+				dp_catalog); \
+}
+
+#define DP_INTERRUPT_STATUS1 \
+	(DP_INTR_AUX_I2C_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_INTR_MASK1		(DP_INTERRUPT_STATUS1 << 2)
+
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 49

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+#define DP_INTERRUPT_STATUS2 \
+	(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
+	DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
+
+#define DP_INTR_MASK2		(DP_INTERRUPT_STATUS2 << 2)

Can you please rename these to be consistent with each other? DP_INTERRUPT_STATUS2_MASK perhaps?

Fixed in V2.

Quoted 29 lines
Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +28 -0
+
+static u8 const vm_pre_emphasis[4][4] = {
+	{0x00, 0x0B, 0x12, 0xFF},       /* pe0, 0 db */
+	{0x00, 0x0A, 0x12, 0xFF},       /* pe1, 3.5 db */
+	{0x00, 0x0C, 0xFF, 0xFF},       /* pe2, 6.0 db */
+	{0xFF, 0xFF, 0xFF, 0xFF}        /* pe3, 9.5 db */
+};
+
+/* voltage swing, 0.2v and 1.0v are not support */
+static u8 const vm_voltage_swing[4][4] = {
+	{0x07, 0x0F, 0x14, 0xFF}, /* sw0, 0.4v  */
+	{0x11, 0x1D, 0x1F, 0xFF}, /* sw1, 0.6 v */
+	{0x18, 0x1F, 0xFF, 0xFF}, /* sw1, 0.8 v */
+	{0xFF, 0xFF, 0xFF, 0xFF}  /* sw1, 1.2 v, optional */
+};
+
+/* audio related catalog functions */
+struct dp_catalog_private {
+	struct device *dev;
+	struct dp_io *io;
+
+	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
+	struct dp_catalog dp_catalog;
+};
+
+/* aux related catalog functions */
+static u32 dp_catalog_aux_read_data(struct dp_catalog_aux *aux)
+{
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 82

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");

And another logging type, please remove pr_* and use a DPU_/DRM_/DRM_DEV_ variant.

Fixed in V2.

Quoted 13 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 91

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	return dp_read(base + DP_AUX_DATA);
+end:
+	return 0;

... or you could just return directly in the if above and remove the label :) Same comment applies below.

Quoted 1 line

Also, probably shouldn't return 0 in an error case.

Forgot to fix this. Will fix in V3.

Quoted 4 lines

Then again, I'm guessing hitting the NULL case is likely impossible, so you can probably remove all of the machinery around checking !aux.

Removed most of the arg null checks except few APIs where unit-testing/simulator-mode is used.

Quoted 81 lines
Quoted 81 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +43 -0
+}
+
+static int dp_catalog_aux_write_data(struct dp_catalog_aux *aux)
+{
+	int rc = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	dp_write(base + DP_AUX_DATA, aux->data);
+end:
+	return rc;
+}
+
+static int dp_catalog_aux_write_trans(struct dp_catalog_aux *aux)
+{
+	int rc = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	dp_write(base + DP_AUX_TRANS_CTRL, aux->data);
+end:
+	return rc;
+}
+
+static int dp_catalog_aux_clear_trans(struct dp_catalog_aux *aux, 

bool read)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +37 -0
+{
+	int rc = 0;
+	u32 data = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	if (read) {
+		data = dp_read(base + DP_AUX_TRANS_CTRL);
+		data &= ~BIT(9);
+		dp_write(base + DP_AUX_TRANS_CTRL, data);
+	} else {
+		dp_write(base + DP_AUX_TRANS_CTRL, 0);
+	}
+end:
+	return rc;
+}
+
+static void dp_catalog_aux_reset(struct dp_catalog_aux *aux)
+{
+	u32 aux_ctrl;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		return;
+	}
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 177

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
+	aux_ctrl = dp_read(base + DP_AUX_CTRL);
+
+	aux_ctrl |= BIT(1);

What's BIT(1)? Can you please #define it?

Fixed in V2. Most of the hardcoded values are fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 179

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_AUX_CTRL, aux_ctrl);
+	usleep_range(1000, 1010); /* h/w recommended delay */

10us diff is right on the line of enough delay to make usleep_range worth it. I'd recommend increasing to 100us to increase the chance of the scheduler being able to batch this wakeup with another.

Fixed in V2.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 183

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+
+	aux_ctrl &= ~BIT(1);
+	dp_write(base + DP_AUX_CTRL, aux_ctrl);
+	wmb();

Can you just use writel for these cases instead of using _relaxed and then wmb()? This applies elsewhere too.

Fixed in V2.

Quoted 17 lines
Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_aux_enable(struct dp_catalog_aux *aux, bool 

enable)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +13 -0
+{
+	u32 aux_ctrl;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+	base = catalog->io->dp_aux.base;
+
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 205

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+	aux_ctrl = dp_read(base + DP_AUX_CTRL);
+
+	if (enable) {
+		dp_write(base + DP_TIMEOUT_COUNT, 0xffff);
+		dp_write(base + DP_AUX_LIMITS, 0xffff);
+		aux_ctrl |= BIT(0);

Please #define BIT(0)

Fixed in V2.

Quoted 40 lines
Quoted 40 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +39 -0
+	} else {
+		aux_ctrl &= ~BIT(0);
+	}
+
+	dp_write(base + DP_AUX_CTRL, aux_ctrl);
+}
+
+static void dp_catalog_aux_update_cfg(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type)
+{
+	struct dp_catalog_private *catalog;
+	u32 new_index = 0, current_index = 0;
+
+	if (!aux || !cfg || (type >= PHY_AUX_CFG_MAX)) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+
+	current_index = cfg[type].current_index;
+	new_index = (current_index + 1) % cfg[type].cfg_cnt;
+	pr_debug("Updating %s from 0x%08x to 0x%08x\n",
+		dp_phy_aux_config_type_to_string(type),
+	cfg[type].lut[current_index], cfg[type].lut[new_index]);
+
+	dp_write(catalog->io->phy_io.base + cfg[type].offset,
+			cfg[type].lut[new_index]);
+	cfg[type].current_index = new_index;
+}
+
+static void dp_catalog_aux_setup(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg)
+{
+	struct dp_catalog_private *catalog;
+	int i = 0;
+
+	if (!aux || !cfg) {
+		pr_err("invalid input\n");
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 250

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+
+	dp_write(catalog->io->phy_io.base + DP_PHY_PD_CTL, 0x65);

What's 0x65? Please #define

Fixed in V2.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 255

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	wmb(); /* make sure PD programming happened */
+
+	/* Turn on BIAS current for PHY/PLL */
+	dp_write(catalog->io->dp_pll_io.base +
+		QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1b);

Same here for 0x1b. I'm going to stop mentioning this, please audit the driver for other instances of hardcoded values (like this and the one at the end of this function) and break them out into meaningful #defines.

Fixed in V2.

Quoted 138 lines
Quoted 125 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +11 -0
+
+	/* DP AUX CFG register programming */
+	for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
+		pr_debug("%s: offset=0x%08x, value=0x%08x\n",
+			dp_phy_aux_config_type_to_string(i),
+			cfg[i].offset, cfg[i].lut[cfg[i].current_index]);
+		dp_write(catalog->io->phy_io.base + cfg[i].offset,
+			cfg[i].lut[cfg[i].current_index]);
+	}
+
+	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_INTERRUPT_MASK, 

0x1F);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_aux_get_irq(struct dp_catalog_aux *aux, bool 

cmd_busy)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +23 -0
+{
+	u32 ack;
+	struct dp_catalog_private *catalog;
+	void __iomem *ahb_base;
+
+	if (!aux) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(aux);
+	ahb_base = catalog->io->dp_ahb.base;
+
+	aux->isr = dp_read(ahb_base + DP_INTR_STATUS);
+	aux->isr &= ~DP_INTR_MASK1;
+	ack = aux->isr & DP_INTERRUPT_STATUS1;
+	ack <<= 1;
+	ack |= DP_INTR_MASK1;
+	dp_write(ahb_base + DP_INTR_STATUS, ack);
+}
+
+/* controller related catalog functions */
+static void dp_catalog_ctrl_update_transfer_unit(struct 

dp_catalog_ctrl *ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +18 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_VALID_BOUNDARY, ctrl->valid_boundary);
+	dp_write(base + DP_TU, ctrl->dp_tu);
+	dp_write(base + DP_VALID_BOUNDARY_2, ctrl->valid_boundary2);
+}
+
+static void dp_catalog_ctrl_state_ctrl(struct dp_catalog_ctrl *ctrl, 

u32 state)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_STATE_CTRL, state);
+}
+
+static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl, 

u32 cfg)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +18 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *link_base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	link_base = catalog->io->dp_link.base;
+
+	pr_debug("DP_CONFIGURATION_CTRL=0x%x\n", cfg);
+
+	dp_write(link_base + DP_CONFIGURATION_CTRL, cfg);
+}
+
+static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_LOGICAL2PHYSICAL_LANE_MAPPING, 0xe4);
+}
+
+static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +13 -0
+						bool enable)
+{
+	u32 mainlink_ctrl;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 383

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	if (enable) {
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000000);
+		wmb(); /* make sure mainlink is turned off before reset */
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000002);
+		wmb(); /* make sure mainlink entered reset */
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000000);
+		wmb(); /* make sure mainlink reset done */
+		dp_write(base + DP_MAINLINK_CTRL, 0x02000001);
+		wmb(); /* make sure mainlink turned on */

Same comments here re: readl vs readl_relaxed + wmb

Quoted 2 lines

Please #define the bits you're setting.

Fixed in V2.

Quoted 28 lines
Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +14 -0
+	} else {
+		mainlink_ctrl = dp_read(base + DP_MAINLINK_CTRL);
+		mainlink_ctrl &= ~BIT(0);
+		dp_write(base + DP_MAINLINK_CTRL, mainlink_ctrl);
+	}
+}
+
+static void dp_catalog_ctrl_config_misc(struct dp_catalog_ctrl *ctrl,
+					u32 cc, u32 tb)
+{
+	u32 misc_val;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 407

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	misc_val = dp_read(base + DP_MISC1_MISC0);
+	misc_val |= cc;

Should you mask this so it doesn't stomp areas it shouldn't?

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 408

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	misc_val |= (tb << 5);

Parentheses are unnecessary

Fixed in V2.

Quoted 77 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	misc_val |= BIT(0); /* Configure clock to synchronous mode */
+
+	pr_debug("misc settings = 0x%x\n", misc_val);
+	dp_write(base + DP_MISC1_MISC0, misc_val);

drivers/gpu/drm/msm/dp/dp_catalog.c line 422

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+}
+
+static void dp_catalog_ctrl_config_msa(struct dp_catalog_ctrl *ctrl,
+					u32 rate, u32 stream_rate_khz,
+					bool fixed_nvid)
+{
+	u32 pixel_m, pixel_n;
+	u32 mvid, nvid;
+	u64 mvid_calc;
+	u32 const nvid_fixed = 0x8000;

You should pull this out into a #define in drm_dp_helper.h and use the new define in the i915 driver (in a separate patch) as well as here.

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +37 -0
+	u32 const link_rate_hbr2 = 540000;
+	u32 const link_rate_hbr3 = 810000;
+	struct dp_catalog_private *catalog;
+	void __iomem *base_cc, *base_ctrl;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	if (fixed_nvid) {
+		pr_debug("use fixed NVID=0x%x\n", nvid_fixed);
+		nvid = nvid_fixed;
+
+		pr_debug("link rate=%dkbps, stream_rate_khz=%uKhz",
+			rate, stream_rate_khz);
+
+		/*
+		 * For intermediate results, use 64 bit arithmetic to avoid
+		 * loss of precision.
+		 */
+		mvid_calc = (u64) stream_rate_khz * nvid;
+		mvid_calc = div_u64(mvid_calc, rate);
+
+		/*
+		 * truncate back to 32 bits as this final divided value will
+		 * always be within the range of a 32 bit unsigned int.
+		 */
+		mvid = (u32) mvid_calc;
+	} else {
+		base_cc = catalog->io->dp_cc_io.base;
+
+		pixel_m = dp_read(base_cc + MMSS_DP_PIXEL_M);
+		pixel_n = dp_read(base_cc + MMSS_DP_PIXEL_N);
+		pr_debug("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 469

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		mvid = (pixel_m & 0xFFFF) * 5;
+		nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+
+		pr_debug("rate = %d\n", rate);
+
+		if (link_rate_hbr2 == rate)
+			nvid *= 2;
+
+		if (link_rate_hbr3 == rate)
+			nvid *= 3;
                switch (drm_dp_bw_code_to_link_rate(rate)) {
                case DP_LINK_BW_5_4:
                        nvid *= 2;
                        break;
                case DP_LINK_BW_8_1:
                        nvid *= 3;
                        break;
                default:
                        break;
                }
Quoted 2 lines

And remove link_rate_hbr* above.

Somehow missed this function. Will fix this function in V3.

Quoted 30 lines
Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+	}
+
+	base_ctrl = catalog->io->dp_link.base;
+	pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
+	dp_write(base_ctrl + DP_SOFTWARE_MVID, mvid);
+	dp_write(base_ctrl + DP_SOFTWARE_NVID, nvid);
+}
+
+static void dp_catalog_ctrl_set_pattern(struct dp_catalog_ctrl *ctrl,
+					u32 pattern)
+{
+	int bit, cnt = 10;
+	u32 data;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 495

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	bit = 1;
+	bit <<= (pattern - 1);
        bit = BIT(pattern - 1);
Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 500

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	pr_debug("hw: bit=%d train=%d\n", bit, pattern);
+	dp_write(base + DP_STATE_CTRL, bit);
+
+	bit = 8;
+	bit <<= (pattern - 1);
        bit = BIT(pattern - 1) << 3;

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 505

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+
+	while (cnt--) {
+		data = dp_read(base + DP_MAINLINK_READY);
+		if (data & bit)
+			break;

Should there be a sleep in here? Also, consider using readx_poll_timeout instead of rolling your own polling.

Fixed in V2.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 509

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	}
+
+	if (cnt == 0)
+		pr_err("set link_train=%d failed\n", pattern);

This function should return an int and report this failure instead of ignoring it.

Fixed in V2.

Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_ctrl_usb_reset(struct dp_catalog_ctrl *ctrl, 

bool flip)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 526

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->usb3_dp_com.base;
+
+	dp_write(base + USB3_DP_COM_RESET_OVRD_CTRL, 0x0a);

Again, all of these magic values need to be pulled out into #defines so we know what the values mean.

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 530

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	dp_write(base + USB3_DP_COM_PHY_MODE_CTRL, 0x02);
+	dp_write(base + USB3_DP_COM_SW_RESET, 0x01);
+	/* make sure usb3 com phy software reset is done */
+	wmb();

Same comments here wrt wmb()

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 535

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+
+	if (!flip) /* CC1 */
+		dp_write(base + USB3_DP_COM_TYPEC_CTRL, 0x02);
+	else /* CC2 */
+		dp_write(base + USB3_DP_COM_TYPEC_CTRL, 0x03);
Quoted 8 lines
        u32 val;
        ...
        val = SOME_DEFINE_THAT_MAKES_SENSE;
        if (flip)
                val |= ANOTHER_DEFINE_THAT_MEANS_FLIP;

        dp_io_write(USB3_DP_COM_TYPEC_CTRL, val);

Forgot to fix the if/else case. Will fix it in V3.

Quoted 31 lines
Quoted 31 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +31 -0
+
+	dp_write(base + USB3_DP_COM_SWI_CTRL, 0x00);
+	dp_write(base + USB3_DP_COM_SW_RESET, 0x00);
+	/* make sure the software reset is done */
+	wmb();
+
+	dp_write(base + USB3_DP_COM_POWER_DOWN_CTRL, 0x01);
+	dp_write(base + USB3_DP_COM_RESET_OVRD_CTRL, 0x00);
+	/* make sure phy is brought out of reset */
+	wmb();
+
+}
+
+static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel,
+	bool enable)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!panel) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(panel);
+	base = catalog->io->dp_p0.base;
+
+	if (!enable) {
+		dp_write(base + MMSS_DP_TPG_MAIN_CONTROL, 0x0);
+		dp_write(base + MMSS_DP_BIST_ENABLE, 0x0);
+		dp_write(base + MMSS_DP_TIMING_ENGINE_EN, 0x0);
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 569

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+		wmb(); /* ensure Timing generator is turned off */
+		return;
+	}

There's really no reason to have both the enable + disable path in the same function, they don't share any code (aside from writing a few different values to the same registers). Could you please split this function into a timing_generator_disable and timing_generator_enable?

Fixed in V2.

Quoted 54 lines
Quoted 41 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	dp_write(base + MMSS_DP_INTF_CONFIG, 0x0);
+	dp_write(base + MMSS_DP_INTF_HSYNC_CTL, panel->hsync_ctl);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PERIOD_F0, panel->vsync_period *
+			panel->hsync_period);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, 

panel->v_sync_width *

drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+			panel->hsync_period);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
+	dp_write(base + MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
+	dp_write(base + MMSS_DP_INTF_DISPLAY_HCTL, panel->display_hctl);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_HCTL, 0);
+	dp_write(base + MMSS_INTF_DISPLAY_V_START_F0, 

panel->display_v_start);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	dp_write(base + MMSS_DP_INTF_DISPLAY_V_END_F0, 

panel->display_v_end);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +25 -0
+	dp_write(base + MMSS_INTF_DISPLAY_V_START_F1, 0);
+	dp_write(base + MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
+	dp_write(base + MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
+	dp_write(base + MMSS_DP_INTF_POLARITY_CTL, 0);
+	wmb(); /* ensure TPG registers are programmed */
+
+	dp_write(base + MMSS_DP_TPG_MAIN_CONTROL, 0x100);
+	dp_write(base + MMSS_DP_TPG_VIDEO_CONFIG, 0x5);
+	wmb(); /* ensure TPG config is programmed */
+	dp_write(base + MMSS_DP_BIST_ENABLE, 0x1);
+	dp_write(base + MMSS_DP_TIMING_ENGINE_EN, 0x1);
+	wmb(); /* ensure Timing generator is turned on */
+	pr_debug("%s: enabled tpg\n", __func__);
+}
+
+static void dp_catalog_ctrl_reset(struct dp_catalog_ctrl *ctrl)
+{
+	u32 sw_reset;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {

drivers/gpu/drm/msm/dp/dp_catalog.c line 617

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	sw_reset = dp_read(base + DP_SW_RESET);
+
+	sw_reset |= BIT(0);

Should be a #define

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 619

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_SW_RESET, sw_reset);
+	usleep_range(1000, 1010); /* h/w recommended delay */

Same comment here regarding the 10us range

Addressed both the above comments in V2.

Quoted 23 lines
Quoted 23 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	sw_reset &= ~BIT(0);
+	dp_write(base + DP_SW_RESET, sw_reset);
+}
+
+static bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+{
+	u32 data;
+	int cnt = 10;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		goto end;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_link.base;
+
+	while (--cnt) {
+		/* DP_MAINLINK_READY */
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 646

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		data = dp_read(base + DP_MAINLINK_READY);
+		if (data & BIT(0))
+			return true;
+
+		usleep_range(1000, 1010); /* 1ms wait before next reg read */

Same comment here regarding using readx_poll_timeout wrapped in a helper, also 10us comment.

Fixed in V2.

Quoted 45 lines
Quoted 45 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +30 -0
+	}
+	pr_err("mainlink not ready\n");
+end:
+	return false;
+}
+
+static void dp_catalog_ctrl_enable_irq(struct dp_catalog_ctrl *ctrl,
+						bool enable)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	if (enable) {
+		dp_write(base + DP_INTR_STATUS, DP_INTR_MASK1);
+		dp_write(base + DP_INTR_STATUS2, DP_INTR_MASK2);
+	} else {
+		dp_write(base + DP_INTR_STATUS, 0x00);
+		dp_write(base + DP_INTR_STATUS2, 0x00);
+	}
+}
+
+static void dp_catalog_ctrl_hpd_config(struct dp_catalog_ctrl *ctrl, 

bool en)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +14 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_aux.base;
+
+	if (en) {
+		u32 reftimer = dp_read(base + DP_DP_HPD_REFTIMER);
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 696

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+		dp_write(base + DP_DP_HPD_INT_ACK, 0xF);
+		dp_write(base + DP_DP_HPD_INT_MASK, 0xF);
+
+		/* Enabling REFTIMER */
+		reftimer |= BIT(16);

You don't use this anywhere?

Removed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 701

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		dp_write(base + DP_DP_HPD_REFTIMER, 0xF);
+		/* Enable HPD */
+		dp_write(base + DP_DP_HPD_CTRL, 0x1);
+	} else {
+		/*Disable HPD */

Space after *

Fixed in v2.

Quoted 32 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		dp_write(base + DP_DP_HPD_CTRL, 0x0);
+	}
+}
+
+static void dp_catalog_ctrl_get_interrupt(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+{
+	u32 ack = 0;
+	struct dp_catalog_private *catalog;
+	void __iomem *base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 720

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	ctrl->isr = dp_read(base + DP_INTR_STATUS2);

This value should just get returned instead of being stored.

drivers/gpu/drm/msm/dp/dp_catalog.c line 721

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	ctrl->isr &= ~DP_INTR_MASK2;

Unmasking the interrupts should not be returned from this function, it should be part of the ack below.

drivers/gpu/drm/msm/dp/dp_catalog.c line 722

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	ack = ctrl->isr & DP_INTERRUPT_STATUS2;

And this does the above unmask already, so you can just turf it.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 724

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	ack <<= 1;
+	ack |= DP_INTR_MASK2;

Instead of rolling the ack code yourself, I'd prefer what you did with _MASK, where you define DP_INTERRUPT_STATUS2_ACK above and just do a bitwise-OR to add the acks here. Without the register map in front of me, it would take a while to figure out what you're trying to accomplish.

Didn't address your comments in get_interrupt function. Will fix this in V3.

Quoted 20 lines
Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +7 -0
+	dp_write(base + DP_INTR_STATUS2, ack);
+}
+
+static void dp_catalog_ctrl_phy_reset(struct dp_catalog_ctrl *ctrl)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;

drivers/gpu/drm/msm/dp/dp_catalog.c line 741

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp_catalog_get_priv(ctrl);
+	base = catalog->io->dp_ahb.base;
+
+	dp_write(base + DP_PHY_CTRL, 0x5); /* bit 0 & 2 */

The comment doesn't help here, please #define these bits

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_catalog.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_catalog.c new file +1 -0
+	usleep_range(1000, 1010); /* h/w recommended delay */

Same comment re: delay range

Fixed in V2.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 744

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_PHY_CTRL, 0x0);
+	wmb(); /* make sure PHY reset done */

Same comment re: wmb

Fixed in V2.

Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_ctrl_phy_lane_cfg(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+		bool flipped, u8 ln_cnt)
+{
+	u32 info = 0x0;
+	struct dp_catalog_private *catalog;
+	u8 orientation = BIT(!!flipped);
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 761

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	}
+
+	dp_catalog_get_priv(ctrl);
+
+	info |= (ln_cnt & 0x0F);

Remove the | and just make this an assignment (and you can remove the initialization to 0 above)

Will remove the initialization to zero in V3. The other comments are addressed.

Quoted 68 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 773

Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +7 -0
+	info |= ((orientation & 0x0F) << 4);
+	pr_debug("Shared Info = 0x%x\n", info);
+
+	dp_write(catalog->io->phy_io.base + DP_PHY_SPARE0, info);
+}
+
+static void dp_catalog_ctrl_update_vx_px(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		u8 v_level, u8 p_level)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base0, *base1;
+	u8 value0, value1;

Can we please pick better names for these?!

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 789

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	dp_catalog_get_priv(ctrl);
+	base0 = catalog->io->ln_tx0_io.base;
+	base1 = catalog->io->ln_tx1_io.base;
+
+	pr_debug("hw: v=%d p=%d\n", v_level, p_level);
+
+	value0 = vm_voltage_swing[v_level][p_level];
+	value1 = vm_pre_emphasis[v_level][p_level];
+
+	/* program default setting first */

Why do you need to do this?

drivers/gpu/drm/msm/dp/dp_catalog.c line 793

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+	dp_write(base0 + TXn_TX_DRV_LVL, 0x2A);
+	dp_write(base1 + TXn_TX_DRV_LVL, 0x2A);
+	dp_write(base0 + TXn_TX_EMP_POST1_LVL, 0x20);
+	dp_write(base1 + TXn_TX_EMP_POST1_LVL, 0x20);

#define these magic values

drivers/gpu/drm/msm/dp/dp_catalog.c line 797

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+
+	/* Enable MUX to use Cursor values from these registers */
+	value0 |= BIT(5);
+	value1 |= BIT(5);

#define these bits please

drivers/gpu/drm/msm/dp/dp_catalog.c line 800

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+
+	/* Configure host and panel only if both values are allowed */
+	if (value0 != 0xFF && value1 != 0xFF) {

You can check this a lot earlier in the function.

drivers/gpu/drm/msm/dp/dp_catalog.c line 810

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		dp_write(base0 + TXn_TX_DRV_LVL, value0);
+		dp_write(base1 + TXn_TX_DRV_LVL, value0);
+		dp_write(base0 + TXn_TX_EMP_POST1_LVL, value1);
+		dp_write(base1 + TXn_TX_EMP_POST1_LVL, value1);
+
+		pr_debug("hw: vx_value=0x%x px_value=0x%x\n",
+			value0, value1);
+	} else {
+		pr_err("invalid vx (0x%x=0x%x), px (0x%x=0x%x\n",
+			v_level, value0, p_level, value1);

Seems like returning an error in this case would be useful

Quoted 2 lines

drivers/gpu/drm/msm/dp/dp_catalog.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	}
+}

Will address comments in *update_vx_px() function in V3.

Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog_ctrl 

*ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+			u32 pattern)
+{
+	struct dp_catalog_private *catalog;
+	u32 value = 0x0;
+	void __iomem *base = NULL;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 830

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_STATE_CTRL, 0x0);

Do you really need to do this?

Yes, to make sure no other pattern is set/enabled in hardware before any new pattern is configured.

Quoted 29 lines
Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +29 -0
+
+	switch (pattern) {
+	case DP_TEST_PHY_PATTERN_D10_2_NO_SCRAMBLING:
+		dp_write(base + DP_STATE_CTRL, 0x1);
+		break;
+	case DP_TEST_PHY_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT:
+		value &= ~(1 << 16);
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		value |= 0xFC;
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		dp_write(base + DP_MAINLINK_LEVELS, 0x2);
+		dp_write(base + DP_STATE_CTRL, 0x10);
+		break;
+	case DP_TEST_PHY_PATTERN_PRBS7:
+		dp_write(base + DP_STATE_CTRL, 0x20);
+		break;
+	case DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN:
+		dp_write(base + DP_STATE_CTRL, 0x40);
+		/* 00111110000011111000001111100000 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG0, 0x3E0F83E0);
+		/* 00001111100000111110000011111000 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG1, 0x0F83E0F8);
+		/* 1111100000111110 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG2, 0x0000F83E);
+		break;
+	case DP_TEST_PHY_PATTERN_HBR2_CTS_EYE_PATTERN:
+		value = BIT(16);
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		value |= 0xFC;
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 842

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		dp_write(base + DP_MAINLINK_LEVELS, 0x2);
+		dp_write(base + DP_STATE_CTRL, 0x10);

This code is the exact same as the case for DP_TEST_PHY_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT, aside from BIT(16) vs ~BIT(16). Can you please combine these cases
and share code?

Will fix this in V3.

Quoted 11 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 867

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		break;
+	default:
+		pr_debug("No valid test pattern requested: 0x%x\n", pattern);
+		return;
+	}

All of the DP_STATE_CTRL values should be #defined, and you can move the write down here instead of duplicating it everywhere (with DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN writing a 0).

All the DP_STATE_CTRL values are defines in V2.

I am not clear on moving the write operations after the switch cases. Can you please provide some more details?

Quoted 39 lines
Quoted 39 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	/* Make sure the test pattern is programmed in the hardware */
+	wmb();
+}
+
+static u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog_ctrl 

*ctrl)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +18 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base = NULL;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return 0;
+	}
+
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->dp_link.base;
+
+	return dp_read(base + DP_MAINLINK_READY);
+}
+
+/* panel related catalog functions */
+static int dp_catalog_panel_timing_cfg(struct dp_catalog_panel 

*panel)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +13 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+
+	if (!panel) {
+		pr_err("invalid input\n");
+		goto end;
+	}
+
+	dp_catalog_get_priv(panel);
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_TOTAL_HOR_VER, panel->total);
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 908

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_START_HOR_VER_FROM_SYNC, panel->sync_start);
+	dp_write(base + DP_HSYNC_VSYNC_WIDTH_POLARITY, 

panel->width_blanking);

drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+	dp_write(base + DP_ACTIVE_HOR_VER, panel->dp_active);
+end:

useless label, but it'll probably go away when you strip out all of the unnecessary NULL checks from the driver.

Fixed in V2.

Quoted 37 lines
Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +37 -0
+	return 0;
+}
+
+static void dp_catalog_audio_init(struct dp_catalog_audio *audio)
+{
+	struct 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 (!audio)
+		return;
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 948

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+	dp_catalog_get_priv(audio);
+
+	catalog->audio_map = sdp_map;

Hmm, this is a bit spooky, we're storing a (non-const) pointer to a static stack variable. Fortunately this looks like it'll be easy to fix since this data is only accessed in this file. So move the map into a static const global and reference it directly when needed (and drop audio_map).

All the Audio related configs/APIs are removed in this patch. Will be adding these changes in a separate patch.

Quoted 44 lines
Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+}
+
+static void dp_catalog_audio_config_sdp(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +14 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	u32 sdp_cfg = 0;
+	u32 sdp_cfg2 = 0;
+
+	if (!audio)
+		return;
+
+	dp_catalog_get_priv(audio);
+	base = catalog->io->dp_link.base;
+
+	sdp_cfg = dp_read(base + MMSS_DP_SDP_CFG);
+

drivers/gpu/drm/msm/dp/dp_catalog.c line 975

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	/* 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);

#define the values and combine the assignment

drivers/gpu/drm/msm/dp/dp_catalog.c line 984

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+
+	pr_debug("sdp_cfg = 0x%x\n", sdp_cfg);
+	dp_write(base + MMSS_DP_SDP_CFG, sdp_cfg);
+
+	sdp_cfg2 = dp_read(base + 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);

The reset value of this register is 0x4, so how can the bits in position 0/1 get flipped? We shouldn't need this code, afaict.

Quoted 2 lines

If we do, the same comments regarding #define and combination as above.

All the audio functions are removed in V2.

Quoted 20 lines
Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	pr_debug("sdp_cfg2 = 0x%x\n", sdp_cfg2);
+	dp_write(base + MMSS_DP_SDP_CFG2, sdp_cfg2);
+}
+
+static void dp_catalog_audio_get_header(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +13 -0
+{
+	struct dp_catalog_private *catalog;
+	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
+	void __iomem *base;
+	enum dp_catalog_audio_sdp_type sdp;
+	enum dp_catalog_audio_header_type header;
+
+	if (!audio)
+		return;
+
+	dp_catalog_get_priv(audio);
+
+	base    = catalog->io->dp_link.base;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 1009

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+	sdp_map = catalog->audio_map;
+	sdp     = audio->sdp_type;
+	header  = audio->sdp_header;
+
+	audio->data = dp_read(base + sdp_map[sdp][header]);
+}

This function is unused, please remove.

Removed in V2.

Quoted 18 lines
Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_audio_set_header(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +15 -0
+{
+	struct dp_catalog_private *catalog;
+	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
+	void __iomem *base;
+	enum dp_catalog_audio_sdp_type sdp;
+	enum dp_catalog_audio_header_type header;
+	u32 data;
+
+	if (!audio)
+		return;
+
+	dp_catalog_get_priv(audio);
+
+	base    = catalog->io->dp_link.base;
+	sdp_map = catalog->audio_map;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 1032

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+	sdp     = audio->sdp_type;
+	header  = audio->sdp_header;
+	data    = audio->data;
+
+	dp_write(base + sdp_map[sdp][header], data);
+}

This function is unused, please remove.

All the audio functions are removed in V2.

Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_audio_config_acr(struct dp_catalog_audio 

*audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	u32 acr_ctrl, select;
+
+	dp_catalog_get_priv(audio);
+
+	select = audio->data;
+	base   = catalog->io->dp_link.base;
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 1050

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+	acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
+
+	pr_debug("select = 0x%x, acr_ctrl = 0x%x\n", select, acr_ctrl);
+
+	dp_write(base + MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
+}

This function is unused, please remove.

All the audio functions are removed in V2.

Quoted 75 lines
Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+static void dp_catalog_audio_safe_to_exit_level(struct 

dp_catalog_audio *audio)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +9 -0
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	u32 mainlink_levels, safe_to_exit_level;
+
+	dp_catalog_get_priv(audio);
+
+	base   = catalog->io->dp_link.base;
+	safe_to_exit_level = audio->data;

drivers/gpu/drm/msm/dp/dp_catalog.c line 1071

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+
+	mainlink_levels = dp_read(base + DP_MAINLINK_LEVELS);
+	mainlink_levels &= 0xFE0;
+	mainlink_levels |= safe_to_exit_level;
+
+	pr_debug("mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
+			mainlink_levels, safe_to_exit_level);
+
+	dp_write(base + DP_MAINLINK_LEVELS, mainlink_levels);
+}

This function is unused, please remove.

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +16 -0
+
+static void dp_catalog_audio_enable(struct dp_catalog_audio *audio)
+{
+	struct dp_catalog_private *catalog;
+	void __iomem *base;
+	bool enable;
+	u32 audio_ctrl;
+
+	dp_catalog_get_priv(audio);
+
+	base   = catalog->io->dp_link.base;
+	enable = !!audio->data;
+
+	audio_ctrl = dp_read(base + MMSS_DP_AUDIO_CFG);
+
+	if (enable)

drivers/gpu/drm/msm/dp/dp_catalog.c line 1097

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+		audio_ctrl |= BIT(0);
+	else
+		audio_ctrl &= ~BIT(0);
+
+	pr_debug("dp_audio_cfg = 0x%x\n", audio_ctrl);
+	dp_write(base + MMSS_DP_AUDIO_CFG, audio_ctrl);
+
+	/* make sure audio engine is disabled */
+	wmb();
+}

This function is unused, please remove.

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io 

*io)

drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+{
+	int rc = 0;
+	struct dp_catalog *dp_catalog;
+	struct dp_catalog_private *catalog;

drivers/gpu/drm/msm/dp/dp_catalog.c line 1113

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+	struct dp_catalog_aux aux = {
+		.read_data     = dp_catalog_aux_read_data,
+		.write_data    = dp_catalog_aux_write_data,
+		.write_trans   = dp_catalog_aux_write_trans,
+		.clear_trans   = dp_catalog_aux_clear_trans,
+		.reset         = dp_catalog_aux_reset,
+		.update_aux_cfg = dp_catalog_aux_update_cfg,
+		.enable        = dp_catalog_aux_enable,
+		.setup         = dp_catalog_aux_setup,
+		.get_irq       = dp_catalog_aux_get_irq,

Out of these, it seems like write_trans, clear_trans, update_aux_cfg, setup and get_irq are all unused. Please remove them.

Quoted 2 lines

Please also check the other functions to ensure they're used.

Fixed in V2.

Quoted 17 lines
Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +17 -0
+	};
+	struct dp_catalog_ctrl ctrl = {
+		.state_ctrl     = dp_catalog_ctrl_state_ctrl,
+		.config_ctrl    = dp_catalog_ctrl_config_ctrl,
+		.lane_mapping   = dp_catalog_ctrl_lane_mapping,
+		.mainlink_ctrl  = dp_catalog_ctrl_mainlink_ctrl,
+		.config_misc    = dp_catalog_ctrl_config_misc,
+		.config_msa     = dp_catalog_ctrl_config_msa,
+		.set_pattern    = dp_catalog_ctrl_set_pattern,
+		.reset          = dp_catalog_ctrl_reset,
+		.usb_reset      = dp_catalog_ctrl_usb_reset,
+		.mainlink_ready = dp_catalog_ctrl_mainlink_ready,
+		.enable_irq     = dp_catalog_ctrl_enable_irq,
+		.hpd_config     = dp_catalog_ctrl_hpd_config,
+		.phy_reset      = dp_catalog_ctrl_phy_reset,
+		.phy_lane_cfg   = dp_catalog_ctrl_phy_lane_cfg,
+		.update_vx_px   = dp_catalog_ctrl_update_vx_px,
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 1134

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +4 -0
+		.get_interrupt  = dp_catalog_ctrl_get_interrupt,
+		.update_transfer_unit = dp_catalog_ctrl_update_transfer_unit,
+		.send_phy_pattern    = dp_catalog_ctrl_send_phy_pattern,
+		.read_phy_pattern = dp_catalog_ctrl_read_phy_pattern,

So, what's the benefit of adding the catalog abstractions? Do you ever have multiple/alternate implementations of a catalog? It doesn't seem like it. You should just remove all of the catalog overhead and call the functions directly.

Fixed in V2.

Quoted 169 lines
Quoted 169 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +54 -0
+	};
+	struct dp_catalog_audio audio = {
+		.init       = dp_catalog_audio_init,
+		.config_acr = dp_catalog_audio_config_acr,
+		.enable     = dp_catalog_audio_enable,
+		.config_sdp = dp_catalog_audio_config_sdp,
+		.set_header = dp_catalog_audio_set_header,
+		.get_header = dp_catalog_audio_get_header,
+		.safe_to_exit_level = dp_catalog_audio_safe_to_exit_level,
+	};
+	struct dp_catalog_panel panel = {
+		.timing_cfg = dp_catalog_panel_timing_cfg,
+		.tpg_config = dp_catalog_panel_tpg_cfg,
+	};
+
+	if (!io) {
+		pr_err("invalid input\n");
+		rc = -EINVAL;
+		goto error;
+	}
+
+	catalog  = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL);
+	if (!catalog) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	catalog->dev = dev;
+	catalog->io = io;
+
+	dp_catalog = &catalog->dp_catalog;
+
+	dp_catalog->aux   = aux;
+	dp_catalog->ctrl  = ctrl;
+	dp_catalog->audio = audio;
+	dp_catalog->panel = panel;
+
+	return dp_catalog;
+error:
+	return ERR_PTR(rc);
+}
+
+void dp_catalog_put(struct dp_catalog *dp_catalog)
+{
+	struct dp_catalog_private *catalog;
+
+	if (!dp_catalog)
+		return;
+
+	catalog = container_of(dp_catalog, struct dp_catalog_private,
+				dp_catalog);
+
+	devm_kfree(catalog->dev, catalog);
+}
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
new file mode 100644
index 0000000..58951df
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_catalog.h new file +94 -0
+
+#ifndef _DP_CATALOG_H_
+#define _DP_CATALOG_H_
+
+#include "dp_parser.h"
+
+/* interrupts */
+#define DP_INTR_HPD		BIT(0)
+#define DP_INTR_AUX_I2C_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)
+
+struct dp_catalog_aux {
+	u32 data;
+	u32 isr;
+
+	u32 (*read_data)(struct dp_catalog_aux *aux);
+	int (*write_data)(struct dp_catalog_aux *aux);
+	int (*write_trans)(struct dp_catalog_aux *aux);
+	int (*clear_trans)(struct dp_catalog_aux *aux, bool read);
+	void (*reset)(struct dp_catalog_aux *aux);
+	void (*enable)(struct dp_catalog_aux *aux, bool enable);
+	void (*update_aux_cfg)(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type);
+	void (*setup)(struct dp_catalog_aux *aux,
+			struct dp_aux_cfg *aux_cfg);
+	void (*get_irq)(struct dp_catalog_aux *aux, bool cmd_busy);
+};
+
+struct dp_catalog_ctrl {
+	u32 dp_tu;
+	u32 valid_boundary;
+	u32 valid_boundary2;
+	u32 isr;
+
+	void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state);
+	void (*config_ctrl)(struct dp_catalog_ctrl *ctrl, u32 config);
+	void (*lane_mapping)(struct dp_catalog_ctrl *ctrl);
+	void (*mainlink_ctrl)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*config_misc)(struct dp_catalog_ctrl *ctrl, u32 cc, u32 tb);
+	void (*config_msa)(struct dp_catalog_ctrl *ctrl, u32 rate,
+				u32 stream_rate_khz, bool fixed_nvid);
+	void (*set_pattern)(struct dp_catalog_ctrl *ctrl, u32 pattern);
+	void (*reset)(struct dp_catalog_ctrl *ctrl);
+	void (*usb_reset)(struct dp_catalog_ctrl *ctrl, bool flip);
+	bool (*mainlink_ready)(struct dp_catalog_ctrl *ctrl);
+	void (*enable_irq)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*hpd_config)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*phy_reset)(struct dp_catalog_ctrl *ctrl);
+	void (*phy_lane_cfg)(struct dp_catalog_ctrl *ctrl, bool flipped,
+				u8 lane_cnt);
+	void (*update_vx_px)(struct dp_catalog_ctrl *ctrl, u8 v_level,
+				u8 p_level);
+	void (*get_interrupt)(struct dp_catalog_ctrl *ctrl);
+	void (*update_transfer_unit)(struct dp_catalog_ctrl *ctrl);
+	void (*send_phy_pattern)(struct dp_catalog_ctrl *ctrl,
+			u32 pattern);
+	u32 (*read_phy_pattern)(struct dp_catalog_ctrl *ctrl);
+};
+
+enum 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 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 dp_catalog_audio {
+	enum dp_catalog_audio_sdp_type sdp_type;
+	enum dp_catalog_audio_header_type sdp_header;
+	u32 data;
+
+	void (*init)(struct dp_catalog_audio *audio);
+	void (*enable)(struct dp_catalog_audio *audio);
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h line 112

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +5 -0
+	void (*config_acr)(struct dp_catalog_audio *audio);
+	void (*config_sdp)(struct dp_catalog_audio *audio);
+	void (*set_header)(struct dp_catalog_audio *audio);
+	void (*get_header)(struct dp_catalog_audio *audio);
+	void (*safe_to_exit_level)(struct dp_catalog_audio *audio);

None of these are called? So get rid of this entire structure, the functions that aren't called, and the audio enums above.

Removed all the Audio related APIs in V2.

Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+};
+
+struct dp_catalog_panel {
+	u32 total;
+	u32 sync_start;
+	u32 width_blanking;
+	u32 dp_active;
+
+	/* TPG */
+	u32 hsync_period;
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.h line 128

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	u32 vsync_period;
+	u32 display_v_start;
+	u32 display_v_end;
+	u32 v_sync_width;
+	u32 hsync_ctl;
+	u32 display_hctl;

All of this information is already available from drm core, so it can go.

Will address this in V3.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.h line 131

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +3 -0
+
+	int (*timing_cfg)(struct dp_catalog_panel *panel);
+	void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);

As suggested elsewhere, these functions should just be called directly wherever applicable. So we can get rid of this struct.

Quoted 16 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+};
+
+struct dp_catalog {
+	struct dp_catalog_aux aux;
+	struct dp_catalog_ctrl ctrl;
+	struct dp_catalog_audio audio;
+	struct dp_catalog_panel panel;
+};
+
+struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io 
Quoted 2 lines

*io);
+void dp_catalog_put(struct dp_catalog *catalog);

As mentioned above, all of this should be removed. We can just call the functions directly.

Removed the func ptrs in V2.

Quoted 41 lines
Quoted 41 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
+
+#endif /* _DP_CATALOG_H_ */
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
new file mode 100644
index 0000000..08a52f5
@@ -0,0 +1,1475 @@
+/*
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +18 -0
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+
+#include "dp_ctrl.h"
+
+#define DP_KHZ_TO_HZ 1000
+
+#define DP_CTRL_INTR_READY_FOR_VIDEO     BIT(0)
+#define DP_CTRL_INTR_IDLE_PATTERN_SENT  BIT(3)
+
+/* dp state ctrl */
+#define ST_TRAIN_PATTERN_1		BIT(0)
+#define ST_TRAIN_PATTERN_2		BIT(1)
+#define ST_TRAIN_PATTERN_3		BIT(2)
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 37

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+#define ST_TRAIN_PATTERN_4		BIT(3)
+#define ST_SYMBOL_ERR_RATE_MEASUREMENT	BIT(4)
+#define ST_PRBS7			BIT(5)
+#define ST_CUSTOM_80_BIT_PATTERN	BIT(6)
+#define ST_SEND_VIDEO			BIT(7)
+#define ST_PUSH_IDLE			BIT(8)

I'd like to see these defined with DP_STATE_CTRL (and s/ST/DP_STATE_CTRL/).

Fixed in V2.

Quoted 12 lines
Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0
+
+#define MR_LINK_TRAINING1  0x8
+#define MR_LINK_SYMBOL_ERM 0x80
+#define MR_LINK_PRBS7 0x100
+#define MR_LINK_CUSTOM80 0x200
+
+struct dp_vc_tu_mapping_table {
+	u32 vic;
+	u8 lanes;
+	u8 lrate; /* DP_LINK_RATE -> 162(6), 270(10), 540(20), 810 (30) */
+	u8 bpp;
+	u8 valid_boundary_link;
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 55

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+	u16 delay_start_link;
+	bool boundary_moderation_en;
+	u8 valid_lower_boundary_link;
+	u8 upper_boundary_count;
+	u8 lower_boundary_count;
+	u8 tu_size_minus1;

Please check this struct for unused members, there are at least a couple.

Updated the TU calculator in V2.

Quoted 17 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 67

Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0
+};
+
+struct dp_ctrl_private {
+	struct dp_ctrl dp_ctrl;
+
+	struct device *dev;
+	struct dp_aux *aux;
+	struct dp_panel *panel;
+	struct dp_link *link;
+	struct dp_power *power;
+	struct dp_parser *parser;
+	struct dp_catalog_ctrl *catalog;

Once you remove struct dp_ctrl and call the functions directly, I suspect you can get rid of all of these.

Even though we call the functions directly, we still need variables present in each module. For example, we need to access link parameters, panel parameters etc

Unnecessary stuff is removed but we still need other variables in the structure. All have been updated in V2.

Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+
+	struct completion idle_comp;
+	struct completion video_comp;
+
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 76

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+	bool orientation;
+	atomic_t aborted;
+
+	u32 pixel_rate;
+	u32 vic;

'u32 vic' shows up in 3 places in this driver, but there is not one use of any vic :) Please remove from here and elsewhere.

Fixed in V2.

Quoted 13 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 85

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0
+};
+
+enum notification_status {
+	NOTIFY_UNKNOWN,
+	NOTIFY_CONNECT,
+	NOTIFY_DISCONNECT,
+	NOTIFY_CONNECT_IRQ_HPD,
+	NOTIFY_DISCONNECT_IRQ_HPD,
+};

Unused, please remove.

Fixed in V2.

Quoted 7 lines
Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0
+
+static void dp_ctrl_idle_patterns_sent(struct dp_ctrl_private *ctrl)
+{
+	pr_debug("idle_patterns_sent\n");
+	complete(&ctrl->idle_comp);
+}
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 97

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+static void dp_ctrl_video_ready(struct dp_ctrl_private *ctrl)
+{
+	pr_debug("dp_video_ready\n");
+	complete(&ctrl->video_comp);
+}

These functions don't provide value, please remove and just call complete() directly.

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+
+static void dp_ctrl_abort(struct dp_ctrl *dp_ctrl)
+{
+	struct dp_ctrl_private *ctrl;
+
+	if (!dp_ctrl) {
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 108

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+		pr_err("Invalid input data\n");
+		return;
+	}
+
+	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

JFYI, this is sprinkled everywhere, would be a good candidate for an inline function. Since dp_ctrl can be removed, it's kind of a moot point now.

I didn't see any major advantage with moving to inline. So, kept it as is.
We still want to have private and public (dp_ctrl_private and dp_ctrl) structures for each module (Ctrl, link, etc) so that we don't expose unnecessary info to other modules.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 115

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+
+	atomic_set(&ctrl->aborted, 1);
+}
+
+static void dp_ctrl_state_ctrl(struct dp_ctrl_private *ctrl, u32 

state)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
+{
+	ctrl->catalog->state_ctrl(ctrl->catalog, state);

No need to wrap this in a function

Fixed in V2.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 120

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+}
+
+static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl)
+{
+	int const idle_pattern_completion_timeout_ms = 3 * HZ / 100;

This should be #define'd outside of the functioninstead. Also, why the '_ms_' suffix? The units are in jiffies.

Quoted 6 lines

I think something like

#define IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES (30 * HZ / 1000) /* 30 ms */

would be clearer.

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+	struct dp_ctrl_private *ctrl;
+
+	if (!dp_ctrl) {
+		pr_err("Invalid input data\n");
+		return;
+	}
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 130

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+
+	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+
+	reinit_completion(&ctrl->idle_comp);

This function is called from a bunch of places, and idle_comp is also used in a bunch of places. Are you certain this is thread-safe if you have concurrent callers or users of idle_comp?

I don't think we need any synchronization logic for idle_comp since it is reinitialized only when the complete core is reset. Only place where it is needed is in push_idle which already has a mutex.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 135

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+	dp_ctrl_state_ctrl(ctrl, ST_PUSH_IDLE);
+
+	if (!wait_for_completion_timeout(&ctrl->idle_comp,
+			idle_pattern_completion_timeout_ms))
+		pr_warn("PUSH_IDLE pattern timedout\n");

Return an error?

Its not fatal error since we are going to reset the controller and we are going to recover from this timeout.

Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+
+	pr_debug("mainlink off done\n");
+}
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 145

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl)
+{
+	u32 config = 0, tbd;
+	u8 *dpcd = ctrl->panel->dpcd;
+
+	config |= (2 << 13); /* Default-> LSCLK DIV: 1/4 LCLK  */

#define value

Fixed in V2.

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 146

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0
+	config |= (0 << 11); /* RGB */

This is a no-op, can be removed

Fixed in V2.

Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+
+	/* Scrambler reset enable */
+	if (dpcd[DP_EDP_CONFIGURATION_CAP] & 

DP_ALTERNATE_SCRAMBLER_RESET_CAP)

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 155

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+		config |= (1 << 10);
+
+	tbd = ctrl->link->get_test_bits_depth(ctrl->link,
+			ctrl->panel->pinfo.bpp);
+
+	if (tbd == DP_TEST_BIT_DEPTH_UNKNOWN)

Should we print a debug message here?

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 161

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+		tbd = DP_TEST_BIT_DEPTH_8;
+
+	config |= tbd << 8;
+
+	/* Num of Lanes */
+	config |= ((ctrl->link->link_params.lane_count - 1) << 4);

These shift values should be #defined

Fixed in V2.

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 164

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+
+	if (drm_dp_enhanced_frame_cap(dpcd))
+		config |= 0x40;

#define 0x40

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 168

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+
+	config |= 0x04; /* progressive video */
+
+	config |= 0x03;	/* sycn clock & static Mvid */

And these, plus s/sycn/sync/

Fixed in V2.

Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+
+	ctrl->catalog->config_ctrl(ctrl->catalog, config);
+}
+
+/**
+ * dp_ctrl_configure_source_params() - configures DP transmitter 

source params
+ * @ctrl: Display Port Driver data
+ *
+ * Configures the DP transmitter source params including details such as lane
+ * configuration, output format and sink/panel timing information.
+ */
+static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl)
+{

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 185

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+	u32 cc, tb;
+
+	ctrl->catalog->lane_mapping(ctrl->catalog);
+	ctrl->catalog->mainlink_ctrl(ctrl->catalog, true);

We go through ctrl->catalog->callback_hook to call a function that is specific to ctrl and only called in this file. It could easily just be a static function without having to go through 2 structs and a callback hook.

Removed the function ptr. We are calling the catalog APIs directly in V2.

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 192

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0
+
+	dp_ctrl_config_ctrl(ctrl);
+
+	tb = ctrl->link->get_test_bits_depth(ctrl->link,
+		ctrl->panel->pinfo.bpp);
+	cc = ctrl->link->get_colorimetry_config(ctrl->link);
+	ctrl->catalog->config_misc(ctrl->catalog, cc, tb);

Same comments with these hooks, they're only called from this file. I'll stop harping on this, but could we please remove the layers of indirection and just embed and call functions as appropriate?

Fixed in V2.

Quoted 55 lines
Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +22 -0
+	ctrl->panel->timing_cfg(ctrl->panel);
+}
+
+static void dp_ctrl_get_extra_req_bytes(u64 result_valid,
+					int valid_bdary_link,
+					u64 value1, u64 value2,
+					bool *negative, u64 *result,
+					u64 compare)
+{
+	*negative = false;
+	if (result_valid >= compare) {
+		if (valid_bdary_link
+				>= compare)
+			*result = value1 + value2;
+		else {
+			if (value1 < value2)
+				*negative = true;
+			*result = (value1 >= value2) ?
+				(value1 - value2) : (value2 - value1);
+		}
+	} else {
+		if (valid_bdary_link

drivers/gpu/drm/msm/dp/dp_ctrl.c line 224

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+				>= compare) {
+			if (value1 >= value2)
+				*negative = true;
+			*result = (value1 >= value2) ?
+				(value1 - value2) : (value2 - value1);
+		} else {
+			*result = value1 + value2;
+			*negative = true;
+		}
+	}

I think this can be simplified to the following, it's still super hard to follow, but I'm not sure if that can be helped.

        bool result_bigger = result_valid >= compare;
        bool valid_bdary_bigger = valid_bdary_link >= compare;

	if (result_bigger && valid_bdary_bigger ||
            !result_bigger && !valid_bdary_bigger) {
                *negative = !valid_bdary_bigger;
                return value1 + value2;
        }

        *negative = (result_bigger && !valid_bdary_bigger && value1 < 
value2) ||
                    (!result_bigger && valid_bdary_bigger && value1 >= 
value2);
        return max(value1, value2) - min(value1, value2);

I don't know. The more I stare at this the less convinced I become that it's better. So take it or leave it. At the very least you can collapse the

if (cond)

Quoted 10 lines
        *negative = true;

to

*negative = cond;

and do the max(v,v) - min(v,v) trick to shave off some of the conditionals in the original.

Most of the code related to tu_calculator has been updated in V2.

Quoted 93 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 231

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0
+}
+
+static u64 roundup_u64(u64 x, u64 y)
+{
+	x += (y - 1);
+	return (div64_ul(x, y) * y);
+}

Please replace all usage with DIV_ROUND_UP_ULL

drivers/gpu/drm/msm/dp/dp_ctrl.c line 239

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +8 -0
+
+static u64 rounddown_u64(u64 x, u64 y)
+{
+	u64 rem;
+
+	div64_u64_rem(x, y, &rem);
+	return (x - rem);
+}

Please replace all usage with DIV_ROUND_DOWN_ULL

Quoted 58 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +58 -0
+
+static void dp_ctrl_calc_tu_parameters(struct dp_ctrl_private *ctrl,
+				       struct dp_vc_tu_mapping_table *tu_table)
+{
+	u32 multiplier = 1000000;
+	u64 pclk, lclk;
+	u8 bpp, ln_cnt;
+	int run_idx = 0;
+	u32 lwidth, h_blank;
+	u32 fifo_empty = 0;
+	u32 ratio_scale = 1001;
+	u64 temp, ratio, original_ratio;
+	u64 temp2, reminder;
+	u64 temp3, temp4, result = 0;
+
+	u64 err = multiplier;
+	u64 n_err = 0, n_n_err = 0;
+	bool n_err_neg, nn_err_neg;
+	u8 hblank_margin = 16;
+
+	u8 tu_size, tu_size_desired = 0, tu_size_minus1;
+	int valid_boundary_link;
+	u64 resulting_valid;
+	u64 total_valid;
+	u64 effective_valid;
+	u64 effective_valid_recorded;
+	int n_tus;
+	int n_tus_per_lane;
+	int paired_tus;
+	int remainder_tus;
+	int remainder_tus_upper, remainder_tus_lower;
+	int extra_bytes;
+	int filler_size;
+	int delay_start_link;
+	int boundary_moderation_en = 0;
+	int upper_bdry_cnt = 0;
+	int lower_bdry_cnt = 0;
+	int i_upper_bdry_cnt = 0;
+	int i_lower_bdry_cnt = 0;
+	int valid_lower_boundary_link = 0;
+	int even_distribution_bf = 0;
+	int even_distribution_legacy = 0;
+	int even_distribution = 0;
+	int min_hblank = 0;
+	int extra_pclk_cycles;
+	u8 extra_pclk_cycle_delay = 4;
+	int extra_pclk_cycles_in_link_clk;
+	u64 ratio_by_tu;
+	u64 average_valid2;
+	u64 extra_buffer_margin;
+	int new_valid_boundary_link;
+
+	u64 resulting_valid_tmp;
+	u64 ratio_by_tu_tmp;
+	int n_tus_tmp;
+	int extra_pclk_cycles_tmp;
+	int extra_pclk_cycles_in_lclk_tmp;
+	int extra_req_bytes_new_tmp;

drivers/gpu/drm/msm/dp/dp_ctrl.c line 307

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0
+	int filler_size_tmp;
+	int lower_filler_size_tmp;
+	int delay_start_link_tmp;
+	int min_hblank_tmp = 0;
+	bool extra_req_bytes_is_neg = false;
+	struct dp_panel_info *pinfo = &ctrl->panel->pinfo;
+
+	u8 dp_brute_force = 1;
+	u64 brute_force_threshold = 10;
+	u64 diff_abs;

76 stack vars and ~450 lines must be a new record somewhere :)

Quoted 3 lines

I'm going to skip reviewing this function and let you split/simplify/reduce it. Please just make it more readable (comments, docs, helper functions, etc).

Most of the code related to tu_calculator has been updated in V2. As per our discussion, we won't be able to modify much of the function since its hardware/IP specific.

Quoted 414 lines
Quoted 414 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +58 -0
+
+	ln_cnt =  ctrl->link->link_params.lane_count;
+
+	bpp = pinfo->bpp;
+	lwidth = pinfo->h_active;
+	h_blank = pinfo->h_back_porch + pinfo->h_front_porch +
+				pinfo->h_sync_width;
+	pclk = pinfo->pixel_clk_khz * 1000;
+
+	boundary_moderation_en = 0;
+	upper_bdry_cnt = 0;
+	lower_bdry_cnt = 0;
+	i_upper_bdry_cnt = 0;
+	i_lower_bdry_cnt = 0;
+	valid_lower_boundary_link = 0;
+	even_distribution_bf = 0;
+	even_distribution_legacy = 0;
+	even_distribution = 0;
+	min_hblank = 0;
+
+	lclk = drm_dp_bw_code_to_link_rate(
+		ctrl->link->link_params.bw_code) * DP_KHZ_TO_HZ;
+
+	pr_debug("pclk=%lld, active_width=%d, h_blank=%d\n",
+						pclk, lwidth, h_blank);
+	pr_debug("lclk = %lld, ln_cnt = %d\n", lclk, ln_cnt);
+	ratio = div64_u64_rem(pclk * bpp * multiplier,
+				8 * ln_cnt * lclk, &reminder);
+	ratio = div64_u64((pclk * bpp * multiplier), (8 * ln_cnt * lclk));
+	original_ratio = ratio;
+
+	extra_buffer_margin = roundup_u64(div64_u64(extra_pclk_cycle_delay
+				* lclk * multiplier, pclk), multiplier);
+	extra_buffer_margin = div64_u64(extra_buffer_margin, multiplier);
+
+	/* To deal with cases where lines are not distributable */
+	if (((lwidth % ln_cnt) != 0) && ratio < multiplier) {
+		ratio = ratio * ratio_scale;
+		ratio = ratio < (1000 * multiplier)
+				? ratio : (1000 * multiplier);
+	}
+	pr_debug("ratio = %lld\n", ratio);
+
+	for (tu_size = 32; tu_size <= 64; tu_size++) {
+		temp = ratio * tu_size;
+		temp2 = ((temp / multiplier) + 1) * multiplier;
+		n_err = roundup_u64(temp, multiplier) - temp;
+
+		if (n_err < err) {
+			err = n_err;
+			tu_size_desired = tu_size;
+		}
+	}
+	pr_debug("Info: tu_size_desired = %d\n", tu_size_desired);
+
+	tu_size_minus1 = tu_size_desired - 1;
+
+	valid_boundary_link = roundup_u64(ratio * tu_size_desired, 

multiplier);

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +15 -0
+	valid_boundary_link /= multiplier;
+	n_tus = rounddown((lwidth * bpp * multiplier)
+			/ (8 * valid_boundary_link), multiplier) / multiplier;
+	even_distribution_legacy = n_tus % ln_cnt == 0 ? 1 : 0;
+	pr_debug("Info: n_symbol_per_tu=%d, number_of_tus=%d\n",
+					valid_boundary_link, n_tus);
+
+	extra_bytes = roundup_u64((n_tus + 1)
+			* ((valid_boundary_link * multiplier)
+			- (original_ratio * tu_size_desired)), multiplier);
+	extra_bytes /= multiplier;
+	extra_pclk_cycles = roundup(extra_bytes * 8 * multiplier / bpp,
+			multiplier);
+	extra_pclk_cycles /= multiplier;
+	extra_pclk_cycles_in_link_clk = 

roundup_u64(div64_u64(extra_pclk_cycles

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +256 -0
+				* lclk * multiplier, pclk), multiplier);
+	extra_pclk_cycles_in_link_clk /= multiplier;
+	filler_size = roundup_u64((tu_size_desired - valid_boundary_link)
+						* multiplier, multiplier);
+	filler_size /= multiplier;
+	ratio_by_tu = div64_u64(ratio * tu_size_desired, multiplier);
+
+	pr_debug("extra_pclk_cycles_in_link_clk=%d, extra_bytes=%d\n",
+				extra_pclk_cycles_in_link_clk, extra_bytes);
+	pr_debug("extra_pclk_cycles_in_link_clk=%d\n",
+				extra_pclk_cycles_in_link_clk);
+	pr_debug("filler_size=%d, extra_buffer_margin=%lld\n",
+				filler_size, extra_buffer_margin);
+
+	delay_start_link = ((extra_bytes > extra_pclk_cycles_in_link_clk)
+			? extra_bytes
+			: extra_pclk_cycles_in_link_clk)
+				+ filler_size + extra_buffer_margin;
+	resulting_valid = valid_boundary_link;
+	pr_debug("Info: delay_start_link=%d, filler_size=%d\n",
+				delay_start_link, filler_size);
+	pr_debug("valid_boundary_link=%d ratio_by_tu=%lld\n",
+				valid_boundary_link, ratio_by_tu);
+
+	diff_abs = (resulting_valid >= ratio_by_tu)
+				? (resulting_valid - ratio_by_tu)
+				: (ratio_by_tu - resulting_valid);
+
+	if (err != 0 && ((diff_abs > brute_force_threshold)
+			|| (even_distribution_legacy == 0)
+			|| (dp_brute_force == 1))) {
+		err = multiplier;
+		for (tu_size = 32; tu_size <= 64; tu_size++) {
+			for (i_upper_bdry_cnt = 1; i_upper_bdry_cnt <= 15;
+						i_upper_bdry_cnt++) {
+				for (i_lower_bdry_cnt = 1;
+					i_lower_bdry_cnt <= 15;
+					i_lower_bdry_cnt++) {
+					new_valid_boundary_link =
+						roundup_u64(ratio
+						* tu_size, multiplier);
+					average_valid2 = (i_upper_bdry_cnt
+						* new_valid_boundary_link
+						+ i_lower_bdry_cnt
+						* (new_valid_boundary_link
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

tu_size_desired=%d, valid_boundary_link=%d, effective_valid=%lld\n",

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

than the min_hblank %d supported.\n",

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

delay_start_link=%d boundary_moderation_en=%d\n upper_boundary_cnt=%d lower_boundary_cnt=%d valid_lower_boundary_link=%d min_hblank=%d\n",

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +38 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Again here, if you just call the function directly, you can avoid the callback. If you add function arguments, you can avoid having to store dp_tu/valid_boundary/
valid_boundary2 entirely.

Will remove the dp_tu/valid_boundary/valid_boundary2 in V3.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Break out the timeout into a #define

Fixed in V2.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You're not checking the return value at the callsite.

Fixed in V2.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I don't think this needs to be a function, just move it all into dp_ctrl_update_vx_px.

Fixed in V2.

Quoted 34 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TRAIN_MAX_SWING_REACHED

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TRAIN_MAX_PRE_EMPHASIS_REACHED

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is DP_TRAIN_PRE_EMPHASIS_SHIFT, but I'm guessing you aren't using the DP_TRAIN_PRE_EMPH_LEVEL_* values when you set p_level. So the right way to fix this is to use those #defines and get rid of this shift.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You shouldn't assume 4 lanes here, use drm_dp_link->num_lanes

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

s/0x103/DP_TRAINING_LANE0_SET/ and s/4/drm_dp_link->num_lanes/

Forgot to fix s/4/drm_dp_link->num_lanes/. Will fix this in V3.

Quoted 18 lines

Also, this will return number of bytes transmitted, not (0 || -errno).

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Fortunately (or unfortunately), the return value isn't checked. So please check the return value.

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why 4?

Will fix this in V3.

Quoted 29 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

1);

Check the return value of this and alll drm_dp_dpcd_(read|write) calls.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just return directly here. You can also just drop len and use ret (or drop ret and use len).

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

And return 0 directly here

Fixed in V2.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Here you're returning successful in the timeout case :( Once you convert the above
to direct returns, this can become return -ETIMEDOUT;

Fixed in V2.

Quoted 19 lines

I think you should also drop the number of retries drastically.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

#define that bit please

Fixed in V2.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

the train_1 comment isn't needed.

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of unbounded, this should be:

        for (tries = 0; tries < maximum_retries; tries++) {

Fixed in v2.

Quoted 19 lines

You'll need to s/break/return ret/ in the rest of the loop and move the timeout error to the bottom of the function

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Since DP_LINK_VOLTAGE_MAX == DP_LINK_VOLTAGE_LEVEL_2, you'll end up not retrying LEVEL_2 at all.

Will follow up on this and fix it in V3.

Quoted 51 lines
Quoted 51 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +51 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TRAINING_PATTERN_DISABLE

Fixed in V2.

Quoted 20 lines
Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_RECOVERED_CLOCK_OUT_EN);

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

for (tries = 0; tries < maximum_retries; tries++)

Fixed in V2.

Quoted 21 lines
Quoted 21 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_SET_ANSI_8B10B

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Drop the hand-rolled ctrl->panel->link_info and use drm_dp_link_probe to fill in drm_dp_link.

Fixed in V2.

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_MAIN_LINK_CHANNEL_CODING_SET,

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print ret

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

this should be debug loglevel

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print ret

Fixed in v2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

debug loglevel

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comments re: wmb

Fixed in V2.

Quoted 9 lines
Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

train)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This can fit on one line

Fixed in V2.

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

All of the "goto end"'s can be replaced with "return ret", then delete the end label.

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You should really protect sink_request with a lock, it's racy. I'm trying to catch the race conditions while I review, but I'd urge you to audit the driver for other places that need locking.

sink_request will be running in a single-threaded work queue. ("drm_dp_extcon" work queue). We might not need locking for sink_request.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of adding the label, just wrap the reset and train calls in an if (train) {} block.

Will fix this in V3.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

"we have to first _do_ a..."

Fixed in V2.

Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value please

Fixed in v2.

Quoted 20 lines
Quoted 20 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +20 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of doing all of this work, just store pointers to the link and pixel clock when you parse the dt. That way you can just access them directly in dp_ctrl_enable_mainlink_clocks.

These are generic implementation for DP_CORE and DP_CTRL clocks. This will help for any future upgrades where the only change will be done dtsi and maybe minor changes in Driver when we add/remove any clocks.

Quoted 22 lines
Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines

+static int dp_ctrl_disable_mainlink_clocks(struct dp_ctrl_private *ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function isn't necesary (even less so when all of the catalog abstractions are gone).

Fixed in V2.

Quoted 58 lines
Quoted 58 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +58 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

For this, you should use the DP_DPCD_QUIRK_CONSTANT_N quirk and drm_dp_has_quirk() instead.

Will follow up on this in V3.

Quoted 21 lines
Quoted 21 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Return value should be checked

Fixed in V2.

Quoted 64 lines

Below you have:

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Between the disable and enable, so you should probably have that here too?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Do you really want to continue here? Seems like you could get into an infinite loop pretty easily in the -EINVAL case.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Are you guaranteed that this doesn't race with other idle_comp uses?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

The do/while is a bit awkward, especially since it starts with a conditional block that can't possibly be true on the first iteration. How about:

	for (tries = 0; tries < max_tries; tries++) {
		ctrl->catalog->phy_lane_cfg(ctrl->catalog,
			ctrl->orientation, ctrl->link->link_params.lane_count);

		/*
		 * Disable and re-enable the mainlink clock since the
		 * link clock might have been adjusted as part of the
		 * link maintenance.
		 */
		ret = dp_ctrl_disable_mainlink_clocks(ctrl);
                if (ret)
                        return ret;

		ret = dp_ctrl_enable_mainlink_clocks(ctrl);
		if (ret)
			return ret;

		dp_ctrl_configure_source_params(ctrl);

		ctrl->catalog->config_msa(ctrl->catalog,
			drm_dp_bw_code_to_link_rate(
			ctrl->link->link_params.bw_code),
			ctrl->pixel_rate, dp_ctrl_use_fixed_nvid(ctrl));

		reinit_completion(&ctrl->idle_comp);

		ret = dp_ctrl_setup_main_link(ctrl, true);
		if (ret != -EAGAIN)
                        return ret;
Quoted 8 lines
                /* try with lower link rate */
                dp_ctrl_link_rate_down_shift(ctrl);

                ctrl->catalog->mainlink_ctrl(ctrl->catalog, false);
	}

        return -ETIMEDOUT;

Implemented the above functionality in V2.

Quoted 6 lines

There's a lot of similarity between this code and dp_ctrl_on. If the code were shared, we wouldn't have the missing 20ms delay above. So can you please pull the common bits which [re-]initialize the link into a helper function that you call from both functions?

Will follow up and see if we can have common helper function. Will update in V3.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

It's nice that we return a value here, but it's never checked by our callers :(

Will fix this in V3.

Quoted 7 lines
Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This and the "end" debug statements should be removed

Fixed in v2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

s/related/ralated/

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please propagate errors instead of swallowing them.

Will fix this in V3.

Quoted 31 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 27 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*ctrl)

drivers/gpu/drm/msm/dp/dp_ctrl.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

success = pattern_requested == DP_LINK_QUAL_PATTERN_11_D10_2;

Quoted 3 lines

Same can be done below.

Fixed in v2.

Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I feel like you should return success (or a ret). As it is, this doesn't do much.

Fixed in V2.

Quoted 14 lines
Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Downgrade to DEBUG level please

Fixed in v2.

Quoted 24 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think this function goes away with all of the catalog stuff removed.

Will fix this in V3.

Quoted 55 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This amount is excessive, 5 times should suffice (unless you have data that suggests otherwise).

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Should this be a #define in drm_dp_helper?

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why is this needed over is_connected? It seems like if you had proper locking around is_connected (which I think is necessary), you could just acquire the lock
and try the training. If it fails b/c someone unplugged the cable, that's quite Ok.

Quoted 24 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Are you guaranteed that this doesn't race with other idle_comp uses (or other dp_ctrl_on callers)?

I don't think we need to lock for idle_comp. Mentioned more details in dp_ctrl_push_idle().

Quoted 22 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 19 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return code

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return code

Will fix this in V3.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comment here as in dp_ctrl_link_maintenance(), we should pull out the common code and put it in a helper.

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is racy, sink_request could change between the check above and here.

Sink_request is accessed in single thread context.

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please remove

Fixed in V2.

Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

readl/wmb nit

Fixed in V2.

Quoted 15 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check and propagate return value

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This should return the isr instead of store it in ctrl->catalog->isr, since that could potentially be overwritten after this function acks the current interrupts.

Will fix this in V3.

Quoted 5 lines

(Also, it's only used in this function, so there's no need to store it). One you remove the catalog indirection, hopefully there will be a bunch of these cases that become clear.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

As mentioned above, just call the completions directly.

Fixed in v2.

Quoted 57 lines
Quoted 57 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +57 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Once again, these functions can be deleted. Just store the _necessary_ data in a central struct (with substructs as necessary) and call functions directly.

Removed all the functions/func_ptrs in V2 and calling the functions directly.

Quoted 38 lines
Quoted 38 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +2 -0
new file mode 100644
index 0000000..6ab221a

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_ctrl.h new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comment as catalog, these should just be functions to be called directly.

Removed these function ptrs in V2.

Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This struct is not needed, function arguments work just as well.

removed in V2.

Quoted 11 lines

drivers/gpu/drm/msm/dp/dp_debug.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_ctrl.h new file +5 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_debug.c new file +0 -0
new file mode 100644
index 0000000..5c0a8ce
@@ -0,0 +1,507 @@

The rest of this diff is not shown. View the raw message.

/snip

Quoted 6 lines

edid, hpd, and connected can all be deleted. They're provided by core.

AFAICT, you can also infer the information from dp_debug, so I think you can just drop this entire file.

Removed dp_debug.[ch] in V2.

/snip

Quoted 228 lines

Drop this too

drivers/gpu/drm/msm/dp/dp_display.c

Quoted 220 lines
drivers/gpu/drm/msm/dp/dp_debug.c new file +2 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_display.c new file +2 -0
new file mode 100644
index 0000000..8c98399

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_display.c new file +131 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*master,

drivers/gpu/drm/msm/dp/dp_display.c new file +35 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp)

drivers/gpu/drm/msm/dp/dp_display.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp,

drivers/gpu/drm/msm/dp/dp_display.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function is called from a few different threads with no locking. It seems like there's good opportunity for is_connected and notification_comp to get out of sync.

Quoted 4 lines

Additionally, is_connected is set to true before the function returns (and enable has been completed). So is that going to cause problems when we call detect/get_modes where is_connected == true and the hw is not up?

Will fix this in V3.

Quoted 6 lines

Perhaps I'm misreading this function, but it seems like the plan is to block until userspace has been notified and does a full modeset (ie: enable)? If that is the case, we usually don't want to have the hardware lit up until it's actually going to be used. In these cases, we'll wrap get_modes in enable/disable (with proper locking), and wait for modeset to leave it on.

When HPD goes high, we do dpcd reads to get the sink capabilities and then inform the framework so that "enable" gets called by drm framework.

Quoted 697 lines
Quoted 697 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +168 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp)

drivers/gpu/drm/msm/dp/dp_display.c new file +70 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp)

drivers/gpu/drm/msm/dp/dp_display.c new file +135 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +24 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +30 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +10 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

mode_pclk_khz)

drivers/gpu/drm/msm/dp/dp_display.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +30 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +18 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +77 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_display.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These 2 functions are never used, and as such g_dp_display is never used. AFAICT, the callback hooks linked from g_dp_display also aren't called from anywhere else. So can you just dump these functions, the struct, and all of the unused callback hooks?

Fixed in V2.

Quoted 42 lines
Quoted 42 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +42 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_display.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dev,

drivers/gpu/drm/msm/dp/dp_display.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called?

this is called from dpu_kms.c.
https://patchwork.kernel.org/patch/10686905/
Will be adding the DPU specific change in this V3 patch series.

Quoted 225 lines
Quoted 225 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +38 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_display.h new file +2 -0
new file mode 100644
index 0000000..ca5eae5

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_display.h new file +42 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0
new file mode 100644
index 0000000..64d6449

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_drm.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*drm_mode,

drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_mode->hsync_end;

drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_mode->vsync_end;

drivers/gpu/drm/msm/dp/dp_drm.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp_mode,

drivers/gpu/drm/msm/dp/dp_drm.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_mode->timing.h_back_porch;

drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_mode->timing.v_back_porch;

drivers/gpu/drm/msm/dp/dp_drm.c new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use the drm modes directly and delete these functions.

Fixed in V2.

Quoted 166 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 160 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_drm.c new file +143 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I'm not convinced you need any of this. The only advantage a bridge gets you is to be involved in modeset. However the only thing you do in modeset is save the mode (which is only used in enable). So why not just use the mode from the crtc's state when encoder->enable is called?

Quoted 2 lines

That allows you to delete all of the bridge stuff here.

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*display)

drivers/gpu/drm/msm/dp/dp_drm.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This isn't called from anything?

Fixed in V2.

Quoted 25 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

connected
+ * @connector: Pointer to drm connector structure
+ * @force: Force detect setting from drm framework
+ * Returns: Connector 'is connected' status
+ */
+static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,

drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

connector_status_unknown;

drivers/gpu/drm/msm/dp/dp_drm.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

no need for dp_conn, just do

Quoted 2 lines
        dp = to_dp_connector(conn)->dp_display;

Will fix this in V3.

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This is always true.

removed the bridge->encoder check in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

detect() should never do work, please remove.

Had this fixed locally but some how missed these fixes in V2. Will add the missing fixes in V3. Same think with current_status.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why?

Quoted 16 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Once dp_conn is devm managed, you can just remove this function and set .destroy to drm_connector_cleanup

Fixed in V2.

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called?

Fixed in V2.

Quoted 32 lines
Quoted 32 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_mode_probed_add()
+ * @connector: Pointer to drm connector structure
+ * Returns: Number of modes added
+ */

drivers/gpu/drm/msm/dp/dp_drm.c new file +12 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

When you get rid of dp_display_mode, please use the stack for the new drm_display_mode

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why is only one mode returned?

The get_modes() function might return one mode that is stored in dp_mode when compliance test is in progress. If not, the return value is equal to the total number of modes supported by the sink

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_drm.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This can also return -errno, you should check for that too.

Fixed in V2.

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_drm.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why continue if you know you failed?

Quoted 17 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You shouldn't overwrite these.

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This shouldn't be an error

Fixed in V2.

Quoted 83 lines
Quoted 83 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +63 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

is valid
+ * @connector: Pointer to drm connector structure
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+static enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector,

drivers/gpu/drm/msm/dp/dp_drm.c new file +13 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think the value of max_pclk_khz is racy, you'll probably want to audit its use.

Fixed in V2.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please drop this.

Fixed in v2.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

So I guess I was wrong when I said none of the g_dp_display functions are being used. I'm still unsure where they're set, perhaps there's some missing code. At any rate, what's the benefit of sticking all of that work into an abstract callback hook when it only has one implementation and one callsite.

g_dp_display is initialized in dp_display.c
We are calling the APIs directly in V2.

Quoted 25 lines

All of that code can move in here (and the same goes for the other callbacks (move the code where it's used).

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

drm_atomic_helper_connector_duplicate_state,

drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_connector_helper_funcs = {

drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp_display)
+{

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Use devm_kzalloc (you've already got a memory leak if drm_connector_init fails below).

Fixed in V2.

Quoted 21 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 18 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

&dp_connector_funcs,

drivers/gpu/drm/msm/dp/dp_drm.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These lines don't extend to 80 chars

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_drm.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These are already false by virtue of kzalloc

Fixed in V2.

Quoted 116 lines
Quoted 116 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_drm.h new file +2 -0
new file mode 100644
index 0000000..efbc1be

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_drm.h new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

initialization steps
+ * @connector: Pointer to drm connector structure
+ * @display: Pointer to private display handle
+ * Returns: Zero on success
+ */
+int dp_connector_post_init(struct drm_connector *connector, void *display);

drivers/gpu/drm/msm/dp/dp_drm.h new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*dp_display);

drivers/gpu/drm/msm/dp/dp_drm.h new file +3 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0
new file mode 100644
index 0000000..635c13b

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_extcon.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this used?

Fixed in V2.

Quoted 21 lines
Quoted 21 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

No need to have this just for one debug statement, just print the enum value with %d below.

Removed them in V2.

Quoted 5 lines
Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here.

Most of these static functions (usbpd)have been removed in V2.

Quoted 17 lines
Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called from?

Removed in V2.

Quoted 17 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Please #define hardcoded values

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

All of the values in cap->port seem to be hardcoded, so why not just use the #define's directly where applicable?

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Where is this called?

Removed in v2.

Quoted 28 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only multi_func, hpd_high, and hpd_irq are used out of this struct. Can you cull the values down? hpd_irq is also only set to its hardcoded value, so just use that value directly where applicable.

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function is also unused

Removed in V2.

Quoted 38 lines
Quoted 38 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +38 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just return -EINVAL and get rid of the error label and rc.

fixed in V2.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If forced_disconnect is always !dp_usbpd->hpd_high, why not just use !dp_usbpd->hpd_high directly?

Will fix this in V3.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Do you need locking in this function/file?

I don't think so, This function is called by single threaded work queue.

Quoted 25 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

        return (property.intval) ? 2 : 4;
Quoted 3 lines

and delete lanes

Fixed in V2.

Quoted 14 lines
Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Can fit on 1 line

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Can fit on 1 line, plus remove all () from this, they're not needed.

Fixed in V2.

Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This part is a bit confusing, you add a helper function to get the lanes, and interpret the USB_SS property to return 2 vs. 4, but then immediately convert that back into what the USB_SS property returns. Instead, remove the helper function and read USB_SS directly here.

Will implement this in V3.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I feel like this can never be false anyways, but you're not using either of these members in the conditional block. So why not just call dp_extcon_connect unconditionally?

Will implement this in V3.

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

Fixed in v2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here.

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Check return value

Fixed in V2.

Quoted 11 lines
Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*extcon_priv)

drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

create_singlethread_workqueue("drm_dp_extcon");

What's the benefit of using a dedicated workqueue instead of the system wq?

We wanted to have a single-threaded workqueue to avoid any synchronization issues. Also, following the existing implementation in upstream drivers for extcon events.

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This function can't fail, so it should return void. In fact, this really doesn't need to be a separate function, roll it into dp_extcon_register().

Fixed in V2.

Quoted 17 lines
Quoted 17 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +17 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Yikes, this doesn't look like an error!

Fixed in V2.

Quoted 7 lines
Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_usbpd);

drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

extcon_priv->extcon,

drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why keep going and create the workqueue if we have no notifier? This should probably be a return.

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

return ret?

Fixed in V2.

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same here

Fixed in V2.

Quoted 7 lines
Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +7 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

dp_usbpd);

drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

extcon_priv->extcon,

drivers/gpu/drm/msm/dp/dp_extcon.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

Fixed in V2.

Quoted 11 lines
Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*cb)

drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

All the unnecessary printed added for debugging are removed in V2.

Quoted 24 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 21 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

remove.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_extcon.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This label isn't useful, return directly where applicable.

Removed in V2.

Quoted 162 lines
Quoted 162 lines
drivers/gpu/drm/msm/dp/dp_extcon.c new file +16 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_extcon.h new file +2 -0
new file mode 100644
index 0000000..1f83a18

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_extcon.h new file +91 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*cb);

drivers/gpu/drm/msm/dp/dp_extcon.h new file +7 -0

Lines of this file are not shown. View the raw message.

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0
new file mode 100644
index 0000000..5ab1efc

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

These should be in drm_dp_helper.h

Fixed in V2.

Quoted 329 lines
Quoted 329 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +67 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

addr)

drivers/gpu/drm/msm/dp/dp_link.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +65 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*link)

drivers/gpu/drm/msm/dp/dp_link.c new file +80 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

from DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the audio link pattern parameters.
+ */
+static int dp_link_parse_audio_pattern_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +75 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

No need for this, just print the value in the debug statement.

Removed in V2.

Quoted 28 lines
Quoted 28 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +28 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same thing here, just remove this and print the enum value.

Removed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

pass-by-value doesn't need const same comment applies elsewhere, please sweep the code for other instances.

Quoted 11 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If you're going to check len < 2, you should probably also check len > 2 to prevent overflow. At this point, len can really only be 2, so you can just remove
it entirely as an argument.

Fixed in v2. (checking for len != 2)

Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +16 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Same comment here rt bounds checking

Fixed in V2.

Quoted 59 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 31 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Putting aside the uninformative names, these dp_link_parse_timing_params* can be combined into one pretty easily, like:

static int dp_link_read_u32(struct dp_link_private *link, unsigned int offset,
u32 *val, int num_bytes)

{
        int i;
        ssize_t ret;
        __be32 tmp_val;

        for (i = 0; num_bytes > 0; i += sizeof(*val)) {
                int to_read = min(sizeof(tmp_val), num_bytes);

                tmp_val = 0;
                ret = drm_dp_dpcd_read(link->aux->drm_aux, offset + i, 
&tmp_val,
                                       to_read);
                if (rlen < 0) {
                        /* print error message here */
                        return rlen;
                }
                val[i] = be32_to_cpu(tmp_val);
                num_bytes -= to_read;
        }
        return 0;
}
Quoted 5 lines

If you need to strip off the first bit, do it from the caller.

I didn't compile or test this, so it might need tweaking, but you get the idea.

Will follow up on this implementation and fix the params* APIs in V3.

Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

from DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the video link pattern and the link
+ * bit depth requested by the sink and, and if the values parsed are valid.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines

+ */
+static int dp_link_parse_video_pattern_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

All the rlen in each function have been changed to ssize_t V2.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Why do you need data and bp? I think you only need one.

Fixed in V2.

Quoted 40 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 37 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +25 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

*/

drivers/gpu/drm/msm/dp/dp_link.c new file +11 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This mask isolates one bit from data

Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

and this function returns true if the input is 0 || 1

So remove this code, and remove dp_link_is_dynamic_range_valid.

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

And now you can just assign this directly. You should probably stay consistent and store the value shifted like the other values you're storing.

Fixed in V2.

Quoted 113 lines
Quoted 113 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +27 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_h_total);

drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_v_total);

drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_h_start);

drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_v_start);

drivers/gpu/drm/msm/dp/dp_link.c new file +32 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link->dp_link.test_video.test_h_width);

drivers/gpu/drm/msm/dp/dp_link.c new file +21 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_TEST_REFRESH_RATE_NUMERATOR,

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines

(DP_TEST_REFRESH_RATE_NUMERATOR)\n");

drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Instead of sprinkling all of these pr_debug messages around, just have one big debug at the end to print everything.

Fixed in V2.

Quoted 4 lines
Quoted 1 line

+exit:

This label isn't useful, just return directly above

Fixed in V2.

Quoted 12 lines
Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

parameters from
+ * DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
+ * count (Byte 0x220), and if these values parse are valid.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines

+ */
+static int dp_link_parse_link_training_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You don't need both bp and data

Fixed in v2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use 1 directly below.

All the one byte reads have been changed to drm_dp_dpcd_readb in V2.

Quoted 22 lines
Quoted 22 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +22 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

DP_MAX_LANE_COUNT_MASK

Fixed in V2.

Quoted 51 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

You might also want to data against max lanes

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

return directly above and remove exit + ret;

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 31 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

phy_test_pattern_sel)

drivers/gpu/drm/msm/dp/dp_link.c new file +19 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

being
+ * requested.
+ */
+static int dp_link_parse_phy_test_params(struct dp_link_private *link)

drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only need one of these.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just use 1 below

All the above comments in this function are fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

FWIW, drm_dp_dpcd_read will return either len or an -errno. Partial reads return -EPROTO. So instead of checking that rlen < param_len, you can just do rlen < 0.

Fixed in V2.

Quoted 3 lines

Please also change all of the 1-byte reads over to using drm_dp_dpcd_readb().

Fixed in V2.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

print and return rlen.

Fixed in V2.

Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Just embed that code here.

Will fix this in V3.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove label/ret and return directly

Fixed in v2.

Quoted 14 lines
Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +14 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Remove this and just print the enum.

Fixed in V2.

Quoted 14 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

link request
+ * @link: link requested by the sink
+ *
+ * Returns true if the requested link is a permitted audio/video link.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Should you be masking link to isolate these bits?

Quoted 11 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

And once you mask the value, just check if any of the bits are set instead of enumerating all possible values.

Updated the function in V2.

Quoted 18 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

supported
+ * @test_requested: link requested by the sink
+ *
+ * Returns true if the requested link is supported.
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I think this all equates to:

Quoted 5 lines
	return test_requested != DP_TEST_LINK_FAUX_PATTERN;

and in that case, you can just remove this function and insert that condition in the if statement below.

Removed this function and implemented at the caller in V2 patch.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

This doesn't warrant its own function. Also, should this be & instead of ==?

Fixed in V2.

Quoted 26 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +3 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

sink
+ * @link: Display Port Driver data
+ *
+ * Parses the DPCD to check if an automated link is requested (Byte 0x201),
+ * and what type of link automation is being requested (Byte 0x218).
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Only need 1 of bp/data

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

ssize_t

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Not needed, use drm_dp_dpcd_readb()

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Print error. This goes for other failure messages in this file.

Addressed all the comments above in this function in V2.

Quoted 31 lines
Quoted 31 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +31 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_link.c

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

data);

drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

If test_requested is only used in the scope of this function, just use a local and pass it around. If test_requested is used outside the scope of this function, you need locking.

4,069 lines not shown · raw message

Parts of this message are not shown here. View the raw message.

reviewer
#16 lore raw

Re: [Freedreno] [DPU PATCH 2/3] drm/msm/dp: add displayPort driver support

Quoted 11 lines · On Thu, Feb 14, 2019 at 04:28:33AM -0800, [email protected] wrote:
Quoted 9 lines · Sean Paul
Quoted 7 lines · Chandan Uddaraju

Add the needed displayPort files to enable DP driver on msm target.

"dp_display" module is the main module that calls into other sub-modules. "dp_drm" file represents the interface between DRM framework and DP driver.

Quoted 6 lines

Hello Sean,
I have responded to all of your comments and queries. I have specified the comments addressed
in V2 patch series and what I have missed that will be fixed in V3.

/snip

Quoted 11 lines
Quoted 10 lines

drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h line 29

Quoted 5 lines
drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +4 -0
+struct dss_io_data {
+	u32 len;
+	void __iomem *base;
+};

len isn't used anywhere, so this struct can go away. If the struct goes away,
you can really simplify (or eliminate msm_dss_ioremap_byname())

Quoted 3 lines

We want to keep this since we use len for our internal unit level testing and in simulation mode.

That's not really a valid reason to keep unused code around. We can't reasonably expect upstream developers to know which structs and unused fields are used for Qualcomm's downstream testing, and afaict, those results aren't published so there's no benefit to the upsteam community.

So you can either opensource the unit tests along with the driver, or keep the downstream code in the downstream kernel.

/snip

Quoted 8 lines
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 29

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+#define dp_catalog_get_priv(x) { \

static inline struct dp_catalog_private *dp_catalog_get_priv(...)

{
        ...
}
Quoted 6 lines

For inline, we have to use 3 different functions (one each for aux, ctrl and panel).
Looking at "type-checking" w.r.t macro, container_of will through an error if its not valid pointer.
Please let me know if you still want to change this macro to inline func.

Yeah, I think it's worth it to have the 3.

Quoted 5 lines
Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 34

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+	struct dp_catalog *dp_catalog; \
+	dp_catalog = container_of(x, struct dp_catalog, x); \
+	catalog = container_of(dp_catalog, struct dp_catalog_private, \
+				dp_catalog); \
+}

/snip

Quoted 9 lines
Quoted 5 lines

Then again, I'm guessing hitting the NULL case is likely impossible, so you can
probably remove all of the machinery around checking !aux.

Removed most of the arg null checks except few APIs where unit-testing/simulator-mode is used.

There should only be null checks if null is a possibility. If you have pathelogical unit tests injecting bogus values in your function, you should probably just fix/delete those unit tests. If upstream doesn't have visibility into your internal testing, we can't distinguish between test-pleasing vs unused code.

Quoted 76 lines
Quoted 12 lines
Quoted 12 lines

+static void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog_ctrl *ctrl,

drivers/gpu/drm/msm/dp/dp_catalog.c new file +10 -0
+			u32 pattern)
+{
+	struct dp_catalog_private *catalog;
+	u32 value = 0x0;
+	void __iomem *base = NULL;
+
+	if (!ctrl) {
+		pr_err("invalid input\n");
+		return;
+	}
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 830

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+	dp_catalog_get_priv(ctrl);
+
+	base = catalog->io->dp_link.base;
+
+	dp_write(base + DP_STATE_CTRL, 0x0);

Do you really need to do this?

Yes, to make sure no other pattern is set/enabled in hardware before any new pattern is configured.

Quoted 29 lines
Quoted 29 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +29 -0
+
+	switch (pattern) {
+	case DP_TEST_PHY_PATTERN_D10_2_NO_SCRAMBLING:
+		dp_write(base + DP_STATE_CTRL, 0x1);
+		break;
+	case DP_TEST_PHY_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT:
+		value &= ~(1 << 16);
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		value |= 0xFC;
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		dp_write(base + DP_MAINLINK_LEVELS, 0x2);
+		dp_write(base + DP_STATE_CTRL, 0x10);
+		break;
+	case DP_TEST_PHY_PATTERN_PRBS7:
+		dp_write(base + DP_STATE_CTRL, 0x20);
+		break;
+	case DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN:
+		dp_write(base + DP_STATE_CTRL, 0x40);
+		/* 00111110000011111000001111100000 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG0, 0x3E0F83E0);
+		/* 00001111100000111110000011111000 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG1, 0x0F83E0F8);
+		/* 1111100000111110 */
+		dp_write(base + DP_TEST_80BIT_CUSTOM_PATTERN_REG2, 0x0000F83E);
+		break;
+	case DP_TEST_PHY_PATTERN_HBR2_CTS_EYE_PATTERN:
+		value = BIT(16);
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		value |= 0xFC;
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 842

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+		dp_write(base + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET, value);
+		dp_write(base + DP_MAINLINK_LEVELS, 0x2);
+		dp_write(base + DP_STATE_CTRL, 0x10);

This code is the exact same as the case for DP_TEST_PHY_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT, aside from BIT(16) vs ~BIT(16). Can you please combine these cases
and share code?

Will fix this in V3.

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 867

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+		break;
+	default:
+		pr_debug("No valid test pattern requested: 0x%x\n", pattern);
+		return;
+	}

All of the DP_STATE_CTRL values should be #defined, and you can move the write
down here instead of duplicating it everywhere (with DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN writing a 0).

Quoted 5 lines

All the DP_STATE_CTRL values are defines in V2.

I am not clear on moving the write operations after the switch cases. Can you please provide
some more details?

I think what I meant was that since all cases finish with a write to DP_STATE_CTRL, you can move that write out of each case and put it at the bottom. But I think I missed that DP_STATE_CTRL is set at the beginning of DP_TEST_PHY_PATTERN_80_BIT_CUSTOM_PATTERN, so I don't think that'll work.

/snip

Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +6 -0
+struct dp_ctrl_private {
+	struct dp_ctrl dp_ctrl;
+
+	struct device *dev;
+	struct dp_aux *aux;
+	struct dp_panel *panel;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 67

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +4 -0
+	struct dp_link *link;
+	struct dp_power *power;
+	struct dp_parser *parser;
+	struct dp_catalog_ctrl *catalog;

Once you remove struct dp_ctrl and call the functions directly, I suspect you
can get rid of all of these.

Quoted 7 lines

Even though we call the functions directly, we still need variables present in each module.
For example, we need to access link parameters, panel parameters etc

Unnecessary stuff is removed but we still need other variables in the structure. All have been
updated in V2.

Ok, I'll re-evaluate in v3

/snip

Quoted 34 lines
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 120

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +3 -0
+static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl)
+{
+	int const idle_pattern_completion_timeout_ms = 3 * HZ / 100;

This should be #define'd outside of the functioninstead. Also, why the '_ms_'
suffix? The units are in jiffies.

Quoted 7 lines

I think something like

#define IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES (30 * HZ / 1000) /* 30 ms */

would be clearer.

Fixed in V2.

Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +8 -0
+	struct dp_ctrl_private *ctrl;
+
+	if (!dp_ctrl) {
+		pr_err("Invalid input data\n");
+		return;
+	}
+
+	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
Quoted 9 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+	reinit_completion(&ctrl->idle_comp);

This function is called from a bunch of places, and idle_comp is also used in a
bunch of places. Are you certain this is thread-safe if you have concurrent
callers or users of idle_comp?

Quoted 5 lines

I don't think we need any synchronization logic for idle_comp since it is reinitialized only
when the complete core is reset. Only place where it is needed is in push_idle which already has
a mutex.

So here are the callsites for push_idle():
- dp_display_clean- called on extcon event thread, unlocked
- dp_display_pre_disable- called on drm thread, locked with modeset locks
- dp_ctrl_link_maintenance- called in hpd handler, unlocked

It _seems_ like there could be races here, and I don't know which mutex you're referring to above. Mind walking me through it in more detail?

Quoted 9 lines
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 135

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +5 -0
+	dp_ctrl_state_ctrl(ctrl, ST_PUSH_IDLE);
+
+	if (!wait_for_completion_timeout(&ctrl->idle_comp,
+			idle_pattern_completion_timeout_ms))
+		pr_warn("PUSH_IDLE pattern timedout\n");

Return an error?

Quoted 3 lines

Its not fatal error since we are going to reset the controller and we are going to recover from
this timeout.

In that case, can you please downgrade the log level to debug or info?

/snip

Quoted 9 lines
Quoted 9 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)

You should really protect sink_request with a lock, it's racy. I'm trying
to catch the race conditions while I review, but I'd urge you to audit the
driver for other places that need locking.

Quoted 4 lines

sink_request will be running in a single-threaded work queue. ("drm_dp_extcon" work queue).
We might not need locking for sink_request.

It seems like sink_request could change in between reads in dp_ctrl_on? dp_ctrl_on reads the value twice, and calls dp_ctrl_setup_main_link which also reads the value.

/snip

Quoted 25 lines
Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +16 -0
+static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
+				   char *name, u32 rate)
+{
+	u32 num = ctrl->parser->mp[DP_CTRL_PM].num_clk;
+	struct dss_clk *cfg = ctrl->parser->mp[DP_CTRL_PM].clk_config;
+
+	while (num && strcmp(cfg->clk_name, name)) {
+		num--;
+		cfg++;
+	}
+
+	pr_debug("setting rate=%d on clk=%s\n", rate, name);
+
+	if (num)
+		cfg->rate = rate;
+	else
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_ctrl.c line 1048

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_ctrl.c new file +2 -0
+		pr_err("%s clock could not be set with rate %d\n", name, rate);
+}

Instead of doing all of this work, just store pointers to the link and pixel
clock when you parse the dt. That way you can just access them directly in
dp_ctrl_enable_mainlink_clocks.

Quoted 5 lines

These are generic implementation for DP_CORE and DP_CTRL clocks. This will help
for any future upgrades where the only change will be done dtsi and maybe minor
changes in Driver when we add/remove any clocks.

Just add new pointers and NULL checks in the future if/when this is needed.

/snip

Quoted 8 lines
Quoted 6 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)

This is racy, sink_request could change between the check above and here.

Sink_request is accessed in single thread context.

Ah, so I mentioned that in the earlier review. I guess I'm not seeing what prevents that single thread from modifying the value twice? This code will be run in a different thread, so it really seems like there could be a race here.

/snip

Quoted 50 lines
Quoted 31 lines
Quoted 23 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +11 -0
+static void dp_display_send_hpd_event(struct msm_dp *dp_display)
+{
+	struct dp_display_private *dp;
+	struct drm_connector *connector;
+
+	if (!dp_display) {
+		pr_err("invalid input\n");
+		return;
+	}
+
+	dp = container_of(dp_display, struct dp_display_private,

dp_display);

drivers/gpu/drm/msm/dp/dp_display.c new file +10 -0
+	if (!dp) {
+		pr_err("invalid params\n");
+		return;
+	}
+
+	connector = dp->dp_display.connector;
+	drm_helper_hpd_irq_event(connector->dev);
+}
+
+static int dp_display_send_hpd_notification(struct

dp_display_private *dp,

drivers/gpu/drm/msm/dp/dp_display.c line 206

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_display.c new file +1 -0
+					    bool hpd)

This function is called from a few different threads with no locking. It seems
like there's good opportunity for is_connected and notification_comp to get out
of sync.

Quoted 6 lines

Additionally, is_connected is set to true before the function returns (and
enable has been completed). So is that going to cause problems when we call
detect/get_modes where is_connected == true and the hw is not up?

Will fix this in V3.

Quoted 10 lines

Perhaps I'm misreading this function, but it seems like the plan is to block
until userspace has been notified and does a full modeset (ie: enable)? If that
is the case, we usually don't want to have the hardware lit up until it's
actually going to be used. In these cases, we'll wrap get_modes in enable/disable (with proper locking), and wait for modeset to leave it on.

Quoted 4 lines

When HPD goes high, we do dpcd reads to get the sink capabilities and then inform the framework so that "enable"
gets called by drm framework.

I'm not sure I follow what you're saying. Is notification_comp meant to ratelimit/debounce hpd notifications? I don't think it's needed, and if it is, it would be interesting to know why.

Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +14 -0
+{
+	if ((hpd && dp->dp_display.is_connected) ||
+			(!hpd && !dp->dp_display.is_connected)) {
+		pr_info("HPD already %s\n", (hpd ? "on" : "off"));
+		return 0;
+	}
+
+	/* reset video pattern flag on disconnect */
+	if (!hpd)
+		dp->panel->video_test = false;
+
+	dp->dp_display.is_connected = hpd;
+	reinit_completion(&dp->notification_comp);
+	dp_display_send_hpd_event(&dp->dp_display);
Quoted 8 lines
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_display.c line 228

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_display.c new file +8 -0
+
+	if (!wait_for_completion_timeout(&dp->notification_comp, HZ * 2)) {
+		pr_warn("%s timeout\n", hpd ? "connect" : "disconnect");
+		return -EINVAL;
+	}
+
+	return 0;
+}

/snip

Quoted 36 lines
Quoted 18 lines
Quoted 18 lines

+/**
+ * dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * @connector: Pointer to drm connector structure
+ * Returns: Number of modes added
+ */

drivers/gpu/drm/msm/dp/dp_drm.c new file +12 -0
+static int dp_connector_get_modes(struct drm_connector *connector)
+{
+	int rc = 0;
+	struct msm_dp *dp;
+	struct dp_display_mode *dp_mode = NULL;
+	struct drm_display_mode *m, drm_mode;
+	struct dp_connector *dp_conn;
+
+	if (!connector)
+		return 0;
+
+	dp_conn = to_dp_connector(connector);
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_drm.c line 371

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0
+	dp = dp_conn->dp_display;
+
+	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
+	if (!dp_mode)
+		return 0;

When you get rid of dp_display_mode, please use the stack for the new drm_display_mode

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_drm.c line 375

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0
+
+	/* pluggable case assumes EDID is read when HPD */
+	if (dp->is_connected) {
+		rc = dp->get_modes(dp, dp_mode);

Why is only one mode returned?

Quoted 4 lines

The get_modes() function might return one mode that is stored in dp_mode when compliance test is in progress. If not, the return value is equal to the total number of modes supported by the sink

Ah. I think this would be better to do this work in dp_panel_get_modes and return 1 from there. Then you can remove all of the special handling from this function.

Quoted 37 lines
Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +1 -0
+		if (!rc)

This can also return -errno, you should check for that too.

Fixed in V2.

Quoted 4 lines

drivers/gpu/drm/msm/dp/dp_drm.c line 377

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_drm.c new file +1 -0
+			pr_err("failed to get DP sink modes, rc=%d\n", rc);

Why continue if you know you failed?

Quoted 17 lines
Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0
+
+		if (dp_mode->timing.pixel_clk_khz) { /* valid DP mode */
+			memset(&drm_mode, 0x0, sizeof(drm_mode));
+			convert_to_drm_mode(dp_mode, &drm_mode);

drivers/gpu/drm/msm/dp/dp_drm.c line 391

Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +10 -0
+			m = drm_mode_duplicate(connector->dev, &drm_mode);
+			if (!m) {
+				pr_err("failed to add mode %ux%u\n",
+				       drm_mode.hdisplay,
+				       drm_mode.vdisplay);
+				kfree(dp_mode);
+				return 0;
+			}
+			m->width_mm = connector->display_info.width_mm;
+			m->height_mm = connector->display_info.height_mm;

You shouldn't overwrite these.

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_drm.c line 395

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +4 -0
+			drm_mode_probed_add(connector, m);
+		}
+	} else {
+		pr_err("No sink connected\n");

This shouldn't be an error

Quoted 7 lines

Fixed in V2.

Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_drm.c line 400

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_drm.c new file +5 -0
+	}
+	kfree(dp_mode);
+
+	return rc;
+}

/snip

Quoted 77 lines
Quoted 22 lines

drivers/gpu/drm/msm/dp/dp_link.c line 791

Quoted 11 lines

+ * @link: Display Port Driver data
+ *
+ * Parses the DPCD to check if an automated link is requested (Byte 0x201),
+ * and what type of link automation is being requested (Byte 0x218).
+ */

drivers/gpu/drm/msm/dp/dp_link.c new file +5 -0
+static int dp_link_parse_request(struct dp_link_private *link)
+{
+	int ret = 0;
+	u8 bp;
+	u8 data;

Only need 1 of bp/data

Review

Quoted 1 line
(quoted diff) +1 -0
+	int rlen;

ssize_t

Review

Quoted 1 line
(quoted diff) +1 -0
+	u32 const param_len = 0x1;

Not needed, use drm_dp_dpcd_readb()

Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_link.c line 802

Quoted 9 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +9 -0
+
+	/**
+	 * Read the device service IRQ vector (Byte 0x201) to determine
+	 * whether an automated link has been requested by the sink.
+	 */
+	rlen = drm_dp_dpcd_read(link->aux->drm_aux,
+		DP_DEVICE_SERVICE_IRQ_VECTOR, &bp, param_len);
+	if (rlen < param_len) {
+		pr_err("aux read failed\n");

Print error. This goes for other failure messages in this file.

Addressed all the comments above in this function in V2.

Quoted 32 lines
Quoted 32 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +32 -0
+		ret = -EINVAL;
+		goto end;
+	}
+
+	data = bp;
+
+	pr_debug("device service irq vector = 0x%x\n", data);
+
+	if (!(data & DP_AUTOMATED_TEST_REQUEST)) {
+		pr_debug("no test requested\n");
+		return 0;
+	}
+
+	/**
+	 * Read the link request byte (Byte 0x218) to determine what type
+	 * of automated link has been requested by the sink.
+	 */
+	rlen = drm_dp_dpcd_read(link->aux->drm_aux, DP_TEST_REQUEST,
+			&bp, param_len);
+	if (rlen < param_len) {
+		pr_err("aux read failed\n");
+		ret = -EINVAL;
+		goto end;
+	}
+
+	data = bp;
+
+	if (!dp_link_is_test_supported(data)) {
+		pr_debug("link 0x%x not supported\n", data);
+		goto end;
+	}
+
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_link.c line 836

Quoted 3 lines
(quoted diff) +1 -0
+	pr_debug("%s (0x%x) requested\n", dp_link_get_test_name(data),

data);

drivers/gpu/drm/msm/dp/dp_link.c new file +1 -0
+	link->request.test_requested = data;

If test_requested is only used in the scope of this function, just use a local
and pass it around. If test_requested is used outside the scope of this function, you need locking.

Quoted 5 lines

test_requested in only used in dp_link.c. But we use this in dp_debug for debugging. We also
use this in unit testing. This is one of main reason we have it in dp_link structure.

Ok, same comment regarding unit testing as above. Please change this to a local in the upstream version.

/snip

Quoted 6 lines
Quoted 4 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	/**

/*

Multi-line comments, we use "/**"

This will cause warnings in the htmldocs build. See
https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting

/snip

Quoted 17 lines
Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +8 -0
+static void dp_link_send_test_response(struct dp_link *dp_link)
+{
+	struct dp_link_private *link = NULL;
+	u32 const response_len = 0x1;
+
+	if (!dp_link) {
+		pr_err("invalid input\n");
+		return;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c line 966

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +6 -0
+	}
+
+	link = container_of(dp_link, struct dp_link_private, dp_link);
+
+	drm_dp_dpcd_write(link->aux->drm_aux, DP_TEST_RESPONSE,
+			&dp_link->test_response, response_len);

I strongly suspect you should have locking protecting test_response.

Quoted 3 lines

Will cross-check whether we need locking and fix it in V3. Just curious, do you still think
we need locking even though we handle this in a single thread?

AFAICT, this is called from the drm thread (via dp_ctrl_on->dp_ctrl_send_phy_test_pattern), and extcon hpd thread?

/snip

Quoted 11 lines
Quoted 11 lines

drivers/gpu/drm/msm/dp/dp_link.c line 1135

Quoted 4 lines

+static u8 get_link_status(const u8
link_status[DP_LINK_STATUS_SIZE], int r)

drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0
+{
+	return link_status[r - DP_LANE0_1_STATUS];

I don't think you're really supposed to reach into the link_status like this.
How about adding a new helper to check for DP_LINK_STATUS_UPDATED and one for
DP_DOWNSTREAM_PORT_STATUS_CHANGED?

Quoted 3 lines

This function is similar to function in upstream drm_dp_helper.c file.
https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-3.18/drivers/gpu/drm/drm_dp_helper.c#259

Yeah, that's my point, it's something that's done internally to the helper. Adding a couple helpers to drm_dp_helper will clean up this code and also benefit others who need to do the same thing (I don't see anyone else checking those bits yet).

Quoted 1 line
Quoted 1 line
Quoted 1 line

+}

/snip

Quoted 14 lines
Quoted 5 lines
Quoted 5 lines

+static bool dp_link_is_ds_port_status_changed(struct dp_link_private *link)

(quoted diff) +2 -0
+{
+	if (get_link_status(link->link_status,

DP_LANE_ALIGN_STATUS_UPDATED) &

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c line 1174

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +4 -0
+		DP_DOWNSTREAM_PORT_STATUS_CHANGED) /* port status changed */
+		return true;
+
+	if (link->prev_sink_count != link->dp_link.sink_count.count)

It seems like this is running in a separate thread from where prev_sink_count is
set, potential race here?

Quoted 4 lines

I don't think we might need locking here. All the updates/checks related to prev_sink_count are done
in dp_link_process_request() which will run in single threaded work queue.

Hmm, didn't realize it's only set/accessed in dp_link_process_request. Can you change this to a local var and just pass it via arguments so 1- the code is more clear, and 2- there's no chance it gets stomped by another thread.

/snip

Quoted 34 lines
Quoted 25 lines
Quoted 25 lines

+static u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp)

drivers/gpu/drm/msm/dp/dp_link.c new file +23 -0
+{
+	u32 tbd;
+
+	/*
+	 * Few simplistic rules and assumptions made here:
+	 *    1. Test bit depth is bit depth per color component
+	 *    2. Assume 3 color components
+	 */
+	switch (bpp) {
+	case 18:
+		tbd = DP_TEST_BIT_DEPTH_6;
+		break;
+	case 24:
+		tbd = DP_TEST_BIT_DEPTH_8;
+		break;
+	case 30:
+		tbd = DP_TEST_BIT_DEPTH_10;
+		break;
+	default:
+		tbd = DP_TEST_BIT_DEPTH_UNKNOWN;
+		break;
+	}
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_link.c line 1497

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_link.c new file +2 -0
+	if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN)
+		tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT);

AFAICT tbd corresponds to a SoC register value, as opposed to the DPCD value.
It's a happy coincidence that they're the same, however I think you should use a
separate msm-specific #define instead of the drm_dp_helper values.

Quoted 3 lines

These are standard bpp values and will match to the DPCD values. For the same reason
we are using existing standard macros.

Hmm, Ok. Mind adding a comment then? It's a bit confusing to mix the values.

/snip

Quoted 8 lines
Quoted 6 lines

drivers/gpu/drm/msm/dp/dp_panel.c line 201

Quoted 1 line
drivers/gpu/drm/msm/dp/dp_panel.c new file +1 -0
+	rc = dp_panel_read_edid(dp_panel, connector);

Why read the edid so early? Can't you wait until get_modes is called (you'll
have to re-read anyways).

We won't do re-read again when get_modes is called.

You really should be, userspace should determine when/whether to limit it. With that change, you can remove the read from here.

Quoted 14 lines
Quoted 12 lines

drivers/gpu/drm/msm/dp/dp_panel.c line 209

Quoted 8 lines
drivers/gpu/drm/msm/dp/dp_panel.c new file +8 -0
+	if (rc) {
+		pr_err("panel edid read failed, set failsafe mode\n");
+		return rc;
+	}
+
+	if (panel->aux_cfg_update_done) {
+		pr_debug("read DPCD with updated AUX config\n");
+		dp_panel_read_dpcd(dp_panel);

Check return value. Should you also check the rate/lane_count validity again too?

Fixed in V2.

Quoted 7 lines
Quoted 4 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+		panel->aux_cfg_update_done = false;

Should you have locking for aux_cfg_update_done?

panel_read_edid() and aux_cfg_update_done = false is done one after the other in this function. I don't think
we locking for this.

Another good case of not needing to store this in a central place. Just make this a local in dp_panel_read_sink_caps().

/snip

Quoted 24 lines
Quoted 15 lines
Quoted 15 lines
drivers/gpu/drm/msm/dp/dp_parser.c new file +15 -0
+	mp->vreg_config = devm_kzalloc(&parser->pdev->dev,
+		sizeof(struct dss_vreg) * mp->num_vreg, GFP_KERNEL);
+	if (!mp->vreg_config) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	for_each_child_of_node(supply_root_node, supply_node) {
+		const char *st = NULL;
+		/* vreg-name */
+		rc = of_property_read_string(supply_node,
+			"qcom,supply-name", &st);
+		if (rc) {
+			pr_err("error reading name. rc=%d\n",
+				 rc);
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_parser.c line 339

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_parser.c new file +4 -0
+			goto error;
+		}
+		snprintf(mp->vreg_config[i].vreg_name,
+			ARRAY_SIZE((mp->vreg_config[i].vreg_name)), "%s", st);

Instead of storing the name just to get a regulator reference later, why don't
you just grab the reference now and avoid the string ops?

Quoted 3 lines

Vreg keep changing for each chip. This is more generic implementation that avoids doing changes to the code.
Updating the dtsi-platform specific changes will have access to the vregs.

Changing the code is fun, string operations are not fun. In order to maximize fun, can we please change these?

More seriously, trying to come up with generic solutions is super tricky and more often than not, incorrect. The only thing we know for certain about designing code is that it will eventually be obsolete :)

/snip

Quoted 9 lines
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_parser.c line 503

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_parser.c new file +6 -0
+
+		if (dp_parser_check_prefix(core_clk, clk_name))
+			core_clk_count++;
+
+		if (dp_parser_check_prefix(ctrl_clk, clk_name))
+			ctrl_clk_count++;

Just use "core"/"ctrl" directly here.

Quoted 8 lines
Quoted 4 lines

Have you considered just having 2 clock lists? That would avoid having to do
this.

I didn't get what you meant by two clock lists. We currently have two clock list to store them locally.
You mean having two clock lists in dtsi?

Yes, I believe that's what I meant.

/snip

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

Signature · 5 lines
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): 03cce7603e8e65a88d08d9f3558019ac-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

#18 lore raw

Re: [DPU PATCH 2/3] drm/msm/dp: add displayPort driver support

On 2019-02-14 04:28, [email protected] wrote:
Hello Sean
I had few more queries regarding your comments. Can you please provide your feedback? (Queries/responses are present below)

thanks
Chandan

Quoted 172 lines · Sean Paul
Quoted 9 lines · Chandan Uddaraju
Quoted 7 lines

Add the needed displayPort files to enable DP driver on msm target.

"dp_display" module is the main module that calls into other sub-modules. "dp_drm" file represents the interface between DRM framework and DP driver.

Hello Sean,
I have responded to all of your comments and queries. I have specified the comments addressed
in V2 patch series and what I have missed that will be fixed in V3.

Quoted 119 lines

Hi Chandan,
A few themes which I've pointed out below, but want to call out at the top so it's obvious.

- Please remove all superfluous NULL checks at the beginning of functions.
Included in this is reflowing initialization of variables and
checking that
return types still make sense (ie: if a function's only error path
is the NULL
check, make it void).
- Please remove all of the new callbacks and just call functions directly. This
should also get rid of the _get/_put functions that allocate/set
them up
- Please consolidate state structs into one struct with a few substructs,
there's too much state right now.
- Please #define hardcoded values
- Instead of sprinkling wmb() everywhere, use readl/writel instead of *_relaxed
- There are a bunch of races that I found, please audit the code and remove
races with locks as necessary
- I tried to catch as much dead code as possible, please audit the rest for
unused structs/variables/functions/etc
- Use drm dp helper structs for link parameter storage

Quoted 89 lines
---
 drivers/gpu/drm/msm/Kconfig                 |    9 +
 drivers/gpu/drm/msm/Makefile                |   15 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c |  206 ++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h |   44 +
 drivers/gpu/drm/msm/dp/dp_aux.c             |  570 ++++++++++
 drivers/gpu/drm/msm/dp/dp_aux.h             |   44 +
 drivers/gpu/drm/msm/dp/dp_catalog.c         | 1188 
++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_catalog.h         |  144 +++
 drivers/gpu/drm/msm/dp/dp_ctrl.c            | 1475 
+++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_ctrl.h            |   50 +
 drivers/gpu/drm/msm/dp/dp_debug.c           |  507 +++++++++
 drivers/gpu/drm/msm/dp/dp_debug.h           |   81 ++
 drivers/gpu/drm/msm/dp/dp_display.c         |  977 +++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_display.h         |   55 +
 drivers/gpu/drm/msm/dp/dp_drm.c             |  542 ++++++++++
 drivers/gpu/drm/msm/dp/dp_drm.h             |   52 +
 drivers/gpu/drm/msm/dp/dp_extcon.c          |  400 +++++++
 drivers/gpu/drm/msm/dp/dp_extcon.h          |  111 ++
 drivers/gpu/drm/msm/dp/dp_link.c            | 1549 
+++++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_link.h            |  184 ++++
 drivers/gpu/drm/msm/dp/dp_panel.c           |  624 +++++++++++
 drivers/gpu/drm/msm/dp/dp_panel.h           |  121 +++
 drivers/gpu/drm/msm/dp/dp_parser.c          |  679 ++++++++++++
 drivers/gpu/drm/msm/dp/dp_parser.h          |  205 ++++
 drivers/gpu/drm/msm/dp/dp_power.c           |  599 +++++++++++
 drivers/gpu/drm/msm/dp/dp_power.h           |   57 +
 drivers/gpu/drm/msm/dp/dp_reg.h             |  357 ++++++
 drivers/gpu/drm/msm/msm_drv.c               |    2 +
 drivers/gpu/drm/msm/msm_drv.h               |   22 +
 include/drm/drm_dp_helper.h                 |   19 +
 30 files changed, 10887 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_display.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_display.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_drm.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_drm.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_extcon.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_extcon.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_link.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_link.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_panel.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_panel.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_parser.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_parser.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_power.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_power.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_reg.h
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
new file mode 100644
index 0000000..5818612
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_catalog.c new file +5 -0
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <drm/drm_dp_helper.h>
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 24

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +6 -0
+
+#include "dp_catalog.h"
+#include "dp_reg.h"
+
+#define DP_GET_MSB(x)	(x >> 8)
+#define DP_GET_LSB(x)	(x & 0xff)

These aren't used anywhere

Fixed in V2.

Quoted 7 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 27

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +3 -0
+
+#define dp_read(offset) readl_relaxed((offset))
+#define dp_write(offset, data) writel_relaxed((data), (offset))

These macros aren't useful. I think you'd be much better having a read_/write_ for the different io types, ie:

Quoted 6 lines

static inline u32 dp_read_audio(struct dp_catalog *catalog, u32 offset)

{
        return readl_relaxed(catalog->io->dp_link.base + offset);
}

Then you can remove a ton of boilerplate code below getting base;

Fixed in V2.

Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.c line 29

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.c new file +2 -0
+
+#define dp_catalog_get_priv(x) { \

static inline struct dp_catalog_private *dp_catalog_get_priv(...)

{
        ...
}
Quoted 6 lines

For inline, we have to use 3 different functions (one each for aux, ctrl and panel).
Looking at "type-checking" w.r.t macro, container_of will through an error if its not valid pointer.
Please let me know if you still want to change this macro to inline func.

/snip

Quoted 146 lines
Quoted 116 lines
Quoted 116 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
new file mode 100644
index 0000000..58951df
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights 

reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */

drivers/gpu/drm/msm/dp/dp_catalog.h new file +94 -0
+
+#ifndef _DP_CATALOG_H_
+#define _DP_CATALOG_H_
+
+#include "dp_parser.h"
+
+/* interrupts */
+#define DP_INTR_HPD		BIT(0)
+#define DP_INTR_AUX_I2C_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)
+
+struct dp_catalog_aux {
+	u32 data;
+	u32 isr;
+
+	u32 (*read_data)(struct dp_catalog_aux *aux);
+	int (*write_data)(struct dp_catalog_aux *aux);
+	int (*write_trans)(struct dp_catalog_aux *aux);
+	int (*clear_trans)(struct dp_catalog_aux *aux, bool read);
+	void (*reset)(struct dp_catalog_aux *aux);
+	void (*enable)(struct dp_catalog_aux *aux, bool enable);
+	void (*update_aux_cfg)(struct dp_catalog_aux *aux,
+		struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type);
+	void (*setup)(struct dp_catalog_aux *aux,
+			struct dp_aux_cfg *aux_cfg);
+	void (*get_irq)(struct dp_catalog_aux *aux, bool cmd_busy);
+};
+
+struct dp_catalog_ctrl {
+	u32 dp_tu;
+	u32 valid_boundary;
+	u32 valid_boundary2;
+	u32 isr;
+
+	void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state);
+	void (*config_ctrl)(struct dp_catalog_ctrl *ctrl, u32 config);
+	void (*lane_mapping)(struct dp_catalog_ctrl *ctrl);
+	void (*mainlink_ctrl)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*config_misc)(struct dp_catalog_ctrl *ctrl, u32 cc, u32 tb);
+	void (*config_msa)(struct dp_catalog_ctrl *ctrl, u32 rate,
+				u32 stream_rate_khz, bool fixed_nvid);
+	void (*set_pattern)(struct dp_catalog_ctrl *ctrl, u32 pattern);
+	void (*reset)(struct dp_catalog_ctrl *ctrl);
+	void (*usb_reset)(struct dp_catalog_ctrl *ctrl, bool flip);
+	bool (*mainlink_ready)(struct dp_catalog_ctrl *ctrl);
+	void (*enable_irq)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*hpd_config)(struct dp_catalog_ctrl *ctrl, bool enable);
+	void (*phy_reset)(struct dp_catalog_ctrl *ctrl);
+	void (*phy_lane_cfg)(struct dp_catalog_ctrl *ctrl, bool flipped,
+				u8 lane_cnt);
+	void (*update_vx_px)(struct dp_catalog_ctrl *ctrl, u8 v_level,
+				u8 p_level);
+	void (*get_interrupt)(struct dp_catalog_ctrl *ctrl);
+	void (*update_transfer_unit)(struct dp_catalog_ctrl *ctrl);
+	void (*send_phy_pattern)(struct dp_catalog_ctrl *ctrl,
+			u32 pattern);
+	u32 (*read_phy_pattern)(struct dp_catalog_ctrl *ctrl);
+};
+
+enum 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 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 dp_catalog_audio {
+	enum dp_catalog_audio_sdp_type sdp_type;
+	enum dp_catalog_audio_header_type sdp_header;
+	u32 data;
+
+	void (*init)(struct dp_catalog_audio *audio);
+	void (*enable)(struct dp_catalog_audio *audio);
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h line 112

Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +5 -0
+	void (*config_acr)(struct dp_catalog_audio *audio);
+	void (*config_sdp)(struct dp_catalog_audio *audio);
+	void (*set_header)(struct dp_catalog_audio *audio);
+	void (*get_header)(struct dp_catalog_audio *audio);
+	void (*safe_to_exit_level)(struct dp_catalog_audio *audio);

None of these are called? So get rid of this entire structure, the functions that aren't called, and the audio enums above.

Removed all the Audio related APIs in V2.

Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+};
+
+struct dp_catalog_panel {
+	u32 total;
+	u32 sync_start;
+	u32 width_blanking;
+	u32 dp_active;
+
+	/* TPG */
+	u32 hsync_period;
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.h line 128

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	u32 vsync_period;
+	u32 display_v_start;
+	u32 display_v_end;
+	u32 v_sync_width;
+	u32 hsync_ctl;
+	u32 display_hctl;

All of this information is already available from drm core, so it can go.

Quoted 2 lines

Will address this in V3.

/snip

Quoted 35 lines
Quoted 26 lines
Quoted 26 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +26 -0
+
+static void dp_ctrl_setup_tr_unit(struct dp_ctrl_private *ctrl)
+{
+	u32 dp_tu = 0x0;
+	u32 valid_boundary = 0x0;
+	u32 valid_boundary2 = 0x0;
+	struct dp_vc_tu_mapping_table tu_calc_table;
+
+	dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
+
+	dp_tu |= tu_calc_table.tu_size_minus1;
+	valid_boundary |= tu_calc_table.valid_boundary_link;
+	valid_boundary |= (tu_calc_table.delay_start_link << 16);
+
+	valid_boundary2 |= (tu_calc_table.valid_lower_boundary_link << 1);
+	valid_boundary2 |= (tu_calc_table.upper_boundary_count << 16);
+	valid_boundary2 |= (tu_calc_table.lower_boundary_count << 20);
+
+	if (tu_calc_table.boundary_moderation_en)
+		valid_boundary2 |= BIT(0);
+
+	pr_debug("dp_tu=0x%x, valid_boundary=0x%x, valid_boundary2=0x%x\n",
+			dp_tu, valid_boundary, valid_boundary2);
+
+	ctrl->catalog->dp_tu = dp_tu;
+	ctrl->catalog->valid_boundary = valid_boundary;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 3 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +3 -0
+	ctrl->catalog->valid_boundary2 = valid_boundary2;
+
+	ctrl->catalog->update_transfer_unit(ctrl->catalog);

Again here, if you just call the function directly, you can avoid the callback. If you add function arguments, you can avoid having to store dp_tu/valid_boundary/
valid_boundary2 entirely.

Quoted 2 lines

Will remove the dp_tu/valid_boundary/valid_boundary2 in V3.

Quoted 1 line
Quoted 1 line

+}

After removing all the function ptrs in each structure and removing dp_tu/valid_boundary/valid_boundary2 for dp_catalog_ctrl structure, we can get rid of dp_catalog_ctrl structure. Similarly, even the other aux and panel structures have minimal data that can be removed. If we remove these structures and get read of dp_catalog structure, we have to find a different way to access dp_catalog_private structure present in dp_catalog.c file. Having "static dp_catalog_private *dp_catalog_private_ptr" is acceptable in upstream? Please share if you have any better suggestion?

Quoted 21 lines
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+
+static int dp_ctrl_wait4video_ready(struct dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+
+	ret = wait_for_completion_timeout(&ctrl->video_comp, HZ / 2);

Break out the timeout into a #define

Fixed in V2.

Quoted 10 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	if (ret <= 0) {
+		pr_err("Link Train timedout\n");
+		ret = -EINVAL;
+	}
+
+	return ret;

You're not checking the return value at the callsite.

Quoted 3 lines

Fixed in V2.

Quoted 1 line
Quoted 1 line

+}

/snip

Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +11 -0
+
+static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
+		u32 mode_edid_bpp, u32 mode_pclk_khz)
+{
+	struct drm_dp_link *link_info;
+	const u32 max_supported_bpp = 30, min_supported_bpp = 18;
+	u32 bpp = 0, data_rate_khz = 0;
+
+	bpp = min_t(u32, mode_edid_bpp, max_supported_bpp);
+
+	link_info = &dp_panel->link_info;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	data_rate_khz = link_info->num_lanes * link_info->rate * 8;
+
+	while (bpp > min_supported_bpp) {
+		if (mode_pclk_khz * bpp <= data_rate_khz)
+			break;
+		bpp -= 6;

Watch out for underflow here.

Quoted 2 lines

Will add check in V3 patch series.

Since min_supported_bpp is 18, bpp can never go below 12. I don't think we need to check underflow here.

Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +25 -0
+	}
+
+	return bpp;
+}
+
+static u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel,
+		u32 mode_edid_bpp, u32 mode_pclk_khz)
+{
+	struct dp_panel_private *panel;
+	u32 bpp = mode_edid_bpp;
+
+	if (!dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
+		pr_err("invalid input\n");
+		return 0;
+	}
+
+	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+
+	if (dp_panel->video_test)
+		bpp = dp_link_bit_depth_to_bpp(
+				panel->link->test_video.test_bit_depth);
+	else
+		bpp = dp_panel_get_supported_bpp(dp_panel, mode_edid_bpp,
+				mode_pclk_khz);
+
Quoted 8 lines
Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 7 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +7 -0
+	return bpp;
+}
+
+static void dp_panel_set_test_mode(struct dp_panel_private *panel,
+		struct dp_display_mode *mode)
+{
+	struct dp_panel_info *pinfo = NULL;

/snip

Quoted 19 lines
Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -0
+
+struct dp_display_mode {
+	struct dp_panel_info timing;
+	u32 capabilities;
+};
+
+struct dp_panel_in {
+	struct device *dev;
+	struct dp_aux *aux;
+	struct dp_link *link;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	struct dp_catalog_panel *catalog;
+};
+
+struct dp_panel {
+	/* dpcd raw data */
+	u8 dpcd[DP_RECEIVER_CAP_SIZE + 1];

Why + 1?

Quoted 1 line

Will follow up on this in V3.

DP_RECIEVER_CAP_SIZE is 0xf. We need 16 bytes for dpcd read.

Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +12 -0
+	u8 ds_ports[DP_MAX_DOWNSTREAM_PORTS];
+
+	struct drm_dp_link link_info;
+	struct edid *edid;
+	struct drm_connector *connector;
+	struct dp_panel_info pinfo;
+	bool video_test;
+
+	u32 vic;
+	u32 max_pclk_khz;
+
+	u32 max_bw_code;
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	int (*init_info)(struct dp_panel *dp_panel);
+	int (*deinit)(struct dp_panel *dp_panel);
+	int (*timing_cfg)(struct dp_panel *dp_panel);
+	int (*read_sink_caps)(struct dp_panel *dp_panel,
+		struct drm_connector *connector);
+	u32 (*get_min_req_link_rate)(struct dp_panel *dp_panel);

This function isn't called anywhere

Quoted 2 lines

Removed in V2.

/Snip

Quoted 21 lines
Quoted 12 lines
Quoted 12 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
+
+static int dp_power_pinctrl_set(struct dp_power_private *power, bool 

active)

drivers/gpu/drm/msm/dp/dp_catalog.h new file +7 -0
+{
+	int rc = -EFAULT;
+	struct pinctrl_state *pin_state;
+	struct dp_parser *parser;
+
+	parser = power->parser;
+
Quoted 9 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +6 -0
+	if (IS_ERR_OR_NULL(parser->pinctrl.pin))
+		return PTR_ERR(parser->pinctrl.pin);
+
+	pin_state = active ? parser->pinctrl.state_active
+				: parser->pinctrl.state_suspend;
+	if (!IS_ERR_OR_NULL(pin_state)) {

How is this not possible? You check these on initialization.

Quoted 1 line

Will remove this in V3.

GPIO/pin_ctrl entries are optional entries in dtsi for DP since we don't need them for specific target. During init, we allow the probe to go through even though we initialize pin_state or not. So, we have to check this again here.

Quoted 31 lines
Quoted 5 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 2 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +2 -0
+		rc = pinctrl_select_state(parser->pinctrl.pin,
+				pin_state);

Combine on 1 line

Fixed in V2.

Quoted 8 lines

drivers/gpu/drm/msm/dp/dp_catalog.h

Quoted 4 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +4 -0
+		if (rc)
+			pr_err("can not set %s pins\n",
+			       active ? "dp_active"
+			       : "dp_sleep");

Combine on one line. Also return immediately if this is the case.

Fixed in V2.

Quoted 5 lines
Quoted 5 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +5 -0
+	} else {
+		pr_err("invalid '%s' pinstate\n",
+		       active ? "dp_active"
+		       : "dp_sleep");
+	}
Quoted 9 lines
Quoted 6 lines
drivers/gpu/drm/msm/dp/dp_catalog.h new file +5 -0
+
+	return rc;
+}
+
+static int dp_power_clk_init(struct dp_power_private *power, bool 

enable)

Split this into init/deinit, the paths don't share code.

Quoted 2 lines

Fixed in V2.

/snip

Quoted 19 lines
Quoted 19 lines
Quoted 19 lines

#define DP_TEST_SINK 0x270

 # define DP_TEST_SINK_START		    (1 << 0)
drivers/gpu/drm/msm/dp/dp_catalog.h new file +10 -1
+#define DP_TEST_AUDIO_MODE		    0x271
+#define DP_TEST_AUDIO_PATTERN_TYPE	    0x272
+#define DP_TEST_AUDIO_PERIOD_CH1	    0x273
+#define DP_TEST_AUDIO_PERIOD_CH2	    0x274
+#define DP_TEST_AUDIO_PERIOD_CH3	    0x275
+#define DP_TEST_AUDIO_PERIOD_CH4	    0x276
+#define DP_TEST_AUDIO_PERIOD_CH5	    0x277
+#define DP_TEST_AUDIO_PERIOD_CH6	    0x278
+#define DP_TEST_AUDIO_PERIOD_CH7	    0x279
+#define DP_TEST_AUDIO_PERIOD_CH8	    0x27A
 
 #define DP_FEC_STATUS			    0x280    /* 1.4 */
 # define DP_FEC_DECODE_EN_DETECTED	    (1 << 0)
--

The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

#19 lore raw

PATCH 3/3 drm/msm/dp: add support for DP PLL driver

In reply to a message not in the archive

Add the needed DP PLL specific files to support
display port interface on msm targets.

The DP driver calls the DP PLL driver registration. The DP driver sets the link and pixel clock sources.

---
 drivers/gpu/drm/msm/Kconfig                   |  16 +
 drivers/gpu/drm/msm/Makefile                  |   6 +
 drivers/gpu/drm/msm/dp/dp_ctrl.c              |   1 +
 drivers/gpu/drm/msm/dp/dp_display.c           |  50 +++
 drivers/gpu/drm/msm/dp/dp_display.h           |   3 +
 drivers/gpu/drm/msm/dp/dp_parser.h            |   3 +
 drivers/gpu/drm/msm/dp/dp_power.c             |  77 +++-
 drivers/gpu/drm/msm/dp/dp_power.h             |   2 +
 drivers/gpu/drm/msm/dp/pll/dp_pll.c           | 153 ++++++++
 drivers/gpu/drm/msm/dp/pll/dp_pll.h           |  64 ++++
 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.c      | 401 +++++++++++++++++++
 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.h      |  94 +++++
 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm_util.c | 531 ++++++++++++++++++++++++++
 13 files changed, 1389 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/pll/dp_pll.c
 create mode 100644 drivers/gpu/drm/msm/dp/pll/dp_pll.h
 create mode 100644 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.c
 create mode 100644 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.h
 create mode 100644 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm_util.c
drivers/gpu/drm/msm/Kconfig +16 -0
index c363f24..1e0b9158 100644
@@ -58,6 +58,22 @@ config DRM_MSM_DP
 	  driver. DP external display support is enabled
 	  through this config option. It can be primary or
 	  secondary display on device.
+
+config DRM_MSM_DP_PLL
+	bool "Enable DP PLL driver in MSM DRM"
+	depends on DRM_MSM_DP && COMMON_CLK
+	default y
+	help
+	  Choose this option to enable DP PLL driver which provides DP
+	  source clocks under common clock framework.
+
+config DRM_MSM_DP_10NM_PLL
+	bool "Enable DP 10nm PLL driver in MSM DRM (used by SDM845)"
+	depends on DRM_MSM_DP
+	default y
+	help
+	  Choose this option if DP PLL on SDM845 is used on the platform.
+
 config DRM_MSM_DSI
 	bool "Enable DSI support in MSM DRM driver"
 	depends on DRM_MSM
drivers/gpu/drm/msm/Makefile +6 -0
index 765a8d8..8d18353 100644
@@ -137,4 +137,10 @@ msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o
 msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/pll/dsi_pll_10nm.o
 endif
 
+ifeq ($(CONFIG_DRM_MSM_DP_PLL),y)
+msm-y += dp/pll/dp_pll.o
+msm-y += dp/pll/dp_pll_10nm.o
+msm-y += dp/pll/dp_pll_10nm_util.o
+endif
+
 obj-$(CONFIG_DRM_MSM)	+= msm.o
drivers/gpu/drm/msm/dp/dp_ctrl.c +1 -0
index 08a52f5..e23beee 100644
@@ -1051,6 +1051,7 @@ static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl)
 {
 	int ret = 0;
 
+	ctrl->power->set_link_clk_parent(ctrl->power);
 	ctrl->power->set_pixel_clk_parent(ctrl->power);
 
 	dp_ctrl_set_clock_rate(ctrl, "ctrl_link_clk",
drivers/gpu/drm/msm/dp/dp_display.c +50 -0

74 lines not on this page · raw message

drivers/gpu/drm/msm/dp/dp_display.h +3 -0
index ca5eae5..9cd6a6b 100644
@@ -52,4 +52,7 @@ struct msm_dp {
 
 int dp_display_get_num_of_displays(void);
 int dp_display_get_displays(void **displays, int count);
+void __init msm_dp_pll_driver_register(void);
+void __exit msm_dp_pll_driver_unregister(void);
+
 #endif /* _DP_DISPLAY_H_ */
drivers/gpu/drm/msm/dp/dp_parser.h +3 -0
index b39ea02..372997e 100644
@@ -16,6 +16,7 @@
 #define _DP_PARSER_H_
 
 #include "dpu_io_util.h"
+#include "pll/dp_pll.h"
 
 #define DP_LABEL "MDSS DP DISPLAY"
 #define AUX_CFG_LEN	10
@@ -175,6 +176,8 @@ struct dp_parser {
 	struct dp_pinctrl pinctrl;
 	struct dp_io io;
 	struct dp_display_data disp_data;
+	struct msm_dp_pll *pll;
+	struct device *pll_dev;
 
 	u8 l_map[4];
 	struct dp_aux_cfg aux_cfg[AUX_CFG_LEN];
drivers/gpu/drm/msm/dp/dp_power.c +65 -12

115 lines not on this page · raw message

drivers/gpu/drm/msm/dp/dp_power.h +2 -0
index d1adaaf..5effd32 100644
@@ -24,6 +24,7 @@
  * @init: initializes the regulators/core clocks/GPIOs/pinctrl
  * @deinit: turns off the regulators/core clocks/GPIOs/pinctrl
  * @clk_enable: enable/disable the DP clocks
+ * @set_link_clk_parent: set the parent of DP link clock
  * @set_pixel_clk_parent: set the parent of DP pixel clock
  */
 struct dp_power {
@@ -31,6 +32,7 @@ struct dp_power {
 	int (*deinit)(struct dp_power *power);
 	int (*clk_enable)(struct dp_power *power, enum dp_pm_type pm_type,
 				bool enable);
+	int (*set_link_clk_parent)(struct dp_power *power);
 	int (*set_pixel_clk_parent)(struct dp_power *power);
 	int (*power_client_init)(struct dp_power *power);
 	void (*power_client_deinit)(struct dp_power *power);
drivers/gpu/drm/msm/dp/pll/dp_pll.c new file +153 -0

153 lines not on this page · raw message

drivers/gpu/drm/msm/dp/pll/dp_pll.h new file +64 -0

64 lines not on this page · raw message

drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.c new file +401 -0

401 lines not on this page · raw message

drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.h new file +94 -0

94 lines not on this page · raw message

drivers/gpu/drm/msm/dp/pll/dp_pll_10nm_util.c new file +531 -0

531 lines not on this page · raw message

Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno