summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt1
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts25
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-eval.dts108
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts2
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora.dts2
-rw-r--r--arch/arm/boot/dts/imx6qdl-apalis.dtsi76
-rw-r--r--arch/arm/boot/dts/imx6ul.dtsi8
-rw-r--r--arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi25
-rw-r--r--arch/arm/boot/dts/imx7-colibri.dtsi2
-rw-r--r--arch/arm/boot/dts/imx7s.dtsi8
-rw-r--r--arch/arm/boot/dts/overlays/README33
-rw-r--r--arch/arm/boot/dts/overlays/display_10.1_lvds_cap_touch.dts35
-rw-r--r--arch/arm/boot/dts/overlays/display_7_parallel_cap_touch.dts25
-rw-r--r--arch/arm/boot/dts/overlays/display_EDT5.7_parallel_res_touch.dts.dts24
-rw-r--r--arch/arm/boot/dts/overlays/display_EDT7_parallel_res_touch.dts24
-rw-r--r--arch/arm/boot/dts/overlays/touch_cap_apalis_evb.dts20
-rw-r--r--arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_aster.dts37
-rw-r--r--arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_evb.dts31
-rw-r--r--arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_aster.dts18
-rw-r--r--arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_evb.dts50
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/dumb-vga-dac.c28
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c7
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_crtc.c53
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c40
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c46
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c110
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c16
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h1
-rw-r--r--drivers/tty/serial/imx.c19
-rw-r--r--include/drm/drm_bridge.h11
31 files changed, 795 insertions, 92 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
index 164cbb15f04c..adbd2ca0af2f 100644
--- a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
+++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
@@ -18,6 +18,7 @@ graph bindings specified in Documentation/devicetree/bindings/graph.txt.
Optional properties:
- vdd-supply: Power supply for DAC
+- de-active: data-enable pulse is active low/high/ignored
Example
-------
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index 9de45a717356..17a3dbac6695 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -98,7 +98,6 @@
compatible = "fsl,imx-parallel-display";
#address-cells = <1>;
#size-cells = <0>;
- interface-pix-fmt = "bgr666";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ipu1_lcdif>;
status = "okay";
@@ -120,13 +119,25 @@
};
};
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
backlight = <&backlight>;
+ width-mm = <115>;
+ height-mm = <86>;
+
+ data-mapping = "bgr666";
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
port {
lcd_panel_in: endpoint {
diff --git a/arch/arm/boot/dts/imx6q-apalis-eval.dts b/arch/arm/boot/dts/imx6q-apalis-eval.dts
index 707ac9a46115..5a6bff6bf458 100644
--- a/arch/arm/boot/dts/imx6q-apalis-eval.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-eval.dts
@@ -84,7 +84,6 @@
compatible = "fsl,imx-parallel-display";
#address-cells = <1>;
#size-cells = <0>;
- interface-pix-fmt = "rgb24";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ipu1_lcdif>;
status = "okay";
@@ -106,14 +105,25 @@
};
};
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
- backlight = <&backlight>;
- power-supply = <&reg_3v3_sw>;
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
+
+ width-mm = <115>;
+ height-mm = <86>;
+
+ data-mapping = "rgb24";
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
port {
lcd_panel_in: endpoint {
@@ -122,6 +132,36 @@
};
};
+ panel_lvds: panel-lvds {
+ compatible = "panel-lvds";
+
+ width-mm = <218>;
+ height-mm = <137>;
+
+ data-mapping = "vesa-24";
+
+ panel-timing {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ port {
+ lvds_panel_in: endpoint {
+ remote-endpoint = <&lvds_out>;
+ };
+ };
+ };
+
reg_pcie_switch: regulator-pcie-switch {
compatible = "regulator-fixed";
regulator-name = "pcie_switch";
@@ -140,6 +180,16 @@
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_con_in: endpoint {
+ remote-endpoint = <&vga_bridge_out>;
+ };
+ };
+ };
};
&backlight {
@@ -159,6 +209,13 @@
status = "okay";
};
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>,
+ <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+ <&clks IMX6QDL_CLK_PLL2_PFD2_396M>;
+};
+
&hdmi {
status = "okay";
};
@@ -193,9 +250,24 @@
&ldb {
status = "okay";
+
+ lvds-channel@0 {
+ status = "okay";
+ primary;
+
+ port@4 {
+ reg = <4>;
+
+ lvds_out: endpoint {
+ remote-endpoint = <&lvds_panel_in>;
+ };
+ };
+ };
};
&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reset_moci>;
/* active-high meaning opposite of regular PERST# active-low polarity */
reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
reset-gpio-active-high;
@@ -281,6 +353,24 @@
status = "okay";
};
+&vgabridge {
+ status = "okay";
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ vga_bridge_out: endpoint {
+ remote-endpoint = <&vga_con_in>;
+ };
+ };
+ };
+};
+
+&vgadisplay {
+ status = "okay";
+};
+
&iomuxc {
/*
* Mux the Apalis GPIOs
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
index 4e1c8feaef82..b94bb687be6b 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
@@ -196,6 +196,8 @@
};
&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reset_moci>;
/* active-high meaning opposite of regular PERST# active-low polarity */
reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
reset-gpio-active-high;
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 469e3d0e2827..302fd6adc8a7 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -200,6 +200,8 @@
};
&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reset_moci>;
/* active-high meaning opposite of regular PERST# active-low polarity */
reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
reset-gpio-active-high;
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 05f07ea3e8c8..0b47aecf336a 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -61,6 +61,18 @@
status = "disabled";
};
+ /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */
+ i2cddc: i2c@0 {
+ compatible = "i2c-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c_ddc>;
+ gpios = <&gpio3 16 GPIO_ACTIVE_HIGH /* sda */
+ &gpio2 30 GPIO_ACTIVE_HIGH /* scl */
+ >;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ status = "disabled";
+ };
+
reg_module_3v3: regulator-module-3v3 {
compatible = "regulator-fixed";
regulator-name = "+V3.3";
@@ -138,6 +150,54 @@
spdif-out;
status = "disabled";
};
+
+ vgabridge: bridge {
+ compatible = "dumb-vga-dac";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ de-active = <0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ vga_bridge_in: endpoint {
+ remote-endpoint = <&vga_display_out>;
+ };
+ };
+ };
+ };
+
+ vgadisplay: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "rgb565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu2_vdac>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ vga_display_in: endpoint {
+ remote-endpoint = <&ipu2_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ vga_display_out: endpoint {
+ remote-endpoint = <&vga_bridge_in>;
+ };
+ };
+ };
+
};
&audmux {
@@ -373,6 +433,10 @@
status = "disabled";
};
+&ipu2_di0_disp0 {
+ remote-endpoint = <&vga_display_in>;
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
@@ -482,10 +546,6 @@
};
&iomuxc {
- /* pins used on module */
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_reset_moci>;
-
pinctrl_apalis_gpio1: gpio2io04grp {
fsl,pins = <
MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x130b0
@@ -636,6 +696,14 @@
>;
};
+ pinctrl_i2c_ddc: gpioi2cddcgrp {
+ fsl,pins = <
+ /* DDC bitbang */
+ MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0
+ MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 2366f093cc76..9a585e5211a4 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -227,6 +227,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI1>,
<&clks IMX6UL_CLK_ECSPI1>;
clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -239,6 +241,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI2>,
<&clks IMX6UL_CLK_ECSPI2>;
clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -251,6 +255,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI3>,
<&clks IMX6UL_CLK_ECSPI3>;
clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -263,6 +269,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI4>,
<&clks IMX6UL_CLK_ECSPI4>;
clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
index 3f2746169181..b6a4cc387695 100644
--- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
@@ -52,13 +52,30 @@
clock-frequency = <16000000>;
};
- panel: panel {
- compatible = "edt,et057090dhu";
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
backlight = <&bl>;
power-supply = <&reg_3v3>;
+ width-mm = <115>;
+ height-mm = <86>;
+
+ data-mapping = "bgr666";
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
+
port {
- panel_in: endpoint {
+ lcd_panel_in: endpoint {
remote-endpoint = <&lcdif_out>;
};
};
@@ -143,7 +160,7 @@
port {
lcdif_out: endpoint {
- remote-endpoint = <&panel_in>;
+ remote-endpoint = <&lcd_panel_in>;
};
};
};
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 895fbde4d433..37aeba999be3 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -319,10 +319,10 @@
assigned-clock-rates = <400000000>;
bus-width = <8>;
fsl,tuning-step = <2>;
- max-frequency = <100000000>;
vmmc-supply = <&reg_module_3v3>;
vqmmc-supply = <&reg_DCDC3>;
non-removable;
+ sdhci-caps-mask = <0x80000000 0x0>;
};
&iomuxc {
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index a7f697b0290f..78cb374597b3 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -653,6 +653,8 @@
clocks = <&clks IMX7D_ECSPI4_ROOT_CLK>,
<&clks IMX7D_ECSPI4_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 6 7 1>, <&sdma 7 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -734,6 +736,8 @@
clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
<&clks IMX7D_ECSPI1_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 0 7 1>, <&sdma 1 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -746,6 +750,8 @@
clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
<&clks IMX7D_ECSPI2_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 2 7 1>, <&sdma 3 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -758,6 +764,8 @@
clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
<&clks IMX7D_ECSPI3_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 4 7 1>, <&sdma 5 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README
new file mode 100644
index 000000000000..737ec4a8e6e9
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/README
@@ -0,0 +1,33 @@
+Introduction
+============
+
+This directory contains Device Tree overlays.
+
+Current avalible and supported overlays
+=======================================
+
+Display
+---------------------------------------
+display_EDT5.7_parallel_res_touch.dts -> 5.7 inch display proivded by Toradex https://developer.toradex.com/products/edt-display
+display_EDT7_parallel_res_touch.dts -> 7 inch display proivded by Toradex https://developer.toradex.com/products/edt-display
+display_10.1_lvds_cap_touch.dts -> 10.1 inch lvds display proivded by Toradex
+display_7_parallel_cap_touch.dts -> Display with capacitive touch https://developer.toradex.com/products/capacitive-touch-display-7inch-parallel
+
+Touch controllers
+----------------------------------------
+touch_cap_apalis_evb.dts -> touch controller for capacitive touch displays
+touch_cap_colibri_imx6_evb.dts -> touch controller for capaccitive touch display compatible with colibri-imx6 and evaluation board
+touch_cap_colibri_imx6_aster.dts -> touch controller for capaccitive touch display compatible with colibri-imx6 and Aster board
+touch_cap_colibri_imx7_evb.dts -> touch controller for capaccitive touch display compatible with colibri-imx7 and evaluation board
+touch_cap_colibri_imx7_aster.dts -> touch controller for capaccitive touch display compatible with colibri-imx7 and Aster board
+=======================================
+
+touch_cap_apalis_evb.dts
+ -> Compatible with
+ - display_10.1_lvds_cap_touch.dts
+ - display_7_parallel_cap_touch.dts
+
+
+touch_cap_colibri_imx6_evb.dts
+touch_cap_colibri_imx7_evb.dts
+ -> When applying this overlay device has to be powercycled
diff --git a/arch/arm/boot/dts/overlays/display_10.1_lvds_cap_touch.dts b/arch/arm/boot/dts/overlays/display_10.1_lvds_cap_touch.dts
new file mode 100644
index 000000000000..3aa7df403935
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/display_10.1_lvds_cap_touch.dts
@@ -0,0 +1,35 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex,apalis_imx6q";
+ fragment@0 {
+ target-path = "/panel-dpi";
+ __overlay__ {
+ status = "disabled";
+ };
+ };
+ fragment@1 {
+ target-path="/panel-lvds";
+ __overlay__ {
+ status="okay";
+ data-mapping = "vesa-24";
+ width-mm = <1280>;
+ height-mm = <800>;
+ panel-timing {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/display_7_parallel_cap_touch.dts b/arch/arm/boot/dts/overlays/display_7_parallel_cap_touch.dts
new file mode 100644
index 000000000000..e82d58dd1ada
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/display_7_parallel_cap_touch.dts
@@ -0,0 +1,25 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex";
+ fragment@0 {
+ target-path = "/panel-dpi";
+ __overlay__ {
+ width-mm = <154>;
+ height-mm = <86>;
+ panel-timing {
+ clock-frequency = <33230769>;
+ hactive = <800>;
+ vactive = <480>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ vsync-len = <1>;
+ vfront-porch = <10>;
+ vback-porch = <33>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/display_EDT5.7_parallel_res_touch.dts.dts b/arch/arm/boot/dts/overlays/display_EDT5.7_parallel_res_touch.dts.dts
new file mode 100644
index 000000000000..da112f34e0c8
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/display_EDT5.7_parallel_res_touch.dts.dts
@@ -0,0 +1,24 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex";
+ fragment@0 {
+ target-path = "/panel-dpi";
+ __overlay__ {
+ width-mm = <116>;
+ height-mm = <86>;
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/display_EDT7_parallel_res_touch.dts b/arch/arm/boot/dts/overlays/display_EDT7_parallel_res_touch.dts
new file mode 100644
index 000000000000..85df65a7c2cd
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/display_EDT7_parallel_res_touch.dts
@@ -0,0 +1,24 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex";
+ fragment@0 {
+ target-path = "/panel-dpi";
+ __overlay__ {
+ width-mm = <155>;
+ height-mm = <91>;
+ panel-timing {
+ clock-frequency = <33230769>;
+ hactive = <800>;
+ vactive = <480>;
+ hsync-len = <128>;
+ hfront-porch = <40>;
+ hback-porch = <88>;
+ vsync-len = <1>;
+ vfront-porch = <10>;
+ vback-porch = <33>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/touch_cap_apalis_evb.dts b/arch/arm/boot/dts/overlays/touch_cap_apalis_evb.dts
new file mode 100644
index 000000000000..0ecac933b32b
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/touch_cap_apalis_evb.dts
@@ -0,0 +1,20 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex,apalis_imx6q";
+ fragment@0 {
+ target-path="/soc/aips-bus@2100000/i2c@21a0000";
+ __overlay__ {
+ status = "okay";
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <10 2>;
+ reset-gpios = <&gpio6 9 0>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_aster.dts b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_aster.dts
new file mode 100644
index 000000000000..eec97c28bd89
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_aster.dts
@@ -0,0 +1,37 @@
+/dts-v1/;
+/plugin/;
+/ {
+ compatible = "toradex,colibri-imx6dl";
+ fragment@0 {
+ target = <&weim>;
+ __overlay__{
+ status = "disabled";
+ };
+ };
+ fragment@1 {
+ target = <&iomuxc>;
+ __overlay__ {
+ pinctrl_atmel_mxt_ts: atmelmxttsgrp {
+ fsl,pins = <
+ 0x300 0x6e8 0x000 0x5 0x0 0x1b0b1
+ 0x140 0x510 0x000 0x5 0x0 0x1b0b1
+ >;
+ };
+ };
+ };
+ fragment@2 {
+ target = <&i2c3>;
+ __overlay__ {
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_mxt_ts>;
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <24 2>;
+ reset-gpios = <&gpio1 14 0>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_evb.dts b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_evb.dts
new file mode 100644
index 000000000000..ab0c7daff8b1
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx6_evb.dts
@@ -0,0 +1,31 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex,colibri-imx6dl";
+ fragment@0 {
+ target = <&i2c3>;
+ __overlay__ {
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 2>;
+ reset-gpios = <&gpio2 10 0>;
+ status = "okay";
+ };
+ };
+ };
+ fragment@1 {
+ target = <&pwm1>;
+ __overlay__ {
+ status = "disabled";
+ };
+ };
+ fragment@2 {
+ target = <&pwm4>;
+ __overlay__{
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_aster.dts b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_aster.dts
new file mode 100644
index 000000000000..40120335af38
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_aster.dts
@@ -0,0 +1,18 @@
+/dts-v1/;
+/plugin/;
+/ {
+ compatible = "toradex,colibri-imx7s";
+ fragment@0 {
+ target = <&i2c4>;
+ __overlay__ {
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <15 2>;
+ reset-gpios = <&gpio2 28 0>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_evb.dts b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_evb.dts
new file mode 100644
index 000000000000..8b54505565ad
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/touch_cap_colibri_imx7_evb.dts
@@ -0,0 +1,50 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "toradex,colibri-imx7s";
+ fragment@0 {
+ target = <&i2c4>;
+ __overlay__ {
+ atmel_mxt_ts: atmel_mxt_ts@4a {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_atmel_mxt_ts>;
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 2>;
+ reset-gpios = <&gpio1 10 0>;
+ status = "okay";
+ };
+ };
+ };
+ fragment@1 {
+ target = <&pwm2>;
+ __overlay__ {
+ status = "disabled";
+ };
+ };
+ fragment@2 {
+ target = <&pwm3>;
+ __overlay__{
+ status = "disabled";
+ };
+ };
+ fragment@3 {
+ target = <&iomuxc_lpsr>;
+ __overlay__ {
+ pinctrl_atmel_mxt_ts: atmelmxttsgrp {
+ fsl,pins = <
+ 0x0018 0x0270 0x0000 0x0 0x0 0x59
+ 0x001C 0x0274 0x0000 0x0 0x0 0x59
+ >;
+ };
+ };
+ };
+ fragment@4 {
+ target = <&uart1>;
+ __overlay__ {
+ pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1>;
+ };
+ };
+};
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index bae179af21f6..12b05708832d 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -31,7 +31,7 @@ obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
endif
-ifdef CONFIG_SND_IMX_SOC
+ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
obj-y += ssi-fiq.o
obj-y += ssi-fiq-ksym.o
endif
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 9b706789a341..2b8c3d629f2f 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -179,6 +179,7 @@ static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
static int dumb_vga_probe(struct platform_device *pdev)
{
struct dumb_vga *vga;
+ u32 de;
vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
if (!vga)
@@ -194,6 +195,23 @@ static int dumb_vga_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "No vdd regulator found: %d\n", ret);
}
+ vga->bridge.funcs = &dumb_vga_bridge_funcs;
+ vga->bridge.of_node = pdev->dev.of_node;
+ vga->bridge.timings = of_device_get_match_data(&pdev->dev);
+
+ if (!vga->bridge.timings &&
+ !of_property_read_u32(pdev->dev.of_node, "de-active", &de)) {
+ struct drm_bridge_timings *timings;
+
+ timings = devm_kzalloc(&pdev->dev, sizeof(*timings), GFP_KERNEL);
+ if (!timings)
+ return -ENOMEM;
+
+ timings->bus_flags = de ? DRM_BUS_FLAG_DE_HIGH :
+ DRM_BUS_FLAG_DE_LOW;
+ vga->bridge.timings = timings;
+ }
+
vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
if (IS_ERR(vga->ddc)) {
if (PTR_ERR(vga->ddc) == -ENODEV) {
@@ -205,10 +223,6 @@ static int dumb_vga_probe(struct platform_device *pdev)
}
}
- vga->bridge.funcs = &dumb_vga_bridge_funcs;
- vga->bridge.of_node = pdev->dev.of_node;
- vga->bridge.timings = of_device_get_match_data(&pdev->dev);
-
drm_bridge_add(&vga->bridge);
return 0;
@@ -234,7 +248,7 @@ static int dumb_vga_remove(struct platform_device *pdev)
*/
static const struct drm_bridge_timings default_dac_timings = {
/* Timing specifications, datasheet page 7 */
- .sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+ .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
.setup_time_ps = 500,
.hold_time_ps = 1500,
};
@@ -245,7 +259,7 @@ static const struct drm_bridge_timings default_dac_timings = {
*/
static const struct drm_bridge_timings ti_ths8134_dac_timings = {
/* From timing diagram, datasheet page 9 */
- .sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+ .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
/* From datasheet, page 12 */
.setup_time_ps = 3000,
/* I guess this means latched input */
@@ -258,7 +272,7 @@ static const struct drm_bridge_timings ti_ths8134_dac_timings = {
*/
static const struct drm_bridge_timings ti_ths8135_dac_timings = {
/* From timing diagram, datasheet page 14 */
- .sampling_edge = DRM_BUS_FLAG_PIXDATA_POSEDGE,
+ .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
/* From datasheet, page 16 */
.setup_time_ps = 2000,
.hold_time_ps = 500,
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index aefd04e18f93..ee5840cdb9ab 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -239,6 +239,13 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
if (ret && ret != -ENODEV)
return ret;
+ if (imxpd->bridge) {
+ const struct drm_bridge_timings *btimings = imxpd->bridge->timings;
+
+ if (btimings)
+ imxpd->bus_flags = btimings->bus_flags;
+ }
+
imxpd->dev = dev;
ret = imx_pd_register(drm, imxpd);
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
index 0abe77675b76..24b1f0c1432e 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
@@ -129,7 +129,6 @@ static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
if (mxsfb->clk_disp_axi)
clk_prepare_enable(mxsfb->clk_disp_axi);
clk_prepare_enable(mxsfb->clk);
- mxsfb_enable_axi_clk(mxsfb);
/* If it was disabled, re-enable the mode again */
writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_SET);
@@ -159,8 +158,6 @@ static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb)
reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
writel(reg, mxsfb->base + LCDC_VDCTRL4);
- mxsfb_disable_axi_clk(mxsfb);
-
clk_disable_unprepare(mxsfb->clk);
if (mxsfb->clk_disp_axi)
clk_disable_unprepare(mxsfb->clk_disp_axi);
@@ -196,6 +193,21 @@ static int mxsfb_reset_block(void __iomem *reset_addr)
return clear_poll_bit(reset_addr, MODULE_CLKGATE);
}
+static dma_addr_t mxsfb_get_fb_paddr(struct mxsfb_drm_private *mxsfb)
+{
+ struct drm_framebuffer *fb = mxsfb->pipe.plane.state->fb;
+ struct drm_gem_cma_object *gem;
+
+ if (!fb)
+ return 0;
+
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+ if (!gem)
+ return 0;
+
+ return gem->paddr;
+}
+
static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
{
struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
@@ -208,7 +220,6 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
* running. This may lead to shifted pictures (FIFO issue?), so
* first stop the controller and drain its FIFOs.
*/
- mxsfb_enable_axi_clk(mxsfb);
/* Mandatory eLCDIF reset as per the Reference Manual */
err = mxsfb_reset_block(mxsfb->base);
@@ -269,19 +280,29 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
writel(SET_DOTCLK_H_VALID_DATA_CNT(m->hdisplay),
mxsfb->base + LCDC_VDCTRL4);
-
- mxsfb_disable_axi_clk(mxsfb);
}
void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
{
+ dma_addr_t paddr;
+
+ mxsfb_enable_axi_clk(mxsfb);
mxsfb_crtc_mode_set_nofb(mxsfb);
+
+ /* Write cur_buf as well to avoid an initial corrupt frame */
+ paddr = mxsfb_get_fb_paddr(mxsfb);
+ if (paddr) {
+ writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf);
+ writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
+ }
+
mxsfb_enable_controller(mxsfb);
}
void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb)
{
mxsfb_disable_controller(mxsfb);
+ mxsfb_disable_axi_clk(mxsfb);
}
void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
@@ -289,12 +310,8 @@ void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
{
struct drm_simple_display_pipe *pipe = &mxsfb->pipe;
struct drm_crtc *crtc = &pipe->crtc;
- struct drm_framebuffer *fb = pipe->plane.state->fb;
struct drm_pending_vblank_event *event;
- struct drm_gem_cma_object *gem;
-
- if (!crtc)
- return;
+ dma_addr_t paddr;
spin_lock_irq(&crtc->dev->event_lock);
event = crtc->state->event;
@@ -309,12 +326,10 @@ void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
}
spin_unlock_irq(&crtc->dev->event_lock);
- if (!fb)
- return;
-
- gem = drm_fb_cma_get_gem_obj(fb, 0);
-
- mxsfb_enable_axi_clk(mxsfb);
- writel(gem->paddr, mxsfb->base + mxsfb->devdata->next_buf);
- mxsfb_disable_axi_clk(mxsfb);
+ paddr = mxsfb_get_fb_paddr(mxsfb);
+ if (paddr) {
+ mxsfb_enable_axi_clk(mxsfb);
+ writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
+ mxsfb_disable_axi_clk(mxsfb);
+ }
}
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index ffe5137ccaf8..2393e6d16ffd 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -98,12 +98,18 @@ static const struct drm_mode_config_funcs mxsfb_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
};
+static const struct drm_mode_config_helper_funcs mxsfb_mode_config_helpers = {
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+};
+
static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state,
struct drm_plane_state *plane_state)
{
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+ struct drm_device *drm = pipe->plane.dev;
+ pm_runtime_get_sync(drm->dev);
drm_panel_prepare(mxsfb->panel);
mxsfb_crtc_enable(mxsfb);
drm_panel_enable(mxsfb->panel);
@@ -112,10 +118,22 @@ static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe,
static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe)
{
struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
+ struct drm_device *drm = pipe->plane.dev;
+ struct drm_crtc *crtc = &pipe->crtc;
+ struct drm_pending_vblank_event *event;
drm_panel_disable(mxsfb->panel);
mxsfb_crtc_disable(mxsfb);
drm_panel_unprepare(mxsfb->panel);
+ pm_runtime_put_sync(drm->dev);
+
+ spin_lock_irq(&drm->event_lock);
+ event = crtc->state->event;
+ if (event) {
+ crtc->state->event = NULL;
+ drm_crtc_send_vblank_event(crtc, event);
+ }
+ spin_unlock_irq(&drm->event_lock);
}
static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe,
@@ -230,6 +248,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
drm->mode_config.max_width = MXSFB_MAX_XRES;
drm->mode_config.max_height = MXSFB_MAX_YRES;
drm->mode_config.funcs = &mxsfb_mode_config_funcs;
+ drm->mode_config.helper_private = &mxsfb_mode_config_helpers;
drm_mode_config_reset(drm);
@@ -414,6 +433,26 @@ static int mxsfb_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int mxsfb_suspend(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ return drm_mode_config_helper_suspend(drm);
+}
+
+static int mxsfb_resume(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ return drm_mode_config_helper_resume(drm);
+}
+#endif
+
+static const struct dev_pm_ops mxsfb_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mxsfb_suspend, mxsfb_resume)
+};
+
static struct platform_driver mxsfb_platform_driver = {
.probe = mxsfb_probe,
.remove = mxsfb_remove,
@@ -421,6 +460,7 @@ static struct platform_driver mxsfb_platform_driver = {
.driver = {
.name = "mxsfb",
.of_match_table = mxsfb_dt_ids,
+ .pm = &mxsfb_pm_ops,
},
};
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index 8a1687887ae9..542791518d7e 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -28,6 +28,11 @@
#include <video/of_display_timing.h>
#include <video/videomode.h>
+enum panel_type {
+ PANEL_LVDS,
+ PANEL_DPI
+};
+
struct panel_lvds {
struct drm_panel panel;
struct device *dev;
@@ -129,7 +134,9 @@ static int panel_lvds_get_modes(struct drm_panel *panel)
connector->display_info.height_mm = lvds->height;
drm_display_info_set_bus_formats(&connector->display_info,
&lvds->bus_format, 1);
- connector->display_info.bus_flags = lvds->data_mirror
+ drm_bus_flags_from_videomode(&lvds->video_mode,
+ &connector->display_info.bus_flags);
+ connector->display_info.bus_flags |= lvds->data_mirror
? DRM_BUS_FLAG_DATA_LSB_TO_MSB
: DRM_BUS_FLAG_DATA_MSB_TO_LSB;
@@ -150,6 +157,7 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
struct display_timing timing;
const char *mapping;
int ret;
+ enum panel_type type;
ret = of_get_display_timing(np, "panel-timing", &timing);
if (ret < 0)
@@ -179,13 +187,30 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
return -ENODEV;
}
- if (!strcmp(mapping, "jeida-18")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
- } else if (!strcmp(mapping, "jeida-24")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
- } else if (!strcmp(mapping, "vesa-24")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
- } else {
+ type = (enum panel_type)of_device_get_match_data(lvds->dev);
+ switch (type) {
+ case PANEL_LVDS:
+ if (!strcmp(mapping, "jeida-18")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
+ } else if (!strcmp(mapping, "jeida-24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
+ } else if (!strcmp(mapping, "vesa-24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
+ }
+ break;
+ case PANEL_DPI:
+ if (!strcmp(mapping, "rgb24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ } else if (!strcmp(mapping, "rgb565")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB565_1X16;
+ } else if (!strcmp(mapping, "bgr666")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
+ } else if (!strcmp(mapping, "lvds666")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
+ }
+ };
+
+ if (!lvds->bus_format) {
dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
np, "data-mapping");
return -EINVAL;
@@ -293,7 +318,8 @@ static int panel_lvds_remove(struct platform_device *pdev)
}
static const struct of_device_id panel_lvds_of_table[] = {
- { .compatible = "panel-lvds", },
+ { .compatible = "panel-lvds", .data = (void *)PANEL_LVDS },
+ { .compatible = "panel-dpi", .data = (void *)PANEL_DPI },
{ /* Sentinel */ },
};
@@ -303,7 +329,7 @@ static struct platform_driver panel_lvds_driver = {
.probe = panel_lvds_probe,
.remove = panel_lvds_remove,
.driver = {
- .name = "panel-lvds",
+ .name = "panel-generic",
.of_match_table = panel_lvds_of_table,
},
};
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 3826b444298c..3a5f2896be32 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -27,6 +27,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
+#include <asm/opcodes.h>
#include "pcie-designware.h"
@@ -39,6 +40,11 @@ enum imx6_pcie_variants {
IMX7D,
};
+struct imx6_pcie_drvdata {
+ enum imx6_pcie_variants variant;
+ int dbi_length;
+};
+
struct imx6_pcie {
struct dw_pcie *pci;
int reset_gpio;
@@ -50,7 +56,6 @@ struct imx6_pcie {
struct regmap *iomuxc_gpr;
struct reset_control *pciephy_reset;
struct reset_control *apps_reset;
- enum imx6_pcie_variants variant;
u32 tx_deemph_gen1;
u32 tx_deemph_gen2_3p5db;
u32 tx_deemph_gen2_6db;
@@ -58,6 +63,7 @@ struct imx6_pcie {
u32 tx_swing_low;
int link_gen;
struct regulator *vpcie;
+ const struct imx6_pcie_drvdata *drvdata;
};
/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -251,8 +257,14 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
unsigned int fsr, struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
- unsigned long instr = *(unsigned long *)pc;
- int reg = (instr >> 12) & 15;
+ unsigned long instr;
+ int reg;
+
+ if (user_mode(regs))
+ return 1;
+
+ instr = *(unsigned long *)pc;
+ reg = (instr >> 12) & 15;
/*
* If the instruction being executed was a read,
@@ -280,11 +292,64 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
return 1;
}
+static int imx6q_pcie_abort_handler_thumb2(unsigned long addr,
+ unsigned int fsr, struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+ unsigned long instr;
+
+ if (user_mode(regs))
+ return 1;
+
+ instr = __mem_to_opcode_thumb32(*(unsigned long *)pc);
+
+ if (__opcode_is_thumb32(instr)) {
+ /* Load word/byte and halfword immediate offset */
+ if ((instr & 0xff100000UL) == 0xf8100000UL) {
+ int reg = (instr >> 12) & 0xf;
+ unsigned long val;
+
+ if ((instr & 0x00700000UL) == 0x00100000UL)
+ val = 0xff;
+ else if ((instr & 0x00700000UL) == 0x00300000UL)
+ val = 0xffff;
+ else
+ val = 0xffffffffUL;
+
+ regs->uregs[reg] = val;
+ regs->ARM_pc += 4;
+ return 0;
+ }
+ } else {
+ instr = __mem_to_opcode_thumb16(*(unsigned long *)pc);
+
+ /* Load word/byte and halfword immediate offset */
+ if (((instr & 0xe800) == 0x6800) ||
+ ((instr & 0xf800) == 0x8800)) {
+ int reg = instr & 0x7;
+ unsigned long val;
+
+ if (instr & 0x1000)
+ val = 0xff;
+ else if (instr & 0x8000)
+ val = 0xffff;
+ else
+ val = 0xffffffffUL;
+
+ regs->uregs[reg] = val;
+ regs->ARM_pc += 2;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct device *dev = imx6_pcie->pci->dev;
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
reset_control_assert(imx6_pcie->pciephy_reset);
reset_control_assert(imx6_pcie->apps_reset);
@@ -326,7 +391,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
struct device *dev = pci->dev;
int ret = 0;
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
if (ret) {
@@ -429,7 +494,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
!imx6_pcie->gpio_active_high);
}
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
reset_control_deassert(imx6_pcie->pciephy_reset);
imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
@@ -467,7 +532,7 @@ err_pcie_phy:
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
@@ -559,7 +624,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
/* Start LTSSM. */
- if (imx6_pcie->variant == IMX7D)
+ if (imx6_pcie->drvdata->variant == IMX7D)
reset_control_deassert(imx6_pcie->apps_reset);
else
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
@@ -584,7 +649,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
tmp |= PORT_LOGIC_SPEED_CHANGE;
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
- if (imx6_pcie->variant != IMX7D) {
+ if (imx6_pcie->drvdata->variant != IMX7D) {
/*
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
* from i.MX6 family when no link speed transition
@@ -697,8 +762,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
pci->ops = &dw_pcie_ops;
imx6_pcie->pci = pci;
- imx6_pcie->variant =
- (enum imx6_pcie_variants)of_device_get_match_data(dev);
+ imx6_pcie->drvdata = of_device_get_match_data(dev);
dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@@ -742,7 +806,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie);
}
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
"pcie_inbound_axi");
@@ -770,6 +834,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)
break;
}
+ pci->dbi_length = imx6_pcie->drvdata->dbi_length;
+
/* Grab GPR config register range */
imx6_pcie->iomuxc_gpr =
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
@@ -837,11 +903,18 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
imx6_pcie_assert_core_reset(imx6_pcie);
}
+static const struct imx6_pcie_drvdata drvdata[] = {
+ [IMX6Q] = { .variant = IMX6Q, .dbi_length = 0x15c },
+ [IMX6SX] = { .variant = IMX6SX },
+ [IMX6QP] = { .variant = IMX6QP },
+ [IMX7D] = { .variant = IMX7D },
+};
+
static const struct of_device_id imx6_pcie_of_match[] = {
- { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
- { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
- { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
- { .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
+ { .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], },
+ { .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
+ { .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
+ { .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], },
{},
};
@@ -857,6 +930,8 @@ static struct platform_driver imx6_pcie_driver = {
static int __init imx6_pcie_init(void)
{
+ bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
+
/*
* Since probe() can be deferred we need to make sure that
* hook_fault_code is not called after __init memory is freed
@@ -864,7 +939,8 @@ static int __init imx6_pcie_init(void)
* we can install the handler here without risking it
* accessing some uninitialized driver state.
*/
- hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
+ hook_fault_code(8, thumb2 ? imx6q_pcie_abort_handler_thumb2 :
+ imx6q_pcie_abort_handler, SIGBUS, 0,
"external abort on non-linefetch");
return platform_driver_register(&imx6_pcie_driver);
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index acd50920c2ff..35bb36dabd58 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -619,14 +619,20 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
struct pcie_port *pp = bus->sysdata;
+ struct dw_pcie *pci;
if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn))) {
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
- if (bus->number == pp->root_bus_nr)
+ if (bus->number == pp->root_bus_nr) {
+ pci = to_dw_pcie_from_pp(pp);
+ if (pci->dbi_length && where + size > pci->dbi_length)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
return dw_pcie_rd_own_conf(pp, where, size, val);
+ }
return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
}
@@ -635,12 +641,18 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
struct pcie_port *pp = bus->sysdata;
+ struct dw_pcie *pci;
if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
return PCIBIOS_DEVICE_NOT_FOUND;
- if (bus->number == pp->root_bus_nr)
+ if (bus->number == pp->root_bus_nr) {
+ pci = to_dw_pcie_from_pp(pp);
+ if (pci->dbi_length && where + size > pci->dbi_length)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
return dw_pcie_wr_own_conf(pp, where, size, val);
+ }
return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 14dcf6646699..70dfe8929b9a 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -216,6 +216,7 @@ struct dw_pcie {
struct device *dev;
void __iomem *dbi_base;
void __iomem *dbi_base2;
+ int dbi_length;
u32 num_viewport;
u8 iatu_unroll_enabled;
struct pcie_port pp;
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 0f67197a3783..674bd0ea2491 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1966,7 +1966,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
* If the port was already initialised (eg, by a boot loader),
* try to determine the current setup.
*/
-static void __init
+static void
imx_uart_console_get_options(struct imx_port *sport, int *baud,
int *parity, int *bits)
{
@@ -2025,7 +2025,7 @@ imx_uart_console_get_options(struct imx_port *sport, int *baud,
}
}
-static int __init
+static int
imx_uart_console_setup(struct console *co, char *options)
{
struct imx_port *sport;
@@ -2068,7 +2068,7 @@ imx_uart_console_setup(struct console *co, char *options)
retval = clk_prepare(sport->clk_per);
if (retval)
- clk_disable_unprepare(sport->clk_ipg);
+ clk_unprepare(sport->clk_ipg);
error_console:
return retval;
@@ -2085,7 +2085,7 @@ static struct console imx_uart_console = {
.data = &imx_uart_uart_driver,
};
-#define IMX_CONSOLE &imx_uart_console
+#define IMX_CONSOLE (&imx_uart_console)
#ifdef CONFIG_OF
static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
@@ -2378,8 +2378,17 @@ static int imx_uart_probe(struct platform_device *pdev)
static int imx_uart_remove(struct platform_device *pdev)
{
struct imx_port *sport = platform_get_drvdata(pdev);
+ int ret;
- return uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
+ ret = uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
+
+ if (IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) && IMX_CONSOLE->index >= 0) {
+ clk_unprepare(sport->clk_ipg);
+ clk_unprepare(sport->clk_per);
+ IMX_CONSOLE->index = -1;
+ }
+
+ return ret;
}
static void imx_uart_restore_context(struct imx_port *sport)
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index bd850747ce54..85d4b51eae19 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -244,14 +244,13 @@ struct drm_bridge_funcs {
*/
struct drm_bridge_timings {
/**
- * @sampling_edge:
+ * @bus_flags:
*
- * Tells whether the bridge samples the digital input signal
- * from the display engine on the positive or negative edge of the
- * clock, this should reuse the DRM_BUS_FLAG_PIXDATA_[POS|NEG]EDGE
- * bitwise flags from the DRM connector (bit 2 and 3 valid).
+ * Tells what additional settings for the pixel data on the bus
+ * this bridge requires (like pixel signal polarity). See also
+ * &drm_display_info->bus_flags.
*/
- u32 sampling_edge;
+ u32 bus_flags;
/**
* @setup_time_ps:
*