diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2016-07-18 13:46:15 -0700 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2016-07-18 13:46:15 -0700 |
commit | df57a12e5bdaa0b5ab0ce0d8a9d50933835c4de8 (patch) | |
tree | 35a3b51ceec36f1a45f6b31729e2fb03887bc047 | |
parent | eb479e52f9c6d32164ae76606fd7ce372f2aa153 (diff) | |
parent | 77f61547834c4f127b44b13e43c59133a35880dc (diff) |
Merge remote-tracking branch 'nxp/imx_4.1.15_1.0.0_ga' into toradex_imx_4.1.15_1.0.0_ga-next
47 files changed, 1568 insertions, 577 deletions
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt index d02acaff3c35..c09f84816c5a 100644 --- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt @@ -35,6 +35,10 @@ Optional properties: partitions written from Linux with this feature turned on may not be accessible by the BootROM code. + - fsl,legacy-bch-geometry: Use legacy bch geometry(ECC scheme) that + compatible with 3.10 kernel. Without the property, + software may use ECC strength according to NAND chip + spec, e.g. ONFI standard. The device tree may optionally contain sub-nodes describing partitions of the address space. See partition.txt for more detail. diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index d47178b0bfc4..3f7e3fa96cba 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -286,6 +286,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-wandboard.dtb \ imx6dl-wandboard-revb1.dtb \ imx6q-arm2.dtb \ + imx6q-arm2-hsic.dtb \ imx6q-pop-arm2.dtb \ imx6q-cm-fx6.dtb \ imx6q-cubox-i.dtb \ @@ -376,6 +377,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \ dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-12x12-lpddr3-arm2.dtb \ imx7d-12x12-lpddr3-arm2-m4.dtb \ + imx7d-12x12-ddr3-arm2.dtb \ imx7d-12x12-lpddr3-arm2-ecspi.dtb \ imx7d-12x12-lpddr3-arm2-enet2.dtb \ imx7d-12x12-lpddr3-arm2-flexcan.dtb \ @@ -383,6 +385,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-12x12-lpddr3-arm2-qspi.dtb \ imx7d-12x12-lpddr3-arm2-sai.dtb \ imx7d-12x12-lpddr3-arm2-mqs.dtb \ + imx7d-12x12-lpddr3-arm2-pcie.dtb \ imx7d-19x19-lpddr2-arm2.dtb \ imx7d-colibri-eval-v3.dtb \ imx7s-colibri-eval-v3.dtb \ @@ -391,6 +394,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-sdb-gpmi-weim.dtb \ imx7d-sdb-m4.dtb \ imx7d-sdb-qspi.dtb \ + imx7d-sdb-mipi-dsi.dtb \ imx7d-sdb-reva.dtb \ imx7d-sdb-reva-epdc.dtb \ imx7d-sdb-reva-gpmi-weim.dtb \ diff --git a/arch/arm/boot/dts/imx6q-arm2-hsic.dts b/arch/arm/boot/dts/imx6q-arm2-hsic.dts index d2cca3eac3a9..10c95ad96761 100644 --- a/arch/arm/boot/dts/imx6q-arm2-hsic.dts +++ b/arch/arm/boot/dts/imx6q-arm2-hsic.dts @@ -22,11 +22,3 @@ osc-clkgate-delay = <0x3>; status = "okay"; }; - -&usbh3 { - pinctrl-names = "idle", "active"; - pinctrl-0 = <&pinctrl_usbh3_1>; - pinctrl-1 = <&pinctrl_usbh3_2>; - osc-clkgate-delay = <0x3>; - status = "okay"; -}; diff --git a/arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts b/arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts new file mode 100644 index 000000000000..8626f3b50fb3 --- /dev/null +++ b/arch/arm/boot/dts/imx7d-12x12-ddr3-arm2.dts @@ -0,0 +1,558 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * 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. + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include "imx7d.dtsi" + +/ { + model = "Freescale i.MX7 DDR3 12x12 ARM2 Board"; + compatible = "fsl,imx7d-12x12-ddr3-arm2", "fsl,imx7d"; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 5000000>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + status = "okay"; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + volume-up { + label = "Volume Up"; + gpios = <&gpio3 17 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio3 18 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEDOWN>; + }; + }; + + pxp_v4l2_out { + compatible = "fsl,imx7d-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2"; + status = "okay"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + reg_sd3_vmmc: sd3_vmmc { + compatible = "regulator-fixed"; + regulator-name = "VCC_SD3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + gpio = <&gpio6 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg1_vbus: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg2_vbus: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_vref_1v8: regulator@2 { + compatible = "regulator-fixed"; + regulator-name = "vref-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_can1_3v3: can1-3v3 { + compatible = "regulator-fixed"; + regulator-name = "can1-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 2 GPIO_ACTIVE_LOW>; + }; + + reg_can2_3v3: can2-3v3 { + compatible = "regulator-fixed"; + regulator-name = "can2-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; + }; + }; + + memory { + reg = <0x80000000 0x80000000>; + }; +}; + +&adc1 { + vref-supply = <®_vref_1v8>; + status = "okay"; +}; + +&cpu0 { + arm-supply = <&sw1a_reg>; +}; + +&ecspi4 { + fsl,spi-num-chipselects = <4>; + cs-gpios = <&gpio5 3 0>, <&gpio5 4 0>, <&gpio5 5 0>, <&gpio5 6 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi4_1 &pinctrl_ecspi4_cs_1>; + status = "disabled"; + + flash: m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p32"; + spi-max-frequency = <20000000>; + reg = <0>; + }; +}; + +&epxp { + status = "okay"; +}; + +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + xceiver-supply = <®_can1_3v3>; + status = "disabled"; +}; + +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + xceiver-supply = <®_can2_3v3>; + status = "disabled"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_1>; + status = "okay"; + + pmic: pfuze3000@08 { + compatible = "fsl,pfuze3000"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1a { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + /* use sw1c_reg to align with pfuze100/pfuze200 */ + sw1c_reg: sw1b { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1475000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1650000>; + regulator-boot-on; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen2_reg: vldo2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen3_reg: vccsd { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen4_reg: v33 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen5_reg: vldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen6_reg: vldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3_1>; + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_1>; + + imx7d-12x12-ddr3-arm2 { + pinctrl_hog_1: hoggrp-1 { + fsl,pins = < + MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x59 + MX7D_PAD_GPIO1_IO15__GPIO1_IO15 0x59 + MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x59 + >; + }; + + pinctrl_ecspi4_cs_1: ecspi4_cs_grp-1 { + fsl,pins = < + MX7D_PAD_SD1_CLK__GPIO5_IO3 0x2 + MX7D_PAD_SD1_CMD__GPIO5_IO4 0x2 + MX7D_PAD_SD1_DATA0__GPIO5_IO5 0x2 + MX7D_PAD_SD1_DATA1__GPIO5_IO6 0x2 + >; + }; + + pinctrl_ecspi4_1: ecspi4grp-1 { + fsl,pins = < + MX7D_PAD_SD1_RESET_B__ECSPI4_SCLK 0x2 + MX7D_PAD_SD1_WP__ECSPI4_MOSI 0x2 + MX7D_PAD_SD1_CD_B__ECSPI4_MISO 0x2 + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX7D_PAD_SD3_DATA5__FLEXCAN1_TX 0x59 + MX7D_PAD_SD3_DATA7__FLEXCAN1_RX 0x59 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX7D_PAD_SD3_DATA6__FLEXCAN2_TX 0x59 + MX7D_PAD_SD3_DATA4__FLEXCAN2_RX 0x59 + >; + }; + + pinctrl_gpio_keys: gpio_keysgrp { + fsl,pins = < + MX7D_PAD_LCD_DATA12__GPIO3_IO17 0x32 + MX7D_PAD_LCD_DATA13__GPIO3_IO18 0x32 + >; + }; + + pinctrl_i2c3_1: i2c3grp-1 { + fsl,pins = < + MX7D_PAD_ENET1_RGMII_RD0__I2C3_SCL 0x4000007f + MX7D_PAD_ENET1_RGMII_RD1__I2C3_SDA 0x4000007f + >; + }; + + pinctrl_i2c4_1: i2c4grp-1 { + fsl,pins = < + MX7D_PAD_ENET1_RGMII_TD2__I2C4_SCL 0x4000007f + MX7D_PAD_ENET1_RGMII_TD3__I2C4_SDA 0x4000007f + >; + }; + + pinctrl_lcdif_dat: lcdifdatgrp { + fsl,pins = < + MX7D_PAD_EPDC_DATA00__LCD_DATA0 0x4001b0b0 + MX7D_PAD_EPDC_DATA01__LCD_DATA1 0x4001b0b0 + MX7D_PAD_EPDC_DATA02__LCD_DATA2 0x4001b0b0 + MX7D_PAD_EPDC_DATA03__LCD_DATA3 0x4001b0b0 + MX7D_PAD_EPDC_DATA04__LCD_DATA4 0x4001b0b0 + MX7D_PAD_EPDC_DATA05__LCD_DATA5 0x4001b0b0 + MX7D_PAD_EPDC_DATA06__LCD_DATA6 0x4001b0b0 + MX7D_PAD_EPDC_DATA07__LCD_DATA7 0x4001b0b0 + MX7D_PAD_EPDC_DATA08__LCD_DATA8 0x4001b0b0 + MX7D_PAD_EPDC_DATA09__LCD_DATA9 0x4001b0b0 + MX7D_PAD_EPDC_DATA10__LCD_DATA10 0x4001b0b0 + MX7D_PAD_EPDC_DATA11__LCD_DATA11 0x4001b0b0 + MX7D_PAD_EPDC_DATA12__LCD_DATA12 0x4001b0b0 + MX7D_PAD_EPDC_DATA13__LCD_DATA13 0x4001b0b0 + MX7D_PAD_EPDC_DATA14__LCD_DATA14 0x4001b0b0 + MX7D_PAD_EPDC_DATA15__LCD_DATA15 0x4001b0b0 + MX7D_PAD_EPDC_SDLE__LCD_DATA16 0x4001b0b0 + MX7D_PAD_EPDC_SDOE__LCD_DATA17 0x4001b0b0 + MX7D_PAD_EPDC_SDSHR__LCD_DATA18 0x4001b0b0 + MX7D_PAD_EPDC_SDCE0__LCD_DATA19 0x4001b0b0 + MX7D_PAD_EPDC_SDCE1__LCD_DATA20 0x4001b0b0 + MX7D_PAD_EPDC_SDCE2__LCD_DATA21 0x4001b0b0 + MX7D_PAD_EPDC_SDCE3__LCD_DATA22 0x4001b0b0 + MX7D_PAD_EPDC_GDCLK__LCD_DATA23 0x4001b0b0 + >; + }; + + pinctrl_lcdif_ctrl: lcdifctrlgrp { + fsl,pins = < + MX7D_PAD_EPDC_SDCLK__LCD_CLK 0x4001b0b0 + MX7D_PAD_EPDC_BDR1__LCD_ENABLE 0x4001b0b0 + MX7D_PAD_EPDC_PWR_STAT__LCD_VSYNC 0x4001b0b0 + MX7D_PAD_EPDC_PWR_COM__LCD_HSYNC 0x4001b0b0 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO08__PWM1_OUT 0x110b0 + >; + }; + + pinctrl_uart1_1: uart1grp-1 { + fsl,pins = < + MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79 + MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x79 + >; + }; + + pinctrl_usdhc2_1: usdhc2grp-1 { + fsl,pins = < + MX7D_PAD_SD2_CMD__SD2_CMD 0x59 + MX7D_PAD_SD2_CLK__SD2_CLK 0x19 + MX7D_PAD_SD2_DATA0__SD2_DATA0 0x59 + MX7D_PAD_SD2_DATA1__SD2_DATA1 0x59 + MX7D_PAD_SD2_DATA2__SD2_DATA2 0x59 + MX7D_PAD_SD2_DATA3__SD2_DATA3 0x59 + MX7D_PAD_ECSPI1_SCLK__SD2_DATA4 0x59 + MX7D_PAD_ECSPI1_MOSI__SD2_DATA5 0x59 + MX7D_PAD_ECSPI1_MISO__SD2_DATA6 0x59 + MX7D_PAD_ECSPI1_SS0__SD2_DATA7 0x59 + >; + }; + + pinctrl_usdhc2_1_100mhz: usdhc2grp-1_100mhz { + fsl,pins = < + MX7D_PAD_SD2_CMD__SD2_CMD 0x5a + MX7D_PAD_SD2_CLK__SD2_CLK 0x1a + MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5a + MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5a + MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5a + MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5a + MX7D_PAD_ECSPI1_SCLK__SD2_DATA4 0x5a + MX7D_PAD_ECSPI1_MOSI__SD2_DATA5 0x5a + MX7D_PAD_ECSPI1_MISO__SD2_DATA6 0x5a + MX7D_PAD_ECSPI1_SS0__SD2_DATA7 0x5a + >; + }; + + pinctrl_usdhc2_1_200mhz: usdhc2grp-1_200mhz { + fsl,pins = < + MX7D_PAD_SD2_CMD__SD2_CMD 0x5b + MX7D_PAD_SD2_CLK__SD2_CLK 0x1b + MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5b + MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5b + MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5b + MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5b + MX7D_PAD_ECSPI1_SCLK__SD2_DATA4 0x5b + MX7D_PAD_ECSPI1_MOSI__SD2_DATA5 0x5b + MX7D_PAD_ECSPI1_MISO__SD2_DATA6 0x5b + MX7D_PAD_ECSPI1_SS0__SD2_DATA7 0x5b + >; + }; + + pinctrl_usdhc3_1: usdhc3grp-1 { + fsl,pins = < + MX7D_PAD_SD3_CMD__SD3_CMD 0x59 + MX7D_PAD_SD3_CLK__SD3_CLK 0x19 + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59 + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59 + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59 + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59 + >; + }; + }; +}; + +&iomuxc_lpsr { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_2>; + + imx7d-12x12-ddr3-arm2 { + pinctrl_hog_2: hoggrp-2 { + fsl,pins = < + MX7D_PAD_GPIO1_IO02__GPIO1_IO2 0x59 /* flexcan stby1 */ + MX7D_PAD_GPIO1_IO03__GPIO1_IO3 0x59 /* flexcan stby2 */ + MX7D_PAD_GPIO1_IO01__ANATOP_24M_OUT 0x80000000 + >; + }; + + pinctrl_i2c1_1: i2c1grp-1 { + fsl,pins = < + MX7D_PAD_GPIO1_IO04__I2C1_SCL 0x4000007f + MX7D_PAD_GPIO1_IO05__I2C1_SDA 0x4000007f + >; + }; + + pinctrl_i2c2_1: i2c2grp-1 { + fsl,pins = < + MX7D_PAD_GPIO1_IO06__I2C2_SCL 0x4000007f + MX7D_PAD_GPIO1_IO07__I2C2_SDA 0x4000007f + >; + }; + }; +}; + +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif_dat + &pinctrl_lcdif_ctrl>; + display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <33500000>; + hactive = <800>; + vactive = <480>; + hback-porch = <89>; + hfront-porch = <164>; + vback-porch = <23>; + vfront-porch = <10>; + hsync-len = <10>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&sdma { + status = "okay"; +}; + +&pcie { + pinctrl-names = "default"; + status = "disabled"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_1>; + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&usbotg1 { + vbus-supply = <®_usb_otg1_vbus>; + srp-disable; + hnp-disable; + adp-disable; + status = "okay"; +}; + +&usbotg2 { + vbus-supply = <®_usb_otg2_vbus>; + srp-disable; + hnp-disable; + adp-disable; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2_1>; + pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>; + assigned-clocks = <&clks IMX7D_USDHC2_ROOT_CLK>; + assigned-clocks-rates = <400000000>; + bus-width = <8>; + tuning-step = <2>; + non-removable; + keep-power-in-suspend; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3_1>; + vmmc-supply = <®_sd3_vmmc>; + cd-gpios = <&gpio1 14>; + wp-gpios = <&gpio1 15>; + keep-power-in-suspend; + enable-sdio-wakeup; + no-1-8-v; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts index b5765a23e6dd..eb4af7df7b3b 100644 --- a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts +++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2.dts @@ -840,7 +840,7 @@ imx7d-12x12-lpddr3-arm2 { pinctrl_pwm1: pwm1grp { fsl,pins = < - MX7D_PAD_GPIO1_IO01__PWM1_OUT 0x110b0 + MX7D_PAD_GPIO1_IO01__PWM1_OUT 0x30 >; }; }; @@ -951,6 +951,8 @@ &usbotg1 { vbus-supply = <®_usb_otg1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1_vbus>; srp-disable; hnp-disable; adp-disable; @@ -959,6 +961,8 @@ &usbotg2 { vbus-supply = <®_usb_otg2_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg2_vbus>; srp-disable; hnp-disable; adp-disable; diff --git a/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts b/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts index aa031e040736..2af374c66615 100644 --- a/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts +++ b/arch/arm/boot/dts/imx7d-19x19-lpddr2-arm2.dts @@ -444,8 +444,8 @@ &usdhc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc1>; - cd-gpios = <&gpio5 0 0>; - wp-gpios = <&gpio5 1 0>; + cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; no-1-8-v; keep-power-in-suspend; enable-sdio-wakeup; diff --git a/arch/arm/boot/dts/imx7d-pinfunc-lpsr.h b/arch/arm/boot/dts/imx7d-pinfunc-lpsr.h index cbff176f8a1f..aee2da9add91 100644 --- a/arch/arm/boot/dts/imx7d-pinfunc-lpsr.h +++ b/arch/arm/boot/dts/imx7d-pinfunc-lpsr.h @@ -45,26 +45,30 @@ #define MX7D_PAD_GPIO1_IO04__GPIO1_IO4 0x0010 0x0040 0x0000 0x0 0x0 #define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC 0x0010 0x0040 0x072C 0x1 0x1 #define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4 0x0010 0x0040 0x0594 0x2 0x1 -#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B 0x0010 0x0040 0x0710 0x3 0x4 +#define MX7D_PAD_GPIO1_IO04__UART5_DCE_CTS 0x0010 0x0040 0x0000 0x3 0x0 +#define MX7D_PAD_GPIO1_IO04__UART5_DTE_RTS 0x0010 0x0040 0x0710 0x3 0x4 #define MX7D_PAD_GPIO1_IO04__I2C1_SCL 0x0010 0x0040 0x05D4 0x4 0x2 #define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT 0x0010 0x0040 0x0000 0x6 0x0 #define MX7D_PAD_GPIO1_IO05__GPIO1_IO5 0x0014 0x0044 0x0000 0x0 0x0 #define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR 0x0014 0x0044 0x0000 0x1 0x0 #define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5 0x0014 0x0044 0x0598 0x2 0x1 -#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B 0x0014 0x0044 0x0710 0x3 0x5 +#define MX7D_PAD_GPIO1_IO05__UART5_DCE_RTS 0x0014 0x0044 0x0710 0x3 0x5 +#define MX7D_PAD_GPIO1_IO05__UART5_DTE_CTS 0x0014 0x0044 0x0000 0x3 0x0 #define MX7D_PAD_GPIO1_IO05__I2C1_SDA 0x0014 0x0044 0x05D8 0x4 0x2 #define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT 0x0014 0x0044 0x0000 0x6 0x0 #define MX7D_PAD_GPIO1_IO06__GPIO1_IO6 0x0018 0x0048 0x0000 0x0 0x0 #define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC 0x0018 0x0048 0x0728 0x1 0x1 #define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6 0x0018 0x0048 0x059C 0x2 0x1 -#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA 0x0018 0x0048 0x0714 0x3 0x4 +#define MX7D_PAD_GPIO1_IO06__UART5_DCE_RX 0x0018 0x0048 0x0714 0x3 0x4 +#define MX7D_PAD_GPIO1_IO06__UART5_DTE_TX 0x0018 0x0048 0x0000 0x3 0x0 #define MX7D_PAD_GPIO1_IO06__I2C2_SCL 0x0018 0x0048 0x05DC 0x4 0x2 #define MX7D_PAD_GPIO1_IO06__CCM_WAIT 0x0018 0x0048 0x0000 0x5 0x0 #define MX7D_PAD_GPIO1_IO06__KPP_ROW4 0x0018 0x0048 0x0624 0x6 0x1 #define MX7D_PAD_GPIO1_IO07__GPIO1_IO7 0x001C 0x004C 0x0000 0x0 0x0 #define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR 0x001C 0x004C 0x0000 0x1 0x0 #define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7 0x001C 0x004C 0x05A0 0x2 0x1 -#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA 0x001C 0x004C 0x0714 0x3 0x5 +#define MX7D_PAD_GPIO1_IO07__UART5_DCE_TX 0x001C 0x004C 0x0000 0x3 0x0 +#define MX7D_PAD_GPIO1_IO07__UART5_DTE_RX 0x001C 0x004C 0x0714 0x3 0x5 #define MX7D_PAD_GPIO1_IO07__I2C2_SDA 0x001C 0x004C 0x05E0 0x4 0x2 #define MX7D_PAD_GPIO1_IO07__CCM_STOP 0x001C 0x004C 0x0000 0x5 0x0 #define MX7D_PAD_GPIO1_IO07__KPP_COL4 0x001C 0x004C 0x0604 0x6 0x1 diff --git a/arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts b/arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts new file mode 100644 index 000000000000..bbfca36d79a4 --- /dev/null +++ b/arch/arm/boot/dts/imx7d-sdb-mipi-dsi.dts @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * + * 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 "imx7d-sdb.dts" + +/ { + mipi_dsi_reset: mipi-dsi-reset { + compatible = "gpio-reset"; + reset-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>; + reset-delay-us = <1000>; + #reset-cells = <0>; + }; +}; + +&lcdif { + disp-dev = "mipi_dsi_samsung"; +}; + +&mipi_dsi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mipi_dsi_reset>; + lcd_panel = "TRULY-WVGA-TFT3P5581E"; + resets = <&mipi_dsi_reset>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index 1983250de792..09089bbb3d23 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -274,9 +274,10 @@ status = "okay"; port { mipi_sensor_ep: endpoint1 { - remote-endpoint = <&ov5647_mipi_ep>; + remote-endpoint = <&ov5640_mipi_ep>; data-lanes = <2>; csis-hs-settle = <13>; + csis-clk-settle = <2>; csis-wclk; }; @@ -516,17 +517,18 @@ wlf,shared-lrclk; }; - ov5647_mipi: ov5647_mipi@36 { - compatible = "ovti,ov5647_mipi"; - reg = <0x36>; + ov5640_mipi: ov5640_mipi@3c { + compatible = "ovti,ov5640_mipi"; + reg = <0x3c>; clocks = <&clks IMX7D_CLK_DUMMY>; clock-names = "csi_mclk"; csi_id = <0>; pwn-gpios = <&gpio_spi 6 GPIO_ACTIVE_HIGH>; + AVDD-supply = <&vgen6_reg>; mclk = <24000000>; mclk_source = <0>; port { - ov5647_mipi_ep: endpoint { + ov5640_mipi_ep: endpoint { remote-endpoint = <&mipi_sensor_ep>; }; }; @@ -560,6 +562,12 @@ >; }; + pinctrl_mipi_dsi_reset: mipi_dsi_reset_grp { + fsl,pins = < + MX7D_PAD_SAI1_TX_DATA__GPIO6_IO15 0x1b + >; + }; + pinctrl_ecspi3_cs: ecspi3_cs_grp { fsl,pins = < MX7D_PAD_SD2_CD_B__GPIO5_IO9 0x80000000 @@ -970,7 +978,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; - pinctrl-assert-gpios = <&gpio_spi 7 GPIO_ACTIVE_HIGH>; + enable-gpio = <&gpio_spi 7 GPIO_ACTIVE_LOW>; display = <&display0>; status = "okay"; @@ -1050,7 +1058,7 @@ pinctrl_pwm1: pwm1grp { fsl,pins = < - MX7D_PAD_GPIO1_IO01__PWM1_OUT 0x110b0 + MX7D_PAD_GPIO1_IO01__PWM1_OUT 0x30 >; }; diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index 325aee1b61db..ad60f20a8ea9 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2015 Freescale Semiconductor, Inc. + * Copyright 2015-2016 Freescale Semiconductor, Inc. * Copyright 2016 Toradex AG * * This program is free software; you can redistribute it and/or modify diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 572926c7e675..77155bbfebb7 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -679,6 +679,7 @@ fsl,mf-mix-wakeup-irq = <0x54010000 0xc00 0x0 0x1040640>; mipi-phy-supply = <®_1p0d>; pcie-phy-supply = <®_1p0d>; + vcc-supply = <®_1p2>; }; }; @@ -814,8 +815,8 @@ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; reg = <0x30700000 0x10000>; - clocks = <&clks IMX7D_CLK_DUMMY>; - clock-names = "pxp-axi"; + clocks = <&clks IMX7D_PXP_IPG_CLK>, <&clks IMX7D_PXP_AXI_CLK>; + clock-names = "pxp_ipg", "pxp_axi"; status = "disabled"; }; diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index 14931e9cd31c..b6d7c510008e 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -254,6 +254,8 @@ CONFIG_FB_MXC_SYNC_PANEL=y CONFIG_FB_MXC_MIPI_DSI=y CONFIG_FB_MXC_MIPI_DSI_SAMSUNG=y CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y +CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E=y +CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E=y CONFIG_FB_MXC_LDB=y CONFIG_FB_MXC_HDMI=y CONFIG_FB_MXS_SII902X=y diff --git a/arch/arm/mach-imx/busfreq-imx.c b/arch/arm/mach-imx/busfreq-imx.c index 39fe400a48e2..e36b0ffd5cc3 100644 --- a/arch/arm/mach-imx/busfreq-imx.c +++ b/arch/arm/mach-imx/busfreq-imx.c @@ -923,12 +923,16 @@ static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event, mutex_lock(&bus_freq_mutex); if (event == PM_SUSPEND_PREPARE) { + if (cpu_is_imx7d() && imx_src_is_m4_enabled()) + imx_mu_lpm_ready(false); high_bus_count++; set_high_bus_freq(1); busfreq_suspended = 1; } else if (event == PM_POST_SUSPEND) { busfreq_suspended = 0; high_bus_count--; + if (cpu_is_imx7d() && imx_src_is_m4_enabled()) + imx_mu_lpm_ready(true); schedule_delayed_work(&bus_freq_daemon, usecs_to_jiffies(5000000)); } @@ -1180,8 +1184,10 @@ static int busfreq_probe(struct platform_device *pdev) high_bus_count++; } - if (cpu_is_imx7d() && imx_src_is_m4_enabled()) + if (cpu_is_imx7d() && imx_src_is_m4_enabled()) { high_bus_count++; + imx_mu_lpm_ready(true); + } if (err) { dev_err(busfreq_dev, "Busfreq init of ddr controller failed\n"); diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 275a62db8a9f..412efc4d7b30 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -19,6 +19,7 @@ #include <linux/string.h> #include "clk.h" #include "common.h" +#include "hardware.h" /** * DOC: basic gatable clock which can gate and ungate it's ouput @@ -58,7 +59,7 @@ static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable) { struct clk_gate2 *gate = to_clk_gate2(hw); - if (imx_src_is_m4_enabled()) { + if (imx_src_is_m4_enabled() && cpu_is_imx6sx()) { #ifdef CONFIG_SOC_IMX6SX if (!amp_power_mutex || !shared_mem) { if (enable) diff --git a/arch/arm/mach-imx/clk-imx7d.c b/arch/arm/mach-imx/clk-imx7d.c index 980a30a92b33..c3e39eb8eb3b 100644 --- a/arch/arm/mach-imx/clk-imx7d.c +++ b/arch/arm/mach-imx/clk-imx7d.c @@ -376,6 +376,8 @@ static u32 share_count_sai1; static u32 share_count_sai2; static u32 share_count_sai3; +static u32 share_count_pxp; + static struct clk_div_table test_div_table[] = { { .val = 3, .div = 1, }, { .val = 2, .div = 1, }, @@ -862,6 +864,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_USB_PHY1_CLK] = imx_clk_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0); clks[IMX7D_USB_PHY2_CLK] = imx_clk_gate4("usb_phy2_clk", "pll_usb_main_clk", base + 0x46b0, 0); clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate4("adc_root_clk", "ipg_root_clk", base + 0x4200, 0); + clks[IMX7D_PXP_IPG_CLK] = imx_clk_gate2_shared2("pxp_ipg_clk", "ipg_root_clk", base + 0x44c0, 0, &share_count_pxp); + clks[IMX7D_PXP_AXI_CLK] = imx_clk_gate2_shared2("pxp_axi_clk", "main_axi_root_clk", base + 0x44c0, 0, &share_count_pxp); clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c index 92d293416f89..ad8ba14e698c 100644 --- a/arch/arm/mach-imx/clk-pfd.c +++ b/arch/arm/mach-imx/clk-pfd.c @@ -18,6 +18,7 @@ #include <linux/err.h> #include "clk.h" #include "common.h" +#include "hardware.h" /** * struct clk_pfd - IMX PFD clock @@ -53,7 +54,7 @@ static void clk_pfd_do_shared_clks(struct clk_hw *hw, bool enable) { struct clk_pfd *pfd = to_clk_pfd(hw); - if (imx_src_is_m4_enabled()) { + if (imx_src_is_m4_enabled() && cpu_is_imx6sx()) { #ifdef CONFIG_SOC_IMX6SX if (!amp_power_mutex || !shared_mem) { if (enable) diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index cf7d748556dc..c46ffbf5d891 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -108,7 +108,7 @@ static int clk_pllv3_do_hardware(struct clk_hw *hw, bool enable) static void clk_pllv3_do_shared_clks(struct clk_hw *hw, bool enable) { - if (imx_src_is_m4_enabled()) { + if (imx_src_is_m4_enabled() && cpu_is_imx6sx()) { #ifdef CONFIG_SOC_IMX6SX if (!amp_power_mutex || !shared_mem) { if (enable) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 3872420981ea..510fc2bf10f9 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -143,9 +143,11 @@ int imx_gpc_mf_power_on(unsigned int irq, unsigned int on); #ifdef CONFIG_HAVE_IMX_GPCV2 int imx_gpcv2_mf_power_on(unsigned int irq, unsigned int on); void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn); +void imx_gpcv2_add_m4_wake_up_irq(u32 hwirq, bool enable); #else static inline int imx_gpcv2_mf_power_on(unsigned int irq, unsigned int on) { return 0; } static inline void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn) {} +static void imx_gpcv2_add_m4_wake_up_irq(u32 hwirq, bool enable) {} #endif void __init imx_gpcv2_check_dt(void); void imx_gpcv2_set_lpm_mode(enum mxc_cpu_pwr_mode mode); diff --git a/arch/arm/mach-imx/ddr3_freq_imx7d.S b/arch/arm/mach-imx/ddr3_freq_imx7d.S index 0a599ed22e3d..ff767c08af44 100644 --- a/arch/arm/mach-imx/ddr3_freq_imx7d.S +++ b/arch/arm/mach-imx/ddr3_freq_imx7d.S @@ -291,7 +291,7 @@ ldr r8, =0x9880 str r7, [r2, r8] - ldr r7, =0x02020070 + ldr r7, =0x1010007e str r7, [r5, #DDRPHY_MDLL_CON0] ldr r7, =0x10000008 diff --git a/arch/arm/mach-imx/gpcv2.c b/arch/arm/mach-imx/gpcv2.c index d52578d6a1e1..0e2502430cdf 100644 --- a/arch/arm/mach-imx/gpcv2.c +++ b/arch/arm/mach-imx/gpcv2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Freescale Semiconductor, Inc. + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -115,7 +115,24 @@ static u32 gpcv2_saved_imrs_m4[IMR_NUM]; static u32 gpcv2_mf_irqs[IMR_NUM]; static u32 gpcv2_mf_request_on[IMR_NUM]; static DEFINE_SPINLOCK(gpcv2_lock); -static struct notifier_block nb_mipi, nb_pcie; +static struct notifier_block nb_mipi, nb_pcie, nb_usb_hsic; + +void imx_gpcv2_add_m4_wake_up_irq(u32 hwirq, bool enable) +{ + unsigned int idx = hwirq / 32; + unsigned long flags; + u32 mask; + + /* Sanity check for SPI irq */ + if (hwirq < 32) + return; + + mask = 1 << hwirq % 32; + spin_lock_irqsave(&gpcv2_lock, flags); + gpcv2_wake_irqs[idx] = enable ? gpcv2_wake_irqs[idx] | mask : + gpcv2_wake_irqs[idx] & ~mask; + spin_unlock_irqrestore(&gpcv2_lock, flags); +} static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on) { @@ -700,6 +717,41 @@ static struct irq_domain_ops imx_gpcv2_domain_ops = { .free = irq_domain_free_irqs_common, }; +static int imx_usb_hsic_regulator_notify(struct notifier_block *nb, + unsigned long event, + void *ignored) +{ + u32 val = 0; + + val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING); + writel_relaxed(val | BIT(6), gpc_base + GPC_PGC_CPU_MAPPING); + + switch (event) { + case REGULATOR_EVENT_PRE_DO_ENABLE: + val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ); + writel_relaxed(val | BIT(4), gpc_base + GPC_PU_PGC_SW_PUP_REQ); + while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PUP_REQ) & BIT(4)) + ; + break; + case REGULATOR_EVENT_PRE_DO_DISABLE: + /* only disable phy need to set PGC bit, enable does NOT need */ + imx_gpcv2_set_m_core_pgc(true, GPC_PGC_USB_HSIC_PHY); + val = readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ); + writel_relaxed(val | BIT(4), gpc_base + GPC_PU_PGC_SW_PDN_REQ); + while (readl_relaxed(gpc_base + GPC_PU_PGC_SW_PDN_REQ) & BIT(4)) + ; + imx_gpcv2_set_m_core_pgc(false, GPC_PGC_USB_HSIC_PHY); + break; + default: + break; + } + + val = readl_relaxed(gpc_base + GPC_PGC_CPU_MAPPING); + writel_relaxed(val & ~BIT(6), gpc_base + GPC_PGC_CPU_MAPPING); + + return NOTIFY_OK; +} + static int imx_mipi_regulator_notify(struct notifier_block *nb, unsigned long event, void *ignored) @@ -901,7 +953,7 @@ void __init imx_gpcv2_check_dt(void) static int imx_gpcv2_probe(struct platform_device *pdev) { int ret; - struct regulator *mipi_reg, *pcie_reg; + struct regulator *mipi_reg, *pcie_reg, *usb_hsic_reg; if (cpu_is_imx7d()) { mipi_reg = devm_regulator_get(&pdev->dev, "mipi-phy"); @@ -935,6 +987,21 @@ static int imx_gpcv2_probe(struct platform_device *pdev) "pcie regulator notifier request failed\n"); return ret; } + + usb_hsic_reg = devm_regulator_get(&pdev->dev, "vcc"); + if (IS_ERR(usb_hsic_reg)) { + ret = PTR_ERR(usb_hsic_reg); + dev_err(&pdev->dev, "usb hsic regulator not ready.\n"); + return ret; + } + nb_usb_hsic.notifier_call = &imx_usb_hsic_regulator_notify; + + ret = regulator_register_notifier(usb_hsic_reg, &nb_usb_hsic); + if (ret) { + dev_err(&pdev->dev, + "usb hsic regulator notifier request failed\n"); + return ret; + } } return 0; } diff --git a/arch/arm/mach-imx/lpddr3_freq_imx.S b/arch/arm/mach-imx/lpddr3_freq_imx.S index 5d868bd53f6f..71b4e231c4b2 100644 --- a/arch/arm/mach-imx/lpddr3_freq_imx.S +++ b/arch/arm/mach-imx/lpddr3_freq_imx.S @@ -224,7 +224,7 @@ ldr r8, =0x9880 str r7, [r2, r8] - ldr r7, =0x02020070 + ldr r7, =0x1010007e str r7, [r5, #DDRPHY_MDLL_CON0] ldr r7, =0x10000008 diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c index ae502d9f6428..c992e586d8bc 100644 --- a/arch/arm/mach-imx/mu.c +++ b/arch/arm/mach-imx/mu.c @@ -388,7 +388,9 @@ static int imx_mu_probe(struct platform_device *pdev) /* enable the bit26(RIE1) of MU_ACR */ writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(26) | BIT(27), mu_base + MU_ACR); - imx_mu_lpm_ready(true); + /* MU always as a wakeup source for low power mode */ + imx_gpcv2_add_m4_wake_up_irq(irq_to_desc(irq)->irq_data.hwirq, + true); } else { INIT_DELAYED_WORK(&mu_work, mu_work_handler); diff --git a/arch/arm/mach-imx/pm-imx7.c b/arch/arm/mach-imx/pm-imx7.c index 4ce9e6967f77..92e1a9b0795e 100644 --- a/arch/arm/mach-imx/pm-imx7.c +++ b/arch/arm/mach-imx/pm-imx7.c @@ -78,6 +78,8 @@ #define CCM_LPCG_START 0x4040 #define CCM_LPCG_STEP 0x10 +#define CCM_EIM_LPCG 0x4160 +#define CCM_PXP_LPCG 0x44c0 #define CCM_PCIE_LPCG 0x4600 #define BM_CCM_ROOT_POST_PODF 0x3f @@ -85,6 +87,9 @@ #define BM_CCM_ROOT_MUX 0x7000000 #define BM_CCM_ROOT_ENABLE 0x10000000 +#define BM_SYS_COUNTER_CNTCR_FCR1 0x200 +#define BM_SYS_COUNTER_CNTCR_FCR0 0x100 + #define PFD_A_OFFSET 0xc0 #define PFD_B_OFFSET 0xd0 @@ -212,7 +217,7 @@ static const u32 imx7d_ddrc_lpddr3_setting[][2] __initconst = { { 0x1a4, READ_DATA_FROM_HARDWARE }, { 0x1a8, READ_DATA_FROM_HARDWARE }, { 0x64, READ_DATA_FROM_HARDWARE }, - { 0xd0, 0xc0350001 }, + { 0xd0, READ_DATA_FROM_HARDWARE }, { 0xdc, READ_DATA_FROM_HARDWARE }, { 0xe0, READ_DATA_FROM_HARDWARE }, { 0xe4, READ_DATA_FROM_HARDWARE }, @@ -224,6 +229,7 @@ static const u32 imx7d_ddrc_lpddr3_setting[][2] __initconst = { { 0x110, READ_DATA_FROM_HARDWARE }, { 0x114, READ_DATA_FROM_HARDWARE }, { 0x118, READ_DATA_FROM_HARDWARE }, + { 0x120, READ_DATA_FROM_HARDWARE }, { 0x11c, READ_DATA_FROM_HARDWARE }, { 0x180, READ_DATA_FROM_HARDWARE }, { 0x184, READ_DATA_FROM_HARDWARE }, @@ -231,9 +237,10 @@ static const u32 imx7d_ddrc_lpddr3_setting[][2] __initconst = { { 0x194, READ_DATA_FROM_HARDWARE }, { 0x200, READ_DATA_FROM_HARDWARE }, { 0x204, READ_DATA_FROM_HARDWARE }, + { 0x210, READ_DATA_FROM_HARDWARE }, { 0x214, READ_DATA_FROM_HARDWARE }, { 0x218, READ_DATA_FROM_HARDWARE }, - { 0x240, 0x06000601 }, + { 0x240, READ_DATA_FROM_HARDWARE }, { 0x244, READ_DATA_FROM_HARDWARE }, }; @@ -242,6 +249,7 @@ static const u32 imx7d_ddrc_phy_lpddr3_setting[][2] __initconst = { { 0x4, READ_DATA_FROM_HARDWARE }, { 0x8, READ_DATA_FROM_HARDWARE }, { 0x10, READ_DATA_FROM_HARDWARE }, + { 0xb0, READ_DATA_FROM_HARDWARE }, { 0x1c, READ_DATA_FROM_HARDWARE }, { 0x9c, READ_DATA_FROM_HARDWARE }, { 0x7c, READ_DATA_FROM_HARDWARE }, @@ -266,8 +274,8 @@ static const u32 imx7d_ddrc_ddr3_setting[][2] __initconst = { { 0x1a4, READ_DATA_FROM_HARDWARE }, { 0x1a8, READ_DATA_FROM_HARDWARE }, { 0x64, READ_DATA_FROM_HARDWARE }, - { 0x490, 0x00000001 }, - { 0xd0, 0xc0020001 }, + { 0x490, READ_DATA_FROM_HARDWARE }, + { 0xd0, READ_DATA_FROM_HARDWARE }, { 0xd4, READ_DATA_FROM_HARDWARE }, { 0xdc, READ_DATA_FROM_HARDWARE }, { 0xe0, READ_DATA_FROM_HARDWARE }, @@ -279,7 +287,7 @@ static const u32 imx7d_ddrc_ddr3_setting[][2] __initconst = { { 0x10c, READ_DATA_FROM_HARDWARE }, { 0x110, READ_DATA_FROM_HARDWARE }, { 0x114, READ_DATA_FROM_HARDWARE }, - { 0x120, 0x03030803 }, + { 0x120, READ_DATA_FROM_HARDWARE }, { 0x180, READ_DATA_FROM_HARDWARE }, { 0x190, READ_DATA_FROM_HARDWARE }, { 0x194, READ_DATA_FROM_HARDWARE }, @@ -287,7 +295,7 @@ static const u32 imx7d_ddrc_ddr3_setting[][2] __initconst = { { 0x204, READ_DATA_FROM_HARDWARE }, { 0x214, READ_DATA_FROM_HARDWARE }, { 0x218, READ_DATA_FROM_HARDWARE }, - { 0x240, 0x06000601 }, + { 0x240, READ_DATA_FROM_HARDWARE }, { 0x244, READ_DATA_FROM_HARDWARE }, }; @@ -295,6 +303,7 @@ static const u32 imx7d_ddrc_phy_ddr3_setting[][2] __initconst = { { 0x0, READ_DATA_FROM_HARDWARE }, { 0x4, READ_DATA_FROM_HARDWARE }, { 0x10, READ_DATA_FROM_HARDWARE }, + { 0xb0, READ_DATA_FROM_HARDWARE }, { 0x9c, READ_DATA_FROM_HARDWARE }, { 0x7c, READ_DATA_FROM_HARDWARE }, { 0x80, READ_DATA_FROM_HARDWARE }, @@ -687,6 +696,7 @@ static int imx7_pm_is_resume_from_lpsr(void) static int imx7_pm_enter(suspend_state_t state) { unsigned int console_saved_reg[10] = {0}; + u32 val; if (!iram_tlb_base_addr) { pr_warn("No IRAM/OCRAM memory allocated for suspend/resume \ @@ -695,6 +705,22 @@ static int imx7_pm_enter(suspend_state_t state) return -EINVAL; } + /* + * arm_arch_timer driver requires system counter to be + * a clock source with CLOCK_SOURCE_SUSPEND_NONSTOP flag + * set, which means hardware system counter needs to keep + * running during suspend, as the base clock for system + * counter is 24MHz which will be disabled in STOP mode, + * so we need to switch system counter's clock to alternate + * (lower) clock, it is based on 32K, from block guide, there + * is no special flow needs to be followed, system counter + * hardware will handle the clock transition. + */ + val = readl_relaxed(system_counter_ctrl_base); + val &= ~BM_SYS_COUNTER_CNTCR_FCR0; + val |= BM_SYS_COUNTER_CNTCR_FCR1; + writel_relaxed(val, system_counter_ctrl_base); + switch (state) { case PM_SUSPEND_STANDBY: imx_anatop_pre_suspend(); @@ -711,12 +737,16 @@ static int imx7_pm_enter(suspend_state_t state) imx_gpcv2_pre_suspend(true); if (imx_gpcv2_is_mf_mix_off()) { /* - * per design requirement, EXSC for PCIe/EIM + * per design requirement, EXSC for PCIe/EIM/PXP * will need clock to recover RDC setting on * resume, so enable PCIe/EIM LPCG for RDC * recovery when M/F mix off */ writel_relaxed(0x3, pm_info->ccm_base.vbase + + CCM_EIM_LPCG); + writel_relaxed(0x3, pm_info->ccm_base.vbase + + CCM_PXP_LPCG); + writel_relaxed(0x3, pm_info->ccm_base.vbase + CCM_PCIE_LPCG); /* stop m4 if mix will also be shutdown */ if (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop()) { @@ -756,6 +786,10 @@ static int imx7_pm_enter(suspend_state_t state) if (imx_gpcv2_is_mf_mix_off() || imx7_pm_is_resume_from_lpsr()) { writel_relaxed(0x0, pm_info->ccm_base.vbase + + CCM_EIM_LPCG); + writel_relaxed(0x0, pm_info->ccm_base.vbase + + CCM_PXP_LPCG); + writel_relaxed(0x0, pm_info->ccm_base.vbase + CCM_PCIE_LPCG); memcpy(ocram_base, ocram_saved_in_ddr, ocram_size); imx7_console_restore(console_saved_reg); @@ -772,7 +806,6 @@ static int imx7_pm_enter(suspend_state_t state) /* restore M4 to run mode */ imx_mu_set_m4_run_mode(); /* gpc wakeup */ - imx_mu_lpm_ready(true); } } /* clear LPSR resume address */ @@ -784,6 +817,12 @@ static int imx7_pm_enter(suspend_state_t state) return -EINVAL; } + /* restore system counter's clock to base clock */ + val = readl_relaxed(system_counter_ctrl_base); + val &= ~BM_SYS_COUNTER_CNTCR_FCR1; + val |= BM_SYS_COUNTER_CNTCR_FCR0; + writel_relaxed(val, system_counter_ctrl_base); + return 0; } @@ -1001,6 +1040,9 @@ static int __init imx7_suspend_init(const struct imx7_pm_socdata *socdata) ddrc_offset_array[i][0]); else pm_info->ddrc_val[i][1] = ddrc_offset_array[i][1]; + + if (pm_info->ddrc_val[i][0] == 0xd0) + pm_info->ddrc_val[i][1] |= 0xc0000000; } /* initialize DDRC PHY settings */ @@ -1110,18 +1152,18 @@ void __init imx7d_pm_init(void) WARN_ON(!system_counter_cmp_base); np = of_find_node_by_path( - "/soc/aips-bus@30400000/system-counter-ctrl@306c0000"); - if (np) - system_counter_ctrl_base = of_iomap(np, 0); - WARN_ON(!system_counter_ctrl_base); - - np = of_find_node_by_path( "/soc/aips-bus@30000000/gpio@30200000"); if (np) gpio1_base = of_iomap(np, 0); WARN_ON(!gpio1_base); } + np = of_find_node_by_path( + "/soc/aips-bus@30400000/system-counter-ctrl@306c0000"); + if (np) + system_counter_ctrl_base = of_iomap(np, 0); + WARN_ON(!system_counter_ctrl_base); + if (imx_ddrc_get_ddr_type() == IMX_DDR_TYPE_LPDDR3 || imx_ddrc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2) imx7_pm_common_init(&imx7d_pm_data_lpddr3); diff --git a/arch/arm/mach-imx/suspend-imx7.S b/arch/arm/mach-imx/suspend-imx7.S index 2b279795be53..5f4e31152a69 100644 --- a/arch/arm/mach-imx/suspend-imx7.S +++ b/arch/arm/mach-imx/suspend-imx7.S @@ -81,6 +81,8 @@ #define GPC_PGC_C0 0x800 #define GPC_PGC_FM 0xa00 #define ANADIG_SNVS_MISC_CTRL 0x380 +#define ANADIG_SNVS_MISC_CTRL_SET 0x384 +#define ANADIG_SNVS_MISC_CTRL_CLR 0x388 #define ANADIG_DIGPROG 0x800 #define DDRC_STAT 0x4 #define DDRC_PWRCTL 0x30 @@ -307,9 +309,9 @@ ldr r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET] ldr r7, [r11, #ANADIG_DIGPROG] - and r7, r7, #0x11 - cmp r7, #0x10 - beq 10f + and r7, r7, #0xff + cmp r7, #0x11 + bne 10f /* TO 1.1 */ ldr r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_V_OFFSET] @@ -336,11 +338,12 @@ ldr r7, [r11, r6] orr r7, r7, #0x1 str r7, [r11, r6] +11: /* turn off ddr power */ ldr r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET] ldr r7, =(0x1 << 29) - str r7, [r11, #ANADIG_SNVS_MISC_CTRL] -11: + str r7, [r11, #ANADIG_SNVS_MISC_CTRL_SET] + ldr r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET] ldr r6, =0x1000 ldr r7, [r11, r6] @@ -367,7 +370,7 @@ /* turn on ddr power */ ldr r7, =(0x1 << 29) - str r7, [r1, #ANADIG_SNVS_MISC_CTRL] + str r7, [r1, #ANADIG_SNVS_MISC_CTRL_CLR] ldr r6, =50 wait_delay @@ -402,9 +405,9 @@ str r7, [r2, r6] ldr r7, [r1, #ANADIG_DIGPROG] - and r7, r7, #0x11 - cmp r7, #0x10 - beq 12f + and r7, r7, #0xff + cmp r7, #0x11 + bne 12f /* * TKT262940: @@ -419,7 +422,7 @@ str r7, [r11] 12: ldr r7, =(0x1 << 30) - str r7, [r1, #ANADIG_SNVS_MISC_CTRL] + str r7, [r1, #ANADIG_SNVS_MISC_CTRL_SET] /* need to delay ~5mS */ ldr r6, =0x100000 diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c index de679b06945c..0128881a1690 100644 --- a/drivers/dma/pxp/pxp_dma_v2.c +++ b/drivers/dma/pxp/pxp_dma_v2.c @@ -1125,11 +1125,10 @@ static void pxp_clk_disable(struct pxps *pxp) if (pxp->clk_disp_axi) clk_disable_unprepare(pxp->clk_disp_axi); pxp->clk_stat = CLK_STAT_OFF; + pm_runtime_put_sync_suspend(pxp->dev); } else spin_unlock_irqrestore(&pxp->lock, flags); - pm_runtime_put_sync_suspend(pxp->dev); - mutex_unlock(&pxp->clk_mutex); } diff --git a/drivers/dma/pxp/pxp_dma_v3.c b/drivers/dma/pxp/pxp_dma_v3.c index f44045084958..085f1aad4b74 100644 --- a/drivers/dma/pxp/pxp_dma_v3.c +++ b/drivers/dma/pxp/pxp_dma_v3.c @@ -87,7 +87,8 @@ struct pxp_dma { struct pxps { struct platform_device *pdev; - struct clk *clk; + struct clk *ipg_clk; + struct clk *axi_clk; void __iomem *base; int irq; /* PXP IRQ to the CPU */ @@ -1276,7 +1277,8 @@ static void pxp_clk_enable(struct pxps *pxp) pm_runtime_get_sync(pxp->dev); - clk_prepare_enable(pxp->clk); + clk_prepare_enable(pxp->ipg_clk); + clk_prepare_enable(pxp->axi_clk); pxp->clk_stat = CLK_STAT_ON; mutex_unlock(&pxp->clk_mutex); @@ -1296,7 +1298,8 @@ static void pxp_clk_disable(struct pxps *pxp) spin_lock_irqsave(&pxp->lock, flags); if ((pxp->pxp_ongoing == 0) && list_empty(&head)) { spin_unlock_irqrestore(&pxp->lock, flags); - clk_disable_unprepare(pxp->clk); + clk_disable_unprepare(pxp->ipg_clk); + clk_disable_unprepare(pxp->axi_clk); pxp->clk_stat = CLK_STAT_OFF; } else spin_unlock_irqrestore(&pxp->lock, flags); @@ -1809,6 +1812,8 @@ static void pxp_issue_pending(struct dma_chan *chan) struct pxps *pxp = to_pxp(pxp_dma); unsigned long flags0, flags; + down(&pxp->sema); + spin_lock_irqsave(&pxp->lock, flags0); spin_lock_irqsave(&pxp_chan->lock, flags); @@ -1825,7 +1830,6 @@ static void pxp_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&pxp->lock, flags0); pxp_clk_enable(pxp); - down(&pxp->sema); spin_lock_irqsave(&pxp->lock, flags); pxp->pxp_ongoing = 1; @@ -4310,7 +4314,14 @@ static int pxp_probe(struct platform_device *pdev) pxp->pdev = pdev; - pxp->clk = devm_clk_get(&pdev->dev, "pxp-axi"); + pxp->ipg_clk = devm_clk_get(&pdev->dev, "pxp_ipg"); + pxp->axi_clk = devm_clk_get(&pdev->dev, "pxp_axi"); + + if (IS_ERR(pxp->ipg_clk) || IS_ERR(pxp->axi_clk)) { + dev_err(&pdev->dev, "pxp clocks invalid\n"); + err = -EINVAL; + goto exit; + } err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0, "pxp-dmaengine", pxp); @@ -4385,7 +4396,8 @@ static int pxp_remove(struct platform_device *pdev) unregister_pxp_device(); cancel_work_sync(&pxp->work); del_timer_sync(&pxp->clk_timer); - clk_disable_unprepare(pxp->clk); + clk_disable_unprepare(pxp->ipg_clk); + clk_disable_unprepare(pxp->axi_clk); device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout); device_remove_file(&pdev->dev, &dev_attr_block_size); dma_async_device_unregister(&(pxp->pxp_dma.dma)); diff --git a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c index 17f3c07fa8a4..b3bc18125359 100644 --- a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c +++ b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c @@ -106,7 +106,7 @@ static unsigned int v4l2_fmt_to_pxp_fmt(u32 v4l2_pix_fmt) u32 pxp_fmt = 0; if (v4l2_pix_fmt == V4L2_PIX_FMT_RGB24) - pxp_fmt = PXP_PIX_FMT_RGB24; + pxp_fmt = PXP_PIX_FMT_RGB32; else if (v4l2_pix_fmt == V4L2_PIX_FMT_RGB565) pxp_fmt = PXP_PIX_FMT_RGB565; else if (v4l2_pix_fmt == V4L2_PIX_FMT_RGB555) @@ -478,7 +478,7 @@ static int pxp_s_output(struct file *file, void *fh, pxp->pxp_conf.out_param.width = fmt->width; pxp->pxp_conf.out_param.height = fmt->height; if (fmt->pixelformat == V4L2_PIX_FMT_RGB24) - pxp->pxp_conf.out_param.pixel_fmt = PXP_PIX_FMT_RGB24; + pxp->pxp_conf.out_param.pixel_fmt = PXP_PIX_FMT_RGB32; else pxp->pxp_conf.out_param.pixel_fmt = PXP_PIX_FMT_RGB565; diff --git a/drivers/media/platform/mxc/subdev/mx6s_capture.c b/drivers/media/platform/mxc/subdev/mx6s_capture.c index ed60f8dc72dd..49d4f73c4c24 100644 --- a/drivers/media/platform/mxc/subdev/mx6s_capture.c +++ b/drivers/media/platform/mxc/subdev/mx6s_capture.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -588,33 +588,7 @@ static void csi_dmareq_rff_disable(struct mx6s_csi_dev *csi_dev) __raw_writel(cr3, csi_dev->regbase + CSI_CSICR3); } -static void csi_set_32bit_imagpara(struct mx6s_csi_dev *csi, - int width, int height) -{ - int imag_para = 0; - unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3); - - imag_para = (width << 16) | height; - __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA); - - /* reflash the embeded DMA controller */ - __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3); -} - -static void csi_set_16bit_imagpara(struct mx6s_csi_dev *csi, - int width, int height) -{ - int imag_para = 0; - unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3); - - imag_para = ((width * 2) << 16) | height; - __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA); - - /* reflash the embeded DMA controller */ - __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3); -} - -static void csi_set_8bit_imagpara(struct mx6s_csi_dev *csi, +static void csi_set_imagpara(struct mx6s_csi_dev *csi, int width, int height) { int imag_para = 0; @@ -816,6 +790,7 @@ static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev) { struct v4l2_pix_format *pix = &csi_dev->pix; u32 cr1, cr18; + u32 width; if (pix->field == V4L2_FIELD_INTERLACED) { csi_deinterlace_enable(csi_dev, true); @@ -828,21 +803,22 @@ static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev) switch (csi_dev->fmt->pixelformat) { case V4L2_PIX_FMT_YUV32: - csi_set_32bit_imagpara(csi_dev, pix->width, pix->height); + case V4L2_PIX_FMT_SBGGR8: + width = pix->width; break; case V4L2_PIX_FMT_UYVY: - csi_set_16bit_imagpara(csi_dev, pix->width, pix->height); - break; case V4L2_PIX_FMT_YUYV: - csi_set_16bit_imagpara(csi_dev, pix->width, pix->height); - break; - case V4L2_PIX_FMT_SBGGR8: - csi_set_8bit_imagpara(csi_dev, pix->width, pix->height); + if (csi_dev->csi_mux_mipi == true) + width = pix->width; + else + /* For parallel 8-bit sensor input */ + width = pix->width * 2; break; default: pr_debug(" case not supported\n"); return -EINVAL; } + csi_set_imagpara(csi_dev, width, pix->height); if (csi_dev->csi_mux_mipi == true) { cr1 = csi_read(csi_dev, CSI_CSICR1); diff --git a/drivers/media/platform/mxc/subdev/mxc_mipi_csi.c b/drivers/media/platform/mxc/subdev/mxc_mipi_csi.c index a1ed48a9507a..bb9dd3d48e53 100644 --- a/drivers/media/platform/mxc/subdev/mxc_mipi_csi.c +++ b/drivers/media/platform/mxc/subdev/mxc_mipi_csi.c @@ -1,7 +1,7 @@ /* * Freescale i.MX7 SoC series MIPI-CSI V3.3 receiver driver * - * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -250,6 +250,7 @@ struct csis_hw_reset { * @flags: the state variable for power and streaming control * @clock_frequency: device bus clock frequency * @hs_settle: HS-RX settle time + * @clk_settle: Clk settle time * @num_lanes: number of MIPI-CSI data lanes used * @max_num_lanes: maximum number of MIPI-CSI data lanes supported * @wclk_ext: CSI wrapper clock: 0 - bus clock, 1 - external SCLK_CAM @@ -277,6 +278,7 @@ struct csi_state { u32 clk_frequency; u32 hs_settle; + u32 clk_settle; u32 num_lanes; u32 max_num_lanes; u8 wclk_ext; @@ -379,11 +381,6 @@ static int mipi_csis_phy_init(struct csi_state *state) ret = regulator_set_voltage(state->mipi_phy_regulator, 1000000, 1000000); - ret = regulator_enable(state->mipi_phy_regulator); - if (ret) { - dev_err(state->dev, "failed to set mipi regulator.\n"); - return ret; - } return ret; } @@ -468,11 +465,14 @@ static void __mipi_csis_set_format(struct csi_state *state) mipi_csis_write(state, MIPI_CSIS_ISPRESOL_CH0, val); } -static void mipi_csis_set_hsync_settle(struct csi_state *state, int settle) +static void mipi_csis_set_hsync_settle(struct csi_state *state, + int hs_settle, int clk_settle) { u32 val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); - val = (val & ~MIPI_CSIS_DPHYCTRL_HSS_MASK) | (settle << 24); + val = (val & ~MIPI_CSIS_DPHYCTRL_HSS_MASK) | + (hs_settle << 24) | (clk_settle << 22); + mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); } @@ -487,7 +487,7 @@ static void mipi_csis_set_params(struct csi_state *state) __mipi_csis_set_format(state); - mipi_csis_set_hsync_settle(state, state->hs_settle); + mipi_csis_set_hsync_settle(state, state->hs_settle, state->clk_settle); val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0); if (state->csis_fmt->data_alignment == 32) @@ -942,6 +942,9 @@ static int mipi_csis_parse_dt(struct platform_device *pdev, /* Get MIPI CSI-2 bus configration from the endpoint node. */ of_property_read_u32(node, "csis-hs-settle", &state->hs_settle); + + of_property_read_u32(node, "csis-clk-settle", + &state->clk_settle); state->wclk_ext = of_property_read_bool(node, "csis-wclk"); @@ -1117,9 +1120,10 @@ static int mipi_csis_probe(struct platform_device *pdev) goto e_sd_host; } - dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n", - state->num_lanes, state->hs_settle, state->wclk_ext, - state->clk_frequency); + dev_info(&pdev->dev, + "lanes: %d, hs_settle: %d, clk_settle: %d, wclk: %d, freq: %u\n", + state->num_lanes, state->hs_settle, state->clk_settle, + state->wclk_ext, state->clk_frequency); return 0; e_sd_host: diff --git a/drivers/media/platform/mxc/subdev/ov5640_mipi.c b/drivers/media/platform/mxc/subdev/ov5640_mipi.c index 135eefa550a7..739a24c7d426 100644 --- a/drivers/media/platform/mxc/subdev/ov5640_mipi.c +++ b/drivers/media/platform/mxc/subdev/ov5640_mipi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2015 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -44,15 +44,11 @@ enum ov5640_mode { ov5640_mode_MIN = 0, ov5640_mode_VGA_640_480 = 0, - ov5640_mode_QVGA_320_240 = 1, - ov5640_mode_NTSC_720_480 = 2, - ov5640_mode_PAL_720_576 = 3, - ov5640_mode_720P_1280_720 = 4, - ov5640_mode_1080P_1920_1080 = 5, - ov5640_mode_QSXGA_2592_1944 = 6, - ov5640_mode_QCIF_176_144 = 7, - ov5640_mode_XGA_1024_768 = 8, - ov5640_mode_MAX = 8, + ov5640_mode_NTSC_720_480 = 1, + ov5640_mode_720P_1280_720 = 2, + ov5640_mode_1080P_1920_1080 = 3, + ov5640_mode_QSXGA_2592_1944 = 4, + ov5640_mode_MAX = 5, ov5640_mode_INIT = 0xff, /*only for sensor init*/ }; @@ -212,55 +208,12 @@ static struct reg_value ov5640_init_setting_30fps_VGA[] = { {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, - {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300}, + {0x3a1f, 0x14, 0, 0}, {0x3008, 0x42, 0, 0}, {0x3c00, 0x04, 0, 300}, }; static struct reg_value ov5640_setting_30fps_VGA_640_480[] = { - - {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, - {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0}, -}; - -static struct reg_value ov5640_setting_15fps_VGA_640_480[] = { - {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, - {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; - -static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = { - - {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, + {0x3008, 0x42, 0, 0}, + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, @@ -277,117 +230,12 @@ static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = { {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0}, - {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, - {0x380b, 0x00, 0, 0}, {0x3035, 0x12, 0, 0}, -}; - -static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = { - {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, - {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3808, 0x04, 0, 0}, - {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, -}; - -static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = { - {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0}, - {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; - -static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = { - {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0}, - {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; - -static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = { - {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0}, - {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; -static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = { - {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0}, - {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 0}, }; static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = { + {0x3008, 0x42, 0, 0}, {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -406,69 +254,7 @@ static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = { {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; - -static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = { - {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0}, - {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; - -static struct reg_value ov5640_setting_30fps_PAL_720_576[] = { - {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0}, - {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, -}; - -static struct reg_value ov5640_setting_15fps_PAL_720_576[] = { - {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0}, - {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0}, - {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0}, }; static struct reg_value ov5640_setting_30fps_720P_1280_720[] = { @@ -494,27 +280,6 @@ static struct reg_value ov5640_setting_30fps_720P_1280_720[] = { {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0}, }; -static struct reg_value ov5640_setting_15fps_720P_1280_720[] = { - {0x3035, 0x41, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0}, - {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0}, - {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0}, - {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0}, - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, - {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0}, - {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0}, - {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, - {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, -}; - static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = { {0x3008, 0x42, 0, 0}, {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0}, @@ -552,43 +317,8 @@ static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = { {0x3503, 0, 0, 0}, }; -static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = { - {0x3008, 0x42, 0, 0}, - {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0}, - {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0}, - {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, - {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0}, - {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0}, - {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0}, - {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0}, - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x21, 0, 0}, - {0x3036, 0x54, 0, 1}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0}, - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0}, - {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0}, - {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0}, - {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, - {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0}, - {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0}, - {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0}, - {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0}, - {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0}, - {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0}, - {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0}, - {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0}, -}; - static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = { + {0x3008, 0x42, 0, 0}, {0x4202, 0x0f, 0, 0}, /* stream off the sensor */ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/ {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0}, @@ -608,53 +338,27 @@ static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = { {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70}, + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70}, {0x3008, 0x02, 0, 0}, {0x4202, 0x00, 0, 0}, /* stream on the sensor */ }; static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = { { - {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480, - ov5640_setting_15fps_VGA_640_480, - ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)}, - {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240, - ov5640_setting_15fps_QVGA_320_240, - ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)}, - {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480, - ov5640_setting_15fps_NTSC_720_480, - ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)}, - {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576, - ov5640_setting_15fps_PAL_720_576, - ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)}, - {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720, - ov5640_setting_15fps_720P_1280_720, - ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)}, - {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080, - ov5640_setting_15fps_1080P_1920_1080, - ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)}, + {ov5640_mode_VGA_640_480, -1, 0, 0, NULL, 0}, + {ov5640_mode_NTSC_720_480, -1, 0, 0, NULL, 0}, + {ov5640_mode_720P_1280_720, -1, 0, 0, NULL, 0}, + {ov5640_mode_1080P_1920_1080, -1, 0, 0, NULL, 0}, {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944, ov5640_setting_15fps_QSXGA_2592_1944, ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)}, - {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144, - ov5640_setting_15fps_QCIF_176_144, - ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)}, - {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768, - ov5640_setting_15fps_XGA_1024_768, - ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)}, }, { {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480, ov5640_setting_30fps_VGA_640_480, ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)}, - {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240, - ov5640_setting_30fps_QVGA_320_240, - ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)}, {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480, ov5640_setting_30fps_NTSC_720_480, ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)}, - {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576, - ov5640_setting_30fps_PAL_720_576, - ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)}, {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720, ov5640_setting_30fps_720P_1280_720, ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)}, @@ -662,12 +366,6 @@ static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = { ov5640_setting_30fps_1080P_1920_1080, ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)}, {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0}, - {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144, - ov5640_setting_30fps_QCIF_176_144, - ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)}, - {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768, - ov5640_setting_30fps_XGA_1024_768, - ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)}, }, }; @@ -724,17 +422,22 @@ static const struct ov5640_datafmt static inline void ov5640_power_down(int enable) { - /* 19x19 pwdn pin invert by mipi daughter card */ + if (pwn_gpio < 0) + return; + if (!enable) - gpio_set_value(pwn_gpio, 1); + gpio_set_value_cansleep(pwn_gpio, 0); else - gpio_set_value(pwn_gpio, 0); + gpio_set_value_cansleep(pwn_gpio, 1); msleep(2); } static void ov5640_reset(void) { + if (rst_gpio < 0 || pwn_gpio < 0) + return; + /* camera reset */ gpio_set_value(rst_gpio, 1); @@ -869,6 +572,7 @@ static void OV5640_stream_on(void) static void OV5640_stream_off(void) { ov5640_write_reg(0x4202, 0x0f); + ov5640_write_reg(0x3008, 0x42); } static int OV5640_get_sysclk(void) @@ -1402,12 +1106,9 @@ static int ov5640_init_mode(enum ov5640_frame_rate frame_rate, /* dump the first two frames: 1/7.5*2 * the frame rate of QSXGA is 7.5fps */ msec_wait4stable = 267; - } else if (frame_rate == ov5640_15_fps) { - /* dump the first nine frames: 1/15*9 */ + } else { + /* dump the first eighteen frames: 1/30*18 */ msec_wait4stable = 600; - } else if (frame_rate == ov5640_30_fps) { - /* dump the first nine frames: 1/30*9 */ - msec_wait4stable = 300; } msleep(msec_wait4stable); @@ -1808,31 +1509,35 @@ static int ov5640_probe(struct i2c_client *client, /* ov5640 pinctrl */ pinctrl = devm_pinctrl_get_select_default(dev); - if (IS_ERR(pinctrl)) { - dev_warn(dev, "no pin available\n"); - } + if (IS_ERR(pinctrl)) + dev_warn(dev, "no pin available\n"); /* request power down pin */ pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0); - if (!gpio_is_valid(pwn_gpio)) { + if (!gpio_is_valid(pwn_gpio)) dev_warn(dev, "no sensor pwdn pin available"); - return -EINVAL; + else { + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH, + "ov5640_mipi_pwdn"); + if (retval < 0) { + dev_warn(dev, "Failed to set power pin\n"); + dev_warn(dev, "retval=%d\n", retval); + return retval; + } } - retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH, - "ov5640_mipi_pwdn"); - if (retval < 0) - return retval; /* request reset pin */ rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0); - if (!gpio_is_valid(rst_gpio)) { + if (!gpio_is_valid(rst_gpio)) dev_warn(dev, "no sensor reset pin available"); - return -EINVAL; + else { + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH, + "ov5640_mipi_reset"); + if (retval < 0) { + dev_warn(dev, "Failed to set reset pin\n"); + return retval; + } } - retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH, - "ov5640_mipi_reset"); - if (retval < 0) - return retval; /* Set initial values for the sensor struct. */ memset(&ov5640_data, 0, sizeof(ov5640_data)); @@ -1913,6 +1618,7 @@ static int ov5640_probe(struct i2c_client *client, dev_err(&client->dev, "%s--Async register failed, ret=%d\n", __func__, retval); + OV5640_stream_off(); pr_info("camera ov5640_mipi is found\n"); return retval; } diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 6a50cc6faf72..cd5280f686d7 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -489,6 +489,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, unsigned long timeout; u32 status = 0; bool use_r1b_resp = use_busy_signal; + bool expired = false; mmc_retune_hold(host); @@ -548,9 +549,15 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, timeout_ms = MMC_OPS_TIMEOUT_MS; /* Must check status to be sure of no errors. */ - timeout = jiffies + msecs_to_jiffies(timeout_ms); + timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1; do { if (send_status) { + /* + * Due to the possibility of being preempted after + * sending the status command, check the expiration + * time first. + */ + expired = time_after(jiffies, timeout); err = __mmc_send_status(card, &status, ignore_crc); if (err) goto out; @@ -571,7 +578,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, } /* Timeout if the device never leaves the program state. */ - if (time_after(jiffies, timeout)) { + if (expired && R1_CURRENT_STATE(status) == R1_STATE_PRG) { pr_err("%s: Card stuck in programming state! %s\n", mmc_hostname(host), __func__); err = -ETIMEDOUT; diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index b5293f36d45d..e3807494979a 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -32,6 +32,7 @@ #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" +#define ESDHC_SYS_CTRL_DTOCV_MASK 0x0f #define ESDHC_CTRL_D3CD 0x08 #define ESDHC_BURST_LEN_EN_INCR (1 << 27) /* VENDOR SPEC register */ @@ -140,8 +141,6 @@ #define ESDHC_FLAG_HS200 BIT(8) /* The IP supports HS400 mode */ #define ESDHC_FLAG_HS400 BIT(9) -/* need request bus freq during low power */ -#define ESDHC_FLAG_BUSFREQ BIT(10) /* A higher clock ferquency than this rate requires strobell dll control */ #define ESDHC_STROBE_DLL_CLK_FREQ 100000000 @@ -186,7 +185,7 @@ static struct esdhc_soc_data usdhc_imx6q_data = { static struct esdhc_soc_data usdhc_imx6sl_data = { .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536 - | ESDHC_FLAG_HS200 | ESDHC_FLAG_BUSFREQ, + | ESDHC_FLAG_HS200, }; static struct esdhc_soc_data usdhc_imx6sx_data = { @@ -990,7 +989,7 @@ static unsigned int esdhc_get_max_timeout_count(struct sdhci_host *host) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host->priv; - return esdhc_is_usdhc(imx_data) ? 1 << 28 : 1 << 27; + return esdhc_is_usdhc(imx_data) ? 1 << 29 : 1 << 27; } static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) @@ -999,7 +998,8 @@ static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) struct pltfm_imx_data *imx_data = pltfm_host->priv; /* use maximum timeout counter */ - sdhci_writeb(host, esdhc_is_usdhc(imx_data) ? 0xF : 0xE, + esdhc_clrset_le(host, ESDHC_SYS_CTRL_DTOCV_MASK, + esdhc_is_usdhc(imx_data) ? 0xF : 0xE, SDHCI_TIMEOUT_CONTROL); } @@ -1217,8 +1217,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) pltfm_host->clk = imx_data->clk_per; pltfm_host->clock = clk_get_rate(pltfm_host->clk); - if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ) - request_bus_freq(BUS_FREQ_HIGH); + request_bus_freq(BUS_FREQ_HIGH); clk_prepare_enable(imx_data->clk_per); clk_prepare_enable(imx_data->clk_ipg); @@ -1310,8 +1309,7 @@ disable_clk: clk_disable_unprepare(imx_data->clk_per); clk_disable_unprepare(imx_data->clk_ipg); clk_disable_unprepare(imx_data->clk_ahb); - if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ) - release_bus_freq(BUS_FREQ_HIGH); + release_bus_freq(BUS_FREQ_HIGH); free_sdhci: sdhci_pltfm_free(pdev); return err; @@ -1355,8 +1353,7 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev) } clk_disable_unprepare(imx_data->clk_ahb); - if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ) - release_bus_freq(BUS_FREQ_HIGH); + release_bus_freq(BUS_FREQ_HIGH); return ret; } @@ -1367,8 +1364,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = pltfm_host->priv; - if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ) - request_bus_freq(BUS_FREQ_HIGH); + request_bus_freq(BUS_FREQ_HIGH); if (!sdhci_sdio_irq_enabled(host)) { clk_prepare_enable(imx_data->clk_per); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index b72e5f68ac7a..8339d4fd4ddd 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -559,9 +559,11 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this) return -EINVAL; } - if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) && - !(mtd->oobsize > 1024)) + if ((!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) && + (mtd->oobsize < 1024)) || this->legacy_bch_geometry) { + dev_warn(this->dev, "use legacy bch geometry\n"); return legacy_set_geometry(this); + } if (mtd->oobsize > 1024 || chip->ecc_step_ds < mtd->oobsize) return set_geometry_for_large_oob(this); @@ -1008,6 +1010,7 @@ static void gpmi_free_dma_buffer(struct gpmi_nand_data *this) this->cmd_buffer = NULL; this->data_buffer_dma = NULL; + this->raw_buffer = NULL; this->page_buffer_virt = NULL; this->page_buffer_size = 0; } @@ -2114,7 +2117,7 @@ static int mx23_boot_init(struct gpmi_nand_data *this) */ chipnr = block >> (chip->chip_shift - chip->phys_erase_shift); page = block << (chip->phys_erase_shift - chip->page_shift); - byte = block << chip->phys_erase_shift; + byte = (loff_t) block << chip->phys_erase_shift; /* Send the command to read the conventional block mark. */ chip->select_chip(mtd, chipnr); @@ -2262,6 +2265,9 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) if (of_get_nand_on_flash_bbt(this->dev->of_node)) { chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; + if (of_property_read_bool(this->dev->of_node, + "fsl,legacy-bch-geometry")) + this->legacy_bch_geometry = true; if (of_property_read_bool(this->dev->of_node, "fsl,no-blockmark-swap")) diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index c3a51f1bb143..a92158ad29e8 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -197,6 +197,8 @@ struct gpmi_nand_data { dma_addr_t auxiliary_phys; void *raw_buffer; + /* legacy bch geometry flag */ + bool legacy_bch_geometry; /* DMA channels */ #define DMA_CHANS 8 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c index b78fb65e2246..f7d31bf0acb9 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c @@ -576,6 +576,8 @@ gceSTATUS gckVGKERNEL_Dispatch( gckVIDMEM_HANDLE_Lookup(Kernel, processID, (gctUINT32)kernelInterface->u.ReleaseVideoMemory.node, &nodeObject)); + gckVIDMEM_HANDLE_Dereference(Kernel, processID,(gctUINT32)Interface->u.ReleaseVideoMemory.node); + gckVIDMEM_NODE_Dereference(Kernel, nodeObject); } diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index f3644cf4aa3a..9613856e3a09 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -1,7 +1,7 @@ /* * Core driver for the imx pin controller * - * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. + * Copyright (C) 2012-2016 Freescale Semiconductor, Inc. * Copyright (C) 2012 Linaro Ltd. * * Author: Dong Aisheng <dong.aisheng@linaro.org> @@ -485,13 +485,6 @@ static const struct pinconf_ops imx_pinconf_ops = { .pin_config_group_dbg_show = imx_pinconf_group_dbg_show, }; -static struct pinctrl_desc imx_pinctrl_desc = { - .pctlops = &imx_pctrl_ops, - .pmxops = &imx_pmx_ops, - .confops = &imx_pinconf_ops, - .owner = THIS_MODULE, -}; - /* * Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and * 1 u32 CONFIG, so 24 types in total for each pin. @@ -659,6 +652,7 @@ int imx_pinctrl_probe(struct platform_device *pdev, struct device_node *np; struct imx_pinctrl *ipctl; struct resource *res; + struct pinctrl_desc *imx_pinctrl_desc; int ret, i; if (!info || !info->pins || !info->npins) { @@ -667,6 +661,11 @@ int imx_pinctrl_probe(struct platform_device *pdev, } info->dev = &pdev->dev; + imx_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*imx_pinctrl_desc), + GFP_KERNEL); + if (!imx_pinctrl_desc) + return -ENOMEM; + /* Create state holders etc for this driver */ ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL); if (!ipctl) @@ -704,9 +703,13 @@ int imx_pinctrl_probe(struct platform_device *pdev, of_node_put(np); } - imx_pinctrl_desc.name = dev_name(&pdev->dev); - imx_pinctrl_desc.pins = info->pins; - imx_pinctrl_desc.npins = info->npins; + imx_pinctrl_desc->name = dev_name(&pdev->dev); + imx_pinctrl_desc->pins = info->pins; + imx_pinctrl_desc->npins = info->npins; + imx_pinctrl_desc->pctlops = &imx_pctrl_ops; + imx_pinctrl_desc->pmxops = &imx_pmx_ops; + imx_pinctrl_desc->confops = &imx_pinconf_ops; + imx_pinctrl_desc->owner = THIS_MODULE; ret = imx_pinctrl_probe_dt(pdev, info); if (ret) { @@ -717,7 +720,7 @@ int imx_pinctrl_probe(struct platform_device *pdev, ipctl->info = info; ipctl->dev = info->dev; platform_set_drvdata(pdev, ipctl); - ipctl->pctl = pinctrl_register(&imx_pinctrl_desc, &pdev->dev, ipctl); + ipctl->pctl = pinctrl_register(imx_pinctrl_desc, &pdev->dev, ipctl); if (!ipctl->pctl) { dev_err(&pdev->dev, "could not register IMX pinctrl driver\n"); return -EINVAL; diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 0e59c812fc0b..b1ba565af1ba 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Freescale Semiconductor, Inc. + * Copyright 2012-2016 Freescale Semiconductor, Inc. * Copyright (C) 2012 Marek Vasut <marex@denx.de> * on behalf of DENX Software Engineering GmbH * @@ -136,10 +136,15 @@ static inline bool is_imx6sx_con(struct ci_hdrc_imx_data *imx_data) return imx_data->data == &imx6sx_usb_data; } +static inline bool is_imx7d_con(struct ci_hdrc_imx_data *imx_data) +{ + return imx_data->data == &imx7d_usb_data; +} + static inline bool imx_has_hsic_con(struct ci_hdrc_imx_data *imx_data) { return is_imx6q_con(imx_data) || is_imx6sl_con(imx_data) - || is_imx6sx_con(imx_data); + || is_imx6sx_con(imx_data) || is_imx7d_con(imx_data); } /* Common functions shared by usbmisc drivers */ diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h index 527c9607b2ba..4dfb59a05a1a 100644 --- a/drivers/usb/chipidea/host.h +++ b/drivers/usb/chipidea/host.h @@ -20,7 +20,7 @@ static inline void ci_hdrc_host_destroy(struct ci_hdrc *ci) } -static void ci_hdrc_host_driver_init(void) +static inline void ci_hdrc_host_driver_init(void) { } diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 43c6ec29d825..5f133fb2ca6d 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -381,7 +381,7 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) { struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); unsigned long flags; - u32 reg; + u32 reg, val; if (data->index > 3) return -EINVAL; @@ -399,6 +399,27 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base + data->index * 4); + /* For HSIC controller */ + if (data->index == 2 || data->index == 3) { + val = readl(usbmisc->base + data->index * 4); + writel(val | MX6_BM_UTMI_ON_CLOCK, + usbmisc->base + data->index * 4); + val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + + (data->index - 2) * 4); + val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; + writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + + (data->index - 2) * 4); + + /* + * Need to add delay to wait 24M OSC to be stable, + * It is board specific. + */ + regmap_read(data->anatop, ANADIG_ANA_MISC0, &val); + /* 0 <= data->osc_clkgate_delay <= 7 */ + if (data->osc_clkgate_delay > ANADIG_ANA_MISC0_CLK_DELAY(val)) + regmap_write(data->anatop, ANADIG_ANA_MISC0_SET, + (data->osc_clkgate_delay) << 26); + } spin_unlock_irqrestore(&usbmisc->lock, flags); usbmisc_imx6q_set_wakeup(data, false); @@ -415,9 +436,9 @@ static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) usbmisc_imx6q_init(data); + spin_lock_irqsave(&usbmisc->lock, flags); if (data->index == 0 || data->index == 1) { reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4; - spin_lock_irqsave(&usbmisc->lock, flags); /* Set vbus wakeup source as bvalid */ val = readl(reg); writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg); @@ -428,33 +449,17 @@ static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) val = readl(usbmisc->base + data->index * 4); writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN, usbmisc->base + data->index * 4); - spin_unlock_irqrestore(&usbmisc->lock, flags); } /* For HSIC controller */ if (data->index == 2) { - spin_lock_irqsave(&usbmisc->lock, flags); - val = readl(usbmisc->base + data->index * 4); - writel(val | MX6_BM_UTMI_ON_CLOCK, - usbmisc->base + data->index * 4); val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + (data->index - 2) * 4); - val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON | - MX6SX_BM_HSIC_AUTO_RESUME; + val |= MX6SX_BM_HSIC_AUTO_RESUME; writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + (data->index - 2) * 4); - spin_unlock_irqrestore(&usbmisc->lock, flags); - - /* - * Need to add delay to wait 24M OSC to be stable, - * it's board specific. - */ - regmap_read(data->anatop, ANADIG_ANA_MISC0, &val); - /* 0 <= data->osc_clkgate_delay <= 7 */ - if (data->osc_clkgate_delay > ANADIG_ANA_MISC0_CLK_DELAY(val)) - regmap_write(data->anatop, ANADIG_ANA_MISC0_SET, - (data->osc_clkgate_delay) << 26); } + spin_unlock_irqrestore(&usbmisc->lock, flags); return 0; } diff --git a/drivers/video/fbdev/mxc/Kconfig b/drivers/video/fbdev/mxc/Kconfig index 801da762ff34..3650a538d5ff 100644 --- a/drivers/video/fbdev/mxc/Kconfig +++ b/drivers/video/fbdev/mxc/Kconfig @@ -33,6 +33,16 @@ config FB_MXC_TRULY_WVGA_SYNC_PANEL depends on FB_MXC_SYNC_PANEL depends on FB_MXC_MIPI_DSI || FB_MXC_MIPI_DSI_SAMSUNG +config FB_MXC_TRULY_PANEL_TFT3P5079E + tristate "TRULY Panel TFT3P5079E" + depends on FB_MXC_SYNC_PANEL + depends on FB_MXC_MIPI_DSI_SAMSUNG + +config FB_MXC_TRULY_PANEL_TFT3P5581E + tristate "TRULY Panel TFT3P5581E" + depends on FB_MXC_SYNC_PANEL + depends on FB_MXC_MIPI_DSI_SAMSUNG + config FB_MXC_LDB tristate "MXC LDB" depends on FB_MXC_SYNC_PANEL diff --git a/drivers/video/fbdev/mxc/Makefile b/drivers/video/fbdev/mxc/Makefile index 58a889ba97af..922f98aed665 100644 --- a/drivers/video/fbdev/mxc/Makefile +++ b/drivers/video/fbdev/mxc/Makefile @@ -2,6 +2,8 @@ obj-y += mxc_dispdrv.o obj-$(CONFIG_FB_MXC_MIPI_DSI) += mipi_dsi.o obj-$(CONFIG_FB_MXC_MIPI_DSI_SAMSUNG) += mipi_dsi_samsung.o obj-$(CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL) += mxcfb_hx8369_wvga.o +obj-$(CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E) += mxcfb_otm8018b_wvga.o +obj-$(CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E) += mxcfb_hx8363_wvga.o obj-$(CONFIG_FB_MXC_LDB) += ldb.o obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o diff --git a/drivers/video/fbdev/mxc/mipi_dsi.h b/drivers/video/fbdev/mxc/mipi_dsi.h index 722ac6c2066b..1f8db555e58f 100644 --- a/drivers/video/fbdev/mxc/mipi_dsi.h +++ b/drivers/video/fbdev/mxc/mipi_dsi.h @@ -22,7 +22,7 @@ #define mipi_dbg(fmt, ...) #endif -#define DSI_CMD_BUF_MAXSIZE (32) +#define DSI_CMD_BUF_MAXSIZE (128) /* DPI interface pixel color coding map */ enum mipi_dsi_dpi_fmt { @@ -99,6 +99,16 @@ void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size, struct mipi_lcd_config **data); int mipid_hx8369_lcd_setup(struct mipi_dsi_info *); #endif +#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E +void mipid_otm8018b_get_lcd_videomode(struct fb_videomode **mode, int *size, + struct mipi_lcd_config **data); +int mipid_otm8018b_lcd_setup(struct mipi_dsi_info *); +#endif +#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E +void mipid_hx8363_get_lcd_videomode(struct fb_videomode **mode, int *size, + struct mipi_lcd_config **data); +int mipid_hx8363_lcd_setup(struct mipi_dsi_info *); +#endif #ifndef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL #error "Please configure MIPI LCD panel, we cannot find one!" diff --git a/drivers/video/fbdev/mxc/mipi_dsi_samsung.c b/drivers/video/fbdev/mxc/mipi_dsi_samsung.c index 553c0e83a7ea..7de2e2455665 100644 --- a/drivers/video/fbdev/mxc/mipi_dsi_samsung.c +++ b/drivers/video/fbdev/mxc/mipi_dsi_samsung.c @@ -56,6 +56,18 @@ static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = { {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup} }, #endif +#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E + { + "TRULY-WVGA-TFT3P5079E", + {mipid_otm8018b_get_lcd_videomode, mipid_otm8018b_lcd_setup} + }, +#endif +#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E + { + "TRULY-WVGA-TFT3P5581E", + {mipid_hx8363_get_lcd_videomode, mipid_hx8363_lcd_setup} + }, +#endif { "", {NULL, NULL} } @@ -66,13 +78,18 @@ enum mipi_dsi_mode { DSI_VIDEO_MODE }; +enum mipi_dsi_trans_mode { + DSI_LP_MODE, + DSI_HS_MODE +}; + static struct regulator *mipi_phy_reg; static DECLARE_COMPLETION(dsi_rx_done); static DECLARE_COMPLETION(dsi_tx_done); static void mipi_dsi_dphy_power_down(void); static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi, - enum mipi_dsi_mode mode); + enum mipi_dsi_trans_mode mode); static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi, struct mxc_dispdrv_setting *setting) @@ -214,6 +231,7 @@ static int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi, return -ETIMEDOUT; } } + mdelay(10); return 0; } @@ -374,9 +392,13 @@ static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi, MIPI_DSI_PLL_BYPASS(0) | MIPI_DSI_BYTE_CLK_SRC(0), mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL); - writel(MIPI_DSI_PLL_EN(1) | - MIPI_DSI_PMS(0x4190), - mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL); + if (!strcmp(mipi_dsi->lcd_panel, "TRULY-WVGA-TFT3P5581E")) + writel(MIPI_DSI_PLL_EN(1) | MIPI_DSI_PMS(0x3141), + mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL); + else + writel(MIPI_DSI_PLL_EN(1) | MIPI_DSI_PMS(0x4190), + mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL); + /* set PLLTMR: stable time */ writel(33024, mipi_dsi->mmio_base + MIPI_DSI_PLLTMR); udelay(300); @@ -392,17 +414,6 @@ static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi, reg |= MIPI_DSI_ESC_CLK_EN(1); writel(reg, mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL); - /* check clock and data lanes are in stop state - * which means dphy is in low power mode - */ - while (!mipi_dsi_lane_stop_state(mipi_dsi)) { - time_out--; - if (time_out == 0) { - dev_err(dev, "MIPI DSI is not stop state.\n"); - return -EINVAL; - } - } - /* set main display resolution */ writel(MIPI_DSI_MAIN_HRESOL(mode->xres) | MIPI_DSI_MAIN_VRESOL(mode->yres) | @@ -412,8 +423,8 @@ static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi, /* set config register */ writel(MIPI_DSI_MFLUSH_VS(1) | MIPI_DSI_SYNC_IN_FORM(0) | - MIPI_DSI_BURST_MODE(0) | - MIPI_DSI_VIDEO_MODE(0) | + MIPI_DSI_BURST_MODE(1) | + MIPI_DSI_VIDEO_MODE(1) | MIPI_DSI_AUTO_MODE(0) | MIPI_DSI_HSE_DISABLE_MODE(0) | MIPI_DSI_HFP_DISABLE_MODE(0) | @@ -442,17 +453,31 @@ static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi, mipi_dsi->mmio_base + MIPI_DSI_MSYNC); /* configure d-phy timings */ - writel(MIPI_DSI_M_TLPXCTL(11) | MIPI_DSI_M_THSEXITCTL(18), - mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING); - writel(MIPI_DSI_M_TCLKPRPRCTL(13) | - MIPI_DSI_M_TCLKZEROCTL(65) | - MIPI_DSI_M_TCLKPOSTCTL(17) | - MIPI_DSI_M_TCLKTRAILCTL(13), - mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1); - writel(MIPI_DSI_M_THSPRPRCTL(16) | - MIPI_DSI_M_THSZEROCTL(24) | - MIPI_DSI_M_THSTRAILCTL(16), - mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2); + if (!strcmp(mipi_dsi->lcd_panel, "TRULY-WVGA-TFT3P5581E")) { + writel(MIPI_DSI_M_TLPXCTL(2) | MIPI_DSI_M_THSEXITCTL(4), + mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING); + writel(MIPI_DSI_M_TCLKPRPRCTL(5) | + MIPI_DSI_M_TCLKZEROCTL(14) | + MIPI_DSI_M_TCLKPOSTCTL(8) | + MIPI_DSI_M_TCLKTRAILCTL(3), + mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1); + writel(MIPI_DSI_M_THSPRPRCTL(3) | + MIPI_DSI_M_THSZEROCTL(3) | + MIPI_DSI_M_THSTRAILCTL(3), + mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2); + } else { + writel(MIPI_DSI_M_TLPXCTL(11) | MIPI_DSI_M_THSEXITCTL(18), + mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING); + writel(MIPI_DSI_M_TCLKPRPRCTL(13) | + MIPI_DSI_M_TCLKZEROCTL(65) | + MIPI_DSI_M_TCLKPOSTCTL(17) | + MIPI_DSI_M_TCLKTRAILCTL(13), + mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1); + writel(MIPI_DSI_M_THSPRPRCTL(16) | + MIPI_DSI_M_THSZEROCTL(24) | + MIPI_DSI_M_THSTRAILCTL(16), + mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2); + } writel(0xf000f, mipi_dsi->mmio_base + MIPI_DSI_TIMEOUT); @@ -461,6 +486,20 @@ static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi, udelay(300); writel(0x1f, mipi_dsi->mmio_base + MIPI_DSI_FIFOCTRL); + /* check clock and data lanes are in stop state + * which means dphy is in low power mode + */ + while (!mipi_dsi_lane_stop_state(mipi_dsi)) { + time_out--; + if (time_out == 0) { + dev_err(dev, "MIPI DSI is not stop state.\n"); + return -EINVAL; + } + } + + /* transfer commands always in lp mode */ + writel(MIPI_DSI_CMD_LPDT, mipi_dsi->mmio_base + MIPI_DSI_ESCMODE); + mipi_dsi_init_interrupt(mipi_dsi); return 0; @@ -496,23 +535,17 @@ static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp) } static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi, - enum mipi_dsi_mode mode) + enum mipi_dsi_trans_mode mode) { - unsigned int dsi_config, escape_mode, dsi_clkctrl; + unsigned int dsi_clkctrl; - dsi_config = readl(mipi_dsi->mmio_base + MIPI_DSI_CONFIG); - escape_mode = readl(mipi_dsi->mmio_base + MIPI_DSI_ESCMODE); dsi_clkctrl = readl(mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL); switch (mode) { - case DSI_COMMAND_MODE: - dsi_config &= ~MIPI_DSI_VIDEO_MODE(1); - escape_mode |= (MIPI_DSI_CMD_LPDT | MIPI_DSI_TX_LPDT); + case DSI_LP_MODE: dsi_clkctrl &= ~MIPI_DSI_TX_REQUEST_HSCLK(1); break; - case DSI_VIDEO_MODE: - dsi_config |= (MIPI_DSI_VIDEO_MODE(1) | MIPI_DSI_BURST_MODE(1)); - escape_mode &= ~(MIPI_DSI_CMD_LPDT | MIPI_DSI_TX_LPDT); + case DSI_HS_MODE: dsi_clkctrl |= MIPI_DSI_TX_REQUEST_HSCLK(1); break; default: @@ -521,10 +554,8 @@ static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi, return; } - writel(escape_mode, mipi_dsi->mmio_base + MIPI_DSI_ESCMODE); - writel(dsi_config, mipi_dsi->mmio_base + MIPI_DSI_CONFIG); - writel(dsi_clkctrl, mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL); + mdelay(1); } static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp, @@ -542,14 +573,6 @@ static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp, return ret; } } - - ret = device_reset(&mipi_dsi->pdev->dev); - if (ret) { - dev_err(&mipi_dsi->pdev->dev, - "failed to reset device: %d\n", ret); - return -EINVAL; - } - msleep(120); } if (!mipi_dsi->dsi_power_on) @@ -568,10 +591,15 @@ static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp, if (ret) return -EINVAL; - /* the mipi lcd panel should be config - * in the dsi command mode. - */ - mipi_dsi_set_mode(mipi_dsi, DSI_COMMAND_MODE); + msleep(20); + ret = device_reset(&mipi_dsi->pdev->dev); + if (ret) { + dev_err(&mipi_dsi->pdev->dev, "failed to reset device: %d\n", ret); + return -EINVAL; + } + msleep(120); + + /* the panel should be config under LP mode */ ret = mipi_dsi->lcd_callback->mipi_lcd_setup(mipi_dsi); if (ret < 0) { dev_err(&mipi_dsi->pdev->dev, @@ -580,8 +608,8 @@ static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp, } mipi_dsi->lcd_inited = 1; - /* change to video mode for panel display */ - mipi_dsi_set_mode(mipi_dsi, DSI_VIDEO_MODE); + /* change to HS mode for panel display */ + mipi_dsi_set_mode(mipi_dsi, DSI_HS_MODE); } else { ret = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); @@ -775,12 +803,6 @@ static int mipi_dsi_probe(struct platform_device *pdev) } } - ret = device_reset(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "failed to reset device: %d\n", ret); - goto dev_reset_fail; - } - mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL); if (!mipi_dsi->lcd_panel) { dev_err(&pdev->dev, "failed to allocate lcd panel name\n"); @@ -810,7 +832,6 @@ static int mipi_dsi_probe(struct platform_device *pdev) dispdrv_reg_fail: kfree(mipi_dsi->lcd_panel); kstrdup_fail: -dev_reset_fail: if (mipi_dsi->disp_power_on) regulator_disable(mipi_dsi->disp_power_on); diff --git a/drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c b/drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c new file mode 100644 index 000000000000..be97e8104067 --- /dev/null +++ b/drivers/video/fbdev/mxc/mxcfb_hx8363_wvga.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/console.h> +#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/spinlock.h> +#include <linux/mipi_dsi.h> +#include <linux/mxcfb.h> +#include <linux/backlight.h> +#include <video/mipi_display.h> + +#include "mipi_dsi.h" + +#define HX8363_TWO_DATA_LANE (0x2) +#define HX8363_MAX_DPHY_CLK (800) +#define HX8363_CMD_GETHXID (0xF4) +#define HX8363_CMD_GETHXID_LEN (0x4) +#define HX8363_ID (0x84) +#define HX8363_ID_MASK (0xFF) + + +#define CHECK_RETCODE(ret) \ +do { \ + if (ret < 0) { \ + dev_err(&mipi_dsi->pdev->dev, \ + "%s ERR: ret:%d, line:%d.\n", \ + __func__, ret, __LINE__); \ + return ret; \ + } \ +} while (0) + +static void parse_variadic(int n, u8 *buf, ...) +{ + int i = 0; + va_list args; + + if (unlikely(!n)) return; + + va_start(args, buf); + + for (i = 0; i < n; i++) + buf[i + 1] = (u8)va_arg(args, int); + + va_end(args); +} + +#define TC358763_DCS_write_1A_nP(n, addr, ...) { \ + int err; \ + \ + buf[0] = addr; \ + parse_variadic(n, buf, ##__VA_ARGS__); \ + \ + if (n >= 2) \ + err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \ + MIPI_DSI_DCS_LONG_WRITE, (u32*)buf, n + 1); \ + else if (n == 1) \ + err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \ + MIPI_DSI_DCS_SHORT_WRITE_PARAM, (u32*)buf, 0); \ + else if (n == 0) \ + { \ + buf[1] = 0; \ + err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \ + MIPI_DSI_DCS_SHORT_WRITE, (u32*)buf, 0); \ + } \ + CHECK_RETCODE(err); \ +} + +#define TC358763_DCS_write_1A_0P(addr) \ + TC358763_DCS_write_1A_nP(0, addr) + +#define TC358763_DCS_write_1A_1P(addr, ...) \ + TC358763_DCS_write_1A_nP(1, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_2P(addr, ...) \ + TC358763_DCS_write_1A_nP(2, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_3P(addr, ...) \ + TC358763_DCS_write_1A_nP(3, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_5P(addr, ...) \ + TC358763_DCS_write_1A_nP(5, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_6P(addr, ...) \ + TC358763_DCS_write_1A_nP(6, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_7P(addr, ...) \ + TC358763_DCS_write_1A_nP(7, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_12P(addr, ...) \ + TC358763_DCS_write_1A_nP(12, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_13P(addr, ...) \ + TC358763_DCS_write_1A_nP(13, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_14P(addr, ...) \ + TC358763_DCS_write_1A_nP(14, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_19P(addr, ...) \ + TC358763_DCS_write_1A_nP(19, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_34P(addr, ...) \ + TC358763_DCS_write_1A_nP(34, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_127P(addr, ...) \ + TC358763_DCS_write_1A_nP(127, addr, __VA_ARGS__) + +static int hx8363bl_brightness; + +static struct fb_videomode truly_lcd_modedb[] = { + { + "TRUULY-WVGA", 50, 480, 854, 41042, + 40, 60, + 3, 3, + 8, 4, + FB_SYNC_OE_LOW_ACT, + FB_VMODE_NONINTERLACED, + 0, + }, +}; + +static struct mipi_lcd_config lcd_config = { + .virtual_ch = 0x0, + .data_lane_num = HX8363_TWO_DATA_LANE, + .max_phy_clk = HX8363_MAX_DPHY_CLK, + .dpi_fmt = MIPI_RGB888, +}; + +void mipid_hx8363_get_lcd_videomode(struct fb_videomode **mode, int *size, + struct mipi_lcd_config **data) +{ + *mode = &truly_lcd_modedb[0]; + *size = ARRAY_SIZE(truly_lcd_modedb); + *data = &lcd_config; +} + +int mipid_hx8363_lcd_setup(struct mipi_dsi_info *mipi_dsi) +{ + u8 buf[DSI_CMD_BUF_MAXSIZE]; + + dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD HX8363 setup.\n"); + + TC358763_DCS_write_1A_3P(0xB9,0xFF,0x83,0x63);/* SET password */ + + TC358763_DCS_write_1A_19P(0xB1,0x01,0x00,0x44,0x08,0x01,0x10,0x10,0x36, + 0x3E,0x1A,0x1A,0x40,0x12,0x00,0xE6,0xE6,0xE6,0xE6,0xE6);/* Set Power */ + TC358763_DCS_write_1A_2P(0xB2,0x08,0x03);/* Set DISP */ + TC358763_DCS_write_1A_7P(0xB4,0x02,0x18,0x9C,0x08,0x18,0x04,0x6C); + TC358763_DCS_write_1A_1P(0xB6,0x00);/* Set VCOM */ + TC358763_DCS_write_1A_1P(0xCC,0x0B);/* Set Panel */ + TC358763_DCS_write_1A_34P(0xE0,0x0E,0x15,0x19,0x30,0x31,0x3F,0x27,0x3C,0x88,0x8F,0xD1,0xD5,0xD7,0x16,0x16, + 0x0C,0x1E,0x0E,0x15,0x19,0x30,0x31,0x3F,0x27,0x3C,0x88,0x8F, + 0xD1,0xD5,0xD7,0x16,0x16,0x0C,0x1E); + mdelay(5); + + TC358763_DCS_write_1A_1P(0x3A,0x77);/* 24bit */ + TC358763_DCS_write_1A_14P(0xBA,0x11,0x00,0x56,0xC6,0x10,0x89,0xFF,0x0F,0x32,0x6E,0x04,0x07,0x9A,0x92); + TC358763_DCS_write_1A_0P(0x21); + + TC358763_DCS_write_1A_0P(0x11); + msleep(10); + + TC358763_DCS_write_1A_0P(0x29); + msleep(120); + + return 0; +} + +static int mipid_bl_update_status(struct backlight_device *bl) +{ + return 0; +} + +static int mipid_bl_get_brightness(struct backlight_device *bl) +{ + return hx8363bl_brightness; +} + +static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi) +{ + return 0; +} + +static const struct backlight_ops mipid_lcd_bl_ops = { + .update_status = mipid_bl_update_status, + .get_brightness = mipid_bl_get_brightness, + .check_fb = mipi_bl_check_fb, +}; diff --git a/drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c b/drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c new file mode 100644 index 000000000000..fa7db02f37f6 --- /dev/null +++ b/drivers/video/fbdev/mxc/mxcfb_otm8018b_wvga.c @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/console.h> +#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/spinlock.h> +#include <linux/mipi_dsi.h> +#include <linux/mxcfb.h> +#include <linux/backlight.h> +#include <video/mipi_display.h> + +#include "mipi_dsi.h" + +#define OTM8018B_TWO_DATA_LANE (0x2) +#define OTM8018B_MAX_DPHY_CLK (800) + +#define CHECK_RETCODE(ret) \ +do { \ + if (ret < 0) { \ + dev_err(&mipi_dsi->pdev->dev, \ + "%s ERR: ret:%d, line:%d.\n", \ + __func__, ret, __LINE__); \ + return ret; \ + } \ +} while (0) + +static void parse_variadic(int n, u8 *buf, ...) +{ + int i = 0; + va_list args; + + if (unlikely(!n)) return; + + va_start(args, buf); + + for (i = 0; i < n; i++) + buf[i + 1] = (u8)va_arg(args, int); + + va_end(args); +} + +#define TC358763_DCS_write_1A_nP(n, addr, ...) { \ + int err; \ + \ + buf[0] = addr; \ + parse_variadic(n, buf, ##__VA_ARGS__); \ + \ + err = mipi_dsi->mipi_dsi_pkt_write(mipi_dsi, \ + MIPI_DSI_GENERIC_LONG_WRITE, (u32*)buf, n + 1); \ + CHECK_RETCODE(err); \ +} + +#define TC358763_DCS_write_1A_0P(addr) \ + TC358763_DCS_write_1A_nP(0, addr) + +#define TC358763_DCS_write_1A_1P(addr, ...) \ + TC358763_DCS_write_1A_nP(1, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_2P(addr, ...) \ + TC358763_DCS_write_1A_nP(2, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_3P(addr, ...) \ + TC358763_DCS_write_1A_nP(3, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_5P(addr, ...) \ + TC358763_DCS_write_1A_nP(5, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_6P(addr, ...) \ + TC358763_DCS_write_1A_nP(6, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_12P(addr, ...) \ + TC358763_DCS_write_1A_nP(12, addr, __VA_ARGS__) + +#define TC358763_DCS_write_1A_14P(addr, ...) \ + TC358763_DCS_write_1A_nP(14, addr, __VA_ARGS__) + +static int otm8018bbl_brightness; + +static struct fb_videomode truly_lcd_modedb[] = { + { + "TRULY-WVGA", 64, 480, 800, 37880, + 8, 8, + 6, 6, + 8, 6, + FB_SYNC_OE_LOW_ACT, + FB_VMODE_NONINTERLACED, + 0, + }, +}; + +static struct mipi_lcd_config lcd_config = { + .virtual_ch = 0x0, + .data_lane_num = OTM8018B_TWO_DATA_LANE, + .max_phy_clk = OTM8018B_MAX_DPHY_CLK, + .dpi_fmt = MIPI_RGB888, +}; + +void mipid_otm8018b_get_lcd_videomode(struct fb_videomode **mode, int *size, + struct mipi_lcd_config **data) +{ + *mode = &truly_lcd_modedb[0]; + *size = ARRAY_SIZE(truly_lcd_modedb); + *data = &lcd_config; +} + +int mipid_otm8018b_lcd_setup(struct mipi_dsi_info *mipi_dsi) +{ + u8 buf[DSI_CMD_BUF_MAXSIZE]; + + dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD setup.\n"); + + TC358763_DCS_write_1A_3P(0xFF,0x80,0x09,0x01); + TC358763_DCS_write_1A_1P(0x00,0x80); + TC358763_DCS_write_1A_2P(0xFF,0x80,0x09); + + TC358763_DCS_write_1A_1P(0x00,0x03); + TC358763_DCS_write_1A_1P(0xff,0x01); + + TC358763_DCS_write_1A_1P(0x00,0xb4); + TC358763_DCS_write_1A_1P(0xc0,0x10); + + TC358763_DCS_write_1A_1P(0x00,0x82); + TC358763_DCS_write_1A_1P(0xC5,0xa3); + + TC358763_DCS_write_1A_1P(0x00,0x90); + TC358763_DCS_write_1A_2P(0xC5,0x96,0x76); + + TC358763_DCS_write_1A_1P(0x00,0x00); + TC358763_DCS_write_1A_2P(0xD8,0x75,0x73); + + TC358763_DCS_write_1A_1P(0x00,0x00); + TC358763_DCS_write_1A_1P(0xD9,0x5e); + + TC358763_DCS_write_1A_1P(0x00,0x81); + TC358763_DCS_write_1A_1P(0xC1,0x66); + + TC358763_DCS_write_1A_1P(0x00,0xA1); + TC358763_DCS_write_1A_1P(0xC1,0x08); + + TC358763_DCS_write_1A_1P(0x00,0x89); + TC358763_DCS_write_1A_1P(0xC4,0x08); + + TC358763_DCS_write_1A_1P(0x00,0xA2); + TC358763_DCS_write_1A_3P(0xC0,0x1B,0x00,0x02); + + TC358763_DCS_write_1A_1P(0x00,0x81); + TC358763_DCS_write_1A_1P(0xC4,0x83); + + TC358763_DCS_write_1A_1P(0x00,0x92); + TC358763_DCS_write_1A_1P(0xC5,0x01); + + TC358763_DCS_write_1A_1P(0x00,0xb1); + TC358763_DCS_write_1A_1P(0xC5,0xa9); + + TC358763_DCS_write_1A_1P(0x00,0x90); + TC358763_DCS_write_1A_6P(0xC0,0x00,0x44,0x00,0x00,0x00,0x03); + + TC358763_DCS_write_1A_1P(0x00,0xA6); + TC358763_DCS_write_1A_3P(0xC1,0x00,0x00,0x00); + + TC358763_DCS_write_1A_1P(0x00,0x80); + TC358763_DCS_write_1A_12P(0xCE,0x87,0x03,0x00,0x85,0x03,0x00, + 0x86,0x03,0x00,0x84,0x03,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xA0); + TC358763_DCS_write_1A_14P(0xCE,0x38,0x03,0x03,0x58,0x00,0x00, + 0x00,0x38,0x02,0x03,0x59,0x00,0x00,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xB0); + TC358763_DCS_write_1A_14P(0xCE,0x38,0x01,0x03,0x5a,0x00,0x00, + 0x00,0x38,0x00,0x03,0x5b,0x00,0x00,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xC0); + TC358763_DCS_write_1A_14P(0xCE,0x30,0x00,0x03,0x5c,0x00,0x00, + 0x00,0x30,0x01,0x03,0x5d,0x00,0x00,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xD0); + TC358763_DCS_write_1A_14P(0xCE,0x30,0x02,0x03,0x5e,0x00,0x00, + 0x00,0x30,0x03,0x03,0x5f,0x00,0x00,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xC7); + TC358763_DCS_write_1A_1P(0xCF,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xC9); + TC358763_DCS_write_1A_1P(0xCF,0x00); + + TC358763_DCS_write_1A_1P(0x00,0xC4); + TC358763_DCS_write_1A_6P(0xCB,0x04,0x04,0x04,0x04,0x04,0x04); + + TC358763_DCS_write_1A_1P(0x00,0xd9); + TC358763_DCS_write_1A_6P(0xCB,0x04,0x04,0x04,0x04,0x04,0x04); + + TC358763_DCS_write_1A_1P(0x00,0x84); + TC358763_DCS_write_1A_6P(0xCc,0x0c,0x0a,0x10,0x0e,0x03,0x04); + + TC358763_DCS_write_1A_1P(0x00,0x9e); + TC358763_DCS_write_1A_1P(0xCc,0x0b); + + TC358763_DCS_write_1A_1P(0x00,0xA0); + TC358763_DCS_write_1A_5P(0xCC,0x09,0x0f,0x0d,0x01,0x02); + + TC358763_DCS_write_1A_1P(0x00,0xb4); + TC358763_DCS_write_1A_5P(0xCC,0x0d,0x09,0x0b,0x02,0x01); + + TC358763_DCS_write_1A_1P(0x00,0xce); + TC358763_DCS_write_1A_1P(0xCc,0x0e); + + TC358763_DCS_write_1A_1P(0x00,0xD0); + TC358763_DCS_write_1A_5P(0xCC,0x10,0x0a,0x0c,0x04,0x03); + + TC358763_DCS_write_1A_1P(0x00,0x00); + TC358763_DCS_write_1A_1P(0x3a,0x77); + + TC358763_DCS_write_1A_0P(0x11); + + msleep(200); + + TC358763_DCS_write_1A_0P(0x29); + + TC358763_DCS_write_1A_0P(0x2C); + + return 0; +} + +static int mipid_bl_update_status(struct backlight_device *bl) +{ + return 0; +} + +static int mipid_bl_get_brightness(struct backlight_device *bl) +{ + return otm8018bbl_brightness; +} + +static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi) +{ + return 0; +} + +static const struct backlight_ops mipid_lcd_bl_ops = { + .update_status = mipid_bl_update_status, + .get_brightness = mipid_bl_get_brightness, + .check_fb = mipi_bl_check_fb, +}; diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c index a50c35b48951..4e0fa2a1cc6d 100644 --- a/drivers/video/fbdev/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -44,6 +44,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/of_device.h> +#include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/interrupt.h> @@ -1384,11 +1385,23 @@ static int mxsfb_probe(struct platform_device *pdev) struct fb_info *fb_info; struct pinctrl *pinctrl; int irq = platform_get_irq(pdev, 0); - int ret; + int gpio, ret; if (of_id) pdev->id_entry = of_id->data; + gpio = of_get_named_gpio(pdev->dev.of_node, "enable-gpio", 0); + if (gpio == -EPROBE_DEFER) + return -EPROBE_DEFER; + + if (gpio_is_valid(gpio)) { + ret = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_OUT_INIT_LOW, "lcd_pwr_en"); + if (ret) { + dev_err(&pdev->dev, "faild to request gpio %d, ret = %d\n", gpio, ret); + return ret; + } + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Cannot get memory IO resource\n"); diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h index 5c03a008ddde..c48ef189cded 100644 --- a/include/dt-bindings/clock/imx7d-clock.h +++ b/include/dt-bindings/clock/imx7d-clock.h @@ -449,5 +449,7 @@ #define IMX7D_CAAM_CLK 436 #define IMX7D_OCOTP_CLK 437 #define IMX7D_ADC_ROOT_CLK 438 -#define IMX7D_END_CLK 439 +#define IMX7D_PXP_IPG_CLK 439 +#define IMX7D_PXP_AXI_CLK 440 +#define IMX7D_END_CLK 441 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ |