Skip to content

Commit b160245

Browse files
committed
Merge tag 'imx-drm-next-2016-06-01' of git://git.pengutronix.de/git/pza/linux into drm-fixes
imx-drm updates - add support for reading LVDS panel EDID over DDC - enable UYVY/VYUY support - add support for pixel clock polarity configuration - honor the native-mode DT property for LVDS - various fixes and cleanups * tag 'imx-drm-next-2016-06-01' of git://git.pengutronix.de/git/pza/linux: drm/imx: plane: Don't set plane->crtc in ipu_plane_update() drm/imx: ipuv3-plane: Constify ipu_plane_funcs drm/imx: imx-ldb: honor 'native-mode' property when selecting video mode from DT drm/imx: parallel-display: remove dead code drm/imx: use bus_flags for pixel clock polarity drm/imx: ipuv3-plane: enable UYVY and VYUY formats drm/imx: parallel-display: use of_graph_get_endpoint_by_regs helper drm/imx: imx-ldb: use of_graph_get_endpoint_by_regs helper dt-bindings: imx: ldb: Add ddc-i2c-bus property drm/imx: imx-ldb: Add DDC support
2 parents 35962ea + 151787b commit b160245

File tree

8 files changed

+94
-66
lines changed

8 files changed

+94
-66
lines changed

Documentation/devicetree/bindings/display/imx/ldb.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Required properties:
6262
display-timings are used instead.
6363

6464
Optional properties (required if display-timings are used):
65+
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
6566
- display-timings : A node that describes the display timings as defined in
6667
Documentation/devicetree/bindings/display/display-timing.txt.
6768
- fsl,data-mapping : should be "spwg" or "jeida"

drivers/gpu/drm/imx/imx-drm-core.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
9797
return NULL;
9898
}
9999

100-
int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
101-
int hsync_pin, int vsync_pin)
100+
int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
101+
int hsync_pin, int vsync_pin, u32 bus_flags)
102102
{
103103
struct imx_drm_crtc_helper_funcs *helper;
104104
struct imx_drm_crtc *imx_crtc;
@@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
110110
helper = &imx_crtc->imx_drm_helper_funcs;
111111
if (helper->set_interface_pix_fmt)
112112
return helper->set_interface_pix_fmt(encoder->crtc,
113-
bus_format, hsync_pin, vsync_pin);
113+
bus_format, hsync_pin, vsync_pin,
114+
bus_flags);
114115
return 0;
115116
}
116-
EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins);
117+
EXPORT_SYMBOL_GPL(imx_drm_set_bus_config);
117118

118119
int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
119120
{
120-
return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3);
121+
return imx_drm_set_bus_config(encoder, bus_format, 2, 3,
122+
DRM_BUS_FLAG_DE_HIGH |
123+
DRM_BUS_FLAG_PIXDATA_NEGEDGE);
121124
}
122125
EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
123126

drivers/gpu/drm/imx/imx-drm.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs {
1919
int (*enable_vblank)(struct drm_crtc *crtc);
2020
void (*disable_vblank)(struct drm_crtc *crtc);
2121
int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
22-
u32 bus_format, int hsync_pin, int vsync_pin);
22+
u32 bus_format, int hsync_pin, int vsync_pin,
23+
u32 bus_flags);
2324
const struct drm_crtc_helper_funcs *crtc_helper_funcs;
2425
const struct drm_crtc_funcs *crtc_funcs;
2526
};
@@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm);
4142

4243
struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
4344

44-
int imx_drm_set_bus_format_pins(struct drm_encoder *encoder,
45-
u32 bus_format, int hsync_pin, int vsync_pin);
45+
int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
46+
int hsync_pin, int vsync_pin, u32 bus_flags);
4647
int imx_drm_set_bus_format(struct drm_encoder *encoder,
4748
u32 bus_format);
4849

drivers/gpu/drm/imx/imx-ldb.c

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
2626
#include <linux/of_device.h>
2727
#include <linux/of_graph.h>
28+
#include <video/of_display_timing.h>
2829
#include <video/of_videomode.h>
2930
#include <linux/regmap.h>
3031
#include <linux/videodev2.h>
@@ -59,6 +60,7 @@ struct imx_ldb_channel {
5960
struct drm_encoder encoder;
6061
struct drm_panel *panel;
6162
struct device_node *child;
63+
struct i2c_adapter *ddc;
6264
int chno;
6365
void *edid;
6466
int edid_len;
@@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
107109
return num_modes;
108110
}
109111

