Commit cbb11ef9 authored by Laurent Pinchart's avatar Laurent Pinchart

drm: xlnx: zynqmp_dpsub: Use DRM connector bridge helper

Replace the manual connector implementation and registration in the DP
encoder with the DRM connector bridge helper. This removes boilerplate
code and simplifies the driver.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
parent bd68b9b3
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <drm/display/drm_dp_helper.h> #include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
...@@ -275,7 +274,6 @@ struct zynqmp_dp_config { ...@@ -275,7 +274,6 @@ struct zynqmp_dp_config {
/** /**
* struct zynqmp_dp - Xilinx DisplayPort core * struct zynqmp_dp - Xilinx DisplayPort core
* @connector: the drm connector structure
* @dev: device structure * @dev: device structure
* @dpsub: Display subsystem * @dpsub: Display subsystem
* @drm: DRM core * @drm: DRM core
...@@ -297,7 +295,6 @@ struct zynqmp_dp_config { ...@@ -297,7 +295,6 @@ struct zynqmp_dp_config {
* @train_set: set of training data * @train_set: set of training data
*/ */
struct zynqmp_dp { struct zynqmp_dp {
struct drm_connector connector;
struct device *dev; struct device *dev;
struct zynqmp_dpsub *dpsub; struct zynqmp_dpsub *dpsub;
struct drm_device *drm; struct drm_device *drm;
...@@ -322,11 +319,6 @@ struct zynqmp_dp { ...@@ -322,11 +319,6 @@ struct zynqmp_dp {
u8 train_set[ZYNQMP_DP_MAX_LANES]; u8 train_set[ZYNQMP_DP_MAX_LANES];
}; };
static inline struct zynqmp_dp *connector_to_dp(struct drm_connector *connector)
{
return container_of(connector, struct zynqmp_dp, connector);
}
static inline struct zynqmp_dp *bridge_to_dp(struct drm_bridge *bridge) static inline struct zynqmp_dp *bridge_to_dp(struct drm_bridge *bridge)
{ {
return container_of(bridge, struct zynqmp_dp, bridge); return container_of(bridge, struct zynqmp_dp, bridge);
...@@ -1285,33 +1277,15 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp, ...@@ -1285,33 +1277,15 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
* DRM Bridge * DRM Bridge
*/ */
static const struct drm_connector_funcs zynqmp_dp_connector_funcs;
static const struct drm_connector_helper_funcs zynqmp_dp_connector_helper_funcs;
static int zynqmp_dp_bridge_attach(struct drm_bridge *bridge, static int zynqmp_dp_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags) enum drm_bridge_attach_flags flags)
{ {
struct zynqmp_dp *dp = bridge_to_dp(bridge); struct zynqmp_dp *dp = bridge_to_dp(bridge);
struct drm_connector *connector = &dp->connector;
int ret; int ret;
/* Create the DRM connector. */
connector->polled = DRM_CONNECTOR_POLL_HPD;
ret = drm_connector_init(dp->drm, connector,
&zynqmp_dp_connector_funcs,
DRM_MODE_CONNECTOR_DisplayPort);
if (ret) {
dev_err(dp->dev, "failed to create the DRM connector\n");
return ret;
}
drm_connector_helper_add(connector, &zynqmp_dp_connector_helper_funcs);
drm_connector_register(connector);
drm_connector_attach_encoder(connector, bridge->encoder);
if (dp->next_bridge) { if (dp->next_bridge) {
ret = drm_bridge_attach(bridge->encoder, dp->next_bridge, ret = drm_bridge_attach(bridge->encoder, dp->next_bridge,
bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR); bridge, flags);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
...@@ -1532,68 +1506,6 @@ static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = { ...@@ -1532,68 +1506,6 @@ static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = {
.get_edid = zynqmp_dp_bridge_get_edid, .get_edid = zynqmp_dp_bridge_get_edid,
}; };
/* -----------------------------------------------------------------------------
* DRM Connector
*/
static enum drm_connector_status
zynqmp_dp_connector_detect(struct drm_connector *connector, bool force)
{
struct zynqmp_dp *dp = connector_to_dp(connector);
return zynqmp_dp_bridge_detect(&dp->bridge);
}
static int zynqmp_dp_connector_get_modes(struct drm_connector *connector)
{
struct zynqmp_dp *dp = connector_to_dp(connector);
struct edid *edid;
int ret;
edid = zynqmp_dp_bridge_get_edid(&dp->bridge, connector);
if (!edid)
return 0;
drm_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
return ret;
}
static struct drm_encoder *
zynqmp_dp_connector_best_encoder(struct drm_connector *connector)
{
struct zynqmp_dp *dp = connector_to_dp(connector);
return &dp->dpsub->encoder;
}
static int zynqmp_dp_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct zynqmp_dp *dp = connector_to_dp(connector);
return zynqmp_dp_bridge_mode_valid(&dp->bridge, &connector->display_info,
mode);
}
static const struct drm_connector_funcs zynqmp_dp_connector_funcs = {
.detect = zynqmp_dp_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.reset = drm_atomic_helper_connector_reset,
};
static const struct drm_connector_helper_funcs
zynqmp_dp_connector_helper_funcs = {
.get_modes = zynqmp_dp_connector_get_modes,
.best_encoder = zynqmp_dp_connector_best_encoder,
.mode_valid = zynqmp_dp_connector_mode_valid,
};
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Interrupt Handling * Interrupt Handling
*/ */
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h> #include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_connector.h>
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
...@@ -97,6 +99,7 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = { ...@@ -97,6 +99,7 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = {
static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
{ {
struct drm_encoder *encoder = &dpsub->encoder; struct drm_encoder *encoder = &dpsub->encoder;
struct drm_connector *connector;
struct drm_device *drm = &dpsub->drm; struct drm_device *drm = &dpsub->drm;
int ret; int ret;
...@@ -133,12 +136,27 @@ static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) ...@@ -133,12 +136,27 @@ static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
encoder->possible_crtcs |= zynqmp_disp_get_crtc_mask(dpsub->disp); encoder->possible_crtcs |= zynqmp_disp_get_crtc_mask(dpsub->disp);
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE); drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
ret = drm_bridge_attach(encoder, dpsub->bridge, NULL, 0); ret = drm_bridge_attach(encoder, dpsub->bridge, NULL,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret) { if (ret) {
dev_err(dpsub->dev, "failed to attach bridge to encoder\n"); dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
goto err_poll_fini; goto err_poll_fini;
} }
/* Create the connector for the chain of bridges. */
connector = drm_bridge_connector_init(drm, encoder);
if (IS_ERR(connector)) {
dev_err(dpsub->dev, "failed to created connector\n");
ret = PTR_ERR(connector);
goto err_poll_fini;
}
ret = drm_connector_attach_encoder(connector, encoder);
if (ret < 0) {
dev_err(dpsub->dev, "failed to attach connector to encoder\n");
goto err_poll_fini;
}
/* Reset all components and register the DRM device. */ /* Reset all components and register the DRM device. */
drm_mode_config_reset(drm); drm_mode_config_reset(drm);
......
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