Commit 12c683e1 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Sam Ravnborg

drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()

When validating a mode, bridges may need to do so in the context of a
display, as specified by drm_display_info. An example is the meson
dw-hdmi bridge that needs to consider the YUV 4:2:0 output format to
perform clock calculations.

Bridges that need the display info currently retrieve it from the
drm_connector created by the bridge. This gets in the way of moving
connector creation out of bridge drivers. To make this possible, pass
the drm_display_info to drm_bridge_funcs .mode_valid().

Changes to the bridge drivers have been performed with the following
coccinelle semantic patch and have been compile-tested.

@ rule1 @
identifier funcs;
identifier fn;
@@
 struct drm_bridge_funcs funcs = {
 	...,
 	.mode_valid = fn
 };

@ depends on rule1 @
identifier rule1.fn;
identifier bridge;
identifier mode;
@@
 enum drm_mode_status fn(
 	struct drm_bridge *bridge,
+	const struct drm_display_info *info,
 	const struct drm_display_mode *mode
 )
 {
 	...
 }
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Guido Günther <agx@sigxcpu.org> # for the nwl-dsi part:
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-11-laurent.pinchart+renesas@ideasonboard.com
parent 192a3aa0
...@@ -585,6 +585,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge, ...@@ -585,6 +585,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
anx6345_bridge_mode_valid(struct drm_bridge *bridge, anx6345_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
if (mode->flags & DRM_MODE_FLAG_INTERLACE) if (mode->flags & DRM_MODE_FLAG_INTERLACE)
......
...@@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, ...@@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
anx78xx_bridge_mode_valid(struct drm_bridge *bridge, anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
if (mode->flags & DRM_MODE_FLAG_INTERLACE) if (mode->flags & DRM_MODE_FLAG_INTERLACE)
......
...@@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge, ...@@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
......
...@@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge) ...@@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge)
} }
static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
if (mode->clock > 165000) if (mode->clock > 165000)
......
...@@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge, ...@@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct nwl_dsi *dsi = bridge_to_dsi(bridge); struct nwl_dsi *dsi = bridge_to_dsi(bridge);
......
...@@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge) ...@@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge)
} }
static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
if (mode->clock > MHL1_MAX_CLK) if (mode->clock > MHL1_MAX_CLK)
......
...@@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx, ...@@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx,
} }
static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct sii8620 *ctx = bridge_to_sii8620(bridge); struct sii8620 *ctx = bridge_to_sii8620(bridge);
......
...@@ -2767,6 +2767,7 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge) ...@@ -2767,6 +2767,7 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
static enum drm_mode_status static enum drm_mode_status
dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct dw_hdmi *hdmi = bridge->driver_private; struct dw_hdmi *hdmi = bridge->driver_private;
......
...@@ -924,6 +924,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge) ...@@ -924,6 +924,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
static enum drm_mode_status static enum drm_mode_status
dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge, dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
......
...@@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge, ...@@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
} }
static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct tc_data *tc = bridge_to_tc(bridge); struct tc_data *tc = bridge_to_tc(bridge);
......
...@@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge, ...@@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
tc358768_bridge_mode_valid(struct drm_bridge *bridge, tc358768_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct tc358768_priv *priv = bridge_to_tc358768(bridge); struct tc358768_priv *priv = bridge_to_tc358768(bridge);
......
...@@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge, ...@@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge,
} }
static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct thc63_dev *thc63 = to_thc63(bridge); struct thc63_dev *thc63 = to_thc63(bridge);
......
...@@ -192,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge) ...@@ -192,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge)
} }
static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
if (mode->clock < 25000) if (mode->clock < 25000)
......
...@@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector, ...@@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
} }
bridge = drm_bridge_chain_get_first_bridge(encoder); bridge = drm_bridge_chain_get_first_bridge(encoder);
ret = drm_bridge_chain_mode_valid(bridge, mode); ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info,
mode);
if (ret != MODE_OK) { if (ret != MODE_OK) {
DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n"); DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
return ret; return ret;
......
...@@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); ...@@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
* drm_bridge_chain_mode_valid - validate the mode against all bridges in the * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
* encoder chain. * encoder chain.
* @bridge: bridge control structure * @bridge: bridge control structure
* @info: display info against which the mode shall be validated
* @mode: desired mode to be validated * @mode: desired mode to be validated
* *
* Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
...@@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); ...@@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
*/ */
enum drm_mode_status enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge, drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge, ...@@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
if (!bridge->funcs->mode_valid) if (!bridge->funcs->mode_valid)
continue; continue;
ret = bridge->funcs->mode_valid(bridge, mode); ret = bridge->funcs->mode_valid(bridge, info, mode);
if (ret != MODE_OK) if (ret != MODE_OK)
return ret; return ret;
} }
......
...@@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode, ...@@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
} }
bridge = drm_bridge_chain_get_first_bridge(encoder); bridge = drm_bridge_chain_get_first_bridge(encoder);
ret = drm_bridge_chain_mode_valid(bridge, mode); ret = drm_bridge_chain_mode_valid(bridge,
&connector->display_info,
mode);
if (ret != MODE_OK) { if (ret != MODE_OK) {
/* There is also no point in continuing for crtc check /* There is also no point in continuing for crtc check
* here. */ * here. */
......
...@@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge) ...@@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
} }
static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge, static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
/* TDA19988 dotclock can go up to 165MHz */ /* TDA19988 dotclock can go up to 165MHz */
......
...@@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge, ...@@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
dpi_bridge_mode_valid(struct drm_bridge *bridge, dpi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct dpi_data *dpi = drm_bridge_to_dpi(bridge); struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
......
...@@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge, ...@@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
sdi_bridge_mode_valid(struct drm_bridge *bridge, sdi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
struct sdi_device *sdi = drm_bridge_to_sdi(bridge); struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
......
...@@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge, ...@@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge,
static enum drm_mode_status static enum drm_mode_status
venc_bridge_mode_valid(struct drm_bridge *bridge, venc_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
switch (venc_get_videomode(mode)) { switch (venc_get_videomode(mode)) {
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
struct drm_bridge; struct drm_bridge;
struct drm_bridge_timings; struct drm_bridge_timings;
struct drm_connector; struct drm_connector;
struct drm_display_info;
struct drm_panel; struct drm_panel;
struct edid; struct edid;
struct i2c_adapter; struct i2c_adapter;
...@@ -112,6 +113,7 @@ struct drm_bridge_funcs { ...@@ -112,6 +113,7 @@ struct drm_bridge_funcs {
* drm_mode_status Enum * drm_mode_status Enum
*/ */
enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge, enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode); const struct drm_display_mode *mode);
/** /**
...@@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, ...@@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
struct drm_display_mode *adjusted_mode); struct drm_display_mode *adjusted_mode);
enum drm_mode_status enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge, drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode); const struct drm_display_mode *mode);
void drm_bridge_chain_disable(struct drm_bridge *bridge); void drm_bridge_chain_disable(struct drm_bridge *bridge);
void drm_bridge_chain_post_disable(struct drm_bridge *bridge); void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment