const struct drm_display_mode *mode,
unsigned long long clock)
{
+ const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
const struct drm_display_info *info = &connector->display_info;
if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
return MODE_CLOCK_HIGH;
+ if (funcs && funcs->tmds_char_rate_valid) {
+ enum drm_mode_status status;
+
+ status = funcs->tmds_char_rate_valid(connector, mode, clock);
+ if (status != MODE_OK)
+ return status;
+ }
+
return MODE_OK;
}
* @dev: DRM device
* @connector: A pointer to the HDMI connector to init
* @funcs: callbacks for this connector
+ * @hdmi_funcs: HDMI-related callbacks for this connector
* @connector_type: user visible type of the connector
* @ddc: optional pointer to the associated ddc adapter
* @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats
int drmm_connector_hdmi_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
+ const struct drm_connector_hdmi_funcs *hdmi_funcs,
int connector_type,
struct i2c_adapter *ddc,
unsigned long supported_formats,
if (max_bpc > 8)
drm_connector_attach_hdr_output_metadata_property(connector);
+ connector->hdmi.funcs = hdmi_funcs;
+
return 0;
}
EXPORT_SYMBOL(drmm_connector_hdmi_init);
struct i2c_adapter ddc;
};
+static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
+};
+
static const struct drm_connector_funcs dummy_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
NULL,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
0,
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
&priv->ddc,
BIT(HDMI_COLORSPACE_YUV422),
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
connector_type,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
+ &dummy_hdmi_funcs,
connector_type,
&priv->ddc,
BIT(HDMI_COLORSPACE_RGB),
return 0;
}
+static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
+};
+
static int dummy_connector_get_modes(struct drm_connector *connector)
{
struct drm_atomic_helper_connector_hdmi_priv *priv =
conn = &priv->connector;
ret = drmm_connector_hdmi_init(drm, conn,
&dummy_connector_funcs,
+ &dummy_connector_hdmi_funcs,
DRM_MODE_CONNECTOR_HDMIA,
NULL,
formats,
struct drm_modeset_acquire_ctx;
struct drm_device;
struct drm_crtc;
+struct drm_display_mode;
struct drm_encoder;
struct drm_panel;
struct drm_property;
} hdmi;
};
+/**
+ * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ */
+struct drm_connector_hdmi_funcs {
+ /**
+ * @tmds_char_rate_valid:
+ *
+ * This callback is invoked at atomic_check time to figure out
+ * whether a particular TMDS character rate is supported by the
+ * driver.
+ *
+ * The @tmds_char_rate_valid callback is optional.
+ *
+ * Returns:
+ *
+ * Either &drm_mode_status.MODE_OK or one of the failure reasons
+ * in &enum drm_mode_status.
+ */
+ enum drm_mode_status
+ (*tmds_char_rate_valid)(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long tmds_rate);
+};
+
/**
* struct drm_connector_funcs - control connectors on a given device
*
* supported by the controller.
*/
unsigned long supported_formats;
+
+ /**
+ * @funcs: HDMI connector Control Functions
+ */
+ const struct drm_connector_hdmi_funcs *funcs;
} hdmi;
};
int drmm_connector_hdmi_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
+ const struct drm_connector_hdmi_funcs *hdmi_funcs,
int connector_type,
struct i2c_adapter *ddc,
unsigned long supported_formats,