diff options
author | Dave Airlie <airlied@redhat.com> | 2015-04-13 03:28:57 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-04-13 03:28:57 -0400 |
commit | 1d2add28edd268a8290801ccf46b37f6d5239cdb (patch) | |
tree | 534e967b692f816434c00de0893e1089d425ae92 /drivers/gpu/drm/imx/imx-ldb.c | |
parent | bb1dc08c94ead1b98e750caf535422f79363c1a2 (diff) | |
parent | 5e501ed7253b369a8a9ec553c35238a3d6808f28 (diff) |
Merge tag 'imx-drm-next-2015-03-31' of git://git.pengutronix.de/git/pza/linux into drm-next
imx-drm changes to use media bus formats and LDB drm_panel support
- Add media bus formats needed by imx-drm
- Switch to use media bus formats to describe the pixel format
on the internal parallel bus between display interface and
encoders
- Some preparations for TV Output via TVEv2 on i.MX5
- Add drm_panel support to the i.MX LVDS driver, allow to
determine the bus pixel format from the panel descriptor.
* tag 'imx-drm-next-2015-03-31' of git://git.pengutronix.de/git/pza/linux:
drm/imx: imx-ldb: allow to determine bus format from the connected panel
drm/imx: imx-ldb: reset display clock input when disabling LVDS
drm/imx: imx-ldb: add drm_panel support
drm/imx: consolidate bus format variable names
drm/imx: switch to use media bus formats
Add RGB666_1X24_CPADHI media bus format
Add YUV8_1X24 media bus format
Add BGR888_1X24 and GBR888_1X24 media bus formats
Add LVDS RGB media bus formats
Add RGB444_1X12 and RGB565_1X16 media bus formats
drm/imx: ipuv3-crtc: Allow to divide DI clock from TVEv2
drm/imx: Add support for interlaced scanout
Diffstat (limited to 'drivers/gpu/drm/imx/imx-ldb.c')
-rw-r--r-- | drivers/gpu/drm/imx/imx-ldb.c | 196 |
1 files changed, 138 insertions, 58 deletions
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 2d6dc94e1e64..abacc8f67469 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
@@ -19,10 +19,11 @@ | |||
19 | #include <drm/drmP.h> | 19 | #include <drm/drmP.h> |
20 | #include <drm/drm_fb_helper.h> | 20 | #include <drm/drm_fb_helper.h> |
21 | #include <drm/drm_crtc_helper.h> | 21 | #include <drm/drm_crtc_helper.h> |
22 | #include <drm/drm_panel.h> | ||
22 | #include <linux/mfd/syscon.h> | 23 | #include <linux/mfd/syscon.h> |
23 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 24 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
24 | #include <linux/of_address.h> | ||
25 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
26 | #include <linux/of_graph.h> | ||
26 | #include <video/of_videomode.h> | 27 | #include <video/of_videomode.h> |
27 | #include <linux/regmap.h> | 28 | #include <linux/regmap.h> |
28 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
@@ -55,12 +56,14 @@ struct imx_ldb_channel { | |||
55 | struct imx_ldb *ldb; | 56 | struct imx_ldb *ldb; |
56 | struct drm_connector connector; | 57 | struct drm_connector connector; |
57 | struct drm_encoder encoder; | 58 | struct drm_encoder encoder; |
59 | struct drm_panel *panel; | ||
58 | struct device_node *child; | 60 | struct device_node *child; |
59 | int chno; | 61 | int chno; |
60 | void *edid; | 62 | void *edid; |
61 | int edid_len; | 63 | int edid_len; |
62 | struct drm_display_mode mode; | 64 | struct drm_display_mode mode; |
63 | int mode_valid; | 65 | int mode_valid; |
66 | int bus_format; | ||
64 | }; | 67 | }; |
65 | 68 | ||
66 | struct bus_mux { | 69 | struct bus_mux { |
@@ -75,6 +78,7 @@ struct imx_ldb { | |||
75 | struct imx_ldb_channel channel[2]; | 78 | struct imx_ldb_channel channel[2]; |
76 | struct clk *clk[2]; /* our own clock */ | 79 | struct clk *clk[2]; /* our own clock */ |
77 | struct clk *clk_sel[4]; /* parent of display clock */ | 80 | struct clk *clk_sel[4]; /* parent of display clock */ |
81 | struct clk *clk_parent[4]; /* original parent of clk_sel */ | ||
78 | struct clk *clk_pll[2]; /* upstream clock we can adjust */ | 82 | struct clk *clk_pll[2]; /* upstream clock we can adjust */ |
79 | u32 ldb_ctrl; | 83 | u32 ldb_ctrl; |
80 | const struct bus_mux *lvds_mux; | 84 | const struct bus_mux *lvds_mux; |
@@ -91,6 +95,17 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) | |||
91 | struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); | 95 | struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); |
92 | int num_modes = 0; | 96 | int num_modes = 0; |
93 | 97 | ||
98 | if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs && | ||
99 | imx_ldb_ch->panel->funcs->get_modes) { | ||
100 | struct drm_display_info *di = &connector->display_info; | ||
101 | |||
102 | num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); | ||
103 | if (!imx_ldb_ch->bus_format && di->num_bus_formats) | ||
104 | imx_ldb_ch->bus_format = di->bus_formats[0]; | ||
105 | if (num_modes > 0) | ||
106 | return num_modes; | ||
107 | } | ||
108 | |||
94 | if (imx_ldb_ch->edid) { | 109 | if (imx_ldb_ch->edid) { |
95 | drm_mode_connector_update_edid_property(connector, | 110 | drm_mode_connector_update_edid_property(connector, |
96 | imx_ldb_ch->edid); | 111 | imx_ldb_ch->edid); |
@@ -163,24 +178,36 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) | |||
163 | { | 178 | { |
164 | struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); | 179 | struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); |
165 | struct imx_ldb *ldb = imx_ldb_ch->ldb; | 180 | struct imx_ldb *ldb = imx_ldb_ch->ldb; |
166 | u32 pixel_fmt; | 181 | int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; |
182 | u32 bus_format; | ||
167 | 183 | ||
168 | switch (imx_ldb_ch->chno) { | 184 | switch (imx_ldb_ch->bus_format) { |
169 | case 0: | 185 | default: |
170 | pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ? | 186 | dev_warn(ldb->dev, |
171 | V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; | 187 | "could not determine data mapping, default to 18-bit \"spwg\"\n"); |
188 | /* fallthrough */ | ||
189 | case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: | ||
190 | bus_format = MEDIA_BUS_FMT_RGB666_1X18; | ||
172 | break; | 191 | break; |
173 | case 1: | 192 | case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: |
174 | pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ? | 193 | bus_format = MEDIA_BUS_FMT_RGB888_1X24; |
175 | V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; | 194 | if (imx_ldb_ch->chno == 0 || dual) |
195 | ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; | ||
196 | if (imx_ldb_ch->chno == 1 || dual) | ||
197 | ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; | ||
198 | break; | ||
199 | case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: | ||
200 | bus_format = MEDIA_BUS_FMT_RGB888_1X24; | ||
201 | if (imx_ldb_ch->chno == 0 || dual) | ||
202 | ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | | ||
203 | LDB_BIT_MAP_CH0_JEIDA; | ||
204 | if (imx_ldb_ch->chno == 1 || dual) | ||
205 | ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | | ||
206 | LDB_BIT_MAP_CH1_JEIDA; | ||
176 | break; | 207 | break; |
177 | default: | ||
178 | dev_err(ldb->dev, "unable to config di%d panel format\n", | ||
179 | imx_ldb_ch->chno); | ||
180 | pixel_fmt = V4L2_PIX_FMT_RGB24; | ||
181 | } | 208 | } |
182 | 209 | ||
183 | imx_drm_panel_format(encoder, pixel_fmt); | 210 | imx_drm_set_bus_format(encoder, bus_format); |
184 | } | 211 | } |
185 | 212 | ||
186 | static void imx_ldb_encoder_commit(struct drm_encoder *encoder) | 213 | static void imx_ldb_encoder_commit(struct drm_encoder *encoder) |
@@ -190,6 +217,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder) | |||
190 | int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; | 217 | int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; |
191 | int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder); | 218 | int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder); |
192 | 219 | ||
220 | drm_panel_prepare(imx_ldb_ch->panel); | ||
221 | |||
193 | if (dual) { | 222 | if (dual) { |
194 | clk_prepare_enable(ldb->clk[0]); | 223 | clk_prepare_enable(ldb->clk[0]); |
195 | clk_prepare_enable(ldb->clk[1]); | 224 | clk_prepare_enable(ldb->clk[1]); |
@@ -223,6 +252,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder) | |||
223 | } | 252 | } |
224 | 253 | ||
225 | regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); | 254 | regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); |
255 | |||
256 | drm_panel_enable(imx_ldb_ch->panel); | ||
226 | } | 257 | } |
227 | 258 | ||
228 | static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, | 259 | static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, |
@@ -274,6 +305,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) | |||
274 | { | 305 | { |
275 | struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); | 306 | struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); |
276 | struct imx_ldb *ldb = imx_ldb_ch->ldb; | 307 | struct imx_ldb *ldb = imx_ldb_ch->ldb; |
308 | int mux, ret; | ||
277 | 309 | ||
278 | /* | 310 | /* |
279 | * imx_ldb_encoder_disable is called by | 311 | * imx_ldb_encoder_disable is called by |
@@ -287,6 +319,8 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) | |||
287 | (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0) | 319 | (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0) |
288 | return; | 320 | return; |
289 | 321 | ||
322 | drm_panel_disable(imx_ldb_ch->panel); | ||
323 | |||
290 | if (imx_ldb_ch == &ldb->channel[0]) | 324 | if (imx_ldb_ch == &ldb->channel[0]) |
291 | ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; | 325 | ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; |
292 | else if (imx_ldb_ch == &ldb->channel[1]) | 326 | else if (imx_ldb_ch == &ldb->channel[1]) |
@@ -298,6 +332,30 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) | |||
298 | clk_disable_unprepare(ldb->clk[0]); | 332 | clk_disable_unprepare(ldb->clk[0]); |
299 | clk_disable_unprepare(ldb->clk[1]); | 333 | clk_disable_unprepare(ldb->clk[1]); |
300 | } | 334 | } |
335 | |||
336 | if (ldb->lvds_mux) { | ||
337 | const struct bus_mux *lvds_mux = NULL; | ||
338 | |||
339 | if (imx_ldb_ch == &ldb->channel[0]) | ||
340 | lvds_mux = &ldb->lvds_mux[0]; | ||
341 | else if (imx_ldb_ch == &ldb->channel[1]) | ||
342 | lvds_mux = &ldb->lvds_mux[1]; | ||
343 | |||
344 | regmap_read(ldb->regmap, lvds_mux->reg, &mux); | ||
345 | mux &= lvds_mux->mask; | ||
346 | mux >>= lvds_mux->shift; | ||
347 | } else { | ||
348 | mux = (imx_ldb_ch == &ldb->channel[0]) ? 0 : 1; | ||
349 | } | ||
350 | |||
351 | /* set display clock mux back to original input clock */ | ||
352 | ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk_parent[mux]); | ||
353 | if (ret) | ||
354 | dev_err(ldb->dev, | ||
355 | "unable to set di%d parent clock to original parent\n", | ||
356 | mux); | ||
357 | |||
358 | drm_panel_unprepare(imx_ldb_ch->panel); | ||
301 | } | 359 | } |
302 | 360 | ||
303 | static struct drm_connector_funcs imx_ldb_connector_funcs = { | 361 | static struct drm_connector_funcs imx_ldb_connector_funcs = { |
@@ -371,6 +429,9 @@ static int imx_ldb_register(struct drm_device *drm, | |||
371 | drm_connector_init(drm, &imx_ldb_ch->connector, | 429 | drm_connector_init(drm, &imx_ldb_ch->connector, |
372 | &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); | 430 | &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); |
373 | 431 | ||
432 | if (imx_ldb_ch->panel) | ||
433 | drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector); | ||
434 | |||
374 | drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, | 435 | drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, |
375 | &imx_ldb_ch->encoder); | 436 | &imx_ldb_ch->encoder); |
376 | 437 | ||
@@ -382,25 +443,39 @@ enum { | |||
382 | LVDS_BIT_MAP_JEIDA | 443 | LVDS_BIT_MAP_JEIDA |
383 | }; | 444 | }; |
384 | 445 | ||
385 | static const char * const imx_ldb_bit_mappings[] = { | 446 | struct imx_ldb_bit_mapping { |
386 | [LVDS_BIT_MAP_SPWG] = "spwg", | 447 | u32 bus_format; |
387 | [LVDS_BIT_MAP_JEIDA] = "jeida", | 448 | u32 datawidth; |
449 | const char * const mapping; | ||
450 | }; | ||
451 | |||
452 | static const struct imx_ldb_bit_mapping imx_ldb_bit_mappings[] = { | ||
453 | { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, "spwg" }, | ||
454 | { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, "spwg" }, | ||
455 | { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, "jeida" }, | ||
388 | }; | 456 | }; |
389 | 457 | ||
390 | static const int of_get_data_mapping(struct device_node *np) | 458 | static u32 of_get_bus_format(struct device *dev, struct device_node *np) |
391 | { | 459 | { |
392 | const char *bm; | 460 | const char *bm; |
461 | u32 datawidth = 0; | ||
393 | int ret, i; | 462 | int ret, i; |
394 | 463 | ||
395 | ret = of_property_read_string(np, "fsl,data-mapping", &bm); | 464 | ret = of_property_read_string(np, "fsl,data-mapping", &bm); |
396 | if (ret < 0) | 465 | if (ret < 0) |
397 | return ret; | 466 | return ret; |
398 | 467 | ||
399 | for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) | 468 | of_property_read_u32(np, "fsl,data-width", &datawidth); |
400 | if (!strcasecmp(bm, imx_ldb_bit_mappings[i])) | ||
401 | return i; | ||
402 | 469 | ||
403 | return -EINVAL; | 470 | for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) { |
471 | if (!strcasecmp(bm, imx_ldb_bit_mappings[i].mapping) && | ||
472 | datawidth == imx_ldb_bit_mappings[i].datawidth) | ||
473 | return imx_ldb_bit_mappings[i].bus_format; | ||
474 | } | ||
475 | |||
476 | dev_err(dev, "invalid data mapping: %d-bit \"%s\"\n", datawidth, bm); | ||
477 | |||
478 | return -ENOENT; | ||
404 | } | 479 | } |
405 | 480 | ||
406 | static struct bus_mux imx6q_lvds_mux[2] = { | 481 | static struct bus_mux imx6q_lvds_mux[2] = { |
@@ -437,8 +512,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
437 | struct device_node *child; | 512 | struct device_node *child; |
438 | const u8 *edidp; | 513 | const u8 *edidp; |
439 | struct imx_ldb *imx_ldb; | 514 | struct imx_ldb *imx_ldb; |
440 | int datawidth; | ||
441 | int mapping; | ||
442 | int dual; | 515 | int dual; |
443 | int ret; | 516 | int ret; |
444 | int i; | 517 | int i; |
@@ -479,12 +552,15 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
479 | imx_ldb->clk_sel[i] = NULL; | 552 | imx_ldb->clk_sel[i] = NULL; |
480 | break; | 553 | break; |
481 | } | 554 | } |
555 | |||
556 | imx_ldb->clk_parent[i] = clk_get_parent(imx_ldb->clk_sel[i]); | ||
482 | } | 557 | } |
483 | if (i == 0) | 558 | if (i == 0) |
484 | return ret; | 559 | return ret; |
485 | 560 | ||
486 | for_each_child_of_node(np, child) { | 561 | for_each_child_of_node(np, child) { |
487 | struct imx_ldb_channel *channel; | 562 | struct imx_ldb_channel *channel; |
563 | struct device_node *port; | ||
488 | 564 | ||
489 | ret = of_property_read_u32(child, "reg", &i); | 565 | ret = of_property_read_u32(child, "reg", &i); |
490 | if (ret || i < 0 || i > 1) | 566 | if (ret || i < 0 || i > 1) |
@@ -503,49 +579,53 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
503 | channel->chno = i; | 579 | channel->chno = i; |
504 | channel->child = child; | 580 | channel->child = child; |
505 | 581 | ||
582 | /* | ||
583 | * The output port is port@4 with an external 4-port mux or | ||
584 | * port@2 with the internal 2-port mux. | ||
585 | */ | ||
586 | port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2); | ||
587 | if (port) { | ||
588 | struct device_node *endpoint, *remote; | ||
589 | |||
590 | endpoint = of_get_child_by_name(port, "endpoint"); | ||
591 | if (endpoint) { | ||
592 | remote = of_graph_get_remote_port_parent(endpoint); | ||
593 | if (remote) | ||
594 | channel->panel = of_drm_find_panel(remote); | ||
595 | else | ||
596 | return -EPROBE_DEFER; | ||
597 | if (!channel->panel) { | ||
598 | dev_err(dev, "panel not found: %s\n", | ||
599 | remote->full_name); | ||
600 | return -EPROBE_DEFER; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | |||
506 | edidp = of_get_property(child, "edid", &channel->edid_len); | 605 | edidp = of_get_property(child, "edid", &channel->edid_len); |
507 | if (edidp) { | 606 | if (edidp) { |
508 | channel->edid = kmemdup(edidp, channel->edid_len, | 607 | channel->edid = kmemdup(edidp, channel->edid_len, |
509 | GFP_KERNEL); | 608 | GFP_KERNEL); |
510 | } else { | 609 | } else if (!channel->panel) { |
511 | ret = of_get_drm_display_mode(child, &channel->mode, 0); | 610 | ret = of_get_drm_display_mode(child, &channel->mode, 0); |
512 | if (!ret) | 611 | if (!ret) |
513 | channel->mode_valid = 1; | 612 | channel->mode_valid = 1; |
514 | } | 613 | } |
515 | 614 | ||
516 | ret = of_property_read_u32(child, "fsl,data-width", &datawidth); | 615 | channel->bus_format = of_get_bus_format(dev, child); |
517 | if (ret) | 616 | if (channel->bus_format == -EINVAL) { |
518 | datawidth = 0; | 617 | /* |
519 | else if (datawidth != 18 && datawidth != 24) | 618 | * If no bus format was specified in the device tree, |
520 | return -EINVAL; | 619 | * we can still get it from the connected panel later. |
521 | 620 | */ | |
522 | mapping = of_get_data_mapping(child); | 621 | if (channel->panel && channel->panel->funcs && |
523 | switch (mapping) { | 622 | channel->panel->funcs->get_modes) |
524 | case LVDS_BIT_MAP_SPWG: | 623 | channel->bus_format = 0; |
525 | if (datawidth == 24) { | 624 | } |
526 | if (i == 0 || dual) | 625 | if (channel->bus_format < 0) { |
527 | imx_ldb->ldb_ctrl |= | 626 | dev_err(dev, "could not determine data mapping: %d\n", |
528 | LDB_DATA_WIDTH_CH0_24; | 627 | channel->bus_format); |
529 | if (i == 1 || dual) | 628 | return channel->bus_format; |
530 | imx_ldb->ldb_ctrl |= | ||
531 | LDB_DATA_WIDTH_CH1_24; | ||
532 | } | ||
533 | break; | ||
534 | case LVDS_BIT_MAP_JEIDA: | ||
535 | if (datawidth == 18) { | ||
536 | dev_err(dev, "JEIDA standard only supported in 24 bit\n"); | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | if (i == 0 || dual) | ||
540 | imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | | ||
541 | LDB_BIT_MAP_CH0_JEIDA; | ||
542 | if (i == 1 || dual) | ||
543 | imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | | ||
544 | LDB_BIT_MAP_CH1_JEIDA; | ||
545 | break; | ||
546 | default: | ||
547 | dev_err(dev, "data mapping not specified or invalid\n"); | ||
548 | return -EINVAL; | ||
549 | } | 629 | } |
550 | 630 | ||
551 | ret = imx_ldb_register(drm, channel); | 631 | ret = imx_ldb_register(drm, channel); |