112+
if (!imx_ldb_ch->edid && imx_ldb_ch->ddc)
113+
imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc);
114+
110115
if (imx_ldb_ch->edid) {
111116
drm_mode_connector_update_edid_property(connector,
112117
imx_ldb_ch->edid);
@@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
553558

554559
for_each_child_of_node(np, child) {
555560
struct imx_ldb_channel *channel;
556-
struct device_node *port;
561+
struct device_node *ddc_node;
562+
struct device_node *ep;
557563

558564
ret = of_property_read_u32(child, "reg", &i);
559565
if (ret || i < 0 || i > 1)
@@ -576,33 +582,54 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
576582
* The output port is port@4 with an external 4-port mux or
577583
* port@2 with the internal 2-port mux.
578584
*/
579-
port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2);
580-
if (port) {
581-
struct device_node *endpoint, *remote;
582-
583-
endpoint = of_get_child_by_name(port, "endpoint");
584-
if (endpoint) {
585-
remote = of_graph_get_remote_port_parent(endpoint);
586-
if (remote)
587-
channel->panel = of_drm_find_panel(remote);
588-
else
589-
return -EPROBE_DEFER;
590-
if (!channel->panel) {
591-
dev_err(dev, "panel not found: %s\n",
592-
remote->full_name);
593-
return -EPROBE_DEFER;
594-
}
585+
ep = of_graph_get_endpoint_by_regs(child,
586+
imx_ldb->lvds_mux ? 4 : 2,
587+
-1);
588+
if (ep) {
589+
struct device_node *remote;
590+
591+
remote = of_graph_get_remote_port_parent(ep);
592+
of_node_put(ep);
593+
if (remote)
594+
channel->panel = of_drm_find_panel(remote);
595+
else
596+
return -EPROBE_DEFER;
597+
of_node_put(remote);
598+
if (!channel->panel) {
599+
dev_err(dev, "panel not found: %s\n",
600+
remote->full_name);
601+
return -EPROBE_DEFER;
595602
}
596603
}
597604

598-
edidp = of_get_property(child, "edid", &channel->edid_len);
599-
if (edidp) {
600-
channel->edid = kmemdup(edidp, channel->edid_len,
601-
GFP_KERNEL);
602-
} else if (!channel->panel) {
603-
ret = of_get_drm_display_mode(child, &channel->mode, 0);
604-
if (!ret)
605-
channel->mode_valid = 1;
605+
ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
606+
if (ddc_node) {
607+
channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
608+
of_node_put(ddc_node);
609+
if (!channel->ddc) {
610+
dev_warn(dev, "failed to get ddc i2c adapter\n");
611+
return -EPROBE_DEFER;
612+
}
613+
}
614+
615+
if (!channel->ddc) {
616+
/* if no DDC available, fallback to hardcoded EDID */
617+
dev_dbg(dev, "no ddc available\n");
618+
619+
edidp = of_get_property(child, "edid",
620+
&channel->edid_len);
621+
if (edidp) {
622+
channel->edid = kmemdup(edidp,
623+
channel->edid_len,
624+
GFP_KERNEL);
625+
} else if (!channel->panel) {
626+
/* fallback to display-timings node */
627+
ret = of_get_drm_display_mode(child,
628+
&channel->mode,
629+
OF_USE_NATIVE_MODE);
630+
if (!ret)
631+
channel->mode_valid = 1;
632+
}
606633
}
607634

608635
channel->bus_format = of_get_bus_format(dev, child);
@@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
647674
channel->encoder.funcs->destroy(&channel->encoder);
648675

649676
kfree(channel->edid);
677+
i2c_put_adapter(channel->ddc);
650678
}
651679
}
652680

drivers/gpu/drm/imx/imx-tve.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
294294

295295
switch (tve->mode) {
296296
case TVE_MODE_VGA:
297-
imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24,
298-
tve->hsync_pin, tve->vsync_pin);
297+
imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24,
298+
tve->hsync_pin, tve->vsync_pin,
299+
DRM_BUS_FLAG_DE_HIGH |
300+
DRM_BUS_FLAG_PIXDATA_NEGEDGE);
299301
break;
300302
case TVE_MODE_TVOUT:
301303
imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);

drivers/gpu/drm/imx/ipuv3-crtc.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct ipu_crtc {
6666
struct ipu_flip_work *flip_work;
6767
int irq;
6868
u32 bus_format;
69+
u32 bus_flags;
6970
int di_hsync_pin;
7071
int di_vsync_pin;
7172
};
@@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
271272
else
272273
sig_cfg.clkflags = 0;
273274

