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: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Guido Günther <agx@sigxcpu.org> # for the nwl-dsi part:
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-11-laurent.pinchart+renesas@ideasonboard.com
static enum drm_mode_status
anx6345_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
static enum drm_mode_status
anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
static enum drm_mode_status
cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(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)
{
if (mode->clock > 165000)
static enum drm_mode_status
nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct nwl_dsi *dsi = bridge_to_dsi(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)
{
if (mode->clock > MHL1_MAX_CLK)
}
static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct sii8620 *ctx = bridge_to_sii8620(bridge);
static enum drm_mode_status
dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct dw_hdmi *hdmi = bridge->driver_private;
static enum drm_mode_status
dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct dw_mipi_dsi *dsi = bridge_to_dsi(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)
{
struct tc_data *tc = bridge_to_tc(bridge);
static enum drm_mode_status
tc358768_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct tc358768_priv *priv = bridge_to_tc358768(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)
{
struct thc63_dev *thc63 = to_thc63(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)
{
if (mode->clock < 25000)
}
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) {
DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
return ret;
* drm_bridge_chain_mode_valid - validate the mode against all bridges in the
* encoder chain.
* @bridge: bridge control structure
+ * @info: display info against which the mode shall be validated
* @mode: desired mode to be validated
*
* Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
*/
enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct drm_encoder *encoder;
if (!bridge->funcs->mode_valid)
continue;
- ret = bridge->funcs->mode_valid(bridge, mode);
+ ret = bridge->funcs->mode_valid(bridge, info, mode);
if (ret != MODE_OK)
return ret;
}
}
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) {
/* There is also no point in continuing for crtc check
* here. */
}
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)
{
/* TDA19988 dotclock can go up to 165MHz */
static enum drm_mode_status
dpi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
static enum drm_mode_status
sdi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
static enum drm_mode_status
venc_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
switch (venc_get_videomode(mode)) {
struct drm_bridge;
struct drm_bridge_timings;
struct drm_connector;
+struct drm_display_info;
struct drm_panel;
struct edid;
struct i2c_adapter;
* drm_mode_status Enum
*/
enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode);
/**
struct drm_display_mode *adjusted_mode);
enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
const struct drm_display_mode *mode);
void drm_bridge_chain_disable(struct drm_bridge *bridge);
void drm_bridge_chain_post_disable(struct drm_bridge *bridge);