diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 65b1ab4e4d2dd..28f92b5d8385d 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -15,12 +15,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include @@ -277,7 +275,6 @@ struct zynqmp_dp_config { /** * struct zynqmp_dp - Xilinx DisplayPort core - * @encoder: the drm encoder structure * @connector: the drm connector structure * @dev: device structure * @dpsub: Display subsystem @@ -299,7 +296,6 @@ struct zynqmp_dp_config { * @train_set: set of training data */ struct zynqmp_dp { - struct drm_encoder encoder; struct drm_connector connector; struct device *dev; struct zynqmp_dpsub *dpsub; @@ -324,11 +320,6 @@ struct zynqmp_dp { u8 train_set[ZYNQMP_DP_MAX_LANES]; }; -static inline struct zynqmp_dp *encoder_to_dp(struct drm_encoder *encoder) -{ - return container_of(encoder, struct zynqmp_dp, encoder); -} - static inline struct zynqmp_dp *connector_to_dp(struct drm_connector *connector) { return container_of(connector, struct zynqmp_dp, connector); @@ -1566,7 +1557,7 @@ zynqmp_dp_connector_best_encoder(struct drm_connector *connector) { struct zynqmp_dp *dp = connector_to_dp(connector); - return &dp->encoder; + return &dp->dpsub->encoder; } static int zynqmp_dp_connector_mode_valid(struct drm_connector *connector, @@ -1594,55 +1585,6 @@ zynqmp_dp_connector_helper_funcs = { .mode_valid = zynqmp_dp_connector_mode_valid, }; -/* ----------------------------------------------------------------------------- - * DRM Encoder - */ - -static void zynqmp_dp_encoder_atomic_enable(struct drm_encoder *encoder, - struct drm_atomic_state *state) -{ - struct zynqmp_dp *dp = encoder_to_dp(encoder); - struct drm_bridge_state bridge_state; - - bridge_state.base.state = state; - zynqmp_dp_bridge_atomic_enable(&dp->bridge, &bridge_state); -} - -static void zynqmp_dp_encoder_atomic_disable(struct drm_encoder *encoder, - struct drm_atomic_state *state) -{ - struct zynqmp_dp *dp = encoder_to_dp(encoder); - struct drm_bridge_state bridge_state; - - bridge_state.base.state = state; - zynqmp_dp_bridge_atomic_disable(&dp->bridge, &bridge_state); -} - -static void -zynqmp_dp_encoder_atomic_mode_set(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *connector_state) -{ -} - -static int -zynqmp_dp_encoder_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct zynqmp_dp *dp = encoder_to_dp(encoder); - - return zynqmp_dp_bridge_atomic_check(&dp->bridge, NULL, crtc_state, - conn_state); -} - -static const struct drm_encoder_helper_funcs zynqmp_dp_encoder_helper_funcs = { - .atomic_enable = zynqmp_dp_encoder_atomic_enable, - .atomic_disable = zynqmp_dp_encoder_atomic_disable, - .atomic_mode_set = zynqmp_dp_encoder_atomic_mode_set, - .atomic_check = zynqmp_dp_encoder_atomic_check, -}; - /* ----------------------------------------------------------------------------- * Interrupt Handling */ @@ -1731,32 +1673,17 @@ int zynqmp_dp_drm_init(struct zynqmp_dpsub *dpsub) { struct zynqmp_dp *dp = dpsub->dp; struct drm_bridge *bridge = &dp->bridge; - struct drm_encoder *encoder = &dp->encoder; int ret; dp->config.misc0 &= ~ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK; zynqmp_dp_set_format(dp, NULL, ZYNQMP_DPSUB_FORMAT_RGB, 8); - /* - * Initialize the bridge. Setting the device and encoder manually is a - * hack, to be removed once the bridge will get attached to the encoder - * using the bridge API. - */ - bridge->dev = dp->drm; - bridge->encoder = &dp->encoder; + /* Initialize the bridge. */ bridge->funcs = &zynqmp_dp_bridge_funcs; bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; bridge->type = DRM_MODE_CONNECTOR_DisplayPort; - - /* Create the DRM encoder and attach the bridge. */ - encoder->possible_crtcs |= zynqmp_disp_get_crtc_mask(dpsub->disp); - drm_simple_encoder_init(dp->drm, encoder, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(encoder, &zynqmp_dp_encoder_helper_funcs); - - ret = zynqmp_dp_bridge_attach(bridge, 0); - if (ret < 0) - return ret; + dpsub->bridge = bridge; /* Initialize and register the AUX adapter. */ ret = zynqmp_dp_aux_init(dp); diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c index 1de2d927c32b0..bb7c74a73dc21 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include "zynqmp_disp.h" @@ -94,6 +96,7 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = { static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) { + struct drm_encoder *encoder = &dpsub->encoder; struct drm_device *drm = &dpsub->drm; int ret; @@ -116,8 +119,7 @@ static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) /* * Initialize the DISP and DP components. This will creates planes, - * CRTC, encoder and connector. The DISP should be initialized first as - * the DP encoder needs the CRTC. + * CRTC, and a bridge for the DP encoder. */ ret = zynqmp_disp_drm_init(dpsub); if (ret) @@ -127,6 +129,16 @@ static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) if (ret) goto err_poll_fini; + /* Create the encoder and attach the bridge. */ + 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); + if (ret) { + dev_err(dpsub->dev, "failed to attach bridge to encoder\n"); + goto err_poll_fini; + } + /* Reset all components and register the DRM device. */ drm_mode_config_reset(drm); diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h index c04026d82639c..66820bbc4507f 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h @@ -12,8 +12,11 @@ #ifndef _ZYNQMP_DPSUB_H_ #define _ZYNQMP_DPSUB_H_ +#include + struct clk; struct device; +struct drm_bridge; struct drm_device; struct zynqmp_disp; struct zynqmp_dp; @@ -30,6 +33,8 @@ enum zynqmp_dpsub_format { * @drm: The DRM/KMS device * @dev: The physical device * @apb_clk: The APB clock + * @encoder: The dummy DRM encoder + * @bridge: The DP encoder bridge * @disp: The display controller * @dp: The DisplayPort controller * @dma_align: DMA alignment constraint (must be a power of 2) @@ -40,6 +45,9 @@ struct zynqmp_dpsub { struct clk *apb_clk; + struct drm_encoder encoder; + struct drm_bridge *bridge; + struct zynqmp_disp *disp; struct zynqmp_dp *dp;