forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/omapdrm/dss/dpi.c
....@@ -1,62 +1,54 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2009 Nokia Corporation
34 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
45 *
56 * Some code and ideas taken from drivers/video/omap/ driver
67 * by Imre Deak.
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License version 2 as published by
10
- * the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
- * more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along with
18
- * this program. If not, see <http://www.gnu.org/licenses/>.
198 */
209
2110 #define DSS_SUBSYS_NAME "DPI"
2211
23
-#include <linux/kernel.h>
12
+#include <linux/clk.h>
2413 #include <linux/delay.h>
25
-#include <linux/export.h>
2614 #include <linux/err.h>
2715 #include <linux/errno.h>
16
+#include <linux/export.h>
17
+#include <linux/kernel.h>
18
+#include <linux/of.h>
2819 #include <linux/platform_device.h>
2920 #include <linux/regulator/consumer.h>
3021 #include <linux/string.h>
31
-#include <linux/of.h>
32
-#include <linux/clk.h>
3322 #include <linux/sys_soc.h>
3423
35
-#include "omapdss.h"
24
+#include <drm/drm_bridge.h>
25
+
3626 #include "dss.h"
27
+#include "omapdss.h"
3728
3829 struct dpi_data {
3930 struct platform_device *pdev;
4031 enum dss_model dss_model;
4132 struct dss_device *dss;
33
+ unsigned int id;
4234
4335 struct regulator *vdds_dsi_reg;
4436 enum dss_clk_source clk_src;
4537 struct dss_pll *pll;
4638
47
- struct mutex lock;
48
-
49
- struct videomode vm;
5039 struct dss_lcd_mgr_config mgr_config;
40
+ unsigned long pixelclock;
5141 int data_lines;
5242
5343 struct omap_dss_device output;
44
+ struct drm_bridge bridge;
5445 };
5546
56
-static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
57
-{
58
- return container_of(dssdev, struct dpi_data, output);
59
-}
47
+#define drm_bridge_to_dpi(bridge) container_of(bridge, struct dpi_data, bridge)
48
+
49
+/* -----------------------------------------------------------------------------
50
+ * Clock Handling and PLL
51
+ */
6052
6153 static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
6254 enum omap_channel channel)
....@@ -293,9 +285,7 @@
293285
294286
295287
296
-static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
297
- unsigned long pck_req, unsigned long *fck, int *lck_div,
298
- int *pck_div)
288
+static int dpi_set_pll_clk(struct dpi_data *dpi, unsigned long pck_req)
299289 {
300290 struct dpi_clk_calc_ctx ctx;
301291 int r;
....@@ -309,19 +299,15 @@
309299 if (r)
310300 return r;
311301
312
- dss_select_lcd_clk_source(dpi->dss, channel, dpi->clk_src);
302
+ dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
303
+ dpi->clk_src);
313304
314305 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
315
-
316
- *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
317
- *lck_div = ctx.dispc_cinfo.lck_div;
318
- *pck_div = ctx.dispc_cinfo.pck_div;
319306
320307 return 0;
321308 }
322309
323
-static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
324
- unsigned long *fck, int *lck_div, int *pck_div)
310
+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req)
325311 {
326312 struct dpi_clk_calc_ctx ctx;
327313 int r;
....@@ -337,42 +323,19 @@
337323
338324 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
339325
340
- *fck = ctx.fck;
341
- *lck_div = ctx.dispc_cinfo.lck_div;
342
- *pck_div = ctx.dispc_cinfo.pck_div;
343
-
344326 return 0;
345327 }
346328
347329 static int dpi_set_mode(struct dpi_data *dpi)
348330 {
349
- struct videomode *vm = &dpi->vm;
350
- int lck_div = 0, pck_div = 0;
351
- unsigned long fck = 0;
352
- unsigned long pck;
353
- int r = 0;
331
+ int r;
354332
355333 if (dpi->pll)
356
- r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel,
357
- vm->pixelclock, &fck, &lck_div, &pck_div);
334
+ r = dpi_set_pll_clk(dpi, dpi->pixelclock);
358335 else
359
- r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck,
360
- &lck_div, &pck_div);
361
- if (r)
362
- return r;
336
+ r = dpi_set_dispc_clk(dpi, dpi->pixelclock);
363337
364
- pck = fck / lck_div / pck_div;
365
-
366
- if (pck != vm->pixelclock) {
367
- DSSWARN("Could not find exact pixel clock. Requested %lu Hz, got %lu Hz\n",
368
- vm->pixelclock, pck);
369
-
370
- vm->pixelclock = pck;
371
- }
372
-
373
- dss_mgr_set_timings(&dpi->output, vm);
374
-
375
- return 0;
338
+ return r;
376339 }
377340
378341 static void dpi_config_lcd_manager(struct dpi_data *dpi)
....@@ -389,149 +352,19 @@
389352 dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
390353 }
391354
392
-static int dpi_display_enable(struct omap_dss_device *dssdev)
355
+static int dpi_clock_update(struct dpi_data *dpi, unsigned long *clock)
393356 {
394
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
395
- struct omap_dss_device *out = &dpi->output;
396
- int r;
397
-
398
- mutex_lock(&dpi->lock);
399
-
400
- if (!out->dispc_channel_connected) {
401
- DSSERR("failed to enable display: no output/manager\n");
402
- r = -ENODEV;
403
- goto err_no_out_mgr;
404
- }
405
-
406
- if (dpi->vdds_dsi_reg) {
407
- r = regulator_enable(dpi->vdds_dsi_reg);
408
- if (r)
409
- goto err_reg_enable;
410
- }
411
-
412
- r = dispc_runtime_get(dpi->dss->dispc);
413
- if (r)
414
- goto err_get_dispc;
415
-
416
- r = dss_dpi_select_source(dpi->dss, out->port_num, out->dispc_channel);
417
- if (r)
418
- goto err_src_sel;
419
-
420
- if (dpi->pll) {
421
- r = dss_pll_enable(dpi->pll);
422
- if (r)
423
- goto err_pll_init;
424
- }
425
-
426
- r = dpi_set_mode(dpi);
427
- if (r)
428
- goto err_set_mode;
429
-
430
- dpi_config_lcd_manager(dpi);
431
-
432
- mdelay(2);
433
-
434
- r = dss_mgr_enable(&dpi->output);
435
- if (r)
436
- goto err_mgr_enable;
437
-
438
- mutex_unlock(&dpi->lock);
439
-
440
- return 0;
441
-
442
-err_mgr_enable:
443
-err_set_mode:
444
- if (dpi->pll)
445
- dss_pll_disable(dpi->pll);
446
-err_pll_init:
447
-err_src_sel:
448
- dispc_runtime_put(dpi->dss->dispc);
449
-err_get_dispc:
450
- if (dpi->vdds_dsi_reg)
451
- regulator_disable(dpi->vdds_dsi_reg);
452
-err_reg_enable:
453
-err_no_out_mgr:
454
- mutex_unlock(&dpi->lock);
455
- return r;
456
-}
457
-
458
-static void dpi_display_disable(struct omap_dss_device *dssdev)
459
-{
460
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
461
-
462
- mutex_lock(&dpi->lock);
463
-
464
- dss_mgr_disable(&dpi->output);
465
-
466
- if (dpi->pll) {
467
- dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
468
- DSS_CLK_SRC_FCK);
469
- dss_pll_disable(dpi->pll);
470
- }
471
-
472
- dispc_runtime_put(dpi->dss->dispc);
473
-
474
- if (dpi->vdds_dsi_reg)
475
- regulator_disable(dpi->vdds_dsi_reg);
476
-
477
- mutex_unlock(&dpi->lock);
478
-}
479
-
480
-static void dpi_set_timings(struct omap_dss_device *dssdev,
481
- struct videomode *vm)
482
-{
483
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
484
-
485
- DSSDBG("dpi_set_timings\n");
486
-
487
- mutex_lock(&dpi->lock);
488
-
489
- dpi->vm = *vm;
490
-
491
- mutex_unlock(&dpi->lock);
492
-}
493
-
494
-static void dpi_get_timings(struct omap_dss_device *dssdev,
495
- struct videomode *vm)
496
-{
497
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
498
-
499
- mutex_lock(&dpi->lock);
500
-
501
- *vm = dpi->vm;
502
-
503
- mutex_unlock(&dpi->lock);
504
-}
505
-
506
-static int dpi_check_timings(struct omap_dss_device *dssdev,
507
- struct videomode *vm)
508
-{
509
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
510
- enum omap_channel channel = dpi->output.dispc_channel;
511357 int lck_div, pck_div;
512358 unsigned long fck;
513
- unsigned long pck;
514359 struct dpi_clk_calc_ctx ctx;
515
- bool ok;
516
-
517
- if (vm->hactive % 8 != 0)
518
- return -EINVAL;
519
-
520
- if (!dispc_mgr_timings_ok(dpi->dss->dispc, channel, vm))
521
- return -EINVAL;
522
-
523
- if (vm->pixelclock == 0)
524
- return -EINVAL;
525360
526361 if (dpi->pll) {
527
- ok = dpi_pll_clk_calc(dpi, vm->pixelclock, &ctx);
528
- if (!ok)
362
+ if (!dpi_pll_clk_calc(dpi, *clock, &ctx))
529363 return -EINVAL;
530364
531365 fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
532366 } else {
533
- ok = dpi_dss_clk_calc(dpi, vm->pixelclock, &ctx);
534
- if (!ok)
367
+ if (!dpi_dss_clk_calc(dpi, *clock, &ctx))
535368 return -EINVAL;
536369
537370 fck = ctx.fck;
....@@ -540,9 +373,7 @@
540373 lck_div = ctx.dispc_cinfo.lck_div;
541374 pck_div = ctx.dispc_cinfo.pck_div;
542375
543
- pck = fck / lck_div / pck_div;
544
-
545
- vm->pixelclock = pck;
376
+ *clock = fck / lck_div / pck_div;
546377
547378 return 0;
548379 }
....@@ -558,38 +389,6 @@
558389 return r;
559390
560391 dss_pll_disable(pll);
561
-
562
- return 0;
563
-}
564
-
565
-static const struct soc_device_attribute dpi_soc_devices[] = {
566
- { .machine = "OMAP3[456]*" },
567
- { .machine = "[AD]M37*" },
568
- { /* sentinel */ }
569
-};
570
-
571
-static int dpi_init_regulator(struct dpi_data *dpi)
572
-{
573
- struct regulator *vdds_dsi;
574
-
575
- /*
576
- * The DPI uses the DSI VDDS on OMAP34xx, OMAP35xx, OMAP36xx, AM37xx and
577
- * DM37xx only.
578
- */
579
- if (!soc_device_match(dpi_soc_devices))
580
- return 0;
581
-
582
- if (dpi->vdds_dsi_reg)
583
- return 0;
584
-
585
- vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
586
- if (IS_ERR(vdds_dsi)) {
587
- if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
588
- DSSERR("can't get VDDS_DSI regulator\n");
589
- return PTR_ERR(vdds_dsi);
590
- }
591
-
592
- dpi->vdds_dsi_reg = vdds_dsi;
593392
594393 return 0;
595394 }
....@@ -615,13 +414,175 @@
615414 dpi->pll = pll;
616415 }
617416
417
+/* -----------------------------------------------------------------------------
418
+ * DRM Bridge Operations
419
+ */
420
+
421
+static int dpi_bridge_attach(struct drm_bridge *bridge,
422
+ enum drm_bridge_attach_flags flags)
423
+{
424
+ struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
425
+
426
+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
427
+ return -EINVAL;
428
+
429
+ dpi_init_pll(dpi);
430
+
431
+ return drm_bridge_attach(bridge->encoder, dpi->output.next_bridge,
432
+ bridge, flags);
433
+}
434
+
435
+static enum drm_mode_status
436
+dpi_bridge_mode_valid(struct drm_bridge *bridge,
437
+ const struct drm_display_info *info,
438
+ const struct drm_display_mode *mode)
439
+{
440
+ struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
441
+ unsigned long clock = mode->clock * 1000;
442
+ int ret;
443
+
444
+ if (mode->hdisplay % 8 != 0)
445
+ return MODE_BAD_WIDTH;
446
+
447
+ if (mode->clock == 0)
448
+ return MODE_NOCLOCK;
449
+
450
+ ret = dpi_clock_update(dpi, &clock);
451
+ if (ret < 0)
452
+ return MODE_CLOCK_RANGE;
453
+
454
+ return MODE_OK;
455
+}
456
+
457
+static bool dpi_bridge_mode_fixup(struct drm_bridge *bridge,
458
+ const struct drm_display_mode *mode,
459
+ struct drm_display_mode *adjusted_mode)
460
+{
461
+ struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
462
+ unsigned long clock = mode->clock * 1000;
463
+ int ret;
464
+
465
+ ret = dpi_clock_update(dpi, &clock);
466
+ if (ret < 0)
467
+ return false;
468
+
469
+ adjusted_mode->clock = clock / 1000;
470
+
471
+ return true;
472
+}
473
+
474
+static void dpi_bridge_mode_set(struct drm_bridge *bridge,
475
+ const struct drm_display_mode *mode,
476
+ const struct drm_display_mode *adjusted_mode)
477
+{
478
+ struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
479
+
480
+ dpi->pixelclock = adjusted_mode->clock * 1000;
481
+}
482
+
483
+static void dpi_bridge_enable(struct drm_bridge *bridge)
484
+{
485
+ struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
486
+ int r;
487
+
488
+ if (dpi->vdds_dsi_reg) {
489
+ r = regulator_enable(dpi->vdds_dsi_reg);
490
+ if (r)
491
+ return;
492
+ }
493
+
494
+ r = dispc_runtime_get(dpi->dss->dispc);
495
+ if (r)
496
+ goto err_get_dispc;
497
+
498
+ r = dss_dpi_select_source(dpi->dss, dpi->id, dpi->output.dispc_channel);
499
+ if (r)
500
+ goto err_src_sel;
501
+
502
+ if (dpi->pll) {
503
+ r = dss_pll_enable(dpi->pll);
504
+ if (r)
505
+ goto err_pll_init;
506
+ }
507
+
508
+ r = dpi_set_mode(dpi);
509
+ if (r)
510
+ goto err_set_mode;
511
+
512
+ dpi_config_lcd_manager(dpi);
513
+
514
+ mdelay(2);
515
+
516
+ r = dss_mgr_enable(&dpi->output);
517
+ if (r)
518
+ goto err_mgr_enable;
519
+
520
+ return;
521
+
522
+err_mgr_enable:
523
+err_set_mode:
524
+ if (dpi->pll)
525
+ dss_pll_disable(dpi->pll);
526
+err_pll_init:
527
+err_src_sel:
528
+ dispc_runtime_put(dpi->dss->dispc);
529
+err_get_dispc:
530
+ if (dpi->vdds_dsi_reg)
531
+ regulator_disable(dpi->vdds_dsi_reg);
532
+}
533
+
534
+static void dpi_bridge_disable(struct drm_bridge *bridge)
535
+{
536
+ struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
537
+
538
+ dss_mgr_disable(&dpi->output);
539
+
540
+ if (dpi->pll) {
541
+ dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
542
+ DSS_CLK_SRC_FCK);
543
+ dss_pll_disable(dpi->pll);
544
+ }
545
+
546
+ dispc_runtime_put(dpi->dss->dispc);
547
+
548
+ if (dpi->vdds_dsi_reg)
549
+ regulator_disable(dpi->vdds_dsi_reg);
550
+}
551
+
552
+static const struct drm_bridge_funcs dpi_bridge_funcs = {
553
+ .attach = dpi_bridge_attach,
554
+ .mode_valid = dpi_bridge_mode_valid,
555
+ .mode_fixup = dpi_bridge_mode_fixup,
556
+ .mode_set = dpi_bridge_mode_set,
557
+ .enable = dpi_bridge_enable,
558
+ .disable = dpi_bridge_disable,
559
+};
560
+
561
+static void dpi_bridge_init(struct dpi_data *dpi)
562
+{
563
+ dpi->bridge.funcs = &dpi_bridge_funcs;
564
+ dpi->bridge.of_node = dpi->pdev->dev.of_node;
565
+ dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
566
+
567
+ drm_bridge_add(&dpi->bridge);
568
+}
569
+
570
+static void dpi_bridge_cleanup(struct dpi_data *dpi)
571
+{
572
+ drm_bridge_remove(&dpi->bridge);
573
+}
574
+
575
+/* -----------------------------------------------------------------------------
576
+ * Initialisation and Cleanup
577
+ */
578
+
618579 /*
619580 * Return a hardcoded channel for the DPI output. This should work for
620581 * current use cases, but this can be later expanded to either resolve
621582 * the channel in some more dynamic manner, or get the channel as a user
622583 * parameter.
623584 */
624
-static enum omap_channel dpi_get_channel(struct dpi_data *dpi, int port_num)
585
+static enum omap_channel dpi_get_channel(struct dpi_data *dpi)
625586 {
626587 switch (dpi->dss_model) {
627588 case DSS_MODEL_OMAP2:
....@@ -629,7 +590,7 @@
629590 return OMAP_DSS_CHANNEL_LCD;
630591
631592 case DSS_MODEL_DRA7:
632
- switch (port_num) {
593
+ switch (dpi->id) {
633594 case 2:
634595 return OMAP_DSS_CHANNEL_LCD3;
635596 case 1:
....@@ -651,69 +612,16 @@
651612 }
652613 }
653614
654
-static int dpi_connect(struct omap_dss_device *dssdev,
655
- struct omap_dss_device *dst)
656
-{
657
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
658
- int r;
659
-
660
- r = dpi_init_regulator(dpi);
661
- if (r)
662
- return r;
663
-
664
- dpi_init_pll(dpi);
665
-
666
- r = dss_mgr_connect(&dpi->output, dssdev);
667
- if (r)
668
- return r;
669
-
670
- r = omapdss_output_set_device(dssdev, dst);
671
- if (r) {
672
- DSSERR("failed to connect output to new device: %s\n",
673
- dst->name);
674
- dss_mgr_disconnect(&dpi->output, dssdev);
675
- return r;
676
- }
677
-
678
- return 0;
679
-}
680
-
681
-static void dpi_disconnect(struct omap_dss_device *dssdev,
682
- struct omap_dss_device *dst)
683
-{
684
- struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
685
-
686
- WARN_ON(dst != dssdev->dst);
687
-
688
- if (dst != dssdev->dst)
689
- return;
690
-
691
- omapdss_output_unset_device(dssdev);
692
-
693
- dss_mgr_disconnect(&dpi->output, dssdev);
694
-}
695
-
696
-static const struct omapdss_dpi_ops dpi_ops = {
697
- .connect = dpi_connect,
698
- .disconnect = dpi_disconnect,
699
-
700
- .enable = dpi_display_enable,
701
- .disable = dpi_display_disable,
702
-
703
- .check_timings = dpi_check_timings,
704
- .set_timings = dpi_set_timings,
705
- .get_timings = dpi_get_timings,
706
-};
707
-
708
-static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
615
+static int dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
709616 {
710617 struct omap_dss_device *out = &dpi->output;
618
+ u32 port_num = 0;
711619 int r;
712
- u32 port_num;
713620
714
- r = of_property_read_u32(port, "reg", &port_num);
715
- if (r)
716
- port_num = 0;
621
+ dpi_bridge_init(dpi);
622
+
623
+ of_property_read_u32(port, "reg", &port_num);
624
+ dpi->id = port_num <= 2 ? port_num : 0;
717625
718626 switch (port_num) {
719627 case 2:
....@@ -730,13 +638,20 @@
730638
731639 out->dev = &dpi->pdev->dev;
732640 out->id = OMAP_DSS_OUTPUT_DPI;
733
- out->output_type = OMAP_DISPLAY_TYPE_DPI;
734
- out->dispc_channel = dpi_get_channel(dpi, port_num);
735
- out->port_num = port_num;
736
- out->ops.dpi = &dpi_ops;
641
+ out->type = OMAP_DISPLAY_TYPE_DPI;
642
+ out->dispc_channel = dpi_get_channel(dpi);
643
+ out->of_port = port_num;
737644 out->owner = THIS_MODULE;
738645
739
- omapdss_register_output(out);
646
+ r = omapdss_device_init_output(out, &dpi->bridge);
647
+ if (r < 0) {
648
+ dpi_bridge_cleanup(dpi);
649
+ return r;
650
+ }
651
+
652
+ omapdss_device_register(out);
653
+
654
+ return 0;
740655 }
741656
742657 static void dpi_uninit_output_port(struct device_node *port)
....@@ -744,7 +659,43 @@
744659 struct dpi_data *dpi = port->data;
745660 struct omap_dss_device *out = &dpi->output;
746661
747
- omapdss_unregister_output(out);
662
+ omapdss_device_unregister(out);
663
+ omapdss_device_cleanup_output(out);
664
+
665
+ dpi_bridge_cleanup(dpi);
666
+}
667
+
668
+/* -----------------------------------------------------------------------------
669
+ * Initialisation and Cleanup
670
+ */
671
+
672
+static const struct soc_device_attribute dpi_soc_devices[] = {
673
+ { .machine = "OMAP3[456]*" },
674
+ { .machine = "[AD]M37*" },
675
+ { /* sentinel */ }
676
+};
677
+
678
+static int dpi_init_regulator(struct dpi_data *dpi)
679
+{
680
+ struct regulator *vdds_dsi;
681
+
682
+ /*
683
+ * The DPI uses the DSI VDDS on OMAP34xx, OMAP35xx, OMAP36xx, AM37xx and
684
+ * DM37xx only.
685
+ */
686
+ if (!soc_device_match(dpi_soc_devices))
687
+ return 0;
688
+
689
+ vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
690
+ if (IS_ERR(vdds_dsi)) {
691
+ if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
692
+ DSSERR("can't get VDDS_DSI regulator\n");
693
+ return PTR_ERR(vdds_dsi);
694
+ }
695
+
696
+ dpi->vdds_dsi_reg = vdds_dsi;
697
+
698
+ return 0;
748699 }
749700
750701 int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
....@@ -764,30 +715,24 @@
764715 return 0;
765716
766717 r = of_property_read_u32(ep, "data-lines", &datalines);
718
+ of_node_put(ep);
767719 if (r) {
768720 DSSERR("failed to parse datalines\n");
769
- goto err_datalines;
721
+ return r;
770722 }
771723
772724 dpi->data_lines = datalines;
773
-
774
- of_node_put(ep);
775725
776726 dpi->pdev = pdev;
777727 dpi->dss_model = dss_model;
778728 dpi->dss = dss;
779729 port->data = dpi;
780730
781
- mutex_init(&dpi->lock);
731
+ r = dpi_init_regulator(dpi);
732
+ if (r)
733
+ return r;
782734
783
- dpi_init_output_port(dpi, port);
784
-
785
- return 0;
786
-
787
-err_datalines:
788
- of_node_put(ep);
789
-
790
- return r;
735
+ return dpi_init_output_port(dpi, port);
791736 }
792737
793738 void dpi_uninit_port(struct device_node *port)