diff mbox series

[02/14] drm/bridge: dw-hdmi: Add dw-hdmi-common.h header

Message ID 20240601-b4-rk3588-bridge-upstream-v1-2-f6203753232b@collabora.com (mailing list archive)
State New
Headers show
Series Add initial support for the Rockchip RK3588 HDMI TX Controller | expand

Commit Message

Cristian Ciocaltea June 1, 2024, 1:12 p.m. UTC
In preparation to add support for the HDMI 2.1 Quad-Pixel TX Controller
and minimize code duplication as much as possible, export all reusable
functions and provide the related declarations and structs within a new
header file.

For consistency, ensure the newly exported symbols share the 'dw_'
prefix.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-common.h | 167 ++++++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c        | 170 ++++-------------------
 2 files changed, 194 insertions(+), 143 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-common.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-common.h
new file mode 100644
index 000000000000..28e26ac142e6
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-common.h
@@ -0,0 +1,167 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __DW_HDMI_COMMON_H__
+#define __DW_HDMI_COMMON_H__
+
+#include <linux/i2c.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
+
+#include <drm/bridge/dw_hdmi.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_modes.h>
+
+#include <sound/hdmi-codec.h>
+
+struct cec_notifier;
+struct device;
+struct drm_bridge_state;
+struct drm_crtc_state;
+struct drm_edid;
+struct pinctrl;
+struct pinctrl_state;
+struct platform_device;
+struct regmap;
+
+#define DDC_CI_ADDR		0x37
+#define DDC_SEGMENT_ADDR	0x30
+
+#define HDMI_EDID_LEN		512
+
+/* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */
+#define SCDC_MIN_SOURCE_VERSION	0x1
+
+#define HDMI14_MAX_TMDSCLK	340000000
+
+struct hdmi_vmode {
+	bool mdataenablepolarity;
+
+	unsigned int mpixelclock;
+	unsigned int mpixelrepetitioninput;
+	unsigned int mpixelrepetitionoutput;
+	unsigned int mtmdsclock;
+};
+
+struct hdmi_data_info {
+	unsigned int enc_in_bus_format;
+	unsigned int enc_out_bus_format;
+	unsigned int enc_in_encoding;
+	unsigned int enc_out_encoding;
+	unsigned int pix_repet_factor;
+	unsigned int hdcp_enable;
+	struct hdmi_vmode video_mode;
+	bool rgb_limited_range;
+};
+
+struct dw_hdmi_i2c {
+	struct i2c_adapter	adap;
+
+	struct mutex		lock;	/* used to serialize data transfers */
+	struct completion	cmp;
+	u8			stat;
+
+	u8			slave_reg;
+	bool			is_regaddr;
+	bool			is_segment;
+};
+
+struct dw_hdmi_phy_data {
+	enum dw_hdmi_phy_type type;
+	const char *name;
+	unsigned int gen;
+	bool has_svsret;
+	int (*configure)(struct dw_hdmi *hdmi,
+			 const struct dw_hdmi_plat_data *pdata,
+			 unsigned long mpixelclock);
+};
+
+struct dw_hdmi {
+	struct drm_connector connector;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+
+	unsigned int version;
+
+	struct platform_device *audio;
+	struct platform_device *cec;
+	struct device *dev;
+	struct dw_hdmi_i2c *i2c;
+
+	struct hdmi_data_info hdmi_data;
+	const struct dw_hdmi_plat_data *plat_data;
+
+	int vic;
+
+	u8 edid[HDMI_EDID_LEN];
+
+	struct {
+		const struct dw_hdmi_phy_ops *ops;
+		const char *name;
+		void *data;
+		bool enabled;
+	} phy;
+
+	struct drm_display_mode previous_mode;
+
+	struct i2c_adapter *ddc;
+	void __iomem *regs;
+	bool sink_is_hdmi;
+	bool sink_has_audio;
+
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *default_state;
+	struct pinctrl_state *unwedge_state;
+
+	struct mutex mutex;		/* for state below and previous_mode */
+	enum drm_connector_force force;	/* mutex-protected force state */
+	struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
+	bool disabled;			/* DRM has disabled our bridge */
+	bool bridge_is_on;		/* indicates the bridge is on */
+	bool rxsense;			/* rxsense state */
+	u8 phy_mask;			/* desired phy int mask settings */
+	u8 mc_clkdis;			/* clock disable register */
+
+	spinlock_t audio_lock;
+	struct mutex audio_mutex;
+	unsigned int sample_non_pcm;
+	unsigned int sample_width;
+	unsigned int sample_rate;
+	unsigned int channels;
+	unsigned int audio_cts;
+	unsigned int audio_n;
+	bool audio_enable;
+
+	unsigned int reg_shift;
+	struct regmap *regm;
+	void (*enable_audio)(struct dw_hdmi *hdmi);
+	void (*disable_audio)(struct dw_hdmi *hdmi);
+
+	struct mutex cec_notifier_mutex;
+	struct cec_notifier *cec_notifier;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	enum drm_connector_status last_connector_result;
+};
+
+void dw_handle_plugged_change(struct dw_hdmi *hdmi, bool plugged);
+bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
+			  const struct drm_display_info *display);
+
+enum drm_connector_status
+dw_hdmi_connector_detect(struct drm_connector *connector, bool force);
+
+int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
+				struct drm_bridge_state *bridge_state,
+				struct drm_crtc_state *crtc_state,
+				struct drm_connector_state *conn_state);
+void dw_hdmi_bridge_detach(struct drm_bridge *bridge);
+void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+			     const struct drm_display_mode *orig_mode,
+			     const struct drm_display_mode *mode);
+enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge);
+const struct drm_edid *
+dw_hdmi_bridge_edid_read(struct drm_bridge *bridge,
+			 struct drm_connector *connector);
+#endif /* __DW_HDMI_COMMON_H__ */
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 0031f3c54882..b66877771f56 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -10,10 +10,8 @@ 
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/hdmi.h>
-#include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/module.h>
-#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
@@ -25,12 +23,10 @@ 
 #include <uapi/linux/media-bus-format.h>
 #include <uapi/linux/videodev2.h>
 
