#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
/**
* struct zynqmp_dp - Xilinx DisplayPort core
- * @connector: the drm connector structure
* @dev: device structure
* @dpsub: Display subsystem
* @drm: DRM core
* @train_set: set of training data
*/
struct zynqmp_dp {
- struct drm_connector connector;
struct device *dev;
struct zynqmp_dpsub *dpsub;
struct drm_device *drm;
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)
{
return container_of(bridge, struct zynqmp_dp, 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,
enum drm_bridge_attach_flags flags)
{
struct zynqmp_dp *dp = bridge_to_dp(bridge);
- struct drm_connector *connector = &dp->connector;
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) {
ret = drm_bridge_attach(bridge->encoder, dp->next_bridge,
- bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ bridge, flags);
if (ret < 0)
return ret;
}
};
/* -----------------------------------------------------------------------------
- * 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
*/
#include <drm/drm_atomic_helper.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_drv.h>
#include <drm/drm_fb_helper.h>
static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
{
struct drm_encoder *encoder = &dpsub->encoder;
+ struct drm_connector *connector;
struct drm_device *drm = &dpsub->drm;
int ret;
encoder->possible_crtcs |= zynqmp_disp_get_crtc_mask(dpsub->disp);
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) {
dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
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. */
drm_mode_config_reset(drm);