274-
sig_cfg.enable_pol = 1;
275-
sig_cfg.clk_pol = 0;
275+
sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW);
276+
/* Default to driving pixel data on negative clock edges */
277+
sig_cfg.clk_pol = !!(ipu_crtc->bus_flags &
278+
DRM_BUS_FLAG_PIXDATA_POSEDGE);
276279
sig_cfg.bus_format = ipu_crtc->bus_format;
277280
sig_cfg.v_to_h_sync = 0;
278281
sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
@@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
396399
}
397400

398401
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
399-
u32 bus_format, int hsync_pin, int vsync_pin)
402+
u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags)
400403
{
401404
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
402405

403406
ipu_crtc->bus_format = bus_format;
407+
ipu_crtc->bus_flags = bus_flags;
404408
ipu_crtc->di_hsync_pin = hsync_pin;
405409
ipu_crtc->di_vsync_pin = vsync_pin;
406410

drivers/gpu/drm/imx/ipuv3-plane.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = {
3838
DRM_FORMAT_RGBX8888,
3939
DRM_FORMAT_BGRA8888,
4040
DRM_FORMAT_BGRA8888,
41+
DRM_FORMAT_UYVY,
42+
DRM_FORMAT_VYUY,
4143
DRM_FORMAT_YUYV,
4244
DRM_FORMAT_YVYU,
4345
DRM_FORMAT_YUV420,
@@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
428430
if (crtc != plane->crtc)
429431
dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n",
430432
plane->crtc, crtc);
431-
plane->crtc = crtc;
432433

433434
if (!ipu_plane->enabled)
434435
ipu_plane_enable(ipu_plane);
@@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *plane)
461462
kfree(ipu_plane);
462463
}
463464

464-
static struct drm_plane_funcs ipu_plane_funcs = {
465+
static const struct drm_plane_funcs ipu_plane_funcs = {
465466
.update_plane = ipu_update_plane,
466467
.disable_plane = ipu_disable_plane,
467468
.destroy = ipu_plane_destroy,

drivers/gpu/drm/imx/parallel-display.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ struct imx_parallel_display {
3535
void *edid;
3636
int edid_len;
3737
u32 bus_format;
38-
int mode_valid;
3938
struct drm_display_mode mode;
4039
struct drm_panel *panel;
4140
};
@@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
6867
num_modes = drm_add_edid_modes(connector, imxpd->edid);
6968
}
7069

71-
if (imxpd->mode_valid) {
72-
struct drm_display_mode *mode = drm_mode_create(connector->dev);
73-
74-
if (!mode)
75-
return -EINVAL;
76-
drm_mode_copy(mode, &imxpd->mode);
77-
mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
78-
drm_mode_probed_add(connector, mode);
79-
num_modes++;
80-
}
81-
8270
if (np) {
8371
struct drm_display_mode *mode = drm_mode_create(connector->dev);
8472

@@ -115,8 +103,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
115103
static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
116104
{
117105
struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
118-
119-
imx_drm_set_bus_format(encoder, imxpd->bus_format);
106+
imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3,
107+
imxpd->connector.display_info.bus_flags);
120108
}
121109

122110
static void imx_pd_encoder_commit(struct drm_encoder *encoder)
@@ -203,7 +191,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
203191
{
204192
struct drm_device *drm = data;
205193
struct device_node *np = dev->of_node;
206-
struct device_node *port;
194+
struct device_node *ep;
207195
const u8 *edidp;
208196
struct imx_parallel_display *imxpd;
209197
int ret;
@@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
230218
}
231219

232220
/* port@1 is the output port */
233-
port = of_graph_get_port_by_id(np, 1);
234-
if (port) {
235-
struct device_node *endpoint, *remote;
236-
237-
endpoint = of_get_child_by_name(port, "endpoint");
238-
if (endpoint) {
239-
remote = of_graph_get_remote_port_parent(endpoint);
240-
if (remote)
241-
imxpd->panel = of_drm_find_panel(remote);
242-
if (!imxpd->panel)
243-
return -EPROBE_DEFER;
221+
ep = of_graph_get_endpoint_by_regs(np, 1, -1);
222+
if (ep) {
223+
struct device_node *remote;
224+
225+
remote = of_graph_get_remote_port_parent(ep);
226+
of_node_put(ep);
227+
if (remote) {
228+
imxpd->panel = of_drm_find_panel(remote);
229+
of_node_put(remote);
244230
}
231+
if (!imxpd->panel)
232+
return -EPROBE_DEFER;
245233
}
246234

247235
imxpd->dev = dev;

0 commit comments

Comments
 (0)