mutex_unlock(&dp->lock);
- return ret;
+ return drm_edid;
}
static enum drm_mode_status
-cdn_dp_connector_mode_valid(struct drm_connector *connector,
- const struct drm_display_mode *mode)
+cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *display_info,
+ const struct drm_display_mode *mode)
{
- struct cdn_dp_device *dp = connector_to_dp(connector);
- struct drm_display_info *display_info = &dp->connector.display_info;
+ struct cdn_dp_device *dp = bridge_to_dp(bridge);
u32 requested, actual, rate, sink_max, source_max = 0;
u8 lanes, bpc;
@@ -323,11 +308,6 @@ cdn_dp_connector_mode_valid(struct drm_connector
*connector,
return MODE_OK;
}
-static struct drm_connector_helper_funcs cdn_dp_connector_helper_funcs = {
- .get_modes = cdn_dp_connector_get_modes,
- .mode_valid = cdn_dp_connector_mode_valid,
-};
-
static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
{
int ret;
@@ -360,7 +340,7 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
{
- const struct drm_display_info *info = &dp->connector.display_info;
+ const struct drm_display_info *info = &dp->connector->display_info;
int ret;
if (!cdn_dp_check_sink_connection(dp))
@@ -374,9 +354,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device
*dp)
}
drm_edid_free(dp->drm_edid);
- dp->drm_edid = drm_edid_read_custom(&dp->connector,
+ dp->drm_edid = drm_edid_read_custom(dp->connector,
cdn_dp_get_edid_block, dp);
- drm_edid_connector_update(&dp->connector, dp->drm_edid);
+ drm_edid_connector_update(dp->connector, dp->drm_edid);
dp->sink_has_audio = info->has_audio;
@@ -416,11 +396,11 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp,
struct cdn_dp_port *port)
goto err_power_on;
}
- ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
- EXTCON_PROP_USB_TYPEC_POLARITY, &property);
- if (ret) {
- DRM_DEV_ERROR(dp->dev, "get property failed\n");
- goto err_power_on;
+ ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
+ EXTCON_PROP_USB_TYPEC_POLARITY,
&property);
+ if (ret) {
+ DRM_DEV_ERROR(dp->dev, "get property failed\n");
+ goto err_power_on;
}
port->lanes = cdn_dp_get_port_lanes(port);
@@ -551,7 +531,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder
*encoder,
struct drm_display_mode *adjusted)
{
struct cdn_dp_device *dp = encoder_to_dp(encoder);
- struct drm_display_info *display_info = &dp->connector.display_info;
+ struct drm_display_info *display_info = &dp->connector->display_info;
struct video_info *video = &dp->video_info;
switch (display_info->bpc) {
@@ -599,12 +579,12 @@ static void cdn_dp_audio_handle_plugged_change(struct
cdn_dp_device *dp,
dp->plugged_cb(dp->codec_dev, plugged);
}
-static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
+static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct
drm_atomic_state *state)
{
- struct cdn_dp_device *dp = encoder_to_dp(encoder);
+ struct cdn_dp_device *dp = bridge_to_dp(bridge);
int ret, val;
- ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+ ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node,
&dp->encoder.encoder);
if (ret < 0) {
DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
return;
@@ -625,7 +605,7 @@ static void cdn_dp_encoder_enable(struct drm_encoder
*encoder)
ret = cdn_dp_enable(dp);
if (ret) {
- DRM_DEV_ERROR(dp->dev, "Failed to enable encoder %d\n",
+ DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
ret);
goto out;
}
@@ -661,9 +641,9 @@ static void cdn_dp_encoder_enable(struct drm_encoder
*encoder)
mutex_unlock(&dp->lock);
}
-static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
+static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct
drm_atomic_state *state)
{
- struct cdn_dp_device *dp = encoder_to_dp(encoder);
+ struct cdn_dp_device *dp = bridge_to_dp(bridge);
int ret;
mutex_lock(&dp->lock);
@@ -672,7 +652,7 @@ static void cdn_dp_encoder_disable(struct drm_encoder
*encoder)
if (dp->active) {
ret = cdn_dp_disable(dp);
if (ret) {
- DRM_DEV_ERROR(dp->dev, "Failed to disable encoder %d\n",
+ DRM_DEV_ERROR(dp->dev, "Failed to disable bridge %d\n",
ret);
}
}
@@ -703,13 +683,31 @@ static int cdn_dp_encoder_atomic_check(struct drm_encoder
*encoder,
return 0;
}
+static void cdn_dp_hpd_notify(struct drm_bridge *bridge,
+ enum drm_connector_status status)
+{
+ struct cdn_dp_device *dp = bridge_to_dp(bridge);
+
+ schedule_work(&dp->event_work);
+}
+
static const struct drm_encoder_helper_funcs cdn_dp_encoder_helper_funcs = {
.mode_set = cdn_dp_encoder_mode_set,
- .enable = cdn_dp_encoder_enable,
- .disable = cdn_dp_encoder_disable,
.atomic_check = cdn_dp_encoder_atomic_check,
};
+static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .detect = cdn_dp_bridge_detect,
+ .edid_read = cdn_dp_connector_edid_read,
+ .atomic_enable = cdn_dp_bridge_atomic_enable,
+ .atomic_disable = cdn_dp_bridge_atomic_disable,
+ .mode_valid = cdn_dp_bridge_mode_valid,
+ .hpd_notify = cdn_dp_hpd_notify,
+};
+
static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
{
struct device *dev = dp->dev;
@@ -859,7 +857,7 @@ static int cdn_dp_audio_get_eld(struct device *dev, void
*data,
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
- memcpy(buf, dp->connector.eld, min(sizeof(dp->connector.eld), len));
+ memcpy(buf, dp->connector->eld, min(sizeof(dp->connector->eld), len));
return 0;
}
@@ -1006,7 +1004,6 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
out:
mutex_unlock(&dp->lock);
- drm_connector_helper_hpd_irq_event(&dp->connector);
}
static int cdn_dp_pd_event(struct notifier_block *nb,
@@ -1030,7 +1027,6 @@ static int cdn_dp_bind(struct device *dev, struct device
*master, void *data)
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
struct drm_encoder *encoder;
- struct drm_connector *connector;
struct cdn_dp_port *port;
struct drm_device *drm_dev = data;
int ret, i;
@@ -1053,6 +1049,15 @@ static int cdn_dp_bind(struct device *dev, struct device
*master, void *data)
dev->of_node);
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+ /*
+ * If we failed to find the CRTC(s) which this encoder is
+ * supposed to be connected to, it's because the CRTC has
+ * not been registered yet. Defer probing, and hope that
+ * the required CRTC is added later.
+ */
+ if (encoder->possible_crtcs == 0)
+ return -EPROBE_DEFER;
+
ret = drm_simple_encoder_init(drm_dev, encoder,
DRM_MODE_ENCODER_TMDS);
if (ret) {
@@ -1062,26 +1067,31 @@ static int cdn_dp_bind(struct device *dev, struct
device *master, void *data)
drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
- connector = &dp->connector;
- connector->polled = DRM_CONNECTOR_POLL_HPD;
- connector->dpms = DRM_MODE_DPMS_OFF;
+ dp->bridge.driver_private = dp;
+ dp->bridge.funcs = &cdn_dp_bridge_funcs;