Files
LibreELEC.tv/projects/Rockchip/patches/linux/default/linux-0002-rockchip-from-5.6.patch
2019-12-31 09:09:33 +00:00

3133 lines
105 KiB
Diff

From 1e0d4fb882dd98268e8431a8358a456564713d25 Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 11 Nov 2019 16:38:26 +0100
Subject: [PATCH] arm64: dts: rockchip: Add node for gpu on rk3399-roc-pc
rk3399-roc-pc has a Mali gpu, enable it for use with panfrost and mesa >19.2.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/c2b88509-129d-46d4-9e23-15d0482951be@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit ec7d731d81e794489ee8e76da221f3358d682ad0)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 7e07dae33d0f..287f97488f65 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -238,6 +238,11 @@
status = "okay";
};
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
&hdmi {
ddc-i2c-bus = <&i2c3>;
pinctrl-names = "default";
@@ -465,8 +470,6 @@
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1500000>;
regulator-ramp-delay = <1000>;
- regulator-always-on;
- regulator-boot-on;
vin-supply = <&vcc3v3_sys>;
regulator-state-mem {
From 82c5ee9ad7a5d7a4eda79c85d44f83366af9b51a Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 11 Nov 2019 15:21:39 +0100
Subject: [PATCH] arm64: dts: rockchip: Add regulators for pcie on
rk3399-roc-pc
Add regulators to pcie node from schematics.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/8fa0c3da-b64d-f47f-a9eb-b3456a3fd073@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit ec5b0af7da34fc1f62fdb93d6f7dad52369f6509)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts | 2 ++
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts
index d6b3042cffa9..2c9c13a0fca9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts
@@ -50,6 +50,8 @@
pinctrl-names = "default";
pinctrl-0 = <&pcie_perst>;
vpcie3v3-supply = <&vcc3v3_pcie>;
+ vpcie1v8-supply = <&vcc1v8_pmu>;
+ vpcie0v9-supply = <&vcca_0v9>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 287f97488f65..2ef8ee2eae02 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -145,6 +145,16 @@
vin-supply = <&dc_12v>;
};
+ vcca_0v9: vcca-0v9 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcca_0v9";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
/* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
From be7361ce0b9dc0094423a68a78634cf28e2383f5 Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 11 Nov 2019 15:37:41 +0100
Subject: [PATCH] arm64: dts: rockchip: Enable HDMI Sound on rk3399-roc-pc
HDMI-Sound is the only available sound card on rk3399-roc-pc, enable it.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/c9db5599-743b-bb90-999e-5989be6556ac@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit e748d355273354c486ea73f0badcc835e86c59e6)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 2ef8ee2eae02..40f446c77e89 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -260,6 +260,10 @@
status = "okay";
};
+&hdmi_sound {
+ status = "okay";
+};
+
&i2c0 {
clock-frequency = <400000>;
i2c-scl-rising-time-ns = <168>;
From 07c24d748d6cda3b0929034b31f117e55e96b096 Mon Sep 17 00:00:00 2001
From: Anand Moon <linux.amoon@gmail.com>
Date: Sun, 17 Nov 2019 14:07:28 +0000
Subject: [PATCH] arm64: dts: rockchip: Add regulators for pcie on
rk3399-rock960
As per Rock960 schematics add 0V9 and 1V8 voltage supplies to the
RK3399 PCIe block.
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
Link: https://lore.kernel.org/r/20191117140728.917-1-linux.amoon@gmail.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 635f9a6d9cdcabfbd76de24f2bccb2d7924abf59)
---
arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
index c7d48d41e184..b69f0f2cbd67 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
@@ -76,6 +76,15 @@
regulator-always-on;
vin-supply = <&vcc5v0_sys>;
};
+
+ vcc_0v9: vcc-0v9 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_0v9";
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
};
&cpu_l0 {
@@ -384,6 +393,8 @@
num-lanes = <4>;
pinctrl-names = "default";
pinctrl-0 = <&pcie_clkreqn_cpm>;
+ vpcie0v9-supply = <&vcc_0v9>;
+ vpcie1v8-supply = <&vcca_1v8>;
vpcie3v3-supply = <&vcc3v3_pcie>;
status = "okay";
};
From b20cb05a95026b28031f15f6a73cabd502bdd43a Mon Sep 17 00:00:00 2001
From: "Matwey V. Kornilov" <matwey@sai.msu.ru>
Date: Sun, 17 Nov 2019 13:15:37 +0300
Subject: [PATCH] arm64: dts: rockchip: Enable PCIe for Radxa Rock Pi 4 board
Radxa Rock Pi 4 is equipped with M.2 PCIe slot,
so enable PCIe for the board.
The changes has been tested with Intel SSD 660p series device.
01:00.0 Class 0108: Device 8086:f1a8 (rev 03)
Signed-off-by: Matwey V. Kornilov <matwey@sai.msu.ru>
Link: https://lore.kernel.org/r/20191117101545.6406-1-matwey@sai.msu.ru
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 526ba2e2cf61cfae1c20c55e6fb0a2528751501c)
---
arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
index 188d9dfc297b..45b6c0eeb5cd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
@@ -463,6 +463,20 @@
pmu1830-supply = <&vcc_3v0>;
};
+&pcie_phy {
+ status = "okay";
+};
+
+&pcie0 {
+ ep-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>;
+ max-link-speed = <2>;
+ num-lanes = <4>;
+ pinctrl-0 = <&pcie_clkreqnb_cpm>;
+ pinctrl-names = "default";
+ vpcie3v3-supply = <&vcc3v3_pcie>;
+ status = "okay";
+};
+
&pinctrl {
bt {
bt_enable_h: bt-enable-h {
From 0682bb1bf4f7fd3c1abbc913e90226717e53f1db Mon Sep 17 00:00:00 2001
From: Robin Murphy <robin.murphy@arm.com>
Date: Sat, 16 Nov 2019 12:47:19 +0000
Subject: [PATCH] arm64: dts: rockchip: Fix NanoPC-T4 cooling maps
Although it appeared to follow logically from the bindings, apparently
the thermal framework can't properly cope with a single cooling device
being shared between multiple maps. The CPU zone is probably easier to
overheat, so remove the references to the (optional) fan from the GPU
cooling zone to avoid things getting confused. Hopefully GPU-intensive
tasks will leak enough heat across to the CPU zone to still hit the
fan trips before reaching critical GPU temperatures.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/5bb39f3115df1a487d717d3ae87e523b03749379.1573908197.git.robin.murphy@arm.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit a793e19c15f25a126138ac4ae9facf9204754af3)
---
arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts | 27 -----------------------
1 file changed, 27 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
index 2a127985ab17..d3ed8e5e770f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
@@ -94,33 +94,6 @@
};
};
-&gpu_thermal {
- trips {
- gpu_warm: gpu_warm {
- temperature = <55000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- gpu_hot: gpu_hot {
- temperature = <65000>;
- hysteresis = <2000>;
- type = "active";
- };
- };
- cooling-maps {
- map1 {
- trip = <&gpu_warm>;
- cooling-device = <&fan THERMAL_NO_LIMIT 1>;
- };
-
- map2 {
- trip = <&gpu_hot>;
- cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
- };
- };
-};
-
&pinctrl {
ir {
ir_rx: ir-rx {
From 45670e4cda962766c8f845d4417585efac79db91 Mon Sep 17 00:00:00 2001
From: Robin Murphy <robin.murphy@arm.com>
Date: Sat, 16 Nov 2019 12:47:20 +0000
Subject: [PATCH] arm64: dts: rockchip: Improve nanopi4 PCIe
Expand the power tree description with the 0V9 and 1V8 supplies to the
RK3399 PCIe block. The NanoPis M4 and NEO4 just route 2 lanes to the
user expansion pins, so there's not much more to say at the board level
for them; NanoPC-T4 has a standard M.2 connector so we can at least
claim the 3.3V supply to that too.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/a04a17f4b9b12e8698c76b34e7ca22f0c81845ce.1573908195.git.robin.murphy@arm.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 876816b2679f0bf2bdc5f9d04b00f58f419d88e2)
---
arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts | 5 +++++
arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi | 27 +++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
index d3ed8e5e770f..e0d75617bb7e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
@@ -94,6 +94,11 @@
};
};
+&pcie0 {
+ num-lanes = <4>;
+ vpcie3v3-supply = <&vcc3v3_sys>;
+};
+
&pinctrl {
ir {
ir_rx: ir-rx {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
index b788ae4f47f0..c88018a0ef35 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
@@ -48,7 +48,7 @@
};
/* switched by pmic_sleep */
- vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
+ vcc1v8_s3: vcc1v8-s3 {
compatible = "regulator-fixed";
regulator-always-on;
regulator-boot-on;
@@ -71,6 +71,27 @@
vin-supply = <&vcc3v3_sys>;
};
+ /*
+ * Really, this is supplied by vcc_1v8, and vcc1v8_s3 only
+ * drives the enable pin, but we can't quite model that.
+ */
+ vcca0v9_s3: vcca0v9-s3 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vcca0v9_s3";
+ vin-supply = <&vcc1v8_s3>;
+ };
+
+ /* As above, actually supplied by vcc3v3_sys */
+ vcca1v8_s3: vcca1v8-s3 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcca1v8_s3";
+ vin-supply = <&vcc1v8_s3>;
+ };
+
vbus_typec: vbus-typec {
compatible = "regulator-fixed";
regulator-min-microvolt = <5000000>;
@@ -485,7 +506,9 @@
&pcie0 {
ep-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>;
max-link-speed = <2>;
- num-lanes = <4>;
+ num-lanes = <2>;
+ vpcie0v9-supply = <&vcca0v9_s3>;
+ vpcie1v8-supply = <&vcca1v8_s3>;
status = "okay";
};
From 38d21a4b646ea84a67d3007e519370c2ea53c7a8 Mon Sep 17 00:00:00 2001
From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Date: Sat, 16 Nov 2019 10:52:20 +0100
Subject: [PATCH] arm64: dts: rockchip: remove 408MHz operating point from px30
It looks like the px30 is running unstable at this 408MHz operating point.
This shows in stalled threads and other big numbers of kernel exception.
At 600MHz and above it instead works stable and as expected. As the 408MHz
point doesn't even decrease the voltage compared to 600MHz, just drop this
408MHz operating point for now.
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Link: https://lore.kernel.org/r/20191116095220.31122-1-heiko@sntech.de
(cherry picked from commit 8554723e664d8ac2a0e2e07c81e88cd15b75b0c6)
---
arch/arm64/boot/dts/rockchip/px30.dtsi | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 8812b70f3911..633eb917220a 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -113,16 +113,11 @@
compatible = "operating-points-v2";
opp-shared;
- opp-408000000 {
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <950000 950000 1350000>;
- clock-latency-ns = <40000>;
- opp-suspend;
- };
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <950000 950000 1350000>;
clock-latency-ns = <40000>;
+ opp-suspend;
};
opp-816000000 {
opp-hz = /bits/ 64 <816000000>;
From 3ac4e7b005c85ace01097bc25c12ec79846ab1c8 Mon Sep 17 00:00:00 2001
From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Date: Sat, 16 Nov 2019 10:52:48 +0100
Subject: [PATCH] arm64: dts: rockchip: add thermal infrastructure to px30
Add tsadc and necessary connections to core px30 components.
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Link: https://lore.kernel.org/r/20191116095249.31193-1-heiko@sntech.de
(cherry picked from commit 023115cdea26b914a54589db0f6caef85bed5fb0)
---
arch/arm64/boot/dts/rockchip/px30.dtsi | 64 ++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 633eb917220a..9a0f77ea4a78 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/power/px30-power.h>
#include <dt-bindings/soc/rockchip,boot-mode.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "rockchip,px30";
@@ -176,6 +177,49 @@
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
+ thermal_zones: thermal-zones {
+ soc_thermal: soc-thermal {
+ polling-delay-passive = <20>;
+ polling-delay = <1000>;
+ sustainable-power = <750>;
+ thermal-sensors = <&tsadc 0>;
+
+ trips {
+ threshold: trip-point-0 {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ target: trip-point-1 {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ soc_crit: soc-crit {
+ temperature = <115000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&target>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ contribution = <4096>;
+ };
+ };
+ };
+
+ gpu_thermal: gpu-thermal {
+ polling-delay-passive = <100>; /* milliseconds */
+ polling-delay = <1000>; /* milliseconds */
+ thermal-sensors = <&tsadc 1>;
+ };
+ };
+
xin24m: xin24m {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -640,6 +684,26 @@
};
};
+ tsadc: tsadc@ff280000 {
+ compatible = "rockchip,px30-tsadc";
+ reg = <0x0 0xff280000 0x0 0x100>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ assigned-clocks = <&cru SCLK_TSADC>;
+ assigned-clock-rates = <50000>;
+ clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+ clock-names = "tsadc", "apb_pclk";
+ resets = <&cru SRST_TSADC>;
+ reset-names = "tsadc-apb";
+ rockchip,grf = <&grf>;
+ rockchip,hw-tshut-temp = <120000>;
+ pinctrl-names = "init", "default", "sleep";
+ pinctrl-0 = <&tsadc_otp_gpio>;
+ pinctrl-1 = <&tsadc_otp_out>;
+ pinctrl-2 = <&tsadc_otp_gpio>;
+ #thermal-sensor-cells = <1>;
+ status = "disabled";
+ };
+
saradc: saradc@ff288000 {
compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc";
reg = <0x0 0xff288000 0x0 0x100>;
From 995366a674b2ef0f85f0b64ab2b4031b18154d79 Mon Sep 17 00:00:00 2001
From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Date: Sat, 16 Nov 2019 10:52:49 +0100
Subject: [PATCH] arm64: dts: rockchip: enable tsadc on px30-evb
Enable the tsadc thermal controller on px30-evb.
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Link: https://lore.kernel.org/r/20191116095249.31193-2-heiko@sntech.de
(cherry picked from commit 67dd31f71580c2832936e08cf221d1610ee44b7c)
---
arch/arm64/boot/dts/rockchip/px30-evb.dts | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/px30-evb.dts b/arch/arm64/boot/dts/rockchip/px30-evb.dts
index 936ed7d71ffc..f2fcca21c04d 100644
--- a/arch/arm64/boot/dts/rockchip/px30-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/px30-evb.dts
@@ -485,6 +485,12 @@
status = "okay";
};
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <1>;
+ status = "okay";
+};
+
&u2phy {
status = "okay";
From f6db9947742592b96c9b798a384c65e1e99c11f9 Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 11 Nov 2019 10:51:04 +0100
Subject: [PATCH] arm64: dts: rockchip: Disable HS400 for mmc on rk3399-roc-pc
Working with rootfs on two 128GB mmcs on rk3399-roc-pc.
One (mmc name 128G72, one screw hole) works fine in HS400 mode.
Other (mmc name DJNB4R, firefly on pcb, two screw holes) gets lots of
mmc1: "running CQE recovery", even hangs with damaged fs,
when running under heavy load, e.g. compiling kernel.
Both run fine with HS200.
Disabling CQ with patch mmc: core: Add MMC Command Queue Support kernel parameter [0] did not help.
[0] https://gitlab.com/ayufan-repos/rock64/linux-mainline-kernel/commit/54e264154b87dfe32a8359b2726e2d5611adbaf3
Therefore I propose to disable HS400 mode on roc-pc for now.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/367bf78a-f079-f0b4-68fe-52c86823c174@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit a8e611f634e3ace01ec7e81e4f37ae351a49f404)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 40f446c77e89..d1eb55c855b3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -674,8 +674,6 @@
&sdhci {
bus-width = <8>;
- mmc-hs400-1_8v;
- mmc-hs400-enhanced-strobe;
non-removable;
status = "okay";
};
From f9b8b424bcc054119212d85f9f63de47bb53a789 Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Tue, 12 Nov 2019 12:42:09 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix vdd_log on rk3399-roc-pc
On rk3399 vdd_log shall not exceed 1.0 V. On rk3399-roc-pc
vdd_log is presently 1118 mV. Fix by setting the min voltage
of the respective pwm-regulator down to 450 mV.
This results in a vdd_log of 953 mV.
Specify the supply to silence warning.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/d786ef47-eda8-3994-2ef2-fc4a584bcdcc@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit c38d8009ed6c41b5332b04acc39a3d6a16aae689)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index d1eb55c855b3..44617c8e0773 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -198,9 +198,9 @@
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
- regulator-min-microvolt = <800000>;
+ regulator-min-microvolt = <450000>;
regulator-max-microvolt = <1400000>;
- vin-supply = <&vcc3v3_sys>;
+ pwm-supply = <&vcc3v3_sys>;
};
};
From 98ce81464aaea1f6cd6fb624cefa0655c678097f Mon Sep 17 00:00:00 2001
From: Kever Yang <kever.yang@rock-chips.com>
Date: Mon, 11 Nov 2019 08:51:56 +0800
Subject: [PATCH] arm64: dts: rockchip: Fix min voltage for rk3399-firefly
vdd_log
The min/max value of vdd_log is decide by pwm IO voltage and its
resistors, the rk3399-firefly board's pwm regulator circuit is designed
for IO voltage at 1.8V, while the board actually use 3.0V for IO, which
at last lead to the min-microvolt to '430mV' instead of '800mV'.
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Link: https://lore.kernel.org/r/20191111005158.25070-1-kever.yang@rock-chips.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 88c5a235e88bef675d75265d066ca7d1b7f1f210)
---
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
index c706db0ee9ec..92de83dd4dbc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
@@ -206,7 +206,7 @@
regulator-name = "vdd_log";
regulator-always-on;
regulator-boot-on;
- regulator-min-microvolt = <800000>;
+ regulator-min-microvolt = <430000>;
regulator-max-microvolt = <1400000>;
vin-supply = <&vcc_sys>;
};
From fde7bc804b45a403185a5b366a02dbca37d4e89c Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 18 Nov 2019 12:23:18 +0100
Subject: [PATCH] arm64: dts: rockchip: Use correct pin for lcd-reset pinctrl
on rk3399-roc-pc
Fix typo according to schematics.
The original pin is needed to enable vcc3v0_sd in second patch of this series.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/cd5fd3a8-b0eb-9dc1-c473-9355762cdaa5@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit a308163a9d4be9feb256cc6f17ddade83f0c9543)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 44617c8e0773..6d485712f47c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -576,7 +576,7 @@
lcd-panel {
lcd_panel_reset: lcd-panel-reset {
- rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+ rockchip,pins = <4 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
From 06e7268b057fac2df6977f102c59a6ac500c26cf Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 18 Nov 2019 12:23:47 +0100
Subject: [PATCH] arm64: dts: rockchip: Add SDR104 mode to SD-card I/F on
rk3399-roc-pc
Add SDR104 capability and regulators to SD card node.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/1b9b8314-8778-2d48-6f7a-3502c2146c42@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 140e816a8083fef0d71e593873fd52e2169d15e1)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 6d485712f47c..0b3a0b9667c8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -135,6 +135,19 @@
vin-supply = <&vcc_1v8>;
};
+ vcc3v0_sd: vcc3v0-sd {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v0_sd_en>;
+ regulator-name = "vcc3v0_sd";
+ regulator-boot-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
vcc3v3_sys: vcc3v3-sys {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_sys";
@@ -610,6 +623,12 @@
};
};
+ sdmmc {
+ vcc3v0_sd_en: vcc3v0-sd-en {
+ rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -662,13 +681,15 @@
&sdmmc {
bus-width = <4>;
- cap-mmc-highspeed;
cap-sd-highspeed;
cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
disable-wp;
max-frequency = <150000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v0_sd>;
+ vqmmc-supply = <&vcc_sdio>;
status = "okay";
};
From 128ac34a7a2671f4be52720b62a04658de78e357 Mon Sep 17 00:00:00 2001
From: Markus Reichl <m.reichl@fivetechno.de>
Date: Mon, 18 Nov 2019 13:44:54 +0100
Subject: [PATCH] arm64: dts: rockchip: Enable MTD Flash on rk3399-roc-pc
rk3399-roc-pc has 16 MB SPI NOR Flash, enable it.
Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/94f44e1d-86c6-1e32-aa63-56edbd7d75f5@fivetechno.de
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit a43e29090934670233026838b05a7aa8be1d76d6)
---
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
index 0b3a0b9667c8..9a1ce3a4ae12 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
@@ -699,6 +699,16 @@
status = "okay";
};
+&spi1 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
&tcphy0 {
status = "okay";
};
From bfec0931eb1f99325fd415c5259dcace70328460 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Fri, 6 Dec 2019 11:35:42 +0100
Subject: [PATCH] ASoC: hdmi-codec: re-introduce mutex locking again
The dai codec needs to ensure that on one dai is used at any time.
This is currently protected by bit atomic operation. With this change,
it done with a mutex instead.
This change is not about functionality or efficiency. It is done with
the hope that it help maintainability in the future.
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20191206103542.485224-1-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 1442842952ccfe4178602c7a8459ac2ecb9d9e1a)
---
sound/soc/codecs/hdmi-codec.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f8b5b960e597..543363102d03 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -274,7 +274,8 @@ struct hdmi_codec_priv {
uint8_t eld[MAX_ELD_BYTES];
struct snd_pcm_chmap *chmap_info;
unsigned int chmap_idx;
- unsigned long busy;
+ struct mutex lock;
+ bool busy;
struct snd_soc_jack *jack;
unsigned int jack_status;
};
@@ -390,9 +391,10 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
int ret = 0;
- ret = test_and_set_bit(0, &hcp->busy);
- if (ret) {
+ mutex_lock(&hcp->lock);
+ if (hcp->busy) {
dev_err(dai->dev, "Only one simultaneous stream supported!\n");
+ mutex_unlock(&hcp->lock);
return -EINVAL;
}
@@ -405,21 +407,21 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
if (hcp->hcd.ops->get_eld) {
ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
hcp->eld, sizeof(hcp->eld));
+ if (ret)
+ goto err;
+
+ ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld);
+ if (ret)
+ goto err;
- if (!ret) {
- ret = snd_pcm_hw_constraint_eld(substream->runtime,
- hcp->eld);
- if (ret)
- goto err;
- }
/* Select chmap supported */
hdmi_codec_eld_chmap(hcp);
}
- return 0;
+
+ hcp->busy = true;
err:
- /* Release the exclusive lock on error */
- clear_bit(0, &hcp->busy);
+ mutex_unlock(&hcp->lock);
return ret;
}
@@ -431,7 +433,9 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
- clear_bit(0, &hcp->busy);
+ mutex_lock(&hcp->lock);
+ hcp->busy = false;
+ mutex_unlock(&hcp->lock);
}
static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
@@ -811,6 +815,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
return -ENOMEM;
hcp->hcd = *hcd;
+ mutex_init(&hcp->lock);
+
daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
if (!daidrv)
return -ENOMEM;
From b4129cd81f128d1e538ed222a1f4e5201671cb59 Mon Sep 17 00:00:00 2001
From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Date: Wed, 27 Nov 2019 14:39:09 -0800
Subject: [PATCH] ARM: dts: rockchip: Add brcm bluetooth for rk3288-veyron
This enables the Broadcom uart bluetooth driver on uart0 and gives it
ownership of its gpios. In order to use this, you must enable the
following kconfig options:
- CONFIG_BT_HCIUART_BCM
- CONFIG_SERIAL_DEV
This is applicable to rk3288-veyron series boards that use the bcm43540
wifi+bt chips.
As part of this change, also refactor the pinctrl across the various
boards. All the boards using broadcom bluetooth shouldn't touch the
bt_dev_wake pin.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Link: https://lore.kernel.org/r/20191127223909.253873-2-abhishekpandit@chromium.org
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit 8784692d2800c91330c8f8b6158204dedee97d6d)
---
arch/arm/boot/dts/rk3288-veyron-brain.dts | 9 ++++
.../boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi | 22 ++++++++
arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi | 21 --------
arch/arm/boot/dts/rk3288-veyron-fievel.dts | 2 -
arch/arm/boot/dts/rk3288-veyron-jaq.dts | 22 ++++++++
arch/arm/boot/dts/rk3288-veyron-jerry.dts | 22 ++++++++
arch/arm/boot/dts/rk3288-veyron-mickey.dts | 9 ++++
arch/arm/boot/dts/rk3288-veyron-minnie.dts | 21 ++++++++
arch/arm/boot/dts/rk3288-veyron-pinky.dts | 22 ++++++++
arch/arm/boot/dts/rk3288-veyron-speedy.dts | 21 ++++++++
arch/arm/boot/dts/rk3288-veyron.dtsi | 59 +++-------------------
11 files changed, 155 insertions(+), 75 deletions(-)
create mode 100644 arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi
diff --git a/arch/arm/boot/dts/rk3288-veyron-brain.dts b/arch/arm/boot/dts/rk3288-veyron-brain.dts
index 406146cbff29..aa33d09184ad 100644
--- a/arch/arm/boot/dts/rk3288-veyron-brain.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-brain.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include "rk3288-veyron.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
/ {
model = "Google Brain";
@@ -40,6 +41,14 @@
};
&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+ >;
+
hdmi {
vcc50_hdmi_en: vcc50-hdmi-en {
rockchip,pins = <7 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi b/arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi
new file mode 100644
index 000000000000..a10d25ac8f7b
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Veyron (and derivatives) fragment for the Broadcom 43450 bluetooth
+ * chip.
+ *
+ * Copyright 2019 Google, Inc
+ */
+
+&uart0 {
+ bluetooth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_host_wake_l>, <&bt_enable_l>,
+ <&bt_dev_wake>;
+
+ compatible = "brcm,bcm43540-bt";
+ host-wakeup-gpios = <&gpio4 RK_PD7 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
+ device-wakeup-gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+ max-speed = <3000000>;
+ brcm,bt-pcm-int-params = [01 02 00 01 01];
+ };
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
index ffb60f880b39..05112c25176d 100644
--- a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
@@ -136,27 +136,6 @@
};
&pinctrl {
- pinctrl-0 = <
- /* Common for sleep and wake, but no owners */
- &ddr0_retention
- &ddrio_pwroff
- &global_pwroff
-
- /* Wake only */
- &suspend_l_wake
- &bt_dev_wake_awake
- >;
- pinctrl-1 = <
- /* Common for sleep and wake, but no owners */
- &ddr0_retention
- &ddrio_pwroff
- &global_pwroff
-
- /* Sleep only */
- &suspend_l_sleep
- &bt_dev_wake_sleep
- >;
-
buttons {
ap_lid_int_l: ap-lid-int-l {
rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-fievel.dts b/arch/arm/boot/dts/rk3288-veyron-fievel.dts
index 9a0f55085839..7e7ef8e06b8d 100644
--- a/arch/arm/boot/dts/rk3288-veyron-fievel.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-fievel.dts
@@ -18,8 +18,6 @@
"google,veyron-fievel-rev0", "google,veyron-fievel",
"google,veyron", "rockchip,rk3288";
- /delete-node/ bt-activity;
-
vccsys: vccsys {
compatible = "regulator-fixed";
regulator-name = "vccsys";
diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
index a4966e505a2f..171ba6185b6d 100644
--- a/arch/arm/boot/dts/rk3288-veyron-jaq.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
@@ -273,6 +273,28 @@
};
&pinctrl {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Wake only */
+ &suspend_l_wake
+ &bt_dev_wake_awake
+ >;
+ pinctrl-1 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Sleep only */
+ &suspend_l_sleep
+ &bt_dev_wake_sleep
+ >;
+
buck-5v {
drv_5v: drv-5v {
rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-jerry.dts b/arch/arm/boot/dts/rk3288-veyron-jerry.dts
index a6ee44f0fe13..66f00d28801a 100644
--- a/arch/arm/boot/dts/rk3288-veyron-jerry.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-jerry.dts
@@ -418,6 +418,28 @@
};
&pinctrl {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Wake only */
+ &suspend_l_wake
+ &bt_dev_wake_awake
+ >;
+ pinctrl-1 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Sleep only */
+ &suspend_l_sleep
+ &bt_dev_wake_sleep
+ >;
+
buck-5v {
drv_5v: drv-5v {
rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-mickey.dts b/arch/arm/boot/dts/rk3288-veyron-mickey.dts
index 06a6a9554c48..ffd1121d19be 100644
--- a/arch/arm/boot/dts/rk3288-veyron-mickey.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-mickey.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include "rk3288-veyron.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
/ {
model = "Google Mickey";
@@ -411,6 +412,14 @@
};
&pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+ >;
+
hdmi {
power_hdmi_on: power-hdmi-on {
rockchip,pins = <7 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
index c833716dbe48..39f76e02875f 100644
--- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include "rk3288-veyron-chromebook.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
/ {
model = "Google Minnie";
@@ -344,6 +345,26 @@
};
&pinctrl {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Wake only */
+ &suspend_l_wake
+ >;
+ pinctrl-1 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Sleep only */
+ &suspend_l_sleep
+ >;
+
buck-5v {
drv_5v: drv-5v {
rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-pinky.dts b/arch/arm/boot/dts/rk3288-veyron-pinky.dts
index f420499f300a..71e6629cc208 100644
--- a/arch/arm/boot/dts/rk3288-veyron-pinky.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-pinky.dts
@@ -64,6 +64,28 @@
};
&pinctrl {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Wake only */
+ &suspend_l_wake
+ &bt_dev_wake_awake
+ >;
+ pinctrl-1 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Sleep only */
+ &suspend_l_sleep
+ &bt_dev_wake_sleep
+ >;
+
/delete-node/ lcd;
backlight {
diff --git a/arch/arm/boot/dts/rk3288-veyron-speedy.dts b/arch/arm/boot/dts/rk3288-veyron-speedy.dts
index 2f2989bc3f9c..e354c61a45e7 100644
--- a/arch/arm/boot/dts/rk3288-veyron-speedy.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-speedy.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include "rk3288-veyron-chromebook.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
#include "cros-ec-sbs.dtsi"
/ {
@@ -279,6 +280,26 @@
};
&pinctrl {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Wake only */
+ &suspend_l_wake
+ >;
+ pinctrl-1 = <
+ /* Common for sleep and wake, but no owners */
+ &ddr0_retention
+ &ddrio_pwroff
+ &global_pwroff
+
+ /* Sleep only */
+ &suspend_l_sleep
+ >;
+
buck-5v {
drv_5v: drv-5v {
rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi
index 7525e3dd1fc1..54a6838d73f5 100644
--- a/arch/arm/boot/dts/rk3288-veyron.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
@@ -23,30 +23,6 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
- bt_activity: bt-activity {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&bt_host_wake>;
-
- /*
- * HACK: until we have an LPM driver, we'll use an
- * ugly GPIO key to allow Bluetooth to wake from S3.
- * This is expected to only be used by BT modules that
- * use UART for comms. For BT modules that talk over
- * SDIO we should use a wakeup mechanism related to SDIO.
- *
- * Use KEY_RESERVED here since that will work as a wakeup but
- * doesn't get reported to higher levels (so doesn't confuse
- * Chrome).
- */
- bt-wake {
- label = "BT Wakeup";
- gpios = <&gpio4 RK_PD7 GPIO_ACTIVE_HIGH>;
- linux,code = <KEY_RESERVED>;
- wakeup-source;
- };
-
- };
power_button: power-button {
compatible = "gpio-keys";
@@ -82,22 +58,17 @@
clocks = <&rk808 RK808_CLKOUT1>;
clock-names = "ext_clock";
pinctrl-names = "default";
- pinctrl-0 = <&bt_enable_l>, <&wifi_enable_h>;
+ pinctrl-0 = <&wifi_enable_h>;
/*
- * Depending on the actual card populated GPIO4 D4 and D5
+ * Depending on the actual card populated GPIO4 D4
* correspond to one of these signals on the module:
*
* D4:
* - SDIO_RESET_L_WL_REG_ON
* - PDN (power down when low)
- *
- * D5:
- * - BT_I2S_WS_BT_RFDISABLE_L
- * - No connect
*/
- reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>,
- <&gpio4 RK_PD5 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>;
};
vcc_5v: vcc-5v {
@@ -481,26 +452,6 @@
};
&pinctrl {
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <
- /* Common for sleep and wake, but no owners */
- &ddr0_retention
- &ddrio_pwroff
- &global_pwroff
-
- /* Wake only */
- &bt_dev_wake_awake
- >;
- pinctrl-1 = <
- /* Common for sleep and wake, but no owners */
- &ddr0_retention
- &ddrio_pwroff
- &global_pwroff
-
- /* Sleep only */
- &bt_dev_wake_sleep
- >;
-
pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
bias-disable;
drive-strength = <8>;
@@ -622,6 +573,10 @@
bt_dev_wake_awake: bt-dev-wake-awake {
rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_output_high>;
};
+
+ bt_dev_wake: bt-dev-wake {
+ rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
};
tpm {
From 36d1c963e7e40076357ac3f65ba71fed9c829cf1 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:05 +0100
Subject: [PATCH] drm/bridge: Rename bridge helpers targeting a bridge chain
Change the prefix of bridge helpers targeting a bridge chain from
drm_bridge_ to drm_bridge_chain_ to better reflect the fact that
the operation will happen on all elements of chain, starting at the
bridge passed in argument.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-2-boris.brezillon@collabora.com
(cherry picked from commit ea099adfdf4bf35903dc1c0f59a0d60175759c70)
---
drivers/gpu/drm/drm_atomic_helper.c | 19 +++--
drivers/gpu/drm/drm_bridge.c | 125 ++++++++++++++++----------------
drivers/gpu/drm/drm_probe_helper.c | 2 +-
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 8 +-
drivers/gpu/drm/mediatek/mtk_hdmi.c | 4 +-
drivers/gpu/drm/vc4/vc4_dsi.c | 8 +-
include/drm/drm_bridge.h | 64 ++++++++--------
7 files changed, 120 insertions(+), 110 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 47936e3a506c..d0ee71b7194d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -435,8 +435,9 @@ mode_fixup(struct drm_atomic_state *state)
encoder = new_conn_state->best_encoder;
funcs = encoder->helper_private;
- ret = drm_bridge_mode_fixup(encoder->bridge, &new_crtc_state->mode,
- &new_crtc_state->adjusted_mode);
+ ret = drm_bridge_chain_mode_fixup(encoder->bridge,
+ &new_crtc_state->mode,
+ &new_crtc_state->adjusted_mode);
if (!ret) {
DRM_DEBUG_ATOMIC("Bridge fixup failed\n");
return -EINVAL;
@@ -501,7 +502,7 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
return ret;
}
- ret = drm_bridge_mode_valid(encoder->bridge, mode);
+ ret = drm_bridge_chain_mode_valid(encoder->bridge, mode);
if (ret != MODE_OK) {
DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
return ret;
@@ -1020,7 +1021,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
* Each encoder has at most one connector (since we always steal
* it away), so we won't call disable hooks twice.
*/
- drm_atomic_bridge_disable(encoder->bridge, old_state);
+ drm_atomic_bridge_chain_disable(encoder->bridge, old_state);
/* Right function depends upon target state. */
if (funcs) {
@@ -1034,7 +1035,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
}
- drm_atomic_bridge_post_disable(encoder->bridge, old_state);
+ drm_atomic_bridge_chain_post_disable(encoder->bridge,
+ old_state);
}
for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
@@ -1215,7 +1217,8 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
funcs->mode_set(encoder, mode, adjusted_mode);
}
- drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
+ drm_bridge_chain_mode_set(encoder->bridge, mode,
+ adjusted_mode);
}
}
@@ -1332,7 +1335,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
* Each encoder has at most one connector (since we always steal
* it away), so we won't call enable hooks twice.
*/
- drm_atomic_bridge_pre_enable(encoder->bridge, old_state);
+ drm_atomic_bridge_chain_pre_enable(encoder->bridge, old_state);
if (funcs) {
if (funcs->atomic_enable)
@@ -1343,7 +1346,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
funcs->commit(encoder);
}
- drm_atomic_bridge_enable(encoder->bridge, old_state);
+ drm_atomic_bridge_chain_enable(encoder->bridge, old_state);
}
drm_atomic_helper_commit_writebacks(dev, old_state);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index cba537c99e43..54c874493c57 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -172,8 +172,8 @@ void drm_bridge_detach(struct drm_bridge *bridge)
*/
/**
- * drm_bridge_mode_fixup - fixup proposed mode for all bridges in the
- * encoder chain
+ * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the
+ * encoder chain
* @bridge: bridge control structure
* @mode: desired mode to be set for the bridge
* @adjusted_mode: updated mode that works for this bridge
@@ -186,9 +186,9 @@ void drm_bridge_detach(struct drm_bridge *bridge)
* RETURNS:
* true on success, false on failure
*/
-bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
bool ret = true;
@@ -198,15 +198,16 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
if (bridge->funcs->mode_fixup)
ret = bridge->funcs->mode_fixup(bridge, mode, adjusted_mode);
- ret = ret && drm_bridge_mode_fixup(bridge->next, mode, adjusted_mode);
+ ret = ret && drm_bridge_chain_mode_fixup(bridge->next, mode,
+ adjusted_mode);
return ret;
}
-EXPORT_SYMBOL(drm_bridge_mode_fixup);
+EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
/**
- * drm_bridge_mode_valid - validate the mode against all bridges in the
- * encoder chain.
+ * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
+ * encoder chain.
* @bridge: bridge control structure
* @mode: desired mode to be validated
*
@@ -219,8 +220,9 @@ EXPORT_SYMBOL(drm_bridge_mode_fixup);
* RETURNS:
* MODE_OK on success, drm_mode_status Enum error code on failure
*/
-enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
- const struct drm_display_mode *mode)
+enum drm_mode_status
+drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode)
{
enum drm_mode_status ret = MODE_OK;
@@ -233,12 +235,12 @@ enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
if (ret != MODE_OK)
return ret;
- return drm_bridge_mode_valid(bridge->next, mode);
+ return drm_bridge_chain_mode_valid(bridge->next, mode);
}
-EXPORT_SYMBOL(drm_bridge_mode_valid);
+EXPORT_SYMBOL(drm_bridge_chain_mode_valid);
/**
- * drm_bridge_disable - disables all bridges in the encoder chain
+ * drm_bridge_chain_disable - disables all bridges in the encoder chain
* @bridge: bridge control structure
*
* Calls &drm_bridge_funcs.disable op for all the bridges in the encoder
@@ -247,20 +249,21 @@ EXPORT_SYMBOL(drm_bridge_mode_valid);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_bridge_disable(struct drm_bridge *bridge)
+void drm_bridge_chain_disable(struct drm_bridge *bridge)
{
if (!bridge)
return;
- drm_bridge_disable(bridge->next);
+ drm_bridge_chain_disable(bridge->next);
if (bridge->funcs->disable)
bridge->funcs->disable(bridge);
}
-EXPORT_SYMBOL(drm_bridge_disable);
+EXPORT_SYMBOL(drm_bridge_chain_disable);
/**
- * drm_bridge_post_disable - cleans up after disabling all bridges in the encoder chain
+ * drm_bridge_chain_post_disable - cleans up after disabling all bridges in the
+ * encoder chain
* @bridge: bridge control structure
*
* Calls &drm_bridge_funcs.post_disable op for all the bridges in the
@@ -269,7 +272,7 @@ EXPORT_SYMBOL(drm_bridge_disable);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_bridge_post_disable(struct drm_bridge *bridge)
+void drm_bridge_chain_post_disable(struct drm_bridge *bridge)
{
if (!bridge)
return;
@@ -277,25 +280,25 @@ void drm_bridge_post_disable(struct drm_bridge *bridge)
if (bridge->funcs->post_disable)
bridge->funcs->post_disable(bridge);
- drm_bridge_post_disable(bridge->next);
+ drm_bridge_chain_post_disable(bridge->next);
}
-EXPORT_SYMBOL(drm_bridge_post_disable);
+EXPORT_SYMBOL(drm_bridge_chain_post_disable);
/**
- * drm_bridge_mode_set - set proposed mode for all bridges in the
- * encoder chain
+ * drm_bridge_chain_mode_set - set proposed mode for all bridges in the
+ * encoder chain
* @bridge: bridge control structure
- * @mode: desired mode to be set for the bridge
- * @adjusted_mode: updated mode that works for this bridge
+ * @mode: desired mode to be set for the encoder chain
+ * @adjusted_mode: updated mode that works for this encoder chain
*
* Calls &drm_bridge_funcs.mode_set op for all the bridges in the
* encoder chain, starting from the first bridge to the last.
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_bridge_mode_set(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- const struct drm_display_mode *adjusted_mode)
+void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
{
if (!bridge)
return;
@@ -303,13 +306,13 @@ void drm_bridge_mode_set(struct drm_bridge *bridge,
if (bridge->funcs->mode_set)
bridge->funcs->mode_set(bridge, mode, adjusted_mode);
- drm_bridge_mode_set(bridge->next, mode, adjusted_mode);
+ drm_bridge_chain_mode_set(bridge->next, mode, adjusted_mode);
}
-EXPORT_SYMBOL(drm_bridge_mode_set);
+EXPORT_SYMBOL(drm_bridge_chain_mode_set);
/**
- * drm_bridge_pre_enable - prepares for enabling all
- * bridges in the encoder chain
+ * drm_bridge_chain_pre_enable - prepares for enabling all bridges in the
+ * encoder chain
* @bridge: bridge control structure
*
* Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder
@@ -318,20 +321,20 @@ EXPORT_SYMBOL(drm_bridge_mode_set);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_bridge_pre_enable(struct drm_bridge *bridge)
+void drm_bridge_chain_pre_enable(struct drm_bridge *bridge)
{
if (!bridge)
return;
- drm_bridge_pre_enable(bridge->next);
+ drm_bridge_chain_pre_enable(bridge->next);
if (bridge->funcs->pre_enable)
bridge->funcs->pre_enable(bridge);
}
-EXPORT_SYMBOL(drm_bridge_pre_enable);
+EXPORT_SYMBOL(drm_bridge_chain_pre_enable);
/**
- * drm_bridge_enable - enables all bridges in the encoder chain
+ * drm_bridge_chain_enable - enables all bridges in the encoder chain
* @bridge: bridge control structure
*
* Calls &drm_bridge_funcs.enable op for all the bridges in the encoder
@@ -340,7 +343,7 @@ EXPORT_SYMBOL(drm_bridge_pre_enable);
*
* Note that the bridge passed should be the one closest to the encoder
*/
-void drm_bridge_enable(struct drm_bridge *bridge)
+void drm_bridge_chain_enable(struct drm_bridge *bridge)
{
if (!bridge)
return;
@@ -348,12 +351,12 @@ void drm_bridge_enable(struct drm_bridge *bridge)
if (bridge->funcs->enable)
bridge->funcs->enable(bridge);
- drm_bridge_enable(bridge->next);
+ drm_bridge_chain_enable(bridge->next);
}
-EXPORT_SYMBOL(drm_bridge_enable);
+EXPORT_SYMBOL(drm_bridge_chain_enable);
/**
- * drm_atomic_bridge_disable - disables all bridges in the encoder chain
+ * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain
* @bridge: bridge control structure
* @state: atomic state being committed
*
@@ -364,24 +367,24 @@ EXPORT_SYMBOL(drm_bridge_enable);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_atomic_bridge_disable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
{
if (!bridge)
return;
- drm_atomic_bridge_disable(bridge->next, state);
+ drm_atomic_bridge_chain_disable(bridge->next, state);
if (bridge->funcs->atomic_disable)
bridge->funcs->atomic_disable(bridge, state);
else if (bridge->funcs->disable)
bridge->funcs->disable(bridge);
}
-EXPORT_SYMBOL(drm_atomic_bridge_disable);
+EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
/**
- * drm_atomic_bridge_post_disable - cleans up after disabling all bridges in the
- * encoder chain
+ * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
+ * in the encoder chain
* @bridge: bridge control structure
* @state: atomic state being committed
*
@@ -392,8 +395,8 @@ EXPORT_SYMBOL(drm_atomic_bridge_disable);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_atomic_bridge_post_disable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
{
if (!bridge)
return;
@@ -403,13 +406,13 @@ void drm_atomic_bridge_post_disable(struct drm_bridge *bridge,
else if (bridge->funcs->post_disable)
bridge->funcs->post_disable(bridge);
- drm_atomic_bridge_post_disable(bridge->next, state);
+ drm_atomic_bridge_chain_post_disable(bridge->next, state);
}
-EXPORT_SYMBOL(drm_atomic_bridge_post_disable);
+EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
/**
- * drm_atomic_bridge_pre_enable - prepares for enabling all bridges in the
- * encoder chain
+ * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in
+ * the encoder chain
* @bridge: bridge control structure
* @state: atomic state being committed
*
@@ -420,23 +423,23 @@ EXPORT_SYMBOL(drm_atomic_bridge_post_disable);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_atomic_bridge_pre_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
{
if (!bridge)
return;
- drm_atomic_bridge_pre_enable(bridge->next, state);
+ drm_atomic_bridge_chain_pre_enable(bridge->next, state);
if (bridge->funcs->atomic_pre_enable)
bridge->funcs->atomic_pre_enable(bridge, state);
else if (bridge->funcs->pre_enable)
bridge->funcs->pre_enable(bridge);
}
-EXPORT_SYMBOL(drm_atomic_bridge_pre_enable);
+EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
/**
- * drm_atomic_bridge_enable - enables all bridges in the encoder chain
+ * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain
* @bridge: bridge control structure
* @state: atomic state being committed
*
@@ -447,8 +450,8 @@ EXPORT_SYMBOL(drm_atomic_bridge_pre_enable);
*
* Note: the bridge passed should be the one closest to the encoder
*/
-void drm_atomic_bridge_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
{
if (!bridge)
return;
@@ -458,9 +461,9 @@ void drm_atomic_bridge_enable(struct drm_bridge *bridge,
else if (bridge->funcs->enable)
bridge->funcs->enable(bridge);
- drm_atomic_bridge_enable(bridge->next, state);
+ drm_atomic_bridge_chain_enable(bridge->next, state);
}
-EXPORT_SYMBOL(drm_atomic_bridge_enable);
+EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
#ifdef CONFIG_OF
/**
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index a7c87abe88d0..c3ea722065c4 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -112,7 +112,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
continue;
}
- ret = drm_bridge_mode_valid(encoder->bridge, mode);
+ ret = drm_bridge_chain_mode_valid(encoder->bridge, mode);
if (ret != MODE_OK) {
/* There is also no point in continuing for crtc check
* here. */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 72726f2c7a9f..d921ea36c683 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1390,7 +1390,7 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
if (ret < 0)
goto err_put_sync;
} else {
- drm_bridge_pre_enable(dsi->out_bridge);
+ drm_bridge_chain_pre_enable(dsi->out_bridge);
}
exynos_dsi_set_display_mode(dsi);
@@ -1401,7 +1401,7 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
if (ret < 0)
goto err_display_disable;
} else {
- drm_bridge_enable(dsi->out_bridge);
+ drm_bridge_chain_enable(dsi->out_bridge);
}
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
@@ -1426,10 +1426,10 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
drm_panel_disable(dsi->panel);
- drm_bridge_disable(dsi->out_bridge);
+ drm_bridge_chain_disable(dsi->out_bridge);
exynos_dsi_set_display_enable(dsi, false);
drm_panel_unprepare(dsi->panel);
- drm_bridge_post_disable(dsi->out_bridge);
+ drm_bridge_chain_post_disable(dsi->out_bridge);
dsi->state &= ~DSIM_STATE_ENABLED;
pm_runtime_put_sync(dsi->dev);
}
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index c79b1f855d89..ea68b5adccbe 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1247,8 +1247,8 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn,
struct drm_display_mode adjusted_mode;
drm_mode_copy(&adjusted_mode, mode);
- if (!drm_bridge_mode_fixup(hdmi->bridge.next, mode,
- &adjusted_mode))
+ if (!drm_bridge_chain_mode_fixup(hdmi->bridge.next, mode,
+ &adjusted_mode))
return MODE_BAD;
}
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 3f63943e5472..462b8ec040b3 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -753,9 +753,9 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
struct vc4_dsi *dsi = vc4_encoder->dsi;
struct device *dev = &dsi->pdev->dev;
- drm_bridge_disable(dsi->bridge);
+ drm_bridge_chain_disable(dsi->bridge);
vc4_dsi_ulps(dsi, true);
- drm_bridge_post_disable(dsi->bridge);
+ drm_bridge_chain_post_disable(dsi->bridge);
clk_disable_unprepare(dsi->pll_phy_clock);
clk_disable_unprepare(dsi->escape_clock);
@@ -1055,7 +1055,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
vc4_dsi_ulps(dsi, false);
- drm_bridge_pre_enable(dsi->bridge);
+ drm_bridge_chain_pre_enable(dsi->bridge);
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
DSI_PORT_WRITE(DISP0_CTRL,
@@ -1072,7 +1072,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
DSI_DISP0_ENABLE);
}
- drm_bridge_enable(dsi->bridge);
+ drm_bridge_chain_enable(dsi->bridge);
if (debug_dump_regs) {
struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 6d76c67fb819..aac01d1c0b61 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -254,9 +254,10 @@ struct drm_bridge_funcs {
* there is one) when this callback is called.
*
* Note that this function will only be invoked in the context of an
- * atomic commit. It will not be invoked from &drm_bridge_pre_enable. It
- * would be prudent to also provide an implementation of @pre_enable if
- * you are expecting driver calls into &drm_bridge_pre_enable.
+ * atomic commit. It will not be invoked from
+ * &drm_bridge_chain_pre_enable. It would be prudent to also provide an
+ * implementation of @pre_enable if you are expecting driver calls into
+ * &drm_bridge_chain_pre_enable.
*
* The @atomic_pre_enable callback is optional.
*/
@@ -279,9 +280,9 @@ struct drm_bridge_funcs {
* chain if there is one.
*
* Note that this function will only be invoked in the context of an
- * atomic commit. It will not be invoked from &drm_bridge_enable. It
- * would be prudent to also provide an implementation of @enable if
- * you are expecting driver calls into &drm_bridge_enable.
+ * atomic commit. It will not be invoked from &drm_bridge_chain_enable.
+ * It would be prudent to also provide an implementation of @enable if
+ * you are expecting driver calls into &drm_bridge_chain_enable.
*
* The @atomic_enable callback is optional.
*/
@@ -301,9 +302,10 @@ struct drm_bridge_funcs {
* signals) feeding it is still running when this callback is called.
*
* Note that this function will only be invoked in the context of an
- * atomic commit. It will not be invoked from &drm_bridge_disable. It
- * would be prudent to also provide an implementation of @disable if
- * you are expecting driver calls into &drm_bridge_disable.
+ * atomic commit. It will not be invoked from
+ * &drm_bridge_chain_disable. It would be prudent to also provide an
+ * implementation of @disable if you are expecting driver calls into
+ * &drm_bridge_chain_disable.
*
* The @atomic_disable callback is optional.
*/
@@ -325,10 +327,11 @@ struct drm_bridge_funcs {
* called.
*
* Note that this function will only be invoked in the context of an
- * atomic commit. It will not be invoked from &drm_bridge_post_disable.
+ * atomic commit. It will not be invoked from
+ * &drm_bridge_chain_post_disable.
* It would be prudent to also provide an implementation of
* @post_disable if you are expecting driver calls into
- * &drm_bridge_post_disable.
+ * &drm_bridge_chain_post_disable.
*
* The @atomic_post_disable callback is optional.
*/
@@ -406,27 +409,28 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np);
int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
struct drm_bridge *previous);
-bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
- const struct drm_display_mode *mode);
-void drm_bridge_disable(struct drm_bridge *bridge);
-void drm_bridge_post_disable(struct drm_bridge *bridge);
-void drm_bridge_mode_set(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- const struct drm_display_mode *adjusted_mode);
-void drm_bridge_pre_enable(struct drm_bridge *bridge);
-void drm_bridge_enable(struct drm_bridge *bridge);
+bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+enum drm_mode_status
+drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode);
+void drm_bridge_chain_disable(struct drm_bridge *bridge);
+void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
+void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode);
+void drm_bridge_chain_pre_enable(struct drm_bridge *bridge);
+void drm_bridge_chain_enable(struct drm_bridge *bridge);
-void drm_atomic_bridge_disable(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
-void drm_atomic_bridge_post_disable(struct drm_bridge *bridge,
+void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state);
+void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state);
+void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state);
+void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
-void drm_atomic_bridge_pre_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
-void drm_atomic_bridge_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
#ifdef CONFIG_DRM_PANEL_BRIDGE
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
From a333a8a47e260f90cf64db135af053b7a7ddd1d5 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:06 +0100
Subject: [PATCH] drm/bridge: Introduce drm_bridge_get_next_bridge()
And use it in drivers accessing the bridge->next field directly.
This is part of our attempt to make the bridge chain a double-linked list
based on the generic list helpers.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-3-boris.brezillon@collabora.com
(cherry picked from commit fadf872d9d9274a3be34d8438e0f6bb465c8f98b)
---
drivers/gpu/drm/drm_encoder.c | 2 +-
drivers/gpu/drm/mediatek/mtk_hdmi.c | 6 ++++--
drivers/gpu/drm/omapdrm/omap_drv.c | 4 ++--
drivers/gpu/drm/omapdrm/omap_encoder.c | 3 ++-
include/drm/drm_bridge.h | 13 +++++++++++++
5 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 80d88a55302e..fcd3af1ac432 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -171,7 +171,7 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
struct drm_bridge *next;
while (bridge) {
- next = bridge->next;
+ next = drm_bridge_get_next_bridge(bridge);
drm_bridge_detach(bridge);
bridge = next;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index ea68b5adccbe..96510b60733b 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1238,16 +1238,18 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn,
struct drm_display_mode *mode)
{
struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
+ struct drm_bridge *next_bridge;
dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
mode->hdisplay, mode->vdisplay, mode->vrefresh,
!!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000);
- if (hdmi->bridge.next) {
+ next_bridge = drm_bridge_get_next_bridge(&hdmi->bridge);
+ if (next_bridge) {
struct drm_display_mode adjusted_mode;
drm_mode_copy(&adjusted_mode, mode);
- if (!drm_bridge_chain_mode_fixup(hdmi->bridge.next, mode,
+ if (!drm_bridge_chain_mode_fixup(next_bridge, mode,
&adjusted_mode))
return MODE_BAD;
}
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index b3e22c890c51..d2750f60f519 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -217,8 +217,8 @@ static int omap_display_id(struct omap_dss_device *output)
} else if (output->bridge) {
struct drm_bridge *bridge = output->bridge;
- while (bridge->next)
- bridge = bridge->next;
+ while (drm_bridge_get_next_bridge(bridge))
+ bridge = drm_bridge_get_next_bridge(bridge);
node = bridge->of_node;
} else if (output->panel) {
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 24bbe9f2a32e..4f2165a37795 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -126,7 +126,8 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
for (dssdev = output; dssdev; dssdev = dssdev->next)
omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags);
- for (bridge = output->bridge; bridge; bridge = bridge->next) {
+ for (bridge = output->bridge; bridge;
+ bridge = drm_bridge_get_next_bridge(bridge)) {
if (!bridge->timings)
continue;
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index aac01d1c0b61..84bf30b3c083 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -409,6 +409,19 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np);
int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
struct drm_bridge *previous);
+/**
+ * drm_bridge_get_next_bridge() - Get the next bridge in the chain
+ * @bridge: bridge object
+ *
+ * RETURNS:
+ * the next bridge in the chain after @bridge, or NULL if @bridge is the last.
+ */
+static inline struct drm_bridge *
+drm_bridge_get_next_bridge(struct drm_bridge *bridge)
+{
+ return bridge->next;
+}
+
bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
From dc032a2e9eecfce507fd7698d2cf0f6a0e971a90 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:07 +0100
Subject: [PATCH] drm: Stop accessing encoder->bridge directly
We are about to replace the single-linked bridge list by a double-linked
one based on list.h, leading to the suppression of the encoder->bridge
field. But before we can do that we must provide a
drm_bridge_chain_get_first_bridge() bridge helper and patch all drivers
and core helpers to use it instead of directly accessing encoder->bridge.
Note that we still have 2 drivers (VC4 and Exynos) manipulating the
encoder->bridge field directly because they need to cut the bridge chain
in order to control the enable/disable sequence. This is definitely
not something we want to encourage, so let's keep those 2 oddities
around until we find a better solution.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-4-boris.brezillon@collabora.com
(cherry picked from commit 35a61fe9218a9d32a93447bdcca1d0f167cd0433)
---
drivers/gpu/drm/drm_atomic_helper.c | 26 +++++++++++++++++---------
drivers/gpu/drm/drm_encoder.c | 3 ++-
drivers/gpu/drm/drm_probe_helper.c | 4 +++-
drivers/gpu/drm/msm/edp/edp_bridge.c | 10 ++++++++--
drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 10 +++++++---
include/drm/drm_bridge.h | 15 +++++++++++++++
6 files changed, 52 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index d0ee71b7194d..62cb03d8f76e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -419,6 +419,7 @@ mode_fixup(struct drm_atomic_state *state)
for_each_new_connector_in_state(state, connector, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
WARN_ON(!!new_conn_state->best_encoder != !!new_conn_state->crtc);
@@ -435,7 +436,8 @@ mode_fixup(struct drm_atomic_state *state)
encoder = new_conn_state->best_encoder;
funcs = encoder->helper_private;
- ret = drm_bridge_chain_mode_fixup(encoder->bridge,
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ ret = drm_bridge_chain_mode_fixup(bridge,
&new_crtc_state->mode,
&new_crtc_state->adjusted_mode);
if (!ret) {
@@ -493,6 +495,7 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
struct drm_crtc *crtc,
const struct drm_display_mode *mode)
{
+ struct drm_bridge *bridge;
enum drm_mode_status ret;
ret = drm_encoder_mode_valid(encoder, mode);
@@ -502,7 +505,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
return ret;
}
- ret = drm_bridge_chain_mode_valid(encoder->bridge, mode);
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ ret = drm_bridge_chain_mode_valid(bridge, mode);
if (ret != MODE_OK) {
DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
return ret;
@@ -985,6 +989,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
/* Shut down everything that's in the changeset and currently
* still on. So need to check the old, saved state. */
@@ -1021,7 +1026,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
* Each encoder has at most one connector (since we always steal
* it away), so we won't call disable hooks twice.
*/
- drm_atomic_bridge_chain_disable(encoder->bridge, old_state);
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ drm_atomic_bridge_chain_disable(bridge, old_state);
/* Right function depends upon target state. */
if (funcs) {
@@ -1035,8 +1041,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
}
- drm_atomic_bridge_chain_post_disable(encoder->bridge,
- old_state);
+ drm_atomic_bridge_chain_post_disable(bridge, old_state);
}
for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
@@ -1190,6 +1195,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder;
struct drm_display_mode *mode, *adjusted_mode;
+ struct drm_bridge *bridge;
if (!new_conn_state->best_encoder)
continue;
@@ -1217,8 +1223,8 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
funcs->mode_set(encoder, mode, adjusted_mode);
}
- drm_bridge_chain_mode_set(encoder->bridge, mode,
- adjusted_mode);
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ drm_bridge_chain_mode_set(bridge, mode, adjusted_mode);
}
}
@@ -1317,6 +1323,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
if (!new_conn_state->best_encoder)
continue;
@@ -1335,7 +1342,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
* Each encoder has at most one connector (since we always steal
* it away), so we won't call enable hooks twice.
*/
- drm_atomic_bridge_chain_pre_enable(encoder->bridge, old_state);
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ drm_atomic_bridge_chain_pre_enable(bridge, old_state);
if (funcs) {
if (funcs->atomic_enable)
@@ -1346,7 +1354,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
funcs->commit(encoder);
}
- drm_atomic_bridge_chain_enable(encoder->bridge, old_state);
+ drm_atomic_bridge_chain_enable(bridge, old_state);
}
drm_atomic_helper_commit_writebacks(dev, old_state);
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index fcd3af1ac432..a2cc7e7241a9 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -167,9 +167,10 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
*/
if (encoder->bridge) {
- struct drm_bridge *bridge = encoder->bridge;
+ struct drm_bridge *bridge;
struct drm_bridge *next;
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
while (bridge) {
next = drm_bridge_get_next_bridge(bridge);
drm_bridge_detach(bridge);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index c3ea722065c4..576b4b7dcd89 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -101,6 +101,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
/* Step 2: Validate against encoders and crtcs */
drm_connector_for_each_possible_encoder(connector, encoder) {
+ struct drm_bridge *bridge;
struct drm_crtc *crtc;
ret = drm_encoder_mode_valid(encoder, mode);
@@ -112,7 +113,8 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
continue;
}
- ret = drm_bridge_chain_mode_valid(encoder->bridge, mode);
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ ret = drm_bridge_chain_mode_valid(bridge, mode);
if (ret != MODE_OK) {
/* There is also no point in continuing for crtc check
* here. */
diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c
index 2950bba4aca9..b65b5cc2dba2 100644
--- a/drivers/gpu/drm/msm/edp/edp_bridge.c
+++ b/drivers/gpu/drm/msm/edp/edp_bridge.c
@@ -55,8 +55,14 @@ static void edp_bridge_mode_set(struct drm_bridge *bridge,
DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if ((connector->encoder != NULL) &&
- (connector->encoder->bridge == bridge)) {
+ struct drm_encoder *encoder = connector->encoder;
+ struct drm_bridge *first_bridge;
+
+ if (!connector->encoder)
+ continue;
+
+ first_bridge = drm_bridge_chain_get_first_bridge(encoder);
+ if (bridge == first_bridge) {
msm_edp_ctrl_timing_cfg(edp->ctrl,
adjusted_mode, &connector->display_info);
break;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 2da46e3dc4ae..f2ae4c410244 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -14,6 +14,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_fb_cma_helper.h>
@@ -680,9 +681,10 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
const struct drm_display_mode *mode =
&crtc->state->adjusted_mode;
+ struct drm_bridge *bridge;
- rcar_lvds_clk_enable(encoder->base.bridge,
- mode->clock * 1000);
+ bridge = drm_bridge_chain_get_first_bridge(&encoder->base);
+ rcar_lvds_clk_enable(bridge, mode->clock * 1000);
}
rcar_du_crtc_start(rcrtc);
@@ -702,12 +704,14 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
struct rcar_du_encoder *encoder =
rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
+ struct drm_bridge *bridge;
/*
* Disable the LVDS clock output, see
* rcar_du_crtc_atomic_enable().
*/
- rcar_lvds_clk_disable(encoder->base.bridge);
+ bridge = drm_bridge_chain_get_first_bridge(&encoder->base);
+ rcar_lvds_clk_disable(bridge);
}
spin_lock_irq(&crtc->dev->event_lock);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 84bf30b3c083..c5e55e10fd1c 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -25,6 +25,7 @@
#include <linux/list.h>
#include <linux/ctype.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_modes.h>
@@ -422,6 +423,20 @@ drm_bridge_get_next_bridge(struct drm_bridge *bridge)
return bridge->next;
}
+/**
+ * drm_bridge_chain_get_first_bridge() - Get the first bridge in the chain
+ * @encoder: encoder object
+ *
+ * RETURNS:
+ * the first bridge in the chain, or NULL if @encoder has no bridge attached
+ * to it.
+ */
+static inline struct drm_bridge *
+drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
+{
+ return encoder->bridge;
+}
+
bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
From 66063eb67a63ff30b49639314b3266085ea630cd Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:08 +0100
Subject: [PATCH] drm/bridge: Make the bridge chain a double-linked list
So that each element in the chain can easily access its predecessor.
This will be needed to support bus format negotiation between elements
of the bridge chain.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-5-boris.brezillon@collabora.com
(cherry picked from commit 05193dc38197021894b17239fafbd2eb1afe5a45)
---
drivers/gpu/drm/drm_bridge.c | 171 +++++++++++++++++++++-----------
drivers/gpu/drm/drm_encoder.c | 16 +--
drivers/gpu/drm/exynos/exynos_drm_dsi.c | 5 +-
drivers/gpu/drm/vc4/vc4_dsi.c | 10 +-
include/drm/drm_bridge.h | 12 ++-
include/drm/drm_encoder.h | 7 +-
6 files changed, 143 insertions(+), 78 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 54c874493c57..b6517b4fa3d1 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -55,7 +55,7 @@
* just provide additional hooks to get the desired output at the end of the
* encoder chain.
*
- * Bridges can also be chained up using the &drm_bridge.next pointer.
+ * Bridges can also be chained up using the &drm_bridge.chain_node field.
*
* Both legacy CRTC helpers and the new atomic modeset helpers support bridges.
*/
@@ -128,20 +128,21 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
bridge->dev = encoder->dev;
bridge->encoder = encoder;
+ if (previous)
+ list_add(&bridge->chain_node, &previous->chain_node);
+ else
+ list_add(&bridge->chain_node, &encoder->bridge_chain);
+
if (bridge->funcs->attach) {
ret = bridge->funcs->attach(bridge);
if (ret < 0) {
+ list_del(&bridge->chain_node);
bridge->dev = NULL;
bridge->encoder = NULL;
return ret;
}
}
- if (previous)
- previous->next = bridge;
- else
- encoder->bridge = bridge;
-
return 0;
}
EXPORT_SYMBOL(drm_bridge_attach);
@@ -157,6 +158,7 @@ void drm_bridge_detach(struct drm_bridge *bridge)
if (bridge->funcs->detach)
bridge->funcs->detach(bridge);
+ list_del(&bridge->chain_node);
bridge->dev = NULL;
}
@@ -190,18 +192,21 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- bool ret = true;
+ struct drm_encoder *encoder;
if (!bridge)
return true;
- if (bridge->funcs->mode_fixup)
- ret = bridge->funcs->mode_fixup(bridge, mode, adjusted_mode);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (!bridge->funcs->mode_fixup)
+ continue;
- ret = ret && drm_bridge_chain_mode_fixup(bridge->next, mode,
- adjusted_mode);
+ if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode))
+ return false;
+ }
- return ret;
+ return true;
}
EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
@@ -224,18 +229,24 @@ enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
const struct drm_display_mode *mode)
{
- enum drm_mode_status ret = MODE_OK;
+ struct drm_encoder *encoder;
if (!bridge)
- return ret;
+ return MODE_OK;
- if (bridge->funcs->mode_valid)
- ret = bridge->funcs->mode_valid(bridge, mode);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ enum drm_mode_status ret;
+
+ if (!bridge->funcs->mode_valid)
+ continue;
- if (ret != MODE_OK)
- return ret;
+ ret = bridge->funcs->mode_valid(bridge, mode);
+ if (ret != MODE_OK)
+ return ret;
+ }
- return drm_bridge_chain_mode_valid(bridge->next, mode);
+ return MODE_OK;
}
EXPORT_SYMBOL(drm_bridge_chain_mode_valid);
@@ -251,13 +262,20 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_valid);
*/
void drm_bridge_chain_disable(struct drm_bridge *bridge)
{
+ struct drm_encoder *encoder;
+ struct drm_bridge *iter;
+
if (!bridge)
return;
- drm_bridge_chain_disable(bridge->next);
+ encoder = bridge->encoder;
+ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ if (iter->funcs->disable)
+ iter->funcs->disable(iter);
- if (bridge->funcs->disable)
- bridge->funcs->disable(bridge);
+ if (iter == bridge)
+ break;
+ }
}
EXPORT_SYMBOL(drm_bridge_chain_disable);
@@ -274,13 +292,16 @@ EXPORT_SYMBOL(drm_bridge_chain_disable);
*/
void drm_bridge_chain_post_disable(struct drm_bridge *bridge)
{
+ struct drm_encoder *encoder;
+
if (!bridge)
return;
- if (bridge->funcs->post_disable)
- bridge->funcs->post_disable(bridge);
-
- drm_bridge_chain_post_disable(bridge->next);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (bridge->funcs->post_disable)
+ bridge->funcs->post_disable(bridge);
+ }
}
EXPORT_SYMBOL(drm_bridge_chain_post_disable);
@@ -300,13 +321,16 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{
+ struct drm_encoder *encoder;
+
if (!bridge)
return;
- if (bridge->funcs->mode_set)
- bridge->funcs->mode_set(bridge, mode, adjusted_mode);
-
- drm_bridge_chain_mode_set(bridge->next, mode, adjusted_mode);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (bridge->funcs->mode_set)
+ bridge->funcs->mode_set(bridge, mode, adjusted_mode);
+ }
}
EXPORT_SYMBOL(drm_bridge_chain_mode_set);
@@ -323,13 +347,17 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_set);
*/
void drm_bridge_chain_pre_enable(struct drm_bridge *bridge)
{
+ struct drm_encoder *encoder;
+ struct drm_bridge *iter;
+
if (!bridge)
return;
- drm_bridge_chain_pre_enable(bridge->next);
-
- if (bridge->funcs->pre_enable)
- bridge->funcs->pre_enable(bridge);
+ encoder = bridge->encoder;
+ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ if (iter->funcs->pre_enable)
+ iter->funcs->pre_enable(iter);
+ }
}
EXPORT_SYMBOL(drm_bridge_chain_pre_enable);
@@ -345,13 +373,16 @@ EXPORT_SYMBOL(drm_bridge_chain_pre_enable);
*/
void drm_bridge_chain_enable(struct drm_bridge *bridge)
{
+ struct drm_encoder *encoder;
+
if (!bridge)
return;
- if (bridge->funcs->enable)
- bridge->funcs->enable(bridge);
-
- drm_bridge_chain_enable(bridge->next);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (bridge->funcs->enable)
+ bridge->funcs->enable(bridge);
+ }
}
EXPORT_SYMBOL(drm_bridge_chain_enable);
@@ -370,15 +401,22 @@ EXPORT_SYMBOL(drm_bridge_chain_enable);
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
+ struct drm_encoder *encoder;
+ struct drm_bridge *iter;
+
if (!bridge)
return;
- drm_atomic_bridge_chain_disable(bridge->next, state);
+ encoder = bridge->encoder;
+ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ if (iter->funcs->atomic_disable)
+ iter->funcs->atomic_disable(iter, state);
+ else if (iter->funcs->disable)
+ iter->funcs->disable(iter);
- if (bridge->funcs->atomic_disable)
- bridge->funcs->atomic_disable(bridge, state);
- else if (bridge->funcs->disable)
- bridge->funcs->disable(bridge);
+ if (iter == bridge)
+ break;
+ }
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
@@ -398,15 +436,18 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
+ struct drm_encoder *encoder;
+
if (!bridge)
return;
- if (bridge->funcs->atomic_post_disable)
- bridge->funcs->atomic_post_disable(bridge, state);
- else if (bridge->funcs->post_disable)
- bridge->funcs->post_disable(bridge);
-
- drm_atomic_bridge_chain_post_disable(bridge->next, state);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (bridge->funcs->atomic_post_disable)
+ bridge->funcs->atomic_post_disable(bridge, state);
+ else if (bridge->funcs->post_disable)
+ bridge->funcs->post_disable(bridge);
+ }
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
@@ -426,15 +467,22 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
+ struct drm_encoder *encoder;
+ struct drm_bridge *iter;
+
if (!bridge)
return;
- drm_atomic_bridge_chain_pre_enable(bridge->next, state);
+ encoder = bridge->encoder;
+ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ if (iter->funcs->atomic_pre_enable)
+ iter->funcs->atomic_pre_enable(iter, state);
+ else if (iter->funcs->pre_enable)
+ iter->funcs->pre_enable(iter);
- if (bridge->funcs->atomic_pre_enable)
- bridge->funcs->atomic_pre_enable(bridge, state);
- else if (bridge->funcs->pre_enable)
- bridge->funcs->pre_enable(bridge);
+ if (iter == bridge)
+ break;
+ }
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
@@ -453,15 +501,18 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
+ struct drm_encoder *encoder;
+
if (!bridge)
return;
- if (bridge->funcs->atomic_enable)
- bridge->funcs->atomic_enable(bridge, state);
- else if (bridge->funcs->enable)
- bridge->funcs->enable(bridge);
-
- drm_atomic_bridge_chain_enable(bridge->next, state);
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (bridge->funcs->atomic_enable)
+ bridge->funcs->atomic_enable(bridge, state);
+ else if (bridge->funcs->enable)
+ bridge->funcs->enable(bridge);
+ }
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index a2cc7e7241a9..e555281f43d4 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -140,6 +140,7 @@ int drm_encoder_init(struct drm_device *dev,
goto out_put;
}
+ INIT_LIST_HEAD(&encoder->bridge_chain);
list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
encoder->index = dev->mode_config.num_encoder++;
@@ -160,23 +161,16 @@ EXPORT_SYMBOL(drm_encoder_init);
void drm_encoder_cleanup(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
+ struct drm_bridge *bridge, *next;
/* Note that the encoder_list is considered to be static; should we
* remove the drm_encoder at runtime we would have to decrement all
* the indices on the drm_encoder after us in the encoder_list.
*/
- if (encoder->bridge) {
- struct drm_bridge *bridge;
- struct drm_bridge *next;
-
- bridge = drm_bridge_chain_get_first_bridge(encoder);
- while (bridge) {
- next = drm_bridge_get_next_bridge(bridge);
- drm_bridge_detach(bridge);
- bridge = next;
- }
- }
+ list_for_each_entry_safe(bridge, next, &encoder->bridge_chain,
+ chain_node)
+ drm_bridge_detach(bridge);
drm_mode_object_unregister(dev, &encoder->base);
kfree(encoder->name);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index d921ea36c683..0e868e2594b0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -255,6 +255,7 @@ struct exynos_dsi {
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
struct drm_panel *panel;
+ struct list_head bridge_chain;
struct drm_bridge *out_bridge;
struct device *dev;
@@ -1522,7 +1523,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
if (out_bridge) {
drm_bridge_attach(encoder, out_bridge, NULL);
dsi->out_bridge = out_bridge;
- encoder->bridge = NULL;
+ list_splice(&encoder->bridge_chain, &dsi->bridge_chain);
} else {
int ret = exynos_dsi_create_connector(encoder);
@@ -1588,6 +1589,7 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
if (dsi->out_bridge->funcs->detach)
dsi->out_bridge->funcs->detach(dsi->out_bridge);
dsi->out_bridge = NULL;
+ INIT_LIST_HEAD(&dsi->bridge_chain);
}
if (drm->mode_config.poll_enabled)
@@ -1735,6 +1737,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
init_completion(&dsi->completed);
spin_lock_init(&dsi->transfer_lock);
INIT_LIST_HEAD(&dsi->transfer_list);
+ INIT_LIST_HEAD(&dsi->bridge_chain);
dsi->dsi_host.ops = &exynos_dsi_ops;
dsi->dsi_host.dev = dev;
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 462b8ec040b3..8506a0e50039 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -499,6 +499,7 @@ struct vc4_dsi {
struct mipi_dsi_host dsi_host;
struct drm_encoder *encoder;
struct drm_bridge *bridge;
+ struct list_head bridge_chain;
void __iomem *regs;
@@ -1460,6 +1461,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
GFP_KERNEL);
if (!vc4_dsi_encoder)
return -ENOMEM;
+
+ INIT_LIST_HEAD(&dsi->bridge_chain);
vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1;
vc4_dsi_encoder->dsi = dsi;
dsi->encoder = &vc4_dsi_encoder->base.base;
@@ -1610,7 +1613,7 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
* from our driver, since we need to sequence them within the
* encoder's enable/disable paths.
*/
- dsi->encoder->bridge = NULL;
+ list_splice(&dsi->encoder->bridge_chain, &dsi->bridge_chain);
if (dsi->port == 0)
vc4_debugfs_add_regset32(drm, "dsi0_regs", &dsi->regset);
@@ -1632,6 +1635,11 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
if (dsi->bridge)
pm_runtime_disable(dev);
+ /*
+ * Restore the bridge_chain so the bridge detach procedure can happen
+ * normally.
+ */
+ list_splice(&dsi->bridge_chain, &dsi->encoder->bridge_chain);
vc4_dsi_encoder_destroy(dsi->encoder);
if (dsi->port == 1)
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index c5e55e10fd1c..f6ba742b0c29 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -384,8 +384,8 @@ struct drm_bridge {
struct drm_device *dev;
/** @encoder: encoder to which this bridge is connected */
struct drm_encoder *encoder;
- /** @next: the next bridge in the encoder chain */
- struct drm_bridge *next;
+ /** @chain_node: used to form a bridge chain */
+ struct list_head chain_node;
#ifdef CONFIG_OF
/** @of_node: device node pointer to the bridge */
struct device_node *of_node;
@@ -420,7 +420,10 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
static inline struct drm_bridge *
drm_bridge_get_next_bridge(struct drm_bridge *bridge)
{
- return bridge->next;
+ if (list_is_last(&bridge->chain_node, &bridge->encoder->bridge_chain))
+ return NULL;
+
+ return list_next_entry(bridge, chain_node);
}
/**
@@ -434,7 +437,8 @@ drm_bridge_get_next_bridge(struct drm_bridge *bridge)
static inline struct drm_bridge *
drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
{
- return encoder->bridge;
+ return list_first_entry_or_null(&encoder->bridge_chain,
+ struct drm_bridge, chain_node);
}
bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 70cfca03d812..f542be87f54c 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -172,7 +172,12 @@ struct drm_encoder {
* &drm_connector_state.crtc.
*/
struct drm_crtc *crtc;
- struct drm_bridge *bridge;
+
+ /**
+ * @bridge_chain: Bridges attached to this encoder.
+ */
+ struct list_head bridge_chain;
+
const struct drm_encoder_funcs *funcs;
const struct drm_encoder_helper_funcs *helper_private;
};
From 98f83ba36df010c5b7b347d7c7493d44261dea57 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:09 +0100
Subject: [PATCH] drm/bridge: Add the drm_for_each_bridge_in_chain() helper
To iterate over all bridges attached to a specific encoder.
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-6-boris.brezillon@collabora.com
(cherry picked from commit 4ec5c9050a496a984ffdaaf2307aef353634dc87)
---
include/drm/drm_bridge.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index f6ba742b0c29..31458f4e416c 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -441,6 +441,17 @@ drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
struct drm_bridge, chain_node);
}
+/**
+ * drm_for_each_bridge_in_chain() - Iterate over all bridges present in a chain
+ * @encoder: the encoder to iterate bridges on
+ * @bridge: a bridge pointer updated to point to the current bridge at each
+ * iteration
+ *
+ * Iterate over all bridges present in the bridge chain attached to @encoder.
+ */
+#define drm_for_each_bridge_in_chain(encoder, bridge) \
+ list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node)
+
bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
From 424736c97c461c547515ddb74b9c2fa7f68cd31b Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:10 +0100
Subject: [PATCH] drm/bridge: Add the drm_bridge_get_prev_bridge() helper
The drm_bridge_get_prev_bridge() helper will be useful for bridge
drivers that want to do bus format negotiation with their neighbours.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-7-boris.brezillon@collabora.com
(cherry picked from commit ac877c64c87aff5d228cf53e40d8f68899afa815)
---
include/drm/drm_bridge.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 31458f4e416c..fac463f13424 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -426,6 +426,22 @@ drm_bridge_get_next_bridge(struct drm_bridge *bridge)
return list_next_entry(bridge, chain_node);
}
+/**
+ * drm_bridge_get_prev_bridge() - Get the previous bridge in the chain
+ * @bridge: bridge object
+ *
+ * RETURNS:
+ * the previous bridge in the chain, or NULL if @bridge is the first.
+ */
+static inline struct drm_bridge *
+drm_bridge_get_prev_bridge(struct drm_bridge *bridge)
+{
+ if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
+ return NULL;
+
+ return list_prev_entry(bridge, chain_node);
+}
+
/**
* drm_bridge_chain_get_first_bridge() - Get the first bridge in the chain
* @encoder: encoder object
From a1b8ca8d41703286c692c962fe9c417ec2e38a23 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@collabora.com>
Date: Tue, 3 Dec 2019 15:15:11 +0100
Subject: [PATCH] drm/bridge: Clarify the atomic enable/disable hooks semantics
The [pre_]enable/[post_]disable hooks are passed the old atomic state.
Update the doc and rename the arguments to make it clear.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203141515.3597631-8-boris.brezillon@collabora.com
(cherry picked from commit f3fdbc721b8bc99c692716cf9a3cf061b5a49a18)
---
drivers/gpu/drm/drm_bridge.c | 24 ++++++++++++------------
include/drm/drm_bridge.h | 8 ++++----
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index b6517b4fa3d1..c2cf0c90fa26 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -389,7 +389,7 @@ EXPORT_SYMBOL(drm_bridge_chain_enable);
/**
* drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain
* @bridge: bridge control structure
- * @state: atomic state being committed
+ * @old_state: old atomic state
*
* Calls &drm_bridge_funcs.atomic_disable (falls back on
* &drm_bridge_funcs.disable) op for all the bridges in the encoder chain,
@@ -399,7 +399,7 @@ EXPORT_SYMBOL(drm_bridge_chain_enable);
* Note: the bridge passed should be the one closest to the encoder
*/
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+ struct drm_atomic_state *old_state)
{
struct drm_encoder *encoder;
struct drm_bridge *iter;
@@ -410,7 +410,7 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
encoder = bridge->encoder;
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
if (iter->funcs->atomic_disable)
- iter->funcs->atomic_disable(iter, state);
+ iter->funcs->atomic_disable(iter, old_state);
else if (iter->funcs->disable)
iter->funcs->disable(iter);
@@ -424,7 +424,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
* drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
* in the encoder chain
* @bridge: bridge control structure
- * @state: atomic state being committed
+ * @old_state: old atomic state
*
* Calls &drm_bridge_funcs.atomic_post_disable (falls back on
* &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain,
@@ -434,7 +434,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);
* Note: the bridge passed should be the one closest to the encoder
*/
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+ struct drm_atomic_state *old_state)
{
struct drm_encoder *encoder;
@@ -444,7 +444,7 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
encoder = bridge->encoder;
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
if (bridge->funcs->atomic_post_disable)
- bridge->funcs->atomic_post_disable(bridge, state);
+ bridge->funcs->atomic_post_disable(bridge, old_state);
else if (bridge->funcs->post_disable)
bridge->funcs->post_disable(bridge);
}
@@ -455,7 +455,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
* drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in
* the encoder chain
* @bridge: bridge control structure
- * @state: atomic state being committed
+ * @old_state: old atomic state
*
* Calls &drm_bridge_funcs.atomic_pre_enable (falls back on
* &drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain,
@@ -465,7 +465,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
* Note: the bridge passed should be the one closest to the encoder
*/
void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+ struct drm_atomic_state *old_state)
{
struct drm_encoder *encoder;
struct drm_bridge *iter;
@@ -476,7 +476,7 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
encoder = bridge->encoder;
list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
if (iter->funcs->atomic_pre_enable)
- iter->funcs->atomic_pre_enable(iter, state);
+ iter->funcs->atomic_pre_enable(iter, old_state);
else if (iter->funcs->pre_enable)
iter->funcs->pre_enable(iter);
@@ -489,7 +489,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
/**
* drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain
* @bridge: bridge control structure
- * @state: atomic state being committed
+ * @old_state: old atomic state
*
* Calls &drm_bridge_funcs.atomic_enable (falls back on
* &drm_bridge_funcs.enable) op for all the bridges in the encoder chain,
@@ -499,7 +499,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
* Note: the bridge passed should be the one closest to the encoder
*/
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
- struct drm_atomic_state *state)
+ struct drm_atomic_state *old_state)
{
struct drm_encoder *encoder;
@@ -509,7 +509,7 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
encoder = bridge->encoder;
list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
if (bridge->funcs->atomic_enable)
- bridge->funcs->atomic_enable(bridge, state);
+ bridge->funcs->atomic_enable(bridge, old_state);
else if (bridge->funcs->enable)
bridge->funcs->enable(bridge);
}
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index fac463f13424..51834036a42d 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -263,7 +263,7 @@ struct drm_bridge_funcs {
* The @atomic_pre_enable callback is optional.
*/
void (*atomic_pre_enable)(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
+ struct drm_atomic_state *old_state);
/**
* @atomic_enable:
@@ -288,7 +288,7 @@ struct drm_bridge_funcs {
* The @atomic_enable callback is optional.
*/
void (*atomic_enable)(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
+ struct drm_atomic_state *old_state);
/**
* @atomic_disable:
*
@@ -311,7 +311,7 @@ struct drm_bridge_funcs {
* The @atomic_disable callback is optional.
*/
void (*atomic_disable)(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
+ struct drm_atomic_state *old_state);
/**
* @atomic_post_disable:
@@ -337,7 +337,7 @@ struct drm_bridge_funcs {
* The @atomic_post_disable callback is optional.
*/
void (*atomic_post_disable)(struct drm_bridge *bridge,
- struct drm_atomic_state *state);
+ struct drm_atomic_state *old_state);
};
/**