drm/rockchip: cdn-dp: Convert to drm bridge
Subsystems (4)
PATCH 1/1 drm/rockchip: cdn-dp: Convert to drm bridge
From: Chaoyi Chen <[email protected]>
Convert it to drm bridge driver, it will be convenient for us to migrate the connector part to the display driver later.
Tested with RK3399 EVB IND board.
--- drivers/gpu/drm/rockchip/cdn-dp-core.c | 163 +++++++++++++------------ drivers/gpu/drm/rockchip/cdn-dp-core.h | 5 +- 2 files changed, 86 insertions(+), 82 deletions(-)
drivers/gpu/drm/rockchip/cdn-dp-core.c +82 -81
@@ -25,9 +25,9 @@#include "cdn-dp-core.h" #include "cdn-dp-reg.h" -static inline struct cdn_dp_device *connector_to_dp (struct drm_connector *connector) +static inline struct cdn_dp_device *bridge_to_dp (struct drm_bridge *bridge) { - return container_of(connector, struct cdn_dp_device, connector); + return container_of(bridge, struct cdn_dp_device, bridge); }static inline struct cdn_dp_device *encoder_to_dp (struct drm_encoder *encoder)
@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp) }static enum drm_connector_status -cdn_dp_connector_detect (struct drm_connector *connector,bool force) +cdn_dp_bridge_detect (struct drm_bridge *bridge) { -struct cdn_dp_device *dp =connector_to_dp (connector); +struct cdn_dp_device *dp =bridge_to_dp (bridge);enum drm_connector_status status = connector_status_disconnected;mutex_lock (&dp->lock);
@@ -244,41 +244,26 @@ cdn_dp_connector_detect(struct drm_connector *connector, bool force)return status; } -static void cdn_dp_connector_destroy (struct drm_connector *connector) +static const struct drm_edid * +cdn_dp_connector_edid_read (struct drm_bridge *bridge,struct drm_connector *connector) { -drm_connector_unregister (connector); -drm_connector_cleanup (connector); -} - -static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = { - .detect = cdn_dp_connector_detect, - .destroy = cdn_dp_connector_destroy, - .fill_modes = drm_helper_probe_single_connector_modes, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int cdn_dp_connector_get_modes (struct drm_connector *connector) -{ -struct cdn_dp_device *dp =connector_to_dp (connector); -int ret =0 ; +struct cdn_dp_device *dp =bridge_to_dp (bridge); +const struct drm_edid *drm_edid;mutex_lock (&dp->lock); - - ret =drm_edid_connector_add_modes (connector); - + drm_edid =drm_edid_read_custom (dp->connector, + cdn_dp_get_edid_block, dp);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; + dp->bridge.ops =DRM_BRIDGE_OP_DETECT | +DRM_BRIDGE_OP_EDID | +DRM_BRIDGE_OP_HPD ; + dp->bridge.of_node = dp->dev->of_node; + dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; - ret =drm_connector_init (drm_dev, connector, - &cdn_dp_atomic_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); -if (ret) { -DRM_ERROR ("failed to initialize connector with drm\n" ); - goto err_free_encoder; - } + ret =devm_drm_bridge_add (dev, &dp->bridge); +if (ret) +return ret; -drm_connector_helper_add (connector, &cdn_dp_connector_helper_funcs); + ret =drm_bridge_attach (encoder, &dp->bridge,NULL ,DRM_BRIDGE_ATTACH_NO_CONNECTOR ); +if (ret) +return ret; - ret =drm_connector_attach_encoder (connector, encoder); -if (ret) { -DRM_ERROR ("failed to attach connector and encoder\n" ); - goto err_free_connector; + dp->connector =drm_bridge_connector_init (drm_dev, encoder); +if (IS_ERR (dp->connector)) { + ret =PTR_ERR (dp->connector); +dev_err (dp->dev,"failed to init bridge connector: %d\n" , ret); +return ret; } +drm_connector_attach_encoder (dp->connector, encoder); +for (i =0 ; i < dp->ports; i++) { port = dp->port[i];
@@ -1092,7 +1102,7 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)if (ret) {DRM_DEV_ERROR (dev,"register EXTCON_DISP_DP notifier err\n" ); - goto err_free_connector; +return ret; } }
@@ -1101,24 +1111,15 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)schedule_work (&dp->event_work);return 0 ; - -err_free_connector: -drm_connector_cleanup (connector); -err_free_encoder: -drm_encoder_cleanup (encoder); -return ret; }static void cdn_dp_unbind (struct device *dev,struct device *master,void *data) {struct cdn_dp_device *dp =dev_get_drvdata (dev);struct drm_encoder *encoder = &dp->encoder.encoder; -struct drm_connector *connector = &dp->connector;cancel_work_sync (&dp->event_work); -cdn_dp_encoder_disable (encoder); encoder->funcs->destroy (encoder); - connector->funcs->destroy (connector);pm_runtime_disable (dev);if (dp->fw_loaded)
drivers/gpu/drm/rockchip/cdn-dp-core.h +4 -1
@@ -8,6 +8,8 @@#define _CDN_DP_CORE_H#include <drm/display/drm_dp_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> #include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> #include <sound/hdmi-codec.h>
@@ -65,7 +67,8 @@ struct cdn_dp_port {struct cdn_dp_device {struct device *dev;struct drm_device *drm_dev; -struct drm_connector connector; +struct drm_bridge bridge; +struct drm_connector *connector;struct rockchip_encoder encoder;struct drm_display_mode mode;struct platform_device *audio_pdev;
Signature · 1 line
2.49.0
Andy Yan
maintainerHi Chaoyi,
Quoted 42 lines · Chaoyi Chen
From: Chaoyi Chen <[email protected]>
Convert it to drm bridge driver, it will be convenient for us to migrate the connector part to the display driver later.
Tested with RK3399 EVB IND board.
Signed-off-by Chaoyi Chen <[email protected]>---
drivers/gpu/drm/rockchip/cdn-dp-core.c| 163 +++++++++++++------------drivers/gpu/drm/rockchip/cdn-dp-core.h| 5 +-2 files changed, 86 insertions(+), 82 deletions(-)drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-2@@ -25,9 +25,9 @@#include "cdn-dp-core.h" #include "cdn-dp-reg.h" -static inline struct cdn_dp_device *connector_to_dp (struct drm_connector *connector) +static inline struct cdn_dp_device *bridge_to_dp (struct drm_bridge *bridge) { - return container_of(connector, struct cdn_dp_device, connector); + return container_of(bridge, struct cdn_dp_device, bridge); }static inline struct cdn_dp_device *encoder_to_dp (struct drm_encoder *encoder)@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp) }static enum
drm_connector_statusdrivers/gpu/drm/rockchip/cdn-dp-core.c +1
-1-cdn_dp_connector_detect(struct drm_connector *connector, bool force) +cdn_dp_bridge_detect(struct drm_bridge *bridge){
drivers/gpu/drm/rockchip/cdn-dp-core.c +1
-1-struct cdn_dp_device *dp =connector_to_dp (connector); +struct cdn_dp_device *dp =bridge_to_dp (bridge);enum drm_connector_status status = connector_status_disconnected; mutex_lock(&dp->lock);
drivers/gpu/drm/rockchip/cdn-dp-core.c cdn_dp_connector_detect(struct drm_connector *connector, bool force) · line 248
Quoted 6 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-1@@ -244,41 +244,26 @@ cdn_dp_connector_detect(struct drm_connector *connector, bool force)return status; } -static void cdn_dp_connector_destroy (struct drm_connector *connector) +static const struct drm_edid * +cdn_dp_connector_edid_read (struct drm_bridge *bridge,struct drm_connector *connector)
This should be cdn_dp_bridge_edid_read
Quoted 17 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +0
-16{ -drm_connector_unregister (connector); -drm_connector_cleanup (connector); -} - -static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = { - .detect = cdn_dp_connector_detect, - .destroy = cdn_dp_connector_destroy, - .fill_modes = drm_helper_probe_single_connector_modes, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int cdn_dp_connector_get_modes (struct drm_connector *connector) -{ -struct cdn_dp_device *dp =connector_to_dp (connector);
drivers/gpu/drm/rockchip/cdn-dp-core.c cdn_dp_connector_detect(struct drm_connector *connector, bool force) · line 255
Quoted 10 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +4
-4-int ret =0 ; +struct cdn_dp_device *dp =bridge_to_dp (bridge); +const struct drm_edid *drm_edid;mutex_lock (&dp->lock); - - ret =drm_edid_connector_add_modes (connector); - + drm_edid =drm_edid_read_custom (dp->connector, + cdn_dp_get_edid_block, dp);
Use drm_edid_read_ddc
Quoted 200 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +1
-1mutex_unlock (&dp->lock); -return ret; +return drm_edid; }static enum
drm_mode_statusdrivers/gpu/drm/rockchip/cdn-dp-core.c +3
-2-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){
drivers/gpu/drm/rockchip/cdn-dp-core.c +1
-2-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;drivers/gpu/drm/rockchip/cdn-dp-core.c +37
-24@@ -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);drivers/gpu/drm/rockchip/cdn-dp-core.c +0
-1-drm_connector_helper_hpd_irq_event (&dp->connector);}
static int cdn_dp_pd_event(struct
notifier_block*nb,drivers/gpu/drm/rockchip/cdn-dp-core.c +9
-1@@ -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) {
drivers/gpu/drm/rockchip/cdn-dp-core.c static int cdn_dp_bind(struct device *dev, struct device *master, void *data) · line 1071
Quoted 8 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-3@@ -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;
Try use devm_drm_bridge_alloc
Quoted 22 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +11
-8+ dp->bridge.ops =DRM_BRIDGE_OP_DETECT | +DRM_BRIDGE_OP_EDID | +DRM_BRIDGE_OP_HPD ; + dp->bridge.of_node = dp->dev->of_node; + dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; - ret =drm_connector_init (drm_dev, connector, - &cdn_dp_atomic_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); -if (ret) { -DRM_ERROR ("failed to initialize connector with drm\n" ); - goto err_free_encoder; - } + ret =devm_drm_bridge_add (dev, &dp->bridge); +if (ret) +return ret; -drm_connector_helper_add (connector, &cdn_dp_connector_helper_funcs); + ret =drm_bridge_attach (encoder, &dp->bridge,NULL ,DRM_BRIDGE_ATTACH_NO_CONNECTOR ); +if (ret) +return ret;
drivers/gpu/drm/rockchip/cdn-dp-core.c static int cdn_dp_bind(struct device *dev, struct device *master, void *data) · line 1091
Quoted 10 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +5
-4- ret =drm_connector_attach_encoder (connector, encoder); -if (ret) { -DRM_ERROR ("failed to attach connector and encoder\n" ); - goto err_free_connector; + dp->connector =drm_bridge_connector_init (drm_dev, encoder); +if (IS_ERR (dp->connector)) { + ret =PTR_ERR (dp->connector); +dev_err (dp->dev,"failed to init bridge connector: %d\n" , ret); +return ret; }
Don't store connector here, we will move connector init to display controller side in the future.
You can get connector by: connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); at atomic enable.
Quoted 65 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +3
-10+drm_connector_attach_encoder (dp->connector, encoder); +for (i =0 ; i < dp->ports; i++) { port = dp->port[i];@@ -1092,7 +1102,7 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)if (ret) {DRM_DEV_ERROR (dev,"register EXTCON_DISP_DP notifier err\n" ); - goto err_free_connector; +return ret; } }@@ -1101,24 +1111,15 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)schedule_work (&dp->event_work);return 0 ; - -err_free_connector: -drm_connector_cleanup (connector); -err_free_encoder: -drm_encoder_cleanup (encoder); -return ret; }static void cdn_dp_unbind (struct device *dev,struct device *master,void *data) {struct cdn_dp_device *dp =dev_get_drvdata (dev);struct drm_encoder *encoder = &dp->encoder.encoder; -struct drm_connector *connector = &dp->connector;cancel_work_sync (&dp->event_work); -cdn_dp_encoder_disable (encoder); encoder->funcs->destroy (encoder); - connector->funcs->destroy (connector);pm_runtime_disable (dev);if (dp->fw_loaded)drivers/gpu/drm/rockchip/cdn-dp-core.h +4
-1@@ -8,6 +8,8 @@#define _CDN_DP_CORE_H#include <drm/display/drm_dp_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> #include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> #include <sound/hdmi-codec.h> @@ -65,7 +67,8 @@ struct cdn_dp_port {struct cdn_dp_device {struct device *dev;struct drm_device *drm_dev; -struct drm_connector connector; +struct drm_bridge bridge; +struct drm_connector *connector;struct rockchip_encoder encoder;struct drm_display_mode mode;struct platform_device *audio_pdev;Signature · 1 line
2.49.0
Hi Andy,
Quoted 48 lines · Andy Yan
Hi Chaoyi,
Quoted 45 lines · Chaoyi Chen
From: Chaoyi Chen <[email protected]>
Convert it to drm bridge driver, it will be convenient for us to migrate the connector part to the display driver later.
Tested with RK3399 EVB IND board.
Signed-off-by Chaoyi Chen <[email protected]>---
drivers/gpu/drm/rockchip/cdn-dp-core.c| 163 +++++++++++++------------drivers/gpu/drm/rockchip/cdn-dp-core.h| 5 +-2 files changed, 86 insertions(+), 82 deletions(-)drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-2@@ -25,9 +25,9 @@#include "cdn-dp-core.h" #include "cdn-dp-reg.h" -static inline struct cdn_dp_device *connector_to_dp (struct drm_connector *connector) +static inline struct cdn_dp_device *bridge_to_dp (struct drm_bridge *bridge) { - return container_of(connector, struct cdn_dp_device, connector); + return container_of(bridge, struct cdn_dp_device, bridge); }static inline struct cdn_dp_device *encoder_to_dp (struct drm_encoder *encoder)@@ -231,9 +231,9 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp) }static enum
drm_connector_statusdrivers/gpu/drm/rockchip/cdn-dp-core.c +1
-1-cdn_dp_connector_detect(struct drm_connector *connector, bool force) +cdn_dp_bridge_detect(struct drm_bridge *bridge){
drivers/gpu/drm/rockchip/cdn-dp-core.c +1
-1-struct cdn_dp_device *dp =connector_to_dp (connector); +struct cdn_dp_device *dp =bridge_to_dp (bridge);enum drm_connector_status status = connector_status_disconnected; mutex_lock(&dp->lock);drivers/gpu/drm/rockchip/cdn-dp-core.c +0
-0@@ -244,41 +244,26 @@ cdn_dp_connector_detect(struct drm_connector *connector, bool force)return status; }
Quoted 4 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c cdn_dp_connector_detect(struct drm_connector *connector, bool force) · line 248
Quoted 3 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-1-static void cdn_dp_connector_destroy (struct drm_connector *connector) +static const struct drm_edid * +cdn_dp_connector_edid_read (struct drm_bridge *bridge,struct drm_connector *connector)This should be
cdn_dp_bridge_edid_read
Will fix in v2.
Quoted 22 lines
Quoted 22 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-17{ -drm_connector_unregister (connector); -drm_connector_cleanup (connector); -} - -static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = { - .detect = cdn_dp_connector_detect, - .destroy = cdn_dp_connector_destroy, - .fill_modes = drm_helper_probe_single_connector_modes, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int cdn_dp_connector_get_modes (struct drm_connector *connector) -{ -struct cdn_dp_device *dp =connector_to_dp (connector); -int ret =0 ; +struct cdn_dp_device *dp =bridge_to_dp (bridge); +const struct drm_edid *drm_edid;
Quoted 7 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c cdn_dp_connector_detect(struct drm_connector *connector, bool force) · line 255
Quoted 6 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-3mutex_lock (&dp->lock); - - ret =drm_edid_connector_add_modes (connector); - + drm_edid =drm_edid_read_custom (dp->connector, + cdn_dp_get_edid_block, dp);Use
drm_edid_read_ddc
drm_edid_read_ddc() need a i2c_adapter, but cdn-dp doesn't have it.
Quoted 202 lines
Quoted 202 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +1
-1mutex_unlock (&dp->lock); -return ret; +return drm_edid; }static enum
drm_mode_statusdrivers/gpu/drm/rockchip/cdn-dp-core.c +3
-2-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){
drivers/gpu/drm/rockchip/cdn-dp-core.c +1
-2-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;drivers/gpu/drm/rockchip/cdn-dp-core.c +37
-24@@ -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);drivers/gpu/drm/rockchip/cdn-dp-core.c +0
-1-drm_connector_helper_hpd_irq_event (&dp->connector);}
static int cdn_dp_pd_event(struct
notifier_block*nb,drivers/gpu/drm/rockchip/cdn-dp-core.c +9
-1@@ -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)
Quoted 8 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c static int cdn_dp_bind(struct device *dev, struct device *master, void *data) · line 1071
Quoted 7 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +2
-3drm_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;Try use
devm_drm_bridge_alloc
Okay, I will try to use this in v2.
Quoted 35 lines
Quoted 23 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +11
-8+ dp->bridge.ops =DRM_BRIDGE_OP_DETECT | +DRM_BRIDGE_OP_EDID | +DRM_BRIDGE_OP_HPD ; + dp->bridge.of_node = dp->dev->of_node; + dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; - ret =drm_connector_init (drm_dev, connector, - &cdn_dp_atomic_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); -if (ret) { -DRM_ERROR ("failed to initialize connector with drm\n" ); - goto err_free_encoder; - } + ret =devm_drm_bridge_add (dev, &dp->bridge); +if (ret) +return ret; -drm_connector_helper_add (connector, &cdn_dp_connector_helper_funcs); + ret =drm_bridge_attach (encoder, &dp->bridge,NULL ,DRM_BRIDGE_ATTACH_NO_CONNECTOR ); +if (ret) +return ret;drivers/gpu/drm/rockchip/cdn-dp-core.c static int cdn_dp_bind(struct device *dev, struct device *master, void *data) · line 1091
Quoted 10 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +5
-4- ret =drm_connector_attach_encoder (connector, encoder); -if (ret) { -DRM_ERROR ("failed to attach connector and encoder\n" ); - goto err_free_connector; + dp->connector =drm_bridge_connector_init (drm_dev, encoder); +if (IS_ERR (dp->connector)) { + ret =PTR_ERR (dp->connector); +dev_err (dp->dev,"failed to init bridge connector: %d\n" , ret); +return ret; }Don't store connector here, we will move connector init to display controller side in the future.
Quoted 2 lines
You can get connector by: connector =
drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); at atomic enable.
Will fix in v2.
Quoted 57 lines
Quoted 57 lines
drivers/gpu/drm/rockchip/cdn-dp-core.c +3
-10+drm_connector_attach_encoder (dp->connector, encoder); +for (i =0 ; i < dp->ports; i++) { port = dp->port[i];@@ -1092,7 +1102,7 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)if (ret) {DRM_DEV_ERROR (dev,"register EXTCON_DISP_DP notifier err\n" ); - goto err_free_connector; +return ret; } }@@ -1101,24 +1111,15 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)schedule_work (&dp->event_work);return 0 ; - -err_free_connector: -drm_connector_cleanup (connector); -err_free_encoder: -drm_encoder_cleanup (encoder); -return ret; }static void cdn_dp_unbind (struct device *dev,struct device *master,void *data) {struct cdn_dp_device *dp =dev_get_drvdata (dev);struct drm_encoder *encoder = &dp->encoder.encoder; -struct drm_connector *connector = &dp->connector;cancel_work_sync (&dp->event_work); -cdn_dp_encoder_disable (encoder); encoder->funcs->destroy (encoder); - connector->funcs->destroy (connector);pm_runtime_disable (dev);if (dp->fw_loaded)drivers/gpu/drm/rockchip/cdn-dp-core.h +2
-0@@ -8,6 +8,8 @@#define _CDN_DP_CORE_H#include <drm/display/drm_dp_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> #include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> #include <sound/hdmi-codec.h> @@ -65,7 +67,8 @@ struct cdn_dp_port {struct cdn_dp_device {struct device *dev;struct drm_device *drm_dev;
Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/rockchip/cdn-dp-core.h +2
-1-struct drm_connector connector; +struct drm_bridge bridge; +struct drm_connector *connector;struct rockchip_encoder encoder;struct drm_display_mode mode;struct platform_device *audio_pdev;Signature · 1 line
2.49.0
_______________________________________________
Linux-rockchip mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-rockchip