-#include <drm/bridge/dw_hdmi.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_scdc_helper.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
-#include <drm/drm_bridge.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_print.h>
@@ -38,18 +34,9 @@ 
 
 #include "dw-hdmi-audio.h"
 #include "dw-hdmi-cec.h"
+#include "dw-hdmi-common.h"
 #include "dw-hdmi.h"
 
-#define DDC_CI_ADDR		0x37
-#define DDC_SEGMENT_ADDR	0x30
-
-#define HDMI_EDID_LEN		512
-
-/* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */
-#define SCDC_MIN_SOURCE_VERSION	0x1
-
-#define HDMI14_MAX_TMDSCLK	340000000
-
 static const u16 csc_coeff_default[3][4] = {
 	{ 0x2000, 0x0000, 0x0000, 0x0000 },
 	{ 0x0000, 0x2000, 0x0000, 0x0000 },
@@ -86,117 +73,6 @@  static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
 	{ 0x0000, 0x0000, 0x1b7c, 0x0020 }
 };
 
-struct hdmi_vmode {
-	bool mdataenablepolarity;
-
-	unsigned int mpixelclock;
-	unsigned int mpixelrepetitioninput;
-	unsigned int mpixelrepetitionoutput;
-	unsigned int mtmdsclock;
-};
-
-struct hdmi_data_info {
-	unsigned int enc_in_bus_format;
-	unsigned int enc_out_bus_format;
-	unsigned int enc_in_encoding;
-	unsigned int enc_out_encoding;
-	unsigned int pix_repet_factor;
-	unsigned int hdcp_enable;
-	struct hdmi_vmode video_mode;
-	bool rgb_limited_range;
-};
-
-struct dw_hdmi_i2c {
-	struct i2c_adapter	adap;
-
-	struct mutex		lock;	/* used to serialize data transfers */
-	struct completion	cmp;
-	u8			stat;
-
-	u8			slave_reg;
-	bool			is_regaddr;
-	bool			is_segment;
-};
-
-struct dw_hdmi_phy_data {
-	enum dw_hdmi_phy_type type;
-	const char *name;
-	unsigned int gen;
-	bool has_svsret;
-	int (*configure)(struct dw_hdmi *hdmi,
-			 const struct dw_hdmi_plat_data *pdata,
-			 unsigned long mpixelclock);
-};
-
-struct dw_hdmi {
-	struct drm_connector connector;
-	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
-
-	unsigned int version;
-
-	struct platform_device *audio;
-	struct platform_device *cec;
-	struct device *dev;
-	struct dw_hdmi_i2c *i2c;
-
-	struct hdmi_data_info hdmi_data;
-	const struct dw_hdmi_plat_data *plat_data;
-
-	int vic;
-
-	u8 edid[HDMI_EDID_LEN];
-
-	struct {
-		const struct dw_hdmi_phy_ops *ops;
-		const char *name;
-		void *data;
-		bool enabled;
-	} phy;
-
-	struct drm_display_mode previous_mode;
-
-	struct i2c_adapter *ddc;
-	void __iomem *regs;
-	bool sink_is_hdmi;
-	bool sink_has_audio;
-
-	struct pinctrl *pinctrl;
-	struct pinctrl_state *default_state;
-	struct pinctrl_state *unwedge_state;
-
-	struct mutex mutex;		/* for state below and previous_mode */
-	enum drm_connector_force force;	/* mutex-protected force state */
-	struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
-	bool disabled;			/* DRM has disabled our bridge */
-	bool bridge_is_on;		/* indicates the bridge is on */
-	bool rxsense;			/* rxsense state */
-	u8 phy_mask;			/* desired phy int mask settings */
-	u8 mc_clkdis;			/* clock disable register */
-
-	spinlock_t audio_lock;
-	struct mutex audio_mutex;
-	unsigned int sample_non_pcm;
-	unsigned int sample_width;
-	unsigned int sample_rate;
-	unsigned int channels;
-	unsigned int audio_cts;
-	unsigned int audio_n;
-	bool audio_enable;
-
-	unsigned int reg_shift;
-	struct regmap *regm;
-	void (*enable_audio)(struct dw_hdmi *hdmi);
-	void (*disable_audio)(struct dw_hdmi *hdmi);
-
-	struct mutex cec_notifier_mutex;
-	struct cec_notifier *cec_notifier;
-
-	hdmi_codec_plugged_cb plugged_cb;
-	struct device *codec_dev;
-	enum drm_connector_status last_connector_result;
-};
-
 #define HDMI_IH_PHY_STAT0_RX_SENSE \
 	(HDMI_IH_PHY_STAT0_RX_SENSE0 | HDMI_IH_PHY_STAT0_RX_SENSE1 | \
 	 HDMI_IH_PHY_STAT0_RX_SENSE2 | HDMI_IH_PHY_STAT0_RX_SENSE3)
