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