summaryrefslogtreecommitdiff
path: root/target/arm/cubox-i/patches/3.15/rmk.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/cubox-i/patches/3.15/rmk.patch')
-rw-r--r--target/arm/cubox-i/patches/3.15/rmk.patch6640
1 files changed, 6640 insertions, 0 deletions
diff --git a/target/arm/cubox-i/patches/3.15/rmk.patch b/target/arm/cubox-i/patches/3.15/rmk.patch
new file mode 100644
index 000000000..7ccbf3b4a
--- /dev/null
+++ b/target/arm/cubox-i/patches/3.15/rmk.patch
@@ -0,0 +1,6640 @@
+ .../DocBook/media/v4l/pixfmt-packed-rgb.xml | 39 ++
+ .../devicetree/bindings/leds/leds-pwm.txt | 2 +
+ Documentation/devicetree/bindings/mmc/mmc.txt | 11 +
+ .../bindings/staging/imx-drm/fsl-imx-drm.txt | 3 +-
+ arch/arm/boot/dts/imx6dl-hummingboard.dts | 27 +
+ arch/arm/boot/dts/imx6q-cubox-i.dts | 4 +
+ arch/arm/boot/dts/imx6qdl-cubox-i.dtsi | 78 ++-
+ arch/arm/boot/dts/imx6qdl-microsom.dtsi | 98 +++
+ arch/arm/configs/imx_v6_v7_defconfig | 1 +
+ arch/arm/mach-imx/clk-imx6q.c | 12 +
+ arch/arm/mach-imx/clk-pllv3.c | 27 +-
+ drivers/Kconfig | 2 +
+ drivers/Makefile | 1 +
+ drivers/ata/ahci_imx.c | 184 +++++-
+ drivers/cec/Kconfig | 14 +
+ drivers/cec/Makefile | 1 +
+ drivers/cec/cec-dev.c | 384 +++++++++++
+ drivers/gpu/drm/drm_crtc_helper.c | 6 -
+ drivers/leds/leds-pwm.c | 144 ++--
+ drivers/mmc/core/core.c | 42 ++
+ drivers/mmc/core/host.c | 68 ++
+ drivers/mmc/core/sdio_irq.c | 41 +-
+ drivers/mmc/host/Kconfig | 63 +-
+ drivers/mmc/host/dw_mmc.c | 2 +
+ drivers/mmc/host/sdhci-acpi.c | 8 +
+ drivers/mmc/host/sdhci-bcm-kona.c | 4 +
+ drivers/mmc/host/sdhci-bcm2835.c | 4 +
+ drivers/mmc/host/sdhci-cns3xxx.c | 13 +-
+ drivers/mmc/host/sdhci-dove.c | 4 +
+ drivers/mmc/host/sdhci-esdhc-imx.c | 82 +--
+ drivers/mmc/host/sdhci-esdhc.h | 4 +-
+ drivers/mmc/host/sdhci-of-arasan.c | 4 +
+ drivers/mmc/host/sdhci-of-esdhc.c | 70 +-
+ drivers/mmc/host/sdhci-of-hlwd.c | 4 +
+ drivers/mmc/host/sdhci-pci.c | 9 +-
+ drivers/mmc/host/sdhci-pltfm.c | 4 +
+ drivers/mmc/host/sdhci-pxav2.c | 14 +-
+ drivers/mmc/host/sdhci-pxav3.c | 13 +-
+ drivers/mmc/host/sdhci-s3c.c | 36 +-
+ drivers/mmc/host/sdhci-sirf.c | 4 +
+ drivers/mmc/host/sdhci-spear.c | 5 +-
+ drivers/mmc/host/sdhci-tegra.c | 27 +-
+ drivers/mmc/host/sdhci.c | 722 ++++++++++-----------
+ drivers/mmc/host/sdhci.h | 20 +-
+ drivers/regulator/anatop-regulator.c | 1 +
+ drivers/regulator/core.c | 2 +-
+ drivers/regulator/dummy.c | 1 +
+ drivers/regulator/fixed.c | 4 +-
+ drivers/staging/imx-drm/Kconfig | 18 +
+ drivers/staging/imx-drm/Makefile | 3 +
+ drivers/staging/imx-drm/drm-ddc-connector.c | 92 +++
+ drivers/staging/imx-drm/drm-ddc-connector.h | 26 +
+ drivers/staging/imx-drm/dw-hdmi-audio.c | 652 +++++++++++++++++++
+ drivers/staging/imx-drm/dw-hdmi-audio.h | 15 +
+ drivers/staging/imx-drm/dw-hdmi-cec.c | 205 ++++++
+ drivers/staging/imx-drm/dw-hdmi-cec.h | 16 +
+ drivers/staging/imx-drm/imx-hdmi.c | 178 ++---
+ drivers/staging/imx-drm/imx-ldb.c | 21 +
+ drivers/staging/imx-drm/imx-tve.c | 63 +-
+ drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h | 5 +
+ drivers/staging/imx-drm/ipu-v3/ipu-common.c | 41 +-
+ drivers/staging/imx-drm/ipu-v3/ipu-dc.c | 94 ++-
+ drivers/staging/imx-drm/ipu-v3/ipu-di.c | 2 +-
+ drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c | 25 +-
+ drivers/staging/imx-drm/ipu-v3/ipu-dp.c | 71 +-
+ drivers/staging/imx-drm/ipu-v3/ipu-prv.h | 3 +
+ drivers/staging/imx-drm/ipuv3-crtc.c | 16 +-
+ drivers/staging/imx-drm/ipuv3-plane.c | 4 +
+ drivers/staging/imx-drm/parallel-display.c | 2 +
+ include/linux/cec-dev.h | 69 ++
+ include/linux/mmc/host.h | 8 +
+ include/linux/mmc/sdhci.h | 15 +-
+ include/uapi/linux/cec-dev.h | 34 +
+ include/uapi/linux/videodev2.h | 1 +
+ sound/soc/fsl/imx-pcm-dma.c | 2 +-
+ 75 files changed, 3162 insertions(+), 832 deletions(-)
+
+diff --git a/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml b/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
+index e1c4f8b4c0b3..88a7fe1ecaf1 100644
+--- a/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
++++ b/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
+@@ -279,6 +279,45 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
+ <entry></entry>
+ <entry></entry>
+ </row>
++ <row id="V4L2-PIX-FMT-RGB666">
++ <entry><constant>V4L2_PIX_FMT_RGB666</constant></entry>
++ <entry>'RGBH'</entry>
++ <entry></entry>
++ <entry>r<subscript>5</subscript></entry>
++ <entry>r<subscript>4</subscript></entry>
++ <entry>r<subscript>3</subscript></entry>
++ <entry>r<subscript>2</subscript></entry>
++ <entry>r<subscript>1</subscript></entry>
++ <entry>r<subscript>0</subscript></entry>
++ <entry>g<subscript>5</subscript></entry>
++ <entry>g<subscript>4</subscript></entry>
++ <entry></entry>
++ <entry>g<subscript>3</subscript></entry>
++ <entry>g<subscript>2</subscript></entry>
++ <entry>g<subscript>1</subscript></entry>
++ <entry>g<subscript>0</subscript></entry>
++ <entry>b<subscript>5</subscript></entry>
++ <entry>b<subscript>4</subscript></entry>
++ <entry>b<subscript>3</subscript></entry>
++ <entry>b<subscript>2</subscript></entry>
++ <entry></entry>
++ <entry>b<subscript>1</subscript></entry>
++ <entry>b<subscript>0</subscript></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ <entry></entry>
++ </row>
+ <row id="V4L2-PIX-FMT-BGR24">
+ <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+ <entry>'BGR3'</entry>
+diff --git a/Documentation/devicetree/bindings/leds/leds-pwm.txt b/Documentation/devicetree/bindings/leds/leds-pwm.txt
+index 7297107cf832..6c6583c35f2f 100644
+--- a/Documentation/devicetree/bindings/leds/leds-pwm.txt
++++ b/Documentation/devicetree/bindings/leds/leds-pwm.txt
+@@ -13,6 +13,8 @@ node's name represents the name of the corresponding LED.
+ For the pwms and pwm-names property please refer to:
+ Documentation/devicetree/bindings/pwm/pwm.txt
+ - max-brightness : Maximum brightness possible for the LED
++- active-low : (optional) For PWMs where the LED is wired to supply
++ rather than ground.
+ - label : (optional)
+ see Documentation/devicetree/bindings/leds/common.txt
+ - linux,default-trigger : (optional)
+diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
+index 9dce540771fb..b9b534ebc0c5 100644
+--- a/Documentation/devicetree/bindings/mmc/mmc.txt
++++ b/Documentation/devicetree/bindings/mmc/mmc.txt
+@@ -5,6 +5,8 @@ these definitions.
+ Interpreted by the OF core:
+ - reg: Registers location and length.
+ - interrupts: Interrupts used by the MMC controller.
++- clocks: Clocks needed for the host controller, if any.
++- clock-names: Goes with clocks above.
+
+ Card detection:
+ If no property below is supplied, host native card detect is used.
+@@ -39,6 +41,15 @@ If no property below is supplied, host native card detect is used.
+ - mmc-hs200-1_8v: eMMC HS200 mode(1.8V I/O) is supported
+ - mmc-hs200-1_2v: eMMC HS200 mode(1.2V I/O) is supported
+
++Card power and reset control:
++The following properties can be specified for cases where the MMC
++peripheral needs additional reset, regulator and clock lines. It is for
++example common for WiFi/BT adapters to have these separate from the main
++MMC bus:
++ - card-reset-gpios: Specify GPIOs for card reset (reset active low)
++ - card-external-vcc-supply: Regulator to drive (independent) card VCC
++ - clock with name "card_ext_clock": External clock provided to the card
++
+ *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
+ polarity properties, we have to fix the meaning of the "normal" and "inverted"
+ line levels. We choose to follow the SDHCI standard, which specifies both those
+diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
+index 3be5ce7a9654..83137ef5a1ba 100644
+--- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
++++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
+@@ -60,7 +60,8 @@ Parallel display support
+ - compatible: Should be "fsl,imx-parallel-display"
+ Optional properties:
+ - interface_pix_fmt: How this display is connected to the
+- display interface. Currently supported types: "rgb24", "rgb565", "bgr666"
++ display interface. Currently supported types: "rgb24", "rgb565", "bgr666",
++ "rgb666"
+ - edid: verbatim EDID data block describing attached display.
+ - ddc: phandle describing the i2c bus handling the display data
+ channel
+diff --git a/arch/arm/boot/dts/imx6dl-hummingboard.dts b/arch/arm/boot/dts/imx6dl-hummingboard.dts
+index 5bfae54fb780..5cfab68fe43d 100644
+--- a/arch/arm/boot/dts/imx6dl-hummingboard.dts
++++ b/arch/arm/boot/dts/imx6dl-hummingboard.dts
+@@ -67,6 +67,13 @@
+ status = "okay";
+ };
+
++&hdmi {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
++ ddc-i2c-bus = <&i2c2>;
++ status = "okay";
++};
++
+ &i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
+@@ -82,6 +89,13 @@
+ */
+ };
+
++&i2c2 {
++ clock-frequency = <100000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_hummingboard_i2c2>;
++ status = "okay";
++};
++
+ &iomuxc {
+ hummingboard {
+ pinctrl_hummingboard_flexcan1: hummingboard-flexcan1 {
+@@ -97,6 +111,12 @@
+ >;
+ };
+
++ pinctrl_hummingboard_hdmi: hummingboard-hdmi {
++ fsl,pins = <
++ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
++ >;
++ };
++
+ pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+@@ -104,6 +124,13 @@
+ >;
+ };
+
++ pinctrl_hummingboard_i2c2: hummingboard-i2c2 {
++ fsl,pins = <
++ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
++ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
++ >;
++ };
++
+ pinctrl_hummingboard_spdif: hummingboard-spdif {
+ fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
+ };
+diff --git a/arch/arm/boot/dts/imx6q-cubox-i.dts b/arch/arm/boot/dts/imx6q-cubox-i.dts
+index bc5f31e3e892..9efd8b0c8011 100644
+--- a/arch/arm/boot/dts/imx6q-cubox-i.dts
++++ b/arch/arm/boot/dts/imx6q-cubox-i.dts
+@@ -13,4 +13,8 @@
+
+ &sata {
+ status = "okay";
++ fsl,transmit-level-mV = <1104>;
++ fsl,transmit-boost-mdB = <0>;
++ fsl,transmit-atten-16ths = <9>;
++ fsl,no-spread-spectrum;
+ };
+diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
+index c2a24888a276..f45380073973 100644
+--- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
+@@ -12,6 +12,19 @@
+ pinctrl-0 = <&pinctrl_cubox_i_ir>;
+ };
+
++ pwmleds {
++ compatible = "pwm-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_cubox_i_pwm1>;
++
++ front {
++ active-low;
++ label = "imx6:red:front";
++ max-brightness = <248>;
++ pwms = <&pwm1 0 50000>;
++ };
++ };
++
+ regulators {
+ compatible = "simple-bus";
+
+@@ -55,6 +68,20 @@
+ };
+ };
+
++&hdmi {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_cubox_i_hdmi>;
++ ddc-i2c-bus = <&i2c2>;
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <100000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_cubox_i_i2c2>;
++ status = "okay";
++};
++
+ &i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cubox_i_i2c3>;
+@@ -69,6 +96,19 @@
+
+ &iomuxc {
+ cubox_i {
++ pinctrl_cubox_i_hdmi: cubox-i-hdmi {
++ fsl,pins = <
++ MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
++ >;
++ };
++
++ pinctrl_cubox_i_i2c2: cubox-i-i2c2 {
++ fsl,pins = <
++ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
++ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
++ >;
++ };
++
+ pinctrl_cubox_i_i2c3: cubox-i-i2c3 {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+@@ -82,6 +122,10 @@
+ >;
+ };
+
++ pinctrl_cubox_i_pwm1: cubox-i-pwm1-front-led {
++ fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0>;
++ };
++
+ pinctrl_cubox_i_spdif: cubox-i-spdif {
+ fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
+ };
+@@ -111,6 +155,28 @@
+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
+ >;
+ };
++
++ pinctrl_cubox_i_usdhc2_100mhz: cubox-i-usdhc2-100mhz {
++ fsl,pins = <
++ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9
++ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9
++ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
++ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
++ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
++ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130b9
++ >;
++ };
++
++ pinctrl_cubox_i_usdhc2_200mhz: cubox-i-usdhc2-200mhz {
++ fsl,pins = <
++ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9
++ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9
++ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
++ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
++ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
++ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130f9
++ >;
++ };
+ };
+ };
+
+@@ -130,9 +196,19 @@
+ status = "okay";
+ };
+
++&uart4 {
++ status = "okay";
++};
++
++&usdhc1 {
++ status = "okay";
++};
++
+ &usdhc2 {
+- pinctrl-names = "default";
++ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2>;
++ pinctrl-1 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_100mhz>;
++ pinctrl-2 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_200mhz>;
+ vmmc-supply = <&reg_3p3v>;
+ cd-gpios = <&gpio1 4 0>;
+ status = "okay";
+diff --git a/arch/arm/boot/dts/imx6qdl-microsom.dtsi b/arch/arm/boot/dts/imx6qdl-microsom.dtsi
+index d729d0b15f25..a5d72895d9ce 100644
+--- a/arch/arm/boot/dts/imx6qdl-microsom.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-microsom.dtsi
+@@ -1,9 +1,69 @@
+ /*
+ * Copyright (C) 2013,2014 Russell King
+ */
++#include <dt-bindings/gpio/gpio.h>
++/ {
++ regulators {
++ compatible = "simple-bus";
++
++ reg_brcm_osc: brcm-osc-reg {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio5 5 0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_microsom_brcm_osc_reg>;
++ regulator-name = "brcm_osc_reg";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ reg_brcm: brcm-reg {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio3 19 0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_microsom_brcm_reg>;
++ regulator-name = "brcm_reg";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <200000>;
++ };
++ };
++};
+
+ &iomuxc {
+ microsom {
++ pinctrl_microsom_brcm_osc_reg: microsom-brcm-osc-reg {
++ fsl,pins = <
++ MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x40013070
++ >;
++ };
++
++ pinctrl_microsom_brcm_reg: microsom-brcm-reg {
++ fsl,pins = <
++ MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x40013070
++ >;
++ };
++
++ pinctrl_microsom_brcm_wifi: microsom-brcm-wifi {
++ fsl,pins = <
++ MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x1b0b0
++ MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x40013070
++ MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x40013070
++ MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x40013070
++ >;
++ };
++
++ pinctrl_microsom_brcm_bt: microsom-brcm-bt {
++ fsl,pins = <
++ MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x40013070
++ MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x40013070
++ MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x40013070
++ >;
++ };
++
+ pinctrl_microsom_uart1: microsom-uart1 {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+@@ -11,6 +71,15 @@
+ >;
+ };
+
++ pinctrl_microsom_uart4_1: microsom-uart4 {
++ fsl,pins = <
++ MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
++ MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
++ MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
++ MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
++ >;
++ };
++
+ pinctrl_microsom_usbotg: microsom-usbotg {
+ /*
+ * Similar to pinctrl_usbotg_2, but we want it
+@@ -18,6 +87,17 @@
+ */
+ fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
+ };
++
++ pinctrl_microsom_usdhc1: microsom-usdhc1 {
++ fsl,pins = <
++ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
++ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
++ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
++ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
++ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
++ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
++ >;
++ };
+ };
+ };
+
+@@ -27,7 +107,25 @@
+ status = "okay";
+ };
+
++/* UART4 - Connected to optional BRCM Wifi/BT/FM */
++&uart4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_microsom_brcm_bt &pinctrl_microsom_uart4_1>;
++ fsl,uart-has-rtscts;
++};
++
+ &usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_microsom_usbotg>;
+ };
++
++/* USDHC1 - Connected to optional BRCM Wifi/BT/FM */
++&usdhc1 {
++ card-external-vcc-supply = <&reg_brcm>;
++ card-reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>, <&gpio6 0 GPIO_ACTIVE_LOW>;
++ keep-power-in-suspend;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_microsom_brcm_wifi &pinctrl_microsom_usdhc1>;
++ vmmc-supply = <&reg_brcm>;
++};
+diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
+index 09e974392fa1..ea50d34f7944 100644
+--- a/arch/arm/configs/imx_v6_v7_defconfig
++++ b/arch/arm/configs/imx_v6_v7_defconfig
+@@ -245,6 +245,7 @@ CONFIG_DRM_IMX_TVE=y
+ CONFIG_DRM_IMX_LDB=y
+ CONFIG_DRM_IMX_IPUV3_CORE=y
+ CONFIG_DRM_IMX_IPUV3=y
++CONFIG_DRM_IMX_HDMI=y
+ CONFIG_COMMON_CLK_DEBUG=y
+ # CONFIG_IOMMU_SUPPORT is not set
+ CONFIG_PWM=y
+diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
+index 2b4d6acfa34a..fefa6c3d4c86 100644
+--- a/arch/arm/mach-imx/clk-imx6q.c
++++ b/arch/arm/mach-imx/clk-imx6q.c
+@@ -454,6 +454,18 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+ clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
+ clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
+
++ if (cpu_is_imx6dl())
++ clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
++
++ clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
++ clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
++ clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
++ clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
++ clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
++ clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
++ clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
++ clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
++
+ /*
+ * The gpmi needs 100MHz frequency in the EDO/Sync mode,
+ * We can not get the 100MHz from the pll2_pfd0_352m.
+diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
+index 61364050fccd..3776f974d1dc 100644
+--- a/arch/arm/mach-imx/clk-pllv3.c
++++ b/arch/arm/mach-imx/clk-pllv3.c
+@@ -273,9 +273,10 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+- u32 val, div;
++ u32 val, newval, div;
+ u32 mfn, mfd = 1000000;
+ s64 temp64;
++ int ret;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+@@ -287,13 +288,27 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
+ mfn = temp64;
+
+ val = readl_relaxed(pll->base);
+- val &= ~pll->div_mask;
+- val |= div;
+- writel_relaxed(val, pll->base);
++
++ /* set the PLL into bypass mode */
++ newval = val | BM_PLL_BYPASS;
++ writel_relaxed(newval, pll->base);
++
++ /* configure the new frequency */
++ newval &= ~pll->div_mask;
++ newval |= div;
++ writel_relaxed(newval, pll->base);
+ writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
+- writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
++ writel(mfd, pll->base + PLL_DENOM_OFFSET);
+
+- return clk_pllv3_wait_lock(pll);
++ ret = clk_pllv3_wait_lock(pll);
++ if (ret == 0 && val & BM_PLL_POWER) {
++ /* only if it locked can we switch back to the PLL */
++ newval &= ~BM_PLL_BYPASS;
++ newval |= val & BM_PLL_BYPASS;
++ writel(newval, pll->base);
++ }
++
++ return ret;
+ }
+
+ static const struct clk_ops clk_pllv3_av_ops = {
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index 0a0a90f52d26..05a21b857996 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -174,4 +174,6 @@ source "drivers/powercap/Kconfig"
+
+ source "drivers/mcb/Kconfig"
+
++source "drivers/cec/Kconfig"
++
+ endmenu
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 7183b6af5dac..470eec2238ca 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -157,3 +157,4 @@ obj-$(CONFIG_NTB) += ntb/
+ obj-$(CONFIG_FMC) += fmc/
+ obj-$(CONFIG_POWERCAP) += powercap/
+ obj-$(CONFIG_MCB) += mcb/
++obj-$(CONFIG_CEC) += cec/
+diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
+index 8befeb69eeb1..54e2972fc6da 100644
+--- a/drivers/ata/ahci_imx.c
++++ b/drivers/ata/ahci_imx.c
+@@ -62,6 +62,7 @@ struct imx_ahci_priv {
+ struct regmap *gpr;
+ bool no_device;
+ bool first_time;
++ u32 phy_params;
+ };
+
+ static int ahci_imx_hotplug;
+@@ -246,14 +247,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
+ IMX6Q_GPR13_SATA_TX_LVL_MASK |
+ IMX6Q_GPR13_SATA_MPLL_CLK_EN |
+ IMX6Q_GPR13_SATA_TX_EDGE_RATE,
+- IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
+- IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
+- IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
+- IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
+- IMX6Q_GPR13_SATA_MPLL_SS_EN |
+- IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
+- IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
+- IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
++ imxpriv->phy_params);
+ regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
+ IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+ IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+@@ -324,6 +318,10 @@ static void ahci_imx_error_handler(struct ata_port *ap)
+ writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR);
+ imx_sata_disable(hpriv);
+ imxpriv->no_device = true;
++
++ dev_info(ap->dev, "no device found, disabling link.\n");
++ dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX
++ ".hotplug=1 to enable hotplug\n");
+ }
+
+ static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
+@@ -364,6 +362,165 @@ static const struct of_device_id imx_ahci_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
+
++struct reg_value {
++ u32 of_value;
++ u32 reg_value;
++};
++
++struct reg_property {
++ const char *name;
++ const struct reg_value *values;
++ size_t num_values;
++ u32 def_value;
++ u32 set_value;
++};
++
++static const struct reg_value gpr13_tx_level[] = {
++ { 937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
++ { 947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
++ { 957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
++ { 966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
++ { 976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
++ { 986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
++ { 996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
++ { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
++ { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
++ { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
++ { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
++ { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
++ { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
++ { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
++ { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
++ { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
++ { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
++ { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
++ { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
++ { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
++ { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
++ { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
++ { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
++ { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
++ { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
++ { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
++ { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
++ { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
++ { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
++ { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
++ { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
++ { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
++};
++
++static const struct reg_value gpr13_tx_boost[] = {
++ { 0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
++ { 370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
++ { 740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
++ { 111, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
++ { 148, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
++ { 185, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
++ { 222, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
++ { 259, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
++ { 296, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
++ { 333, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
++ { 370, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
++ { 407, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
++ { 444, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
++ { 481, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
++ { 528, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
++ { 575, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
++};
++
++static const struct reg_value gpr13_tx_atten[] = {
++ { 8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
++ { 9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
++ { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
++ { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
++ { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
++ { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
++};
++
++static const struct reg_value gpr13_rx_eq[] = {
++ { 500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
++ { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
++ { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
++ { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
++ { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
++ { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
++ { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
++ { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
++};
++
++static const struct reg_property gpr13_props[] = {
++ {
++ .name = "fsl,transmit-level-mV",
++ .values = gpr13_tx_level,
++ .num_values = ARRAY_SIZE(gpr13_tx_level),
++ .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
++ }, {
++ .name = "fsl,transmit-boost-mdB",
++ .values = gpr13_tx_boost,
++ .num_values = ARRAY_SIZE(gpr13_tx_boost),
++ .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
++ }, {
++ .name = "fsl,transmit-atten-16ths",
++ .values = gpr13_tx_atten,
++ .num_values = ARRAY_SIZE(gpr13_tx_atten),
++ .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
++ }, {
++ .name = "fsl,receive-eq-mdB",
++ .values = gpr13_rx_eq,
++ .num_values = ARRAY_SIZE(gpr13_rx_eq),
++ .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
++ }, {
++ .name = "fsl,no-spread-spectrum",
++ .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
++ .set_value = 0,
++ },
++};
++
++static u32 imx_ahci_parse_props(struct device *dev,
++ const struct reg_property *prop, size_t num)
++{
++ struct device_node *np = dev->of_node;
++ u32 reg_value = 0;
++ int i, j;
++
++ for (i = 0; i < num; i++, prop++) {
++ u32 of_val;
++
++ if (prop->num_values == 0) {
++ if (of_property_read_bool(np, prop->name))
++ reg_value |= prop->set_value;
++ else
++ reg_value |= prop->def_value;
++ continue;
++ }
++
++ if (of_property_read_u32(np, prop->name, &of_val)) {
++ dev_info(dev, "%s not specified, using %08x\n",
++ prop->name, prop->def_value);
++ reg_value |= prop->def_value;
++ continue;
++ }
++
++ for (j = 0; j < prop->num_values; j++) {
++ if (prop->values[j].of_value == of_val) {
++ dev_info(dev, "%s value %u, using %08x\n",
++ prop->name, of_val, prop->values[j].reg_value);
++ reg_value |= prop->values[j].reg_value;
++ break;
++ }
++ }
++
++ if (j == prop->num_values) {
++ dev_err(dev, "DT property %s is not a valid value\n",
++ prop->name);
++ reg_value |= prop->def_value;
++ }
++ }
++
++ return reg_value;
++}
++
+ static int imx_ahci_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -392,6 +549,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
+ }
+
+ if (imxpriv->type == AHCI_IMX6Q) {
++ u32 reg_value;
++
+ imxpriv->gpr = syscon_regmap_lookup_by_compatible(
+ "fsl,imx6q-iomuxc-gpr");
+ if (IS_ERR(imxpriv->gpr)) {
+@@ -399,6 +558,15 @@ static int imx_ahci_probe(struct platform_device *pdev)
+ "failed to find fsl,imx6q-iomux-gpr regmap\n");
+ return PTR_ERR(imxpriv->gpr);
+ }
++
++ reg_value = imx_ahci_parse_props(dev, gpr13_props,
++ ARRAY_SIZE(gpr13_props));
++
++ imxpriv->phy_params =
++ IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
++ IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
++ IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
++ reg_value;
+ }
+
+ hpriv = ahci_platform_get_resources(pdev);
+diff --git a/drivers/cec/Kconfig b/drivers/cec/Kconfig
+new file mode 100644
+index 000000000000..d67cfb83de6a
+--- /dev/null
++++ b/drivers/cec/Kconfig
+@@ -0,0 +1,14 @@
++#
++# Consumer Electroncs Control support
++#
++
++menu "Consumer Electronics Control devices"
++
++config CEC
++ bool
++
++config HDMI_CEC_CORE
++ tristate
++ select CEC
++
++endmenu
+diff --git a/drivers/cec/Makefile b/drivers/cec/Makefile
+new file mode 100644
+index 000000000000..b94278bc8321
+--- /dev/null
++++ b/drivers/cec/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_HDMI_CEC_CORE) += cec-dev.o
+diff --git a/drivers/cec/cec-dev.c b/drivers/cec/cec-dev.c
+new file mode 100644
+index 000000000000..ba58d8217851
+--- /dev/null
++++ b/drivers/cec/cec-dev.c
+@@ -0,0 +1,384 @@
++/*
++ * HDMI Consumer Electronics Control
++ *
++ * This provides the user API for communication with HDMI CEC complaint
++ * devices in kernel drivers, and is based upon the protocol developed
++ * by Freescale for their i.MX SoCs.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/cec-dev.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <linux/poll.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++
++struct cec_event {
++ struct cec_user_event usr;
++ struct list_head node;
++};
++
++static struct class *cec_class;
++static int cec_major;
++
++static void cec_dev_send_message(struct cec_dev *cec_dev, u8 *msg,
++ size_t count)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&cec_dev->lock, flags);
++ cec_dev->retries = 5;
++ cec_dev->write_busy = 1;
++ cec_dev->send_message(cec_dev, msg, count);
++ spin_unlock_irqrestore(&cec_dev->lock, flags);
++}
++
++void cec_dev_event(struct cec_dev *cec_dev, int type, u8 *msg, size_t len)
++{
++ struct cec_event *event;
++ unsigned long flags;
++
++ event = kzalloc(sizeof(*event), GFP_ATOMIC);
++ if (event) {
++ event->usr.event_type = type;
++ event->usr.msg_len = len;
++ if (msg)
++ memcpy(event->usr.msg, msg, len);
++
++ spin_lock_irqsave(&cec_dev->lock, flags);
++ list_add_tail(&event->node, &cec_dev->events);
++ spin_unlock_irqrestore(&cec_dev->lock, flags);
++ wake_up(&cec_dev->waitq);
++ }
++}
++EXPORT_SYMBOL_GPL(cec_dev_event);
++
++static int cec_dev_lock_write(struct cec_dev *cec_dev, struct file *file)
++ __acquires(cec_dev->mutex)
++{
++ int ret;
++
++ do {
++ if (file->f_flags & O_NONBLOCK) {
++ if (cec_dev->write_busy)
++ return -EAGAIN;
++ } else {
++ ret = wait_event_interruptible(cec_dev->waitq,
++ !cec_dev->write_busy);
++ if (ret)
++ break;
++ }
++
++ ret = mutex_lock_interruptible(&cec_dev->mutex);
++ if (ret)
++ break;
++
++ if (!cec_dev->write_busy)
++ break;
++
++ mutex_unlock(&cec_dev->mutex);
++ } while (1);
++
++ return ret;
++}
++
++static ssize_t cec_dev_read(struct file *file, char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct cec_dev *cec_dev = file->private_data;
++ ssize_t ret;
++
++ if (count > sizeof(struct cec_user_event))
++ count = sizeof(struct cec_user_event);
++
++ if (!access_ok(VERIFY_WRITE, buf, count))
++ return -EFAULT;
++
++ do {
++ struct cec_event *event = NULL;
++ unsigned long flags;
++
++ spin_lock_irqsave(&cec_dev->lock, flags);
++ if (!list_empty(&cec_dev->events)) {
++ event = list_first_entry(&cec_dev->events,
++ struct cec_event, node);
++ list_del(&event->node);
++ }
++ spin_unlock_irqrestore(&cec_dev->lock, flags);
++
++ if (event) {
++ ret = __copy_to_user(buf, &event->usr, count) ?
++ -EFAULT : count;
++ kfree(event);
++ break;
++ }
++
++ if (file->f_flags & O_NONBLOCK) {
++ ret = -EAGAIN;
++ break;
++ }
++
++ ret = wait_event_interruptible(cec_dev->waitq,
++ !list_empty(&cec_dev->events));
++ if (ret)
++ break;
++ } while (1);
++
++ return ret;
++}
++
++static ssize_t cec_dev_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct cec_dev *cec_dev = file->private_data;
++ u8 msg[MAX_MESSAGE_LEN];
++ int ret;
++
++ if (count > sizeof(msg))
++ return -E2BIG;
++
++ if (copy_from_user(msg, buf, count))
++ return -EFAULT;
++
++ ret = cec_dev_lock_write(cec_dev, file);
++ if (ret)
++ return ret;
++
++ cec_dev_send_message(cec_dev, msg, count);
++
++ mute