aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/imx/parallel-display.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2016-07-06 08:49:24 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-07-12 12:24:28 -0400
commit49f98bc4d44a4ee507737f8d5531d05539787319 (patch)
treef450326225bb4215a191bf10170cbbbae8b87b04 /drivers/gpu/drm/imx/parallel-display.c
parente41c5c2411bca56775663a4153e0c00ea8c8f130 (diff)
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 <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/parallel-display.c')
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c63
1 files changed, 38 insertions, 25 deletions
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 @@
27#include "imx-drm.h" 27#include "imx-drm.h"
28 28
29#define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector) 29#define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector)
30#define imx_enc_to_imxpd(x) \
31 container_of(x, struct imx_parallel_display, imx_encoder)
32 30
33struct imx_parallel_display { 31struct imx_parallel_display {
34 struct drm_connector connector; 32 struct drm_connector connector;
35 struct imx_drm_encoder imx_encoder; 33 struct drm_encoder encoder;
36 struct device *dev; 34 struct device *dev;
37 void *edid; 35 void *edid;
38 int edid_len; 36 int edid_len;
37 u32 bus_format;
39 struct drm_display_mode mode; 38 struct drm_display_mode mode;
40 struct drm_panel *panel; 39 struct drm_panel *panel;
41}; 40};
42 41
42static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e)
43{
44 return container_of(e, struct imx_parallel_display, encoder);
45}
46
43static enum drm_connector_status imx_pd_connector_detect( 47static enum drm_connector_status imx_pd_connector_detect(
44 struct drm_connector *connector, bool force) 48 struct drm_connector *connector, bool force)
45{ 49{
@@ -54,12 +58,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
54 58
55 if (imxpd->panel && imxpd->panel->funcs && 59 if (imxpd->panel && imxpd->panel->funcs &&
56 imxpd->panel->funcs->get_modes) { 60 imxpd->panel->funcs->get_modes) {
57 struct drm_display_info *di = &connector->display_info;
58
59 num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); 61 num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
60 if (!imxpd->imx_encoder.bus_format && di->num_bus_formats)
61 imxpd->imx_encoder.bus_format = di->bus_formats[0];
62 imxpd->imx_encoder.bus_flags = di->bus_flags;
63 if (num_modes > 0) 62 if (num_modes > 0)
64 return num_modes; 63 return num_modes;
65 } 64 }
@@ -89,13 +88,12 @@ static struct drm_encoder *imx_pd_connector_best_encoder(
89{ 88{
90 struct imx_parallel_display *imxpd = con_to_imxpd(connector); 89 struct imx_parallel_display *imxpd = con_to_imxpd(connector);
91 90
92 return &imxpd->imx_encoder.encoder; 91 return &imxpd->encoder;
93} 92}
94 93
95static void imx_pd_encoder_enable(struct drm_encoder *encoder) 94static void imx_pd_encoder_enable(struct drm_encoder *encoder)
96{ 95{
97 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); 96 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
98 struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder);
99 97
100 drm_panel_prepare(imxpd->panel); 98 drm_panel_prepare(imxpd->panel);
101 drm_panel_enable(imxpd->panel); 99 drm_panel_enable(imxpd->panel);
@@ -103,13 +101,31 @@ static void imx_pd_encoder_enable(struct drm_encoder *encoder)
103 101
104static void imx_pd_encoder_disable(struct drm_encoder *encoder) 102static void imx_pd_encoder_disable(struct drm_encoder *encoder)
105{ 103{
106 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); 104 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
107 struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder);
108 105
109 drm_panel_disable(imxpd->panel); 106 drm_panel_disable(imxpd->panel);
110 drm_panel_unprepare(imxpd->panel); 107 drm_panel_unprepare(imxpd->panel);
111} 108}
112 109
110static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
111 struct drm_crtc_state *crtc_state,
112 struct drm_connector_state *conn_state)
113{
114 struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
115 struct drm_display_info *di = &conn_state->connector->display_info;
116 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
117
118 imx_crtc_state->bus_flags = di->bus_flags;
119 if (!imxpd->bus_format && di->num_bus_formats)
120 imx_crtc_state->bus_format = di->bus_formats[0];
121 else
122 imx_crtc_state->bus_format = imxpd->bus_format;
123 imx_crtc_state->di_hsync_pin = 2;
124 imx_crtc_state->di_vsync_pin = 3;
125
126 return 0;
127}
128
113static const struct drm_connector_funcs imx_pd_connector_funcs = { 129static const struct drm_connector_funcs imx_pd_connector_funcs = {
114 .dpms = drm_atomic_helper_connector_dpms, 130 .dpms = drm_atomic_helper_connector_dpms,
115 .fill_modes = drm_helper_probe_single_connector_modes, 131 .fill_modes = drm_helper_probe_single_connector_modes,
@@ -132,15 +148,16 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = {
132static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { 148static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
133 .enable = imx_pd_encoder_enable, 149 .enable = imx_pd_encoder_enable,
134 .disable = imx_pd_encoder_disable, 150 .disable = imx_pd_encoder_disable,
151 .atomic_check = imx_pd_encoder_atomic_check,
135}; 152};
136 153
137static int imx_pd_register(struct drm_device *drm, 154static int imx_pd_register(struct drm_device *drm,
138 struct imx_parallel_display *imxpd) 155 struct imx_parallel_display *imxpd)
139{ 156{
157 struct drm_encoder *encoder = &imxpd->encoder;
140 int ret; 158 int ret;
141 159
142 ret = imx_drm_encoder_parse_of(drm, &imxpd->imx_encoder.encoder, 160 ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
143 imxpd->dev->of_node);
144 if (ret) 161 if (ret)
145 return ret; 162 return ret;
146 163
@@ -151,10 +168,9 @@ static int imx_pd_register(struct drm_device *drm,
151 */ 168 */
152 imxpd->connector.dpms = DRM_MODE_DPMS_OFF; 169 imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
153 170
154 drm_encoder_helper_add(&imxpd->imx_encoder.encoder, 171 drm_encoder_helper_add(encoder, &imx_pd_encoder_helper_funcs);
155 &imx_pd_encoder_helper_funcs); 172 drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs,
156 drm_encoder_init(drm, &imxpd->imx_encoder.encoder, 173 DRM_MODE_ENCODER_NONE, NULL);
157 &imx_pd_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL);
158 174
159 drm_connector_helper_add(&imxpd->connector, 175 drm_connector_helper_add(&imxpd->connector,
160 &imx_pd_connector_helper_funcs); 176 &imx_pd_connector_helper_funcs);
@@ -164,8 +180,7 @@ static int imx_pd_register(struct drm_device *drm,
164 if (imxpd->panel) 180 if (imxpd->panel)
165 drm_panel_attach(imxpd->panel, &imxpd->connector); 181 drm_panel_attach(imxpd->panel, &imxpd->connector);
166 182
167 drm_mode_connector_attach_encoder(&imxpd->connector, 183 drm_mode_connector_attach_encoder(&imxpd->connector, encoder);
168 &imxpd->imx_encoder.encoder);
169 184
170 return 0; 185 return 0;
171} 186}
@@ -200,9 +215,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
200 else if (!strcmp(fmt, "lvds666")) 215 else if (!strcmp(fmt, "lvds666"))
201 bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; 216 bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
202 } 217 }
203 imxpd->imx_encoder.bus_format = bus_format; 218 imxpd->bus_format = bus_format;
204 imxpd->imx_encoder.di_hsync_pin = 2;
205 imxpd->imx_encoder.di_vsync_pin = 3;
206 219
207 /* port@1 is the output port */ 220 /* port@1 is the output port */
208 ep = of_graph_get_endpoint_by_regs(np, 1, -1); 221 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,
235{ 248{
236 struct imx_parallel_display *imxpd = dev_get_drvdata(dev); 249 struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
237 250
238 imxpd->imx_encoder.encoder.funcs->destroy(&imxpd->imx_encoder.encoder); 251 imxpd->encoder.funcs->destroy(&imxpd->encoder);
239 imxpd->connector.funcs->destroy(&imxpd->connector); 252 imxpd->connector.funcs->destroy(&imxpd->connector);
240 253
241 kfree(imxpd->edid); 254 kfree(imxpd->edid);