1359 lines
42 KiB
Diff
1359 lines
42 KiB
Diff
From 6f34ef4b6d1647582a1e81f7b5c0f07fd18f5caa Mon Sep 17 00:00:00 2001
|
|||
|
|
From: rui.zhang1 <rui.zhang1@unisoc.com>
|
||
|
|
Date: Wed, 29 Jul 2026 20:40:52 +0800
|
||
|
|
Subject: [PATCH] Bug #3548825 - bananapi(2c10) lcd ili9881c porting
|
||
|
|
|
||
|
|
[root cause ]: na
|
||
|
|
[changes ]:na
|
||
|
|
[side effects]:na
|
||
|
|
[self test ]:na
|
||
|
|
[download normally]:na
|
||
|
|
[power on/off normally]:na
|
||
|
|
[do common repository/branch inspection]:na
|
||
|
|
[is there dependence]:na
|
||
|
|
[confirm dependent commit]:na
|
||
|
|
[board]:na
|
||
|
|
[test case]:na
|
||
|
|
[reviewers]:na
|
||
|
|
|
||
|
|
commit_template_version:v1
|
||
|
|
|
||
|
|
Change-Id: I74a27a7a5571d87a45855a32d40bf8c9186a9a02
|
||
|
|
---
|
||
|
|
|
||
|
|
diff --git a/arch/arm64/boot/dts/sprd/lcd/lcd_ili9881c_truly_mipi_wxga.dtsi b/arch/arm64/boot/dts/sprd/lcd/lcd_ili9881c_truly_mipi_wxga.dtsi
|
||
|
|
new file mode 100755
|
||
|
|
index 0000000..23eb2a8
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/arch/arm64/boot/dts/sprd/lcd/lcd_ili9881c_truly_mipi_wxga.dtsi
|
||
|
|
@@ -0,0 +1,261 @@
|
||
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
||
|
|
+/*
|
||
|
|
+ * Unisoc ili9881c Truly LCD config DTS file
|
||
|
|
+ *
|
||
|
|
+ * Copyright (C) 2021, Unisoc Inc.
|
||
|
|
+ */
|
||
|
|
+/ {
|
||
|
|
+ fragment {
|
||
|
|
+ target-path = "/";
|
||
|
|
+ __overlay__ {
|
||
|
|
+ lcds {
|
||
|
|
+ lcd_ili9881c_truly_mipi_wxga: lcd_ili9881c_truly_mipi_wxga {
|
||
|
|
+
|
||
|
|
+ sprd,dsi-work-mode = <1>;
|
||
|
|
+ sprd,dsi-lane-number = <2>;
|
||
|
|
+ sprd,dsi-color-format = "rgb888";
|
||
|
|
+
|
||
|
|
+ sprd,phy-bit-clock = <921600>;
|
||
|
|
+ sprd,phy-escape-clock = <20000>;
|
||
|
|
+
|
||
|
|
+ sprd,width-mm = <68>;
|
||
|
|
+ sprd,height-mm = <121>;
|
||
|
|
+
|
||
|
|
+ sprd,esd-check-enable = <0>;
|
||
|
|
+ sprd,esd-check-mode = <3>;
|
||
|
|
+ sprd,esd-check-period = <1000>;
|
||
|
|
+ sprd,esd-check-register = <0x0A>;
|
||
|
|
+ sprd,esd-check-value = <0x9C>;
|
||
|
|
+
|
||
|
|
+ sprd,mipi-port = <1>;
|
||
|
|
+
|
||
|
|
+ sprd,reset-on-sequence = <1 5>, <0 5>, <1 20>;
|
||
|
|
+ sprd,reset-off-sequence = <0 20>;
|
||
|
|
+
|
||
|
|
+ sprd,initial-command = [
|
||
|
|
+ 39 00 00 04 FF 98 81 03
|
||
|
|
+ 39 00 00 04 FF 98 81 03
|
||
|
|
+ 23 00 00 02 01 00
|
||
|
|
+ 23 00 00 02 02 00
|
||
|
|
+ 23 00 00 02 03 73
|
||
|
|
+ 23 00 00 02 04 13
|
||
|
|
+ 23 00 00 02 05 00
|
||
|
|
+ 23 00 00 02 06 0A
|
||
|
|
+ 23 00 00 02 07 05
|
||
|
|
+ 23 00 00 02 08 00
|
||
|
|
+ 23 00 00 02 09 28
|
||
|
|
+ 23 00 00 02 0a 00
|
||
|
|
+ 23 00 00 02 0b 00
|
||
|
|
+ 23 00 00 02 0c 00
|
||
|
|
+ 23 00 00 02 0d 28
|
||
|
|
+ 23 00 00 02 0e 00
|
||
|
|
+ 23 00 00 02 0f 28
|
||
|
|
+ 23 00 00 02 10 28
|
||
|
|
+ 23 00 00 02 11 00
|
||
|
|
+ 23 00 00 02 12 00
|
||
|
|
+ 23 00 00 02 13 00
|
||
|
|
+ 23 00 00 02 14 00
|
||
|
|
+ 23 00 00 02 15 00
|
||
|
|
+ 23 00 00 02 16 00
|
||
|
|
+ 23 00 00 02 17 00
|
||
|
|
+ 23 00 00 02 18 00
|
||
|
|
+ 23 00 00 02 19 00
|
||
|
|
+ 23 00 00 02 1a 00
|
||
|
|
+ 23 00 00 02 1b 00
|
||
|
|
+ 23 00 00 02 1c 00
|
||
|
|
+ 23 00 00 02 1d 00
|
||
|
|
+ 23 00 00 02 1e 40
|
||
|
|
+ 23 00 00 02 1f 80
|
||
|
|
+ 23 00 00 02 20 06
|
||
|
|
+ 23 00 00 02 21 01
|
||
|
|
+ 23 00 00 02 22 00
|
||
|
|
+ 23 00 00 02 23 00
|
||
|
|
+ 23 00 00 02 24 00
|
||
|
|
+ 23 00 00 02 25 00
|
||
|
|
+ 23 00 00 02 26 00
|
||
|
|
+ 23 00 00 02 27 00
|
||
|
|
+ 23 00 00 02 28 33
|
||
|
|
+ 23 00 00 02 29 33
|
||
|
|
+ 23 00 00 02 2a 00
|
||
|
|
+ 23 00 00 02 2b 00
|
||
|
|
+ 23 00 00 02 2c 04
|
||
|
|
+ 23 00 00 02 2d 04
|
||
|
|
+ 23 00 00 02 2e 05
|
||
|
|
+ 23 00 00 02 2f 05
|
||
|
|
+ 23 00 00 02 30 00
|
||
|
|
+ 23 00 00 02 31 00
|
||
|
|
+ 23 00 00 02 32 31
|
||
|
|
+ 23 00 00 02 33 00
|
||
|
|
+ 23 00 00 02 34 00
|
||
|
|
+ 23 00 00 02 35 0A
|
||
|
|
+ 23 00 00 02 36 00
|
||
|
|
+ 23 00 00 02 37 08
|
||
|
|
+ 23 00 00 02 38 00
|
||
|
|
+ 23 00 00 02 39 00
|
||
|
|
+ 23 00 00 02 3a 00
|
||
|
|
+ 23 00 00 02 3b 00
|
||
|
|
+ 23 00 00 02 3c 00
|
||
|
|
+ 23 00 00 02 3d 00
|
||
|
|
+ 23 00 00 02 3e 00
|
||
|
|
+ 23 00 00 02 3f 00
|
||
|
|
+ 23 00 00 02 40 00
|
||
|
|
+ 23 00 00 02 41 00
|
||
|
|
+ 23 00 00 02 42 00
|
||
|
|
+ 23 00 00 02 43 08
|
||
|
|
+ 23 00 00 02 44 00
|
||
|
|
+ 23 00 00 02 50 01
|
||
|
|
+ 23 00 00 02 51 23
|
||
|
|
+ 23 00 00 02 52 44
|
||
|
|
+ 23 00 00 02 53 67
|
||
|
|
+ 23 00 00 02 54 89
|
||
|
|
+ 23 00 00 02 55 ab
|
||
|
|
+ 23 00 00 02 56 01
|
||
|
|
+ 23 00 00 02 57 23
|
||
|
|
+ 23 00 00 02 58 45
|
||
|
|
+ 23 00 00 02 59 67
|
||
|
|
+ 23 00 00 02 5a 89
|
||
|
|
+ 23 00 00 02 5b ab
|
||
|
|
+ 23 00 00 02 5c cd
|
||
|
|
+ 23 00 00 02 5d ef
|
||
|
|
+ 23 00 00 02 5e 11
|
||
|
|
+ 23 00 00 02 5f 02
|
||
|
|
+ 23 00 00 02 60 08
|
||
|
|
+ 23 00 00 02 61 0E
|
||
|
|
+ 23 00 00 02 62 0F
|
||
|
|
+ 23 00 00 02 63 0C
|
||
|
|
+ 23 00 00 02 64 0D
|
||
|
|
+ 23 00 00 02 65 17
|
||
|
|
+ 23 00 00 02 66 01
|
||
|
|
+ 23 00 00 02 67 01
|
||
|
|
+ 23 00 00 02 68 02
|
||
|
|
+ 23 00 00 02 69 02
|
||
|
|
+ 23 00 00 02 6a 00
|
||
|
|
+ 23 00 00 02 6b 00
|
||
|
|
+ 23 00 00 02 6c 02
|
||
|
|
+ 23 00 00 02 6d 02
|
||
|
|
+ 23 00 00 02 6e 16
|
||
|
|
+ 23 00 00 02 6f 16
|
||
|
|
+ 23 00 00 02 70 06
|
||
|
|
+ 23 00 00 02 71 06
|
||
|
|
+ 23 00 00 02 72 07
|
||
|
|
+ 23 00 00 02 73 07
|
||
|
|
+ 23 00 00 02 74 02
|
||
|
|
+ 23 00 00 02 75 02
|
||
|
|
+ 23 00 00 02 76 08
|
||
|
|
+ 23 00 00 02 77 0E
|
||
|
|
+ 23 00 00 02 78 0F
|
||
|
|
+ 23 00 00 02 79 0C
|
||
|
|
+ 23 00 00 02 7a 0D
|
||
|
|
+ 23 00 00 02 7b 17
|
||
|
|
+ 23 00 00 02 7c 01
|
||
|
|
+ 23 00 00 02 7d 01
|
||
|
|
+ 23 00 00 02 7e 02
|
||
|
|
+ 23 00 00 02 7f 02
|
||
|
|
+ 23 00 00 02 80 00
|
||
|
|
+ 23 00 00 02 81 00
|
||
|
|
+ 23 00 00 02 82 02
|
||
|
|
+ 23 00 00 02 83 02
|
||
|
|
+ 23 00 00 02 84 16
|
||
|
|
+ 23 00 00 02 85 16
|
||
|
|
+ 23 00 00 02 86 06
|
||
|
|
+ 23 00 00 02 87 06
|
||
|
|
+ 23 00 00 02 88 07
|
||
|
|
+ 23 00 00 02 89 07
|
||
|
|
+ 23 00 00 02 8A 02
|
||
|
|
+ 39 00 00 04 FF 98 81 04
|
||
|
|
+ 23 00 00 02 6E 1A
|
||
|
|
+ 23 00 00 02 6F 37
|
||
|
|
+ 23 00 00 02 3B C0
|
||
|
|
+ 23 00 00 02 8D 1F
|
||
|
|
+ 23 00 00 02 87 BA
|
||
|
|
+ 23 00 00 02 B2 D1
|
||
|
|
+ 23 00 00 02 88 0B
|
||
|
|
+ 23 00 00 02 38 01
|
||
|
|
+ 23 00 00 02 39 00
|
||
|
|
+ 23 00 00 02 B5 02
|
||
|
|
+ 23 00 00 02 31 25
|
||
|
|
+ 23 00 00 02 3B 98
|
||
|
|
+ 39 00 00 04 FF 98 81 01
|
||
|
|
+ 23 00 00 02 22 0A
|
||
|
|
+ 23 00 00 02 31 00
|
||
|
|
+ 23 00 00 02 53 62
|
||
|
|
+ 23 00 00 02 55 7B
|
||
|
|
+ 23 00 00 02 50 9E
|
||
|
|
+ 23 00 00 02 51 99
|
||
|
|
+ 23 00 00 02 60 06
|
||
|
|
+ 23 00 00 02 62 20
|
||
|
|
+ 23 00 00 02 B7 03
|
||
|
|
+ 23 00 00 02 A0 00
|
||
|
|
+ 23 00 00 02 A1 17
|
||
|
|
+ 23 00 00 02 A2 26
|
||
|
|
+ 23 00 00 02 A3 13
|
||
|
|
+ 23 00 00 02 A4 16
|
||
|
|
+ 23 00 00 02 A5 29
|
||
|
|
+ 23 00 00 02 A6 1E
|
||
|
|
+ 23 00 00 02 A7 1F
|
||
|
|
+ 23 00 00 02 A8 8B
|
||
|
|
+ 23 00 00 02 A9 1D
|
||
|
|
+ 23 00 00 02 AA 2A
|
||
|
|
+ 23 00 00 02 AB 7B
|
||
|
|
+ 23 00 00 02 AC 1A
|
||
|
|
+ 23 00 00 02 AD 19
|
||
|
|
+ 23 00 00 02 AE 4E
|
||
|
|
+ 23 00 00 02 AF 24
|
||
|
|
+ 23 00 00 02 B0 29
|
||
|
|
+ 23 00 00 02 B1 4F
|
||
|
|
+ 23 00 00 02 B2 5C
|
||
|
|
+ 23 00 00 02 B3 23
|
||
|
|
+ 23 00 00 02 C0 00
|
||
|
|
+ 23 00 00 02 C1 17
|
||
|
|
+ 23 00 00 02 C2 26
|
||
|
|
+ 23 00 00 02 C3 13
|
||
|
|
+ 23 00 00 02 C4 16
|
||
|
|
+ 23 00 00 02 C5 29
|
||
|
|
+ 23 00 00 02 C6 1E
|
||
|
|
+ 23 00 00 02 C7 1F
|
||
|
|
+ 23 00 00 02 C8 8B
|
||
|
|
+ 23 00 00 02 C9 1D
|
||
|
|
+ 23 00 00 02 CA 2A
|
||
|
|
+ 23 00 00 02 CB 7B
|
||
|
|
+ 23 00 00 02 CC 1A
|
||
|
|
+ 23 00 00 02 CD 19
|
||
|
|
+ 23 00 00 02 CE 4E
|
||
|
|
+ 23 00 00 02 CF 24
|
||
|
|
+ 23 00 00 02 D0 29
|
||
|
|
+ 23 00 00 02 D1 4F
|
||
|
|
+ 23 00 00 02 D2 5C
|
||
|
|
+ 23 00 00 02 D3 23
|
||
|
|
+ 39 00 00 04 FF 98 81 00
|
||
|
|
+ 23 78 00 02 11 00
|
||
|
|
+ 23 32 00 02 29 00
|
||
|
|
+ ];
|
||
|
|
+ sprd,sleep-in-command = [
|
||
|
|
+ 13 0A 00 01 28
|
||
|
|
+ 13 78 00 01 10
|
||
|
|
+ ];
|
||
|
|
+ sprd,sleep-out-command = [
|
||
|
|
+ 13 78 00 01 11
|
||
|
|
+ 13 64 00 01 29
|
||
|
|
+ ];
|
||
|
|
+
|
||
|
|
+ display-timings {
|
||
|
|
+ native-mode = <&ili9881c_truly_timing0>;
|
||
|
|
+
|
||
|
|
+ ili9881c_truly_timing0: timing0 {
|
||
|
|
+ clock-frequency = <64000000>;
|
||
|
|
+ hactive = <800>;
|
||
|
|
+ vactive = <1280>;
|
||
|
|
+ hback-porch = <8>;
|
||
|
|
+ hfront-porch = <24>;
|
||
|
|
+ vback-porch = <8>;
|
||
|
|
+ vfront-porch = <24>;
|
||
|
|
+ hsync-len = <18>;
|
||
|
|
+ vsync-len = <4>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
diff --git a/arch/arm64/boot/dts/sprd/qogirn6pro.dtsi b/arch/arm64/boot/dts/sprd/qogirn6pro.dtsi
|
||
|
|
index 67743bc..a70019b 100644
|
||
|
|
--- a/arch/arm64/boot/dts/sprd/qogirn6pro.dtsi
|
||
|
|
+++ b/arch/arm64/boot/dts/sprd/qogirn6pro.dtsi
|
||
|
|
@@ -755,11 +755,23 @@
|
||
|
|
#power-domain-cells = <0>;
|
||
|
|
power-domains = <&vpu_pd_top>;
|
||
|
|
|
||
|
|
- dpu_port: port {
|
||
|
|
- dpu_out: endpoint {
|
||
|
|
- remote-endpoint = <&dsi_in>;
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+
|
||
|
|
+ dpu_port: port@0 {
|
||
|
|
+ reg = <0>;
|
||
|
|
+ dpu0_out: endpoint {
|
||
|
|
+ remote-endpoint = <&dsi_in>;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
+
|
||
|
|
+ dpu_port1: port@1 {
|
||
|
|
+ reg = <1>;
|
||
|
|
+ dpu_s_out: endpoint {
|
||
|
|
+ remote-endpoint = <&dsi1_in>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+
|
||
|
|
};
|
||
|
|
|
||
|
|
iommu_dispc: iommu@31001800 {
|
||
|
|
@@ -820,9 +832,8 @@
|
||
|
|
reg = <0x0 0x31300000 0x0 0x1000>;
|
||
|
|
reset-syscon = <&dpu_vsp_apb_regs REG_DPU_VSP_APB_RST
|
||
|
|
MASK_DPU_VSP_APB_DSI0_SOFT_RST>;
|
||
|
|
-
|
||
|
|
- interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
|
||
|
|
- <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
|
||
|
|
+ interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
|
||
|
|
+ <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
|
||
|
|
|
||
|
|
status = "disabled";
|
||
|
|
|
||
|
|
@@ -843,7 +854,42 @@
|
||
|
|
port@1 {
|
||
|
|
reg = <1>;
|
||
|
|
dsi_in: endpoint {
|
||
|
|
- remote-endpoint = <&dpu_out>;
|
||
|
|
+ remote-endpoint = <&dpu0_out>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+
|
||
|
|
+ dsi1: dsi1@31400000 {
|
||
|
|
+ compatible = "sprd,qogirn6pro-s-dsi-host";
|
||
|
|
+ reg = <0x0 0x31400000 0x0 0x1000>;
|
||
|
|
+ reset-syscon = <&dpu_vsp_apb_regs REG_DPU_VSP_APB_RST
|
||
|
|
+ MASK_DPU_VSP_APB_DSI1_SOFT_RST>;
|
||
|
|
+ enable-syscon = <&dpu_vsp_apb_regs REG_DPU_VSP_APB_EN
|
||
|
|
+ MASK_DPU_VSP_APB_DSI1_SOFT_RST>;
|
||
|
|
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
|
||
|
|
+ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
|
||
|
|
+
|
||
|
|
+ status = "disabled";
|
||
|
|
+
|
||
|
|
+ #power-domain-cells = <0>;
|
||
|
|
+ power-domains = <&vpu_pd_top>;
|
||
|
|
+
|
||
|
|
+ ports {
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+
|
||
|
|
+ port@0 {
|
||
|
|
+ reg = <0>;
|
||
|
|
+ dsi1_out: endpoint {
|
||
|
|
+ remote-endpoint = <&dphy1_in>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+
|
||
|
|
+ port@1 {
|
||
|
|
+ reg = <1>;
|
||
|
|
+ dsi1_in: endpoint {
|
||
|
|
+ remote-endpoint = <&dpu_s_out>;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
@@ -883,6 +929,39 @@
|
||
|
|
};
|
||
|
|
};
|
||
|
|
};
|
||
|
|
+ dphy1: dphy1 {
|
||
|
|
+ compatible = "sprd,qogirn6pro-s-dsi-phy";
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+ reg = <0x0 0x31400000 0x0 0x1000>;
|
||
|
|
+ enable-syscon = <&dpu_vsp_apb_regs REG_DPU_VSP_APB_MISC_CKG_EB
|
||
|
|
+ (MASK_DPU_VSP_APB_DPHY1_REF_CKG_EN |
|
||
|
|
+ MASK_DPU_VSP_APB_DPHY1_CFG_CKG_EN)>;
|
||
|
|
+ power-syscon = <&pmu_apb_regs REG_PMU_APB_RF_ANALOG_PHY_PD_CFG MASK_PMU_APB_RF_DSI0_PD_REG>;
|
||
|
|
+ aod_mode-syscon = <&aon_apb_regs REG_AON_APB_MIPI_DSI8_CTRL
|
||
|
|
+ (MASK_AON_APB_MIPI_DSI_8LANE_DSI_AOD_EN_M |
|
||
|
|
+ MASK_AON_APB_MIPI_DSI_8LANE_DSI_AOD_MOD_M)>;
|
||
|
|
+ aod_pd-syscon = <&aon_apb_regs REG_AON_APB_MIPI_DSI8_CTRL
|
||
|
|
+ MASK_AON_APB_MIPI_DSI_8LANE_DSI_AOD_PD_M>;
|
||
|
|
+ status = "disabled";
|
||
|
|
+ sprd,mipi-drive-capability = <7>;
|
||
|
|
+ ports {
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+ port@0 {
|
||
|
|
+ reg = <0>;
|
||
|
|
+ dphy1_out: endpoint {
|
||
|
|
+ remote-endpoint = <&panel1_in>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ port@1 {
|
||
|
|
+ reg = <1>;
|
||
|
|
+ dphy1_in: endpoint {
|
||
|
|
+ remote-endpoint = <&dsi1_out>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
};
|
||
|
|
|
||
|
|
mm {
|
||
|
|
diff --git a/arch/arm64/boot/dts/sprd/uis7885-mach.dtsi b/arch/arm64/boot/dts/sprd/uis7885-mach.dtsi
|
||
|
|
index 1d70d82..211143e 100755
|
||
|
|
--- a/arch/arm64/boot/dts/sprd/uis7885-mach.dtsi
|
||
|
|
+++ b/arch/arm64/boot/dts/sprd/uis7885-mach.dtsi
|
||
|
|
@@ -878,7 +878,7 @@
|
||
|
|
|
||
|
|
display-subsystem {
|
||
|
|
compatible = "sprd,display-subsystem";
|
||
|
|
- ports = <&dpu_port>;
|
||
|
|
+ ports = <&dpu_port>,<&dpu_port1>;
|
||
|
|
/*gsp = <&gsp0>, <&gsp1>;*/
|
||
|
|
};
|
||
|
|
|
||
|
|
@@ -916,6 +916,25 @@
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
+&dsi1 {
|
||
|
|
+ status = "okay";
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+
|
||
|
|
+ panel1: panel1 {
|
||
|
|
+ compatible = "sprd,generic-mipi-panel";
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+ reg = <0>;
|
||
|
|
+
|
||
|
|
+ port@1 {
|
||
|
|
+ reg = <1>;
|
||
|
|
+ panel1_in: endpoint {
|
||
|
|
+ remote-endpoint = <&dphy1_out>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+};
|
||
|
|
|
||
|
|
&dpu1 {
|
||
|
|
status = "okay";
|
||
|
|
@@ -941,6 +960,10 @@
|
||
|
|
status = "okay";
|
||
|
|
};
|
||
|
|
|
||
|
|
+&dphy1 {
|
||
|
|
+ status = "okay";
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
&jpg {
|
||
|
|
status = "okay";
|
||
|
|
};
|
||
|
|
diff --git a/arch/arm64/boot/dts/sprd/uis7885.dtsi b/arch/arm64/boot/dts/sprd/uis7885.dtsi
|
||
|
|
index b16a9bb..1f5ad5a 100755
|
||
|
|
--- a/arch/arm64/boot/dts/sprd/uis7885.dtsi
|
||
|
|
+++ b/arch/arm64/boot/dts/sprd/uis7885.dtsi
|
||
|
|
@@ -1024,6 +1024,19 @@
|
||
|
|
<&dpu_vsp_gate CLK_DPU_EB>;
|
||
|
|
};
|
||
|
|
|
||
|
|
+&dsi1 {
|
||
|
|
+ clock-names = "clk_dsi1_eb",
|
||
|
|
+ "clk_dpu_dpi",
|
||
|
|
+ "clk_src_384m",
|
||
|
|
+ "clk_dpuvsp_eb",
|
||
|
|
+ "clk_dpuvsp_disp_eb";
|
||
|
|
+ clocks = <&dpu_vsp_gate CLK_DSI1_EB>,
|
||
|
|
+ <&dpu_vsp_clk CLK_DISPC0_DPI>,
|
||
|
|
+ <&g5l_pll CLK_TGPLL_384M>,
|
||
|
|
+ <&aonapb_gate CLK_DPU_VSP_EB>,
|
||
|
|
+ <&dpu_vsp_gate CLK_DPU_EB>;
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
&gsp0_core0 {
|
||
|
|
clock-names = "clk_src_512m",
|
||
|
|
"clk_gsp0_eb",
|
||
|
|
diff --git a/arch/arm64/boot/dts/sprd/ums9620-mach.dtsi b/arch/arm64/boot/dts/sprd/ums9620-mach.dtsi
|
||
|
|
index 514c124..32ec777 100644
|
||
|
|
--- a/arch/arm64/boot/dts/sprd/ums9620-mach.dtsi
|
||
|
|
+++ b/arch/arm64/boot/dts/sprd/ums9620-mach.dtsi
|
||
|
|
@@ -912,6 +912,25 @@
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
+&dsi1 {
|
||
|
|
+ status = "okay";
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+
|
||
|
|
+ panel1: panel1 {
|
||
|
|
+ compatible = "sprd,generic-mipi-panel";
|
||
|
|
+ #address-cells = <1>;
|
||
|
|
+ #size-cells = <0>;
|
||
|
|
+ reg = <0>;
|
||
|
|
+
|
||
|
|
+ port@1 {
|
||
|
|
+ reg = <1>;
|
||
|
|
+ panel1_in: endpoint {
|
||
|
|
+ remote-endpoint = <&dphy1_out>;
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+ };
|
||
|
|
+};
|
||
|
|
|
||
|
|
&dpu1 {
|
||
|
|
status = "okay";
|
||
|
|
@@ -937,6 +956,10 @@
|
||
|
|
status = "okay";
|
||
|
|
};
|
||
|
|
|
||
|
|
+&dphy1 {
|
||
|
|
+ status = "okay";
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
&jpg {
|
||
|
|
status = "okay";
|
||
|
|
};
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/disp_lib.c b/drivers/gpu/drm/sprd/disp_lib.c
|
||
|
|
index 02711a7..4c0f9db 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/disp_lib.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/disp_lib.c
|
||
|
|
@@ -199,9 +199,9 @@
|
||
|
|
return sprd_disp_pipe_get_by_port(dev, 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
-struct device *sprd_disp_pipe_get_output(struct device *dev)
|
||
|
|
+struct device *sprd_disp_pipe_get_output(struct device *dev,u32 swtich_port)
|
||
|
|
{
|
||
|
|
- return sprd_disp_pipe_get_by_port(dev, 0);
|
||
|
|
+ return sprd_disp_pipe_get_by_port(dev, swtich_port);
|
||
|
|
}
|
||
|
|
|
||
|
|
MODULE_AUTHOR("Leon He <leon.he@unisoc.com>");
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/disp_lib.h b/drivers/gpu/drm/sprd/disp_lib.h
|
||
|
|
index 2f31dcd..52d454d 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/disp_lib.h
|
||
|
|
+++ b/drivers/gpu/drm/sprd/disp_lib.h
|
||
|
|
@@ -24,6 +24,6 @@
|
||
|
|
|
||
|
|
struct device *sprd_disp_pipe_get_by_port(struct device *dev, int port);
|
||
|
|
struct device *sprd_disp_pipe_get_input(struct device *dev);
|
||
|
|
-struct device *sprd_disp_pipe_get_output(struct device *dev);
|
||
|
|
+struct device *sprd_disp_pipe_get_output(struct device *dev,u32 port);
|
||
|
|
|
||
|
|
#endif /* _DISP_LIB_H_ */
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/dpu/dpu_r6p0.c b/drivers/gpu/drm/sprd/dpu/dpu_r6p0.c
|
||
|
|
index aec1598..4327dfc9 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/dpu/dpu_r6p0.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/dpu/dpu_r6p0.c
|
||
|
|
@@ -1943,10 +1943,16 @@
|
||
|
|
{
|
||
|
|
struct sprd_dpu *dpu = container_of(ctx, struct sprd_dpu, ctx);
|
||
|
|
struct sprd_dsi *dsi = dpu->dsi;
|
||
|
|
- struct sprd_panel *panel = container_of(dsi->panel, struct sprd_panel, base);
|
||
|
|
+ //struct sprd_panel *panel = container_of(dsi->panel, struct sprd_panel, base);
|
||
|
|
+ struct sprd_panel *panel;
|
||
|
|
u32 int_mask = 0;
|
||
|
|
u32 reg_val;
|
||
|
|
|
||
|
|
+ if (!dsi || !dsi->panel) {
|
||
|
|
+ pr_err("dsi or panel is NULL, skip dpu_dpi_init\n");
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+ panel = container_of(dsi->panel, struct sprd_panel, base);
|
||
|
|
if (ctx->if_type == SPRD_DPU_IF_DPI) {
|
||
|
|
/* use dpi as interface */
|
||
|
|
DPU_REG_CLR(ctx->base + REG_DPU_CFG0, BIT_DPU_IF_EDPI);
|
||
|
|
@@ -1954,6 +1960,9 @@
|
||
|
|
/* enable Halt function for SPRD DSI */
|
||
|
|
DPU_REG_SET(ctx->base + REG_DPI_CTRL, BIT_DPU_DPI_HALT_EN);
|
||
|
|
|
||
|
|
+ if(panel->info.mipi_port == SPRD_DSI_1)
|
||
|
|
+ DPU_REG_SET(ctx->base + REG_DPI_CTRL, BIT_DPU_INT_TE);
|
||
|
|
+
|
||
|
|
if (ctx->is_single_run)
|
||
|
|
DPU_REG_SET(ctx->base + REG_DPU_CTRL, BIT(0));
|
||
|
|
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c b/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c
|
||
|
|
index d7ab66e..a2d2f73 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/dsi/sprd_dsi_api.c
|
||
|
|
@@ -191,8 +191,10 @@
|
||
|
|
|
||
|
|
data_hs2lp = ns_to_cycle(ctx->data_hs2lp, ctx->byte_clk);
|
||
|
|
data_lp2hs = ns_to_cycle(ctx->data_lp2hs, ctx->byte_clk);
|
||
|
|
- clk_hs2lp = ns_to_cycle(ctx->clk_hs2lp, ctx->byte_clk);
|
||
|
|
- clk_lp2hs = ns_to_cycle(ctx->clk_lp2hs, ctx->byte_clk);
|
||
|
|
+ //clk_hs2lp = ns_to_cycle(ctx->clk_hs2lp, ctx->byte_clk);
|
||
|
|
+ //clk_lp2hs = ns_to_cycle(ctx->clk_lp2hs, ctx->byte_clk);
|
||
|
|
+ clk_hs2lp = ctx->clk_hs2lp;
|
||
|
|
+ clk_lp2hs = ctx->clk_lp2hs;
|
||
|
|
dsi_hal_datalane_hs2lp_config(dsi, data_hs2lp);
|
||
|
|
dsi_hal_datalane_lp2hs_config(dsi, data_lp2hs);
|
||
|
|
dsi_hal_clklane_hs2lp_config(dsi, clk_hs2lp);
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/qogirn6pro/global_dphy.c b/drivers/gpu/drm/sprd/qogirn6pro/global_dphy.c
|
||
|
|
index 78b1d39..77fe120 100755
|
||
|
|
--- a/drivers/gpu/drm/sprd/qogirn6pro/global_dphy.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/qogirn6pro/global_dphy.c
|
||
|
|
@@ -9,9 +9,15 @@
|
||
|
|
#include <linux/slab.h>
|
||
|
|
#include <linux/mfd/syscon.h>
|
||
|
|
#include <linux/regmap.h>
|
||
|
|
-
|
||
|
|
+#include <linux/io.h>
|
||
|
|
#include "sprd_dphy.h"
|
||
|
|
|
||
|
|
+#define Analog_Reg_G3_BASE 0x64314000UL
|
||
|
|
+#define Analog_Reg_G3_SIZE 0x100
|
||
|
|
+#define REG_SEL_CFG_0 0x64
|
||
|
|
+#define REG_DBG_SEL_MASK 0xff
|
||
|
|
+static void __iomem *analog_reg_g3_base;
|
||
|
|
+
|
||
|
|
static struct dphy_glb_context {
|
||
|
|
unsigned int ctrl_reg;
|
||
|
|
unsigned int ctrl_mask;
|
||
|
|
@@ -83,6 +89,15 @@
|
||
|
|
s_ctx_power.ctrl_reg = syscon_args[0];
|
||
|
|
s_ctx_power.ctrl_mask = syscon_args[1];
|
||
|
|
}
|
||
|
|
+ if (!analog_reg_g3_base) {
|
||
|
|
+ analog_reg_g3_base = ioremap_nocache(Analog_Reg_G3_BASE,
|
||
|
|
+ Analog_Reg_G3_SIZE);
|
||
|
|
+ if (!analog_reg_g3_base)
|
||
|
|
+ pr_err("ioremap analog_reg_g3 (0x%lx) failed\n",
|
||
|
|
+ Analog_Reg_G3_BASE);
|
||
|
|
+ else
|
||
|
|
+ pr_info("analog_reg_g3 base mapped for mipi dsi workaround\n");
|
||
|
|
+ }
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
@@ -107,10 +122,28 @@
|
||
|
|
|
||
|
|
static void dphy_s_glb_enable(struct dphy_context *ctx)
|
||
|
|
{
|
||
|
|
+ void __iomem *reg;
|
||
|
|
+ u32 val;
|
||
|
|
+
|
||
|
|
+ if (!analog_reg_g3_base) {
|
||
|
|
+ pr_err("force DSI analog mmio not mapped\n");
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ reg = analog_reg_g3_base + REG_SEL_CFG_0;
|
||
|
|
+
|
||
|
|
+ val = readl_relaxed(reg);
|
||
|
|
+ val = val & ~REG_DBG_SEL_MASK;
|
||
|
|
+ writel_relaxed(val, reg);
|
||
|
|
+
|
||
|
|
+ /* read-back flush, then re-read to confirm */
|
||
|
|
+ val = readl_relaxed(reg);
|
||
|
|
+
|
||
|
|
regmap_update_bits(s_ctx_enable.regmap,
|
||
|
|
s_ctx_enable.ctrl_reg,
|
||
|
|
s_ctx_enable.ctrl_mask,
|
||
|
|
s_ctx_enable.ctrl_mask);
|
||
|
|
+ pr_info("drm dphy_s_glb_enable\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
static void dphy_glb_disable(struct dphy_context *ctx)
|
||
|
|
@@ -159,6 +192,7 @@
|
||
|
|
|
||
|
|
static void dphy_s_power_domain(struct dphy_context *ctx, int enable)
|
||
|
|
{
|
||
|
|
+ pr_info("dphy_s_power_domain enable=%d\n",enable);
|
||
|
|
if (enable) {
|
||
|
|
regmap_update_bits(s_ctx_power.regmap,
|
||
|
|
s_ctx_power.ctrl_reg,
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c b/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c
|
||
|
|
index b43ccce..d5e1094 100755
|
||
|
|
--- a/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/qogirn6pro/global_dpu.c
|
||
|
|
@@ -13,6 +13,14 @@
|
||
|
|
|
||
|
|
#include "sprd_dpu.h"
|
||
|
|
|
||
|
|
+/* DPU_VSP clock-controller (ums9620 dpu_vsp_clk) register block @ 0x30110000. */
|
||
|
|
+#define DPU_VSP_CLK_BASE 0x30110000UL
|
||
|
|
+#define DPU_VSP_CLK_SIZE 0x3000
|
||
|
|
+/* dispc0_dpi pixel-clock divider: offset 0x78, bits[3:0] (value 3 = div-by-4). */
|
||
|
|
+#define REG_DISPC0_DPI_DIV 0x78
|
||
|
|
+#define REG_DISPC0_DPI_DIV_MASK 0xf
|
||
|
|
+static void __iomem *dpu_vsp_clk_base;
|
||
|
|
+
|
||
|
|
static struct clk *clk_dpuvsp_eb;
|
||
|
|
static struct clk *clk_dpuvsp_disp_eb;
|
||
|
|
static struct clk *clk_master_div6_eb;
|
||
|
|
@@ -155,6 +163,20 @@
|
||
|
|
clk_ctx->clk_dpu_dpi = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ /* Map the DPU_VSP clock-controller MMIO so the DPI-divider workaround
|
||
|
|
+ * can write register 0x30110078 directly. pr_err on failure - the ioremap
|
||
|
|
+ * must succeed or the workaround cannot fire at all.
|
||
|
|
+ */
|
||
|
|
+ if (!dpu_vsp_clk_base) {
|
||
|
|
+ dpu_vsp_clk_base = ioremap_nocache(DPU_VSP_CLK_BASE,
|
||
|
|
+ DPU_VSP_CLK_SIZE);
|
||
|
|
+ if (!dpu_vsp_clk_base)
|
||
|
|
+ pr_err("ioremap dpu_vsp_clk (0x%lx) failed\n",
|
||
|
|
+ DPU_VSP_CLK_BASE);
|
||
|
|
+ else
|
||
|
|
+ pr_info("dpu_vsp_clk base mapped for dpi-div workaround\n");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -188,6 +210,41 @@
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+ * Most direct path to force the dispc0_dpi pixel-clock divider to 3
|
||
|
|
+ * (divide-by-4): write bits[3:0] of register 0x30110078 (= DPU_VSP clock
|
||
|
|
+ * controller base 0x30110000 + offset 0x78). This bypasses the CCF and writes
|
||
|
|
+ * the MMIO register directly; the value is read back to confirm it latched.
|
||
|
|
+ * Returns the final divider value (should be 3 on success) or a negative errno.
|
||
|
|
+ */
|
||
|
|
+static int dpu_force_dpi_div3(void)
|
||
|
|
+{
|
||
|
|
+ void __iomem *reg;
|
||
|
|
+ u32 val;
|
||
|
|
+
|
||
|
|
+ if (!dpu_vsp_clk_base) {
|
||
|
|
+ pr_err("force dpi div=3: clk mmio not mapped\n");
|
||
|
|
+ return -ENXIO;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ reg = dpu_vsp_clk_base + REG_DISPC0_DPI_DIV;
|
||
|
|
+
|
||
|
|
+ val = readl_relaxed(reg);
|
||
|
|
+ val = (val & ~REG_DISPC0_DPI_DIV_MASK) | 3;
|
||
|
|
+ writel_relaxed(val, reg);
|
||
|
|
+
|
||
|
|
+ /* read-back flush, then re-read to confirm */
|
||
|
|
+ val = readl_relaxed(reg);
|
||
|
|
+ if ((val & REG_DISPC0_DPI_DIV_MASK) != 3) {
|
||
|
|
+ pr_err("force dpi div=3 (0x30110078) failed, readback=0x%x\n", val);
|
||
|
|
+ return -EIO;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ pr_info("force dpi div=3 (0x30110078) ok, reg=0x%x\n", val);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int dpu_clk_init(struct dpu_context *ctx)
|
||
|
|
{
|
||
|
|
int ret;
|
||
|
|
@@ -229,6 +286,17 @@
|
||
|
|
ret = clk_set_rate(clk_ctx->clk_dpu_dpi, ctx->vm.pixelclock);
|
||
|
|
if (ret)
|
||
|
|
pr_err("dpu update dpi clk rate failed\n");
|
||
|
|
+
|
||
|
|
+ /* Workaround: on resume (suspend->on), the DPI pixel-clock divider
|
||
|
|
+ * at 0x30110078 (dispc0_dpi div, bits[3:0]) is not re-applied and
|
||
|
|
+ * the panel lights up black. Force divider value 3 (div-by-4) by
|
||
|
|
+ * writing the MMIO register directly (most-direct path). Only acted
|
||
|
|
+ * upon when flagged from the resume path.
|
||
|
|
+ */
|
||
|
|
+ if (ctx->dpi_div_force3) {
|
||
|
|
+ ctx->dpi_div_force3 = false;
|
||
|
|
+ dpu_force_dpi_div3();
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/qogirn6pro/global_dsi.c b/drivers/gpu/drm/sprd/qogirn6pro/global_dsi.c
|
||
|
|
index 8eee971..f655b77 100755
|
||
|
|
--- a/drivers/gpu/drm/sprd/qogirn6pro/global_dsi.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/qogirn6pro/global_dsi.c
|
||
|
|
@@ -22,7 +22,7 @@
|
||
|
|
unsigned int ctrl_reg;
|
||
|
|
unsigned int ctrl_mask;
|
||
|
|
struct regmap *regmap;
|
||
|
|
-} ctx_reset, s_ctx_reset;
|
||
|
|
+} ctx_reset, s_ctx_reset, s_ctx_enable;
|
||
|
|
|
||
|
|
static int dsi_glb_parse_dt(struct dsi_context *ctx,
|
||
|
|
struct device_node *np)
|
||
|
|
@@ -82,7 +82,6 @@
|
||
|
|
unsigned int syscon_args[2];
|
||
|
|
|
||
|
|
pr_info("%s enter\n", __func__);
|
||
|
|
-
|
||
|
|
clk_dsi1_eb =
|
||
|
|
of_clk_get_by_name(np, "clk_dsi1_eb");
|
||
|
|
if (IS_ERR(clk_dsi1_eb)) {
|
||
|
|
@@ -90,14 +89,48 @@
|
||
|
|
clk_dsi1_eb = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
- s_ctx_reset.regmap = syscon_regmap_lookup_by_phandle_args(np, "reset", 2,syscon_args);
|
||
|
|
+ clk_dpu_dpi =
|
||
|
|
+ of_clk_get_by_name(np, "clk_dpu_dpi");
|
||
|
|
+ if (IS_ERR(clk_dpu_dpi)) {
|
||
|
|
+ pr_warn("read clk_dpu_dpi failed\n");
|
||
|
|
+ clk_dpu_dpi = NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ clk_src_384m =
|
||
|
|
+ of_clk_get_by_name(np, "clk_src_384m");
|
||
|
|
+ if (IS_ERR(clk_src_384m)) {
|
||
|
|
+ pr_warn("read clk_src_384m failed\n");
|
||
|
|
+ clk_src_384m = NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ clk_dpuvsp_eb =
|
||
|
|
+ of_clk_get_by_name(np, "clk_dpuvsp_eb");
|
||
|
|
+ if (IS_ERR(clk_dpuvsp_eb)) {
|
||
|
|
+ pr_warn("read clk_dpuvsp_eb failed\n");
|
||
|
|
+ clk_dpuvsp_eb = NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ clk_dpuvsp_disp_eb =
|
||
|
|
+ of_clk_get_by_name(np, "clk_dpuvsp_disp_eb");
|
||
|
|
+ if (IS_ERR(clk_dpuvsp_disp_eb)) {
|
||
|
|
+ pr_warn("read clk_dpuvsp_disp_eb failed\n");
|
||
|
|
+ clk_dpuvsp_disp_eb = NULL;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ s_ctx_reset.regmap = syscon_regmap_lookup_by_phandle_args(np, "reset-syscon", 2,syscon_args);
|
||
|
|
if (IS_ERR(s_ctx_reset.regmap)) {
|
||
|
|
pr_warn("failed to map dsi glb reg\n");
|
||
|
|
} else {
|
||
|
|
s_ctx_reset.ctrl_reg = syscon_args[0];
|
||
|
|
s_ctx_reset.ctrl_mask = syscon_args[1];
|
||
|
|
}
|
||
|
|
-
|
||
|
|
+ s_ctx_enable.regmap = syscon_regmap_lookup_by_phandle_args(np, "enable-syscon", 2,syscon_args);
|
||
|
|
+ if (IS_ERR(s_ctx_enable.regmap)) {
|
||
|
|
+ pr_warn("failed to map dsi glb enable reg\n");
|
||
|
|
+ } else {
|
||
|
|
+ s_ctx_enable.ctrl_reg = syscon_args[0];
|
||
|
|
+ s_ctx_enable.ctrl_mask = syscon_args[1];
|
||
|
|
+ }
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -143,10 +176,28 @@
|
||
|
|
static void dsi_s_glb_enable(struct dsi_context *ctx)
|
||
|
|
{
|
||
|
|
int ret;
|
||
|
|
+ pr_info("drm dsi_s_glb_enable\n");
|
||
|
|
+ if (!ctx->is_esd_rst) {
|
||
|
|
+ ret = clk_prepare_enable(clk_dpuvsp_eb);
|
||
|
|
+ if (ret) {
|
||
|
|
+ pr_err("enable clk_dpuvsp_eb failed!\n");
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
+ ret = clk_prepare_enable(clk_dpuvsp_disp_eb);
|
||
|
|
+ if (ret) {
|
||
|
|
+ pr_err("enable clk_dpuvsp_disp_eb failed!\n");
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
ret = clk_prepare_enable(clk_dsi1_eb);
|
||
|
|
if (ret)
|
||
|
|
pr_err("enable clk_dsi1_eb failed!\n");
|
||
|
|
+
|
||
|
|
+ regmap_update_bits(s_ctx_enable.regmap,
|
||
|
|
+ s_ctx_enable.ctrl_reg,
|
||
|
|
+ s_ctx_enable.ctrl_mask,
|
||
|
|
+ s_ctx_enable.ctrl_mask);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void dsi_glb_disable(struct dsi_context *ctx)
|
||
|
|
@@ -161,7 +212,16 @@
|
||
|
|
|
||
|
|
static void dsi_s_glb_disable(struct dsi_context *ctx)
|
||
|
|
{
|
||
|
|
- clk_disable_unprepare(clk_dsi1_eb);
|
||
|
|
+ regmap_update_bits(s_ctx_enable.regmap,
|
||
|
|
+ s_ctx_enable.ctrl_reg,
|
||
|
|
+ s_ctx_enable.ctrl_mask,
|
||
|
|
+ (unsigned int)(~s_ctx_enable.ctrl_mask));
|
||
|
|
+ if (ctx->clk_dpi_384m) {
|
||
|
|
+ dsi_core_clk_switch(ctx);
|
||
|
|
+ ctx->clk_dpi_384m = false;
|
||
|
|
+ } else {
|
||
|
|
+ clk_disable_unprepare(clk_dsi1_eb);
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
static void dsi_reset(struct dsi_context *ctx)
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dphy.c b/drivers/gpu/drm/sprd/sprd_dphy.c
|
||
|
|
index a069d0f..d2c3380 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dphy.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dphy.c
|
||
|
|
@@ -134,7 +134,13 @@
|
||
|
|
dphy->dev.class = display_class;
|
||
|
|
dphy->dev.parent = parent;
|
||
|
|
dphy->dev.of_node = parent->of_node;
|
||
|
|
- dev_set_name(&dphy->dev, "dphy0");
|
||
|
|
+ if (of_device_is_compatible(parent->of_node, "sprd,qogirn6pro-s-dsi-phy")){
|
||
|
|
+ dev_set_name(&dphy->dev, "dphy1");
|
||
|
|
+ }
|
||
|
|
+ else{
|
||
|
|
+ dev_set_name(&dphy->dev, "dphy0");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
dev_set_drvdata(&dphy->dev, dphy);
|
||
|
|
|
||
|
|
ret = device_register(&dphy->dev);
|
||
|
|
@@ -236,6 +242,12 @@
|
||
|
|
.glb = &qogirn6pro_dphy_glb_ops,
|
||
|
|
};
|
||
|
|
|
||
|
|
+static const struct sprd_dphy_ops qogirn6pro_s_dphy = {
|
||
|
|
+ .ppi = &dsi_ctrl_ppi_ops,
|
||
|
|
+ .pll = &sharkl5_dphy_pll_ops,
|
||
|
|
+ .glb = &qogirn6pro_dphy_s_glb_ops,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
static const struct of_device_id dphy_match_table[] = {
|
||
|
|
{ .compatible = "sprd,sharkle-dsi-phy",
|
||
|
|
.data = &sharkle_dphy },
|
||
|
|
@@ -251,6 +263,8 @@
|
||
|
|
.data = &qogirl6_dphy },
|
||
|
|
{ .compatible = "sprd,qogirn6pro-dsi-phy",
|
||
|
|
.data = &qogirn6pro_dphy },
|
||
|
|
+ { .compatible = "sprd,qogirn6pro-s-dsi-phy",
|
||
|
|
+ .data = &qogirn6pro_s_dphy },
|
||
|
|
{ /* sentinel */ },
|
||
|
|
};
|
||
|
|
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dphy.h b/drivers/gpu/drm/sprd/sprd_dphy.h
|
||
|
|
index 281a26d..9e7e559 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dphy.h
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dphy.h
|
||
|
|
@@ -102,4 +102,5 @@
|
||
|
|
extern const struct dphy_glb_ops sharkl5pro_dphy_glb_ops;
|
||
|
|
extern const struct dphy_glb_ops qogirl6_dphy_glb_ops;
|
||
|
|
extern const struct dphy_glb_ops qogirn6pro_dphy_glb_ops;
|
||
|
|
+extern const struct dphy_glb_ops qogirn6pro_dphy_s_glb_ops;
|
||
|
|
#endif /* _SPRD_DPHY_H_ */
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dpu.c b/drivers/gpu/drm/sprd/sprd_dpu.c
|
||
|
|
old mode 100644
|
||
|
|
new mode 100755
|
||
|
|
index 819c839..ac2649b
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dpu.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dpu.c
|
||
|
|
@@ -199,8 +199,8 @@
|
||
|
|
|
||
|
|
DRM_INFO("%s()\n", __func__);
|
||
|
|
#ifdef CONFIG_DRM_SPRD_DSI
|
||
|
|
- if (!dpu || !dpu->dsi) {
|
||
|
|
- DRM_ERROR("dpu or dsi ptr is NULL\n");
|
||
|
|
+ if (!dpu || !dpu->dsi || !dpu->dsi->panel) {
|
||
|
|
+ DRM_ERROR("dpu or dsi or panel ptr is NULL\n");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -378,6 +378,18 @@
|
||
|
|
|
||
|
|
void sprd_dpu_resume(struct sprd_dpu *dpu)
|
||
|
|
{
|
||
|
|
+ struct dpu_context *ctx = &dpu->ctx;
|
||
|
|
+ u32 mipi_port = 0;
|
||
|
|
+ /* Flag the DPI-divider workaround: force value 3 at 0x30110078 on the
|
||
|
|
+ * next dpu_clk_init() to avoid black screen on wake.
|
||
|
|
+ */
|
||
|
|
+ if (dpu->dsi && dpu->dsi->panel) {
|
||
|
|
+ struct sprd_panel *panel = (struct sprd_panel *)container_of(dpu->dsi->panel, struct sprd_panel, base);
|
||
|
|
+ mipi_port = panel->info.mipi_port;
|
||
|
|
+ }
|
||
|
|
+ if(mipi_port == 1){
|
||
|
|
+ ctx->dpi_div_force3 = true;
|
||
|
|
+ }
|
||
|
|
sprd_dpu_enable(dpu);
|
||
|
|
enable_irq(dpu->ctx.irq);
|
||
|
|
sprd_iommu_restore(&dpu->dev);
|
||
|
|
@@ -463,11 +475,37 @@
|
||
|
|
{
|
||
|
|
struct device *dev;
|
||
|
|
struct sprd_dsi *dsi;
|
||
|
|
+ struct device_node *chosen, *lcd_node;
|
||
|
|
+ const char *bootargs, *p;
|
||
|
|
+ char lcd_name[64], lcd_path[80];
|
||
|
|
+ u32 mipi_port = 0;
|
||
|
|
|
||
|
|
DRM_INFO("dpu attach dsi\n");
|
||
|
|
- dev = sprd_disp_pipe_get_output(&dpu->dev);
|
||
|
|
+ /*
|
||
|
|
+ * Two DSI paths coexist: dsi0->dphy0 = HDMI/LT8912B, dsi1->dphy1 = MIPI panel.
|
||
|
|
+ * Pick the one selected by cmdline lcd_name: read "sprd,mipi-port" from
|
||
|
|
+ * /lcds/<lcd_name> and attach the dpu output port that maps to that dsi host
|
||
|
|
+ * (port0 -> dsi0, port1 -> dsi1). dpu->dsi is not assigned yet here, so the
|
||
|
|
+ * mipi-port must be read from the /lcds node itself, exactly like the panel
|
||
|
|
+ * driver parses cmdline.
|
||
|
|
+ */
|
||
|
|
+ chosen = of_find_node_by_path("/chosen");
|
||
|
|
+ if (chosen && !of_property_read_string(chosen, "bootargs", &bootargs)) {
|
||
|
|
+ p = strstr(bootargs, "lcd_name=");
|
||
|
|
+ if (p) {
|
||
|
|
+ sscanf(p, "lcd_name=%s", lcd_name);
|
||
|
|
+ snprintf(lcd_path, sizeof(lcd_path), "/lcds/%s", lcd_name);
|
||
|
|
+ lcd_node = of_find_node_by_path(lcd_path);
|
||
|
|
+ if (lcd_node) {
|
||
|
|
+ of_property_read_u32(lcd_node, "sprd,mipi-port", &mipi_port);
|
||
|
|
+ DRM_INFO("dpu attach dsi mipi_port=%d\n", mipi_port);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ dev = sprd_disp_pipe_get_output(&dpu->dev, mipi_port);
|
||
|
|
if (!dev) {
|
||
|
|
- DRM_ERROR("dpu pipe get output failed\n");
|
||
|
|
+ DRM_ERROR("dpu pipe get output (port=%d) failed\n", mipi_port);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -484,9 +522,11 @@
|
||
|
|
{
|
||
|
|
struct device *dev;
|
||
|
|
struct sprd_spi *spi;
|
||
|
|
+ struct sprd_panel *panel;
|
||
|
|
|
||
|
|
DRM_INFO("%s()\n", __func__);
|
||
|
|
- dev = sprd_disp_pipe_get_output(&dpu->dev);
|
||
|
|
+ panel = (struct sprd_panel *)container_of(dpu->dsi->panel, struct sprd_panel, base);
|
||
|
|
+ dev = sprd_disp_pipe_get_output(&dpu->dev,0);
|
||
|
|
if (!dev) {
|
||
|
|
DRM_ERROR("dpu pipe get output failed\n");
|
||
|
|
return NULL;
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dpu.h b/drivers/gpu/drm/sprd/sprd_dpu.h
|
||
|
|
old mode 100644
|
||
|
|
new mode 100755
|
||
|
|
index d8174be..7ffc889
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dpu.h
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dpu.h
|
||
|
|
@@ -219,6 +219,13 @@
|
||
|
|
|
||
|
|
/* spi frame refresh parameters */
|
||
|
|
unsigned int flag_mask_refresh;
|
||
|
|
+
|
||
|
|
+ /* DPI pixel-clock divider force workaround.
|
||
|
|
+ * Set true from the resume path so dpu_clk_init() re-applies divider
|
||
|
|
+ * value 3 to register 0x30110078 (dispc0_dpi div, bits[3:0]) which is
|
||
|
|
+ * lost/missing on resume and causes a black screen on wake.
|
||
|
|
+ */
|
||
|
|
+ bool dpi_div_force3;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct sprd_dpu_ops {
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dsi.c b/drivers/gpu/drm/sprd/sprd_dsi.c
|
||
|
|
old mode 100644
|
||
|
|
new mode 100755
|
||
|
|
index 85e56d5..3eca9f0
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dsi.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dsi.c
|
||
|
|
@@ -197,8 +197,9 @@
|
||
|
|
* its current contents indefinitely. If call sprd_dpu_run, background color will appear
|
||
|
|
* that will cause panel flickering. So we should call sprd_dpu_run when flip in edpi mode.
|
||
|
|
*/
|
||
|
|
- if (dsi->ctx.last_dpms != DRM_MODE_DPMS_SUSPEND)
|
||
|
|
+ if (dsi->ctx.last_dpms != DRM_MODE_DPMS_SUSPEND){
|
||
|
|
sprd_dpu_run(crtc->priv);
|
||
|
|
+ }
|
||
|
|
|
||
|
|
dsi->ctx.enabled = true;
|
||
|
|
dsi->ctx.last_dpms = dsi->ctx.dpms;
|
||
|
|
@@ -384,12 +385,21 @@
|
||
|
|
struct device *dev = dsi->host.dev;
|
||
|
|
struct device_node *child, *lcds_node;
|
||
|
|
struct drm_panel *panel;
|
||
|
|
+ struct sprd_panel *p;
|
||
|
|
|
||
|
|
/* search /lcds child node first */
|
||
|
|
lcds_node = of_find_node_by_path("/lcds");
|
||
|
|
for_each_child_of_node(lcds_node, child) {
|
||
|
|
panel = of_drm_find_panel(child);
|
||
|
|
if (!IS_ERR(panel)) {
|
||
|
|
+ p = container_of(panel, struct sprd_panel, base);
|
||
|
|
+ /*
|
||
|
|
+ * Two hosts can share the same /lcds of_node; only accept
|
||
|
|
+ * the panel attaching to THIS dsi host (its device parent
|
||
|
|
+ * is this host's dsi slave, set in sprd_dsi_host_attach).
|
||
|
|
+ */
|
||
|
|
+ if (dsi->slave && p->dev.parent != &dsi->slave->dev)
|
||
|
|
+ continue;
|
||
|
|
dsi->panel = panel;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
@@ -402,6 +412,9 @@
|
||
|
|
for_each_child_of_node(dev->of_node, child) {
|
||
|
|
panel = of_drm_find_panel(child);
|
||
|
|
if (!IS_ERR(panel)) {
|
||
|
|
+ p = container_of(panel, struct sprd_panel, base);
|
||
|
|
+ if (dsi->slave && p->dev.parent != &dsi->slave->dev)
|
||
|
|
+ continue;
|
||
|
|
dsi->panel = panel;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
@@ -415,7 +428,7 @@
|
||
|
|
{
|
||
|
|
struct device *dev;
|
||
|
|
|
||
|
|
- dev = sprd_disp_pipe_get_output(&dsi->dev);
|
||
|
|
+ dev = sprd_disp_pipe_get_output(&dsi->dev,0);
|
||
|
|
if (!dev)
|
||
|
|
return -ENODEV;
|
||
|
|
|
||
|
|
@@ -550,7 +563,10 @@
|
||
|
|
struct sprd_dsi *dsi = connector_to_dsi(connector);
|
||
|
|
|
||
|
|
DRM_INFO("%s()\n", __func__);
|
||
|
|
-
|
||
|
|
+ /* unused host in two-way pick-one has no panel bound */
|
||
|
|
+ if (!dsi->panel){
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
return drm_panel_get_modes(dsi->panel);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -796,7 +812,12 @@
|
||
|
|
dsi->dev.class = display_class;
|
||
|
|
dsi->dev.parent = parent;
|
||
|
|
dsi->dev.of_node = parent->of_node;
|
||
|
|
- dev_set_name(&dsi->dev, "dsi");
|
||
|
|
+ if (of_device_is_compatible(parent->of_node, "sprd,qogirn6pro-s-dsi-host")){
|
||
|
|
+ dev_set_name(&dsi->dev, "dsi1");
|
||
|
|
+ }
|
||
|
|
+ else{
|
||
|
|
+ dev_set_name(&dsi->dev, "dsi");
|
||
|
|
+ }
|
||
|
|
dev_set_drvdata(&dsi->dev, dsi);
|
||
|
|
|
||
|
|
ret = device_register(&dsi->dev);
|
||
|
|
@@ -840,7 +861,7 @@
|
||
|
|
ctx->clk_hs2lp = tmp;
|
||
|
|
else
|
||
|
|
ctx->clk_hs2lp = 4;
|
||
|
|
-
|
||
|
|
+
|
||
|
|
if (!of_property_read_u32(np, "sprd,clk-lp2hs", &tmp))
|
||
|
|
ctx->clk_lp2hs = tmp;
|
||
|
|
else
|
||
|
|
@@ -898,7 +919,12 @@
|
||
|
|
|
||
|
|
static const struct sprd_dsi_ops qogirn6pro_dsi = {
|
||
|
|
.core = &dsi_ctrl_r1p0_ops,
|
||
|
|
- .glb = &qogirn6pro_dsi_glb_ops
|
||
|
|
+ .glb = &qogirn6pro_dsi_glb_ops,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static const struct sprd_dsi_ops qogirn6pro_s_dsi = {
|
||
|
|
+ .core = &dsi_ctrl_r1p0_ops,
|
||
|
|
+ .glb = &qogirn6pro_dsi_s_glb_ops,
|
||
|
|
};
|
||
|
|
|
||
|
|
static const struct of_device_id dsi_match_table[] = {
|
||
|
|
@@ -916,6 +942,8 @@
|
||
|
|
.data = &qogirl6_dsi },
|
||
|
|
{ .compatible = "sprd,qogirn6pro-dsi-host",
|
||
|
|
.data = &qogirn6pro_dsi },
|
||
|
|
+ { .compatible = "sprd,qogirn6pro-s-dsi-host",
|
||
|
|
+ .data = &qogirn6pro_s_dsi },
|
||
|
|
{ /* sentinel */ },
|
||
|
|
};
|
||
|
|
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dsi.h b/drivers/gpu/drm/sprd/sprd_dsi.h
|
||
|
|
index e5964b0..3b99cee 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dsi.h
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dsi.h
|
||
|
|
@@ -228,4 +228,5 @@
|
||
|
|
extern const struct dsi_glb_ops sharkl5pro_dsi_glb_ops;
|
||
|
|
extern const struct dsi_glb_ops qogirl6_dsi_glb_ops;
|
||
|
|
extern const struct dsi_glb_ops qogirn6pro_dsi_glb_ops;
|
||
|
|
+extern const struct dsi_glb_ops qogirn6pro_dsi_s_glb_ops;
|
||
|
|
#endif /* _SPRD_DSI_H_ */
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dsi_panel.c b/drivers/gpu/drm/sprd/sprd_dsi_panel.c
|
||
|
|
index 1772f84..6c36ae4 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dsi_panel.c
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dsi_panel.c
|
||
|
|
@@ -75,14 +75,16 @@
|
||
|
|
mdelay(timing[i].delay);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
-
|
||
|
|
+ if (panel->info.avdd_gpio) {
|
||
|
|
+ gpiod_direction_output(panel->info.avdd_gpio, 0);
|
||
|
|
+ mdelay(5);
|
||
|
|
+ }
|
||
|
|
if (panel->info.avee_gpio) {
|
||
|
|
gpiod_direction_output(panel->info.avee_gpio, 0);
|
||
|
|
mdelay(5);
|
||
|
|
}
|
||
|
|
-
|
||
|
|
- if (panel->info.avdd_gpio) {
|
||
|
|
- gpiod_direction_output(panel->info.avdd_gpio, 0);
|
||
|
|
+ if (panel->info.iovdd_gpio) {
|
||
|
|
+ gpiod_direction_output(panel->info.iovdd_gpio, 0);
|
||
|
|
mdelay(5);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -100,17 +102,21 @@
|
||
|
|
DRM_INFO("%s()\n", __func__);
|
||
|
|
|
||
|
|
ret = regulator_enable(panel->supply);
|
||
|
|
- if (ret < 0)
|
||
|
|
+ if (ret < 0){
|
||
|
|
DRM_ERROR("enable lcd regulator failed\n");
|
||
|
|
-
|
||
|
|
+ }
|
||
|
|
+ if (panel->info.iovdd_gpio) {
|
||
|
|
+ gpiod_direction_output(panel->info.iovdd_gpio, 1);
|
||
|
|
+ mdelay(10);
|
||
|
|
+ }
|
||
|
|
if (panel->info.avdd_gpio) {
|
||
|
|
gpiod_direction_output(panel->info.avdd_gpio, 1);
|
||
|
|
- mdelay(5);
|
||
|
|
+ mdelay(20);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (panel->info.avee_gpio) {
|
||
|
|
gpiod_direction_output(panel->info.avee_gpio, 1);
|
||
|
|
- mdelay(5);
|
||
|
|
+ mdelay(20);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (panel->info.reset_gpio) {
|
||
|
|
@@ -477,6 +483,12 @@
|
||
|
|
static int sprd_panel_gpio_request(struct device *dev,
|
||
|
|
struct sprd_panel *panel)
|
||
|
|
{
|
||
|
|
+ panel->info.iovdd_gpio = devm_gpiod_get_optional(dev,
|
||
|
|
+ "iovdd", GPIOD_ASIS);
|
||
|
|
+ if (IS_ERR_OR_NULL(panel->info.iovdd_gpio))
|
||
|
|
+ DRM_WARN("can't get panel iovdd gpio: %ld\n",
|
||
|
|
+ PTR_ERR(panel->info.iovdd_gpio));
|
||
|
|
+
|
||
|
|
panel->info.avdd_gpio = devm_gpiod_get_optional(dev,
|
||
|
|
"avdd", GPIOD_ASIS);
|
||
|
|
if (IS_ERR_OR_NULL(panel->info.avdd_gpio))
|
||
|
|
@@ -868,6 +880,12 @@
|
||
|
|
else
|
||
|
|
info->mode.height_mm = 121;
|
||
|
|
|
||
|
|
+ rc = of_property_read_u32(lcd_node, "sprd,mipi-port", &val);
|
||
|
|
+ if (!rc)
|
||
|
|
+ info->mipi_port = val;
|
||
|
|
+ else
|
||
|
|
+ info->mipi_port = 0;
|
||
|
|
+
|
||
|
|
rc = of_property_read_u32(lcd_node, "sprd,esd-check-enable", &val);
|
||
|
|
if (!rc)
|
||
|
|
info->esd_check_en = val;
|
||
|
|
@@ -992,7 +1010,9 @@
|
||
|
|
panel->dev.class = display_class;
|
||
|
|
panel->dev.parent = parent;
|
||
|
|
panel->dev.of_node = panel->info.of_node;
|
||
|
|
- dev_set_name(&panel->dev, "panel0");
|
||
|
|
+ /* name per dsi host so two hosts never collide on -EEXIST */
|
||
|
|
+ dev_set_name(&panel->dev,
|
||
|
|
+ panel->info.mipi_port == SPRD_DSI_1 ? "panel1" : "panel0");
|
||
|
|
dev_set_drvdata(&panel->dev, panel);
|
||
|
|
|
||
|
|
return device_register(&panel->dev);
|
||
|
|
@@ -1042,7 +1062,23 @@
|
||
|
|
DRM_ERROR("parse panel info failed\n");
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
+ /*
|
||
|
|
+ * Two-way pick-one: only the panel sitting on the dsi host whose physical
|
||
|
|
+ * id matches the /lcds "sprd,mipi-port" of the cmdline-selected lcd is
|
||
|
|
+ * allowed to register. The panel on the other host bails out before
|
||
|
|
+ * drm_panel_add()/mipi_dsi_attach(), so there is exactly one panel in the
|
||
|
|
+ * system on the correct dsi -- no dual-host collision (-EEXIST / shared
|
||
|
|
+ * of_node -> first-match-wins confusion in of_drm_find_panel).
|
||
|
|
+ */
|
||
|
|
+ {
|
||
|
|
+ bool host_is_dsi1 = of_device_is_compatible(slave->host->dev->of_node,"sprd,qogirn6pro-s-dsi-host");
|
||
|
|
+ u32 host_port = host_is_dsi1 ? SPRD_DSI_1 : SPRD_DSI_0;
|
||
|
|
|
||
|
|
+ if (host_port != panel->info.mipi_port) {
|
||
|
|
+ DRM_INFO("panel on dsi%d skipped, lcd_name selects dsi%d\n",host_port, panel->info.mipi_port);
|
||
|
|
+ return -ENODEV;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
ret = sprd_panel_gpio_request(&slave->dev, panel);
|
||
|
|
if (ret) {
|
||
|
|
DRM_WARN("gpio is not ready, panel probe deferred\n");
|
||
|
|
diff --git a/drivers/gpu/drm/sprd/sprd_dsi_panel.h b/drivers/gpu/drm/sprd/sprd_dsi_panel.h
|
||
|
|
index 62f86794..6f4866d 100644
|
||
|
|
--- a/drivers/gpu/drm/sprd/sprd_dsi_panel.h
|
||
|
|
+++ b/drivers/gpu/drm/sprd/sprd_dsi_panel.h
|
||
|
|
@@ -39,6 +39,11 @@
|
||
|
|
};
|
||
|
|
|
||
|
|
enum {
|
||
|
|
+ SPRD_DSI_0 = 0,
|
||
|
|
+ SPRD_DSI_1,
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+enum {
|
||
|
|
ESD_MODE_REG_CHECK,
|
||
|
|
ESD_MODE_TE_CHECK,
|
||
|
|
ESD_MODE_MIX_CHECK,
|
||
|
|
@@ -69,6 +74,7 @@
|
||
|
|
struct drm_display_mode *buildin_modes;
|
||
|
|
int display_mode_count;
|
||
|
|
int num_buildin_modes;
|
||
|
|
+ struct gpio_desc *iovdd_gpio;
|
||
|
|
struct gpio_desc *avdd_gpio;
|
||
|
|
struct gpio_desc *avee_gpio;
|
||
|
|
struct gpio_desc *reset_gpio;
|
||
|
|
@@ -82,7 +88,8 @@
|
||
|
|
u32 output_bpc;
|
||
|
|
u32 dsc_en;
|
||
|
|
u32 dual_dsi_en;
|
||
|
|
-
|
||
|
|
+ /* dsi choose*/
|
||
|
|
+ u32 mipi_port;
|
||
|
|
/* esd check parameters*/
|
||
|
|
bool esd_check_en;
|
||
|
|
u8 esd_check_mode;
|
||
|
|
diff --git a/include/dt-bindings/soc/sprd,qogirn6pro-mask.h b/include/dt-bindings/soc/sprd,qogirn6pro-mask.h
|
||
|
|
index fb49e7ef..c35ecf0 100644
|
||
|
|
--- a/include/dt-bindings/soc/sprd,qogirn6pro-mask.h
|
||
|
|
+++ b/include/dt-bindings/soc/sprd,qogirn6pro-mask.h
|
||
|
|
@@ -4421,6 +4421,7 @@
|
||
|
|
#define MASK_DPU_VSP_APB_DISPC_SOFT_RST 0x0001
|
||
|
|
#define MASK_DPU_VSP_APB_DSI0_SOFT_RST 0x0002
|
||
|
|
#define MASK_DPU_VSP_APB_DSI1_SOFT_RST 0x0004
|
||
|
|
+#define MASK_DPU_VSP_APB_DSI1_SOFT_EN 0x0004
|
||
|
|
#define MASK_DPU_VSP_APB_DISPC_VAU_SOFT_RST 0x40000
|
||
|
|
#define MASK_DPU_VSP_APB_DPHY0_CFG_CKG_EN 0x0001
|
||
|
|
#define MASK_DPU_VSP_APB_DPHY0_REF_CKG_EN 0x0002
|
||
|
|
diff --git a/include/dt-bindings/soc/sprd,qogirn6pro-regs.h b/include/dt-bindings/soc/sprd,qogirn6pro-regs.h
|
||
|
|
index 424d13f..7522e48 100644
|
||
|
|
--- a/include/dt-bindings/soc/sprd,qogirn6pro-regs.h
|
||
|
|
+++ b/include/dt-bindings/soc/sprd,qogirn6pro-regs.h
|
||
|
|
@@ -926,6 +926,7 @@
|
||
|
|
#define REG_DISPC1_GLB_APB_AP2IPA_S0_LPC 0x00AC
|
||
|
|
#define REG_DISPC1_GLB_APB_DPTX_CTRL 0x00B0
|
||
|
|
#define REG_DPU_VSP_APB_RST 0x0004
|
||
|
|
+#define REG_DPU_VSP_APB_EN 0x0000
|
||
|
|
#define REG_IPA_GLB_APB_IPA_IP_RST 0x0000
|
||
|
|
#define REG_IPA_GLB_APB_IPA_IP_EB 0x0004
|
||
|
|
#define REG_IPA_GLB_APB_IPA_IP_LPC_CTRL 0x0008
|