From 49f98bc4d44a4ee507737f8d5531d05539787319 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 6 Jul 2016 14:49:24 +0200 Subject: drm/imx: store internal bus configuration in crtc state The internal bus configuration is imx-drm specific crtc state. Store it in imx_crtc_state and let the encoder atomic_check callbacks determine bus_flags, bus_format and the sync pins, possibly taking into account the mode and the connector display info. The custom imx_drm_encoder structure can be replaced again with drm_encoder. Signed-off-by: Philipp Zabel --- drivers/gpu/drm/imx/parallel-display.c | 63 ++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 25 deletions(-) (limited to 'drivers/gpu/drm/imx/parallel-display.c') diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 4a2942ecec17..9da60df5efa7 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -27,19 +27,23 @@ #include "imx-drm.h" #define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector) -#define imx_enc_to_imxpd(x) \ - container_of(x, struct imx_parallel_display, imx_encoder) struct imx_parallel_display { struct drm_connector connector; - struct imx_drm_encoder imx_encoder; + struct drm_encoder encoder; struct device *dev; void *edid; int edid_len; + u32 bus_format; struct drm_display_mode mode; struct drm_panel *panel; }; +static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e) +{ + return container_of(e, struct imx_parallel_display, encoder); +} + static enum drm_connector_status imx_pd_connector_detect( struct drm_connector *connector, bool force) { @@ -54,12 +58,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) if (imxpd->panel && imxpd->panel->funcs && imxpd->panel->funcs->get_modes) { - struct drm_display_info *di = &connector->display_info; - num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); - if (!imxpd->imx_encoder.bus_format && di->num_bus_formats) - imxpd->imx_encoder.bus_format = di->bus_formats[0]; - imxpd->imx_encoder.bus_flags = di->bus_flags; if (num_modes > 0) return num_modes; } @@ -89,13 +88,12 @@ static struct drm_encoder *imx_pd_connector_best_encoder( { struct imx_parallel_display *imxpd = con_to_imxpd(connector); - return &imxpd->imx_encoder.encoder; + return &imxpd->encoder; } static void imx_pd_encoder_enable(struct drm_encoder *encoder) { - struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); - struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); drm_panel_prepare(imxpd->panel); drm_panel_enable(imxpd->panel); @@ -103,13 +101,31 @@ static void imx_pd_encoder_enable(struct drm_encoder *encoder) static void imx_pd_encoder_disable(struct drm_encoder *encoder) { - struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); - struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); drm_panel_disable(imxpd->panel); drm_panel_unprepare(imxpd->panel); } +static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); + struct drm_display_info *di = &conn_state->connector->display_info; + struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + + imx_crtc_state->bus_flags = di->bus_flags; + if (!imxpd->bus_format && di->num_bus_formats) + imx_crtc_state->bus_format = di->bus_formats[0]; + else + imx_crtc_state->bus_format = imxpd->bus_format; + imx_crtc_state->di_hsync_pin = 2; + imx_crtc_state->di_vsync_pin = 3; + + return 0; +} + static const struct drm_connector_funcs imx_pd_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, @@ -132,15 +148,16 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { .enable = imx_pd_encoder_enable, .disable = imx_pd_encoder_disable, + .atomic_check = imx_pd_encoder_atomic_check, }; static int imx_pd_register(struct drm_device *drm, struct imx_parallel_display *imxpd) { + struct drm_encoder *encoder = &imxpd->encoder; int ret; - ret = imx_drm_encoder_parse_of(drm, &imxpd->imx_encoder.encoder, - imxpd->dev->of_node); + ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node); if (ret) return ret; @@ -151,10 +168,9 @@ static int imx_pd_register(struct drm_device *drm, */ imxpd->connector.dpms = DRM_MODE_DPMS_OFF; - drm_encoder_helper_add(&imxpd->imx_encoder.encoder, - &imx_pd_encoder_helper_funcs); - drm_encoder_init(drm, &imxpd->imx_encoder.encoder, - &imx_pd_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); + drm_encoder_helper_add(encoder, &imx_pd_encoder_helper_funcs); + drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs, + DRM_MODE_ENCODER_NONE, NULL); drm_connector_helper_add(&imxpd->connector, &imx_pd_connector_helper_funcs); @@ -164,8 +180,7 @@ static int imx_pd_register(struct drm_device *drm, if (imxpd->panel) drm_panel_attach(imxpd->panel, &imxpd->connector); - drm_mode_connector_attach_encoder(&imxpd->connector, - &imxpd->imx_encoder.encoder); + drm_mode_connector_attach_encoder(&imxpd->connector, encoder); return 0; } @@ -200,9 +215,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) else if (!strcmp(fmt, "lvds666")) bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; } - imxpd->imx_encoder.bus_format = bus_format; - imxpd->imx_encoder.di_hsync_pin = 2; - imxpd->imx_encoder.di_vsync_pin = 3; + imxpd->bus_format = bus_format; /* port@1 is the output port */ ep = of_graph_get_endpoint_by_regs(np, 1, -1); @@ -235,7 +248,7 @@ static void imx_pd_unbind(struct device *dev, struct device *master, { struct imx_parallel_display *imxpd = dev_get_drvdata(dev); - imxpd->imx_encoder.encoder.funcs->destroy(&imxpd->imx_encoder.encoder); + imxpd->encoder.funcs->destroy(&imxpd->encoder); imxpd->connector.funcs->destroy(&imxpd->connector); kfree(imxpd->edid); -- cgit v1.2.3