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@xxxxxxxxxxxxx> --- 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 --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, -- 2.45.0