hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
....@@ -9,21 +9,25 @@
99 #include <linux/clk.h>
1010 #include <linux/component.h>
1111 #include <linux/crc-ccitt.h>
12
+#include <linux/module.h>
1213 #include <linux/of_address.h>
13
-#include <linux/pm_runtime.h>
14
+#include <linux/phy/phy-mipi-dphy.h>
15
+#include <linux/phy/phy.h>
16
+#include <linux/platform_device.h>
1417 #include <linux/regmap.h>
18
+#include <linux/regulator/consumer.h>
1519 #include <linux/reset.h>
1620 #include <linux/slab.h>
1721
18
-#include <linux/phy/phy.h>
19
-
20
-#include <drm/drmP.h>
2122 #include <drm/drm_atomic_helper.h>
22
-#include <drm/drm_crtc_helper.h>
2323 #include <drm/drm_mipi_dsi.h>
2424 #include <drm/drm_panel.h>
25
+#include <drm/drm_print.h>
26
+#include <drm/drm_probe_helper.h>
27
+#include <drm/drm_simple_kms_helper.h>
2528
26
-#include "sun4i_drv.h"
29
+#include "sun4i_crtc.h"
30
+#include "sun4i_tcon.h"
2731 #include "sun6i_mipi_dsi.h"
2832
2933 #include <video/mipi_display.h>
....@@ -32,6 +36,8 @@
3236 #define SUN6I_DSI_CTL_EN BIT(0)
3337
3438 #define SUN6I_DSI_BASIC_CTL_REG 0x00c
39
+#define SUN6I_DSI_BASIC_CTL_TRAIL_INV(n) (((n) & 0xf) << 4)
40
+#define SUN6I_DSI_BASIC_CTL_TRAIL_FILL BIT(3)
3541 #define SUN6I_DSI_BASIC_CTL_HBP_DIS BIT(2)
3642 #define SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS BIT(1)
3743 #define SUN6I_DSI_BASIC_CTL_VIDEO_BURST BIT(0)
....@@ -151,6 +157,8 @@
151157 #define SUN6I_DSI_DEBUG_DATA_REG 0x2f8
152158
153159 #define SUN6I_DSI_CMD_TX_REG(n) (0x300 + (n) * 0x04)
160
+
161
+#define SUN6I_DSI_SYNC_POINT 40
154162
155163 enum sun6i_dsi_start_inst {
156164 DSI_START_LPRX,
....@@ -357,12 +365,53 @@
357365 static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
358366 struct drm_display_mode *mode)
359367 {
360
- u16 delay = mode->vtotal - (mode->vsync_end - mode->vdisplay) + 1;
368
+ u16 delay = mode->vtotal - (mode->vsync_start - mode->vdisplay) + 1;
361369
362370 if (delay > mode->vtotal)
363371 delay = delay % mode->vtotal;
364372
365373 return max_t(u16, delay, 1);
374
+}
375
+
376
+static u16 sun6i_dsi_get_line_num(struct sun6i_dsi *dsi,
377
+ struct drm_display_mode *mode)
378
+{
379
+ struct mipi_dsi_device *device = dsi->device;
380
+ unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
381
+
382
+ return mode->htotal * Bpp / device->lanes;
383
+}
384
+
385
+static u16 sun6i_dsi_get_drq_edge0(struct sun6i_dsi *dsi,
386
+ struct drm_display_mode *mode,
387
+ u16 line_num, u16 edge1)
388
+{
389
+ u16 edge0 = edge1;
390
+
391
+ edge0 += (mode->hdisplay + 40) * SUN6I_DSI_TCON_DIV / 8;
392
+
393
+ if (edge0 > line_num)
394
+ return edge0 - line_num;
395
+
396
+ return 1;
397
+}
398
+
399
+static u16 sun6i_dsi_get_drq_edge1(struct sun6i_dsi *dsi,
400
+ struct drm_display_mode *mode,
401
+ u16 line_num)
402
+{
403
+ struct mipi_dsi_device *device = dsi->device;
404
+ unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
405
+ unsigned int hbp = mode->htotal - mode->hsync_end;
406
+ u16 edge1;
407
+
408
+ edge1 = SUN6I_DSI_SYNC_POINT;
409
+ edge1 += (mode->hdisplay + hbp + 20) * Bpp / device->lanes;
410
+
411
+ if (edge1 > line_num)
412
+ return line_num;
413
+
414
+ return edge1;
366415 }
367416
368417 static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
....@@ -371,9 +420,25 @@
371420 struct mipi_dsi_device *device = dsi->device;
372421 u32 val = 0;
373422
374
- if ((mode->hsync_end - mode->hdisplay) > 20) {
423
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
424
+ u16 line_num = sun6i_dsi_get_line_num(dsi, mode);
425
+ u16 edge0, edge1;
426
+
427
+ edge1 = sun6i_dsi_get_drq_edge1(dsi, mode, line_num);
428
+ edge0 = sun6i_dsi_get_drq_edge0(dsi, mode, line_num, edge1);
429
+
430
+ regmap_write(dsi->regs, SUN6I_DSI_BURST_DRQ_REG,
431
+ SUN6I_DSI_BURST_DRQ_EDGE0(edge0) |
432
+ SUN6I_DSI_BURST_DRQ_EDGE1(edge1));
433
+
434
+ regmap_write(dsi->regs, SUN6I_DSI_BURST_LINE_REG,
435
+ SUN6I_DSI_BURST_LINE_NUM(line_num) |
436
+ SUN6I_DSI_BURST_LINE_SYNC_POINT(SUN6I_DSI_SYNC_POINT));
437
+
438
+ val = SUN6I_DSI_TCON_DRQ_ENABLE_MODE;
439
+ } else if ((mode->hsync_start - mode->hdisplay) > 20) {
375440 /* Maaaaaagic */
376
- u16 drq = (mode->hsync_end - mode->hdisplay) - 20;
441
+ u16 drq = (mode->hsync_start - mode->hdisplay) - 20;
377442
378443 drq *= mipi_dsi_pixel_format_to_bpp(device->format);
379444 drq /= 32;
....@@ -388,7 +453,19 @@
388453 static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi,
389454 struct drm_display_mode *mode)
390455 {
456
+ struct mipi_dsi_device *device = dsi->device;
391457 u16 delay = 50 - 1;
458
+
459
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
460
+ u32 hsync_porch = (mode->htotal - mode->hdisplay) * 150;
461
+
462
+ delay = (hsync_porch / ((mode->clock / 1000) * 8));
463
+ delay -= 50;
464
+ }
465
+
466
+ regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_SEL_REG,
467
+ 2 << (4 * DSI_INST_ID_LP11) |
468
+ 3 << (4 * DSI_INST_ID_DLY));
392469
393470 regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_NUM_REG(0),
394471 SUN6I_DSI_INST_LOOP_NUM_N0(50 - 1) |
....@@ -454,50 +531,70 @@
454531 struct drm_display_mode *mode)
455532 {
456533 struct mipi_dsi_device *device = dsi->device;
457
- unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
458
- u16 hbp, hfp, hsa, hblk, vblk;
534
+ int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
535
+ u16 hbp = 0, hfp = 0, hsa = 0, hblk = 0, vblk = 0;
536
+ u32 basic_ctl = 0;
459537 size_t bytes;
460538 u8 *buffer;
461539
462540 /* Do all timing calculations up front to allocate buffer space */
463541
464
- /*
465
- * A sync period is composed of a blanking packet (4 bytes +
466
- * payload + 2 bytes) and a sync event packet (4 bytes). Its
467
- * minimal size is therefore 10 bytes
468
- */
542
+ if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
543
+ hblk = mode->hdisplay * Bpp;
544
+ basic_ctl = SUN6I_DSI_BASIC_CTL_VIDEO_BURST |
545
+ SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS |
546
+ SUN6I_DSI_BASIC_CTL_HBP_DIS;
547
+
548
+ if (device->lanes == 4)
549
+ basic_ctl |= SUN6I_DSI_BASIC_CTL_TRAIL_FILL |
550
+ SUN6I_DSI_BASIC_CTL_TRAIL_INV(0xc);
551
+ } else {
552
+ /*
553
+ * A sync period is composed of a blanking packet (4
554
+ * bytes + payload + 2 bytes) and a sync event packet
555
+ * (4 bytes). Its minimal size is therefore 10 bytes
556
+ */
469557 #define HSA_PACKET_OVERHEAD 10
470
- hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
471
- (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
558
+ hsa = max(HSA_PACKET_OVERHEAD,
559
+ (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
472560
473
- /*
474
- * The backporch is set using a blanking packet (4 bytes +
475
- * payload + 2 bytes). Its minimal size is therefore 6 bytes
476
- */
561
+ /*
562
+ * The backporch is set using a blanking packet (4
563
+ * bytes + payload + 2 bytes). Its minimal size is
564
+ * therefore 6 bytes
565
+ */
477566 #define HBP_PACKET_OVERHEAD 6
478
- hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
479
- (mode->hsync_start - mode->hdisplay) * Bpp - HBP_PACKET_OVERHEAD);
567
+ hbp = max(HBP_PACKET_OVERHEAD,
568
+ (mode->htotal - mode->hsync_end) * Bpp - HBP_PACKET_OVERHEAD);
480569
481
- /*
482
- * The frontporch is set using a blanking packet (4 bytes +
483
- * payload + 2 bytes). Its minimal size is therefore 6 bytes
484
- */
485
-#define HFP_PACKET_OVERHEAD 6
486
- hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
487
- (mode->htotal - mode->hsync_end) * Bpp - HFP_PACKET_OVERHEAD);
570
+ /*
571
+ * The frontporch is set using a sync event (4 bytes)
572
+ * and two blanking packets (each one is 4 bytes +
573
+ * payload + 2 bytes). Its minimal size is therefore
574
+ * 16 bytes
575
+ */
576
+#define HFP_PACKET_OVERHEAD 16
577
+ hfp = max(HFP_PACKET_OVERHEAD,
578
+ (mode->hsync_start - mode->hdisplay) * Bpp - HFP_PACKET_OVERHEAD);
488579
489
- /*
490
- * hblk seems to be the line + porches length.
491
- */
492
- hblk = mode->htotal * Bpp - hsa;
580
+ /*
581
+ * The blanking is set using a sync event (4 bytes)
582
+ * and a blanking packet (4 bytes + payload + 2
583
+ * bytes). Its minimal size is therefore 10 bytes.
584
+ */
585
+#define HBLK_PACKET_OVERHEAD 10
586
+ hblk = max(HBLK_PACKET_OVERHEAD,
587
+ (mode->htotal - (mode->hsync_end - mode->hsync_start)) * Bpp -
588
+ HBLK_PACKET_OVERHEAD);
493589
494
- /*
495
- * And I'm not entirely sure what vblk is about. The driver in
496
- * Allwinner BSP is using a rather convoluted calculation
497
- * there only for 4 lanes. However, using 0 (the !4 lanes
498
- * case) even with a 4 lanes screen seems to work...
499
- */
500
- vblk = 0;
590
+ /*
591
+ * And I'm not entirely sure what vblk is about. The driver in
592
+ * Allwinner BSP is using a rather convoluted calculation
593
+ * there only for 4 lanes. However, using 0 (the !4 lanes
594
+ * case) even with a 4 lanes screen seems to work...
595
+ */
596
+ vblk = 0;
597
+ }
501598
502599 /* How many bytes do we need to send all payloads? */
503600 bytes = max_t(size_t, max(max(hfp, hblk), max(hsa, hbp)), vblk);
....@@ -505,7 +602,7 @@
505602 if (WARN_ON(!buffer))
506603 return;
507604
508
- regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, 0);
605
+ regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, basic_ctl);
509606
510607 regmap_write(dsi->regs, SUN6I_DSI_SYNC_HSS_REG,
511608 sun6i_dsi_build_sync_pkt(MIPI_DSI_H_SYNC_START,
....@@ -530,8 +627,8 @@
530627 regmap_write(dsi->regs, SUN6I_DSI_BASIC_SIZE0_REG,
531628 SUN6I_DSI_BASIC_SIZE0_VSA(mode->vsync_end -
532629 mode->vsync_start) |
533
- SUN6I_DSI_BASIC_SIZE0_VBP(mode->vsync_start -
534
- mode->vdisplay));
630
+ SUN6I_DSI_BASIC_SIZE0_VBP(mode->vtotal -
631
+ mode->vsync_end));
535632
536633 regmap_write(dsi->regs, SUN6I_DSI_BASIC_SIZE1_REG,
537634 SUN6I_DSI_BASIC_SIZE1_VACT(mode->vdisplay) |
....@@ -621,11 +718,34 @@
621718 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
622719 struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
623720 struct mipi_dsi_device *device = dsi->device;
721
+ union phy_configure_opts opts = { };
722
+ struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
624723 u16 delay;
724
+ int err;
625725
626726 DRM_DEBUG_DRIVER("Enabling DSI output\n");
627727
628
- pm_runtime_get_sync(dsi->dev);
728
+ err = regulator_enable(dsi->regulator);
729
+ if (err)
730
+ dev_warn(dsi->dev, "failed to enable VCC-DSI supply: %d\n", err);
731
+
732
+ reset_control_deassert(dsi->reset);
733
+ clk_prepare_enable(dsi->mod_clk);
734
+
735
+ /*
736
+ * Enable the DSI block.
737
+ */
738
+ regmap_write(dsi->regs, SUN6I_DSI_CTL_REG, SUN6I_DSI_CTL_EN);
739
+
740
+ regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG,
741
+ SUN6I_DSI_BASIC_CTL0_ECC_EN | SUN6I_DSI_BASIC_CTL0_CRC_EN);
742
+
743
+ regmap_write(dsi->regs, SUN6I_DSI_TRANS_START_REG, 10);
744
+ regmap_write(dsi->regs, SUN6I_DSI_TRANS_ZERO_REG, 0);
745
+
746
+ sun6i_dsi_inst_init(dsi, dsi->device);
747
+
748
+ regmap_write(dsi->regs, SUN6I_DSI_DEBUG_DATA_REG, 0xff);
629749
630750 delay = sun6i_dsi_get_video_start_delay(dsi, mode);
631751 regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL1_REG,
....@@ -639,10 +759,17 @@
639759 sun6i_dsi_setup_format(dsi, mode);
640760 sun6i_dsi_setup_timings(dsi, mode);
641761
642
- sun6i_dphy_init(dsi->dphy, device->lanes);
643
- sun6i_dphy_power_on(dsi->dphy, device->lanes);
762
+ phy_init(dsi->dphy);
644763
645
- if (!IS_ERR(dsi->panel))
764
+ phy_mipi_dphy_get_default_config(mode->clock * 1000,
765
+ mipi_dsi_pixel_format_to_bpp(device->format),
766
+ device->lanes, cfg);
767
+
768
+ phy_set_mode(dsi->dphy, PHY_MODE_MIPI_DPHY);
769
+ phy_configure(dsi->dphy, &opts);
770
+ phy_power_on(dsi->dphy);
771
+
772
+ if (dsi->panel)
646773 drm_panel_prepare(dsi->panel);
647774
648775 /*
....@@ -657,7 +784,7 @@
657784 * ordering on the panels I've tested it with, so I guess this
658785 * will do for now, until that IP is better understood.
659786 */
660
- if (!IS_ERR(dsi->panel))
787
+ if (dsi->panel)
661788 drm_panel_enable(dsi->panel);
662789
663790 sun6i_dsi_start(dsi, DSI_START_HSC);
....@@ -673,32 +800,37 @@
673800
674801 DRM_DEBUG_DRIVER("Disabling DSI output\n");
675802
676
- if (!IS_ERR(dsi->panel)) {
803
+ if (dsi->panel) {
677804 drm_panel_disable(dsi->panel);
678805 drm_panel_unprepare(dsi->panel);
679806 }
680807
681
- sun6i_dphy_power_off(dsi->dphy);
682
- sun6i_dphy_exit(dsi->dphy);
808
+ phy_power_off(dsi->dphy);
809
+ phy_exit(dsi->dphy);
683810
684
- pm_runtime_put(dsi->dev);
811
+ clk_disable_unprepare(dsi->mod_clk);
812
+ reset_control_assert(dsi->reset);
813
+ regulator_disable(dsi->regulator);
685814 }
686815
687816 static int sun6i_dsi_get_modes(struct drm_connector *connector)
688817 {
689818 struct sun6i_dsi *dsi = connector_to_sun6i_dsi(connector);
690819
691
- return drm_panel_get_modes(dsi->panel);
820
+ return drm_panel_get_modes(dsi->panel, connector);
692821 }
693822
694
-static struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = {
823
+static const struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = {
695824 .get_modes = sun6i_dsi_get_modes,
696825 };
697826
698827 static enum drm_connector_status
699828 sun6i_dsi_connector_detect(struct drm_connector *connector, bool force)
700829 {
701
- return connector_status_connected;
830
+ struct sun6i_dsi *dsi = connector_to_sun6i_dsi(connector);
831
+
832
+ return dsi->panel ? connector_status_connected :
833
+ connector_status_disconnected;
702834 }
703835
704836 static const struct drm_connector_funcs sun6i_dsi_connector_funcs = {
....@@ -715,18 +847,14 @@
715847 .enable = sun6i_dsi_encoder_enable,
716848 };
717849
718
-static const struct drm_encoder_funcs sun6i_dsi_enc_funcs = {
719
- .destroy = drm_encoder_cleanup,
720
-};
721
-
722850 static u32 sun6i_dsi_dcs_build_pkt_hdr(struct sun6i_dsi *dsi,
723851 const struct mipi_dsi_msg *msg)
724852 {
725853 u32 pkt = msg->type;
726854
727855 if (msg->type == MIPI_DSI_DCS_LONG_WRITE) {
728
- pkt |= ((msg->tx_len + 1) & 0xffff) << 8;
729
- pkt |= (((msg->tx_len + 1) >> 8) & 0xffff) << 16;
856
+ pkt |= ((msg->tx_len) & 0xffff) << 8;
857
+ pkt |= (((msg->tx_len) >> 8) & 0xffff) << 16;
730858 } else {
731859 pkt |= (((u8 *)msg->tx_buf)[0] << 8);
732860 if (msg->tx_len > 1)
....@@ -835,11 +963,17 @@
835963 struct mipi_dsi_device *device)
836964 {
837965 struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
966
+ struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);
838967
968
+ if (IS_ERR(panel))
969
+ return PTR_ERR(panel);
970
+ if (!dsi->drm || !dsi->drm->registered)
971
+ return -EPROBE_DEFER;
972
+
973
+ dsi->panel = panel;
839974 dsi->device = device;
840
- dsi->panel = of_drm_find_panel(device->dev.of_node);
841
- if (IS_ERR(dsi->panel))
842
- return PTR_ERR(dsi->panel);
975
+
976
+ drm_kms_helper_hotplug_event(dsi->drm);
843977
844978 dev_info(host->dev, "Attached device %s\n", device->name);
845979
....@@ -853,6 +987,8 @@
853987
854988 dsi->panel = NULL;
855989 dsi->device = NULL;
990
+
991
+ drm_kms_helper_hotplug_event(dsi->drm);
856992
857993 return 0;
858994 }
....@@ -875,6 +1011,7 @@
8751011 switch (msg->type) {
8761012 case MIPI_DSI_DCS_SHORT_WRITE:
8771013 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
1014
+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
8781015 ret = sun6i_dsi_dcs_write_short(dsi, msg);
8791016 break;
8801017
....@@ -887,6 +1024,7 @@
8871024 ret = sun6i_dsi_dcs_read(dsi, msg);
8881025 break;
8891026 }
1027
+ fallthrough;
8901028
8911029 default:
8921030 ret = -EINVAL;
....@@ -913,22 +1051,13 @@
9131051 void *data)
9141052 {
9151053 struct drm_device *drm = data;
916
- struct sun4i_drv *drv = drm->dev_private;
9171054 struct sun6i_dsi *dsi = dev_get_drvdata(dev);
9181055 int ret;
9191056
920
- if (!dsi->panel)
921
- return -EPROBE_DEFER;
922
-
923
- dsi->drv = drv;
924
-
9251057 drm_encoder_helper_add(&dsi->encoder,
9261058 &sun6i_dsi_enc_helper_funcs);
927
- ret = drm_encoder_init(drm,
928
- &dsi->encoder,
929
- &sun6i_dsi_enc_funcs,
930
- DRM_MODE_ENCODER_DSI,
931
- NULL);
1059
+ ret = drm_simple_encoder_init(drm, &dsi->encoder,
1060
+ DRM_MODE_ENCODER_DSI);
9321061 if (ret) {
9331062 dev_err(dsi->dev, "Couldn't initialise the DSI encoder\n");
9341063 return ret;
....@@ -947,7 +1076,8 @@
9471076 }
9481077
9491078 drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
950
- drm_panel_attach(dsi->panel, &dsi->connector);
1079
+
1080
+ dsi->drm = drm;
9511081
9521082 return 0;
9531083
....@@ -961,7 +1091,7 @@
9611091 {
9621092 struct sun6i_dsi *dsi = dev_get_drvdata(dev);
9631093
964
- drm_panel_detach(dsi->panel);
1094
+ dsi->drm = NULL;
9651095 }
9661096
9671097 static const struct component_ops sun6i_dsi_ops = {
....@@ -972,7 +1102,7 @@
9721102 static int sun6i_dsi_probe(struct platform_device *pdev)
9731103 {
9741104 struct device *dev = &pdev->dev;
975
- struct device_node *dphy_node;
1105
+ const char *bus_clk_name = NULL;
9761106 struct sun6i_dsi *dsi;
9771107 struct resource *res;
9781108 void __iomem *base;
....@@ -986,6 +1116,10 @@
9861116 dsi->host.ops = &sun6i_dsi_host_ops;
9871117 dsi->host.dev = dev;
9881118
1119
+ if (of_device_is_compatible(dev->of_node,
1120
+ "allwinner,sun6i-a31-mipi-dsi"))
1121
+ bus_clk_name = "bus";
1122
+
9891123 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
9901124 base = devm_ioremap_resource(dev, res);
9911125 if (IS_ERR(base)) {
....@@ -993,11 +1127,10 @@
9931127 return PTR_ERR(base);
9941128 }
9951129
996
- dsi->regs = devm_regmap_init_mmio_clk(dev, "bus", base,
997
- &sun6i_dsi_regmap_config);
998
- if (IS_ERR(dsi->regs)) {
999
- dev_err(dev, "Couldn't create the DSI encoder regmap\n");
1000
- return PTR_ERR(dsi->regs);
1130
+ dsi->regulator = devm_regulator_get(dev, "vcc-dsi");
1131
+ if (IS_ERR(dsi->regulator)) {
1132
+ dev_err(dev, "Couldn't get VCC-DSI supply\n");
1133
+ return PTR_ERR(dsi->regulator);
10011134 }
10021135
10031136 dsi->reset = devm_reset_control_get_shared(dev, NULL);
....@@ -1006,10 +1139,30 @@
10061139 return PTR_ERR(dsi->reset);
10071140 }
10081141
1009
- dsi->mod_clk = devm_clk_get(dev, "mod");
1010
- if (IS_ERR(dsi->mod_clk)) {
1011
- dev_err(dev, "Couldn't get the DSI mod clock\n");
1012
- return PTR_ERR(dsi->mod_clk);
1142
+ dsi->regs = devm_regmap_init_mmio(dev, base, &sun6i_dsi_regmap_config);
1143
+ if (IS_ERR(dsi->regs)) {
1144
+ dev_err(dev, "Couldn't init regmap\n");
1145
+ return PTR_ERR(dsi->regs);
1146
+ }
1147
+
1148
+ dsi->bus_clk = devm_clk_get(dev, bus_clk_name);
1149
+ if (IS_ERR(dsi->bus_clk)) {
1150
+ dev_err(dev, "Couldn't get the DSI bus clock\n");
1151
+ return PTR_ERR(dsi->bus_clk);
1152
+ }
1153
+
1154
+ ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk);
1155
+ if (ret)
1156
+ return ret;
1157
+
1158
+ if (of_device_is_compatible(dev->of_node,
1159
+ "allwinner,sun6i-a31-mipi-dsi")) {
1160
+ dsi->mod_clk = devm_clk_get(dev, "mod");
1161
+ if (IS_ERR(dsi->mod_clk)) {
1162
+ dev_err(dev, "Couldn't get the DSI mod clock\n");
1163
+ ret = PTR_ERR(dsi->mod_clk);
1164
+ goto err_attach_clk;
1165
+ }
10131166 }
10141167
10151168 /*
....@@ -1018,20 +1171,17 @@
10181171 */
10191172 clk_set_rate_exclusive(dsi->mod_clk, 297000000);
10201173
1021
- dphy_node = of_parse_phandle(dev->of_node, "phys", 0);
1022
- ret = sun6i_dphy_probe(dsi, dphy_node);
1023
- of_node_put(dphy_node);
1024
- if (ret) {
1174
+ dsi->dphy = devm_phy_get(dev, "dphy");
1175
+ if (IS_ERR(dsi->dphy)) {
10251176 dev_err(dev, "Couldn't get the MIPI D-PHY\n");
1177
+ ret = PTR_ERR(dsi->dphy);
10261178 goto err_unprotect_clk;
10271179 }
1028
-
1029
- pm_runtime_enable(dev);
10301180
10311181 ret = mipi_dsi_host_register(&dsi->host);
10321182 if (ret) {
10331183 dev_err(dev, "Couldn't register MIPI-DSI host\n");
1034
- goto err_remove_phy;
1184
+ goto err_unprotect_clk;
10351185 }
10361186
10371187 ret = component_add(&pdev->dev, &sun6i_dsi_ops);
....@@ -1044,11 +1194,11 @@
10441194
10451195 err_remove_dsi_host:
10461196 mipi_dsi_host_unregister(&dsi->host);
1047
-err_remove_phy:
1048
- pm_runtime_disable(dev);
1049
- sun6i_dphy_remove(dsi);
10501197 err_unprotect_clk:
10511198 clk_rate_exclusive_put(dsi->mod_clk);
1199
+err_attach_clk:
1200
+ if (!IS_ERR(dsi->bus_clk))
1201
+ regmap_mmio_detach_clk(dsi->regs);
10521202 return ret;
10531203 }
10541204
....@@ -1059,60 +1209,17 @@
10591209
10601210 component_del(&pdev->dev, &sun6i_dsi_ops);
10611211 mipi_dsi_host_unregister(&dsi->host);
1062
- pm_runtime_disable(dev);
1063
- sun6i_dphy_remove(dsi);
10641212 clk_rate_exclusive_put(dsi->mod_clk);
10651213
1066
- return 0;
1067
-}
1068
-
1069
-static int __maybe_unused sun6i_dsi_runtime_resume(struct device *dev)
1070
-{
1071
- struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1072
-
1073
- reset_control_deassert(dsi->reset);
1074
- clk_prepare_enable(dsi->mod_clk);
1075
-
1076
- /*
1077
- * Enable the DSI block.
1078
- *
1079
- * Some part of it can only be done once we get a number of
1080
- * lanes, see sun6i_dsi_inst_init
1081
- */
1082
- regmap_write(dsi->regs, SUN6I_DSI_CTL_REG, SUN6I_DSI_CTL_EN);
1083
-
1084
- regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG,
1085
- SUN6I_DSI_BASIC_CTL0_ECC_EN | SUN6I_DSI_BASIC_CTL0_CRC_EN);
1086
-
1087
- regmap_write(dsi->regs, SUN6I_DSI_TRANS_START_REG, 10);
1088
- regmap_write(dsi->regs, SUN6I_DSI_TRANS_ZERO_REG, 0);
1089
-
1090
- if (dsi->device)
1091
- sun6i_dsi_inst_init(dsi, dsi->device);
1092
-
1093
- regmap_write(dsi->regs, SUN6I_DSI_DEBUG_DATA_REG, 0xff);
1214
+ if (!IS_ERR(dsi->bus_clk))
1215
+ regmap_mmio_detach_clk(dsi->regs);
10941216
10951217 return 0;
10961218 }
1097
-
1098
-static int __maybe_unused sun6i_dsi_runtime_suspend(struct device *dev)
1099
-{
1100
- struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1101
-
1102
- clk_disable_unprepare(dsi->mod_clk);
1103
- reset_control_assert(dsi->reset);
1104
-
1105
- return 0;
1106
-}
1107
-
1108
-static const struct dev_pm_ops sun6i_dsi_pm_ops = {
1109
- SET_RUNTIME_PM_OPS(sun6i_dsi_runtime_suspend,
1110
- sun6i_dsi_runtime_resume,
1111
- NULL)
1112
-};
11131219
11141220 static const struct of_device_id sun6i_dsi_of_table[] = {
11151221 { .compatible = "allwinner,sun6i-a31-mipi-dsi" },
1222
+ { .compatible = "allwinner,sun50i-a64-mipi-dsi" },
11161223 { }
11171224 };
11181225 MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table);
....@@ -1123,7 +1230,6 @@
11231230 .driver = {
11241231 .name = "sun6i-mipi-dsi",
11251232 .of_match_table = sun6i_dsi_of_table,
1126
- .pm = &sun6i_dsi_pm_ops,
11271233 },
11281234 };
11291235 module_platform_driver(sun6i_dsi_platform_driver);