@@ -219,11 +95,12 @@  static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
 	return val;
 }
 
-static void handle_plugged_change(struct dw_hdmi *hdmi, bool plugged)
+void dw_handle_plugged_change(struct dw_hdmi *hdmi, bool plugged)
 {
 	if (hdmi->plugged_cb && hdmi->codec_dev)
 		hdmi->plugged_cb(hdmi->codec_dev, plugged);
 }
+EXPORT_SYMBOL_GPL(dw_handle_plugged_change);
 
 int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn,
 			   struct device *codec_dev)
@@ -234,7 +111,7 @@  int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn,
 	hdmi->plugged_cb = fn;
 	hdmi->codec_dev = codec_dev;
 	plugged = hdmi->last_connector_result == connector_status_connected;
-	handle_plugged_change(hdmi, plugged);
+	dw_handle_plugged_change(hdmi, plugged);
 	mutex_unlock(&hdmi->mutex);
 
 	return 0;
@@ -1361,8 +1238,8 @@  void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
 
 /* Filter out invalid setups to avoid configuring SCDC and scrambling */
-static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
-				 const struct drm_display_info *display)
+bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
+			  const struct drm_display_info *display)
 {
 	/* Completely disable SCDC support for older controllers */
 	if (hdmi->version < 0x200a)
@@ -1387,6 +1264,7 @@  static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
 
 	return true;
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_support_scdc);
 
 /*
  * HDMI2.0 Specifies the following procedure for High TMDS Bit Rates:
@@ -2486,13 +2364,14 @@  static const struct drm_edid *dw_hdmi_edid_read(struct dw_hdmi *hdmi,
  * DRM Connector Operations
  */
 
-static enum drm_connector_status
+enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 	return dw_hdmi_detect(hdmi);
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_connector_detect);
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 {
@@ -2868,10 +2747,10 @@  static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
 	return input_fmts;
 }
 
-static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
-				       struct drm_bridge_state *bridge_state,
-				       struct drm_crtc_state *crtc_state,
-				       struct drm_connector_state *conn_state)
+int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
+				struct drm_bridge_state *bridge_state,
+				struct drm_crtc_state *crtc_state,
+				struct drm_connector_state *conn_state)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
@@ -2887,6 +2766,7 @@  static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_bridge_atomic_check);
 
 static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
 				 enum drm_bridge_attach_flags flags)
@@ -2900,7 +2780,7 @@  static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
 	return dw_hdmi_connector_create(hdmi);
 }
 
-static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
+void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
@@ -2909,6 +2789,7 @@  static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
 	hdmi->cec_notifier = NULL;
 	mutex_unlock(&hdmi->cec_notifier_mutex);
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_bridge_detach);
 
 static enum drm_mode_status
 dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
@@ -2930,9 +2811,9 @@  dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
 	return mode_status;
 }
 
-static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				    const struct drm_display_mode *orig_mode,
-				    const struct drm_display_mode *mode)
+void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+			     const struct drm_display_mode *orig_mode,
+			     const struct drm_display_mode *mode)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
@@ -2943,6 +2824,7 @@  static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 
 	mutex_unlock(&hdmi->mutex);
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_bridge_mode_set);
 
 static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
 					  struct drm_bridge_state *old_state)
@@ -2954,7 +2836,7 @@  static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
 	hdmi->curr_conn = NULL;
 	dw_hdmi_update_power(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
-	handle_plugged_change(hdmi, false);
+	dw_handle_plugged_change(hdmi, false);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -2973,24 +2855,26 @@  static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
 	hdmi->curr_conn = connector;
 	dw_hdmi_update_power(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
-	handle_plugged_change(hdmi, true);
+	dw_handle_plugged_change(hdmi, true);
 	mutex_unlock(&hdmi->mutex);
 }
 
-static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge)
+enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
 	return dw_hdmi_detect(hdmi);
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_bridge_detect);
 
-static const struct drm_edid *dw_hdmi_bridge_edid_read(struct drm_bridge *bridge,
-						       struct drm_connector *connector)
+const struct drm_edid *dw_hdmi_bridge_edid_read(struct drm_bridge *bridge,
+						struct drm_connector *connector)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
 	return dw_hdmi_edid_read(hdmi, connector);
 }
+EXPORT_SYMBOL_GPL(dw_hdmi_bridge_edid_read);
 
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,