diff options
author | Imre Kaloz <kaloz@openwrt.org> | 2013-11-15 12:23:17 +0000 |
---|---|---|
committer | Imre Kaloz <kaloz@openwrt.org> | 2013-11-15 12:23:17 +0000 |
commit | e4eef7e6207078a4987b0e02d2ad4068083cf921 (patch) | |
tree | ae97c3d14f8a010428d78dfc27dde471ad897232 | |
parent | 1f3478901593dd3bb4f32b2cdcb4c4cfecdbea5a (diff) | |
download | upstream-e4eef7e6207078a4987b0e02d2ad4068083cf921.tar.gz upstream-e4eef7e6207078a4987b0e02d2ad4068083cf921.tar.bz2 upstream-e4eef7e6207078a4987b0e02d2ad4068083cf921.zip |
replace the TI patch with a smaller patchset
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
SVN-Revision: 38816
50 files changed, 4940 insertions, 82370 deletions
diff --git a/target/linux/omap/patches-3.12/001-ti_git.patch b/target/linux/omap/patches-3.12/001-ti_git.patch deleted file mode 100644 index 9a1b6c2ef1..0000000000 --- a/target/linux/omap/patches-3.12/001-ti_git.patch +++ /dev/null @@ -1,82370 +0,0 @@ ---- a/arch/arm/boot/dts/am335x-boneblack.dts -+++ b/arch/arm/boot/dts/am335x-boneblack.dts -@@ -15,3 +15,80 @@ - regulator-max-microvolt = <1800000>; - regulator-always-on; - }; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ ti,non-removable; -+ status = "okay"; -+}; -+ -+&am33xx_pinmux { -+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { -+ pinctrl-single,pins = < -+ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */ -+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xb0 0x08 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ >; -+ }; -+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { -+ pinctrl-single,pins = < -+ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */ -+ >; -+ }; -+}; -+ -+&i2c0 { -+ hdmi1: hdmi@70 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ }; -+}; -+ -+&lcdc { -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ status = "okay"; -+ hdmi = <&hdmi1>; -+ display-timings { -+ 640x480P60 { -+ clock-frequency = <25200000>; -+ hactive = <640>; -+ vactive = <480>; -+ hfront-porch = <16>; -+ hback-porch = <48>; -+ hsync-len = <96>; -+ vback-porch = <31>; -+ vfront-porch = <11>; -+ vsync-len = <2>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ }; -+}; -+ ---- a/arch/arm/boot/dts/am335x-bone-common.dtsi -+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi -@@ -107,6 +107,27 @@ - 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x160 (PIN_INPUT | MUX_MODE7) /* GPIO0_6 */ -+ >; -+ }; -+ -+ emmc_pins: pinmux_emmc_pins { -+ pinctrl-single,pins = < -+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */ -+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */ -+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */ -+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */ -+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */ -+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */ -+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */ -+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */ -+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */ -+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */ -+ >; -+ }; - }; - - ocp { -@@ -183,15 +204,24 @@ - led@4 { - label = "beaglebone:green:usr2"; - gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "cpu0"; - default-state = "off"; - }; - - led@5 { - label = "beaglebone:green:usr3"; - gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "mmc1"; - default-state = "off"; - }; - }; -+ -+ vmmcsd_fixed: fixedregulator@0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vmmcsd_fixed"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; - }; - - /include/ "tps65217.dtsi" -@@ -260,3 +290,12 @@ - pinctrl-0 = <&davinci_mdio_default>; - pinctrl-1 = <&davinci_mdio_sleep>; - }; -+ -+&mmc1 { -+ status = "okay"; -+ bus-width = <0x4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; -+ cd-inverted; -+}; ---- a/arch/arm/boot/dts/am335x-bone.dts -+++ b/arch/arm/boot/dts/am335x-bone.dts -@@ -9,3 +9,13 @@ - - #include "am33xx.dtsi" - #include "am335x-bone-common.dtsi" -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&ldo3_reg>; -+}; ---- a/arch/arm/boot/dts/am335x-evm.dts -+++ b/arch/arm/boot/dts/am335x-evm.dts -@@ -149,6 +149,54 @@ - 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ -+ >; -+ }; -+ -+ lcd_pins_s0: lcd_pins_s0 { -+ pinctrl-single,pins = < -+ 0x20 0x01 /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */ -+ 0x24 0x01 /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */ -+ 0x28 0x01 /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */ -+ 0x2c 0x01 /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */ -+ 0x30 0x01 /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */ -+ 0x34 0x01 /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */ -+ 0x38 0x01 /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */ -+ 0x3c 0x01 /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */ -+ 0xa0 0x00 /* lcd_data0.lcd_data0, OUTPUT | MODE0 */ -+ 0xa4 0x00 /* lcd_data1.lcd_data1, OUTPUT | MODE0 */ -+ 0xa8 0x00 /* lcd_data2.lcd_data2, OUTPUT | MODE0 */ -+ 0xac 0x00 /* lcd_data3.lcd_data3, OUTPUT | MODE0 */ -+ 0xb0 0x00 /* lcd_data4.lcd_data4, OUTPUT | MODE0 */ -+ 0xb4 0x00 /* lcd_data5.lcd_data5, OUTPUT | MODE0 */ -+ 0xb8 0x00 /* lcd_data6.lcd_data6, OUTPUT | MODE0 */ -+ 0xbc 0x00 /* lcd_data7.lcd_data7, OUTPUT | MODE0 */ -+ 0xc0 0x00 /* lcd_data8.lcd_data8, OUTPUT | MODE0 */ -+ 0xc4 0x00 /* lcd_data9.lcd_data9, OUTPUT | MODE0 */ -+ 0xc8 0x00 /* lcd_data10.lcd_data10, OUTPUT | MODE0 */ -+ 0xcc 0x00 /* lcd_data11.lcd_data11, OUTPUT | MODE0 */ -+ 0xd0 0x00 /* lcd_data12.lcd_data12, OUTPUT | MODE0 */ -+ 0xd4 0x00 /* lcd_data13.lcd_data13, OUTPUT | MODE0 */ -+ 0xd8 0x00 /* lcd_data14.lcd_data14, OUTPUT | MODE0 */ -+ 0xdc 0x00 /* lcd_data15.lcd_data15, OUTPUT | MODE0 */ -+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */ -+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */ -+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */ -+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */ -+ >; -+ }; -+ -+ am335x_evm_audio_pins: am335x_evm_audio_pins { -+ pinctrl-single,pins = < -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */ -+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */ -+ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ -+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ -+ >; -+ }; - }; - - ocp { -@@ -244,6 +292,18 @@ - compatible = "ti,tmp275"; - reg = <0x48>; - }; -+ -+ tlv320aic3106: tlv320aic3106@1b { -+ compatible = "ti,tlv320aic3106"; -+ reg = <0x1b>; -+ status = "okay"; -+ -+ /* Regulators */ -+ AVDD-supply = <&vaux2_reg>; -+ IOVDD-supply = <&vaux2_reg>; -+ DRVDD-supply = <&vaux2_reg>; -+ DVDD-supply = <&vbat>; -+ }; - }; - - elm: elm@48080000 { -@@ -268,8 +328,7 @@ - nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ - nand-bus-width = <8>; -- ti,nand-ecc-opt = "bch8"; -- gpmc,device-nand = "true"; -+ ti,nand-ecc-opt= "bch8"; - gpmc,device-width = <1>; - gpmc,sync-clk-ps = <0>; - gpmc,cs-on-ns = <0>; -@@ -293,53 +352,78 @@ - gpmc,wait-monitoring-ns = <0>; - gpmc,wr-access-ns = <40>; - gpmc,wr-data-mux-bus-ns = <0>; -- - #address-cells = <1>; - #size-cells = <1>; -- elm_id = <&elm>; -- -+ ti,elm-id = <&elm>; - /* MTD partition table */ - partition@0 { - label = "SPL1"; - reg = <0x00000000 0x000020000>; - }; -- - partition@1 { - label = "SPL2"; - reg = <0x00020000 0x00020000>; - }; -- - partition@2 { - label = "SPL3"; - reg = <0x00040000 0x00020000>; - }; -- - partition@3 { - label = "SPL4"; - reg = <0x00060000 0x00020000>; - }; -- - partition@4 { - label = "U-boot"; - reg = <0x00080000 0x001e0000>; - }; -- - partition@5 { - label = "environment"; - reg = <0x00260000 0x00020000>; - }; -- - partition@6 { - label = "Kernel"; - reg = <0x00280000 0x00500000>; - }; -- - partition@7 { - label = "File-System"; - reg = <0x00780000 0x0F880000>; - }; - }; - }; -+ -+ lcdc: lcdc@0x4830e000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lcd_pins_s0>; -+ status = "okay"; -+ display-timings { -+ 800x480p62 { -+ clock-frequency = <30000000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <39>; -+ hback-porch = <39>; -+ hsync-len = <47>; -+ vback-porch = <29>; -+ vfront-porch = <13>; -+ vsync-len = <2>; -+ hsync-active = <1>; -+ vsync-active = <1>; -+ }; -+ }; -+ }; -+ -+ sound { -+ compatible = "ti,da830-evm-audio"; -+ ti,model = "AM335x-EVM"; -+ ti,audio-codec = <&tlv320aic3106>; -+ ti,mcasp-controller = <&mcasp1>; -+ ti,codec-clock-rate = <12000000>; -+ ti,audio-routing = -+ "Headphone Jack", "HPLOUT", -+ "Headphone Jack", "HPROUT", -+ "LINE1L", "Line In", -+ "LINE1R", "Line In"; -+ }; - }; - - vbat: fixedregulator@0 { -@@ -403,10 +487,63 @@ - brightness-levels = <0 51 53 56 62 75 101 152 255>; - default-brightness-level = <8>; - }; -+ -+ panel { -+ compatible = "ti,tilcdc,panel"; -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lcd_pins_s0>; -+ panel-info { -+ ac-bias = <255>; -+ ac-bias-intrpt = <0>; -+ dma-burst-sz = <16>; -+ bpp = <32>; -+ fdd = <0x80>; -+ sync-edge = <0>; -+ sync-ctrl = <1>; -+ raster-order = <0>; -+ fifo-th = <0>; -+ }; -+ -+ display-timings { -+ 800x480p62 { -+ clock-frequency = <30000000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <39>; -+ hback-porch = <39>; -+ hsync-len = <47>; -+ vback-porch = <29>; -+ vfront-porch = <13>; -+ vsync-len = <2>; -+ hsync-active = <1>; -+ vsync-active = <1>; -+ }; -+ }; -+ }; - }; - - #include "tps65910.dtsi" - -+&mcasp1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&am335x_evm_audio_pins>; -+ -+ status = "okay"; -+ -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ /* 16 serializer */ -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 0 0 1 2 -+ 0 0 0 0 -+ 0 0 0 0 -+ 0 0 0 0 -+ >; -+ tx-num-evt = <1>; -+ rx-num-evt = <1>; -+}; -+ - &tps { - vcc1-supply = <&vbat>; - vcc2-supply = <&vbat>; -@@ -477,6 +614,8 @@ - }; - - vmmc_reg: regulator@12 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - }; -@@ -509,7 +648,7 @@ - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; -- ti,coordiante-readouts = <5>; -+ ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - }; - -@@ -517,3 +656,12 @@ - ti,adc-channels = <4 5 6 7>; - }; - }; -+ -+&mmc1 { -+ status = "okay"; -+ vmmc-supply = <&vmmc_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-evm-profile2.dts -@@ -0,0 +1,296 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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 "am33xx.dtsi" -+ -+/ { -+ model = "TI AM335x EVM"; -+ compatible = "ti,am335x-evm", "ti,am33xx"; -+ -+ cpus { -+ cpu@0 { -+ cpu0-supply = <&vdd1_reg>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x80000000 0x10000000>; /* 256 MB */ -+ }; -+ -+ am33xx_pinmux: pinmux@44e10800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&matrix_keypad_s0 &clkout2_pin>; -+ -+ matrix_keypad_s0: matrix_keypad_s0 { -+ pinctrl-single,pins = < -+ 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ -+ 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a6.gpio1_22 */ -+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a9.gpio1_25 */ -+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a10.gpio1_26 */ -+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.gpio1_27 */ -+ >; -+ }; -+ -+ i2c0_pins: pinmux_i2c0_pins { -+ pinctrl-single,pins = < -+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ -+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ -+ >; -+ }; -+ -+ spi0_pins: pinmux_spi0_pins { -+ pinctrl-single,pins = < -+ 0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_clk.spi0_clk */ -+ 0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */ -+ 0x158 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */ -+ 0x15c (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */ -+ >; -+ }; -+ -+ uart0_pins: pinmux_uart0_pins { -+ pinctrl-single,pins = < -+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ -+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ -+ >; -+ }; -+ -+ clkout2_pin: pinmux_clkout2_pin { -+ pinctrl-single,pins = < -+ 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ -+ >; -+ }; -+ -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */ -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */ -+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */ -+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */ -+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */ -+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */ -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */ -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */ -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */ -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */ -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */ -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */ -+ >; -+ }; -+ -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 reset value */ -+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ -+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ /* MDIO reset value */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ }; -+ -+ ocp { -+ uart0: serial@44e09000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ -+ status = "okay"; -+ }; -+ -+ i2c0: i2c@44e0b000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ -+ status = "okay"; -+ clock-frequency = <400000>; -+ -+ tps: tps@2d { -+ reg = <0x2d>; -+ }; -+ }; -+ -+ spi0: spi@48030000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ status = "okay"; -+ m25p80@0 { -+ compatible = "w25q64"; -+ spi-max-frequency = <24000000>; -+ reg = <0x0>; -+ }; -+ }; -+ }; -+ -+ vbat: fixedregulator@0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vbat"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ }; -+ -+ lis3_reg: fixedregulator@1 { -+ compatible = "regulator-fixed"; -+ regulator-name = "lis3_reg"; -+ regulator-boot-on; -+ }; -+ -+ matrix_keypad: matrix_keypad@0 { -+ compatible = "gpio-matrix-keypad"; -+ debounce-delay-ms = <5>; -+ col-scan-delay-us = <2>; -+ -+ row-gpios = <&gpio1 25 GPIO_ACTIVE_HIGH /* Bank1, pin25 */ -+ &gpio1 26 GPIO_ACTIVE_HIGH /* Bank1, pin26 */ -+ &gpio1 27 GPIO_ACTIVE_HIGH>; /* Bank1, pin27 */ -+ -+ col-gpios = <&gpio1 21 GPIO_ACTIVE_HIGH /* Bank1, pin21 */ -+ &gpio1 22 GPIO_ACTIVE_HIGH>; /* Bank1, pin22 */ -+ -+ linux,keymap = <0x0000008b /* MENU */ -+ 0x0100009e /* BACK */ -+ 0x02000069 /* LEFT */ -+ 0x0001006a /* RIGHT */ -+ 0x0101001c /* ENTER */ -+ 0x0201006c>; /* DOWN */ -+ }; -+}; -+ -+#include "tps65910.dtsi" -+ -+&tps { -+ vcc1-supply = <&vbat>; -+ vcc2-supply = <&vbat>; -+ vcc3-supply = <&vbat>; -+ vcc4-supply = <&vbat>; -+ vcc5-supply = <&vbat>; -+ vcc6-supply = <&vbat>; -+ vcc7-supply = <&vbat>; -+ vccio-supply = <&vbat>; -+ -+ regulators { -+ vrtc_reg: regulator@0 { -+ regulator-always-on; -+ }; -+ -+ vio_reg: regulator@1 { -+ regulator-always-on; -+ }; -+ -+ vdd1_reg: regulator@2 { -+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ -+ regulator-name = "vdd_mpu"; -+ regulator-min-microvolt = <912500>; -+ regulator-max-microvolt = <1312500>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vdd2_reg: regulator@3 { -+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ -+ regulator-name = "vdd_core"; -+ regulator-min-microvolt = <912500>; -+ regulator-max-microvolt = <1150000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ vdd3_reg: regulator@4 { -+ regulator-always-on; -+ }; -+ -+ vdig1_reg: regulator@5 { -+ regulator-always-on; -+ }; -+ -+ vdig2_reg: regulator@6 { -+ regulator-always-on; -+ }; -+ -+ vpll_reg: regulator@7 { -+ regulator-always-on; -+ }; -+ -+ vdac_reg: regulator@8 { -+ regulator-always-on; -+ }; -+ -+ vaux1_reg: regulator@9 { -+ regulator-always-on; -+ }; -+ -+ vaux2_reg: regulator@10 { -+ regulator-always-on; -+ }; -+ -+ vaux33_reg: regulator@11 { -+ regulator-always-on; -+ }; -+ -+ vmmc_reg: regulator@12 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ }; -+}; -+ -+&mac { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <0>; -+ phy-mode = "rgmii-txid"; -+}; -+ -+&cpsw_emac1 { -+ phy_id = <&davinci_mdio>, <1>; -+ phy-mode = "rgmii-txid"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ vmmc-supply = <&vmmc_reg>; -+ bus-width = <4>; -+}; ---- a/arch/arm/boot/dts/am335x-evmsk.dts -+++ b/arch/arm/boot/dts/am335x-evmsk.dts -@@ -35,6 +35,39 @@ - pinctrl-names = "default"; - pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>; - -+ lcd_pins_s0: lcd_pins_s0 { -+ pinctrl-single,pins = < -+ 0x20 0x01 /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */ -+ 0x24 0x01 /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */ -+ 0x28 0x01 /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */ -+ 0x2c 0x01 /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */ -+ 0x30 0x01 /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */ -+ 0x34 0x01 /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */ -+ 0x38 0x01 /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */ -+ 0x3c 0x01 /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */ -+ 0xa0 0x00 /* lcd_data0.lcd_data0, OUTPUT | MODE0 */ -+ 0xa4 0x00 /* lcd_data1.lcd_data1, OUTPUT | MODE0 */ -+ 0xa8 0x00 /* lcd_data2.lcd_data2, OUTPUT | MODE0 */ -+ 0xac 0x00 /* lcd_data3.lcd_data3, OUTPUT | MODE0 */ -+ 0xb0 0x00 /* lcd_data4.lcd_data4, OUTPUT | MODE0 */ -+ 0xb4 0x00 /* lcd_data5.lcd_data5, OUTPUT | MODE0 */ -+ 0xb8 0x00 /* lcd_data6.lcd_data6, OUTPUT | MODE0 */ -+ 0xbc 0x00 /* lcd_data7.lcd_data7, OUTPUT | MODE0 */ -+ 0xc0 0x00 /* lcd_data8.lcd_data8, OUTPUT | MODE0 */ -+ 0xc4 0x00 /* lcd_data9.lcd_data9, OUTPUT | MODE0 */ -+ 0xc8 0x00 /* lcd_data10.lcd_data10, OUTPUT | MODE0 */ -+ 0xcc 0x00 /* lcd_data11.lcd_data11, OUTPUT | MODE0 */ -+ 0xd0 0x00 /* lcd_data12.lcd_data12, OUTPUT | MODE0 */ -+ 0xd4 0x00 /* lcd_data13.lcd_data13, OUTPUT | MODE0 */ -+ 0xd8 0x00 /* lcd_data14.lcd_data14, OUTPUT | MODE0 */ -+ 0xdc 0x00 /* lcd_data15.lcd_data15, OUTPUT | MODE0 */ -+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */ -+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */ -+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */ -+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */ -+ >; -+ }; -+ - user_leds_s0: user_leds_s0 { - pinctrl-single,pins = < - 0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */ -@@ -158,6 +191,21 @@ - 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) - >; - }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ -+ >; -+ }; -+ -+ mcasp1_pins: mcasp1_pins { -+ pinctrl-single,pins = < -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */ -+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */ -+ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ -+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ -+ >; -+ }; - }; - - ocp { -@@ -206,6 +254,18 @@ - st,max-limit-y = <550>; - st,max-limit-z = <750>; - }; -+ -+ tlv320aic3106: tlv320aic3106@1b { -+ compatible = "ti,tlv320aic3106"; -+ reg = <0x1b>; -+ status = "okay"; -+ -+ /* Regulators */ -+ AVDD-supply = <&vaux2_reg>; -+ IOVDD-supply = <&vaux2_reg>; -+ DRVDD-supply = <&vaux2_reg>; -+ DVDD-supply = <&vbat>; -+ }; - }; - - musb: usb@47400000 { -@@ -219,9 +279,22 @@ - status = "okay"; - }; - -+ usb-phy@47401b00 { -+ status = "okay"; -+ }; -+ - usb@47401000 { - status = "okay"; - }; -+ -+ usb@47401800 { -+ status = "okay"; -+ dr_mode = "host"; -+ }; -+ -+ dma-controller@07402000 { -+ status = "okay"; -+ }; - }; - - epwmss2: epwmss@48304000 { -@@ -233,6 +306,38 @@ - pinctrl-0 = <&ecap2_pins>; - }; - }; -+ -+ lcdc: lcdc@0x4830e000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lcd_pins_s0>; -+ status = "okay"; -+ display-timings { -+ 480x272 { -+ hactive = <480>; -+ vactive = <272>; -+ hback-porch = <43>; -+ hfront-porch = <8>; -+ hsync-len = <4>; -+ vback-porch = <12>; -+ vfront-porch = <4>; -+ vsync-len = <10>; -+ clock-frequency = <9000000>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ }; -+ }; -+ -+ sound { -+ compatible = "ti,da830-evm-audio"; -+ ti,model = "AM335x-EVMSK"; -+ ti,audio-codec = <&tlv320aic3106>; -+ ti,mcasp-controller = <&mcasp1>; -+ ti,codec-clock-rate = <24576000>; -+ ti,audio-routing = -+ "Headphone Jack", "HPLOUT", -+ "Headphone Jack", "HPROUT"; -+ }; - }; - - vbat: fixedregulator@0 { -@@ -393,6 +498,8 @@ - }; - - vmmc_reg: regulator@12 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - }; -@@ -419,3 +526,45 @@ - phy_id = <&davinci_mdio>, <1>; - phy-mode = "rgmii-txid"; - }; -+ -+&tscadc { -+ status = "okay"; -+ tsc { -+ ti,wires = <4>; -+ ti,x-plate-resistance = <200>; -+ ti,coordinate-readouts = <5>; -+ ti,wire-config = <0x00 0x11 0x22 0x33>; -+ }; -+}; -+ -+&gpio0 { -+ ti,no-reset; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ vmmc-supply = <&vmmc_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; -+}; -+ -+&mcasp1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcasp1_pins>; -+ -+ status = "okay"; -+ -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ /* 16 serializer */ -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 0 0 1 2 -+ 0 0 0 0 -+ 0 0 0 0 -+ 0 0 0 0 -+ >; -+ tx-num-evt = <1>; -+ rx-num-evt = <1>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/am33xx-clocks.dtsi -@@ -0,0 +1,661 @@ -+/* -+ * Device Tree Source for AM33xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+clk_32768_ck: clk_32768_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+clk_rc32k_ck: clk_rc32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32000>; -+}; -+ -+virt_19200000_ck: virt_19200000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <19200000>; -+}; -+ -+virt_24000000_ck: virt_24000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24000000>; -+}; -+ -+virt_25000000_ck: virt_25000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+}; -+ -+virt_26000000_ck: virt_26000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+sys_clkin_ck: sys_clkin_ck@44e10040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>; -+ bit-shift = <22>; -+ reg = <0x44e10040 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+tclkin_ck: tclkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+dpll_core_ck: dpll_core_ck@44e00490 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-core-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44e00490 0x4>, <0x44e0045c 0x4>, <0x44e00468 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_core_x2_ck: dpll_core_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_core_ck>; -+}; -+ -+dpll_core_m4_ck: dpll_core_m4_ck@44e00480 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ reg = <0x44e00480 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_core_m5_ck: dpll_core_m5_ck@44e00484 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ reg = <0x44e00484 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_core_m6_ck: dpll_core_m6_ck@44e004d8 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ reg = <0x44e004d8 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_mpu_ck: dpll_mpu_ck@44e00488 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44e00488 0x4>, <0x44e00420 0x4>, <0x44e0042c 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_mpu_m2_ck: dpll_mpu_m2_ck@44e004a8 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_mpu_ck>; -+ reg = <0x44e004a8 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_ddr_ck: dpll_ddr_ck@44e00494 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-no-gate-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44e00494 0x4>, <0x44e00434 0x4>, <0x44e00440 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_ddr_m2_ck: dpll_ddr_m2_ck@44e004a0 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_ddr_ck>; -+ reg = <0x44e004a0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_ddr_m2_div2_ck: dpll_ddr_m2_div2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_ddr_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_disp_ck: dpll_disp_ck@44e00498 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-no-gate-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44e00498 0x4>, <0x44e00448 0x4>, <0x44e00454 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_disp_m2_ck: dpll_disp_m2_ck@44e004a4 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_disp_ck>; -+ reg = <0x44e004a4 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ set-rate-parent; -+}; -+ -+dpll_per_ck: dpll_per_ck@44e0048c { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-no-gate-j-type-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44e0048c 0x4>, <0x44e00470 0x4>, <0x44e0049c 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_per_m2_ck: dpll_per_m2_ck@44e004ac { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_ck>; -+ reg = <0x44e004ac 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_per_m2_div4_wkupdm_ck: dpll_per_m2_div4_wkupdm_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+dpll_per_m2_div4_ck: dpll_per_m2_div4_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+adc_tsc_fck: adc_tsc_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+cefuse_fck: cefuse_fck@44e00a20 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_clkin_ck>; -+ bit-shift = <1>; -+ reg = <0x44e00a20 0x4>; -+}; -+ -+clk_24mhz: clk_24mhz { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+clkdiv32k_ck: clkdiv32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&clk_24mhz>; -+ clock-mult = <1>; -+ clock-div = <732>; -+}; -+ -+clkdiv32k_ick: clkdiv32k_ick@44e0014c { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&clkdiv32k_ck>; -+ reg = <0x44e0014c 0x4>; -+ bit-shift = <1>; -+}; -+ -+dcan0_fck: dcan0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dcan1_fck: dcan1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l3_gclk: l3_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+pruss_ocp_gclk: pruss_ocp_gclk@44e00530 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3_gclk>, <&dpll_disp_m2_ck>; -+ reg = <0x44e00530 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcasp0_fck: mcasp0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mcasp1_fck: mcasp1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mmu_fck: mmu_fck@44e00914 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ bit-shift = <1>; -+ reg = <0x44e00914 0x4>; -+}; -+ -+smartreflex0_fck: smartreflex0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+smartreflex1_fck: smartreflex1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sha0_fck: sha0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+rng_fck: rng_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+aes0_fck: aes0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+timer1_fck: timer1_fck@44e00528 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&clkdiv32k_ick>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>; -+ reg = <0x44e00528 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+timer2_fck: timer2_fck@44e00508 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e00508 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer3_fck: timer3_fck@44e0050c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e0050c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer4_fck: timer4_fck@44e00510 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e00510 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer5_fck: timer5_fck@44e00518 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e00518 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer6_fck: timer6_fck@44e0051c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e0051c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer7_fck: timer7_fck@44e00504 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e00504 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+usbotg_fck: usbotg_fck@44e0047c { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_ck>; -+ bit-shift = <8>; -+ reg = <0x44e0047c 0x4>; -+}; -+ -+dpll_core_m4_div2_ck: dpll_core_m4_div2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+ieee5000_fck: ieee5000_fck@44e000e4 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_core_m4_div2_ck>; -+ bit-shift = <1>; -+ reg = <0x44e000e4 0x4>; -+}; -+ -+wdt1_fck: wdt1_fck@44e00538 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_rc32k_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e00538 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+l4_rtc_gclk: l4_rtc_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+l4hs_gclk: l4hs_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l3s_gclk: l3s_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_div2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l4fw_gclk: l4fw_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_div2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l4ls_gclk: l4ls_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_div2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sysclk_div_ck: sysclk_div_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+cpsw_125mhz_gclk: cpsw_125mhz_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m5_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+cpsw_cpts_rft_clk: cpsw_cpts_rft_clk@44e00520 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_m5_ck>, <&dpll_core_m4_ck>; -+ reg = <0x44e00520 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpio0_dbclk_mux_ck: gpio0_dbclk_mux_ck@44e0053c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&clkdiv32k_ick>; -+ reg = <0x44e0053c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+gpio0_dbclk: gpio0_dbclk@44e00408 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpio0_dbclk_mux_ck>; -+ bit-shift = <18>; -+ reg = <0x44e00408 0x4>; -+}; -+ -+gpio1_dbclk: gpio1_dbclk@44e000ac { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <18>; -+ reg = <0x44e000ac 0x4>; -+}; -+ -+gpio2_dbclk: gpio2_dbclk@44e000b0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <18>; -+ reg = <0x44e000b0 0x4>; -+}; -+ -+gpio3_dbclk: gpio3_dbclk@44e000b4 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <18>; -+ reg = <0x44e000b4 0x4>; -+}; -+ -+lcd_gclk: lcd_gclk@44e00534 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_disp_m2_ck>, <&dpll_core_m5_ck>, <&dpll_per_m2_ck>; -+ reg = <0x44e00534 0x4>; -+ bit-mask = <0x3>; -+ set-rate-parent; -+}; -+ -+mmc_clk: mmc_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+gfx_fclk_clksel_ck: gfx_fclk_clksel_ck@44e0052c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_m4_ck>, <&dpll_per_m2_ck>; -+ bit-shift = <1>; -+ reg = <0x44e0052c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gfx_fck_div_ck: gfx_fck_div_ck@44e0052c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&gfx_fclk_clksel_ck>; -+ reg = <0x44e0052c 0x4>; -+ table = < 1 0 >, < 2 1 >; -+ bit-mask = <0x1>; -+}; -+ -+sysclkout_pre_ck: sysclkout_pre_ck@44e00700 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_32768_ck>, <&l3_gclk>, <&dpll_ddr_m2_ck>, <&dpll_per_m2_ck>, <&lcd_gclk>; -+ reg = <0x44e00700 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+clkout2_div_ck: clkout2_div_ck@44e00700 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sysclkout_pre_ck>; -+ bit-shift = <3>; -+ reg = <0x44e00700 0x4>; -+ table = < 1 0 >, < 2 1 >, < 3 2 >, < 4 3 >, < 5 4 >, < 6 5 >, < 7 6 >, < 8 7 >; -+ bit-mask = <0x7>; -+}; -+ -+dbg_sysclk_ck: dbg_sysclk_ck@44e00414 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_clkin_ck>; -+ bit-shift = <19>; -+ reg = <0x44e00414 0x4>; -+}; -+ -+dbg_clka_ck: dbg_clka_ck@44e00414 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ bit-shift = <30>; -+ reg = <0x44e00414 0x4>; -+}; -+ -+stm_pmd_clock_mux_ck: stm_pmd_clock_mux_ck@44e00414 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dbg_sysclk_ck>, <&dbg_clka_ck>; -+ bit-shift = <22>; -+ reg = <0x44e00414 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+trace_pmd_clk_mux_ck: trace_pmd_clk_mux_ck@44e00414 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dbg_sysclk_ck>, <&dbg_clka_ck>; -+ bit-shift = <20>; -+ reg = <0x44e00414 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+stm_clk_div_ck: stm_clk_div_ck@44e00414 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&stm_pmd_clock_mux_ck>; -+ bit-shift = <27>; -+ reg = <0x44e00414 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+trace_clk_div_ck: trace_clk_div_ck@44e00414 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&trace_pmd_clk_mux_ck>; -+ bit-shift = <24>; -+ reg = <0x44e00414 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+clkout2_ck: clkout2_ck@44e00700 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkout2_div_ck>; -+ bit-shift = <7>; -+ reg = <0x44e00700 0x4>; -+}; -+ -+ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ bit-shift = <0>; -+ reg = <0x44e10664 0x4>; -+}; -+ -+ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ bit-shift = <1>; -+ reg = <0x44e10664 0x4>; -+}; -+ -+ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ bit-shift = <2>; -+ reg = <0x44e10664 0x4>; -+}; ---- a/arch/arm/boot/dts/am33xx.dtsi -+++ b/arch/arm/boot/dts/am33xx.dtsi -@@ -18,6 +18,9 @@ - interrupt-parent = <&intc>; - - aliases { -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2c2 = &i2c2; - serial0 = &uart0; - serial1 = &uart1; - serial2 = &uart2; -@@ -30,6 +33,8 @@ - usb1 = &usb1; - phy0 = &usb0_phy; - phy1 = &usb1_phy; -+ ethernet0 = &cpsw_emac0; -+ ethernet1 = &cpsw_emac1; - }; - - cpus { -@@ -53,6 +58,10 @@ - 275000 1125000 - >; - voltage-tolerance = <2>; /* 2 percentage */ -+ -+ clocks = <&dpll_mpu_ck>; -+ clock-names = "cpu"; -+ - clock-latency = <300000>; /* From omap-cpufreq driver */ - }; - }; -@@ -91,6 +100,8 @@ - #size-cells = <1>; - ranges; - ti,hwmods = "l3_main"; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; - - intc: interrupt-controller@48200000 { - compatible = "ti,omap2-intc"; -@@ -100,9 +111,23 @@ - reg = <0x48200000 0x1000>; - }; - -+ edma: edma@49000000 { -+ compatible = "ti,edma3"; -+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; -+ reg = <0x49000000 0x10000>, -+ <0x44e10f90 0x10>; -+ interrupts = <12 13 14>; -+ #dma-cells = <1>; -+ dma-channels = <64>; -+ ti,edma-regions = <4>; -+ ti,edma-slots = <256>; -+ }; -+ - gpio0: gpio@44e07000 { - compatible = "ti,omap4-gpio"; - ti,hwmods = "gpio1"; -+ clocks = <&dpll_core_m4_div2_ck>, <&gpio0_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -114,6 +139,8 @@ - gpio1: gpio@4804c000 { - compatible = "ti,omap4-gpio"; - ti,hwmods = "gpio2"; -+ clocks = <&l4ls_gclk>, <&gpio1_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -125,6 +152,8 @@ - gpio2: gpio@481ac000 { - compatible = "ti,omap4-gpio"; - ti,hwmods = "gpio3"; -+ clocks = <&l4ls_gclk>, <&gpio2_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -136,6 +165,8 @@ - gpio3: gpio@481ae000 { - compatible = "ti,omap4-gpio"; - ti,hwmods = "gpio4"; -+ clocks = <&l4ls_gclk>, <&gpio3_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -147,6 +178,8 @@ - uart0: serial@44e09000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart1"; -+ clocks = <&dpll_per_m2_div4_wkupdm_ck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - reg = <0x44e09000 0x2000>; - interrupts = <72>; -@@ -156,6 +189,8 @@ - uart1: serial@48022000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart2"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - reg = <0x48022000 0x2000>; - interrupts = <73>; -@@ -165,6 +200,8 @@ - uart2: serial@48024000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart3"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - reg = <0x48024000 0x2000>; - interrupts = <74>; -@@ -174,6 +211,8 @@ - uart3: serial@481a6000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart4"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - reg = <0x481a6000 0x2000>; - interrupts = <44>; -@@ -183,6 +222,8 @@ - uart4: serial@481a8000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart5"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - reg = <0x481a8000 0x2000>; - interrupts = <45>; -@@ -192,6 +233,8 @@ - uart5: serial@481aa000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart6"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - reg = <0x481aa000 0x2000>; - interrupts = <46>; -@@ -203,6 +246,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c1"; -+ clocks = <&dpll_per_m2_div4_wkupdm_ck>; -+ clock-names = "fck"; - reg = <0x44e0b000 0x1000>; - interrupts = <70>; - status = "disabled"; -@@ -213,6 +258,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c2"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - reg = <0x4802a000 0x1000>; - interrupts = <71>; - status = "disabled"; -@@ -223,14 +270,62 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c3"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; - reg = <0x4819c000 0x1000>; - interrupts = <30>; - status = "disabled"; - }; - -+ mmc1: mmc@48060000 { -+ compatible = "ti,omap4-hsmmc"; -+ ti,hwmods = "mmc1"; -+ clocks = <&mmc_clk>, <&clkdiv32k_ick>; -+ clock-names = "fck", "mmchsdb_fck"; -+ ti,dual-volt; -+ ti,needs-special-reset; -+ ti,needs-special-hs-handling; -+ dmas = <&edma 24 -+ &edma 25>; -+ dma-names = "tx", "rx"; -+ interrupts = <64>; -+ interrupt-parent = <&intc>; -+ reg = <0x48060000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@481d8000 { -+ compatible = "ti,omap4-hsmmc"; -+ ti,hwmods = "mmc2"; -+ clocks = <&mmc_clk>, <&clkdiv32k_ick>; -+ clock-names = "fck", "mmchsdb_fck"; -+ ti,needs-special-reset; -+ dmas = <&edma 2 -+ &edma 3>; -+ dma-names = "tx", "rx"; -+ interrupts = <28>; -+ interrupt-parent = <&intc>; -+ reg = <0x481d8000 0x1000>; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@47810000 { -+ compatible = "ti,omap4-hsmmc"; -+ ti,hwmods = "mmc3"; -+ clocks = <&mmc_clk>, <&clkdiv32k_ick>; -+ clock-names = "fck", "mmchsdb_fck"; -+ ti,needs-special-reset; -+ interrupts = <29>; -+ interrupt-parent = <&intc>; -+ reg = <0x47810000 0x1000>; -+ status = "disabled"; -+ }; -+ - wdt2: wdt@44e35000 { - compatible = "ti,omap3-wdt"; - ti,hwmods = "wd_timer2"; -+ clocks = <&wdt1_fck>; -+ clock-names = "fck"; - reg = <0x44e35000 0x1000>; - interrupts = <91>; - }; -@@ -238,6 +333,8 @@ - dcan0: d_can@481cc000 { - compatible = "bosch,d_can"; - ti,hwmods = "d_can0"; -+ clocks = <&dcan0_fck>; -+ clock-names = "fck"; - reg = <0x481cc000 0x2000 - 0x44e10644 0x4>; - interrupts = <52>; -@@ -247,17 +344,32 @@ - dcan1: d_can@481d0000 { - compatible = "bosch,d_can"; - ti,hwmods = "d_can1"; -+ clocks = <&dcan1_fck>; -+ clock-names = "fck"; - reg = <0x481d0000 0x2000 - 0x44e10644 0x4>; - interrupts = <55>; - status = "disabled"; - }; - -+ mailbox: mailbox@480C8000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x480C8000 0x200>; -+ interrupts = <77>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <8>; -+ ti,mbox-names = "wkup_m3"; -+ ti,mbox-data = <0 0 0 0>; -+ }; -+ - timer1: timer@44e31000 { - compatible = "ti,am335x-timer-1ms"; - reg = <0x44e31000 0x400>; - interrupts = <67>; - ti,hwmods = "timer1"; -+ clocks = <&timer1_fck>; -+ clock-names = "fck"; - ti,timer-alwon; - }; - -@@ -266,6 +378,8 @@ - reg = <0x48040000 0x400>; - interrupts = <68>; - ti,hwmods = "timer2"; -+ clocks = <&timer2_fck>; -+ clock-names = "fck"; - }; - - timer3: timer@48042000 { -@@ -273,6 +387,8 @@ - reg = <0x48042000 0x400>; - interrupts = <69>; - ti,hwmods = "timer3"; -+ clocks = <&timer3_fck>; -+ clock-names = "fck"; - }; - - timer4: timer@48044000 { -@@ -280,6 +396,8 @@ - reg = <0x48044000 0x400>; - interrupts = <92>; - ti,hwmods = "timer4"; -+ clocks = <&timer4_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -288,6 +406,8 @@ - reg = <0x48046000 0x400>; - interrupts = <93>; - ti,hwmods = "timer5"; -+ clocks = <&timer5_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -296,6 +416,8 @@ - reg = <0x48048000 0x400>; - interrupts = <94>; - ti,hwmods = "timer6"; -+ clocks = <&timer6_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -304,6 +426,8 @@ - reg = <0x4804a000 0x400>; - interrupts = <95>; - ti,hwmods = "timer7"; -+ clocks = <&timer7_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -313,6 +437,8 @@ - interrupts = <75 - 76>; - ti,hwmods = "rtc"; -+ clocks = <&clk_32768_ck>; -+ clock-names = "fck"; - }; - - spi0: spi@48030000 { -@@ -323,6 +449,13 @@ - interrupts = <65>; - ti,spi-num-cs = <2>; - ti,hwmods = "spi0"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ dmas = <&edma 16 -+ &edma 17 -+ &edma 18 -+ &edma 19>; -+ dma-names = "tx0", "rx0", "tx1", "rx1"; - status = "disabled"; - }; - -@@ -334,6 +467,13 @@ - interrupts = <125>; - ti,spi-num-cs = <2>; - ti,hwmods = "spi1"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ dmas = <&edma 42 -+ &edma 43 -+ &edma 44 -+ &edma 45>; -+ dma-names = "tx0", "rx0", "tx1", "rx1"; - status = "disabled"; - }; - -@@ -345,6 +485,8 @@ - #size-cells = <1>; - ti,hwmods = "usb_otg_hs"; - status = "disabled"; -+ clocks = <&usbotg_fck>; -+ clock-names = "fck"; - - ctrl_mod: control@44e10000 { - compatible = "ti,am335x-usb-ctrl-module"; -@@ -469,6 +611,8 @@ - compatible = "ti,am33xx-pwmss"; - reg = <0x48300000 0x10>; - ti,hwmods = "epwmss0"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - status = "disabled"; -@@ -481,6 +625,8 @@ - #pwm-cells = <3>; - reg = <0x48300100 0x80>; - ti,hwmods = "ecap0"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - -@@ -489,6 +635,8 @@ - #pwm-cells = <3>; - reg = <0x48300200 0x80>; - ti,hwmods = "ehrpwm0"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - }; -@@ -497,6 +645,8 @@ - compatible = "ti,am33xx-pwmss"; - reg = <0x48302000 0x10>; - ti,hwmods = "epwmss1"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - status = "disabled"; -@@ -509,6 +659,8 @@ - #pwm-cells = <3>; - reg = <0x48302100 0x80>; - ti,hwmods = "ecap1"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - -@@ -517,6 +669,8 @@ - #pwm-cells = <3>; - reg = <0x48302200 0x80>; - ti,hwmods = "ehrpwm1"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - }; -@@ -525,6 +679,8 @@ - compatible = "ti,am33xx-pwmss"; - reg = <0x48304000 0x10>; - ti,hwmods = "epwmss2"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - status = "disabled"; -@@ -537,6 +693,8 @@ - #pwm-cells = <3>; - reg = <0x48304100 0x80>; - ti,hwmods = "ecap2"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - -@@ -545,6 +703,8 @@ - #pwm-cells = <3>; - reg = <0x48304200 0x80>; - ti,hwmods = "ehrpwm2"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - }; -@@ -552,6 +712,8 @@ - mac: ethernet@4a100000 { - compatible = "ti,cpsw"; - ti,hwmods = "cpgmac0"; -+ clocks = <&cpsw_125mhz_gclk>; -+ clock-names = "fck"; - cpdma_channels = <8>; - ale_entries = <1024>; - bd_ram_size = <0x2000>; -@@ -581,6 +743,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "davinci_mdio"; -+ clocks = <&cpsw_125mhz_gclk>; -+ clock-names = "fck"; - bus_freq = <1000000>; - reg = <0x4a101000 0x100>; - }; -@@ -594,19 +758,33 @@ - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - }; -+ -+ phy_sel: cpsw-phy-sel@44e10650 { -+ compatible = "ti,am3352-cpsw-phy-sel"; -+ reg= <0x44e10650 0x4>; -+ reg-names = "gmii-sel"; -+ }; - }; - - ocmcram: ocmcram@40300000 { - compatible = "ti,am3352-ocmcram"; - reg = <0x40300000 0x10000>; - ti,hwmods = "ocmcram"; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; - }; - - wkup_m3: wkup_m3@44d00000 { - compatible = "ti,am3353-wkup-m3"; -- reg = <0x44d00000 0x4000 /* M3 UMEM */ -- 0x44d80000 0x2000>; /* M3 DMEM */ -+ reg = <0x44d00000 0x4000 -+ 0x44d80000 0x2000 -+ 0x44e11324 0x0024>; -+ reg-names = "m3_umem", "m3_dmem", "ipc_regs"; -+ interrupts = <78>; - ti,hwmods = "wkup_m3"; -+ ti,no-reset; -+ clocks = <&dpll_core_m4_div2_ck>; -+ clock-names = "fck"; - }; - - elm: elm@48080000 { -@@ -614,6 +792,8 @@ - reg = <0x48080000 0x2000>; - interrupts = <4>; - ti,hwmods = "elm"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; - status = "disabled"; - }; - -@@ -623,6 +803,8 @@ - interrupt-parent = <&intc>; - interrupts = <16>; - ti,hwmods = "adc_tsc"; -+ clocks = <&adc_tsc_fck>; -+ clock-names = "fck"; - status = "disabled"; - - tsc { -@@ -637,6 +819,9 @@ - gpmc: gpmc@50000000 { - compatible = "ti,am3352-gpmc"; - ti,hwmods = "gpmc"; -+ ti,no-idle; -+ clocks = <&l3s_gclk>; -+ clock-names = "fck"; - reg = <0x50000000 0x2000>; - interrupts = <100>; - gpmc,num-cs = <7>; -@@ -645,5 +830,102 @@ - #size-cells = <1>; - status = "disabled"; - }; -+ -+ prcm: prcm@44e00000 { -+ compatible = "ti,am3352-prcm"; -+ reg = <0x44e00000 0x1300>; -+ #reset-cells = <1>; -+ }; -+ -+ sham: sham@53100000 { -+ compatible = "ti,omap4-sham"; -+ ti,hwmods = "sham"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x53100000 0x200>; -+ interrupt-parent = <&intc>; -+ interrupts = <109>; -+ dmas = <&edma 36>; -+ dma-names = "rx"; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; -+ }; -+ -+ aes: aes@53500000 { -+ compatible = "ti,omap4-aes"; -+ ti,hwmods = "aes"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x53500000 0xa0>; -+ interrupt-parent = <&intc>; -+ interrupts = <103>; -+ dmas = <&edma 6 -+ &edma 5>; -+ dma-names = "tx", "rx"; -+ clocks = <&aes0_fck>; -+ clock-names = "fck"; -+ }; -+ -+ rng: rng@48310000 { -+ compatible = "ti,omap4-rng"; -+ ti,hwmods = "rng"; -+ reg = <0x48310000 0x2000>; -+ interrupts = <111>; -+ clocks = <&rng_fck>; -+ clock-names = "fck"; -+ }; -+ -+ lcdc: lcdc@0x4830e000 { -+ compatible = "ti,am33xx-tilcdc"; -+ reg = <0x4830e000 0x1000>; -+ interrupt-parent = <&intc>; -+ interrupts = <36>; -+ clocks = <&lcd_gclk>; -+ clock-names = "fck"; -+ ti,hwmods = "lcdc"; -+ status = "disabled"; -+ }; -+ -+ mcasp0: mcasp@48038000 { -+ compatible = "ti,omap2-mcasp-audio"; -+ ti,hwmods = "mcasp0"; -+ reg = <0x48038000 0x2000>, -+ <0x46400000 0x400000>; -+ reg-names = "mpu", "dma"; -+ interrupts = <80 81>; -+ interrupts-names = "tx", "rx"; -+ status = "disabled"; -+ dmas = <&edma 8 -+ &edma 9>; -+ dma-names = "tx", "rx"; -+ }; -+ -+ mcasp1: mcasp@4803C000 { -+ compatible = "ti,omap2-mcasp-audio"; -+ ti,hwmods = "mcasp1"; -+ reg = <0x4803C000 0x2000>, -+ <0x46400000 0x400000>; -+ reg-names = "mpu", "dma"; -+ interrupts = <82 83>; -+ interrupts-names = "tx", "rx"; -+ status = "disabled"; -+ dmas = <&edma 10 -+ &edma 11>; -+ dma-names = "tx", "rx"; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "am33xx-clocks.dtsi" - }; -+ -+ clockdomains { -+ clk_24mhz_clkdm: clk_24mhz_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&clkdiv32k_ick>; -+ }; -+ }; - }; ---- /dev/null -+++ b/arch/arm/boot/dts/am3517.dtsi -@@ -0,0 +1,116 @@ -+/* -+ * Device Tree Source for AM3517 SoC -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+#include "omap3.dtsi" -+ -+/ { -+ cpus { -+ cpu@0 { -+ /* OMAP343x/OMAP35xx variants OPP1-5 */ -+ operating-points = < -+ /* kHz uV */ -+ 125000 975000 -+ 250000 1075000 -+ 500000 1200000 -+ 550000 1270000 -+ 600000 1350000 -+ >; -+ clock-latency = <300000>; /* From legacy driver */ -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "am35xx-clocks.dtsi" -+ /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ dss_clkdm: dss_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; -+ }; -+ -+ usbhost_clkdm: usbhost_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&usbhost_48m_fck>, <&usbhost_ick>; -+ }; -+ -+ core_l4_clkdm: core_l4_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&mmchs1_ick>, <&mmchs2_ick>, <&hdq_fck>, -+ <&uart1_ick>, <&mcspi4_fck>, <&i2c3_fck>, -+ <&mcspi2_ick>, <&uart2_ick>, <&mcspi3_ick>, -+ <&i2c1_fck>, <&hdq_ick>, <&sha12_ick>, -+ <&mcbsp5_ick>, <&mcspi3_fck>, <&aes2_ick>, -+ <&mcspi1_ick>, <&uart2_fck>, <&mmchs2_fck>, -+ <&mmchs1_fck>, <&i2c3_ick>, <&mcspi1_fck>, -+ <&mcspi4_ick>, <&omapctrl_ick>, <&mcbsp1_ick>, -+ <&mcspi2_fck>, <&gpt10_ick>, <&i2c2_fck>, -+ <&i2c2_ick>, <&gpt11_ick>, <&i2c1_ick>, -+ <&uart1_fck>; -+ }; -+ -+ wkup_clkdm: wkup_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&wdt1_ick>, <&gpt12_ick>, <&gpio1_ick>, -+ <&gpt1_ick>, <&omap_32ksync_ick>, <&wdt2_ick>, -+ <&wdt2_fck>; -+ }; -+ -+ dpll4_clkdm: dpll4_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll4_ck>; -+ }; -+ -+ core_l3_clkdm: core_l3_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&sdrc_ick>; -+ }; -+ -+ per_clkdm: per_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&gpt2_ick>, <&uart3_fck>, <&gpio3_ick>, -+ <&mcbsp2_ick>, <&gpt6_ick>, <&mcbsp4_ick>, -+ <&gpt4_ick>, <&mcbsp3_ick>, <&gpt8_ick>, -+ <&uart3_ick>, <&gpt5_ick>, <&gpt7_ick>, -+ <&gpio2_ick>, <&gpio6_ick>, <&gpt9_ick>, -+ <&gpt3_ick>, <&gpio5_ick>, <&wdt3_ick>, -+ <&gpio4_ick>, <&wdt3_fck>, <&uart4_ick>; -+ }; -+ -+ emu_clkdm: emu_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&emu_src_ck>; -+ }; -+ -+ sgx_clkdm: sgx_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&sgx_ick>; -+ }; -+ -+ dpll3_clkdm: dpll3_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll3_ck>; -+ }; -+ -+ dpll5_clkdm: dpll5_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll5_ck>; -+ }; -+ -+ dpll1_clkdm: dpll1_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll1_ck>; -+ }; -+ }; -+}; ---- a/arch/arm/boot/dts/am3517-evm.dts -+++ b/arch/arm/boot/dts/am3517-evm.dts -@@ -7,7 +7,7 @@ - */ - /dts-v1/; - --#include "omap34xx.dtsi" -+#include "am3517.dtsi" - - / { - model = "TI AM3517 EVM (AM3517/05)"; ---- a/arch/arm/boot/dts/am3517_mt_ventoux.dts -+++ b/arch/arm/boot/dts/am3517_mt_ventoux.dts -@@ -7,7 +7,7 @@ - */ - /dts-v1/; - --#include "omap34xx.dtsi" -+#include "am3517.dtsi" - - / { - model = "TeeJet Mt.Ventoux"; ---- /dev/null -+++ b/arch/arm/boot/dts/am35xx-clocks.dtsi -@@ -0,0 +1,101 @@ -+/* -+ * Device Tree Source for AM35xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+ipss_ick: ipss_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,am35xx-interface-clock"; -+ clocks = <&core_l3_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <4>; -+}; -+ -+rmii_ck: rmii_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <50000000>; -+}; -+ -+pclk_ck: pclk_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <27000000>; -+}; -+ -+emac_ick: emac_ick@4800259c { -+ #clock-cells = <0>; -+ compatible = "ti,am35xx-gate-clock"; -+ clocks = <&ipss_ick>; -+ reg = <0x4800259c 0x4>; -+ ti,enable-bit = <1>; -+}; -+ -+emac_fck: emac_fck@4800259c { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&rmii_ck>; -+ reg = <0x4800259c 0x4>; -+ bit-shift = <9>; -+}; -+ -+vpfe_ick: vpfe_ick@4800259c { -+ #clock-cells = <0>; -+ compatible = "ti,am35xx-gate-clock"; -+ clocks = <&ipss_ick>; -+ reg = <0x4800259c 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+vpfe_fck: vpfe_fck@4800259c { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&pclk_ck>; -+ reg = <0x4800259c 0x4>; -+ bit-shift = <10>; -+}; -+ -+hsotgusb_ick: hsotgusb_ick@4800259c { -+ #clock-cells = <0>; -+ compatible = "ti,am35xx-gate-clock"; -+ clocks = <&ipss_ick>; -+ reg = <0x4800259c 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+hsotgusb_fck_am35xx: hsotgusb_fck_am35xx@4800259c { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x4800259c 0x4>; -+ bit-shift = <8>; -+}; -+ -+hecc_ck: hecc_ck@4800259c { -+ #clock-cells = <0>; -+ compatible = "ti,am35xx-gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x4800259c 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+uart4_ick_am35xx: uart4_ick_am35xx@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <23>; -+}; -+ -+uart4_fck_am35xx: uart4_fck_am35xx@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <23>; -+}; ---- a/arch/arm/boot/dts/am4372.dtsi -+++ b/arch/arm/boot/dts/am4372.dtsi -@@ -8,6 +8,7 @@ - * kind, whether express or implied. - */ - -+#include <dt-bindings/gpio/gpio.h> - #include <dt-bindings/interrupt-controller/arm-gic.h> - - #include "skeleton.dtsi" -@@ -18,12 +19,21 @@ - - - aliases { -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2c2 = &i2c2; - serial0 = &uart0; -+ ethernet0 = &cpsw_emac0; -+ ethernet1 = &cpsw_emac1; - }; - - cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; - cpu@0 { - compatible = "arm,cortex-a9"; -+ device_type = "cpu"; -+ reg = <0>; - }; - }; - -@@ -35,16 +45,124 @@ - <0x48240100 0x0100>; - }; - -+ l2-cache-controller@48242000 { -+ compatible = "arm,pl310-cache"; -+ reg = <0x48242000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ }; -+ -+ am43xx_pinmux: pinmux@44e10800 { -+ compatible = "pinctrl-single"; -+ reg = <0x44e10800 0x31c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-single,register-width = <32>; -+ pinctrl-single,function-mask = <0xffffffff>; -+ }; -+ - ocp { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; -+ ti,hwmods = "l3_main"; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; -+ -+ edma: edma@49000000 { -+ compatible = "ti,edma3"; -+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; -+ reg = <0x49000000 0x10000>, -+ <0x44e10f90 0x10>; -+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; -+ #dma-cells = <1>; -+ dma-channels = <64>; -+ ti,edma-regions = <4>; -+ ti,edma-slots = <256>; -+ }; - - uart0: serial@44e09000 { - compatible = "ti,am4372-uart","ti,omap2-uart"; - reg = <0x44e09000 0x2000>; - interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "uart1"; -+ clocks = <&dpll_per_m2_div4_wkupdm_ck>; -+ clock-names = "fck"; -+ }; -+ -+ uart1: serial@48022000 { -+ compatible = "ti,am4372-uart","ti,omap2-uart"; -+ reg = <0x48022000 0x2000>; -+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "uart2"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ uart2: serial@48024000 { -+ compatible = "ti,am4372-uart","ti,omap2-uart"; -+ reg = <0x48024000 0x2000>; -+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "uart3"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ uart3: serial@481a6000 { -+ compatible = "ti,am4372-uart","ti,omap2-uart"; -+ reg = <0x481a6000 0x2000>; -+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "uart4"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ uart4: serial@481a8000 { -+ compatible = "ti,am4372-uart","ti,omap2-uart"; -+ reg = <0x481a8000 0x2000>; -+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "uart5"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ uart5: serial@481aa000 { -+ compatible = "ti,am4372-uart","ti,omap2-uart"; -+ reg = <0x481aa000 0x2000>; -+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "uart6"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ mailbox: mailbox@480C8000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x480C8000 0x200>; -+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <8>; -+ ti,mbox-names = "wkup_m3"; -+ ti,mbox-data = <0 0 0 0>; -+ }; -+ -+ qspi: qspi@47900000 { -+ compatible = "ti,am4372-qspi"; -+ reg = <0x47900000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "qspi"; -+ interrupts = <0 138 0x4>; -+ num-cs = <4>; -+ mmap_read; - }; - - timer1: timer@44e31000 { -@@ -52,17 +170,818 @@ - reg = <0x44e31000 0x400>; - interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; - ti,timer-alwon; -+ ti,hwmods = "timer1"; -+ clocks = <&timer1_fck>; -+ clock-names = "fck"; - }; - - timer2: timer@48040000 { - compatible = "ti,am4372-timer","ti,am335x-timer"; - reg = <0x48040000 0x400>; - interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "timer2"; -+ clocks = <&timer2_fck>; -+ clock-names = "fck"; -+ }; -+ -+ timer3: timer@48042000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x48042000 0x400>; -+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "timer3"; -+ clocks = <&timer3_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer4: timer@48044000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x48044000 0x400>; -+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; -+ ti,timer-pwm; -+ ti,hwmods = "timer4"; -+ clocks = <&timer4_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer5: timer@48046000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x48046000 0x400>; -+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; -+ ti,timer-pwm; -+ ti,hwmods = "timer5"; -+ clocks = <&timer5_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer6: timer@48048000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x48048000 0x400>; -+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; -+ ti,timer-pwm; -+ ti,hwmods = "timer6"; -+ clocks = <&timer6_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer7: timer@4804a000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x4804a000 0x400>; -+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; -+ ti,timer-pwm; -+ ti,hwmods = "timer7"; -+ clocks = <&timer7_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer8: timer@481c1000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x481c1000 0x400>; -+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "timer8"; -+ clocks = <&timer8_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer9: timer@4833d000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x4833d000 0x400>; -+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "timer9"; -+ clocks = <&timer9_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer10: timer@4833f000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x4833f000 0x400>; -+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "timer10"; -+ clocks = <&timer10_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ timer11: timer@48341000 { -+ compatible = "ti,am4372-timer","ti,am335x-timer"; -+ reg = <0x48341000 0x400>; -+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "timer11"; -+ clocks = <&timer11_fck>; -+ clock-names = "fck"; -+ status = "disabled"; - }; - - counter32k: counter@44e86000 { - compatible = "ti,am4372-counter32k","ti,omap-counter32k"; - reg = <0x44e86000 0x40>; -+ ti,hwmods = "counter_32k"; -+ clocks = <&synctimer_32kclk>; -+ clock-names = "fck"; -+ }; -+ -+ rtc: rtc@44e3e000 { -+ compatible = "ti,am4372-rtc","ti,da830-rtc"; -+ reg = <0x44e3e000 0x1000>; -+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH -+ GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "rtc"; -+ clocks = <&clk_32768_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ wdt@44e35000 { -+ compatible = "ti,am4372-wdt","ti,omap3-wdt"; -+ reg = <0x44e35000 0x1000>; -+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "wd_timer2"; -+ clocks = <&wdt1_fck>; -+ clock-names = "fck"; -+ }; -+ -+ gpio0: gpio@44e07000 { -+ compatible = "ti,am4372-gpio","ti,omap4-gpio"; -+ reg = <0x44e07000 0x1000>; -+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ ti,hwmods = "gpio1"; -+ clocks = <&sys_clkin_ck>, <&gpio0_dbclk>; -+ clock-names = "fck", "dbclk"; -+ status = "disabled"; -+ }; -+ -+ gpio1: gpio@4804c000 { -+ compatible = "ti,am4372-gpio","ti,omap4-gpio"; -+ reg = <0x4804c000 0x1000>; -+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ ti,hwmods = "gpio2"; -+ clocks = <&l4ls_gclk>, <&gpio1_dbclk>; -+ clock-names = "fck", "dbclk"; -+ status = "disabled"; -+ }; -+ -+ gpio2: gpio@481ac000 { -+ compatible = "ti,am4372-gpio","ti,omap4-gpio"; -+ reg = <0x481ac000 0x1000>; -+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ ti,hwmods = "gpio3"; -+ clocks = <&l4ls_gclk>, <&gpio2_dbclk>; -+ clock-names = "fck", "dbclk"; -+ status = "disabled"; -+ }; -+ -+ gpio3: gpio@481ae000 { -+ compatible = "ti,am4372-gpio","ti,omap4-gpio"; -+ reg = <0x481ae000 0x1000>; -+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ ti,hwmods = "gpio4"; -+ clocks = <&l4ls_gclk>, <&gpio3_dbclk>; -+ clock-names = "fck", "dbclk"; -+ status = "disabled"; -+ }; -+ -+ gpio4: gpio@48320000 { -+ compatible = "ti,am4372-gpio","ti,omap4-gpio"; -+ reg = <0x48320000 0x1000>; -+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ ti,hwmods = "gpio5"; -+ clocks = <&l4ls_gclk>, <&gpio4_dbclk>; -+ clock-names = "fck", "dbclk"; -+ status = "disabled"; -+ }; -+ -+ gpio5: gpio@48322000 { -+ compatible = "ti,am4372-gpio","ti,omap4-gpio"; -+ reg = <0x48322000 0x1000>; -+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ ti,hwmods = "gpio6"; -+ clocks = <&l4ls_gclk>, <&gpio5_dbclk>; -+ clock-names = "fck", "dbclk"; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@44e0b000 { -+ compatible = "ti,am4372-i2c","ti,omap4-i2c"; -+ reg = <0x44e0b000 0x1000>; -+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "i2c1"; -+ clocks = <&dpll_per_m2_div4_wkupdm_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ tps: tps@24 { -+ reg = <0x24>; -+ }; -+ }; -+ -+ i2c1: i2c@4802a000 { -+ compatible = "ti,am4372-i2c","ti,omap4-i2c"; -+ reg = <0x4802a000 0x1000>; -+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "i2c2"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c2: i2c@4819c000 { -+ compatible = "ti,am4372-i2c","ti,omap4-i2c"; -+ reg = <0x4819c000 0x1000>; -+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "i2c3"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@48030000 { -+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; -+ reg = <0x48030000 0x400>; -+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "spi0"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; - }; -+ -+ mmc1: mmc@48060000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x48060000 0x1000>; -+ ti,hwmods = "mmc1"; -+ clocks = <&mmc_clk>, <&clkdiv32k_ick>; -+ clock-names = "fck", "mmchsdb_fck"; -+ ti,dual-volt; -+ ti,needs-special-reset; -+ dmas = <&edma 24 -+ &edma 25>; -+ dma-names = "tx", "rx"; -+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@481d8000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x481d8000 0x1000>; -+ ti,hwmods = "mmc2"; -+ clocks = <&mmc_clk>, <&clkdiv32k_ick>; -+ clock-names = "fck", "mmchsdb_fck"; -+ ti,needs-special-reset; -+ dmas = <&edma 2 -+ &edma 3>; -+ dma-names = "tx", "rx"; -+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@47810000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x47810000 0x1000>; -+ ti,hwmods = "mmc3"; -+ clocks = <&mmc_clk>, <&clkdiv32k_ick>; -+ clock-names = "fck", "mmchsdb_fck"; -+ ti,needs-special-reset; -+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ spi1: spi@481a0000 { -+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; -+ reg = <0x481a0000 0x400>; -+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "spi1"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi2: spi@481a2000 { -+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; -+ reg = <0x481a2000 0x400>; -+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "spi2"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi3: spi@481a4000 { -+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; -+ reg = <0x481a4000 0x400>; -+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "spi3"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi4: spi@48345000 { -+ compatible = "ti,am4372-mcspi","ti,omap4-mcspi"; -+ reg = <0x48345000 0x400>; -+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "spi4"; -+ clocks = <&dpll_per_m2_div4_ck>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ mac: ethernet@4a100000 { -+ compatible = "ti,am4372-cpsw","ti,cpsw"; -+ reg = <0x4a100000 0x800 -+ 0x4a101200 0x100>; -+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH -+ GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH -+ GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH -+ GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ti,hwmods = "cpgmac0"; -+ clocks = <&cpsw_125mhz_gclk>; -+ clock-names = "fck"; -+ cpdma_channels = <8>; -+ ale_entries = <1024>; -+ bd_ram_size = <0x2000>; -+ no_bd_ram = <0>; -+ rx_descs = <64>; -+ mac_control = <0x20>; -+ slaves = <2>; -+ active_slave = <0>; -+ cpts_clock_mult = <0x80000000>; -+ cpts_clock_shift = <29>; -+ ranges; -+ status = "disabled"; -+ -+ davinci_mdio: mdio@4a101000 { -+ compatible = "ti,am4372-mdio","ti,davinci_mdio"; -+ reg = <0x4a101000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "davinci_mdio"; -+ clocks = <&cpsw_125mhz_gclk>; -+ clock-names = "fck"; -+ bus_freq = <1000000>; -+ status = "disabled"; -+ }; -+ -+ cpsw_emac0: slave@4a100200 { -+ /* Filled in by U-Boot */ -+ mac-address = [ 00 00 00 00 00 00 ]; -+ }; -+ -+ cpsw_emac1: slave@4a100300 { -+ /* Filled in by U-Boot */ -+ mac-address = [ 00 00 00 00 00 00 ]; -+ }; -+ -+ phy_sel: cpsw-phy-sel@44e10650 { -+ compatible = "ti,am3352-cpsw-phy-sel"; -+ reg= <0x44e10650 0x4>; -+ reg-names = "gmii-sel"; -+ }; -+ }; -+ -+ epwmss0: epwmss@48300000 { -+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; -+ reg = <0x48300000 0x10>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "epwmss0"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ -+ ecap0: ecap@48300100 { -+ compatible = "ti,am4372-ecap","ti,am33xx-ecap"; -+ reg = <0x48300100 0x80>; -+ ti,hwmods = "ecap0"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ ehrpwm0: ehrpwm@48300200 { -+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; -+ reg = <0x48300200 0x80>; -+ ti,hwmods = "ehrpwm0"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ }; -+ -+ epwmss1: epwmss@48302000 { -+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; -+ reg = <0x48302000 0x10>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "epwmss1"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ -+ ecap1: ecap@48302100 { -+ compatible = "ti,am4372-ecap","ti,am33xx-ecap"; -+ reg = <0x48302100 0x80>; -+ ti,hwmods = "ecap1"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ ehrpwm1: ehrpwm@48302200 { -+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; -+ reg = <0x48302200 0x80>; -+ ti,hwmods = "ehrpwm1"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ }; -+ -+ epwmss2: epwmss@48304000 { -+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; -+ reg = <0x48304000 0x10>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "epwmss2"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ -+ ecap2: ecap@48304100 { -+ compatible = "ti,am4372-ecap","ti,am33xx-ecap"; -+ reg = <0x48304100 0x80>; -+ ti,hwmods = "ecap2"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ ehrpwm2: ehrpwm@48304200 { -+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; -+ reg = <0x48304200 0x80>; -+ ti,hwmods = "ehrpwm2"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ }; -+ -+ epwmss3: epwmss@48306000 { -+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; -+ reg = <0x48306000 0x10>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "epwmss3"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ -+ ehrpwm3: ehrpwm@48306200 { -+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; -+ reg = <0x48306200 0x80>; -+ ti,hwmods = "ehrpwm3"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ }; -+ -+ epwmss4: epwmss@48308000 { -+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; -+ reg = <0x48308000 0x10>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "epwmss4"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ -+ ehrpwm4: ehrpwm@48308200 { -+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; -+ reg = <0x48308200 0x80>; -+ ti,hwmods = "ehrpwm4"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ }; -+ -+ epwmss5: epwmss@4830a000 { -+ compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; -+ reg = <0x4830a000 0x10>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "epwmss5"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ -+ ehrpwm5: ehrpwm@4830a200 { -+ compatible = "ti,am4372-ehrpwm","ti,am33xx-ehrpwm"; -+ reg = <0x4830a200 0x80>; -+ ti,hwmods = "ehrpwm5"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ }; -+ -+ wkup_m3: wkup_m3@44d00000 { -+ compatible = "ti,am4372-wkup-m3","ti,am3353-wkup-m3"; -+ reg = <0x44d00000 0x4000 /* M3 UMEM */ -+ 0x44d80000 0x2000>; /* M3 DMEM */ -+ ti,hwmods = "wkup_m3"; -+ clocks = <&sys_clkin_ck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ tscadc: tscadc@44e0d000 { -+ compatible = "ti,am4372-tscadc","ti,am3359-tscadc"; -+ reg = <0x44e0d000 0x1000>; -+ ti,hwmods = "adc_tsc"; -+ clocks = <&adc_tsc_fck>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ ocmcram: ocmcram@40300000 { -+ compatible = "ti,am4372-ocmcram","ti,am3352-ocmcram"; -+ reg = <0x40300000 0x40000>; -+ ti,hwmods = "ocmcram"; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ dcan0: d_can@481cc000 { -+ compatible = "bosch,d_can"; -+ ti,hwmods = "d_can0"; -+ clocks = <&dcan0_fck>; -+ clock-names = "fck"; -+ reg = <0x481cc000 0x2000 -+ 0x44e10644 0x4>; -+ status = "disabled"; -+ }; -+ -+ dcan1: d_can@481d0000 { -+ compatible = "bosch,d_can"; -+ ti,hwmods = "d_can1"; -+ clocks = <&dcan1_fck>; -+ clock-names = "fck"; -+ reg = <0x481d0000 0x2000 -+ 0x44e10644 0x4>; -+ status = "disabled"; -+ }; -+ -+ elm: elm@48080000 { -+ compatible = "ti,am4372-elm","ti,am3352-elm"; -+ reg = <0x48080000 0x2000>; -+ ti,hwmods = "elm"; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ gpmc: gpmc@50000000 { -+ compatible = "ti,am4372-gpmc","ti,am3352-gpmc"; -+ ti,hwmods = "gpmc"; -+ clocks = <&l3s_gclk>; -+ clock-names = "fck"; -+ reg = <0x50000000 0x2000>; -+ status = "disabled"; -+ }; -+ -+ prcm: prcm@44df0000 { -+ compatible = "ti,am4372-prcm"; -+ reg = <0x44df0000 0xa000>; -+ #reset-cells = <1>; -+ }; -+ -+ rng: rng@48310000 { -+ compatible = "ti,omap4-rng"; -+ ti,hwmods = "rng"; -+ reg = <0x48310000 0x2000>; -+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&rng_fck>; -+ clock-names = "fck"; -+ }; -+ -+ sham: sham@53100000 { -+ compatible = "ti,omap5-sham"; -+ ti,hwmods = "sham"; -+ reg = <0x53100000 0x300>; -+ dmas = <&edma 36>; -+ dma-names = "rx"; -+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; -+ }; -+ -+ aes: aes@53501000 { -+ compatible = "ti,omap4-aes"; -+ ti,hwmods = "aes"; -+ reg = <0x53501000 0xa0>; -+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; -+ dmas = <&edma 6 -+ &edma 5>; -+ dma-names = "tx", "rx"; -+ clocks = <&aes0_fck>; -+ clock-names = "fck"; -+ }; -+ -+ des: des@53701000 { -+ compatible = "ti,omap4-des"; -+ ti,hwmods = "des"; -+ reg = <0x53701000 0xa0>; -+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; -+ dmas = <&edma 34 -+ &edma 33>; -+ dma-names = "tx", "rx"; -+ clocks = <&l3_gclk>; -+ clock-names = "fck"; -+ }; -+ -+ am43xx_control_usb2phy1: control-phy@44e10620 { -+ compatible = "ti,control-phy-am437usb2"; -+ reg = <0x44e10620 0x4>; -+ reg-names = "power"; -+ }; -+ -+ am43xx_control_usb2phy2: control-phy@0x44e10628 { -+ compatible = "ti,control-phy-am437usb2"; -+ reg = <0x44e10628 0x4>; -+ reg-names = "power"; -+ }; -+ -+ ocp2scp0: ocp2scp@483a8000 { -+ compatible = "ti,omap-ocp2scp"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "ocp2scp0"; -+ -+ usb2_phy1: usb2phy1@483a8000 { -+ compatible = "ti,am437x-usb2"; -+ reg = <0x483a8000 0x8000>; -+ ctrl-module = <&am43xx_control_usb2phy1>; -+ clocks = <&clk_32768_ck>, -+ <&usb_otg_ss0_refclk960m>; -+ clock-names = "wkupclk", -+ "refclk"; -+ #phy-cells = <0>; -+ }; -+ -+ }; -+ -+ ocp2scp1: ocp2scp@483e8000 { -+ compatible = "ti,omap-ocp2scp"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "ocp2scp1"; -+ -+ usb2_phy2: usb2phy2@483e8000 { -+ compatible = "ti,am437x-usb2"; -+ reg = <0x483e8000 0x8000>; -+ ctrl-module = <&am43xx_control_usb2phy2>; -+ clocks = <&clk_32768_ck>, -+ <&usb_otg_ss1_refclk960m>; -+ clock-names = "wkupclk", -+ "refclk"; -+ #phy-cells = <0>; -+ }; -+ -+ }; -+ -+ dwc3_1: omap_dwc3_1@48380000 { -+ compatible = "ti,am437x-dwc3"; -+ ti,hwmods = "usb_otg_ss0"; -+ reg = <0x48380000 0x10000>; -+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ utmi-mode = <1>; -+ ranges; -+ usb1: usb@48390000 { -+ compatible = "synopsys,dwc3"; -+ reg = <0x48390000 0x17000>; -+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>; -+ phys = <&usb2_phy1>; -+ phy-names = "usb2-phy"; -+ maximum-speed = "high-speed"; -+ dr_mode = "peripheral"; -+ }; -+ }; -+ -+ dwc3_2: omap_dwc3_2@483c0000 { -+ compatible = "ti,am437x-dwc3"; -+ ti,hwmods = "usb_otg_ss1"; -+ reg = <0x483c0000 0x10000>; -+ interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ utmi-mode = <1>; -+ ranges; -+ usb2: usb@483d0000 { -+ compatible = "synopsys,dwc3"; -+ reg = <0x483d0000 0x17000>; -+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; -+ phys = <&usb2_phy2>; -+ phy-names = "usb2-phy"; -+ maximum-speed = "high-speed"; -+ dr_mode = "host"; -+ }; -+ }; -+ -+ dss: dss@4832A000 { -+ compatible = "ti,omap3-dss", "simple-bus"; -+ reg = <0x4832A000 0x200>; -+ ti,hwmods = "dss_core"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ dispc@4832A400 { -+ compatible = "ti,omap3-dispc"; -+ reg = <0x4832A400 0x400>; -+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "dss_dispc"; -+ }; -+ -+ dpi: encoder@0 { -+ compatible = "ti,omap3-dpi"; -+ }; -+ -+ rfbi: rfbi@4832A800 { -+ compatible = "ti,omap3-rfbi"; -+ reg = <0x4832A800 0x100>; -+ ti,hwmods = "dss_rfbi"; -+ }; -+ -+ }; -+ - }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "am43xx-clocks.dtsi" -+ }; -+ - }; -+ -+/include/ "tps65218.dtsi" ---- /dev/null -+++ b/arch/arm/boot/dts/am437x-gp-evm.dts -@@ -0,0 +1,238 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ */ -+ -+/* AM437x GP EVM */ -+ -+/dts-v1/; -+ -+#include "am43x-common-evm.dtsi" -+#include <dt-bindings/pinctrl/am43xx.h> -+ -+/ { -+ model = "TI AM437x gp EVM"; -+ compatible = "ti,am437x-gp-evm","ti,am4372","ti,am43"; -+ -+ vmmcsd_fixed: fixedregulator-sd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vmmcsd_fixed"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ enable-active-high; -+ }; -+ -+ aliases { -+ display0 = &lcd0; -+ display1 = &hdmi0; -+ }; -+ -+ lcd0: display@0 { -+ compatible = "osddisplays,osd057T0559-34ts", "panel-dpi"; -+ video-source = <&dpi>; -+ data-lines = <24>; -+ gpios = <0 /* No Enable GPIO */ -+ &gpio0 7 GPIO_ACTIVE_LOW>; /* LCD backlight GPIO */ -+ activelow_backlight; /* LCD backlight is Active low */ -+ panel-timing { -+ clock-frequency = <33000000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <210>; -+ hback-porch = <16>; -+ hsync-len = <30>; -+ vback-porch = <10>; -+ vfront-porch = <22>; -+ vsync-len = <13>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ de-active = <1>; -+ pixelclk-active = <1>; -+ }; -+ }; -+ -+ hdmi0: connector@1 { -+ compatible = "ti,hdmi_connector"; -+ video-source = <&sii9022>; -+ }; -+}; -+ -+&am43xx_pinmux { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dss_pinctrl>; -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_txen */ -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rxctl */ -+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd3 */ -+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd2 */ -+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_txd1 */ -+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_txd0 */ -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rmii1_tclk */ -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */ -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd3 */ -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd2 */ -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rxd1 */ -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rxd0 */ -+ >; -+ }; -+ -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 reset value */ -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ -+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ /* MDIO reset value */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ -+ >; -+ }; -+ -+ i2c0_pins: pinmux_i2c0_pins { -+ pinctrl-single,pins = < -+ 0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */ -+ 0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */ -+ >; -+ }; -+ -+ i2c1_pins: i2c1_pins { -+ pinctrl-single,pins = < -+ 0x15c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */ -+ 0x158 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */ -+ >; -+ }; -+ -+ dss_pinctrl: dss_pinctrl { -+ pinctrl-single,pins = < -+ 0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */ -+ 0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x02C (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x03C (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */ -+ 0x0A0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */ -+ 0x0A4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0A8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0AC (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0B0 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0B4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0B8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0BC (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0C0 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0C4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0C8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0CC (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0D0 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0D4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0D8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0DC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */ -+ 0x0E0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */ -+ 0x0E4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */ -+ 0x0E8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */ -+ 0x0EC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */ -+ 0x238 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* GPIO 5_8 to select LCD / HDMI */ -+ 0x164 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* ECAP0_IN_PWM0_OUT -> GPIO 0_7 BACKLIGHT */ -+ >; -+ }; -+}; -+ -+&rtc { -+ status = "okay"; -+}; -+ -+&gpio0 { -+ status = "okay"; -+}; -+ -+&gpio5 { -+ status = "okay"; -+}; -+ -+&mac { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+ status = "okay"; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+ status = "okay"; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <0>; -+ phy-mode = "rgmii"; -+}; -+ -+&cpsw_emac1 { -+ phy_id = <&davinci_mdio>, <1>; -+ phy-mode = "rgmii"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ vmmc-supply = <&vmmcsd_fixed>; -+ bus-width = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ -+ sii9022: sii9022@3b { -+ compatible = "sii,sii9022"; -+ reg = <0x3b>; -+ reset-gpio = <&gpio5 8 GPIO_ACTIVE_LOW>;/* 'SelLCDorHDMI' Gpio, LOW to select HDMI */ -+ video-source = <&dpi>; -+ data-lines = <24>; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/am43x-common-evm.dtsi -@@ -0,0 +1,9 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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 "am4372.dtsi" ---- a/arch/arm/boot/dts/am43x-epos-evm.dts -+++ b/arch/arm/boot/dts/am43x-epos-evm.dts -@@ -10,9 +10,289 @@ - - /dts-v1/; - --#include "am4372.dtsi" -+#include "am43x-common-evm.dtsi" -+#include <dt-bindings/pinctrl/am43xx.h> - - / { - model = "TI AM43x EPOS EVM"; - compatible = "ti,am43x-epos-evm","ti,am4372","ti,am43"; -+ -+ vmmcsd_fixed: fixedregulator-sd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vmmcsd_fixed"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ enable-active-high; -+ }; -+ -+ aliases { -+ display0 = &lcd0; -+ display1 = &hdmi0; -+ }; -+ -+ lcd0: display@0 { -+ compatible = "osddisplays,osd057T0559-34ts", "panel-dpi"; -+ video-source = <&dpi>; -+ data-lines = <24>; -+ gpios = <0 /* No Enable GPIO */ -+ &gpio0 7 GPIO_ACTIVE_LOW>; /* LCD backlight GPIO */ -+ panel-timing { -+ clock-frequency = <33000000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <210>; -+ hback-porch = <16>; -+ hsync-len = <30>; -+ vback-porch = <10>; -+ vfront-porch = <22>; -+ vsync-len = <13>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ de-active = <1>; -+ pixelclk-active = <1>; -+ }; -+ }; -+ -+ hdmi0: connector@1 { -+ compatible = "ti,hdmi_connector"; -+ video-source = <&sii9022>; -+ }; -+}; -+ -+&am43xx_pinmux { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dss_pinctrl>; -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs */ -+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */ -+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */ -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxdv.rmii1_rxdv */ -+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */ -+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */ -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */ -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */ -+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii1_refclk.rmii1_refclk */ -+ >; -+ }; -+ -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 reset value */ -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ -+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ /* MDIO reset value */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ -+ >; -+ }; -+ -+ i2c0_pins: pinmux_i2c0_pins { -+ pinctrl-single,pins = < -+ 0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */ -+ 0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */ -+ >; -+ }; -+ -+ i2c2_pins: pinmux_i2c2_pins { -+ pinctrl-single,pins = < -+ 0x1c0 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c2_sda.i2c2_sda */ -+ 0x1c4 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c2_scl.i2c2_scl */ -+ >; -+ }; -+ -+ spi0_pins: pinmux_spi0_pins { -+ pinctrl-single,pins = < -+ 0x150 (PIN_INPUT | MUX_MODE0) /* spi0_clk.spi0_clk */ -+ 0x154 (PIN_OUTPUT | MUX_MODE0) /* spi0_d0.spi0_d0 */ -+ 0x158 (PIN_INPUT | MUX_MODE0) /* spi0_d1.spi0_d1 */ -+ 0x15c (PIN_OUTPUT | MUX_MODE0) /* spi0_cs0.spi0_cs0 */ -+ >; -+ }; -+ -+ spi1_pins: pinmux_spi1_pins { -+ pinctrl-single,pins = < -+ 0x190 (PIN_INPUT | MUX_MODE3) /* mcasp0_aclkx.spi1_clk */ -+ 0x194 (PIN_OUTPUT | MUX_MODE3) /* mcasp0_fsx.spi1_d0 */ -+ 0x198 (PIN_INPUT | MUX_MODE3) /* mcasp0_axr0.spi1_d1 */ -+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* mcasp0_ahclkr.spi1_cs0 */ -+ >; -+ }; -+ -+ pixcir_ts_pins: pixcir_ts_pins { -+ pinctrl-single,pins = < -+ 0x48 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_a1.gpio1_17 */ -+ >; -+ }; -+ -+ dss_pinctrl: dss_pinctrl { -+ pinctrl-single,pins = < -+ 0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 8 -> DSS DATA 23 */ -+ 0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x02C (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1) -+ 0x03C (PIN_OUTPUT_PULLUP | MUX_MODE1) /*gpmc ad 15 -> DSS DATA 16 */ -+ 0x0A0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */ -+ 0x0A4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0A8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0AC (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0B0 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0B4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0B8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0BC (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0C0 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0C4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0C8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0CC (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0D0 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0D4 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0D8 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ 0x0DC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */ -+ 0x0E0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */ -+ 0x0E4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */ -+ 0x0E8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */ -+ 0x0EC (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */ -+ 0x08C (PIN_OUTPUT_PULLUP | MUX_MODE7) /* GPMC CLK -> GPIO 2_1 to select LCD / HDMI */ -+ 0x164 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* ECAP0_IN_PWM0_OUT -> GPIO 0_7 BACKLIGHT */ -+ >; -+ }; -+}; -+ -+&gpio0 { -+ status = "okay"; -+}; -+ -+&gpio1 { -+ status = "okay"; -+}; -+ -+&gpio2 { -+ status = "okay"; -+}; -+ -+&qspi { -+ spi-max-frequency = <48000000>; -+ m25p80@0 { -+ compatible = "mx66l51235l"; -+ spi-max-frequency = <48000000>; -+ reg = <0>; -+ spi-cpol; -+ spi-cpha; -+ tx-nbits = <1>; -+ rx-nbits = <4>; -+ }; -+}; -+ -+&mac { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+ status = "okay"; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+ status = "okay"; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <16>; -+ phy-mode = "rmii"; -+}; -+ -+&cpsw_emac1 { -+ phy_id = <&davinci_mdio>, <1>; -+ phy-mode = "rmii"; -+}; -+ -+&phy_sel { -+ rmii-clock-ext; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ vmmc-supply = <&vmmcsd_fixed>; -+ bus-width = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+ clock-frequency = <400000>; -+ -+ pixcir_ts@5c { -+ compatible = "pixcir,pixcir_tangoc"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pixcir_ts_pins>; -+ reg = <0x5c>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <17 0>; -+ -+ attb-gpio = <&gpio1 17 GPIO_ACTIVE_HIGH>; -+ -+ x-size = <1024>; -+ y-size = <600>; -+ }; -+}; -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ status = "okay"; -+ -+ sii9022: sii9022@3b { -+ compatible = "sii,sii9022"; -+ reg = <0x3b>; -+ reset-gpio = <&gpio2 1 GPIO_ACTIVE_LOW>;/* 65'SelLCDorHDMI' Gpio, LOW to select HDMI */ -+ video-source = <&dpi>; -+ data-lines = <24>; -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ status = "okay"; -+}; -+ -+&spi1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins>; -+ status = "okay"; - }; ---- /dev/null -+++ b/arch/arm/boot/dts/am43xx-clocks.dtsi -@@ -0,0 +1,735 @@ -+/* -+ * Device Tree Source for AM43xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+clk_32768_ck: clk_32768_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+clk_rc32k_ck: clk_rc32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+virt_19200000_ck: virt_19200000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <19200000>; -+}; -+ -+virt_24000000_ck: virt_24000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24000000>; -+}; -+ -+virt_25000000_ck: virt_25000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+}; -+ -+virt_26000000_ck: virt_26000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+crystal_freq_sel_ck: crystal_freq_sel_ck@44e10040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>; -+ bit-shift = <29>; -+ reg = <0x44e10040 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+sysboot_freq_sel_ck: sysboot_freq_sel_ck@44e10040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_19200000_ck>, <&virt_24000000_ck>, <&virt_25000000_ck>, <&virt_26000000_ck>; -+ bit-shift = <22>; -+ reg = <0x44e10040 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+sys_clkin_ck: sys_clkin_ck@44e10040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sysboot_freq_sel_ck>, <&crystal_freq_sel_ck>; -+ bit-shift = <31>; -+ reg = <0x44e10040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+tclkin_ck: tclkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+dpll_core_ck: dpll_core_ck@44df2d20 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-core-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44df2d20 0x4>, <0x44df2d24 0x4>, <0x44df2d2c 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_core_x2_ck: dpll_core_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_core_ck>; -+}; -+ -+dpll_core_m4_ck: dpll_core_m4_ck@44df2d38 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2d38 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_m5_ck: dpll_core_m5_ck@44df2d3c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2d3c 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_m6_ck: dpll_core_m6_ck@44df2d40 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2d40 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_mpu_ck: dpll_mpu_ck@44df2d60 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44df2d60 0x4>, <0x44df2d64 0x4>, <0x44df2d6c 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_mpu_m2_ck: dpll_mpu_m2_ck@44df2d70 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_mpu_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2d70 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_ddr_ck: dpll_ddr_ck@44df2da0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44df2da0 0x4>, <0x44df2da4 0x4>, <0x44df2dac 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_ddr_m2_ck: dpll_ddr_m2_ck@44df2db0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_ddr_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2db0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_disp_ck: dpll_disp_ck@44df2e20 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44df2e20 0x4>, <0x44df2e24 0x4>, <0x44df2e2c 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_disp_m2_ck: dpll_disp_m2_ck@44df2e30 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_disp_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2e30 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_ck: dpll_per_ck@44df2de0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-j-type-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44df2de0 0x4>, <0x44df2de4 0x4>, <0x44df2dec 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_per_m2_ck: dpll_per_m2_ck@44df2df0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2df0 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m2_div4_wkupdm_ck: dpll_per_m2_div4_wkupdm_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+dpll_per_m2_div4_ck: dpll_per_m2_div4_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+adc_tsc_fck: adc_tsc_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+clk_24mhz: clk_24mhz { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+clkdiv32k_ck: clkdiv32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&clk_24mhz>; -+ clock-mult = <1>; -+ clock-div = <732>; -+}; -+ -+clkdiv32k_ick: clkdiv32k_ick@44df2a38 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ck>; -+ bit-shift = <8>; -+ reg = <0x44df2a38 0x4>; -+}; -+ -+dcan0_fck: dcan0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dcan1_fck: dcan1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sysclk_div: sysclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+pruss_ocp_gclk: pruss_ocp_gclk@44df4248 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sysclk_div>, <&dpll_disp_m2_ck>; -+ reg = <0x44df4248 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcasp0_fck: mcasp0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mcasp1_fck: mcasp1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+smartreflex0_fck: smartreflex0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+smartreflex1_fck: smartreflex1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sha0_fck: sha0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+rng_fck: rng_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+aes0_fck: aes0_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+clk_32k_tpm_ck: clk_32k_tpm_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+timer1_fck: timer1_fck@44df4200 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&clkdiv32k_ick>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>, <&clk_32k_tpm_ck>; -+ reg = <0x44df4200 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+timer2_fck: timer2_fck@44df4204 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df4204 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer3_fck: timer3_fck@44df4208 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df4208 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer4_fck: timer4_fck@44df420c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df420c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer5_fck: timer5_fck@44df4210 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df4210 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer6_fck: timer6_fck@44df4214 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df4214 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer7_fck: timer7_fck@44df4218 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df4218 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+wdt1_fck: wdt1_fck@44df422c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_rc32k_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df422c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+l3_gclk: l3_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_core_m4_div2_ck: dpll_core_m4_div2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sysclk_div>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+l4hs_gclk: l4hs_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l3s_gclk: l3s_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_div2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l4ls_gclk: l4ls_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4_div2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+cpsw_125mhz_gclk: cpsw_125mhz_gclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m5_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+cpsw_cpts_rft_clk: cpsw_cpts_rft_clk@44df4238 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sysclk_div>, <&dpll_core_m5_ck>, <&dpll_disp_m2_ck>; -+ reg = <0x44df4238 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+clk_32k_mosc_ck: clk_32k_mosc_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+gpio0_dbclk_mux_ck: gpio0_dbclk_mux_ck@44df4240 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&clkdiv32k_ick>, <&clk_32k_mosc_ck>, <&clk_32k_tpm_ck>; -+ reg = <0x44df4240 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+gpio0_dbclk: gpio0_dbclk@44df2b68 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpio0_dbclk_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x44df2b68 0x4>; -+}; -+ -+gpio1_dbclk: gpio1_dbclk@44df8c78 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <8>; -+ reg = <0x44df8c78 0x4>; -+}; -+ -+gpio2_dbclk: gpio2_dbclk@44df8c80 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <8>; -+ reg = <0x44df8c80 0x4>; -+}; -+ -+gpio3_dbclk: gpio3_dbclk@44df8c88 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <8>; -+ reg = <0x44df8c88 0x4>; -+}; -+ -+gpio4_dbclk: gpio4_dbclk@44df8c90 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <8>; -+ reg = <0x44df8c90 0x4>; -+}; -+ -+gpio5_dbclk: gpio5_dbclk@44df8c98 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkdiv32k_ick>; -+ bit-shift = <8>; -+ reg = <0x44df8c98 0x4>; -+}; -+ -+mmc_clk: mmc_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+gfx_fclk_clksel_ck: gfx_fclk_clksel_ck@44df423c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sysclk_div>, <&dpll_per_m2_ck>; -+ bit-shift = <1>; -+ reg = <0x44df423c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gfx_fck_div_ck: gfx_fck_div_ck@44df423c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&gfx_fclk_clksel_ck>; -+ reg = <0x44df423c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+disp_clk: disp_clk@44df4244 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_disp_m2_ck>, <&dpll_core_m5_ck>, <&dpll_per_m2_ck>; -+ reg = <0x44df4244 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+dpll_extdev_ck: dpll_extdev_ck@44df2e60 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44df2e60 0x4>, <0x44df2e64 0x4>, <0x44df2e6c 0x4>; -+ reg-names = "control", "idlest", "mult-div1"; -+}; -+ -+dpll_extdev_m2_ck: dpll_extdev_m2_ck@44df2e70 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_extdev_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2e70 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+mux_synctimer32k_ck: mux_synctimer32k_ck@44df4230 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_32768_ck>, <&clk_32k_tpm_ck>, <&clkdiv32k_ick>; -+ reg = <0x44df4230 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+synctimer_32kclk: synctimer_32kclk@44df2a30 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&mux_synctimer32k_ck>; -+ bit-shift = <8>; -+ reg = <0x44df2a30 0x4>; -+}; -+ -+timer8_fck: timer8_fck@44df421c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>; -+ reg = <0x44df421c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer9_fck: timer9_fck@44df4220 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>; -+ reg = <0x44df4220 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer10_fck: timer10_fck@44df4224 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>; -+ reg = <0x44df4224 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+timer11_fck: timer11_fck@44df4228 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clkdiv32k_ick>, <&clk_32k_tpm_ck>; -+ reg = <0x44df4228 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+cpsw_50m_clkdiv: cpsw_50m_clkdiv { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m5_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+cpsw_5m_clkdiv: cpsw_5m_clkdiv { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&cpsw_50m_clkdiv>; -+ clock-mult = <1>; -+ clock-div = <10>; -+}; -+ -+dpll_ddr_x2_ck: dpll_ddr_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_ddr_ck>; -+}; -+ -+dpll_ddr_m4_ck: dpll_ddr_m4_ck@44df2db8 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_ddr_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x44df2db8 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_clkdcoldo: dpll_per_clkdcoldo { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dll_aging_clk_div: dll_aging_clk_div@44df4250 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin_ck>; -+ reg = <0x44df4250 0x4>; -+ table = < 8 0 >, < 16 1 >, < 32 2 >; -+ bit-mask = <0x3>; -+}; -+ -+div_core_25m_ck: div_core_25m_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sysclk_div>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+func_12m_clk: func_12m_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+vtp_clk_div: vtp_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+usbphy_32khz_clkmux: usbphy_32khz_clkmux@44df4260 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clk_32768_ck>, <&clk_32k_tpm_ck>; -+ reg = <0x44df4260 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_otg_ss0_refclk960m: usb_otg_ss0_refclk960m@44df8a60 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_clkdcoldo>; -+ bit-shift = <8>; -+ reg = <0x44df8a60 0x4>; -+}; -+ -+usb_otg_ss1_refclk960m: usb_otg_ss1_refclk960m@44df8a68 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_clkdcoldo>; -+ bit-shift = <8>; -+ reg = <0x44df8a68 0x4>; -+}; -+ -+usb_phy1_always_on_clk32k: usb_phy1_always_on_clk32k { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clocks = <&clk_32768_ck>; -+}; -+ -+usb_phy2_always_on_clk32k: usb_phy2_always_on_clk32k { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clocks = <&clk_32768_ck>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/dra7.dtsi -@@ -0,0 +1,1278 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * Based on "omap4.dtsi" -+ */ -+ -+#include <dt-bindings/interrupt-controller/arm-gic.h> -+ -+#include "skeleton.dtsi" -+ -+/ { -+ compatible = "ti,dra7xx"; -+ interrupt-parent = <&gic>; -+ -+ aliases { -+ i2c0 = &i2c1; -+ i2c1 = &i2c2; -+ i2c2 = &i2c3; -+ i2c3 = &i2c4; -+ i2c4 = &i2c5; -+ serial0 = &uart1; -+ serial1 = &uart2; -+ serial2 = &uart3; -+ serial3 = &uart4; -+ serial4 = &uart5; -+ serial5 = &uart6; -+ ethernet0 = &cpsw_emac0; -+ ethernet1 = &cpsw_emac1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a15"; -+ reg = <0>; -+ -+ operating-points = < -+ /* kHz uV */ -+ 1000000 1090000 -+ 1176000 1210000 -+ >; -+ -+ clocks = <&dpll_mpu_ck>; -+ clock-names = "cpu"; -+ -+ clock-latency = <300000>; /* From omap-cpufreq driver */ -+ }; -+ cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a15"; -+ reg = <1>; -+ }; -+ }; -+ -+ timer { -+ compatible = "arm,armv7-timer"; -+ /* PPI secure/nonsecure IRQ */ -+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, -+ <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, -+ <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, -+ <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>; -+ clock-frequency = <6144000>; -+ }; -+ -+ gic: interrupt-controller@48211000 { -+ compatible = "arm,cortex-a15-gic"; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ reg = <0x48211000 0x1000>, -+ <0x48212000 0x1000>, -+ <0x48214000 0x2000>, -+ <0x48216000 0x2000>; -+ }; -+ -+ /* -+ * The soc node represents the soc top level view. It is uses for IPs -+ * that are not memory mapped in the MPU view or for the MPU itself. -+ */ -+ soc { -+ compatible = "ti,omap-infra"; -+ mpu { -+ compatible = "ti,omap5-mpu"; -+ ti,hwmods = "mpu"; -+ }; -+ }; -+ -+ /* -+ * XXX: Use a flat representation of the SOC interconnect. -+ * The real OMAP interconnect network is quite complex. -+ * Since that will not bring real advantage to represent that in DT for -+ * the moment, just use a fake OCP bus entry to represent the whole bus -+ * hierarchy. -+ */ -+ ocp { -+ compatible = "ti,omap4-l3-noc", "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "l3_main_1", "l3_main_2"; -+ -+ crossbar_mpu: mpuirq@4a002a48 { -+ compatible = "crossbar"; -+ crossbar-name = "mpu-irq"; -+ reg = <0x4a002a48 0x0130>; -+ reg-width = <16>; -+ crossbar-lines = "mpu-irq", "rtc-ss-alarm", <0x9f 0xd9 0x12e>, -+ "mpu-irq", "mcasp3-arevt", <0x9e 0x96 0x12c>, -+ "mpu-irq", "mcasp3-axevt", <0x9d 0x97 0x12a>, -+ "mpu-irq", "mailbox5", <0x88 0xfb 0x100>, -+ "mpu-irq", "mailbox6", <0x8d 0xff 0x10a>, -+ "mpu-irq", "qspi", <0x7c 0x157 0x0ec>, -+ "mpu-irq", "vpe", <0x9c 0x162 0x128>, -+ "mpu-irq", "cpsw-rx-thresh", <0x32 0x14e 0x58>, -+ "mpu-irq", "cpsw-rx", <0x33 0x14f 0x5a>, -+ "mpu-irq", "cpsw-tx", <0x34 0x150 0x5c>, -+ "mpu-irq", "cpsw-misc", <0x35 0x151 0x5e>; -+ }; -+ -+ crossbar_dma: dmareq@4a002b78 { -+ compatible = "crossbar"; -+ crossbar-name = "dma-req"; -+ reg = <0x4a002b78 0x0100>; -+ reg-width = <16>; -+ crossbar-lines = "dma-req", "mcasp3-rx", <0x7e 0x84 0xfc>, -+ "dma-req", "mcasp3-tx", <0x7d 0x85 0xfa>; -+ }; -+ -+ prcm: prcm@4ae06000 { -+ compatible = "ti,dra7-prcm"; -+ reg = <0x4ae06000 0x1f00>; -+ #reset-cells = <1>; -+ }; -+ -+ counter32k: counter@4ae04000 { -+ compatible = "ti,omap-counter32k"; -+ reg = <0x4ae04000 0x40>; -+ ti,hwmods = "counter_32k"; -+ clocks = <&wkupaon_iclk_mux>; -+ clock-names = "fck"; -+ }; -+ -+ avs_mpu: regulator-avs@0x4A003B18 { -+ compatible = "ti,avsclass0"; -+ reg = <0x4A003B18 20>; -+ efuse-settings = <1090000 8 -+ 1210000 12 -+ 1280000 16>; -+ }; -+ -+ avs_core: regulator-avs@0x4A0025EC { -+ compatible = "ti,avsclass0"; -+ reg = <0x4A0025EC 20>; -+ efuse-settings = <1030000 8>; -+ }; -+ -+ avs_gpu: regulator-avs@0x4A003B00 { -+ compatible = "ti,avsclass0"; -+ reg = <0x4A003B00 20>; -+ efuse-settings = <1090000 8 -+ 1210000 12 -+ 1280000 16>; -+ }; -+ -+ avs_dspeve: regulator-avs@0x4A0025D8 { -+ compatible = "ti,avsclass0"; -+ reg = <0x4A0025D8 20>; -+ efuse-settings = <1055000 8 -+ 1150000 12 -+ 1250000 16>; -+ }; -+ -+ avs_iva: regulator-avs@0x4A0025C4 { -+ compatible = "ti,avsclass0"; -+ reg = <0x4A0025C4 20>; -+ efuse-settings = <1055000 8 -+ 1150000 12 -+ 1250000 16>; -+ }; -+ -+ dra7_pmx_core: pinmux@4a003400 { -+ compatible = "pinctrl-single"; -+ reg = <0x4a003400 0x0464>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-single,register-width = <32>; -+ pinctrl-single,function-mask = <0x3fffffff>; -+ }; -+ -+ sdma: dma-controller@4a056000 { -+ compatible = "ti,omap4430-sdma"; -+ reg = <0x4a056000 0x1000>; -+ interrupts = <0 12 0x4>, -+ <0 13 0x4>, -+ <0 14 0x4>, -+ <0 15 0x4>; -+ #dma-cells = <1>; -+ #dma-channels = <32>; -+ #dma-requests = <127>; -+ clocks = <&l3_iclk_div>; -+ clock-names = "fck"; -+ }; -+ -+ gpio1: gpio@4ae10000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x4ae10000 0x200>; -+ interrupts = <0 29 0x4>; -+ ti,hwmods = "gpio1"; -+ clocks = <&wkupaon_iclk_mux>, <&gpio1_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio2: gpio@48055000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x48055000 0x200>; -+ interrupts = <0 30 0x4>; -+ ti,hwmods = "gpio2"; -+ clocks = <&l3_iclk_div>, <&gpio2_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio3: gpio@48057000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x48057000 0x200>; -+ interrupts = <0 31 0x4>; -+ ti,hwmods = "gpio3"; -+ clocks = <&l3_iclk_div>, <&gpio3_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio4: gpio@48059000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x48059000 0x200>; -+ interrupts = <0 32 0x4>; -+ ti,hwmods = "gpio4"; -+ clocks = <&l3_iclk_div>, <&gpio4_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio5: gpio@4805b000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x4805b000 0x200>; -+ interrupts = <0 33 0x4>; -+ ti,hwmods = "gpio5"; -+ clocks = <&l3_iclk_div>, <&gpio5_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio6: gpio@4805d000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x4805d000 0x200>; -+ interrupts = <0 34 0x4>; -+ ti,hwmods = "gpio6"; -+ clocks = <&l3_iclk_div>, <&gpio6_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio7: gpio@48051000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x48051000 0x200>; -+ interrupts = <0 35 0x4>; -+ ti,hwmods = "gpio7"; -+ clocks = <&l3_iclk_div>, <&gpio7_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ gpio8: gpio@48053000 { -+ compatible = "ti,omap4-gpio"; -+ reg = <0x48053000 0x200>; -+ interrupts = <0 121 0x4>; -+ ti,hwmods = "gpio8"; -+ clocks = <&l3_iclk_div>, <&gpio8_dbclk>; -+ clock-names = "fck", "dbclk"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ }; -+ -+ uart1: serial@4806a000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x4806a000 0x100>; -+ interrupts = <0 72 0x4>; -+ ti,hwmods = "uart1"; -+ clocks = <&uart1_gfclk_mux>; -+ clock-names = "fck"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart2: serial@4806c000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x4806c000 0x100>; -+ interrupts = <0 73 0x4>; -+ ti,hwmods = "uart2"; -+ clocks = <&uart2_gfclk_mux>; -+ clock-names = "fck"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart3: serial@48020000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x48020000 0x100>; -+ interrupts = <0 74 0x4>; -+ ti,hwmods = "uart3"; -+ clocks = <&uart3_gfclk_mux>; -+ clock-names = "fck"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart4: serial@4806e000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x4806e000 0x100>; -+ interrupts = <0 70 0x4>; -+ ti,hwmods = "uart4"; -+ clocks = <&uart4_gfclk_mux>; -+ clock-names = "fck"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart5: serial@48066000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x48066000 0x100>; -+ interrupts = <0 105 0x4>; -+ ti,hwmods = "uart5"; -+ clocks = <&uart5_gfclk_mux>; -+ clock-names = "fck"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart6: serial@48068000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x48068000 0x100>; -+ interrupts = <0 106 0x4>; -+ ti,hwmods = "uart6"; -+ clocks = <&uart6_gfclk_mux>; -+ clock-names = "fck"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart7: serial@48420000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x48420000 0x100>; -+ ti,hwmods = "uart7"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart8: serial@48422000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x48422000 0x100>; -+ ti,hwmods = "uart8"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart9: serial@48424000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x48424000 0x100>; -+ ti,hwmods = "uart9"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ uart10: serial@4ae2b000 { -+ compatible = "ti,omap4-uart"; -+ reg = <0x4ae2b000 0x100>; -+ ti,hwmods = "uart10"; -+ clock-frequency = <48000000>; -+ status = "disabled"; -+ }; -+ -+ mailbox1: mailbox@4a0f4000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4a0f4000 0x200>; -+ interrupts = <0 26 0x4>; -+ ti,hwmods = "mailbox1"; -+ ti,mbox-num-users = <3>; -+ ti,mbox-num-fifos = <8>; -+ #ti,mbox-data-cells = <4>; -+ ti,mbox-names = "mbox1-1", "mbox1-2"; -+ ti,mbox-data = <0 1 0 0>, <3 2 0 0>; -+ }; -+ -+ mailbox2: mailbox@4883a000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4883a000 0x200>; -+ ti,hwmods = "mailbox2"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox3: mailbox@4883c000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4883c000 0x200>; -+ ti,hwmods = "mailbox3"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox4: mailbox@4883e000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4883e000 0x200>; -+ ti,hwmods = "mailbox4"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox5: mailbox@48840000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48840000 0x200>; -+ interrupts = <0 136 0x4>; -+ ti,hwmods = "mailbox5"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ ti,mbox-names = "mbox-ipu1", "mbox-dsp1"; -+ ti,mbox-data = <6 4 0 2>, <5 1 0 2>; -+ }; -+ -+ mailbox6: mailbox@48842000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48842000 0x200>; -+ interrupts = <0 141 0x4>; -+ ti,hwmods = "mailbox6"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ ti,mbox-names = "mbox-ipu2", "mbox-dsp2"; -+ ti,mbox-data = <6 4 0 2>, <5 1 0 2>; -+ }; -+ -+ mailbox7: mailbox@48844000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48844000 0x200>; -+ ti,hwmods = "mailbox7"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox8: mailbox@48846000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48846000 0x200>; -+ ti,hwmods = "mailbox8"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox9: mailbox@4885e000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4885e000 0x200>; -+ ti,hwmods = "mailbox9"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox10: mailbox@48860000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48860000 0x200>; -+ ti,hwmods = "mailbox10"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox11: mailbox@48862000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48862000 0x200>; -+ ti,hwmods = "mailbox11"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox12: mailbox@48864000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48864000 0x200>; -+ ti,hwmods = "mailbox12"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ mailbox13: mailbox@48802000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x48802000 0x200>; -+ ti,hwmods = "mailbox13"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <12>; -+ #ti,mbox-data-cells = <4>; -+ status = "disabled"; -+ }; -+ -+ timer1: timer@4ae18000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x4ae18000 0x80>; -+ interrupts = <0 37 0x4>; -+ ti,hwmods = "timer1"; -+ clocks = <&timer1_gfclk_mux>; -+ clock-names = "fck"; -+ ti,timer-alwon; -+ }; -+ -+ timer2: timer@48032000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48032000 0x80>; -+ interrupts = <0 38 0x4>; -+ ti,hwmods = "timer2"; -+ clocks = <&timer2_gfclk_mux>; -+ clock-names = "fck"; -+ }; -+ -+ timer3: timer@48034000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48034000 0x80>; -+ interrupts = <0 39 0x4>; -+ ti,hwmods = "timer3"; -+ clocks = <&timer3_gfclk_mux>; -+ clock-names = "fck"; -+ }; -+ -+ timer4: timer@48036000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48036000 0x80>; -+ interrupts = <0 40 0x4>; -+ ti,hwmods = "timer4"; -+ clocks = <&timer4_gfclk_mux>; -+ clock-names = "fck"; -+ }; -+ -+ timer5: timer@48820000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48820000 0x80>; -+ interrupts = <0 41 0x4>; -+ ti,hwmods = "timer5"; -+ clocks = <&timer5_gfclk_mux>; -+ clock-names = "fck"; -+ ti,timer-dsp; -+ }; -+ -+ timer6: timer@48822000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48822000 0x80>; -+ interrupts = <0 42 0x4>; -+ ti,hwmods = "timer6"; -+ clocks = <&timer6_gfclk_mux>; -+ clock-names = "fck"; -+ ti,timer-dsp; -+ ti,timer-pwm; -+ }; -+ -+ timer7: timer@48824000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48824000 0x80>; -+ interrupts = <0 43 0x4>; -+ ti,hwmods = "timer7"; -+ clocks = <&timer7_gfclk_mux>; -+ clock-names = "fck"; -+ ti,timer-dsp; -+ }; -+ -+ timer8: timer@48826000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48826000 0x80>; -+ interrupts = <0 44 0x4>; -+ ti,hwmods = "timer8"; -+ clocks = <&timer8_gfclk_mux>; -+ clock-names = "fck"; -+ ti,timer-dsp; -+ ti,timer-pwm; -+ }; -+ -+ timer9: timer@4803e000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x4803e000 0x80>; -+ interrupts = <0 45 0x4>; -+ ti,hwmods = "timer9"; -+ clocks = <&timer9_gfclk_mux>; -+ clock-names = "fck"; -+ }; -+ -+ timer10: timer@48086000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48086000 0x80>; -+ interrupts = <0 46 0x4>; -+ ti,hwmods = "timer10"; -+ clocks = <&timer10_gfclk_mux>; -+ clock-names = "fck"; -+ }; -+ -+ timer11: timer@48088000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48088000 0x80>; -+ interrupts = <0 47 0x4>; -+ ti,hwmods = "timer11"; -+ clocks = <&timer11_gfclk_mux>; -+ clock-names = "fck"; -+ ti,timer-pwm; -+ }; -+ -+ timer13: timer@48828000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x48828000 0x80>; -+ ti,hwmods = "timer13"; -+ status = "disabled"; -+ }; -+ -+ timer14: timer@4882a000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x4882a000 0x80>; -+ ti,hwmods = "timer14"; -+ status = "disabled"; -+ }; -+ -+ timer15: timer@4882c000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x4882c000 0x80>; -+ ti,hwmods = "timer15"; -+ status = "disabled"; -+ }; -+ -+ timer16: timer@4882e000 { -+ compatible = "ti,omap5430-timer"; -+ reg = <0x4882e000 0x80>; -+ ti,hwmods = "timer16"; -+ status = "disabled"; -+ }; -+ -+ wdt2: wdt@4ae14000 { -+ compatible = "ti,omap4-wdt"; -+ reg = <0x4ae14000 0x80>; -+ interrupts = <0 80 0x4>; -+ ti,hwmods = "wd_timer2"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; -+ }; -+ -+ i2c1: i2c@48070000 { -+ compatible = "ti,omap4-i2c"; -+ reg = <0x48070000 0x100>; -+ interrupts = <0 56 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "i2c1"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ i2c2: i2c@48072000 { -+ compatible = "ti,omap4-i2c"; -+ reg = <0x48072000 0x100>; -+ interrupts = <0 57 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "i2c2"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ i2c3: i2c@48060000 { -+ compatible = "ti,omap4-i2c"; -+ reg = <0x48060000 0x100>; -+ interrupts = <0 61 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "i2c3"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ i2c4: i2c@4807a000 { -+ compatible = "ti,omap4-i2c"; -+ reg = <0x4807a000 0x100>; -+ interrupts = <0 62 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "i2c4"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ i2c5: i2c@4807c000 { -+ compatible = "ti,omap4-i2c"; -+ reg = <0x4807c000 0x100>; -+ interrupts = <0 60 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "i2c5"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@4809c000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x4809c000 0x400>; -+ interrupts = <0 83 0x4>; -+ ti,hwmods = "mmc1"; -+ clocks = <&mmc1_fclk_div>, <&mmc1_clk32k>; -+ clock-names = "fck", "clk32k"; -+ ti,dual-volt; -+ ti,needs-special-reset; -+ dmas = <&sdma 61>, <&sdma 62>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@480b4000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x480b4000 0x400>; -+ interrupts = <0 86 0x4>; -+ ti,hwmods = "mmc2"; -+ clocks = <&mmc2_fclk_div>, <&mmc2_clk32k>; -+ clock-names = "fck", "clk32k"; -+ ti,needs-special-reset; -+ dmas = <&sdma 47>, <&sdma 48>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@480ad000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x480ad000 0x400>; -+ interrupts = <0 94 0x4>; -+ ti,hwmods = "mmc3"; -+ clocks = <&mmc3_gfclk_div>, <&mmc3_clk32k>; -+ clock-names = "fck", "clk32k"; -+ ti,needs-special-reset; -+ dmas = <&sdma 77>, <&sdma 78>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ mmc4: mmc@480d1000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x480d1000 0x400>; -+ interrupts = <0 96 0x4>; -+ ti,hwmods = "mmc4"; -+ clocks = <&mmc4_gfclk_div>, <&mmc4_clk32k>; -+ clock-names = "fck", "clk32k"; -+ ti,needs-special-reset; -+ dmas = <&sdma 57>, <&sdma 58>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ qspi: qspi@4b300000 { -+ compatible = "ti,dra7xxx-qspi"; -+ reg = <0x4b300000 0x100>, <0x4a002558 0x4>, -+ <0x5c000000 0x3ffffff>; -+ reg-names = "qspi_base", -+ "qspi_ctrlmod", -+ "qspi_mmap"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "qspi"; -+ ti,spi-num-cs = <4>; -+ interrupts = <0 124 0x4>; -+ mmap_read; -+ }; -+ -+ omap_control_sata: control-phy@4a002374 { -+ compatible = "ti,control-phy-pipe3"; -+ reg = <0x4a002374 0x4>; -+ reg-names = "power"; -+ clocks = <&sys_clkin1>; -+ clock-names = "sysclk"; -+ }; -+ -+ ocp2scp@4a090000 { -+ compatible = "ti,omap-ocp2scp"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "ocp2scp3"; -+ reg = <0x4a090000 0x400>; /* ocp2scp3 */ -+ sata_phy: sata-phy@4A096000 { -+ compatible = "ti,phy-pipe3-sata"; -+ reg = <0x4A096000 0x80>, /* phy_rx */ -+ <0x4A096400 0x64>, /* phy_tx */ -+ <0x4A096800 0x40>; /* pll_ctrl */ -+ reg-names = "phy_rx", "phy_tx", "pll_ctrl"; -+ ctrl-module = <&omap_control_sata>; -+ clocks = <&sata_ref_clk>; -+ clock-names = "refclk"; -+ #phy-cells = <0>; -+ }; -+ }; -+ -+ sata@4a141100 { -+ compatible = "ti,sata"; -+ ti,hwmods = "sata"; -+ reg = <0x4a141100 0x100>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ sata@4a140000 { -+ compatible = "snps,dwc-ahci"; -+ reg = <0x4a140000 0x1100>; -+ interrupts = <0 54 0x4>; -+ phys = <&sata_phy>; -+ phy-names = "sata-phy"; -+ }; -+ }; -+ -+ -+ mcspi1: spi@48098000 { -+ compatible = "ti,omap4-mcspi"; -+ reg = <0x48098000 0x200>; -+ interrupts = <0 65 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "mcspi1"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; -+ ti,spi-num-cs = <4>; -+ dmas = <&sdma 35>, -+ <&sdma 36>, -+ <&sdma 37>, -+ <&sdma 38>, -+ <&sdma 39>, -+ <&sdma 40>, -+ <&sdma 41>, -+ <&sdma 42>; -+ dma-names = "tx0", "rx0", "tx1", "rx1", -+ "tx2", "rx2", "tx3", "rx3"; -+ status = "disabled"; -+ }; -+ -+ mcspi2: spi@4809a000 { -+ compatible = "ti,omap4-mcspi"; -+ reg = <0x4809a000 0x200>; -+ interrupts = <0 66 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "mcspi2"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; -+ ti,spi-num-cs = <2>; -+ dmas = <&sdma 43>, -+ <&sdma 44>, -+ <&sdma 45>, -+ <&sdma 46>; -+ dma-names = "tx0", "rx0", "tx1", "rx1"; -+ status = "disabled"; -+ }; -+ -+ mcspi3: spi@480b8000 { -+ compatible = "ti,omap4-mcspi"; -+ reg = <0x480b8000 0x200>; -+ interrupts = <0 91 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "mcspi3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; -+ ti,spi-num-cs = <2>; -+ dmas = <&sdma 15>, <&sdma 16>; -+ dma-names = "tx0", "rx0"; -+ status = "disabled"; -+ }; -+ -+ mcspi4: spi@480ba000 { -+ compatible = "ti,omap4-mcspi"; -+ reg = <0x480ba000 0x200>; -+ interrupts = <0 48 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "mcspi4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; -+ ti,spi-num-cs = <1>; -+ dmas = <&sdma 70>, <&sdma 71>; -+ dma-names = "tx0", "rx0"; -+ status = "disabled"; -+ }; -+ -+ rtcss@48838000 { -+ compatible = "ti,da830-rtc"; -+ reg = <0x48838000 0x100>; -+ interrupts = <0 159 0x4>, -+ <0 159 0x4>; -+ ti,hwmods = "rtcss"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; -+ }; -+ -+ omap_control_usb2phy1: control-phy@4a002300 { -+ compatible = "ti,control-phy-usb2"; -+ reg = <0x4a002300 0x4>; -+ reg-names = "power"; -+ }; -+ -+ omap_control_usb3phy1: control-phy@4a002370 { -+ compatible = "ti,control-phy-pipe3"; -+ reg = <0x4a002370 0x4>; -+ reg-names = "power"; -+ }; -+ -+ omap_control_usb2phy2: control-phy@0x4a002e74 { -+ compatible = "ti,control-phy-dra7usb2"; -+ reg = <0x4a002e74 0x4>; -+ reg-names = "power"; -+ }; -+ -+ ocp2scp@4a080000 { -+ compatible = "ti,omap-ocp2scp"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "ocp2scp1"; -+ reg = <0x4a080000 0x400>; /* ocp2scp1 */ -+ -+ usb2_phy1: usb2phy1@4a084000 { -+ compatible = "ti,omap-usb2"; -+ reg = <0x4a084000 0x400>; -+ ctrl-module = <&omap_control_usb2phy1>; -+ clocks = <&usb_phy1_always_on_clk32k>, -+ <&usb_otg_ss1_refclk960m>; -+ clock-names = "wkupclk", -+ "refclk"; -+ #phy-cells = <0>; -+ }; -+ -+ usb2_phy2: usb2phy2@4a085000 { -+ compatible = "ti,omap-usb2"; -+ reg = <0x4a085000 0x400>; -+ ctrl-module = <&omap_control_usb2phy2>; -+ clocks = <&usb_phy2_always_on_clk32k>, -+ <&usb_otg_ss2_refclk960m>; -+ clock-names = "wkupclk", -+ "refclk"; -+ #phy-cells = <0>; -+ }; -+ -+ usb3_phy1: usb3phy@4a084400 { -+ compatible = "ti,phy-pipe3-usb3"; -+ reg = <0x4a084400 0x80>, -+ <0x4a084800 0x64>, -+ <0x4a084c00 0x40>; -+ reg-names = "phy_rx", "phy_tx", "pll_ctrl"; -+ ctrl-module = <&omap_control_usb3phy1>; -+ clocks = <&usb_phy1_always_on_clk32k>, -+ <&usb_otg_ss1_refclk960m>, -+ <&dpll_core_h13x2_ck>; -+ clock-names = "wkupclk", -+ "refclk", -+ "refclk2"; -+ #phy-cells = <0>; -+ }; -+ }; -+ -+ dwc3_1: omap_dwc3_1@48880000 { -+ compatible = "ti,dwc3"; -+ ti,hwmods = "usb_otg_ss1"; -+ reg = <0x48880000 0x10000>; -+ interrupts = <0 77 4>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ utmi-mode = <2>; -+ ranges; -+ usb1: usb@48890000 { -+ compatible = "synopsys,dwc3"; -+ reg = <0x48890000 0x17000>; -+ interrupts = <0 76 4>; -+ phys = <&usb2_phy1>, <&usb3_phy1>; -+ phy-names = "usb2-phy", "usb3-phy"; -+ tx-fifo-resize; -+ maximum-speed = "super-speed"; -+ dr_mode = "otg"; -+ }; -+ }; -+ -+ dwc3_2: omap_dwc3_2@488c0000 { -+ compatible = "ti,dwc3"; -+ ti,hwmods = "usb_otg_ss2"; -+ reg = <0x488c0000 0x10000>; -+ interrupts = <0 92 4>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ utmi-mode = <2>; -+ ranges; -+ usb2: usb@488d0000 { -+ compatible = "synopsys,dwc3"; -+ reg = <0x488d0000 0x17000>; -+ interrupts = <0 78 4>; -+ phys = <&usb2_phy2>; -+ phy-names = "usb2-phy"; -+ tx-fifo-resize; -+ maximum-speed = "high-speed"; -+ dr_mode = "otg"; -+ }; -+ }; -+ -+ /* IRQ for DWC3_3 and DWC3_4 need IRQ crossbar */ -+ dwc3_3: omap_dwc3_3@48900000 { -+ compatible = "ti,dwc3"; -+ ti,hwmods = "usb_otg_ss3"; -+ reg = <0x48900000 0x10000>; -+ /* interrupts = <0 TBD 4>; */ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ utmi-mode = <2>; -+ ranges; -+ status = "disabled"; -+ usb3: usb@48910000 { -+ compatible = "synopsys,dwc3"; -+ reg = <0x48910000 0x17000>; -+ /* interrupts = <0 93 4>; */ -+ tx-fifo-resize; -+ maximum-speed = "high-speed"; -+ dr_mode = "otg"; -+ }; -+ }; -+ -+ dwc3_4: omap_dwc3_4@48940000 { -+ compatible = "ti,dwc3"; -+ ti,hwmods = "usb_otg_ss4"; -+ reg = <0x48940000 0x10000>; -+ /* interrupts = <0 TBD 4>; */ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ utmi-mode = <2>; -+ ranges; -+ status = "disabled"; -+ usb4: usb@48950000 { -+ compatible = "synopsys,dwc3"; -+ reg = <0x48950000 0x17000>; -+ /* interrupts = <0 TBD 4>; */ -+ tx-fifo-resize; -+ maximum-speed = "high-speed"; -+ dr_mode = "otg"; -+ }; -+ }; -+ -+ dmm: dmm@4e000000 { -+ compatible = "ti,omap5-dmm"; -+ reg = <0x4e000000 0x800>; -+ interrupts = <0 113 0x4>; -+ ti,hwmods = "dmm"; -+ }; -+ -+ dss: dss@58000000 { -+ compatible = "ti,omap4-dss", "simple-bus"; -+ reg = <0x58000000 0x80>, -+ <0x58004000 0x340>, -+ <0x58009000 0x340>; -+ ti,hwmods = "dss_core"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ dispc@58001000 { -+ compatible = "ti,omap4-dispc"; -+ reg = <0x58001000 0x1000>; -+ interrupts = <0 25 0x4>; -+ ti,hwmods = "dss_dispc"; -+ }; -+ -+ dpi1: encoder@0 { -+ compatible = "ti,dra7xx-dpi"; -+ id = <0>; -+ channel = <0>; -+ }; -+ -+ dpi2: encoder@1 { -+ compatible = "ti,dra7xx-dpi"; -+ id = <1>; -+ }; -+ -+ dpi3: encoder@2 { -+ compatible = "ti,dra7xx-dpi"; -+ id = <2>; -+ }; -+ -+ hdmi: encoder@58040000 { -+ compatible = "ti,omap5-hdmi"; -+ reg = <0x58040000 0x100>, -+ <0x58040200 0x40>, -+ <0x58040300 0x40>, -+ <0x58060000 0x19000>; -+ reg-names = "hdmi_wp", "hdmi_pllctrl", -+ "hdmi_txphy", "hdmi_core"; -+ interrupts = <0 101 0x4>; -+ ti,hwmods = "dss_hdmi"; -+ }; -+ }; -+ -+ vpe { -+ compatible = "ti,vpe"; -+ ti,hwmods = "vpe"; -+ reg = <0x489d0000 0x120>, -+ <0x489d0300 0x20>, -+ <0x489d0400 0x20>, -+ <0x489d0500 0x20>, -+ <0x489d0600 0x3c>, -+ <0x489d0700 0x80>, -+ <0x489d5700 0x18>, -+ <0x489dd000 0x400>; -+ reg-names = "vpe_top", -+ "vpe_chr_us0", -+ "vpe_chr_us1", -+ "vpe_chr_us2", -+ "vpe_dei", -+ "vpe_sc", -+ "vpe_csc", -+ "vpdma"; -+ interrupts = <0 0x9c 0x4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mac: ethernet@4a100000 { -+ compatible = "ti,cpsw"; -+ ti,hwmods = "gmac"; -+ cpdma_channels = <8>; -+ ale_entries = <1024>; -+ bd_ram_size = <0x2000>; -+ no_bd_ram = <0>; -+ rx_descs = <64>; -+ mac_control = <0x20>; -+ slaves = <2>; -+ active_slave = <0>; -+ cpts_clock_mult = <0x80000000>; -+ cpts_clock_shift = <29>; -+ reg = <0x48484000 0x800 -+ 0x48485200 0x100>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ /* -+ * rx_thresh_pend -+ * rx_pend -+ * tx_pend -+ * misc_pend -+ */ -+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>, -+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; -+ status = "disabled"; -+ -+ davinci_mdio: mdio@4a101000 { -+ compatible = "ti,davinci_mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ti,hwmods = "davinci_mdio"; -+ bus_freq = <1000000>; -+ reg = <0x48485000 0x100>; -+ }; -+ -+ cpsw_emac0: slave@4a100200 { -+ /* Filled in by U-Boot */ -+ mac-address = [ 00 00 00 00 00 00 ]; -+ }; -+ -+ cpsw_emac1: slave@4a100300 { -+ /* Filled in by U-Boot */ -+ mac-address = [ 00 00 00 00 00 00 ]; -+ }; -+ }; -+ -+ elm: elm@48078000 { -+ compatible = "ti,am3352-elm"; -+ /* compatible = "ti,elm"; */ -+ reg = <0x48078000 0x2000>; -+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "elm"; -+ status = "disabled"; -+ }; -+ -+ gpmc: gpmc@50000000 { -+ compatible = "ti,am3352-gpmc"; -+ /* compatible = "ti,gpmc"; */ -+ ti,hwmods = "gpmc"; -+ reg = <0x50000000 0x2000>; -+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; -+ gpmc,num-cs = <8>; -+ gpmc,num-waitpins = <2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ status = "disabled"; -+ }; -+ -+ aes: aes@4b500000 { -+ compatible = "ti,omap4-aes"; -+ ti,hwmods = "aes"; -+ reg = <0x4b500000 0xa0>; -+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; -+ dmas = <&sdma 111>, <&sdma 110>; -+ dma-names = "tx", "rx"; -+ clocks = <&l3_iclk_div>; -+ clock-names = "fck"; -+ }; -+ -+ des: des@480a5000 { -+ compatible = "ti,omap4-des"; -+ ti,hwmods = "des"; -+ reg = <0x480a5000 0xa0>; -+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; -+ dmas = <&sdma 117>, <&sdma 116>; -+ dma-names = "tx", "rx"; -+ clocks = <&l3_iclk_div>; -+ clock-names = "fck"; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "dra7xx-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ coreaon_clkdm: coreaon_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll_usb_ck>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/dra7-evm.dts -@@ -0,0 +1,761 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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 "dra7.dtsi" -+#include <dt-bindings/pinctrl/dra7xx.h> -+ -+/ { -+ model = "TI DRA7"; -+ compatible = "ti,dra7-evm", "ti,dra752", "ti,dra7"; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x80000000 0x60000000>; /* 1536 MB */ -+ }; -+ -+ extcon1: gpio_usbvid_extcon1 { -+ compatible = "ti,gpio-usb-id"; -+ gpios = <&gpio21 1 0>; -+ }; -+ -+ extcon2: gpio_usbvid_extcon2 { -+ compatible = "ti,gpio-usb-id"; -+ gpios = <&gpio21 2 0>; -+ }; -+ -+ mmc2_3v3: fixedregulator-mmc2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "mmc2_3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+}; -+ -+&dra7_pmx_core { -+ pinctrl-names = "default"; -+ pinctrl-0 = < -+ &vout1_pins -+ &irq_pins -+ >; -+ -+ i2c1_pins: pinmux_i2c1_pins { -+ pinctrl-single,pins = < -+ 0x400 0x60000 /* i2c1_sda */ -+ 0x404 0x60000 /* i2c1_scl */ -+ >; -+ }; -+ -+ i2c2_pins: pinmux_i2c2_pins { -+ pinctrl-single,pins = < -+ 0x408 0x60000 /* i2c2_sda */ -+ 0x40c 0x60000 /* i2c2_scl */ -+ >; -+ }; -+ -+ i2c3_pins: pinmux_i2c3_pins { -+ pinctrl-single,pins = < -+ 0x410 0x60000 /* i2c3_sda */ -+ 0x414 0x60000 /* i2c3_scl */ -+ >; -+ }; -+ -+ irq_pins: pinmux_irq_pins { -+ pinctrl-single,pins = < -+ 0x420 0x1 /* Wakeup2 INPUT | MODE1 */ -+ >; -+ }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x36c 0x4000e /* mmc1sdcd.gpio INPUT | MODE15 */ -+ >; -+ }; -+ -+ mcspi1_pins: pinmux_mcspi1_pins { -+ pinctrl-single,pins = < -+ 0x3a4 0x40000 /* spi2_clk */ -+ 0x3a8 0x40000 /* spi2_d1 */ -+ 0x3ac 0x40000 /* spi2_d0 */ -+ 0x3b0 0xc0000 /* spi2_cs0 */ -+ 0x3b4 0xc0000 /* spi2_cs1 */ -+ 0x3b8 0xe0006 /* spi2_cs2 */ -+ 0x3bc 0xe0006 /* spi2_cs3 */ -+ >; -+ }; -+ -+ mcspi2_pins: pinmux_mcspi2_pins { -+ pinctrl-single,pins = < -+ 0x3c0 0x40000 /* spi2_sclk */ -+ 0x3c4 0xc0000 /* spi2_d1 */ -+ 0x3c8 0xc0000 /* spi2_d1 */ -+ 0x3cc 0xe0000 /* spi2_cs0 */ -+ >; -+ }; -+ -+ uart1_pins: pinmux_uart1_pins { -+ pinctrl-single,pins = < -+ 0x3e0 0xe0000 /* uart1_rxd */ -+ 0x3e4 0xe0000 /* uart1_txd */ -+ 0x3e8 0x60003 /* uart1_ctsn */ -+ 0x3ec 0x60003 /* uart1_rtsn */ -+ >; -+ }; -+ -+ uart2_pins: pinmux_uart2_pins { -+ pinctrl-single,pins = < -+ 0x3f0 0x60000 /* uart2_rxd */ -+ 0x3f4 0x60000 /* uart2_txd */ -+ 0x3f8 0x60000 /* uart2_ctsn */ -+ 0x3fc 0x60000 /* uart2_rtsn */ -+ >; -+ }; -+ -+ uart3_pins: pinmux_uart3_pins { -+ pinctrl-single,pins = < -+ 0x248 0xc0000 /* uart3_rxd */ -+ 0x24c 0xc0000 /* uart3_txd */ -+ >; -+ }; -+ -+ qspi1_pins: pinmux_qspi1_pins { -+ pinctrl-single,pins = < -+ 0x4c 0x40001 /* gpmc_a3.qspi1_cs2 */ -+ 0x50 0x40001 /* gpmc_a4.qspi1_cs3 */ -+ 0x74 0x40001 /* gpmc_a13.qspi1_rtclk */ -+ 0x78 0x40001 /* gpmc_a14.qspi1_d3 */ -+ 0x7c 0x40001 /* gpmc_a15.qspi1_d2 */ -+ 0x80 0x40001 /* gpmc_a16.qspi1_d1 */ -+ 0x84 0x40001 /* gpmc_a17.qspi1_d0 */ -+ 0x88 0x40001 /* qpmc_a18.qspi1_sclk */ -+ 0xb8 0x60001 /* gpmc_cs2.qspi1_cs0 */ -+ 0xbc 0x60001 /* gpmc_cs3.qspi1_cs1 */ -+ >; -+ }; -+ -+ usb1_pins: pinmux_usb1_pins { -+ pinctrl-single,pins = < -+ 0x280 0xc0000 /* usb1_drvvbus, SLOW_SLEW | PULLUPEN | MODE0 */ -+ >; -+ }; -+ -+ usb2_pins: pinmux_usb2_pins { -+ pinctrl-single,pins = < -+ 0x284 0xc0000 /* usb2_drvvbus, SLOW_SLEW | PULLUPEN | MODE0 */ -+ >; -+ }; -+ -+ vout1_pins: pinmux_vout1_pins { -+ pinctrl-single,pins = < -+ 0x1C8 0x0 /* vout1_clk OUTPUT | MODE0 */ -+ 0x1CC 0x0 /* vout1_de OUTPUT | MODE0 */ -+ 0x1D0 0x0 /* vout1_fld OUTPUT | MODE0 */ -+ 0x1D4 0x0 /* vout1_hsync OUTPUT | MODE0 */ -+ 0x1D8 0x0 /* vout1_vsync OUTPUT | MODE0 */ -+ 0x1DC 0x0 /* vout1_d0 OUTPUT | MODE0 */ -+ 0x1E0 0x0 /* vout1_d1 OUTPUT | MODE0 */ -+ 0x1E4 0x0 /* vout1_d2 OUTPUT | MODE0 */ -+ 0x1E8 0x0 /* vout1_d3 OUTPUT | MODE0 */ -+ 0x1EC 0x0 /* vout1_d4 OUTPUT | MODE0 */ -+ 0x1F0 0x0 /* vout1_d5 OUTPUT | MODE0 */ -+ 0x1F4 0x0 /* vout1_d6 OUTPUT | MODE0 */ -+ 0x1F8 0x0 /* vout1_d7 OUTPUT | MODE0 */ -+ 0x1FC 0x0 /* vout1_d8 OUTPUT | MODE0 */ -+ 0x200 0x0 /* vout1_d9 OUTPUT | MODE0 */ -+ 0x204 0x0 /* vout1_d10 OUTPUT | MODE0 */ -+ 0x208 0x0 /* vout1_d11 OUTPUT | MODE0 */ -+ 0x20C 0x0 /* vout1_d12 OUTPUT | MODE0 */ -+ 0x210 0x0 /* vout1_d13 OUTPUT | MODE0 */ -+ 0x214 0x0 /* vout1_d14 OUTPUT | MODE0 */ -+ 0x218 0x0 /* vout1_d15 OUTPUT | MODE0 */ -+ 0x21C 0x0 /* vout1_d16 OUTPUT | MODE0 */ -+ 0x220 0x0 /* vout1_d17 OUTPUT | MODE0 */ -+ 0x224 0x0 /* vout1_d18 OUTPUT | MODE0 */ -+ 0x228 0x0 /* vout1_d19 OUTPUT | MODE0 */ -+ 0x22C 0x0 /* vout1_d20 OUTPUT | MODE0 */ -+ 0x230 0x0 /* vout1_d21 OUTPUT | MODE0 */ -+ 0x234 0x0 /* vout1_d22 OUTPUT | MODE0 */ -+ 0x238 0x0 /* vout1_d23 OUTPUT | MODE0 */ -+ >; -+ }; -+ -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x250 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_tclk */ -+ 0x254 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_tctl */ -+ 0x258 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td3 */ -+ 0x25c (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td2 */ -+ 0x260 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td1 */ -+ 0x264 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td0 */ -+ 0x268 (PIN_INPUT | MUX_MODE0) /* rgmii1_rclk */ -+ 0x26c (PIN_INPUT | MUX_MODE0) /* rgmii1_rctl */ -+ 0x270 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd3 */ -+ 0x274 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd2 */ -+ 0x278 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd1 */ -+ 0x27c (PIN_INPUT | MUX_MODE0) /* rgmii1_rd0 */ -+ -+ /* Slave 2 */ -+ 0x198 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_tclk */ -+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* rgmii2_tctl */ -+ 0x1a0 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td3 */ -+ 0x1a4 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td2 */ -+ 0x1a8 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td1 */ -+ 0x1ac (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td0 */ -+ 0x1b0 (PIN_INPUT | MUX_MODE3) /* rgmii2_rclk */ -+ 0x1b4 (PIN_INPUT | MUX_MODE3) /* rgmii2_rctl */ -+ 0x1b8 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd3 */ -+ 0x1bc (PIN_INPUT | MUX_MODE3) /* rgmii2_rd2 */ -+ 0x1c0 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd1 */ -+ 0x1c4 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd0 */ -+ >; -+ -+ }; -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x250 (PIN_OFF_NONE) -+ 0x254 (PIN_OFF_NONE) -+ 0x258 (PIN_OFF_NONE) -+ 0x25c (PIN_OFF_NONE) -+ 0x260 (PIN_OFF_NONE) -+ 0x264 (PIN_OFF_NONE) -+ 0x268 (PIN_OFF_NONE) -+ 0x26c (PIN_OFF_NONE) -+ 0x270 (PIN_OFF_NONE) -+ 0x274 (PIN_OFF_NONE) -+ 0x278 (PIN_OFF_NONE) -+ 0x27c (PIN_OFF_NONE) -+ -+ /* Slave 1 */ -+ 0x198 (PIN_OFF_NONE) -+ 0x19c (PIN_OFF_NONE) -+ 0x1a0 (PIN_OFF_NONE) -+ 0x1a4 (PIN_OFF_NONE) -+ 0x1a8 (PIN_OFF_NONE) -+ 0x1ac (PIN_OFF_NONE) -+ 0x1b0 (PIN_OFF_NONE) -+ 0x1b4 (PIN_OFF_NONE) -+ 0x1b8 (PIN_OFF_NONE) -+ 0x1bc (PIN_OFF_NONE) -+ 0x1c0 (PIN_OFF_NONE) -+ 0x1c4 (PIN_OFF_NONE) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ 0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_data */ -+ 0x240 (PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ 0x23c (PIN_OFF_NONE) -+ 0x240 (PIN_OFF_NONE) -+ >; -+ }; -+ -+ nand_flash_x16: nand_flash_x16 { -+ /* On DRA7 EVM, GPMC_WPN and NAND_BOOTn comes from DIP switch -+ * So NAND flash requires following switch settings: -+ * SW5.9 (GPMC_WPN) = LOW -+ * SW5.1 (NAND_BOOTn) = HIGH */ -+ pinctrl-single,pins = < -+ 0x0 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad0 */ -+ 0x4 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad1 */ -+ 0x8 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad2 */ -+ 0xc 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad3 */ -+ 0x10 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad4 */ -+ 0x14 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad5 */ -+ 0x18 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad6 */ -+ 0x1c 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad7 */ -+ 0x20 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad8 */ -+ 0x24 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad9 */ -+ 0x28 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad10 */ -+ 0x2c 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad11 */ -+ 0x30 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad12 */ -+ 0x34 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad13 */ -+ 0x38 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad14 */ -+ 0x3c 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_ad15 */ -+ 0xD8 0x70000 /* (PIN_INPUT | MUX_MODE0) gpmc_wait0 */ -+ 0xCC 0x0 /* (PIN_OUTPUT | MUX_MODE0) gpmc_wen */ -+ 0xB4 0x0 /* (PIN_OUTPUT | MUX_MODE0) gpmc_csn0 */ -+ 0xC4 0x0 /* (PIN_OUTPUT | MUX_MODE0) gpmc_advn_ale */ -+ 0xC8 0x0 /* (PIN_OUTPUT | MUX_MODE0) gpmc_oen_ren */ -+ 0xD0 0x0 /* (PIN_OUTPUT | MUX_MODE0) gpmc_be0n_cle */ -+ >; -+ }; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <400000>; -+ -+ tps659038: tps659038@58 { -+ compatible = "ti,tps659038"; -+ reg = <0x58>; -+ -+ tps659038_pmic { -+ compatible = "ti,tps659038-pmic"; -+ -+ regulators { -+ smps123_reg: smps123 { -+ /* VDD_MPU */ -+ regulator-name = "smps123"; -+ regulator-min-microvolt = < 850000>; -+ regulator-max-microvolt = <1250000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ smps45_reg: smps45 { -+ /* VDD_DSPEVE */ -+ regulator-name = "smps45"; -+ regulator-min-microvolt = < 850000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-boot-on; -+ }; -+ -+ smps6_reg: smps6 { -+ /* VDD_GPU - over VDD_SMPS6 */ -+ regulator-name = "smps6"; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <12500000>; -+ regulator-boot-on; -+ }; -+ -+ smps7_reg: smps7 { -+ /* CORE_VDD */ -+ regulator-name = "smps7"; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <1030000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ smps8_reg: smps8 { -+ /* VDD_IVAHD */ -+ regulator-name = "smps8"; -+ regulator-min-microvolt = < 850000>; -+ regulator-max-microvolt = <1250000>; -+ regulator-boot-on; -+ }; -+ -+ smps9_reg: smps9 { -+ /* VDDS1V8 */ -+ regulator-name = "smps9"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ ldo1_reg: ldo1 { -+ /* LDO1_OUT --> SDIO */ -+ regulator-name = "ldo1"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ }; -+ -+ ldo2_reg: ldo2 { -+ /* VDD_RTCIO */ -+ /* LDO2 -> VDDSHV5, LDO2 also goes to CAN_PHY_3V3 */ -+ regulator-name = "ldo2"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ }; -+ -+ ldo3_reg: ldo3 { -+ /* VDDA_1V8_PHY */ -+ regulator-name = "ldo3"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ }; -+ -+ ldo9_reg: ldo9 { -+ /* VDD_RTC */ -+ regulator-name = "ldo9"; -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-boot-on; -+ }; -+ -+ ldoln_reg: ldoln { -+ /* VDDA_1V8_PLL */ -+ regulator-name = "ldoln"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ ldousb_reg: ldousb { -+ /* VDDA_3V_USB: VDDA_USBHS33 */ -+ regulator-name = "ldousb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ }; -+ -+ }; -+ }; -+ }; -+ -+ pcf_gpio_20: gpio@20 { -+ compatible = "ti,pcf8575"; -+ reg = <0x20>; -+ lines-initial-states = <0x4000>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-parent = <&gpio6>; -+ interrupts = <11 2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio21: gpio@21 { -+ compatible = "ti,pcf8575"; -+ reg = <0x21>; -+ lines-initial-states = <0x1408>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-parent = <&pcf_gpio_20>; -+ interrupts = <14 2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ /* TLC chip for LCD panel power and backlight */ -+ tlc59108: tlc59108@40 { -+ compatible = "ti,tlc59108"; -+ reg = <0x40>; -+ gpios = <&pcf_gpio_20 13 0>; /* P15, CON_LCD_PWR_DN */ -+ video-source = <&dpi1>; -+ data-lines = <24>; -+ }; -+ -+ mxt244: touchscreen@4a { -+ compatible = "atmel,mXT244"; -+ status = "okay"; -+ reg = <0x4a>; -+ interrupts = <0 119 0x4>; -+ -+ atmel,config = < -+ /* MXT244_GEN_COMMAND(6) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_GEN_POWER(7) */ -+ 0x20 0xff 0x32 -+ /* MXT244_GEN_ACQUIRE(8) */ -+ 0x0a 0x00 0x05 0x00 0x00 0x00 0x09 0x23 -+ /* MXT244_TOUCH_MULTI(9) */ -+ 0x00 0x00 0x00 0x13 0x0b 0x00 0x00 0x00 0x02 0x00 -+ 0x00 0x01 0x01 0x0e 0x0a 0x0a 0x0a 0x0a 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 -+ /* MXT244_TOUCH_KEYARRAY(15) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 -+ /* MXT244_COMMSCONFIG_T18(2) */ -+ 0x00 0x00 -+ /* MXT244_SPT_GPIOPWM(19) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_PROCI_GRIPFACE(20) */ -+ 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x50 0x28 0x04 -+ 0x0f 0x0a -+ /* MXT244_PROCG_NOISE(22) */ -+ 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x03 0x23 0x00 -+ 0x00 0x05 0x0f 0x19 0x23 0x2d 0x03 -+ /* MXT244_TOUCH_PROXIMITY(23) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_PROCI_ONETOUCH(24) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_SPT_SELFTEST(25) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 -+ /* MXT244_PROCI_TWOTOUCH(27) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_SPT_CTECONFIG(28) */ -+ 0x00 0x00 0x02 0x08 0x10 0x00 -+ >; -+ -+ atmel,x_line = <18>; -+ atmel,y_line = <12>; -+ atmel,x_size = <800>; -+ atmel,y_size = <480>; -+ atmel,blen = <0x01>; -+ atmel,threshold = <30>; -+ atmel,voltage = <2800000>; -+ atmel,orient = <0x4>; -+ }; -+}; -+ -+&i2c2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ clock-frequency = <400000>; -+ -+ pcf_hdmi: gpio@26 { -+ compatible = "nxp,pcf8575"; -+ reg = <0x26>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ }; -+}; -+ -+&i2c3 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c3_pins>; -+ clock-frequency = <3400000>; -+}; -+ -+&mcspi1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcspi1_pins>; -+}; -+ -+&mcspi2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcspi2_pins>; -+}; -+ -+&uart1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+}; -+ -+&uart2 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; -+}; -+ -+&uart3 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>; -+}; -+ -+&qspi { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&qspi1_pins>; -+ -+ spi-max-frequency = <48000000>; -+ m25p80@0 { -+ compatible = "s25fl256s1"; -+ spi-max-frequency = <48000000>; -+ reg = <0>; -+ spi-tx-bus-width = <1>; -+ spi-rx-bus-width = <4>; -+ spi-cpol; -+ spi-cpha; -+ }; -+}; -+ -+&usb1 { -+ dr_mode = "peripheral"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb1_pins>; -+}; -+ -+&usb2 { -+ dr_mode = "host"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb2_pins>; -+}; -+ -+&dwc3_1 { -+ extcon = <&extcon1>; -+}; -+ -+&dwc3_2 { -+ extcon = <&extcon2>; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ vmmc-supply = <&ldo1_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio6 27 0>; /* gpio 187 */ -+}; -+ -+&mmc2 { -+ status = "okay"; -+ vmmc-supply = <&mmc2_3v3>; -+ bus-width = <8>; -+ ti,non-removable; -+}; -+ -+&dss { -+ vdda_video-supply = <&ldoln_reg>; -+}; -+ -+&hdmi { -+ vdda_hdmi_dac-supply = <&ldo3_reg>; -+}; -+ -+&avs_mpu { -+ avs-supply = <&smps123_reg>; -+}; -+ -+&avs_core { -+ avs-supply = <&smps7_reg>; -+}; -+ -+&avs_gpu { -+ avs-supply = <&smps6_reg>; -+}; -+ -+&avs_dspeve { -+ avs-supply = <&smps45_reg>; -+}; -+ -+&avs_iva { -+ avs-supply = <&smps8_reg>; -+}; -+ -+&cpu0 { -+ cpu0-supply = <&avs_mpu>; -+}; -+ -+/ { -+ aliases { -+ display0 = &tlc59108; -+ display1 = &hdmi0; -+ }; -+ -+ tpd12s015: encoder@0 { -+ compatible = "ti,draevm-tpd12s015"; -+ -+ video-source = <&hdmi>; -+ -+ gpios = <&pcf_hdmi 4 0>, /* P4, CT CP HPD */ -+ <&pcf_hdmi 5 0>, /* P5, LS OE */ -+ <&gpio7 12 0>; /* gpio7_12/sp1_cs2, HPD */ -+ }; -+ -+ hdmi0: connector@0 { -+ compatible = "ti,hdmi_connector"; -+ -+ video-source = <&tpd12s015>; -+ }; -+}; -+ -+&mac { -+ status = "okay"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <2>; -+}; -+ -+&cpsw_emac1 { -+ phy_id = <&davinci_mdio>, <3>; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+}; -+ -+&elm { -+ status = "okay"; -+}; -+ -+&gpmc { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&nand_flash_x16>; -+ ranges = <0 0 0x08000000 0x10000000>; -+ nand@0,0 { -+ reg = <0 0 0>; -+ nand-bus-width = <16>; -+ ti,nand-ecc-opt = "bch8"; -+ gpmc,device-width = <2>; -+ gpmc,sync-clk-ps = <0>; -+ gpmc,cs-on-ns = <0>; -+ gpmc,cs-rd-off-ns = <55>; -+ gpmc,cs-wr-off-ns = <55>; -+ gpmc,adv-on-ns = <0>; -+ gpmc,adv-rd-off-ns = <55>; -+ gpmc,adv-wr-off-ns = <55>; -+ gpmc,we-on-ns = <5>; -+ gpmc,we-off-ns = <40>; -+ gpmc,oe-on-ns = <2>; -+ gpmc,oe-off-ns = <45>; -+ gpmc,access-ns = <40>; -+ gpmc,wr-access-ns = <37>; -+ gpmc,rd-cycle-ns = <55>; -+ gpmc,wr-cycle-ns = <55>; -+ gpmc,wait-on-read = "true"; -+ gpmc,wait-on-write = "true"; -+ gpmc,bus-turnaround-ns = <0>; -+ gpmc,cycle2cycle-delay-ns = <0>; -+ gpmc,clk-activation-ns = <0>; -+ gpmc,wait-monitoring-ns = <0>; -+ gpmc,wr-data-mux-bus-ns = <0>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ti,elm-id = <&elm>; -+ /* MTD partition table */ -+ partition@0 { -+ label = "SPL1"; -+ reg = <0x00000000 0x000020000>; -+ }; -+ partition@1 { -+ label = "SPL2"; -+ reg = <0x00020000 0x00020000>; -+ }; -+ partition@2 { -+ label = "SPL3"; -+ reg = <0x00040000 0x00020000>; -+ }; -+ partition@3 { -+ label = "SPL4"; -+ reg = <0x00060000 0x00020000>; -+ }; -+ partition@4 { -+ label = "U-boot"; -+ reg = <0x00080000 0x001e0000>; -+ }; -+ partition@5 { -+ label = "environment"; -+ reg = <0x00260000 0x00020000>; -+ }; -+ partition@6 { -+ label = "Kernel"; -+ reg = <0x00280000 0x00500000>; -+ }; -+ partition@7 { -+ label = "File-System"; -+ reg = <0x00780000 0x0F880000>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi -@@ -0,0 +1,2103 @@ -+/* -+ * Device Tree Source for DRA7xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+atl_clkin0_ck: atl_clkin0_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+atl_clkin1_ck: atl_clkin1_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+atl_clkin2_ck: atl_clkin2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+atlclkin3_ck: atlclkin3_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+hdmi_clkin_ck: hdmi_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+mlb_clkin_ck: mlb_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+mlbp_clkin_ck: mlbp_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+pciesref_acs_clk_ck: pciesref_acs_clk_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <100000000>; -+}; -+ -+ref_clkin0_ck: ref_clkin0_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+ref_clkin1_ck: ref_clkin1_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+ref_clkin2_ck: ref_clkin2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+ref_clkin3_ck: ref_clkin3_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+rmii_clk_ck: rmii_clk_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+sdvenc_clkin_ck: sdvenc_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+secure_32k_clk_src_ck: secure_32k_clk_src_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+sys_32k_ck: sys_32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+virt_12000000_ck: virt_12000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+virt_13000000_ck: virt_13000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <13000000>; -+}; -+ -+virt_16800000_ck: virt_16800000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <16800000>; -+}; -+ -+virt_19200000_ck: virt_19200000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <19200000>; -+}; -+ -+virt_20000000_ck: virt_20000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <20000000>; -+}; -+ -+virt_26000000_ck: virt_26000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+virt_27000000_ck: virt_27000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <27000000>; -+}; -+ -+virt_38400000_ck: virt_38400000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <38400000>; -+}; -+ -+sys_clkin1: sys_clkin1@4ae06110 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_12000000_ck>, <&virt_20000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>; -+ reg = <0x4ae06110 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+sys_clkin2: sys_clkin2 { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <22579200>; -+}; -+ -+usb_otg_clkin_ck: usb_otg_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+video1_clkin_ck: video1_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+video1_m2_clkin_ck: video1_m2_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+video2_clkin_ck: video2_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+video2_m2_clkin_ck: video2_m2_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+abe_dpll_sys_clk_mux: abe_dpll_sys_clk_mux@4ae06118 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin2>; -+ reg = <0x4ae06118 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+abe_dpll_bypass_clk_mux: abe_dpll_bypass_clk_mux@4ae06114 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_dpll_sys_clk_mux>, <&sys_32k_ck>; -+ reg = <0x4ae06114 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+abe_dpll_clk_mux: abe_dpll_clk_mux@4ae0610c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_dpll_sys_clk_mux>, <&sys_32k_ck>; -+ reg = <0x4ae0610c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_abe_ck: dpll_abe_ck@4a0051e0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-m4xen-clock"; -+ clocks = <&abe_dpll_clk_mux>, <&abe_dpll_bypass_clk_mux>; -+ reg = <0x4a0051e0 0x4>, <0x4a0051e4 0x4>, <0x4a0051e8 0x4>, <0x4a0051ec 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_abe_x2_ck: dpll_abe_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_abe_ck>; -+}; -+ -+dpll_abe_m2x2_ck: dpll_abe_m2x2_ck@4a0051f0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0051f0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+abe_24m_fclk: abe_24m_fclk@4ae0611c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ reg = <0x4ae0611c 0x4>; -+ table = < 8 0 >, < 16 1 >; -+ bit-mask = <0x1>; -+}; -+ -+abe_clk: abe_clk@4a005108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ reg = <0x4a005108 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+aess_fclk: aess_fclk@4ae06178 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&abe_clk>; -+ reg = <0x4ae06178 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+abe_giclk_div: abe_giclk_div@4ae06174 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&aess_fclk>; -+ reg = <0x4ae06174 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+abe_lp_clk_div: abe_lp_clk_div@4ae061d8 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ reg = <0x4ae061d8 0x4>; -+ table = < 16 0 >, < 32 1 >; -+ bit-mask = <0x1>; -+}; -+ -+abe_sys_clk_div: abe_sys_clk_div@4ae06120 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin1>; -+ reg = <0x4ae06120 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+adc_gfclk_mux: adc_gfclk_mux@4ae061dc { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin2>, <&sys_32k_ck>; -+ reg = <0x4ae061dc 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+dpll_pcie_ref_ck: dpll_pcie_ref_ck@4a008200 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin1>; -+ reg = <0x4a008200 0x4>, <0x4a008204 0x4>, <0x4a008208 0x4>, <0x4a00820c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_pcie_ref_m2ldo_ck: dpll_pcie_ref_m2ldo_ck@4a008210 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_pcie_ref_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008210 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+apll_pcie_in_clk_mux: apll_pcie_in_clk_mux@4ae06118 { -+ compatible = "mux-clock"; -+ clocks = <&dpll_pcie_ref_ck>, <&pciesref_acs_clk_ck>; -+ #clock-cells = <0>; -+ reg = <0x4a00821c 0x4>; -+ bit-mask = <0x80>; -+}; -+ -+apll_pcie_ck: apll_pcie_ck@4a008200 { -+ #clock-cells = <0>; -+ compatible = "ti,dra7-apll-clock"; -+ clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; -+ reg = <0x4a00821c 0x4>, <0x4a008220 0x4>; -+ reg-names = "control", "idlest"; -+}; -+ -+apll_pcie_clkvcoldo: apll_pcie_clkvcoldo { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&apll_pcie_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+apll_pcie_clkvcoldo_div: apll_pcie_clkvcoldo_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&apll_pcie_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+apll_pcie_m2_ck: apll_pcie_m2_ck@4a008224 { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&apll_pcie_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sys_clk1_dclk_div: sys_clk1_dclk_div@4ae061c8 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin1>; -+ reg = <0x4ae061c8 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+sys_clk2_dclk_div: sys_clk2_dclk_div@4ae061cc { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin2>; -+ reg = <0x4ae061cc 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+dpll_abe_m2_ck: dpll_abe_m2_ck@4a0051f0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0051f0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+per_abe_x1_dclk_div: per_abe_x1_dclk_div@4ae061bc { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2_ck>; -+ reg = <0x4ae061bc 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+dpll_abe_m3x2_ck: dpll_abe_m3x2_ck@4a0051f4 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0051f4 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_ck: dpll_core_ck@4a005120 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-core-clock"; -+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; -+ reg = <0x4a005120 0x4>, <0x4a005124 0x4>, <0x4a005128 0x4>, <0x4a00512c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_core_x2_ck: dpll_core_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_core_ck>; -+}; -+ -+dpll_core_h12x2_ck: dpll_core_h12x2_ck@4a00513c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00513c 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+mpu_dpll_hs_clk_div: mpu_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_mpu_ck: dpll_mpu_ck@4a005160 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&mpu_dpll_hs_clk_div>; -+ reg = <0x4a005160 0x4>, <0x4a005164 0x4>, <0x4a005168 0x4>, <0x4a00516c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_mpu_m2_ck: dpll_mpu_m2_ck@4a005170 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_mpu_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005170 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+mpu_dclk_div: mpu_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_mpu_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dsp_dpll_hs_clk_div: dsp_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_dsp_ck: dpll_dsp_ck@4a005234 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; -+ reg = <0x4a005234 0x4>, <0x4a005238 0x4>, <0x4a00523c 0x4>, <0x4a005240 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_dsp_m2_ck: dpll_dsp_m2_ck@4a005244 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_dsp_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005244 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dsp_gclk_div: dsp_gclk_div@4ae0618c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_dsp_m2_ck>; -+ reg = <0x4ae0618c 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+iva_dpll_hs_clk_div: iva_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_iva_ck: dpll_iva_ck@4a0051a0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; -+ reg = <0x4a0051a0 0x4>, <0x4a0051a4 0x4>, <0x4a0051a8 0x4>, <0x4a0051ac 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_iva_m2_ck: dpll_iva_m2_ck@4a0051b0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_iva_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0051b0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+iva_dclk: iva_dclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_iva_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_gpu_ck: dpll_gpu_ck@4a0052d8 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; -+ reg = <0x4a0052d8 0x4>, <0x4a0052dc 0x4>, <0x4a0052e0 0x4>, <0x4a0052e4 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_gpu_m2_ck: dpll_gpu_m2_ck@4a0052e8 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_gpu_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0052e8 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+gpu_dclk: gpu_dclk@4ae061a0 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_gpu_m2_ck>; -+ reg = <0x4ae061a0 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+dpll_core_m2_ck: dpll_core_m2_ck@4a005130 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005130 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+core_dpll_out_dclk_div: core_dpll_out_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_ddr_ck: dpll_ddr_ck@4a005210 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; -+ reg = <0x4a005210 0x4>, <0x4a005214 0x4>, <0x4a005218 0x4>, <0x4a00521c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_ddr_m2_ck: dpll_ddr_m2_ck@4a005220 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_ddr_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005220 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+emif_phy_dclk_div: emif_phy_dclk_div@4ae06190 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_ddr_m2_ck>; -+ reg = <0x4ae06190 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+dpll_gmac_ck: dpll_gmac_ck@4a0052a8 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; -+ reg = <0x4a0052a8 0x4>, <0x4a0052ac 0x4>, <0x4a0052b0 0x4>, <0x4a0052b4 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_gmac_m2_ck: dpll_gmac_m2_ck@4a0052b8 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_gmac_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0052b8 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+gmac_250m_dclk_div: gmac_250m_dclk_div@4ae0619c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_gmac_m2_ck>; -+ reg = <0x4ae0619c 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+video2_dclk_div: video2_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&video2_m2_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+video1_dclk_div: video1_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&video1_m2_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+hdmi_dclk_div: hdmi_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&hdmi_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+per_dpll_hs_clk_div: per_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_per_ck: dpll_per_ck@4a008140 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; -+ reg = <0x4a008140 0x4>, <0x4a008144 0x4>, <0x4a008148 0x4>, <0x4a00814c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_per_m2_ck: dpll_per_m2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008150 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+func_96m_aon_dclk_div: func_96m_aon_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+usb_dpll_hs_clk_div: usb_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <3>; -+}; -+ -+dpll_usb_ck: dpll_usb_ck@4a008180 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-j-type-clock"; -+ clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; -+ reg = <0x4a008180 0x4>, <0x4a008184 0x4>, <0x4a008188 0x4>, <0x4a00818c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_usb_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008190 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+l3init_480m_dclk_div: l3init_480m_dclk_div@4ae061ac { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ reg = <0x4ae061ac 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+usb_otg_dclk_div: usb_otg_dclk_div@4ae06184 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&usb_otg_clkin_ck>; -+ reg = <0x4ae06184 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+sata_dclk_div: sata_dclk_div@4ae061c0 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin1>; -+ reg = <0x4ae061c0 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+dpll_pcie_ref_m2_ck: dpll_pcie_ref_m2_ck@4a008210 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_pcie_ref_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008210 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+pcie2_dclk_div: pcie2_dclk_div@4ae061b8 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_pcie_ref_m2_ck>; -+ reg = <0x4ae061b8 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+pcie_dclk_div: pcie_dclk_div@4ae061b4 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&apll_pcie_m2_ck>; -+ reg = <0x4ae061b4 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+emu_dclk_div: emu_dclk_div@4ae06194 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin1>; -+ reg = <0x4ae06194 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+secure_32k_dclk_div: secure_32k_dclk_div@4ae061c4 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&secure_32k_clk_src_ck>; -+ reg = <0x4ae061c4 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+eve_dpll_hs_clk_div: eve_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_eve_ck: dpll_eve_ck@4a005284 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; -+ reg = <0x4a005284 0x4>, <0x4a005288 0x4>, <0x4a00528c 0x4>, <0x4a005290 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_eve_m2_ck: dpll_eve_m2_ck@4a005294 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_eve_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005294 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+eve_dclk_div: eve_dclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_eve_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+clkoutmux0_clk_mux: clkoutmux0_clk_mux@4ae06158 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>; -+ reg = <0x4ae06158 0x4>; -+ bit-mask = <0x1f>; -+}; -+ -+clkoutmux1_clk_mux: clkoutmux1_clk_mux@4ae0615c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>; -+ reg = <0x4ae0615c 0x4>; -+ bit-mask = <0x1f>; -+}; -+ -+clkoutmux2_clk_mux: clkoutmux2_clk_mux@4ae06160 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clk1_dclk_div>, <&sys_clk2_dclk_div>, <&per_abe_x1_dclk_div>, <&mpu_dclk_div>, <&dsp_gclk_div>, <&iva_dclk>, <&gpu_dclk>, <&core_dpll_out_dclk_div>, <&emif_phy_dclk_div>, <&gmac_250m_dclk_div>, <&video2_dclk_div>, <&video1_dclk_div>, <&hdmi_dclk_div>, <&func_96m_aon_dclk_div>, <&l3init_480m_dclk_div>, <&usb_otg_dclk_div>, <&sata_dclk_div>, <&pcie2_dclk_div>, <&pcie_dclk_div>, <&emu_dclk_div>, <&secure_32k_dclk_div>, <&eve_dclk_div>; -+ reg = <0x4ae06160 0x4>; -+ bit-mask = <0x1f>; -+}; -+ -+custefuse_sys_gfclk_div: custefuse_sys_gfclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin1>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_core_h13x2_ck: dpll_core_h13x2_ck@4a005140 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005140 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h14x2_ck: dpll_core_h14x2_ck@4a005144 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005144 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h22x2_ck: dpll_core_h22x2_ck@4a005154 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005154 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h23x2_ck: dpll_core_h23x2_ck@4a005158 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005158 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h24x2_ck: dpll_core_h24x2_ck@4a00515c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00515c 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_ddr_x2_ck: dpll_ddr_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_ddr_ck>; -+}; -+ -+dpll_ddr_h11x2_ck: dpll_ddr_h11x2_ck@4a005228 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_ddr_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005228 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_dsp_x2_ck: dpll_dsp_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_dsp_ck>; -+}; -+ -+dpll_dsp_m3x2_ck: dpll_dsp_m3x2_ck@4a005248 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_dsp_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a005248 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_gmac_x2_ck: dpll_gmac_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_gmac_ck>; -+}; -+ -+dpll_gmac_h11x2_ck: dpll_gmac_h11x2_ck@4a0052c0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_gmac_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0052c0 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_gmac_h12x2_ck: dpll_gmac_h12x2_ck@4a0052c4 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_gmac_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0052c4 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_gmac_h13x2_ck: dpll_gmac_h13x2_ck@4a0052c8 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_gmac_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0052c8 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_gmac_m3x2_ck: dpll_gmac_m3x2_ck@4a0052bc { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_gmac_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0052bc 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_x2_ck: dpll_per_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_per_ck>; -+}; -+ -+dpll_per_h11x2_ck: dpll_per_h11x2_ck@4a008158 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008158 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_h12x2_ck: dpll_per_h12x2_ck@4a00815c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00815c 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_h13x2_ck: dpll_per_h13x2_ck@4a008160 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008160 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_h14x2_ck: dpll_per_h14x2_ck@4a008164 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008164 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m2x2_ck: dpll_per_m2x2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008150 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_usb_clkdcoldo: dpll_usb_clkdcoldo { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_usb_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+eve_clk: eve_clk@4ae06180 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_eve_m2_ck>, <&dpll_dsp_m3x2_ck>; -+ reg = <0x4ae06180 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_128m_clk: func_128m_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_h11x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+func_12m_fclk: func_12m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+func_24m_clk: func_24m_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+func_48m_fclk: func_48m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+func_96m_fclk: func_96m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+gmii_m_clk_div: gmii_m_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_gmac_h11x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+hdmi_clk2_div: hdmi_clk2_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&hdmi_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+hdmi_div_clk: hdmi_div_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&hdmi_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+hdmi_dpll_clk_mux: hdmi_dpll_clk_mux@4ae061a4 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin2>; -+ reg = <0x4ae061a4 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+l3_iclk_div: l3_iclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l3init_60m_fclk: l3init_60m_fclk@4a008104 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ reg = <0x4a008104 0x4>; -+ table = < 1 0 >, < 8 1 >; -+ bit-mask = <0x1>; -+}; -+ -+l3init_960m_gfclk: l3init_960m_gfclk@4a0086c0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_clkdcoldo>; -+ bit-shift = <8>; -+ reg = <0x4a0086c0 0x4>; -+}; -+ -+l4_root_clk_div: l4_root_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l3_iclk_div>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mlb_clk: mlb_clk@4ae06134 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mlb_clkin_ck>; -+ reg = <0x4ae06134 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+mlbp_clk: mlbp_clk@4ae06130 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mlbp_clkin_ck>; -+ reg = <0x4ae06130 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+per_abe_x1_gfclk2_div: per_abe_x1_gfclk2_div@4ae06138 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2_ck>; -+ reg = <0x4ae06138 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+timer_sys_clk_div: timer_sys_clk_div@4ae06144 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin1>; -+ reg = <0x4ae06144 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+video1_clk2_div: video1_clk2_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&video1_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+video1_div_clk: video1_div_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&video1_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+video1_dpll_clk_mux: video1_dpll_clk_mux@4ae061d0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin2>; -+ reg = <0x4ae061d0 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+video2_clk2_div: video2_clk2_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&video2_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+video2_div_clk: video2_div_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&video2_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+video2_dpll_clk_mux: video2_dpll_clk_mux@4ae061d4 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin2>; -+ reg = <0x4ae061d4 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+wkupaon_iclk_mux: wkupaon_iclk_mux@4ae06108 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&abe_lp_clk_div>; -+ reg = <0x4ae06108 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dss_32khz_clk: dss_32khz_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <11>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_48mhz_clk: dss_48mhz_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_48m_fclk>; -+ bit-shift = <9>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_dss_clk: dss_dss_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_h12x2_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_hdmi_clk: dss_hdmi_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&hdmi_dpll_clk_mux>; -+ bit-shift = <10>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_video1_clk: dss_video1_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&video1_dpll_clk_mux>; -+ bit-shift = <12>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_video2_clk: dss_video2_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&video2_dpll_clk_mux>; -+ bit-shift = <13>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_deshdcp_clk: dss_deshdcp_clk@4a002558 { -+ compatible = "gate-clock"; -+ clocks = <&l3_iclk_div>; -+ #clock-cells = <0>; -+ reg = <0x4a002558 0x1>; -+ bit-shift = <0>; -+}; -+ -+gpio1_dbclk: gpio1_dbclk@4ae07838 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae07838 0x4>; -+}; -+ -+gpio2_dbclk: gpio2_dbclk@4a009760 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009760 0x4>; -+}; -+ -+gpio3_dbclk: gpio3_dbclk@4a009768 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009768 0x4>; -+}; -+ -+gpio4_dbclk: gpio4_dbclk@4a009770 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009770 0x4>; -+}; -+ -+gpio5_dbclk: gpio5_dbclk@4a009778 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009778 0x4>; -+}; -+ -+gpio6_dbclk: gpio6_dbclk@4a009780 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009780 0x4>; -+}; -+ -+gpio7_dbclk: gpio7_dbclk@4a009810 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009810 0x4>; -+}; -+ -+gpio8_dbclk: gpio8_dbclk@4a009818 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009818 0x4>; -+}; -+ -+mmc1_clk32k: mmc1_clk32k@4a009328 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009328 0x4>; -+}; -+ -+mmc2_clk32k: mmc2_clk32k@4a009330 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009330 0x4>; -+}; -+ -+mmc3_clk32k: mmc3_clk32k@4a009820 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009820 0x4>; -+}; -+ -+mmc4_clk32k: mmc4_clk32k@4a009828 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009828 0x4>; -+}; -+ -+sata_ref_clk: sata_ref_clk@4a009388 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_clkin1>; -+ bit-shift = <8>; -+ reg = <0x4a009388 0x4>; -+}; -+ -+usb_otg_ss1_refclk960m: usb_otg_ss1_refclk960m@4a0093f0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_960m_gfclk>; -+ bit-shift = <8>; -+ reg = <0x4a0093f0 0x4>; -+}; -+ -+usb_otg_ss2_refclk960m: usb_otg_ss2_refclk960m@4a009340 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_960m_gfclk>; -+ bit-shift = <8>; -+ reg = <0x4a009340 0x4>; -+}; -+ -+usb_phy1_always_on_clk32k: usb_phy1_always_on_clk32k@4a008640 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a008640 0x4>; -+}; -+ -+usb_phy2_always_on_clk32k: usb_phy2_always_on_clk32k@4a008688 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a008688 0x4>; -+}; -+ -+usb_phy3_always_on_clk32k: usb_phy3_always_on_clk32k@4a008698 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a008698 0x4>; -+}; -+ -+atl_dpll_clk_mux: atl_dpll_clk_mux@4a008c00 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_32k_ck>, <&video1_clkin_ck>, <&video2_clkin_ck>, <&hdmi_clkin_ck>; -+ bit-shift = <24>; -+ reg = <0x4a008c00 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+atl_gfclk_mux: atl_gfclk_mux@4a008c00 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3_iclk_div>, <&dpll_abe_m2_ck>, <&atl_dpll_clk_mux>; -+ bit-shift = <26>; -+ reg = <0x4a008c00 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+dcan1_sys_clk_mux: dcan1_sys_clk_mux@4ae07888 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin1>, <&sys_clkin2>; -+ bit-shift = <24>; -+ reg = <0x4ae07888 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gmac_gmii_ref_clk_div: gmac_gmii_ref_clk_div@4a0093d0 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_gmac_m2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a0093d0 0x4>; -+ table = < 2 0 >; -+ bit-mask = <0x1>; -+}; -+ -+gmac_rft_clk_mux: gmac_rft_clk_mux@4a0093d0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&video1_clkin_ck>, <&video2_clkin_ck>, <&dpll_abe_m2_ck>, <&hdmi_clkin_ck>, <&l3_iclk_div>; -+ bit-shift = <25>; -+ reg = <0x4a0093d0 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+gpu_core_gclk_mux: gpu_core_gclk_mux@4a009220 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009220 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+gpu_hyd_gclk_mux: gpu_hyd_gclk_mux@4a009220 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>, <&dpll_gpu_m2_ck>; -+ bit-shift = <26>; -+ reg = <0x4a009220 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+ipu1_gfclk_mux: ipu1_gfclk_mux@4a005520 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a005520 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+l3instr_ts_gclk_div: l3instr_ts_gclk_div@4a008e50 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&wkupaon_iclk_mux>; -+ bit-shift = <24>; -+ reg = <0x4a008e50 0x4>; -+ table = < 8 0 >, < 16 1 >, < 32 2 >; -+ bit-mask = <0x3>; -+}; -+ -+mcasp1_ahclkr_mux: mcasp1_ahclkr_mux@4a005550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <28>; -+ reg = <0x4a005550 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp1_ahclkx_mux: mcasp1_ahclkx_mux@4a005550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <24>; -+ reg = <0x4a005550 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp1_aux_gfclk_mux: mcasp1_aux_gfclk_mux@4a005550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a005550 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp2_ahclkr_mux: mcasp2_ahclkr_mux@4a009860 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <28>; -+ reg = <0x4a009860 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp2_ahclkx_mux: mcasp2_ahclkx_mux@4a009860 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <28>; -+ reg = <0x4a009860 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp2_aux_gfclk_mux: mcasp2_aux_gfclk_mux@4a009860 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a009860 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp3_ahclkx_mux: mcasp3_ahclkx_mux@4a009868 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009868 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp3_aux_gfclk_mux: mcasp3_aux_gfclk_mux@4a009868 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a009868 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp4_ahclkx_mux: mcasp4_ahclkx_mux@4a009898 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009898 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp4_aux_gfclk_mux: mcasp4_aux_gfclk_mux@4a009898 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a009898 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp5_ahclkx_mux: mcasp5_ahclkx_mux@4a009878 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009878 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp5_aux_gfclk_mux: mcasp5_aux_gfclk_mux@4a009878 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a009878 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp6_ahclkx_mux: mcasp6_ahclkx_mux@4a009904 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009904 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp6_aux_gfclk_mux: mcasp6_aux_gfclk_mux@4a009904 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a009904 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp7_ahclkx_mux: mcasp7_ahclkx_mux@4a009908 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009908 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mcasp7_aux_gfclk_mux: mcasp7_aux_gfclk_mux@4a009908 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <22>; -+ reg = <0x4a009908 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp8_ahclk_mux: mcasp8_ahclk_mux@4a009890 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; -+ bit-shift = <22>; -+ reg = <0x4a009890 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp8_aux_gfclk_mux: mcasp8_aux_gfclk_mux@4a009890 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_abe_x1_gfclk2_div>, <&video1_clk2_div>, <&video2_clk2_div>, <&hdmi_clk2_div>; -+ bit-shift = <24>; -+ reg = <0x4a009890 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+mmc1_fclk_mux: mmc1_fclk_mux@4a009328 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009328 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc1_fclk_div: mmc1_fclk_div@4a009328 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mmc1_fclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009328 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+mmc2_fclk_mux: mmc2_fclk_mux@4a009330 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009330 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc2_fclk_div: mmc2_fclk_div@4a009330 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mmc2_fclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009330 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+mmc3_gfclk_mux: mmc3_gfclk_mux@4a009820 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009820 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc3_gfclk_div: mmc3_gfclk_div@4a009820 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mmc3_gfclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009820 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+mmc4_gfclk_mux: mmc4_gfclk_mux@4a009828 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009828 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc4_gfclk_div: mmc4_gfclk_div@4a009828 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mmc4_gfclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009828 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+qspi_gfclk_mux: qspi_gfclk_mux@4a009838 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_128m_clk>, <&dpll_per_h13x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009838 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+qspi_gfclk_div: qspi_gfclk_div@4a009838 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&qspi_gfclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009838 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+timer10_gfclk_mux: timer10_gfclk_mux@4a009728 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009728 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer11_gfclk_mux: timer11_gfclk_mux@4a009730 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009730 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer13_gfclk_mux: timer13_gfclk_mux@4a0097c8 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a0097c8 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer14_gfclk_mux: timer14_gfclk_mux@4a0097d0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a0097d0 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer15_gfclk_mux: timer15_gfclk_mux@4a0097d8 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a0097d8 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer16_gfclk_mux: timer16_gfclk_mux@4a009830 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009830 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer1_gfclk_mux: timer1_gfclk_mux@4ae07840 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4ae07840 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer2_gfclk_mux: timer2_gfclk_mux@4a009738 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009738 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer3_gfclk_mux: timer3_gfclk_mux@4a009740 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009740 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer4_gfclk_mux: timer4_gfclk_mux@4a009748 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009748 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer5_gfclk_mux: timer5_gfclk_mux@4a005558 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; -+ bit-shift = <24>; -+ reg = <0x4a005558 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer6_gfclk_mux: timer6_gfclk_mux@4a005560 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; -+ bit-shift = <24>; -+ reg = <0x4a005560 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer7_gfclk_mux: timer7_gfclk_mux@4a005568 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; -+ bit-shift = <24>; -+ reg = <0x4a005568 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer8_gfclk_mux: timer8_gfclk_mux@4a005570 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>, <&clkoutmux0_clk_mux>; -+ bit-shift = <24>; -+ reg = <0x4a005570 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+timer9_gfclk_mux: timer9_gfclk_mux@4a009750 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&timer_sys_clk_div>, <&sys_32k_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&abe_giclk_div>, <&video1_div_clk>, <&video2_div_clk>, <&hdmi_div_clk>; -+ bit-shift = <24>; -+ reg = <0x4a009750 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+uart10_gfclk_mux: uart10_gfclk_mux@4ae07880 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4ae07880 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart1_gfclk_mux: uart1_gfclk_mux@4a009840 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009840 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart2_gfclk_mux: uart2_gfclk_mux@4a009848 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009848 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart3_gfclk_mux: uart3_gfclk_mux@4a009850 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009850 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart4_gfclk_mux: uart4_gfclk_mux@4a009858 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009858 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart5_gfclk_mux: uart5_gfclk_mux@4a009870 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009870 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart6_gfclk_mux: uart6_gfclk_mux@4a005580 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a005580 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart7_gfclk_mux: uart7_gfclk_mux@4a0098d0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a0098d0 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart8_gfclk_mux: uart8_gfclk_mux@4a0098e0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a0098e0 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+uart9_gfclk_mux: uart9_gfclk_mux@4a0098e8 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_48m_fclk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a0098e8 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+vip1_gclk_mux: vip1_gclk_mux@4a009020 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009020 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+vip2_gclk_mux: vip2_gclk_mux@4a009028 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009028 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+vip3_gclk_mux: vip3_gclk_mux@4a009030 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3_iclk_div>, <&dpll_core_h23x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009030 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+optfclk_pciephy_div: optfclk_pciephy_div@4a00821c { -+ compatible = "divider-clock"; -+ clocks = <&apll_pcie_ck>; -+ #clock-cells = <0>; -+ reg = <0x4a00821c 0x4>; -+ bit-mask = <0x100>; -+}; -+ -+optfclk_pciephy_clk: optfclk_pciephy_clk@4a0093b0 { -+ compatible = "gate-clock"; -+ clocks = <&apll_pcie_ck>; -+ #clock-cells = <0>; -+ reg = <0x4a0093b0 0x4>; -+ bit-shift = <9>; -+}; -+ -+optfclk_pciephy_div_clk: optfclk_pciephy_div_clk@4a0093b0 { -+ compatible = "gate-clock"; -+ clocks = <&optfclk_pciephy_div>; -+ #clock-cells = <0>; -+ reg = <0x4a0093b0 0x4>; -+ bit-shift = <10>; -+}; ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -186,9 +186,12 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420 - am335x-evmsk.dtb \ - am335x-bone.dtb \ - am335x-boneblack.dtb \ -+ am335x-evm-profile2.dtb \ - am3517-evm.dtb \ - am3517_mt_ventoux.dtb \ -- am43x-epos-evm.dtb -+ am43x-epos-evm.dtb \ -+ am437x-gp-evm.dtb \ -+ dra7-evm.dtb - dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb - dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb - dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ ---- a/arch/arm/boot/dts/omap2420.dtsi -+++ b/arch/arm/boot/dts/omap2420.dtsi -@@ -114,6 +114,18 @@ - dma-names = "tx", "rx"; - }; - -+ mailbox: mailbox@48094000 { -+ compatible = "ti,omap2-mailbox"; -+ reg = <0x48094000 0x200>; -+ interrupts = <26>, /* DSP Interrupt */ -+ <34>; /* IVA Interrupt */ -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <6>; -+ ti,mbox-names = "dsp", "iva"; -+ ti,mbox-data = <0 1 0 0>, <2 3 1 3>; -+ }; -+ - timer1: timer@48028000 { - compatible = "ti,omap2420-timer"; - reg = <0x48028000 0x400>; ---- a/arch/arm/boot/dts/omap2430.dtsi -+++ b/arch/arm/boot/dts/omap2430.dtsi -@@ -175,6 +175,17 @@ - dma-names = "tx", "rx"; - }; - -+ mailbox: mailbox@48094000 { -+ compatible = "ti,omap2-mailbox"; -+ reg = <0x48094000 0x200>; -+ interrupts = <26>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <4>; -+ ti,mbox-num-fifos = <6>; -+ ti,mbox-names = "dsp"; -+ ti,mbox-data = <0 1 0 0>; -+ }; -+ - timer1: timer@49018000 { - compatible = "ti,omap2420-timer"; - reg = <0x49018000 0x400>; ---- /dev/null -+++ b/arch/arm/boot/dts/omap3430es1-clocks.dtsi -@@ -0,0 +1,158 @@ -+/* -+ * Device Tree Source for OMAP3430 ES1 clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+gfx_l3_ck: gfx_l3_ck@48004b10 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&l3_ick>; -+ reg = <0x48004b10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+gfx_l3_fck: gfx_l3_fck@48004b40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&l3_ick>; -+ reg = <0x48004b40 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+gfx_l3_ick: gfx_l3_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&gfx_l3_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+gfx_cg1_ck: gfx_cg1_ck@48004b00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&gfx_l3_fck>; -+ reg = <0x48004b00 0x4>; -+ ti,enable-bit = <1>; -+}; -+ -+gfx_cg2_ck: gfx_cg2_ck@48004b00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&gfx_l3_fck>; -+ reg = <0x48004b00 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+d2d_26m_fck: d2d_26m_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+fshostusb_fck: fshostusb_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <5>; -+}; -+ -+ssi_ssr_div_fck_3430es1: ssi_ssr_div_fck_3430es1@48004a40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&corex2_fck>; -+ bit-shift = <8>; -+ reg = <0x48004a40 0x4>; -+ table = < 1 1 >, < 2 2 >, < 3 3 >, < 4 4 >, < 6 6 >, < 8 8 >; -+ bit-mask = <0xf>; -+}; -+ -+ssi_ssr_fck_3430es1: ssi_ssr_fck_3430es1@48004a00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&ssi_ssr_div_fck_3430es1>; -+ bit-shift = <0>; -+ reg = <0x48004a00 0x4>; -+}; -+ -+ssi_sst_fck_3430es1: ssi_sst_fck_3430es1 { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&ssi_ssr_fck_3430es1>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+hsotgusb_ick: hsotgusb_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-no-wait-interface-clock"; -+ clocks = <&core_l3_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <4>; -+}; -+ -+fac_ick: fac_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <8>; -+}; -+ -+ssi_l4_ick: ssi_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+ssi_ick_3430es1: ssi_ick_3430es1@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-no-wait-interface-clock"; -+ clocks = <&ssi_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+usb_l4_div_ick: usb_l4_div_ick@48004a40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&l4_ick>; -+ bit-shift = <4>; -+ reg = <0x48004a40 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+usb_l4_ick: usb_l4_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&usb_l4_div_ick>; -+ bit-shift = <5>; -+ reg = <0x48004a10 0x4>; -+}; -+ -+dss1_alwon_fck_3430es1: dss1_alwon_fck_3430es1@48004e00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m4x2_ck>; -+ reg = <0x48004e00 0x4>; -+ bit-shift = <0>; -+}; -+ -+dss_ick_3430es1: dss_ick_3430es1@48004e10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-no-wait-interface-clock"; -+ clocks = <&l4_ick>; -+ reg = <0x48004e10 0x4>; -+ ti,enable-bit = <0>; -+}; ---- a/arch/arm/boot/dts/omap34xx.dtsi -+++ b/arch/arm/boot/dts/omap34xx.dtsi -@@ -25,4 +25,113 @@ - clock-latency = <300000>; /* From legacy driver */ - }; - }; --}; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "omap34xx-omap36xx-clocks.dtsi" -+ /include/ "omap36xx-omap3430es2plus-clocks.dtsi" -+ /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ usbhost_clkdm: usbhost_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&usbhost_48m_fck>, <&usbhost_ick>; -+ }; -+ -+ wkup_clkdm: wkup_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&wdt1_ick>, <&gpt12_ick>, <&gpio1_ick>, -+ <&gpt1_ick>, <&omap_32ksync_ick>, <&wdt2_ick>, -+ <&wdt2_fck>; -+ }; -+ -+ cam_clkdm: cam_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&cam_ick>; -+ }; -+ -+ dpll4_clkdm: dpll4_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll4_ck>; -+ }; -+ -+ sgx_clkdm: sgx_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&sgx_ick>; -+ }; -+ -+ dpll3_clkdm: dpll3_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll3_ck>; -+ }; -+ -+ iva2_clkdm: iva2_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&iva2_ck>; -+ }; -+ -+ dpll1_clkdm: dpll1_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll1_ck>; -+ }; -+ -+ dpll2_clkdm: dpll2_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll2_ck>; -+ }; -+ -+ dpll5_clkdm: dpll5_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll5_ck>; -+ }; -+ -+ dss_clkdm: dss_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; -+ }; -+ -+ core_l4_clkdm: core_l4_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&mmchs1_ick>, <&mmchs2_ick>, <&hdq_fck>, -+ <&uart1_ick>, <&mcspi4_fck>, <&i2c3_fck>, -+ <&mcspi2_ick>, <&uart2_ick>, <&mcspi3_ick>, -+ <&i2c1_fck>, <&hdq_ick>, <&sha12_ick>, -+ <&mcbsp5_ick>, <&mcspi3_fck>, <&aes2_ick>, -+ <&mcspi1_ick>, <&uart2_fck>, <&mmchs2_fck>, -+ <&mmchs1_fck>, <&i2c3_ick>, <&mcspi1_fck>, -+ <&mcspi4_ick>, <&omapctrl_ick>, <&mcbsp1_ick>, -+ <&mcspi2_fck>, <&gpt10_ick>, <&i2c2_fck>, -+ <&i2c2_ick>, <&gpt11_ick>, <&i2c1_ick>, -+ <&uart1_fck>; -+ }; -+ -+ core_l3_clkdm: core_l3_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&sdrc_ick>; -+ }; -+ -+ per_clkdm: per_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&gpt2_ick>, <&uart3_fck>, <&gpio3_ick>, -+ <&mcbsp2_ick>, <&gpt6_ick>, <&mcbsp4_ick>, -+ <&gpt4_ick>, <&mcbsp3_ick>, <&gpt8_ick>, -+ <&uart3_ick>, <&gpt5_ick>, <&gpt7_ick>, -+ <&gpio2_ick>, <&gpio6_ick>, <&gpt9_ick>, -+ <&gpt3_ick>, <&gpio5_ick>, <&wdt3_ick>, -+ <&gpio4_ick>, <&wdt3_fck>, <&uart4_ick>; -+ }; -+ -+ emu_clkdm: emu_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&emu_src_ck>; -+ }; -+ -+ d2d_clkdm: d2d_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&mad2d_ick>, <&sad2d_ick>, <&modem_fck>; -+ }; -+ }; -+}; -\ No newline at end of file ---- /dev/null -+++ b/arch/arm/boot/dts/omap34xx-omap36xx-clocks.dtsi -@@ -0,0 +1,222 @@ -+/* -+ * Device Tree Source for OMAP34xx/OMAP36xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+security_l4_ick2: security_l4_ick2 { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+aes1_ick: aes1_ick@48004a14 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&security_l4_ick2>; -+ reg = <0x48004a14 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+rng_ick: rng_ick@48004a14 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&security_l4_ick2>; -+ reg = <0x48004a14 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+sha11_ick: sha11_ick@48004a14 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&security_l4_ick2>; -+ reg = <0x48004a14 0x4>; -+ ti,enable-bit = <1>; -+}; -+ -+des1_ick: des1_ick@48004a14 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&security_l4_ick2>; -+ reg = <0x48004a14 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+cam_mclk: cam_mclk@48004f00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m5x2_ck>; -+ bit-shift = <0>; -+ reg = <0x48004f00 0x4>; -+ set-rate-parent; -+}; -+ -+cam_ick: cam_ick@48004f10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-no-wait-interface-clock"; -+ clocks = <&l4_ick>; -+ reg = <0x48004f10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+csi2_96m_fck: csi2_96m_fck@48004f00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004f00 0x4>; -+ bit-shift = <1>; -+}; -+ -+security_l3_ick: security_l3_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l3_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+pka_ick: pka_ick@48004a14 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&security_l3_ick>; -+ reg = <0x48004a14 0x4>; -+ ti,enable-bit = <4>; -+}; -+ -+icr_ick: icr_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <29>; -+}; -+ -+des2_ick: des2_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <26>; -+}; -+ -+mspro_ick: mspro_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <23>; -+}; -+ -+mailboxes_ick: mailboxes_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <7>; -+}; -+ -+ssi_l4_ick: ssi_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sr1_fck: sr1_fck@48004c00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x48004c00 0x4>; -+ ti,enable-bit = <6>; -+}; -+ -+sr2_fck: sr2_fck@48004c00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x48004c00 0x4>; -+ ti,enable-bit = <7>; -+}; -+ -+sr_l4_ick: sr_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll2_fck: dpll2_fck@48004040 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&core_ck>; -+ bit-shift = <19>; -+ reg = <0x48004040 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+dpll2_ck: dpll2_ck@48004004 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-clock"; -+ clocks = <&sys_ck>, <&dpll2_fck>; -+ ti,modes = <0xa2>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004004 0x4>, <0x48004024 0x4>, <0x48004034 0x4>, <0x48004040 0x4>; -+}; -+ -+dpll2_m2_ck: dpll2_m2_ck@48004044 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll2_ck>; -+ reg = <0x48004044 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+iva2_ck: iva2_ck@48004000 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&dpll2_m2_ck>; -+ reg = <0x48004000 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+modem_fck: modem_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <31>; -+}; -+ -+sad2d_ick: sad2d_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&l3_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+mad2d_ick: mad2d_ick@48004a18 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&l3_ick>; -+ reg = <0x48004a18 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+mspro_fck: mspro_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <23>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/omap36xx-am35xx-omap3430es2plus-clocks.dtsi -@@ -0,0 +1,196 @@ -+/* -+ * Device Tree Source for OMAP36xx/AM35xx/OMAP34xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+dpll5_ck: dpll5_ck@48004d04 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-clock"; -+ clocks = <&sys_ck>, <&sys_ck>; -+ ti,modes = <0x82>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004d04 0x4>, <0x48004d24 0x4>, <0x48004d34 0x4>, <0x48004d4c 0x4>; -+}; -+ -+dpll5_m2_ck: dpll5_m2_ck@48004d50 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll5_ck>; -+ reg = <0x48004d50 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+core_d3_ck: core_d3_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&core_ck>; -+ clock-mult = <1>; -+ clock-div = <3>; -+}; -+ -+core_d4_ck: core_d4_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&core_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+core_d6_ck: core_d6_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&core_ck>; -+ clock-mult = <1>; -+ clock-div = <6>; -+}; -+ -+omap_192m_alwon_fck: omap_192m_alwon_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+core_d2_ck: core_d2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&core_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+corex2_d3_fck: corex2_d3_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&corex2_fck>; -+ clock-mult = <1>; -+ clock-div = <3>; -+}; -+ -+corex2_d5_fck: corex2_d5_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&corex2_fck>; -+ clock-mult = <1>; -+ clock-div = <5>; -+}; -+ -+sgx_mux_fck: sgx_mux_fck@48004b40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&core_d3_ck>, <&core_d4_ck>, <&core_d6_ck>, <&cm_96m_fck>, <&omap_192m_alwon_fck>, <&core_d2_ck>, <&corex2_d3_fck>, <&corex2_d5_fck>; -+ reg = <0x48004b40 0x4>; -+ table = <&core_d3_ck 0>, <&core_d4_ck 1>, <&core_d6_ck 2>, <&cm_96m_fck 3>, <&omap_192m_alwon_fck 4>, <&core_d2_ck 5>, <&corex2_d3_fck 6>, <&corex2_d5_fck 7>; -+ bit-mask = <0x7>; -+}; -+ -+sgx_fck: sgx_fck@48004b00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sgx_mux_fck>; -+ bit-shift = <1>; -+ reg = <0x48004b00 0x4>; -+}; -+ -+sgx_ick: sgx_ick@48004b10 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&l3_ick>; -+ reg = <0x48004b10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+cpefuse_fck: cpefuse_fck@48004a08 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x48004a08 0x4>; -+ bit-shift = <0>; -+}; -+ -+ts_fck: ts_fck@48004a08 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&omap_32k_fck>; -+ reg = <0x48004a08 0x4>; -+ bit-shift = <1>; -+}; -+ -+usbtll_fck: usbtll_fck@48004a08 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&dpll5_m2_ck>; -+ reg = <0x48004a08 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+usbtll_ick: usbtll_ick@48004a18 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a18 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+mmchs3_ick: mmchs3_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <30>; -+}; -+ -+mmchs3_fck: mmchs3_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <30>; -+}; -+ -+dss1_alwon_fck_3430es2: dss1_alwon_fck_3430es2@48004e00 { -+ #clock-cells = <0>; -+ compatible = "ti,dss-gate-clock"; -+ clocks = <&dpll4_m4x2_ck>; -+ reg = <0x48004e00 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+dss_ick_3430es2: dss_ick_3430es2@48004e10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dss-interface-clock"; -+ clocks = <&l4_ick>; -+ reg = <0x48004e10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+usbhost_120m_fck: usbhost_120m_fck@48005400 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll5_m2_ck>; -+ reg = <0x48005400 0x4>; -+ bit-shift = <1>; -+}; -+ -+usbhost_48m_fck: usbhost_48m_fck@48005400 { -+ #clock-cells = <0>; -+ compatible = "ti,dss-gate-clock"; -+ clocks = <&omap_48m_fck>; -+ reg = <0x48005400 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+usbhost_ick: usbhost_ick@48005410 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dss-interface-clock"; -+ clocks = <&l4_ick>; -+ reg = <0x48005410 0x4>; -+ ti,enable-bit = <0>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/omap36xx-clocks.dtsi -@@ -0,0 +1,80 @@ -+/* -+ * Device Tree Source for OMAP36xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+dpll4_ck: dpll4_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-per-j-type-clock"; -+ clocks = <&sys_ck>, <&sys_ck>; -+ ti,modes = <0x82>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004d00 0x4>, <0x48004d20 0x4>, <0x48004d30 0x4>, <0x48004d44 0x4>; -+}; -+ -+dpll4_m2x2_ck: dpll4_m2x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,hsdiv-gate-clock"; -+ clocks = <&dpll4_m2x2_mul_ck>; -+ reg = <0x48004d00 0x4>; -+ ti,enable-bit = <0x1b>; -+ ti,set-bit-to-disable; -+}; -+ -+dpll3_m3x2_ck: dpll3_m3x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,hsdiv-gate-clock"; -+ clocks = <&dpll3_m3x2_mul_ck>; -+ reg = <0x48004d00 0x4>; -+ ti,enable-bit = <0xc>; -+ ti,set-bit-to-disable; -+}; -+ -+dpll4_m3x2_ck: dpll4_m3x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,hsdiv-gate-clock"; -+ clocks = <&dpll4_m3x2_mul_ck>; -+ reg = <0x48004d00 0x4>; -+ ti,enable-bit = <0x1c>; -+ ti,set-bit-to-disable; -+}; -+ -+dpll4_m5x2_ck: dpll4_m5x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,hsdiv-gate-clock"; -+ clocks = <&dpll4_m5x2_mul_ck>; -+ reg = <0x48004d00 0x4>; -+ ti,enable-bit = <0x1e>; -+ ti,set-rate-parent; -+ ti,set-bit-to-disable; -+}; -+ -+dpll4_m6x2_ck: dpll4_m6x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,hsdiv-gate-clock"; -+ clocks = <&dpll4_m6x2_mul_ck>; -+ reg = <0x48004d00 0x4>; -+ ti,enable-bit = <0x1f>; -+ ti,set-bit-to-disable; -+}; -+ -+omap_192m_alwon_fck: omap_192m_alwon_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+uart4_fck: uart4_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&per_48m_fck>; -+ reg = <0x48005000 0x4>; -+ ti,enable-bit = <18>; -+}; ---- a/arch/arm/boot/dts/omap36xx.dtsi -+++ b/arch/arm/boot/dts/omap36xx.dtsi -@@ -35,4 +35,114 @@ - clock-frequency = <48000000>; - }; - }; --}; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "omap36xx-clocks.dtsi" -+ /include/ "omap34xx-omap36xx-clocks.dtsi" -+ /include/ "omap36xx-omap3430es2plus-clocks.dtsi" -+ /include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ usbhost_clkdm: usbhost_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&usbhost_48m_fck>, <&usbhost_ick>; -+ }; -+ -+ wkup_clkdm: wkup_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&wdt1_ick>, <&gpt12_ick>, <&gpio1_ick>, -+ <&gpt1_ick>, <&omap_32ksync_ick>, <&wdt2_ick>, -+ <&wdt2_fck>; -+ }; -+ -+ cam_clkdm: cam_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&cam_ick>; -+ }; -+ -+ dpll4_clkdm: dpll4_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll4_ck>; -+ }; -+ -+ sgx_clkdm: sgx_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&sgx_ick>; -+ }; -+ -+ dpll3_clkdm: dpll3_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll3_ck>; -+ }; -+ -+ iva2_clkdm: iva2_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&iva2_ck>; -+ }; -+ -+ dpll1_clkdm: dpll1_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll1_ck>; -+ }; -+ -+ dpll5_clkdm: dpll5_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll5_ck>; -+ }; -+ -+ dpll2_clkdm: dpll2_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll2_ck>; -+ }; -+ -+ dss_clkdm: dss_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; -+ }; -+ -+ core_l4_clkdm: core_l4_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&mmchs1_ick>, <&mmchs2_ick>, <&hdq_fck>, -+ <&uart1_ick>, <&mcspi4_fck>, <&i2c3_fck>, -+ <&mcspi2_ick>, <&uart2_ick>, <&mcspi3_ick>, -+ <&i2c1_fck>, <&hdq_ick>, <&sha12_ick>, -+ <&mcbsp5_ick>, <&mcspi3_fck>, <&aes2_ick>, -+ <&mcspi1_ick>, <&uart2_fck>, <&mmchs2_fck>, -+ <&mmchs1_fck>, <&i2c3_ick>, <&mcspi1_fck>, -+ <&mcspi4_ick>, <&omapctrl_ick>, <&mcbsp1_ick>, -+ <&mcspi2_fck>, <&gpt10_ick>, <&i2c2_fck>, -+ <&i2c2_ick>, <&gpt11_ick>, <&i2c1_ick>, -+ <&uart1_fck>; -+ }; -+ -+ core_l3_clkdm: core_l3_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&sdrc_ick>; -+ }; -+ -+ per_clkdm: per_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&gpt2_ick>, <&uart3_fck>, <&gpio3_ick>, -+ <&mcbsp2_ick>, <&gpt6_ick>, <&mcbsp4_ick>, -+ <&gpt4_ick>, <&mcbsp3_ick>, <&gpt8_ick>, -+ <&uart3_ick>, <&gpt5_ick>, <&gpt7_ick>, -+ <&gpio2_ick>, <&gpio6_ick>, <&gpt9_ick>, -+ <&gpt3_ick>, <&gpio5_ick>, <&wdt3_ick>, -+ <&gpio4_ick>, <&wdt3_fck>, <&uart4_ick>; -+ }; -+ -+ emu_clkdm: emu_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&emu_src_ck>; -+ }; -+ -+ d2d_clkdm: d2d_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&mad2d_ick>, <&sad2d_ick>, <&modem_fck>; -+ }; -+ }; -+}; -\ No newline at end of file ---- /dev/null -+++ b/arch/arm/boot/dts/omap36xx-omap3430es2plus-clocks.dtsi -@@ -0,0 +1,175 @@ -+/* -+ * Device Tree Source for OMAP34xx/OMAP36xx clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+ssi_ssr_div_fck_3430es2: ssi_ssr_div_fck_3430es2@48004a40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&corex2_fck>; -+ bit-shift = <8>; -+ reg = <0x48004a40 0x4>; -+ table = < 1 1 >, < 2 2 >, < 3 3 >, < 4 4 >, < 6 6 >, < 8 8 >; -+ bit-mask = <0xf>; -+}; -+ -+ssi_ssr_fck_3430es2: ssi_ssr_fck_3430es2@48004a00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&ssi_ssr_div_fck_3430es2>; -+ bit-shift = <0>; -+ reg = <0x48004a00 0x4>; -+}; -+ -+ssi_sst_fck_3430es2: ssi_sst_fck_3430es2 { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&ssi_ssr_fck_3430es2>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+hsotgusb_ick: hsotgusb_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-hsotgusb-interface-clock"; -+ clocks = <&core_l3_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <4>; -+}; -+ -+ssi_l4_ick: ssi_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+ssi_ick_3430es2: ssi_ick_3430es2@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-ssi-interface-clock"; -+ clocks = <&ssi_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+dpll5_ck: dpll5_ck@48004d04 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-clock"; -+ clocks = <&sys_ck>, <&sys_ck>; -+ ti,modes = <0x82>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004d04 0x4>, <0x48004d24 0x4>, <0x48004d34 0x4>, <0x48004d4c 0x4>; -+}; -+ -+dpll5_m2_ck: dpll5_m2_ck@48004d50 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll5_ck>; -+ reg = <0x48004d50 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll5_m2_d20_ck: dpll5_m2_d20_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll5_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <20>; -+}; -+ -+sys_d2_ck: sys_d2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+omap_96m_d2_fck: omap_96m_d2_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_fck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+omap_96m_d4_fck: omap_96m_d4_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_fck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+omap_96m_d8_fck: omap_96m_d8_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_fck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+omap_96m_d10_fck: omap_96m_d10_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_fck>; -+ clock-mult = <1>; -+ clock-div = <10>; -+}; -+ -+dpll5_m2_d4_ck: dpll5_m2_d4_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll5_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+dpll5_m2_d8_ck: dpll5_m2_d8_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll5_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+dpll5_m2_d16_ck: dpll5_m2_d16_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll5_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+usim_mux_fck: usim_mux_fck@48004c40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_ck>, <&dpll5_m2_d20_ck>, <&sys_d2_ck>, <&omap_96m_d2_fck>, <&omap_96m_d4_fck>, <&omap_96m_d8_fck>, <&omap_96m_d10_fck>, <&dpll5_m2_d4_ck>, <&dpll5_m2_d8_ck>, <&dpll5_m2_d16_ck>; -+ bit-shift = <3>; -+ reg = <0x48004c40 0x4>; -+ table = <&sys_ck 1>, <&dpll5_m2_d20_ck 10>, <&sys_d2_ck 2>, <&omap_96m_d2_fck 3>, <&omap_96m_d4_fck 4>, <&omap_96m_d8_fck 5>, <&omap_96m_d10_fck 6>, <&dpll5_m2_d4_ck 7>, <&dpll5_m2_d8_ck 8>, <&dpll5_m2_d16_ck 9>; -+ bit-mask = <0xf>; -+}; -+ -+usim_fck: usim_fck@48004c00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&usim_mux_fck>; -+ bit-shift = <9>; -+ reg = <0x48004c00 0x4>; -+}; -+ -+usim_ick: usim_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <9>; -+}; ---- a/arch/arm/boot/dts/omap3-beagle.dts -+++ b/arch/arm/boot/dts/omap3-beagle.dts -@@ -44,17 +44,6 @@ - }; - }; - -- /* HS USB Port 2 RESET */ -- hsusb2_reset: hsusb2_reset_reg { -- compatible = "regulator-fixed"; -- regulator-name = "hsusb2_reset"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- gpio = <&gpio5 19 0>; /* gpio_147 */ -- startup-delay-us = <70000>; -- enable-active-high; -- }; -- - /* HS USB Port 2 Power */ - hsusb2_power: hsusb2_power_reg { - compatible = "regulator-fixed"; -@@ -68,7 +57,7 @@ - /* HS USB Host PHY on PORT 2 */ - hsusb2_phy: hsusb2_phy { - compatible = "usb-nop-xceiv"; -- reset-supply = <&hsusb2_reset>; -+ reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */ - vcc-supply = <&hsusb2_power>; - }; - -@@ -101,18 +90,18 @@ - - hsusbb2_pins: pinmux_hsusbb2_pins { - pinctrl-single,pins = < -- 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_clk */ -- 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_stp */ -- 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dir */ -- 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_nxt */ -- 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat0 */ -- 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat1 */ -- 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat2 */ -- 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat3 */ -- 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat4 */ -- 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat5 */ -- 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat6 */ -- 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* usbb2_ulpitll_clk.usbb1_ulpiphy_dat7 */ -+ 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ -+ 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ -+ 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ -+ 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ -+ 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ -+ 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ -+ 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ -+ 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ -+ 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ -+ 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ -+ 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ -+ 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ - >; - }; - -@@ -180,3 +169,39 @@ - pinctrl-names = "default"; - pinctrl-0 = <&gpio1_pins>; - }; -+ -+&usb_otg_hs { -+ interface-type = <0>; -+ usb-phy = <&usb2_phy>; -+ mode = <3>; -+ power = <50>; -+}; -+ -+&dpi { -+ vdds_dsi-supply = <&vpll2>; -+}; -+ -+/ { -+ aliases { -+ display0 = &dvi0; -+ display1 = &tv0; -+ }; -+ -+ tfp410: encoder@0 { -+ compatible = "ti,tfp410"; -+ video-source = <&dpi>; -+ data-lines = <24>; -+ gpios = <&gpio5 10 0>; /* 170, power-down */ -+ }; -+ -+ dvi0: connector@0 { -+ compatible = "ti,dvi_connector"; -+ video-source = <&tfp410>; -+ i2c-bus = <&i2c3>; -+ }; -+ -+ tv0: connector@1 { -+ compatible = "ti,svideo_connector"; -+ video-source = <&venc>; -+ }; -+}; ---- a/arch/arm/boot/dts/omap3-beagle-xm.dts -+++ b/arch/arm/boot/dts/omap3-beagle-xm.dts -@@ -69,6 +69,23 @@ - }; - - }; -+ -+ /* HS USB Port 2 Power */ -+ hsusb2_power: hsusb2_power_reg { -+ compatible = "regulator-fixed"; -+ regulator-name = "hsusb2_vbus"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ gpio = <&twl_gpio 18 0>; /* GPIO LEDA */ -+ startup-delay-us = <70000>; -+ }; -+ -+ /* HS USB Host PHY on PORT 2 */ -+ hsusb2_phy: hsusb2_phy { -+ compatible = "usb-nop-xceiv"; -+ reset-gpios = <&gpio5 19 GPIO_ACTIVE_LOW>; /* gpio_147 */ -+ vcc-supply = <&hsusb2_power>; -+ }; - }; - - &omap3_pmx_wkup { -@@ -79,6 +96,37 @@ - }; - }; - -+&omap3_pmx_core { -+ pinctrl-names = "default"; -+ pinctrl-0 = < -+ &hsusbb2_pins -+ >; -+ -+ uart3_pins: pinmux_uart3_pins { -+ pinctrl-single,pins = < -+ 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ -+ 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */ -+ >; -+ }; -+ -+ hsusbb2_pins: pinmux_hsusbb2_pins { -+ pinctrl-single,pins = < -+ 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ -+ 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ -+ 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ -+ 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ -+ 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ -+ 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ -+ 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ -+ 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ -+ 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ -+ 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ -+ 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ -+ 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ -+ >; -+ }; -+}; -+ - &i2c1 { - clock-frequency = <2600000>; - -@@ -144,19 +192,12 @@ - &usb_otg_hs { - interface-type = <0>; - usb-phy = <&usb2_phy>; -+ phys = <&usb2_phy>; -+ phy-names = "usb2-phy"; - mode = <3>; - power = <50>; - }; - --&omap3_pmx_core { -- uart3_pins: pinmux_uart3_pins { -- pinctrl-single,pins = < -- 0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ -- 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */ -- >; -- }; --}; -- - &uart3 { - pinctrl-names = "default"; - pinctrl-0 = <&uart3_pins>; -@@ -166,3 +207,11 @@ - pinctrl-names = "default"; - pinctrl-0 = <&gpio1_pins>; - }; -+ -+&usbhshost { -+ port2-mode = "ehci-phy"; -+}; -+ -+&usbhsehci { -+ phys = <0 &hsusb2_phy>; -+}; ---- a/arch/arm/boot/dts/omap3.dtsi -+++ b/arch/arm/boot/dts/omap3.dtsi -@@ -19,6 +19,9 @@ - interrupt-parent = <&intc>; - - aliases { -+ i2c0 = &i2c1; -+ i2c1 = &i2c2; -+ i2c2 = &i2c3; - serial0 = &uart1; - serial1 = &uart2; - serial2 = &uart3; -@@ -32,6 +35,11 @@ - compatible = "arm,cortex-a8"; - device_type = "cpu"; - reg = <0x0>; -+ -+ clocks = <&dpll1_ck>; -+ clock-names = "cpu"; -+ -+ clock-latency = <300000>; /* From omap-cpufreq driver */ - }; - }; - -@@ -80,6 +88,8 @@ - compatible = "ti,omap-counter32k"; - reg = <0x48320000 0x20>; - ti,hwmods = "counter_32k"; -+ clocks = <&wkup_32k_fck>; -+ clock-names = "fck"; - }; - - intc: interrupt-controller@48200000 { -@@ -100,6 +110,8 @@ - #dma-cells = <1>; - #dma-channels = <32>; - #dma-requests = <96>; -+ clocks = <&core_l3_ick>; -+ clock-names = "fck"; - }; - - omap3_pmx_core: pinmux@48002030 { -@@ -125,6 +137,8 @@ - reg = <0x48310000 0x200>; - interrupts = <29>; - ti,hwmods = "gpio1"; -+ clocks = <&gpio1_ick>, <&gpio1_dbck>; -+ clock-names = "fck", "dbclk"; - ti,gpio-always-on; - gpio-controller; - #gpio-cells = <2>; -@@ -137,6 +151,8 @@ - reg = <0x49050000 0x200>; - interrupts = <30>; - ti,hwmods = "gpio2"; -+ clocks = <&gpio2_ick>, <&gpio2_dbck>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -148,6 +164,8 @@ - reg = <0x49052000 0x200>; - interrupts = <31>; - ti,hwmods = "gpio3"; -+ clocks = <&gpio3_ick>, <&gpio3_dbck>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -159,6 +177,8 @@ - reg = <0x49054000 0x200>; - interrupts = <32>; - ti,hwmods = "gpio4"; -+ clocks = <&gpio4_ick>, <&gpio4_dbck>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -170,6 +190,8 @@ - reg = <0x49056000 0x200>; - interrupts = <33>; - ti,hwmods = "gpio5"; -+ clocks = <&gpio5_ick>, <&gpio5_dbck>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -181,6 +203,8 @@ - reg = <0x49058000 0x200>; - interrupts = <34>; - ti,hwmods = "gpio6"; -+ clocks = <&gpio6_ick>, <&gpio6_dbck>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -190,18 +214,24 @@ - uart1: serial@4806a000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart1"; -+ clocks = <&uart1_fck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - - uart2: serial@4806c000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart2"; -+ clocks = <&uart2_fck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - - uart3: serial@49020000 { - compatible = "ti,omap3-uart"; - ti,hwmods = "uart3"; -+ clocks = <&uart3_fck>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - -@@ -210,6 +240,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c1"; -+ clocks = <&i2c1_fck>; -+ clock-names = "fck"; - }; - - i2c2: i2c@48072000 { -@@ -217,6 +249,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c2"; -+ clocks = <&i2c2_fck>; -+ clock-names = "fck"; - }; - - i2c3: i2c@48060000 { -@@ -224,6 +258,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c3"; -+ clocks = <&i2c3_fck>; -+ clock-names = "fck"; - }; - - mcspi1: spi@48098000 { -@@ -231,6 +267,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi1"; -+ clocks = <&mcspi1_fck>; -+ clock-names = "fck"; - ti,spi-num-cs = <4>; - dmas = <&sdma 35>, - <&sdma 36>, -@@ -249,6 +287,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi2"; -+ clocks = <&mcspi2_fck>; -+ clock-names = "fck"; - ti,spi-num-cs = <2>; - dmas = <&sdma 43>, - <&sdma 44>, -@@ -262,6 +302,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi3"; -+ clocks = <&mcspi3_fck>; -+ clock-names = "fck"; - ti,spi-num-cs = <2>; - dmas = <&sdma 15>, - <&sdma 16>, -@@ -275,6 +317,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi4"; -+ clocks = <&mcspi4_fck>; -+ clock-names = "fck"; - ti,spi-num-cs = <1>; - dmas = <&sdma 70>, <&sdma 71>; - dma-names = "tx0", "rx0"; -@@ -283,6 +327,8 @@ - mmc1: mmc@4809c000 { - compatible = "ti,omap3-hsmmc"; - ti,hwmods = "mmc1"; -+ clocks = <&mmchs1_fck>, <&omap_32k_fck>; -+ clock-names = "fck", "dbck"; - ti,dual-volt; - dmas = <&sdma 61>, <&sdma 62>; - dma-names = "tx", "rx"; -@@ -291,6 +337,8 @@ - mmc2: mmc@480b4000 { - compatible = "ti,omap3-hsmmc"; - ti,hwmods = "mmc2"; -+ clocks = <&mmchs2_fck>, <&omap_32k_fck>; -+ clock-names = "fck", "dbck"; - dmas = <&sdma 47>, <&sdma 48>; - dma-names = "tx", "rx"; - }; -@@ -298,6 +346,8 @@ - mmc3: mmc@480ad000 { - compatible = "ti,omap3-hsmmc"; - ti,hwmods = "mmc3"; -+ clocks = <&mmchs3_fck>, <&omap_32k_fck>; -+ clock-names = "fck", "dbck"; - dmas = <&sdma 77>, <&sdma 78>; - dma-names = "tx", "rx"; - }; -@@ -305,6 +355,8 @@ - wdt2: wdt@48314000 { - compatible = "ti,omap3-wdt"; - ti,hwmods = "wd_timer2"; -+ clocks = <&wdt2_fck>; -+ clock-names = "fck"; - }; - - mcbsp1: mcbsp@48074000 { -@@ -317,6 +369,8 @@ - interrupt-names = "common", "tx", "rx"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp1"; -+ clocks = <&mcbsp1_fck>, <&mcbsp_clks>, <&core_96m_fck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 31>, - <&sdma 32>; - dma-names = "tx", "rx"; -@@ -366,6 +420,8 @@ - interrupt-names = "common", "tx", "rx"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp4"; -+ clocks = <&mcbsp4_fck>, <&mcbsp_clks>, <&per_96m_fck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 19>, - <&sdma 20>; - dma-names = "tx", "rx"; -@@ -381,16 +437,31 @@ - interrupt-names = "common", "tx", "rx"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp5"; -+ clocks = <&mcbsp5_fck>, <&mcbsp_clks>, <&core_96m_fck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 21>, - <&sdma 22>; - dma-names = "tx", "rx"; - }; - -+ mailbox: mailbox@48094000 { -+ compatible = "ti,omap2-mailbox"; -+ reg = <0x48094000 0x200>; -+ interrupts = <26>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <2>; -+ ti,mbox-num-fifos = <2>; -+ ti,mbox-names = "dsp"; -+ ti,mbox-data = <0 1 0 0>; -+ }; -+ - timer1: timer@48318000 { - compatible = "ti,omap3430-timer"; - reg = <0x48318000 0x400>; - interrupts = <37>; - ti,hwmods = "timer1"; -+ clocks = <&gpt1_fck>; -+ clock-names = "fck"; - ti,timer-alwon; - }; - -@@ -399,6 +470,8 @@ - reg = <0x49032000 0x400>; - interrupts = <38>; - ti,hwmods = "timer2"; -+ clocks = <&gpt2_fck>; -+ clock-names = "fck"; - }; - - timer3: timer@49034000 { -@@ -406,6 +479,8 @@ - reg = <0x49034000 0x400>; - interrupts = <39>; - ti,hwmods = "timer3"; -+ clocks = <&gpt3_fck>; -+ clock-names = "fck"; - }; - - timer4: timer@49036000 { -@@ -413,6 +488,8 @@ - reg = <0x49036000 0x400>; - interrupts = <40>; - ti,hwmods = "timer4"; -+ clocks = <&gpt4_fck>; -+ clock-names = "fck"; - }; - - timer5: timer@49038000 { -@@ -420,6 +497,8 @@ - reg = <0x49038000 0x400>; - interrupts = <41>; - ti,hwmods = "timer5"; -+ clocks = <&gpt5_fck>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -428,6 +507,8 @@ - reg = <0x4903a000 0x400>; - interrupts = <42>; - ti,hwmods = "timer6"; -+ clocks = <&gpt6_fck>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -436,6 +517,8 @@ - reg = <0x4903c000 0x400>; - interrupts = <43>; - ti,hwmods = "timer7"; -+ clocks = <&gpt7_fck>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -444,6 +527,8 @@ - reg = <0x4903e000 0x400>; - interrupts = <44>; - ti,hwmods = "timer8"; -+ clocks = <&gpt8_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - ti,timer-dsp; - }; -@@ -453,6 +538,8 @@ - reg = <0x49040000 0x400>; - interrupts = <45>; - ti,hwmods = "timer9"; -+ clocks = <&gpt9_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -461,6 +548,8 @@ - reg = <0x48086000 0x400>; - interrupts = <46>; - ti,hwmods = "timer10"; -+ clocks = <&gpt10_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -469,6 +558,8 @@ - reg = <0x48088000 0x400>; - interrupts = <47>; - ti,hwmods = "timer11"; -+ clocks = <&gpt11_fck>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -477,6 +568,8 @@ - reg = <0x48304000 0x400>; - interrupts = <95>; - ti,hwmods = "timer12"; -+ clocks = <&gpt12_fck>; -+ clock-names = "fck"; - ti,timer-alwon; - ti,timer-secure; - }; -@@ -486,12 +579,16 @@ - reg = <0x48062000 0x1000>; - interrupts = <78>; - ti,hwmods = "usb_tll_hs"; -+ clocks = <&usbtll_fck>; -+ clock-names = "fck"; - }; - - usbhshost: usbhshost@48064000 { - compatible = "ti,usbhs-host"; - reg = <0x48064000 0x400>; - ti,hwmods = "usb_host_hs"; -+ clocks = <&usbhost_48m_fck>, <&usbhost_120m_fck>; -+ clock-names = "fck", "ehci_logic_fck"; - #address-cells = <1>; - #size-cells = <1>; - ranges; -@@ -514,6 +611,8 @@ - gpmc: gpmc@6e000000 { - compatible = "ti,omap3430-gpmc"; - ti,hwmods = "gpmc"; -+ clocks = <&gpmc_fck>; -+ clock-names = "fck"; - reg = <0x6e000000 0x02d0>; - interrupts = <20>; - gpmc,num-cs = <8>; -@@ -528,9 +627,61 @@ - interrupts = <92>, <93>; - interrupt-names = "mc", "dma"; - ti,hwmods = "usb_otg_hs"; -+ clocks = <&hsotgusb_ick>; -+ clock-names = "fck"; - multipoint = <1>; - num-eps = <16>; - ram-bits = <12>; - }; -+ -+ dss@48050000 { -+ compatible = "ti,omap3-dss", "simple-bus"; -+ reg = <0x48050000 0x200>; -+ ti,hwmods = "dss_core"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ dispc@48050400 { -+ compatible = "ti,omap3-dispc"; -+ reg = <0x48050400 0x400>; -+ interrupts = <25>; -+ ti,hwmods = "dss_dispc"; -+ }; -+ -+ dpi: encoder@0 { -+ compatible = "ti,omap3-dpi"; -+ }; -+ -+ sdi: encoder@1 { -+ compatible = "ti,omap3-sdi"; -+ }; -+ -+ dsi: encoder@4804fc00 { -+ compatible = "ti,omap3-dsi"; -+ reg = <0x4804fc00 0x400>; -+ interrupts = <25>; -+ ti,hwmods = "dss_dsi1"; -+ }; -+ -+ rfbi: encoder@48050800 { -+ compatible = "ti,omap3-rfbi"; -+ reg = <0x48050800 0x100>; -+ ti,hwmods = "dss_rfbi"; -+ }; -+ -+ venc: encoder@48050c00 { -+ compatible = "ti,omap3-venc"; -+ reg = <0x48050c00 0x100>; -+ ti,hwmods = "dss_venc"; -+ }; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "omap3xxx-clocks.dtsi" - }; - }; ---- a/arch/arm/boot/dts/omap3-evm.dts -+++ b/arch/arm/boot/dts/omap3-evm.dts -@@ -70,6 +70,8 @@ - &usb_otg_hs { - interface-type = <0>; - usb-phy = <&usb2_phy>; -+ phys = <&usb2_phy>; -+ phy-names = "usb2-phy"; - mode = <3>; - power = <50>; - }; ---- a/arch/arm/boot/dts/omap3-overo.dtsi -+++ b/arch/arm/boot/dts/omap3-overo.dtsi -@@ -76,6 +76,8 @@ - &usb_otg_hs { - interface-type = <0>; - usb-phy = <&usb2_phy>; -+ phys = <&usb2_phy>; -+ phy-names = "usb2-phy"; - mode = <3>; - power = <50>; - }; ---- a/arch/arm/boot/dts/omap3-tobi.dts -+++ b/arch/arm/boot/dts/omap3-tobi.dts -@@ -81,3 +81,36 @@ - &mmc3 { - status = "disabled"; - }; -+ -+&dpi { -+ vdds_dsi-supply = <&vpll2>; -+}; -+ -+/ { -+ aliases { -+ display0 = &lcd0; -+ }; -+ -+ lcd0: display@0 { -+ compatible = "samsung,lte430wq-f0c", "panel-dpi"; -+ video-source = <&dpi>; -+ data-lines = <24>; -+ -+ panel-timing { -+ clock-frequency = <9200000>; -+ hactive = <480>; -+ vactive = <272>; -+ hfront-porch = <8>; -+ hback-porch = <4>; -+ hsync-len = <41>; -+ vback-porch = <2>; -+ vfront-porch = <4>; -+ vsync-len = <10>; -+ -+ hsync-active = <0>; -+ vsync-active = <0>; -+ de-active = <1>; -+ pixelclk-active = <1>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/omap3xxx-clocks.dtsi -@@ -0,0 +1,1513 @@ -+/* -+ * Device Tree Source for OMAP3 clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+dummy_apb_pclk: dummy_apb_pclk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0x0>; -+}; -+ -+omap_32k_fck: omap_32k_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+virt_12m_ck: virt_12m_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+virt_13m_ck: virt_13m_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <13000000>; -+}; -+ -+virt_19200000_ck: virt_19200000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <19200000>; -+}; -+ -+virt_26000000_ck: virt_26000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+virt_38_4m_ck: virt_38_4m_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <38400000>; -+}; -+ -+virt_16_8m_ck: virt_16_8m_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <16800000>; -+}; -+ -+osc_sys_ck: osc_sys_ck@48306d40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_12m_ck>, <&virt_13m_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_38_4m_ck>, <&virt_16_8m_ck>; -+ reg = <0x48306d40 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+sys_ck: sys_ck@48307270 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&osc_sys_ck>; -+ bit-shift = <6>; -+ reg = <0x48307270 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+dpll4_ck: dpll4_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-per-clock"; -+ clocks = <&sys_ck>, <&sys_ck>; -+ ti,modes = <0x82>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004d00 0x4>, <0x48004d20 0x4>, <0x48004d30 0x4>, <0x48004d44 0x4>; -+}; -+ -+dpll4_m2_ck: dpll4_m2_ck@48004d48 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll4_ck>; -+ reg = <0x48004d48 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+}; -+ -+dpll4_m2x2_mul_ck: dpll4_m2x2_mul_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m2_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll4_m2x2_ck: dpll4_m2x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m2x2_mul_ck>; -+ bit-shift = <0x1b>; -+ reg = <0x48004d00 0x4>; -+ set-bit-to-disable; -+}; -+ -+omap_96m_alwon_fck: omap_96m_alwon_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll3_ck: dpll3_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-core-clock"; -+ clocks = <&sys_ck>, <&sys_ck>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004d00 0x4>, <0x48004d20 0x4>, <0x48004d30 0x4>, <0x48004d40 0x4>; -+}; -+ -+dpll3_m3_ck: dpll3_m3_ck@48005140 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll3_ck>; -+ bit-shift = <16>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll3_m3x2_mul_ck: dpll3_m3x2_mul_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll3_m3_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll3_m3x2_ck: dpll3_m3x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll3_m3x2_mul_ck>; -+ bit-shift = <0xc>; -+ reg = <0x48004d00 0x4>; -+ set-bit-to-disable; -+}; -+ -+emu_core_alwon_ck: emu_core_alwon_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll3_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sys_altclk: sys_altclk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0x0>; -+}; -+ -+mcbsp_clks: mcbsp_clks { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0x0>; -+}; -+ -+sys_clkout1: sys_clkout1@48306d70 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&osc_sys_ck>; -+ reg = <0x48306d70 0x4>; -+ bit-shift = <7>; -+}; -+ -+dpll3_m2_ck: dpll3_m2_ck@48004d40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll3_ck>; -+ bit-shift = <27>; -+ reg = <0x48004d40 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+core_ck: core_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll3_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll1_fck: dpll1_fck@48004940 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&core_ck>; -+ bit-shift = <19>; -+ reg = <0x48004940 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+dpll1_ck: dpll1_ck@48004904 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-clock"; -+ clocks = <&sys_ck>, <&dpll1_fck>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ reg = <0x48004904 0x4>, <0x48004924 0x4>, <0x48004934 0x4>, <0x48004940 0x4>; -+}; -+ -+dpll1_x2_ck: dpll1_x2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll1_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll1_x2m2_ck: dpll1_x2m2_ck@48004944 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll1_x2_ck>; -+ reg = <0x48004944 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll3_x2_ck: dpll3_x2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll3_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll3_m2x2_ck: dpll3_m2x2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll3_m2_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll4_x2_ck: dpll4_x2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+cm_96m_fck: cm_96m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_alwon_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+omap_96m_fck: omap_96m_fck@48004d40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&cm_96m_fck>, <&sys_ck>; -+ bit-shift = <6>; -+ reg = <0x48004d40 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll4_m3_ck: dpll4_m3_ck@48004e40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll4_ck>; -+ bit-shift = <8>; -+ reg = <0x48004e40 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+}; -+ -+dpll4_m3x2_mul_ck: dpll4_m3x2_mul_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m3_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll4_m3x2_ck: dpll4_m3x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m3x2_mul_ck>; -+ bit-shift = <0x1c>; -+ reg = <0x48004d00 0x4>; -+ set-bit-to-disable; -+}; -+ -+omap_54m_fck: omap_54m_fck@48004d40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll4_m3x2_ck>, <&sys_altclk>; -+ bit-shift = <5>; -+ reg = <0x48004d40 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm_96m_d2_fck: cm_96m_d2_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&cm_96m_fck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+omap_48m_fck: omap_48m_fck@48004d40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&cm_96m_d2_fck>, <&sys_altclk>; -+ bit-shift = <3>; -+ reg = <0x48004d40 0x4>; -+ table = <&cm_96m_d2_fck 0>, <&sys_altclk 1>; -+ bit-mask = <0x1>; -+}; -+ -+omap_12m_fck: omap_12m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_48m_fck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+dpll4_m4_ck: dpll4_m4_ck@48004e40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll4_ck>; -+ reg = <0x48004e40 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+}; -+ -+dpll4_m4x2_mul_ck: dpll4_m4x2_mul_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m4_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll4_m4x2_ck: dpll4_m4x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m4x2_mul_ck>; -+ bit-shift = <0x1d>; -+ reg = <0x48004d00 0x4>; -+ set-bit-to-disable; -+}; -+ -+dpll4_m5_ck: dpll4_m5_ck@48004f40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll4_ck>; -+ reg = <0x48004f40 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+}; -+ -+dpll4_m5x2_mul_ck: dpll4_m5x2_mul_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m5_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll4_m5x2_ck: dpll4_m5x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m5x2_mul_ck>; -+ bit-shift = <0x1e>; -+ reg = <0x48004d00 0x4>; -+ set-bit-to-disable; -+}; -+ -+dpll4_m6_ck: dpll4_m6_ck@48005140 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll4_ck>; -+ bit-shift = <24>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+}; -+ -+dpll4_m6x2_mul_ck: dpll4_m6x2_mul_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m6_ck>; -+ clock-mult = <2>; -+ clock-div = <1>; -+}; -+ -+dpll4_m6x2_ck: dpll4_m6x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll4_m6x2_mul_ck>; -+ bit-shift = <0x1f>; -+ reg = <0x48004d00 0x4>; -+ set-bit-to-disable; -+}; -+ -+emu_per_alwon_ck: emu_per_alwon_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll4_m6x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+clkout2_src_mux_ck: clkout2_src_mux_ck@48004d70 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&core_ck>, <&sys_ck>, <&cm_96m_fck>, <&omap_54m_fck>; -+ reg = <0x48004d70 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+clkout2_src_ck: clkout2_src_ck@48004d70 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&clkout2_src_mux_ck>; -+ bit-shift = <7>; -+ reg = <0x48004d70 0x4>; -+}; -+ -+sys_clkout2: sys_clkout2@48004d70 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&clkout2_src_ck>; -+ bit-shift = <3>; -+ reg = <0x48004d70 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+corex2_fck: corex2_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll3_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mpu_ck: mpu_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll1_x2m2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+arm_fck: arm_fck@48004924 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mpu_ck>; -+ reg = <0x48004924 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+emu_mpu_alwon_ck: emu_mpu_alwon_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&mpu_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l3_ick: l3_ick@48004a40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&core_ck>; -+ reg = <0x48004a40 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+l4_ick: l4_ick@48004a40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&l3_ick>; -+ bit-shift = <2>; -+ reg = <0x48004a40 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+rm_ick: rm_ick@48004c40 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&l4_ick>; -+ bit-shift = <1>; -+ reg = <0x48004c40 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+gpt10_mux_fck: gpt10_mux_fck@48004a40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <6>; -+ reg = <0x48004a40 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt10_fck: gpt10_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt10_mux_fck>; -+ bit-shift = <11>; -+ reg = <0x48004a00 0x4>; -+}; -+ -+gpt11_mux_fck: gpt11_mux_fck@48004a40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <7>; -+ reg = <0x48004a40 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt11_fck: gpt11_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt11_mux_fck>; -+ bit-shift = <12>; -+ reg = <0x48004a00 0x4>; -+}; -+ -+core_96m_fck: core_96m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mmchs2_fck: mmchs2_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <25>; -+}; -+ -+mmchs1_fck: mmchs1_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <24>; -+}; -+ -+i2c3_fck: i2c3_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <17>; -+}; -+ -+i2c2_fck: i2c2_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <16>; -+}; -+ -+i2c1_fck: i2c1_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <15>; -+}; -+ -+mcbsp5_mux_fck: mcbsp5_mux_fck@480022d8 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&core_96m_fck>, <&mcbsp_clks>; -+ bit-shift = <4>; -+ reg = <0x480022d8 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcbsp5_fck: mcbsp5_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&mcbsp5_mux_fck>; -+ bit-shift = <10>; -+ reg = <0x48004a00 0x4>; -+}; -+ -+mcbsp1_mux_fck: mcbsp1_mux_fck@48002274 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&core_96m_fck>, <&mcbsp_clks>; -+ bit-shift = <2>; -+ reg = <0x48002274 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcbsp1_fck: mcbsp1_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&mcbsp1_mux_fck>; -+ bit-shift = <9>; -+ reg = <0x48004a00 0x4>; -+}; -+ -+core_48m_fck: core_48m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_48m_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mcspi4_fck: mcspi4_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <21>; -+}; -+ -+mcspi3_fck: mcspi3_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <20>; -+}; -+ -+mcspi2_fck: mcspi2_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <19>; -+}; -+ -+mcspi1_fck: mcspi1_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <18>; -+}; -+ -+uart2_fck: uart2_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <14>; -+}; -+ -+uart1_fck: uart1_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_48m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <13>; -+}; -+ -+core_12m_fck: core_12m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_12m_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+hdq_fck: hdq_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_12m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <22>; -+}; -+ -+core_l3_ick: core_l3_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l3_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+sdrc_ick: sdrc_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_l3_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <1>; -+}; -+ -+gpmc_fck: gpmc_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&core_l3_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+core_l4_ick: core_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+mmchs2_ick: mmchs2_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <25>; -+}; -+ -+mmchs1_ick: mmchs1_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <24>; -+}; -+ -+hdq_ick: hdq_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <22>; -+}; -+ -+mcspi4_ick: mcspi4_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <21>; -+}; -+ -+mcspi3_ick: mcspi3_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <20>; -+}; -+ -+mcspi2_ick: mcspi2_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <19>; -+}; -+ -+mcspi1_ick: mcspi1_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <18>; -+}; -+ -+i2c3_ick: i2c3_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <17>; -+}; -+ -+i2c2_ick: i2c2_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <16>; -+}; -+ -+i2c1_ick: i2c1_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <15>; -+}; -+ -+uart2_ick: uart2_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <14>; -+}; -+ -+uart1_ick: uart1_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <13>; -+}; -+ -+gpt11_ick: gpt11_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <12>; -+}; -+ -+gpt10_ick: gpt10_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <11>; -+}; -+ -+mcbsp5_ick: mcbsp5_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <10>; -+}; -+ -+mcbsp1_ick: mcbsp1_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <9>; -+}; -+ -+omapctrl_ick: omapctrl_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <6>; -+}; -+ -+dss_tv_fck: dss_tv_fck@48004e00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&omap_54m_fck>; -+ reg = <0x48004e00 0x4>; -+ bit-shift = <2>; -+}; -+ -+dss_96m_fck: dss_96m_fck@48004e00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&omap_96m_fck>; -+ reg = <0x48004e00 0x4>; -+ bit-shift = <2>; -+}; -+ -+dss2_alwon_fck: dss2_alwon_fck@48004e00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_ck>; -+ reg = <0x48004e00 0x4>; -+ bit-shift = <1>; -+}; -+ -+gpt1_mux_fck: gpt1_mux_fck@48004c40 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ reg = <0x48004c40 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt1_fck: gpt1_fck@48004c00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt1_mux_fck>; -+ bit-shift = <0>; -+ reg = <0x48004c00 0x4>; -+}; -+ -+aes2_ick: aes2_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <28>; -+}; -+ -+wkup_32k_fck: wkup_32k_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_32k_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+gpio1_dbck: gpio1_dbck@48004c00 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&wkup_32k_fck>; -+ reg = <0x48004c00 0x4>; -+ bit-shift = <3>; -+}; -+ -+sha12_ick: sha12_ick@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&core_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <27>; -+}; -+ -+wdt2_fck: wdt2_fck@48004c00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&wkup_32k_fck>; -+ reg = <0x48004c00 0x4>; -+ ti,enable-bit = <5>; -+}; -+ -+wkup_l4_ick: wkup_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+wdt2_ick: wdt2_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <5>; -+}; -+ -+wdt1_ick: wdt1_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <4>; -+}; -+ -+gpio1_ick: gpio1_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+omap_32ksync_ick: omap_32ksync_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+gpt12_ick: gpt12_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <1>; -+}; -+ -+gpt1_ick: gpt1_ick@48004c10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&wkup_l4_ick>; -+ reg = <0x48004c10 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+per_96m_fck: per_96m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_96m_alwon_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+per_48m_fck: per_48m_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_48m_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+uart3_fck: uart3_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&per_48m_fck>; -+ reg = <0x48005000 0x4>; -+ ti,enable-bit = <11>; -+}; -+ -+gpt2_mux_fck: gpt2_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt2_fck: gpt2_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt2_mux_fck>; -+ bit-shift = <3>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt3_mux_fck: gpt3_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <1>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt3_fck: gpt3_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt3_mux_fck>; -+ bit-shift = <4>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt4_mux_fck: gpt4_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <2>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt4_fck: gpt4_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt4_mux_fck>; -+ bit-shift = <5>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt5_mux_fck: gpt5_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <3>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt5_fck: gpt5_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt5_mux_fck>; -+ bit-shift = <6>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt6_mux_fck: gpt6_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <4>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt6_fck: gpt6_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt6_mux_fck>; -+ bit-shift = <7>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt7_mux_fck: gpt7_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <5>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt7_fck: gpt7_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt7_mux_fck>; -+ bit-shift = <8>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt8_mux_fck: gpt8_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <6>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt8_fck: gpt8_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt8_mux_fck>; -+ bit-shift = <9>; -+ reg = <0x48005000 0x4>; -+}; -+ -+gpt9_mux_fck: gpt9_mux_fck@48005040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&omap_32k_fck>, <&sys_ck>; -+ bit-shift = <7>; -+ reg = <0x48005040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpt9_fck: gpt9_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&gpt9_mux_fck>; -+ bit-shift = <10>; -+ reg = <0x48005000 0x4>; -+}; -+ -+per_32k_alwon_fck: per_32k_alwon_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&omap_32k_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+gpio6_dbck: gpio6_dbck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&per_32k_alwon_fck>; -+ reg = <0x48005000 0x4>; -+ bit-shift = <17>; -+}; -+ -+gpio5_dbck: gpio5_dbck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&per_32k_alwon_fck>; -+ reg = <0x48005000 0x4>; -+ bit-shift = <16>; -+}; -+ -+gpio4_dbck: gpio4_dbck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&per_32k_alwon_fck>; -+ reg = <0x48005000 0x4>; -+ bit-shift = <15>; -+}; -+ -+gpio3_dbck: gpio3_dbck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&per_32k_alwon_fck>; -+ reg = <0x48005000 0x4>; -+ bit-shift = <14>; -+}; -+ -+gpio2_dbck: gpio2_dbck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&per_32k_alwon_fck>; -+ reg = <0x48005000 0x4>; -+ bit-shift = <13>; -+}; -+ -+wdt3_fck: wdt3_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&per_32k_alwon_fck>; -+ reg = <0x48005000 0x4>; -+ ti,enable-bit = <12>; -+}; -+ -+per_l4_ick: per_l4_ick { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l4_ick>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+gpio6_ick: gpio6_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <17>; -+}; -+ -+gpio5_ick: gpio5_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <16>; -+}; -+ -+gpio4_ick: gpio4_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <15>; -+}; -+ -+gpio3_ick: gpio3_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <14>; -+}; -+ -+gpio2_ick: gpio2_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <13>; -+}; -+ -+wdt3_ick: wdt3_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <12>; -+}; -+ -+uart3_ick: uart3_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <11>; -+}; -+ -+uart4_ick: uart4_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <18>; -+}; -+ -+gpt9_ick: gpt9_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <10>; -+}; -+ -+gpt8_ick: gpt8_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <9>; -+}; -+ -+gpt7_ick: gpt7_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <8>; -+}; -+ -+gpt6_ick: gpt6_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <7>; -+}; -+ -+gpt5_ick: gpt5_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <6>; -+}; -+ -+gpt4_ick: gpt4_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <5>; -+}; -+ -+gpt3_ick: gpt3_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <4>; -+}; -+ -+gpt2_ick: gpt2_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <3>; -+}; -+ -+mcbsp2_ick: mcbsp2_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <0>; -+}; -+ -+mcbsp3_ick: mcbsp3_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <1>; -+}; -+ -+mcbsp4_ick: mcbsp4_ick@48005010 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&per_l4_ick>; -+ reg = <0x48005010 0x4>; -+ ti,enable-bit = <2>; -+}; -+ -+mcbsp2_mux_fck: mcbsp2_mux_fck@48002274 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_96m_fck>, <&mcbsp_clks>; -+ bit-shift = <6>; -+ reg = <0x48002274 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcbsp2_fck: mcbsp2_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&mcbsp2_mux_fck>; -+ bit-shift = <0>; -+ reg = <0x48005000 0x4>; -+}; -+ -+mcbsp3_mux_fck: mcbsp3_mux_fck@480022d8 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_96m_fck>, <&mcbsp_clks>; -+ reg = <0x480022d8 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcbsp3_fck: mcbsp3_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&mcbsp3_mux_fck>; -+ bit-shift = <1>; -+ reg = <0x48005000 0x4>; -+}; -+ -+mcbsp4_mux_fck: mcbsp4_mux_fck@480022d8 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&per_96m_fck>, <&mcbsp_clks>; -+ bit-shift = <2>; -+ reg = <0x480022d8 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcbsp4_fck: mcbsp4_fck@48005000 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&mcbsp4_mux_fck>; -+ bit-shift = <2>; -+ reg = <0x48005000 0x4>; -+}; -+ -+emu_src_mux_ck: emu_src_mux_ck@48005140 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_ck>, <&emu_core_alwon_ck>, <&emu_per_alwon_ck>, <&emu_mpu_alwon_ck>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+emu_src_ck: emu_src_ck { -+ #clock-cells = <0>; -+ compatible = "ti,clkdm-gate-clock"; -+ clocks = <&emu_src_mux_ck>; -+}; -+ -+pclk_fck: pclk_fck@48005140 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&emu_src_ck>; -+ bit-shift = <8>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+pclkx2_fck: pclkx2_fck@48005140 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&emu_src_ck>; -+ bit-shift = <6>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+atclk_fck: atclk_fck@48005140 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&emu_src_ck>; -+ bit-shift = <4>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x3>; -+ index-starts-at-one; -+}; -+ -+traceclk_src_fck: traceclk_src_fck@48005140 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_ck>, <&emu_core_alwon_ck>, <&emu_per_alwon_ck>, <&emu_mpu_alwon_ck>; -+ bit-shift = <2>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+traceclk_fck: traceclk_fck@48005140 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&traceclk_src_fck>; -+ bit-shift = <11>; -+ reg = <0x48005140 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+secure_32k_fck: secure_32k_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+gpt12_fck: gpt12_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&secure_32k_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+wdt1_fck: wdt1_fck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&secure_32k_fck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/omap443x-clocks.dtsi -@@ -0,0 +1,17 @@ -+/* -+ * Device Tree Source for OMAP443x clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+bandgap_fclk: bandgap_fclk@4a307888 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a307888 0x4>; -+}; ---- a/arch/arm/boot/dts/omap443x.dtsi -+++ b/arch/arm/boot/dts/omap443x.dtsi -@@ -30,4 +30,24 @@ - 0x4a00232C 0x4>; - compatible = "ti,omap4430-bandgap"; - }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "omap44xx-clocks.dtsi" -+ /include/ "omap443x-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ l3_init_clkdm: l3_init_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll_usb_ck>; -+ }; -+ -+ emu_sys_clkdm: emu_sys_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&trace_clk_div_ck>; -+ }; -+ }; - }; ---- a/arch/arm/boot/dts/omap4460.dtsi -+++ b/arch/arm/boot/dts/omap4460.dtsi -@@ -38,4 +38,24 @@ - interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */ - gpios = <&gpio3 22 0>; /* tshut */ - }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "omap44xx-clocks.dtsi" -+ /include/ "omap446x-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ l3_init_clkdm: l3_init_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll_usb_ck>; -+ }; -+ -+ emu_sys_clkdm: emu_sys_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&trace_clk_div_ck>; -+ }; -+ }; - }; ---- /dev/null -+++ b/arch/arm/boot/dts/omap446x-clocks.dtsi -@@ -0,0 +1,27 @@ -+/* -+ * Device Tree Source for OMAP446x clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+div_ts_ck: div_ts_ck@4a307888 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&l4_wkup_clk_mux_ck>; -+ bit-shift = <24>; -+ reg = <0x4a307888 0x4>; -+ table = < 8 0 >, < 16 1 >, < 32 2 >; -+ bit-mask = <0x3>; -+}; -+ -+bandgap_ts_fclk: bandgap_ts_fclk@4a307888 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&div_ts_ck>; -+ bit-shift = <8>; -+ reg = <0x4a307888 0x4>; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/omap44xx-clocks.dtsi -@@ -0,0 +1,1639 @@ -+/* -+ * Device Tree Source for OMAP4 clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+extalt_clkin_ck: extalt_clkin_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <59000000>; -+}; -+ -+pad_clks_src_ck: pad_clks_src_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+pad_clks_ck: pad_clks_ck@4a004108 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&pad_clks_src_ck>; -+ bit-shift = <8>; -+ reg = <0x4a004108 0x4>; -+}; -+ -+pad_slimbus_core_clks_ck: pad_slimbus_core_clks_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+secure_32k_clk_src_ck: secure_32k_clk_src_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+slimbus_src_clk: slimbus_src_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+slimbus_clk: slimbus_clk@4a004108 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&slimbus_src_clk>; -+ bit-shift = <10>; -+ reg = <0x4a004108 0x4>; -+}; -+ -+sys_32k_ck: sys_32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+virt_12000000_ck: virt_12000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+virt_13000000_ck: virt_13000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <13000000>; -+}; -+ -+virt_16800000_ck: virt_16800000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <16800000>; -+}; -+ -+virt_19200000_ck: virt_19200000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <19200000>; -+}; -+ -+virt_26000000_ck: virt_26000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+virt_27000000_ck: virt_27000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <27000000>; -+}; -+ -+virt_38400000_ck: virt_38400000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <38400000>; -+}; -+ -+sys_clkin_ck: sys_clkin_ck@4a306110 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_12000000_ck>, <&virt_13000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>; -+ reg = <0x4a306110 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+tie_low_clock_ck: tie_low_clock_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <0>; -+}; -+ -+utmi_phy_clkout_ck: utmi_phy_clkout_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <60000000>; -+}; -+ -+xclk60mhsp1_ck: xclk60mhsp1_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <60000000>; -+}; -+ -+xclk60mhsp2_ck: xclk60mhsp2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <60000000>; -+}; -+ -+xclk60motg_ck: xclk60motg_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <60000000>; -+}; -+ -+abe_dpll_bypass_clk_mux_ck: abe_dpll_bypass_clk_mux_ck@4a306108 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a306108 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+abe_dpll_refclk_mux_ck: abe_dpll_refclk_mux_ck@4a30610c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ reg = <0x4a30610c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_abe_ck: dpll_abe_ck@4a0041e0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-m4xen-clock"; -+ clocks = <&abe_dpll_refclk_mux_ck>, <&abe_dpll_bypass_clk_mux_ck>; -+ reg = <0x4a0041e0 0x4>, <0x4a0041e4 0x4>, <0x4a0041e8 0x4>, <0x4a0041ec 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_abe_x2_ck: dpll_abe_x2_ck@4a0041f0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_abe_ck>; -+ reg = <0x4a0041f0 0x4>; -+}; -+ -+dpll_abe_m2x2_ck: dpll_abe_m2x2_ck@4a0041f0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041f0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+abe_24m_fclk: abe_24m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+abe_clk: abe_clk@4a004108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ reg = <0x4a004108 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+aess_fclk: aess_fclk@4a004528 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&abe_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004528 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_abe_m3x2_ck: dpll_abe_m3x2_ck@4a0041f4 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041f4 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+core_hsd_byp_clk_mux_ck: core_hsd_byp_clk_mux_ck@4a00412c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_abe_m3x2_ck>; -+ bit-shift = <23>; -+ reg = <0x4a00412c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_core_ck: dpll_core_ck@4a004120 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-core-clock"; -+ clocks = <&sys_clkin_ck>, <&core_hsd_byp_clk_mux_ck>; -+ reg = <0x4a004120 0x4>, <0x4a004124 0x4>, <0x4a004128 0x4>, <0x4a00412c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_core_x2_ck: dpll_core_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_core_ck>; -+}; -+ -+dpll_core_m6x2_ck: dpll_core_m6x2_ck@4a004140 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004140 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dbgclk_mux_ck: dbgclk_mux_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_core_m2_ck: dpll_core_m2_ck@4a004130 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004130 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+ddrphy_ck: ddrphy_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_core_m5x2_ck: dpll_core_m5x2_ck@4a00413c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00413c 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+div_core_ck: div_core_ck@4a004100 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_m5x2_ck>; -+ reg = <0x4a004100 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+div_iva_hs_clk: div_iva_hs_clk@4a0041dc { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_m5x2_ck>; -+ reg = <0x4a0041dc 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+div_mpu_hs_clk: div_mpu_hs_clk@4a00419c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_m5x2_ck>; -+ reg = <0x4a00419c 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+dpll_core_m4x2_ck: dpll_core_m4x2_ck@4a004138 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004138 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dll_clk_div_ck: dll_clk_div_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_m4x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_abe_m2_ck: dpll_abe_m2_ck@4a0041f0 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_ck>; -+ reg = <0x4a0041f0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_core_m3x2_div_ck: dpll_core_m3x2_div_ck@4a004134 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ reg = <0x4a004134 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_core_m3x2_ck: dpll_core_m3x2_ck@4a004134 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_core_m3x2_div_ck>; -+ bit-shift = <8>; -+ reg = <0x4a004134 0x4>; -+}; -+ -+dpll_core_m7x2_ck: dpll_core_m7x2_ck@4a004144 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004144 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+iva_hsd_byp_clk_mux_ck: iva_hsd_byp_clk_mux_ck@4a0041ac { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&div_iva_hs_clk>; -+ bit-shift = <23>; -+ reg = <0x4a0041ac 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_iva_ck: dpll_iva_ck@4a0041a0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&iva_hsd_byp_clk_mux_ck>; -+ reg = <0x4a0041a0 0x4>, <0x4a0041a4 0x4>, <0x4a0041a8 0x4>, <0x4a0041ac 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_iva_x2_ck: dpll_iva_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_iva_ck>; -+}; -+ -+dpll_iva_m4x2_ck: dpll_iva_m4x2_ck@4a0041b8 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_iva_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041b8 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_iva_m5x2_ck: dpll_iva_m5x2_ck@4a0041bc { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_iva_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041bc 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_mpu_ck: dpll_mpu_ck@4a004160 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&div_mpu_hs_clk>; -+ reg = <0x4a004160 0x4>, <0x4a004164 0x4>, <0x4a004168 0x4>, <0x4a00416c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_mpu_m2_ck: dpll_mpu_m2_ck@4a004170 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_mpu_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004170 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+per_hs_clk_div_ck: per_hs_clk_div_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+per_hsd_byp_clk_mux_ck: per_hsd_byp_clk_mux_ck@4a00814c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&per_hs_clk_div_ck>; -+ bit-shift = <23>; -+ reg = <0x4a00814c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_per_ck: dpll_per_ck@4a008140 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin_ck>, <&per_hsd_byp_clk_mux_ck>; -+ reg = <0x4a008140 0x4>, <0x4a008144 0x4>, <0x4a008148 0x4>, <0x4a00814c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_per_m2_ck: dpll_per_m2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_ck>; -+ reg = <0x4a008150 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_per_x2_ck: dpll_per_x2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_per_ck>; -+ reg = <0x4a008150 0x4>; -+}; -+ -+dpll_per_m2x2_ck: dpll_per_m2x2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008150 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m3x2_div_ck: dpll_per_m3x2_div_ck@4a008154 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ reg = <0x4a008154 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+}; -+ -+dpll_per_m3x2_ck: dpll_per_m3x2_ck@4a008154 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_m3x2_div_ck>; -+ bit-shift = <8>; -+ reg = <0x4a008154 0x4>; -+}; -+ -+dpll_per_m4x2_ck: dpll_per_m4x2_ck@4a008158 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008158 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m5x2_ck: dpll_per_m5x2_ck@4a00815c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00815c 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m6x2_ck: dpll_per_m6x2_ck@4a008160 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008160 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m7x2_ck: dpll_per_m7x2_ck@4a008164 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008164 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+usb_hs_clk_div_ck: usb_hs_clk_div_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <3>; -+}; -+ -+dpll_usb_ck: dpll_usb_ck@4a008180 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-j-type-clock"; -+ clocks = <&sys_clkin_ck>, <&usb_hs_clk_div_ck>; -+ reg = <0x4a008180 0x4>, <0x4a008184 0x4>, <0x4a008188 0x4>, <0x4a00818c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_usb_clkdcoldo_ck: dpll_usb_clkdcoldo_ck@4a0081b4 { -+ #clock-cells = <0>; -+ compatible = "ti,fixed-factor-clock"; -+ clocks = <&dpll_usb_ck>; -+ ti,autoidle-shift = <8>; -+ clock-div = <1>; -+ reg = <0x4a0081b4 0x4>; -+ clock-mult = <1>; -+ ti,autoidle-low; -+}; -+ -+dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_usb_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008190 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+ducati_clk_mux_ck: ducati_clk_mux_ck@4a008100 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&div_core_ck>, <&dpll_per_m6x2_ck>; -+ reg = <0x4a008100 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_12m_fclk: func_12m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+func_24m_clk: func_24m_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+func_24mc_fclk: func_24mc_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+func_48m_fclk: func_48m_fclk@4a008108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ reg = <0x4a008108 0x4>; -+ table = < 4 0 >, < 8 1 >; -+ bit-mask = <0x1>; -+}; -+ -+func_48mc_fclk: func_48mc_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+func_64m_fclk: func_64m_fclk@4a008108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m4x2_ck>; -+ reg = <0x4a008108 0x4>; -+ table = < 2 0 >, < 4 1 >; -+ bit-mask = <0x1>; -+}; -+ -+func_96m_fclk: func_96m_fclk@4a008108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ reg = <0x4a008108 0x4>; -+ table = < 2 0 >, < 4 1 >; -+ bit-mask = <0x1>; -+}; -+ -+init_60m_fclk: init_60m_fclk@4a008104 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ reg = <0x4a008104 0x4>; -+ table = < 1 0 >, < 8 1 >; -+ bit-mask = <0x1>; -+}; -+ -+l3_div_ck: l3_div_ck@4a004100 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&div_core_ck>; -+ bit-shift = <4>; -+ reg = <0x4a004100 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+l4_div_ck: l4_div_ck@4a004100 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&l3_div_ck>; -+ bit-shift = <8>; -+ reg = <0x4a004100 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+lp_clk_div_ck: lp_clk_div_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+l4_wkup_clk_mux_ck: l4_wkup_clk_mux_ck@4a306108 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&lp_clk_div_ck>; -+ reg = <0x4a306108 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mpu_periphclk: mpu_periphclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_mpu_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+ocp_abe_iclk: ocp_abe_iclk@4a004528 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&aess_fclk>; -+ bit-shift = <24>; -+ reg = <0x4a004528 0x4>; -+ table = < 2 0 >, < 1 1 >; -+ bit-mask = <0x1>; -+}; -+ -+per_abe_24m_fclk: per_abe_24m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+per_abe_nc_fclk: per_abe_nc_fclk@4a008108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2_ck>; -+ reg = <0x4a008108 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+syc_clk_div_ck: syc_clk_div_ck@4a306100 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&sys_clkin_ck>; -+ reg = <0x4a306100 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+aes1_fck: aes1_fck@4a0095a0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3_div_ck>; -+ bit-shift = <1>; -+ reg = <0x4a0095a0 0x4>; -+}; -+ -+aes2_fck: aes2_fck@4a0095a8 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3_div_ck>; -+ bit-shift = <1>; -+ reg = <0x4a0095a8 0x4>; -+}; -+ -+dmic_sync_mux_ck: dmic_sync_mux_ck@4a004538 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>; -+ bit-shift = <25>; -+ reg = <0x4a004538 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_dmic_abe_gfclk: func_dmic_abe_gfclk@4a004538 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dmic_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004538 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+dss_sys_clk: dss_sys_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&syc_clk_div_ck>; -+ bit-shift = <10>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_tv_clk: dss_tv_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&extalt_clkin_ck>; -+ bit-shift = <11>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_dss_clk: dss_dss_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_m5x2_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_48mhz_clk: dss_48mhz_clk@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_48mc_fclk>; -+ bit-shift = <9>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+dss_fck: dss_fck@4a009120 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3_div_ck>; -+ bit-shift = <1>; -+ reg = <0x4a009120 0x4>; -+}; -+ -+fdif_fck: fdif_fck@4a009028 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m4x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009028 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+gpio1_dbclk: gpio1_dbclk@4a307838 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a307838 0x4>; -+}; -+ -+gpio2_dbclk: gpio2_dbclk@4a009460 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009460 0x4>; -+}; -+ -+gpio3_dbclk: gpio3_dbclk@4a009468 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009468 0x4>; -+}; -+ -+gpio4_dbclk: gpio4_dbclk@4a009470 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009470 0x4>; -+}; -+ -+gpio5_dbclk: gpio5_dbclk@4a009478 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009478 0x4>; -+}; -+ -+gpio6_dbclk: gpio6_dbclk@4a009480 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009480 0x4>; -+}; -+ -+sgx_clk_mux: sgx_clk_mux@4a009220 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_m7x2_ck>, <&dpll_per_m7x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009220 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+hsi_fck: hsi_fck@4a009338 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009338 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+iss_ctrlclk: iss_ctrlclk@4a009020 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_96m_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a009020 0x4>; -+}; -+ -+mcasp_sync_mux_ck: mcasp_sync_mux_ck@4a004540 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>; -+ bit-shift = <25>; -+ reg = <0x4a004540 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_mcasp_abe_gfclk: func_mcasp_abe_gfclk@4a004540 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcasp_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004540 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp1_sync_mux_ck: mcbsp1_sync_mux_ck@4a004548 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>; -+ bit-shift = <25>; -+ reg = <0x4a004548 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_mcbsp1_gfclk: func_mcbsp1_gfclk@4a004548 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp1_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004548 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp2_sync_mux_ck: mcbsp2_sync_mux_ck@4a004550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>; -+ bit-shift = <25>; -+ reg = <0x4a004550 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_mcbsp2_gfclk: func_mcbsp2_gfclk@4a004550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp2_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004550 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp3_sync_mux_ck: mcbsp3_sync_mux_ck@4a004558 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&syc_clk_div_ck>, <&func_24m_clk>; -+ bit-shift = <25>; -+ reg = <0x4a004558 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+func_mcbsp3_gfclk: func_mcbsp3_gfclk@4a004558 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp3_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004558 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp4_sync_mux_ck: mcbsp4_sync_mux_ck@4a0094e0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_96m_fclk>, <&per_abe_nc_fclk>; -+ bit-shift = <25>; -+ reg = <0x4a0094e0 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+per_mcbsp4_gfclk: per_mcbsp4_gfclk@4a0094e0 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp4_sync_mux_ck>, <&pad_clks_ck>; -+ bit-shift = <24>; -+ reg = <0x4a0094e0 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+hsmmc1_fclk: hsmmc1_fclk@4a009328 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_64m_fclk>, <&func_96m_fclk>; -+ bit-shift = <24>; -+ reg = <0x4a009328 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+hsmmc2_fclk: hsmmc2_fclk@4a009330 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_64m_fclk>, <&func_96m_fclk>; -+ bit-shift = <24>; -+ reg = <0x4a009330 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+ocp2scp_usb_phy_phy_48m: ocp2scp_usb_phy_phy_48m@4a0093e0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_48m_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a0093e0 0x4>; -+}; -+ -+sha2md5_fck: sha2md5_fck@4a0095c8 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3_div_ck>; -+ bit-shift = <1>; -+ reg = <0x4a0095c8 0x4>; -+}; -+ -+slimbus1_fclk_1: slimbus1_fclk_1@4a004560 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_24m_clk>; -+ bit-shift = <9>; -+ reg = <0x4a004560 0x4>; -+}; -+ -+slimbus1_fclk_0: slimbus1_fclk_0@4a004560 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&abe_24m_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a004560 0x4>; -+}; -+ -+slimbus1_fclk_2: slimbus1_fclk_2@4a004560 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&pad_clks_ck>; -+ bit-shift = <10>; -+ reg = <0x4a004560 0x4>; -+}; -+ -+slimbus1_slimbus_clk: slimbus1_slimbus_clk@4a004560 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&slimbus_clk>; -+ bit-shift = <11>; -+ reg = <0x4a004560 0x4>; -+}; -+ -+slimbus2_fclk_1: slimbus2_fclk_1@4a009538 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&per_abe_24m_fclk>; -+ bit-shift = <9>; -+ reg = <0x4a009538 0x4>; -+}; -+ -+slimbus2_fclk_0: slimbus2_fclk_0@4a009538 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_24mc_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a009538 0x4>; -+}; -+ -+slimbus2_slimbus_clk: slimbus2_slimbus_clk@4a009538 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&pad_slimbus_core_clks_ck>; -+ bit-shift = <10>; -+ reg = <0x4a009538 0x4>; -+}; -+ -+smartreflex_core_fck: smartreflex_core_fck@4a008638 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l4_wkup_clk_mux_ck>; -+ bit-shift = <1>; -+ reg = <0x4a008638 0x4>; -+}; -+ -+smartreflex_iva_fck: smartreflex_iva_fck@4a008630 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l4_wkup_clk_mux_ck>; -+ bit-shift = <1>; -+ reg = <0x4a008630 0x4>; -+}; -+ -+smartreflex_mpu_fck: smartreflex_mpu_fck@4a008628 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l4_wkup_clk_mux_ck>; -+ bit-shift = <1>; -+ reg = <0x4a008628 0x4>; -+}; -+ -+dmt1_clk_mux: dmt1_clk_mux@4a307840 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a307840 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm2_dm10_mux: cm2_dm10_mux@4a009428 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009428 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm2_dm11_mux: cm2_dm11_mux@4a009430 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009430 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm2_dm2_mux: cm2_dm2_mux@4a009438 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009438 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm2_dm3_mux: cm2_dm3_mux@4a009440 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009440 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm2_dm4_mux: cm2_dm4_mux@4a009448 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009448 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer5_sync_mux: timer5_sync_mux@4a004568 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004568 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer6_sync_mux: timer6_sync_mux@4a004570 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004570 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer7_sync_mux: timer7_sync_mux@4a004578 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004578 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer8_sync_mux: timer8_sync_mux@4a004580 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&syc_clk_div_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004580 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+cm2_dm9_mux: cm2_dm9_mux@4a009450 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009450 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_host_fs_fck: usb_host_fs_fck@4a0093d0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_48mc_fclk>; -+ reg = <0x4a0093d0 0x4>; -+ bit-shift = <1>; -+}; -+ -+utmi_p1_gfclk: utmi_p1_gfclk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&init_60m_fclk>, <&xclk60mhsp1_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009358 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_host_hs_utmi_p1_clk: usb_host_hs_utmi_p1_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&utmi_p1_gfclk>; -+ bit-shift = <8>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+utmi_p2_gfclk: utmi_p2_gfclk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&init_60m_fclk>, <&xclk60mhsp2_ck>; -+ bit-shift = <25>; -+ reg = <0x4a009358 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_host_hs_utmi_p2_clk: usb_host_hs_utmi_p2_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&utmi_p2_gfclk>; -+ bit-shift = <9>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_utmi_p3_clk: usb_host_hs_utmi_p3_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <10>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_hsic480m_p1_clk: usb_host_hs_hsic480m_p1_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ bit-shift = <13>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_hsic60m_p1_clk: usb_host_hs_hsic60m_p1_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <11>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_hsic60m_p2_clk: usb_host_hs_hsic60m_p2_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <12>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_hsic480m_p2_clk: usb_host_hs_hsic480m_p2_clk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ bit-shift = <14>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_func48mclk: usb_host_hs_func48mclk@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_48mc_fclk>; -+ bit-shift = <15>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+usb_host_hs_fck: usb_host_hs_fck@4a009358 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <1>; -+ reg = <0x4a009358 0x4>; -+}; -+ -+otg_60m_gfclk: otg_60m_gfclk@4a009360 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&utmi_phy_clkout_ck>, <&xclk60motg_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009360 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_otg_hs_xclk: usb_otg_hs_xclk@4a009360 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&otg_60m_gfclk>; -+ bit-shift = <8>; -+ reg = <0x4a009360 0x4>; -+}; -+ -+usb_otg_hs_ick: usb_otg_hs_ick@4a009360 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3_div_ck>; -+ bit-shift = <0>; -+ reg = <0x4a009360 0x4>; -+}; -+ -+usb_phy_cm_clk32k: usb_phy_cm_clk32k@4a008640 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a008640 0x4>; -+}; -+ -+usb_tll_hs_usb_ch2_clk: usb_tll_hs_usb_ch2_clk@4a009368 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <10>; -+ reg = <0x4a009368 0x4>; -+}; -+ -+usb_tll_hs_usb_ch0_clk: usb_tll_hs_usb_ch0_clk@4a009368 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a009368 0x4>; -+}; -+ -+usb_tll_hs_usb_ch1_clk: usb_tll_hs_usb_ch1_clk@4a009368 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&init_60m_fclk>; -+ bit-shift = <9>; -+ reg = <0x4a009368 0x4>; -+}; -+ -+usb_tll_hs_ick: usb_tll_hs_ick@4a009368 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l4_div_ck>; -+ bit-shift = <0>; -+ reg = <0x4a009368 0x4>; -+}; -+ -+usim_ck: usim_ck@4a307858 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m4x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a307858 0x4>; -+ table = < 14 0 >, < 18 1 >; -+ bit-mask = <0x1>; -+}; -+ -+usim_fclk: usim_fclk@4a307858 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&usim_ck>; -+ bit-shift = <8>; -+ reg = <0x4a307858 0x4>; -+}; -+ -+pmd_stm_clock_mux_ck: pmd_stm_clock_mux_ck@4a307a20 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m6x2_ck>, <&tie_low_clock_ck>; -+ bit-shift = <20>; -+ reg = <0x4a307a20 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+pmd_trace_clk_mux_ck: pmd_trace_clk_mux_ck@4a307a20 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m6x2_ck>, <&tie_low_clock_ck>; -+ bit-shift = <22>; -+ reg = <0x4a307a20 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+stm_clk_div_ck: stm_clk_div_ck@4a307a20 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&pmd_stm_clock_mux_ck>; -+ bit-shift = <27>; -+ reg = <0x4a307a20 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+trace_clk_div_div_ck: trace_clk_div_div_ck@4a307a20 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ bit-shift = <24>; -+ reg = <0x4a307a20 0x4>; -+ bit-mask = <0x7>; -+ index-power-of-two; -+}; -+ -+trace_clk_div_ck: trace_clk_div_ck { -+ #clock-cells = <0>; -+ compatible = "ti,clkdm-gate-clock"; -+ clocks = <&trace_clk_div_div_ck>; -+}; -+ -+auxclk0_src_mux_ck: auxclk0_src_mux_ck@4a30a310 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4a30a310 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk0_src_ck: auxclk0_src_ck@4a30a310 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk0_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4a30a310 0x4>; -+}; -+ -+auxclk0_ck: auxclk0_ck@4a30a310 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk0_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4a30a310 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk1_src_mux_ck: auxclk1_src_mux_ck@4a30a314 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4a30a314 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk1_src_ck: auxclk1_src_ck@4a30a314 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk1_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4a30a314 0x4>; -+}; -+ -+auxclk1_ck: auxclk1_ck@4a30a314 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk1_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4a30a314 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk2_src_mux_ck: auxclk2_src_mux_ck@4a30a318 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4a30a318 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk2_src_ck: auxclk2_src_ck@4a30a318 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk2_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4a30a318 0x4>; -+}; -+ -+auxclk2_ck: auxclk2_ck@4a30a318 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk2_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4a30a318 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk3_src_mux_ck: auxclk3_src_mux_ck@4a30a31c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4a30a31c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk3_src_ck: auxclk3_src_ck@4a30a31c { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk3_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4a30a31c 0x4>; -+}; -+ -+auxclk3_ck: auxclk3_ck@4a30a31c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk3_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4a30a31c 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk4_src_mux_ck: auxclk4_src_mux_ck@4a30a320 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4a30a320 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk4_src_ck: auxclk4_src_ck@4a30a320 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk4_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4a30a320 0x4>; -+}; -+ -+auxclk4_ck: auxclk4_ck@4a30a320 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk4_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4a30a320 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk5_src_mux_ck: auxclk5_src_mux_ck@4a30a324 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin_ck>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4a30a324 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk5_src_ck: auxclk5_src_ck@4a30a324 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk5_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4a30a324 0x4>; -+}; -+ -+auxclk5_ck: auxclk5_ck@4a30a324 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk5_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4a30a324 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclkreq0_ck: auxclkreq0_ck@4a30a210 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>; -+ bit-shift = <2>; -+ reg = <0x4a30a210 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq1_ck: auxclkreq1_ck@4a30a214 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>; -+ bit-shift = <2>; -+ reg = <0x4a30a214 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq2_ck: auxclkreq2_ck@4a30a218 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>; -+ bit-shift = <2>; -+ reg = <0x4a30a218 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq3_ck: auxclkreq3_ck@4a30a21c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>; -+ bit-shift = <2>; -+ reg = <0x4a30a21c 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq4_ck: auxclkreq4_ck@4a30a220 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>; -+ bit-shift = <2>; -+ reg = <0x4a30a220 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq5_ck: auxclkreq5_ck@4a30a224 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>, <&auxclk5_ck>; -+ bit-shift = <2>; -+ reg = <0x4a30a224 0x4>; -+ bit-mask = <0x7>; -+}; ---- a/arch/arm/boot/dts/omap4.dtsi -+++ b/arch/arm/boot/dts/omap4.dtsi -@@ -17,6 +17,10 @@ - interrupt-parent = <&gic>; - - aliases { -+ i2c0 = &i2c1; -+ i2c1 = &i2c2; -+ i2c2 = &i2c3; -+ i2c3 = &i2c4; - serial0 = &uart1; - serial1 = &uart2; - serial2 = &uart3; -@@ -32,6 +36,11 @@ - device_type = "cpu"; - next-level-cache = <&L2>; - reg = <0x0>; -+ -+ clocks = <&dpll_mpu_ck>; -+ clock-names = "cpu"; -+ -+ clock-latency = <300000>; /* From omap-cpufreq driver */ - }; - cpu@1 { - compatible = "arm,cortex-a9"; -@@ -107,6 +116,8 @@ - compatible = "ti,omap-counter32k"; - reg = <0x4a304000 0x20>; - ti,hwmods = "counter_32k"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; - }; - - omap4_pmx_core: pinmux@4a100040 { -@@ -136,6 +147,8 @@ - #dma-cells = <1>; - #dma-channels = <32>; - #dma-requests = <127>; -+ clocks = <&l3_div_ck>; -+ clock-names = "fck"; - }; - - gpio1: gpio@4a310000 { -@@ -143,6 +156,8 @@ - reg = <0x4a310000 0x200>; - interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio1"; -+ clocks = <&l4_wkup_clk_mux_ck>, <&gpio1_dbclk>; -+ clock-names = "fck", "dbclk"; - ti,gpio-always-on; - gpio-controller; - #gpio-cells = <2>; -@@ -155,6 +170,8 @@ - reg = <0x48055000 0x200>; - interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio2"; -+ clocks = <&l4_div_ck>, <&gpio2_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -166,6 +183,8 @@ - reg = <0x48057000 0x200>; - interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio3"; -+ clocks = <&l4_div_ck>, <&gpio3_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -177,6 +196,8 @@ - reg = <0x48059000 0x200>; - interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio4"; -+ clocks = <&l4_div_ck>, <&gpio4_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -188,6 +209,8 @@ - reg = <0x4805b000 0x200>; - interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio5"; -+ clocks = <&l4_div_ck>, <&gpio5_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -199,6 +222,8 @@ - reg = <0x4805d000 0x200>; - interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio6"; -+ clocks = <&l4_div_ck>, <&gpio6_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -214,6 +239,7 @@ - gpmc,num-cs = <8>; - gpmc,num-waitpins = <4>; - ti,hwmods = "gpmc"; -+ ti,no-idle; - }; - - uart1: serial@4806a000 { -@@ -221,6 +247,8 @@ - reg = <0x4806a000 0x100>; - interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart1"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - -@@ -229,6 +257,8 @@ - reg = <0x4806c000 0x100>; - interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart2"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - -@@ -237,6 +267,8 @@ - reg = <0x48020000 0x100>; - interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - -@@ -245,6 +277,8 @@ - reg = <0x4806e000 0x100>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; - }; - -@@ -255,6 +289,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c1"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; - }; - - i2c2: i2c@48072000 { -@@ -264,6 +300,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c2"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; - }; - - i2c3: i2c@48060000 { -@@ -273,6 +311,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c3"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; - }; - - i2c4: i2c@48350000 { -@@ -282,6 +322,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c4"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; - }; - - mcspi1: spi@48098000 { -@@ -291,6 +333,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi1"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <4>; - dmas = <&sdma 35>, - <&sdma 36>, -@@ -311,6 +355,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi2"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <2>; - dmas = <&sdma 43>, - <&sdma 44>, -@@ -326,6 +372,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <2>; - dmas = <&sdma 15>, <&sdma 16>; - dma-names = "tx0", "rx0"; -@@ -338,6 +386,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <1>; - dmas = <&sdma 70>, <&sdma 71>; - dma-names = "tx0", "rx0"; -@@ -348,6 +398,8 @@ - reg = <0x4809c000 0x400>; - interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc1"; -+ clocks = <&hsmmc1_fclk>; -+ clock-names = "fck"; - ti,dual-volt; - ti,needs-special-reset; - dmas = <&sdma 61>, <&sdma 62>; -@@ -359,6 +411,8 @@ - reg = <0x480b4000 0x400>; - interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc2"; -+ clocks = <&hsmmc2_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 47>, <&sdma 48>; - dma-names = "tx", "rx"; -@@ -369,6 +423,8 @@ - reg = <0x480ad000 0x400>; - interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 77>, <&sdma 78>; - dma-names = "tx", "rx"; -@@ -379,6 +435,8 @@ - reg = <0x480d1000 0x400>; - interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 57>, <&sdma 58>; - dma-names = "tx", "rx"; -@@ -389,16 +447,20 @@ - reg = <0x480d5000 0x400>; - interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc5"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 59>, <&sdma 60>; - dma-names = "tx", "rx"; - }; - - wdt2: wdt@4a314000 { -- compatible = "ti,omap4-wdt", "ti,omap3-wdt"; -+ compatible = "ti,omap4-wdt"; - reg = <0x4a314000 0x80>; - interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "wd_timer2"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; - }; - - mcpdm: mcpdm@40132000 { -@@ -408,6 +470,8 @@ - reg-names = "mpu", "dma"; - interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mcpdm"; -+ clocks = <&pad_clks_ck>; -+ clock-names = "fck"; - dmas = <&sdma 65>, - <&sdma 66>; - dma-names = "up_link", "dn_link"; -@@ -420,6 +484,8 @@ - reg-names = "mpu", "dma"; - interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "dmic"; -+ clocks = <&func_dmic_abe_gfclk>; -+ clock-names = "fck"; - dmas = <&sdma 67>; - dma-names = "up_link"; - }; -@@ -433,6 +499,8 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp1"; -+ clocks = <&func_mcbsp1_gfclk>, <&pad_clks_ck>, <&mcbsp1_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 33>, - <&sdma 34>; - dma-names = "tx", "rx"; -@@ -447,6 +515,8 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp2"; -+ clocks = <&func_mcbsp2_gfclk>, <&pad_clks_ck>, <&mcbsp2_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 17>, - <&sdma 18>; - dma-names = "tx", "rx"; -@@ -461,6 +531,8 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp3"; -+ clocks = <&func_mcbsp3_gfclk>, <&pad_clks_ck>, <&mcbsp3_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 19>, - <&sdma 20>; - dma-names = "tx", "rx"; -@@ -474,6 +546,8 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp4"; -+ clocks = <&per_mcbsp4_gfclk>, <&pad_clks_ck>, <&mcbsp4_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 31>, - <&sdma 32>; - dma-names = "tx", "rx"; -@@ -485,6 +559,15 @@ - interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; - reg-names = "mpu"; - ti,hwmods = "kbd"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; -+ }; -+ -+ dmm: dmm@4e000000 { -+ compatible = "ti,omap4-dmm"; -+ reg = <0x4e000000 0x800>; -+ interrupts = <0 113 0x4>; -+ ti,hwmods = "dmm"; - }; - - emif1: emif@4c000000 { -@@ -492,6 +575,9 @@ - reg = <0x4c000000 0x100>; - interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "emif1"; -+ ti,no-idle; -+ clocks = <&ddrphy_ck>; -+ clock-names = "fck"; - phy-type = <1>; - hw-caps-read-idle-ctrl; - hw-caps-ll-interface; -@@ -503,6 +589,9 @@ - reg = <0x4d000000 0x100>; - interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "emif2"; -+ ti,no-idle; -+ clocks = <&ddrphy_ck>; -+ clock-names = "fck"; - phy-type = <1>; - hw-caps-read-idle-ctrl; - hw-caps-ll-interface; -@@ -516,18 +605,36 @@ - #size-cells = <1>; - ranges; - ti,hwmods = "ocp2scp_usb_phy"; -+ clocks = <&ocp2scp_usb_phy_phy_48m>; -+ clock-names = "fck"; - usb2_phy: usb2phy@4a0ad080 { - compatible = "ti,omap-usb2"; - reg = <0x4a0ad080 0x58>; -- ctrl-module = <&omap_control_usb>; -+ ctrl-module = <&omap_control_usb2phy>; -+ clocks = <&usb_phy_cm_clk32k>, <&ocp2scp_usb_phy_phy_48m>; -+ clock-names = "wkupclk", "refclk"; -+ #phy-cells = <0>; - }; - }; - -+ mailbox: mailbox@4a0f4000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4a0f4000 0x200>; -+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <3>; -+ ti,mbox-num-fifos = <8>; -+ ti,mbox-names = "mbox-ipu", "mbox-dsp"; -+ ti,mbox-data = <0 1 0 0>, <3 2 0 0>; -+ }; -+ - timer1: timer@4a318000 { - compatible = "ti,omap3430-timer"; - reg = <0x4a318000 0x80>; - interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer1"; -+ clocks = <&dmt1_clk_mux>; -+ clock-names = "fck"; - ti,timer-alwon; - }; - -@@ -536,6 +643,8 @@ - reg = <0x48032000 0x80>; - interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer2"; -+ clocks = <&cm2_dm2_mux>; -+ clock-names = "fck"; - }; - - timer3: timer@48034000 { -@@ -543,6 +652,8 @@ - reg = <0x48034000 0x80>; - interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer3"; -+ clocks = <&cm2_dm3_mux>; -+ clock-names = "fck"; - }; - - timer4: timer@48036000 { -@@ -550,6 +661,8 @@ - reg = <0x48036000 0x80>; - interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer4"; -+ clocks = <&cm2_dm4_mux>; -+ clock-names = "fck"; - }; - - timer5: timer@40138000 { -@@ -558,6 +671,8 @@ - <0x49038000 0x80>; - interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer5"; -+ clocks = <&timer5_sync_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -567,6 +682,8 @@ - <0x4903a000 0x80>; - interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer6"; -+ clocks = <&timer6_sync_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -576,6 +693,8 @@ - <0x4903c000 0x80>; - interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer7"; -+ clocks = <&timer7_sync_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -585,6 +704,8 @@ - <0x4903e000 0x80>; - interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer8"; -+ clocks = <&timer8_sync_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - ti,timer-dsp; - }; -@@ -594,6 +715,8 @@ - reg = <0x4803e000 0x80>; - interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer9"; -+ clocks = <&cm2_dm9_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -602,6 +725,8 @@ - reg = <0x48086000 0x80>; - interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer10"; -+ clocks = <&cm2_dm10_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -610,6 +735,8 @@ - reg = <0x48088000 0x80>; - interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer11"; -+ clocks = <&cm2_dm11_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -618,12 +745,16 @@ - reg = <0x4a062000 0x1000>; - interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "usb_tll_hs"; -+ clocks = <&usb_tll_hs_ick>; -+ clock-names = "fck"; - }; - - usbhshost: usbhshost@4a064000 { - compatible = "ti,usbhs-host"; - reg = <0x4a064000 0x800>; - ti,hwmods = "usb_host_hs"; -+ clocks = <&usb_host_hs_fck>; -+ clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - ranges; -@@ -643,12 +774,16 @@ - }; - }; - -- omap_control_usb: omap-control-usb@4a002300 { -- compatible = "ti,omap-control-usb"; -- reg = <0x4a002300 0x4>, -- <0x4a00233c 0x4>; -- reg-names = "control_dev_conf", "otghs_control"; -- ti,type = <1>; -+ omap_control_usb2phy: control-phy@4a002300 { -+ compatible = "ti,control-phy-usb2"; -+ reg = <0x4a002300 0x4>; -+ reg-names = "power"; -+ }; -+ -+ omap_control_usbotg: control-phy@4a00233c { -+ compatible = "ti,control-phy-otghs"; -+ reg = <0x4a00233c 0x4>; -+ reg-names = "otghs_control"; - }; - - usb_otg_hs: usb_otg_hs@4a0ab000 { -@@ -657,11 +792,98 @@ - interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "mc", "dma"; - ti,hwmods = "usb_otg_hs"; -+ clocks = <&usb_otg_hs_ick>, <&usb_otg_hs_xclk>; -+ clock-names = "fck", "xclk"; - usb-phy = <&usb2_phy>; -+ phys = <&usb2_phy>; -+ phy-names = "usb2-phy"; - multipoint = <1>; - num-eps = <16>; - ram-bits = <12>; -- ti,has-mailbox; -+ ctrl-module = <&omap_control_usbotg>; -+ dr_mode = "peripheral"; -+ }; -+ -+ dss@58000000 { -+ compatible = "ti,omap4-dss", "simple-bus"; -+ reg = <0x58000000 0x80>; -+ ti,hwmods = "dss_core"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ dispc@58001000 { -+ compatible = "ti,omap4-dispc"; -+ reg = <0x58001000 0x1000>; -+ interrupts = <0 25 0x4>; -+ ti,hwmods = "dss_dispc"; -+ }; -+ -+ dpi: encoder@0 { -+ compatible = "ti,omap4-dpi"; -+ }; -+ -+ rfbi: encoder@58002000 { -+ compatible = "ti,omap4-rfbi"; -+ reg = <0x58002000 0x1000>; -+ ti,hwmods = "dss_rfbi"; -+ }; -+ -+ /* -+ * Accessing venc registers cause a crash on omap4, so -+ * this is disabled for now. -+ */ -+ /* -+ venc: encoder@58003000 { -+ compatible = "ti,omap4-venc"; -+ reg = <0x58003000 0x1000>; -+ ti,hwmods = "dss_venc"; -+ }; -+ */ -+ -+ dsi1: encoder@58004000 { -+ compatible = "ti,omap4-dsi"; -+ reg = <0x58004000 0x200>; -+ interrupts = <0 53 0x4>; -+ ti,hwmods = "dss_dsi1"; -+ }; -+ -+ dsi2: encoder@58005000 { -+ compatible = "ti,omap4-dsi"; -+ reg = <0x58005000 0x200>; -+ interrupts = <0 84 0x4>; -+ ti,hwmods = "dss_dsi2"; -+ }; -+ -+ hdmi: encoder@58006000 { -+ compatible = "ti,omap4-hdmi"; -+ reg = <0x58006000 0x200>, -+ <0x58006200 0x100>, -+ <0x58006300 0x100>, -+ <0x58006400 0x1000>; -+ reg-names = "hdmi_wp", "hdmi_pllctrl", -+ "hdmi_txphy", "hdmi_core"; -+ interrupts = <0 101 0x4>; -+ ti,hwmods = "dss_hdmi"; -+ }; -+ }; -+ -+ aes: aes@4b501000 { -+ compatible = "ti,omap4-aes"; -+ ti,hwmods = "aes"; -+ reg = <0x4b501000 0xa0>; -+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; -+ dmas = <&sdma 111>, <&sdma 110>; -+ dma-names = "tx", "rx"; -+ }; -+ -+ des: des@480a5000 { -+ compatible = "ti,omap4-des"; -+ ti,hwmods = "des"; -+ reg = <0x480a5000 0xa0>; -+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; -+ dmas = <&sdma 117>, <&sdma 116>; -+ dma-names = "tx", "rx"; - }; - }; - }; ---- a/arch/arm/boot/dts/omap4-panda-common.dtsi -+++ b/arch/arm/boot/dts/omap4-panda-common.dtsi -@@ -60,22 +60,6 @@ - "AFMR", "Line In"; - }; - -- /* -- * Temp hack: Need to be replaced with the proper gpio-controlled -- * reset driver as soon it will be merged. -- * http://thread.gmane.org/gmane.linux.drivers.devicetree/36830 -- */ -- /* HS USB Port 1 RESET */ -- hsusb1_reset: hsusb1_reset_reg { -- compatible = "regulator-fixed"; -- regulator-name = "hsusb1_reset"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- gpio = <&gpio2 30 0>; /* gpio_62 */ -- startup-delay-us = <70000>; -- enable-active-high; -- }; -- - /* HS USB Port 1 Power */ - hsusb1_power: hsusb1_power_reg { - compatible = "regulator-fixed"; -@@ -97,14 +81,10 @@ - /* HS USB Host PHY on PORT 1 */ - hsusb1_phy: hsusb1_phy { - compatible = "usb-nop-xceiv"; -- reset-supply = <&hsusb1_reset>; -+ reset-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; /* gpio_62 */ - vcc-supply = <&hsusb1_power>; -- /** -- * FIXME: -- * put the right clock phandle here when available -- * clocks = <&auxclk3>; -- * clock-names = "main_clk"; -- */ -+ clocks = <&auxclk3_ck>; -+ clock-names = "main_clk"; - clock-frequency = <19200000>; - }; - -@@ -401,3 +381,51 @@ - &usbhsehci { - phys = <&hsusb1_phy>; - }; -+ -+&dsi1 { -+ vdds_dsi-supply = <&vcxio>; -+}; -+ -+&dsi2 { -+ vdds_dsi-supply = <&vcxio>; -+}; -+ -+&hdmi { -+ vdda_hdmi_dac-supply = <&vdac>; -+}; -+ -+/ { -+ aliases { -+ display0 = &dvi0; -+ display1 = &hdmi0; -+ }; -+ -+ tfp410: encoder@0 { -+ compatible = "ti,tfp410"; -+ video-source = <&dpi>; -+ data-lines = <24>; -+ gpios = <&gpio1 0 0>; /* 0, power-down */ -+ }; -+ -+ dvi0: connector@0 { -+ compatible = "ti,dvi_connector"; -+ video-source = <&tfp410>; -+ i2c-bus = <&i2c3>; -+ }; -+ -+ tpd12s015: encoder@1 { -+ compatible = "ti,tpd12s015"; -+ -+ video-source = <&hdmi>; -+ -+ gpios = <&gpio2 28 0>, /* 60, CT CP HPD */ -+ <&gpio2 9 0>, /* 41, LS OE */ -+ <&gpio2 31 0>; /* 63, HPD */ -+ }; -+ -+ hdmi0: connector@1 { -+ compatible = "ti,hdmi_connector"; -+ -+ video-source = <&tpd12s015>; -+ }; -+}; ---- a/arch/arm/boot/dts/omap4-sdp.dts -+++ b/arch/arm/boot/dts/omap4-sdp.dts -@@ -569,3 +569,73 @@ - mode = <3>; - power = <50>; - }; -+ -+&dsi1 { -+ vdds_dsi-supply = <&vcxio>; -+}; -+ -+&dsi2 { -+ vdds_dsi-supply = <&vcxio>; -+}; -+ -+&hdmi { -+ vdda_hdmi_dac-supply = <&vdac>; -+}; -+ -+/ { -+ aliases { -+ display0 = &lcd0; -+ display1 = &lcd1; -+ display2 = &hdmi0; -+ }; -+ -+ lcd0: display@0 { -+ compatible = "tpo,taal", "panel-dsi-cm"; -+ -+ video-source = <&dsi1>; -+ -+ lanes = < -+ 0 /* clk + */ -+ 1 /* clk - */ -+ 2 /* data1 + */ -+ 3 /* data1 - */ -+ 4 /* data2 + */ -+ 5 /* data2 - */ -+ >; -+ -+ gpios = <&gpio4 6 0>; /* 102, reset */ -+ }; -+ -+ lcd1: display@1 { -+ compatible = "tpo,taal", "panel-dsi-cm"; -+ -+ video-source = <&dsi2>; -+ -+ lanes = < -+ 0 /* clk + */ -+ 1 /* clk - */ -+ 2 /* data1 + */ -+ 3 /* data1 - */ -+ 4 /* data2 + */ -+ 5 /* data2 - */ -+ >; -+ -+ gpios = <&gpio4 8 0>; /* 104, reset */ -+ }; -+ -+ tpd12s015: encoder@0 { -+ compatible = "ti,tpd12s015"; -+ -+ video-source = <&hdmi>; -+ -+ gpios = <&gpio2 28 0>, /* 60, CT CP HPD */ -+ <&gpio2 9 0>, /* 41, LS OE */ -+ <&gpio2 31 0>; /* 63, HPD */ -+ }; -+ -+ hdmi0: connector@0 { -+ compatible = "ti,hdmi_connector"; -+ -+ video-source = <&tpd12s015>; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi -@@ -0,0 +1,1400 @@ -+/* -+ * Device Tree Source for OMAP5 clock data -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ */ -+ -+pad_clks_src_ck: pad_clks_src_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+pad_clks_ck: pad_clks_ck@4a004108 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&pad_clks_src_ck>; -+ bit-shift = <8>; -+ reg = <0x4a004108 0x4>; -+}; -+ -+secure_32k_clk_src_ck: secure_32k_clk_src_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+slimbus_src_clk: slimbus_src_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+slimbus_clk: slimbus_clk@4a004108 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&slimbus_src_clk>; -+ bit-shift = <10>; -+ reg = <0x4a004108 0x4>; -+}; -+ -+sys_32k_ck: sys_32k_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+}; -+ -+virt_12000000_ck: virt_12000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <12000000>; -+}; -+ -+virt_13000000_ck: virt_13000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <13000000>; -+}; -+ -+virt_16800000_ck: virt_16800000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <16800000>; -+}; -+ -+virt_19200000_ck: virt_19200000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <19200000>; -+}; -+ -+virt_26000000_ck: virt_26000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <26000000>; -+}; -+ -+virt_27000000_ck: virt_27000000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <27000000>; -+}; -+ -+virt_38400000_ck: virt_38400000_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <38400000>; -+}; -+ -+sys_clkin: sys_clkin@4ae06110 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&virt_12000000_ck>, <&virt_13000000_ck>, <&virt_16800000_ck>, <&virt_19200000_ck>, <&virt_26000000_ck>, <&virt_27000000_ck>, <&virt_38400000_ck>; -+ reg = <0x4ae06110 0x4>; -+ bit-mask = <0x7>; -+ index-starts-at-one; -+}; -+ -+xclk60mhsp1_ck: xclk60mhsp1_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <60000000>; -+}; -+ -+xclk60mhsp2_ck: xclk60mhsp2_ck { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <60000000>; -+}; -+ -+abe_dpll_bypass_clk_mux: abe_dpll_bypass_clk_mux@4ae06108 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ reg = <0x4ae06108 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+abe_dpll_clk_mux: abe_dpll_clk_mux@4ae0610c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ reg = <0x4ae0610c 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dpll_abe_ck: dpll_abe_ck@4a0041e0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-m4xen-clock"; -+ clocks = <&abe_dpll_clk_mux>, <&abe_dpll_bypass_clk_mux>; -+ reg = <0x4a0041e0 0x4>, <0x4a0041e4 0x4>, <0x4a0041e8 0x4>, <0x4a0041ec 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_abe_x2_ck: dpll_abe_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_abe_ck>; -+}; -+ -+dpll_abe_m2x2_ck: dpll_abe_m2x2_ck@4a0041f0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041f0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+abe_24m_fclk: abe_24m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <8>; -+}; -+ -+abe_clk: abe_clk@4a004108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ reg = <0x4a004108 0x4>; -+ bit-mask = <0x3>; -+ index-power-of-two; -+}; -+ -+abe_iclk: abe_iclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&abe_clk>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+abe_lp_clk_div: abe_lp_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+dpll_abe_m3x2_ck: dpll_abe_m3x2_ck@4a0041f4 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041f4 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_ck: dpll_core_ck@4a004120 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-core-clock"; -+ clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; -+ reg = <0x4a004120 0x4>, <0x4a004124 0x4>, <0x4a004128 0x4>, <0x4a00412c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_core_x2_ck: dpll_core_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_core_ck>; -+}; -+ -+dpll_core_h21x2_ck: dpll_core_h21x2_ck@4a004150 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004150 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+c2c_fclk: c2c_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h21x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+c2c_iclk: c2c_iclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&c2c_fclk>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+custefuse_sys_gfclk_div: custefuse_sys_gfclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_core_h11x2_ck: dpll_core_h11x2_ck@4a004138 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004138 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h12x2_ck: dpll_core_h12x2_ck@4a00413c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00413c 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h13x2_ck: dpll_core_h13x2_ck@4a004140 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004140 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h14x2_ck: dpll_core_h14x2_ck@4a004144 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004144 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h22x2_ck: dpll_core_h22x2_ck@4a004154 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004154 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h23x2_ck: dpll_core_h23x2_ck@4a004158 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004158 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_h24x2_ck: dpll_core_h24x2_ck@4a00415c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00415c 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_m2_ck: dpll_core_m2_ck@4a004130 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004130 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_core_m3x2_ck: dpll_core_m3x2_ck@4a004134 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_core_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004134 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+iva_dpll_hs_clk_div: iva_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_iva_ck: dpll_iva_ck@4a0041a0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; -+ reg = <0x4a0041a0 0x4>, <0x4a0041a4 0x4>, <0x4a0041a8 0x4>, <0x4a0041ac 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_iva_x2_ck: dpll_iva_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_iva_ck>; -+}; -+ -+dpll_iva_h11x2_ck: dpll_iva_h11x2_ck@4a0041b8 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_iva_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041b8 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_iva_h12x2_ck: dpll_iva_h12x2_ck@4a0041bc { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_iva_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0041bc 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+mpu_dpll_hs_clk_div: mpu_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_mpu_ck: dpll_mpu_ck@4a004160 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin>, <&mpu_dpll_hs_clk_div>; -+ reg = <0x4a004160 0x4>, <0x4a004164 0x4>, <0x4a004168 0x4>, <0x4a00416c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_mpu_m2_ck: dpll_mpu_m2_ck@4a004170 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_mpu_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a004170 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+per_dpll_hs_clk_div: per_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+dpll_per_ck: dpll_per_ck@4a008140 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; -+ reg = <0x4a008140 0x4>, <0x4a008144 0x4>, <0x4a008148 0x4>, <0x4a00814c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_per_x2_ck: dpll_per_x2_ck { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-x2-clock"; -+ clocks = <&dpll_per_ck>; -+}; -+ -+dpll_per_h11x2_ck: dpll_per_h11x2_ck@4a008158 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008158 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_h12x2_ck: dpll_per_h12x2_ck@4a00815c { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a00815c 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_h14x2_ck: dpll_per_h14x2_ck@4a008164 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008164 0x4>; -+ bit-mask = <0x3f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m2_ck: dpll_per_m2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008150 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m2x2_ck: dpll_per_m2x2_ck@4a008150 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008150 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_per_m3x2_ck: dpll_per_m3x2_ck@4a008154 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_per_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008154 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_unipro1_ck: dpll_unipro1_ck@4a008200 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin>, <&sys_clkin>; -+ reg = <0x4a008200 0x4>, <0x4a008204 0x4>, <0x4a008208 0x4>, <0x4a00820c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_unipro1_clkdcoldo: dpll_unipro1_clkdcoldo { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_unipro1_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_unipro1_m2_ck: dpll_unipro1_m2_ck@4a008210 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_unipro1_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008210 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dpll_unipro2_ck: dpll_unipro2_ck@4a0081c0 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-clock"; -+ clocks = <&sys_clkin>, <&sys_clkin>; -+ reg = <0x4a0081c0 0x4>, <0x4a0081c4 0x4>, <0x4a0081c8 0x4>, <0x4a0081cc 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_unipro2_clkdcoldo: dpll_unipro2_clkdcoldo { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_unipro2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_unipro2_m2_ck: dpll_unipro2_m2_ck@4a0081d0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_unipro2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0081d0 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+usb_dpll_hs_clk_div: usb_dpll_hs_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_abe_m3x2_ck>; -+ clock-mult = <1>; -+ clock-div = <3>; -+}; -+ -+dpll_usb_ck: dpll_usb_ck@4a008180 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-j-type-clock"; -+ clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; -+ reg = <0x4a008180 0x4>, <0x4a008184 0x4>, <0x4a008188 0x4>, <0x4a00818c 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+}; -+ -+dpll_usb_clkdcoldo: dpll_usb_clkdcoldo { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_usb_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dpll_usb_m2_ck: dpll_usb_m2_ck@4a008190 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_usb_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a008190 0x4>; -+ bit-mask = <0x7f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+}; -+ -+dss_syc_gfclk_div: dss_syc_gfclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&sys_clkin>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+func_128m_clk: func_128m_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_h11x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+func_12m_fclk: func_12m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <16>; -+}; -+ -+func_24m_clk: func_24m_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+func_48m_fclk: func_48m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <4>; -+}; -+ -+func_96m_fclk: func_96m_fclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ clock-mult = <1>; -+ clock-div = <2>; -+}; -+ -+l3_iclk_div: l3_iclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&dpll_core_h12x2_ck>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+gpu_l3_iclk: gpu_l3_iclk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l3_iclk_div>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l3init_60m_fclk: l3init_60m_fclk@4a008104 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ reg = <0x4a008104 0x4>; -+ table = < 1 0 >, < 8 1 >; -+ bit-mask = <0x1>; -+}; -+ -+wkupaon_iclk_mux: wkupaon_iclk_mux@4ae06108 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&abe_lp_clk_div>; -+ reg = <0x4ae06108 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+l3instr_ts_gclk_div: l3instr_ts_gclk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&wkupaon_iclk_mux>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+l4_root_clk_div: l4_root_clk_div { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&l3_iclk_div>; -+ clock-mult = <1>; -+ clock-div = <1>; -+}; -+ -+dss_32khz_clk: dss_32khz_clk@4a009420 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <11>; -+ reg = <0x4a009420 0x4>; -+}; -+ -+dss_48mhz_clk: dss_48mhz_clk@4a009420 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_48m_fclk>; -+ bit-shift = <9>; -+ reg = <0x4a009420 0x4>; -+}; -+ -+dss_dss_clk: dss_dss_clk@4a009420 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_per_h12x2_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009420 0x4>; -+}; -+ -+dss_sys_clk: dss_sys_clk@4a009420 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dss_syc_gfclk_div>; -+ bit-shift = <10>; -+ reg = <0x4a009420 0x4>; -+}; -+ -+gpio1_dbclk: gpio1_dbclk@4ae07938 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae07938 0x4>; -+}; -+ -+gpio2_dbclk: gpio2_dbclk@4a009060 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009060 0x4>; -+}; -+ -+gpio3_dbclk: gpio3_dbclk@4a009068 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009068 0x4>; -+}; -+ -+gpio4_dbclk: gpio4_dbclk@4a009070 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009070 0x4>; -+}; -+ -+gpio5_dbclk: gpio5_dbclk@4a009078 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009078 0x4>; -+}; -+ -+gpio6_dbclk: gpio6_dbclk@4a009080 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009080 0x4>; -+}; -+ -+gpio7_dbclk: gpio7_dbclk@4a009110 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009110 0x4>; -+}; -+ -+gpio8_dbclk: gpio8_dbclk@4a009118 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009118 0x4>; -+}; -+ -+iss_ctrlclk: iss_ctrlclk@4a009320 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&func_96m_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a009320 0x4>; -+}; -+ -+lli_txphy_clk: lli_txphy_clk@4a008f20 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_unipro1_clkdcoldo>; -+ bit-shift = <8>; -+ reg = <0x4a008f20 0x4>; -+}; -+ -+lli_txphy_ls_clk: lli_txphy_ls_clk@4a008f20 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_unipro1_m2_ck>; -+ bit-shift = <9>; -+ reg = <0x4a008f20 0x4>; -+}; -+ -+mmc1_32khz_clk: mmc1_32khz_clk@4a009628 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a009628 0x4>; -+}; -+ -+sata_ref_clk: sata_ref_clk@4a009688 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_clkin>; -+ bit-shift = <8>; -+ reg = <0x4a009688 0x4>; -+}; -+ -+slimbus1_slimbus_clk: slimbus1_slimbus_clk@4a004560 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&slimbus_clk>; -+ bit-shift = <11>; -+ reg = <0x4a004560 0x4>; -+}; -+ -+usb_host_hs_hsic480m_p1_clk: usb_host_hs_hsic480m_p1_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ bit-shift = <13>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_host_hs_hsic480m_p2_clk: usb_host_hs_hsic480m_p2_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ bit-shift = <14>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_host_hs_hsic480m_p3_clk: usb_host_hs_hsic480m_p3_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_m2_ck>; -+ bit-shift = <7>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_host_hs_hsic60m_p1_clk: usb_host_hs_hsic60m_p1_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <11>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_host_hs_hsic60m_p2_clk: usb_host_hs_hsic60m_p2_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <12>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_host_hs_hsic60m_p3_clk: usb_host_hs_hsic60m_p3_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <6>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+utmi_p1_gfclk: utmi_p1_gfclk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3init_60m_fclk>, <&xclk60mhsp1_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009658 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_host_hs_utmi_p1_clk: usb_host_hs_utmi_p1_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&utmi_p1_gfclk>; -+ bit-shift = <8>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+utmi_p2_gfclk: utmi_p2_gfclk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&l3init_60m_fclk>, <&xclk60mhsp2_ck>; -+ bit-shift = <25>; -+ reg = <0x4a009658 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+usb_host_hs_utmi_p2_clk: usb_host_hs_utmi_p2_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&utmi_p2_gfclk>; -+ bit-shift = <9>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_host_hs_utmi_p3_clk: usb_host_hs_utmi_p3_clk@4a009658 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <10>; -+ reg = <0x4a009658 0x4>; -+}; -+ -+usb_otg_ss_refclk960m: usb_otg_ss_refclk960m@4a0096f0 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&dpll_usb_clkdcoldo>; -+ bit-shift = <8>; -+ reg = <0x4a0096f0 0x4>; -+}; -+ -+usb_phy_cm_clk32k: usb_phy_cm_clk32k@4a008640 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&sys_32k_ck>; -+ bit-shift = <8>; -+ reg = <0x4a008640 0x4>; -+}; -+ -+usb_tll_hs_usb_ch0_clk: usb_tll_hs_usb_ch0_clk@4a009668 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <8>; -+ reg = <0x4a009668 0x4>; -+}; -+ -+usb_tll_hs_usb_ch1_clk: usb_tll_hs_usb_ch1_clk@4a009668 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <9>; -+ reg = <0x4a009668 0x4>; -+}; -+ -+usb_tll_hs_usb_ch2_clk: usb_tll_hs_usb_ch2_clk@4a009668 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&l3init_60m_fclk>; -+ bit-shift = <10>; -+ reg = <0x4a009668 0x4>; -+}; -+ -+aess_fclk: aess_fclk@4a004528 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&abe_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004528 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+dmic_sync_mux_ck: dmic_sync_mux_ck@4a004538 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>; -+ bit-shift = <26>; -+ reg = <0x4a004538 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+dmic_gfclk: dmic_gfclk@4a004538 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dmic_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004538 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+fdif_fclk: fdif_fclk@4a009328 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_h11x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009328 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpu_core_gclk_mux: gpu_core_gclk_mux@4a009520 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009520 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+gpu_hyd_gclk_mux: gpu_hyd_gclk_mux@4a009520 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dpll_core_h14x2_ck>, <&dpll_per_h14x2_ck>; -+ bit-shift = <25>; -+ reg = <0x4a009520 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+hsi_fclk: hsi_fclk@4a009638 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009638 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mcasp_sync_mux_ck: mcasp_sync_mux_ck@4a004540 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>; -+ bit-shift = <26>; -+ reg = <0x4a004540 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcasp_gfclk: mcasp_gfclk@4a004540 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcasp_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004540 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp1_sync_mux_ck: mcbsp1_sync_mux_ck@4a004548 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>; -+ bit-shift = <26>; -+ reg = <0x4a004548 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp1_gfclk: mcbsp1_gfclk@4a004548 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp1_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004548 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp2_sync_mux_ck: mcbsp2_sync_mux_ck@4a004550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>; -+ bit-shift = <26>; -+ reg = <0x4a004550 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp2_gfclk: mcbsp2_gfclk@4a004550 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp2_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004550 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp3_sync_mux_ck: mcbsp3_sync_mux_ck@4a004558 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&abe_24m_fclk>, <&dss_syc_gfclk_div>, <&func_24m_clk>; -+ bit-shift = <26>; -+ reg = <0x4a004558 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mcbsp3_gfclk: mcbsp3_gfclk@4a004558 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&mcbsp3_sync_mux_ck>, <&pad_clks_ck>, <&slimbus_clk>; -+ bit-shift = <24>; -+ reg = <0x4a004558 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+mmc1_fclk_mux: mmc1_fclk_mux@4a009628 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009628 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc1_fclk: mmc1_fclk@4a009628 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mmc1_fclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009628 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc2_fclk_mux: mmc2_fclk_mux@4a009630 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&func_128m_clk>, <&dpll_per_m2x2_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009630 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+mmc2_fclk: mmc2_fclk@4a009630 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&mmc2_fclk_mux>; -+ bit-shift = <25>; -+ reg = <0x4a009630 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer10_gfclk_mux: timer10_gfclk_mux@4a009028 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009028 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer11_gfclk_mux: timer11_gfclk_mux@4a009030 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009030 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer1_gfclk_mux: timer1_gfclk_mux@4ae07940 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4ae07940 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer2_gfclk_mux: timer2_gfclk_mux@4a009038 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009038 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer3_gfclk_mux: timer3_gfclk_mux@4a009040 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009040 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer4_gfclk_mux: timer4_gfclk_mux@4a009048 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009048 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer5_gfclk_mux: timer5_gfclk_mux@4a004568 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004568 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer6_gfclk_mux: timer6_gfclk_mux@4a004570 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004570 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer7_gfclk_mux: timer7_gfclk_mux@4a004578 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004578 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer8_gfclk_mux: timer8_gfclk_mux@4a004580 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&dss_syc_gfclk_div>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a004580 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+timer9_gfclk_mux: timer9_gfclk_mux@4a009050 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&sys_32k_ck>; -+ bit-shift = <24>; -+ reg = <0x4a009050 0x4>; -+ bit-mask = <0x1>; -+}; -+ -+auxclk0_src_mux_ck: auxclk0_src_mux_ck@4ae0a310 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4ae0a310 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk0_src_ck: auxclk0_src_ck@4ae0a310 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk0_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae0a310 0x4>; -+}; -+ -+auxclk0_ck: auxclk0_ck@4ae0a310 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk0_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4ae0a310 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk1_src_mux_ck: auxclk1_src_mux_ck@4ae0a314 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4ae0a314 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk1_src_ck: auxclk1_src_ck@4ae0a314 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk1_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae0a314 0x4>; -+}; -+ -+auxclk1_ck: auxclk1_ck@4ae0a314 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk1_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4ae0a314 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk2_src_mux_ck: auxclk2_src_mux_ck@4ae0a318 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4ae0a318 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk2_src_ck: auxclk2_src_ck@4ae0a318 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk2_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae0a318 0x4>; -+}; -+ -+auxclk2_ck: auxclk2_ck@4ae0a318 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk2_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4ae0a318 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk3_src_mux_ck: auxclk3_src_mux_ck@4ae0a31c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4ae0a31c 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk3_src_ck: auxclk3_src_ck@4ae0a31c { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk3_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae0a31c 0x4>; -+}; -+ -+auxclk3_ck: auxclk3_ck@4ae0a31c { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk3_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4ae0a31c 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclk4_src_mux_ck: auxclk4_src_mux_ck@4ae0a320 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&sys_clkin>, <&dpll_core_m3x2_ck>, <&dpll_per_m3x2_ck>; -+ bit-shift = <1>; -+ reg = <0x4ae0a320 0x4>; -+ bit-mask = <0x3>; -+}; -+ -+auxclk4_src_ck: auxclk4_src_ck@4ae0a320 { -+ #clock-cells = <0>; -+ compatible = "gate-clock"; -+ clocks = <&auxclk4_src_mux_ck>; -+ bit-shift = <8>; -+ reg = <0x4ae0a320 0x4>; -+}; -+ -+auxclk4_ck: auxclk4_ck@4ae0a320 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&auxclk4_src_ck>; -+ bit-shift = <16>; -+ reg = <0x4ae0a320 0x4>; -+ bit-mask = <0xf>; -+}; -+ -+auxclkreq0_ck: auxclkreq0_ck@4ae0a210 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>; -+ bit-shift = <2>; -+ reg = <0x4ae0a210 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq1_ck: auxclkreq1_ck@4ae0a214 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>; -+ bit-shift = <2>; -+ reg = <0x4ae0a214 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq2_ck: auxclkreq2_ck@4ae0a218 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>; -+ bit-shift = <2>; -+ reg = <0x4ae0a218 0x4>; -+ bit-mask = <0x7>; -+}; -+ -+auxclkreq3_ck: auxclkreq3_ck@4ae0a21c { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&auxclk0_ck>, <&auxclk1_ck>, <&auxclk2_ck>, <&auxclk3_ck>, <&auxclk4_ck>; -+ bit-shift = <2>; -+ reg = <0x4ae0a21c 0x4>; -+ bit-mask = <0x7>; -+}; ---- a/arch/arm/boot/dts/omap5.dtsi -+++ b/arch/arm/boot/dts/omap5.dtsi -@@ -21,6 +21,11 @@ - interrupt-parent = <&gic>; - - aliases { -+ i2c0 = &i2c1; -+ i2c1 = &i2c2; -+ i2c2 = &i2c3; -+ i2c3 = &i2c4; -+ i2c4 = &i2c5; - serial0 = &uart1; - serial1 = &uart2; - serial2 = &uart3; -@@ -33,10 +38,23 @@ - #address-cells = <1>; - #size-cells = <0>; - -- cpu@0 { -+ cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; -+ -+ operating-points = < -+ /* kHz uV */ -+ 500000 880000 -+ 1000000 1060000 -+ 1500000 1250000 -+ >; -+ -+ clocks = <&dpll_mpu_ck>; -+ clock-names = "cpu"; -+ -+ clock-latency = <300000>; /* From omap-cpufreq driver */ -+ - }; - cpu@1 { - device_type = "cpu"; -@@ -52,7 +70,6 @@ - <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>; -- clock-frequency = <6144000>; - }; - - gic: interrupt-controller@48211000 { -@@ -100,6 +117,8 @@ - compatible = "ti,omap-counter32k"; - reg = <0x4ae04000 0x40>; - ti,hwmods = "counter_32k"; -+ clocks = <&wkupaon_iclk_mux>; -+ clock-names = "fck"; - }; - - omap5_pmx_core: pinmux@4a002840 { -@@ -129,6 +148,8 @@ - #dma-cells = <1>; - #dma-channels = <32>; - #dma-requests = <127>; -+ clocks = <&l3_iclk_div>; -+ clock-names = "fck"; - }; - - gpio1: gpio@4ae10000 { -@@ -136,6 +157,8 @@ - reg = <0x4ae10000 0x200>; - interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio1"; -+ clocks = <&wkupaon_iclk_mux>, <&gpio1_dbclk>; -+ clock-names = "fck", "dbclk"; - ti,gpio-always-on; - gpio-controller; - #gpio-cells = <2>; -@@ -148,6 +171,8 @@ - reg = <0x48055000 0x200>; - interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio2"; -+ clocks = <&l4_root_clk_div>, <&gpio2_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -159,6 +184,8 @@ - reg = <0x48057000 0x200>; - interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio3"; -+ clocks = <&l4_root_clk_div>, <&gpio3_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -170,6 +197,8 @@ - reg = <0x48059000 0x200>; - interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio4"; -+ clocks = <&l4_root_clk_div>, <&gpio4_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -181,6 +210,8 @@ - reg = <0x4805b000 0x200>; - interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio5"; -+ clocks = <&l4_root_clk_div>, <&gpio5_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -192,6 +223,8 @@ - reg = <0x4805d000 0x200>; - interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio6"; -+ clocks = <&l4_root_clk_div>, <&gpio6_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -203,6 +236,8 @@ - reg = <0x48051000 0x200>; - interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio7"; -+ clocks = <&l4_root_clk_div>, <&gpio7_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -214,6 +249,8 @@ - reg = <0x48053000 0x200>; - interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "gpio8"; -+ clocks = <&l4_root_clk_div>, <&gpio8_dbclk>; -+ clock-names = "fck", "dbclk"; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; -@@ -238,6 +275,9 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c1"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; - }; - - i2c2: i2c@48072000 { -@@ -247,6 +287,9 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c2"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; - }; - - i2c3: i2c@48060000 { -@@ -256,6 +299,9 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c3"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; - }; - - i2c4: i2c@4807a000 { -@@ -265,6 +311,9 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c4"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; - }; - - i2c5: i2c@4807c000 { -@@ -274,6 +323,9 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c5"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; -+ status = "disabled"; - }; - - mcspi1: spi@48098000 { -@@ -283,6 +335,8 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi1"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <4>; - dmas = <&sdma 35>, - <&sdma 36>, -@@ -294,6 +348,7 @@ - <&sdma 42>; - dma-names = "tx0", "rx0", "tx1", "rx1", - "tx2", "rx2", "tx3", "rx3"; -+ status = "disabled"; - }; - - mcspi2: spi@4809a000 { -@@ -303,12 +358,15 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi2"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <2>; - dmas = <&sdma 43>, - <&sdma 44>, - <&sdma 45>, - <&sdma 46>; - dma-names = "tx0", "rx0", "tx1", "rx1"; -+ status = "disabled"; - }; - - mcspi3: spi@480b8000 { -@@ -318,9 +376,12 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <2>; - dmas = <&sdma 15>, <&sdma 16>; - dma-names = "tx0", "rx0"; -+ status = "disabled"; - }; - - mcspi4: spi@480ba000 { -@@ -330,9 +391,12 @@ - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "mcspi4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,spi-num-cs = <1>; - dmas = <&sdma 70>, <&sdma 71>; - dma-names = "tx0", "rx0"; -+ status = "disabled"; - }; - - uart1: serial@4806a000 { -@@ -340,7 +404,10 @@ - reg = <0x4806a000 0x100>; - interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart1"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; -+ status = "disabled"; - }; - - uart2: serial@4806c000 { -@@ -348,7 +415,10 @@ - reg = <0x4806c000 0x100>; - interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart2"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; -+ status = "disabled"; - }; - - uart3: serial@48020000 { -@@ -356,7 +426,10 @@ - reg = <0x48020000 0x100>; - interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; -+ status = "disabled"; - }; - - uart4: serial@4806e000 { -@@ -364,7 +437,10 @@ - reg = <0x4806e000 0x100>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; -+ status = "disabled"; - }; - - uart5: serial@48066000 { -@@ -372,7 +448,10 @@ - reg = <0x48066000 0x100>; - interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart5"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; -+ status = "disabled"; - }; - - uart6: serial@48068000 { -@@ -380,7 +459,10 @@ - reg = <0x48068000 0x100>; - interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "uart6"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - clock-frequency = <48000000>; -+ status = "disabled"; - }; - - mmc1: mmc@4809c000 { -@@ -388,6 +470,8 @@ - reg = <0x4809c000 0x400>; - interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc1"; -+ clocks = <&mmc1_fclk>, <&mmc1_32khz_clk>; -+ clock-names = "fck", "32khz_clk"; - ti,dual-volt; - ti,needs-special-reset; - dmas = <&sdma 61>, <&sdma 62>; -@@ -399,6 +483,8 @@ - reg = <0x480b4000 0x400>; - interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc2"; -+ clocks = <&mmc2_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 47>, <&sdma 48>; - dma-names = "tx", "rx"; -@@ -409,6 +495,8 @@ - reg = <0x480ad000 0x400>; - interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc3"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 77>, <&sdma 78>; - dma-names = "tx", "rx"; -@@ -419,6 +507,8 @@ - reg = <0x480d1000 0x400>; - interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc4"; -+ clocks = <&func_48m_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 57>, <&sdma 58>; - dma-names = "tx", "rx"; -@@ -429,15 +519,63 @@ - reg = <0x480d5000 0x400>; - interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mmc5"; -+ clocks = <&func_96m_fclk>; -+ clock-names = "fck"; - ti,needs-special-reset; - dmas = <&sdma 59>, <&sdma 60>; - dma-names = "tx", "rx"; - }; - -+ omap_control_sata: control-phy@4a002374 { -+ compatible = "ti,control-phy-pipe3"; -+ reg = <0x4a002374 0x4>; -+ reg-names = "power"; -+ clocks = <&sys_clkin>; -+ clock-names = "sysclk"; -+ }; -+ -+ ocp2scp@4a090000 { -+ compatible = "ti,omap-ocp2scp"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ ti,hwmods = "ocp2scp3"; -+ reg = <0x4a090000 0x1c>; /* ocp2scp3 */ -+ sata_phy: sata-phy@4A096000 { -+ compatible = "ti,phy-pipe3-sata"; -+ reg = <0x4A096000 0x80>, /* phy_rx */ -+ <0x4A096400 0x64>, /* phy_tx */ -+ <0x4A096800 0x40>; /* pll_ctrl */ -+ reg-names = "phy_rx", "phy_tx", "pll_ctrl"; -+ ctrl-module = <&omap_control_sata>; -+ #phy-cells = <0>; -+ clocks = <&sata_ref_clk>; -+ clock-names = "refclk"; -+ }; -+ }; -+ -+ sata@4a141100 { -+ compatible = "ti,sata"; -+ ti,hwmods = "sata"; -+ reg = <0x4a141100 0x100>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ sata@4a140000 { -+ compatible = "snps,dwc-ahci"; -+ reg = <0x4a140000 0x1100>; -+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; -+ phys = <&sata_phy>; -+ phy-names = "sata-phy"; -+ }; -+ }; -+ - keypad: keypad@4ae1c000 { - compatible = "ti,omap4-keypad"; - reg = <0x4ae1c000 0x400>; - ti,hwmods = "kbd"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; - }; - - mcpdm: mcpdm@40132000 { -@@ -447,6 +585,8 @@ - reg-names = "mpu", "dma"; - interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "mcpdm"; -+ clocks = <&pad_clks_ck>; -+ clock-names = "fck"; - dmas = <&sdma 65>, - <&sdma 66>; - dma-names = "up_link", "dn_link"; -@@ -459,6 +599,8 @@ - reg-names = "mpu", "dma"; - interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "dmic"; -+ clocks = <&dmic_gfclk>; -+ clock-names = "fck"; - dmas = <&sdma 67>; - dma-names = "up_link"; - }; -@@ -472,6 +614,8 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp1"; -+ clocks = <&mcbsp1_gfclk>, <&pad_clks_ck>, <&mcbsp1_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 33>, - <&sdma 34>; - dma-names = "tx", "rx"; -@@ -486,6 +630,8 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp2"; -+ clocks = <&mcbsp2_gfclk>, <&pad_clks_ck>, <&mcbsp2_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 17>, - <&sdma 18>; - dma-names = "tx", "rx"; -@@ -500,16 +646,31 @@ - interrupt-names = "common"; - ti,buffer-size = <128>; - ti,hwmods = "mcbsp3"; -+ clocks = <&mcbsp3_gfclk>, <&pad_clks_ck>, <&mcbsp3_sync_mux_ck>; -+ clock-names = "fck", "pad_fck", "prcm_fck"; - dmas = <&sdma 19>, - <&sdma 20>; - dma-names = "tx", "rx"; - }; - -+ mailbox: mailbox@4a0f4000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4a0f4000 0x200>; -+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <3>; -+ ti,mbox-num-fifos = <8>; -+ ti,mbox-names = "mbox-ipu", "mbox-dsp"; -+ ti,mbox-data = <0 1 0 0>, <3 2 0 0>; -+ }; -+ - timer1: timer@4ae18000 { - compatible = "ti,omap5430-timer"; - reg = <0x4ae18000 0x80>; - interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer1"; -+ clocks = <&timer1_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-alwon; - }; - -@@ -518,6 +679,8 @@ - reg = <0x48032000 0x80>; - interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer2"; -+ clocks = <&timer2_gfclk_mux>; -+ clock-names = "fck"; - }; - - timer3: timer@48034000 { -@@ -525,6 +688,8 @@ - reg = <0x48034000 0x80>; - interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer3"; -+ clocks = <&timer3_gfclk_mux>; -+ clock-names = "fck"; - }; - - timer4: timer@48036000 { -@@ -532,6 +697,8 @@ - reg = <0x48036000 0x80>; - interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer4"; -+ clocks = <&timer4_gfclk_mux>; -+ clock-names = "fck"; - }; - - timer5: timer@40138000 { -@@ -540,6 +707,8 @@ - <0x49038000 0x80>; - interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer5"; -+ clocks = <&timer5_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - ti,timer-pwm; - }; -@@ -550,6 +719,8 @@ - <0x4903a000 0x80>; - interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer6"; -+ clocks = <&timer6_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - ti,timer-pwm; - }; -@@ -560,6 +731,8 @@ - <0x4903c000 0x80>; - interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer7"; -+ clocks = <&timer7_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - }; - -@@ -569,6 +742,8 @@ - <0x4903e000 0x80>; - interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer8"; -+ clocks = <&timer8_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-dsp; - ti,timer-pwm; - }; -@@ -578,6 +753,8 @@ - reg = <0x4803e000 0x80>; - interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer9"; -+ clocks = <&timer9_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -586,6 +763,8 @@ - reg = <0x48086000 0x80>; - interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer10"; -+ clocks = <&timer10_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - -@@ -594,19 +773,33 @@ - reg = <0x48088000 0x80>; - interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "timer11"; -+ clocks = <&timer11_gfclk_mux>; -+ clock-names = "fck"; - ti,timer-pwm; - }; - - wdt2: wdt@4ae14000 { -- compatible = "ti,omap5-wdt", "ti,omap3-wdt"; -+ compatible = "ti,omap5-wdt", "ti,omap4-wdt"; - reg = <0x4ae14000 0x80>; - interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; - ti,hwmods = "wd_timer2"; -+ clocks = <&sys_32k_ck>; -+ clock-names = "fck"; -+ }; -+ -+ dmm: dmm@4e000000 { -+ compatible = "ti,omap5-dmm"; -+ reg = <0x4e000000 0x800>; -+ interrupts = <0 113 0x4>; -+ ti,hwmods = "dmm"; - }; - - emif1: emif@0x4c000000 { - compatible = "ti,emif-4d5"; - ti,hwmods = "emif1"; -+ ti,no-idle; -+ clocks = <&dpll_core_h11x2_ck>; -+ clock-names = "fck"; - phy-type = <2>; /* DDR PHY type: Intelli PHY */ - reg = <0x4c000000 0x400>; - interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; -@@ -618,6 +811,9 @@ - emif2: emif@0x4d000000 { - compatible = "ti,emif-4d5"; - ti,hwmods = "emif2"; -+ ti,no-idle; -+ clocks = <&dpll_core_h11x2_ck>; -+ clock-names = "fck"; - phy-type = <2>; /* DDR PHY type: Intelli PHY */ - reg = <0x4d000000 0x400>; - interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; -@@ -626,18 +822,25 @@ - hw-caps-temp-alert; - }; - -- omap_control_usb: omap-control-usb@4a002300 { -- compatible = "ti,omap-control-usb"; -- reg = <0x4a002300 0x4>, -- <0x4a002370 0x4>; -- reg-names = "control_dev_conf", "phy_power_usb"; -- ti,type = <2>; -+ omap_control_usb2phy: control-phy@4a002300 { -+ compatible = "ti,control-phy-usb2"; -+ reg = <0x4a002300 0x4>; -+ reg-names = "power"; -+ }; -+ -+ omap_control_usb3phy: control-phy@4a002370 { -+ compatible = "ti,control-phy-pipe3"; -+ reg = <0x4a002370 0x4>; -+ reg-names = "power"; - }; - -- omap_dwc3@4a020000 { -+ usb3: omap_dwc3@4a020000 { - compatible = "ti,dwc3"; - ti,hwmods = "usb_otg_ss"; -+ clocks = <&dpll_core_h13x2_ck>, <&usb_otg_ss_refclk960m>; -+ clock-names = "fck", "refclk960m"; - reg = <0x4a020000 0x10000>; -+ - interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <1>; -@@ -647,7 +850,10 @@ - compatible = "snps,dwc3"; - reg = <0x4a030000 0x10000>; - interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; -- usb-phy = <&usb2_phy>, <&usb3_phy>; -+ phys = <&usb2_phy>, <&usb3_phy>; -+ phy-names = "usb2-phy", "usb3-phy"; -+ maximum-speed = "super-speed"; -+ dr_mode = "peripheral"; - tx-fifo-resize; - }; - }; -@@ -662,16 +868,26 @@ - usb2_phy: usb2phy@4a084000 { - compatible = "ti,omap-usb2"; - reg = <0x4a084000 0x7c>; -- ctrl-module = <&omap_control_usb>; -+ ctrl-module = <&omap_control_usb2phy>; -+ clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>; -+ clock-names = "wkupclk", "refclk"; -+ #phy-cells = <0>; - }; - - usb3_phy: usb3phy@4a084400 { -- compatible = "ti,omap-usb3"; -+ compatible = "ti,phy-pipe3-usb3"; - reg = <0x4a084400 0x80>, - <0x4a084800 0x64>, - <0x4a084c00 0x40>; - reg-names = "phy_rx", "phy_tx", "pll_ctrl"; -- ctrl-module = <&omap_control_usb>; -+ ctrl-module = <&omap_control_usb3phy>; -+ clocks = <&usb_phy_cm_clk32k>, -+ <&usb_otg_ss_refclk960m>, -+ <&dpll_core_h13x2_ck>; -+ clock-names = "wkupclk", -+ "refclk", -+ "refclk2"; -+ #phy-cells = <0>; - }; - }; - -@@ -689,6 +905,8 @@ - #address-cells = <1>; - #size-cells = <1>; - ranges; -+ clocks = <&l3init_60m_fclk>; -+ clock-names = "init_60m_fclk"; - - usbhsohci: ohci@4a064800 { - compatible = "ti,ohci-omap3", "usb-ohci"; -@@ -713,5 +931,71 @@ - interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; - compatible = "ti,omap5430-bandgap"; - }; -+ -+ dss@58000000 { -+ compatible = "ti,omap4-dss", "simple-bus"; -+ reg = <0x58000000 0x80>; -+ ti,hwmods = "dss_core"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ dispc@58001000 { -+ compatible = "ti,omap4-dispc"; -+ reg = <0x58001000 0x1000>; -+ interrupts = <0 25 0x4>; -+ ti,hwmods = "dss_dispc"; -+ }; -+ -+ dpi: encoder@0 { -+ compatible = "ti,omap4-dpi"; -+ }; -+ -+ rfbi: encoder@58002000 { -+ compatible = "ti,omap4-rfbi"; -+ reg = <0x58002000 0x1000>; -+ ti,hwmods = "dss_rfbi"; -+ }; -+ -+ dsi1: encoder@58004000 { -+ compatible = "ti,omap4-dsi"; -+ reg = <0x58004000 0x200>; -+ interrupts = <0 53 0x4>; -+ ti,hwmods = "dss_dsi1"; -+ }; -+ -+ dsi2: encoder@58005000 { -+ compatible = "ti,omap4-dsi"; -+ reg = <0x58005000 0x200>; -+ interrupts = <0 84 0x4>; -+ ti,hwmods = "dss_dsi2"; -+ }; -+ -+ hdmi: encoder@58060000 { -+ compatible = "ti,omap5-hdmi"; -+ reg = <0x58040000 0x200>, -+ <0x58040200 0x100>, -+ <0x58040300 0x100>, -+ <0x58060000 0x19000>; -+ reg-names = "hdmi_wp", "hdmi_pllctrl", -+ "hdmi_txphy", "hdmi_core"; -+ interrupts = <0 101 0x4>; -+ ti,hwmods = "dss_hdmi"; -+ }; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ /include/ "omap54xx-clocks.dtsi" -+ }; -+ -+ clockdomains { -+ l3init_clkdm: l3init_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dpll_usb_ck>; -+ }; - }; - }; ---- a/arch/arm/boot/dts/omap5-uevm.dts -+++ b/arch/arm/boot/dts/omap5-uevm.dts -@@ -27,45 +27,19 @@ - regulator-max-microvolt = <3000000>; - }; - -- /* HS USB Port 2 RESET */ -- hsusb2_reset: hsusb2_reset_reg { -- compatible = "regulator-fixed"; -- regulator-name = "hsusb2_reset"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>; /* gpio3_80 HUB_NRESET */ -- startup-delay-us = <70000>; -- enable-active-high; -- }; -- - /* HS USB Host PHY on PORT 2 */ - hsusb2_phy: hsusb2_phy { - compatible = "usb-nop-xceiv"; -- reset-supply = <&hsusb2_reset>; -- /** -- * FIXME -- * Put the right clock phandle here when available -- * clocks = <&auxclk1>; -- * clock-names = "main_clk"; -- */ -+ reset-gpios = <&gpio3 16 GPIO_ACTIVE_LOW>; /* gpio3_80 HUB_NRESET */ -+ clocks = <&auxclk1_ck>; -+ clock-names = "main_clk"; - clock-frequency = <19200000>; - }; - -- /* HS USB Port 3 RESET */ -- hsusb3_reset: hsusb3_reset_reg { -- compatible = "regulator-fixed"; -- regulator-name = "hsusb3_reset"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; /* gpio3_79 ETH_NRESET */ -- startup-delay-us = <70000>; -- enable-active-high; -- }; -- - /* HS USB Host PHY on PORT 3 */ - hsusb3_phy: hsusb3_phy { - compatible = "usb-nop-xceiv"; -- reset-supply = <&hsusb3_reset>; -+ reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; /* gpio3_79 ETH_NRESET */ - }; - - leds { -@@ -77,6 +51,28 @@ - default-state = "off"; - }; - }; -+ -+ sound: sound { -+ compatible = "ti,abe-twl6040"; -+ ti,model = "omap5-uevm"; -+ -+ ti,mclk-freq = <19200000>; -+ -+ ti,mcpdm = <&mcpdm>; -+ -+ ti,twl6040 = <&twl6040>; -+ -+ /* Audio routing */ -+ ti,audio-routing = -+ "Headset Stereophone", "HSOL", -+ "Headset Stereophone", "HSOR", -+ "Line Out", "AUXL", -+ "Line Out", "AUXR", -+ "HSMIC", "Headset Mic", -+ "Headset Mic", "Headset Mic Bias", -+ "AFML", "Line In", -+ "AFMR", "Line In"; -+ }; - }; - - &omap5_pmx_core { -@@ -84,16 +80,18 @@ - pinctrl-0 = < - &twl6040_pins - &mcpdm_pins -- &dmic_pins - &mcbsp1_pins - &mcbsp2_pins - &usbhost_pins - &led_gpio_pins -+ &dss_hdmi_pins -+ &tpd12s015_pins -+ &palmas_pins - >; - - twl6040_pins: pinmux_twl6040_pins { - pinctrl-single,pins = < -- 0x18a (PIN_OUTPUT | MUX_MODE6) /* perslimbus2_clock.gpio5_145 */ -+ 0x17e (PIN_OUTPUT | MUX_MODE6) /* mcspi1_somi.gpio5_141 */ - >; - }; - -@@ -107,15 +105,6 @@ - >; - }; - -- dmic_pins: pinmux_dmic_pins { -- pinctrl-single,pins = < -- 0x144 (PIN_INPUT | MUX_MODE0) /* abedmic_din1.abedmic_din1 */ -- 0x146 (PIN_INPUT | MUX_MODE0) /* abedmic_din2.abedmic_din2 */ -- 0x148 (PIN_INPUT | MUX_MODE0) /* abedmic_din3.abedmic_din3 */ -- 0x14a (PIN_OUTPUT | MUX_MODE0) /* abedmic_clk1.abedmic_clk1 */ -- >; -- }; -- - mcbsp1_pins: pinmux_mcbsp1_pins { - pinctrl-single,pins = < - 0x14c (PIN_INPUT | MUX_MODE1) /* abedmic_clk2.abemcbsp1_fsx */ -@@ -143,8 +132,14 @@ - - i2c5_pins: pinmux_i2c5_pins { - pinctrl-single,pins = < -- 0x184 (PIN_INPUT | MUX_MODE0) /* i2c5_scl */ -- 0x186 (PIN_INPUT | MUX_MODE0) /* i2c5_sda */ -+ 0x186 (PIN_INPUT | MUX_MODE0) /* i2c5_scl */ -+ 0x188 (PIN_INPUT | MUX_MODE0) /* i2c5_sda */ -+ >; -+ }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x194 (PIN_INPUT | MUX_MODE6) /* gpio5_152 */ - >; - }; - -@@ -153,25 +148,25 @@ - 0xbc (PIN_INPUT | MUX_MODE0) /* mcspi2_clk */ - 0xbe (PIN_INPUT | MUX_MODE0) /* mcspi2_simo */ - 0xc0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi2_somi */ -- 0xc2 (PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs */ -+ 0xc2 (PIN_OUTPUT | MUX_MODE0) /* mcspi2_cs0 */ - >; - }; - - mcspi3_pins: pinmux_mcspi3_pins { - pinctrl-single,pins = < -- 0x78 (PIN_INPUT | MUX_MODE1) /* mcspi2_somi */ -- 0x7a (PIN_INPUT | MUX_MODE1) /* mcspi2_cs */ -- 0x7c (PIN_INPUT | MUX_MODE1) /* mcspi2_simo */ -- 0x7e (PIN_INPUT | MUX_MODE1) /* mcspi2_clk */ -+ 0x78 (PIN_INPUT | MUX_MODE1) /* mcspi3_somi */ -+ 0x7a (PIN_INPUT | MUX_MODE1) /* mcspi3_cs0 */ -+ 0x7c (PIN_INPUT | MUX_MODE1) /* mcspi3_simo */ -+ 0x7e (PIN_INPUT | MUX_MODE1) /* mcspi3_clk */ - >; - }; - - mcspi4_pins: pinmux_mcspi4_pins { - pinctrl-single,pins = < -- 0x164 (PIN_INPUT | MUX_MODE1) /* mcspi2_clk */ -- 0x168 (PIN_INPUT | MUX_MODE1) /* mcspi2_simo */ -- 0x16a (PIN_INPUT | MUX_MODE1) /* mcspi2_somi */ -- 0x16c (PIN_INPUT | MUX_MODE1) /* mcspi2_cs */ -+ 0x164 (PIN_INPUT | MUX_MODE1) /* mcspi4_clk */ -+ 0x168 (PIN_INPUT | MUX_MODE1) /* mcspi4_simo */ -+ 0x16a (PIN_INPUT | MUX_MODE1) /* mcspi4_somi */ -+ 0x16c (PIN_INPUT | MUX_MODE1) /* mcspi4_cs0 */ - >; - }; - -@@ -219,6 +214,25 @@ - >; - }; - -+ dss_hdmi_pins: pinmux_dss_hdmi_pins { -+ pinctrl-single,pins = < -+ 0x0fc (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ -+ 0x100 (PIN_INPUT | MUX_MODE0) /* DDC-SCL */ -+ 0x102 (PIN_INPUT | MUX_MODE0) /* DDC-SDA */ -+ >; -+ }; -+ -+ tpd12s015_pins: pinmux_tpd12s015_pins { -+ pinctrl-single,pins = < -+ 0x0fe (PIN_INPUT_PULLDOWN | MUX_MODE6) /* hdmi_hpd.gpio7_193 */ -+ >; -+ }; -+ -+ palmas_pins: pinmux_palmas_pins { -+ pinctrl-single,pins = < -+ 0x140 (PIN_INPUT_PULLUP | MUX_MODE1) /* MSECURE */ -+ >; -+ }; - }; - - &omap5_pmx_wkup { -@@ -235,8 +249,11 @@ - }; - - &mmc1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <&ldo9_reg>; - bus-width = <4>; -+ cd-gpios = <&gpio5 24 0>; /* gpio 152 */ - }; - - &mmc2 { -@@ -259,6 +276,7 @@ - }; - - &i2c1 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins>; - -@@ -272,6 +290,30 @@ - interrupt-controller; - #interrupt-cells = <2>; - -+ extcon_usb3: palmas_usb { -+ compatible = "ti,palmas-usb-vid"; -+ ti,enable-vbus-detection; -+ ti,enable-id-detection; -+ ti,wakeup; -+ }; -+ -+ palmas_rtc: rtc { -+ compatible = "ti,palmas-rtc"; -+ interrupt-parent = <&palmas>; -+ interrupts = <8 IRQ_TYPE_NONE>; -+ ti,backup-battery-chargeable; -+ }; -+ -+ clk32kg: palmas_clk32k@0 { -+ compatible = "ti,palmas-clk32kg"; -+ #clock-cells = <0>; -+ }; -+ -+ clk32kgaudio: palmas_clk32k@1 { -+ compatible = "ti,palmas-clk32kgaudio"; -+ #clock-cells = <0>; -+ }; -+ - palmas_pmic { - compatible = "ti,palmas-pmic"; - interrupt-parent = <&palmas>; -@@ -334,15 +376,22 @@ - ti,smps-range = <0x80>; - }; - -- smps10_reg: smps10 { -+ smps10_out2_reg: smps10_out2 { - /* VBUS_5V_OTG */ -- regulator-name = "smps10"; -+ regulator-name = "smps10_out2"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - regulator-boot-on; - }; - -+ smps10_out1_reg: smps10_out1 { -+ /* VBUS_5V_OTG */ -+ regulator-name = "smps10_out1"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+ - ldo1_reg: ldo1 { - /* VDDAPHY_CAM: vdda_csiport */ - regulator-name = "ldo1"; -@@ -448,13 +497,37 @@ - }; - }; - }; -+ -+ twl6040: twl@4b { -+ compatible = "ti,twl6040"; -+ reg = <0x4b>; -+ -+ interrupts = <GIC_SPI 119 IRQ_TYPE_NONE>; /* IRQ_SYS_2N cascaded to gic */ -+ interrupt-parent = <&gic>; -+ ti,audpwron-gpio = <&gpio5 13 0>; /* gpio line 141 */ -+ -+ vio-supply = <&smps7_reg>; -+ v2v1-supply = <&smps9_reg>; -+ enable-active-high; -+ -+ clocks = <&clk32kgaudio>; -+ clock-names = "clk32k"; -+ }; - }; - - &i2c5 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&i2c5_pins>; - - clock-frequency = <400000>; -+ -+ tca6424a: tca6424a@22 { -+ compatible = "ti,tca6424"; -+ reg = <0x22>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ }; - }; - - &mcbsp3 { -@@ -470,36 +543,91 @@ - phys = <0 &hsusb2_phy &hsusb3_phy>; - }; - --&mcspi1 { -+&usb3 { -+ extcon = <&extcon_usb3>; -+ vbus-supply = <&smps10_out1_reg>; -+}; - -+&mcspi1 { -+ status = "okay"; - }; - - &mcspi2 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mcspi2_pins>; - }; - - &mcspi3 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mcspi3_pins>; - }; - - &mcspi4 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mcspi4_pins>; - }; - - &uart1 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins>; - }; - - &uart3 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart3_pins>; - }; - - &uart5 { -+ status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart5_pins>; - }; -+ -+&hdmi { -+ vdda_hdmi_dac-supply = <&ldo4_reg>; -+}; -+ -+&dsi1 { -+ vdds_dsi-supply = <&ldo4_reg>; -+}; -+ -+&dsi2 { -+ vdds_dsi-supply = <&ldo4_reg>; -+}; -+ -+&cpu0 { -+ cpu0-supply = <&smps123_reg>; -+}; -+ -+/ { -+ aliases { -+ display0 = &hdmi0; -+ ethernet0 = &smsc0; -+ }; -+ -+ tpd12s015: encoder@0 { -+ compatible = "ti,tpd12s015"; -+ -+ video-source = <&hdmi>; -+ -+ gpios = <&tca6424a 0 0>, /* TCA6424A P01, CT CP HPD */ -+ <&tca6424a 1 0>, /* TCA6424A P00, LS OE */ -+ <&gpio7 1 0>; /* GPIO 193, HPD */ -+ }; -+ -+ hdmi0: connector@0 { -+ compatible = "ti,hdmi_connector"; -+ -+ video-source = <&tpd12s015>; -+ }; -+ -+ smsc0: smsc95xx@0 { -+ /* Filled in by U-Boot */ -+ mac-address = [ 00 00 00 00 00 00 ]; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/tps65218.dtsi -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ */ -+ -+&tps { -+ compatible = "ti,tps65218"; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ -+ dcdc1: regulator-dcdc1 { -+ compatible = "ti,tps65218-dcdc1"; -+ }; -+ -+ dcdc2: regulator-dcdc2 { -+ compatible = "ti,tps65218-dcdc2"; -+ }; -+ -+ dcdc3: regulator-dcdc3 { -+ compatible = "ti,tps65218-dcdc3"; -+ }; -+ -+ dcdc4: regulator-dcdc4 { -+ compatible = "ti,tps65218-dcdc4"; -+ }; -+ -+ dcdc5: regulator-dcdc5 { -+ compatible = "ti,tps65218-dcdc5"; -+ }; -+ -+ dcdc6: regulator-dcdc6 { -+ compatible = "ti,tps65218-dcdc6"; -+ }; -+ -+ ldo1: regulator-ldo1 { -+ compatible = "ti,tps65218-ldo1"; -+ }; -+}; ---- a/arch/arm/boot/dts/twl4030.dtsi -+++ b/arch/arm/boot/dts/twl4030.dtsi -@@ -86,6 +86,7 @@ - usb1v8-supply = <&vusb1v8>; - usb3v1-supply = <&vusb3v1>; - usb_mode = <1>; -+ #phy-cells = <0>; - }; - - twl_pwm: pwm { ---- a/arch/arm/boot/Makefile -+++ b/arch/arm/boot/Makefile -@@ -55,6 +55,9 @@ $(obj)/zImage: $(obj)/compressed/vmlinux - $(call if_changed,objcopy) - @$(kecho) ' Kernel: $@ is ready' - -+$(obj)/zImage-dtb.%: $(obj)/dts/%.dtb $(obj)/zImage -+ cat $(obj)/zImage $< > $@ -+ - endif - - ifneq ($(LOADADDR),) -@@ -80,6 +83,10 @@ $(obj)/uImage: $(obj)/zImage FORCE - $(call if_changed,uimage) - @$(kecho) ' Image $@ is ready' - -+$(obj)/uImage.%: $(obj)/zImage-dtb.% FORCE -+ $(call if_changed,uimage) -+ @echo ' Image $@ is ready' -+ - $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE - $(Q)$(MAKE) $(build)=$(obj)/bootp $@ - @: ---- a/arch/arm/configs/omap2plus_defconfig -+++ b/arch/arm/configs/omap2plus_defconfig -@@ -26,11 +26,13 @@ CONFIG_ARCH_OMAP2=y - CONFIG_ARCH_OMAP3=y - CONFIG_ARCH_OMAP4=y - CONFIG_SOC_AM33XX=y -+CONFIG_SOC_AM43XX=y - CONFIG_OMAP_RESET_CLOCKS=y - CONFIG_OMAP_MUX_DEBUG=y - CONFIG_ARCH_VEXPRESS_CA9X4=y - CONFIG_ARM_THUMBEE=y - CONFIG_ARM_ERRATA_411920=y -+CONFIG_OMAP4_ERRATA_I688=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_SMP=y -@@ -42,6 +44,14 @@ CONFIG_ARM_APPENDED_DTB=y - CONFIG_ARM_ATAG_DTB_COMPAT=y - CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200" - CONFIG_KEXEC=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_GENERIC_CPUFREQ_CPU0=y -+# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set - CONFIG_FPE_NWFPE=y - CONFIG_BINFMT_MISC=y - CONFIG_PM_DEBUG=y -@@ -60,6 +70,7 @@ CONFIG_IP_PNP_RARP=y - # CONFIG_INET_LRO is not set - # CONFIG_IPV6 is not set - CONFIG_NETFILTER=y -+CONFIG_VLAN_8021Q=y - CONFIG_CAN=m - CONFIG_CAN_RAW=m - CONFIG_CAN_BCM=m -@@ -82,6 +93,7 @@ CONFIG_DMA_CMA=y - CONFIG_CONNECTOR=y - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_OMAP_OCP2SCP=y - CONFIG_MTD=y - CONFIG_MTD_CMDLINE_PARTS=y - CONFIG_MTD_CHAR=y -@@ -89,8 +101,11 @@ CONFIG_MTD_BLOCK=y - CONFIG_MTD_OOPS=y - CONFIG_MTD_CFI=y - CONFIG_MTD_CFI_INTELEXT=y -+CONFIG_MTD_M25P80=y -+# CONFIG_M25PXX_USE_FAST_READ is not set - CONFIG_MTD_NAND=y - CONFIG_MTD_NAND_OMAP2=y -+CONFIG_MTD_NAND_OMAP_BCH=y - CONFIG_MTD_ONENAND=y - CONFIG_MTD_ONENAND_VERIFY_WRITE=y - CONFIG_MTD_ONENAND_OMAP2=y -@@ -106,6 +121,9 @@ CONFIG_SCSI=y - CONFIG_BLK_DEV_SD=y - CONFIG_SCSI_MULTI_LUN=y - CONFIG_SCSI_SCAN_ASYNC=y -+CONFIG_ATA=y -+CONFIG_SATA_AHCI_PLATFORM=y -+CONFIG_SATA_TI=y - CONFIG_MD=y - CONFIG_NETDEVICES=y - CONFIG_SMSC_PHY=y -@@ -131,6 +149,9 @@ CONFIG_KEYBOARD_MATRIX=m - CONFIG_KEYBOARD_TWL4030=y - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=y -+CONFIG_TOUCHSCREEN_ATMEL_MXT=y -+CONFIG_TOUCHSCREEN_TI_AM335X_TSC=y -+CONFIG_TOUCHSCREEN_PIXCIR=m - CONFIG_INPUT_MISC=y - CONFIG_INPUT_TWL4030_PWRBUTTON=y - CONFIG_VT_HW_CONSOLE_BINDING=y -@@ -151,10 +172,14 @@ CONFIG_HW_RANDOM=y - CONFIG_I2C_CHARDEV=y - CONFIG_SPI=y - CONFIG_SPI_OMAP24XX=y -+CONFIG_SPI_TI_QSPI=y - CONFIG_PINCTRL_SINGLE=y - CONFIG_DEBUG_GPIO=y - CONFIG_GPIO_SYSFS=y - CONFIG_GPIO_TWL4030=y -+CONFIG_GPIOLIB=y -+CONFIG_I2C=y -+CONFIG_GPIO_PCF857X=y - CONFIG_W1=y - CONFIG_POWER_SUPPLY=y - CONFIG_SENSORS_LM75=m -@@ -168,31 +193,52 @@ CONFIG_THERMAL_GOV_USER_SPACE=y - CONFIG_CPU_THERMAL=y - CONFIG_OMAP_WATCHDOG=y - CONFIG_TWL4030_WATCHDOG=y -+CONFIG_MFD_TI_AM335X_TSCADC=y -+CONFIG_MFD_PALMAS=y - CONFIG_MFD_TPS65217=y - CONFIG_MFD_TPS65910=y - CONFIG_TWL6040_CORE=y - CONFIG_REGULATOR_TWL4030=y -+CONFIG_REGULATOR_TIAVSCLASS0=y - CONFIG_REGULATOR_TPS65023=y - CONFIG_REGULATOR_TPS6507X=y - CONFIG_REGULATOR_TPS65217=y - CONFIG_REGULATOR_TPS65910=y -+CONFIG_REGULATOR_PALMAS=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_VIDEO_DEV=m -+CONFIG_VIDEO_V4L2=m -+CONFIG_VIDEOBUF2_CORE=m -+CONFIG_VIDEOBUF2_MEMOPS=m -+CONFIG_VIDEOBUF2_VMALLOC=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m - CONFIG_FB=y - CONFIG_FIRMWARE_EDID=y - CONFIG_FB_MODE_HELPERS=y - CONFIG_FB_TILEBLITTING=y - CONFIG_FB_OMAP_LCD_VGA=y --CONFIG_OMAP2_DSS=m -+CONFIG_FB_DA8XX=y -+CONFIG_FB_DA8XX_TDA998X=y -+CONFIG_OMAP2_DSS=y - CONFIG_OMAP2_DSS_RFBI=y - CONFIG_OMAP2_DSS_SDI=y - CONFIG_OMAP2_DSS_DSI=y --CONFIG_FB_OMAP2=m --CONFIG_DISPLAY_ENCODER_TFP410=m --CONFIG_DISPLAY_ENCODER_TPD12S015=m --CONFIG_DISPLAY_CONNECTOR_DVI=m --CONFIG_DISPLAY_CONNECTOR_HDMI=m --CONFIG_DISPLAY_PANEL_DPI=m -+CONFIG_FB_OMAP2=y -+CONFIG_DISPLAY_ENCODER_TFP410=y -+CONFIG_DISPLAY_ENCODER_TPD12S015=y -+CONFIG_DISPLAY_DRA_EVM_ENCODER_TPD12S015=y -+CONFIG_DISPLAY_CONNECTOR_DVI=y -+CONFIG_DISPLAY_CONNECTOR_HDMI=y -+CONFIG_DISPLAY_PANEL_DPI=y -+CONFIG_DISPLAY_PANEL_TFCS9700=y - CONFIG_BACKLIGHT_LCD_SUPPORT=y - CONFIG_LCD_CLASS_DEVICE=y -+CONFIG_BACKLIGHT_CLASS_DEVICE=y -+CONFIG_BACKLIGHT_PWM=y - CONFIG_LCD_PLATFORM=y - CONFIG_DISPLAY_SUPPORT=y - CONFIG_FRAMEBUFFER_CONSOLE=y -@@ -210,25 +256,57 @@ CONFIG_SND_DEBUG=y - CONFIG_SND_USB_AUDIO=m - CONFIG_SND_SOC=m - CONFIG_SND_OMAP_SOC=m -+CONFIG_SND_AM33XX_SOC_EVM=m -+CONFIG_SND_DAVINCI_SOC=m - CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m - CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m - CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m - CONFIG_USB=y --CONFIG_USB_DEBUG=y - CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_DEVICEFS=y - CONFIG_USB_MON=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_MUSB_HDRC=y -+CONFIG_USB_MUSB_OMAP2PLUS=m -+CONFIG_USB_MUSB_DSPS=m - CONFIG_USB_WDM=y - CONFIG_USB_STORAGE=y - CONFIG_USB_LIBUSUAL=y - CONFIG_USB_TEST=y -+CONFIG_AM335X_PHY_USB=y -+CONFIG_TWL6030_USB=y - CONFIG_USB_PHY=y - CONFIG_NOP_USB_XCEIV=y -+ -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_OMAP=y -+ - CONFIG_USB_GADGET=y - CONFIG_USB_GADGET_DEBUG=y - CONFIG_USB_GADGET_DEBUG_FILES=y - CONFIG_USB_GADGET_DEBUG_FS=y - CONFIG_USB_ZERO=m -+CONFIG_USB_AUDIO=m -+CONFIG_USB_ETH=m -+CONFIG_USB_G_NCM=m -+CONFIG_USB_GADGETFS=m -+CONFIG_USB_FUNCTIONFS=m -+CONFIG_USB_FUNCTIONFS_ETH=y -+CONFIG_USB_FUNCTIONFS_RNDIS=y -+CONFIG_USB_FUNCTIONFS_GENERIC=y -+CONFIG_USB_MASS_STORAGE=m -+CONFIG_USB_G_SERIAL=m -+CONFIG_USB_MIDI_GADGET=m -+CONFIG_USB_G_PRINTER=m -+CONFIG_USB_CDC_COMPOSITE=m -+CONFIG_USB_G_ACM_MS=m -+CONFIG_USB_G_MULTI=m -+CONFIG_USB_G_MULTI_CDC=y -+CONFIG_USB_G_HID=m -+CONFIG_USB_G_DBGP=m -+CONFIG_USB_G_WEBCAM=m - CONFIG_MMC=y - CONFIG_MMC_UNSAFE_RESUME=y - CONFIG_SDIO_UART=y -@@ -249,14 +327,35 @@ CONFIG_RTC_CLASS=y - CONFIG_RTC_DRV_TWL92330=y - CONFIG_RTC_DRV_TWL4030=y - CONFIG_RTC_DRV_OMAP=y -+CONFIG_RTC_DRV_PALMAS=y - CONFIG_DMADEVICES=y - CONFIG_TI_EDMA=y - CONFIG_DMA_OMAP=y -+CONFIG_PWM=y -+CONFIG_COMMON_CLK_DEBUG=y -+CONFIG_PWM_TIECAP=m -+CONFIG_PWM_TIEHRPWM=m - CONFIG_TI_SOC_THERMAL=y - CONFIG_TI_THERMAL=y - CONFIG_OMAP4_THERMAL=y - CONFIG_OMAP5_THERMAL=y - CONFIG_DRA752_THERMAL=y -+ -+CONFIG_EXTCON=y -+CONFIG_EXTCON_PALMAS=y -+CONFIG_EXTCON_GPIO_USBVID=y -+ -+CONFIG_GENERIC_PHY=y -+CONFIG_OMAP_CONTROL_PHY=y -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER=y -+CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_KFIFO_BUF=m -+CONFIG_TI_AM335X_ADC=m -+CONFIG_OMAP_USB2=y -+CONFIG_OMAP_PIPE3=y -+CONFIG_TWL4030_USB=y -+ - CONFIG_EXT2_FS=y - CONFIG_EXT3_FS=y - # CONFIG_EXT3_FS_XATTR is not set -@@ -295,6 +394,10 @@ CONFIG_DEBUG_INFO=y - CONFIG_SECURITY=y - CONFIG_CRYPTO_MICHAEL_MIC=y - # CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DEV_OMAP_SHAM=y -+CONFIG_CRYPTO_DEV_OMAP_AES=y -+CONFIG_CRYPTO_DEV_OMAP_DES=y -+CONFIG_CRYPTO_TEST=m - CONFIG_CRC_CCITT=y - CONFIG_CRC_T10DIF=y - CONFIG_CRC_ITU_T=y -@@ -306,3 +409,4 @@ CONFIG_TI_DAVINCI_CPDMA=y - CONFIG_TI_CPSW=y - CONFIG_AT803X_PHY=y - CONFIG_SOC_DRA7XX=y -+CONFIG_GPIO_PCA953X=y ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -873,10 +873,33 @@ config ARCH_OMAP1 - help - Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx) - -+config ARCH_OMAP2PLUS -+ bool "TI OMAP2+" -+ depends on MMU -+ select ARCH_HAS_BANDGAP -+ select ARCH_HAS_CPUFREQ -+ select ARCH_HAS_HOLES_MEMORYMODEL -+ select ARCH_OMAP -+ select ARCH_REQUIRE_GPIOLIB -+ select CLKDEV_LOOKUP -+ select CLKSRC_MMIO -+ select GENERIC_CLOCKEVENTS -+ select GENERIC_IRQ_CHIP -+ select HAVE_CLK -+ select OMAP_DM_TIMER -+ select PINCTRL -+ select PROC_DEVICETREE if PROC_FS -+ select SOC_BUS -+ select SPARSE_IRQ -+ select TI_PRIV_EDMA -+ select USE_OF -+ select AUTO_ZRELADDR -+ help -+ SUpport for OMAP2, OMAP3, OMAP4 and OMAP5 -+ - endchoice - - menu "Multiple platform selection" -- depends on ARCH_MULTIPLATFORM - - comment "CPU Core family selection" - -@@ -1606,6 +1629,7 @@ config ARCH_NR_GPIO - default 352 if ARCH_VT8500 - default 288 if ARCH_SUNXI - default 264 if MACH_H4700 -+ default 192 if SOC_AM43XX - default 0 - help - Maximum number of GPIOs in the system. ---- a/arch/arm/Kconfig.debug -+++ b/arch/arm/Kconfig.debug -@@ -1077,7 +1077,7 @@ config DEBUG_UNCOMPRESS - - config UNCOMPRESS_INCLUDE - string -- default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM -+ default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || ARCH_OMAP - default "mach/uncompress.h" - - config EARLY_PRINTK ---- a/arch/arm/kernel/head.S -+++ b/arch/arm/kernel/head.S -@@ -534,7 +534,8 @@ smp_on_up: - __do_fixup_smp_on_up: - cmp r4, r5 - movhs pc, lr -- ldmia r4!, {r0, r6} -+ ldmia r4!, {r0} -+ ldmia r4!, {r6} - ARM( str r6, [r0, r3] ) - THUMB( add r0, r0, r3 ) - #ifdef __ARMEB__ ---- a/arch/arm/mach-omap2/am33xx-restart.c -+++ b/arch/arm/mach-omap2/am33xx-restart.c -@@ -9,6 +9,7 @@ - #include <linux/reboot.h> - - #include "common.h" -+#include "prcm43xx.h" - #include "prm-regbits-33xx.h" - #include "prm33xx.h" - -@@ -33,3 +34,25 @@ void am33xx_restart(enum reboot_mode mod - (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, - AM33XX_PRM_RSTCTRL_OFFSET); - } -+ -+/** -+ * am43xx_restart - trigger a software restart of the SoC -+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c -+ * @cmd: passed fr-om the userspace program rebooting the system (if provided) -+ * -+ * Resets the SoC. For @cmd, see the 'reboot' syscall in -+ * kernel/sys.c. No return value. -+ */ -+void am43xx_restart(enum reboot_mode mode, const char *cmd) -+{ -+ /* TODO: Handle mode and cmd if necessary */ -+ -+ am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, -+ AM33XX_RST_GLOBAL_WARM_SW_MASK, -+ AM43XX_PRM_DEVICE_INST, -+ AM33XX_PRM_RSTCTRL_OFFSET); -+ -+ /* OCP barrier */ -+ (void)am33xx_prm_read_reg(AM43XX_PRM_DEVICE_INST, -+ AM33XX_PRM_RSTCTRL_OFFSET); -+} ---- a/arch/arm/mach-omap2/board-2430sdp.c -+++ b/arch/arm/mach-omap2/board-2430sdp.c -@@ -246,7 +246,7 @@ static void __init omap_2430sdp_init(voi - omap_hsmmc_init(mmc); - - omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - board_smc91x_init(); ---- a/arch/arm/mach-omap2/board-3430sdp.c -+++ b/arch/arm/mach-omap2/board-3430sdp.c -@@ -607,7 +607,7 @@ static void __init omap_3430sdp_init(voi - omap_ads7846_init(1, gpio_pendown, 310, NULL); - omap_serial_init(); - omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); ---- a/arch/arm/mach-omap2/board-cm-t35.c -+++ b/arch/arm/mach-omap2/board-cm-t35.c -@@ -725,7 +725,7 @@ static void __init cm_t3x_common_init(vo - cm_t35_init_display(); - omap_twl4030_audio_init("cm-t3x", NULL); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - cm_t35_init_usbh(); - cm_t35_init_camera(); ---- a/arch/arm/mach-omap2/board-devkit8000.c -+++ b/arch/arm/mach-omap2/board-devkit8000.c -@@ -628,7 +628,7 @@ static void __init devkit8000_init(void) - - omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - usbhs_init(&usbhs_bdata); - board_nand_init(devkit8000_nand_partitions, ---- a/arch/arm/mach-omap2/board-flash.c -+++ b/arch/arm/mach-omap2/board-flash.c -@@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partit - board_nand_data.nr_parts = nr_parts; - board_nand_data.devsize = nand_type; - -- board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; -+ board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW; - gpmc_nand_init(&board_nand_data, gpmc_t); - } - #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ ---- a/arch/arm/mach-omap2/board-generic.c -+++ b/arch/arm/mach-omap2/board-generic.c -@@ -15,13 +15,11 @@ - #include <linux/of_irq.h> - #include <linux/of_platform.h> - #include <linux/irqdomain.h> --#include <linux/clk.h> - - #include <asm/mach/arch.h> - - #include "common.h" - #include "common-board-devices.h" --#include "dss-common.h" - - #if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) - #define intc_of_init NULL -@@ -36,40 +34,13 @@ static struct of_device_id omap_dt_match - { } - }; - --/* -- * Create alias for USB host PHY clock. -- * Remove this when clock phandle can be provided via DT -- */ --static void __init legacy_init_ehci_clk(char *clkname) --{ -- int ret; -- -- ret = clk_add_alias("main_clk", NULL, clkname, NULL); -- if (ret) { -- pr_err("%s:Failed to add main_clk alias to %s :%d\n", -- __func__, clkname, ret); -- } --} -- - static void __init omap_generic_init(void) - { - omap_sdrc_init(NULL, NULL); - - of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); - -- /* -- * HACK: call display setup code for selected boards to enable omapdss. -- * This will be removed when omapdss supports DT. -- */ -- if (of_machine_is_compatible("ti,omap4-panda")) { -- omap4_panda_display_init_of(); -- legacy_init_ehci_clk("auxclk3_ck"); -- -- } -- else if (of_machine_is_compatible("ti,omap4-sdp")) -- omap_4430sdp_display_init_of(); -- else if (of_machine_is_compatible("ti,omap5-uevm")) -- legacy_init_ehci_clk("auxclk1_ck"); -+ omapdss_init_of(); - } - - #ifdef CONFIG_SOC_OMAP2420 -@@ -165,6 +136,24 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic O - .dt_compat = omap3_gp_boards_compat, - .restart = omap3xxx_restart, - MACHINE_END -+ -+static const char *omap3630_gp_boards_compat[] __initdata = { -+ "ti,omap3-beagle-xm", -+ NULL, -+}; -+ -+DT_MACHINE_START(OMAP3630_GP_DT, "Generic OMAP3630-GP (Flattened Device Tree)") -+ .reserve = omap_reserve, -+ .map_io = omap3_map_io, -+ .init_early = omap3630_init_early, -+ .init_irq = omap_intc_of_init, -+ .handle_irq = omap3_intc_handle_irq, -+ .init_machine = omap_generic_init, -+ .init_late = omap3_init_late, -+ .init_time = omap3_secure_sync32k_timer_init, -+ .dt_compat = omap3630_gp_boards_compat, -+ .restart = omap3xxx_restart, -+MACHINE_END - #endif - - #ifdef CONFIG_SOC_AM33XX -@@ -174,12 +163,14 @@ static const char *am33xx_boards_compat[ - }; - - DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") -- .reserve = omap_reserve, -+ .reserve = am33xx_reserve, - .map_io = am33xx_map_io, - .init_early = am33xx_init_early, -+ .init_late = am33xx_init_late, - .init_irq = omap_intc_of_init, - .handle_irq = omap3_intc_handle_irq, - .init_machine = omap_generic_init, -+ .init_late = am33xx_init_late, - .init_time = omap3_gptimer_timer_init, - .dt_compat = am33xx_boards_compat, - .restart = am33xx_restart, -@@ -219,6 +210,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP - .init_early = omap5_init_early, - .init_irq = omap_gic_of_init, - .init_machine = omap_generic_init, -+ .init_late = omap5_init_late, - .init_time = omap5_realtime_timer_init, - .dt_compat = omap5_boards_compat, - .restart = omap44xx_restart, -@@ -232,12 +224,14 @@ static const char *am43_boards_compat[] - }; - - DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") -+ .reserve = am33xx_reserve, - .map_io = am33xx_map_io, - .init_early = am43xx_init_early, - .init_irq = omap_gic_of_init, - .init_machine = omap_generic_init, - .init_time = omap3_sync32k_timer_init, - .dt_compat = am43_boards_compat, -+ .restart = am43xx_restart, - MACHINE_END - #endif - -@@ -254,6 +248,7 @@ DT_MACHINE_START(DRA7XX_DT, "Generic DRA - .init_early = dra7xx_init_early, - .init_irq = omap_gic_of_init, - .init_machine = omap_generic_init, -+ .init_late = dra7xx_init_late, - .init_time = omap5_realtime_timer_init, - .dt_compat = dra7xx_boards_compat, - .restart = omap44xx_restart, ---- a/arch/arm/mach-omap2/board-igep0020.c -+++ b/arch/arm/mach-omap2/board-igep0020.c -@@ -667,7 +667,7 @@ static void __init igep_init(void) - omap_serial_init(); - omap_sdrc_init(m65kxxxxam_sdrc_params, - m65kxxxxam_sdrc_params); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - igep_flash_init(); ---- a/arch/arm/mach-omap2/board-ldp.c -+++ b/arch/arm/mach-omap2/board-ldp.c -@@ -403,7 +403,7 @@ static void __init omap_ldp_init(void) - omap_ads7846_init(1, 54, 310, NULL); - omap_serial_init(); - omap_sdrc_init(NULL, NULL); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions), - ZOOM_NAND_CS, 0, nand_default_timings); ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -289,18 +289,12 @@ static struct regulator_consumer_supply - - static struct gpio_led gpio_leds[]; - --/* PHY's VCC regulator might be added later, so flag that we need it */ --static struct usb_phy_gen_xceiv_platform_data hsusb2_phy_data = { -- .needs_vcc = true, --}; -- - static struct usbhs_phy_data phy_data[] = { - { - .port = 2, - .reset_gpio = 147, - .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */ - .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */ -- .platform_data = &hsusb2_phy_data, - }, - }; - -@@ -567,7 +561,7 @@ static void __init omap3_beagle_init(voi - omap_sdrc_init(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - usbhs_init(&usbhs_bdata); ---- a/arch/arm/mach-omap2/board-omap3evm.c -+++ b/arch/arm/mach-omap2/board-omap3evm.c -@@ -723,7 +723,7 @@ static void __init omap3_evm_init(void) - omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); - phy_data[0].reset_gpio = 135; - } -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(&musb_board_data); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); ---- a/arch/arm/mach-omap2/board-omap3logic.c -+++ b/arch/arm/mach-omap2/board-omap3logic.c -@@ -216,7 +216,7 @@ static void __init omap3logic_init(void) - board_mmc_init(); - board_smsc911x_init(); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - /* Ensure SDRC pins are mux'd for self-refresh */ ---- a/arch/arm/mach-omap2/board-omap3pandora.c -+++ b/arch/arm/mach-omap2/board-omap3pandora.c -@@ -607,7 +607,7 @@ static void __init omap3pandora_init(voi - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); - usbhs_init(&usbhs_bdata); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - gpmc_nand_init(&pandora_nand_data, NULL); - ---- a/arch/arm/mach-omap2/board-omap3stalker.c -+++ b/arch/arm/mach-omap2/board-omap3stalker.c -@@ -407,7 +407,7 @@ static void __init omap3_stalker_init(vo - - omap_serial_init(); - omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); ---- a/arch/arm/mach-omap2/board-omap3touchbook.c -+++ b/arch/arm/mach-omap2/board-omap3touchbook.c -@@ -367,7 +367,7 @@ static void __init omap3_touchbook_init( - - /* Touchscreen and accelerometer */ - omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); ---- a/arch/arm/mach-omap2/board-overo.c -+++ b/arch/arm/mach-omap2/board-overo.c -@@ -511,7 +511,7 @@ static void __init overo_init(void) - mt46h32m32lf6_sdrc_params); - board_nand_init(overo_nand_partitions, - ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - - usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); ---- a/arch/arm/mach-omap2/board-rm680.c -+++ b/arch/arm/mach-omap2/board-rm680.c -@@ -135,7 +135,7 @@ static void __init rm680_init(void) - sdrc_params = nokia_get_sdram_timings(); - omap_sdrc_init(sdrc_params, sdrc_params); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - rm680_peripherals_init(); - } ---- a/arch/arm/mach-omap2/board-rx51.c -+++ b/arch/arm/mach-omap2/board-rx51.c -@@ -99,7 +99,7 @@ static void __init rx51_init(void) - sdrc_params = nokia_get_sdram_timings(); - omap_sdrc_init(sdrc_params, sdrc_params); - -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(&musb_board_data); - rx51_peripherals_init(); - ---- a/arch/arm/mach-omap2/board-zoom-peripherals.c -+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c -@@ -353,7 +353,7 @@ void __init zoom_peripherals_init(void) - omap_i2c_init(); - pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup)); - platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices)); -- usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); -+ usb_bind_phy("musb-hdrc.0", 0, "twl4030_usb"); - usb_musb_init(NULL); - enable_board_wakeup_source(); - omap_serial_init(); ---- a/arch/arm/mach-omap2/cclock33xx_data.c -+++ /dev/null -@@ -1,1064 +0,0 @@ --/* -- * AM33XX Clock data -- * -- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -- * Vaibhav Hiremath <hvaibhav@ti.com> -- * -- * 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 version 2. -- * -- * This program is distributed "as is" WITHOUT ANY WARRANTY of any -- * kind, whether express or implied; without even the implied warranty -- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- */ -- --#include <linux/kernel.h> --#include <linux/list.h> --#include <linux/clk-private.h> --#include <linux/clkdev.h> --#include <linux/io.h> -- --#include "am33xx.h" --#include "soc.h" --#include "iomap.h" --#include "clock.h" --#include "control.h" --#include "cm.h" --#include "cm33xx.h" --#include "cm-regbits-33xx.h" --#include "prm.h" -- --/* Modulemode control */ --#define AM33XX_MODULEMODE_HWCTRL_SHIFT 0 --#define AM33XX_MODULEMODE_SWCTRL_SHIFT 1 -- --/*LIST_HEAD(clocks);*/ -- --/* Root clocks */ -- --/* RTC 32k */ --DEFINE_CLK_FIXED_RATE(clk_32768_ck, CLK_IS_ROOT, 32768, 0x0); -- --/* On-Chip 32KHz RC OSC */ --DEFINE_CLK_FIXED_RATE(clk_rc32k_ck, CLK_IS_ROOT, 32000, 0x0); -- --/* Crystal input clks */ --DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0); -- --DEFINE_CLK_FIXED_RATE(virt_24000000_ck, CLK_IS_ROOT, 24000000, 0x0); -- --DEFINE_CLK_FIXED_RATE(virt_25000000_ck, CLK_IS_ROOT, 25000000, 0x0); -- --DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0); -- --/* Oscillator clock */ --/* 19.2, 24, 25 or 26 MHz */ --static const char *sys_clkin_ck_parents[] = { -- "virt_19200000_ck", "virt_24000000_ck", "virt_25000000_ck", -- "virt_26000000_ck", --}; -- --/* -- * sys_clk in: input to the dpll and also used as funtional clock for, -- * adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse -- * -- */ --DEFINE_CLK_MUX(sys_clkin_ck, sys_clkin_ck_parents, NULL, 0x0, -- AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS), -- AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT, -- AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH, -- 0, NULL); -- --/* External clock - 12 MHz */ --DEFINE_CLK_FIXED_RATE(tclkin_ck, CLK_IS_ROOT, 12000000, 0x0); -- --/* Module clocks and DPLL outputs */ -- --/* DPLL_CORE */ --static struct dpll_data dpll_core_dd = { -- .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_CORE, -- .clk_bypass = &sys_clkin_ck, -- .clk_ref = &sys_clkin_ck, -- .control_reg = AM33XX_CM_CLKMODE_DPLL_CORE, -- .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -- .idlest_reg = AM33XX_CM_IDLEST_DPLL_CORE, -- .mult_mask = AM33XX_DPLL_MULT_MASK, -- .div1_mask = AM33XX_DPLL_DIV_MASK, -- .enable_mask = AM33XX_DPLL_EN_MASK, -- .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, -- .max_multiplier = 2047, -- .max_divider = 128, -- .min_divider = 1, --}; -- --/* CLKDCOLDO output */ --static const char *dpll_core_ck_parents[] = { -- "sys_clkin_ck", --}; -- --static struct clk dpll_core_ck; -- --static const struct clk_ops dpll_core_ck_ops = { -- .recalc_rate = &omap3_dpll_recalc, -- .get_parent = &omap2_init_dpll_parent, --}; -- --static struct clk_hw_omap dpll_core_ck_hw = { -- .hw = { -- .clk = &dpll_core_ck, -- }, -- .dpll_data = &dpll_core_dd, -- .ops = &clkhwops_omap3_dpll, --}; -- --DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops); -- --static const char *dpll_core_x2_ck_parents[] = { -- "dpll_core_ck", --}; -- --static struct clk dpll_core_x2_ck; -- --static const struct clk_ops dpll_x2_ck_ops = { -- .recalc_rate = &omap3_clkoutx2_recalc, --}; -- --static struct clk_hw_omap dpll_core_x2_ck_hw = { -- .hw = { -- .clk = &dpll_core_x2_ck, -- }, -- .flags = CLOCK_CLKOUTX2, --}; -- --DEFINE_STRUCT_CLK(dpll_core_x2_ck, dpll_core_x2_ck_parents, dpll_x2_ck_ops); -- --DEFINE_CLK_DIVIDER(dpll_core_m4_ck, "dpll_core_x2_ck", &dpll_core_x2_ck, -- 0x0, AM33XX_CM_DIV_M4_DPLL_CORE, -- AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT, -- AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, -- NULL); -- --DEFINE_CLK_DIVIDER(dpll_core_m5_ck, "dpll_core_x2_ck", &dpll_core_x2_ck, -- 0x0, AM33XX_CM_DIV_M5_DPLL_CORE, -- AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT, -- AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH, -- CLK_DIVIDER_ONE_BASED, NULL); -- --DEFINE_CLK_DIVIDER(dpll_core_m6_ck, "dpll_core_x2_ck", &dpll_core_x2_ck, -- 0x0, AM33XX_CM_DIV_M6_DPLL_CORE, -- AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT, -- AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH, -- CLK_DIVIDER_ONE_BASED, NULL); -- -- --/* DPLL_MPU */ --static struct dpll_data dpll_mpu_dd = { -- .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_MPU, -- .clk_bypass = &sys_clkin_ck, -- .clk_ref = &sys_clkin_ck, -- .control_reg = AM33XX_CM_CLKMODE_DPLL_MPU, -- .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -- .idlest_reg = AM33XX_CM_IDLEST_DPLL_MPU, -- .mult_mask = AM33XX_DPLL_MULT_MASK, -- .div1_mask = AM33XX_DPLL_DIV_MASK, -- .enable_mask = AM33XX_DPLL_EN_MASK, -- .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, -- .max_multiplier = 2047, -- .max_divider = 128, -- .min_divider = 1, --}; -- --/* CLKOUT: fdpll/M2 */ --static struct clk dpll_mpu_ck; -- --static const struct clk_ops dpll_mpu_ck_ops = { -- .enable = &omap3_noncore_dpll_enable, -- .disable = &omap3_noncore_dpll_disable, -- .recalc_rate = &omap3_dpll_recalc, -- .round_rate = &omap2_dpll_round_rate, -- .set_rate = &omap3_noncore_dpll_set_rate, -- .get_parent = &omap2_init_dpll_parent, --}; -- --static struct clk_hw_omap dpll_mpu_ck_hw = { -- .hw = { -- .clk = &dpll_mpu_ck, -- }, -- .dpll_data = &dpll_mpu_dd, -- .ops = &clkhwops_omap3_dpll, --}; -- --DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_mpu_ck_ops); -- --/* -- * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 -- * and ALT_CLK1/2) -- */ --DEFINE_CLK_DIVIDER(dpll_mpu_m2_ck, "dpll_mpu_ck", &dpll_mpu_ck, -- 0x0, AM33XX_CM_DIV_M2_DPLL_MPU, AM33XX_DPLL_CLKOUT_DIV_SHIFT, -- AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); -- --/* DPLL_DDR */ --static struct dpll_data dpll_ddr_dd = { -- .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DDR, -- .clk_bypass = &sys_clkin_ck, -- .clk_ref = &sys_clkin_ck, -- .control_reg = AM33XX_CM_CLKMODE_DPLL_DDR, -- .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -- .idlest_reg = AM33XX_CM_IDLEST_DPLL_DDR, -- .mult_mask = AM33XX_DPLL_MULT_MASK, -- .div1_mask = AM33XX_DPLL_DIV_MASK, -- .enable_mask = AM33XX_DPLL_EN_MASK, -- .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, -- .max_multiplier = 2047, -- .max_divider = 128, -- .min_divider = 1, --}; -- --/* CLKOUT: fdpll/M2 */ --static struct clk dpll_ddr_ck; -- --static const struct clk_ops dpll_ddr_ck_ops = { -- .recalc_rate = &omap3_dpll_recalc, -- .get_parent = &omap2_init_dpll_parent, -- .round_rate = &omap2_dpll_round_rate, -- .set_rate = &omap3_noncore_dpll_set_rate, --}; -- --static struct clk_hw_omap dpll_ddr_ck_hw = { -- .hw = { -- .clk = &dpll_ddr_ck, -- }, -- .dpll_data = &dpll_ddr_dd, -- .ops = &clkhwops_omap3_dpll, --}; -- --DEFINE_STRUCT_CLK(dpll_ddr_ck, dpll_core_ck_parents, dpll_ddr_ck_ops); -- --/* -- * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 -- * and ALT_CLK1/2) -- */ --DEFINE_CLK_DIVIDER(dpll_ddr_m2_ck, "dpll_ddr_ck", &dpll_ddr_ck, -- 0x0, AM33XX_CM_DIV_M2_DPLL_DDR, -- AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH, -- CLK_DIVIDER_ONE_BASED, NULL); -- --/* emif_fck functional clock */ --DEFINE_CLK_FIXED_FACTOR(dpll_ddr_m2_div2_ck, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck, -- 0x0, 1, 2); -- --/* DPLL_DISP */ --static struct dpll_data dpll_disp_dd = { -- .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DISP, -- .clk_bypass = &sys_clkin_ck, -- .clk_ref = &sys_clkin_ck, -- .control_reg = AM33XX_CM_CLKMODE_DPLL_DISP, -- .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -- .idlest_reg = AM33XX_CM_IDLEST_DPLL_DISP, -- .mult_mask = AM33XX_DPLL_MULT_MASK, -- .div1_mask = AM33XX_DPLL_DIV_MASK, -- .enable_mask = AM33XX_DPLL_EN_MASK, -- .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, -- .max_multiplier = 2047, -- .max_divider = 128, -- .min_divider = 1, --}; -- --/* CLKOUT: fdpll/M2 */ --static struct clk dpll_disp_ck; -- --static struct clk_hw_omap dpll_disp_ck_hw = { -- .hw = { -- .clk = &dpll_disp_ck, -- }, -- .dpll_data = &dpll_disp_dd, -- .ops = &clkhwops_omap3_dpll, --}; -- --DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops); -- --/* -- * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 -- * and ALT_CLK1/2) -- */ --DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, -- CLK_SET_RATE_PARENT, AM33XX_CM_DIV_M2_DPLL_DISP, -- AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH, -- CLK_DIVIDER_ONE_BASED, NULL); -- --/* DPLL_PER */ --static struct dpll_data dpll_per_dd = { -- .mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_PERIPH, -- .clk_bypass = &sys_clkin_ck, -- .clk_ref = &sys_clkin_ck, -- .control_reg = AM33XX_CM_CLKMODE_DPLL_PER, -- .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -- .idlest_reg = AM33XX_CM_IDLEST_DPLL_PER, -- .mult_mask = AM33XX_DPLL_MULT_PERIPH_MASK, -- .div1_mask = AM33XX_DPLL_PER_DIV_MASK, -- .enable_mask = AM33XX_DPLL_EN_MASK, -- .idlest_mask = AM33XX_ST_DPLL_CLK_MASK, -- .max_multiplier = 2047, -- .max_divider = 128, -- .min_divider = 1, -- .flags = DPLL_J_TYPE, --}; -- --/* CLKDCOLDO */ --static struct clk dpll_per_ck; -- --static struct clk_hw_omap dpll_per_ck_hw = { -- .hw = { -- .clk = &dpll_per_ck, -- }, -- .dpll_data = &dpll_per_dd, -- .ops = &clkhwops_omap3_dpll, --}; -- --DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_ddr_ck_ops); -- --/* CLKOUT: fdpll/M2 */ --DEFINE_CLK_DIVIDER(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0, -- AM33XX_CM_DIV_M2_DPLL_PER, AM33XX_DPLL_CLKOUT_DIV_SHIFT, -- AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, -- NULL); -- --DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_wkupdm_ck, "dpll_per_m2_ck", -- &dpll_per_m2_ck, 0x0, 1, 4); -- --DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_ck, "dpll_per_m2_ck", -- &dpll_per_m2_ck, 0x0, 1, 4); -- --DEFINE_CLK_FIXED_FACTOR(dpll_core_m4_div2_ck, "dpll_core_m4_ck", -- &dpll_core_m4_ck, 0x0, 1, 2); -- --DEFINE_CLK_FIXED_FACTOR(l4_rtc_gclk, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0, -- 1, 2); -- --DEFINE_CLK_FIXED_FACTOR(clk_24mhz, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1, -- 8); -- --/* -- * Below clock nodes describes clockdomains derived out -- * of core clock. -- */ --static const struct clk_ops clk_ops_null = { --}; -- --static const char *l3_gclk_parents[] = { -- "dpll_core_m4_ck" --}; -- --static struct clk l3_gclk; --DEFINE_STRUCT_CLK_HW_OMAP(l3_gclk, NULL); --DEFINE_STRUCT_CLK(l3_gclk, l3_gclk_parents, clk_ops_null); -- --static struct clk l4hs_gclk; --DEFINE_STRUCT_CLK_HW_OMAP(l4hs_gclk, NULL); --DEFINE_STRUCT_CLK(l4hs_gclk, l3_gclk_parents, clk_ops_null); -- --static const char *l3s_gclk_parents[] = { -- "dpll_core_m4_div2_ck" --}; -- --static struct clk l3s_gclk; --DEFINE_STRUCT_CLK_HW_OMAP(l3s_gclk, NULL); --DEFINE_STRUCT_CLK(l3s_gclk, l3s_gclk_parents, clk_ops_null); -- --static struct clk l4fw_gclk; --DEFINE_STRUCT_CLK_HW_OMAP(l4fw_gclk, NULL); --DEFINE_STRUCT_CLK(l4fw_gclk, l3s_gclk_parents, clk_ops_null); -- --static struct clk l4ls_gclk; --DEFINE_STRUCT_CLK_HW_OMAP(l4ls_gclk, NULL); --DEFINE_STRUCT_CLK(l4ls_gclk, l3s_gclk_parents, clk_ops_null); -- --static struct clk sysclk_div_ck; --DEFINE_STRUCT_CLK_HW_OMAP(sysclk_div_ck, NULL); --DEFINE_STRUCT_CLK(sysclk_div_ck, l3_gclk_parents, clk_ops_null); -- --/* -- * In order to match the clock domain with hwmod clockdomain entry, -- * separate clock nodes is required for the modules which are -- * directly getting their funtioncal clock from sys_clkin. -- */ --static struct clk adc_tsc_fck; --DEFINE_STRUCT_CLK_HW_OMAP(adc_tsc_fck, NULL); --DEFINE_STRUCT_CLK(adc_tsc_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk dcan0_fck; --DEFINE_STRUCT_CLK_HW_OMAP(dcan0_fck, NULL); --DEFINE_STRUCT_CLK(dcan0_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk dcan1_fck; --DEFINE_STRUCT_CLK_HW_OMAP(dcan1_fck, NULL); --DEFINE_STRUCT_CLK(dcan1_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk mcasp0_fck; --DEFINE_STRUCT_CLK_HW_OMAP(mcasp0_fck, NULL); --DEFINE_STRUCT_CLK(mcasp0_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk mcasp1_fck; --DEFINE_STRUCT_CLK_HW_OMAP(mcasp1_fck, NULL); --DEFINE_STRUCT_CLK(mcasp1_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk smartreflex0_fck; --DEFINE_STRUCT_CLK_HW_OMAP(smartreflex0_fck, NULL); --DEFINE_STRUCT_CLK(smartreflex0_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk smartreflex1_fck; --DEFINE_STRUCT_CLK_HW_OMAP(smartreflex1_fck, NULL); --DEFINE_STRUCT_CLK(smartreflex1_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk sha0_fck; --DEFINE_STRUCT_CLK_HW_OMAP(sha0_fck, NULL); --DEFINE_STRUCT_CLK(sha0_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk aes0_fck; --DEFINE_STRUCT_CLK_HW_OMAP(aes0_fck, NULL); --DEFINE_STRUCT_CLK(aes0_fck, dpll_core_ck_parents, clk_ops_null); -- --static struct clk rng_fck; --DEFINE_STRUCT_CLK_HW_OMAP(rng_fck, NULL); --DEFINE_STRUCT_CLK(rng_fck, dpll_core_ck_parents, clk_ops_null); -- --/* -- * Modules clock nodes -- * -- * The following clock leaf nodes are added for the moment because: -- * -- * - hwmod data is not present for these modules, either hwmod -- * control is not required or its not populated. -- * - Driver code is not yet migrated to use hwmod/runtime pm -- * - Modules outside kernel access (to disable them by default) -- * -- * - mmu (gfx domain) -- * - cefuse -- * - usbotg_fck (its additional clock and not really a modulemode) -- * - ieee5000 -- */ -- --DEFINE_CLK_GATE(mmu_fck, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0, -- AM33XX_CM_GFX_MMUDATA_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT, -- 0x0, NULL); -- --DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0, -- AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT, -- 0x0, NULL); -- --/* -- * clkdiv32 is generated from fixed division of 732.4219 -- */ --DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732); -- --static struct clk clkdiv32k_ick; -- --static const char *clkdiv32k_ick_parent_names[] = { -- "clkdiv32k_ck", --}; -- --static const struct clk_ops clkdiv32k_ick_ops = { -- .enable = &omap2_dflt_clk_enable, -- .disable = &omap2_dflt_clk_disable, -- .is_enabled = &omap2_dflt_clk_is_enabled, -- .init = &omap2_init_clk_clkdm, --}; -- --static struct clk_hw_omap clkdiv32k_ick_hw = { -- .hw = { -- .clk = &clkdiv32k_ick, -- }, -- .enable_reg = AM33XX_CM_PER_CLKDIV32K_CLKCTRL, -- .enable_bit = AM33XX_MODULEMODE_SWCTRL_SHIFT, -- .clkdm_name = "clk_24mhz_clkdm", --}; -- --DEFINE_STRUCT_CLK(clkdiv32k_ick, clkdiv32k_ick_parent_names, clkdiv32k_ick_ops); -- --/* "usbotg_fck" is an additional clock and not really a modulemode */ --DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0, -- AM33XX_CM_CLKDCOLDO_DPLL_PER, AM33XX_ST_DPLL_CLKDCOLDO_SHIFT, -- 0x0, NULL); -- --DEFINE_CLK_GATE(ieee5000_fck, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck, -- 0x0, AM33XX_CM_PER_IEEE5000_CLKCTRL, -- AM33XX_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); -- --/* Timers */ --static const struct clksel timer1_clkmux_sel[] = { -- { .parent = &sys_clkin_ck, .rates = div_1_0_rates }, -- { .parent = &clkdiv32k_ick, .rates = div_1_1_rates }, -- { .parent = &tclkin_ck, .rates = div_1_2_rates }, -- { .parent = &clk_rc32k_ck, .rates = div_1_3_rates }, -- { .parent = &clk_32768_ck, .rates = div_1_4_rates }, -- { .parent = NULL }, --}; -- --static const char *timer1_ck_parents[] = { -- "sys_clkin_ck", "clkdiv32k_ick", "tclkin_ck", "clk_rc32k_ck", -- "clk_32768_ck", --}; -- --static struct clk timer1_fck; -- --static const struct clk_ops timer1_fck_ops = { -- .recalc_rate = &omap2_clksel_recalc, -- .get_parent = &omap2_clksel_find_parent_index, -- .set_parent = &omap2_clksel_set_parent, -- .init = &omap2_init_clk_clkdm, --}; -- --static struct clk_hw_omap timer1_fck_hw = { -- .hw = { -- .clk = &timer1_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer1_clkmux_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER1MS_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_2_MASK, --}; -- --DEFINE_STRUCT_CLK(timer1_fck, timer1_ck_parents, timer1_fck_ops); -- --static const struct clksel timer2_to_7_clk_sel[] = { -- { .parent = &tclkin_ck, .rates = div_1_0_rates }, -- { .parent = &sys_clkin_ck, .rates = div_1_1_rates }, -- { .parent = &clkdiv32k_ick, .rates = div_1_2_rates }, -- { .parent = NULL }, --}; -- --static const char *timer2_to_7_ck_parents[] = { -- "tclkin_ck", "sys_clkin_ck", "clkdiv32k_ick", --}; -- --static struct clk timer2_fck; -- --static struct clk_hw_omap timer2_fck_hw = { -- .hw = { -- .clk = &timer2_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer2_to_7_clk_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER2_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(timer2_fck, timer2_to_7_ck_parents, timer1_fck_ops); -- --static struct clk timer3_fck; -- --static struct clk_hw_omap timer3_fck_hw = { -- .hw = { -- .clk = &timer3_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer2_to_7_clk_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER3_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(timer3_fck, timer2_to_7_ck_parents, timer1_fck_ops); -- --static struct clk timer4_fck; -- --static struct clk_hw_omap timer4_fck_hw = { -- .hw = { -- .clk = &timer4_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer2_to_7_clk_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER4_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(timer4_fck, timer2_to_7_ck_parents, timer1_fck_ops); -- --static struct clk timer5_fck; -- --static struct clk_hw_omap timer5_fck_hw = { -- .hw = { -- .clk = &timer5_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer2_to_7_clk_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER5_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(timer5_fck, timer2_to_7_ck_parents, timer1_fck_ops); -- --static struct clk timer6_fck; -- --static struct clk_hw_omap timer6_fck_hw = { -- .hw = { -- .clk = &timer6_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer2_to_7_clk_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER6_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(timer6_fck, timer2_to_7_ck_parents, timer1_fck_ops); -- --static struct clk timer7_fck; -- --static struct clk_hw_omap timer7_fck_hw = { -- .hw = { -- .clk = &timer7_fck, -- }, -- .clkdm_name = "l4ls_clkdm", -- .clksel = timer2_to_7_clk_sel, -- .clksel_reg = AM33XX_CLKSEL_TIMER7_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(timer7_fck, timer2_to_7_ck_parents, timer1_fck_ops); -- --DEFINE_CLK_FIXED_FACTOR(cpsw_125mhz_gclk, -- "dpll_core_m5_ck", -- &dpll_core_m5_ck, -- 0x0, -- 1, 2); -- --static const struct clk_ops cpsw_fck_ops = { -- .recalc_rate = &omap2_clksel_recalc, -- .get_parent = &omap2_clksel_find_parent_index, -- .set_parent = &omap2_clksel_set_parent, --}; -- --static const struct clksel cpsw_cpts_rft_clkmux_sel[] = { -- { .parent = &dpll_core_m5_ck, .rates = div_1_0_rates }, -- { .parent = &dpll_core_m4_ck, .rates = div_1_1_rates }, -- { .parent = NULL }, --}; -- --static const char *cpsw_cpts_rft_ck_parents[] = { -- "dpll_core_m5_ck", "dpll_core_m4_ck", --}; -- --static struct clk cpsw_cpts_rft_clk; -- --static struct clk_hw_omap cpsw_cpts_rft_clk_hw = { -- .hw = { -- .clk = &cpsw_cpts_rft_clk, -- }, -- .clkdm_name = "cpsw_125mhz_clkdm", -- .clksel = cpsw_cpts_rft_clkmux_sel, -- .clksel_reg = AM33XX_CM_CPTS_RFT_CLKSEL, -- .clksel_mask = AM33XX_CLKSEL_0_0_MASK, --}; -- --DEFINE_STRUCT_CLK(cpsw_cpts_rft_clk, cpsw_cpts_rft_ck_parents, cpsw_fck_ops); -- -- --/* gpio */ --static const char *gpio0_ck_parents[] = { -- "clk_rc32k_ck", "clk_32768_ck", "clkdiv32k_ick", --}; -- --static const struct clksel gpio0_dbclk_mux_sel[] = { -- { .parent = &clk_rc32k_ck, .rates = div_1_0_rates }, -- { .parent = &clk_32768_ck, .rates = div_1_1_rates }, -- { .parent = &clkdiv32k_ick, .rates = div_1_2_rates }, -- { .parent = NULL }, --}; -- --static const struct clk_ops gpio_fck_ops = { -- .recalc_rate = &omap2_clksel_recalc, -- .get_parent = &omap2_clksel_find_parent_index, -- .set_parent = &omap2_clksel_set_parent, -- .init = &omap2_init_clk_clkdm, --}; -- --static struct clk gpio0_dbclk_mux_ck; -- --static struct clk_hw_omap gpio0_dbclk_mux_ck_hw = { -- .hw = { -- .clk = &gpio0_dbclk_mux_ck, -- }, -- .clkdm_name = "l4_wkup_clkdm", -- .clksel = gpio0_dbclk_mux_sel, -- .clksel_reg = AM33XX_CLKSEL_GPIO0_DBCLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(gpio0_dbclk_mux_ck, gpio0_ck_parents, gpio_fck_ops); -- --DEFINE_CLK_GATE(gpio0_dbclk, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, 0x0, -- AM33XX_CM_WKUP_GPIO0_CLKCTRL, -- AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT, 0x0, NULL); -- --DEFINE_CLK_GATE(gpio1_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0, -- AM33XX_CM_PER_GPIO1_CLKCTRL, -- AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT, 0x0, NULL); -- --DEFINE_CLK_GATE(gpio2_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0, -- AM33XX_CM_PER_GPIO2_CLKCTRL, -- AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT, 0x0, NULL); -- --DEFINE_CLK_GATE(gpio3_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0, -- AM33XX_CM_PER_GPIO3_CLKCTRL, -- AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT, 0x0, NULL); -- -- --static const char *pruss_ck_parents[] = { -- "l3_gclk", "dpll_disp_m2_ck", --}; -- --static const struct clksel pruss_ocp_clk_mux_sel[] = { -- { .parent = &l3_gclk, .rates = div_1_0_rates }, -- { .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates }, -- { .parent = NULL }, --}; -- --static struct clk pruss_ocp_gclk; -- --static struct clk_hw_omap pruss_ocp_gclk_hw = { -- .hw = { -- .clk = &pruss_ocp_gclk, -- }, -- .clkdm_name = "pruss_ocp_clkdm", -- .clksel = pruss_ocp_clk_mux_sel, -- .clksel_reg = AM33XX_CLKSEL_PRUSS_OCP_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_0_MASK, --}; -- --DEFINE_STRUCT_CLK(pruss_ocp_gclk, pruss_ck_parents, gpio_fck_ops); -- --static const char *lcd_ck_parents[] = { -- "dpll_disp_m2_ck", "dpll_core_m5_ck", "dpll_per_m2_ck", --}; -- --static const struct clksel lcd_clk_mux_sel[] = { -- { .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates }, -- { .parent = &dpll_core_m5_ck, .rates = div_1_1_rates }, -- { .parent = &dpll_per_m2_ck, .rates = div_1_2_rates }, -- { .parent = NULL }, --}; -- --static struct clk lcd_gclk; -- --static struct clk_hw_omap lcd_gclk_hw = { -- .hw = { -- .clk = &lcd_gclk, -- }, -- .clkdm_name = "lcdc_clkdm", -- .clksel = lcd_clk_mux_sel, -- .clksel_reg = AM33XX_CLKSEL_LCDC_PIXEL_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK_FLAGS(lcd_gclk, lcd_ck_parents, -- gpio_fck_ops, CLK_SET_RATE_PARENT); -- --DEFINE_CLK_FIXED_FACTOR(mmc_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1, 2); -- --static const char *gfx_ck_parents[] = { -- "dpll_core_m4_ck", "dpll_per_m2_ck", --}; -- --static const struct clksel gfx_clksel_sel[] = { -- { .parent = &dpll_core_m4_ck, .rates = div_1_0_rates }, -- { .parent = &dpll_per_m2_ck, .rates = div_1_1_rates }, -- { .parent = NULL }, --}; -- --static struct clk gfx_fclk_clksel_ck; -- --static struct clk_hw_omap gfx_fclk_clksel_ck_hw = { -- .hw = { -- .clk = &gfx_fclk_clksel_ck, -- }, -- .clksel = gfx_clksel_sel, -- .clksel_reg = AM33XX_CLKSEL_GFX_FCLK, -- .clksel_mask = AM33XX_CLKSEL_GFX_FCLK_MASK, --}; -- --DEFINE_STRUCT_CLK(gfx_fclk_clksel_ck, gfx_ck_parents, gpio_fck_ops); -- --static const struct clk_div_table div_1_0_2_1_rates[] = { -- { .div = 1, .val = 0, }, -- { .div = 2, .val = 1, }, -- { .div = 0 }, --}; -- --DEFINE_CLK_DIVIDER_TABLE(gfx_fck_div_ck, "gfx_fclk_clksel_ck", -- &gfx_fclk_clksel_ck, 0x0, AM33XX_CLKSEL_GFX_FCLK, -- AM33XX_CLKSEL_0_0_SHIFT, AM33XX_CLKSEL_0_0_WIDTH, -- 0x0, div_1_0_2_1_rates, NULL); -- --static const char *sysclkout_ck_parents[] = { -- "clk_32768_ck", "l3_gclk", "dpll_ddr_m2_ck", "dpll_per_m2_ck", -- "lcd_gclk", --}; -- --static const struct clksel sysclkout_pre_sel[] = { -- { .parent = &clk_32768_ck, .rates = div_1_0_rates }, -- { .parent = &l3_gclk, .rates = div_1_1_rates }, -- { .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates }, -- { .parent = &dpll_per_m2_ck, .rates = div_1_3_rates }, -- { .parent = &lcd_gclk, .rates = div_1_4_rates }, -- { .parent = NULL }, --}; -- --static struct clk sysclkout_pre_ck; -- --static struct clk_hw_omap sysclkout_pre_ck_hw = { -- .hw = { -- .clk = &sysclkout_pre_ck, -- }, -- .clksel = sysclkout_pre_sel, -- .clksel_reg = AM33XX_CM_CLKOUT_CTRL, -- .clksel_mask = AM33XX_CLKOUT2SOURCE_MASK, --}; -- --DEFINE_STRUCT_CLK(sysclkout_pre_ck, sysclkout_ck_parents, gpio_fck_ops); -- --/* Divide by 8 clock rates with default clock is 1/1*/ --static const struct clk_div_table div8_rates[] = { -- { .div = 1, .val = 0, }, -- { .div = 2, .val = 1, }, -- { .div = 3, .val = 2, }, -- { .div = 4, .val = 3, }, -- { .div = 5, .val = 4, }, -- { .div = 6, .val = 5, }, -- { .div = 7, .val = 6, }, -- { .div = 8, .val = 7, }, -- { .div = 0 }, --}; -- --DEFINE_CLK_DIVIDER_TABLE(clkout2_div_ck, "sysclkout_pre_ck", &sysclkout_pre_ck, -- 0x0, AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2DIV_SHIFT, -- AM33XX_CLKOUT2DIV_WIDTH, 0x0, div8_rates, NULL); -- --DEFINE_CLK_GATE(clkout2_ck, "clkout2_div_ck", &clkout2_div_ck, 0x0, -- AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2EN_SHIFT, 0x0, NULL); -- --static const char *wdt_ck_parents[] = { -- "clk_rc32k_ck", "clkdiv32k_ick", --}; -- --static const struct clksel wdt_clkmux_sel[] = { -- { .parent = &clk_rc32k_ck, .rates = div_1_0_rates }, -- { .parent = &clkdiv32k_ick, .rates = div_1_1_rates }, -- { .parent = NULL }, --}; -- --static struct clk wdt1_fck; -- --static struct clk_hw_omap wdt1_fck_hw = { -- .hw = { -- .clk = &wdt1_fck, -- }, -- .clkdm_name = "l4_wkup_clkdm", -- .clksel = wdt_clkmux_sel, -- .clksel_reg = AM33XX_CLKSEL_WDT1_CLK, -- .clksel_mask = AM33XX_CLKSEL_0_1_MASK, --}; -- --DEFINE_STRUCT_CLK(wdt1_fck, wdt_ck_parents, gpio_fck_ops); -- --static const char *pwmss_clk_parents[] = { -- "dpll_per_m2_ck", --}; -- --static const struct clk_ops ehrpwm_tbclk_ops = { -- .enable = &omap2_dflt_clk_enable, -- .disable = &omap2_dflt_clk_disable, --}; -- --DEFINE_CLK_OMAP_MUX_GATE(ehrpwm0_tbclk, "l4ls_clkdm", -- NULL, NULL, 0, -- AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL), -- AM33XX_PWMSS0_TBCLKEN_SHIFT, -- NULL, pwmss_clk_parents, ehrpwm_tbclk_ops); -- --DEFINE_CLK_OMAP_MUX_GATE(ehrpwm1_tbclk, "l4ls_clkdm", -- NULL, NULL, 0, -- AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL), -- AM33XX_PWMSS1_TBCLKEN_SHIFT, -- NULL, pwmss_clk_parents, ehrpwm_tbclk_ops); -- --DEFINE_CLK_OMAP_MUX_GATE(ehrpwm2_tbclk, "l4ls_clkdm", -- NULL, NULL, 0, -- AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL), -- AM33XX_PWMSS2_TBCLKEN_SHIFT, -- NULL, pwmss_clk_parents, ehrpwm_tbclk_ops); -- --/* -- * debugss optional clocks -- */ --DEFINE_CLK_GATE(dbg_sysclk_ck, "sys_clkin_ck", &sys_clkin_ck, -- 0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, -- AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT, 0x0, NULL); -- --DEFINE_CLK_GATE(dbg_clka_ck, "dpll_core_m4_ck", &dpll_core_m4_ck, -- 0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, -- AM33XX_OPTCLK_DEBUG_CLKA_SHIFT, 0x0, NULL); -- --static const char *stm_pmd_clock_mux_ck_parents[] = { -- "dbg_sysclk_ck", "dbg_clka_ck", --}; -- --DEFINE_CLK_MUX(stm_pmd_clock_mux_ck, stm_pmd_clock_mux_ck_parents, NULL, 0x0, -- AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, AM33XX_STM_PMD_CLKSEL_SHIFT, -- AM33XX_STM_PMD_CLKSEL_WIDTH, 0x0, NULL); -- --DEFINE_CLK_MUX(trace_pmd_clk_mux_ck, stm_pmd_clock_mux_ck_parents, NULL, 0x0, -- AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, -- AM33XX_TRC_PMD_CLKSEL_SHIFT, -- AM33XX_TRC_PMD_CLKSEL_WIDTH, 0x0, NULL); -- --DEFINE_CLK_DIVIDER(stm_clk_div_ck, "stm_pmd_clock_mux_ck", -- &stm_pmd_clock_mux_ck, 0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, -- AM33XX_STM_PMD_CLKDIVSEL_SHIFT, -- AM33XX_STM_PMD_CLKDIVSEL_WIDTH, CLK_DIVIDER_POWER_OF_TWO, -- NULL); -- --DEFINE_CLK_DIVIDER(trace_clk_div_ck, "trace_pmd_clk_mux_ck", -- &trace_pmd_clk_mux_ck, 0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, -- AM33XX_TRC_PMD_CLKDIVSEL_SHIFT, -- AM33XX_TRC_PMD_CLKDIVSEL_WIDTH, CLK_DIVIDER_POWER_OF_TWO, -- NULL); -- --/* -- * clkdev -- */ --static struct omap_clk am33xx_clks[] = { -- CLK(NULL, "clk_32768_ck", &clk_32768_ck), -- CLK(NULL, "clk_rc32k_ck", &clk_rc32k_ck), -- CLK(NULL, "virt_19200000_ck", &virt_19200000_ck), -- CLK(NULL, "virt_24000000_ck", &virt_24000000_ck), -- CLK(NULL, "virt_25000000_ck", &virt_25000000_ck), -- CLK(NULL, "virt_26000000_ck", &virt_26000000_ck), -- CLK(NULL, "sys_clkin_ck", &sys_clkin_ck), -- CLK(NULL, "tclkin_ck", &tclkin_ck), -- CLK(NULL, "dpll_core_ck", &dpll_core_ck), -- CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck), -- CLK(NULL, "dpll_core_m4_ck", &dpll_core_m4_ck), -- CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck), -- CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck), -- CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck), -- CLK("cpu0", NULL, &dpll_mpu_ck), -- CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck), -- CLK(NULL, "dpll_ddr_ck", &dpll_ddr_ck), -- CLK(NULL, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck), -- CLK(NULL, "dpll_ddr_m2_div2_ck", &dpll_ddr_m2_div2_ck), -- CLK(NULL, "dpll_disp_ck", &dpll_disp_ck), -- CLK(NULL, "dpll_disp_m2_ck", &dpll_disp_m2_ck), -- CLK(NULL, "dpll_per_ck", &dpll_per_ck), -- CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck), -- CLK(NULL, "dpll_per_m2_div4_wkupdm_ck", &dpll_per_m2_div4_wkupdm_ck), -- CLK(NULL, "dpll_per_m2_div4_ck", &dpll_per_m2_div4_ck), -- CLK(NULL, "adc_tsc_fck", &adc_tsc_fck), -- CLK(NULL, "cefuse_fck", &cefuse_fck), -- CLK(NULL, "clkdiv32k_ck", &clkdiv32k_ck), -- CLK(NULL, "clkdiv32k_ick", &clkdiv32k_ick), -- CLK(NULL, "dcan0_fck", &dcan0_fck), -- CLK("481cc000.d_can", NULL, &dcan0_fck), -- CLK(NULL, "dcan1_fck", &dcan1_fck), -- CLK("481d0000.d_can", NULL, &dcan1_fck), -- CLK(NULL, "pruss_ocp_gclk", &pruss_ocp_gclk), -- CLK(NULL, "mcasp0_fck", &mcasp0_fck), -- CLK(NULL, "mcasp1_fck", &mcasp1_fck), -- CLK(NULL, "mmu_fck", &mmu_fck), -- CLK(NULL, "smartreflex0_fck", &smartreflex0_fck), -- CLK(NULL, "smartreflex1_fck", &smartreflex1_fck), -- CLK(NULL, "sha0_fck", &sha0_fck), -- CLK(NULL, "aes0_fck", &aes0_fck), -- CLK(NULL, "rng_fck", &rng_fck), -- CLK(NULL, "timer1_fck", &timer1_fck), -- CLK(NULL, "timer2_fck", &timer2_fck), -- CLK(NULL, "timer3_fck", &timer3_fck), -- CLK(NULL, "timer4_fck", &timer4_fck), -- CLK(NULL, "timer5_fck", &timer5_fck), -- CLK(NULL, "timer6_fck", &timer6_fck), -- CLK(NULL, "timer7_fck", &timer7_fck), -- CLK(NULL, "usbotg_fck", &usbotg_fck), -- CLK(NULL, "ieee5000_fck", &ieee5000_fck), -- CLK(NULL, "wdt1_fck", &wdt1_fck), -- CLK(NULL, "l4_rtc_gclk", &l4_rtc_gclk), -- CLK(NULL, "l3_gclk", &l3_gclk), -- CLK(NULL, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck), -- CLK(NULL, "l4hs_gclk", &l4hs_gclk), -- CLK(NULL, "l3s_gclk", &l3s_gclk), -- CLK(NULL, "l4fw_gclk", &l4fw_gclk), -- CLK(NULL, "l4ls_gclk", &l4ls_gclk), -- CLK(NULL, "clk_24mhz", &clk_24mhz), -- CLK(NULL, "sysclk_div_ck", &sysclk_div_ck), -- CLK(NULL, "cpsw_125mhz_gclk", &cpsw_125mhz_gclk), -- CLK(NULL, "cpsw_cpts_rft_clk", &cpsw_cpts_rft_clk), -- CLK(NULL, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck), -- CLK(NULL, "gpio0_dbclk", &gpio0_dbclk), -- CLK(NULL, "gpio1_dbclk", &gpio1_dbclk), -- CLK(NULL, "gpio2_dbclk", &gpio2_dbclk), -- CLK(NULL, "gpio3_dbclk", &gpio3_dbclk), -- CLK(NULL, "lcd_gclk", &lcd_gclk), -- CLK(NULL, "mmc_clk", &mmc_clk), -- CLK(NULL, "gfx_fclk_clksel_ck", &gfx_fclk_clksel_ck), -- CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck), -- CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck), -- CLK(NULL, "clkout2_div_ck", &clkout2_div_ck), -- CLK(NULL, "timer_32k_ck", &clkdiv32k_ick), -- CLK(NULL, "timer_sys_ck", &sys_clkin_ck), -- CLK(NULL, "dbg_sysclk_ck", &dbg_sysclk_ck), -- CLK(NULL, "dbg_clka_ck", &dbg_clka_ck), -- CLK(NULL, "stm_pmd_clock_mux_ck", &stm_pmd_clock_mux_ck), -- CLK(NULL, "trace_pmd_clk_mux_ck", &trace_pmd_clk_mux_ck), -- CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck), -- CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck), -- CLK(NULL, "clkout2_ck", &clkout2_ck), -- CLK("48300200.ehrpwm", "tbclk", &ehrpwm0_tbclk), -- CLK("48302200.ehrpwm", "tbclk", &ehrpwm1_tbclk), -- CLK("48304200.ehrpwm", "tbclk", &ehrpwm2_tbclk), --}; -- -- --static const char *enable_init_clks[] = { -- "dpll_ddr_m2_ck", -- "dpll_mpu_m2_ck", -- "l3_gclk", -- "l4hs_gclk", -- "l4fw_gclk", -- "l4ls_gclk", -- "clkout2_ck", /* Required for external peripherals like, Audio codecs */ --}; -- --int __init am33xx_clk_init(void) --{ -- if (soc_is_am33xx()) -- cpu_mask = RATE_IN_AM33XX; -- -- omap_clocks_register(am33xx_clks, ARRAY_SIZE(am33xx_clks)); -- -- omap2_clk_disable_autoidle_all(); -- -- omap2_clk_enable_init_clocks(enable_init_clks, -- ARRAY_SIZE(enable_init_clks)); -- -- /* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always -- * physically present, in such a case HWMOD enabling of -- * clock would be failure with default parent. And timer -- * probe thinks clock is already enabled, this leads to -- * crash upon accessing timer 3 & 6 registers in probe. -- * Fix by setting parent of both these timers to master -- * oscillator clock. -- */ -- -- clk_set_parent(&timer3_fck, &sys_clkin_ck); -- clk_set_parent(&timer6_fck, &sys_clkin_ck); -- /* -- * The On-Chip 32K RC Osc clock is not an accurate clock-source as per -- * the design/spec, so as a result, for example, timer which supposed -- * to get expired @60Sec, but will expire somewhere ~@40Sec, which is -- * not expected by any use-case, so change WDT1 clock source to PRCM -- * 32KHz clock. -- */ -- clk_set_parent(&wdt1_fck, &clkdiv32k_ick); -- -- return 0; --} ---- a/arch/arm/mach-omap2/clkt_dpll.c -+++ b/arch/arm/mach-omap2/clkt_dpll.c -@@ -209,7 +209,7 @@ u8 omap2_init_dpll_parent(struct clk_hw - if (v == OMAP3XXX_EN_DPLL_LPBYPASS || - v == OMAP3XXX_EN_DPLL_FRBYPASS) - return 1; -- } else if (soc_is_am33xx() || cpu_is_omap44xx()) { -+ } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { - if (v == OMAP4XXX_EN_DPLL_LPBYPASS || - v == OMAP4XXX_EN_DPLL_FRBYPASS || - v == OMAP4XXX_EN_DPLL_MNBYPASS) -@@ -255,7 +255,7 @@ unsigned long omap2_get_dpll_rate(struct - if (v == OMAP3XXX_EN_DPLL_LPBYPASS || - v == OMAP3XXX_EN_DPLL_FRBYPASS) - return __clk_get_rate(dd->clk_bypass); -- } else if (soc_is_am33xx() || cpu_is_omap44xx()) { -+ } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { - if (v == OMAP4XXX_EN_DPLL_LPBYPASS || - v == OMAP4XXX_EN_DPLL_FRBYPASS || - v == OMAP4XXX_EN_DPLL_MNBYPASS) ---- a/arch/arm/mach-omap2/clock3xxx.h -+++ b/arch/arm/mach-omap2/clock3xxx.h -@@ -9,11 +9,12 @@ - #define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H - - int omap3xxx_clk_init(void); --int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, -- unsigned long parent_rate); -+int omap3430_clk_init(void); -+int omap3630_clk_init(void); -+int ti81xx_clk_init(void); -+int am35xx_clk_init(void); - int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate, - unsigned long parent_rate); --void omap3_clk_lock_dpll5(void); - - extern struct clk *sdrc_ick_p; - extern struct clk *arm_fck_p; ---- a/arch/arm/mach-omap2/clock.c -+++ b/arch/arm/mach-omap2/clock.c -@@ -520,6 +520,9 @@ int omap2_clk_enable_autoidle_all(void) - list_for_each_entry(c, &clk_hw_omap_clocks, node) - if (c->ops && c->ops->allow_idle) - c->ops->allow_idle(c); -+ -+ of_omap_clk_allow_autoidle_all(); -+ - return 0; - } - -@@ -539,6 +542,9 @@ int omap2_clk_disable_autoidle_all(void) - list_for_each_entry(c, &clk_hw_omap_clocks, node) - if (c->ops && c->ops->deny_idle) - c->ops->deny_idle(c); -+ -+ of_omap_clk_deny_autoidle_all(); -+ - return 0; - } - ---- a/arch/arm/mach-omap2/clockdomain.h -+++ b/arch/arm/mach-omap2/clockdomain.h -@@ -132,7 +132,7 @@ struct clockdomain { - u8 _flags; - const u8 dep_bit; - const u8 prcm_partition; -- const s16 cm_inst; -+ const u16 cm_inst; - const u16 clkdm_offs; - struct clkdm_dep *wkdep_srcs; - struct clkdm_dep *sleepdep_srcs; -@@ -215,6 +215,7 @@ extern void __init omap242x_clockdomains - extern void __init omap243x_clockdomains_init(void); - extern void __init omap3xxx_clockdomains_init(void); - extern void __init am33xx_clockdomains_init(void); -+extern void am43xx_clockdomains_init(void); - extern void __init omap44xx_clockdomains_init(void); - extern void __init omap54xx_clockdomains_init(void); - extern void __init dra7xx_clockdomains_init(void); -@@ -226,6 +227,7 @@ extern struct clkdm_ops omap2_clkdm_oper - extern struct clkdm_ops omap3_clkdm_operations; - extern struct clkdm_ops omap4_clkdm_operations; - extern struct clkdm_ops am33xx_clkdm_operations; -+extern struct clkdm_ops am43xx_clkdm_operations; - - extern struct clkdm_dep gfx_24xx_wkdeps[]; - extern struct clkdm_dep dsp_24xx_wkdeps[]; ---- /dev/null -+++ b/arch/arm/mach-omap2/clockdomains43xx_data.c -@@ -0,0 +1,199 @@ -+/* -+ * AM43xx Clock domains framework -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * This file is made by modifying the file generated automatically -+ * from the OMAP hardware databases. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/io.h> -+ -+#include "clockdomain.h" -+#include "prcm44xx.h" -+#include "prcm43xx.h" -+ -+static struct clockdomain l4_cefuse_43xx_clkdm = { -+ .name = "l4_cefuse_clkdm", -+ .pwrdm = { .name = "cefuse_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_CEFUSE_INST, -+ .clkdm_offs = AM43XX_CM_CEFUSE_CEFUSE_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain mpu_43xx_clkdm = { -+ .name = "mpu_clkdm", -+ .pwrdm = { .name = "mpu_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_MPU_INST, -+ .clkdm_offs = AM43XX_CM_MPU_MPU_CDOFFS, -+ .flags = CLKDM_CAN_HWSUP_SWSUP, -+}; -+ -+static struct clockdomain l4ls_43xx_clkdm = { -+ .name = "l4ls_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_L4LS_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain tamper_43xx_clkdm = { -+ .name = "tamper_clkdm", -+ .pwrdm = { .name = "tamper_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_TAMPER_INST, -+ .clkdm_offs = AM43XX_CM_TAMPER_TAMPER_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain l4_rtc_43xx_clkdm = { -+ .name = "l4_rtc_clkdm", -+ .pwrdm = { .name = "rtc_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_RTC_INST, -+ .clkdm_offs = AM43XX_CM_RTC_RTC_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain pruss_ocp_43xx_clkdm = { -+ .name = "pruss_ocp_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_ICSS_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain ocpwp_l3_43xx_clkdm = { -+ .name = "ocpwp_l3_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_OCPWP_L3_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain l3s_tsc_43xx_clkdm = { -+ .name = "l3s_tsc_clkdm", -+ .pwrdm = { .name = "wkup_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_WKUP_INST, -+ .clkdm_offs = AM43XX_CM_WKUP_L3S_TSC_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain dss_43xx_clkdm = { -+ .name = "dss_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_DSS_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain l3_aon_43xx_clkdm = { -+ .name = "l3_aon_clkdm", -+ .pwrdm = { .name = "wkup_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_WKUP_INST, -+ .clkdm_offs = AM43XX_CM_WKUP_L3_AON_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain emif_43xx_clkdm = { -+ .name = "emif_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_EMIF_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain l4_wkup_aon_43xx_clkdm = { -+ .name = "l4_wkup_aon_clkdm", -+ .pwrdm = { .name = "wkup_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_WKUP_INST, -+ .clkdm_offs = AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS, -+}; -+ -+static struct clockdomain l3_43xx_clkdm = { -+ .name = "l3_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_L3_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain l4_wkup_43xx_clkdm = { -+ .name = "l4_wkup_clkdm", -+ .pwrdm = { .name = "wkup_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_WKUP_INST, -+ .clkdm_offs = AM43XX_CM_WKUP_WKUP_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain cpsw_125mhz_43xx_clkdm = { -+ .name = "cpsw_125mhz_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_CPSW_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain gfx_l3_43xx_clkdm = { -+ .name = "gfx_l3_clkdm", -+ .pwrdm = { .name = "gfx_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_GFX_INST, -+ .clkdm_offs = AM43XX_CM_GFX_GFX_L3_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain l3s_43xx_clkdm = { -+ .name = "l3s_clkdm", -+ .pwrdm = { .name = "per_pwrdm" }, -+ .prcm_partition = AM43XX_CM_PARTITION, -+ .cm_inst = AM43XX_CM_PER_INST, -+ .clkdm_offs = AM43XX_CM_PER_L3S_CDOFFS, -+ .flags = CLKDM_CAN_SWSUP, -+}; -+ -+static struct clockdomain *clockdomains_am43xx[] __initdata = { -+ &l4_cefuse_43xx_clkdm, -+ &mpu_43xx_clkdm, -+ &l4ls_43xx_clkdm, -+ &tamper_43xx_clkdm, -+ &l4_rtc_43xx_clkdm, -+ &pruss_ocp_43xx_clkdm, -+ &ocpwp_l3_43xx_clkdm, -+ &l3s_tsc_43xx_clkdm, -+ &dss_43xx_clkdm, -+ &l3_aon_43xx_clkdm, -+ &emif_43xx_clkdm, -+ &l4_wkup_aon_43xx_clkdm, -+ &l3_43xx_clkdm, -+ &l4_wkup_43xx_clkdm, -+ &cpsw_125mhz_43xx_clkdm, -+ &gfx_l3_43xx_clkdm, -+ &l3s_43xx_clkdm, -+ NULL -+}; -+ -+void __init am43xx_clockdomains_init(void) -+{ -+ clkdm_register_platform_funcs(&am43xx_clkdm_operations); -+ clkdm_register_clkdms(clockdomains_am43xx); -+ clkdm_complete_init(); -+} ---- a/arch/arm/mach-omap2/clockdomains7xx_data.c -+++ b/arch/arm/mach-omap2/clockdomains7xx_data.c -@@ -409,7 +409,7 @@ static struct clockdomain l4sec_7xx_clkd - .dep_bit = DRA7XX_L4SEC_STATDEP_SHIFT, - .wkdep_srcs = l4sec_wkup_sleep_deps, - .sleepdep_srcs = l4sec_wkup_sleep_deps, -- .flags = CLKDM_CAN_HWSUP_SWSUP, -+ .flags = CLKDM_CAN_SWSUP, - }; - - static struct clockdomain l3main1_7xx_clkdm = { -@@ -554,7 +554,7 @@ static struct clockdomain dss_7xx_clkdm - .dep_bit = DRA7XX_DSS_STATDEP_SHIFT, - .wkdep_srcs = dss_wkup_sleep_deps, - .sleepdep_srcs = dss_wkup_sleep_deps, -- .flags = CLKDM_CAN_HWSUP_SWSUP, -+ .flags = CLKDM_CAN_SWSUP, - }; - - static struct clockdomain emif_7xx_clkdm = { ---- a/arch/arm/mach-omap2/clock.h -+++ b/arch/arm/mach-omap2/clock.h -@@ -21,6 +21,7 @@ - - #include <linux/clkdev.h> - #include <linux/clk-provider.h> -+#include <linux/clk/ti.h> - - struct omap_clk { - u16 cpu; -@@ -37,7 +38,6 @@ struct omap_clk { - } - - struct clockdomain; --#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) - - #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ - static struct clk _name = { \ -@@ -178,141 +178,6 @@ struct clksel { - const struct clksel_rate *rates; - }; - --/** -- * struct dpll_data - DPLL registers and integration data -- * @mult_div1_reg: register containing the DPLL M and N bitfields -- * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg -- * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg -- * @clk_bypass: struct clk pointer to the clock's bypass clock input -- * @clk_ref: struct clk pointer to the clock's reference clock input -- * @control_reg: register containing the DPLL mode bitfield -- * @enable_mask: mask of the DPLL mode bitfield in @control_reg -- * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate() -- * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate() -- * @last_rounded_m4xen: cache of the last M4X result of -- * omap4_dpll_regm4xen_round_rate() -- * @last_rounded_lpmode: cache of the last lpmode result of -- * omap4_dpll_lpmode_recalc() -- * @max_multiplier: maximum valid non-bypass multiplier value (actual) -- * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate() -- * @min_divider: minimum valid non-bypass divider value (actual) -- * @max_divider: maximum valid non-bypass divider value (actual) -- * @modes: possible values of @enable_mask -- * @autoidle_reg: register containing the DPLL autoidle mode bitfield -- * @idlest_reg: register containing the DPLL idle status bitfield -- * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg -- * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg -- * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg -- * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg -- * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg -- * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg -- * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs -- * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs -- * @flags: DPLL type/features (see below) -- * -- * Possible values for @flags: -- * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs) -- * -- * @freqsel_mask is only used on the OMAP34xx family and AM35xx. -- * -- * XXX Some DPLLs have multiple bypass inputs, so it's not technically -- * correct to only have one @clk_bypass pointer. -- * -- * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m, -- * @last_rounded_n) should be separated from the runtime-fixed fields -- * and placed into a different structure, so that the runtime-fixed data -- * can be placed into read-only space. -- */ --struct dpll_data { -- void __iomem *mult_div1_reg; -- u32 mult_mask; -- u32 div1_mask; -- struct clk *clk_bypass; -- struct clk *clk_ref; -- void __iomem *control_reg; -- u32 enable_mask; -- unsigned long last_rounded_rate; -- u16 last_rounded_m; -- u8 last_rounded_m4xen; -- u8 last_rounded_lpmode; -- u16 max_multiplier; -- u8 last_rounded_n; -- u8 min_divider; -- u16 max_divider; -- u8 modes; -- void __iomem *autoidle_reg; -- void __iomem *idlest_reg; -- u32 autoidle_mask; -- u32 freqsel_mask; -- u32 idlest_mask; -- u32 dco_mask; -- u32 sddiv_mask; -- u32 lpmode_mask; -- u32 m4xen_mask; -- u8 auto_recal_bit; -- u8 recal_en_bit; -- u8 recal_st_bit; -- u8 flags; --}; -- --/* -- * struct clk.flags possibilities -- * -- * XXX document the rest of the clock flags here -- * -- * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL -- * bits share the same register. This flag allows the -- * omap4_dpllmx*() code to determine which GATE_CTRL bit field -- * should be used. This is a temporary solution - a better approach -- * would be to associate clock type-specific data with the clock, -- * similar to the struct dpll_data approach. -- */ --#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ --#define CLOCK_IDLE_CONTROL (1 << 1) --#define CLOCK_NO_IDLE_PARENT (1 << 2) --#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ --#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ --#define CLOCK_CLKOUTX2 (1 << 5) -- --/** -- * struct clk_hw_omap - OMAP struct clk -- * @node: list_head connecting this clock into the full clock list -- * @enable_reg: register to write to enable the clock (see @enable_bit) -- * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg) -- * @flags: see "struct clk.flags possibilities" above -- * @clksel_reg: for clksel clks, register va containing src/divisor select -- * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector -- * @clksel: for clksel clks, pointer to struct clksel for this clock -- * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock -- * @clkdm_name: clockdomain name that this clock is contained in -- * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime -- * @rate_offset: bitshift for rate selection bitfield (OMAP1 only) -- * @src_offset: bitshift for source selection bitfield (OMAP1 only) -- * -- * XXX @rate_offset, @src_offset should probably be removed and OMAP1 -- * clock code converted to use clksel. -- * -- */ -- --struct clk_hw_omap_ops; -- --struct clk_hw_omap { -- struct clk_hw hw; -- struct list_head node; -- unsigned long fixed_rate; -- u8 fixed_div; -- void __iomem *enable_reg; -- u8 enable_bit; -- u8 flags; -- void __iomem *clksel_reg; -- u32 clksel_mask; -- const struct clksel *clksel; -- struct dpll_data *dpll_data; -- const char *clkdm_name; -- struct clockdomain *clkdm; -- const struct clk_hw_omap_ops *ops; --}; -- - struct clk_hw_omap_ops { - void (*find_idlest)(struct clk_hw_omap *oclk, - void __iomem **idlest_reg, -@@ -348,36 +213,13 @@ unsigned long omap_fixed_divisor_recalc( - #define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 - #define OMAP4XXX_EN_DPLL_LOCKED 0x7 - --/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ --#define DPLL_LOW_POWER_STOP 0x1 --#define DPLL_LOW_POWER_BYPASS 0x5 --#define DPLL_LOCKED 0x7 -- --/* DPLL Type and DCO Selection Flags */ --#define DPLL_J_TYPE 0x1 -- --long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, -- unsigned long *parent_rate); --unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); --int omap3_noncore_dpll_enable(struct clk_hw *hw); --void omap3_noncore_dpll_disable(struct clk_hw *hw); --int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, -- unsigned long parent_rate); - u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); - void omap3_dpll_allow_idle(struct clk_hw_omap *clk); - void omap3_dpll_deny_idle(struct clk_hw_omap *clk); --unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, -- unsigned long parent_rate); - int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); - void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); - void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); --unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, -- unsigned long parent_rate); --long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, -- unsigned long target_rate, -- unsigned long *parent_rate); - --void omap2_init_clk_clkdm(struct clk_hw *clk); - void __init omap2_clk_disable_clkdm_control(void); - - /* clkt_clksel.c public functions */ -@@ -396,22 +238,15 @@ int omap2_clksel_set_parent(struct clk_h - extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); - extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); - --u8 omap2_init_dpll_parent(struct clk_hw *hw); - unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); - --int omap2_dflt_clk_enable(struct clk_hw *hw); --void omap2_dflt_clk_disable(struct clk_hw *hw); --int omap2_dflt_clk_is_enabled(struct clk_hw *hw); - void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, - void __iomem **other_reg, - u8 *other_bit); - void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, - void __iomem **idlest_reg, - u8 *idlest_bit, u8 *idlest_val); --void omap2_init_clk_hw_omap_clocks(struct clk *clk); - int omap2_clk_enable_autoidle_all(void); --int omap2_clk_disable_autoidle_all(void); --void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); - int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name); - void omap2_clk_print_new_rates(const char *hfclkin_ck_name, - const char *core_ck_name, -@@ -431,19 +266,8 @@ extern const struct clksel_rate gfx_l3_r - extern const struct clksel_rate dsp_ick_rates[]; - extern struct clk dummy_ck; - --extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; --extern const struct clk_hw_omap_ops clkhwops_iclk_wait; --extern const struct clk_hw_omap_ops clkhwops_wait; --extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; --extern const struct clk_hw_omap_ops clkhwops_iclk; - extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; --extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; --extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; --extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait; --extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait; - extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait; --extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; --extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait; - extern const struct clk_hw_omap_ops clkhwops_apll54; - extern const struct clk_hw_omap_ops clkhwops_apll96; - extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; -@@ -460,8 +284,5 @@ extern const struct clksel_rate div31_1t - - extern int am33xx_clk_init(void); - --extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); --extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); -- - extern void omap_clocks_register(struct omap_clk *oclks, int cnt); - #endif ---- a/arch/arm/mach-omap2/cm33xx.c -+++ b/arch/arm/mach-omap2/cm33xx.c -@@ -48,13 +48,13 @@ - /* Private functions */ - - /* Read a register in a CM instance */ --static inline u32 am33xx_cm_read_reg(s16 inst, u16 idx) -+static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) - { - return __raw_readl(cm_base + inst + idx); - } - - /* Write into a register in a CM */ --static inline void am33xx_cm_write_reg(u32 val, s16 inst, u16 idx) -+static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) - { - __raw_writel(val, cm_base + inst + idx); - } -@@ -82,7 +82,7 @@ static inline u32 am33xx_cm_clear_reg_bi - return am33xx_cm_rmw_reg_bits(bits, 0x0, inst, idx); - } - --static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask) -+static inline u32 am33xx_cm_read_reg_bits(u16 inst, u16 idx, u32 mask) - { - u32 v; - -@@ -102,7 +102,7 @@ static inline u32 am33xx_cm_read_reg_bit - * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to - * bit 0. - */ --static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) -+static u32 _clkctrl_idlest(u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); - v &= AM33XX_IDLEST_MASK; -@@ -119,7 +119,7 @@ static u32 _clkctrl_idlest(u16 inst, s16 - * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either - * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. - */ --static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) -+static bool _is_module_ready(u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - u32 v; - -@@ -138,7 +138,7 @@ static bool _is_module_ready(u16 inst, s - * @c must be the unshifted value for CLKTRCTRL - i.e., this function - * will handle the shift itself. - */ --static void _clktrctrl_write(u8 c, s16 inst, u16 cdoffs) -+static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs) - { - u32 v; - -@@ -158,7 +158,7 @@ static void _clktrctrl_write(u8 c, s16 i - * Returns true if the clockdomain referred to by (@inst, @cdoffs) - * is in hardware-supervised idle mode, or 0 otherwise. - */ --bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs) -+bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) - { - u32 v; - -@@ -177,7 +177,7 @@ bool am33xx_cm_is_clkdm_in_hwsup(s16 ins - * Put a clockdomain referred to by (@inst, @cdoffs) into - * hardware-supervised idle mode. No return value. - */ --void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs) -+void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); - } -@@ -191,7 +191,7 @@ void am33xx_cm_clkdm_enable_hwsup(s16 in - * software-supervised idle mode, i.e., controlled manually by the - * Linux OMAP clockdomain code. No return value. - */ --void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs) -+void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); - } -@@ -204,7 +204,7 @@ void am33xx_cm_clkdm_disable_hwsup(s16 i - * Put a clockdomain referred to by (@inst, @cdoffs) into idle - * No return value. - */ --void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs) -+void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); - } -@@ -217,7 +217,7 @@ void am33xx_cm_clkdm_force_sleep(s16 ins - * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, - * waking it up. No return value. - */ --void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs) -+void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); - } -@@ -237,7 +237,7 @@ void am33xx_cm_clkdm_force_wakeup(s16 in - * sysconfig cannot be accessed and will probably lead to an "imprecise - * external abort" - */ --int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) -+int am33xx_cm_wait_module_ready(u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - int i = 0; - -@@ -258,7 +258,7 @@ int am33xx_cm_wait_module_ready(u16 inst - * like reset assertion or parent clock de-activation must wait the - * module to be fully disabled. - */ --int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) -+int am33xx_cm_wait_module_idle(u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - int i = 0; - -@@ -281,7 +281,7 @@ int am33xx_cm_wait_module_idle(u16 inst, - * - * No return value. - */ --void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) -+void am33xx_cm_module_enable(u8 mode, u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - u32 v; - -@@ -299,7 +299,7 @@ void am33xx_cm_module_enable(u8 mode, u1 - * - * No return value. - */ --void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) -+void am33xx_cm_module_disable(u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - u32 v; - ---- a/arch/arm/mach-omap2/cm33xx.h -+++ b/arch/arm/mach-omap2/cm33xx.h -@@ -377,36 +377,36 @@ - - - #ifndef __ASSEMBLER__ --extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs); --extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs); --extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs); --extern void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs); --extern void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs); -+extern bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs); -+extern void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs); -+extern void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs); -+extern void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs); -+extern void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs); - --#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) --extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, -+#ifdef CONFIG_SOC_AM33XX -+extern int am33xx_cm_wait_module_idle(u16 inst, u16 cdoffs, - u16 clkctrl_offs); --extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, -+extern void am33xx_cm_module_enable(u8 mode, u16 inst, u16 cdoffs, - u16 clkctrl_offs); --extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs, -+extern void am33xx_cm_module_disable(u16 inst, u16 cdoffs, - u16 clkctrl_offs); --extern int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, -+extern int am33xx_cm_wait_module_ready(u16 inst, u16 cdoffs, - u16 clkctrl_offs); - #else --static inline int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, -+static inline int am33xx_cm_wait_module_idle(u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - return 0; - } --static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, -+static inline void am33xx_cm_module_enable(u8 mode, u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - } --static inline void am33xx_cm_module_disable(u16 inst, s16 cdoffs, -+static inline void am33xx_cm_module_disable(u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - } --static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, -+static inline int am33xx_cm_wait_module_ready(u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - return 0; ---- a/arch/arm/mach-omap2/cminst44xx.c -+++ b/arch/arm/mach-omap2/cminst44xx.c -@@ -80,7 +80,7 @@ void omap_cm_base_init(void) - * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to - * bit 0. - */ --static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) -+static u32 _clkctrl_idlest(u8 part, u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); - v &= OMAP4430_IDLEST_MASK; -@@ -98,7 +98,7 @@ static u32 _clkctrl_idlest(u8 part, u16 - * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either - * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. - */ --static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) -+static bool _is_module_ready(u8 part, u16 inst, u16 cdoffs, u16 clkctrl_offs) - { - u32 v; - -@@ -111,7 +111,7 @@ static bool _is_module_ready(u8 part, u1 - /* Public functions */ - - /* Read a register in a CM instance */ --u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx) -+u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) - { - BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || - part == OMAP4430_INVALID_PRCM_PARTITION || -@@ -120,7 +120,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, - } - - /* Write into a register in a CM instance */ --void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) -+void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) - { - BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || - part == OMAP4430_INVALID_PRCM_PARTITION || -@@ -152,7 +152,7 @@ u32 omap4_cminst_clear_inst_reg_bits(u32 - return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); - } - --u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) -+u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, u16 idx, u32 mask) - { - u32 v; - -@@ -177,7 +177,7 @@ u32 omap4_cminst_read_inst_reg_bits(u8 p - * @c must be the unshifted value for CLKTRCTRL - i.e., this function - * will handle the shift itself. - */ --static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs) -+static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs) - { - u32 v; - -@@ -196,7 +196,7 @@ static void _clktrctrl_write(u8 c, u8 pa - * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) - * is in hardware-supervised idle mode, or 0 otherwise. - */ --bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs) -+bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) - { - u32 v; - -@@ -216,7 +216,7 @@ bool omap4_cminst_is_clkdm_in_hwsup(u8 p - * Put a clockdomain referred to by (@part, @inst, @cdoffs) into - * hardware-supervised idle mode. No return value. - */ --void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs) -+void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); - } -@@ -231,7 +231,7 @@ void omap4_cminst_clkdm_enable_hwsup(u8 - * software-supervised idle mode, i.e., controlled manually by the - * Linux OMAP clockdomain code. No return value. - */ --void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs) -+void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); - } -@@ -245,7 +245,7 @@ void omap4_cminst_clkdm_disable_hwsup(u8 - * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, - * waking it up. No return value. - */ --void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs) -+void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) - { - _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); - } -@@ -266,7 +266,7 @@ void omap4_cminst_clkdm_force_wakeup(u8 - * sysconfig cannot be accessed and will probably lead to an "imprecise - * external abort" - */ --int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, -+int omap4_cminst_wait_module_ready(u8 part, u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - int i = 0; -@@ -292,7 +292,8 @@ int omap4_cminst_wait_module_ready(u8 pa - * like reset assertion or parent clock de-activation must wait the - * module to be fully disabled. - */ --int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) -+int omap4_cminst_wait_module_idle(u8 part, u16 inst, -+ u16 cdoffs, u16 clkctrl_offs) - { - int i = 0; - -@@ -316,7 +317,7 @@ int omap4_cminst_wait_module_idle(u8 par - * - * No return value. - */ --void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, -+void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - u32 v; -@@ -336,7 +337,7 @@ void omap4_cminst_module_enable(u8 mode, - * - * No return value. - */ --void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, -+void omap4_cminst_module_disable(u8 part, u16 inst, u16 cdoffs, - u16 clkctrl_offs) - { - u32 v; -@@ -479,6 +480,15 @@ struct clkdm_ops omap4_clkdm_operations - .clkdm_sleep = omap4_clkdm_sleep, - .clkdm_wakeup = omap4_clkdm_wakeup, - .clkdm_allow_idle = omap4_clkdm_allow_idle, -+ .clkdm_deny_idle = omap4_clkdm_deny_idle, -+ .clkdm_clk_enable = omap4_clkdm_clk_enable, -+ .clkdm_clk_disable = omap4_clkdm_clk_disable, -+}; -+ -+struct clkdm_ops am43xx_clkdm_operations = { -+ .clkdm_sleep = omap4_clkdm_sleep, -+ .clkdm_wakeup = omap4_clkdm_wakeup, -+ .clkdm_allow_idle = omap4_clkdm_allow_idle, - .clkdm_deny_idle = omap4_clkdm_deny_idle, - .clkdm_clk_enable = omap4_clkdm_clk_enable, - .clkdm_clk_disable = omap4_clkdm_clk_disable, ---- a/arch/arm/mach-omap2/cminst44xx.h -+++ b/arch/arm/mach-omap2/cminst44xx.h -@@ -11,31 +11,32 @@ - #ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H - #define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H - --extern bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs); --extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs); --extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs); --extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs); --extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs); --extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); --extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, -+extern bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs); -+extern void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs); -+extern void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs); -+extern void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs); -+extern void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs); -+extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, -+ u16 cdoffs, u16 clkctrl_offs); -+extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, u16 cdoffs, - u16 clkctrl_offs); --extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, -+extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, u16 cdoffs, - u16 clkctrl_offs); --extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, -+extern void omap4_cminst_module_disable(u8 part, u16 inst, u16 cdoffs, - u16 clkctrl_offs); - /* - * In an ideal world, we would not export these low-level functions, - * but this will probably take some time to fix properly - */ --extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx); --extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx); -+extern u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx); -+extern void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx); - extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, - s16 inst, s16 idx); - extern u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, - s16 idx); - extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, - s16 idx); --extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, -+extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, u16 idx, - u32 mask); - - extern void omap_cm_base_init(void); ---- a/arch/arm/mach-omap2/common.c -+++ b/arch/arm/mach-omap2/common.c -@@ -15,10 +15,14 @@ - #include <linux/kernel.h> - #include <linux/init.h> - #include <linux/platform_data/dsp-omap.h> -+#include <asm/memblock.h> -+#include <asm/mach/map.h> - - #include "common.h" - #include "omap-secure.h" - -+#define AM33XX_DRAM_SYNC_VA 0xfe600000 -+ - /* - * Stub function for OMAP2 so that common files - * continue to build when custom builds are used -@@ -34,3 +38,31 @@ void __init omap_reserve(void) - omap_secure_ram_reserve_memblock(); - omap_barrier_reserve_memblock(); - } -+ -+static phys_addr_t am33xx_paddr; -+static u32 am33xx_size; -+ -+/* Steal one page physical memory for uncached read DeepSleep */ -+void __init am33xx_reserve(void) -+{ -+ am33xx_size = ALIGN(PAGE_SIZE, SZ_1M); -+ am33xx_paddr = arm_memblock_steal(am33xx_size, SZ_1M); -+ -+ omap_reserve(); -+} -+ -+void __iomem *am33xx_dram_sync; -+ -+void __init am33xx_dram_sync_init(void) -+{ -+ struct map_desc dram_io_desc[1]; -+ -+ dram_io_desc[0].virtual = AM33XX_DRAM_SYNC_VA; -+ dram_io_desc[0].pfn = __phys_to_pfn(am33xx_paddr); -+ dram_io_desc[0].length = am33xx_size; -+ dram_io_desc[0].type = MT_MEMORY_SO; -+ -+ iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); -+ -+ am33xx_dram_sync = (void __iomem *) dram_io_desc[0].virtual; -+} ---- a/arch/arm/mach-omap2/common.h -+++ b/arch/arm/mach-omap2/common.h -@@ -60,7 +60,7 @@ static inline int omap3_pm_init(void) - } - #endif - --#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4) -+#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)) - int omap4_pm_init(void); - #else - static inline int omap4_pm_init(void) -@@ -69,6 +69,15 @@ static inline int omap4_pm_init(void) - } - #endif - -+#if defined(CONFIG_PM) && defined(CONFIG_SOC_AM33XX) -+int am33xx_pm_init(void); -+#else -+static inline int am33xx_pm_init(void) -+{ -+ return 0; -+} -+#endif -+ - #ifdef CONFIG_OMAP_MUX - int omap_mux_late_init(void); - #else -@@ -107,10 +116,14 @@ void omap2430_init_late(void); - void omap3430_init_late(void); - void omap35xx_init_late(void); - void omap3630_init_late(void); -+void am33xx_init_late(void); - void am35xx_init_late(void); - void ti81xx_init_late(void); -+void am33xx_init_late(void); -+void omap5_init_late(void); - int omap2_common_pm_late_init(void); - void dra7xx_init_early(void); -+void dra7xx_init_late(void); - - #ifdef CONFIG_SOC_BUS - void omap_soc_device_init(void); -@@ -136,6 +149,14 @@ static inline void am33xx_restart(enum r - } - #endif - -+#ifdef CONFIG_SOC_AM43XX -+void am43xx_restart(enum reboot_mode mode, const char *cmd); -+#else -+static inline void am43xx_restart(enum reboot_mode mode, const char *cmd) -+{ -+} -+#endif -+ - #ifdef CONFIG_ARCH_OMAP3 - void omap3xxx_restart(enum reboot_mode mode, const char *cmd); - #else -@@ -152,6 +173,14 @@ static inline void omap44xx_restart(enum - } - #endif - -+#if defined(CONFIG_SUSPEND) -+void omap2_common_suspend_init(void); -+#else -+inline void omap2_common_suspend_init(void); -+{ -+} -+#endif -+ - /* This gets called from mach-omap2/io.c, do not call this */ - void __init omap2_set_globals_tap(u32 class, void __iomem *tap); - -@@ -165,7 +194,6 @@ void __init ti81xx_map_io(void); - - /* omap_barriers_init() is OMAP4 only */ - void omap_barriers_init(void); -- - /** - * omap_test_timeout - busy-loop, testing a condition - * @cond: condition to test until it evaluates to true -@@ -259,6 +287,8 @@ extern int omap4_enter_lowpower(unsigned - extern int omap4_finish_suspend(unsigned long cpu_state); - extern void omap4_cpu_resume(void); - extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); -+extern int omap5_finish_suspend(unsigned long cpu_state); -+extern void omap5_cpu_resume(void); - #else - static inline int omap4_enter_lowpower(unsigned int cpu, - unsigned int power_state) -@@ -286,6 +316,14 @@ static inline int omap4_finish_suspend(u - static inline void omap4_cpu_resume(void) - {} - -+static inline int omap5_finish_suspend(unsigned long cpu_state) -+{ -+ return 0; -+} -+ -+static inline void omap5_cpu_resume(void) -+{} -+ - #endif - - struct omap_sdrc_params; -@@ -295,11 +333,17 @@ struct omap2_hsmmc_info; - extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers); - extern void omap_reserve(void); - -+extern void am33xx_reserve(void); -+extern void am33xx_dram_sync_init(void); -+extern void __iomem *am33xx_dram_sync; -+ - struct omap_hwmod; - extern int omap_dss_reset(struct omap_hwmod *); - - /* SoC specific clock initializer */ - extern int (*omap_clk_init)(void); - -+int __init omapdss_init_of(void); -+ - #endif /* __ASSEMBLER__ */ - #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ ---- a/arch/arm/mach-omap2/devices.c -+++ b/arch/arm/mach-omap2/devices.c -@@ -37,6 +37,7 @@ - #include "mux.h" - #include "control.h" - #include "devices.h" -+#include "display.h" - - #define L3_MODULES_MAX_LEN 12 - #define L3_MODULES 3 -@@ -466,13 +467,13 @@ static struct platform_device omap_vout_ - .resource = &omap_vout_resource[0], - .id = -1, - }; --static void omap_init_vout(void) -+ -+int __init omap_init_vout(void) - { -- if (platform_device_register(&omap_vout_device) < 0) -- printk(KERN_ERR "Unable to register OMAP-VOUT device\n"); -+ return platform_device_register(&omap_vout_device); - } - #else --static inline void omap_init_vout(void) {} -+int __init omap_init_vout(void) { return 0; } - #endif - - #if IS_ENABLED(CONFIG_WL12XX) -@@ -524,9 +525,9 @@ static int __init omap2_init_devices(voi - omap_init_audio(); - omap_init_camera(); - omap_init_hdmi_audio(); -- omap_init_mbox(); - /* If dtb is there, the devices will be created dynamically */ - if (!of_have_populated_dt()) { -+ omap_init_mbox(); - omap_init_mcspi(); - omap_init_sham(); - omap_init_aes(); -@@ -536,7 +537,6 @@ static int __init omap2_init_devices(voi - omap_init_wl12xx_of(); - } - omap_init_sti(); -- omap_init_vout(); - - return 0; - } ---- a/arch/arm/mach-omap2/display.c -+++ b/arch/arm/mach-omap2/display.c -@@ -23,6 +23,8 @@ - #include <linux/clk.h> - #include <linux/err.h> - #include <linux/delay.h> -+#include <linux/of.h> -+#include <linux/of_platform.h> - - #include <video/omapdss.h> - #include "omap_hwmod.h" -@@ -316,6 +318,10 @@ static enum omapdss_version __init omap_ - return OMAPDSS_VER_OMAP4; - else if (soc_is_omap54xx()) - return OMAPDSS_VER_OMAP5; -+ else if (soc_is_dra7xx()) -+ return OMAPDSS_VER_DRA7xx; -+ else if (soc_is_am43xx()) -+ return OMAPDSS_VER_AM43xx; - else - return OMAPDSS_VER_UNKNOWN; - } -@@ -416,6 +422,34 @@ int __init omap_display_init(struct omap - } - } - -+ /* create DRM device */ -+ r = omap_init_drm(); -+ if (r < 0) { -+ pr_err("Unable to register omapdrm device\n"); -+ return r; -+ } -+ -+ /* create vrfb device */ -+ r = omap_init_vrfb(); -+ if (r < 0) { -+ pr_err("Unable to register omapvrfb device\n"); -+ return r; -+ } -+ -+ /* create FB device */ -+ r = omap_init_fb(); -+ if (r < 0) { -+ pr_err("Unable to register omapfb device\n"); -+ return r; -+ } -+ -+ /* create V4L2 display device */ -+ r = omap_init_vout(); -+ if (r < 0) { -+ pr_err("Unable to register omap_vout device\n"); -+ return r; -+ } -+ - return 0; - } - -@@ -564,3 +598,63 @@ int omap_dss_reset(struct omap_hwmod *oh - - return r; - } -+ -+int __init omapdss_init_of(void) -+{ -+ int r; -+ enum omapdss_version ver; -+ -+ static struct omap_dss_board_info board_data = { -+ .dsi_enable_pads = omap_dsi_enable_pads, -+ .dsi_disable_pads = omap_dsi_disable_pads, -+ .get_context_loss_count = omap_pm_get_dev_context_loss_count, -+ .set_min_bus_tput = omap_dss_set_min_bus_tput, -+ }; -+ -+ ver = omap_display_get_version(); -+ -+ if (ver == OMAPDSS_VER_UNKNOWN) { -+ pr_err("DSS not supported on this SoC\n"); -+ return -ENODEV; -+ } -+ -+ board_data.version = ver; -+ -+ omap_display_device.dev.platform_data = &board_data; -+ -+ r = platform_device_register(&omap_display_device); -+ if (r < 0) { -+ pr_err("Unable to register omapdss device\n"); -+ return r; -+ } -+ -+ /* create DRM device */ -+ r = omap_init_drm(); -+ if (r < 0) { -+ pr_err("Unable to register omapdrm device\n"); -+ return r; -+ } -+ -+ /* create vrfb device */ -+ r = omap_init_vrfb(); -+ if (r < 0) { -+ pr_err("Unable to register omapvrfb device\n"); -+ return r; -+ } -+ -+ /* create FB device */ -+ r = omap_init_fb(); -+ if (r < 0) { -+ pr_err("Unable to register omapfb device\n"); -+ return r; -+ } -+ -+ /* create V4L2 display device */ -+ r = omap_init_vout(); -+ if (r < 0) { -+ pr_err("Unable to register omap_vout device\n"); -+ return r; -+ } -+ -+ return 0; -+} ---- a/arch/arm/mach-omap2/display.h -+++ b/arch/arm/mach-omap2/display.h -@@ -26,4 +26,8 @@ struct omap_dss_dispc_dev_attr { - bool has_framedonetv_irq; - }; - -+int omap_init_drm(void); -+int omap_init_vrfb(void); -+int omap_init_fb(void); -+int omap_init_vout(void); - #endif ---- a/arch/arm/mach-omap2/drm.c -+++ b/arch/arm/mach-omap2/drm.c -@@ -26,10 +26,9 @@ - #include <linux/platform_data/omap_drm.h> - - #include "soc.h" --#include "omap_device.h" --#include "omap_hwmod.h" -+#include "display.h" - --#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE) -+#if defined(CONFIG_DRM_OMAP) || defined(CONFIG_DRM_OMAP_MODULE) - - static struct omap_drm_platform_data platform_data; - -@@ -42,26 +41,13 @@ static struct platform_device omap_drm_d - .id = 0, - }; - --static int __init omap_init_drm(void) -+int __init omap_init_drm(void) - { -- struct omap_hwmod *oh = NULL; -- struct platform_device *pdev; -- -- /* lookup and populate the DMM information, if present - OMAP4+ */ -- oh = omap_hwmod_lookup("dmm"); -- -- if (oh) { -- pdev = omap_device_build(oh->name, -1, oh, NULL, 0); -- WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", -- oh->name); -- } -- - platform_data.omaprev = GET_OMAP_TYPE; - - return platform_device_register(&omap_drm_device); - - } -- --omap_arch_initcall(omap_init_drm); -- -+#else -+int __init omap_init_drm(void) { return 0; } - #endif ---- a/arch/arm/mach-omap2/dss-common.c -+++ /dev/null -@@ -1,215 +0,0 @@ --/* -- * Copyright (C) 2012 Texas Instruments, Inc.. -- * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> -- * -- * 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. -- * -- * 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 St, Fifth Floor, Boston, MA -- * 02110-1301 USA -- * -- */ -- --/* -- * NOTE: this is a transitional file to help with DT adaptation. -- * This file will be removed when DSS supports DT. -- */ -- --#include <linux/kernel.h> --#include <linux/gpio.h> --#include <linux/platform_device.h> -- --#include <video/omapdss.h> --#include <video/omap-panel-data.h> -- --#include "soc.h" --#include "dss-common.h" --#include "mux.h" -- --#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ --#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ --#define HDMI_GPIO_HPD 63 /* Hotplug detect */ -- --#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0 -- --/* DVI Connector */ --static struct connector_dvi_platform_data omap4_panda_dvi_connector_pdata = { -- .name = "dvi", -- .source = "tfp410.0", -- .i2c_bus_num = 2, --}; -- --static struct platform_device omap4_panda_dvi_connector_device = { -- .name = "connector-dvi", -- .id = 0, -- .dev.platform_data = &omap4_panda_dvi_connector_pdata, --}; -- --/* TFP410 DPI-to-DVI chip */ --static struct encoder_tfp410_platform_data omap4_panda_tfp410_pdata = { -- .name = "tfp410.0", -- .source = "dpi.0", -- .data_lines = 24, -- .power_down_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO, --}; -- --static struct platform_device omap4_panda_tfp410_device = { -- .name = "tfp410", -- .id = 0, -- .dev.platform_data = &omap4_panda_tfp410_pdata, --}; -- --/* HDMI Connector */ --static struct connector_hdmi_platform_data omap4_panda_hdmi_connector_pdata = { -- .name = "hdmi", -- .source = "tpd12s015.0", --}; -- --static struct platform_device omap4_panda_hdmi_connector_device = { -- .name = "connector-hdmi", -- .id = 0, -- .dev.platform_data = &omap4_panda_hdmi_connector_pdata, --}; -- --/* TPD12S015 HDMI ESD protection & level shifter chip */ --static struct encoder_tpd12s015_platform_data omap4_panda_tpd_pdata = { -- .name = "tpd12s015.0", -- .source = "hdmi.0", -- -- .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, -- .ls_oe_gpio = HDMI_GPIO_LS_OE, -- .hpd_gpio = HDMI_GPIO_HPD, --}; -- --static struct platform_device omap4_panda_tpd_device = { -- .name = "tpd12s015", -- .id = 0, -- .dev.platform_data = &omap4_panda_tpd_pdata, --}; -- --static struct omap_dss_board_info omap4_panda_dss_data = { -- .default_display_name = "dvi", --}; -- --void __init omap4_panda_display_init_of(void) --{ -- omap_display_init(&omap4_panda_dss_data); -- -- platform_device_register(&omap4_panda_tfp410_device); -- platform_device_register(&omap4_panda_dvi_connector_device); -- -- platform_device_register(&omap4_panda_tpd_device); -- platform_device_register(&omap4_panda_hdmi_connector_device); --} -- -- --/* OMAP4 Blaze display data */ -- --#define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */ --#define DLP_POWER_ON_GPIO 40 -- --static struct panel_dsicm_platform_data dsi1_panel = { -- .name = "lcd", -- .source = "dsi.0", -- .reset_gpio = 102, -- .use_ext_te = false, -- .ext_te_gpio = 101, -- .pin_config = { -- .num_pins = 6, -- .pins = { 0, 1, 2, 3, 4, 5 }, -- }, --}; -- --static struct platform_device sdp4430_lcd_device = { -- .name = "panel-dsi-cm", -- .id = 0, -- .dev.platform_data = &dsi1_panel, --}; -- --static struct panel_dsicm_platform_data dsi2_panel = { -- .name = "lcd2", -- .source = "dsi.1", -- .reset_gpio = 104, -- .use_ext_te = false, -- .ext_te_gpio = 103, -- .pin_config = { -- .num_pins = 6, -- .pins = { 0, 1, 2, 3, 4, 5 }, -- }, --}; -- --static struct platform_device sdp4430_lcd2_device = { -- .name = "panel-dsi-cm", -- .id = 1, -- .dev.platform_data = &dsi2_panel, --}; -- --/* HDMI Connector */ --static struct connector_hdmi_platform_data sdp4430_hdmi_connector_pdata = { -- .name = "hdmi", -- .source = "tpd12s015.0", --}; -- --static struct platform_device sdp4430_hdmi_connector_device = { -- .name = "connector-hdmi", -- .id = 0, -- .dev.platform_data = &sdp4430_hdmi_connector_pdata, --}; -- --/* TPD12S015 HDMI ESD protection & level shifter chip */ --static struct encoder_tpd12s015_platform_data sdp4430_tpd_pdata = { -- .name = "tpd12s015.0", -- .source = "hdmi.0", -- -- .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, -- .ls_oe_gpio = HDMI_GPIO_LS_OE, -- .hpd_gpio = HDMI_GPIO_HPD, --}; -- --static struct platform_device sdp4430_tpd_device = { -- .name = "tpd12s015", -- .id = 0, -- .dev.platform_data = &sdp4430_tpd_pdata, --}; -- -- --static struct omap_dss_board_info sdp4430_dss_data = { -- .default_display_name = "lcd", --}; -- --/* -- * we select LCD2 by default (instead of Pico DLP) by setting DISPLAY_SEL_GPIO. -- * Setting DLP_POWER_ON gpio enables the VDLP_2V5 VDLP_1V8 and VDLP_1V0 rails -- * used by picodlp on the 4430sdp platform. Keep this gpio disabled as LCD2 is -- * selected by default -- */ --void __init omap_4430sdp_display_init_of(void) --{ -- int r; -- -- r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH, -- "display_sel"); -- if (r) -- pr_err("%s: Could not get display_sel GPIO\n", __func__); -- -- r = gpio_request_one(DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW, -- "DLP POWER ON"); -- if (r) -- pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__); -- -- omap_display_init(&sdp4430_dss_data); -- -- platform_device_register(&sdp4430_lcd_device); -- platform_device_register(&sdp4430_lcd2_device); -- -- platform_device_register(&sdp4430_tpd_device); -- platform_device_register(&sdp4430_hdmi_connector_device); --} ---- a/arch/arm/mach-omap2/dss-common.h -+++ /dev/null -@@ -1,12 +0,0 @@ --#ifndef __OMAP_DSS_COMMON__ --#define __OMAP_DSS_COMMON__ -- --/* -- * NOTE: this is a transitional file to help with DT adaptation. -- * This file will be removed when DSS supports DT. -- */ -- --void __init omap4_panda_display_init_of(void); --void __init omap_4430sdp_display_init_of(void); -- --#endif ---- a/arch/arm/mach-omap2/fb.c -+++ b/arch/arm/mach-omap2/fb.c -@@ -32,6 +32,7 @@ - #include <asm/mach/map.h> - - #include "soc.h" -+#include "display.h" - - #ifdef CONFIG_OMAP2_VRFB - -@@ -64,7 +65,7 @@ static const struct resource omap3_vrfb_ - DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"), - }; - --static int __init omap_init_vrfb(void) -+int __init omap_init_vrfb(void) - { - struct platform_device *pdev; - const struct resource *res; -@@ -85,8 +86,8 @@ static int __init omap_init_vrfb(void) - - return PTR_RET(pdev); - } -- --omap_arch_initcall(omap_init_vrfb); -+#else -+int __init omap_init_vrfb(void) { return 0; } - #endif - - #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) -@@ -105,11 +106,10 @@ static struct platform_device omap_fb_de - .num_resources = 0, - }; - --static int __init omap_init_fb(void) -+int __init omap_init_fb(void) - { - return platform_device_register(&omap_fb_device); - } -- --omap_arch_initcall(omap_init_fb); -- -+#else -+int __init omap_init_fb(void) { return 0; } - #endif ---- a/arch/arm/mach-omap2/gpmc.c -+++ b/arch/arm/mach-omap2/gpmc.c -@@ -68,6 +68,9 @@ - #define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */ - #define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */ - #define GPMC_ECC_BCH_RESULT_3 0x24c /* not available on OMAP2 */ -+#define GPMC_ECC_BCH_RESULT_4 0x300 /* not available on OMAP2 */ -+#define GPMC_ECC_BCH_RESULT_5 0x304 /* not available on OMAP2 */ -+#define GPMC_ECC_BCH_RESULT_6 0x308 /* not available on OMAP2 */ - - /* GPMC ECC control settings */ - #define GPMC_ECC_CTRL_ECCCLEAR 0x100 -@@ -659,13 +662,19 @@ void gpmc_update_nand_reg(struct gpmc_na - - for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) { - reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 + -- GPMC_BCH_SIZE * i; -+ (GPMC_BCH_SIZE * i); - reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 + -- GPMC_BCH_SIZE * i; -+ (GPMC_BCH_SIZE * i); - reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 + -- GPMC_BCH_SIZE * i; -+ (GPMC_BCH_SIZE * i); - reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 + -- GPMC_BCH_SIZE * i; -+ (GPMC_BCH_SIZE * i); -+ reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 + -+ (GPMC_BCH_SIZE * i); -+ reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 + -+ (GPMC_BCH_SIZE * i); -+ reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 + -+ (GPMC_BCH_SIZE * i); - } - } - -@@ -1340,15 +1349,6 @@ static void __maybe_unused gpmc_read_tim - } - - #ifdef CONFIG_MTD_NAND -- --static const char * const nand_ecc_opts[] = { -- [OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw", -- [OMAP_ECC_HAMMING_CODE_HW] = "hw", -- [OMAP_ECC_HAMMING_CODE_HW_ROMCODE] = "hw-romcode", -- [OMAP_ECC_BCH4_CODE_HW] = "bch4", -- [OMAP_ECC_BCH8_CODE_HW] = "bch8", --}; -- - static const char * const nand_xfer_types[] = { - [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", - [NAND_OMAP_POLLED] = "polled", -@@ -1377,17 +1377,42 @@ static int gpmc_probe_nand_child(struct - - gpmc_nand_data->cs = val; - gpmc_nand_data->of_node = child; -- -- if (!of_property_read_string(child, "ti,nand-ecc-opt", &s)) -- for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++) -- if (!strcasecmp(s, nand_ecc_opts[val])) { -- gpmc_nand_data->ecc_opt = val; -- break; -- } -+ /* Detect availability of ELM module */ -+ gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); -+ if (gpmc_nand_data->elm_of_node == NULL) -+ gpmc_nand_data->elm_of_node = -+ of_parse_phandle(child, "elm_id", 0); -+ if (gpmc_nand_data->elm_of_node == NULL) -+ pr_warn("%s: ti,elm-id property not found\n", __func__); -+ -+ /* select NAND ecc-scheme */ -+ if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { -+ pr_err("%s: valid ti,nand-ecc-opt not found\n", __func__); -+ return -ENODEV; -+ } -+ if (!strcmp(s, "ham1") || !strcmp(s, "sw") || !strcmp(s, "hw") || -+ !strcmp(s, "hw-romcode")) -+ gpmc_nand_data->ecc_opt = OMAP_ECC_HAMMING_CODE_HW; -+ else if (!strcmp(s, "bch4")) -+ if (gpmc_nand_data->elm_of_node) -+ gpmc_nand_data->ecc_opt = OMAP_ECC_BCH4_CODE_HW; -+ else -+ gpmc_nand_data->ecc_opt = -+ OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; -+ else if (!strcmp(s, "bch8")) -+ if (gpmc_nand_data->elm_of_node) -+ gpmc_nand_data->ecc_opt = OMAP_ECC_BCH8_CODE_HW; -+ else -+ gpmc_nand_data->ecc_opt = -+ OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; -+ else if (!strcmp(s, "bch16")) -+ gpmc_nand_data->ecc_opt = OMAP_ECC_BCH16_CODE_HW; -+ else -+ pr_err("%s: ti,nand-ecc-opt: invalid property val\n", __func__); - - if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) - for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++) -- if (!strcasecmp(s, nand_xfer_types[val])) { -+ if (!strcmp(s, nand_xfer_types[val])) { - gpmc_nand_data->xfer_type = val; - break; - } ---- a/arch/arm/mach-omap2/gpmc-nand.c -+++ b/arch/arm/mach-omap2/gpmc-nand.c -@@ -43,28 +43,6 @@ static struct platform_device gpmc_nand_ - .resource = gpmc_nand_resource, - }; - --static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt) --{ -- /* support only OMAP3 class */ -- if (!cpu_is_omap34xx() && !soc_is_am33xx()) { -- pr_err("BCH ecc is not supported on this CPU\n"); -- return 0; -- } -- -- /* -- * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1 -- * and AM33xx derivates. Other chips may be added if confirmed to work. -- */ -- if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) && -- (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0)) && -- (!soc_is_am33xx())) { -- pr_err("BCH 4-bit mode is not supported on this CPU\n"); -- return 0; -- } -- -- return 1; --} -- - int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, - struct gpmc_timings *gpmc_t) - { -@@ -127,9 +105,6 @@ int gpmc_nand_init(struct omap_nand_plat - - gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); - -- if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) -- return -EINVAL; -- - err = platform_device_register(&gpmc_nand_device); - if (err < 0) { - dev_err(dev, "Unable to register NAND device\n"); ---- a/arch/arm/mach-omap2/io.c -+++ b/arch/arm/mach-omap2/io.c -@@ -322,6 +322,7 @@ void __init ti81xx_map_io(void) - void __init am33xx_map_io(void) - { - iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); -+ am33xx_dram_sync_init(); - } - #endif - -@@ -398,6 +399,7 @@ static void __init __maybe_unused omap_c - { - omap_mux_late_init(); - omap2_common_pm_late_init(); -+ omap2_common_suspend_init(); - omap_soc_device_init(); - } - -@@ -488,21 +490,29 @@ void __init omap3_init_early(void) - void __init omap3430_init_early(void) - { - omap3_init_early(); -+ if (of_have_populated_dt()) -+ omap_clk_init = omap3430_clk_init; - } - - void __init omap35xx_init_early(void) - { - omap3_init_early(); -+ if (of_have_populated_dt()) -+ omap_clk_init = omap3430_clk_init; - } - - void __init omap3630_init_early(void) - { - omap3_init_early(); -+ if (of_have_populated_dt()) -+ omap_clk_init = omap3630_clk_init; - } - - void __init am35xx_init_early(void) - { - omap3_init_early(); -+ if (of_have_populated_dt()) -+ omap_clk_init = am35xx_clk_init; - } - - void __init ti81xx_init_early(void) -@@ -520,7 +530,10 @@ void __init ti81xx_init_early(void) - omap3xxx_clockdomains_init(); - omap3xxx_hwmod_init(); - omap_hwmod_init_postsetup(); -- omap_clk_init = omap3xxx_clk_init; -+ if (of_have_populated_dt()) -+ omap_clk_init = ti81xx_clk_init; -+ else -+ omap_clk_init = omap3xxx_clk_init; - } - - void __init omap3_init_late(void) -@@ -583,6 +596,13 @@ void __init am33xx_init_early(void) - omap_hwmod_init_postsetup(); - omap_clk_init = am33xx_clk_init; - } -+ -+void __init am33xx_init_late(void) -+{ -+ omap_hwmod_force_mstandby_repeated(); -+ omap2_common_pm_late_init(); -+ am33xx_pm_init(); -+} - #endif - - #ifdef CONFIG_SOC_AM43XX -@@ -594,7 +614,15 @@ void __init am43xx_init_early(void) - NULL); - omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE)); - omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE), NULL); -+ omap_prm_base_init(); -+ omap_cm_base_init(); - omap3xxx_check_revision(); -+ am33xx_check_features(); -+ am43xx_powerdomains_init(); -+ am43xx_clockdomains_init(); -+ am33xx_hwmod_init(); -+ omap_hwmod_init_postsetup(); -+ omap_clk_init = am43xx_clk_init; - } - #endif - -@@ -650,6 +678,16 @@ void __init omap5_init_early(void) - omap54xx_clockdomains_init(); - omap54xx_hwmod_init(); - omap_hwmod_init_postsetup(); -+ omap_clk_init = omap5xxx_clk_init; -+} -+ -+void __init omap5_init_late(void) -+{ -+ omap_mux_late_init(); -+ omap2_common_pm_late_init(); -+ omap2_common_suspend_init(); -+ omap4_pm_init(); -+ omap2_clk_enable_autoidle_all(); - } - #endif - -@@ -670,9 +708,17 @@ void __init dra7xx_init_early(void) - dra7xx_clockdomains_init(); - dra7xx_hwmod_init(); - omap_hwmod_init_postsetup(); -+ omap_clk_init = dra7xx_clk_init; - } --#endif - -+void __init dra7xx_init_late(void) -+{ -+ omap2_common_pm_late_init(); -+ omap2_common_suspend_init(); -+ omap4_pm_init(); -+ omap2_clk_enable_autoidle_all(); -+} -+#endif - - void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, - struct omap_sdrc_params *sdrc_cs1) ---- a/arch/arm/mach-omap2/Kconfig -+++ b/arch/arm/mach-omap2/Kconfig -@@ -66,11 +66,16 @@ config SOC_OMAP5 - config SOC_AM33XX - bool "TI AM33XX" - depends on ARCH_MULTI_V7 -- select ARCH_OMAP2PLUS -+ default y - select ARM_CPU_SUSPEND if PM -+ select COMMON_CLK - select CPU_V7 -+ select MAILBOX if PM - select MULTI_IRQ_HANDLER -- select COMMON_CLK -+ select ARCH_HAS_RESET_CONTROLLER -+ select OMAP_MBOX_FWK if PM -+ select OMAP2PLUS_MBOX if PM -+ select RESET_TI - - config SOC_AM43XX - bool "TI AM43x" -@@ -81,29 +86,9 @@ config SOC_AM43XX - select ARM_GIC - select COMMON_CLK - select MACH_OMAP_GENERIC -- --config ARCH_OMAP2PLUS -- bool -- select ARCH_HAS_BANDGAP -- select ARCH_HAS_CPUFREQ -- select ARCH_HAS_HOLES_MEMORYMODEL -- select ARCH_OMAP -- select ARCH_REQUIRE_GPIOLIB -- select CLKDEV_LOOKUP -- select CLKSRC_MMIO -- select GENERIC_CLOCKEVENTS -- select GENERIC_IRQ_CHIP -- select HAVE_CLK -- select OMAP_DM_TIMER -- select PINCTRL -- select PROC_DEVICETREE if PROC_FS -- select SOC_BUS -- select SPARSE_IRQ -- select TI_PRIV_EDMA -- select USE_OF -- help -- Systems based on OMAP2, OMAP3, OMAP4 or OMAP5 -- -+ select MIGHT_HAVE_CACHE_L2X0 -+ select ARCH_HAS_RESET_CONTROLLER -+ select RESET_TI - - if ARCH_OMAP2PLUS - -@@ -141,6 +126,9 @@ config SOC_DRA7XX - select ARM_GIC - select HAVE_SMP - select COMMON_CLK -+ select CROSSBAR -+ select ARCH_HAS_RESET_CONTROLLER -+ select RESET_TI - - comment "OMAP Core Type" - depends on ARCH_OMAP2 ---- a/arch/arm/mach-omap2/Makefile -+++ b/arch/arm/mach-omap2/Makefile -@@ -8,7 +8,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := - # Common support - obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \ - common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ -- omap_device.o sram.o -+ omap_device.o sram.o drm.o - - omap-2-3-common = irq.o - hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ -@@ -60,6 +60,7 @@ AFLAGS_sram34xx.o :=-Wa,-march=armv7-a - obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o - obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o - obj-$(CONFIG_SOC_AM33XX) += am33xx-restart.o -+obj-$(CONFIG_SOC_AM43XX) += am33xx-restart.o - obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o - obj-$(CONFIG_ARCH_OMAP4) += omap4-restart.o - obj-$(CONFIG_SOC_OMAP5) += omap4-restart.o -@@ -91,6 +92,7 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sl - obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o - obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o - obj-$(CONFIG_SOC_DRA7XX) += omap-mpuss-lowpower.o -+obj-$(CONFIG_SOC_AM33XX) += pm33xx.o sleep33xx.o wkup_m3.o - obj-$(CONFIG_PM_DEBUG) += pm-debug.o - - obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o -@@ -98,6 +100,7 @@ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) + - - AFLAGS_sleep24xx.o :=-Wa,-march=armv6 - AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) -+AFLAGS_sleep33xx.o :=-Wa,-march=armv7-a$(plus_sec) - - endif - -@@ -112,13 +115,13 @@ obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xx - obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o - obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o - obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o --obj-$(CONFIG_SOC_AM43XX) += prm33xx.o cm33xx.o - omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ - prcm_mpu44xx.o prminst44xx.o \ - vc44xx_data.o vp44xx_data.o - obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) - obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common) - obj-$(CONFIG_SOC_DRA7XX) += $(omap-prcm-4-5-common) -+obj-$(CONFIG_SOC_AM43XX) += $(omap-prcm-4-5-common) - - # OMAP voltage domains - voltagedomain-common := voltage.o vc.o vp.o -@@ -146,6 +149,7 @@ obj-$(CONFIG_ARCH_OMAP4) += powerdomain - obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common) - obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o - obj-$(CONFIG_SOC_AM43XX) += $(powerdomain-common) -+obj-$(CONFIG_SOC_AM43XX) += powerdomains43xx_data.o - obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common) - obj-$(CONFIG_SOC_OMAP5) += powerdomains54xx_data.o - obj-$(CONFIG_SOC_DRA7XX) += $(powerdomain-common) -@@ -165,6 +169,7 @@ obj-$(CONFIG_ARCH_OMAP4) += clockdomain - obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common) - obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o - obj-$(CONFIG_SOC_AM43XX) += $(clockdomain-common) -+obj-$(CONFIG_SOC_AM43XX) += clockdomains43xx_data.o - obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common) - obj-$(CONFIG_SOC_OMAP5) += clockdomains54xx_data.o - obj-$(CONFIG_SOC_DRA7XX) += $(clockdomain-common) -@@ -184,10 +189,9 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o - obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o - obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o - obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o --obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) cclock44xx_data.o -+obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) - obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o - obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o --obj-$(CONFIG_SOC_AM33XX) += cclock33xx_data.o - obj-$(CONFIG_SOC_OMAP5) += $(clock-common) - obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o - -@@ -210,6 +214,7 @@ obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_ - obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_interconnect_data.o - obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o - obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_data.o -+obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_data.o - obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o - obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o - obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o -@@ -228,10 +233,6 @@ endif - # OMAP2420 MSDI controller integration support ("MMC") - obj-$(CONFIG_SOC_OMAP2420) += msdi.o - --ifneq ($(CONFIG_DRM_OMAP),) --obj-y += drm.o --endif -- - # Specific board support - obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o - obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o -@@ -305,4 +306,4 @@ endif - emac-$(CONFIG_TI_DAVINCI_EMAC) := am35xx-emac.o - obj-y += $(emac-m) $(emac-y) - --obj-y += common-board-devices.o twl-common.o dss-common.o -+obj-y += common-board-devices.o twl-common.o ---- a/arch/arm/mach-omap2/omap4-common.c -+++ b/arch/arm/mach-omap2/omap4-common.c -@@ -181,7 +181,7 @@ static int __init omap_l2_cache_init(voi - * To avoid code running on other OMAPs in - * multi-omap builds - */ -- if (!cpu_is_omap44xx()) -+ if (!cpu_is_omap44xx() && !soc_is_am43xx()) - return -ENODEV; - - /* Static mapping, never released */ -@@ -193,26 +193,32 @@ static int __init omap_l2_cache_init(voi - * 16-way associativity, parity disabled - * Way size - 32KB (es1.0) - * Way size - 64KB (es2.0 +) -+ * Way size - 16KB (am43xx) - */ - aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) | - (0x1 << 25) | - (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) | - (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT)); - -- if (omap_rev() == OMAP4430_REV_ES1_0) { -+ if (soc_is_am43xx()) -+ aux_ctrl |= ((0x1 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | -+ (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) | -+ (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) | -+ (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT)); -+ else if (omap_rev() == OMAP4430_REV_ES1_0) - aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT; -- } else { -+ else - aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | - (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) | - (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) | - (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) | - (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT)); -- } -- if (omap_rev() != OMAP4430_REV_ES1_0) -+ -+ if (soc_is_am43xx() || (omap_rev() != OMAP4430_REV_ES1_0)) - omap_smc1(0x109, aux_ctrl); - - /* Enable PL310 L2 Cache controller */ -- omap_smc1(0x102, 0x1); -+ omap_smc1(0x102, L2X0_CTRL_EN); - - if (of_have_populated_dt()) - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK); -@@ -233,7 +239,10 @@ omap_early_initcall(omap_l2_cache_init); - - void __iomem *omap4_get_sar_ram_base(void) - { -- return sar_ram_base; -+ if (sar_ram_base) -+ return sar_ram_base; -+ else -+ return NULL; - } - - /* ---- a/arch/arm/mach-omap2/omap4-sar-layout.h -+++ b/arch/arm/mach-omap2/omap4-sar-layout.h -@@ -31,6 +31,8 @@ - /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ - #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 - #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 -+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xe00 -+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xe04 - - #define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500) - #define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504) ---- a/arch/arm/mach-omap2/omap_device.c -+++ b/arch/arm/mach-omap2/omap_device.c -@@ -35,6 +35,7 @@ - #include <linux/pm_runtime.h> - #include <linux/of.h> - #include <linux/notifier.h> -+#include <linux/suspend.h> - - #include "soc.h" - #include "omap_device.h" -@@ -45,37 +46,32 @@ - static void _add_clkdev(struct omap_device *od, const char *clk_alias, - const char *clk_name) - { -+ int ret; - struct clk *r; -- struct clk_lookup *l; -+ struct device *dev = &od->pdev->dev; -+ struct device_node *node = dev->of_node; - - if (!clk_alias || !clk_name) - return; - -- dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name); -+ dev_dbg(dev, "Creating %s -> %s\n", clk_alias, clk_name); - -- r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias); -+ r = clk_get(dev, clk_alias); - if (!IS_ERR(r)) { -- dev_warn(&od->pdev->dev, -- "alias %s already exists\n", clk_alias); -+ if (!node) -+ dev_warn(dev, "alias '%s' already exists\n", clk_alias); - clk_put(r); - return; - } - -- r = clk_get(NULL, clk_name); -- if (IS_ERR(r)) { -- dev_err(&od->pdev->dev, -- "clk_get for %s failed\n", clk_name); -- return; -- } -+ if (node) -+ dev_err(dev, "FIXME: clock-name '%s' DOES NOT exist in dt!\n", -+ clk_alias); - -- l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev->dev)); -- if (!l) { -- dev_err(&od->pdev->dev, -- "clkdev_alloc for %s failed\n", clk_alias); -- return; -- } -- -- clkdev_add(l); -+ ret = clk_add_alias(clk_alias, dev_name(dev), (char *)clk_name, dev); -+ if (ret) -+ dev_err(dev, "Failed to alias %s to %s: %d\n", clk_alias, -+ clk_name, ret); - } - - /** -@@ -621,6 +617,13 @@ static int _od_suspend_noirq(struct devi - - if (!ret && !pm_runtime_status_suspended(dev)) { - if (pm_generic_runtime_suspend(dev) == 0) { -+ if (!pm_runtime_suspended(dev)) { -+ /* NOTE: *might* indicate driver race */ -+ dev_dbg(dev, "%s: Force suspending\n", -+ __func__); -+ pm_runtime_set_suspended(dev); -+ od->flags |= OMAP_DEVICE_SUSPEND_FORCED; -+ } - omap_device_idle(pdev); - od->flags |= OMAP_DEVICE_SUSPENDED; - } -@@ -634,10 +637,15 @@ static int _od_resume_noirq(struct devic - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *od = to_omap_device(pdev); - -- if ((od->flags & OMAP_DEVICE_SUSPENDED) && -- !pm_runtime_status_suspended(dev)) { -+ if (od->flags & OMAP_DEVICE_SUSPENDED) { - od->flags &= ~OMAP_DEVICE_SUSPENDED; - omap_device_enable(pdev); -+ -+ if (od->flags & OMAP_DEVICE_SUSPEND_FORCED) { -+ pm_runtime_set_active(dev); -+ od->flags &= ~OMAP_DEVICE_SUSPEND_FORCED; -+ } -+ - pm_generic_runtime_resume(dev); - } - -@@ -850,6 +858,7 @@ static int __init omap_device_late_idle( - { - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *od = to_omap_device(pdev); -+ struct omap_hwmod *oh = NULL; - int i; - - if (!od) -@@ -874,6 +883,19 @@ static int __init omap_device_late_idle( - __func__); - omap_device_idle(pdev); - } -+ } else { -+ /* -+ * There are some IPs that do not have MSTANDBY asserted by default -+ * which is necessary for PER domain transition. If the drivers -+ * are not compiled into the kernel HWMOD code will not change the -+ * state of the IPs if the IP was never enabled, so we keep track of -+ * them here to idle them with a pm_notifier. -+ */ -+ for (i = 0; i < od->hwmods_cnt; i++) { -+ oh = od->hwmods[i]; -+ if (oh->flags & HWMOD_FORCE_MSTANDBY_REPEATED) -+ omap_hwmod_disable_force_mstandby_repeated(oh); -+ } - } - - return 0; ---- a/arch/arm/mach-omap2/omap_device.h -+++ b/arch/arm/mach-omap2/omap_device.h -@@ -38,6 +38,7 @@ extern struct dev_pm_domain omap_device_ - - /* omap_device.flags values */ - #define OMAP_DEVICE_SUSPENDED BIT(0) -+#define OMAP_DEVICE_SUSPEND_FORCED BIT(1) - - /** - * struct omap_device - omap_device wrapper for platform_devices ---- a/arch/arm/mach-omap2/omap-hotplug.c -+++ b/arch/arm/mach-omap2/omap-hotplug.c -@@ -22,6 +22,7 @@ - #include "omap-wakeupgen.h" - #include "common.h" - #include "powerdomain.h" -+#include "soc.h" - - /* - * platform-specific code to shutdown a CPU -@@ -47,7 +48,10 @@ void __ref omap4_cpu_die(unsigned int cp - /* - * Enter into low power state - */ -- omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); -+ if (soc_is_dra7xx()) -+ omap4_hotplug_cpu(cpu, PWRDM_POWER_RET); -+ else -+ omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); - - if (omap_secure_apis_support()) - boot_cpu = omap_read_auxcoreboot0(); ---- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c -@@ -26,9 +26,11 @@ - #include "cm33xx.h" - #include "prm33xx.h" - #include "prm-regbits-33xx.h" -+#include "prcm43xx.h" - #include "i2c.h" - #include "mmc.h" - #include "wd_timer.h" -+#include "soc.h" - - /* - * IP blocks -@@ -52,7 +54,7 @@ static struct omap_hwmod am33xx_emif_hwm - .name = "emif", - .class = &am33xx_emif_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_ddr_m2_div2_ck", - .prcm = { - .omap4 = { -@@ -74,11 +76,9 @@ static struct omap_hwmod am33xx_l3_main_ - .name = "l3_main", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -- .main_clk = "l3_gclk", -+ .flags = HWMOD_INIT_NO_IDLE, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_L3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -96,11 +96,10 @@ static struct omap_hwmod am33xx_l3_instr - .name = "l3_instr", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -119,11 +118,10 @@ static struct omap_hwmod am33xx_l4_ls_hw - .name = "l4_ls", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -133,12 +131,10 @@ static struct omap_hwmod am33xx_l4_ls_hw - static struct omap_hwmod am33xx_l4_hs_hwmod = { - .name = "l4_hs", - .class = &am33xx_l4_hwmod_class, -- .clkdm_name = "l4hs_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l4hs_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -150,10 +146,9 @@ static struct omap_hwmod am33xx_l4_wkup_ - .name = "l4_wkup", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .flags = HWMOD_INIT_NO_IDLE, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -170,11 +165,10 @@ static struct omap_hwmod am33xx_mpu_hwmo - .name = "mpu", - .class = &am33xx_mpu_hwmod_class, - .clkdm_name = "mpu_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_mpu_m2_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -198,13 +192,9 @@ static struct omap_hwmod am33xx_wkup_m3_ - .class = &am33xx_wkup_m3_hwmod_class, - .clkdm_name = "l4_wkup_aon_clkdm", - /* Keep hardreset asserted */ -- .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, -- .main_clk = "dpll_core_m4_div2_ck", -+ .flags = HWMOD_NO_IDLEST, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, -- .rstctrl_offs = AM33XX_RM_WKUP_RSTCTRL_OFFSET, -- .rstst_offs = AM33XX_RM_WKUP_RSTST_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -233,8 +223,6 @@ static struct omap_hwmod am33xx_pruss_hw - .main_clk = "pruss_ocp_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET, -- .rstctrl_offs = AM33XX_RM_PER_RSTCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -259,9 +247,6 @@ static struct omap_hwmod am33xx_gfx_hwmo - .main_clk = "gfx_fck_div_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET, -- .rstctrl_offs = AM33XX_RM_GFX_RSTCTRL_OFFSET, -- .rstst_offs = AM33XX_RM_GFX_RSTST_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -305,11 +290,8 @@ static struct omap_hwmod_class am33xx_ad - static struct omap_hwmod am33xx_adc_tsc_hwmod = { - .name = "adc_tsc", - .class = &am33xx_adc_tsc_hwmod_class, -- .clkdm_name = "l4_wkup_clkdm", -- .main_clk = "adc_tsc_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -395,6 +377,7 @@ static struct omap_hwmod_class_sysconfig - .sysc_offs = 0x84, - .syss_offs = 0x88, - .sysc_flags = SYSS_HAS_RESET_STATUS, -+ .sysc_fields = &omap_hwmod_sysc_type4, - }; - - static struct omap_hwmod_class am33xx_aes0_hwmod_class = { -@@ -406,10 +389,8 @@ static struct omap_hwmod am33xx_aes0_hwm - .name = "aes", - .class = &am33xx_aes0_hwmod_class, - .clkdm_name = "l3_clkdm", -- .main_clk = "aes0_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_AES0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -432,10 +413,8 @@ static struct omap_hwmod am33xx_sha0_hwm - .name = "sham", - .class = &am33xx_sha0_hwmod_class, - .clkdm_name = "l3_clkdm", -- .main_clk = "l3_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -450,11 +429,9 @@ static struct omap_hwmod am33xx_ocmcram_ - .name = "ocmcram", - .class = &am33xx_ocmcram_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -- .main_clk = "l3_gclk", -+ .flags = HWMOD_INIT_NO_IDLE, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -501,7 +478,6 @@ static struct omap_hwmod am33xx_smartref - .main_clk = "smartreflex0_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -515,7 +491,6 @@ static struct omap_hwmod am33xx_smartref - .main_clk = "smartreflex1_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -532,11 +507,9 @@ static struct omap_hwmod am33xx_control_ - .name = "control", - .class = &am33xx_control_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -- .main_clk = "dpll_core_m4_div2_ck", -+ .flags = HWMOD_INIT_NO_IDLE, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -566,12 +539,11 @@ static struct omap_hwmod am33xx_cpgmac0_ - .name = "cpgmac0", - .class = &am33xx_cpgmac0_hwmod_class, - .clkdm_name = "cpsw_125mhz_clkdm", -- .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), -- .main_clk = "cpsw_125mhz_gclk", -+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | -+ HWMOD_FORCE_MSTANDBY_REPEATED), - .mpu_rt_idx = 1, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -588,7 +560,6 @@ static struct omap_hwmod am33xx_mdio_hwm - .name = "davinci_mdio", - .class = &am33xx_mdio_hwmod_class, - .clkdm_name = "cpsw_125mhz_clkdm", -- .main_clk = "cpsw_125mhz_gclk", - }; - - /* -@@ -603,10 +574,8 @@ static struct omap_hwmod am33xx_dcan0_hw - .name = "d_can0", - .class = &am33xx_dcan_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "dcan0_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -617,10 +586,8 @@ static struct omap_hwmod am33xx_dcan1_hw - .name = "d_can1", - .class = &am33xx_dcan_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "dcan1_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -647,10 +614,8 @@ static struct omap_hwmod am33xx_elm_hwmo - .name = "elm", - .class = &am33xx_elm_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_ELM_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -689,10 +654,8 @@ static struct omap_hwmod am33xx_epwmss0_ - .name = "epwmss0", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -703,7 +666,6 @@ static struct omap_hwmod am33xx_ecap0_hw - .name = "ecap0", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - }; - - /* eqep0 */ -@@ -719,7 +681,6 @@ static struct omap_hwmod am33xx_ehrpwm0_ - .name = "ehrpwm0", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - }; - - /* epwmss1 */ -@@ -727,10 +688,8 @@ static struct omap_hwmod am33xx_epwmss1_ - .name = "epwmss1", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -741,7 +700,6 @@ static struct omap_hwmod am33xx_ecap1_hw - .name = "ecap1", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - }; - - /* eqep1 */ -@@ -757,7 +715,6 @@ static struct omap_hwmod am33xx_ehrpwm1_ - .name = "ehrpwm1", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - }; - - /* epwmss2 */ -@@ -765,10 +722,8 @@ static struct omap_hwmod am33xx_epwmss2_ - .name = "epwmss2", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -779,7 +734,6 @@ static struct omap_hwmod am33xx_ecap2_hw - .name = "ecap2", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - }; - - /* eqep2 */ -@@ -795,7 +749,6 @@ static struct omap_hwmod am33xx_ehrpwm2_ - .name = "ehrpwm2", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - }; - - /* -@@ -825,90 +778,62 @@ static struct omap_gpio_dev_attr gpio_de - }; - - /* gpio0 */ --static struct omap_hwmod_opt_clk gpio0_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio0_dbclk" }, --}; - - static struct omap_hwmod am33xx_gpio0_hwmod = { - .name = "gpio1", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "dpll_core_m4_div2_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = gpio0_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio1 */ --static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio1_dbclk" }, --}; - - static struct omap_hwmod am33xx_gpio1_hwmod = { - .name = "gpio2", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = gpio1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio2 */ --static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio2_dbclk" }, --}; - - static struct omap_hwmod am33xx_gpio2_hwmod = { - .name = "gpio3", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = gpio2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio3 */ --static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio3_dbclk" }, --}; - - static struct omap_hwmod am33xx_gpio3_hwmod = { - .name = "gpio4", - .class = &am33xx_gpio_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = gpio3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - -@@ -932,11 +857,9 @@ static struct omap_hwmod am33xx_gpmc_hwm - .name = "gpmc", - .class = &am33xx_gpmc_hwmod_class, - .clkdm_name = "l3s_clkdm", -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -- .main_clk = "l3s_gclk", -+ .flags = HWMOD_INIT_NO_RESET, - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -971,10 +894,8 @@ static struct omap_hwmod am33xx_i2c1_hwm - .class = &i2c_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "dpll_per_m2_div4_wkupdm_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -987,10 +908,8 @@ static struct omap_hwmod am33xx_i2c2_hwm - .class = &i2c_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1003,10 +922,8 @@ static struct omap_hwmod am33xx_i2c3_hwm - .class = &i2c_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1065,10 +982,8 @@ static struct omap_hwmod am33xx_mailbox_ - .name = "mailbox", - .class = &am33xx_mailbox_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1098,7 +1013,6 @@ static struct omap_hwmod am33xx_mcasp0_h - .main_clk = "mcasp0_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1112,7 +1026,6 @@ static struct omap_hwmod am33xx_mcasp1_h - .main_clk = "mcasp1_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1147,7 +1060,6 @@ static struct omap_hwmod am33xx_mmc0_hwm - .main_clk = "mmc_clk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1166,7 +1078,6 @@ static struct omap_hwmod am33xx_mmc1_hwm - .main_clk = "mmc_clk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1184,7 +1095,6 @@ static struct omap_hwmod am33xx_mmc2_hwm - .main_clk = "mmc_clk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1213,10 +1123,8 @@ static struct omap_hwmod am33xx_rtc_hwmo - .name = "rtc", - .class = &am33xx_rtc_hwmod_class, - .clkdm_name = "l4_rtc_clkdm", -- .main_clk = "clk_32768_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1248,10 +1156,8 @@ static struct omap_hwmod am33xx_spi0_hwm - .name = "spi0", - .class = &am33xx_spi_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1263,10 +1169,8 @@ static struct omap_hwmod am33xx_spi1_hwm - .name = "spi1", - .class = &am33xx_spi_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1289,12 +1193,119 @@ static struct omap_hwmod am33xx_spinlock - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - }; - -+static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = { -+ .sysc_offs = 0x0010, -+ .sysc_flags = SYSC_HAS_SIDLEMODE, -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class am43xx_qspi_hwmod_class = { -+ .name = "qspi", -+ .sysc = &am43xx_qspi_sysc, -+}; -+ -+static struct omap_hwmod am43xx_qspi_hwmod = { -+ .name = "qspi", -+ .class = &am43xx_qspi_hwmod_class, -+ .clkdm_name = "l3s_clkdm", -+ .main_clk = "l3s_gclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* 'ocp2scp' class -+ * -+ */ -+ -+ -+static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = { -+ .name = "ocp2scp", -+}; -+ -+/* ocp2scp0 */ -+static struct omap_hwmod am43xx_ocp2scp0_hwmod = { -+ .name = "ocp2scp0", -+ .class = &am43xx_ocp2scp_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .main_clk = "l4ls_gclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* ocp2scp1 */ -+static struct omap_hwmod am43xx_ocp2scp1_hwmod = { -+ .name = "ocp2scp1", -+ .class = &am43xx_ocp2scp_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .main_clk = "l4ls_gclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* 'usb_otg_ss' class */ -+static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class am43xx_usb_otg_ss_hwmod_class = { -+ .name = "usb_otg_ss", -+ .sysc = &am43xx_usb_otg_ss_sysc, -+}; -+ -+/* usb_otg_ss0 */ -+static struct omap_hwmod am43xx_usb_otg_ss0_hwmod = { -+ .name = "usb_otg_ss0", -+ .class = &am43xx_usb_otg_ss_hwmod_class, -+ .clkdm_name = "l3s_clkdm", -+ .main_clk = "l3s_gclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* usb_otg_ss1 */ -+static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = { -+ .name = "usb_otg_ss1", -+ .class = &am43xx_usb_otg_ss_hwmod_class, -+ .clkdm_name = "l3s_clkdm", -+ .main_clk = "l3s_gclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ - /* 'timer 2-7' class */ - static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = { - .rev_offs = 0x0000, -@@ -1332,10 +1343,8 @@ static struct omap_hwmod am33xx_timer1_h - .name = "timer1", - .class = &am33xx_timer1ms_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -- .main_clk = "timer1_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1345,10 +1354,8 @@ static struct omap_hwmod am33xx_timer2_h - .name = "timer2", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "timer2_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1358,10 +1365,8 @@ static struct omap_hwmod am33xx_timer3_h - .name = "timer3", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "timer3_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1371,10 +1376,8 @@ static struct omap_hwmod am33xx_timer4_h - .name = "timer4", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "timer4_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1384,10 +1387,8 @@ static struct omap_hwmod am33xx_timer5_h - .name = "timer5", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "timer5_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1397,10 +1398,8 @@ static struct omap_hwmod am33xx_timer6_h - .name = "timer6", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "timer6_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1410,10 +1409,8 @@ static struct omap_hwmod am33xx_timer7_h - .name = "timer7", - .class = &am33xx_timer_hwmod_class, - .clkdm_name = "l4ls_clkdm", -- .main_clk = "timer7_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1431,7 +1428,6 @@ static struct omap_hwmod am33xx_tpcc_hwm - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1457,11 +1453,11 @@ static struct omap_hwmod am33xx_tptc0_hw - .name = "tptc0", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | -+ HWMOD_FORCE_MSTANDBY_REPEATED, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1472,11 +1468,11 @@ static struct omap_hwmod am33xx_tptc1_hw - .name = "tptc1", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), -+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | -+ HWMOD_FORCE_MSTANDBY_REPEATED), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1487,11 +1483,11 @@ static struct omap_hwmod am33xx_tptc2_hw - .name = "tptc2", - .class = &am33xx_tptc_hwmod_class, - .clkdm_name = "l3_clkdm", -- .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), -+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | -+ HWMOD_FORCE_MSTANDBY_REPEATED), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1520,10 +1516,8 @@ static struct omap_hwmod am33xx_uart1_hw - .class = &uart_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "dpll_per_m2_div4_wkupdm_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1534,10 +1528,8 @@ static struct omap_hwmod am33xx_uart2_hw - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_UART1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1549,10 +1541,8 @@ static struct omap_hwmod am33xx_uart3_hw - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_UART2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1563,10 +1553,8 @@ static struct omap_hwmod am33xx_uart4_hw - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_UART3_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1577,10 +1565,8 @@ static struct omap_hwmod am33xx_uart5_hw - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_UART4_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1591,10 +1577,8 @@ static struct omap_hwmod am33xx_uart6_hw - .class = &uart_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "dpll_per_m2_div4_ck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_PER_UART5_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1627,10 +1611,8 @@ static struct omap_hwmod am33xx_wd_timer - .class = &am33xx_wd_timer_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, -- .main_clk = "wdt1_fck", - .prcm = { - .omap4 = { -- .clkctrl_offs = AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -@@ -1658,8 +1640,8 @@ static struct omap_hwmod am33xx_usbss_hw - .name = "usb_otg_hs", - .class = &am33xx_usbotg_class, - .clkdm_name = "l3s_clkdm", -- .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -- .main_clk = "usbotg_fck", -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | -+ HWMOD_FORCE_MSTANDBY_REPEATED, - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_USB0_CLKCTRL_OFFSET, -@@ -1668,6 +1650,272 @@ static struct omap_hwmod am33xx_usbss_hw - }, - }; - -+static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = { -+ .rev_offs = 0x0, -+ .sysc_offs = 0x4, -+ .sysc_flags = SYSC_HAS_SIDLEMODE, -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class am43xx_synctimer_hwmod_class = { -+ .name = "synctimer", -+ .sysc = &am43xx_synctimer_sysc, -+}; -+ -+static struct omap_hwmod am43xx_synctimer_hwmod = { -+ .name = "counter_32k", -+ .class = &am43xx_synctimer_hwmod_class, -+ .clkdm_name = "l4_wkup_aon_clkdm", -+ .flags = HWMOD_SWSUP_SIDLE, -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_timer8_hwmod = { -+ .name = "timer8", -+ .class = &am33xx_timer_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_timer9_hwmod = { -+ .name = "timer9", -+ .class = &am33xx_timer_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_timer10_hwmod = { -+ .name = "timer10", -+ .class = &am33xx_timer_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_timer11_hwmod = { -+ .name = "timer11", -+ .class = &am33xx_timer_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_epwmss3_hwmod = { -+ .name = "epwmss3", -+ .class = &am33xx_epwmss_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_ehrpwm3_hwmod = { -+ .name = "ehrpwm3", -+ .class = &am33xx_ehrpwm_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+}; -+ -+static struct omap_hwmod am43xx_epwmss4_hwmod = { -+ .name = "epwmss4", -+ .class = &am33xx_epwmss_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_ehrpwm4_hwmod = { -+ .name = "ehrpwm4", -+ .class = &am33xx_ehrpwm_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+}; -+ -+static struct omap_hwmod am43xx_epwmss5_hwmod = { -+ .name = "epwmss5", -+ .class = &am33xx_epwmss_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod am43xx_ehrpwm5_hwmod = { -+ .name = "ehrpwm5", -+ .class = &am33xx_ehrpwm_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+}; -+ -+static struct omap_hwmod am43xx_spi2_hwmod = { -+ .name = "spi2", -+ .class = &am33xx_spi_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi_attrib, -+}; -+ -+static struct omap_hwmod am43xx_spi3_hwmod = { -+ .name = "spi3", -+ .class = &am33xx_spi_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi_attrib, -+}; -+ -+static struct omap_hwmod am43xx_spi4_hwmod = { -+ .name = "spi4", -+ .class = &am33xx_spi_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi_attrib, -+}; -+ -+static struct omap_hwmod am43xx_gpio4_hwmod = { -+ .name = "gpio5", -+ .class = &am33xx_gpio_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .dev_attr = &gpio_dev_attr, -+}; -+ -+static struct omap_hwmod am43xx_gpio5_hwmod = { -+ .name = "gpio6", -+ .class = &am33xx_gpio_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .dev_attr = &gpio_dev_attr, -+}; -+ -+/* Display sub system - DSS */ -+ -+static struct omap_hwmod_dma_info am43xx_dss_sdma_chs[] = { -+ { .name = "dispc", .dma_req = 5 }, -+ { .dma_req = -1 }, -+}; -+ -+struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = { -+ .manager_count = 1, -+ .has_framedonetv_irq = 0 -+}; -+ -+ -+static struct omap_hwmod_class_sysconfig am43xx_dispc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class am43xx_dispc_hwmod_class = { -+ .name = "dispc", -+ .sysc = &am43xx_dispc_sysc, -+}; -+ -+ -+ -+static struct omap_hwmod am43xx_dss_core_hwmod = { -+ .name = "dss_core", -+ .class = &omap2_dss_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "disp_clk", -+ .sdma_reqs = am43xx_dss_sdma_chs, -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* display controller -dispc*/ -+ -+static struct omap_hwmod am43xx_dss_dispc_hwmod = { -+ .name = "dss_dispc", -+ .class = &am43xx_dispc_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "disp_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET, -+ }, -+ }, -+ .dev_attr = &am43xx_dss_dispc_dev_attr, -+}; -+ -+/*RFBI*/ -+ -+static struct omap_hwmod am43xx_dss_rfbi_hwmod = { -+ .name = "dss_rfbi", -+ .class = &omap2_rfbi_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "disp_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET, -+ }, -+ }, -+}; - - /* - * Interfaces -@@ -1766,7 +2014,6 @@ static struct omap_hwmod_ocp_if am33xx_p - static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = { - .master = &am33xx_wkup_m3_hwmod, - .slave = &am33xx_l4_wkup_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -@@ -1782,7 +2029,6 @@ static struct omap_hwmod_ocp_if am33xx_g - static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_wkup_m3_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -@@ -1824,7 +2070,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_smartreflex0_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -1832,7 +2077,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_smartreflex1_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -1840,7 +2084,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_control_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -1896,7 +2139,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_i2c1_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -1904,7 +2146,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__gpio0 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_gpio0_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -@@ -2237,6 +2478,45 @@ static struct omap_hwmod_ocp_if am33xx_l - .user = OCP_USER_MPU, - }; - -+static struct omap_hwmod_ocp_if am43xx_l3_s__qspi = { -+ .master = &am33xx_l3_s_hwmod, -+ .slave = &am43xx_qspi_hwmod, -+ .clk = "l3s_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_1 -> usb_otg_ss0 */ -+static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = { -+ .master = &am33xx_l3_s_hwmod, -+ .slave = &am43xx_usb_otg_ss0_hwmod, -+ .clk = "l3s_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_1 -> usb_otg_ss1 */ -+static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = { -+ .master = &am33xx_l3_s_hwmod, -+ .slave = &am43xx_usb_otg_ss1_hwmod, -+ .clk = "l3s_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 ls -> ocp2scp0 */ -+static struct omap_hwmod_ocp_if am33xx_l4_ls__ocp2scp0 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_ocp2scp0_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+/* l4 ls -> ocp2scp0 */ -+static struct omap_hwmod_ocp_if am33xx_l4_ls__ocp2scp1 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_ocp2scp1_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ - /* l4 ls -> mcspi0 */ - static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = { - .master = &am33xx_l4_ls_hwmod, -@@ -2257,7 +2537,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_timer1_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -2375,7 +2654,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_uart1_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -2423,7 +2701,6 @@ static struct omap_hwmod_ocp_if am33xx_l - static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_wd_timer1_hwmod, -- .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, - }; - -@@ -2480,8 +2757,473 @@ static struct omap_hwmod_ocp_if am33xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = { -+ .master = &am33xx_l4_wkup_hwmod, -+ .slave = &am43xx_synctimer_hwmod, -+ .clk = "sys_clkin_ck", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer8 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_timer8_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer9 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_timer9_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer10 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_timer10_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__timer11 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_timer11_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_epwmss3_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = { -+ .master = &am43xx_epwmss3_hwmod, -+ .slave = &am43xx_ehrpwm3_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_epwmss4_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = { -+ .master = &am43xx_epwmss4_hwmod, -+ .slave = &am43xx_ehrpwm4_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_epwmss5_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = { -+ .master = &am43xx_epwmss5_hwmod, -+ .slave = &am43xx_ehrpwm5_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_spi2_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi3 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_spi3_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi4 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_spi4_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio4 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_gpio4_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__gpio5 = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_gpio5_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l3_main__pruss = { -+ .master = &am33xx_l3_main_hwmod, -+ .slave = &am33xx_pruss_hwmod, -+ .clk = "dpll_core_m4_ck", -+ .user = OCP_USER_MPU, -+}; -+ -+/* rng */ -+static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = { -+ .rev_offs = 0x1fe0, -+ .sysc_offs = 0x1fe4, -+ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE, -+ .idlemodes = SIDLE_FORCE | SIDLE_NO, -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class am33xx_rng_hwmod_class = { -+ .name = "rng", -+ .sysc = &am33xx_rng_sysc, -+}; -+ -+static struct omap_hwmod am33xx_rng_hwmod = { -+ .name = "rng", -+ .class = &am33xx_rng_hwmod_class, -+ .clkdm_name = "l4ls_clkdm", -+ .flags = HWMOD_SWSUP_SIDLE, -+ .prcm = { -+ .omap4 = { -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if am33xx_l4_per__rng = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am33xx_rng_hwmod, -+ .clk = "rng_fck", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_class_sysconfig am43xx_des_sysc = { -+ .rev_offs = 0x30, -+ .sysc_offs = 0x34, -+ .syss_offs = 0x38, -+ .sysc_flags = SYSS_HAS_RESET_STATUS, -+}; -+ -+static struct omap_hwmod_class am43xx_des_hwmod_class = { -+ .name = "des", -+ .sysc = &am43xx_des_sysc, -+}; -+ -+static struct omap_hwmod am43xx_des_hwmod = { -+ .name = "des", -+ .class = &am43xx_des_hwmod_class, -+ .clkdm_name = "l3_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = AM43XX_CM_PER_DES_CLKCTRL_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if am43xx_l3_main__des = { -+ .master = &am33xx_l3_main_hwmod, -+ .slave = &am43xx_des_hwmod, -+ .clk = "l3_gclk", -+ .user = OCP_USER_MPU, -+}; -+ -+/* DSS -> L3 Main */ -+static struct omap_hwmod_ocp_if am43xx_dss__l3_main = { -+ .master = &am43xx_dss_core_hwmod, -+ .slave = &am33xx_l3_main_hwmod, -+ .clk = "disp_clk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* L4-ls -> DSS */ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__dss = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_dss_core_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* L4_ls -> dss_dispc */ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_dispc = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_dss_dispc_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* L4_ls -> dss_rfbi */ -+static struct omap_hwmod_ocp_if am43xx_l4_ls__dss_rfbi = { -+ .master = &am33xx_l4_ls_hwmod, -+ .slave = &am43xx_dss_rfbi_hwmod, -+ .clk = "l4ls_gclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+#define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) -+ -+static void am43xx_hwmod_clkctrl(void) -+{ -+ CLKCTRL(am33xx_uart2_hwmod, AM43XX_CM_PER_UART1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart3_hwmod, AM43XX_CM_PER_UART2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart4_hwmod, AM43XX_CM_PER_UART3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart5_hwmod, AM43XX_CM_PER_UART4_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart6_hwmod, AM43XX_CM_PER_UART5_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_dcan0_hwmod, AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_dcan1_hwmod, AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_elm_hwmod, AM43XX_CM_PER_ELM_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio1_hwmod, AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio2_hwmod, AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio3_hwmod, AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_i2c2_hwmod, AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_i2c3_hwmod, AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mailbox_hwmod, AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mmc0_hwmod, AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mmc1_hwmod, AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer3_hwmod, AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer4_hwmod, AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer5_hwmod, AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer6_hwmod, AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer7_hwmod, AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_wkup_m3_hwmod, AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_control_hwmod, AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_smartreflex0_hwmod, -+ AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_smartreflex1_hwmod, -+ AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart1_hwmod, AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer1_hwmod, AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_i2c1_hwmod, AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio0_hwmod, AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_adc_tsc_hwmod, AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_wd_timer1_hwmod, AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mmc2_hwmod, AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mcasp0_hwmod, AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mcasp1_hwmod, AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tpcc_hwmod, AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tptc0_hwmod, AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tptc1_hwmod, AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tptc2_hwmod, AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_cpgmac0_hwmod, AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_pruss_hwmod, AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gfx_hwmod, AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l4_hs_hwmod, AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_rng_hwmod , AM43XX_CM_PER_RNG_CLKCTRL_OFFSET); -+} -+ -+static void am33xx_hwmod_clkctrl(void) -+{ -+ CLKCTRL(am33xx_uart2_hwmod, AM33XX_CM_PER_UART1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart3_hwmod, AM33XX_CM_PER_UART2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart4_hwmod, AM33XX_CM_PER_UART3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart5_hwmod, AM33XX_CM_PER_UART4_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart6_hwmod, AM33XX_CM_PER_UART5_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_dcan1_hwmod, AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_elm_hwmod, AM33XX_CM_PER_ELM_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio1_hwmod, AM33XX_CM_PER_GPIO1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio2_hwmod, AM33XX_CM_PER_GPIO2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio3_hwmod, AM33XX_CM_PER_GPIO3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_i2c2_hwmod, AM33XX_CM_PER_I2C1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_i2c3_hwmod, AM33XX_CM_PER_I2C2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mailbox_hwmod, AM33XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mcasp0_hwmod, AM33XX_CM_PER_MCASP0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mcasp1_hwmod, AM33XX_CM_PER_MCASP1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mmc0_hwmod, AM33XX_CM_PER_MMC0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mmc1_hwmod, AM33XX_CM_PER_MMC1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer3_hwmod, AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer4_hwmod, AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer5_hwmod, AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer6_hwmod, AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer7_hwmod, AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_wkup_m3_hwmod, AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_control_hwmod, AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_smartreflex0_hwmod, -+ AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_smartreflex1_hwmod, -+ AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_uart1_hwmod, AM33XX_CM_WKUP_UART0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_timer1_hwmod, AM33XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_i2c1_hwmod, AM33XX_CM_WKUP_I2C0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpio0_hwmod, AM33XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_adc_tsc_hwmod, AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_wd_timer1_hwmod, AM33XX_CM_WKUP_WDT1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mmc2_hwmod, AM33XX_CM_PER_MMC2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tpcc_hwmod, AM33XX_CM_PER_TPCC_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tptc0_hwmod, AM33XX_CM_PER_TPTC0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tptc1_hwmod, AM33XX_CM_PER_TPTC1_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_tptc2_hwmod, AM33XX_CM_PER_TPTC2_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_gfx_hwmod, AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l4_hs_hwmod, AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_cpgmac0_hwmod, AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_pruss_hwmod, AM33XX_CM_PER_PRUSS_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET); -+ CLKCTRL(am33xx_rng_hwmod, AM33XX_CM_PER_RNG_CLKCTRL_OFFSET); -+} -+ -+#define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) -+ -+static void am43xx_hwmod_rstctrl(void) -+{ -+ RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET); -+ RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET); -+ RSTCTRL(am33xx_wkup_m3_hwmod, AM43XX_RM_WKUP_RSTCTRL_OFFSET); -+} -+ -+static void am33xx_hwmod_rstctrl(void) -+{ -+ RSTCTRL(am33xx_pruss_hwmod, AM33XX_RM_PER_RSTCTRL_OFFSET); -+ RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET); -+ RSTCTRL(am33xx_wkup_m3_hwmod, AM33XX_RM_WKUP_RSTCTRL_OFFSET); -+} -+ -+#define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst)) -+ -+static void am43xx_hwmod_rstst(void) -+{ -+ RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET); -+ RSTST(am33xx_wkup_m3_hwmod, AM43XX_RM_WKUP_RSTST_OFFSET); -+} -+ -+static void am33xx_hwmod_rstst(void) -+{ -+ RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET); -+ RSTST(am33xx_wkup_m3_hwmod, AM33XX_RM_WKUP_RSTST_OFFSET); -+} -+ -+static void am43xx_hwmod_clockdomain(void) -+{ -+ am33xx_l4_hs_hwmod.clkdm_name = "l3_clkdm"; -+ am33xx_adc_tsc_hwmod.clkdm_name = "l3s_tsc_clkdm"; -+} -+ -+static void am33xx_hwmod_clockdomain(void) -+{ -+ am33xx_l4_hs_hwmod.clkdm_name = "l4hs_clkdm"; -+ am33xx_adc_tsc_hwmod.clkdm_name = "l4_wkup_clkdm"; -+} -+ -+#define AM43XX_L4_WKUP_OCPIF_CLK "sys_clkin_ck" -+ -+static void am43xx_hwmod_ocpif_clk(void) -+{ -+ am33xx_l4_wkup__wkup_m3.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__control.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__smartreflex0.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__smartreflex1.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__uart1.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__timer1.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__i2c1.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__gpio0.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__wd_timer1.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_wkup_m3__l4_wkup.clk = AM43XX_L4_WKUP_OCPIF_CLK; -+ am33xx_control_hwmod.main_clk = AM43XX_L4_WKUP_OCPIF_CLK; -+} -+ -+#define AM33XX_L4_WKUP_OCPIF_CLK "dpll_core_m4_div2_ck" -+ -+static void am33xx_hwmod_ocpif_clk(void) -+{ -+ am33xx_l4_wkup__wkup_m3.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__control.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__smartreflex0.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__smartreflex1.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__uart1.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__timer1.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__i2c1.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__gpio0.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_l4_wkup__wd_timer1.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_wkup_m3__l4_wkup.clk = AM33XX_L4_WKUP_OCPIF_CLK; -+ am33xx_control_hwmod.main_clk = AM33XX_L4_WKUP_OCPIF_CLK; -+} -+ -+static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { -+ &am33xx_l4_wkup__synctimer, -+ &am43xx_l4_ls__timer8, -+ &am43xx_l4_ls__timer9, -+ &am43xx_l4_ls__timer10, -+ &am43xx_l4_ls__timer11, -+ &am43xx_l4_ls__epwmss3, -+ &am43xx_epwmss3__ehrpwm3, -+ &am43xx_l4_ls__epwmss4, -+ &am43xx_epwmss4__ehrpwm4, -+ &am43xx_l4_ls__epwmss5, -+ &am43xx_epwmss5__ehrpwm5, -+ &am43xx_l4_ls__mcspi2, -+ &am43xx_l4_ls__mcspi3, -+ &am43xx_l4_ls__mcspi4, -+ &am43xx_l4_ls__gpio4, -+ &am43xx_l4_ls__gpio5, -+ &am43xx_l3_main__pruss, -+ &am43xx_l3_main__des, -+ &am43xx_l3_s__qspi, -+ &am43xx_l3_s__usbotgss0, -+ &am43xx_l3_s__usbotgss1, -+ &am33xx_l4_ls__ocp2scp0, -+ &am33xx_l4_ls__ocp2scp1, -+ &am43xx_dss__l3_main, -+ &am43xx_l4_ls__dss, -+ &am43xx_l4_ls__dss_dispc, -+ &am43xx_l4_ls__dss_rfbi, -+ NULL, -+}; -+ - static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { - &am33xx_l3_main__emif, -+ &am33xx_l3_main__debugss, -+ &am33xx_l4_hs__pruss, -+ &am33xx_l3_main__lcdc, -+ &am33xx_l3_s__usbss, -+ &am33xx_l4_wkup__rtc, -+ NULL, -+}; -+ -+static struct omap_hwmod_ocp_if *amx3xx_hwmod_ocp_ifs[] __initdata = { - &am33xx_mpu__l3_main, - &am33xx_mpu__prcm, - &am33xx_l3_s__l4_ls, -@@ -2494,19 +3236,16 @@ static struct omap_hwmod_ocp_if *am33xx_ - &am33xx_pruss__l3_main, - &am33xx_wkup_m3__l4_wkup, - &am33xx_gfx__l3_main, -- &am33xx_l3_main__debugss, - &am33xx_l4_wkup__wkup_m3, - &am33xx_l4_wkup__control, - &am33xx_l4_wkup__smartreflex0, - &am33xx_l4_wkup__smartreflex1, - &am33xx_l4_wkup__uart1, - &am33xx_l4_wkup__timer1, -- &am33xx_l4_wkup__rtc, - &am33xx_l4_wkup__i2c1, - &am33xx_l4_wkup__gpio0, - &am33xx_l4_wkup__adc_tsc, - &am33xx_l4_wkup__wd_timer1, -- &am33xx_l4_hs__pruss, - &am33xx_l4_per__dcan0, - &am33xx_l4_per__dcan1, - &am33xx_l4_per__gpio1, -@@ -2547,23 +3286,46 @@ static struct omap_hwmod_ocp_if *am33xx_ - &am33xx_epwmss2__eqep2, - &am33xx_epwmss2__ehrpwm2, - &am33xx_l3_s__gpmc, -- &am33xx_l3_main__lcdc, - &am33xx_l4_ls__mcspi0, - &am33xx_l4_ls__mcspi1, - &am33xx_l3_main__tptc0, - &am33xx_l3_main__tptc1, - &am33xx_l3_main__tptc2, - &am33xx_l3_main__ocmc, -- &am33xx_l3_s__usbss, - &am33xx_l4_hs__cpgmac0, - &am33xx_cpgmac0__mdio, - &am33xx_l3_main__sha0, - &am33xx_l3_main__aes0, -+ &am33xx_l4_per__rng, - NULL, - }; - - int __init am33xx_hwmod_init(void) - { -+ int ret; -+ - omap_hwmod_init(); -- return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs); -+ -+ if (soc_is_am33xx()) { -+ am33xx_hwmod_clkctrl(); -+ am33xx_hwmod_rstctrl(); -+ am33xx_hwmod_rstst(); -+ am33xx_hwmod_clockdomain(); -+ am33xx_hwmod_ocpif_clk(); -+ } else { -+ am43xx_hwmod_clkctrl(); -+ am43xx_hwmod_rstctrl(); -+ am43xx_hwmod_rstst(); -+ am43xx_hwmod_clockdomain(); -+ am43xx_hwmod_ocpif_clk(); -+ } -+ -+ ret = omap_hwmod_register_links(amx3xx_hwmod_ocp_ifs); -+ if (ret < 0) -+ return ret; -+ -+ if (soc_is_am33xx()) -+ return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs); -+ else -+ return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); - } ---- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c -@@ -200,7 +200,6 @@ static struct omap_timer_capability_dev_ - static struct omap_hwmod omap3xxx_timer1_hwmod = { - .name = "timer1", - .mpu_irqs = omap2_timer1_mpu_irqs, -- .main_clk = "gpt1_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -219,7 +218,6 @@ static struct omap_hwmod omap3xxx_timer1 - static struct omap_hwmod omap3xxx_timer2_hwmod = { - .name = "timer2", - .mpu_irqs = omap2_timer2_mpu_irqs, -- .main_clk = "gpt2_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -237,7 +235,6 @@ static struct omap_hwmod omap3xxx_timer2 - static struct omap_hwmod omap3xxx_timer3_hwmod = { - .name = "timer3", - .mpu_irqs = omap2_timer3_mpu_irqs, -- .main_clk = "gpt3_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -255,7 +252,6 @@ static struct omap_hwmod omap3xxx_timer3 - static struct omap_hwmod omap3xxx_timer4_hwmod = { - .name = "timer4", - .mpu_irqs = omap2_timer4_mpu_irqs, -- .main_clk = "gpt4_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -273,7 +269,6 @@ static struct omap_hwmod omap3xxx_timer4 - static struct omap_hwmod omap3xxx_timer5_hwmod = { - .name = "timer5", - .mpu_irqs = omap2_timer5_mpu_irqs, -- .main_clk = "gpt5_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -292,7 +287,6 @@ static struct omap_hwmod omap3xxx_timer5 - static struct omap_hwmod omap3xxx_timer6_hwmod = { - .name = "timer6", - .mpu_irqs = omap2_timer6_mpu_irqs, -- .main_clk = "gpt6_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -311,7 +305,6 @@ static struct omap_hwmod omap3xxx_timer6 - static struct omap_hwmod omap3xxx_timer7_hwmod = { - .name = "timer7", - .mpu_irqs = omap2_timer7_mpu_irqs, -- .main_clk = "gpt7_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -330,7 +323,6 @@ static struct omap_hwmod omap3xxx_timer7 - static struct omap_hwmod omap3xxx_timer8_hwmod = { - .name = "timer8", - .mpu_irqs = omap2_timer8_mpu_irqs, -- .main_clk = "gpt8_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -349,7 +341,6 @@ static struct omap_hwmod omap3xxx_timer8 - static struct omap_hwmod omap3xxx_timer9_hwmod = { - .name = "timer9", - .mpu_irqs = omap2_timer9_mpu_irqs, -- .main_clk = "gpt9_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -368,7 +359,6 @@ static struct omap_hwmod omap3xxx_timer9 - static struct omap_hwmod omap3xxx_timer10_hwmod = { - .name = "timer10", - .mpu_irqs = omap2_timer10_mpu_irqs, -- .main_clk = "gpt10_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -387,7 +377,6 @@ static struct omap_hwmod omap3xxx_timer1 - static struct omap_hwmod omap3xxx_timer11_hwmod = { - .name = "timer11", - .mpu_irqs = omap2_timer11_mpu_irqs, -- .main_clk = "gpt11_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -411,7 +400,6 @@ static struct omap_hwmod_irq_info omap3x - static struct omap_hwmod omap3xxx_timer12_hwmod = { - .name = "timer12", - .mpu_irqs = omap3xxx_timer12_mpu_irqs, -- .main_clk = "gpt12_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -467,7 +455,6 @@ static struct omap_hwmod_class omap3xxx_ - static struct omap_hwmod omap3xxx_wd_timer2_hwmod = { - .name = "wd_timer2", - .class = &omap3xxx_wd_timer_hwmod_class, -- .main_clk = "wdt2_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -489,7 +476,6 @@ static struct omap_hwmod omap3xxx_uart1_ - .name = "uart1", - .mpu_irqs = omap2_uart1_mpu_irqs, - .sdma_reqs = omap2_uart1_sdma_reqs, -- .main_clk = "uart1_fck", - .flags = DEBUG_TI81XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap2 = { -@@ -508,7 +494,6 @@ static struct omap_hwmod omap3xxx_uart2_ - .name = "uart2", - .mpu_irqs = omap2_uart2_mpu_irqs, - .sdma_reqs = omap2_uart2_sdma_reqs, -- .main_clk = "uart2_fck", - .flags = DEBUG_TI81XXUART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap2 = { -@@ -527,7 +512,6 @@ static struct omap_hwmod omap3xxx_uart3_ - .name = "uart3", - .mpu_irqs = omap2_uart3_mpu_irqs, - .sdma_reqs = omap2_uart3_sdma_reqs, -- .main_clk = "uart3_fck", - .flags = DEBUG_OMAP3UART3_FLAGS | DEBUG_TI81XXUART3_FLAGS | - HWMOD_SWSUP_SIDLE_ACT, - .prcm = { -@@ -807,7 +791,6 @@ static struct omap_hwmod omap3xxx_i2c1_h - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, - .mpu_irqs = omap2_i2c1_mpu_irqs, - .sdma_reqs = omap2_i2c1_sdma_reqs, -- .main_clk = "i2c1_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -832,7 +815,6 @@ static struct omap_hwmod omap3xxx_i2c2_h - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, - .mpu_irqs = omap2_i2c2_mpu_irqs, - .sdma_reqs = omap2_i2c2_sdma_reqs, -- .main_clk = "i2c2_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -868,7 +850,6 @@ static struct omap_hwmod omap3xxx_i2c3_h - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, - .mpu_irqs = i2c3_mpu_irqs, - .sdma_reqs = i2c3_sdma_reqs, -- .main_clk = "i2c3_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -911,17 +892,11 @@ static struct omap_gpio_dev_attr gpio_de - }; - - /* gpio1 */ --static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio1_dbck", }, --}; - - static struct omap_hwmod omap3xxx_gpio1_hwmod = { - .name = "gpio1", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .mpu_irqs = omap2_gpio1_irqs, -- .main_clk = "gpio1_ick", -- .opt_clks = gpio1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -936,17 +911,11 @@ static struct omap_hwmod omap3xxx_gpio1_ - }; - - /* gpio2 */ --static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio2_dbck", }, --}; - - static struct omap_hwmod omap3xxx_gpio2_hwmod = { - .name = "gpio2", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .mpu_irqs = omap2_gpio2_irqs, -- .main_clk = "gpio2_ick", -- .opt_clks = gpio2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -961,17 +930,11 @@ static struct omap_hwmod omap3xxx_gpio2_ - }; - - /* gpio3 */ --static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio3_dbck", }, --}; - - static struct omap_hwmod omap3xxx_gpio3_hwmod = { - .name = "gpio3", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .mpu_irqs = omap2_gpio3_irqs, -- .main_clk = "gpio3_ick", -- .opt_clks = gpio3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -986,17 +949,11 @@ static struct omap_hwmod omap3xxx_gpio3_ - }; - - /* gpio4 */ --static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio4_dbck", }, --}; - - static struct omap_hwmod omap3xxx_gpio4_hwmod = { - .name = "gpio4", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .mpu_irqs = omap2_gpio4_irqs, -- .main_clk = "gpio4_ick", -- .opt_clks = gpio4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1016,17 +973,11 @@ static struct omap_hwmod_irq_info omap3x - { .irq = -1 }, - }; - --static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio5_dbck", }, --}; - - static struct omap_hwmod omap3xxx_gpio5_hwmod = { - .name = "gpio5", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .mpu_irqs = omap3xxx_gpio5_irqs, -- .main_clk = "gpio5_ick", -- .opt_clks = gpio5_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1046,17 +997,11 @@ static struct omap_hwmod_irq_info omap3x - { .irq = -1 }, - }; - --static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio6_dbck", }, --}; - - static struct omap_hwmod omap3xxx_gpio6_hwmod = { - .name = "gpio6", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, - .mpu_irqs = omap3xxx_gpio6_irqs, -- .main_clk = "gpio6_ick", -- .opt_clks = gpio6_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1100,7 +1045,6 @@ static struct omap_hwmod omap3xxx_dma_sy - .name = "dma", - .class = &omap3xxx_dma_hwmod_class, - .mpu_irqs = omap2_dma_system_irqs, -- .main_clk = "core_l3_ick", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1135,15 +1079,7 @@ static struct omap_hwmod_class omap3xxx_ - }; - - /* McBSP functional clock mapping */ --static struct omap_hwmod_opt_clk mcbsp15_opt_clks[] = { -- { .role = "pad_fck", .clk = "mcbsp_clks" }, -- { .role = "prcm_fck", .clk = "core_96m_fck" }, --}; - --static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = { -- { .role = "pad_fck", .clk = "mcbsp_clks" }, -- { .role = "prcm_fck", .clk = "per_96m_fck" }, --}; - - /* mcbsp1 */ - static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = { -@@ -1158,7 +1094,6 @@ static struct omap_hwmod omap3xxx_mcbsp1 - .class = &omap3xxx_mcbsp_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp1_irqs, - .sdma_reqs = omap2_mcbsp1_sdma_reqs, -- .main_clk = "mcbsp1_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1168,8 +1103,6 @@ static struct omap_hwmod omap3xxx_mcbsp1 - .idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT, - }, - }, -- .opt_clks = mcbsp15_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks), - }; - - /* mcbsp2 */ -@@ -1189,7 +1122,6 @@ static struct omap_hwmod omap3xxx_mcbsp2 - .class = &omap3xxx_mcbsp_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp2_irqs, - .sdma_reqs = omap2_mcbsp2_sdma_reqs, -- .main_clk = "mcbsp2_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1199,8 +1131,6 @@ static struct omap_hwmod omap3xxx_mcbsp2 - .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, - }, - }, -- .opt_clks = mcbsp234_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), - .dev_attr = &omap34xx_mcbsp2_dev_attr, - }; - -@@ -1221,7 +1151,6 @@ static struct omap_hwmod omap3xxx_mcbsp3 - .class = &omap3xxx_mcbsp_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp3_irqs, - .sdma_reqs = omap2_mcbsp3_sdma_reqs, -- .main_clk = "mcbsp3_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1231,8 +1160,6 @@ static struct omap_hwmod omap3xxx_mcbsp3 - .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, - }, - }, -- .opt_clks = mcbsp234_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), - .dev_attr = &omap34xx_mcbsp3_dev_attr, - }; - -@@ -1255,7 +1182,6 @@ static struct omap_hwmod omap3xxx_mcbsp4 - .class = &omap3xxx_mcbsp_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp4_irqs, - .sdma_reqs = omap3xxx_mcbsp4_sdma_chs, -- .main_clk = "mcbsp4_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1265,8 +1191,6 @@ static struct omap_hwmod omap3xxx_mcbsp4 - .idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT, - }, - }, -- .opt_clks = mcbsp234_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), - }; - - /* mcbsp5 */ -@@ -1288,7 +1212,6 @@ static struct omap_hwmod omap3xxx_mcbsp5 - .class = &omap3xxx_mcbsp_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp5_irqs, - .sdma_reqs = omap3xxx_mcbsp5_sdma_chs, -- .main_clk = "mcbsp5_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1298,8 +1221,6 @@ static struct omap_hwmod omap3xxx_mcbsp5 - .idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT, - }, - }, -- .opt_clks = mcbsp15_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp15_opt_clks), - }; - - /* 'mcbsp sidetone' class */ -@@ -1324,7 +1245,6 @@ static struct omap_hwmod omap3xxx_mcbsp2 - .name = "mcbsp2_sidetone", - .class = &omap3xxx_mcbsp_sidetone_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs, -- .main_clk = "mcbsp2_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1346,7 +1266,6 @@ static struct omap_hwmod omap3xxx_mcbsp3 - .name = "mcbsp3_sidetone", - .class = &omap3xxx_mcbsp_sidetone_hwmod_class, - .mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs, -- .main_clk = "mcbsp3_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1571,7 +1490,6 @@ static struct omap_hwmod omap34xx_mcspi1 - .name = "mcspi1", - .mpu_irqs = omap2_mcspi1_mpu_irqs, - .sdma_reqs = omap2_mcspi1_sdma_reqs, -- .main_clk = "mcspi1_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1594,7 +1512,6 @@ static struct omap_hwmod omap34xx_mcspi2 - .name = "mcspi2", - .mpu_irqs = omap2_mcspi2_mpu_irqs, - .sdma_reqs = omap2_mcspi2_sdma_reqs, -- .main_clk = "mcspi2_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1630,7 +1547,6 @@ static struct omap_hwmod omap34xx_mcspi3 - .name = "mcspi3", - .mpu_irqs = omap34xx_mcspi3_mpu_irqs, - .sdma_reqs = omap34xx_mcspi3_sdma_reqs, -- .main_clk = "mcspi3_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1664,7 +1580,6 @@ static struct omap_hwmod omap34xx_mcspi4 - .name = "mcspi4", - .mpu_irqs = omap34xx_mcspi4_mpu_irqs, - .sdma_reqs = omap34xx_mcspi4_sdma_reqs, -- .main_clk = "mcspi4_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1707,7 +1622,6 @@ static struct omap_hwmod_irq_info omap3x - static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { - .name = "usb_otg_hs", - .mpu_irqs = omap3xxx_usbhsotg_mpu_irqs, -- .main_clk = "hsotgusb_ick", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1782,9 +1696,6 @@ static struct omap_hwmod_dma_info omap34 - { .dma_req = -1 } - }; - --static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = { -- { .role = "dbck", .clk = "omap_32k_fck", }, --}; - - static struct omap_mmc_dev_attr mmc1_dev_attr = { - .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -@@ -1800,9 +1711,6 @@ static struct omap_hwmod omap3xxx_pre_es - .name = "mmc1", - .mpu_irqs = omap34xx_mmc1_mpu_irqs, - .sdma_reqs = omap34xx_mmc1_sdma_reqs, -- .opt_clks = omap34xx_mmc1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks), -- .main_clk = "mmchs1_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1820,9 +1728,6 @@ static struct omap_hwmod omap3xxx_es3plu - .name = "mmc1", - .mpu_irqs = omap34xx_mmc1_mpu_irqs, - .sdma_reqs = omap34xx_mmc1_sdma_reqs, -- .opt_clks = omap34xx_mmc1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks), -- .main_clk = "mmchs1_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1849,9 +1754,6 @@ static struct omap_hwmod_dma_info omap34 - { .dma_req = -1 } - }; - --static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = { -- { .role = "dbck", .clk = "omap_32k_fck", }, --}; - - /* See 35xx errata 2.1.1.128 in SPRZ278F */ - static struct omap_mmc_dev_attr mmc2_pre_es3_dev_attr = { -@@ -1862,9 +1764,6 @@ static struct omap_hwmod omap3xxx_pre_es - .name = "mmc2", - .mpu_irqs = omap34xx_mmc2_mpu_irqs, - .sdma_reqs = omap34xx_mmc2_sdma_reqs, -- .opt_clks = omap34xx_mmc2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks), -- .main_clk = "mmchs2_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1882,9 +1781,6 @@ static struct omap_hwmod omap3xxx_es3plu - .name = "mmc2", - .mpu_irqs = omap34xx_mmc2_mpu_irqs, - .sdma_reqs = omap34xx_mmc2_sdma_reqs, -- .opt_clks = omap34xx_mmc2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks), -- .main_clk = "mmchs2_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -1910,17 +1806,11 @@ static struct omap_hwmod_dma_info omap34 - { .dma_req = -1 } - }; - --static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = { -- { .role = "dbck", .clk = "omap_32k_fck", }, --}; - - static struct omap_hwmod omap3xxx_mmc3_hwmod = { - .name = "mmc3", - .mpu_irqs = omap34xx_mmc3_mpu_irqs, - .sdma_reqs = omap34xx_mmc3_sdma_reqs, -- .opt_clks = omap34xx_mmc3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc3_opt_clks), -- .main_clk = "mmchs3_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -@@ -1954,9 +1844,6 @@ static struct omap_hwmod_class omap3xxx_ - .sysc = &omap3xxx_usb_host_hs_sysc, - }; - --static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = { -- { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", }, --}; - - static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = { - { .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, }, -@@ -1969,7 +1856,6 @@ static struct omap_hwmod omap3xxx_usb_ho - .class = &omap3xxx_usb_host_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", - .mpu_irqs = omap3xxx_usb_host_hs_irqs, -- .main_clk = "usbhost_48m_fck", - .prcm = { - .omap2 = { - .module_offs = OMAP3430ES2_USBHOST_MOD, -@@ -1980,8 +1866,6 @@ static struct omap_hwmod omap3xxx_usb_ho - .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT, - }, - }, -- .opt_clks = omap3xxx_usb_host_hs_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks), - - /* - * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock -@@ -2062,7 +1946,6 @@ static struct omap_hwmod omap3xxx_usb_tl - .class = &omap3xxx_usb_tll_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", - .mpu_irqs = omap3xxx_usb_tll_hs_irqs, -- .main_clk = "usbtll_fck", - .prcm = { - .omap2 = { - .module_offs = CORE_MOD, -@@ -2139,7 +2022,6 @@ static struct omap_hwmod omap3xxx_counte - .class = &omap3xxx_counter_hwmod_class, - .clkdm_name = "wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, -- .main_clk = "wkup_32k_fck", - .prcm = { - .omap2 = { - .module_offs = WKUP_MOD, -@@ -2181,7 +2063,6 @@ static struct omap_hwmod omap3xxx_gpmc_h - .class = &omap3xxx_gpmc_hwmod_class, - .clkdm_name = "core_l3_clkdm", - .mpu_irqs = omap3xxx_gpmc_irqs, -- .main_clk = "gpmc_fck", - /* - * XXX HWMOD_INIT_NO_RESET should not be needed for this IP - * block. It is not being added due to any known bugs with ---- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c -@@ -334,7 +334,6 @@ static struct omap_hwmod omap44xx_counte - .class = &omap44xx_counter_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, -- .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET, -@@ -479,7 +478,6 @@ static struct omap_hwmod omap44xx_dma_sy - .class = &omap44xx_dma_hwmod_class, - .clkdm_name = "l3_dma_clkdm", - .mpu_irqs = omap44xx_dma_system_irqs, -- .main_clk = "l3_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET, -@@ -514,7 +512,6 @@ static struct omap_hwmod omap44xx_dmic_h - .name = "dmic", - .class = &omap44xx_dmic_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "func_dmic_abe_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, -@@ -914,8 +911,6 @@ static struct omap_hwmod omap44xx_emif1_ - .name = "emif1", - .class = &omap44xx_emif_hwmod_class, - .clkdm_name = "l3_emif_clkdm", -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -- .main_clk = "ddrphy_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET, -@@ -930,8 +925,6 @@ static struct omap_hwmod omap44xx_emif2_ - .name = "emif2", - .class = &omap44xx_emif_hwmod_class, - .clkdm_name = "l3_emif_clkdm", -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -- .main_clk = "ddrphy_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET, -@@ -1015,15 +1008,11 @@ static struct omap_gpio_dev_attr gpio_de - }; - - /* gpio1 */ --static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio1_dbclk" }, --}; - - static struct omap_hwmod omap44xx_gpio1_hwmod = { - .name = "gpio1", - .class = &omap44xx_gpio_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -- .main_clk = "l4_wkup_clk_mux_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, -@@ -1031,22 +1020,16 @@ static struct omap_hwmod omap44xx_gpio1_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio2 */ --static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio2_dbclk" }, --}; - - static struct omap_hwmod omap44xx_gpio2_hwmod = { - .name = "gpio2", - .class = &omap44xx_gpio_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, -@@ -1054,22 +1037,16 @@ static struct omap_hwmod omap44xx_gpio2_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio3 */ --static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio3_dbclk" }, --}; - - static struct omap_hwmod omap44xx_gpio3_hwmod = { - .name = "gpio3", - .class = &omap44xx_gpio_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, -@@ -1077,22 +1054,16 @@ static struct omap_hwmod omap44xx_gpio3_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio4 */ --static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio4_dbclk" }, --}; - - static struct omap_hwmod omap44xx_gpio4_hwmod = { - .name = "gpio4", - .class = &omap44xx_gpio_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, -@@ -1100,22 +1071,16 @@ static struct omap_hwmod omap44xx_gpio4_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio5 */ --static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio5_dbclk" }, --}; - - static struct omap_hwmod omap44xx_gpio5_hwmod = { - .name = "gpio5", - .class = &omap44xx_gpio_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, -@@ -1123,22 +1088,16 @@ static struct omap_hwmod omap44xx_gpio5_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio5_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio6 */ --static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio6_dbclk" }, --}; - - static struct omap_hwmod omap44xx_gpio6_hwmod = { - .name = "gpio6", - .class = &omap44xx_gpio_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, -@@ -1146,8 +1105,6 @@ static struct omap_hwmod omap44xx_gpio6_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio6_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - -@@ -1184,7 +1141,7 @@ static struct omap_hwmod omap44xx_gpmc_h - * the kernel from the board file or DT data. - * HWMOD_INIT_NO_RESET should be removed ASAP. - */ -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -+ .flags = HWMOD_INIT_NO_RESET, - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, -@@ -1337,7 +1294,6 @@ static struct omap_hwmod omap44xx_i2c1_h - .class = &omap44xx_i2c_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, -@@ -1354,7 +1310,6 @@ static struct omap_hwmod omap44xx_i2c2_h - .class = &omap44xx_i2c_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, -@@ -1371,7 +1326,6 @@ static struct omap_hwmod omap44xx_i2c3_h - .class = &omap44xx_i2c_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, -@@ -1388,7 +1342,6 @@ static struct omap_hwmod omap44xx_i2c4_h - .class = &omap44xx_i2c_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, -@@ -1542,7 +1495,6 @@ static struct omap_hwmod omap44xx_kbd_hw - .name = "kbd", - .class = &omap44xx_kbd_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -- .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, -@@ -1643,16 +1595,11 @@ static struct omap_hwmod_class omap44xx_ - }; - - /* mcbsp1 */ --static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" }, --}; - - static struct omap_hwmod omap44xx_mcbsp1_hwmod = { - .name = "mcbsp1", - .class = &omap44xx_mcbsp_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "func_mcbsp1_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, -@@ -1660,21 +1607,14 @@ static struct omap_hwmod omap44xx_mcbsp1 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks), - }; - - /* mcbsp2 */ --static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" }, --}; - - static struct omap_hwmod omap44xx_mcbsp2_hwmod = { - .name = "mcbsp2", - .class = &omap44xx_mcbsp_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "func_mcbsp2_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, -@@ -1682,21 +1622,14 @@ static struct omap_hwmod omap44xx_mcbsp2 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks), - }; - - /* mcbsp3 */ --static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" }, --}; - - static struct omap_hwmod omap44xx_mcbsp3_hwmod = { - .name = "mcbsp3", - .class = &omap44xx_mcbsp_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "func_mcbsp3_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, -@@ -1704,21 +1637,14 @@ static struct omap_hwmod omap44xx_mcbsp3 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks), - }; - - /* mcbsp4 */ --static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" }, --}; - - static struct omap_hwmod omap44xx_mcbsp4_hwmod = { - .name = "mcbsp4", - .class = &omap44xx_mcbsp_hwmod_class, - .clkdm_name = "l4_per_clkdm", -- .main_clk = "per_mcbsp4_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, -@@ -1726,8 +1652,6 @@ static struct omap_hwmod omap44xx_mcbsp4 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp4_opt_clks), - }; - - /* -@@ -1768,7 +1692,6 @@ static struct omap_hwmod omap44xx_mcpdm_ - * results 'slow motion' audio playback. - */ - .flags = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE, -- .main_clk = "pad_clks_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, -@@ -1823,7 +1746,6 @@ static struct omap_hwmod omap44xx_mcspi1 - .class = &omap44xx_mcspi_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mcspi1_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, -@@ -1853,7 +1775,6 @@ static struct omap_hwmod omap44xx_mcspi2 - .class = &omap44xx_mcspi_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mcspi2_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, -@@ -1883,7 +1804,6 @@ static struct omap_hwmod omap44xx_mcspi3 - .class = &omap44xx_mcspi_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mcspi3_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, -@@ -1911,7 +1831,6 @@ static struct omap_hwmod omap44xx_mcspi4 - .class = &omap44xx_mcspi_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mcspi4_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, -@@ -1961,7 +1880,6 @@ static struct omap_hwmod omap44xx_mmc1_h - .class = &omap44xx_mmc_hwmod_class, - .clkdm_name = "l3_init_clkdm", - .sdma_reqs = omap44xx_mmc1_sdma_reqs, -- .main_clk = "hsmmc1_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, -@@ -1984,7 +1902,6 @@ static struct omap_hwmod omap44xx_mmc2_h - .class = &omap44xx_mmc_hwmod_class, - .clkdm_name = "l3_init_clkdm", - .sdma_reqs = omap44xx_mmc2_sdma_reqs, -- .main_clk = "hsmmc2_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, -@@ -2006,7 +1923,6 @@ static struct omap_hwmod omap44xx_mmc3_h - .class = &omap44xx_mmc_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mmc3_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, -@@ -2028,7 +1944,6 @@ static struct omap_hwmod omap44xx_mmc4_h - .class = &omap44xx_mmc_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mmc4_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, -@@ -2050,7 +1965,6 @@ static struct omap_hwmod omap44xx_mmc5_h - .class = &omap44xx_mmc_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .sdma_reqs = omap44xx_mmc5_sdma_reqs, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, -@@ -2193,7 +2107,7 @@ static struct omap_hwmod omap44xx_mpu_hw - .name = "mpu", - .class = &omap44xx_mpu_hwmod_class, - .clkdm_name = "mpuss_clkdm", -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_mpu_m2_ck", - .prcm = { - .omap4 = { -@@ -2261,7 +2175,6 @@ static struct omap_hwmod omap44xx_ocp2sc - * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems - * to be the best workaround. - */ -- .main_clk = "ocp2scp_usb_phy_phy_48m", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, -@@ -2629,7 +2542,6 @@ static struct omap_hwmod omap44xx_timer1 - .class = &omap44xx_timer_1ms_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "dmt1_clk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, -@@ -2646,7 +2558,6 @@ static struct omap_hwmod omap44xx_timer2 - .class = &omap44xx_timer_1ms_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "cm2_dm2_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, -@@ -2661,7 +2572,6 @@ static struct omap_hwmod omap44xx_timer3 - .name = "timer3", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "l4_per_clkdm", -- .main_clk = "cm2_dm3_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, -@@ -2676,7 +2586,6 @@ static struct omap_hwmod omap44xx_timer4 - .name = "timer4", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "l4_per_clkdm", -- .main_clk = "cm2_dm4_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, -@@ -2691,7 +2600,6 @@ static struct omap_hwmod omap44xx_timer5 - .name = "timer5", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer5_sync_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, -@@ -2707,7 +2615,6 @@ static struct omap_hwmod omap44xx_timer6 - .name = "timer6", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer6_sync_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, -@@ -2723,7 +2630,6 @@ static struct omap_hwmod omap44xx_timer7 - .name = "timer7", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer7_sync_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, -@@ -2739,7 +2645,6 @@ static struct omap_hwmod omap44xx_timer8 - .name = "timer8", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer8_sync_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, -@@ -2755,7 +2660,6 @@ static struct omap_hwmod omap44xx_timer9 - .name = "timer9", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "l4_per_clkdm", -- .main_clk = "cm2_dm9_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, -@@ -2772,7 +2676,6 @@ static struct omap_hwmod omap44xx_timer1 - .class = &omap44xx_timer_1ms_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "cm2_dm10_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, -@@ -2788,7 +2691,6 @@ static struct omap_hwmod omap44xx_timer1 - .name = "timer11", - .class = &omap44xx_timer_hwmod_class, - .clkdm_name = "l4_per_clkdm", -- .main_clk = "cm2_dm11_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, -@@ -2827,7 +2729,6 @@ static struct omap_hwmod omap44xx_uart1_ - .class = &omap44xx_uart_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, -@@ -2843,7 +2744,6 @@ static struct omap_hwmod omap44xx_uart2_ - .class = &omap44xx_uart_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, -@@ -2859,7 +2759,6 @@ static struct omap_hwmod omap44xx_uart3_ - .class = &omap44xx_uart_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = DEBUG_OMAP4UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, -@@ -2875,7 +2774,6 @@ static struct omap_hwmod omap44xx_uart4_ - .class = &omap44xx_uart_hwmod_class, - .clkdm_name = "l4_per_clkdm", - .flags = DEBUG_OMAP4UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, -@@ -2954,7 +2852,6 @@ static struct omap_hwmod omap44xx_usb_ho - .name = "usb_host_hs", - .class = &omap44xx_usb_host_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", -- .main_clk = "usb_host_hs_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET, -@@ -3036,16 +2933,12 @@ static struct omap_hwmod_class omap44xx_ - }; - - /* usb_otg_hs */ --static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = { -- { .role = "xclk", .clk = "usb_otg_hs_xclk" }, --}; - - static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = { - .name = "usb_otg_hs", - .class = &omap44xx_usb_otg_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", - .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -- .main_clk = "usb_otg_hs_ick", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET, -@@ -3053,8 +2946,6 @@ static struct omap_hwmod omap44xx_usb_ot - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = usb_otg_hs_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(usb_otg_hs_opt_clks), - }; - - /* -@@ -3082,7 +2973,6 @@ static struct omap_hwmod omap44xx_usb_tl - .name = "usb_tll_hs", - .class = &omap44xx_usb_tll_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", -- .main_clk = "usb_tll_hs_ick", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET, -@@ -3121,7 +3011,6 @@ static struct omap_hwmod omap44xx_wd_tim - .name = "wd_timer2", - .class = &omap44xx_wd_timer_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -- .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, -@@ -4791,6 +4680,105 @@ static struct omap_hwmod_ocp_if omap44xx - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* -+ Crypto modules AES0/1 belong to: -+ PD_L4_PER power domain -+ CD_L4_SEC clock domain -+ On the L3, the AES modules are mapped to -+ L3_CLK2: Peripherals and multimedia sub clock domain -+*/ -+ -+static struct omap_hwmod_class_sysconfig omap4_aes1_sysc = { -+ .rev_offs = 0x80, -+ .sysc_offs = 0x84, -+ .syss_offs = 0x88, -+ .sysc_flags = SYSS_HAS_RESET_STATUS, -+ .sysc_fields = &omap_hwmod_sysc_type4, -+}; -+ -+static struct omap_hwmod_class omap4_aes1_hwmod_class = { -+ .name = "aes1", -+ .sysc = &omap4_aes1_sysc, -+}; -+ -+static struct omap_hwmod omap4_aes1_hwmod = { -+ .name = "aes", -+ .class = &omap4_aes1_hwmod_class, -+ .clkdm_name = "l4_secure_clkdm", -+ .main_clk = "aes1_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET, -+ .context_offs = OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* l3_main_2 -> aes1 */ -+static struct omap_hwmod_addr_space omap4_aes1_addrs[] = { -+ { -+ .pa_start = 0x4B500000, -+ .pa_end = 0x4B500000 + SZ_1M - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+ { } -+}; -+ -+static struct omap_hwmod_ocp_if omap4_l3_main_2__aes1 = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap4_aes1_hwmod, -+ .clk = "aes1_fck", -+ .addr = omap4_aes1_addrs, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* DES3DES */ -+static struct omap_hwmod_class_sysconfig omap4_des_sysc = { -+ .rev_offs = 0x30, -+ .sysc_offs = 0x34, -+ .syss_offs = 0x38, -+ .sysc_flags = SYSS_HAS_RESET_STATUS, -+ .sysc_fields = &omap_hwmod_sysc_type4, -+}; -+ -+static struct omap_hwmod_class omap4_des_hwmod_class = { -+ .name = "des", -+ .sysc = &omap4_des_sysc, -+}; -+ -+ -+static struct omap_hwmod omap4_des_hwmod = { -+ .name = "des", -+ .class = &omap4_des_hwmod_class, -+ .clkdm_name = "l4_secure_clkdm", -+ .main_clk = "des_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET, -+ .context_offs = OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod_addr_space omap4_des_addrs[] = { -+ { -+ .pa_start = 0x480A4000, -+ .pa_end = 0x481A4000, -+ .flags = ADDR_TYPE_RT -+ }, -+ { } -+}; -+ -+static struct omap_hwmod_ocp_if omap4_l4_per__des = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap4_des_hwmod, -+ .clk = "des_fck", -+ .addr = omap4_des_addrs, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { - &omap44xx_l3_main_1__dmm, - &omap44xx_mpu__dmm, -@@ -4945,6 +4933,8 @@ static struct omap_hwmod_ocp_if *omap44x - &omap44xx_l4_abe__wd_timer3_dma, - &omap44xx_mpu__emif1, - &omap44xx_mpu__emif2, -+ &omap4_l3_main_2__aes1, -+ &omap4_l4_per__des, - NULL, - }; - ---- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c -@@ -234,7 +234,6 @@ static struct omap_hwmod omap54xx_counte - .class = &omap54xx_counter_hwmod_class, - .clkdm_name = "wkupaon_clkdm", - .flags = HWMOD_SWSUP_SIDLE, -- .main_clk = "wkupaon_iclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET, -@@ -288,7 +287,6 @@ static struct omap_hwmod omap54xx_dma_sy - .class = &omap54xx_dma_hwmod_class, - .clkdm_name = "dma_clkdm", - .mpu_irqs = omap54xx_dma_system_irqs, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET, -@@ -323,7 +321,6 @@ static struct omap_hwmod omap54xx_dmic_h - .name = "dmic", - .class = &omap54xx_dmic_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "dmic_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET, -@@ -334,6 +331,235 @@ static struct omap_hwmod omap54xx_dmic_h - }; - - /* -+ * 'dss' class -+ * display sub-system -+ */ -+static struct omap_hwmod_class_sysconfig omap54xx_dss_sysc = { -+ .rev_offs = 0x0000, -+ .syss_offs = 0x0014, -+ .sysc_flags = SYSS_HAS_RESET_STATUS, -+}; -+ -+static struct omap_hwmod_class omap54xx_dss_hwmod_class = { -+ .name = "dss", -+ .sysc = &omap54xx_dss_sysc, -+ .reset = omap_dss_reset, -+}; -+ -+/* dss */ -+static struct omap_hwmod_opt_clk dss_opt_clks[] = { -+ { .role = "32khz_clk", .clk = "dss_32khz_clk" }, -+ { .role = "sys_clk", .clk = "dss_sys_clk" }, -+ { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, -+}; -+ -+static struct omap_hwmod omap54xx_dss_hwmod = { -+ .name = "dss_core", -+ .class = &omap54xx_dss_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .main_clk = "dss_dss_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, -+ .context_offs = OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .opt_clks = dss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -+}; -+ -+/* -+ * 'dispc' class -+ * display controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_dispc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap54xx_dispc_hwmod_class = { -+ .name = "dispc", -+ .sysc = &omap54xx_dispc_sysc, -+}; -+ -+/* dss_dispc */ -+static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = { -+ { .role = "sys_clk", .clk = "dss_sys_clk" }, -+}; -+ -+/* dss_dispc dev_attr */ -+static struct omap_dss_dispc_dev_attr dss_dispc_dev_attr = { -+ .has_framedonetv_irq = 1, -+ .manager_count = 4, -+}; -+ -+static struct omap_hwmod omap54xx_dss_dispc_hwmod = { -+ .name = "dss_dispc", -+ .class = &omap54xx_dispc_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "dss_dss_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, -+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, -+ }, -+ }, -+ .opt_clks = dss_dispc_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), -+ .dev_attr = &dss_dispc_dev_attr, -+}; -+ -+/* -+ * 'dsi1' class -+ * display serial interface controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_dsi1_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap54xx_dsi1_hwmod_class = { -+ .name = "dsi1", -+ .sysc = &omap54xx_dsi1_sysc, -+}; -+ -+/* dss_dsi1_a */ -+static struct omap_hwmod_opt_clk dss_dsi1_a_opt_clks[] = { -+ { .role = "sys_clk", .clk = "dss_sys_clk" }, -+}; -+ -+static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = { -+ .name = "dss_dsi1", -+ .class = &omap54xx_dsi1_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "dss_dss_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, -+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, -+ }, -+ }, -+ .opt_clks = dss_dsi1_a_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), -+}; -+ -+/* dss_dsi1_c */ -+static struct omap_hwmod_opt_clk dss_dsi1_c_opt_clks[] = { -+ { .role = "sys_clk", .clk = "dss_sys_clk" }, -+}; -+ -+static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = { -+ .name = "dss_dsi2", -+ .class = &omap54xx_dsi1_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "dss_dss_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, -+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, -+ }, -+ }, -+ .opt_clks = dss_dsi1_c_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), -+}; -+ -+/* -+ * 'hdmi' class -+ * hdmi controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_hdmi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap54xx_hdmi_hwmod_class = { -+ .name = "hdmi", -+ .sysc = &omap54xx_hdmi_sysc, -+}; -+ -+static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { -+ { .role = "sys_clk", .clk = "dss_sys_clk" }, -+}; -+ -+static struct omap_hwmod omap54xx_dss_hdmi_hwmod = { -+ .name = "dss_hdmi", -+ .class = &omap54xx_hdmi_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .main_clk = "dss_48mhz_clk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, -+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, -+ }, -+ }, -+ .opt_clks = dss_hdmi_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), -+}; -+ -+/* -+ * 'rfbi' class -+ * remote frame buffer interface -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_rfbi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap54xx_rfbi_hwmod_class = { -+ .name = "rfbi", -+ .sysc = &omap54xx_rfbi_sysc, -+}; -+ -+/* dss_rfbi */ -+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { -+ { .role = "ick", .clk = "l3_iclk_div" }, -+}; -+ -+static struct omap_hwmod omap54xx_dss_rfbi_hwmod = { -+ .name = "dss_rfbi", -+ .class = &omap54xx_rfbi_hwmod_class, -+ .clkdm_name = "dss_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET, -+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, -+ }, -+ }, -+ .opt_clks = dss_rfbi_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), -+}; -+ -+/* - * 'emif' class - * external memory interface no1 (wrapper) - */ -@@ -352,8 +578,6 @@ static struct omap_hwmod omap54xx_emif1_ - .name = "emif1", - .class = &omap54xx_emif_hwmod_class, - .clkdm_name = "emif_clkdm", -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -- .main_clk = "dpll_core_h11x2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET, -@@ -368,8 +592,6 @@ static struct omap_hwmod omap54xx_emif2_ - .name = "emif2", - .class = &omap54xx_emif_hwmod_class, - .clkdm_name = "emif_clkdm", -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -- .main_clk = "dpll_core_h11x2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET, -@@ -409,15 +631,11 @@ static struct omap_gpio_dev_attr gpio_de - }; - - /* gpio1 */ --static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio1_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio1_hwmod = { - .name = "gpio1", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "wkupaon_iclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET, -@@ -425,22 +643,16 @@ static struct omap_hwmod omap54xx_gpio1_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio2 */ --static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio2_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio2_hwmod = { - .name = "gpio2", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET, -@@ -448,22 +660,16 @@ static struct omap_hwmod omap54xx_gpio2_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio3 */ --static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio3_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio3_hwmod = { - .name = "gpio3", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET, -@@ -471,22 +677,16 @@ static struct omap_hwmod omap54xx_gpio3_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio4 */ --static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio4_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio4_hwmod = { - .name = "gpio4", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET, -@@ -494,22 +694,16 @@ static struct omap_hwmod omap54xx_gpio4_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio5 */ --static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio5_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio5_hwmod = { - .name = "gpio5", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET, -@@ -517,22 +711,16 @@ static struct omap_hwmod omap54xx_gpio5_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio5_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio6 */ --static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio6_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio6_hwmod = { - .name = "gpio6", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET, -@@ -540,22 +728,16 @@ static struct omap_hwmod omap54xx_gpio6_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio6_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio7 */ --static struct omap_hwmod_opt_clk gpio7_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio7_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio7_hwmod = { - .name = "gpio7", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET, -@@ -563,22 +745,16 @@ static struct omap_hwmod omap54xx_gpio7_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio7_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio8 */ --static struct omap_hwmod_opt_clk gpio8_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio8_dbclk" }, --}; - - static struct omap_hwmod omap54xx_gpio8_hwmod = { - .name = "gpio8", - .class = &omap54xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l4_root_clk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET, -@@ -586,8 +762,6 @@ static struct omap_hwmod omap54xx_gpio8_ - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio8_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - -@@ -626,7 +800,6 @@ static struct omap_hwmod omap54xx_i2c1_h - .class = &omap54xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET, -@@ -643,7 +816,6 @@ static struct omap_hwmod omap54xx_i2c2_h - .class = &omap54xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET, -@@ -660,7 +832,6 @@ static struct omap_hwmod omap54xx_i2c3_h - .class = &omap54xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET, -@@ -677,7 +848,6 @@ static struct omap_hwmod omap54xx_i2c4_h - .class = &omap54xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET, -@@ -694,7 +864,6 @@ static struct omap_hwmod omap54xx_i2c5_h - .class = &omap54xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET, -@@ -729,7 +898,6 @@ static struct omap_hwmod omap54xx_kbd_hw - .name = "kbd", - .class = &omap54xx_kbd_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET, -@@ -792,16 +960,11 @@ static struct omap_hwmod_class omap54xx_ - }; - - /* mcbsp1 */ --static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" }, --}; - - static struct omap_hwmod omap54xx_mcbsp1_hwmod = { - .name = "mcbsp1", - .class = &omap54xx_mcbsp_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "mcbsp1_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET, -@@ -809,21 +972,14 @@ static struct omap_hwmod omap54xx_mcbsp1 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks), - }; - - /* mcbsp2 */ --static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" }, --}; - - static struct omap_hwmod omap54xx_mcbsp2_hwmod = { - .name = "mcbsp2", - .class = &omap54xx_mcbsp_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "mcbsp2_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET, -@@ -831,21 +987,14 @@ static struct omap_hwmod omap54xx_mcbsp2 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks), - }; - - /* mcbsp3 */ --static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { -- { .role = "pad_fck", .clk = "pad_clks_ck" }, -- { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" }, --}; - - static struct omap_hwmod omap54xx_mcbsp3_hwmod = { - .name = "mcbsp3", - .class = &omap54xx_mcbsp_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "mcbsp3_gfclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET, -@@ -853,8 +1002,6 @@ static struct omap_hwmod omap54xx_mcbsp3 - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mcbsp3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks), - }; - - /* -@@ -896,7 +1043,6 @@ static struct omap_hwmod omap54xx_mcpdm_ - */ - - .flags = HWMOD_EXT_OPT_MAIN_CLK, -- .main_clk = "pad_clks_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET, -@@ -938,7 +1084,6 @@ static struct omap_hwmod omap54xx_mcspi1 - .name = "mcspi1", - .class = &omap54xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, -@@ -959,7 +1104,6 @@ static struct omap_hwmod omap54xx_mcspi2 - .name = "mcspi2", - .class = &omap54xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, -@@ -980,7 +1124,6 @@ static struct omap_hwmod omap54xx_mcspi3 - .name = "mcspi3", - .class = &omap54xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, -@@ -1001,7 +1144,6 @@ static struct omap_hwmod omap54xx_mcspi4 - .name = "mcspi4", - .class = &omap54xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, -@@ -1035,9 +1177,6 @@ static struct omap_hwmod_class omap54xx_ - }; - - /* mmc1 */ --static struct omap_hwmod_opt_clk mmc1_opt_clks[] = { -- { .role = "32khz_clk", .clk = "mmc1_32khz_clk" }, --}; - - /* mmc1 dev_attr */ - static struct omap_mmc_dev_attr mmc1_dev_attr = { -@@ -1048,7 +1187,6 @@ static struct omap_hwmod omap54xx_mmc1_h - .name = "mmc1", - .class = &omap54xx_mmc_hwmod_class, - .clkdm_name = "l3init_clkdm", -- .main_clk = "mmc1_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET, -@@ -1056,8 +1194,6 @@ static struct omap_hwmod omap54xx_mmc1_h - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mmc1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mmc1_opt_clks), - .dev_attr = &mmc1_dev_attr, - }; - -@@ -1066,7 +1202,6 @@ static struct omap_hwmod omap54xx_mmc2_h - .name = "mmc2", - .class = &omap54xx_mmc_hwmod_class, - .clkdm_name = "l3init_clkdm", -- .main_clk = "mmc2_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET, -@@ -1081,7 +1216,6 @@ static struct omap_hwmod omap54xx_mmc3_h - .name = "mmc3", - .class = &omap54xx_mmc_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET, -@@ -1096,7 +1230,6 @@ static struct omap_hwmod omap54xx_mmc4_h - .name = "mmc4", - .class = &omap54xx_mmc_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET, -@@ -1111,7 +1244,6 @@ static struct omap_hwmod omap54xx_mmc5_h - .name = "mmc5", - .class = &omap54xx_mmc_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET, -@@ -1135,7 +1267,7 @@ static struct omap_hwmod omap54xx_mpu_hw - .name = "mpu", - .class = &omap54xx_mpu_hwmod_class, - .clkdm_name = "mpu_clkdm", -- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, -+ .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_mpu_m2_ck", - .prcm = { - .omap4 = { -@@ -1146,6 +1278,42 @@ static struct omap_hwmod omap54xx_mpu_hw - }; - - /* -+ * 'ocp2scp' class -+ * bridge to transform ocp interface protocol to scp (serial control port) -+ * protocol -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap54xx_ocp2scp_hwmod_class = { -+ .name = "ocp2scp", -+ .sysc = &omap54xx_ocp2scp_sysc, -+}; -+ -+/* ocp2scp1 */ -+static struct omap_hwmod omap54xx_ocp2scp1_hwmod = { -+ .name = "ocp2scp1", -+ .class = &omap54xx_ocp2scp_hwmod_class, -+ .clkdm_name = "l3init_clkdm", -+ .main_clk = "l4_root_clk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET, -+ .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+}; -+ -+/* - * 'timer' class - * general purpose timer module with accurate 1ms tick - * This class contains several variants: ['timer_1ms', 'timer'] -@@ -1187,7 +1355,6 @@ static struct omap_hwmod omap54xx_timer1 - .name = "timer1", - .class = &omap54xx_timer_1ms_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "timer1_gfclk_mux", - .flags = HWMOD_SET_DEFAULT_CLOCKACT, - .prcm = { - .omap4 = { -@@ -1203,7 +1370,6 @@ static struct omap_hwmod omap54xx_timer2 - .name = "timer2", - .class = &omap54xx_timer_1ms_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer2_gfclk_mux", - .flags = HWMOD_SET_DEFAULT_CLOCKACT, - .prcm = { - .omap4 = { -@@ -1219,7 +1385,6 @@ static struct omap_hwmod omap54xx_timer3 - .name = "timer3", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer3_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET, -@@ -1234,7 +1399,6 @@ static struct omap_hwmod omap54xx_timer4 - .name = "timer4", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer4_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET, -@@ -1249,7 +1413,6 @@ static struct omap_hwmod omap54xx_timer5 - .name = "timer5", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer5_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET, -@@ -1264,7 +1427,6 @@ static struct omap_hwmod omap54xx_timer6 - .name = "timer6", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer6_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET, -@@ -1279,7 +1441,6 @@ static struct omap_hwmod omap54xx_timer7 - .name = "timer7", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer7_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET, -@@ -1294,7 +1455,6 @@ static struct omap_hwmod omap54xx_timer8 - .name = "timer8", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "abe_clkdm", -- .main_clk = "timer8_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET, -@@ -1309,7 +1469,6 @@ static struct omap_hwmod omap54xx_timer9 - .name = "timer9", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer9_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET, -@@ -1324,7 +1483,6 @@ static struct omap_hwmod omap54xx_timer1 - .name = "timer10", - .class = &omap54xx_timer_1ms_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer10_gfclk_mux", - .flags = HWMOD_SET_DEFAULT_CLOCKACT, - .prcm = { - .omap4 = { -@@ -1340,7 +1498,6 @@ static struct omap_hwmod omap54xx_timer1 - .name = "timer11", - .class = &omap54xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer11_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET, -@@ -1377,7 +1534,6 @@ static struct omap_hwmod omap54xx_uart1_ - .name = "uart1", - .class = &omap54xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET, -@@ -1392,7 +1548,6 @@ static struct omap_hwmod omap54xx_uart2_ - .name = "uart2", - .class = &omap54xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET, -@@ -1408,7 +1563,6 @@ static struct omap_hwmod omap54xx_uart3_ - .class = &omap54xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = DEBUG_OMAP4UART3_FLAGS, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET, -@@ -1424,7 +1578,6 @@ static struct omap_hwmod omap54xx_uart4_ - .class = &omap54xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = DEBUG_OMAP4UART4_FLAGS, -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET, -@@ -1439,7 +1592,6 @@ static struct omap_hwmod omap54xx_uart5_ - .name = "uart5", - .class = &omap54xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET, -@@ -1454,7 +1606,6 @@ static struct omap_hwmod omap54xx_uart6_ - .name = "uart6", - .class = &omap54xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET, -@@ -1465,6 +1616,145 @@ static struct omap_hwmod omap54xx_uart6_ - }; - - /* -+ * 'usb_host_hs' class -+ * high-speed multi-port usb host controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap54xx_usb_host_hs_hwmod_class = { -+ .name = "usb_host_hs", -+ .sysc = &omap54xx_usb_host_hs_sysc, -+}; -+ -+static struct omap_hwmod_opt_clk usb_host_hs_opt_clks[] = { -+ { .role = "hsic60m_p2_clk", .clk = "usb_host_hs_hsic60m_p2_clk" }, -+ { .role = "hsic60m_p3_clk", .clk = "usb_host_hs_hsic60m_p3_clk" }, -+ { .role = "utmi_p1_clk", .clk = "usb_host_hs_utmi_p1_clk" }, -+ { .role = "utmi_p2_clk", .clk = "usb_host_hs_utmi_p2_clk" }, -+ { .role = "utmi_p3_clk", .clk = "usb_host_hs_utmi_p3_clk" }, -+ { .role = "hsic480m_p1_clk", .clk = "usb_host_hs_hsic480m_p1_clk" }, -+ { .role = "hsic60m_p1_clk", .clk = "usb_host_hs_hsic60m_p1_clk" }, -+ { .role = "hsic480m_p3_clk", .clk = "usb_host_hs_hsic480m_p3_clk" }, -+ { .role = "hsic480m_p2_clk", .clk = "usb_host_hs_hsic480m_p2_clk" }, -+}; -+ -+static struct omap_hwmod omap54xx_usb_host_hs_hwmod = { -+ .name = "usb_host_hs", -+ .class = &omap54xx_usb_host_hs_hwmod_class, -+ .clkdm_name = "l3init_clkdm", -+ /* -+ * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock -+ * id: i660 -+ * -+ * Description: -+ * In the following configuration : -+ * - USBHOST module is set to smart-idle mode -+ * - PRCM asserts idle_req to the USBHOST module ( This typically -+ * happens when the system is going to a low power mode : all ports -+ * have been suspended, the master part of the USBHOST module has -+ * entered the standby state, and SW has cut the functional clocks) -+ * - an USBHOST interrupt occurs before the module is able to answer -+ * idle_ack, typically a remote wakeup IRQ. -+ * Then the USB HOST module will enter a deadlock situation where it -+ * is no more accessible nor functional. -+ * -+ * Workaround: -+ * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE -+ */ -+ -+ /* -+ * Errata: USB host EHCI may stall when entering smart-standby mode -+ * Id: i571 -+ * -+ * Description: -+ * When the USBHOST module is set to smart-standby mode, and when it is -+ * ready to enter the standby state (i.e. all ports are suspended and -+ * all attached devices are in suspend mode), then it can wrongly assert -+ * the Mstandby signal too early while there are still some residual OCP -+ * transactions ongoing. If this condition occurs, the internal state -+ * machine may go to an undefined state and the USB link may be stuck -+ * upon the next resume. -+ * -+ * Workaround: -+ * Don't use smart standby; use only force standby, -+ * hence HWMOD_SWSUP_MSTANDBY -+ */ -+ -+ /* -+ * During system boot; If the hwmod framework resets the module -+ * the module will have smart idle settings; which can lead to deadlock -+ * (above Errata Id:i660); so, dont reset the module during boot; -+ * Use HWMOD_INIT_NO_RESET. -+ */ -+ -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | -+ HWMOD_INIT_NO_RESET, -+ .main_clk = "l3init_60m_fclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET, -+ .context_offs = OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+ .opt_clks = usb_host_hs_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(usb_host_hs_opt_clks), -+}; -+ -+/* -+ * 'usb_tll_hs' class -+ * usb_tll_hs module is the adapter on the usb_host_hs ports -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_usb_tll_hs_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap54xx_usb_tll_hs_hwmod_class = { -+ .name = "usb_tll_hs", -+ .sysc = &omap54xx_usb_tll_hs_sysc, -+}; -+ -+static struct omap_hwmod_opt_clk usb_tll_hs_opt_clks[] = { -+ { .role = "usb_ch2_clk", .clk = "usb_tll_hs_usb_ch2_clk" }, -+ { .role = "usb_ch0_clk", .clk = "usb_tll_hs_usb_ch0_clk" }, -+ { .role = "usb_ch1_clk", .clk = "usb_tll_hs_usb_ch1_clk" }, -+}; -+ -+static struct omap_hwmod omap54xx_usb_tll_hs_hwmod = { -+ .name = "usb_tll_hs", -+ .class = &omap54xx_usb_tll_hs_hwmod_class, -+ .clkdm_name = "l3init_clkdm", -+ .main_clk = "l4_root_clk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET, -+ .context_offs = OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+ .opt_clks = usb_tll_hs_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(usb_tll_hs_opt_clks), -+}; -+ -+/* - * 'usb_otg_ss' class - * 2.0 super speed (usb_otg_ss) controller - */ -@@ -1486,16 +1776,12 @@ static struct omap_hwmod_class omap54xx_ - }; - - /* usb_otg_ss */ --static struct omap_hwmod_opt_clk usb_otg_ss_opt_clks[] = { -- { .role = "refclk960m", .clk = "usb_otg_ss_refclk960m" }, --}; - - static struct omap_hwmod omap54xx_usb_otg_ss_hwmod = { - .name = "usb_otg_ss", - .class = &omap54xx_usb_otg_ss_hwmod_class, - .clkdm_name = "l3init_clkdm", - .flags = HWMOD_SWSUP_SIDLE, -- .main_clk = "dpll_core_h13x2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET, -@@ -1503,8 +1789,6 @@ static struct omap_hwmod omap54xx_usb_ot - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = usb_otg_ss_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(usb_otg_ss_opt_clks), - }; - - /* -@@ -1535,7 +1819,6 @@ static struct omap_hwmod omap54xx_wd_tim - .name = "wd_timer2", - .class = &omap54xx_wd_timer_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET, -@@ -1545,6 +1828,76 @@ static struct omap_hwmod omap54xx_wd_tim - }, - }; - -+/* -+ * 'ocp2scp' class -+ * bridge to transform ocp interface protocol to scp (serial control port) -+ * protocol -+ */ -+/* ocp2scp3 */ -+static struct omap_hwmod omap54xx_ocp2scp3_hwmod; -+/* l4_cfg -> ocp2scp3 */ -+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp3 = { -+ .master = &omap54xx_l4_cfg_hwmod, -+ .slave = &omap54xx_ocp2scp3_hwmod, -+ .clk = "l4_root_clk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod omap54xx_ocp2scp3_hwmod = { -+ .name = "ocp2scp3", -+ .class = &omap54xx_ocp2scp_hwmod_class, -+ .clkdm_name = "l3init_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET, -+ .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+}; -+ -+/* -+ * 'sata' class -+ * sata: serial ata interface gen2 compliant ( 1 rx/ 1 tx) -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap54xx_sata_sysc = { -+ .sysc_offs = 0x0000, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap54xx_sata_hwmod_class = { -+ .name = "sata", -+ .sysc = &omap54xx_sata_sysc, -+}; -+ -+/* sata */ -+static struct omap_hwmod omap54xx_sata_hwmod = { -+ .name = "sata", -+ .class = &omap54xx_sata_hwmod_class, -+ .clkdm_name = "l3init_clkdm", -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .main_clk = "func_48m_fclk", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = OMAP54XX_CM_L3INIT_SATA_CLKCTRL_OFFSET, -+ .context_offs = OMAP54XX_RM_L3INIT_SATA_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* l4_cfg -> sata */ -+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__sata = { -+ .master = &omap54xx_l4_cfg_hwmod, -+ .slave = &omap54xx_sata_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; - - /* - * Interfaces -@@ -1712,6 +2065,54 @@ static struct omap_hwmod_ocp_if omap54xx - .user = OCP_USER_MPU, - }; - -+/* l3_main_2 -> dss */ -+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = { -+ .master = &omap54xx_l3_main_2_hwmod, -+ .slave = &omap54xx_dss_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_2 -> dss_dispc */ -+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dispc = { -+ .master = &omap54xx_l3_main_2_hwmod, -+ .slave = &omap54xx_dss_dispc_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_2 -> dss_dsi1_a */ -+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_a = { -+ .master = &omap54xx_l3_main_2_hwmod, -+ .slave = &omap54xx_dss_dsi1_a_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_2 -> dss_dsi1_c */ -+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_dsi1_c = { -+ .master = &omap54xx_l3_main_2_hwmod, -+ .slave = &omap54xx_dss_dsi1_c_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_2 -> dss_hdmi */ -+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_hdmi = { -+ .master = &omap54xx_l3_main_2_hwmod, -+ .slave = &omap54xx_dss_hdmi_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l3_main_2 -> dss_rfbi */ -+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss_rfbi = { -+ .master = &omap54xx_l3_main_2_hwmod, -+ .slave = &omap54xx_dss_rfbi_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* mpu -> emif1 */ - static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = { - .master = &omap54xx_mpu_hwmod, -@@ -1960,6 +2361,14 @@ static struct omap_hwmod_ocp_if omap54xx - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l4_cfg -> ocp2scp1 */ -+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = { -+ .master = &omap54xx_l4_cfg_hwmod, -+ .slave = &omap54xx_ocp2scp1_hwmod, -+ .clk = "l4_root_clk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* l4_wkup -> timer1 */ - static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = { - .master = &omap54xx_l4_wkup_hwmod, -@@ -2096,6 +2505,22 @@ static struct omap_hwmod_ocp_if omap54xx - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l4_cfg -> usb_host_hs */ -+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = { -+ .master = &omap54xx_l4_cfg_hwmod, -+ .slave = &omap54xx_usb_host_hs_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_cfg -> usb_tll_hs */ -+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_tll_hs = { -+ .master = &omap54xx_l4_cfg_hwmod, -+ .slave = &omap54xx_usb_tll_hs_hwmod, -+ .clk = "l4_root_clk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* l4_cfg -> usb_otg_ss */ - static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = { - .master = &omap54xx_l4_cfg_hwmod, -@@ -2132,6 +2557,12 @@ static struct omap_hwmod_ocp_if *omap54x - &omap54xx_l4_wkup__counter_32k, - &omap54xx_l4_cfg__dma_system, - &omap54xx_l4_abe__dmic, -+ &omap54xx_l3_main_2__dss, -+ &omap54xx_l3_main_2__dss_dispc, -+ &omap54xx_l3_main_2__dss_dsi1_a, -+ &omap54xx_l3_main_2__dss_dsi1_c, -+ &omap54xx_l3_main_2__dss_hdmi, -+ &omap54xx_l3_main_2__dss_rfbi, - &omap54xx_mpu__emif1, - &omap54xx_mpu__emif2, - &omap54xx_l4_wkup__gpio1, -@@ -2163,6 +2594,7 @@ static struct omap_hwmod_ocp_if *omap54x - &omap54xx_l4_per__mmc4, - &omap54xx_l4_per__mmc5, - &omap54xx_l4_cfg__mpu, -+ &omap54xx_l4_cfg__ocp2scp1, - &omap54xx_l4_wkup__timer1, - &omap54xx_l4_per__timer2, - &omap54xx_l4_per__timer3, -@@ -2180,8 +2612,12 @@ static struct omap_hwmod_ocp_if *omap54x - &omap54xx_l4_per__uart4, - &omap54xx_l4_per__uart5, - &omap54xx_l4_per__uart6, -+ &omap54xx_l4_cfg__usb_host_hs, -+ &omap54xx_l4_cfg__usb_tll_hs, - &omap54xx_l4_cfg__usb_otg_ss, - &omap54xx_l4_wkup__wd_timer2, -+ &omap54xx_l4_cfg__ocp2scp3, -+ &omap54xx_l4_cfg__sata, - NULL, - }; - ---- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c -@@ -242,7 +242,6 @@ static struct omap_hwmod dra7xx_counter_ - .class = &dra7xx_counter_hwmod_class, - .clkdm_name = "wkupaon_clkdm", - .flags = HWMOD_SWSUP_SIDLE, -- .main_clk = "wkupaon_iclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET, -@@ -273,6 +272,56 @@ static struct omap_hwmod dra7xx_ctrl_mod - }; - - /* -+ * 'gmac' class -+ * cpsw/gmac sub system -+ */ -+static struct omap_hwmod_class_sysconfig dra7xx_gmac_sysc = { -+ .rev_offs = 0x0, -+ .sysc_offs = 0x8, -+ .syss_offs = 0x4, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE | -+ MSTANDBY_NO), -+ .sysc_fields = &omap_hwmod_sysc_type3, -+}; -+ -+static struct omap_hwmod_class dra7xx_gmac_hwmod_class = { -+ .name = "gmac", -+ .sysc = &dra7xx_gmac_sysc, -+}; -+ -+static struct omap_hwmod dra7xx_gmac_hwmod = { -+ .name = "gmac", -+ .class = &dra7xx_gmac_hwmod_class, -+ .clkdm_name = "gmac_clkdm", -+ .flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY), -+ .main_clk = "dpll_gmac_ck", -+ .mpu_rt_idx = 1, -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_GMAC_GMAC_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_GMAC_GMAC_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* -+ * 'mdio' class -+ */ -+static struct omap_hwmod_class dra7xx_mdio_hwmod_class = { -+ .name = "davinci_mdio", -+}; -+ -+static struct omap_hwmod dra7xx_mdio_hwmod = { -+ .name = "davinci_mdio", -+ .class = &dra7xx_mdio_hwmod_class, -+ .clkdm_name = "gmac_clkdm", -+ .main_clk = "dpll_gmac_ck", -+}; -+ -+/* - * 'dcan' class - * - */ -@@ -325,8 +374,8 @@ static struct omap_hwmod_class_sysconfig - SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | - SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -- SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -- MSTANDBY_SMART | MSTANDBY_SMART_WKUP), -+ MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, - }; - -@@ -356,7 +405,6 @@ static struct omap_hwmod dra7xx_dma_syst - .class = &dra7xx_dma_hwmod_class, - .clkdm_name = "dma_clkdm", - .mpu_irqs = dra7xx_dma_system_irqs, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET, -@@ -561,6 +609,40 @@ static struct omap_hwmod_class dra7xx_gp - .rev = 2, - }; - -+static struct omap_hwmod_class_sysconfig dra7xx_aes_sysc = { -+ .rev_offs = 0x0080, -+ .sysc_offs = 0x0084, -+ .syss_offs = 0x0088, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type4, -+}; -+ -+static struct omap_hwmod_class_sysconfig dra7xx_des_sysc = { -+ .rev_offs = 0x0030, -+ .sysc_offs = 0x0034, -+ .syss_offs = 0x0038, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO), -+ .sysc_fields = &omap_hwmod_sysc_type4, -+}; -+ -+static struct omap_hwmod_class dra7xx_aes_hwmod_class = { -+ .name = "aes", -+ .sysc = &dra7xx_aes_sysc, -+ .rev = 2, -+}; -+ -+static struct omap_hwmod_class dra7xx_des_hwmod_class = { -+ .name = "des", -+ .sysc = &dra7xx_des_sysc, -+ .rev = 2, -+}; -+ - /* gpio dev_attr */ - static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, -@@ -568,15 +650,11 @@ static struct omap_gpio_dev_attr gpio_de - }; - - /* gpio1 */ --static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio1_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio1_hwmod = { - .name = "gpio1", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "wkupaon_iclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET, -@@ -584,22 +662,16 @@ static struct omap_hwmod dra7xx_gpio1_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio2 */ --static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio2_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio2_hwmod = { - .name = "gpio2", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET, -@@ -607,22 +679,16 @@ static struct omap_hwmod dra7xx_gpio2_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio3 */ --static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio3_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio3_hwmod = { - .name = "gpio3", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET, -@@ -630,22 +696,16 @@ static struct omap_hwmod dra7xx_gpio3_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio4 */ --static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio4_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio4_hwmod = { - .name = "gpio4", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET, -@@ -653,22 +713,16 @@ static struct omap_hwmod dra7xx_gpio4_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio5 */ --static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio5_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio5_hwmod = { - .name = "gpio5", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET, -@@ -676,22 +730,16 @@ static struct omap_hwmod dra7xx_gpio5_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio5_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio6 */ --static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio6_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio6_hwmod = { - .name = "gpio6", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET, -@@ -699,22 +747,16 @@ static struct omap_hwmod dra7xx_gpio6_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio6_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio7 */ --static struct omap_hwmod_opt_clk gpio7_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio7_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio7_hwmod = { - .name = "gpio7", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET, -@@ -722,22 +764,16 @@ static struct omap_hwmod dra7xx_gpio7_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio7_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - - /* gpio8 */ --static struct omap_hwmod_opt_clk gpio8_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio8_dbclk" }, --}; - - static struct omap_hwmod dra7xx_gpio8_hwmod = { - .name = "gpio8", - .class = &dra7xx_gpio_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET, -@@ -745,11 +781,35 @@ static struct omap_hwmod dra7xx_gpio8_hw - .modulemode = MODULEMODE_HWCTRL, - }, - }, -- .opt_clks = gpio8_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks), - .dev_attr = &gpio_dev_attr, - }; - -+static struct omap_hwmod dra7xx_aes_hwmod = { -+ .name = "aes", -+ .class = &dra7xx_aes_hwmod_class, -+ .clkdm_name = "l4sec_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4SEC_AES1_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4SEC_AES1_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+}; -+ -+static struct omap_hwmod dra7xx_des_hwmod = { -+ .name = "des", -+ .class = &dra7xx_des_hwmod_class, -+ .clkdm_name = "l4sec_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+}; -+ - /* - * 'gpmc' class - * -@@ -859,7 +919,6 @@ static struct omap_hwmod dra7xx_i2c1_hwm - .class = &dra7xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_I2C1_CLKCTRL_OFFSET, -@@ -876,7 +935,6 @@ static struct omap_hwmod dra7xx_i2c2_hwm - .class = &dra7xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_I2C2_CLKCTRL_OFFSET, -@@ -893,7 +951,6 @@ static struct omap_hwmod dra7xx_i2c3_hwm - .class = &dra7xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_I2C3_CLKCTRL_OFFSET, -@@ -910,7 +967,6 @@ static struct omap_hwmod dra7xx_i2c4_hwm - .class = &dra7xx_i2c_hwmod_class, - .clkdm_name = "l4per_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_I2C4_CLKCTRL_OFFSET, -@@ -927,7 +983,6 @@ static struct omap_hwmod dra7xx_i2c5_hwm - .class = &dra7xx_i2c_hwmod_class, - .clkdm_name = "ipu_clkdm", - .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, -- .main_clk = "func_96m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_IPU_I2C5_CLKCTRL_OFFSET, -@@ -939,6 +994,207 @@ static struct omap_hwmod dra7xx_i2c5_hwm - }; - - /* -+ * 'mailbox' class -+ * -+ */ -+ -+static struct omap_hwmod_class_sysconfig dra7xx_mailbox_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class dra7xx_mailbox_hwmod_class = { -+ .name = "mailbox", -+ .sysc = &dra7xx_mailbox_sysc, -+}; -+ -+/* mailbox1 */ -+static struct omap_hwmod dra7xx_mailbox1_hwmod = { -+ .name = "mailbox1", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX1_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX1_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox2 */ -+static struct omap_hwmod dra7xx_mailbox2_hwmod = { -+ .name = "mailbox2", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX2_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX2_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox3 */ -+static struct omap_hwmod dra7xx_mailbox3_hwmod = { -+ .name = "mailbox3", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX3_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX3_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox4 */ -+static struct omap_hwmod dra7xx_mailbox4_hwmod = { -+ .name = "mailbox4", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX4_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX4_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox5 */ -+static struct omap_hwmod dra7xx_mailbox5_hwmod = { -+ .name = "mailbox5", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX5_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX5_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox6 */ -+static struct omap_hwmod dra7xx_mailbox6_hwmod = { -+ .name = "mailbox6", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX6_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX6_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox7 */ -+static struct omap_hwmod dra7xx_mailbox7_hwmod = { -+ .name = "mailbox7", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX7_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX7_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox8 */ -+static struct omap_hwmod dra7xx_mailbox8_hwmod = { -+ .name = "mailbox8", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX8_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX8_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox9 */ -+static struct omap_hwmod dra7xx_mailbox9_hwmod = { -+ .name = "mailbox9", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX9_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX9_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox10 */ -+static struct omap_hwmod dra7xx_mailbox10_hwmod = { -+ .name = "mailbox10", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX10_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX10_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox11 */ -+static struct omap_hwmod dra7xx_mailbox11_hwmod = { -+ .name = "mailbox11", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX11_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX11_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox12 */ -+static struct omap_hwmod dra7xx_mailbox12_hwmod = { -+ .name = "mailbox12", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX12_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX12_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* mailbox13 */ -+static struct omap_hwmod dra7xx_mailbox13_hwmod = { -+ .name = "mailbox13", -+ .class = &dra7xx_mailbox_hwmod_class, -+ .clkdm_name = "l4cfg_clkdm", -+ .main_clk = "l3_iclk_div", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L4CFG_MAILBOX13_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L4CFG_MAILBOX13_CONTEXT_OFFSET, -+ }, -+ }, -+}; -+ -+/* - * 'mcspi' class - * - */ -@@ -969,7 +1225,6 @@ static struct omap_hwmod dra7xx_mcspi1_h - .name = "mcspi1", - .class = &dra7xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, -@@ -990,7 +1245,6 @@ static struct omap_hwmod dra7xx_mcspi2_h - .name = "mcspi2", - .class = &dra7xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, -@@ -1011,7 +1265,6 @@ static struct omap_hwmod dra7xx_mcspi3_h - .name = "mcspi3", - .class = &dra7xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, -@@ -1032,7 +1285,6 @@ static struct omap_hwmod dra7xx_mcspi4_h - .name = "mcspi4", - .class = &dra7xx_mcspi_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "func_48m_fclk", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, -@@ -1066,9 +1318,6 @@ static struct omap_hwmod_class dra7xx_mm - }; - - /* mmc1 */ --static struct omap_hwmod_opt_clk mmc1_opt_clks[] = { -- { .role = "clk32k", .clk = "mmc1_clk32k" }, --}; - - /* mmc1 dev_attr */ - static struct omap_mmc_dev_attr mmc1_dev_attr = { -@@ -1079,7 +1328,6 @@ static struct omap_hwmod dra7xx_mmc1_hwm - .name = "mmc1", - .class = &dra7xx_mmc_hwmod_class, - .clkdm_name = "l3init_clkdm", -- .main_clk = "mmc1_fclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET, -@@ -1087,21 +1335,15 @@ static struct omap_hwmod dra7xx_mmc1_hwm - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mmc1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mmc1_opt_clks), - .dev_attr = &mmc1_dev_attr, - }; - - /* mmc2 */ --static struct omap_hwmod_opt_clk mmc2_opt_clks[] = { -- { .role = "clk32k", .clk = "mmc2_clk32k" }, --}; - - static struct omap_hwmod dra7xx_mmc2_hwmod = { - .name = "mmc2", - .class = &dra7xx_mmc_hwmod_class, - .clkdm_name = "l3init_clkdm", -- .main_clk = "mmc2_fclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET, -@@ -1109,20 +1351,14 @@ static struct omap_hwmod dra7xx_mmc2_hwm - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mmc2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mmc2_opt_clks), - }; - - /* mmc3 */ --static struct omap_hwmod_opt_clk mmc3_opt_clks[] = { -- { .role = "clk32k", .clk = "mmc3_clk32k" }, --}; - - static struct omap_hwmod dra7xx_mmc3_hwmod = { - .name = "mmc3", - .class = &dra7xx_mmc_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "mmc3_gfclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_MMC3_CLKCTRL_OFFSET, -@@ -1130,20 +1366,14 @@ static struct omap_hwmod dra7xx_mmc3_hwm - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mmc3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mmc3_opt_clks), - }; - - /* mmc4 */ --static struct omap_hwmod_opt_clk mmc4_opt_clks[] = { -- { .role = "clk32k", .clk = "mmc4_clk32k" }, --}; - - static struct omap_hwmod dra7xx_mmc4_hwmod = { - .name = "mmc4", - .class = &dra7xx_mmc_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "mmc4_gfclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_MMC4_CLKCTRL_OFFSET, -@@ -1151,8 +1381,6 @@ static struct omap_hwmod dra7xx_mmc4_hwm - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = mmc4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(mmc4_opt_clks), - }; - - /* -@@ -1215,6 +1443,30 @@ static struct omap_hwmod dra7xx_ocp2scp1 - }, - }; - -+/* ocp2scp3 */ -+static struct omap_hwmod dra7xx_ocp2scp3_hwmod; -+ -+/* l4_cfg -> ocp2scp3 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp3 = { -+ .master = &dra7xx_l4_cfg_hwmod, -+ .slave = &dra7xx_ocp2scp3_hwmod, -+ .clk = "l4_root_clk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod dra7xx_ocp2scp3_hwmod = { -+ .name = "ocp2scp3", -+ .class = &dra7xx_ocp2scp_hwmod_class, -+ .clkdm_name = "l3init_clkdm", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+}; -+ - /* - * 'qspi' class - * -@@ -1249,6 +1501,38 @@ static struct omap_hwmod dra7xx_qspi_hwm - }; - - /* -+ * 'rtcss' class -+ * -+ */ -+static struct omap_hwmod_class_sysconfig dra7xx_rtcss_sysc = { -+ .sysc_offs = 0x0078, -+ .sysc_flags = SYSC_HAS_SIDLEMODE, -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type3, -+}; -+ -+static struct omap_hwmod_class dra7xx_rtcss_hwmod_class = { -+ .name = "rtcss", -+ .sysc = &dra7xx_rtcss_sysc, -+}; -+ -+/* rtcss */ -+static struct omap_hwmod dra7xx_rtcss_hwmod = { -+ .name = "rtcss", -+ .class = &dra7xx_rtcss_hwmod_class, -+ .clkdm_name = "rtc_clkdm", -+ .main_clk = "sys_32k_ck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_RTC_RTCSS_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_RTC_RTCSS_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_SWCTRL, -+ }, -+ }, -+}; -+ -+/* - * 'sata' class - * - */ -@@ -1268,9 +1552,6 @@ static struct omap_hwmod_class dra7xx_sa - }; - - /* sata */ --static struct omap_hwmod_opt_clk sata_opt_clks[] = { -- { .role = "ref_clk", .clk = "sata_ref_clk" }, --}; - - static struct omap_hwmod dra7xx_sata_hwmod = { - .name = "sata", -@@ -1285,8 +1566,6 @@ static struct omap_hwmod dra7xx_sata_hwm - .modulemode = MODULEMODE_SWCTRL, - }, - }, -- .opt_clks = sata_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(sata_opt_clks), - }; - - /* -@@ -1449,7 +1728,6 @@ static struct omap_hwmod dra7xx_timer1_h - .name = "timer1", - .class = &dra7xx_timer_1ms_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "timer1_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET, -@@ -1464,7 +1742,6 @@ static struct omap_hwmod dra7xx_timer2_h - .name = "timer2", - .class = &dra7xx_timer_1ms_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer2_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET, -@@ -1479,7 +1756,6 @@ static struct omap_hwmod dra7xx_timer3_h - .name = "timer3", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer3_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET, -@@ -1494,7 +1770,6 @@ static struct omap_hwmod dra7xx_timer4_h - .name = "timer4", - .class = &dra7xx_timer_secure_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer4_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET, -@@ -1509,7 +1784,6 @@ static struct omap_hwmod dra7xx_timer5_h - .name = "timer5", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "ipu_clkdm", -- .main_clk = "timer5_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_IPU_TIMER5_CLKCTRL_OFFSET, -@@ -1524,7 +1798,6 @@ static struct omap_hwmod dra7xx_timer6_h - .name = "timer6", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "ipu_clkdm", -- .main_clk = "timer6_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_IPU_TIMER6_CLKCTRL_OFFSET, -@@ -1539,7 +1812,6 @@ static struct omap_hwmod dra7xx_timer7_h - .name = "timer7", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "ipu_clkdm", -- .main_clk = "timer7_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_IPU_TIMER7_CLKCTRL_OFFSET, -@@ -1554,7 +1826,6 @@ static struct omap_hwmod dra7xx_timer8_h - .name = "timer8", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "ipu_clkdm", -- .main_clk = "timer8_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_IPU_TIMER8_CLKCTRL_OFFSET, -@@ -1569,7 +1840,6 @@ static struct omap_hwmod dra7xx_timer9_h - .name = "timer9", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer9_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET, -@@ -1584,7 +1854,6 @@ static struct omap_hwmod dra7xx_timer10_ - .name = "timer10", - .class = &dra7xx_timer_1ms_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer10_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET, -@@ -1599,7 +1868,6 @@ static struct omap_hwmod dra7xx_timer11_ - .name = "timer11", - .class = &dra7xx_timer_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "timer11_gfclk_mux", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET, -@@ -1636,8 +1904,7 @@ static struct omap_hwmod dra7xx_uart1_hw - .name = "uart1", - .class = &dra7xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "uart1_gfclk_mux", -- .flags = HWMOD_SWSUP_SIDLE_ACT, -+ .flags = DEBUG_OMAP2UART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L4PER_UART1_CLKCTRL_OFFSET, -@@ -1652,7 +1919,6 @@ static struct omap_hwmod dra7xx_uart2_hw - .name = "uart2", - .class = &dra7xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "uart2_gfclk_mux", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap4 = { -@@ -1668,7 +1934,6 @@ static struct omap_hwmod dra7xx_uart3_hw - .name = "uart3", - .class = &dra7xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "uart3_gfclk_mux", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap4 = { -@@ -1684,7 +1949,6 @@ static struct omap_hwmod dra7xx_uart4_hw - .name = "uart4", - .class = &dra7xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "uart4_gfclk_mux", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap4 = { -@@ -1700,7 +1964,6 @@ static struct omap_hwmod dra7xx_uart5_hw - .name = "uart5", - .class = &dra7xx_uart_hwmod_class, - .clkdm_name = "l4per_clkdm", -- .main_clk = "uart5_gfclk_mux", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap4 = { -@@ -1716,7 +1979,6 @@ static struct omap_hwmod dra7xx_uart6_hw - .name = "uart6", - .class = &dra7xx_uart_hwmod_class, - .clkdm_name = "ipu_clkdm", -- .main_clk = "uart6_gfclk_mux", - .flags = HWMOD_SWSUP_SIDLE_ACT, - .prcm = { - .omap4 = { -@@ -1732,8 +1994,20 @@ static struct omap_hwmod dra7xx_uart6_hw - * - */ - -+static struct omap_hwmod_class_sysconfig dra7xx_usb_otg_ss_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ - static struct omap_hwmod_class dra7xx_usb_otg_ss_hwmod_class = { - .name = "usb_otg_ss", -+ .sysc = &dra7xx_usb_otg_ss_sysc, - }; - - /* usb_otg_ss1 */ -@@ -1873,7 +2147,6 @@ static struct omap_hwmod dra7xx_wd_timer - .name = "wd_timer2", - .class = &dra7xx_wd_timer_hwmod_class, - .clkdm_name = "wkupaon_clkdm", -- .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET, -@@ -1883,6 +2156,39 @@ static struct omap_hwmod dra7xx_wd_timer - }, - }; - -+/* -+ * 'vpe' class -+ * -+ */ -+ -+static struct omap_hwmod_class_sysconfig dra7xx_vpe_sysc = { -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART | MSTANDBY_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class dra7xx_vpe_hwmod_class = { -+ .name = "vpe", -+ .sysc = &dra7xx_vpe_sysc, -+}; -+ -+/* vpe */ -+static struct omap_hwmod dra7xx_vpe_hwmod = { -+ .name = "vpe", -+ .class = &dra7xx_vpe_hwmod_class, -+ .clkdm_name = "vpe_clkdm", -+ .main_clk = "dpll_core_h23x2_ck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_offs = DRA7XX_CM_VPE_VPE_CLKCTRL_OFFSET, -+ .context_offs = DRA7XX_RM_VPE_VPE_CONTEXT_OFFSET, -+ .modulemode = MODULEMODE_HWCTRL, -+ }, -+ }, -+}; - - /* - * Interfaces -@@ -2000,6 +2306,19 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+static struct omap_hwmod_ocp_if dra7xx_l4_per2__cpgmac0 = { -+ .master = &dra7xx_l4_per2_hwmod, -+ .slave = &dra7xx_gmac_hwmod, -+ .clk = "dpll_gmac_ck", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if dra7xx_gmac__mdio = { -+ .master = &dra7xx_gmac_hwmod, -+ .slave = &dra7xx_mdio_hwmod, -+ .user = OCP_USER_MPU, -+}; -+ - /* l4_wkup -> dcan1 */ - static struct omap_hwmod_ocp_if dra7xx_l4_wkup__dcan1 = { - .master = &dra7xx_l4_wkup_hwmod, -@@ -2089,6 +2408,14 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l3_main_1 -> aes */ -+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__aes = { -+ .master = &dra7xx_l3_main_1_hwmod, -+ .slave = &dra7xx_aes_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = { - { - .pa_start = 0x48078000, -@@ -2171,6 +2498,14 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l4_per1 -> des */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per1__des = { -+ .master = &dra7xx_l4_per1_hwmod, -+ .slave = &dra7xx_des_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - static struct omap_hwmod_addr_space dra7xx_gpmc_addrs[] = { - { - .pa_start = 0x50000000, -@@ -2247,6 +2582,110 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l4_cfg -> mailbox1 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mailbox1 = { -+ .master = &dra7xx_l4_cfg_hwmod, -+ .slave = &dra7xx_mailbox1_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox2 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox2 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox2_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox3 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox3 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox3_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox4 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox4 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox4_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox5 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox5 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox5_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox6 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox6 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox6_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox7 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox7 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox7_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox8 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox8 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox8_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox9 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox9 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox9_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox10 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox10 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox10_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox11 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox11 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox11_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox12 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox12 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox12_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_per3 -> mailbox13 */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__mailbox13 = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_mailbox13_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* l4_per1 -> mcspi1 */ - static struct omap_hwmod_ocp_if dra7xx_l4_per1__mcspi1 = { - .master = &dra7xx_l4_per1_hwmod, -@@ -2319,21 +2758,11 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_addr_space dra7xx_ocp2scp1_addrs[] = { -- { -- .pa_start = 0x4a080000, -- .pa_end = 0x4a08001f, -- .flags = ADDR_TYPE_RT -- }, -- { } --}; -- - /* l4_cfg -> ocp2scp1 */ - static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp1 = { - .master = &dra7xx_l4_cfg_hwmod, - .slave = &dra7xx_ocp2scp1_hwmod, - .clk = "l4_root_clk_div", -- .addr = dra7xx_ocp2scp1_addrs, - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -@@ -2355,6 +2784,14 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l4_per3 -> rtcss */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__rtcss = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_rtcss_hwmod, -+ .clk = "l4_root_clk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - static struct omap_hwmod_addr_space dra7xx_sata_addrs[] = { - { - .name = "sysc", -@@ -2636,6 +3073,14 @@ static struct omap_hwmod_ocp_if dra7xx_l - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* l4_per3 -> vpe */ -+static struct omap_hwmod_ocp_if dra7xx_l4_per3__vpe = { -+ .master = &dra7xx_l4_per3_hwmod, -+ .slave = &dra7xx_vpe_hwmod, -+ .clk = "l3_iclk_div", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { - &dra7xx_l3_main_2__l3_instr, - &dra7xx_l4_cfg__l3_main_1, -@@ -2653,10 +3098,13 @@ static struct omap_hwmod_ocp_if *dra7xx_ - &dra7xx_l4_wkup__ctrl_module_wkup, - &dra7xx_l4_wkup__dcan1, - &dra7xx_l4_per2__dcan2, -+ &dra7xx_l4_per2__cpgmac0, -+ &dra7xx_gmac__mdio, - &dra7xx_l4_cfg__dma_system, - &dra7xx_l3_main_1__dss, - &dra7xx_l3_main_1__dispc, - &dra7xx_l3_main_1__hdmi, -+ &dra7xx_l3_main_1__aes, - &dra7xx_l4_per1__elm, - &dra7xx_l4_wkup__gpio1, - &dra7xx_l4_per1__gpio2, -@@ -2673,6 +3121,19 @@ static struct omap_hwmod_ocp_if *dra7xx_ - &dra7xx_l4_per1__i2c3, - &dra7xx_l4_per1__i2c4, - &dra7xx_l4_per1__i2c5, -+ &dra7xx_l4_cfg__mailbox1, -+ &dra7xx_l4_per3__mailbox2, -+ &dra7xx_l4_per3__mailbox3, -+ &dra7xx_l4_per3__mailbox4, -+ &dra7xx_l4_per3__mailbox5, -+ &dra7xx_l4_per3__mailbox6, -+ &dra7xx_l4_per3__mailbox7, -+ &dra7xx_l4_per3__mailbox8, -+ &dra7xx_l4_per3__mailbox9, -+ &dra7xx_l4_per3__mailbox10, -+ &dra7xx_l4_per3__mailbox11, -+ &dra7xx_l4_per3__mailbox12, -+ &dra7xx_l4_per3__mailbox13, - &dra7xx_l4_per1__mcspi1, - &dra7xx_l4_per1__mcspi2, - &dra7xx_l4_per1__mcspi3, -@@ -2683,7 +3144,9 @@ static struct omap_hwmod_ocp_if *dra7xx_ - &dra7xx_l4_per1__mmc4, - &dra7xx_l4_cfg__mpu, - &dra7xx_l4_cfg__ocp2scp1, -+ &dra7xx_l4_cfg__ocp2scp3, - &dra7xx_l3_main_1__qspi, -+ &dra7xx_l4_per3__rtcss, - &dra7xx_l4_cfg__sata, - &dra7xx_l4_cfg__smartreflex_core, - &dra7xx_l4_cfg__smartreflex_mpu, -@@ -2705,6 +3168,7 @@ static struct omap_hwmod_ocp_if *dra7xx_ - &dra7xx_l4_per1__uart4, - &dra7xx_l4_per1__uart5, - &dra7xx_l4_per1__uart6, -+ &dra7xx_l4_per1__des, - &dra7xx_l4_per3__usb_otg_ss1, - &dra7xx_l4_per3__usb_otg_ss2, - &dra7xx_l4_per3__usb_otg_ss3, -@@ -2714,6 +3178,7 @@ static struct omap_hwmod_ocp_if *dra7xx_ - &dra7xx_l3_main_1__vcp2, - &dra7xx_l4_per2__vcp2, - &dra7xx_l4_wkup__wd_timer2, -+ &dra7xx_l4_per3__vpe, - NULL, - }; - ---- a/arch/arm/mach-omap2/omap_hwmod.c -+++ b/arch/arm/mach-omap2/omap_hwmod.c -@@ -141,6 +141,7 @@ - #include <linux/cpu.h> - #include <linux/of.h> - #include <linux/of_address.h> -+#include <linux/suspend.h> - - #include <asm/system_misc.h> - -@@ -208,6 +209,9 @@ static struct omap_hwmod *mpu_oh; - /* io_chain_lock: used to serialize reconfigurations of the I/O chain */ - static DEFINE_SPINLOCK(io_chain_lock); - -+/* _oh_force_mstandby_repeated_list for tracking nonstandard mstandby hwmods */ -+static LIST_HEAD(_oh_force_mstandby_repeated_list); -+ - /* - * linkspace: ptr to a buffer that struct omap_hwmod_link records are - * allocated from - used to reduce the number of small memory -@@ -656,6 +660,8 @@ static struct clockdomain *_get_clkdm(st - if (oh->clkdm) { - return oh->clkdm; - } else if (oh->_clk) { -+ if (__clk_get_flags(oh->_clk) & CLK_IS_BASIC) -+ return NULL; - clk = to_clk_hw_omap(__clk_get_hw(oh->_clk)); - return clk->clkdm; - } -@@ -728,14 +734,18 @@ static int _del_initiator_dep(struct oma - * functional clock pointer) if a main_clk is present. Returns 0 on - * success or -EINVAL on error. - */ --static int _init_main_clk(struct omap_hwmod *oh) -+static int _init_main_clk(struct omap_hwmod *oh, struct device_node *np) - { - int ret = 0; - -- if (!oh->main_clk) -+ if (!oh->main_clk && !of_get_property(np, "clocks", NULL)) - return 0; - -- oh->_clk = clk_get(NULL, oh->main_clk); -+ if (oh->main_clk) -+ oh->_clk = clk_get(NULL, oh->main_clk); -+ else -+ oh->_clk = of_clk_get_by_name(np, "fck"); -+ - if (IS_ERR(oh->_clk)) { - pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", - oh->name, oh->main_clk); -@@ -801,6 +811,63 @@ static int _init_interface_clks(struct o - return ret; - } - -+static const char **_parse_opt_clks_dt(struct omap_hwmod *oh, -+ struct device_node *np, -+ int *opt_clks_cnt) -+{ -+ int i, clks_cnt; -+ const char *clk_name; -+ const char **opt_clk_names; -+ -+ clks_cnt = of_property_count_strings(np, "clock-names"); -+ if (!clks_cnt) -+ return NULL; -+ -+ opt_clk_names = kzalloc(sizeof(char *)*clks_cnt, GFP_KERNEL); -+ if (!opt_clk_names) -+ return NULL; -+ -+ for (i = 0; i < clks_cnt; i++) { -+ of_property_read_string_index(np, "clock-names", i, &clk_name); -+ if (!strcmp(clk_name, "fck")) -+ continue; -+ opt_clk_names[(*opt_clks_cnt)++] = clk_name; -+ } -+ return opt_clk_names; -+} -+ -+static int _init_opt_clks_dt(struct omap_hwmod *oh, struct device_node *np) -+{ -+ struct clk *c; -+ int i, opt_clks_cnt = 0; -+ int ret = 0; -+ const char **opt_clk_names; -+ -+ opt_clk_names = _parse_opt_clks_dt(oh, np, &opt_clks_cnt); -+ if (!opt_clk_names) -+ return -EINVAL; -+ -+ oh->opt_clks = kzalloc(sizeof(struct omap_hwmod_opt_clk *) -+ * opt_clks_cnt, GFP_KERNEL); -+ if (!oh->opt_clks) -+ return -ENOMEM; -+ -+ oh->opt_clks_cnt = opt_clks_cnt; -+ -+ for (i = 0; i < opt_clks_cnt; i++) { -+ c = of_clk_get_by_name(np, opt_clk_names[i]); -+ if (IS_ERR(c)) { -+ pr_warn("omap_hwmod: %s: cannot clk_get opt_clk %s\n", -+ oh->name, opt_clk_names[i]); -+ ret = -EINVAL; -+ } -+ oh->opt_clks[i]._clk = c; -+ oh->opt_clks[i].role = opt_clk_names[i]; -+ clk_prepare(oh->opt_clks[i]._clk); -+ } -+ return ret; -+} -+ - /** - * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks - * @oh: struct omap_hwmod * -@@ -808,13 +875,16 @@ static int _init_interface_clks(struct o - * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk - * clock pointers. Returns 0 on success or -EINVAL on error. - */ --static int _init_opt_clks(struct omap_hwmod *oh) -+static int _init_opt_clks(struct omap_hwmod *oh, struct device_node *np) - { - struct omap_hwmod_opt_clk *oc; - struct clk *c; - int i; - int ret = 0; - -+ if (of_get_property(np, "clocks", NULL)) -+ return _init_opt_clks_dt(oh, np); -+ - for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { - c = clk_get(NULL, oc->clk); - if (IS_ERR(c)) { -@@ -1544,7 +1614,7 @@ static int _init_clkdm(struct omap_hwmod - if (!oh->clkdm) { - pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n", - oh->name, oh->clkdm_name); -- return -EINVAL; -+ return 0; - } - - pr_debug("omap_hwmod: %s: associated to clkdm %s\n", -@@ -1563,7 +1633,8 @@ static int _init_clkdm(struct omap_hwmod - * Resolves all clock names embedded in the hwmod. Returns 0 on - * success, or a negative error code on failure. - */ --static int _init_clocks(struct omap_hwmod *oh, void *data) -+static int _init_clocks(struct omap_hwmod *oh, void *data, -+ struct device_node *np) - { - int ret = 0; - -@@ -1575,9 +1646,9 @@ static int _init_clocks(struct omap_hwmo - if (soc_ops.init_clkdm) - ret |= soc_ops.init_clkdm(oh); - -- ret |= _init_main_clk(oh); -+ ret |= _init_main_clk(oh, np); - ret |= _init_interface_clks(oh); -- ret |= _init_opt_clks(oh); -+ ret |= _init_opt_clks(oh, np); - - if (!ret) - oh->_state = _HWMOD_STATE_CLKS_INITED; -@@ -2363,11 +2434,11 @@ static struct device_node *of_dev_hwmod_ - * are part of the device's address space can be ioremapped properly. - * No return value. - */ --static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) -+static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, -+ struct device_node *np) - { - struct omap_hwmod_addr_space *mem; - void __iomem *va_start = NULL; -- struct device_node *np; - - if (!oh) - return; -@@ -2383,12 +2454,10 @@ static void __init _init_mpu_rt_base(str - oh->name); - - /* Extract the IO space from device tree blob */ -- if (!of_have_populated_dt()) -+ if (!np) - return; - -- np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); -- if (np) -- va_start = of_iomap(np, oh->mpu_rt_idx); -+ va_start = of_iomap(np, oh->mpu_rt_idx); - } else { - va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); - } -@@ -2420,19 +2489,31 @@ static void __init _init_mpu_rt_base(str - static int __init _init(struct omap_hwmod *oh, void *data) - { - int r; -+ struct device_node *np = NULL; - - if (oh->_state != _HWMOD_STATE_REGISTERED) - return 0; - -+ /* If booting with DT, parse the DT node for IO space/clocks etc */ -+ if (of_have_populated_dt()) -+ np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); -+ - if (oh->class->sysc) -- _init_mpu_rt_base(oh, NULL); -+ _init_mpu_rt_base(oh, NULL, np); - -- r = _init_clocks(oh, NULL); -+ r = _init_clocks(oh, NULL, np); - if (r < 0) { - WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); - return -EINVAL; - } - -+ if (np) { -+ if (of_find_property(np, "ti,no-reset", NULL)) -+ oh->flags |= HWMOD_INIT_NO_RESET; -+ if (of_find_property(np, "ti,no-idle", NULL)) -+ oh->flags |= HWMOD_INIT_NO_IDLE; -+ } -+ - oh->_state = _HWMOD_STATE_INITIALIZED; - - return 0; -@@ -3826,6 +3907,75 @@ int omap_hwmod_disable_wakeup(struct oma - return 0; - } - -+/* -+ * There are some IPs that do not have MSTANDBY asserted by default -+ * which is necessary for PER domain transition. If the drivers -+ * are not compiled into the kernel HWMOD code will not change the -+ * state of the IPs if the IP was never enabled, so we keep track of -+ * them here to idle them with a pm_notifier. -+ */ -+ -+static int _omap_mstandby_pm_notifier(struct notifier_block *self, -+ unsigned long action, void *dev) -+{ -+ struct omap_hwmod_list *oh_list_item = NULL; -+ switch (action) { -+ case PM_POST_SUSPEND: -+ list_for_each_entry(oh_list_item, -+ &_oh_force_mstandby_repeated_list, oh_list) { -+ omap_hwmod_enable(oh_list_item->oh); -+ omap_hwmod_idle(oh_list_item->oh); -+ } -+ } -+ -+ return NOTIFY_DONE; -+} -+ -+struct notifier_block pm_nb = { -+ .notifier_call = _omap_mstandby_pm_notifier, -+}; -+ -+static int _check_for_force_mstandby_repeated(struct omap_hwmod *oh, void *data) -+{ -+ if (oh->flags & HWMOD_FORCE_MSTANDBY_REPEATED) -+ omap_hwmod_enable_force_mstandby_repeated(oh); -+ -+ return 0; -+} -+ -+int omap_hwmod_force_mstandby_repeated(void) -+{ -+ omap_hwmod_for_each(_check_for_force_mstandby_repeated, NULL); -+ register_pm_notifier(&pm_nb); -+ return 0; -+} -+ -+int omap_hwmod_enable_force_mstandby_repeated(struct omap_hwmod *oh) -+{ -+ struct omap_hwmod_list *oh_list_item = NULL; -+ -+ oh_list_item = kzalloc(sizeof(*oh_list_item), GFP_KERNEL); -+ oh_list_item->oh = oh; -+ list_add(&oh_list_item->oh_list, &_oh_force_mstandby_repeated_list); -+ -+ return 0; -+} -+ -+int omap_hwmod_disable_force_mstandby_repeated(struct omap_hwmod *oh) -+{ -+ struct omap_hwmod_list *oh_list_item, *tmp; -+ -+ list_for_each_entry_safe(oh_list_item, tmp, -+ &_oh_force_mstandby_repeated_list, oh_list) { -+ if (oh_list_item->oh == oh) { -+ list_del(&oh_list_item->oh_list); -+ kfree(oh_list_item); -+ } -+ } -+ -+ return 0; -+} -+ - /** - * omap_hwmod_assert_hardreset - assert the HW reset line of submodules - * contained in the hwmod module. -@@ -4115,6 +4265,7 @@ void __init omap_hwmod_init(void) - soc_ops.assert_hardreset = _omap2_assert_hardreset; - soc_ops.deassert_hardreset = _omap2_deassert_hardreset; - soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; -+ soc_ops.init_clkdm = _init_clkdm; - } else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) { - soc_ops.enable_module = _omap4_enable_module; - soc_ops.disable_module = _omap4_disable_module; -@@ -4125,6 +4276,14 @@ void __init omap_hwmod_init(void) - soc_ops.init_clkdm = _init_clkdm; - soc_ops.update_context_lost = _omap4_update_context_lost; - soc_ops.get_context_lost = _omap4_get_context_lost; -+ } else if (soc_is_am43xx()) { -+ soc_ops.enable_module = _omap4_enable_module; -+ soc_ops.disable_module = _omap4_disable_module; -+ soc_ops.wait_target_ready = _omap4_wait_target_ready; -+ soc_ops.assert_hardreset = _omap4_assert_hardreset; -+ soc_ops.deassert_hardreset = _omap4_deassert_hardreset; -+ soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; -+ soc_ops.init_clkdm = _init_clkdm; - } else if (soc_is_am33xx()) { - soc_ops.enable_module = _am33xx_enable_module; - soc_ops.disable_module = _am33xx_disable_module; ---- a/arch/arm/mach-omap2/omap_hwmod_common_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c -@@ -59,6 +59,16 @@ struct omap_hwmod_sysc_fields omap_hwmod - .sidle_shift = SYSC_TYPE3_SIDLEMODE_SHIFT, - }; - -+/** -+ * struct omap_hwmod_sysc_type4 - TYPE4 sysconfig scheme. -+ * Used by some IPs on AM33xx -+ */ -+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type4 = { -+ .sidle_shift = SYSC_TYPE4_SIDLEMODE_SHIFT, -+ .srst_shift = SYSC_TYPE4_SOFTRESET_SHIFT, -+ .autoidle_shift = SYSC_TYPE4_AUTOIDLE_SHIFT, -+}; -+ - struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = { - .manager_count = 2, - .has_framedonetv_irq = 0 ---- a/arch/arm/mach-omap2/omap_hwmod.h -+++ b/arch/arm/mach-omap2/omap_hwmod.h -@@ -41,6 +41,7 @@ struct omap_device; - extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1; - extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; - extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3; -+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type4; - - /* - * OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant -@@ -81,6 +82,16 @@ extern struct omap_hwmod_sysc_fields oma - #define SYSC_TYPE3_MIDLEMODE_SHIFT 2 - #define SYSC_TYPE3_MIDLEMODE_MASK (0x3 << SYSC_TYPE3_MIDLEMODE_SHIFT) - -+/* -+ * OCP SYSCONFIG bit shifts/masks TYPE4. -+ */ -+#define SYSC_TYPE4_SIDLEMODE_SHIFT 2 -+#define SYSC_TYPE4_SIDLEMODE_MASK (0x3 << SYSC_TYPE4_SIDLEMODE_SHIFT) -+#define SYSC_TYPE4_SOFTRESET_SHIFT 1 -+#define SYSC_TYPE4_SOFTRESET_MASK (1 << SYSC_TYPE4_SOFTRESET_SHIFT) -+#define SYSC_TYPE4_AUTOIDLE_SHIFT 0 -+#define SYSC_TYPE4_AUTOIDLE_MASK (1 << SYSC_TYPE4_AUTOIDLE_SHIFT) -+ - /* OCP SYSSTATUS bit shifts/masks */ - #define SYSS_RESETDONE_SHIFT 0 - #define SYSS_RESETDONE_MASK (1 << SYSS_RESETDONE_SHIFT) -@@ -528,6 +539,7 @@ struct omap_hwmod_omap4_prcm { - #define HWMOD_BLOCK_WFI (1 << 10) - #define HWMOD_FORCE_MSTANDBY (1 << 11) - #define HWMOD_SWSUP_SIDLE_ACT (1 << 12) -+#define HWMOD_FORCE_MSTANDBY_REPEATED (1 << 13) - - /* - * omap_hwmod._int_flags definitions -@@ -678,6 +690,11 @@ struct omap_hwmod { - u8 _postsetup_state; - }; - -+struct omap_hwmod_list { -+ struct omap_hwmod *oh; -+ struct list_head oh_list; -+}; -+ - struct omap_hwmod *omap_hwmod_lookup(const char *name); - int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), - void *data); -@@ -731,6 +748,10 @@ int omap_hwmod_no_setup_reset(struct oma - - int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx); - -+int omap_hwmod_force_mstandby_repeated(void); -+int omap_hwmod_enable_force_mstandby_repeated(struct omap_hwmod *oh); -+int omap_hwmod_disable_force_mstandby_repeated(struct omap_hwmod *oh); -+ - extern void __init omap_hwmod_init(void); - - const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh); ---- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c -+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c -@@ -56,6 +56,7 @@ - #include "omap4-sar-layout.h" - #include "pm.h" - #include "prcm_mpu44xx.h" -+#include "prcm_mpu54xx.h" - #include "prminst44xx.h" - #include "prcm44xx.h" - #include "prm44xx.h" -@@ -84,11 +85,13 @@ struct cpu_pm_ops { - int (*finish_suspend)(unsigned long cpu_state); - void (*resume)(void); - void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state); -+ void (*hotplug_restart)(void); - }; - - static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); - static struct powerdomain *mpuss_pd; - static void __iomem *sar_base; -+static u32 cpu_context_offset; - - static int default_finish_suspend(unsigned long cpu_state) - { -@@ -106,6 +109,7 @@ struct cpu_pm_ops omap_pm_ops = { - .finish_suspend = default_finish_suspend, - .resume = dummy_cpu_resume, - .scu_prepare = dummy_scu_prepare, -+ .hotplug_restart = dummy_cpu_resume, - }; - - /* -@@ -116,7 +120,8 @@ static inline void set_cpu_wakeup_addr(u - { - struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); - -- __raw_writel(addr, pm_info->wkup_sar_addr); -+ if (pm_info->wkup_sar_addr) -+ __raw_writel(addr, pm_info->wkup_sar_addr); - } - - /* -@@ -127,6 +132,9 @@ static void scu_pwrst_prepare(unsigned i - struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); - u32 scu_pwr_st; - -+ if (!pm_info->scu_sar_addr) -+ return; -+ - switch (cpu_state) { - case PWRDM_POWER_RET: - scu_pwr_st = SCU_PM_DORMANT; -@@ -161,14 +169,14 @@ static inline void cpu_clear_prev_logic_ - - if (cpu_id) { - reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST, -- OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); -+ cpu_context_offset); - omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST, -- OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); -+ cpu_context_offset); - } else { - reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST, -- OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); -+ cpu_context_offset); - omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST, -- OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); -+ cpu_context_offset); - } - } - -@@ -179,7 +187,8 @@ static void l2x0_pwrst_prepare(unsigned - { - struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); - -- __raw_writel(save_state, pm_info->l2x0_sar_addr); -+ if (pm_info->l2x0_sar_addr) -+ __raw_writel(save_state, pm_info->l2x0_sar_addr); - } - - /* -@@ -235,6 +244,8 @@ int omap4_enter_lowpower(unsigned int cp - save_state = 1; - break; - case PWRDM_POWER_RET: -+ save_state = 0; -+ break; - default: - /* - * CPUx CSWR is invalid hardware state. Also CPUx OSWR -@@ -304,7 +315,7 @@ int omap4_hotplug_cpu(unsigned int cpu, - - pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); - pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); -- set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); -+ set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart)); - omap_pm_ops.scu_prepare(cpu, power_state); - - /* -@@ -320,11 +331,26 @@ int omap4_hotplug_cpu(unsigned int cpu, - - - /* -+ * Enable Mercury Fast HG retention mode by default. -+ */ -+static void enable_mercury_retention_mode(void) -+{ -+ u32 reg; -+ -+ reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST, -+ OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET); -+ reg |= BIT(24) | BIT(25); -+ omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST, -+ OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET); -+} -+ -+/* - * Initialise OMAP4 MPUSS - */ - int __init omap4_mpuss_init(void) - { - struct omap4_cpu_pm_info *pm_info; -+ u32 cpu_wakeup_addr = 0; - - if (omap_rev() == OMAP4430_REV_ES1_0) { - WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); -@@ -334,10 +360,16 @@ int __init omap4_mpuss_init(void) - sar_base = omap4_get_sar_ram_base(); - - /* Initilaise per CPU PM information */ -+ if (cpu_is_omap44xx()) -+ cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET; -+ else if (soc_is_omap54xx()) -+ cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET; - pm_info = &per_cpu(omap4_pm_info, 0x0); -- pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; -- pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET; -- pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0; -+ if (sar_base) { -+ pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; -+ pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr; -+ pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0; -+ } - pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm"); - if (!pm_info->pwrdm) { - pr_err("Lookup failed for CPU0 pwrdm\n"); -@@ -351,14 +383,17 @@ int __init omap4_mpuss_init(void) - /* Initialise CPU0 power domain state to ON */ - pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); - -+ if (cpu_is_omap44xx()) -+ cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET; -+ else if (soc_is_omap54xx()) -+ cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET; -+ - pm_info = &per_cpu(omap4_pm_info, 0x1); -- pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; -- pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; -- pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; -- if (cpu_is_omap446x()) -- pm_info->secondary_startup = omap4460_secondary_startup; -- else -- pm_info->secondary_startup = omap4_secondary_startup; -+ if (sar_base) { -+ pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; -+ pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr; -+ pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; -+ } - - pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); - if (!pm_info->pwrdm) { -@@ -382,19 +417,32 @@ int __init omap4_mpuss_init(void) - mpuss_clear_prev_logic_pwrst(); - - /* Save device type on scratchpad for low level code to use */ -- if (omap_type() != OMAP2_DEVICE_TYPE_GP) -- __raw_writel(1, sar_base + OMAP_TYPE_OFFSET); -- else -- __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); -+ if (sar_base) { -+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) -+ __raw_writel(1, sar_base + OMAP_TYPE_OFFSET); -+ else -+ __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); - -- save_l2x0_context(); -+ save_l2x0_context(); -+ } - - if (cpu_is_omap44xx()) { - omap_pm_ops.finish_suspend = omap4_finish_suspend; -+ omap_pm_ops.hotplug_restart = omap4_secondary_startup; - omap_pm_ops.resume = omap4_cpu_resume; - omap_pm_ops.scu_prepare = scu_pwrst_prepare; -+ cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET; -+ } else if (soc_is_omap54xx() || soc_is_dra7xx()) { -+ omap_pm_ops.finish_suspend = omap5_finish_suspend; -+ omap_pm_ops.hotplug_restart = omap5_secondary_startup; -+ omap_pm_ops.resume = omap5_cpu_resume; -+ cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET; -+ enable_mercury_retention_mode(); - } - -+ if (cpu_is_omap446x()) -+ omap_pm_ops.hotplug_restart = omap4460_secondary_startup; -+ - return 0; - } - ---- a/arch/arm/mach-omap2/omap-secure.h -+++ b/arch/arm/mach-omap2/omap-secure.h -@@ -34,6 +34,10 @@ - #define OMAP4_HAL_SAVEHW_INDEX 0x1b - #define OMAP4_HAL_SAVEALL_INDEX 0x1c - #define OMAP4_HAL_SAVEGIC_INDEX 0x1d -+#define OMAP5_HAL_SAVESECURERAM_INDEX 0x1c -+#define OMAP5_HAL_SAVEHW_INDEX 0x1d -+#define OMAP5_HAL_SAVEALL_INDEX 0x1e -+#define OMAP5_HAL_SAVEGIC_INDEX 0x1f - - /* Secure Monitor mode APIs */ - #define OMAP4_MON_SCU_PWR_INDEX 0x108 -@@ -41,6 +45,13 @@ - #define OMAP4_MON_L2X0_CTRL_INDEX 0x102 - #define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 - #define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 -+#define OMAP5_MON_CACHES_CLEAN_INDEX 0x103 -+#define OMAP5_MON_AUX_CTRL_INDEX 0x107 -+#define OMAP5_MON_L2AUX_CTRL_INDEX 0x104 -+ -+#define OMAP5_MON_AMBA_IF_INDEX 0x108 -+ -+#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 - - /* Secure PPA(Primary Protected Application) APIs */ - #define OMAP4_PPA_L2_POR_INDEX 0x23 ---- a/arch/arm/mach-omap2/omap-smp.c -+++ b/arch/arm/mach-omap2/omap-smp.c -@@ -41,6 +41,8 @@ - - u16 pm44xx_errata; - -+extern unsigned long arch_timer_freq; -+ - /* SCU base address */ - static void __iomem *scu_base; - -@@ -66,6 +68,13 @@ static void omap4_secondary_init(unsigne - 4, 0, 0, 0, 0, 0); - - /* -+ * Configure the CNTFRQ register for the secondary cpu's which -+ * indicates the frequency of the cpu local timers. -+ */ -+ if (soc_is_omap54xx() || soc_is_dra7xx()) -+ omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); -+ -+ /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); ---- a/arch/arm/mach-omap2/omap-wakeupgen.c -+++ b/arch/arm/mach-omap2/omap-wakeupgen.c -@@ -33,8 +33,11 @@ - #include "omap4-sar-layout.h" - #include "common.h" - --#define MAX_NR_REG_BANKS 5 --#define MAX_IRQS 160 -+/* maximum value correspond to that of AM43x */ -+#define MAX_NR_REG_BANKS 7 -+#define MAX_IRQS 224 -+#define DEFAULT_NR_REG_BANKS 5 -+#define DEFAULT_IRQS 160 - #define WKG_MASK_ALL 0x00000000 - #define WKG_UNMASK_ALL 0xffffffff - #define CPU_ENA_OFFSET 0x400 -@@ -47,9 +50,9 @@ static void __iomem *wakeupgen_base; - static void __iomem *sar_base; - static DEFINE_RAW_SPINLOCK(wakeupgen_lock); - static unsigned int irq_target_cpu[MAX_IRQS]; --static unsigned int irq_banks = MAX_NR_REG_BANKS; --static unsigned int max_irqs = MAX_IRQS; --static unsigned int omap_secure_apis; -+static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; -+static unsigned int max_irqs = DEFAULT_IRQS; -+static unsigned int omap_secure_apis, secure_api_index; - - /* - * Static helper functions. -@@ -314,7 +317,7 @@ static void irq_sar_clear(void) - static void irq_save_secure_context(void) - { - u32 ret; -- ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, -+ ret = omap_secure_dispatcher(secure_api_index, - FLAG_START_CRITICAL, - 0, 0, 0, 0, 0); - if (ret != API_HAL_RET_VALUE_OK) -@@ -376,8 +379,8 @@ static struct notifier_block irq_notifie - - static void __init irq_pm_init(void) - { -- /* FIXME: Remove this when MPU OSWR support is added */ -- if (!soc_is_omap54xx()) -+ /* No OFF mode support on dra7xx */ -+ if (!soc_is_dra7xx()) - cpu_pm_register_notifier(&irq_notifier_block); - } - #else -@@ -402,6 +405,8 @@ int __init omap_wakeupgen_init(void) - { - int i; - unsigned int boot_cpu = smp_processor_id(); -+ u32 val; -+ bool am43x = soc_is_am43xx() ? true : false; - - /* Not supported on OMAP4 ES1.0 silicon */ - if (omap_rev() == OMAP4430_REV_ES1_0) { -@@ -418,12 +423,19 @@ int __init omap_wakeupgen_init(void) - irq_banks = OMAP4_NR_BANKS; - max_irqs = OMAP4_NR_IRQS; - omap_secure_apis = 1; -+ secure_api_index = OMAP4_HAL_SAVEGIC_INDEX; -+ } else if (soc_is_omap54xx()) { -+ secure_api_index = OMAP5_HAL_SAVEGIC_INDEX; -+ } else if (am43x) { -+ irq_banks = MAX_NR_REG_BANKS; -+ max_irqs = MAX_IRQS; - } - - /* Clear all IRQ bitmasks at wakeupGen level */ - for (i = 0; i < irq_banks; i++) { - wakeupgen_writel(0, i, CPU0_ID); -- wakeupgen_writel(0, i, CPU1_ID); -+ if (!am43x) -+ wakeupgen_writel(0, i, CPU1_ID); - } - - /* -@@ -443,6 +455,19 @@ int __init omap_wakeupgen_init(void) - for (i = 0; i < max_irqs; i++) - irq_target_cpu[i] = boot_cpu; - -+ /* -+ * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE -+ * 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. -+ * 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode -+ * independently. -+ * This needs to be set one time thanks to always ON domain. -+ */ -+ if (soc_is_omap54xx()) { -+ val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE); -+ val |= BIT(5); -+ omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val); -+ } -+ - irq_hotplug_init(); - irq_pm_init(); - ---- a/arch/arm/mach-omap2/omap-wakeupgen.h -+++ b/arch/arm/mach-omap2/omap-wakeupgen.h -@@ -27,6 +27,7 @@ - #define OMAP_WKG_ENB_E_1 0x420 - #define OMAP_AUX_CORE_BOOT_0 0x800 - #define OMAP_AUX_CORE_BOOT_1 0x804 -+#define OMAP_AMBA_IF_MODE 0x80c - #define OMAP_PTMSYNCREQ_MASK 0xc00 - #define OMAP_PTMSYNCREQ_EN 0xc04 - #define OMAP_TIMESTAMPCYCLELO 0xc08 ---- a/arch/arm/mach-omap2/opp.c -+++ b/arch/arm/mach-omap2/opp.c -@@ -17,6 +17,7 @@ - * GNU General Public License for more details. - */ - #include <linux/module.h> -+#include <linux/of.h> - #include <linux/opp.h> - #include <linux/cpu.h> - -@@ -40,6 +41,9 @@ int __init omap_init_opp_table(struct om - { - int i, r; - -+ if (of_have_populated_dt()) -+ return -EINVAL; -+ - if (!opp_def || !opp_def_size) { - pr_err("%s: invalid params!\n", __func__); - return -EINVAL; ---- /dev/null -+++ b/arch/arm/mach-omap2/pm33xx.c -@@ -0,0 +1,387 @@ -+/* -+ * AM33XX Power Management Routines -+ * -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * Vaibhav Bedia <vaibhav.bedia@ti.com> -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/cpu.h> -+#include <linux/err.h> -+#include <linux/firmware.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <linux/sched.h> -+#include <linux/suspend.h> -+#include <linux/completion.h> -+#include <linux/module.h> -+#include <linux/interrupt.h> -+#include <linux/ti_emif.h> -+#include <linux/omap-mailbox.h> -+ -+#include <asm/suspend.h> -+#include <asm/proc-fns.h> -+#include <asm/sizes.h> -+#include <asm/fncpy.h> -+#include <asm/system_misc.h> -+ -+#include "pm.h" -+#include "cm33xx.h" -+#include "pm33xx.h" -+#include "common.h" -+#include "clockdomain.h" -+#include "powerdomain.h" -+#include "soc.h" -+#include "sram.h" -+ -+static void __iomem *am33xx_emif_base; -+static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm; -+static struct clockdomain *gfx_l4ls_clkdm; -+static struct clockdomain *l3s_clkdm, *l4fw_clkdm, *clk_24mhz_clkdm; -+ -+static struct am33xx_pm_context *am33xx_pm; -+ -+static DECLARE_COMPLETION(am33xx_pm_sync); -+ -+static void (*am33xx_do_wfi_sram)(struct am33xx_suspend_params *); -+ -+static struct am33xx_suspend_params susp_params; -+ -+#ifdef CONFIG_SUSPEND -+ -+static int am33xx_do_sram_idle(long unsigned int unused) -+{ -+ am33xx_do_wfi_sram(&susp_params); -+ return 0; -+} -+ -+static int am33xx_pm_suspend(unsigned int state) -+{ -+ int i, ret = 0; -+ int status = 0; -+ struct wkup_m3_wakeup_src wakeup_src; -+ -+ if (state == PM_SUSPEND_STANDBY) { -+ clkdm_wakeup(l3s_clkdm); -+ clkdm_wakeup(l4fw_clkdm); -+ clkdm_wakeup(clk_24mhz_clkdm); -+ } -+ -+ /* Try to put GFX to sleep */ -+ omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF); -+ -+ ret = cpu_suspend(0, am33xx_do_sram_idle); -+ -+ status = pwrdm_read_pwrst(gfx_pwrdm); -+ if (status != PWRDM_POWER_OFF) -+ pr_err("PM: GFX domain did not transition\n"); -+ -+ /* -+ * BUG: GFX_L4LS clock domain needs to be woken up to -+ * ensure thet L4LS clock domain does not get stuck in transition -+ * If that happens L3 module does not get disabled, thereby leading -+ * to PER power domain transition failing -+ */ -+ clkdm_wakeup(gfx_l4ls_clkdm); -+ clkdm_sleep(gfx_l4ls_clkdm); -+ -+ if (ret) { -+ pr_err("PM: Kernel suspend failure\n"); -+ } else { -+ i = wkup_m3_pm_status(); -+ switch (i) { -+ case 0: -+ pr_info("PM: Successfully put all powerdomains to target state\n"); -+ -+ /* -+ * The PRCM registers on AM335x do not contain -+ * previous state information like those present on -+ * OMAP4 so we must manually indicate transition so -+ * state counters are properly incremented -+ */ -+ pwrdm_post_transition(mpu_pwrdm); -+ pwrdm_post_transition(per_pwrdm); -+ break; -+ case 1: -+ pr_err("PM: Could not transition all powerdomains to target state\n"); -+ ret = -1; -+ break; -+ default: -+ pr_err("PM: CM3 returned unknown result = %d\n", i); -+ ret = -1; -+ } -+ /* print the wakeup reason */ -+ wakeup_src = wkup_m3_wake_src(); -+ -+ pr_info("PM: Wakeup source %s\n", wakeup_src.src); -+ } -+ -+ return ret; -+} -+ -+static int am33xx_pm_enter(suspend_state_t suspend_state) -+{ -+ int ret = 0; -+ -+ switch (suspend_state) { -+ case PM_SUSPEND_STANDBY: -+ case PM_SUSPEND_MEM: -+ ret = am33xx_pm_suspend(suspend_state); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+ -+static void am33xx_m3_state_machine_reset(void) -+{ -+ int i; -+ -+ am33xx_pm->ipc.reg1 = IPC_CMD_RESET; -+ -+ wkup_m3_pm_set_cmd(&am33xx_pm->ipc); -+ -+ am33xx_pm->state = M3_STATE_MSG_FOR_RESET; -+ -+ if (!wkup_m3_ping()) { -+ i = wait_for_completion_timeout(&am33xx_pm_sync, -+ msecs_to_jiffies(500)); -+ if (!i) { -+ WARN(1, "PM: MPU<->CM3 sync failure\n"); -+ am33xx_pm->state = M3_STATE_UNKNOWN; -+ } -+ } else { -+ pr_warn("PM: Unable to ping CM3\n"); -+ } -+} -+ -+static int am33xx_pm_begin(suspend_state_t state) -+{ -+ int i; -+ -+ cpu_idle_poll_ctrl(true); -+ -+ switch (state) { -+ case PM_SUSPEND_MEM: -+ am33xx_pm->ipc.reg1 = IPC_CMD_DS0; -+ break; -+ case PM_SUSPEND_STANDBY: -+ am33xx_pm->ipc.reg1 = IPC_CMD_STANDBY; -+ break; -+ } -+ -+ am33xx_pm->ipc.reg2 = DS_IPC_DEFAULT; -+ am33xx_pm->ipc.reg3 = DS_IPC_DEFAULT; -+ -+ wkup_m3_pm_set_cmd(&am33xx_pm->ipc); -+ -+ am33xx_pm->state = M3_STATE_MSG_FOR_LP; -+ -+ if (!wkup_m3_ping()) { -+ i = wait_for_completion_timeout(&am33xx_pm_sync, -+ msecs_to_jiffies(500)); -+ if (!i) { -+ WARN(1, "PM: MPU<->CM3 sync failure\n"); -+ return -1; -+ } -+ } else { -+ pr_warn("PM: Unable to ping CM3\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void am33xx_pm_end(void) -+{ -+ am33xx_m3_state_machine_reset(); -+ -+ cpu_idle_poll_ctrl(false); -+ -+ return; -+} -+ -+static int am33xx_pm_valid(suspend_state_t state) -+{ -+ switch (state) { -+ case PM_SUSPEND_STANDBY: -+ case PM_SUSPEND_MEM: -+ return 1; -+ default: -+ return 0; -+ } -+} -+ -+static const struct platform_suspend_ops am33xx_pm_ops = { -+ .begin = am33xx_pm_begin, -+ .end = am33xx_pm_end, -+ .enter = am33xx_pm_enter, -+ .valid = am33xx_pm_valid, -+}; -+#endif /* CONFIG_SUSPEND */ -+ -+static void am33xx_txev_handler(void) -+{ -+ switch (am33xx_pm->state) { -+ case M3_STATE_RESET: -+ am33xx_pm->state = M3_STATE_INITED; -+ complete(&am33xx_pm_sync); -+ break; -+ case M3_STATE_MSG_FOR_RESET: -+ am33xx_pm->state = M3_STATE_INITED; -+ complete(&am33xx_pm_sync); -+ break; -+ case M3_STATE_MSG_FOR_LP: -+ complete(&am33xx_pm_sync); -+ break; -+ case M3_STATE_UNKNOWN: -+ pr_warn("PM: Unknown CM3 State\n"); -+ } -+ -+ return; -+} -+ -+static void am33xx_m3_fw_ready_cb(void) -+{ -+ int ret = 0; -+ -+ ret = wkup_m3_prepare(); -+ if (ret) { -+ pr_err("PM: Could not prepare WKUP_M3\n"); -+ return; -+ } -+ -+ ret = wait_for_completion_timeout(&am33xx_pm_sync, -+ msecs_to_jiffies(500)); -+ -+ if (WARN(ret == 0, "PM: MPU<->CM3 sync failure\n")) -+ return; -+ -+ am33xx_pm->ver = wkup_m3_fw_version_read(); -+ -+ if (am33xx_pm->ver == M3_VERSION_UNKNOWN || -+ am33xx_pm->ver < M3_BASELINE_VERSION) { -+ pr_warn("PM: CM3 Firmware Version %x not supported\n", -+ am33xx_pm->ver); -+ return; -+ } else { -+ pr_info("PM: CM3 Firmware Version = 0x%x\n", -+ am33xx_pm->ver); -+ } -+ -+#ifdef CONFIG_SUSPEND -+ suspend_set_ops(&am33xx_pm_ops); -+#endif /* CONFIG_SUSPEND */ -+} -+ -+static struct wkup_m3_ops am33xx_wkup_m3_ops = { -+ .txev_handler = am33xx_txev_handler, -+ .firmware_loaded = am33xx_m3_fw_ready_cb, -+}; -+ -+/* -+ * Push the minimal suspend-resume code to SRAM -+ */ -+void am33xx_push_sram_idle(void) -+{ -+ am33xx_do_wfi_sram = (void *)omap_sram_push -+ (am33xx_do_wfi, am33xx_do_wfi_sz); -+} -+ -+static int __init am33xx_map_emif(void) -+{ -+ am33xx_emif_base = ioremap(AM33XX_EMIF_BASE, SZ_32K); -+ -+ if (!am33xx_emif_base) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+int __init am33xx_pm_init(void) -+{ -+ int ret; -+ u32 temp; -+ -+ if (!soc_is_am33xx()) -+ return -ENODEV; -+ -+ gfx_pwrdm = pwrdm_lookup("gfx_pwrdm"); -+ per_pwrdm = pwrdm_lookup("per_pwrdm"); -+ mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); -+ -+ gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm"); -+ l3s_clkdm = clkdm_lookup("l3s_clkdm"); -+ l4fw_clkdm = clkdm_lookup("l4fw_clkdm"); -+ clk_24mhz_clkdm = clkdm_lookup("clk_24mhz_clkdm"); -+ -+ if ((!gfx_pwrdm) || (!per_pwrdm) || (!mpu_pwrdm) || (!gfx_l4ls_clkdm) || -+ (!l3s_clkdm) || (!l4fw_clkdm) || (!clk_24mhz_clkdm)) { -+ ret = -ENODEV; -+ goto err; -+ } -+ -+ am33xx_pm = kzalloc(sizeof(*am33xx_pm), GFP_KERNEL); -+ if (!am33xx_pm) { -+ pr_err("Memory allocation failed\n"); -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ ret = am33xx_map_emif(); -+ if (ret) { -+ pr_err("PM: Could not ioremap EMIF\n"); -+ goto err; -+ } -+ -+ /* Determine Memory Type */ -+ temp = readl(am33xx_emif_base + EMIF_SDRAM_CONFIG); -+ temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT; -+ /* Parameters to pass to aseembly code */ -+ susp_params.emif_addr_virt = am33xx_emif_base; -+ susp_params.dram_sync = am33xx_dram_sync; -+ susp_params.mem_type = temp; -+ am33xx_pm->ipc.reg4 = temp; -+ -+ (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); -+ -+ /* CEFUSE domain can be turned off post bootup */ -+ cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm"); -+ if (cefuse_pwrdm) -+ omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF); -+ else -+ pr_err("PM: Failed to get cefuse_pwrdm\n"); -+ -+ am33xx_pm->state = M3_STATE_RESET; -+ -+ wkup_m3_set_ops(&am33xx_wkup_m3_ops); -+ -+ /* m3 may have already loaded but ops were not set yet, -+ * manually invoke */ -+ -+ if (wkup_m3_is_valid()) -+ am33xx_m3_fw_ready_cb(); -+ -+ /* Physical resume address to be used by ROM code */ -+ am33xx_pm->ipc.reg0 = (AM33XX_OCMC_END - -+ am33xx_do_wfi_sz + am33xx_resume_offset + 0x4); -+ -+ return 0; -+ -+err: -+ kfree(am33xx_pm); -+ return ret; -+} ---- /dev/null -+++ b/arch/arm/mach-omap2/pm33xx.h -@@ -0,0 +1,77 @@ -+/* -+ * AM33XX Power Management Routines -+ * -+ * Copyright (C) 2012 Texas Instruments Inc. -+ * Vaibhav Bedia <vaibhav.bedia@ti.com> -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef __ARCH_ARM_MACH_OMAP2_PM33XX_H -+#define __ARCH_ARM_MACH_OMAP2_PM33XX_H -+ -+#include "wkup_m3.h" -+ -+#ifndef __ASSEMBLER__ -+ -+struct am33xx_pm_context { -+ struct am33xx_ipc_regs ipc; -+ struct firmware *firmware; -+ struct omap_mbox *mbox; -+ u8 state; -+ u32 ver; -+}; -+ -+/* -+ * Params passed to suspend routine -+ * -+ * These are used to load into registers by suspend code, -+ * entries here must always be in sync with the suspend code -+ * in arm/mach-omap2/sleep33xx.S -+ */ -+struct am33xx_suspend_params { -+ void __iomem *emif_addr_virt; -+ u32 mem_type; -+ void __iomem *dram_sync; -+}; -+ -+ -+#endif -+ -+#define IPC_CMD_DS0 0x4 -+#define IPC_CMD_STANDBY 0xc -+#define IPC_CMD_RESET 0xe -+#define DS_IPC_DEFAULT 0xffffffff -+#define M3_VERSION_UNKNOWN 0x0000ffff -+#define M3_BASELINE_VERSION 0x21 -+ -+#define M3_STATE_UNKNOWN 0 -+#define M3_STATE_RESET 1 -+#define M3_STATE_INITED 2 -+#define M3_STATE_MSG_FOR_LP 3 -+#define M3_STATE_MSG_FOR_RESET 4 -+ -+#define AM33XX_OCMC_END 0x40310000 -+#define AM33XX_EMIF_BASE 0x4C000000 -+ -+#define MEM_TYPE_DDR2 2 -+ -+/* -+ * 9-4 = VTT GPIO PIN (6 Bits) -+ * 3 = VTT Status (1 Bit) -+ * 2-0 = Memory Type (2 Bits) -+*/ -+#define MEM_TYPE_SHIFT (0x0) -+#define MEM_TYPE_MASK (0x7 << 0) -+#define VTT_STAT_SHIFT (0x3) -+#define VTT_STAT_MASK (0x1 << 3) -+#define VTT_GPIO_PIN_SHIFT (0x4) -+#define VTT_GPIO_PIN_MASK (0x2f << 4) -+ -+#endif ---- a/arch/arm/mach-omap2/pm44xx.c -+++ b/arch/arm/mach-omap2/pm44xx.c -@@ -35,6 +35,7 @@ struct power_state { - }; - - static LIST_HEAD(pwrst_list); -+u32 cpu_suspend_state; - - #ifdef CONFIG_SUSPEND - static int omap4_pm_suspend(void) -@@ -52,7 +53,10 @@ static int omap4_pm_suspend(void) - /* Set targeted power domain states by suspend */ - list_for_each_entry(pwrst, &pwrst_list, node) { - omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); -- pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); -+ if (!strcmp(pwrst->pwrdm->name, "mpu_pwrdm")) -+ pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_ON); -+ else -+ pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); - } - - /* -@@ -64,7 +68,7 @@ static int omap4_pm_suspend(void) - * domain CSWR is not supported by hardware. - * More details can be found in OMAP4430 TRM section 4.3.4.2. - */ -- omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF); -+ omap4_enter_lowpower(cpu_id, cpu_suspend_state); - - /* Restore next powerdomain state */ - list_for_each_entry(pwrst, &pwrst_list, node) { -@@ -199,6 +203,32 @@ static inline int omap4_init_static_deps - } - - /** -+ * omap5_dra7_init_static_deps - Init static clkdm dependencies on OMAP5 -+ * and DRA7 -+ * -+ * The dynamic dependency between MPUSS -> EMIF is broken and has -+ * not worked as expected. The hardware recommendation is to -+ * enable static dependencies for these to avoid system -+ * lock ups or random crashes. -+ */ -+static inline int omap5_dra7_init_static_deps(void) -+{ -+ struct clockdomain *mpuss_clkdm, *emif_clkdm; -+ int ret; -+ -+ mpuss_clkdm = clkdm_lookup("mpu_clkdm"); -+ emif_clkdm = clkdm_lookup("emif_clkdm"); -+ if (!mpuss_clkdm || !emif_clkdm) -+ return -EINVAL; -+ -+ ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); -+ if (ret) -+ pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n"); -+ -+ return ret; -+} -+ -+/** - * omap4_pm_init - Init routine for OMAP4+ devices - * - * Initializes all powerdomain and clockdomain target states -@@ -222,10 +252,14 @@ int __init omap4_pm_init(void) - goto err2; - } - -- if (cpu_is_omap44xx()) { -+ if (cpu_is_omap44xx()) - ret = omap4_init_static_deps(); -- if (ret) -- goto err2; -+ else if (soc_is_omap54xx() || soc_is_dra7xx()) -+ ret = omap5_dra7_init_static_deps(); -+ -+ if (ret) { -+ pr_err("Failed to initialise static dependencies.\n"); -+ goto err2; - } - - ret = omap4_mpuss_init(); -@@ -246,6 +280,11 @@ int __init omap4_pm_init(void) - if (cpu_is_omap44xx()) - omap4_idle_init(); - -+ if (soc_is_dra7xx()) -+ cpu_suspend_state = PWRDM_POWER_RET; -+ else -+ cpu_suspend_state = PWRDM_POWER_OFF; -+ - err2: - return ret; - } ---- a/arch/arm/mach-omap2/pm.c -+++ b/arch/arm/mach-omap2/pm.c -@@ -266,7 +266,12 @@ static void __init omap4_init_voltages(v - - static inline void omap_init_cpufreq(void) - { -- struct platform_device_info devinfo = { .name = "omap-cpufreq", }; -+ struct platform_device_info devinfo = { }; -+ -+ if (!of_have_populated_dt()) -+ devinfo.name = "omap-cpufreq"; -+ else -+ devinfo.name = "cpufreq-cpu0"; - platform_device_register_full(&devinfo); - } - -@@ -300,13 +305,16 @@ int __init omap2_common_pm_late_init(voi - /* Smartreflex device init */ - omap_devinit_smartreflex(); - -- /* cpufreq dummy device instantiation */ -- omap_init_cpufreq(); - } - --#ifdef CONFIG_SUSPEND -- suspend_set_ops(&omap_pm_ops); --#endif -+ /* cpufreq dummy device instantiation */ -+ omap_init_cpufreq(); - - return 0; - } -+ -+void __init omap2_common_suspend_init(void) -+{ -+ suspend_set_ops(&omap_pm_ops); -+} -+ ---- a/arch/arm/mach-omap2/pm.h -+++ b/arch/arm/mach-omap2/pm.h -@@ -82,6 +82,11 @@ extern unsigned int omap3_do_wfi_sz; - /* ... and its pointer from SRAM after copy */ - extern void (*omap3_do_wfi_sram)(void); - -+/* am33xx_do_wfi function pointer and size, for copy to SRAM */ -+extern void am33xx_do_wfi(void); -+extern unsigned int am33xx_do_wfi_sz; -+extern unsigned int am33xx_resume_offset; -+ - /* save_secure_ram_context function pointer and size, for copy to SRAM */ - extern int save_secure_ram_context(u32 *addr); - extern unsigned int save_secure_ram_context_sz; ---- a/arch/arm/mach-omap2/powerdomain.h -+++ b/arch/arm/mach-omap2/powerdomain.h -@@ -254,6 +254,7 @@ extern void omap242x_powerdomains_init(v - extern void omap243x_powerdomains_init(void); - extern void omap3xxx_powerdomains_init(void); - extern void am33xx_powerdomains_init(void); -+extern void am43xx_powerdomains_init(void); - extern void omap44xx_powerdomains_init(void); - extern void omap54xx_powerdomains_init(void); - extern void dra7xx_powerdomains_init(void); ---- /dev/null -+++ b/arch/arm/mach-omap2/powerdomains43xx_data.c -@@ -0,0 +1,145 @@ -+/* -+ * AM43xx Power domains framework -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * This file is made by modifying the file generated automatically -+ * from the OMAP hardware databases. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/init.h> -+ -+#include "powerdomain.h" -+ -+#include "prcm-common.h" -+#include "prcm44xx.h" -+#include "prcm43xx.h" -+ -+static struct powerdomain gfx_43xx_pwrdm = { -+ .name = "gfx_pwrdm", -+ .voltdm = { .name = "core" }, -+ .prcm_offs = AM43XX_PRM_GFX_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_OFF_ON, -+ .banks = 1, -+ .pwrsts_mem_ret = { -+ [0] = PWRSTS_OFF_RET, /* gfx_mem */ -+ }, -+ .pwrsts_mem_on = { -+ [0] = PWRSTS_ON, /* gfx_mem */ -+ }, -+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, -+}; -+ -+static struct powerdomain mpu_43xx_pwrdm = { -+ .name = "mpu_pwrdm", -+ .voltdm = { .name = "mpu" }, -+ .prcm_offs = AM43XX_PRM_MPU_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_OFF_RET_ON, -+ .pwrsts_logic_ret = PWRSTS_OFF_RET, -+ .banks = 3, -+ .pwrsts_mem_ret = { -+ [0] = PWRSTS_OFF_RET, /* mpu_l1 */ -+ [1] = PWRSTS_OFF_RET, /* mpu_l2 */ -+ [2] = PWRSTS_OFF_RET, /* mpu_ram */ -+ }, -+ .pwrsts_mem_on = { -+ [0] = PWRSTS_ON, /* mpu_l1 */ -+ [1] = PWRSTS_ON, /* mpu_l2 */ -+ [2] = PWRSTS_ON, /* mpu_ram */ -+ }, -+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, -+}; -+ -+static struct powerdomain rtc_43xx_pwrdm = { -+ .name = "rtc_pwrdm", -+ .voltdm = { .name = "rtc" }, -+ .prcm_offs = AM43XX_PRM_RTC_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_ON, -+}; -+ -+static struct powerdomain wkup_43xx_pwrdm = { -+ .name = "wkup_pwrdm", -+ .voltdm = { .name = "core" }, -+ .prcm_offs = AM43XX_PRM_WKUP_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_ON, -+ .banks = 1, -+ .pwrsts_mem_ret = { -+ [0] = PWRSTS_OFF, /* debugss_mem */ -+ }, -+ .pwrsts_mem_on = { -+ [0] = PWRSTS_ON, /* debugss_mem */ -+ }, -+}; -+ -+static struct powerdomain tamper_43xx_pwrdm = { -+ .name = "tamper_pwrdm", -+ .voltdm = { .name = "tamper" }, -+ .prcm_offs = AM43XX_PRM_TAMPER_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_ON, -+}; -+ -+static struct powerdomain cefuse_43xx_pwrdm = { -+ .name = "cefuse_pwrdm", -+ .voltdm = { .name = "core" }, -+ .prcm_offs = AM43XX_PRM_CEFUSE_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, -+}; -+ -+static struct powerdomain per_43xx_pwrdm = { -+ .name = "per_pwrdm", -+ .voltdm = { .name = "core" }, -+ .prcm_offs = AM43XX_PRM_PER_INST, -+ .prcm_partition = AM43XX_PRM_PARTITION, -+ .pwrsts = PWRSTS_OFF_RET_ON, -+ .pwrsts_logic_ret = PWRSTS_OFF_RET, -+ .banks = 4, -+ .pwrsts_mem_ret = { -+ [0] = PWRSTS_OFF_RET, /* icss_mem */ -+ [1] = PWRSTS_OFF_RET, /* per_mem */ -+ [2] = PWRSTS_OFF_RET, /* ram1_mem */ -+ [3] = PWRSTS_OFF_RET, /* ram2_mem */ -+ }, -+ .pwrsts_mem_on = { -+ [0] = PWRSTS_OFF_RET, /* icss_mem */ -+ [1] = PWRSTS_ON, /* per_mem */ -+ [2] = PWRSTS_OFF_RET, /* ram1_mem */ -+ [3] = PWRSTS_OFF_RET, /* ram2_mem */ -+ }, -+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, -+}; -+ -+static struct powerdomain *powerdomains_am43xx[] __initdata = { -+ &gfx_43xx_pwrdm, -+ &mpu_43xx_pwrdm, -+ &rtc_43xx_pwrdm, -+ &wkup_43xx_pwrdm, -+ &tamper_43xx_pwrdm, -+ &cefuse_43xx_pwrdm, -+ &per_43xx_pwrdm, -+ NULL -+}; -+ -+static int am43xx_check_vcvp(void) -+{ -+ return 0; -+} -+ -+void __init am43xx_powerdomains_init(void) -+{ -+ omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp; -+ pwrdm_register_platform_funcs(&omap4_pwrdm_operations); -+ pwrdm_register_pwrdms(powerdomains_am43xx); -+ pwrdm_complete_init(); -+} ---- /dev/null -+++ b/arch/arm/mach-omap2/prcm43xx.h -@@ -0,0 +1,149 @@ -+/* -+ * AM43x PRCM defines -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H -+#define __ARCH_ARM_MACH_OMAP2_PRCM_43XX_H -+ -+#define AM43XX_PRM_PARTITION 1 -+#define AM43XX_CM_PARTITION 1 -+ -+/* PRM instances */ -+#define AM43XX_PRM_OCP_SOCKET_INST 0x0000 -+#define AM43XX_PRM_MPU_INST 0x0300 -+#define AM43XX_PRM_GFX_INST 0x0400 -+#define AM43XX_PRM_RTC_INST 0x0500 -+#define AM43XX_PRM_TAMPER_INST 0x0600 -+#define AM43XX_PRM_CEFUSE_INST 0x0700 -+#define AM43XX_PRM_PER_INST 0x0800 -+#define AM43XX_PRM_WKUP_INST 0x2000 -+#define AM43XX_PRM_DEVICE_INST 0x4000 -+ -+/* RM RSTCTRL offsets */ -+#define AM43XX_RM_PER_RSTCTRL_OFFSET 0x0010 -+#define AM43XX_RM_GFX_RSTCTRL_OFFSET 0x0010 -+#define AM43XX_RM_WKUP_RSTCTRL_OFFSET 0x0010 -+ -+/* RM RSTST offsets */ -+#define AM43XX_RM_GFX_RSTST_OFFSET 0x0014 -+#define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014 -+ -+/* CM instances */ -+#define AM43XX_CM_WKUP_INST 0x2800 -+#define AM43XX_CM_DEVICE_INST 0x4100 -+#define AM43XX_CM_DPLL_INST 0x4200 -+#define AM43XX_CM_MPU_INST 0x8300 -+#define AM43XX_CM_GFX_INST 0x8400 -+#define AM43XX_CM_RTC_INST 0x8500 -+#define AM43XX_CM_TAMPER_INST 0x8600 -+#define AM43XX_CM_CEFUSE_INST 0x8700 -+#define AM43XX_CM_PER_INST 0x8800 -+ -+/* CD offsets */ -+#define AM43XX_CM_WKUP_L3_AON_CDOFFS 0x0000 -+#define AM43XX_CM_WKUP_L3S_TSC_CDOFFS 0x0100 -+#define AM43XX_CM_WKUP_L4_WKUP_AON_CDOFFS 0x0200 -+#define AM43XX_CM_WKUP_WKUP_CDOFFS 0x0300 -+#define AM43XX_CM_MPU_MPU_CDOFFS 0x0000 -+#define AM43XX_CM_GFX_GFX_L3_CDOFFS 0x0000 -+#define AM43XX_CM_RTC_RTC_CDOFFS 0x0000 -+#define AM43XX_CM_TAMPER_TAMPER_CDOFFS 0x0000 -+#define AM43XX_CM_CEFUSE_CEFUSE_CDOFFS 0x0000 -+#define AM43XX_CM_PER_L3_CDOFFS 0x0000 -+#define AM43XX_CM_PER_L3S_CDOFFS 0x0200 -+#define AM43XX_CM_PER_ICSS_CDOFFS 0x0300 -+#define AM43XX_CM_PER_L4LS_CDOFFS 0x0400 -+#define AM43XX_CM_PER_EMIF_CDOFFS 0x0700 -+#define AM43XX_CM_PER_DSS_CDOFFS 0x0a00 -+#define AM43XX_CM_PER_CPSW_CDOFFS 0x0b00 -+#define AM43XX_CM_PER_OCPWP_L3_CDOFFS 0x0c00 -+ -+/* CLK CTRL offsets */ -+#define AM43XX_CM_PER_UART1_CLKCTRL_OFFSET 0x0580 -+#define AM43XX_CM_PER_UART2_CLKCTRL_OFFSET 0x0588 -+#define AM43XX_CM_PER_UART3_CLKCTRL_OFFSET 0x0590 -+#define AM43XX_CM_PER_UART4_CLKCTRL_OFFSET 0x0598 -+#define AM43XX_CM_PER_UART5_CLKCTRL_OFFSET 0x05a0 -+#define AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET 0x0428 -+#define AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET 0x0430 -+#define AM43XX_CM_PER_ELM_CLKCTRL_OFFSET 0x0468 -+#define AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x0438 -+#define AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x0440 -+#define AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x0448 -+#define AM43XX_CM_PER_GPIO1_CLKCTRL_OFFSET 0x0478 -+#define AM43XX_CM_PER_GPIO2_CLKCTRL_OFFSET 0x0480 -+#define AM43XX_CM_PER_GPIO3_CLKCTRL_OFFSET 0x0488 -+#define AM43XX_CM_PER_I2C1_CLKCTRL_OFFSET 0x04a8 -+#define AM43XX_CM_PER_I2C2_CLKCTRL_OFFSET 0x04b0 -+#define AM43XX_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x04b8 -+#define AM43XX_CM_PER_MMC0_CLKCTRL_OFFSET 0x04c0 -+#define AM43XX_CM_PER_MMC1_CLKCTRL_OFFSET 0x04c8 -+#define AM43XX_CM_PER_DES_CLKCTRL_OFFSET 0x0030 -+#define AM43XX_CM_PER_RNG_CLKCTRL_OFFSET 0x04e0 -+#define AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET 0x0500 -+#define AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET 0x0508 -+#define AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x0528 -+#define AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0530 -+#define AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0538 -+#define AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0540 -+#define AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET 0x0548 -+#define AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET 0x0550 -+#define AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET 0x0558 -+#define AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x0228 -+#define AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0360 -+#define AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x0350 -+#define AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x0358 -+#define AM43XX_CM_WKUP_UART0_CLKCTRL_OFFSET 0x0348 -+#define AM43XX_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0328 -+#define AM43XX_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x0340 -+#define AM43XX_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0368 -+#define AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x0120 -+#define AM43XX_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0338 -+#define AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0220 -+#define AM43XX_CM_RTC_RTC_CLKCTRL_OFFSET 0x0020 -+#define AM43XX_CM_PER_MMC2_CLKCTRL_OFFSET 0x0248 -+#define AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET 0x0258 -+#define AM43XX_CM_PER_USB_OTG_SS0_CLKCTRL_OFFSET 0x0260 -+#define AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET 0x05B8 -+#define AM43XX_CM_PER_USB_OTG_SS1_CLKCTRL_OFFSET 0x0268 -+#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET 0x05C0 -+#define AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET 0x0220 -+#define AM43XX_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0238 -+#define AM43XX_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0240 -+#define AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET 0x0420 -+#define AM43XX_CM_PER_L3_CLKCTRL_OFFSET 0x0020 -+#define AM43XX_CM_PER_TPCC_CLKCTRL_OFFSET 0x0078 -+#define AM43XX_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0080 -+#define AM43XX_CM_PER_TPTC1_CLKCTRL_OFFSET 0x0088 -+#define AM43XX_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0090 -+#define AM43XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0b20 -+#define AM43XX_CM_PER_PRUSS_CLKCTRL_OFFSET 0x0320 -+#define AM43XX_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020 -+#define AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET 0x00a0 -+#define AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020 -+#define AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x0040 -+#define AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x0050 -+#define AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET 0x0058 -+#define AM43XX_CM_PER_AES0_CLKCTRL_OFFSET 0x0028 -+#define AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET 0x0560 -+#define AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET 0x0568 -+#define AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET 0x0570 -+#define AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET 0x0578 -+#define AM43XX_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0230 -+#define AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET 0x0450 -+#define AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET 0x0458 -+#define AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET 0x0460 -+#define AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET 0x0510 -+#define AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET 0x0518 -+#define AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET 0x0520 -+#define AM43XX_CM_PER_GPIO4_CLKCTRL_OFFSET 0x0490 -+#define AM43XX_CM_PER_GPIO5_CLKCTRL_OFFSET 0x0498 -+#define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET 0x0a20 -+ -+#endif ---- a/arch/arm/mach-omap2/prminst44xx.c -+++ b/arch/arm/mach-omap2/prminst44xx.c -@@ -182,12 +182,10 @@ void omap4_prminst_global_warm_sw_reset( - v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, - OMAP4_PRM_RSTCTRL_OFFSET); - v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; -- omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, -- OMAP4430_PRM_DEVICE_INST, -+ omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, dev_inst, - OMAP4_PRM_RSTCTRL_OFFSET); - - /* OCP barrier */ -- v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, -- OMAP4430_PRM_DEVICE_INST, -+ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, - OMAP4_PRM_RSTCTRL_OFFSET); - } ---- /dev/null -+++ b/arch/arm/mach-omap2/sleep33xx.S -@@ -0,0 +1,362 @@ -+/* -+ * Low level suspend code for AM33XX SoCs -+ * -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * Vaibhav Bedia <vaibhav.bedia@ti.com> -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/linkage.h> -+#include <linux/ti_emif.h> -+#include <asm/memory.h> -+#include <asm/assembler.h> -+ -+#include "cm33xx.h" -+#include "pm33xx.h" -+#include "prm33xx.h" -+ -+#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a0 -+#define EMIF_POWER_MGMT_SR_TIMER_MASK 0x00f0 -+ -+#define EMIF_POWER_MGMT_SELF_REFRESH_MODE 0x0200 -+#define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 0x0700 -+#define EMIF_POWER_MGMT_DELAY_PERIOD 0x1000 -+ -+#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003 -+#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002 -+ -+ .text -+ .align 3 -+ -+/* -+ * This routine is executed from internal RAM and expects some -+ * parameters to be passed in r0 _strictly_ in following order: -+ * 1) emif_addr_virt - ioremapped EMIF address -+ * 2) mem_type - 2 -> DDR2, 3-> DDR3 -+ * 3) dram_sync_word - uncached word in SDRAM -+ * -+ * The code loads these values taking r0 value as reference to -+ * the array in registers starting from r0, i.e emif_addr_virt -+ * goes to r1, mem_type goes to r2 and and so on. These are -+ * then saved into memory locations before proceeding with the -+ * sleep sequence and hence registers r0, r1 etc can still be -+ * used in the rest of the sleep code. -+ */ -+ -+ENTRY(am33xx_do_wfi) -+ stmfd sp!, {r4 - r11, lr} @ save registers on stack -+ -+ ldm r0, {r1-r3} @ gather values passed -+ -+ /* Save the values passed */ -+ str r1, emif_addr_virt -+ str r2, mem_type -+ str r3, dram_sync_word -+ -+ /* -+ * Flush all data from the L1 and L2 data cache before disabling -+ * SCTLR.C bit. -+ */ -+ ldr r1, kernel_flush -+ blx r1 -+ -+ /* -+ * Clear the SCTLR.C bit to prevent further data cache -+ * allocation. Clearing SCTLR.C would make all the data accesses -+ * strongly ordered and would not hit the cache. -+ */ -+ mrc p15, 0, r0, c1, c0, 0 -+ bic r0, r0, #(1 << 2) @ Disable the C bit -+ mcr p15, 0, r0, c1, c0, 0 -+ isb -+ -+ /* -+ * Invalidate L1 and L2 data cache. -+ */ -+ ldr r1, kernel_flush -+ blx r1 -+ -+ ldr r0, emif_addr_virt -+ /* Save EMIF configuration */ -+ ldr r1, [r0, #EMIF_SDRAM_CONFIG] -+ str r1, emif_sdcfg_val -+ ldr r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL] -+ str r1, emif_ref_ctrl_val -+ ldr r1, [r0, #EMIF_SDRAM_TIMING_1] -+ str r1, emif_timing1_val -+ ldr r1, [r0, #EMIF_SDRAM_TIMING_2] -+ str r1, emif_timing2_val -+ ldr r1, [r0, #EMIF_SDRAM_TIMING_3] -+ str r1, emif_timing3_val -+ ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ str r1, emif_pmcr_val -+ ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW] -+ str r1, emif_pmcr_shdw_val -+ ldr r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG] -+ str r1, emif_zqcfg_val -+ ldr r1, [r0, #EMIF_DDR_PHY_CTRL_1] -+ str r1, emif_rd_lat_val -+ -+ /* Put SDRAM in self-refresh */ -+ ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ bic r1, r1, #EMIF_POWER_MGMT_SR_TIMER_MASK -+ orr r1, r1, #EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW] -+ -+ ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK -+ orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ -+ ldr r1, dram_sync_word @ a dummy access to DDR as per spec -+ ldr r2, [r1, #0] -+ -+ -+ mov r1, #EMIF_POWER_MGMT_DELAY_PERIOD @ Wait for system -+wait_self_refresh: @ to enter SR -+ subs r1, r1, #1 -+ bne wait_self_refresh -+ -+ /* Disable EMIF */ -+ ldr r1, virt_emif_clkctrl -+ ldr r2, [r1] -+ bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE -+ str r2, [r1] -+ -+ ldr r1, virt_emif_clkctrl -+wait_emif_disable: -+ ldr r2, [r1] -+ ldr r3, module_disabled_val -+ cmp r2, r3 -+ bne wait_emif_disable -+ -+ /* -+ * For the MPU WFI to be registered as an interrupt -+ * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set -+ * to DISABLED -+ */ -+ ldr r1, virt_mpu_clkctrl -+ ldr r2, [r1] -+ bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE -+ str r2, [r1] -+ -+ /* -+ * Execute an ISB instruction to ensure that all of the -+ * CP15 register changes have been committed. -+ */ -+ isb -+ -+ /* -+ * Execute a barrier instruction to ensure that all cache, -+ * TLB and branch predictor maintenance operations issued -+ * have completed. -+ */ -+ dsb -+ dmb -+ -+ /* -+ * Execute a WFI instruction and wait until the -+ * STANDBYWFI output is asserted to indicate that the -+ * CPU is in idle and low power state. CPU can specualatively -+ * prefetch the instructions so add NOPs after WFI. Thirteen -+ * NOPs as per Cortex-A8 pipeline. -+ */ -+ wfi -+ -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ -+ /* We come here in case of an abort due to a late interrupt */ -+ -+ /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */ -+ ldr r1, virt_mpu_clkctrl -+ mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE -+ str r2, [r1] -+ -+ /* Re-enable EMIF */ -+ ldr r1, virt_emif_clkctrl -+ mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE -+ str r2, [r1] -+wait_emif_enable: -+ ldr r3, [r1] -+ cmp r2, r3 -+ bne wait_emif_enable -+ -+ /* Disable EMIF self-refresh */ -+ ldr r0, emif_addr_virt -+ ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ bic r1, r1, #LP_MODE_MASK -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW] -+ -+ /* -+ * A write to SDRAM CONFIG register triggers -+ * an init sequence and hence it must be done -+ * at the end for DDR2 -+ */ -+ ldr r0, emif_addr_virt -+ add r0, r0, #EMIF_SDRAM_CONFIG -+ ldr r4, emif_sdcfg_val -+ str r4, [r0] -+ -+ /* -+ * Set SCTLR.C bit to allow data cache allocation -+ */ -+ mrc p15, 0, r0, c1, c0, 0 -+ orr r0, r0, #(1 << 2) @ Enable the C bit -+ mcr p15, 0, r0, c1, c0, 0 -+ isb -+ -+ /* EMIF needs some time before read/write possible */ -+ mov r0, #EMIF_POWER_MGMT_DELAY_PERIOD -+wait_abt: -+ subs r0, r0, #1 -+ bne wait_abt -+ -+ /* Let the suspend code know about the abort */ -+ mov r0, #1 -+ ldmfd sp!, {r4 - r11, pc} @ restore regs and return -+ENDPROC(am33xx_do_wfi) -+ -+ .align -+ENTRY(am33xx_resume_offset) -+ .word . - am33xx_do_wfi -+ -+ENTRY(am33xx_resume_from_deep_sleep) -+ /* Re-enable EMIF */ -+ ldr r0, phys_emif_clkctrl -+ mov r1, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE -+ str r1, [r0] -+wait_emif_enable1: -+ ldr r2, [r0] -+ cmp r1, r2 -+ bne wait_emif_enable1 -+ -+ /* Config EMIF Timings */ -+ ldr r0, emif_phys_addr -+ ldr r1, emif_rd_lat_val -+ str r1, [r0, #EMIF_DDR_PHY_CTRL_1] -+ str r1, [r0, #EMIF_DDR_PHY_CTRL_1_SHDW] -+ ldr r1, emif_timing1_val -+ str r1, [r0, #EMIF_SDRAM_TIMING_1] -+ str r1, [r0, #EMIF_SDRAM_TIMING_1_SHDW] -+ ldr r1, emif_timing2_val -+ str r1, [r0, #EMIF_SDRAM_TIMING_2] -+ str r1, [r0, #EMIF_SDRAM_TIMING_2_SHDW] -+ ldr r1, emif_timing3_val -+ str r1, [r0, #EMIF_SDRAM_TIMING_3] -+ str r1, [r0, #EMIF_SDRAM_TIMING_3_SHDW] -+ ldr r1, emif_ref_ctrl_val -+ str r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL] -+ str r1, [r0, #EMIF_SDRAM_REFRESH_CTRL_SHDW] -+ ldr r1, emif_pmcr_val -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL] -+ ldr r1, emif_pmcr_shdw_val -+ str r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW] -+ -+ /* -+ * Output impedence calib needed only for DDR3 -+ * but since the initial state of this will be -+ * disabled for DDR2 no harm in restoring the -+ * old configuration -+ */ -+ ldr r1, emif_zqcfg_val -+ str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG] -+ -+ /* Write to SDRAM_CONFIG only for DDR2 */ -+ ldr r2, mem_type -+ cmp r2, #MEM_TYPE_DDR2 -+ bne resume_to_ddr -+ -+ /* -+ * A write to SDRAM CONFIG register triggers -+ * an init sequence and hence it must be done -+ * at the end for DDR2 -+ */ -+ ldr r1, emif_sdcfg_val -+ str r1, [r0, #EMIF_SDRAM_CONFIG] -+ -+resume_to_ddr: -+ /* EMIF needs some time before read/write possible */ -+ mov r0, #EMIF_POWER_MGMT_DELAY_PERIOD -+wait_resume: -+ subs r0, r0, #1 -+ bne wait_resume -+ -+ /* We are back. Branch to the common CPU resume routine */ -+ mov r0, #0 -+ ldr pc, resume_addr -+ENDPROC(am33xx_resume_from_deep_sleep) -+ -+ -+/* -+ * Local variables -+ */ -+ .align -+resume_addr: -+ .word cpu_resume - PAGE_OFFSET + 0x80000000 -+kernel_flush: -+ .word v7_flush_dcache_all -+ddr_start: -+ .word PAGE_OFFSET -+emif_phys_addr: -+ .word AM33XX_EMIF_BASE -+virt_mpu_clkctrl: -+ .word AM33XX_CM_MPU_MPU_CLKCTRL -+virt_emif_clkctrl: -+ .word AM33XX_CM_PER_EMIF_CLKCTRL -+phys_emif_clkctrl: -+ .word (AM33XX_CM_BASE + AM33XX_CM_PER_MOD + \ -+ AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET) -+module_disabled_val: -+ .word 0x30000 -+ -+/* DDR related defines */ -+dram_sync_word: -+ .word 0xDEADBEEF -+mem_type: -+ .word 0xDEADBEEF -+emif_addr_virt: -+ .word 0xDEADBEEF -+emif_rd_lat_val: -+ .word 0xDEADBEEF -+emif_timing1_val: -+ .word 0xDEADBEEF -+emif_timing2_val: -+ .word 0xDEADBEEF -+emif_timing3_val: -+ .word 0xDEADBEEF -+emif_sdcfg_val: -+ .word 0xDEADBEEF -+emif_ref_ctrl_val: -+ .word 0xDEADBEEF -+emif_zqcfg_val: -+ .word 0xDEADBEEF -+emif_pmcr_val: -+ .word 0xDEADBEEF -+emif_pmcr_shdw_val: -+ .word 0xDEADBEEF -+ -+ .align 3 -+ENTRY(am33xx_do_wfi_sz) -+ .word . - am33xx_do_wfi ---- a/arch/arm/mach-omap2/sleep44xx.S -+++ b/arch/arm/mach-omap2/sleep44xx.S -@@ -330,6 +330,141 @@ skip_l2en: - ENDPROC(omap4_cpu_resume) - #endif /* CONFIG_ARCH_OMAP4 */ - -+#ifdef CONFIG_SOC_OMAP5 -+/* -+ * ================================ -+ * == OMAP5 CPU suspend finisher == -+ * ================================ -+ * -+ * OMAP5 MPUSS states for the context save: -+ * save_state = -+ * 0 - Nothing lost and no need to save: MPUSS INA/CSWR -+ * 1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR -+ * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR -+ * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF -+ */ -+ENTRY(omap5_finish_suspend) -+ stmfd sp!, {r4-r12, lr} -+ cmp r0, #0x0 -+ beq do_wfi @ No lowpower state, jump to WFI -+ -+ /* -+ * Flush all data from the L1 data cache before disabling -+ * SCTLR.C bit. -+ */ -+ bl omap4_get_sar_ram_base -+ ldr r9, [r0, #OMAP_TYPE_OFFSET] -+ cmp r9, #0x1 @ Check for HS device -+ bne skip_secure_l1_clean_op -+ mov r0, #0 @ Clean secure L1 -+ stmfd r13!, {r4-r12, r14} -+ ldr r12, =OMAP5_MON_CACHES_CLEAN_INDEX -+ DO_SMC -+ ldmfd r13!, {r4-r12, r14} -+skip_secure_l1_clean_op: -+ bl v7_flush_dcache_louis -+ -+ /* -+ * Clear the SCTLR.C bit to prevent further data cache -+ * allocation. Clearing SCTLR.C would make all the data accesses -+ * strongly ordered and would not hit the cache. -+ */ -+ mrc p15, 0, r0, c1, c0, 0 -+ bic r0, r0, #(1 << 2) @ Disable the C bit -+ mcr p15, 0, r0, c1, c0, 0 -+ isb -+ -+ /* Clean and Invalidate L1 data cache. */ -+ bl v7_flush_dcache_louis -+ -+ /* -+ * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus -+ * preventing the CPU from receiving cache, TLB, or BTB -+ * maintenance operations broadcast by other CPUs in the cluster. -+ */ -+ mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data -+ tst r0, #(1 << 18) -+ mrcne p15, 0, r0, c1, c0, 1 -+ bicne r0, r0, #(1 << 6) @ Disable SMP bit -+ mcrne p15, 0, r0, c1, c0, 1 -+ isb -+ dsb -+ -+ bl omap4_get_sar_ram_base -+ mov r8, r0 -+ mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR -+ ands r5, r5, #0x0f -+ ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state -+ ldrne r0, [r8, #L2X0_SAVE_OFFSET1] -+ cmp r0, #3 -+ bne do_wfi -+ bl omap4_get_sar_ram_base -+ ldr r9, [r0, #OMAP_TYPE_OFFSET] -+ cmp r9, #0x1 @ Check for HS device -+ bne skip_secure_l2_clean_op -+ mov r0, #1 @ Clean secure L2 -+ stmfd r13!, {r4-r12, r14} -+ ldr r12, =OMAP5_MON_CACHES_CLEAN_INDEX -+ DO_SMC -+ ldmfd r13!, {r4-r12, r14} -+skip_secure_l2_clean_op: -+ mov r0, #2 @ Flush L2 -+ bl v7_flush_dcache_all -+ -+do_wfi: -+ bl omap_do_wfi -+ -+ /* -+ * CPU is here when it failed to enter OFF/DORMANT or -+ * no low power state was attempted. -+ */ -+ mrc p15, 0, r0, c1, c0, 0 -+ tst r0, #(1 << 2) @ Check C bit enabled? -+ orreq r0, r0, #(1 << 2) @ Enable the C bit -+ mcreq p15, 0, r0, c1, c0, 0 -+ isb -+ mrc p15, 0, r0, c1, c0, 1 -+ tst r0, #(1 << 6) @ Check SMP bit enabled? -+ orreq r0, r0, #(1 << 6) -+ mcreq p15, 0, r0, c1, c0, 1 -+ isb -+ dsb -+ ldmfd sp!, {r4-r12, pc} -+ENDPROC(omap5_finish_suspend) -+ -+ENTRY(omap5_cpu_resume) -+#ifdef CONFIG_ARM_ERRATA_761171 -+ /* -+ * Work around for errata for 761171. Streaming write that will not -+ * allocate in L2 could lead to data corruption. -+ */ -+ mrc p15, 0, r0, c0, c0, 0 @ read main ID register -+ and r5, r0, #0x00f00000 @ variant -+ and r6, r0, #0x0000000f @ revision -+ orr r6, r6, r5, lsr #20-4 @ combine variant and revision -+ cmp r6, #0x03 @ Present before r0p3 -+ bgt 1f -+ mrc p15, 0, r0, c1, c0, 1 @ Read Auxctrl -+ orr r0, r0, #0x3 << 27 @ bits[28:27]-L1_mode3_threshold -+ ldr r12, =OMAP5_MON_AUX_CTRL_INDEX -+ dsb -+ smc #0 -+ dsb -+1: -+#endif -+ mrc p15, 1, r0, c15, c0, 0 @ Read L2 ACTLR -+ cmp r0, #0x118 @ Check if it is already set -+ beq skip_sec_l2 -+ ldr r0, =0x118 @ Setup L2 ACTLR = 0x118 -+ ldr r12, =OMAP5_MON_L2AUX_CTRL_INDEX -+ dsb -+ smc #0 -+ dsb -+skip_sec_l2: -+ b cpu_resume @ Jump to generic resume -+ENDPROC(omap5_cpu_resume) -+#endif /* CONFIG_SOC_OMAP5 */ -+ - #endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ - - #ifndef CONFIG_OMAP4_ERRATA_I688 ---- a/arch/arm/mach-omap2/sram.c -+++ b/arch/arm/mach-omap2/sram.c -@@ -154,7 +154,7 @@ static void __init omap2_map_sram(void) - omap_sram_size -= SZ_16K; - } - #endif -- if (cpu_is_omap34xx()) { -+ if (cpu_is_omap34xx() || soc_is_am33xx()) { - /* - * SRAM must be marked as non-cached on OMAP3 since the - * CORE DPLL M2 divider change code (in SRAM) runs with the -@@ -285,10 +285,18 @@ static inline int omap34xx_sram_init(voi - } - #endif /* CONFIG_ARCH_OMAP3 */ - -+#ifdef CONFIG_SOC_AM33XX - static inline int am33xx_sram_init(void) - { -+ am33xx_push_sram_idle(); - return 0; - } -+#else -+static inline int am33xx_sram_init(void) -+{ -+ return 0; -+} -+#endif - - int __init omap_sram_init(void) - { ---- a/arch/arm/mach-omap2/sram.h -+++ b/arch/arm/mach-omap2/sram.h -@@ -62,8 +62,10 @@ extern unsigned long omap3_sram_configur - - #ifdef CONFIG_PM - extern void omap_push_sram_idle(void); -+extern void am33xx_push_sram_idle(void); - #else - static inline void omap_push_sram_idle(void) {} -+static inline void am33xx_push_sram_idle(void) {} - #endif /* CONFIG_PM */ - - #endif /* __ASSEMBLY__ */ ---- a/arch/arm/mach-omap2/timer.c -+++ b/arch/arm/mach-omap2/timer.c -@@ -55,6 +55,7 @@ - #include "soc.h" - #include "common.h" - #include "powerdomain.h" -+#include "omap-secure.h" - - #define REALTIME_COUNTER_BASE 0x48243200 - #define INCREMENTER_NUMERATOR_OFFSET 0x10 -@@ -65,6 +66,7 @@ - - static struct omap_dm_timer clkev; - static struct clock_event_device clockevent_gpt; -+unsigned long arch_timer_freq; - - static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) - { -@@ -118,6 +120,29 @@ static void omap2_gp_timer_set_mode(enum - } - } - -+static void omap_clkevt_suspend(struct clock_event_device *unused) -+{ -+ struct omap_hwmod *oh; -+ -+ oh = omap_hwmod_lookup(clockevent_gpt.name); -+ if (!oh) -+ return; -+ -+ omap_hwmod_idle(oh); -+} -+ -+static void omap_clkevt_resume(struct clock_event_device *unused) -+{ -+ struct omap_hwmod *oh; -+ -+ oh = omap_hwmod_lookup(clockevent_gpt.name); -+ if (!oh) -+ return; -+ -+ omap_hwmod_enable(oh); -+ __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); -+} -+ - static struct clock_event_device clockevent_gpt = { - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .rating = 300, -@@ -276,8 +301,13 @@ static int __init omap_dm_timer_init_one - if (!timer->io_base) - return -ENXIO; - -+ omap_hwmod_setup_one(oh_name); -+ - /* After the dmtimer is using hwmod these clocks won't be needed */ -- timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); -+ if (oh->_clk) -+ timer->fclk = oh->_clk; -+ else -+ timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); - if (IS_ERR(timer->fclk)) - return PTR_ERR(timer->fclk); - -@@ -297,7 +327,6 @@ static int __init omap_dm_timer_init_one - - clk_put(src); - -- omap_hwmod_setup_one(oh_name); - omap_hwmod_enable(oh); - __omap_dm_timer_init_regs(timer); - -@@ -323,6 +352,11 @@ static void __init omap2_gp_clockevent_i - clkev.id = gptimer_id; - clkev.errata = omap_dm_timer_get_errata(); - -+ if (soc_is_am33xx()) { -+ clockevent_gpt.suspend = omap_clkevt_suspend; -+ clockevent_gpt.resume = omap_clkevt_resume; -+ } -+ - /* - * For clock-event timers we never read the timer counter and - * so we are not impacted by errata i103 and i767. Therefore, -@@ -515,6 +549,10 @@ static void __init realtime_counter_init - num = 8; - den = 25; - break; -+ case 20000000: -+ num = 192; -+ den = 625; -+ break; - case 2600000: - num = 384; - den = 1625; -@@ -542,6 +580,9 @@ static void __init realtime_counter_init - reg |= den; - __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); - -+ arch_timer_freq = (rate / den) * num; -+ omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); -+ - iounmap(base); - } - #else ---- a/arch/arm/mach-omap2/twl-common.c -+++ b/arch/arm/mach-omap2/twl-common.c -@@ -24,6 +24,7 @@ - #include <linux/i2c/twl.h> - #include <linux/gpio.h> - #include <linux/string.h> -+#include <linux/phy/phy.h> - #include <linux/regulator/machine.h> - #include <linux/regulator/fixed.h> - -@@ -90,8 +91,18 @@ void __init omap_pmic_late_init(void) - } - - #if defined(CONFIG_ARCH_OMAP3) -+struct phy_consumer consumers[] = { -+ PHY_CONSUMER("musb-hdrc.0", "usb"), -+}; -+ -+struct phy_init_data init_data = { -+ .consumers = consumers, -+ .num_consumers = ARRAY_SIZE(consumers), -+}; -+ - static struct twl4030_usb_data omap3_usb_pdata = { - .usb_mode = T2_USB_MODE_ULPI, -+ .init_data = &init_data, - }; - - static int omap3_batt_table[] = { ---- a/arch/arm/mach-omap2/usb.h -+++ b/arch/arm/mach-omap2/usb.h -@@ -58,7 +58,6 @@ struct usbhs_phy_data { - int reset_gpio; - int vcc_gpio; - bool vcc_polarity; /* 1 active high, 0 active low */ -- void *platform_data; - }; - - extern void usb_musb_init(struct omap_musb_board_data *board_data); ---- a/arch/arm/mach-omap2/usb-host.c -+++ b/arch/arm/mach-omap2/usb-host.c -@@ -435,6 +435,7 @@ int usbhs_init_phys(struct usbhs_phy_dat - struct platform_device *pdev; - char *phy_id; - struct platform_device_info pdevinfo; -+ struct usb_phy_gen_xceiv_platform_data nop_pdata; - - for (i = 0; i < num_phys; i++) { - -@@ -455,11 +456,18 @@ int usbhs_init_phys(struct usbhs_phy_dat - return -ENOMEM; - } - -+ /* set platform data */ -+ memset(&nop_pdata, 0, sizeof(nop_pdata)); -+ if (gpio_is_valid(phy->vcc_gpio)) -+ nop_pdata.needs_vcc = true; -+ nop_pdata.gpio_reset = phy->reset_gpio; -+ nop_pdata.type = USB_PHY_TYPE_USB2; -+ - /* create a NOP PHY device */ - memset(&pdevinfo, 0, sizeof(pdevinfo)); - pdevinfo.name = nop_name; - pdevinfo.id = phy->port; -- pdevinfo.data = phy->platform_data; -+ pdevinfo.data = &nop_pdata; - pdevinfo.size_data = - sizeof(struct usb_phy_gen_xceiv_platform_data); - scnprintf(phy_id, MAX_STR, "usb_phy_gen_xceiv.%d", -@@ -474,14 +482,6 @@ int usbhs_init_phys(struct usbhs_phy_dat - - usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id); - -- /* Do we need RESET regulator ? */ -- if (gpio_is_valid(phy->reset_gpio)) { -- scnprintf(rail_name, MAX_STR, -- "hsusb%d_reset", phy->port); -- usbhs_add_regulator(rail_name, phy_id, "reset", -- phy->reset_gpio, 1); -- } -- - /* Do we need VCC regulator ? */ - if (gpio_is_valid(phy->vcc_gpio)) { - scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port); ---- a/arch/arm/mach-omap2/wd_timer.c -+++ b/arch/arm/mach-omap2/wd_timer.c -@@ -123,6 +123,11 @@ static int __init omap_init_wdt(void) - - pdata.read_reset_sources = prm_read_reset_sources; - -+ if (cpu_is_omap44xx() || soc_is_omap54xx()) -+ pdata.ip_rev = WDTIMER2_IP4; -+ else -+ pdata.ip_rev = WDTIMER2_IP3; -+ - pdev = omap_device_build(dev_name, id, oh, &pdata, - sizeof(struct omap_wd_timer_platform_data)); - WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", ---- /dev/null -+++ b/arch/arm/mach-omap2/wkup_m3.c -@@ -0,0 +1,410 @@ -+/* -+* AM33XX Power Management Routines -+ * -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * Vaibhav Bedia <vaibhav.bedia@ti.com> -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/cpu.h> -+#include <linux/err.h> -+#include <linux/firmware.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/module.h> -+#include <linux/interrupt.h> -+#include <linux/of.h> -+#include <linux/omap-mailbox.h> -+ -+#include "pm33xx.h" -+#include "omap_device.h" -+ -+#define WKUP_M3_WAKE_SRC_MASK 0xFF -+ -+#define WKUP_M3_STATUS_RESP_SHIFT 16 -+#define WKUP_M3_STATUS_RESP_MASK (0xffff << 16) -+ -+#define WKUP_M3_FW_VERSION_SHIFT 0 -+#define WKUP_M3_FW_VERSION_MASK 0xffff -+ -+/* AM33XX M3_TXEV_EOI register */ -+#define AM33XX_CONTROL_M3_TXEV_EOI 0x00 -+ -+#define AM33XX_M3_TXEV_ACK (0x1 << 0) -+#define AM33XX_M3_TXEV_ENABLE (0x0 << 0) -+ -+/* AM33XX IPC message registers */ -+#define AM33XX_CONTROL_IPC_MSG_REG0 0x04 -+#define AM33XX_CONTROL_IPC_MSG_REG1 0x08 -+#define AM33XX_CONTROL_IPC_MSG_REG2 0x0c -+#define AM33XX_CONTROL_IPC_MSG_REG3 0x10 -+#define AM33XX_CONTROL_IPC_MSG_REG4 0x14 -+#define AM33XX_CONTROL_IPC_MSG_REG5 0x18 -+#define AM33XX_CONTROL_IPC_MSG_REG6 0x1c -+#define AM33XX_CONTROL_IPC_MSG_REG7 0x20 -+ -+struct wkup_m3_context { -+ struct device *dev; -+ void __iomem *code; -+ void __iomem *ipc; -+ u8 is_valid; -+ struct wkup_m3_ops *ops; -+ struct omap_mbox *mbox; -+}; -+ -+struct wkup_m3_wakeup_src wakeups[] = { -+ {.irq_nr = 35, .src = "USB0_PHY"}, -+ {.irq_nr = 36, .src = "USB1_PHY"}, -+ {.irq_nr = 40, .src = "I2C0"}, -+ {.irq_nr = 41, .src = "RTC Timer"}, -+ {.irq_nr = 42, .src = "RTC Alarm"}, -+ {.irq_nr = 43, .src = "Timer0"}, -+ {.irq_nr = 44, .src = "Timer1"}, -+ {.irq_nr = 45, .src = "UART"}, -+ {.irq_nr = 46, .src = "GPIO0"}, -+ {.irq_nr = 48, .src = "MPU_WAKE"}, -+ {.irq_nr = 49, .src = "WDT0"}, -+ {.irq_nr = 50, .src = "WDT1"}, -+ {.irq_nr = 51, .src = "ADC_TSC"}, -+ {.irq_nr = 0, .src = "Unknown"}, -+}; -+ -+static struct wkup_m3_context *wkup_m3; -+ -+static void am33xx_txev_eoi(void) -+{ -+ writel(AM33XX_M3_TXEV_ACK, -+ wkup_m3->ipc + AM33XX_CONTROL_M3_TXEV_EOI); -+} -+ -+static void am33xx_txev_enable(void) -+{ -+ writel(AM33XX_M3_TXEV_ENABLE, -+ wkup_m3->ipc + AM33XX_CONTROL_M3_TXEV_EOI); -+} -+ -+static void am33xx_ctrl_ipc_write(struct am33xx_ipc_regs *ipc_regs) -+{ -+ writel(ipc_regs->reg0, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG0); -+ writel(ipc_regs->reg1, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG1); -+ writel(ipc_regs->reg2, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG2); -+ writel(ipc_regs->reg3, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG3); -+ writel(ipc_regs->reg4, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG4); -+ writel(ipc_regs->reg5, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG5); -+ writel(ipc_regs->reg6, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG6); -+ writel(ipc_regs->reg7, -+ wkup_m3->ipc + AM33XX_CONTROL_IPC_MSG_REG7); -+} -+ -+static void am33xx_ctrl_ipc_read(struct am33xx_ipc_regs *ipc_regs) -+{ -+ ipc_regs->reg0 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG0); -+ ipc_regs->reg1 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG1); -+ ipc_regs->reg2 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG2); -+ ipc_regs->reg3 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG3); -+ ipc_regs->reg4 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG4); -+ ipc_regs->reg5 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG5); -+ ipc_regs->reg6 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG6); -+ ipc_regs->reg7 = readl(wkup_m3->ipc -+ + AM33XX_CONTROL_IPC_MSG_REG7); -+} -+ -+int wkup_m3_is_valid() -+{ -+ return wkup_m3->is_valid; -+} -+ -+int wkup_m3_ping(void) -+{ -+ int ret = 0; -+ -+ if (!wkup_m3->mbox) { -+ pr_err("PM: No IPC channel to communicate with wkup_m3!\n"); -+ return -EIO; -+ } -+ -+ /* -+ * Write a dummy message to the mailbox in order to trigger the RX -+ * interrupt to alert the M3 that data is available in the IPC -+ * registers. -+ */ -+ ret = omap_mbox_msg_send(wkup_m3->mbox, 0xABCDABCD); -+ -+ return ret; -+} -+ -+struct wkup_m3_wakeup_src wkup_m3_wake_src(void) -+{ -+ struct am33xx_ipc_regs ipc_regs; -+ unsigned int wakeup_src_idx; -+ int j; -+ -+ am33xx_ctrl_ipc_read(&ipc_regs); -+ -+ wakeup_src_idx = ipc_regs.reg6 & WKUP_M3_WAKE_SRC_MASK; -+ -+ for (j = 0; j < ARRAY_SIZE(wakeups)-1; j++) { -+ if (wakeups[j].irq_nr == wakeup_src_idx) -+ return wakeups[j]; -+ } -+ -+ return wakeups[j]; -+} -+ -+ -+int wkup_m3_pm_status(void) -+{ -+ unsigned int i; -+ struct am33xx_ipc_regs ipc_regs; -+ -+ am33xx_ctrl_ipc_read(&ipc_regs); -+ -+ i = WKUP_M3_STATUS_RESP_MASK & ipc_regs.reg1; -+ i >>= __ffs(WKUP_M3_STATUS_RESP_MASK); -+ -+ return i; -+} -+ -+/* -+ * Invalidate M3 firmware version before hardreset. -+ * Write invalid version in lower 4 nibbles of parameter -+ * register (ipc_regs + 0x8). -+ */ -+ -+static void wkup_m3_fw_version_clear(void) -+{ -+ struct am33xx_ipc_regs ipc_regs; -+ -+ am33xx_ctrl_ipc_read(&ipc_regs); -+ ipc_regs.reg2 = 0xFFFF0000; -+ am33xx_ctrl_ipc_write(&ipc_regs); -+ -+ return; -+} -+ -+int wkup_m3_fw_version_read(void) -+{ -+ struct am33xx_ipc_regs ipc_regs; -+ -+ am33xx_ctrl_ipc_read(&ipc_regs); -+ -+ return ipc_regs.reg2 & WKUP_M3_FW_VERSION_MASK; -+} -+ -+void wkup_m3_pm_set_cmd(struct am33xx_ipc_regs *ipc_regs) -+{ -+ am33xx_ctrl_ipc_write(ipc_regs); -+} -+ -+void wkup_m3_set_ops(struct wkup_m3_ops *ops) -+{ -+ wkup_m3->ops = ops; -+} -+ -+static irqreturn_t wkup_m3_txev_handler(int irq, void *unused) -+{ -+ am33xx_txev_eoi(); -+ -+ if (wkup_m3->ops && wkup_m3->ops->firmware_loaded) -+ wkup_m3->ops->txev_handler(); -+ -+ am33xx_txev_enable(); -+ -+ return IRQ_HANDLED; -+} -+ -+int wkup_m3_prepare(void) -+{ -+ int ret = 0; -+ struct platform_device *pdev = to_platform_device(wkup_m3->dev); -+ -+ wkup_m3->mbox = omap_mbox_get("wkup_m3", NULL); -+ -+ if (IS_ERR(wkup_m3->mbox)) { -+ ret = -EBUSY; -+ pr_err("PM: IPC Request for A8->M3 Channel failed!\n"); -+ return ret; -+ } -+ -+ wkup_m3_fw_version_clear(); -+ -+ /* check that the code is loaded */ -+ ret = omap_device_deassert_hardreset(pdev, "wkup_m3"); -+ -+ return ret; -+} -+ -+static int wkup_m3_copy_code(const u8 *data, size_t size) -+{ -+ if (size > SZ_16K) -+ return -ENOMEM; -+ -+ memcpy_toio(wkup_m3->code, data, size); -+ -+ return 0; -+} -+ -+static void wkup_m3_firmware_cb(const struct firmware *fw, void *context) -+{ -+ int ret = 0; -+ -+ /* no firmware found */ -+ if (!fw) { -+ pr_err("PM: request_firmware failed\n"); -+ return; -+ } -+ -+ ret = wkup_m3_copy_code(fw->data, fw->size); -+ -+ if (ret) { -+ pr_info("PM: Failed to copy firmware for M3"); -+ } else { -+ if (wkup_m3->ops && wkup_m3->ops->firmware_loaded) -+ wkup_m3->ops->firmware_loaded(); -+ -+ wkup_m3->is_valid = true; -+ } -+ -+ return; -+} -+ -+static int wkup_m3_probe(struct platform_device *pdev) -+{ -+ int irq, ret = 0; -+ struct resource *res; -+ -+ pm_runtime_enable(&pdev->dev); -+ -+ ret = pm_runtime_get_sync(&pdev->dev); -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); -+ return ret; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (!irq) { -+ dev_err(&pdev->dev, "no irq resource\n"); -+ ret = -ENXIO; -+ goto err; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m3_umem"); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource\n"); -+ ret = -ENXIO; -+ goto err; -+ } -+ -+ wkup_m3 = devm_kzalloc(&pdev->dev, sizeof(*wkup_m3), GFP_KERNEL); -+ if (!wkup_m3) { -+ pr_err("Memory allocation failed\n"); -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ wkup_m3->dev = &pdev->dev; -+ -+ wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, res); -+ if (!wkup_m3->code) { -+ dev_err(wkup_m3->dev, "could not ioremap\n"); -+ ret = -EADDRNOTAVAIL; -+ goto err; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipc_regs"); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource for ipc\n"); -+ ret = -ENXIO; -+ goto err; -+ } -+ -+ wkup_m3->ipc = devm_request_and_ioremap(wkup_m3->dev, res); -+ if (!wkup_m3->ipc) { -+ dev_err(wkup_m3->dev, "could not ioremap ipc_mem\n"); -+ ret = -EADDRNOTAVAIL; -+ goto err; -+ } -+ -+ ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler, -+ IRQF_DISABLED, "wkup_m3_txev", NULL); -+ if (ret) { -+ dev_err(wkup_m3->dev, "request_irq failed\n"); -+ goto err; -+ } -+ -+ wkup_m3->is_valid = false; -+ -+ pr_info("PM: Loading am335x-pm-firmware.bin"); -+ -+ /* We don't want to delay boot */ -+ ret = request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin", -+ &pdev->dev, GFP_KERNEL, NULL, -+ wkup_m3_firmware_cb); -+ -+err: -+ return ret; -+} -+ -+static int wkup_m3_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+static struct of_device_id wkup_m3_dt_ids[] = { -+ { .compatible = "ti,am3353-wkup-m3" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, wkup_m3_dt_ids); -+ -+static int wkup_m3_rpm_suspend(struct device *dev) -+{ -+ return -EBUSY; -+} -+ -+static int wkup_m3_rpm_resume(struct device *dev) -+{ -+ return 0; -+} -+ -+static const struct dev_pm_ops wkup_m3_ops = { -+ SET_RUNTIME_PM_OPS(wkup_m3_rpm_suspend, wkup_m3_rpm_resume, NULL) -+}; -+ -+static struct platform_driver wkup_m3_driver = { -+ .probe = wkup_m3_probe, -+ .remove = wkup_m3_remove, -+ .driver = { -+ .name = "wkup_m3", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(wkup_m3_dt_ids), -+ .pm = &wkup_m3_ops, -+ }, -+}; -+ -+module_platform_driver(wkup_m3_driver); ---- /dev/null -+++ b/arch/arm/mach-omap2/wkup_m3.h -@@ -0,0 +1,60 @@ -+/* -+ * TI Wakeup M3 Power Management Routines -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * Dave Gerlach <d-gerlach@ti.com> -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __ASSEMBLER__ -+ -+/** -+ * struct wkup_m3_ops - Callbacks for allowing pm code to interact with wkup_m3. -+ * -+ * @txev_handler: Callback to allow pm code to react to response from wkup_m3 -+ * after pinging it using wkup_m3_ping. -+ * -+ * @firmware_loaded: Callback invoked when the firmware has been loaded to the -+ * m3 to allow the pm code to enable suspend/resume ops. -+ */ -+ -+struct wkup_m3_ops { -+ void (*txev_handler)(void); -+ void (*firmware_loaded)(void); -+}; -+ -+struct wkup_m3_wakeup_src { -+ int irq_nr; -+ char src[10]; -+}; -+ -+struct am33xx_ipc_regs { -+ u32 reg0; -+ u32 reg1; -+ u32 reg2; -+ u32 reg3; -+ u32 reg4; -+ u32 reg5; -+ u32 reg6; -+ u32 reg7; -+}; -+ -+int wkup_m3_prepare(void); -+void wkup_m3_set_ops(struct wkup_m3_ops *ops); -+int wkup_m3_ping(void); -+struct wkup_m3_wakeup_src wkup_m3_wake_src(void); -+int wkup_m3_pm_status(void); -+int wkup_m3_is_valid(void); -+int wkup_m3_fw_version_read(void); -+void wkup_m3_pm_set_cmd(struct am33xx_ipc_regs *ipc_regs); -+ -+#endif -+ ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -314,6 +314,8 @@ $(INSTALL_TARGETS): - - %.dtb: | scripts - $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ -+uImage.%: uImage -+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ - - PHONY += dtbs - dtbs: scripts ---- a/arch/arm/plat-omap/include/plat/dmtimer.h -+++ b/arch/arm/plat-omap/include/plat/dmtimer.h -@@ -336,8 +336,11 @@ static inline void __omap_dm_timer_enabl - if (timer->posted) - return; - -- if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) -+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) { -+ timer->posted = OMAP_TIMER_NONPOSTED; -+ __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0); - return; -+ } - - __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, - OMAP_TIMER_CTRL_POSTED, 0); ---- /dev/null -+++ b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage -@@ -0,0 +1,31 @@ -+What: /config/usb-gadget/gadget/functions/mass_storage.name -+Date: Oct 2013 -+KenelVersion: 3.13 -+Description: -+ The attributes: -+ -+ stall - Set to permit function to halt bulk endpoints. -+ Disabled on some USB devices known not to work -+ correctly. You should set it to true. -+ num_buffers - Number of pipeline buffers. Valid numbers -+ are 2..4. Available only if -+ CONFIG_USB_GADGET_DEBUG_FILES is set. -+ -+What: /config/usb-gadget/gadget/functions/mass_storage.name/lun.name -+Date: Oct 2013 -+KenelVersion: 3.13 -+Description: -+ The attributes: -+ -+ file - The path to the backing file for the LUN. -+ Required if LUN is not marked as removable. -+ ro - Flag specifying access to the LUN shall be -+ read-only. This is implied if CD-ROM emulation -+ is enabled as well as when it was impossible -+ to open "filename" in R/W mode. -+ removable - Flag specifying that LUN shall be indicated as -+ being removable. -+ cdrom - Flag specifying that LUN shall be reported as -+ being a CD-ROM. -+ nofua - Flag specifying that FUA flag -+ in SCSI WRITE(10,12) ---- /dev/null -+++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt -@@ -0,0 +1,24 @@ -+* TI - IRQ/DMA Crossbar -+ -+This version is an implementation of the Crossbar IRQ/DMA IP -+ -+Required properties: -+- compatible : Should be "ti,dra-crossbar" -+- crossbar-name: Name of the controller to which crossbar output is routed -+- reg: Contains crossbar register address range -+- reg-width: Represents the width of the individual registers -+- crossbar-lines: Default mappings.Should contain the crossbar-name -+ device name, int/dma request number, crossbar number, -+ register offset in the same order. -+ -+Examples: -+ crossbar_mpu: mpuirq@4a002a48 { -+ compatible = "crossbar"; -+ crossbar-name = "mpu-irq"; -+ reg = <0x4a002a48 0x0130>; -+ reg-width = <16>; -+ crossbar-lines = "mpu-irq", "rtc-ss-alarm", <0x9f 0xd9 0x12c>, -+ "mpu-irq", "mcasp3-arevt", <0x9e 0x96 0x12a>, -+ "mpu-irq", "mcasp3-axevt", <0x9d 0x97 0x128>; -+ }; -+ ---- /dev/null -+++ b/Documentation/devicetree/bindings/arm/omap/dmm.txt -@@ -0,0 +1,17 @@ -+OMAP Dynamic Memory Manager (DMM) bindings -+ -+Required properties: -+- compatible: Must be "ti,omap4-dmm" for OMAP4 family -+ Must be "ti,omap5-dmm" for OMAP5 family -+- reg: Contains timer register address range (base address and length) -+- interrupts: Contains interrupt information (source, etc) for the DMM IRQ -+- ti,hwmods: Name of the hwmod associated to the counter, which is typically -+ "dmm" -+ -+Example: -+ -+dmm: dmm@4e000000 { -+ compatible = "ti,omap4-dmm"; -+ reg = <0x4e000000 0x800>; -+ ti,hwmods = "dmm"; -+}; ---- a/Documentation/devicetree/bindings/arm/omap/omap.txt -+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt -@@ -21,7 +21,8 @@ Required properties: - Optional properties: - - ti,no_idle_on_suspend: When present, it prevents the PM to idle the module - during suspend. -- -+- ti,no-reset: When present, the module should not be reset -+- ti,no-idle: When present, the module should not be idled - - Example: - -@@ -60,5 +61,8 @@ Boards: - - AM43x EPOS EVM - compatible = "ti,am43x-epos-evm", "ti,am4372", "ti,am43" - -+- AM437x GP EVM -+ compatible = "ti,am437x-gp-evm", "ti,am4372", "ti,am43" -+ - - DRA7 EVM: Software Developement Board for DRA7XX - compatible = "ti,dra7-evm", "ti,dra7" ---- /dev/null -+++ b/Documentation/devicetree/bindings/arm/omap/prcm.txt -@@ -0,0 +1,13 @@ -+TI Power Reset Clock Manager (PRCM) -+ -+Properties: -+- compatible: "ti,am4372-prcm" for prcm in am43x SoC's -+ "ti,am3352-prcm" for prcm in am335x SoC's -+- #reset-cells: 1 (refer generic reset bindings for details) -+ -+example: -+ prcm: prcm@44df0000 { -+ compatible = "ti,am4372-prcm"; -+ reg = <0x44df0000 0xa000>; -+ #reset-cells = <1>; -+ }; ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -4,7 +4,8 @@ SATA nodes are defined to describe on-ch - Each SATA controller should have its own node. - - Required properties: --- compatible : compatible list, contains "snps,spear-ahci" -+- compatible : compatible list, contains "snps,spear-ahci", -+ snps,exynos5440-ahci or "snps,dwc-ahci" - - interrupts : <interrupt mapping for SATA IRQ> - - reg : <registers mapping> - ---- /dev/null -+++ b/Documentation/devicetree/bindings/ata/ti-sata.txt -@@ -0,0 +1,31 @@ -+* Texas Instruments SATA Controller Wrapper -+ -+Required properties: -+- compatible : "ti,sata" -+- ti,hwmods : "sata" -+- reg : Register mapping -+- #address-cells: <1> -+- #size-cells : <1> -+- ranges : allows valid translation between child's address space and parent's -+ address space. -+- Must contain at least one child node for the SATA controller core -+ -+Example: -+ -+ sata: sata@4a141100 { -+ compatible = "ti,sata"; -+ ti,hwmods = "sata"; -+ reg = <0x4a141100 0x7>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ dwc-ahci@4a140000 { -+ compatible = "snps,dwc-ahci"; -+ reg = <0x4a140000 0x1100>; -+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; -+ phys = <&sata_phy>; -+ phy-names = "sata-phy"; -+ clocks = <&sata_ref_clk>; -+ clock-names = "optclk"; -+ }; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/clk-palmas.txt -@@ -0,0 +1,35 @@ -+* Palmas 32KHz clocks * -+ -+Palmas device has two clock output pins for 32KHz, KG and KG_AUDIO. -+ -+This binding uses the common clock binding ./clock-bindings.txt. -+ -+Required properties: -+- compatible : "ti,palmas-clk32kg" for clk32kg clock -+ "ti,palmas-clk32kgaudio" for clk32kgaudio clock -+- #clock-cells : shall be set to 0. -+ -+Optional property: -+- ti,external-sleep-control: The external enable input pins controlled the -+ enable/disable of clocks. The external enable input pins ENABLE1, -+ ENABLE2 and NSLEEP. The valid values for the external pins are: -+ PALMAS_EXT_CONTROL_PIN_ENABLE1 for ENABLE1 pin -+ PALMAS_EXT_CONTROL_PIN_ENABLE2 for ENABLE2 pin -+ PALMAS_EXT_CONTROL_PIN_NSLEEP for NSLEEP pin -+ Option 0 or missing this property means the clock is enabled/disabled -+ via register access and these pins do not have any control. -+ The macros of external control pins for DTS is defined at -+ dt-bindings/mfd/palmas.h -+ -+Example: -+ #include <dt-bindings/mfd/palmas.h> -+ ... -+ palmas: tps65913@58 { -+ ... -+ clk32kg: palmas_clk32k@0 { -+ compatible = "ti,palmas-clk32kg"; -+ #clock-cells = <0>; -+ ti,external-sleep-control = <PALMAS_EXT_CONTROL_PIN_NSLEEP>; -+ }; -+ ... -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/divider-clock.txt -@@ -0,0 +1,90 @@ -+Binding for simple divider clock. -+ -+This binding uses the common clock binding[1]. It assumes a -+register-mapped adjustable clock rate divider that does not gate and has -+only one input clock or parent. By default the value programmed into -+the register is one less than the actual divisor value. E.g: -+ -+register value actual divisor value -+0 1 -+1 2 -+2 3 -+ -+This assumption may be modified by the following optional properties: -+ -+index-starts-at-one - valid divisor values start at 1, not the default -+of 0. E.g: -+register value actual divisor value -+1 1 -+2 2 -+3 3 -+ -+index-power-of-two - valid divisor values are powers of two. E.g: -+register value actual divisor value -+0 1 -+1 2 -+2 4 -+ -+index-allow-zero - same as index_one, but zero is divide-by-1. E.g: -+register value actual divisor value -+0 1 -+1 1 -+2 2 -+ -+Additionally a table of valid dividers may be supplied like so: -+ -+ table = <4 0>, <8, 1>; -+ -+where the first value in the pair is the divider and the second value is -+the programmed register bitfield. -+ -+The binding must also provide the register to control the divider and -+the mask for the corresponding control bits. Optionally the number of -+bits to shift that mask, if necessary. If the shift value is missing it -+is the same as supplying a zero shift. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+Required properties: -+- compatible : shall be "divider-clock". -+- #clock-cells : from common clock binding; shall be set to 0. -+- clocks : link to phandle of parent clock -+- reg : base address for register controlling adjustable divider -+- bit-mask : arbitrary bitmask for programming the adjustable divider -+ -+Optional properties: -+- clock-output-names : from common clock binding. -+- table : array of integer pairs defining divisors & bitfield values -+- bit-shift : number of bits to shift the bit-mask, defaults to -+ (ffs(mask) - 1) if not present -+- minimum-divider : min divisor for dividing the input clock rate, only -+ needed if the first divisor is offset from the default value -+- maximum-divider : max divisor for dividing the input clock rate, only -+ needed if the max divisor is less than (mask + 1). -+- index-starts-at-one : valid divisor programming starts at 1, not zero -+- index-power-of-two : valid divisor programming must be a power of two -+- index-allow-zero : implies index-one, and programming zero results in -+ divide-by-one -+- hiword-mask : lower half of the register programs the divider, upper -+ half of the register indicates bits that were updated in the lower -+ half -+ -+Examples: -+ clock_foo: clock_foo@4a008100 { -+ compatible = "divider-clock"; -+ #clock-cells = <0>; -+ clocks = <&clock_baz>; -+ reg = <0x4a008100 0x4> -+ mask = <0x3> -+ maximum-divider = <3> -+ }; -+ -+ clock_bar: clock_bar@4a008108 { -+ #clock-cells = <0>; -+ compatible = "divider-clock"; -+ clocks = <&clock_foo>; -+ reg = <0x4a008108 0x4>; -+ mask = <0x1>; -+ shift = <0>; -+ table = < 4 0 >, < 8 1 >; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/gate-clock.txt -@@ -0,0 +1,36 @@ -+Binding for simple gate clock. -+ -+This binding uses the common clock binding[1]. It assumes a -+register-mapped clock gate controlled by a single bit that has only one -+input clock or parent. By default setting the specified bit gates the -+clock signal and clearing the bit ungates it. -+ -+The binding must provide the register to control the gate and the bit -+shift for the corresponding gate control bit. Some clocks set the bit to -+gate the clock signal, and clear it to ungate the clock signal. The -+optional "set-bit-to-disable" specifies this behavior. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+Required properties: -+- compatible : shall be "gate-clock". -+- #clock-cells : from common clock binding; shall be set to 0. -+- clocks : link to phandle of parent clock -+- reg : base address for register controlling adjustable gate -+- bit-shift : bit shift for programming the clock gate -+ -+Optional properties: -+- clock-output-names : from common clock binding. -+- set-bit-to-disable : inverts default gate programming. Setting the bit -+ gates the clock and clearing the bit ungates the clock. -+- hiword-mask : lower half of the register controls the gate, upper half -+ of the register indicates bits that were updated in the lower half -+ -+Examples: -+ clock_foo: clock_foo@4a008100 { -+ compatible = "gate-clock"; -+ #clock-cells = <0>; -+ clocks = <&clock_bar>; -+ reg = <0x4a008100 0x4> -+ bit-shift = <3> -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/mux-clock.txt -@@ -0,0 +1,79 @@ -+Binding for simple mux clock. -+ -+This binding uses the common clock binding[1]. It assumes a -+register-mapped multiplexer with multiple input clock signals or -+parents, one of which can be selected as output. This clock does not -+gate or adjust the parent rate via a divider or multiplier. -+ -+By default the "clocks" property lists the parents in the same order -+as they are programmed into the regster. E.g: -+ -+ clocks = <&foo_clock>, <&bar_clock>, <&baz_clock>; -+ -+results in programming the register as follows: -+ -+register value selected parent clock -+0 foo_clock -+1 bar_clock -+2 baz_clock -+ -+Some clock controller IPs do not allow a value of zero to be programmed -+into the register, instead indexing begins at 1. The optional property -+"index-starts-at-one" modified the scheme as follows: -+ -+register value selected clock parent -+1 foo_clock -+2 bar_clock -+3 baz_clock -+ -+Additionally an optional table of bit and parent pairs may be supplied -+like so: -+ -+ table = <&foo_clock 0x0>, <&bar_clock, 0x2>, <&baz_clock, 0x4>; -+ -+where the first value in the pair is the parent clock and the second -+value is the bitfield to be programmed into the register. -+ -+The binding must provide the register to control the mux and the mask -+for the corresponding control bits. Optionally the number of bits to -+shift that mask if necessary. If the shift value is missing it is the -+same as supplying a zero shift. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+Required properties: -+- compatible : shall be "mux-clock". -+- #clock-cells : from common clock binding; shall be set to 0. -+- clocks : link phandles of parent clocks -+- reg : base address for register controlling adjustable mux -+- bit-mask : arbitrary bitmask for programming the adjustable mux -+ -+Optional properties: -+- clock-output-names : From common clock binding. -+- table : array of integer pairs defining parents & bitfield values -+- bit-shift : number of bits to shift the bit-mask, defaults to -+ (ffs(mask) - 1) if not present -+- index-starts-at-one : valid input select programming starts at 1, not -+ zero -+- hiword-mask : lower half of the register programs the mux, upper half -+ of the register indicates bits that were updated in the lower half -+ -+Examples: -+ clock: clock@4a008100 { -+ compatible = "mux-clock"; -+ #clock-cells = <0>; -+ clocks = <&clock_foo>, <&clock_bar>, <&clock_baz>; -+ reg = <0x4a008100 0x4> -+ mask = <0x3>; -+ index-starts-at-one; -+ }; -+ -+ clock: clock@4a008100 { -+ #clock-cells = <0>; -+ compatible = "mux-clock"; -+ clocks = <&clock_foo>, <&clock_bar>, <&clock_baz>; -+ reg = <0x4a008100 0x4>; -+ mask = <0x3>; -+ shift = <0>; -+ table = <&clock_foo 1>, <&clock_bar 2>, <&clock_baz 3>; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/ti/apll.txt -@@ -0,0 +1,33 @@ -+Binding for Texas Instruments APLL clock. -+ -+This binding uses the common clock binding[1]. It assumes a -+register-mapped APLL with usually two selectable input clocks -+(reference clock and bypass clock), with analog phase locked -+loop logic for multiplying the input clock to a desired output -+clock. This clock also typically supports different operation -+modes (locked, low power stop etc.) APLL mostly behaves like -+a subtype of a DPLL [2], although a simplified one at that. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+[2] Documentation/devicetree/bindings/clock/ti/dpll.txt -+ -+Required properties: -+- compatible : shall be "ti,dra7-apll-clock" -+- #clock-cells : from common clock binding; shall be set to 0. -+- clocks : link phandles of parent clocks (clk-ref and clk-bypass) -+- reg : address and length of the register set for controlling the APLL. -+ It contains the information of registers in the same order as described by -+ reg-names. -+- reg-names: array of the register names for controlling the device, sorted -+ in the same order as the reg property. -+ "control" - contains the control register base address -+ "idlest" - contains the idlest register base address -+ -+Examples: -+ apll_pcie_ck: apll_pcie_ck@4a008200 { -+ #clock-cells = <0>; -+ clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>; -+ reg = <0x4a00821c 0x4>, <0x4a008220 0x4>; -+ reg-names = "control", "idlest"; -+ compatible = "ti,dra7-apll-clock"; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/ti/autoidle.txt -@@ -0,0 +1,48 @@ -+Binding for Texas Instruments autoidling clock. -+ -+This binding uses the common clock binding[1]. Autoidle clocks -+are inherited clocks from basic divider-clock [2] or -+fixed-factor-clock [3] and just add autoidle support on top of -+this. Autoidle is an OMAP clock feature, which allows the clock -+to gate autonomously by hardware when they are no longer needed. -+The autoidle feature must be enabled manually for these clocks. -+Otherwise the clocks behave exactly as their base clock type. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+[2] Documentation/devicetree/bindings/clock/divider-clock.txt -+[3] Documentation/devicetree/bindings/clock/fixed-factor-clock.txt -+ -+Required properties: -+- compatible : shall be one of: -+ "ti,divider-clock", -+ "ti,fixed-factor-clock" -+- ti,autoidle-shift : bit shift of the autoidle enable bit for the clock -+- reg : base address for the control register of this clock -+ -+Optional properties: -+- ti,autoidle-low : autoidle is enabled by setting the bit to 0 -+ -+Other properties as per the base clock type. -+ -+Examples: -+ dpll_abe_m2x2_ck: dpll_abe_m2x2_ck@4a0051f0 { -+ #clock-cells = <0>; -+ compatible = "ti,divider-clock"; -+ clocks = <&dpll_abe_x2_ck>; -+ ti,autoidle-shift = <8>; -+ reg = <0x4a0051f0 0x4>; -+ bit-mask = <0x1f>; -+ index-starts-at-one; -+ ti,autoidle-low; -+ }; -+ -+ dpll_usb_clkdcoldo_ck: dpll_usb_clkdcoldo_ck@4a0081b4 { -+ #clock-cells = <0>; -+ compatible = "ti,fixed-factor-clock"; -+ clocks = <&dpll_usb_ck>; -+ ti,autoidle-shift = <8>; -+ clock-div = <1>; -+ reg = <0x4a0081b4 0x4>; -+ clock-mult = <1>; -+ ti,autoidle-low; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/ti/clockdomain.txt -@@ -0,0 +1,19 @@ -+Binding for Texas Instruments clockdomain. -+ -+This binding uses the common clock binding[1]. Every clock on -+TI SoC belongs to one clockdomain, but software only needs this -+information for specific clocks which require their parent -+clockdomain to be controlled when the clock is enabled/disabled. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+Required properties: -+- compatible : shall be "ti,clockdomain" -+- #clock-cells : from common clock binding; shall be set to 0. -+- clocks : link phandles of clocks within this domain -+ -+Examples: -+ dss_clkdm: dss_clkdm { -+ compatible = "ti,clockdomain"; -+ clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/ti/dpll.txt -@@ -0,0 +1,68 @@ -+Binding for Texas Instruments DPLL clock. -+ -+This binding uses the common clock binding[1]. It assumes a -+register-mapped DPLL with usually two selectable input clocks -+(reference clock and bypass clock), with digital phase locked -+loop logic for multiplying the input clock to a desired output -+clock. This clock also typically supports different operation -+modes (locked, low power stop etc.) This binding has several -+sub-types, which effectively result in slightly different setup -+for the actual DPLL clock. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+Required properties: -+- compatible : shall be one of: -+ "ti,omap4-dpll-x2-clock", -+ "ti,omap3-dpll-clock", -+ "ti,omap3-dpll-core-clock", -+ "ti,omap3-dpll-per-clock", -+ "ti,omap3-dpll-per-j-type-clock", -+ "ti,omap4-dpll-clock", -+ "ti,omap4-dpll-core-clock", -+ "ti,omap4-dpll-m4xen-clock", -+ "ti,omap4-dpll-j-type-clock", -+ "ti,omap4-dpll-no-gate-clock", -+ "ti,omap4-dpll-no-gate-j-type-clock", -+ -+- #clock-cells : from common clock binding; shall be set to 0. -+- clocks : link phandles of parent clocks, first entry lists reference clock -+ and second entry bypass clock -+- reg : address and length of the register set for controlling the DPLL. -+ It contains the information of registers in the same order as described by -+ reg-names. -+- reg-names : array of the register names for controlling the device, sorted -+ in the same order as the reg property. -+ "control" - contains the control register base address -+ "idlest" - contains the idle status register base address -+ "autoidle" - contains the autoidle register base address -+ "mult-div1" - contains the multiplier / divider register base address -+ -+Optional properties: -+- ti,modes : available modes for the DPLL, bitmask of: -+ 0x02 - DPLL supports low power stop mode -+ 0x20 - DPLL can be put to low power bypass mode -+ 0x80 - DPLL can be put to lock mode (running) -+ Other values currently unsupported. -+- ti,clkdm-name : clockdomain name for the DPLL -+ -+Examples: -+ dpll_core_ck: dpll_core_ck@44e00490 { -+ #clock-cells = <0>; -+ compatible = "ti,omap4-dpll-core-clock"; -+ clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; -+ reg = <0x44e00490 0x4>, <0x44e0045c 0x4>, <0x0 0x4>, -+ <0x44e00468 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ }; -+ -+ dpll2_ck: dpll2_ck@48004004 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-dpll-clock"; -+ clocks = <&sys_ck>, <&dpll2_fck>; -+ ti,modes = <0xa2>; -+ reg = <0x48004004 0x4>, <0x48004024 0x4>, <0x48004034 0x4>, -+ <0x48004040 0x4>; -+ reg-names = "control", "idlest", "autoidle", "mult-div1"; -+ ti,clkdm-name = "dpll2_clkdm"; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/ti/gate.txt -@@ -0,0 +1,73 @@ -+Binding for Texas Instruments gate clock. -+ -+This binding uses the common clock binding[1]. This clock is -+quite much similar to the basic gate-clock [2], however, -+it supports a number of additional features. If no register -+is provided for this clock, the code assumes that a clockdomain -+will be controlled instead and the corresponding hw-ops for -+that is used. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+[2] Documentation/devicetree/bindings/clock/gate-clock.txt -+[3] Documentation/devicetree/bindings/clock/ti/clockdomain.txt -+ -+Required properties: -+- compatible : shall be one of: -+ "ti,gate-clock" - basic gate clock -+ "ti,dss-gate-clock" - gate clock with DSS specific hardware handling -+ "ti,am35xx-gate-clock" - gate clock with AM35xx specific hardware handling -+ "ti,clkdm-gate-clock" - clockdomain gate clock, which derives its functional -+ clock directly from a clockdomain, see [3] how -+ to map clockdomains properly -+ "ti,hsdiv-gate-clock" - gate clock with OMAP36xx specific hardware handling, -+ required for a hardware errata -+- #clock-cells : from common clock binding; shall be set to 0 -+- clocks : link to phandle of parent clock -+- reg : base address for register controlling adjustable gate, not needed for -+ ti,clkdm-gate-clock type -+- ti,enable-bit : bit shift for programming the clock gate, not needed for -+ ti,clkdm-gate-clock type -+ -+Optional properties: -+- ti,set-bit-to-disable : inverts default gate programming. Setting the bit -+ gates the clock and clearing the bit ungates the clock. -+ -+Examples: -+ mmchs2_fck: mmchs2_fck@48004a00 { -+ #clock-cells = <0>; -+ compatible = "ti,gate-clock"; -+ clocks = <&core_96m_fck>; -+ reg = <0x48004a00 0x4>; -+ ti,enable-bit = <25>; -+ }; -+ -+ dss1_alwon_fck_3430es2: dss1_alwon_fck_3430es2@48004e00 { -+ #clock-cells = <0>; -+ compatible = "ti,dss-gate-clock"; -+ clocks = <&dpll4_m4x2_ck>; -+ reg = <0x48004e00 0x4>; -+ ti,enable-bit = <0>; -+ }; -+ -+ emac_ick: emac_ick@4800259c { -+ #clock-cells = <0>; -+ compatible = "ti,am35xx-gate-clock"; -+ clocks = <&ipss_ick>; -+ reg = <0x4800259c 0x4>; -+ ti,enable-bit = <1>; -+ }; -+ -+ emu_src_ck: emu_src_ck { -+ #clock-cells = <0>; -+ compatible = "ti,clkdm-gate-clock"; -+ clocks = <&emu_src_mux_ck>; -+ }; -+ -+ dpll4_m2x2_ck: dpll4_m2x2_ck@48004d00 { -+ #clock-cells = <0>; -+ compatible = "ti,hsdiv-gate-clock"; -+ clocks = <&dpll4_m2x2_mul_ck>; -+ ti,enable-bit = <0x1b>; -+ reg = <0x48004d00 0x4>; -+ ti,set-bit-to-disable; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/ti/interface.txt -@@ -0,0 +1,53 @@ -+Binding for Texas Instruments interface clock. -+ -+This binding uses the common clock binding[1]. This clock is -+quite much similar to the basic gate-clock [2], however, -+it supports a number of additional features, including -+companion clock finding (match corresponding functional gate -+clock) and hardware autoidle enable / disable. -+ -+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -+[2] Documentation/devicetree/bindings/clock/gate-clock.txt -+ -+Required properties: -+- compatible : shall be one of: -+ "ti,omap3-interface-clock" - basic OMAP3 interface clock -+ "ti,omap3-no-wait-interface-clock" - interface clock which has no hardware -+ capability for waiting clock to be ready -+ "ti,omap3-hsotgusb-interface-clock" - interface clock with USB specific HW -+ handling -+ "ti,omap3-dss-interface-clock" - interface clock with DSS specific HW handling -+ "ti,omap3-ssi-interface-clock" - interface clock with SSI specific HW handling -+ "ti,am35xx-interface-clock" - interface clock with AM35xx specific HW handling -+- #clock-cells : from common clock binding; shall be set to 0 -+- clocks : link to phandle of parent clock -+- reg : base address for the control register -+ -+Optional properties: -+- ti,enable-bit : bit shift for the bit enabling/disabling the clock -+ (default 0) -+ -+Examples: -+ aes1_ick: aes1_ick@48004a14 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-interface-clock"; -+ clocks = <&security_l4_ick2>; -+ reg = <0x48004a14 0x4>; -+ ti,enable-bit = <3>; -+ }; -+ -+ cam_ick: cam_ick@48004f10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-no-wait-interface-clock"; -+ clocks = <&l4_ick>; -+ reg = <0x48004f10 0x4>; -+ ti,enable-bit = <0>; -+ }; -+ -+ ssi_ick_3430es2: ssi_ick_3430es2@48004a10 { -+ #clock-cells = <0>; -+ compatible = "ti,omap3-ssi-interface-clock"; -+ clocks = <&ssi_l4_ick>; -+ reg = <0x48004a10 0x4>; -+ ti,enable-bit = <0>; -+ }; ---- a/Documentation/devicetree/bindings/dma/atmel-dma.txt -+++ b/Documentation/devicetree/bindings/dma/atmel-dma.txt -@@ -28,7 +28,7 @@ The three cells in order are: - dependent: - - bit 7-0: peripheral identifier for the hardware handshaking interface. The - identifier can be different for tx and rx. -- - bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 1 for ASAP. -+ - bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 2 for ASAP. - - Example: - ---- /dev/null -+++ b/Documentation/devicetree/bindings/extcon/extcon-gpio-usbvid.txt -@@ -0,0 +1,20 @@ -+EXTCON FOR USB VIA GPIO -+ -+Required Properties: -+ - compatible : Should be "ti,gpio-usb-vid" for USB VBUS-ID detector -+ using gpios or "ti,gpio-usb-id" for USB ID pin detector -+ - gpios : phandle and args ID pin gpio and VBUS gpio. -+ The first gpio used for ID pin detection -+ and the second used for VBUS detection. -+ ID pin gpio is mandatory and VBUS is optional -+ depending on implementation. -+ -+Please refer to ../gpio/gpio.txt for details of the common GPIO bindings -+ -+Example: -+ -+ gpio_usbvid_extcon1 { -+ compatible = "ti,gpio-usb-vid"; -+ gpios = <&gpio1 1 0>, -+ <&gpio2 2 0>; -+ }; ---- a/Documentation/devicetree/bindings/extcon/extcon-palmas.txt -+++ b/Documentation/devicetree/bindings/extcon/extcon-palmas.txt -@@ -2,7 +2,8 @@ EXTCON FOR PALMAS/TWL CHIPS - - PALMAS USB COMPARATOR - Required Properties: -- - compatible : Should be "ti,palmas-usb" or "ti,twl6035-usb" -+ - compatible : Should be "ti,palmas-usb-vid". "ti,twl6035-usb" and -+ "ti,palmas-usb" is deprecated and is kept for backward compatibility. - - Optional Properties: - - ti,wakeup : To enable the wakeup comparator in probe ---- /dev/null -+++ b/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt -@@ -0,0 +1,71 @@ -+* PCF857x-compatible I/O expanders -+ -+The PCF857x-compatible chips have "quasi-bidirectional" I/O lines that can be -+driven high by a pull-up current source or driven low to ground. This combines -+the direction and output level into a single bit per line, which can't be read -+back. We can't actually know at initialization time whether a line is configured -+(a) as output and driving the signal low/high, or (b) as input and reporting a -+low/high value, without knowing the last value written since the chip came out -+of reset (if any). The only reliable solution for setting up line direction is -+thus to do it explicitly. -+ -+Required Properties: -+ -+ - compatible: should be one of the following. -+ - "maxim,max7328": For the Maxim MAX7378 -+ - "maxim,max7329": For the Maxim MAX7329 -+ - "nxp,pca8574": For the NXP PCA8574 -+ - "nxp,pca8575": For the NXP PCA8575 -+ - "nxp,pca9670": For the NXP PCA9670 -+ - "nxp,pca9671": For the NXP PCA9671 -+ - "nxp,pca9672": For the NXP PCA9672 -+ - "nxp,pca9673": For the NXP PCA9673 -+ - "nxp,pca9674": For the NXP PCA9674 -+ - "nxp,pca9675": For the NXP PCA9675 -+ - "nxp,pcf8574": For the NXP PCF8574 -+ - "nxp,pcf8574a": For the NXP PCF8574A -+ - "nxp,pcf8575": For the NXP PCF8575 -+ - "ti,tca9554": For the TI TCA9554 -+ -+ - reg: I2C slave address. -+ -+ - gpio-controller: Marks the device node as a gpio controller. -+ - #gpio-cells: Should be 2. The first cell is the GPIO number and the second -+ cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the -+ GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported. -+ -+Optional Properties: -+ -+ - lines-initial-states: Bitmask that specifies the initial state of each -+ line. When a bit is set to zero, the corresponding line will be initialized to -+ the input (pulled-up) state. When the bit is set to one, the line will be -+ initialized the the low-level output state. If the property is not specified -+ all lines will be initialized to the input state. -+ -+ The I/O expander can detect input state changes, and thus optionally act as -+ an interrupt controller. When the expander interrupt line is connected all the -+ following properties must be set. For more information please see the -+ interrupt controller device tree bindings documentation available at -+ Documentation/devicetree/bindings/interrupt-controller/interrupts.txt. -+ -+ - interrupt-controller: Identifies the node as an interrupt controller. -+ - #interrupt-cells: Number of cells to encode an interrupt source, shall be 2. -+ - interrupt-parent: phandle of the parent interrupt controller. -+ - interrupts: Interrupt specifier for the controllers interrupt. -+ -+ -+Please refer to gpio.txt in this directory for details of the common GPIO -+bindings used by client devices. -+ -+Example: PCF8575 I/O expander node -+ -+ pcf8575: gpio@20 { -+ compatible = "nxp,pcf8575"; -+ reg = <0x20>; -+ interrupt-parent = <&irqpin2>; -+ interrupts = <3 0>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/hwrng/omap_rng.txt -@@ -0,0 +1,22 @@ -+OMAP SoC HWRNG Module -+ -+Required properties: -+ -+- compatible : Should contain entries for this and backward compatible -+ RNG versions: -+ - "ti,omap2-rng" for OMAP2. -+ - "ti,omap4-rng" for OMAP4, OMAP5 and AM33XX. -+ Note that these two versions are incompatible. -+- ti,hwmods: Name of the hwmod associated with the RNG module -+- reg : Offset and length of the register set for the module -+- interrupts : the interrupt number for the RNG module. -+ Only used for "ti,omap4-rng". -+ -+Example: -+/* AM335x */ -+rng: rng@48310000 { -+ compatible = "ti,omap4-rng"; -+ ti,hwmods = "rng"; -+ reg = <0x48310000 0x2000>; -+ interrupts = <111>; -+}; ---- /dev/null -+++ b/Documentation/devicetree/bindings/input/touchscreen/atmel_mxt_ts.txt -@@ -0,0 +1,108 @@ -+Atmel MaxTouch Touchscreen -+-------------------------- -+Required properties: -+ - compatible: "atmel,mXT244" or "atmel,qt602240_ts" -+ or "atmel,atmel_mxt_ts" -+ - reg: I2C address of the chip -+ - interrupts: interrupt signal to which the chip is connected -+ - atmel,x-line: Number of x lines the touch object occupies in pixels -+ - atmel,y-line: Number of y lines the touch object occupies in pixels -+ - atmel,x-size: Horizontal resolution of touchscreen in pixels -+ - atmel,y-size: Vertical resolution of touchscreen in pixels -+ - atmel,blen: Sets the gain of the analog circuit in front of ADC -+ Gain setting depends on package type. Range: 0-3 -+ - atmel,threshold: Channel detection threshold value. Range: 0-255 -+ Typical: 30-80. Lower the threshold, higher the -+ sensitivity -+ - atmel,voltage: Nominal AVdd in uV for analog circuitry, greater than -+ or less than base voltage of 2.7V, used for optimizing -+ capacitive sensing. For example, if you want to -+ program an optimum voltage of 2.8V in your design, -+ specify 2800000 for this parameter -+ - atmel,orientation: touchscreen orientation, must be one of following, -+ as defined inside include/linux/i2c/atmel_mxt_ts.h -+ - 0: MXT_NORMAL - normal -+ - 1: MXT_DIAGONAL - diagonal -+ - 2: MXT_HORIZONTAL_FLIP - horizonally flipped -+ - 3: MXT_ROTATED_90_COUNTER - rotated by 90 degrees -+ counter-clockwise -+ - 4: MXT_VERTICAL_FLIP - vertically flipped -+ - 5: MXT_ROTATED_90 - rotated by 90 degress clockwise -+ - 6: MXT_ROTATED_180 - rotated by 180 degrees -+ - 7: MXT_DIAGONAL_COUNTER - diagonal counter -+ -+Optional properties: -+ - atmel,config: list of 8-bit register values for controller objects -+ in the following order. Number of objects and values depends on the -+ particular model of Atmel touch screen you are using. Please check -+ with your Atmel representative for helping you tune these values -+ GEN_COMMAND, GEN_POWER, GEN_ACQUIRE, TOUCH_MULTI -+ TOUCH_KEYARRAY, MXT244_COMMSCONFIG_T18, SPT_GPIOPWM, PROCI_GRIPFACE, -+ PROCG_NOISE, TOUCH_PROXIMITY, PROCI_ONETOUCH, SPT_SELFTEST, -+ PROCI_TWOTOUCH, SPT_CTECONFIG -+ Note: These register values can be specified here according to -+ the specific controller and platform configuration desired. The -+ driver does not configure these registers by default and leaves it -+ to the platform dts file to supply them -+ -+Example: -+ -+ &i2c1 { -+ mXT244:mXT244@4a { -+ reg = <0x4a>; -+ }; -+ }; -+ -+ &mXT244 { -+ compatible = "atmel,mXT244"; -+ interrupts = <0 119 0x4>; -+ -+ atmel,config = < -+ /* MXT244_GEN_COMMAND(6) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_GEN_POWER(7) */ -+ 0x20 0xff 0x32 -+ /* MXT244_GEN_ACQUIRE(8) */ -+ 0x0a 0x00 0x05 0x00 0x00 0x00 0x09 0x23 -+ /* MXT244_TOUCH_MULTI(9) */ -+ 0x00 0x00 0x00 0x13 0x0b 0x00 0x00 0x00 0x02 0x00 -+ 0x00 0x01 0x01 0x0e 0x0a 0x0a 0x0a 0x0a 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 -+ /* MXT244_TOUCH_KEYARRAY(15) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 -+ /* MXT244_COMMSCONFIG_T18(2) */ -+ 0x00 0x00 -+ /* MXT244_SPT_GPIOPWM(19) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_PROCI_GRIPFACE(20) */ -+ 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x50 0x28 0x04 -+ 0x0f 0x0a -+ /* MXT244_PROCG_NOISE(22) */ -+ 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x03 0x23 0x00 -+ 0x00 0x05 0x0f 0x19 0x23 0x2d 0x03 -+ /* MXT244_TOUCH_PROXIMITY(23) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_PROCI_ONETOUCH(24) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_SPT_SELFTEST(25) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ 0x00 0x00 0x00 0x00 -+ /* MXT244_PROCI_TWOTOUCH(27) */ -+ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 -+ /* MXT244_SPT_CTECONFIG(28) */ -+ 0x00 0x00 0x02 0x08 0x10 0x00 >; -+ -+ atmel,x_line = <18>; -+ atmel,y_line = <12>; -+ atmel,x_size = <800>; -+ atmel,y_size = <480>; -+ atmel,blen = <0x01>; -+ atmel,threshold = <30>; -+ atmel,voltage = <2800000>; -+ atmel,orient = <0x4>; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt -@@ -0,0 +1,26 @@ -+* Pixcir I2C touchscreen controllers -+ -+Required properties: -+- compatible: must be "pixcir,pixcir_ts" or "pixcir,pixcir_tangoc" -+- reg: I2C address of the chip -+- interrupts: interrupt to which the chip is connected -+- attb-gpio: GPIO connected to the ATTB line of the chip -+- x-size: horizontal resolution of touchscreen -+- y-size: vertical resolution of touchscreen -+ -+Example: -+ -+ i2c@00000000 { -+ /* ... */ -+ -+ pixcir_ts@5c { -+ compatible = "pixcir,pixcir_ts"; -+ reg = <0x5c>; -+ interrupts = <2 0>; -+ attb-gpio = <&gpf 2 0 2>; -+ x-size = <800>; -+ y-size = <600>; -+ }; -+ -+ /* ... */ -+ }; ---- a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt -+++ b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt -@@ -6,7 +6,7 @@ Required properties: - ti,wires: Wires refer to application modes i.e. 4/5/8 wire touchscreen - support on the platform. - ti,x-plate-resistance: X plate resistance -- ti,coordiante-readouts: The sequencer supports a total of 16 -+ ti,coordinate-readouts: The sequencer supports a total of 16 - programmable steps each step is used to - read a single coordinate. A single - readout is enough but multiple reads can ---- /dev/null -+++ b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt -@@ -0,0 +1,76 @@ -+OMAP2+ Mailbox Driver -+===================== -+ -+The OMAP mailbox hardware facilitates communication between different -+processors using a queued mailbox interrupt mechanism. The IP block is -+external to the various processor subsystems and is connected on an -+interconnect bus. The communication is achieved through a set of -+registers for message storage and interrupt configuration registers. -+ -+Each mailbox IP block has a certain number of h/w fifo queues and output -+interrupt lines. An output interrupt line is routed to a specific interrupt -+controller on a processor subsystem, and there can be more than one line -+going to a specific processor's interrupt controller. The interrupt line -+connections are fixed for an instance and are dictated by the IP integration -+into the SoC. Each interrupt line is programmable through a set of interrupt -+configuration registers, and have a rx and tx interrupt source per h/w fifo. -+Communication between different processors is achieved through the appropriate -+programming of the rx and tx interrupt sources on the appropriate interrupt -+lines. -+ -+The number of h/w fifo queues and interrupt lines dictate the usable registers. -+All the current OMAP SoCs except for the newest DRA7xx SoC has a single IP -+instance. DRA7xx has multiple instances with different number of h/w fifo -+queues and interrupt lines between different instances. The interrupt lines -+can also be routed to different processor sub-systems on DRA7xx as they are -+routed through the Crossbar, a kind of interrupt router/multiplexer. -+ -+The above two varying SoC IP integration parameters are defined specifically -+through the "ti,mbox-num-users" and "ti,mbox-num-fifos" device-tree properties. -+These are defined in the DT nodes since these design parameters can vary between -+one instance to another in an SoC (eg: DRA7xx) even though the base IP design -+is identical. -+ -+Required properties: -+-------------------- -+- compatible: Should be one of the following, -+ "ti,omap2-mailbox" for -+ OMAP2420, OMAP2430, OMAP3430, OMAP3630 SoCs -+ "ti,omap4-mailbox" for -+ OMAP44xx, OMAP54xx, AM33xx, AM43xx, DRA7xx SoCs -+- reg: Contains the mailbox register address range (base address -+ and length) -+- interrupts: Contains the interrupt information for the mailbox -+ device. The format is dependent on which interrupt -+ controller the OMAP device uses -+- ti,hwmods: Name of the hwmod associated with the mailbox -+- ti,mbox-num-users: Number of targets (processor devices) that the mailbox device -+ can interrupt -+- ti,mbox-num-fifos: Number of h/w fifos within the mailbox device -+- ti,mbox-names: Array of the names of the mailboxes -+- ti,mbox-data: Mailbox descriptor data private to each mailbox. The 4 -+ cells represent the following data, -+ Cell #1 (tx_id) - mailbox fifo id used for -+ transmitting messages -+ Cell #2 (rx_id) - mailbox fifo id on which messages -+ are received -+ Cell #3 (irq_id) - irq identifier index number to use -+ from the interrupts data -+ Cell #4 (usr_id) - mailbox user id for identifying the -+ interrupt into the MPU interrupt -+ controller. -+ -+Example: -+-------- -+ -+/* OMAP4 */ -+mailbox: mailbox@4a0f4000 { -+ compatible = "ti,omap4-mailbox"; -+ reg = <0x4a0f4000 0x200>; -+ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "mailbox"; -+ ti,mbox-num-users = <3>; -+ ti,mbox-num-fifos = <8>; -+ ti,mbox-names = "mbox-ipu", "mbox-dsp"; -+ ti,mbox-data = <0 1 0 0>, <3 2 0 0>; -+}; ---- /dev/null -+++ b/Documentation/devicetree/bindings/mfd/tps65218.txt -@@ -0,0 +1,27 @@ -+The TPS65218 Integrated Power Management Chips. -+These chips are connected to an i2c bus. -+ -+Required properties: -+- compatible : Must be "ti,tps65218"; -+- interrupts : This i2c device has an IRQ line connected to the main SoC -+- interrupt-controller : Since the tps65218 support several interrupts -+ internally, it is considered as an interrupt controller cascaded to the SoC. -+- #interrupt-cells = <2>; -+- interrupt-parent : The parent interrupt controller. -+ -+Optional node: -+- Child nodes contain in the tps65218. -+ It supports a number of features. -+ The children nodes will thus depend of the capability of the variant. -+ -+Example: -+/* -+ * Integrated Power Management Chip -+ */ -+tps@24 { -+ compatible = "ti,tps65218"; -+ reg = <0x24>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ interrupt-parent = <&gic>; -+}; ---- a/Documentation/devicetree/bindings/mfd/twl6040.txt -+++ b/Documentation/devicetree/bindings/mfd/twl6040.txt -@@ -19,6 +19,8 @@ Required properties: - - Optional properties, nodes: - - enable-active-high: To power on the twl6040 during boot. -+- clocks: phandle to the clk32k clock provider -+- clock-names: Must be "clk32k" - - Vibra functionality - Required properties: ---- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt -+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt -@@ -20,8 +20,29 @@ ti,dual-volt: boolean, supports dual vol - ti,non-removable: non-removable slot (like eMMC) - ti,needs-special-reset: Requires a special softreset sequence - ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed -+dmas: List of DMA specifiers with the controller specific format -+as described in the generic DMA client binding. A tx and rx -+specifier is required. -+dma-names: List of DMA request names. These strings correspond -+1:1 with the DMA specifiers listed in dmas. The string naming is -+to be "rx" and "tx" for RX and TX DMA requests, respectively. -+ -+Examples: -+ -+[hwmod populated DMA resources] -+ -+ mmc1: mmc@0x4809c000 { -+ compatible = "ti,omap4-hsmmc"; -+ reg = <0x4809c000 0x400>; -+ ti,hwmods = "mmc1"; -+ ti,dual-volt; -+ bus-width = <4>; -+ vmmc-supply = <&vmmc>; /* phandle to regulator node */ -+ ti,non-removable; -+ }; -+ -+[generic DMA request binding] - --Example: - mmc1: mmc@0x4809c000 { - compatible = "ti,omap4-hsmmc"; - reg = <0x4809c000 0x400>; -@@ -30,4 +51,7 @@ Example: - bus-width = <4>; - vmmc-supply = <&vmmc>; /* phandle to regulator node */ - ti,non-removable; -+ dmas = <&edma 24 -+ &edma 25>; -+ dma-names = "tx", "rx"; - }; ---- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt -+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt -@@ -21,13 +21,11 @@ Optional properties: - is wired that way. If not specified, a bus - width of 8 is assumed. - -- - ti,nand-ecc-opt: A string setting the ECC layout to use. One of: -- -- "sw" Software method (default) -- "hw" Hardware method -- "hw-romcode" gpmc hamming mode method & romcode layout -+ - ti,nand-ecc-scheme: A string setting the ECC layout to use. One of: -+ "ham1" 1-bit Hamming ecc code - "bch4" 4-bit BCH ecc code - "bch8" 8-bit BCH ecc code -+ "bch16" 16-bit BCH ecc code - - - ti,nand-xfer-type: A string setting the data transfer type. One of: - -@@ -36,8 +34,11 @@ Optional properties: - "prefetch-dma" Prefetch enabled sDMA mode - "prefetch-irq" Prefetch enabled irq mode - -- - elm_id: Specifies elm device node. This is required to support BCH -- error correction using ELM module. -+ - ti,elm-id: Specifies pHandle of the ELM devicetree node. -+ ELM is an on-chip hardware engine on TI SoC which is used for -+ locating ECC errors for BCHx algorithms. SoC devices which have -+ ELM hardware engines should specify this device node in .dtsi -+ Using ELM for ECC error correction frees some CPU cycles. - - For inline partiton table parsing (optional): - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/cpsw-phy-sel.txt -@@ -0,0 +1,28 @@ -+TI CPSW Phy mode Selection Device Tree Bindings -+----------------------------------------------- -+ -+Required properties: -+- compatible : Should be "ti,am3352-cpsw-phy-sel" -+- reg : physical base address and size of the cpsw -+ registers map -+- reg-names : names of the register map given in "reg" node -+ -+Optional properties: -+-rmii-clock-ext : If present, the driver will configure the RMII -+ interface to external clock usage -+ -+Examples: -+ -+ phy_sel: cpsw-phy-sel@44e10650 { -+ compatible = "ti,am3352-cpsw-phy-sel"; -+ reg= <0x44e10650 0x4>; -+ reg-names = "gmii-sel"; -+ }; -+ -+(or) -+ phy_sel: cpsw-phy-sel@44e10650 { -+ compatible = "ti,am3352-cpsw-phy-sel"; -+ reg= <0x44e10650 0x4>; -+ reg-names = "gmii-sel"; -+ rmii-clock-ext; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/smsc95xx.txt -@@ -0,0 +1,16 @@ -+* Smart Mixed-Signal Connectivity (SMSC) 95xx Controller -+ -+Required properties: -+None -+ -+Optional properties: -+- mac-address - Read the mac address that was stored by uBoot -+- local-address - Read the mac address that was stored by uBoot -+- address - Read the mac address that was stored by uBoot -+ -+Examples: -+ -+smsc0: smsc95xx@0 { -+ /* Filled in by U-Boot */ -+ mac-address = [ 00 00 00 00 00 00 ]; -+}; ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/omap-phy.txt -@@ -0,0 +1,78 @@ -+OMAP PHY: DT DOCUMENTATION FOR PHYs in OMAP PLATFORM -+ -+OMAP CONTROL PHY -+ -+Required properties: -+ - compatible: Should be one of -+ "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4. -+ "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register -+ e.g. USB2_PHY on OMAP5. -+ "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control -+ e.g. USB3 PHY and SATA PHY on OMAP5. -+ "ti,control-phy-dra7usb2" - if it has power down register like USB2 PHY on -+ DRA7 platform. -+ "ti,control-phy-am437usb2" - if it has power down register like USB2 PHY on -+ AM437 platform. -+ - reg : Address and length of the register set for the device. It contains -+ the address of "otghs_control" for control-phy-otghs or "power" register -+ for other types. -+ - reg-names: should be "otghs_control" control-phy-otghs and "power" for -+ other types. -+ -+omap_control_otghs: omap-control-phy@4a002300 { -+ compatible = "ti,control-phy-otghs"; -+ reg = <0x4a00233c 0x4>; -+ reg-names = "otghs_control"; -+}; -+ -+OMAP USB2 PHY -+ -+Required properties: -+ - compatible: Should be either of -+ * "ti,omap-usb2" for OMAP4,OMAP5,DRA7 -+ * "ti,am437x-usb2" for AM437x -+ - reg : Address and length of the register set for the device. -+ - #phy-cells: determine the number of cells that should be given in the -+ phandle while referencing this phy. -+ -+Optional properties: -+ - ctrl-module : phandle of the control module used by PHY driver to power on -+ the PHY. -+ -+This is usually a subnode of ocp2scp to which it is connected. -+ -+usb2phy@4a0ad080 { -+ compatible = "ti,omap-usb2"; -+ reg = <0x4a0ad080 0x58>; -+ ctrl-module = <&omap_control_usb>; -+ #phy-cells = <0>; -+}; -+ -+OMAP PIPE3 PHY -+ -+Required properties: -+ - compatible: Should be "ti,phy-pipe3-usb3" or "ti,phy-pipe3-sata" -+ - reg : Address and length of the register set for the device. -+ - reg-names: The names of the register addresses corresponding to the registers -+ filled in "reg". -+ - #phy-cells: determine the number of cells that should be given in the -+ phandle while referencing this phy. -+ - clocks: phandle to PHY clocks i.e. 32KHz wakup clock, 960MHz clock and lfps clock. -+ Use as per Documentation/devicetree/bindings/clock/clock-bindings.txt -+ - clock-names: should contain "wkupclk", "refclk1" and "refclk2" -+ -+Optional properties: -+ - ctrl-module : phandle of the control module used by PHY driver to power on -+ the PHY. -+ -+This is usually a subnode of ocp2scp to which it is connected. -+ -+usb3phy@4a084400 { -+ compatible = "ti,omap-usb3"; -+ reg = <0x4a084400 0x80>, -+ <0x4a084800 0x64>, -+ <0x4a084c00 0x40>; -+ reg-names = "phy_rx", "phy_tx", "pll_ctrl"; -+ ctrl-module = <&omap_control_usb>; -+ #phy-cells = <0>; -+}; ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt -@@ -0,0 +1,66 @@ -+This document explains only the device tree data binding. For general -+information about PHY subsystem refer to Documentation/phy.txt -+ -+PHY device node -+=============== -+ -+Required Properties: -+#phy-cells: Number of cells in a PHY specifier; The meaning of all those -+ cells is defined by the binding for the phy node. The PHY -+ provider can use the values in cells to find the appropriate -+ PHY. -+ -+For example: -+ -+phys: phy { -+ compatible = "xxx"; -+ reg = <...>; -+ . -+ . -+ #phy-cells = <1>; -+ . -+ . -+}; -+ -+That node describes an IP block (PHY provider) that implements 2 different PHYs. -+In order to differentiate between these 2 PHYs, an additonal specifier should be -+given while trying to get a reference to it. -+ -+PHY user node -+============= -+ -+Required Properties: -+phys : the phandle for the PHY device (used by the PHY subsystem) -+phy-names : the names of the PHY corresponding to the PHYs present in the -+ *phys* phandle -+ -+Example 1: -+usb1: usb_otg_ss@xxx { -+ compatible = "xxx"; -+ reg = <xxx>; -+ . -+ . -+ phys = <&usb2_phy>, <&usb3_phy>; -+ phy-names = "usb2phy", "usb3phy"; -+ . -+ . -+}; -+ -+This node represents a controller that uses two PHYs, one for usb2 and one for -+usb3. -+ -+Example 2: -+usb2: usb_otg_ss@xxx { -+ compatible = "xxx"; -+ reg = <xxx>; -+ . -+ . -+ phys = <&phys 1>; -+ phy-names = "usbphy"; -+ . -+ . -+}; -+ -+This node represents a controller that uses one of the PHYs of the PHY provider -+device defined previously. Note that the phy handle has an additional specifier -+"1" to differentiate between the two PHYs. ---- /dev/null -+++ b/Documentation/devicetree/bindings/regulator/ti-avs-class0.txt -@@ -0,0 +1,66 @@ -+Texas Instrument SmartReflex AVS Class 0 Regulator -+ -+Required properties: -+- compatible: "ti,avsclass0" -+- reg: Should contain Efuse registers location and length -+- avs-supply: The supply for AVS block -+- efuse-settings: An array of 2-tuples items, and each item consists -+ of Voltage index and efuse offset(from reg) like: <voltage offset> -+ voltage: Voltage index in microvolts (also called nominal voltage) -+ offset: ofset in bytes from base provided in reg -+ NOTE: min_uV, max_uV are pickedup from this list -+ -+Optional properties: -+- voltage-tolerance: Specify the voltage tolerance in percentage -+- ti,avsclass0-microvolt-values: Boolean property indicating that the efuse -+ values are in microvolts -+ -+Example #1: single rails: -+soc.dtsi: -+avs_mpu: regulator-avs@0x40200000 { -+ compatible = "ti,avsclass0"; -+ reg = <0x40200000 0x20>; -+ efuse-settings = <975000 0 -+ 1075000 4 -+ 1200000 8>; -+}; -+ -+avs_core: regulator-avs@0x40300000 { -+ compatible = "ti,avsclass0"; -+ reg = <0x40300000 0x20>; -+ efuse-settings = <975000 0 -+ 1050000 4>; -+}; -+ -+board.dtsi: -+&avs_mpu { -+ avs-supply = <&vcc>; -+}; -+&avs_core { -+ avs-supply = <&smps2>; -+}; -+ -+Example #2: Ganged (combined) rails: -+soc.dtsi: -+avs_mpu: regulator-avs@0x40200000 { -+ compatible = "ti,avsclass0"; -+ reg = <0x40200000 0x20>; -+ efuse-settings = <975000 0 -+ 1075000 4 -+ 1200000 8>; -+}; -+ -+avs_core: regulator-avs@0x40300000 { -+ compatible = "ti,avsclass0"; -+ reg = <0x40300000 0x20>; -+ efuse-settings = <975000 0 -+ 1050000 4>; -+}; -+ -+board.dtsi: -+&avs_mpu { -+ avs-supply = <&smps3>; -+}; -+&avs_core { -+ avs-supply = <&smps3>; -+}; ---- /dev/null -+++ b/Documentation/devicetree/bindings/regulator/tps65218.txt -@@ -0,0 +1,22 @@ -+TPS65218 family of regulators -+ -+Required properties: -+For tps65218 regulators/LDOs -+- compatible: -+ - "ti,tps65218-dcdc1" for DCDC1 -+ - "ti,tps65218-dcdc2" for DCDC2 -+ - "ti,tps65218-dcdc3" for DCDC3 -+ - "ti,tps65218-dcdc4" for DCDC4 -+ - "ti,tps65218-dcdc5" for DCDC5 -+ - "ti,tps65218-dcdc6" for DCDC6 -+ - "ti,tps65218-ldo1" for LDO1 LDO -+ -+Optional properties: -+- Any optional property defined in bindings/regulator/regulator.txt -+ -+Example: -+ xyz: regulator@0 { -+ compatible = "ti,tps65218-dcdc1"; -+ regulator-min-microvolt = <1000000>; -+ regulator-max-microvolt = <3000000>; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt -@@ -0,0 +1,58 @@ -+* Texas Instruments SoC audio setups with TLV320AIC3X Codec -+ -+Required properties: -+- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx -+- ti,model : The user-visible name of this sound complex. -+- ti,audio-codec : The phandle of the TLV320AIC3x audio codec -+- ti,mcasp-controller : The phandle of the McASP controller -+- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec -+- ti,audio-routing : A list of the connections between audio components. -+ Each entry is a pair of strings, the first being the connection's sink, -+ the second being the connection's source. Valid names for sources and -+ sinks are the codec's pins, and the jacks on the board: -+ -+ TLV320AIC3X pins: -+ -+ * LLOUT -+ * RLOUT -+ * MONO_LOUT -+ * HPLOUT -+ * HPROUT -+ * HPLCOM -+ * HPRCOM -+ * MIC3L -+ * MIC3R -+ * LINE1L -+ * LINE2L -+ * LINE1R -+ * LINE2R -+ -+ Board connectors: -+ -+ * Headphone Jack -+ * Line Out -+ * Mic Jack -+ * Line In -+ -+ -+Example: -+ -+sound { -+ compatible = "ti,da830-evm-audio"; -+ ti,model = "DA830 EVM"; -+ ti,audio-codec = <&tlv320aic3x>; -+ ti,mcasp-controller = <&mcasp1>; -+ ti,codec-clock-rate = <12000000>; -+ ti,audio-routing = -+ "Headphone Jack", "HPLOUT", -+ "Headphone Jack", "HPROUT", -+ "Line Out", "LLOUT", -+ "Line Out", "RLOUT", -+ "MIC3L", "Mic Bias 2V", -+ "MIC3R", "Mic Bias 2V", -+ "Mic Bias 2V", "Mic Jack", -+ "LINE1L", "Line In", -+ "LINE2L", "Line In", -+ "LINE1R", "Line In", -+ "LINE2R", "Line In"; -+}; ---- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt -+++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt -@@ -6,15 +6,21 @@ Required properties: - "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms - "ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx) - --- reg : Should contain McASP registers offset and length --- interrupts : Interrupt number for McASP -+- reg : Should contain McASP registers address and length for mpu and -+ optionally for dma controller access. -+- reg-names : The mandatory reg-range must be named "mpu" and the optional DMA -+ reg-range must be named "dma". For backward compatibility it is -+ good to keep "mpu" first in the list. - - op-mode : I2S/DIT ops mode. - - tdm-slots : Slots for TDM operation. --- num-serializer : Serializers used by McASP. --- serial-dir : A list of serializer pin mode. The list number should be equal -- to "num-serializer" parameter. Each entry is a number indication -- serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX) -- -+- serial-dir : A list of serializer configuration. Each entry is a number -+ indication serializer pin direction. -+ (0 - INACTIVE, 1 - TX, 2 - RX) -+- dmas: two element list of DMA controller phandles and DMA request line -+ ordered pairs. -+- dma-names: identifier string for each DMA request line in the dmas property. -+ These strings correspond 1:1 with the ordered pairs in dmas. The dma -+ identifiers must be "rx" and "tx". - - Optional properties: - -@@ -23,6 +29,8 @@ Optional properties: - - rx-num-evt : FIFO levels. - - sram-size-playback : size of sram to be allocated during playback - - sram-size-capture : size of sram to be allocated during capture -+- interrupts : Interrupt numbers for McASP, currently not used by the driver -+- interrupt-names : Known interrupt names are "tx" and "rx" - - Example: - -@@ -31,10 +39,11 @@ mcasp0: mcasp0@1d00000 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0x100000 0x3000>; -+ reg-names "mpu"; - interrupts = <82 83>; -+ interrupts-names = "tx", "rx"; - op-mode = <0>; /* MCASP_IIS_MODE */ - tdm-slots = <2>; -- num-serializer = <16>; - serial-dir = < - 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */ - 0 0 0 0 ---- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt -+++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt -@@ -24,10 +24,36 @@ Optional properties: - 3 - MICBIAS output is connected to AVDD, - If this node is not mentioned or if the value is incorrect, then MicBias - is powered down. -+- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the -+ device as covered in Documentation/devicetree/bindings/regulator/regulator.txt -+ -+CODEC output pins: -+ * LLOUT -+ * RLOUT -+ * MONO_LOUT -+ * HPLOUT -+ * HPROUT -+ * HPLCOM -+ * HPRCOM -+ -+CODEC input pins: -+ * MIC3L -+ * MIC3R -+ * LINE1L -+ * LINE2L -+ * LINE1R -+ * LINE2R -+ -+The pins can be used in referring sound node's audio-routing property. - - Example: - - tlv320aic3x: tlv320aic3x@1b { - compatible = "ti,tlv320aic3x"; - reg = <0x1b>; -+ -+ AVDD-supply = <®ulator>; -+ IOVDD-supply = <®ulator>; -+ DRVDD-supply = <®ulator>; -+ DVDD-supply = <®ulator>; - }; ---- a/Documentation/devicetree/bindings/spi/omap-spi.txt -+++ b/Documentation/devicetree/bindings/spi/omap-spi.txt -@@ -2,8 +2,8 @@ OMAP2+ McSPI device - - Required properties: - - compatible : -- - "ti,omap2-spi" for OMAP2 & OMAP3. -- - "ti,omap4-spi" for OMAP4+. -+ - "ti,omap2-mcspi" for OMAP2 & OMAP3. -+ - "ti,omap4-mcspi" for OMAP4+. - - ti,spi-num-cs : Number of chipselect supported by the instance. - - ti,hwmods: Name of the hwmod associated to the McSPI - - ti,pindir-d0-out-d1-in: Select the D0 pin as output and D1 as ---- a/Documentation/devicetree/bindings/usb/dwc3.txt -+++ b/Documentation/devicetree/bindings/usb/dwc3.txt -@@ -6,11 +6,13 @@ Required properties: - - compatible: must be "snps,dwc3" - - reg : Address and length of the register set for the device - - interrupts: Interrupts used by the dwc3 controller. -+ -+Optional properties: - - usb-phy : array of phandle for the PHY device. The first element - in the array is expected to be a handle to the USB2/HS PHY and - the second element is expected to be a handle to the USB3/SS PHY -- --Optional properties: -+ - phys: from the *Generic PHY* bindings -+ - phy-names: from the *Generic PHY* bindings - - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - - This is usually a subnode to DWC3 glue to which it is connected. ---- a/Documentation/devicetree/bindings/usb/omap-usb.txt -+++ b/Documentation/devicetree/bindings/usb/omap-usb.txt -@@ -3,9 +3,6 @@ OMAP GLUE AND OTHER OMAP SPECIFIC COMPON - OMAP MUSB GLUE - - compatible : Should be "ti,omap4-musb" or "ti,omap3-musb" - - ti,hwmods : must be "usb_otg_hs" -- - ti,has-mailbox : to specify that omap uses an external mailbox -- (in control module) to communicate with the musb core during device connect -- and disconnect. - - multipoint : Should be "1" indicating the musb controller supports - multipoint. This is a MUSB configuration-specific setting. - - num-eps : Specifies the number of endpoints. This is also a -@@ -19,6 +16,9 @@ OMAP MUSB GLUE - - power : Should be "50". This signifies the controller can supply up to - 100mA when operating in host mode. - - usb-phy : the phandle for the PHY device -+ - phys : the phandle for the PHY device (used by generic PHY framework) -+ - phy-names : the names of the PHY corresponding to the PHYs present in the -+ *phy* phandle. - - Optional properties: - - ctrl-module : phandle of the control module this glue uses to write to -@@ -28,11 +28,12 @@ SOC specific device node entry - usb_otg_hs: usb_otg_hs@4a0ab000 { - compatible = "ti,omap4-musb"; - ti,hwmods = "usb_otg_hs"; -- ti,has-mailbox; - multipoint = <1>; - num-eps = <16>; - ram-bits = <12>; - ctrl-module = <&omap_control_usb>; -+ phys = <&usb2_phy>; -+ phy-names = "usb2-phy"; - }; - - Board specific device node entry -@@ -74,26 +75,3 @@ omap_dwc3 { - utmi-mode = <2>; - ranges; - }; -- --OMAP CONTROL USB -- --Required properties: -- - compatible: Should be "ti,omap-control-usb" -- - reg : Address and length of the register set for the device. It contains -- the address of "control_dev_conf" and "otghs_control" or "phy_power_usb" -- depending upon omap4 or omap5. -- - reg-names: The names of the register addresses corresponding to the registers -- filled in "reg". -- - ti,type: This is used to differentiate whether the control module has -- usb mailbox or usb3 phy power. omap4 has usb mailbox in control module to -- notify events to the musb core and omap5 has usb3 phy power register to -- power on usb3 phy. Should be "1" if it has mailbox and "2" if it has usb3 -- phy power. -- --omap_control_usb: omap-control-usb@4a002300 { -- compatible = "ti,omap-control-usb"; -- reg = <0x4a002300 0x4>, -- <0x4a00233c 0x4>; -- reg-names = "control_dev_conf", "otghs_control"; -- ti,type = <1>; --}; ---- a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt -+++ b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt -@@ -15,7 +15,7 @@ Optional properties: - - - vcc-supply: phandle to the regulator that provides RESET to the PHY. - --- reset-supply: phandle to the regulator that provides power to the PHY. -+- reset-gpios: Should specify the GPIO for reset. - - Example: - -@@ -25,10 +25,9 @@ Example: - clocks = <&osc 0>; - clock-names = "main_clk"; - vcc-supply = <&hsusb1_vcc_regulator>; -- reset-supply = <&hsusb1_reset_regulator>; -+ reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; - }; - - hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator - and expects that clock to be configured to 19.2MHz by the NOP PHY driver. --hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator --controls RESET. -+hsusb1_vcc_regulator provides power to the PHY and GPIO 7 controls RESET. ---- a/Documentation/devicetree/bindings/usb/usb-phy.txt -+++ /dev/null -@@ -1,42 +0,0 @@ --USB PHY -- --OMAP USB2 PHY -- --Required properties: -- - compatible: Should be "ti,omap-usb2" -- - reg : Address and length of the register set for the device. -- --Optional properties: -- - ctrl-module : phandle of the control module used by PHY driver to power on -- the PHY. -- --This is usually a subnode of ocp2scp to which it is connected. -- --usb2phy@4a0ad080 { -- compatible = "ti,omap-usb2"; -- reg = <0x4a0ad080 0x58>; -- ctrl-module = <&omap_control_usb>; --}; -- --OMAP USB3 PHY -- --Required properties: -- - compatible: Should be "ti,omap-usb3" -- - reg : Address and length of the register set for the device. -- - reg-names: The names of the register addresses corresponding to the registers -- filled in "reg". -- --Optional properties: -- - ctrl-module : phandle of the control module used by PHY driver to power on -- the PHY. -- --This is usually a subnode of ocp2scp to which it is connected. -- --usb3phy@4a084400 { -- compatible = "ti,omap-usb3"; -- reg = <0x4a084400 0x80>, -- <0x4a084800 0x64>, -- <0x4a084c00 0x40>; -- reg-names = "phy_rx", "phy_tx", "pll_ctrl"; -- ctrl-module = <&omap_control_usb>; --}; ---- /dev/null -+++ b/Documentation/devicetree/bindings/video/da8xx-fb.txt -@@ -0,0 +1,42 @@ -+TI LCD Controller on DA830/DA850/AM335x SoC's -+ -+Required properties: -+- compatible: -+ DA830, DA850 - "ti,da8xx-tilcdc" -+ AM335x SoC's - "ti,am33xx-tilcdc" -+- reg: Address range of lcdc register set -+- interrupts: lcdc interrupt -+- display-timings: typical videomode of lcd panel, represented as child. -+ Refer Documentation/devicetree/bindings/video/display-timing.txt for -+ display timing binding details. If multiple videomodes are mentioned -+ in display timings node, typical videomode has to be mentioned as the -+ native mode or it has to be first child (driver cares only for native -+ videomode). -+ -+Recommended properties: -+- ti,hwmods: Name of the hwmod associated to the LCDC -+ -+Example for am335x SoC's: -+ -+lcdc@4830e000 { -+ compatible = "ti,am33xx-tilcdc"; -+ reg = <0x4830e000 0x1000>; -+ interrupts = <36>; -+ ti,hwmods = "lcdc"; -+ status = "okay"; -+ display-timings { -+ 800x480p62 { -+ clock-frequency = <30000000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <39>; -+ hback-porch = <39>; -+ hsync-len = <47>; -+ vback-porch = <29>; -+ vfront-porch = <13>; -+ vsync-len = <2>; -+ hsync-active = <1>; -+ vsync-active = <1>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/Documentation/phy.txt -@@ -0,0 +1,166 @@ -+ PHY SUBSYSTEM -+ Kishon Vijay Abraham I <kishon@ti.com> -+ -+This document explains the Generic PHY Framework along with the APIs provided, -+and how-to-use. -+ -+1. Introduction -+ -+*PHY* is the abbreviation for physical layer. It is used to connect a device -+to the physical medium e.g., the USB controller has a PHY to provide functions -+such as serialization, de-serialization, encoding, decoding and is responsible -+for obtaining the required data transmission rate. Note that some USB -+controllers have PHY functionality embedded into it and others use an external -+PHY. Other peripherals that use PHY include Wireless LAN, Ethernet, -+SATA etc. -+ -+The intention of creating this framework is to bring the PHY drivers spread -+all over the Linux kernel to drivers/phy to increase code re-use and for -+better code maintainability. -+ -+This framework will be of use only to devices that use external PHY (PHY -+functionality is not embedded within the controller). -+ -+2. Registering/Unregistering the PHY provider -+ -+PHY provider refers to an entity that implements one or more PHY instances. -+For the simple case where the PHY provider implements only a single instance of -+the PHY, the framework provides its own implementation of of_xlate in -+of_phy_simple_xlate. If the PHY provider implements multiple instances, it -+should provide its own implementation of of_xlate. of_xlate is used only for -+dt boot case. -+ -+#define of_phy_provider_register(dev, xlate) \ -+ __of_phy_provider_register((dev), THIS_MODULE, (xlate)) -+ -+#define devm_of_phy_provider_register(dev, xlate) \ -+ __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate)) -+ -+of_phy_provider_register and devm_of_phy_provider_register macros can be used to -+register the phy_provider and it takes device and of_xlate as -+arguments. For the dt boot case, all PHY providers should use one of the above -+2 macros to register the PHY provider. -+ -+void devm_of_phy_provider_unregister(struct device *dev, -+ struct phy_provider *phy_provider); -+void of_phy_provider_unregister(struct phy_provider *phy_provider); -+ -+devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to -+unregister the PHY. -+ -+3. Creating the PHY -+ -+The PHY driver should create the PHY in order for other peripheral controllers -+to make use of it. The PHY framework provides 2 APIs to create the PHY. -+ -+struct phy *phy_create(struct device *dev, const struct phy_ops *ops, -+ struct phy_init_data *init_data); -+struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops, -+ struct phy_init_data *init_data); -+ -+The PHY drivers can use one of the above 2 APIs to create the PHY by passing -+the device pointer, phy ops and init_data. -+phy_ops is a set of function pointers for performing PHY operations such as -+init, exit, power_on and power_off. *init_data* is mandatory to get a reference -+to the PHY in the case of non-dt boot. See section *Board File Initialization* -+on how init_data should be used. -+ -+Inorder to dereference the private data (in phy_ops), the phy provider driver -+can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in -+phy_ops to get back the private data. -+ -+4. Getting a reference to the PHY -+ -+Before the controller can make use of the PHY, it has to get a reference to -+it. This framework provides the following APIs to get a reference to the PHY. -+ -+struct phy *phy_get(struct device *dev, const char *string); -+struct phy *devm_phy_get(struct device *dev, const char *string); -+ -+phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot, -+the string arguments should contain the phy name as given in the dt data and -+in the case of non-dt boot, it should contain the label of the PHY. -+The only difference between the two APIs is that devm_phy_get associates the -+device with the PHY using devres on successful PHY get. On driver detach, -+release function is invoked on the the devres data and devres data is freed. -+ -+5. Releasing a reference to the PHY -+ -+When the controller no longer needs the PHY, it has to release the reference -+to the PHY it has obtained using the APIs mentioned in the above section. The -+PHY framework provides 2 APIs to release a reference to the PHY. -+ -+void phy_put(struct phy *phy); -+void devm_phy_put(struct device *dev, struct phy *phy); -+ -+Both these APIs are used to release a reference to the PHY and devm_phy_put -+destroys the devres associated with this PHY. -+ -+6. Destroying the PHY -+ -+When the driver that created the PHY is unloaded, it should destroy the PHY it -+created using one of the following 2 APIs. -+ -+void phy_destroy(struct phy *phy); -+void devm_phy_destroy(struct device *dev, struct phy *phy); -+ -+Both these APIs destroy the PHY and devm_phy_destroy destroys the devres -+associated with this PHY. -+ -+7. PM Runtime -+ -+This subsystem is pm runtime enabled. So while creating the PHY, -+pm_runtime_enable of the phy device created by this subsystem is called and -+while destroying the PHY, pm_runtime_disable is called. Note that the phy -+device created by this subsystem will be a child of the device that calls -+phy_create (PHY provider device). -+ -+So pm_runtime_get_sync of the phy_device created by this subsystem will invoke -+pm_runtime_get_sync of PHY provider device because of parent-child relationship. -+It should also be noted that phy_power_on and phy_power_off performs -+phy_pm_runtime_get_sync and phy_pm_runtime_put respectively. -+There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync, -+phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and -+phy_pm_runtime_forbid for performing PM operations. -+ -+8. Board File Initialization -+ -+Certain board file initialization is necessary in order to get a reference -+to the PHY in the case of non-dt boot. -+Say we have a single device that implements 3 PHYs that of USB, SATA and PCIe, -+then in the board file the following initialization should be done. -+ -+struct phy_consumer consumers[] = { -+ PHY_CONSUMER("dwc3.0", "usb"), -+ PHY_CONSUMER("pcie.0", "pcie"), -+ PHY_CONSUMER("sata.0", "sata"), -+}; -+PHY_CONSUMER takes 2 parameters, first is the device name of the controller -+(PHY consumer) and second is the port name. -+ -+struct phy_init_data init_data = { -+ .consumers = consumers, -+ .num_consumers = ARRAY_SIZE(consumers), -+}; -+ -+static const struct platform_device pipe3_phy_dev = { -+ .name = "pipe3-phy", -+ .id = -1, -+ .dev = { -+ .platform_data = { -+ .init_data = &init_data, -+ }, -+ }, -+}; -+ -+then, while doing phy_create, the PHY driver should pass this init_data -+ phy_create(dev, ops, pdata->init_data); -+ -+and the controller driver (phy consumer) should pass the port name along with -+the device to get a reference to the PHY -+ phy_get(dev, "pcie"); -+ -+9. DeviceTree Binding -+ -+The documentation for PHY dt binding can be found @ -+Documentation/devicetree/bindings/phy/phy-bindings.txt ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -322,6 +322,7 @@ struct ahci_host_priv { - u32 em_buf_sz; /* EM buffer size in byte */ - u32 em_msg_type; /* EM message type */ - struct clk *clk; /* Only for platforms supporting clk */ -+ struct phy *phy; /* If platforms use phy */ - void *plat_data; /* Other platform data */ - }; - ---- a/drivers/ata/ahci_platform.c -+++ b/drivers/ata/ahci_platform.c -@@ -23,6 +23,7 @@ - #include <linux/platform_device.h> - #include <linux/libata.h> - #include <linux/ahci_platform.h> -+#include <linux/phy/phy.h> - #include "ahci.h" - - static void ahci_host_stop(struct ata_host *host); -@@ -141,16 +142,32 @@ static int ahci_probe(struct platform_de - } - } - -+ hpriv->phy = devm_phy_get(dev, "sata-phy"); -+ if (IS_ERR(hpriv->phy)) { -+ dev_dbg(dev, "can't get sata-phy\n"); -+ /* return only if -EPROBE_DEFER */ -+ if (PTR_ERR(hpriv->phy) == -EPROBE_DEFER) { -+ rc = -EPROBE_DEFER; -+ goto disable_unprepare_clk; -+ } -+ } -+ -+ if (!IS_ERR(hpriv->phy)) { -+ phy_init(hpriv->phy); -+ phy_power_on(hpriv->phy); -+ } -+ - /* - * Some platforms might need to prepare for mmio region access, - * which could be done in the following init call. So, the mmio - * region shouldn't be accessed before init (if provided) has - * returned successfully. - */ -+ - if (pdata && pdata->init) { - rc = pdata->init(dev, hpriv->mmio); - if (rc) -- goto disable_unprepare_clk; -+ goto disable_phy; - } - - ahci_save_initial_config(dev, hpriv, -@@ -220,6 +237,12 @@ static int ahci_probe(struct platform_de - pdata_exit: - if (pdata && pdata->exit) - pdata->exit(dev); -+disable_phy: -+ if (!IS_ERR(hpriv->phy)) { -+ phy_power_off(hpriv->phy); -+ phy_exit(hpriv->phy); -+ } -+ - disable_unprepare_clk: - if (!IS_ERR(hpriv->clk)) - clk_disable_unprepare(hpriv->clk); -@@ -238,6 +261,11 @@ static void ahci_host_stop(struct ata_ho - if (pdata && pdata->exit) - pdata->exit(dev); - -+ if (!IS_ERR(hpriv->phy)) { -+ phy_power_off(hpriv->phy); -+ phy_exit(hpriv->phy); -+ } -+ - if (!IS_ERR(hpriv->clk)) { - clk_disable_unprepare(hpriv->clk); - clk_put(hpriv->clk); -@@ -328,6 +356,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ah - static const struct of_device_id ahci_of_match[] = { - { .compatible = "snps,spear-ahci", }, - { .compatible = "snps,exynos5440-ahci", }, -+ { .compatible = "snps,dwc-ahci", }, - {}, - }; - MODULE_DEVICE_TABLE(of, ahci_of_match); ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -137,6 +137,13 @@ config SATA_SIL24 - - If unsure, say N. - -+config SATA_TI -+ tristate "Texas Instruments SATA Wrapper driver" -+ depends on ARCH_OMAP -+ help -+ This options enables SATA Wrapper driver for Texas Instruments SoCs. -+ It is found on OMAP5 and DRA7. -+ - config ATA_SFF - bool "ATA SFF support (for legacy IDE and PATA)" - default y ---- a/drivers/ata/Makefile -+++ b/drivers/ata/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_SATA_SIL24) += sata_sil24.o - obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o - obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o - obj-$(CONFIG_AHCI_IMX) += ahci_imx.o -+obj-$(CONFIG_SATA_TI) += sata_ti.o - - # SFF w/ custom DMA - obj-$(CONFIG_PDC_ADMA) += pdc_adma.o ---- /dev/null -+++ b/drivers/ata/sata_ti.c -@@ -0,0 +1,160 @@ -+/** -+ * sata-ti.c - Texas Instruments Specific SATA Glue layer -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Authors: Roger Quadros <rogerq@ti.com> -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 of -+ * the License as published by the Free Software Foundation. -+ * -+ * 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. -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/platform_device.h> -+#include <linux/ioport.h> -+#include <linux/io.h> -+#include <linux/pm_runtime.h> -+#include <linux/of.h> -+#include <linux/of_platform.h> -+ -+/* -+ * All these registers belong to OMAP's Wrapper around the -+ * DesignWare SATA Core. -+ */ -+ -+#define SATA_SYSCONFIG 0x0000 -+#define SATA_CDRLOCK 0x0004 -+ -+struct ti_sata { -+ struct device *dev; -+ void __iomem *base; -+}; -+ -+static int ti_sata_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device *dev = &pdev->dev; -+ struct ti_sata *sata; -+ struct resource *res; -+ void __iomem *base; -+ int ret; -+ -+ if (!np) { -+ dev_err(dev, "device node not found\n"); -+ return -EINVAL; -+ } -+ -+ sata = devm_kzalloc(dev, sizeof(*sata), GFP_KERNEL); -+ if (!sata) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, sata); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(dev, "missing memory base resource\n"); -+ return -EINVAL; -+ } -+ -+ base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ sata->dev = dev; -+ sata->base = base; -+ -+ pm_runtime_enable(dev); -+ ret = pm_runtime_get_sync(dev); -+ if (ret < 0) { -+ dev_err(dev, "pm_runtime_get_sync failed with err %d\n", -+ ret); -+ goto runtime_disable; -+ } -+ -+ ret = of_platform_populate(np, NULL, NULL, dev); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to create TI SATA children\n"); -+ goto runtime_put; -+ } -+ -+ return 0; -+ -+runtime_put: -+ pm_runtime_put_sync(dev); -+ -+runtime_disable: -+ pm_runtime_disable(dev); -+ -+ return ret; -+} -+ -+static int ti_sata_remove_child(struct device *dev, void *c) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ -+ platform_device_unregister(pdev); -+ -+ return 0; -+} -+ -+static int ti_sata_remove(struct platform_device *pdev) -+{ -+ pm_runtime_put_sync(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ device_for_each_child(&pdev->dev, NULL, ti_sata_remove_child); -+ -+ return 0; -+} -+ -+static const struct of_device_id of_ti_sata_match[] = { -+ { -+ .compatible = "ti,sata" -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, of_ti_sata_match); -+ -+#ifdef CONFIG_PM -+ -+static int ti_sata_resume(struct device *dev) -+{ -+ pm_runtime_disable(dev); -+ pm_runtime_set_active(dev); -+ pm_runtime_enable(dev); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops ti_sata_dev_pm_ops = { -+ .resume = ti_sata_resume, -+}; -+ -+#define DEV_PM_OPS (&ti_sata_dev_pm_ops) -+#else -+#define DEV_PM_OPS NULL -+#endif /* CONFIG_PM */ -+ -+static struct platform_driver ti_sata_driver = { -+ .probe = ti_sata_probe, -+ .remove = ti_sata_remove, -+ .driver = { -+ .name = "ti-sata", -+ .of_match_table = of_ti_sata_match, -+ .pm = DEV_PM_OPS, -+ }, -+}; -+ -+module_platform_driver(ti_sata_driver); -+ -+MODULE_ALIAS("platform:ti-sata"); -+MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>"); -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("TI SATA Glue Layer"); ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -2196,6 +2196,12 @@ struct clk *of_clk_get_from_provider(str - return clk; - } - -+int of_clk_get_parent_count(struct device_node *np) -+{ -+ return of_count_phandle_with_args(np, "clocks", "#clock-cells"); -+} -+EXPORT_SYMBOL_GPL(of_clk_get_parent_count); -+ - const char *of_clk_get_parent_name(struct device_node *np, int index) - { - struct of_phandle_args clkspec; ---- a/drivers/clk/clk-divider.c -+++ b/drivers/clk/clk-divider.c -@@ -1,7 +1,7 @@ - /* - * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> -- * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> -+ * Copyright (C) 2011-2013 Mike Turquette, Linaro Ltd <mturquette@linaro.org> - * - * 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 -@@ -17,6 +17,8 @@ - #include <linux/err.h> - #include <linux/string.h> - #include <linux/log2.h> -+#include <linux/of.h> -+#include <linux/of_address.h> - - /* - * DOC: basic adjustable divider clock that cannot gate -@@ -30,8 +32,6 @@ - - #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - --#define div_mask(d) ((1 << ((d)->width)) - 1) -- - static unsigned int _get_table_maxdiv(const struct clk_div_table *table) - { - unsigned int maxdiv = 0; -@@ -46,12 +46,12 @@ static unsigned int _get_table_maxdiv(co - static unsigned int _get_maxdiv(struct clk_divider *divider) - { - if (divider->flags & CLK_DIVIDER_ONE_BASED) -- return div_mask(divider); -+ return divider->mask; - if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) -- return 1 << div_mask(divider); -+ return 1 << divider->mask; - if (divider->table) - return _get_table_maxdiv(divider->table); -- return div_mask(divider) + 1; -+ return divider->mask + 1; - } - - static unsigned int _get_table_div(const struct clk_div_table *table, -@@ -105,7 +105,7 @@ static unsigned long clk_divider_recalc_ - unsigned int div, val; - - val = clk_readl(divider->reg) >> divider->shift; -- val &= div_mask(divider); -+ val &= divider->mask; - - div = _get_div(divider, val); - if (!div) { -@@ -221,17 +221,17 @@ static int clk_divider_set_rate(struct c - div = parent_rate / rate; - value = _get_val(divider, div); - -- if (value > div_mask(divider)) -- value = div_mask(divider); -+ if (value > divider->mask) -+ value = divider->mask; - - if (divider->lock) - spin_lock_irqsave(divider->lock, flags); - - if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { -- val = div_mask(divider) << (divider->shift + 16); -+ val = divider->mask << (divider->shift + 16); - } else { - val = clk_readl(divider->reg); -- val &= ~(div_mask(divider) << divider->shift); -+ val &= ~(divider->mask << divider->shift); - } - val |= value << divider->shift; - clk_writel(val, divider->reg); -@@ -251,7 +251,7 @@ EXPORT_SYMBOL_GPL(clk_divider_ops); - - static struct clk *_register_divider(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, -- void __iomem *reg, u8 shift, u8 width, -+ void __iomem *reg, u8 shift, u32 mask, - u8 clk_divider_flags, const struct clk_div_table *table, - spinlock_t *lock) - { -@@ -260,8 +260,9 @@ static struct clk *_register_divider(str - struct clk_init_data init; - - if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { -- if (width + shift > 16) { -- pr_warn("divider value exceeds LOWORD field\n"); -+ if ((mask << shift) & 0xffff0000) { -+ pr_warn("%s: divider value exceeds LOWORD field\n", -+ __func__); - return ERR_PTR(-EINVAL); - } - } -@@ -282,7 +283,7 @@ static struct clk *_register_divider(str - /* struct clk_divider assignments */ - div->reg = reg; - div->shift = shift; -- div->width = width; -+ div->mask = mask; - div->flags = clk_divider_flags; - div->lock = lock; - div->hw.init = &init; -@@ -315,7 +316,7 @@ struct clk *clk_register_divider(struct - u8 clk_divider_flags, spinlock_t *lock) - { - return _register_divider(dev, name, parent_name, flags, reg, shift, -- width, clk_divider_flags, NULL, lock); -+ ((1 << width) - 1), clk_divider_flags, NULL, lock); - } - EXPORT_SYMBOL_GPL(clk_register_divider); - -@@ -340,6 +341,103 @@ struct clk *clk_register_divider_table(s - spinlock_t *lock) - { - return _register_divider(dev, name, parent_name, flags, reg, shift, -- width, clk_divider_flags, table, lock); -+ ((1 << width) - 1), clk_divider_flags, table, lock); - } - EXPORT_SYMBOL_GPL(clk_register_divider_table); -+ -+#ifdef CONFIG_OF -+struct clk_div_table *of_clk_get_div_table(struct device_node *node) -+{ -+ int i; -+ u32 table_size; -+ struct clk_div_table *table; -+ const __be32 *tablespec; -+ u32 val; -+ -+ tablespec = of_get_property(node, "table", &table_size); -+ -+ if (!tablespec) -+ return NULL; -+ -+ table_size /= sizeof(struct clk_div_table); -+ -+ table = kzalloc(sizeof(struct clk_div_table) * table_size, GFP_KERNEL); -+ if (!table) { -+ pr_err("%s: unable to allocate memory for %s table\n", __func__, node->name); -+ return NULL; -+ } -+ -+ for (i = 0; i < table_size; i++) { -+ of_property_read_u32_index(node, "table", i * 2, &val); -+ table[i].div = val; -+ of_property_read_u32_index(node, "table", i * 2 + 1, &val); -+ table[i].val = val; -+ } -+ -+ return table; -+} -+ -+/** -+ * of_divider_clk_setup() - Setup function for simple div rate clock -+ */ -+void of_divider_clk_setup(struct device_node *node) -+{ -+ struct clk *clk; -+ const char *clk_name = node->name; -+ void __iomem *reg; -+ const char *parent_name; -+ u8 clk_divider_flags = 0; -+ u32 mask = 0; -+ u32 shift = 0; -+ struct clk_div_table *table; -+ u32 flags = 0; -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ parent_name = of_clk_get_parent_name(node, 0); -+ -+ reg = of_iomap(node, 0); -+ if (!reg) { -+ pr_err("%s: no memory mapped for property reg\n", __func__); -+ return; -+ } -+ -+ if (of_property_read_u32(node, "bit-mask", &mask)) { -+ pr_err("%s: missing bit-mask property for %s\n", __func__, node->name); -+ return; -+ } -+ -+ if (of_property_read_u32(node, "bit-shift", &shift)) { -+ shift = __ffs(mask); -+ pr_debug("%s: bit-shift property defaults to 0x%x for %s\n", -+ __func__, shift, node->name); -+ } -+ -+ if (of_property_read_bool(node, "index-starts-at-one")) -+ clk_divider_flags |= CLK_DIVIDER_ONE_BASED; -+ -+ if (of_property_read_bool(node, "index-power-of-two")) -+ clk_divider_flags |= CLK_DIVIDER_POWER_OF_TWO; -+ -+ if (of_property_read_bool(node, "index-allow-zero")) -+ clk_divider_flags |= CLK_DIVIDER_ALLOW_ZERO; -+ -+ if (of_property_read_bool(node, "hiword-mask")) -+ clk_divider_flags |= CLK_DIVIDER_HIWORD_MASK; -+ -+ if (of_property_read_bool(node, "set-rate-parent")) -+ flags |= CLK_SET_RATE_PARENT; -+ -+ table = of_clk_get_div_table(node); -+ if (IS_ERR(table)) -+ return; -+ -+ clk = _register_divider(NULL, clk_name, parent_name, flags, reg, shift, -+ mask, clk_divider_flags, table, NULL); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+} -+EXPORT_SYMBOL_GPL(of_divider_clk_setup); -+CLK_OF_DECLARE(divider_clk, "divider-clock", of_divider_clk_setup); -+#endif ---- a/drivers/clk/clk-fixed-factor.c -+++ b/drivers/clk/clk-fixed-factor.c -@@ -109,6 +109,7 @@ void __init of_fixed_factor_clk_setup(st - const char *clk_name = node->name; - const char *parent_name; - u32 div, mult; -+ u32 flags = 0; - - if (of_property_read_u32(node, "clock-div", &div)) { - pr_err("%s Fixed factor clock <%s> must have a clock-div property\n", -@@ -125,7 +126,10 @@ void __init of_fixed_factor_clk_setup(st - of_property_read_string(node, "clock-output-names", &clk_name); - parent_name = of_clk_get_parent_name(node, 0); - -- clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, -+ if (of_property_read_bool(node, "set-rate-parent")) -+ flags |= CLK_SET_RATE_PARENT; -+ -+ clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, - mult, div); - if (!IS_ERR(clk)) - of_clk_add_provider(node, of_clk_src_simple_get, clk); ---- a/drivers/clk/clk-gate.c -+++ b/drivers/clk/clk-gate.c -@@ -15,6 +15,8 @@ - #include <linux/io.h> - #include <linux/err.h> - #include <linux/string.h> -+#include <linux/of.h> -+#include <linux/of_address.h> - - /** - * DOC: basic gatable clock which can gate and ungate it's ouput -@@ -162,3 +164,52 @@ struct clk *clk_register_gate(struct dev - return clk; - } - EXPORT_SYMBOL_GPL(clk_register_gate); -+ -+#ifdef CONFIG_OF -+/** -+ * of_gate_clk_setup() - Setup function for simple gate rate clock -+ */ -+void of_gate_clk_setup(struct device_node *node) -+{ -+ struct clk *clk; -+ const char *clk_name = node->name; -+ void __iomem *reg; -+ const char *parent_name; -+ u8 clk_gate_flags = 0; -+ u32 bit_idx = 0; -+ u32 flags = 0; -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ parent_name = of_clk_get_parent_name(node, 0); -+ -+ reg = of_iomap(node, 0); -+ if (!reg) { -+ pr_err("%s: no memory mapped for property reg\n", __func__); -+ return; -+ } -+ -+ if (of_property_read_u32(node, "bit-shift", &bit_idx)) { -+ pr_err("%s: missing bit-shift property for %s\n", -+ __func__, node->name); -+ return; -+ } -+ -+ if (of_property_read_bool(node, "set-bit-to-disable")) -+ clk_gate_flags |= CLK_GATE_SET_TO_DISABLE; -+ -+ if (of_property_read_bool(node, "hiword-mask")) -+ clk_gate_flags |= CLK_GATE_HIWORD_MASK; -+ -+ if (of_property_read_bool(node, "set-rate-parent")) -+ flags |= CLK_SET_RATE_PARENT; -+ -+ clk = clk_register_gate(NULL, clk_name, parent_name, flags, reg, -+ bit_idx, clk_gate_flags, NULL); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+} -+EXPORT_SYMBOL_GPL(of_gate_clk_setup); -+CLK_OF_DECLARE(gate_clk, "gate-clock", of_gate_clk_setup); -+#endif ---- a/drivers/clk/clk-mux.c -+++ b/drivers/clk/clk-mux.c -@@ -1,7 +1,7 @@ - /* - * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> -- * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> -+ * Copyright (C) 2011-2013 Mike Turquette, Linaro Ltd <mturquette@linaro.org> - * - * 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 -@@ -16,6 +16,8 @@ - #include <linux/slab.h> - #include <linux/io.h> - #include <linux/err.h> -+#include <linux/of.h> -+#include <linux/of_address.h> - - /* - * DOC: basic adjustable multiplexer clock that cannot gate -@@ -177,3 +179,71 @@ struct clk *clk_register_mux(struct devi - NULL, lock); - } - EXPORT_SYMBOL_GPL(clk_register_mux); -+ -+#ifdef CONFIG_OF -+/** -+ * of_mux_clk_setup() - Setup function for simple mux rate clock -+ */ -+void of_mux_clk_setup(struct device_node *node) -+{ -+ struct clk *clk; -+ const char *clk_name = node->name; -+ void __iomem *reg; -+ int num_parents; -+ const char **parent_names; -+ int i; -+ u8 clk_mux_flags = 0; -+ u32 mask = 0; -+ u32 shift = 0; -+ u32 flags = 0; -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ num_parents = of_clk_get_parent_count(node); -+ if (num_parents < 1) { -+ pr_err("%s: mux-clock %s must have parent(s)\n", -+ __func__, node->name); -+ return; -+ } -+ -+ parent_names = kzalloc((sizeof(char*) * num_parents), -+ GFP_KERNEL); -+ -+ for (i = 0; i < num_parents; i++) -+ parent_names[i] = of_clk_get_parent_name(node, i); -+ -+ reg = of_iomap(node, 0); -+ if (!reg) { -+ pr_err("%s: no memory mapped for property reg\n", __func__); -+ return; -+ } -+ -+ if (of_property_read_u32(node, "bit-mask", &mask)) { -+ pr_err("%s: missing bit-mask property for %s\n", __func__, node->name); -+ return; -+ } -+ -+ if (of_property_read_u32(node, "bit-shift", &shift)) { -+ shift = __ffs(mask); -+ pr_debug("%s: bit-shift property defaults to 0x%x for %s\n", -+ __func__, shift, node->name); -+ } -+ -+ if (of_property_read_bool(node, "index-starts-at-one")) -+ clk_mux_flags |= CLK_MUX_INDEX_ONE; -+ -+ if (of_property_read_bool(node, "hiword-mask")) -+ clk_mux_flags |= CLK_MUX_HIWORD_MASK; -+ -+ if (of_property_read_bool(node, "set-rate-parent")) -+ flags |= CLK_SET_RATE_PARENT; -+ -+ clk = clk_register_mux_table(NULL, clk_name, parent_names, num_parents, -+ flags, reg, shift, mask, clk_mux_flags, NULL, NULL); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+} -+EXPORT_SYMBOL_GPL(of_mux_clk_setup); -+CLK_OF_DECLARE(mux_clk, "mux-clock", of_mux_clk_setup); -+#endif ---- /dev/null -+++ b/drivers/clk/clk-palmas.c -@@ -0,0 +1,305 @@ -+/* -+ * Clock driver for Palmas device. -+ * -+ * Copyright (c) 2013, NVIDIA Corporation. -+ * -+ * Author: Laxman Dewangan <ldewangan@nvidia.com> -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, -+ * whether express or implied; 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., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307, USA -+ */ -+ -+#include <linux/clk.h> -+#include <linux/clkdev.h> -+#include <linux/clk-provider.h> -+#include <linux/mfd/palmas.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+ -+#define PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE1 1 -+#define PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE2 2 -+#define PALMAS_CLOCK_DT_EXT_CONTROL_NSLEEP 3 -+ -+struct palmas_clk32k_desc { -+ const char *clk_name; -+ unsigned int control_reg; -+ unsigned int enable_mask; -+ unsigned int sleep_mask; -+ unsigned int sleep_reqstr_id; -+ int delay; -+}; -+ -+struct palmas_clock_info { -+ struct device *dev; -+ struct clk *clk; -+ struct clk_hw hw; -+ struct palmas *palmas; -+ struct palmas_clk32k_desc *clk_desc; -+ int ext_control_pin; -+}; -+ -+static inline struct palmas_clock_info *to_palmas_clks_info(struct clk_hw *hw) -+{ -+ return container_of(hw, struct palmas_clock_info, hw); -+} -+ -+static unsigned long palmas_clks_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return 32768; -+} -+ -+static int palmas_clks_prepare(struct clk_hw *hw) -+{ -+ struct palmas_clock_info *cinfo = to_palmas_clks_info(hw); -+ int ret; -+ -+ ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE, -+ cinfo->clk_desc->control_reg, -+ cinfo->clk_desc->enable_mask, -+ cinfo->clk_desc->enable_mask); -+ if (ret < 0) -+ dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n", -+ cinfo->clk_desc->control_reg, ret); -+ else if (cinfo->clk_desc->delay) -+ udelay(cinfo->clk_desc->delay); -+ -+ return ret; -+} -+ -+static void palmas_clks_unprepare(struct clk_hw *hw) -+{ -+ struct palmas_clock_info *cinfo = to_palmas_clks_info(hw); -+ int ret; -+ -+ /* -+ * Clock can be disabled through external pin if it is externally -+ * controlled. -+ */ -+ if (cinfo->ext_control_pin) -+ return; -+ -+ ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE, -+ cinfo->clk_desc->control_reg, -+ cinfo->clk_desc->enable_mask, 0); -+ if (ret < 0) -+ dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n", -+ cinfo->clk_desc->control_reg, ret); -+ -+} -+ -+static int palmas_clks_is_prepared(struct clk_hw *hw) -+{ -+ struct palmas_clock_info *cinfo = to_palmas_clks_info(hw); -+ int ret; -+ u32 val; -+ -+ if (cinfo->ext_control_pin) -+ return 1; -+ -+ ret = palmas_read(cinfo->palmas, PALMAS_RESOURCE_BASE, -+ cinfo->clk_desc->control_reg, &val); -+ if (ret < 0) { -+ dev_err(cinfo->dev, "Reg 0x%02x read failed, %d\n", -+ cinfo->clk_desc->control_reg, ret); -+ return ret; -+ } -+ return !!(val & cinfo->clk_desc->enable_mask); -+} -+ -+static struct clk_ops palmas_clks_ops = { -+ .prepare = palmas_clks_prepare, -+ .unprepare = palmas_clks_unprepare, -+ .is_prepared = palmas_clks_is_prepared, -+ .recalc_rate = palmas_clks_recalc_rate, -+}; -+ -+struct palmas_clks_of_match { -+ struct clk_init_data init; -+ struct palmas_clk32k_desc desc; -+}; -+ -+static struct palmas_clks_of_match palmas_of_clk32kg = { -+ .init = { -+ .name = "clk32kg", -+ .ops = &palmas_clks_ops, -+ .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, -+ }, -+ .desc = { -+ .clk_name = "clk32kg", -+ .control_reg = PALMAS_CLK32KG_CTRL, -+ .enable_mask = PALMAS_CLK32KG_CTRL_MODE_ACTIVE, -+ .sleep_mask = PALMAS_CLK32KG_CTRL_MODE_SLEEP, -+ .sleep_reqstr_id = PALMAS_EXTERNAL_REQSTR_ID_CLK32KG, -+ .delay = 200, -+ }, -+}; -+ -+static struct palmas_clks_of_match palmas_of_clk32kgaudio = { -+ .init = { -+ .name = "clk32kgaudio", -+ .ops = &palmas_clks_ops, -+ .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, -+ }, -+ .desc = { -+ .clk_name = "clk32kgaudio", -+ .control_reg = PALMAS_CLK32KGAUDIO_CTRL, -+ .enable_mask = PALMAS_CLK32KG_CTRL_MODE_ACTIVE, -+ .sleep_mask = PALMAS_CLK32KG_CTRL_MODE_SLEEP, -+ .sleep_reqstr_id = PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO, -+ .delay = 200, -+ }, -+}; -+ -+static struct of_device_id of_palmas_clks_match_tbl[] = { -+ { .compatible = "ti,palmas-clk32kg", .data = &palmas_of_clk32kg, }, -+ { .compatible = "ti,palmas-clk32kgaudio", .data = &palmas_of_clk32kgaudio, }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, of_palmas_clks_match_tbl); -+ -+static void palmas_clks_get_clk_data(struct platform_device *pdev, -+ struct palmas_clock_info *cinfo) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ unsigned int prop; -+ int ret; -+ -+ ret = of_property_read_u32(node, "ti,external-sleep-control", -+ &prop); -+ if (ret) -+ return; -+ -+ switch (prop) { -+ case PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE1: -+ prop = PALMAS_EXT_CONTROL_ENABLE1; -+ break; -+ case PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE2: -+ prop = PALMAS_EXT_CONTROL_ENABLE2; -+ break; -+ case PALMAS_CLOCK_DT_EXT_CONTROL_NSLEEP: -+ prop = PALMAS_EXT_CONTROL_NSLEEP; -+ break; -+ default: -+ dev_warn(&pdev->dev, "%s: Invalid ext control option: %u\n", -+ node->name, prop); -+ prop = 0; -+ break; -+ } -+ cinfo->ext_control_pin = prop; -+} -+ -+static int palmas_clks_init_configure(struct palmas_clock_info *cinfo) -+{ -+ int ret; -+ -+ ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE, -+ cinfo->clk_desc->control_reg, -+ cinfo->clk_desc->sleep_mask, 0); -+ if (ret < 0) { -+ dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n", -+ cinfo->clk_desc->control_reg, ret); -+ return ret; -+ } -+ -+ if (cinfo->ext_control_pin) { -+ ret = clk_prepare(cinfo->clk); -+ if (ret < 0) { -+ dev_err(cinfo->dev, "Clock prep failed, %d\n", ret); -+ return ret; -+ } -+ -+ ret = palmas_ext_control_req_config(cinfo->palmas, -+ cinfo->clk_desc->sleep_reqstr_id, -+ cinfo->ext_control_pin, true); -+ if (ret < 0) { -+ dev_err(cinfo->dev, "Ext config for %s failed, %d\n", -+ cinfo->clk_desc->clk_name, ret); -+ return ret; -+ } -+ } -+ -+ return ret; -+} -+static int palmas_clks_probe(struct platform_device *pdev) -+{ -+ struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); -+ struct device_node *node = pdev->dev.of_node; -+ struct palmas_clks_of_match *match_data; -+ const struct of_device_id *match; -+ struct palmas_clock_info *cinfo; -+ struct clk *clk; -+ int ret; -+ -+ match = of_match_device(of_palmas_clks_match_tbl, &pdev->dev); -+ match_data = (struct palmas_clks_of_match *) match->data; -+ -+ cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); -+ if (!cinfo) -+ return -ENOMEM; -+ -+ palmas_clks_get_clk_data(pdev, cinfo); -+ platform_set_drvdata(pdev, cinfo); -+ -+ cinfo->dev = &pdev->dev; -+ cinfo->palmas = palmas; -+ -+ cinfo->clk_desc = &match_data->desc; -+ cinfo->hw.init = &match_data->init; -+ clk = devm_clk_register(&pdev->dev, &cinfo->hw); -+ if (IS_ERR(clk)) { -+ ret = PTR_ERR(clk); -+ dev_err(&pdev->dev, "Fail to register clock %s, %d\n", -+ match_data->desc.clk_name, ret); -+ return ret; -+ } -+ -+ cinfo->clk = clk; -+ ret = palmas_clks_init_configure(cinfo); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Clock config failed, %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_clk_add_provider(node, of_clk_src_simple_get, cinfo->clk); -+ if (ret < 0) -+ dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret); -+ return ret; -+} -+ -+static int palmas_clks_remove(struct platform_device *pdev) -+{ -+ of_clk_del_provider(pdev->dev.of_node); -+ return 0; -+} -+ -+static struct platform_driver palmas_clks_driver = { -+ .driver = { -+ .name = "palmas-clk", -+ .owner = THIS_MODULE, -+ .of_match_table = of_palmas_clks_match_tbl, -+ }, -+ .probe = palmas_clks_probe, -+ .remove = palmas_clks_remove, -+}; -+ -+module_platform_driver(palmas_clks_driver); -+ -+MODULE_DESCRIPTION("Clock driver for Palmas Series Devices"); -+MODULE_ALIAS("platform:palmas-clk"); -+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -93,6 +93,13 @@ config CLK_PPC_CORENET - This adds the clock driver support for Freescale PowerPC corenet - platforms using common clock framework. - -+config COMMON_CLK_PALMAS -+ bool "Clock driver for TI Palmas devices" -+ depends on MFD_PALMAS -+ ---help--- -+ This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO -+ using common clock framework. -+ - endmenu - - source "drivers/clk/mvebu/Kconfig" ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -32,6 +32,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500. - obj-$(CONFIG_ARCH_ZYNQ) += zynq/ - obj-$(CONFIG_ARCH_TEGRA) += tegra/ - obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ -+obj-$(CONFIG_ARCH_OMAP) += ti/ - - obj-$(CONFIG_X86) += x86/ - -@@ -43,3 +44,4 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-s - obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o - obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o - obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o -+obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o ---- /dev/null -+++ b/drivers/clk/ti/apll.c -@@ -0,0 +1,212 @@ -+/* -+ * OMAP APLL clock support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * J Keerthy <j-keerthy@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/io.h> -+#include <linux/err.h> -+#include <linux/string.h> -+#include <linux/log2.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/clk/ti.h> -+#include <linux/delay.h> -+ -+#define APLL_FORCE_LOCK 0x1 -+#define APLL_AUTO_IDLE 0x2 -+#define MAX_APLL_WAIT_TRIES 1000000 -+ -+static int dra7_apll_enable(struct clk_hw *hw) -+{ -+ struct clk_hw_omap *clk = to_clk_hw_omap(hw); -+ int r = 0, i = 0; -+ struct dpll_data *ad; -+ const char *clk_name; -+ u8 state = 1; -+ u32 v; -+ -+ ad = clk->dpll_data; -+ if (!ad) -+ return -EINVAL; -+ -+ clk_name = __clk_get_name(clk->hw.clk); -+ -+ state <<= __ffs(ad->idlest_mask); -+ -+ /* Check is already locked */ -+ if ((readl(ad->idlest_reg) & ad->idlest_mask) == state) -+ return r; -+ -+ v = readl(ad->control_reg); -+ v &= ~ad->enable_mask; -+ v |= APLL_FORCE_LOCK << __ffs(ad->enable_mask); -+ writel(v, ad->control_reg); -+ -+ state <<= __ffs(ad->idlest_mask); -+ -+ while (((readl(ad->idlest_reg) & ad->idlest_mask) != state) && -+ i < MAX_APLL_WAIT_TRIES) { -+ i++; -+ udelay(1); -+ } -+ -+ if (i == MAX_APLL_WAIT_TRIES) { -+ pr_warn("clock: %s failed transition to '%s'\n", -+ clk_name, (state) ? "locked" : "bypassed"); -+ } else { -+ pr_debug("clock: %s transition to '%s' in %d loops\n", -+ clk_name, (state) ? "locked" : "bypassed", i); -+ -+ r = 0; -+ } -+ -+ return r; -+} -+ -+static void dra7_apll_disable(struct clk_hw *hw) -+{ -+ struct clk_hw_omap *clk = to_clk_hw_omap(hw); -+ struct dpll_data *ad; -+ u8 state = 1; -+ u32 v; -+ -+ ad = clk->dpll_data; -+ -+ state <<= __ffs(ad->idlest_mask); -+ -+ v = readl(ad->control_reg); -+ v &= ~ad->enable_mask; -+ v |= APLL_AUTO_IDLE << __ffs(ad->enable_mask); -+ writel(v, ad->control_reg); -+} -+ -+static u8 dra7_init_apll_parent(struct clk_hw *hw) -+{ -+ return 0; -+} -+ -+static const struct clk_ops apll_ck_ops = { -+ .enable = &dra7_apll_enable, -+ .disable = &dra7_apll_disable, -+ .get_parent = &dra7_init_apll_parent, -+}; -+ -+static struct clk *omap_clk_register_apll(struct device *dev, const char *name, -+ const char **parent_names, int num_parents, unsigned long flags, -+ struct dpll_data *dpll_data, const char *clkdm_name, -+ const struct clk_ops *ops) -+{ -+ struct clk *clk; -+ struct clk_init_data init = { 0 }; -+ struct clk_hw_omap *clk_hw; -+ -+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); -+ if (!clk_hw) { -+ pr_err("%s: could not allocate clk_hw_omap\n", __func__); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ clk_hw->dpll_data = dpll_data; -+ clk_hw->hw.init = &init; -+ -+ init.name = name; -+ init.ops = ops; -+ init.flags = flags; -+ init.parent_names = parent_names; -+ init.num_parents = num_parents; -+ -+ /* register the clock */ -+ clk = clk_register(dev, &clk_hw->hw); -+ -+ return clk; -+} -+ -+void __init of_dra7_apll_setup(struct device_node *node) -+{ -+ const struct clk_ops *ops; -+ struct clk *clk; -+ const char *clk_name = node->name; -+ int num_parents; -+ const char **parent_names = NULL; -+ u8 apll_flags = 0; -+ struct dpll_data *ad; -+ u32 idlest_mask = 0x1; -+ u32 autoidle_mask = 0x3; -+ int i; -+ -+ ops = &apll_ck_ops; -+ ad = kzalloc(sizeof(*ad), GFP_KERNEL); -+ if (!ad) { -+ pr_err("%s: could not allocate dpll_data\n", __func__); -+ return; -+ } -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ num_parents = of_clk_get_parent_count(node); -+ if (num_parents < 1) { -+ pr_err("%s: omap dpll %s must have parent(s)\n", -+ __func__, node->name); -+ goto cleanup; -+ } -+ -+ parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL); -+ -+ for (i = 0; i < num_parents; i++) -+ parent_names[i] = of_clk_get_parent_name(node, i); -+ -+ ad->clk_ref = of_clk_get(node, 0); -+ ad->clk_bypass = of_clk_get(node, 1); -+ -+ if (IS_ERR(ad->clk_ref)) { -+ pr_err("%s: ti,clk-ref for %s not found\n", __func__, -+ clk_name); -+ goto cleanup; -+ } -+ -+ if (IS_ERR(ad->clk_bypass)) { -+ pr_err("%s: ti,clk-bypass for %s not found\n", __func__, -+ clk_name); -+ goto cleanup; -+ } -+ -+ i = of_property_match_string(node, "reg-names", "control"); -+ if (i >= 0) -+ ad->control_reg = of_iomap(node, i); -+ -+ i = of_property_match_string(node, "reg-names", "idlest"); -+ if (i >= 0) -+ ad->idlest_reg = of_iomap(node, i); -+ -+ ad->idlest_mask = idlest_mask; -+ ad->enable_mask = autoidle_mask; -+ -+ clk = omap_clk_register_apll(NULL, clk_name, parent_names, -+ num_parents, apll_flags, ad, -+ NULL, ops); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+ return; -+ -+cleanup: -+ kfree(parent_names); -+ kfree(ad); -+ return; -+} -+CLK_OF_DECLARE(dra7_apll_clock, "ti,dra7-apll-clock", of_dra7_apll_setup); ---- /dev/null -+++ b/drivers/clk/ti/autoidle.c -@@ -0,0 +1,121 @@ -+/* -+ * OMAP clock autoidle support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo <t-kristo@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/slab.h> -+#include <linux/io.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+ -+struct clk_omap_autoidle { -+ void __iomem *reg; -+ u8 shift; -+ u8 flags; -+ const char *name; -+ struct list_head node; -+}; -+ -+#define AUTOIDLE_LOW 0x1 -+ -+static LIST_HEAD(autoidle_clks); -+ -+static void omap_allow_autoidle(struct clk_omap_autoidle *clk) -+{ -+ u32 val; -+ -+ val = readl(clk->reg); -+ -+ if (clk->flags & AUTOIDLE_LOW) -+ val &= ~(1 << clk->shift); -+ else -+ val |= (1 << clk->shift); -+ -+ writel(val, clk->reg); -+} -+ -+static void omap_deny_autoidle(struct clk_omap_autoidle *clk) -+{ -+ u32 val; -+ -+ val = readl(clk->reg); -+ -+ if (clk->flags & AUTOIDLE_LOW) -+ val |= (1 << clk->shift); -+ else -+ val &= ~(1 << clk->shift); -+ -+ writel(val, clk->reg); -+} -+ -+void of_omap_clk_allow_autoidle_all(void) -+{ -+ struct clk_omap_autoidle *c; -+ -+ list_for_each_entry(c, &autoidle_clks, node) -+ omap_allow_autoidle(c); -+} -+ -+void of_omap_clk_deny_autoidle_all(void) -+{ -+ struct clk_omap_autoidle *c; -+ -+ list_for_each_entry(c, &autoidle_clks, node) -+ omap_deny_autoidle(c); -+} -+ -+static void __init of_omap_autoidle_setup(struct device_node *node) -+{ -+ u32 shift; -+ void __iomem *reg; -+ struct clk_omap_autoidle *clk; -+ -+ if (of_property_read_u32(node, "ti,autoidle-shift", &shift)) -+ return; -+ -+ reg = of_iomap(node, 0); -+ -+ clk = kzalloc(sizeof(*clk), GFP_KERNEL); -+ -+ if (!clk) { -+ pr_err("%s: kzalloc failed\n", __func__); -+ return; -+ } -+ -+ clk->shift = shift; -+ clk->name = node->name; -+ clk->reg = reg; -+ -+ if (of_property_read_bool(node, "ti,autoidle-low")) -+ clk->flags |= AUTOIDLE_LOW; -+ -+ list_add(&clk->node, &autoidle_clks); -+} -+ -+static void __init of_omap_divider_setup(struct device_node *node) -+{ -+ of_divider_clk_setup(node); -+ of_omap_autoidle_setup(node); -+} -+CLK_OF_DECLARE(omap_divider_clock, "ti,divider-clock", of_omap_divider_setup); -+ -+static void __init of_omap_fixed_factor_setup(struct device_node *node) -+{ -+ of_fixed_factor_clk_setup(node); -+ of_omap_autoidle_setup(node); -+} -+CLK_OF_DECLARE(omap_fixed_factor_clock, "ti,fixed-factor-clock", -+ of_omap_fixed_factor_setup); ---- /dev/null -+++ b/drivers/clk/ti/clk-33xx.c -@@ -0,0 +1,163 @@ -+/* -+ * AM33XX Clock init -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc -+ * Tero Kristo (t-kristo@ti.com) -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/clk-provider.h> -+#include <linux/clk/ti.h> -+ -+static struct omap_dt_clk am33xx_clks[] = { -+ DT_CLK(NULL, "clk_32768_ck", "clk_32768_ck"), -+ DT_CLK(NULL, "clk_rc32k_ck", "clk_rc32k_ck"), -+ DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), -+ DT_CLK(NULL, "virt_24000000_ck", "virt_24000000_ck"), -+ DT_CLK(NULL, "virt_25000000_ck", "virt_25000000_ck"), -+ DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), -+ DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"), -+ DT_CLK(NULL, "tclkin_ck", "tclkin_ck"), -+ DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"), -+ DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"), -+ DT_CLK(NULL, "dpll_core_m4_ck", "dpll_core_m4_ck"), -+ DT_CLK(NULL, "dpll_core_m5_ck", "dpll_core_m5_ck"), -+ DT_CLK(NULL, "dpll_core_m6_ck", "dpll_core_m6_ck"), -+ DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"), -+ DT_CLK("cpu0", NULL, "dpll_mpu_ck"), -+ DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"), -+ DT_CLK(NULL, "dpll_ddr_ck", "dpll_ddr_ck"), -+ DT_CLK(NULL, "dpll_ddr_m2_ck", "dpll_ddr_m2_ck"), -+ DT_CLK(NULL, "dpll_ddr_m2_div2_ck", "dpll_ddr_m2_div2_ck"), -+ DT_CLK(NULL, "dpll_disp_ck", "dpll_disp_ck"), -+ DT_CLK(NULL, "dpll_disp_m2_ck", "dpll_disp_m2_ck"), -+ DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"), -+ DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"), -+ DT_CLK(NULL, "dpll_per_m2_div4_wkupdm_ck", "dpll_per_m2_div4_wkupdm_ck"), -+ DT_CLK(NULL, "dpll_per_m2_div4_ck", "dpll_per_m2_div4_ck"), -+ DT_CLK(NULL, "adc_tsc_fck", "adc_tsc_fck"), -+ DT_CLK(NULL, "cefuse_fck", "cefuse_fck"), -+ DT_CLK(NULL, "clkdiv32k_ck", "clkdiv32k_ck"), -+ DT_CLK(NULL, "clkdiv32k_ick", "clkdiv32k_ick"), -+ DT_CLK(NULL, "dcan0_fck", "dcan0_fck"), -+ DT_CLK("481cc000.d_can", NULL, "dcan0_fck"), -+ DT_CLK(NULL, "dcan1_fck", "dcan1_fck"), -+ DT_CLK("481d0000.d_can", NULL, "dcan1_fck"), -+ DT_CLK(NULL, "pruss_ocp_gclk", "pruss_ocp_gclk"), -+ DT_CLK(NULL, "mcasp0_fck", "mcasp0_fck"), -+ DT_CLK(NULL, "mcasp1_fck", "mcasp1_fck"), -+ DT_CLK(NULL, "mmu_fck", "mmu_fck"), -+ DT_CLK(NULL, "smartreflex0_fck", "smartreflex0_fck"), -+ DT_CLK(NULL, "smartreflex1_fck", "smartreflex1_fck"), -+ DT_CLK(NULL, "sha0_fck", "sha0_fck"), -+ DT_CLK(NULL, "rng_fck", "rng_fck"), -+ DT_CLK(NULL, "aes0_fck", "aes0_fck"), -+ DT_CLK(NULL, "timer1_fck", "timer1_fck"), -+ DT_CLK(NULL, "timer2_fck", "timer2_fck"), -+ DT_CLK(NULL, "timer3_fck", "timer3_fck"), -+ DT_CLK(NULL, "timer4_fck", "timer4_fck"), -+ DT_CLK(NULL, "timer5_fck", "timer5_fck"), -+ DT_CLK(NULL, "timer6_fck", "timer6_fck"), -+ DT_CLK(NULL, "timer7_fck", "timer7_fck"), -+ DT_CLK(NULL, "usbotg_fck", "usbotg_fck"), -+ DT_CLK(NULL, "ieee5000_fck", "ieee5000_fck"), -+ DT_CLK(NULL, "wdt1_fck", "wdt1_fck"), -+ DT_CLK(NULL, "l4_rtc_gclk", "l4_rtc_gclk"), -+ DT_CLK(NULL, "l3_gclk", "l3_gclk"), -+ DT_CLK(NULL, "dpll_core_m4_div2_ck", "dpll_core_m4_div2_ck"), -+ DT_CLK(NULL, "l4hs_gclk", "l4hs_gclk"), -+ DT_CLK(NULL, "l3s_gclk", "l3s_gclk"), -+ DT_CLK(NULL, "l4fw_gclk", "l4fw_gclk"), -+ DT_CLK(NULL, "l4ls_gclk", "l4ls_gclk"), -+ DT_CLK(NULL, "clk_24mhz", "clk_24mhz"), -+ DT_CLK(NULL, "sysclk_div_ck", "sysclk_div_ck"), -+ DT_CLK(NULL, "cpsw_125mhz_gclk", "cpsw_125mhz_gclk"), -+ DT_CLK(NULL, "cpsw_cpts_rft_clk", "cpsw_cpts_rft_clk"), -+ DT_CLK(NULL, "gpio0_dbclk_mux_ck", "gpio0_dbclk_mux_ck"), -+ DT_CLK(NULL, "gpio0_dbclk", "gpio0_dbclk"), -+ DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"), -+ DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"), -+ DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"), -+ DT_CLK(NULL, "lcd_gclk", "lcd_gclk"), -+ DT_CLK(NULL, "mmc_clk", "mmc_clk"), -+ DT_CLK(NULL, "gfx_fclk_clksel_ck", "gfx_fclk_clksel_ck"), -+ DT_CLK(NULL, "gfx_fck_div_ck", "gfx_fck_div_ck"), -+ DT_CLK(NULL, "sysclkout_pre_ck", "sysclkout_pre_ck"), -+ DT_CLK(NULL, "clkout2_div_ck", "clkout2_div_ck"), -+ DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"), -+ DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK(NULL, "dbg_sysclk_ck", "dbg_sysclk_ck"), -+ DT_CLK(NULL, "dbg_clka_ck", "dbg_clka_ck"), -+ DT_CLK(NULL, "stm_pmd_clock_mux_ck", "stm_pmd_clock_mux_ck"), -+ DT_CLK(NULL, "trace_pmd_clk_mux_ck", "trace_pmd_clk_mux_ck"), -+ DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"), -+ DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"), -+ DT_CLK(NULL, "clkout2_ck", "clkout2_ck"), -+ DT_CLK("48300200.ehrpwm", "tbclk", "ehrpwm0_tbclk"), -+ DT_CLK("48302200.ehrpwm", "tbclk", "ehrpwm1_tbclk"), -+ DT_CLK("48304200.ehrpwm", "tbclk", "ehrpwm2_tbclk"), -+ { .node_name = NULL }, -+}; -+ -+static const char *enable_init_clks[] = { -+ "dpll_ddr_m2_ck", -+ "dpll_mpu_m2_ck", -+ "l3_gclk", -+ "l4hs_gclk", -+ "l4fw_gclk", -+ "l4ls_gclk", -+ /* Required for external peripherals like, Audio codecs */ -+ "clkout2_ck", -+}; -+ -+int __init am33xx_clk_init(void) -+{ -+ struct clk *clk1, *clk2; -+ -+ of_clk_init(NULL); -+ -+ omap_dt_clocks_register(am33xx_clks); -+ -+ omap2_clk_disable_autoidle_all(); -+ -+ omap2_clk_enable_init_clocks(enable_init_clks, -+ ARRAY_SIZE(enable_init_clks)); -+ -+ /* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always -+ * physically present, in such a case HWMOD enabling of -+ * clock would be failure with default parent. And timer -+ * probe thinks clock is already enabled, this leads to -+ * crash upon accessing timer 3 & 6 registers in probe. -+ * Fix by setting parent of both these timers to master -+ * oscillator clock. -+ */ -+ -+ clk1 = clk_get_sys(NULL, "sys_clkin_ck"); -+ clk2 = clk_get_sys(NULL, "timer3_fck"); -+ clk_set_parent(clk2, clk1); -+ -+ clk2 = clk_get_sys(NULL, "timer6_fck"); -+ clk_set_parent(clk2, clk1); -+ /* -+ * The On-Chip 32K RC Osc clock is not an accurate clock-source as per -+ * the design/spec, so as a result, for example, timer which supposed -+ * to get expired @60Sec, but will expire somewhere ~@40Sec, which is -+ * not expected by any use-case, so change WDT1 clock source to PRCM -+ * 32KHz clock. -+ */ -+ clk1 = clk_get_sys(NULL, "wdt1_fck"); -+ clk2 = clk_get_sys(NULL, "clkdiv32k_ick"); -+ clk_set_parent(clk1, clk2); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/clk/ti/clk-3xxx.c -@@ -0,0 +1,388 @@ -+/* -+ * OMAP3 Clock init -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc -+ * Tero Kristo (t-kristo@ti.com) -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/clk-provider.h> -+#include <linux/clk/ti.h> -+ -+ -+static struct omap_dt_clk omap3xxx_clks[] = { -+ DT_CLK(NULL, "apb_pclk", "dummy_apb_pclk"), -+ DT_CLK(NULL, "omap_32k_fck", "omap_32k_fck"), -+ DT_CLK(NULL, "virt_12m_ck", "virt_12m_ck"), -+ DT_CLK(NULL, "virt_13m_ck", "virt_13m_ck"), -+ DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), -+ DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), -+ DT_CLK(NULL, "virt_38_4m_ck", "virt_38_4m_ck"), -+ DT_CLK(NULL, "osc_sys_ck", "osc_sys_ck"), -+ DT_CLK("twl", "fck", "osc_sys_ck"), -+ DT_CLK(NULL, "sys_ck", "sys_ck"), -+ DT_CLK(NULL, "omap_96m_alwon_fck", "omap_96m_alwon_fck"), -+ DT_CLK("etb", "emu_core_alwon_ck", "emu_core_alwon_ck"), -+ DT_CLK(NULL, "sys_altclk", "sys_altclk"), -+ DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"), -+ DT_CLK(NULL, "sys_clkout1", "sys_clkout1"), -+ DT_CLK(NULL, "dpll1_ck", "dpll1_ck"), -+ DT_CLK(NULL, "dpll1_x2_ck", "dpll1_x2_ck"), -+ DT_CLK(NULL, "dpll1_x2m2_ck", "dpll1_x2m2_ck"), -+ DT_CLK(NULL, "dpll3_ck", "dpll3_ck"), -+ DT_CLK(NULL, "core_ck", "core_ck"), -+ DT_CLK(NULL, "dpll3_x2_ck", "dpll3_x2_ck"), -+ DT_CLK(NULL, "dpll3_m2_ck", "dpll3_m2_ck"), -+ DT_CLK(NULL, "dpll3_m2x2_ck", "dpll3_m2x2_ck"), -+ DT_CLK(NULL, "dpll3_m3_ck", "dpll3_m3_ck"), -+ DT_CLK(NULL, "dpll3_m3x2_ck", "dpll3_m3x2_ck"), -+ DT_CLK(NULL, "dpll4_ck", "dpll4_ck"), -+ DT_CLK(NULL, "dpll4_x2_ck", "dpll4_x2_ck"), -+ DT_CLK(NULL, "omap_96m_fck", "omap_96m_fck"), -+ DT_CLK(NULL, "cm_96m_fck", "cm_96m_fck"), -+ DT_CLK(NULL, "omap_54m_fck", "omap_54m_fck"), -+ DT_CLK(NULL, "omap_48m_fck", "omap_48m_fck"), -+ DT_CLK(NULL, "omap_12m_fck", "omap_12m_fck"), -+ DT_CLK(NULL, "dpll4_m2_ck", "dpll4_m2_ck"), -+ DT_CLK(NULL, "dpll4_m2x2_ck", "dpll4_m2x2_ck"), -+ DT_CLK(NULL, "dpll4_m3_ck", "dpll4_m3_ck"), -+ DT_CLK(NULL, "dpll4_m3x2_ck", "dpll4_m3x2_ck"), -+ DT_CLK(NULL, "dpll4_m4_ck", "dpll4_m4_ck"), -+ DT_CLK(NULL, "dpll4_m4x2_ck", "dpll4_m4x2_ck"), -+ DT_CLK(NULL, "dpll4_m5_ck", "dpll4_m5_ck"), -+ DT_CLK(NULL, "dpll4_m5x2_ck", "dpll4_m5x2_ck"), -+ DT_CLK(NULL, "dpll4_m6_ck", "dpll4_m6_ck"), -+ DT_CLK(NULL, "dpll4_m6x2_ck", "dpll4_m6x2_ck"), -+ DT_CLK("etb", "emu_per_alwon_ck", "emu_per_alwon_ck"), -+ DT_CLK(NULL, "clkout2_src_ck", "clkout2_src_ck"), -+ DT_CLK(NULL, "sys_clkout2", "sys_clkout2"), -+ DT_CLK(NULL, "corex2_fck", "corex2_fck"), -+ DT_CLK(NULL, "dpll1_fck", "dpll1_fck"), -+ DT_CLK(NULL, "mpu_ck", "mpu_ck"), -+ DT_CLK(NULL, "arm_fck", "arm_fck"), -+ DT_CLK("etb", "emu_mpu_alwon_ck", "emu_mpu_alwon_ck"), -+ DT_CLK(NULL, "l3_ick", "l3_ick"), -+ DT_CLK(NULL, "l4_ick", "l4_ick"), -+ DT_CLK(NULL, "rm_ick", "rm_ick"), -+ DT_CLK(NULL, "gpt10_fck", "gpt10_fck"), -+ DT_CLK(NULL, "gpt11_fck", "gpt11_fck"), -+ DT_CLK(NULL, "core_96m_fck", "core_96m_fck"), -+ DT_CLK(NULL, "mmchs2_fck", "mmchs2_fck"), -+ DT_CLK(NULL, "mmchs1_fck", "mmchs1_fck"), -+ DT_CLK(NULL, "i2c3_fck", "i2c3_fck"), -+ DT_CLK(NULL, "i2c2_fck", "i2c2_fck"), -+ DT_CLK(NULL, "i2c1_fck", "i2c1_fck"), -+ DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"), -+ DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"), -+ DT_CLK(NULL, "core_48m_fck", "core_48m_fck"), -+ DT_CLK(NULL, "mcspi4_fck", "mcspi4_fck"), -+ DT_CLK(NULL, "mcspi3_fck", "mcspi3_fck"), -+ DT_CLK(NULL, "mcspi2_fck", "mcspi2_fck"), -+ DT_CLK(NULL, "mcspi1_fck", "mcspi1_fck"), -+ DT_CLK(NULL, "uart2_fck", "uart2_fck"), -+ DT_CLK(NULL, "uart1_fck", "uart1_fck"), -+ DT_CLK(NULL, "core_12m_fck", "core_12m_fck"), -+ DT_CLK("omap_hdq.0", "fck", "hdq_fck"), -+ DT_CLK(NULL, "hdq_fck", "hdq_fck"), -+ DT_CLK(NULL, "core_l3_ick", "core_l3_ick"), -+ DT_CLK(NULL, "sdrc_ick", "sdrc_ick"), -+ DT_CLK(NULL, "gpmc_fck", "gpmc_fck"), -+ DT_CLK(NULL, "core_l4_ick", "core_l4_ick"), -+ DT_CLK("omap_hsmmc.1", "ick", "mmchs2_ick"), -+ DT_CLK("omap_hsmmc.0", "ick", "mmchs1_ick"), -+ DT_CLK(NULL, "mmchs2_ick", "mmchs2_ick"), -+ DT_CLK(NULL, "mmchs1_ick", "mmchs1_ick"), -+ DT_CLK("omap_hdq.0", "ick", "hdq_ick"), -+ DT_CLK(NULL, "hdq_ick", "hdq_ick"), -+ DT_CLK("omap2_mcspi.4", "ick", "mcspi4_ick"), -+ DT_CLK("omap2_mcspi.3", "ick", "mcspi3_ick"), -+ DT_CLK("omap2_mcspi.2", "ick", "mcspi2_ick"), -+ DT_CLK("omap2_mcspi.1", "ick", "mcspi1_ick"), -+ DT_CLK(NULL, "mcspi4_ick", "mcspi4_ick"), -+ DT_CLK(NULL, "mcspi3_ick", "mcspi3_ick"), -+ DT_CLK(NULL, "mcspi2_ick", "mcspi2_ick"), -+ DT_CLK(NULL, "mcspi1_ick", "mcspi1_ick"), -+ DT_CLK("omap_i2c.3", "ick", "i2c3_ick"), -+ DT_CLK("omap_i2c.2", "ick", "i2c2_ick"), -+ DT_CLK("omap_i2c.1", "ick", "i2c1_ick"), -+ DT_CLK(NULL, "i2c3_ick", "i2c3_ick"), -+ DT_CLK(NULL, "i2c2_ick", "i2c2_ick"), -+ DT_CLK(NULL, "i2c1_ick", "i2c1_ick"), -+ DT_CLK(NULL, "uart2_ick", "uart2_ick"), -+ DT_CLK(NULL, "uart1_ick", "uart1_ick"), -+ DT_CLK(NULL, "gpt11_ick", "gpt11_ick"), -+ DT_CLK(NULL, "gpt10_ick", "gpt10_ick"), -+ DT_CLK("omap-mcbsp.5", "ick", "mcbsp5_ick"), -+ DT_CLK("omap-mcbsp.1", "ick", "mcbsp1_ick"), -+ DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"), -+ DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"), -+ DT_CLK(NULL, "omapctrl_ick", "omapctrl_ick"), -+ DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"), -+ DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"), -+ DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"), -+ DT_CLK(NULL, "gpt1_fck", "gpt1_fck"), -+ DT_CLK(NULL, "aes2_ick", "aes2_ick"), -+ DT_CLK(NULL, "wkup_32k_fck", "wkup_32k_fck"), -+ DT_CLK(NULL, "gpio1_dbck", "gpio1_dbck"), -+ DT_CLK(NULL, "sha12_ick", "sha12_ick"), -+ DT_CLK(NULL, "wdt2_fck", "wdt2_fck"), -+ DT_CLK("omap_wdt", "ick", "wdt2_ick"), -+ DT_CLK(NULL, "wdt2_ick", "wdt2_ick"), -+ DT_CLK(NULL, "wdt1_ick", "wdt1_ick"), -+ DT_CLK(NULL, "gpio1_ick", "gpio1_ick"), -+ DT_CLK(NULL, "omap_32ksync_ick", "omap_32ksync_ick"), -+ DT_CLK(NULL, "gpt12_ick", "gpt12_ick"), -+ DT_CLK(NULL, "gpt1_ick", "gpt1_ick"), -+ DT_CLK(NULL, "per_96m_fck", "per_96m_fck"), -+ DT_CLK(NULL, "per_48m_fck", "per_48m_fck"), -+ DT_CLK(NULL, "uart3_fck", "uart3_fck"), -+ DT_CLK(NULL, "gpt2_fck", "gpt2_fck"), -+ DT_CLK(NULL, "gpt3_fck", "gpt3_fck"), -+ DT_CLK(NULL, "gpt4_fck", "gpt4_fck"), -+ DT_CLK(NULL, "gpt5_fck", "gpt5_fck"), -+ DT_CLK(NULL, "gpt6_fck", "gpt6_fck"), -+ DT_CLK(NULL, "gpt7_fck", "gpt7_fck"), -+ DT_CLK(NULL, "gpt8_fck", "gpt8_fck"), -+ DT_CLK(NULL, "gpt9_fck", "gpt9_fck"), -+ DT_CLK(NULL, "per_32k_alwon_fck", "per_32k_alwon_fck"), -+ DT_CLK(NULL, "gpio6_dbck", "gpio6_dbck"), -+ DT_CLK(NULL, "gpio5_dbck", "gpio5_dbck"), -+ DT_CLK(NULL, "gpio4_dbck", "gpio4_dbck"), -+ DT_CLK(NULL, "gpio3_dbck", "gpio3_dbck"), -+ DT_CLK(NULL, "gpio2_dbck", "gpio2_dbck"), -+ DT_CLK(NULL, "wdt3_fck", "wdt3_fck"), -+ DT_CLK(NULL, "per_l4_ick", "per_l4_ick"), -+ DT_CLK(NULL, "gpio6_ick", "gpio6_ick"), -+ DT_CLK(NULL, "gpio5_ick", "gpio5_ick"), -+ DT_CLK(NULL, "gpio4_ick", "gpio4_ick"), -+ DT_CLK(NULL, "gpio3_ick", "gpio3_ick"), -+ DT_CLK(NULL, "gpio2_ick", "gpio2_ick"), -+ DT_CLK(NULL, "wdt3_ick", "wdt3_ick"), -+ DT_CLK(NULL, "uart3_ick", "uart3_ick"), -+ DT_CLK(NULL, "uart4_ick", "uart4_ick"), -+ DT_CLK(NULL, "gpt9_ick", "gpt9_ick"), -+ DT_CLK(NULL, "gpt8_ick", "gpt8_ick"), -+ DT_CLK(NULL, "gpt7_ick", "gpt7_ick"), -+ DT_CLK(NULL, "gpt6_ick", "gpt6_ick"), -+ DT_CLK(NULL, "gpt5_ick", "gpt5_ick"), -+ DT_CLK(NULL, "gpt4_ick", "gpt4_ick"), -+ DT_CLK(NULL, "gpt3_ick", "gpt3_ick"), -+ DT_CLK(NULL, "gpt2_ick", "gpt2_ick"), -+ DT_CLK("omap-mcbsp.2", "ick", "mcbsp2_ick"), -+ DT_CLK("omap-mcbsp.3", "ick", "mcbsp3_ick"), -+ DT_CLK("omap-mcbsp.4", "ick", "mcbsp4_ick"), -+ DT_CLK(NULL, "mcbsp4_ick", "mcbsp2_ick"), -+ DT_CLK(NULL, "mcbsp3_ick", "mcbsp3_ick"), -+ DT_CLK(NULL, "mcbsp2_ick", "mcbsp4_ick"), -+ DT_CLK(NULL, "mcbsp2_fck", "mcbsp2_fck"), -+ DT_CLK(NULL, "mcbsp3_fck", "mcbsp3_fck"), -+ DT_CLK(NULL, "mcbsp4_fck", "mcbsp4_fck"), -+ DT_CLK("etb", "emu_src_ck", "emu_src_ck"), -+ DT_CLK(NULL, "emu_src_ck", "emu_src_ck"), -+ DT_CLK(NULL, "pclk_fck", "pclk_fck"), -+ DT_CLK(NULL, "pclkx2_fck", "pclkx2_fck"), -+ DT_CLK(NULL, "atclk_fck", "atclk_fck"), -+ DT_CLK(NULL, "traceclk_src_fck", "traceclk_src_fck"), -+ DT_CLK(NULL, "traceclk_fck", "traceclk_fck"), -+ DT_CLK(NULL, "secure_32k_fck", "secure_32k_fck"), -+ DT_CLK(NULL, "gpt12_fck", "gpt12_fck"), -+ DT_CLK(NULL, "wdt1_fck", "wdt1_fck"), -+ DT_CLK(NULL, "timer_32k_ck", "omap_32k_fck"), -+ DT_CLK(NULL, "timer_sys_ck", "sys_ck"), -+ DT_CLK(NULL, "cpufreq_ck", "dpll1_ck"), -+ { .node_name = NULL }, -+}; -+ -+static struct omap_dt_clk omap34xx_omap36xx_clks[] = { -+ DT_CLK(NULL, "aes1_ick", "aes1_ick"), -+ DT_CLK("omap_rng", "ick", "rng_ick"), -+ DT_CLK(NULL, "sha11_ick", "sha11_ick"), -+ DT_CLK(NULL, "des1_ick", "des1_ick"), -+ DT_CLK(NULL, "cam_mclk", "cam_mclk"), -+ DT_CLK(NULL, "cam_ick", "cam_ick"), -+ DT_CLK(NULL, "csi2_96m_fck", "csi2_96m_fck"), -+ DT_CLK(NULL, "security_l3_ick", "security_l3_ick"), -+ DT_CLK(NULL, "pka_ick", "pka_ick"), -+ DT_CLK(NULL, "icr_ick", "icr_ick"), -+ DT_CLK("omap-aes", "ick", "aes2_ick"), -+ DT_CLK("omap-sham", "ick", "sha12_ick"), -+ DT_CLK(NULL, "des2_ick", "des2_ick"), -+ DT_CLK(NULL, "mspro_ick", "mspro_ick"), -+ DT_CLK(NULL, "mailboxes_ick", "mailboxes_ick"), -+ DT_CLK(NULL, "ssi_l4_ick", "ssi_l4_ick"), -+ DT_CLK(NULL, "sr1_fck", "sr1_fck"), -+ DT_CLK(NULL, "sr2_fck", "sr2_fck"), -+ DT_CLK(NULL, "sr_l4_ick", "sr_l4_ick"), -+ DT_CLK(NULL, "security_l4_ick2", "security_l4_ick2"), -+ DT_CLK(NULL, "wkup_l4_ick", "wkup_l4_ick"), -+ DT_CLK(NULL, "dpll2_fck", "dpll2_fck"), -+ DT_CLK(NULL, "iva2_ck", "iva2_ck"), -+ DT_CLK(NULL, "modem_fck", "modem_fck"), -+ DT_CLK(NULL, "sad2d_ick", "sad2d_ick"), -+ DT_CLK(NULL, "mad2d_ick", "mad2d_ick"), -+ DT_CLK(NULL, "mspro_fck", "mspro_fck"), -+ DT_CLK(NULL, "dpll2_ck", "dpll2_ck"), -+ DT_CLK(NULL, "dpll2_m2_ck", "dpll2_m2_ck"), -+ { .node_name = NULL }, -+}; -+ -+static struct omap_dt_clk omap36xx_omap3430es2plus_clks[] = { -+ DT_CLK(NULL, "ssi_ssr_fck", "ssi_ssr_fck_3430es2"), -+ DT_CLK(NULL, "ssi_sst_fck", "ssi_sst_fck_3430es2"), -+ DT_CLK("musb-omap2430", "ick", "hsotgusb_ick_3430es2"), -+ DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_3430es2"), -+ DT_CLK(NULL, "ssi_ick", "ssi_ick_3430es2"), -+ DT_CLK(NULL, "usim_fck", "usim_fck"), -+ DT_CLK(NULL, "usim_ick", "usim_ick"), -+ { .node_name = NULL }, -+}; -+ -+static struct omap_dt_clk omap3430es1_clks[] = { -+ DT_CLK(NULL, "gfx_l3_ck", "gfx_l3_ck"), -+ DT_CLK(NULL, "gfx_l3_fck", "gfx_l3_fck"), -+ DT_CLK(NULL, "gfx_l3_ick", "gfx_l3_ick"), -+ DT_CLK(NULL, "gfx_cg1_ck", "gfx_cg1_ck"), -+ DT_CLK(NULL, "gfx_cg2_ck", "gfx_cg2_ck"), -+ DT_CLK(NULL, "d2d_26m_fck", "d2d_26m_fck"), -+ DT_CLK(NULL, "fshostusb_fck", "fshostusb_fck"), -+ DT_CLK(NULL, "ssi_ssr_fck", "ssi_ssr_fck_3430es1"), -+ DT_CLK(NULL, "ssi_sst_fck", "ssi_sst_fck_3430es1"), -+ DT_CLK("musb-omap2430", "ick", "hsotgusb_ick_3430es1"), -+ DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_3430es1"), -+ DT_CLK(NULL, "fac_ick", "fac_ick"), -+ DT_CLK(NULL, "ssi_ick", "ssi_ick_3430es1"), -+ DT_CLK(NULL, "usb_l4_ick", "usb_l4_ick"), -+ DT_CLK(NULL, "dss1_alwon_fck", "dss1_alwon_fck_3430es1"), -+ DT_CLK("omapdss_dss", "ick", "dss_ick_3430es1"), -+ DT_CLK(NULL, "dss_ick", "dss_ick_3430es1"), -+ { .node_name = NULL }, -+}; -+ -+static struct omap_dt_clk omap36xx_am35xx_omap3430es2plus_clks[] = { -+ DT_CLK(NULL, "virt_16_8m_ck", "virt_16_8m_ck"), -+ DT_CLK(NULL, "dpll5_ck", "dpll5_ck"), -+ DT_CLK(NULL, "dpll5_m2_ck", "dpll5_m2_ck"), -+ DT_CLK(NULL, "sgx_fck", "sgx_fck"), -+ DT_CLK(NULL, "sgx_ick", "sgx_ick"), -+ DT_CLK(NULL, "cpefuse_fck", "cpefuse_fck"), -+ DT_CLK(NULL, "ts_fck", "ts_fck"), -+ DT_CLK(NULL, "usbtll_fck", "usbtll_fck"), -+ DT_CLK(NULL, "usbtll_ick", "usbtll_ick"), -+ DT_CLK("omap_hsmmc.2", "ick", "mmchs3_ick"), -+ DT_CLK(NULL, "mmchs3_ick", "mmchs3_ick"), -+ DT_CLK(NULL, "mmchs3_fck", "mmchs3_fck"), -+ DT_CLK(NULL, "dss1_alwon_fck", "dss1_alwon_fck_3430es2"), -+ DT_CLK("omapdss_dss", "ick", "dss_ick_3430es2"), -+ DT_CLK(NULL, "dss_ick", "dss_ick_3430es2"), -+ DT_CLK(NULL, "usbhost_120m_fck", "usbhost_120m_fck"), -+ DT_CLK(NULL, "usbhost_48m_fck", "usbhost_48m_fck"), -+ DT_CLK(NULL, "usbhost_ick", "usbhost_ick"), -+ { .node_name = NULL }, -+}; -+ -+static struct omap_dt_clk am35xx_clks[] = { -+ DT_CLK(NULL, "ipss_ick", "ipss_ick"), -+ DT_CLK(NULL, "rmii_ck", "rmii_ck"), -+ DT_CLK(NULL, "pclk_ck", "pclk_ck"), -+ DT_CLK(NULL, "emac_ick", "emac_ick"), -+ DT_CLK(NULL, "emac_fck", "emac_fck"), -+ DT_CLK("davinci_emac.0", NULL, "emac_ick"), -+ DT_CLK("davinci_mdio.0", NULL, "emac_fck"), -+ DT_CLK("vpfe-capture", "master", "vpfe_ick"), -+ DT_CLK("vpfe-capture", "slave", "vpfe_fck"), -+ DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_am35xx"), -+ DT_CLK(NULL, "hsotgusb_fck", "hsotgusb_fck_am35xx"), -+ DT_CLK(NULL, "hecc_ck", "hecc_ck"), -+ DT_CLK(NULL, "uart4_ick", "uart4_ick_am35xx"), -+ DT_CLK(NULL, "uart4_fck", "uart4_fck_am35xx"), -+ { .node_name = NULL }, -+}; -+ -+static const char *enable_init_clks[] = { -+ "sdrc_ick", -+ "gpmc_fck", -+ "omapctrl_ick", -+}; -+ -+enum { -+ OMAP3_SOC_AM35XX, -+ OMAP3_SOC_OMAP3430_ES1, -+ OMAP3_SOC_OMAP3430_ES2_PLUS, -+ OMAP3_SOC_OMAP3630, -+ OMAP3_SOC_TI81XX, -+}; -+ -+static int __init omap3xxx_clk_init(int soc_type) -+{ -+ of_clk_init(NULL); -+ -+ if (soc_type == OMAP3_SOC_AM35XX || soc_type == OMAP3_SOC_OMAP3630 || -+ soc_type == OMAP3_SOC_OMAP3430_ES1 || -+ soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS) -+ omap_dt_clocks_register(omap3xxx_clks); -+ -+ if (soc_type == OMAP3_SOC_AM35XX) -+ omap_dt_clocks_register(am35xx_clks); -+ -+ if (soc_type == OMAP3_SOC_OMAP3630 || soc_type == OMAP3_SOC_AM35XX || -+ soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS) -+ omap_dt_clocks_register(omap36xx_am35xx_omap3430es2plus_clks); -+ -+ if (soc_type == OMAP3_SOC_OMAP3430_ES1) -+ omap_dt_clocks_register(omap3430es1_clks); -+ -+ if (soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS || -+ soc_type == OMAP3_SOC_OMAP3630) -+ omap_dt_clocks_register(omap36xx_omap3430es2plus_clks); -+ -+ if (soc_type == OMAP3_SOC_OMAP3430_ES1 || -+ soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS || -+ soc_type == OMAP3_SOC_OMAP3630) -+ omap_dt_clocks_register(omap34xx_omap36xx_clks); -+ -+ omap2_clk_disable_autoidle_all(); -+ -+ omap2_clk_enable_init_clocks(enable_init_clks, -+ ARRAY_SIZE(enable_init_clks)); -+ -+ pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n", -+ (clk_get_rate(clk_get_sys(NULL, "osc_sys_ck")) / 1000000), -+ (clk_get_rate(clk_get_sys(NULL, "osc_sys_ck")) / 100000) % 10, -+ (clk_get_rate(clk_get_sys(NULL, "core_ck")) / 1000000), -+ (clk_get_rate(clk_get_sys(NULL, "arm_fck")) / 1000000)); -+ -+ if (soc_type != OMAP3_SOC_TI81XX && soc_type != OMAP3_SOC_OMAP3430_ES1) -+ omap3_clk_lock_dpll5(); -+ -+ return 0; -+} -+ -+int __init omap3430_clk_init(void) -+{ -+ return omap3xxx_clk_init(OMAP3_SOC_OMAP3430_ES2_PLUS); -+} -+ -+int __init omap3630_clk_init(void) -+{ -+ return omap3xxx_clk_init(OMAP3_SOC_OMAP3630); -+} -+ -+int __init am35xx_clk_init(void) -+{ -+ return omap3xxx_clk_init(OMAP3_SOC_AM35XX); -+} -+ -+int __init ti81xx_clk_init(void) -+{ -+ return omap3xxx_clk_init(OMAP3_SOC_TI81XX); -+} ---- /dev/null -+++ b/drivers/clk/ti/clk-43xx.c -@@ -0,0 +1,136 @@ -+/* -+ * AM43XX Clock init -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc -+ * Tero Kristo (t-kristo@ti.com) -+ * -+ * 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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/clk-provider.h> -+#include <linux/clk/ti.h> -+ -+ -+static struct omap_dt_clk am43xx_clks[] = { -+ DT_CLK(NULL, "clk_32768_ck", "clk_32768_ck"), -+ DT_CLK(NULL, "clk_rc32k_ck", "clk_rc32k_ck"), -+ DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), -+ DT_CLK(NULL, "virt_24000000_ck", "virt_24000000_ck"), -+ DT_CLK(NULL, "virt_25000000_ck", "virt_25000000_ck"), -+ DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), -+ DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"), -+ DT_CLK(NULL, "tclkin_ck", "tclkin_ck"), -+ DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"), -+ DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"), -+ DT_CLK(NULL, "dpll_core_m4_ck", "dpll_core_m4_ck"), -+ DT_CLK(NULL, "dpll_core_m5_ck", "dpll_core_m5_ck"), -+ DT_CLK(NULL, "dpll_core_m6_ck", "dpll_core_m6_ck"), -+ DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"), -+ DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"), -+ DT_CLK(NULL, "dpll_ddr_ck", "dpll_ddr_ck"), -+ DT_CLK(NULL, "dpll_ddr_m2_ck", "dpll_ddr_m2_ck"), -+ DT_CLK(NULL, "dpll_disp_ck", "dpll_disp_ck"), -+ DT_CLK(NULL, "dpll_disp_m2_ck", "dpll_disp_m2_ck"), -+ DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"), -+ DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"), -+ DT_CLK(NULL, "dpll_per_m2_div4_wkupdm_ck", "dpll_per_m2_div4_wkupdm_ck"), -+ DT_CLK(NULL, "dpll_per_m2_div4_ck", "dpll_per_m2_div4_ck"), -+ DT_CLK(NULL, "adc_tsc_fck", "adc_tsc_fck"), -+ DT_CLK(NULL, "clkdiv32k_ck", "clkdiv32k_ck"), -+ DT_CLK(NULL, "clkdiv32k_ick", "clkdiv32k_ick"), -+ DT_CLK(NULL, "dcan0_fck", "dcan0_fck"), -+ DT_CLK(NULL, "dcan1_fck", "dcan1_fck"), -+ DT_CLK(NULL, "pruss_ocp_gclk", "pruss_ocp_gclk"), -+ DT_CLK(NULL, "mcasp0_fck", "mcasp0_fck"), -+ DT_CLK(NULL, "mcasp1_fck", "mcasp1_fck"), -+ DT_CLK(NULL, "smartreflex0_fck", "smartreflex0_fck"), -+ DT_CLK(NULL, "smartreflex1_fck", "smartreflex1_fck"), -+ DT_CLK(NULL, "sha0_fck", "sha0_fck"), -+ DT_CLK(NULL, "rng_fck", "rng_fck"), -+ DT_CLK(NULL, "aes0_fck", "aes0_fck"), -+ DT_CLK(NULL, "timer1_fck", "timer1_fck"), -+ DT_CLK(NULL, "timer2_fck", "timer2_fck"), -+ DT_CLK(NULL, "timer3_fck", "timer3_fck"), -+ DT_CLK(NULL, "timer4_fck", "timer4_fck"), -+ DT_CLK(NULL, "timer5_fck", "timer5_fck"), -+ DT_CLK(NULL, "timer6_fck", "timer6_fck"), -+ DT_CLK(NULL, "timer7_fck", "timer7_fck"), -+ DT_CLK(NULL, "wdt1_fck", "wdt1_fck"), -+ DT_CLK(NULL, "l3_gclk", "l3_gclk"), -+ DT_CLK(NULL, "dpll_core_m4_div2_ck", "dpll_core_m4_div2_ck"), -+ DT_CLK(NULL, "l4hs_gclk", "l4hs_gclk"), -+ DT_CLK(NULL, "l3s_gclk", "l3s_gclk"), -+ DT_CLK(NULL, "l4ls_gclk", "l4ls_gclk"), -+ DT_CLK(NULL, "clk_24mhz", "clk_24mhz"), -+ DT_CLK(NULL, "cpsw_125mhz_gclk", "cpsw_125mhz_gclk"), -+ DT_CLK(NULL, "cpsw_cpts_rft_clk", "cpsw_cpts_rft_clk"), -+ DT_CLK(NULL, "gpio0_dbclk_mux_ck", "gpio0_dbclk_mux_ck"), -+ DT_CLK(NULL, "gpio0_dbclk", "gpio0_dbclk"), -+ DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"), -+ DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"), -+ DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"), -+ DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"), -+ DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"), -+ DT_CLK(NULL, "mmc_clk", "mmc_clk"), -+ DT_CLK(NULL, "gfx_fclk_clksel_ck", "gfx_fclk_clksel_ck"), -+ DT_CLK(NULL, "gfx_fck_div_ck", "gfx_fck_div_ck"), -+ DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"), -+ DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK(NULL, "sysclk_div", "sysclk_div"), -+ DT_CLK(NULL, "disp_clk", "disp_clk"), -+ DT_CLK(NULL, "clk_32k_mosc_ck", "clk_32k_mosc_ck"), -+ DT_CLK(NULL, "clk_32k_tpm_ck", "clk_32k_tpm_ck"), -+ DT_CLK(NULL, "dpll_extdev_ck", "dpll_extdev_ck"), -+ DT_CLK(NULL, "dpll_extdev_m2_ck", "dpll_extdev_m2_ck"), -+ DT_CLK(NULL, "mux_synctimer32k_ck", "mux_synctimer32k_ck"), -+ DT_CLK(NULL, "synctimer_32kclk", "synctimer_32kclk"), -+ DT_CLK(NULL, "timer8_fck", "timer8_fck"), -+ DT_CLK(NULL, "timer9_fck", "timer9_fck"), -+ DT_CLK(NULL, "timer10_fck", "timer10_fck"), -+ DT_CLK(NULL, "timer11_fck", "timer11_fck"), -+ DT_CLK(NULL, "cpsw_50m_clkdiv", "cpsw_50m_clkdiv"), -+ DT_CLK(NULL, "cpsw_5m_clkdiv", "cpsw_5m_clkdiv"), -+ DT_CLK(NULL, "dpll_ddr_x2_ck", "dpll_ddr_x2_ck"), -+ DT_CLK(NULL, "dpll_ddr_m4_ck", "dpll_ddr_m4_ck"), -+ DT_CLK(NULL, "dpll_per_clkdcoldo", "dpll_per_clkdcoldo"), -+ DT_CLK(NULL, "dll_aging_clk_div", "dll_aging_clk_div"), -+ DT_CLK(NULL, "div_core_25m_ck", "div_core_25m_ck"), -+ DT_CLK(NULL, "func_12m_clk", "func_12m_clk"), -+ DT_CLK(NULL, "vtp_clk_div", "vtp_clk_div"), -+ DT_CLK(NULL, "usbphy_32khz_clkmux", "usbphy_32khz_clkmux"), -+ { .node_name = NULL }, -+}; -+ -+int __init am43xx_clk_init(void) -+{ -+ struct clk *clk1, *clk2; -+ -+ of_clk_init(NULL); -+ -+ omap_dt_clocks_register(am43xx_clks); -+ -+ omap2_clk_disable_autoidle_all(); -+ -+ /* -+ * The external 32KHz RTC clock source may not always be available -+ * on board like in the case of ePOS EVM. By default sync timer, which -+ * is used as clock source, feeds of this clock. This is a problem. -+ * Change the parent of sync timer to PER PLL 32KHz clock instead -+ * which is always present. This has a side effect that in low power -+ * modes, sync timer will stop. -+ */ -+ clk1 = clk_get_sys(NULL, "mux_synctimer32k_ck"); -+ clk2 = clk_get_sys(NULL, "clkdiv32k_ick"); -+ clk_set_parent(clk1, clk2); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/clk/ti/clk-44xx.c -@@ -0,0 +1,307 @@ -+/* -+ * OMAP4 Clock data -+ * -+ * Copyright (C) 2009-2012 Texas Instruments, Inc. -+ * Copyright (C) 2009-2010 Nokia Corporation -+ * -+ * Paul Walmsley (paul@pwsan.com) -+ * Rajendra Nayak (rnayak@ti.com) -+ * Benoit Cousson (b-cousson@ti.com) -+ * Mike Turquette (mturquette@ti.com) -+ * -+ * 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. -+ * -+ * XXX Some of the ES1 clocks have been removed/changed; once support -+ * is added for discriminating clocks by ES level, these should be added back -+ * in. -+ * -+ * XXX All of the remaining MODULEMODE clock nodes should be removed -+ * once the drivers are updated to use pm_runtime or to use the appropriate -+ * upstream clock node for rate/parent selection. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/clk-private.h> -+#include <linux/clkdev.h> -+#include <linux/clk/ti.h> -+ -+/* -+ * OMAP4 ABE DPLL default frequency. In OMAP4460 TRM version V, section -+ * "3.6.3.2.3 CM1_ABE Clock Generator" states that the "DPLL_ABE_X2_CLK -+ * must be set to 196.608 MHz" and hence, the DPLL locked frequency is -+ * half of this value. -+ */ -+#define OMAP4_DPLL_ABE_DEFFREQ 98304000 -+ -+/* -+ * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section -+ * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred -+ * locked frequency for the USB DPLL is 960MHz. -+ */ -+#define OMAP4_DPLL_USB_DEFFREQ 960000000 -+ -+static struct omap_dt_clk omap44xx_clks[] = { -+ DT_CLK(NULL, "extalt_clkin_ck", "extalt_clkin_ck"), -+ DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"), -+ DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"), -+ DT_CLK(NULL, "pad_slimbus_core_clks_ck", "pad_slimbus_core_clks_ck"), -+ DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"), -+ DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"), -+ DT_CLK(NULL, "slimbus_clk", "slimbus_clk"), -+ DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"), -+ DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"), -+ DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"), -+ DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"), -+ DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), -+ DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), -+ DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"), -+ DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"), -+ DT_CLK(NULL, "sys_clkin_ck", "sys_clkin_ck"), -+ DT_CLK(NULL, "tie_low_clock_ck", "tie_low_clock_ck"), -+ DT_CLK(NULL, "utmi_phy_clkout_ck", "utmi_phy_clkout_ck"), -+ DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"), -+ DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"), -+ DT_CLK(NULL, "xclk60motg_ck", "xclk60motg_ck"), -+ DT_CLK(NULL, "abe_dpll_bypass_clk_mux_ck", "abe_dpll_bypass_clk_mux_ck"), -+ DT_CLK(NULL, "abe_dpll_refclk_mux_ck", "abe_dpll_refclk_mux_ck"), -+ DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"), -+ DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"), -+ DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"), -+ DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"), -+ DT_CLK(NULL, "abe_clk", "abe_clk"), -+ DT_CLK(NULL, "aess_fclk", "aess_fclk"), -+ DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"), -+ DT_CLK(NULL, "core_hsd_byp_clk_mux_ck", "core_hsd_byp_clk_mux_ck"), -+ DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"), -+ DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"), -+ DT_CLK(NULL, "dpll_core_m6x2_ck", "dpll_core_m6x2_ck"), -+ DT_CLK(NULL, "dbgclk_mux_ck", "dbgclk_mux_ck"), -+ DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"), -+ DT_CLK(NULL, "ddrphy_ck", "ddrphy_ck"), -+ DT_CLK(NULL, "dpll_core_m5x2_ck", "dpll_core_m5x2_ck"), -+ DT_CLK(NULL, "div_core_ck", "div_core_ck"), -+ DT_CLK(NULL, "div_iva_hs_clk", "div_iva_hs_clk"), -+ DT_CLK(NULL, "div_mpu_hs_clk", "div_mpu_hs_clk"), -+ DT_CLK(NULL, "dpll_core_m4x2_ck", "dpll_core_m4x2_ck"), -+ DT_CLK(NULL, "dll_clk_div_ck", "dll_clk_div_ck"), -+ DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"), -+ DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"), -+ DT_CLK(NULL, "dpll_core_m7x2_ck", "dpll_core_m7x2_ck"), -+ DT_CLK(NULL, "iva_hsd_byp_clk_mux_ck", "iva_hsd_byp_clk_mux_ck"), -+ DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"), -+ DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"), -+ DT_CLK(NULL, "dpll_iva_m4x2_ck", "dpll_iva_m4x2_ck"), -+ DT_CLK(NULL, "dpll_iva_m5x2_ck", "dpll_iva_m5x2_ck"), -+ DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"), -+ DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"), -+ DT_CLK(NULL, "per_hs_clk_div_ck", "per_hs_clk_div_ck"), -+ DT_CLK(NULL, "per_hsd_byp_clk_mux_ck", "per_hsd_byp_clk_mux_ck"), -+ DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"), -+ DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"), -+ DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"), -+ DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"), -+ DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"), -+ DT_CLK(NULL, "dpll_per_m4x2_ck", "dpll_per_m4x2_ck"), -+ DT_CLK(NULL, "dpll_per_m5x2_ck", "dpll_per_m5x2_ck"), -+ DT_CLK(NULL, "dpll_per_m6x2_ck", "dpll_per_m6x2_ck"), -+ DT_CLK(NULL, "dpll_per_m7x2_ck", "dpll_per_m7x2_ck"), -+ DT_CLK(NULL, "usb_hs_clk_div_ck", "usb_hs_clk_div_ck"), -+ DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"), -+ DT_CLK(NULL, "dpll_usb_clkdcoldo_ck", "dpll_usb_clkdcoldo_ck"), -+ DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"), -+ DT_CLK(NULL, "ducati_clk_mux_ck", "ducati_clk_mux_ck"), -+ DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"), -+ DT_CLK(NULL, "func_24m_clk", "func_24m_clk"), -+ DT_CLK(NULL, "func_24mc_fclk", "func_24mc_fclk"), -+ DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"), -+ DT_CLK(NULL, "func_48mc_fclk", "func_48mc_fclk"), -+ DT_CLK(NULL, "func_64m_fclk", "func_64m_fclk"), -+ DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"), -+ DT_CLK(NULL, "init_60m_fclk", "init_60m_fclk"), -+ DT_CLK(NULL, "l3_div_ck", "l3_div_ck"), -+ DT_CLK(NULL, "l4_div_ck", "l4_div_ck"), -+ DT_CLK(NULL, "lp_clk_div_ck", "lp_clk_div_ck"), -+ DT_CLK(NULL, "l4_wkup_clk_mux_ck", "l4_wkup_clk_mux_ck"), -+ DT_CLK("smp_twd", NULL, "mpu_periphclk"), -+ DT_CLK(NULL, "ocp_abe_iclk", "ocp_abe_iclk"), -+ DT_CLK(NULL, "per_abe_24m_fclk", "per_abe_24m_fclk"), -+ DT_CLK(NULL, "per_abe_nc_fclk", "per_abe_nc_fclk"), -+ DT_CLK(NULL, "syc_clk_div_ck", "syc_clk_div_ck"), -+ DT_CLK(NULL, "aes1_fck", "aes1_fck"), -+ DT_CLK(NULL, "aes2_fck", "aes2_fck"), -+ DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"), -+ DT_CLK(NULL, "func_dmic_abe_gfclk", "func_dmic_abe_gfclk"), -+ DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"), -+ DT_CLK(NULL, "dss_tv_clk", "dss_tv_clk"), -+ DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"), -+ DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"), -+ DT_CLK(NULL, "dss_fck", "dss_fck"), -+ DT_CLK("omapdss_dss", "ick", "dss_fck"), -+ DT_CLK(NULL, "fdif_fck", "fdif_fck"), -+ DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"), -+ DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"), -+ DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"), -+ DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"), -+ DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"), -+ DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"), -+ DT_CLK(NULL, "sgx_clk_mux", "sgx_clk_mux"), -+ DT_CLK(NULL, "hsi_fck", "hsi_fck"), -+ DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"), -+ DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"), -+ DT_CLK(NULL, "func_mcasp_abe_gfclk", "func_mcasp_abe_gfclk"), -+ DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"), -+ DT_CLK(NULL, "func_mcbsp1_gfclk", "func_mcbsp1_gfclk"), -+ DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"), -+ DT_CLK(NULL, "func_mcbsp2_gfclk", "func_mcbsp2_gfclk"), -+ DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"), -+ DT_CLK(NULL, "func_mcbsp3_gfclk", "func_mcbsp3_gfclk"), -+ DT_CLK(NULL, "mcbsp4_sync_mux_ck", "mcbsp4_sync_mux_ck"), -+ DT_CLK(NULL, "per_mcbsp4_gfclk", "per_mcbsp4_gfclk"), -+ DT_CLK(NULL, "hsmmc1_fclk", "hsmmc1_fclk"), -+ DT_CLK(NULL, "hsmmc2_fclk", "hsmmc2_fclk"), -+ DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "ocp2scp_usb_phy_phy_48m"), -+ DT_CLK(NULL, "sha2md5_fck", "sha2md5_fck"), -+ DT_CLK(NULL, "slimbus1_fclk_1", "slimbus1_fclk_1"), -+ DT_CLK(NULL, "slimbus1_fclk_0", "slimbus1_fclk_0"), -+ DT_CLK(NULL, "slimbus1_fclk_2", "slimbus1_fclk_2"), -+ DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"), -+ DT_CLK(NULL, "slimbus2_fclk_1", "slimbus2_fclk_1"), -+ DT_CLK(NULL, "slimbus2_fclk_0", "slimbus2_fclk_0"), -+ DT_CLK(NULL, "slimbus2_slimbus_clk", "slimbus2_slimbus_clk"), -+ DT_CLK(NULL, "smartreflex_core_fck", "smartreflex_core_fck"), -+ DT_CLK(NULL, "smartreflex_iva_fck", "smartreflex_iva_fck"), -+ DT_CLK(NULL, "smartreflex_mpu_fck", "smartreflex_mpu_fck"), -+ DT_CLK(NULL, "dmt1_clk_mux", "dmt1_clk_mux"), -+ DT_CLK(NULL, "cm2_dm10_mux", "cm2_dm10_mux"), -+ DT_CLK(NULL, "cm2_dm11_mux", "cm2_dm11_mux"), -+ DT_CLK(NULL, "cm2_dm2_mux", "cm2_dm2_mux"), -+ DT_CLK(NULL, "cm2_dm3_mux", "cm2_dm3_mux"), -+ DT_CLK(NULL, "cm2_dm4_mux", "cm2_dm4_mux"), -+ DT_CLK(NULL, "timer5_sync_mux", "timer5_sync_mux"), -+ DT_CLK(NULL, "timer6_sync_mux", "timer6_sync_mux"), -+ DT_CLK(NULL, "timer7_sync_mux", "timer7_sync_mux"), -+ DT_CLK(NULL, "timer8_sync_mux", "timer8_sync_mux"), -+ DT_CLK(NULL, "cm2_dm9_mux", "cm2_dm9_mux"), -+ DT_CLK(NULL, "usb_host_fs_fck", "usb_host_fs_fck"), -+ DT_CLK("usbhs_omap", "fs_fck", "usb_host_fs_fck"), -+ DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"), -+ DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"), -+ DT_CLK(NULL, "usb_host_hs_func48mclk", "usb_host_hs_func48mclk"), -+ DT_CLK(NULL, "usb_host_hs_fck", "usb_host_hs_fck"), -+ DT_CLK("usbhs_omap", "hs_fck", "usb_host_hs_fck"), -+ DT_CLK(NULL, "otg_60m_gfclk", "otg_60m_gfclk"), -+ DT_CLK(NULL, "usb_otg_hs_xclk", "usb_otg_hs_xclk"), -+ DT_CLK(NULL, "usb_otg_hs_ick", "usb_otg_hs_ick"), -+ DT_CLK("musb-omap2430", "ick", "usb_otg_hs_ick"), -+ DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"), -+ DT_CLK(NULL, "usb_tll_hs_ick", "usb_tll_hs_ick"), -+ DT_CLK("usbhs_omap", "usbtll_ick", "usb_tll_hs_ick"), -+ DT_CLK("usbhs_tll", "usbtll_ick", "usb_tll_hs_ick"), -+ DT_CLK(NULL, "usim_ck", "usim_ck"), -+ DT_CLK(NULL, "usim_fclk", "usim_fclk"), -+ DT_CLK(NULL, "pmd_stm_clock_mux_ck", "pmd_stm_clock_mux_ck"), -+ DT_CLK(NULL, "pmd_trace_clk_mux_ck", "pmd_trace_clk_mux_ck"), -+ DT_CLK(NULL, "stm_clk_div_ck", "stm_clk_div_ck"), -+ DT_CLK(NULL, "trace_clk_div_ck", "trace_clk_div_ck"), -+ DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"), -+ DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"), -+ DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"), -+ DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"), -+ DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"), -+ DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"), -+ DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"), -+ DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"), -+ DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"), -+ DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"), -+ DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"), -+ DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"), -+ DT_CLK(NULL, "auxclk4_src_ck", "auxclk4_src_ck"), -+ DT_CLK(NULL, "auxclk4_ck", "auxclk4_ck"), -+ DT_CLK(NULL, "auxclkreq4_ck", "auxclkreq4_ck"), -+ DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"), -+ DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"), -+ DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"), -+ DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), -+ DT_CLK("omap_timer.1", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.2", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.3", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.4", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.9", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.10", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.11", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("omap_timer.5", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("omap_timer.6", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("omap_timer.7", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("omap_timer.8", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("4a318000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("48036000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("4803e000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("48086000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("48088000.timer", "timer_sys_ck", "sys_clkin_ck"), -+ DT_CLK("40138000.timer", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("4013a000.timer", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("4013c000.timer", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK("4013e000.timer", "timer_sys_ck", "syc_clk_div_ck"), -+ DT_CLK(NULL, "cpufreq_ck", "dpll_mpu_ck"), -+ DT_CLK(NULL, "bandgap_fclk", "bandgap_fclk"), -+ DT_CLK(NULL, "div_ts_ck", "div_ts_ck"), -+ DT_CLK(NULL, "bandgap_ts_fclk", "bandgap_ts_fclk"), -+ { .node_name = NULL }, -+}; -+ -+int __init omap4xxx_clk_init(void) -+{ -+ int rc; -+ struct clk *abe_dpll_ref, *abe_dpll, *sys_32k_ck, *usb_dpll; -+ -+ of_clk_init(NULL); -+ -+ omap_dt_clocks_register(omap44xx_clks); -+ -+ omap2_clk_disable_autoidle_all(); -+ -+ /* -+ * A set rate of ABE DPLL inturn triggers a set rate of USB DPLL -+ * when its in bypass. So always lock USB before ABE DPLL. -+ */ -+ /* -+ * Lock USB DPLL on OMAP4 devices so that the L3INIT power -+ * domain can transition to retention state when not in use. -+ */ -+ usb_dpll = clk_get_sys(NULL, "dpll_usb_ck"); -+ rc = clk_set_rate(usb_dpll, OMAP4_DPLL_USB_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure USB DPLL!\n", __func__); -+ -+ /* -+ * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power -+ * state when turning the ABE clock domain. Workaround this by -+ * locking the ABE DPLL on boot. -+ * Lock the ABE DPLL in any case to avoid issues with audio. -+ */ -+ abe_dpll_ref = clk_get_sys(NULL, "abe_dpll_refclk_mux_ck"); -+ sys_32k_ck = clk_get_sys(NULL, "sys_32k_ck"); -+ rc = clk_set_parent(abe_dpll_ref, sys_32k_ck); -+ abe_dpll = clk_get_sys(NULL, "dpll_abe_ck"); -+ if (!rc) -+ rc = clk_set_rate(abe_dpll, OMAP4_DPLL_ABE_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure ABE DPLL!\n", __func__); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/clk/ti/clk-54xx.c -@@ -0,0 +1,231 @@ -+/* -+ * OMAP5 Clock init -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo (t-kristo@ti.com) -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/clk-private.h> -+#include <linux/clkdev.h> -+#include <linux/io.h> -+#include <linux/clk/ti.h> -+ -+#define OMAP5_DPLL_ABE_DEFFREQ 98304000 -+ -+/* -+ * OMAP543x TRM, section "3.6.3.9.5 DPLL_USB Preferred Settings" -+ * states it must be at 960MHz -+ */ -+#define OMAP5_DPLL_USB_DEFFREQ 960000000 -+ -+static struct omap_dt_clk omap54xx_clks[] = { -+ DT_CLK(NULL, "pad_clks_src_ck", "pad_clks_src_ck"), -+ DT_CLK(NULL, "pad_clks_ck", "pad_clks_ck"), -+ DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"), -+ DT_CLK(NULL, "slimbus_src_clk", "slimbus_src_clk"), -+ DT_CLK(NULL, "slimbus_clk", "slimbus_clk"), -+ DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"), -+ DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"), -+ DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"), -+ DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"), -+ DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), -+ DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), -+ DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"), -+ DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"), -+ DT_CLK(NULL, "sys_clkin", "sys_clkin"), -+ DT_CLK(NULL, "xclk60mhsp1_ck", "xclk60mhsp1_ck"), -+ DT_CLK(NULL, "xclk60mhsp2_ck", "xclk60mhsp2_ck"), -+ DT_CLK(NULL, "abe_dpll_bypass_clk_mux", "abe_dpll_bypass_clk_mux"), -+ DT_CLK(NULL, "abe_dpll_clk_mux", "abe_dpll_clk_mux"), -+ DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"), -+ DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"), -+ DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"), -+ DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"), -+ DT_CLK(NULL, "abe_clk", "abe_clk"), -+ DT_CLK(NULL, "abe_iclk", "abe_iclk"), -+ DT_CLK(NULL, "abe_lp_clk_div", "abe_lp_clk_div"), -+ DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"), -+ DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"), -+ DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"), -+ DT_CLK(NULL, "dpll_core_h21x2_ck", "dpll_core_h21x2_ck"), -+ DT_CLK(NULL, "c2c_fclk", "c2c_fclk"), -+ DT_CLK(NULL, "c2c_iclk", "c2c_iclk"), -+ DT_CLK(NULL, "custefuse_sys_gfclk_div", "custefuse_sys_gfclk_div"), -+ DT_CLK(NULL, "dpll_core_h11x2_ck", "dpll_core_h11x2_ck"), -+ DT_CLK(NULL, "dpll_core_h12x2_ck", "dpll_core_h12x2_ck"), -+ DT_CLK(NULL, "dpll_core_h13x2_ck", "dpll_core_h13x2_ck"), -+ DT_CLK(NULL, "dpll_core_h14x2_ck", "dpll_core_h14x2_ck"), -+ DT_CLK(NULL, "dpll_core_h22x2_ck", "dpll_core_h22x2_ck"), -+ DT_CLK(NULL, "dpll_core_h23x2_ck", "dpll_core_h23x2_ck"), -+ DT_CLK(NULL, "dpll_core_h24x2_ck", "dpll_core_h24x2_ck"), -+ DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"), -+ DT_CLK(NULL, "dpll_core_m3x2_ck", "dpll_core_m3x2_ck"), -+ DT_CLK(NULL, "iva_dpll_hs_clk_div", "iva_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"), -+ DT_CLK(NULL, "dpll_iva_x2_ck", "dpll_iva_x2_ck"), -+ DT_CLK(NULL, "dpll_iva_h11x2_ck", "dpll_iva_h11x2_ck"), -+ DT_CLK(NULL, "dpll_iva_h12x2_ck", "dpll_iva_h12x2_ck"), -+ DT_CLK(NULL, "mpu_dpll_hs_clk_div", "mpu_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"), -+ DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"), -+ DT_CLK(NULL, "per_dpll_hs_clk_div", "per_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"), -+ DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"), -+ DT_CLK(NULL, "dpll_per_h11x2_ck", "dpll_per_h11x2_ck"), -+ DT_CLK(NULL, "dpll_per_h12x2_ck", "dpll_per_h12x2_ck"), -+ DT_CLK(NULL, "dpll_per_h14x2_ck", "dpll_per_h14x2_ck"), -+ DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"), -+ DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"), -+ DT_CLK(NULL, "dpll_per_m3x2_ck", "dpll_per_m3x2_ck"), -+ DT_CLK(NULL, "dpll_unipro1_ck", "dpll_unipro1_ck"), -+ DT_CLK(NULL, "dpll_unipro1_clkdcoldo", "dpll_unipro1_clkdcoldo"), -+ DT_CLK(NULL, "dpll_unipro1_m2_ck", "dpll_unipro1_m2_ck"), -+ DT_CLK(NULL, "dpll_unipro2_ck", "dpll_unipro2_ck"), -+ DT_CLK(NULL, "dpll_unipro2_clkdcoldo", "dpll_unipro2_clkdcoldo"), -+ DT_CLK(NULL, "dpll_unipro2_m2_ck", "dpll_unipro2_m2_ck"), -+ DT_CLK(NULL, "usb_dpll_hs_clk_div", "usb_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"), -+ DT_CLK(NULL, "dpll_usb_clkdcoldo", "dpll_usb_clkdcoldo"), -+ DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"), -+ DT_CLK(NULL, "dss_syc_gfclk_div", "dss_syc_gfclk_div"), -+ DT_CLK(NULL, "func_128m_clk", "func_128m_clk"), -+ DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"), -+ DT_CLK(NULL, "func_24m_clk", "func_24m_clk"), -+ DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"), -+ DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"), -+ DT_CLK(NULL, "l3_iclk_div", "l3_iclk_div"), -+ DT_CLK(NULL, "gpu_l3_iclk", "gpu_l3_iclk"), -+ DT_CLK(NULL, "l3init_60m_fclk", "l3init_60m_fclk"), -+ DT_CLK(NULL, "wkupaon_iclk_mux", "wkupaon_iclk_mux"), -+ DT_CLK(NULL, "l3instr_ts_gclk_div", "l3instr_ts_gclk_div"), -+ DT_CLK(NULL, "l4_root_clk_div", "l4_root_clk_div"), -+ DT_CLK(NULL, "dss_32khz_clk", "dss_32khz_clk"), -+ DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"), -+ DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"), -+ DT_CLK(NULL, "dss_sys_clk", "dss_sys_clk"), -+ DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"), -+ DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"), -+ DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"), -+ DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"), -+ DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"), -+ DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"), -+ DT_CLK(NULL, "gpio7_dbclk", "gpio7_dbclk"), -+ DT_CLK(NULL, "gpio8_dbclk", "gpio8_dbclk"), -+ DT_CLK(NULL, "iss_ctrlclk", "iss_ctrlclk"), -+ DT_CLK(NULL, "lli_txphy_clk", "lli_txphy_clk"), -+ DT_CLK(NULL, "lli_txphy_ls_clk", "lli_txphy_ls_clk"), -+ DT_CLK(NULL, "mmc1_32khz_clk", "mmc1_32khz_clk"), -+ DT_CLK(NULL, "sata_ref_clk", "sata_ref_clk"), -+ DT_CLK(NULL, "slimbus1_slimbus_clk", "slimbus1_slimbus_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p1_clk", "usb_host_hs_hsic480m_p1_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p2_clk", "usb_host_hs_hsic480m_p2_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic480m_p3_clk", "usb_host_hs_hsic480m_p3_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p1_clk", "usb_host_hs_hsic60m_p1_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p2_clk", "usb_host_hs_hsic60m_p2_clk"), -+ DT_CLK(NULL, "usb_host_hs_hsic60m_p3_clk", "usb_host_hs_hsic60m_p3_clk"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p1_clk", "usb_host_hs_utmi_p1_clk"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p2_clk", "usb_host_hs_utmi_p2_clk"), -+ DT_CLK(NULL, "usb_host_hs_utmi_p3_clk", "usb_host_hs_utmi_p3_clk"), -+ DT_CLK(NULL, "usb_otg_ss_refclk960m", "usb_otg_ss_refclk960m"), -+ DT_CLK(NULL, "usb_phy_cm_clk32k", "usb_phy_cm_clk32k"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch0_clk", "usb_tll_hs_usb_ch0_clk"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch1_clk", "usb_tll_hs_usb_ch1_clk"), -+ DT_CLK(NULL, "usb_tll_hs_usb_ch2_clk", "usb_tll_hs_usb_ch2_clk"), -+ DT_CLK(NULL, "aess_fclk", "aess_fclk"), -+ DT_CLK(NULL, "dmic_sync_mux_ck", "dmic_sync_mux_ck"), -+ DT_CLK(NULL, "dmic_gfclk", "dmic_gfclk"), -+ DT_CLK(NULL, "fdif_fclk", "fdif_fclk"), -+ DT_CLK(NULL, "gpu_core_gclk_mux", "gpu_core_gclk_mux"), -+ DT_CLK(NULL, "gpu_hyd_gclk_mux", "gpu_hyd_gclk_mux"), -+ DT_CLK(NULL, "hsi_fclk", "hsi_fclk"), -+ DT_CLK(NULL, "mcasp_sync_mux_ck", "mcasp_sync_mux_ck"), -+ DT_CLK(NULL, "mcasp_gfclk", "mcasp_gfclk"), -+ DT_CLK(NULL, "mcbsp1_sync_mux_ck", "mcbsp1_sync_mux_ck"), -+ DT_CLK(NULL, "mcbsp1_gfclk", "mcbsp1_gfclk"), -+ DT_CLK(NULL, "mcbsp2_sync_mux_ck", "mcbsp2_sync_mux_ck"), -+ DT_CLK(NULL, "mcbsp2_gfclk", "mcbsp2_gfclk"), -+ DT_CLK(NULL, "mcbsp3_sync_mux_ck", "mcbsp3_sync_mux_ck"), -+ DT_CLK(NULL, "mcbsp3_gfclk", "mcbsp3_gfclk"), -+ DT_CLK(NULL, "mmc1_fclk_mux", "mmc1_fclk_mux"), -+ DT_CLK(NULL, "mmc1_fclk", "mmc1_fclk"), -+ DT_CLK(NULL, "mmc2_fclk_mux", "mmc2_fclk_mux"), -+ DT_CLK(NULL, "mmc2_fclk", "mmc2_fclk"), -+ DT_CLK(NULL, "timer10_gfclk_mux", "timer10_gfclk_mux"), -+ DT_CLK(NULL, "timer11_gfclk_mux", "timer11_gfclk_mux"), -+ DT_CLK(NULL, "timer1_gfclk_mux", "timer1_gfclk_mux"), -+ DT_CLK(NULL, "timer2_gfclk_mux", "timer2_gfclk_mux"), -+ DT_CLK(NULL, "timer3_gfclk_mux", "timer3_gfclk_mux"), -+ DT_CLK(NULL, "timer4_gfclk_mux", "timer4_gfclk_mux"), -+ DT_CLK(NULL, "timer5_gfclk_mux", "timer5_gfclk_mux"), -+ DT_CLK(NULL, "timer6_gfclk_mux", "timer6_gfclk_mux"), -+ DT_CLK(NULL, "timer7_gfclk_mux", "timer7_gfclk_mux"), -+ DT_CLK(NULL, "timer8_gfclk_mux", "timer8_gfclk_mux"), -+ DT_CLK(NULL, "timer9_gfclk_mux", "timer9_gfclk_mux"), -+ DT_CLK(NULL, "utmi_p1_gfclk", "utmi_p1_gfclk"), -+ DT_CLK(NULL, "utmi_p2_gfclk", "utmi_p2_gfclk"), -+ DT_CLK(NULL, "auxclk0_src_ck", "auxclk0_src_ck"), -+ DT_CLK(NULL, "auxclk0_ck", "auxclk0_ck"), -+ DT_CLK(NULL, "auxclkreq0_ck", "auxclkreq0_ck"), -+ DT_CLK(NULL, "auxclk1_src_ck", "auxclk1_src_ck"), -+ DT_CLK(NULL, "auxclk1_ck", "auxclk1_ck"), -+ DT_CLK(NULL, "auxclkreq1_ck", "auxclkreq1_ck"), -+ DT_CLK(NULL, "auxclk2_src_ck", "auxclk2_src_ck"), -+ DT_CLK(NULL, "auxclk2_ck", "auxclk2_ck"), -+ DT_CLK(NULL, "auxclkreq2_ck", "auxclkreq2_ck"), -+ DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"), -+ DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"), -+ DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"), -+ DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), -+ DT_CLK("omap_timer.1", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.2", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.3", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.4", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.9", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.10", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.11", "sys_ck", "sys_clkin"), -+ DT_CLK("omap_timer.5", "sys_ck", "dss_syc_gfclk_div"), -+ DT_CLK("omap_timer.6", "sys_ck", "dss_syc_gfclk_div"), -+ DT_CLK("omap_timer.7", "sys_ck", "dss_syc_gfclk_div"), -+ DT_CLK("omap_timer.8", "sys_ck", "dss_syc_gfclk_div"), -+ { .node_name = NULL }, -+}; -+ -+int __init omap5xxx_clk_init(void) -+{ -+ int rc; -+ struct clk *abe_dpll_ref, *abe_dpll, *sys_32k_ck, *usb_dpll; -+ -+ of_clk_init(NULL); -+ -+ omap_dt_clocks_register(omap54xx_clks); -+ -+ omap2_clk_disable_autoidle_all(); -+ -+ abe_dpll_ref = clk_get_sys(NULL, "abe_dpll_clk_mux"); -+ sys_32k_ck = clk_get_sys(NULL, "sys_32k_ck"); -+ rc = clk_set_parent(abe_dpll_ref, sys_32k_ck); -+ abe_dpll = clk_get_sys(NULL, "dpll_abe_ck"); -+ if (!rc) -+ rc = clk_set_rate(abe_dpll, OMAP5_DPLL_ABE_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure ABE DPLL!\n", __func__); -+ -+ usb_dpll = clk_get_sys(NULL, "dpll_usb_ck"); -+ rc = clk_set_rate(usb_dpll, OMAP5_DPLL_USB_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure USB DPLL!\n", __func__); -+ -+ usb_dpll = clk_get_sys(NULL, "dpll_usb_m2_ck"); -+ rc = clk_set_rate(usb_dpll, OMAP5_DPLL_USB_DEFFREQ/2); -+ if (rc) -+ pr_err("%s: failed to set USB_DPLL M2 OUT\n", __func__); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/clk/ti/clk-7xx.c -@@ -0,0 +1,325 @@ -+/* -+ * DRA7 Clock init -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo (t-kristo@ti.com) -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include <linux/clk-private.h> -+#include <linux/clkdev.h> -+#include <linux/clk/ti.h> -+ -+#define DRA7_DPLL_ABE_DEFFREQ 361267200 -+#define DRA7_DPLL_GMAC_DEFFREQ 1000000000 -+#define DRA7_DPLL_USB_DEFFREQ 960000000 -+ -+ -+static struct omap_dt_clk dra7xx_clks[] = { -+ DT_CLK(NULL, "atl_clkin0_ck", "atl_clkin0_ck"), -+ DT_CLK(NULL, "atl_clkin1_ck", "atl_clkin1_ck"), -+ DT_CLK(NULL, "atl_clkin2_ck", "atl_clkin2_ck"), -+ DT_CLK(NULL, "atlclkin3_ck", "atlclkin3_ck"), -+ DT_CLK(NULL, "hdmi_clkin_ck", "hdmi_clkin_ck"), -+ DT_CLK(NULL, "mlb_clkin_ck", "mlb_clkin_ck"), -+ DT_CLK(NULL, "mlbp_clkin_ck", "mlbp_clkin_ck"), -+ DT_CLK(NULL, "pciesref_acs_clk_ck", "pciesref_acs_clk_ck"), -+ DT_CLK(NULL, "ref_clkin0_ck", "ref_clkin0_ck"), -+ DT_CLK(NULL, "ref_clkin1_ck", "ref_clkin1_ck"), -+ DT_CLK(NULL, "ref_clkin2_ck", "ref_clkin2_ck"), -+ DT_CLK(NULL, "ref_clkin3_ck", "ref_clkin3_ck"), -+ DT_CLK(NULL, "rmii_clk_ck", "rmii_clk_ck"), -+ DT_CLK(NULL, "sdvenc_clkin_ck", "sdvenc_clkin_ck"), -+ DT_CLK(NULL, "secure_32k_clk_src_ck", "secure_32k_clk_src_ck"), -+ DT_CLK(NULL, "sys_32k_ck", "sys_32k_ck"), -+ DT_CLK(NULL, "virt_12000000_ck", "virt_12000000_ck"), -+ DT_CLK(NULL, "virt_13000000_ck", "virt_13000000_ck"), -+ DT_CLK(NULL, "virt_16800000_ck", "virt_16800000_ck"), -+ DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), -+ DT_CLK(NULL, "virt_20000000_ck", "virt_20000000_ck"), -+ DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), -+ DT_CLK(NULL, "virt_27000000_ck", "virt_27000000_ck"), -+ DT_CLK(NULL, "virt_38400000_ck", "virt_38400000_ck"), -+ DT_CLK(NULL, "sys_clkin1", "sys_clkin1"), -+ DT_CLK(NULL, "sys_clkin2", "sys_clkin2"), -+ DT_CLK(NULL, "usb_otg_clkin_ck", "usb_otg_clkin_ck"), -+ DT_CLK(NULL, "video1_clkin_ck", "video1_clkin_ck"), -+ DT_CLK(NULL, "video1_m2_clkin_ck", "video1_m2_clkin_ck"), -+ DT_CLK(NULL, "video2_clkin_ck", "video2_clkin_ck"), -+ DT_CLK(NULL, "video2_m2_clkin_ck", "video2_m2_clkin_ck"), -+ DT_CLK(NULL, "abe_dpll_sys_clk_mux", "abe_dpll_sys_clk_mux"), -+ DT_CLK(NULL, "abe_dpll_bypass_clk_mux", "abe_dpll_bypass_clk_mux"), -+ DT_CLK(NULL, "abe_dpll_clk_mux", "abe_dpll_clk_mux"), -+ DT_CLK(NULL, "dpll_abe_ck", "dpll_abe_ck"), -+ DT_CLK(NULL, "dpll_abe_x2_ck", "dpll_abe_x2_ck"), -+ DT_CLK(NULL, "dpll_abe_m2x2_ck", "dpll_abe_m2x2_ck"), -+ DT_CLK(NULL, "abe_24m_fclk", "abe_24m_fclk"), -+ DT_CLK(NULL, "abe_clk", "abe_clk"), -+ DT_CLK(NULL, "aess_fclk", "aess_fclk"), -+ DT_CLK(NULL, "abe_giclk_div", "abe_giclk_div"), -+ DT_CLK(NULL, "abe_lp_clk_div", "abe_lp_clk_div"), -+ DT_CLK(NULL, "abe_sys_clk_div", "abe_sys_clk_div"), -+ DT_CLK(NULL, "adc_gfclk_mux", "adc_gfclk_mux"), -+ DT_CLK(NULL, "dpll_pcie_ref_ck", "dpll_pcie_ref_ck"), -+ DT_CLK(NULL, "dpll_pcie_ref_m2ldo_ck", "dpll_pcie_ref_m2ldo_ck"), -+ DT_CLK(NULL, "apll_pcie_ck", "apll_pcie_ck"), -+ DT_CLK(NULL, "apll_pcie_clkvcoldo", "apll_pcie_clkvcoldo"), -+ DT_CLK(NULL, "apll_pcie_clkvcoldo_div", "apll_pcie_clkvcoldo_div"), -+ DT_CLK(NULL, "apll_pcie_m2_ck", "apll_pcie_m2_ck"), -+ DT_CLK(NULL, "sys_clk1_dclk_div", "sys_clk1_dclk_div"), -+ DT_CLK(NULL, "sys_clk2_dclk_div", "sys_clk2_dclk_div"), -+ DT_CLK(NULL, "dpll_abe_m2_ck", "dpll_abe_m2_ck"), -+ DT_CLK(NULL, "per_abe_x1_dclk_div", "per_abe_x1_dclk_div"), -+ DT_CLK(NULL, "dpll_abe_m3x2_ck", "dpll_abe_m3x2_ck"), -+ DT_CLK(NULL, "dpll_core_ck", "dpll_core_ck"), -+ DT_CLK(NULL, "dpll_core_x2_ck", "dpll_core_x2_ck"), -+ DT_CLK(NULL, "dpll_core_h12x2_ck", "dpll_core_h12x2_ck"), -+ DT_CLK(NULL, "mpu_dpll_hs_clk_div", "mpu_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"), -+ DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"), -+ DT_CLK(NULL, "mpu_dclk_div", "mpu_dclk_div"), -+ DT_CLK(NULL, "dsp_dpll_hs_clk_div", "dsp_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_dsp_ck", "dpll_dsp_ck"), -+ DT_CLK(NULL, "dpll_dsp_m2_ck", "dpll_dsp_m2_ck"), -+ DT_CLK(NULL, "dsp_gclk_div", "dsp_gclk_div"), -+ DT_CLK(NULL, "iva_dpll_hs_clk_div", "iva_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_iva_ck", "dpll_iva_ck"), -+ DT_CLK(NULL, "dpll_iva_m2_ck", "dpll_iva_m2_ck"), -+ DT_CLK(NULL, "iva_dclk", "iva_dclk"), -+ DT_CLK(NULL, "dpll_gpu_ck", "dpll_gpu_ck"), -+ DT_CLK(NULL, "dpll_gpu_m2_ck", "dpll_gpu_m2_ck"), -+ DT_CLK(NULL, "gpu_dclk", "gpu_dclk"), -+ DT_CLK(NULL, "dpll_core_m2_ck", "dpll_core_m2_ck"), -+ DT_CLK(NULL, "core_dpll_out_dclk_div", "core_dpll_out_dclk_div"), -+ DT_CLK(NULL, "dpll_ddr_ck", "dpll_ddr_ck"), -+ DT_CLK(NULL, "dpll_ddr_m2_ck", "dpll_ddr_m2_ck"), -+ DT_CLK(NULL, "emif_phy_dclk_div", "emif_phy_dclk_div"), -+ DT_CLK(NULL, "dpll_gmac_ck", "dpll_gmac_ck"), -+ DT_CLK(NULL, "dpll_gmac_m2_ck", "dpll_gmac_m2_ck"), -+ DT_CLK(NULL, "gmac_250m_dclk_div", "gmac_250m_dclk_div"), -+ DT_CLK(NULL, "video2_dclk_div", "video2_dclk_div"), -+ DT_CLK(NULL, "video1_dclk_div", "video1_dclk_div"), -+ DT_CLK(NULL, "hdmi_dclk_div", "hdmi_dclk_div"), -+ DT_CLK(NULL, "per_dpll_hs_clk_div", "per_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_per_ck", "dpll_per_ck"), -+ DT_CLK(NULL, "dpll_per_m2_ck", "dpll_per_m2_ck"), -+ DT_CLK(NULL, "func_96m_aon_dclk_div", "func_96m_aon_dclk_div"), -+ DT_CLK(NULL, "usb_dpll_hs_clk_div", "usb_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_usb_ck", "dpll_usb_ck"), -+ DT_CLK(NULL, "dpll_usb_m2_ck", "dpll_usb_m2_ck"), -+ DT_CLK(NULL, "l3init_480m_dclk_div", "l3init_480m_dclk_div"), -+ DT_CLK(NULL, "usb_otg_dclk_div", "usb_otg_dclk_div"), -+ DT_CLK(NULL, "sata_dclk_div", "sata_dclk_div"), -+ DT_CLK(NULL, "dpll_pcie_ref_m2_ck", "dpll_pcie_ref_m2_ck"), -+ DT_CLK(NULL, "pcie2_dclk_div", "pcie2_dclk_div"), -+ DT_CLK(NULL, "pcie_dclk_div", "pcie_dclk_div"), -+ DT_CLK(NULL, "emu_dclk_div", "emu_dclk_div"), -+ DT_CLK(NULL, "secure_32k_dclk_div", "secure_32k_dclk_div"), -+ DT_CLK(NULL, "eve_dpll_hs_clk_div", "eve_dpll_hs_clk_div"), -+ DT_CLK(NULL, "dpll_eve_ck", "dpll_eve_ck"), -+ DT_CLK(NULL, "dpll_eve_m2_ck", "dpll_eve_m2_ck"), -+ DT_CLK(NULL, "eve_dclk_div", "eve_dclk_div"), -+ DT_CLK(NULL, "clkoutmux0_clk_mux", "clkoutmux0_clk_mux"), -+ DT_CLK(NULL, "clkoutmux1_clk_mux", "clkoutmux1_clk_mux"), -+ DT_CLK(NULL, "clkoutmux2_clk_mux", "clkoutmux2_clk_mux"), -+ DT_CLK(NULL, "custefuse_sys_gfclk_div", "custefuse_sys_gfclk_div"), -+ DT_CLK(NULL, "dpll_core_h13x2_ck", "dpll_core_h13x2_ck"), -+ DT_CLK(NULL, "dpll_core_h14x2_ck", "dpll_core_h14x2_ck"), -+ DT_CLK(NULL, "dpll_core_h22x2_ck", "dpll_core_h22x2_ck"), -+ DT_CLK(NULL, "dpll_core_h23x2_ck", "dpll_core_h23x2_ck"), -+ DT_CLK(NULL, "dpll_core_h24x2_ck", "dpll_core_h24x2_ck"), -+ DT_CLK(NULL, "dpll_ddr_x2_ck", "dpll_ddr_x2_ck"), -+ DT_CLK(NULL, "dpll_ddr_h11x2_ck", "dpll_ddr_h11x2_ck"), -+ DT_CLK(NULL, "dpll_dsp_x2_ck", "dpll_dsp_x2_ck"), -+ DT_CLK(NULL, "dpll_dsp_m3x2_ck", "dpll_dsp_m3x2_ck"), -+ DT_CLK(NULL, "dpll_gmac_x2_ck", "dpll_gmac_x2_ck"), -+ DT_CLK(NULL, "dpll_gmac_h11x2_ck", "dpll_gmac_h11x2_ck"), -+ DT_CLK(NULL, "dpll_gmac_h12x2_ck", "dpll_gmac_h12x2_ck"), -+ DT_CLK(NULL, "dpll_gmac_h13x2_ck", "dpll_gmac_h13x2_ck"), -+ DT_CLK(NULL, "dpll_gmac_m3x2_ck", "dpll_gmac_m3x2_ck"), -+ DT_CLK(NULL, "dpll_per_x2_ck", "dpll_per_x2_ck"), -+ DT_CLK(NULL, "dpll_per_h11x2_ck", "dpll_per_h11x2_ck"), -+ DT_CLK(NULL, "dpll_per_h12x2_ck", "dpll_per_h12x2_ck"), -+ DT_CLK(NULL, "dpll_per_h13x2_ck", "dpll_per_h13x2_ck"), -+ DT_CLK(NULL, "dpll_per_h14x2_ck", "dpll_per_h14x2_ck"), -+ DT_CLK(NULL, "dpll_per_m2x2_ck", "dpll_per_m2x2_ck"), -+ DT_CLK(NULL, "dpll_usb_clkdcoldo", "dpll_usb_clkdcoldo"), -+ DT_CLK(NULL, "eve_clk", "eve_clk"), -+ DT_CLK(NULL, "func_128m_clk", "func_128m_clk"), -+ DT_CLK(NULL, "func_12m_fclk", "func_12m_fclk"), -+ DT_CLK(NULL, "func_24m_clk", "func_24m_clk"), -+ DT_CLK(NULL, "func_48m_fclk", "func_48m_fclk"), -+ DT_CLK(NULL, "func_96m_fclk", "func_96m_fclk"), -+ DT_CLK(NULL, "gmii_m_clk_div", "gmii_m_clk_div"), -+ DT_CLK(NULL, "hdmi_clk2_div", "hdmi_clk2_div"), -+ DT_CLK(NULL, "hdmi_div_clk", "hdmi_div_clk"), -+ DT_CLK(NULL, "hdmi_dpll_clk_mux", "hdmi_dpll_clk_mux"), -+ DT_CLK(NULL, "l3_iclk_div", "l3_iclk_div"), -+ DT_CLK(NULL, "l3init_60m_fclk", "l3init_60m_fclk"), -+ DT_CLK(NULL, "l4_root_clk_div", "l4_root_clk_div"), -+ DT_CLK(NULL, "mlb_clk", "mlb_clk"), -+ DT_CLK(NULL, "mlbp_clk", "mlbp_clk"), -+ DT_CLK(NULL, "per_abe_x1_gfclk2_div", "per_abe_x1_gfclk2_div"), -+ DT_CLK(NULL, "timer_sys_clk_div", "timer_sys_clk_div"), -+ DT_CLK(NULL, "video1_clk2_div", "video1_clk2_div"), -+ DT_CLK(NULL, "video1_div_clk", "video1_div_clk"), -+ DT_CLK(NULL, "video1_dpll_clk_mux", "video1_dpll_clk_mux"), -+ DT_CLK(NULL, "video2_clk2_div", "video2_clk2_div"), -+ DT_CLK(NULL, "video2_div_clk", "video2_div_clk"), -+ DT_CLK(NULL, "video2_dpll_clk_mux", "video2_dpll_clk_mux"), -+ DT_CLK(NULL, "wkupaon_iclk_mux", "wkupaon_iclk_mux"), -+ DT_CLK(NULL, "dss_32khz_clk", "dss_32khz_clk"), -+ DT_CLK(NULL, "dss_48mhz_clk", "dss_48mhz_clk"), -+ DT_CLK(NULL, "dss_dss_clk", "dss_dss_clk"), -+ DT_CLK(NULL, "dss_hdmi_clk", "dss_hdmi_clk"), -+ DT_CLK(NULL, "dss_video1_clk", "dss_video1_clk"), -+ DT_CLK(NULL, "dss_video2_clk", "dss_video2_clk"), -+ DT_CLK(NULL, "dss_deshdcp_clk", "dss_deshdcp_clk"), -+ DT_CLK(NULL, "gpio1_dbclk", "gpio1_dbclk"), -+ DT_CLK(NULL, "gpio2_dbclk", "gpio2_dbclk"), -+ DT_CLK(NULL, "gpio3_dbclk", "gpio3_dbclk"), -+ DT_CLK(NULL, "gpio4_dbclk", "gpio4_dbclk"), -+ DT_CLK(NULL, "gpio5_dbclk", "gpio5_dbclk"), -+ DT_CLK(NULL, "gpio6_dbclk", "gpio6_dbclk"), -+ DT_CLK(NULL, "gpio7_dbclk", "gpio7_dbclk"), -+ DT_CLK(NULL, "gpio8_dbclk", "gpio8_dbclk"), -+ DT_CLK(NULL, "mmc1_clk32k", "mmc1_clk32k"), -+ DT_CLK(NULL, "mmc2_clk32k", "mmc2_clk32k"), -+ DT_CLK(NULL, "mmc3_clk32k", "mmc3_clk32k"), -+ DT_CLK(NULL, "mmc4_clk32k", "mmc4_clk32k"), -+ DT_CLK(NULL, "sata_ref_clk", "sata_ref_clk"), -+ DT_CLK(NULL, "usb_otg_ss1_refclk960m", "usb_otg_ss1_refclk960m"), -+ DT_CLK(NULL, "usb_otg_ss2_refclk960m", "usb_otg_ss2_refclk960m"), -+ DT_CLK(NULL, "usb_phy1_always_on_clk32k", "usb_phy1_always_on_clk32k"), -+ DT_CLK(NULL, "usb_phy2_always_on_clk32k", "usb_phy2_always_on_clk32k"), -+ DT_CLK(NULL, "usb_phy3_always_on_clk32k", "usb_phy3_always_on_clk32k"), -+ DT_CLK(NULL, "atl_dpll_clk_mux", "atl_dpll_clk_mux"), -+ DT_CLK(NULL, "atl_gfclk_mux", "atl_gfclk_mux"), -+ DT_CLK(NULL, "dcan1_sys_clk_mux", "dcan1_sys_clk_mux"), -+ DT_CLK(NULL, "gmac_gmii_ref_clk_div", "gmac_gmii_ref_clk_div"), -+ DT_CLK(NULL, "gmac_rft_clk_mux", "gmac_rft_clk_mux"), -+ DT_CLK(NULL, "gpu_core_gclk_mux", "gpu_core_gclk_mux"), -+ DT_CLK(NULL, "gpu_hyd_gclk_mux", "gpu_hyd_gclk_mux"), -+ DT_CLK(NULL, "ipu1_gfclk_mux", "ipu1_gfclk_mux"), -+ DT_CLK(NULL, "l3instr_ts_gclk_div", "l3instr_ts_gclk_div"), -+ DT_CLK(NULL, "mcasp1_ahclkr_mux", "mcasp1_ahclkr_mux"), -+ DT_CLK(NULL, "mcasp1_ahclkx_mux", "mcasp1_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "mcasp1_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp2_ahclkr_mux", "mcasp2_ahclkr_mux"), -+ DT_CLK(NULL, "mcasp2_ahclkx_mux", "mcasp2_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "mcasp2_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp3_ahclkx_mux", "mcasp3_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "mcasp3_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp4_ahclkx_mux", "mcasp4_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "mcasp4_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp5_ahclkx_mux", "mcasp5_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "mcasp5_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp6_ahclkx_mux", "mcasp6_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "mcasp6_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp7_ahclkx_mux", "mcasp7_ahclkx_mux"), -+ DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "mcasp7_aux_gfclk_mux"), -+ DT_CLK(NULL, "mcasp8_ahclk_mux", "mcasp8_ahclk_mux"), -+ DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "mcasp8_aux_gfclk_mux"), -+ DT_CLK(NULL, "mmc1_fclk_mux", "mmc1_fclk_mux"), -+ DT_CLK(NULL, "mmc1_fclk_div", "mmc1_fclk_div"), -+ DT_CLK(NULL, "mmc2_fclk_mux", "mmc2_fclk_mux"), -+ DT_CLK(NULL, "mmc2_fclk_div", "mmc2_fclk_div"), -+ DT_CLK(NULL, "mmc3_gfclk_mux", "mmc3_gfclk_mux"), -+ DT_CLK(NULL, "mmc3_gfclk_div", "mmc3_gfclk_div"), -+ DT_CLK(NULL, "mmc4_gfclk_mux", "mmc4_gfclk_mux"), -+ DT_CLK(NULL, "mmc4_gfclk_div", "mmc4_gfclk_div"), -+ DT_CLK(NULL, "qspi_gfclk_mux", "qspi_gfclk_mux"), -+ DT_CLK(NULL, "qspi_gfclk_div", "qspi_gfclk_div"), -+ DT_CLK(NULL, "timer10_gfclk_mux", "timer10_gfclk_mux"), -+ DT_CLK(NULL, "timer11_gfclk_mux", "timer11_gfclk_mux"), -+ DT_CLK(NULL, "timer13_gfclk_mux", "timer13_gfclk_mux"), -+ DT_CLK(NULL, "timer14_gfclk_mux", "timer14_gfclk_mux"), -+ DT_CLK(NULL, "timer15_gfclk_mux", "timer15_gfclk_mux"), -+ DT_CLK(NULL, "timer16_gfclk_mux", "timer16_gfclk_mux"), -+ DT_CLK(NULL, "timer1_gfclk_mux", "timer1_gfclk_mux"), -+ DT_CLK(NULL, "timer2_gfclk_mux", "timer2_gfclk_mux"), -+ DT_CLK(NULL, "timer3_gfclk_mux", "timer3_gfclk_mux"), -+ DT_CLK(NULL, "timer4_gfclk_mux", "timer4_gfclk_mux"), -+ DT_CLK(NULL, "timer5_gfclk_mux", "timer5_gfclk_mux"), -+ DT_CLK(NULL, "timer6_gfclk_mux", "timer6_gfclk_mux"), -+ DT_CLK(NULL, "timer7_gfclk_mux", "timer7_gfclk_mux"), -+ DT_CLK(NULL, "timer8_gfclk_mux", "timer8_gfclk_mux"), -+ DT_CLK(NULL, "timer9_gfclk_mux", "timer9_gfclk_mux"), -+ DT_CLK(NULL, "uart10_gfclk_mux", "uart10_gfclk_mux"), -+ DT_CLK(NULL, "uart1_gfclk_mux", "uart1_gfclk_mux"), -+ DT_CLK(NULL, "uart2_gfclk_mux", "uart2_gfclk_mux"), -+ DT_CLK(NULL, "uart3_gfclk_mux", "uart3_gfclk_mux"), -+ DT_CLK(NULL, "uart4_gfclk_mux", "uart4_gfclk_mux"), -+ DT_CLK(NULL, "uart5_gfclk_mux", "uart5_gfclk_mux"), -+ DT_CLK(NULL, "uart6_gfclk_mux", "uart6_gfclk_mux"), -+ DT_CLK(NULL, "uart7_gfclk_mux", "uart7_gfclk_mux"), -+ DT_CLK(NULL, "uart8_gfclk_mux", "uart8_gfclk_mux"), -+ DT_CLK(NULL, "uart9_gfclk_mux", "uart9_gfclk_mux"), -+ DT_CLK(NULL, "vip1_gclk_mux", "vip1_gclk_mux"), -+ DT_CLK(NULL, "vip2_gclk_mux", "vip2_gclk_mux"), -+ DT_CLK(NULL, "vip3_gclk_mux", "vip3_gclk_mux"), -+ DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), -+ DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("48036000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("4803e000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("48086000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("48088000.timer", "timer_sys_ck", "sys_clkin2"), -+ DT_CLK("48820000.timer", "timer_sys_ck", "timer_sys_clk_div"), -+ DT_CLK("48822000.timer", "timer_sys_ck", "timer_sys_clk_div"), -+ DT_CLK("48824000.timer", "timer_sys_ck", "timer_sys_clk_div"), -+ DT_CLK("48826000.timer", "timer_sys_ck", "timer_sys_clk_div"), -+ DT_CLK(NULL, "sys_clkin", "sys_clkin1"), -+ { .node_name = NULL }, -+}; -+ -+int __init dra7xx_clk_init(void) -+{ -+ int rc; -+ struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *deshdcp_clk; -+ -+ of_clk_init(NULL); -+ -+ omap_dt_clocks_register(dra7xx_clks); -+ -+ omap2_clk_disable_autoidle_all(); -+ -+ abe_dpll_mux = clk_get_sys(NULL, "abe_dpll_sys_clk_mux"); -+ sys_clkin2 = clk_get_sys(NULL, "sys_clkin2"); -+ dpll_ck = clk_get_sys(NULL, "dpll_abe_ck"); -+ -+ rc = clk_set_parent(abe_dpll_mux, sys_clkin2); -+ if (!rc) -+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure ABE DPLL!\n", __func__); -+ -+ dpll_ck = clk_get_sys(NULL, "dpll_gmac_ck"); -+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_GMAC_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure GMAC DPLL!\n", __func__); -+ -+ dpll_ck = clk_get_sys(NULL, "dpll_usb_ck"); -+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_USB_DEFFREQ); -+ if (rc) -+ pr_err("%s: failed to configure USB DPLL!\n", __func__); -+ -+ dpll_ck = clk_get_sys(NULL, "dpll_usb_m2_ck"); -+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_USB_DEFFREQ/2); -+ if (rc) -+ pr_err("%s: failed to set USB_DPLL M2 OUT\n", __func__); -+ -+ deshdcp_clk = clk_get_sys(NULL, "dss_deshdcp_clk"); -+ rc = clk_prepare_enable(deshdcp_clk); -+ if (rc) -+ pr_err("%s: failed to enable DESHDCP clock\n", __func__); -+ -+ return rc; -+} ---- /dev/null -+++ b/drivers/clk/ti/clk.c -@@ -0,0 +1,52 @@ -+/* -+ * TI clock support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo <t-kristo@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/clkdev.h> -+#include <linux/clk/ti.h> -+#include <linux/of.h> -+ -+/** -+ * omap_dt_clocks_register - register DT duplicate clocks during boot -+ * @oclks: list of clocks to register -+ * -+ * Register duplicate or non-standard DT clock entries during boot. By -+ * default, DT clocks are found based on their node name. If any -+ * additional con-id / dev-id -> clock mapping is required, use this -+ * function to list these. -+ */ -+void __init omap_dt_clocks_register(struct omap_dt_clk oclks[]) -+{ -+ struct omap_dt_clk *c; -+ struct device_node *node; -+ struct clk *clk; -+ struct of_phandle_args clkspec; -+ -+ for (c = oclks; c->node_name != NULL; c++) { -+ node = of_find_node_by_name(NULL, c->node_name); -+ clkspec.np = node; -+ clk = of_clk_get_from_provider(&clkspec); -+ -+ if (!IS_ERR(clk)) { -+ c->lk.clk = clk; -+ clkdev_add(&c->lk); -+ } else { -+ pr_warn("%s: failed to lookup clock node %s\n", -+ __func__, c->node_name); -+ } -+ } -+} ---- /dev/null -+++ b/drivers/clk/ti/clockdomain.c -@@ -0,0 +1,46 @@ -+/* -+ * OMAP clockdomain support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo <t-kristo@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/clk/ti.h> -+ -+void __init of_omap_clockdomain_setup(struct device_node *node) -+{ -+ struct clk *clk; -+ struct clk_hw *clk_hw; -+ const char *clkdm_name = node->name; -+ int i; -+ int num_clks; -+ -+ num_clks = of_count_phandle_with_args(node, "clocks", "#clock-cells"); -+ -+ for (i = 0; i < num_clks; i++) { -+ clk = of_clk_get(node, i); -+ if (__clk_get_flags(clk) & CLK_IS_BASIC) { -+ pr_warn("%s: can't setup clkdm for basic clk %s\n", -+ __func__, __clk_get_name(clk)); -+ continue; -+ } -+ clk_hw = __clk_get_hw(clk); -+ to_clk_hw_omap(clk_hw)->clkdm_name = clkdm_name; -+ omap2_init_clk_clkdm(clk_hw); -+ } -+} -+CLK_OF_DECLARE(omap_clockdomain, "ti,clockdomain", of_omap_clockdomain_setup); ---- /dev/null -+++ b/drivers/clk/ti/dpll.c -@@ -0,0 +1,476 @@ -+/* -+ * OMAP DPLL clock support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo <t-kristo@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/slab.h> -+#include <linux/err.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/clk/ti.h> -+ -+static const struct clk_ops dpll_m4xen_ck_ops = { -+ .enable = &omap3_noncore_dpll_enable, -+ .disable = &omap3_noncore_dpll_disable, -+ .recalc_rate = &omap4_dpll_regm4xen_recalc, -+ .round_rate = &omap4_dpll_regm4xen_round_rate, -+ .set_rate = &omap3_noncore_dpll_set_rate, -+ .get_parent = &omap2_init_dpll_parent, -+}; -+ -+static const struct clk_ops dpll_core_ck_ops = { -+ .recalc_rate = &omap3_dpll_recalc, -+ .get_parent = &omap2_init_dpll_parent, -+}; -+ -+static const struct clk_ops omap3_dpll_core_ck_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .get_parent = &omap2_init_dpll_parent, -+ .recalc_rate = &omap3_dpll_recalc, -+ .round_rate = &omap2_dpll_round_rate, -+}; -+ -+static const struct clk_ops dpll_ck_ops = { -+ .enable = &omap3_noncore_dpll_enable, -+ .disable = &omap3_noncore_dpll_disable, -+ .recalc_rate = &omap3_dpll_recalc, -+ .round_rate = &omap2_dpll_round_rate, -+ .set_rate = &omap3_noncore_dpll_set_rate, -+ .get_parent = &omap2_init_dpll_parent, -+ .init = &omap2_init_clk_clkdm, -+}; -+ -+static const struct clk_ops dpll_no_gate_ck_ops = { -+ .recalc_rate = &omap3_dpll_recalc, -+ .get_parent = &omap2_init_dpll_parent, -+ .round_rate = &omap2_dpll_round_rate, -+ .set_rate = &omap3_noncore_dpll_set_rate, -+}; -+ -+static const struct clk_ops omap3_dpll_ck_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .enable = &omap3_noncore_dpll_enable, -+ .disable = &omap3_noncore_dpll_disable, -+ .get_parent = &omap2_init_dpll_parent, -+ .recalc_rate = &omap3_dpll_recalc, -+ .set_rate = &omap3_noncore_dpll_set_rate, -+ .round_rate = &omap2_dpll_round_rate, -+}; -+ -+static const struct clk_ops omap3_dpll_per_ck_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .enable = &omap3_noncore_dpll_enable, -+ .disable = &omap3_noncore_dpll_disable, -+ .get_parent = &omap2_init_dpll_parent, -+ .recalc_rate = &omap3_dpll_recalc, -+ .set_rate = &omap3_dpll4_set_rate, -+ .round_rate = &omap2_dpll_round_rate, -+}; -+ -+static const struct clk_ops dpll_x2_ck_ops = { -+ .recalc_rate = &omap3_clkoutx2_recalc, -+}; -+ -+static struct clk *omap_clk_register_dpll(struct device *dev, const char *name, -+ const char **parent_names, int num_parents, unsigned long flags, -+ struct dpll_data *dpll_data, const char *clkdm_name, -+ const struct clk_ops *ops) -+{ -+ struct clk *clk; -+ struct clk_init_data init = { 0 }; -+ struct clk_hw_omap *clk_hw; -+ -+ /* allocate the divider */ -+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); -+ if (!clk_hw) { -+ pr_err("%s: could not allocate clk_hw_omap\n", __func__); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ clk_hw->dpll_data = dpll_data; -+ clk_hw->ops = &clkhwops_omap3_dpll; -+ clk_hw->clkdm_name = clkdm_name; -+ clk_hw->hw.init = &init; -+ -+ init.name = name; -+ init.ops = ops; -+ init.flags = flags; -+ init.parent_names = parent_names; -+ init.num_parents = num_parents; -+ -+ /* register the clock */ -+ clk = clk_register(dev, &clk_hw->hw); -+ -+ if (IS_ERR(clk)) -+ kfree(clk_hw); -+ else -+ omap2_init_clk_hw_omap_clocks(clk); -+ -+ return clk; -+} -+ -+static struct clk *omap_clk_register_dpll_x2(struct device *dev, -+ const char *name, const char *parent_name, void __iomem *reg, -+ const struct clk_ops *ops) -+{ -+ struct clk *clk; -+ struct clk_init_data init = { 0 }; -+ struct clk_hw_omap *clk_hw; -+ -+ if (!parent_name) { -+ pr_err("%s: dpll_x2 must have parent\n", __func__); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); -+ if (!clk_hw) { -+ pr_err("%s: could not allocate clk_hw_omap\n", __func__); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ clk_hw->ops = &clkhwops_omap4_dpllmx; -+ clk_hw->clksel_reg = reg; -+ clk_hw->hw.init = &init; -+ -+ init.name = name; -+ init.ops = ops; -+ init.parent_names = &parent_name; -+ init.num_parents = 1; -+ -+ /* register the clock */ -+ clk = clk_register(dev, &clk_hw->hw); -+ -+ if (IS_ERR(clk)) -+ kfree(clk_hw); -+ else -+ omap2_init_clk_hw_omap_clocks(clk); -+ -+ return clk; -+} -+ -+/** -+ * of_omap_dpll_setup() - Setup function for OMAP DPLL clocks -+ * -+ * @node: device node containing the DPLL info -+ * @ops: ops for the DPLL -+ * @ddt: DPLL data template to use -+ */ -+static void __init of_omap_dpll_setup(struct device_node *node, -+ const struct clk_ops *ops, -+ const struct dpll_data *ddt) -+{ -+ struct clk *clk; -+ const char *clk_name = node->name; -+ int num_parents; -+ const char **parent_names = NULL; -+ const char *clkdm_name = NULL; -+ u8 dpll_flags = 0; -+ struct dpll_data *dd; -+ int i; -+ u32 val; -+ -+ dd = kzalloc(sizeof(*dd), GFP_KERNEL); -+ if (!dd) { -+ pr_err("%s: could not allocate dpll_data\n", __func__); -+ return; -+ } -+ -+ memcpy(dd, ddt, sizeof(*dd)); -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ num_parents = of_clk_get_parent_count(node); -+ if (num_parents < 1) { -+ pr_err("%s: omap dpll %s must have parent(s)\n", -+ __func__, node->name); -+ goto cleanup; -+ } -+ -+ parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL); -+ -+ for (i = 0; i < num_parents; i++) -+ parent_names[i] = of_clk_get_parent_name(node, i); -+ -+ dd->clk_ref = of_clk_get(node, 0); -+ dd->clk_bypass = of_clk_get(node, 1); -+ -+ if (IS_ERR(dd->clk_ref)) { -+ pr_err("%s: ti,clk-ref for %s not found\n", __func__, -+ clk_name); -+ goto cleanup; -+ } -+ -+ if (IS_ERR(dd->clk_bypass)) { -+ pr_err("%s: ti,clk-bypass for %s not found\n", __func__, -+ clk_name); -+ goto cleanup; -+ } -+ -+ of_property_read_string(node, "ti,clkdm-name", &clkdm_name); -+ -+ i = of_property_match_string(node, "reg-names", "control"); -+ if (i >= 0) -+ dd->control_reg = of_iomap(node, i); -+ -+ i = of_property_match_string(node, "reg-names", "idlest"); -+ if (i >= 0) -+ dd->idlest_reg = of_iomap(node, i); -+ -+ i = of_property_match_string(node, "reg-names", "autoidle"); -+ if (i >= 0) -+ dd->autoidle_reg = of_iomap(node, i); -+ -+ i = of_property_match_string(node, "reg-names", "mult-div1"); -+ if (i >= 0) -+ dd->mult_div1_reg = of_iomap(node, i); -+ -+ if (!of_property_read_u32(node, "ti,modes", &val)) -+ dd->modes = val; -+ -+ clk = omap_clk_register_dpll(NULL, clk_name, parent_names, -+ num_parents, dpll_flags, dd, -+ clkdm_name, ops); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+ return; -+ -+cleanup: -+ kfree(dd); -+ kfree(parent_names); -+ return; -+} -+ -+static void __init of_omap_dpll_x2_setup(struct device_node *node) -+{ -+ struct clk *clk; -+ const char *clk_name = node->name; -+ void __iomem *reg; -+ const char *parent_name; -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ parent_name = of_clk_get_parent_name(node, 0); -+ -+ reg = of_iomap(node, 0); -+ -+ clk = omap_clk_register_dpll_x2(NULL, clk_name, parent_name, -+ reg, &dpll_x2_ck_ops); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+} -+CLK_OF_DECLARE(omap_dpll_x2_clock, "ti,omap4-dpll-x2-clock", -+ of_omap_dpll_x2_setup); -+ -+static void __init of_omap3_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .freqsel_mask = 0xf0, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &omap3_dpll_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap3_dpll_clock, "ti,omap3-dpll-clock", of_omap3_dpll_setup); -+ -+static void __init of_omap3_core_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 16, -+ .div1_mask = 0x7f << 8, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .freqsel_mask = 0xf0, -+ }; -+ -+ of_omap_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap3_core_dpll_clock, "ti,omap3-dpll-core-clock", -+ of_omap3_core_dpll_setup); -+ -+static void __init of_omap3_per_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1 << 1, -+ .enable_mask = 0x7 << 16, -+ .autoidle_mask = 0x7 << 3, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .freqsel_mask = 0xf00000, -+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap3_per_dpll_clock, "ti,omap3-dpll-per-clock", -+ of_omap3_per_dpll_setup); -+ -+static void __init of_omap3_per_jtype_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1 << 1, -+ .enable_mask = 0x7 << 16, -+ .autoidle_mask = 0x7 << 3, -+ .mult_mask = 0xfff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 4095, -+ .max_divider = 128, -+ .min_divider = 1, -+ .sddiv_mask = 0xff << 24, -+ .dco_mask = 0xe << 20, -+ .flags = DPLL_J_TYPE, -+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock", -+ of_omap3_per_jtype_dpll_setup); -+ -+static void __init of_omap4_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &dpll_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap4_dpll_clock, "ti,omap4-dpll-clock", of_omap4_dpll_setup); -+ -+static void __init of_omap4_core_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &dpll_core_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap4_core_dpll_clock, "ti,omap4-dpll-core-clock", -+ of_omap4_core_dpll_setup); -+ -+static void __init of_omap4_m4xen_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .m4xen_mask = 0x800, -+ .lpmode_mask = 1 << 10, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &dpll_m4xen_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock", -+ of_omap4_m4xen_dpll_setup); -+ -+static void __init of_omap4_jtype_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0xfff << 8, -+ .div1_mask = 0xff, -+ .max_multiplier = 4095, -+ .max_divider = 256, -+ .min_divider = 1, -+ .sddiv_mask = 0xff << 24, -+ .flags = DPLL_J_TYPE, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &dpll_m4xen_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock", -+ of_omap4_jtype_dpll_setup); -+ -+static void __init of_omap4_no_gate_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &dpll_no_gate_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap4_no_gate_dpll_clock, "ti,omap4-dpll-no-gate-clock", -+ of_omap4_no_gate_dpll_setup); -+ -+static void __init of_omap4_no_gate_jtype_dpll_setup(struct device_node *node) -+{ -+ const struct dpll_data dd = { -+ .idlest_mask = 0x1, -+ .enable_mask = 0x7, -+ .autoidle_mask = 0x7, -+ .mult_mask = 0x7ff << 8, -+ .div1_mask = 0x7f, -+ .max_multiplier = 2047, -+ .max_divider = 128, -+ .min_divider = 1, -+ .flags = DPLL_J_TYPE, -+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), -+ }; -+ -+ of_omap_dpll_setup(node, &dpll_no_gate_ck_ops, &dd); -+} -+CLK_OF_DECLARE(omap4_no_gate_jtype_dpll_clock, -+ "ti,omap4-dpll-no-gate-j-type-clock", -+ of_omap4_no_gate_jtype_dpll_setup); ---- /dev/null -+++ b/drivers/clk/ti/gate.c -@@ -0,0 +1,174 @@ -+/* -+ * OMAP gate clock support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo <t-kristo@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/slab.h> -+#include <linux/io.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/clk/ti.h> -+ -+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) -+ -+static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *clk); -+ -+static const struct clk_ops omap_gate_clkdm_clk_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .enable = &omap2_clkops_enable_clkdm, -+ .disable = &omap2_clkops_disable_clkdm, -+}; -+ -+static const struct clk_ops omap_gate_clk_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .enable = &omap2_dflt_clk_enable, -+ .disable = &omap2_dflt_clk_disable, -+ .is_enabled = &omap2_dflt_clk_is_enabled, -+}; -+ -+static const struct clk_ops omap_gate_clk_hsdiv_restore_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .enable = &omap36xx_gate_clk_enable_with_hsdiv_restore, -+ .disable = &omap2_dflt_clk_disable, -+ .is_enabled = &omap2_dflt_clk_is_enabled, -+}; -+ -+/** -+ * omap36xx_gate_clk_enable_with_hsdiv_restore - enable clocks suffering -+ * from HSDivider PWRDN problem Implements Errata ID: i556. -+ * @clk: DPLL output struct clk -+ * -+ * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck, -+ * dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset -+ * valueafter their respective PWRDN bits are set. Any dummy write -+ * (Any other value different from the Read value) to the -+ * corresponding CM_CLKSEL register will refresh the dividers. -+ */ -+static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *clk) -+{ -+ struct clk_divider *parent; -+ struct clk_hw *parent_hw; -+ u32 dummy_v, orig_v; -+ int ret; -+ -+ /* Clear PWRDN bit of HSDIVIDER */ -+ ret = omap2_dflt_clk_enable(clk); -+ -+ /* Parent is the x2 node, get parent of parent for the m2 div */ -+ parent_hw = __clk_get_hw(__clk_get_parent(__clk_get_parent(clk->clk))); -+ parent = to_clk_divider(parent_hw); -+ -+ /* Restore the dividers */ -+ if (!ret) { -+ orig_v = __raw_readl(parent->reg); -+ dummy_v = orig_v; -+ -+ /* Write any other value different from the Read value */ -+ dummy_v ^= (1 << parent->shift); -+ __raw_writel(dummy_v, parent->reg); -+ -+ /* Write the original divider */ -+ __raw_writel(orig_v, parent->reg); -+ } -+ -+ return ret; -+} -+ -+static void __init _of_omap_gate_clk_setup(struct device_node *node, -+ void __iomem *reg, -+ const struct clk_ops *ops, -+ const struct clk_hw_omap_ops *hw_ops) -+{ -+ struct clk *clk; -+ struct clk_init_data init = { 0 }; -+ struct clk_hw_omap *clk_hw; -+ const char *clk_name = node->name; -+ const char *parent_name; -+ u32 val; -+ -+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); -+ if (!clk_hw) { -+ pr_err("%s: could not allocate clk_hw_omap\n", __func__); -+ return; -+ } -+ -+ clk_hw->hw.init = &init; -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ init.name = clk_name; -+ init.ops = ops; -+ clk_hw->enable_reg = reg; -+ if (!of_property_read_u32(node, "ti,enable-bit", &val)) -+ clk_hw->enable_bit = val; -+ clk_hw->ops = hw_ops; -+ -+ parent_name = of_clk_get_parent_name(node, 0); -+ init.parent_names = &parent_name; -+ init.num_parents = 1; -+ -+ if (of_property_read_bool(node, "ti,set-rate-parent")) -+ init.flags |= CLK_SET_RATE_PARENT; -+ -+ if (of_property_read_bool(node, "ti,set-bit-to-disable")) -+ clk_hw->flags |= INVERT_ENABLE; -+ -+ clk = clk_register(NULL, &clk_hw->hw); -+ -+ if (!IS_ERR(clk)) -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+} -+ -+static void __init of_omap_clkdm_gate_clk_setup(struct device_node *node) -+{ -+ _of_omap_gate_clk_setup(node, NULL, &omap_gate_clkdm_clk_ops, NULL); -+} -+CLK_OF_DECLARE(omap_clkdm_gate_clk, "ti,clkdm-gate-clock", -+ of_omap_clkdm_gate_clk_setup); -+ -+static void __init of_omap_hsdiv_gate_clk_setup(struct device_node *node) -+{ -+ void __iomem *reg = of_iomap(node, 0); -+ _of_omap_gate_clk_setup(node, reg, &omap_gate_clk_hsdiv_restore_ops, -+ &clkhwops_wait); -+} -+CLK_OF_DECLARE(omap_hsdiv_gate_clk, "ti,hsdiv-gate-clock", -+ of_omap_hsdiv_gate_clk_setup); -+ -+static void __init of_omap_gate_clk_setup(struct device_node *node) -+{ -+ void __iomem *reg = of_iomap(node, 0); -+ _of_omap_gate_clk_setup(node, reg, &omap_gate_clk_ops, &clkhwops_wait); -+} -+CLK_OF_DECLARE(omap_gate_clk, "ti,gate-clock", of_omap_gate_clk_setup); -+ -+static void __init of_omap_am35xx_gate_clk_setup(struct device_node *node) -+{ -+ void __iomem *reg = of_iomap(node, 0); -+ _of_omap_gate_clk_setup(node, reg, &omap_gate_clk_ops, -+ &clkhwops_am35xx_ipss_module_wait); -+} -+CLK_OF_DECLARE(omap_am35xx_gate_clk, "ti,am35xx-gate-clock", -+ of_omap_am35xx_gate_clk_setup); -+ -+static void __init of_omap_dss_gate_clk_setup(struct device_node *node) -+{ -+ void __iomem *reg = of_iomap(node, 0); -+ _of_omap_gate_clk_setup(node, reg, &omap_gate_clk_ops, -+ &clkhwops_omap3430es2_dss_usbhost_wait); -+} -+CLK_OF_DECLARE(omap_dss_gate_clk, "ti,dss-gate-clock", -+ of_omap_dss_gate_clk_setup); ---- /dev/null -+++ b/drivers/clk/ti/interface.c -@@ -0,0 +1,124 @@ -+/* -+ * OMAP interface clock support -+ * -+ * Copyright (C) 2013 Texas Instruments, Inc. -+ * -+ * Tero Kristo <t-kristo@ti.com> -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/clk/ti.h> -+ -+static const struct clk_ops omap_interface_clk_ops = { -+ .init = &omap2_init_clk_clkdm, -+ .enable = &omap2_dflt_clk_enable, -+ .disable = &omap2_dflt_clk_disable, -+ .is_enabled = &omap2_dflt_clk_is_enabled, -+}; -+ -+void __init _of_omap_interface_clk_setup(struct device_node *node, -+ const struct clk_hw_omap_ops *ops) -+{ -+ struct clk *clk; -+ struct clk_init_data init = { 0 }; -+ struct clk_hw_omap *clk_hw; -+ const char *clk_name = node->name; -+ const char *parent_name; -+ u32 val; -+ -+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); -+ if (!clk_hw) { -+ pr_err("%s: could not allocate clk_hw_omap\n", __func__); -+ return; -+ } -+ -+ clk_hw->hw.init = &init; -+ clk_hw->ops = ops; -+ clk_hw->enable_reg = of_iomap(node, 0); -+ -+ if (!of_property_read_u32(node, "ti,enable-bit", &val)) -+ clk_hw->enable_bit = val; -+ -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ -+ init.name = clk_name; -+ init.ops = &omap_interface_clk_ops; -+ init.flags = 0; -+ -+ parent_name = of_clk_get_parent_name(node, 0); -+ if (!parent_name) { -+ pr_err("%s: %s must have a parent\n", __func__, clk_name); -+ goto cleanup; -+ } -+ -+ init.num_parents = 1; -+ init.parent_names = &parent_name; -+ -+ clk = clk_register(NULL, &clk_hw->hw); -+ -+ if (!IS_ERR(clk)) { -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+ omap2_init_clk_hw_omap_clocks(clk); -+ return; -+ } -+ -+cleanup: -+ kfree(clk_hw); -+} -+ -+static void __init of_omap_interface_clk_setup(struct device_node *node) -+{ -+ _of_omap_interface_clk_setup(node, &clkhwops_iclk_wait); -+} -+CLK_OF_DECLARE(omap_interface_clk, "ti,omap3-interface-clock", -+ of_omap_interface_clk_setup); -+ -+static void __init of_omap_no_wait_interface_clk_setup(struct device_node *node) -+{ -+ _of_omap_interface_clk_setup(node, &clkhwops_iclk); -+} -+CLK_OF_DECLARE(omap_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock", -+ of_omap_no_wait_interface_clk_setup); -+ -+static void __init -+of_omap_hsotgusb_interface_clk_setup(struct device_node *node) -+{ -+ _of_omap_interface_clk_setup(node, -+ &clkhwops_omap3430es2_iclk_hsotgusb_wait); -+} -+CLK_OF_DECLARE(omap_hsotgusb_interface_clk, "ti,omap3-hsotgusb-interface-clock", -+ of_omap_hsotgusb_interface_clk_setup); -+ -+static void __init of_omap_dss_interface_clk_setup(struct device_node *node) -+{ -+ _of_omap_interface_clk_setup(node, -+ &clkhwops_omap3430es2_iclk_dss_usbhost_wait); -+} -+CLK_OF_DECLARE(omap_dss_interface_clk, "ti,omap3-dss-interface-clock", -+ of_omap_dss_interface_clk_setup); -+ -+static void __init of_omap_ssi_interface_clk_setup(struct device_node *node) -+{ -+ _of_omap_interface_clk_setup(node, &clkhwops_omap3430es2_iclk_ssi_wait); -+} -+CLK_OF_DECLARE(omap_ssi_interface_clk, "ti,omap3-ssi-interface-clock", -+ of_omap_ssi_interface_clk_setup); -+ -+static void __init of_omap_am35xx_interface_clk_setup(struct device_node *node) -+{ -+ _of_omap_interface_clk_setup(node, &clkhwops_am35xx_ipss_wait); -+} -+CLK_OF_DECLARE(omap_am35xx_interface_clk, "ti,am35xx-interface-clock", -+ of_omap_am35xx_interface_clk_setup); ---- /dev/null -+++ b/drivers/clk/ti/Makefile -@@ -0,0 +1,6 @@ -+ifneq ($(CONFIG_OF),) -+obj-y += clk.o dpll.o autoidle.o gate.o \ -+ clockdomain.o apll.o clk-44xx.o \ -+ clk-54xx.o clk-7xx.o clk-33xx.o \ -+ clk-43xx.o interface.o clk-3xxx.o -+endif ---- a/drivers/cpufreq/cpufreq-cpu0.c -+++ b/drivers/cpufreq/cpufreq-cpu0.c -@@ -21,6 +21,7 @@ - #include <linux/platform_device.h> - #include <linux/regulator/consumer.h> - #include <linux/slab.h> -+#include <linux/suspend.h> - - static unsigned int transition_latency; - static unsigned int voltage_tolerance; /* in percentage */ -@@ -29,6 +30,8 @@ static struct device *cpu_dev; - static struct clk *cpu_clk; - static struct regulator *cpu_reg; - static struct cpufreq_frequency_table *freq_table; -+static DEFINE_MUTEX(cpu_lock); -+static bool is_suspended; - - static int cpu0_verify_speed(struct cpufreq_policy *policy) - { -@@ -50,12 +53,19 @@ static int cpu0_set_target(struct cpufre - unsigned int index; - int ret; - -+ mutex_lock(&cpu_lock); -+ -+ if (is_suspended) { -+ ret = -EBUSY; -+ goto out; -+ } -+ - ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &index); - if (ret) { - pr_err("failed to match target freqency %d: %d\n", - target_freq, ret); -- return ret; -+ goto out; - } - - freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); -@@ -65,8 +75,10 @@ static int cpu0_set_target(struct cpufre - freqs.new = freq_Hz / 1000; - freqs.old = clk_get_rate(cpu_clk) / 1000; - -- if (freqs.old == freqs.new) -- return 0; -+ if (freqs.old == freqs.new) { -+ ret = 0; -+ goto out; -+ } - - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - -@@ -122,9 +134,32 @@ static int cpu0_set_target(struct cpufre - post_notify: - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - -+out: -+ mutex_unlock(&cpu_lock); - return ret; - } - -+static int cpu0_pm_notify(struct notifier_block *nb, unsigned long event, -+ void *dummy) -+{ -+ mutex_lock(&cpu_lock); -+ switch (event) { -+ case PM_SUSPEND_PREPARE: -+ is_suspended = true; -+ break; -+ case PM_POST_SUSPEND: -+ is_suspended = false; -+ break; -+ } -+ mutex_unlock(&cpu_lock); -+ -+ return NOTIFY_OK; -+} -+ -+static struct notifier_block cpu_pm_notifier = { -+ .notifier_call = cpu0_pm_notify, -+}; -+ - static int cpu0_cpufreq_init(struct cpufreq_policy *policy) - { - int ret; -@@ -147,11 +182,17 @@ static int cpu0_cpufreq_init(struct cpuf - - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); - -+ if (!IS_ERR(cpu_reg)) -+ register_pm_notifier(&cpu_pm_notifier); -+ - return 0; - } - - static int cpu0_cpufreq_exit(struct cpufreq_policy *policy) - { -+ if (!IS_ERR(cpu_reg)) -+ unregister_pm_notifier(&cpu_pm_notifier); -+ - cpufreq_frequency_table_put_attr(policy->cpu); - - return 0; ---- a/drivers/crypto/Kconfig -+++ b/drivers/crypto/Kconfig -@@ -263,6 +263,17 @@ config CRYPTO_DEV_OMAP_AES - OMAP processors have AES module accelerator. Select this if you - want to use the OMAP module for AES algorithms. - -+config CRYPTO_DEV_OMAP_DES -+ tristate "Support for OMAP DES3DES hw engine" -+ depends on ARCH_OMAP2PLUS -+ select CRYPTO_DES -+ select CRYPTO_BLKCIPHER2 -+ help -+ OMAP processors have DES/3DES module accelerator. Select this if you -+ want to use the OMAP module for DES and 3DES algorithms. Currently -+ the ECB and CBC modes of operation supported by the driver. Also -+ accesses made on unaligned boundaries are also supported. -+ - config CRYPTO_DEV_PICOXCELL - tristate "Support for picoXcell IPSEC and Layer2 crypto engines" - depends on ARCH_PICOXCELL && HAVE_CLK ---- a/drivers/crypto/Makefile -+++ b/drivers/crypto/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4x - obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ - obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o - obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o -+obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o - obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o - obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o - obj-$(CONFIG_CRYPTO_DEV_DCP) += dcp.o ---- a/drivers/crypto/omap-aes.c -+++ b/drivers/crypto/omap-aes.c -@@ -275,7 +275,7 @@ static int omap_aes_write_ctrl(struct om - if (dd->flags & FLAGS_CBC) - val |= AES_REG_CTRL_CBC; - if (dd->flags & FLAGS_CTR) { -- val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32; -+ val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_128; - mask = AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_MASK; - } - if (dd->flags & FLAGS_ENCRYPT) ---- /dev/null -+++ b/drivers/crypto/omap-des.c -@@ -0,0 +1,1239 @@ -+/* -+ * Cryptographic API. -+ * -+ * Support for OMAP DES and Triple DES HW acceleration. -+ * -+ * Copyright (c) 2012 Texas Instruments Incorporated -+ * Author: Joel Fernandes <joelf@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#define pr_fmt(fmt) "%s: " fmt, __func__ -+ -+#ifdef DEBUG -+#define prn(num) printk(#num "=%d\n", num) -+#define prx(num) printk(#num "=%x\n", num) -+#else -+#define prn(num) do { } while (0) -+#define prx(num) do { } while (0) -+#endif -+ -+#include <linux/err.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/kernel.h> -+#include <linux/platform_device.h> -+#include <linux/scatterlist.h> -+#include <linux/dma-mapping.h> -+#include <linux/dmaengine.h> -+#include <linux/omap-dma.h> -+#include <linux/pm_runtime.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/of_address.h> -+#include <linux/io.h> -+#include <linux/crypto.h> -+#include <linux/interrupt.h> -+#include <crypto/scatterwalk.h> -+#include <crypto/des.h> -+ -+#define DST_MAXBURST 2 -+ -+#define DES_BLOCK_WORDS (DES_BLOCK_SIZE >> 2) -+ -+#define _calc_walked(inout) (dd->inout##_walk.offset - dd->inout##_sg->offset) -+ -+#define DES_REG_KEY(dd, x) ((dd)->pdata->key_ofs - \ -+ ((x ^ 0x01) * 0x04)) -+ -+#define DES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04)) -+ -+#define DES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs) -+#define DES_REG_CTRL_CBC (1 << 4) -+#define DES_REG_CTRL_TDES (1 << 3) -+#define DES_REG_CTRL_DIRECTION (1 << 2) -+#define DES_REG_CTRL_INPUT_READY (1 << 1) -+#define DES_REG_CTRL_OUTPUT_READY (1 << 0) -+ -+#define DES_REG_DATA_N(dd, x) ((dd)->pdata->data_ofs + ((x) * 0x04)) -+ -+#define DES_REG_REV(dd) ((dd)->pdata->rev_ofs) -+ -+#define DES_REG_MASK(dd) ((dd)->pdata->mask_ofs) -+ -+#define DES_REG_LENGTH_N(x) (0x24 + ((x) * 0x04)) -+ -+#define DES_REG_IRQ_STATUS(dd) ((dd)->pdata->irq_status_ofs) -+#define DES_REG_IRQ_ENABLE(dd) ((dd)->pdata->irq_enable_ofs) -+#define DES_REG_IRQ_DATA_IN BIT(1) -+#define DES_REG_IRQ_DATA_OUT BIT(2) -+ -+#define FLAGS_MODE_MASK 0x000f -+#define FLAGS_ENCRYPT BIT(0) -+#define FLAGS_CBC BIT(1) -+#define FLAGS_INIT BIT(4) -+#define FLAGS_BUSY BIT(6) -+ -+struct omap_des_ctx { -+ struct omap_des_dev *dd; -+ -+ int keylen; -+ u32 key[(3 * DES_KEY_SIZE) / sizeof(u32)]; -+ unsigned long flags; -+}; -+ -+struct omap_des_reqctx { -+ unsigned long mode; -+}; -+ -+#define OMAP_DES_QUEUE_LENGTH 1 -+#define OMAP_DES_CACHE_SIZE 0 -+ -+struct omap_des_algs_info { -+ struct crypto_alg *algs_list; -+ unsigned int size; -+ unsigned int registered; -+}; -+ -+struct omap_des_pdata { -+ struct omap_des_algs_info *algs_info; -+ unsigned int algs_info_size; -+ -+ void (*trigger)(struct omap_des_dev *dd, int length); -+ -+ u32 key_ofs; -+ u32 iv_ofs; -+ u32 ctrl_ofs; -+ u32 data_ofs; -+ u32 rev_ofs; -+ u32 mask_ofs; -+ u32 irq_enable_ofs; -+ u32 irq_status_ofs; -+ -+ u32 dma_enable_in; -+ u32 dma_enable_out; -+ u32 dma_start; -+ -+ u32 major_mask; -+ u32 major_shift; -+ u32 minor_mask; -+ u32 minor_shift; -+}; -+ -+struct omap_des_dev { -+ struct list_head list; -+ unsigned long phys_base; -+ void __iomem *io_base; -+ struct omap_des_ctx *ctx; -+ struct device *dev; -+ unsigned long flags; -+ int err; -+ -+ /* spinlock used for queues */ -+ spinlock_t lock; -+ struct crypto_queue queue; -+ -+ struct tasklet_struct done_task; -+ struct tasklet_struct queue_task; -+ -+ struct ablkcipher_request *req; -+ /* -+ * total is used by PIO mode for book keeping so introduce -+ * variable total_save as need it to calc page_order -+ */ -+ size_t total; -+ size_t total_save; -+ -+ struct scatterlist *in_sg; -+ struct scatterlist *out_sg; -+ -+ /* Buffers for copying for unaligned cases */ -+ struct scatterlist in_sgl; -+ struct scatterlist out_sgl; -+ struct scatterlist *orig_out; -+ int sgs_copied; -+ -+ struct scatter_walk in_walk; -+ struct scatter_walk out_walk; -+ int dma_in; -+ struct dma_chan *dma_lch_in; -+ int dma_out; -+ struct dma_chan *dma_lch_out; -+ int in_sg_len; -+ int out_sg_len; -+ int pio_only; -+ const struct omap_des_pdata *pdata; -+}; -+ -+/* keep registered devices data here */ -+static LIST_HEAD(dev_list); -+static DEFINE_SPINLOCK(list_lock); -+ -+#ifdef DEBUG -+#define omap_des_read(dd, offset) \ -+ ({ \ -+ int _read_ret; \ -+ _read_ret = __raw_readl(dd->io_base + offset); \ -+ pr_err("omap_des_read(" #offset "=%#x)= %#x\n", \ -+ offset, _read_ret); \ -+ _read_ret; \ -+ }) -+#else -+static inline u32 omap_des_read(struct omap_des_dev *dd, u32 offset) -+{ -+ return __raw_readl(dd->io_base + offset); -+} -+#endif -+ -+#ifdef DEBUG -+#define omap_des_write(dd, offset, value) \ -+ do { \ -+ pr_err("omap_des_write(" #offset "=%#x) value=%#x\n", \ -+ offset, value); \ -+ __raw_writel(value, dd->io_base + offset); \ -+ } while (0) -+#else -+static inline void omap_des_write(struct omap_des_dev *dd, u32 offset, -+ u32 value) -+{ -+ __raw_writel(value, dd->io_base + offset); -+} -+#endif -+ -+static inline void omap_des_write_mask(struct omap_des_dev *dd, u32 offset, -+ u32 value, u32 mask) -+{ -+ u32 val; -+ -+ val = omap_des_read(dd, offset); -+ val &= ~mask; -+ val |= value; -+ omap_des_write(dd, offset, val); -+} -+ -+static void omap_des_write_n(struct omap_des_dev *dd, u32 offset, -+ u32 *value, int count) -+{ -+ for (; count--; value++, offset += 4) -+ omap_des_write(dd, offset, *value); -+} -+ -+static int omap_des_hw_init(struct omap_des_dev *dd) -+{ -+ /* -+ * clocks are enabled when request starts and disabled when finished. -+ * It may be long delays between requests. -+ * Device might go to off mode to save power. -+ */ -+ pm_runtime_get_sync(dd->dev); -+ -+ if (!(dd->flags & FLAGS_INIT)) { -+ dd->flags |= FLAGS_INIT; -+ dd->err = 0; -+ } -+ -+ return 0; -+} -+ -+static int omap_des_write_ctrl(struct omap_des_dev *dd) -+{ -+ unsigned int key32; -+ int i, err; -+ u32 val = 0, mask = 0; -+ -+ err = omap_des_hw_init(dd); -+ if (err) -+ return err; -+ -+ key32 = dd->ctx->keylen / sizeof(u32); -+ -+ /* it seems a key should always be set even if it has not changed */ -+ for (i = 0; i < key32; i++) { -+ omap_des_write(dd, DES_REG_KEY(dd, i), -+ __le32_to_cpu(dd->ctx->key[i])); -+ } -+ -+ if ((dd->flags & FLAGS_CBC) && dd->req->info) -+ omap_des_write_n(dd, DES_REG_IV(dd, 0), dd->req->info, 2); -+ -+ if (dd->flags & FLAGS_CBC) -+ val |= DES_REG_CTRL_CBC; -+ if (dd->flags & FLAGS_ENCRYPT) -+ val |= DES_REG_CTRL_DIRECTION; -+ if (key32 == 6) -+ val |= DES_REG_CTRL_TDES; -+ -+ mask |= DES_REG_CTRL_CBC | DES_REG_CTRL_DIRECTION | DES_REG_CTRL_TDES; -+ -+ omap_des_write_mask(dd, DES_REG_CTRL(dd), val, mask); -+ -+ return 0; -+} -+ -+static void omap_des_dma_trigger_omap4(struct omap_des_dev *dd, int length) -+{ -+ u32 mask, val; -+ -+ omap_des_write(dd, DES_REG_LENGTH_N(0), length); -+ -+ val = dd->pdata->dma_start; -+ -+ if (dd->dma_lch_out != NULL) -+ val |= dd->pdata->dma_enable_out; -+ if (dd->dma_lch_in != NULL) -+ val |= dd->pdata->dma_enable_in; -+ -+ mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in | -+ dd->pdata->dma_start; -+ -+ omap_des_write_mask(dd, DES_REG_MASK(dd), val, mask); -+} -+ -+static void omap_des_dma_stop(struct omap_des_dev *dd) -+{ -+ u32 mask; -+ -+ mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in | -+ dd->pdata->dma_start; -+ -+ omap_des_write_mask(dd, DES_REG_MASK(dd), 0, mask); -+} -+ -+static struct omap_des_dev *omap_des_find_dev(struct omap_des_ctx *ctx) -+{ -+ struct omap_des_dev *dd = NULL, *tmp; -+ -+ spin_lock_bh(&list_lock); -+ if (!ctx->dd) { -+ list_for_each_entry(tmp, &dev_list, list) { -+ /* FIXME: take fist available des core */ -+ dd = tmp; -+ break; -+ } -+ ctx->dd = dd; -+ } else { -+ /* already found before */ -+ dd = ctx->dd; -+ } -+ spin_unlock_bh(&list_lock); -+ -+ return dd; -+} -+ -+static void omap_des_dma_out_callback(void *data) -+{ -+ struct omap_des_dev *dd = data; -+ -+ /* dma_lch_out - completed */ -+ tasklet_schedule(&dd->done_task); -+} -+ -+static int omap_des_dma_init(struct omap_des_dev *dd) -+{ -+ int err = -ENOMEM; -+ dma_cap_mask_t mask; -+ -+ dd->dma_lch_out = NULL; -+ dd->dma_lch_in = NULL; -+ -+ dma_cap_zero(mask); -+ dma_cap_set(DMA_SLAVE, mask); -+ -+ dd->dma_lch_in = dma_request_slave_channel_compat(mask, -+ omap_dma_filter_fn, -+ &dd->dma_in, -+ dd->dev, "rx"); -+ if (!dd->dma_lch_in) { -+ dev_err(dd->dev, "Unable to request in DMA channel\n"); -+ goto err_dma_in; -+ } -+ -+ dd->dma_lch_out = dma_request_slave_channel_compat(mask, -+ omap_dma_filter_fn, -+ &dd->dma_out, -+ dd->dev, "tx"); -+ if (!dd->dma_lch_out) { -+ dev_err(dd->dev, "Unable to request out DMA channel\n"); -+ goto err_dma_out; -+ } -+ -+ return 0; -+ -+err_dma_out: -+ dma_release_channel(dd->dma_lch_in); -+err_dma_in: -+ if (err) -+ pr_err("error: %d\n", err); -+ return err; -+} -+ -+static void omap_des_dma_cleanup(struct omap_des_dev *dd) -+{ -+ dma_release_channel(dd->dma_lch_out); -+ dma_release_channel(dd->dma_lch_in); -+} -+ -+static void sg_copy_buf(void *buf, struct scatterlist *sg, -+ unsigned int start, unsigned int nbytes, int out) -+{ -+ struct scatter_walk walk; -+ -+ if (!nbytes) -+ return; -+ -+ scatterwalk_start(&walk, sg); -+ scatterwalk_advance(&walk, start); -+ scatterwalk_copychunks(buf, &walk, nbytes, out); -+ scatterwalk_done(&walk, out, 0); -+} -+ -+static int omap_des_crypt_dma(struct crypto_tfm *tfm, -+ struct scatterlist *in_sg, struct scatterlist *out_sg, -+ int in_sg_len, int out_sg_len) -+{ -+ struct omap_des_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct omap_des_dev *dd = ctx->dd; -+ struct dma_async_tx_descriptor *tx_in, *tx_out; -+ struct dma_slave_config cfg; -+ int ret; -+ -+ if (dd->pio_only) { -+ scatterwalk_start(&dd->in_walk, dd->in_sg); -+ scatterwalk_start(&dd->out_walk, dd->out_sg); -+ -+ /* Enable DATAIN interrupt and let it take -+ care of the rest */ -+ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x2); -+ return 0; -+ } -+ -+ dma_sync_sg_for_device(dd->dev, dd->in_sg, in_sg_len, DMA_TO_DEVICE); -+ -+ memset(&cfg, 0, sizeof(cfg)); -+ -+ cfg.src_addr = dd->phys_base + DES_REG_DATA_N(dd, 0); -+ cfg.dst_addr = dd->phys_base + DES_REG_DATA_N(dd, 0); -+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ cfg.src_maxburst = DST_MAXBURST; -+ cfg.dst_maxburst = DST_MAXBURST; -+ -+ /* IN */ -+ ret = dmaengine_slave_config(dd->dma_lch_in, &cfg); -+ if (ret) { -+ dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n", -+ ret); -+ return ret; -+ } -+ -+ tx_in = dmaengine_prep_slave_sg(dd->dma_lch_in, in_sg, in_sg_len, -+ DMA_MEM_TO_DEV, -+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -+ if (!tx_in) { -+ dev_err(dd->dev, "IN prep_slave_sg() failed\n"); -+ return -EINVAL; -+ } -+ -+ /* No callback necessary */ -+ tx_in->callback_param = dd; -+ -+ /* OUT */ -+ ret = dmaengine_slave_config(dd->dma_lch_out, &cfg); -+ if (ret) { -+ dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n", -+ ret); -+ return ret; -+ } -+ -+ tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, out_sg_len, -+ DMA_DEV_TO_MEM, -+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -+ if (!tx_out) { -+ dev_err(dd->dev, "OUT prep_slave_sg() failed\n"); -+ return -EINVAL; -+ } -+ -+ tx_out->callback = omap_des_dma_out_callback; -+ tx_out->callback_param = dd; -+ -+ dmaengine_submit(tx_in); -+ dmaengine_submit(tx_out); -+ -+ dma_async_issue_pending(dd->dma_lch_in); -+ dma_async_issue_pending(dd->dma_lch_out); -+ -+ /* start DMA */ -+ dd->pdata->trigger(dd, dd->total); -+ -+ return 0; -+} -+ -+static int omap_des_crypt_dma_start(struct omap_des_dev *dd) -+{ -+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm( -+ crypto_ablkcipher_reqtfm(dd->req)); -+ int err; -+ -+ pr_debug("total: %d\n", dd->total); -+ -+ if (!dd->pio_only) { -+ err = dma_map_sg(dd->dev, dd->in_sg, dd->in_sg_len, -+ DMA_TO_DEVICE); -+ if (!err) { -+ dev_err(dd->dev, "dma_map_sg() error\n"); -+ return -EINVAL; -+ } -+ -+ err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len, -+ DMA_FROM_DEVICE); -+ if (!err) { -+ dev_err(dd->dev, "dma_map_sg() error\n"); -+ return -EINVAL; -+ } -+ } -+ -+ err = omap_des_crypt_dma(tfm, dd->in_sg, dd->out_sg, dd->in_sg_len, -+ dd->out_sg_len); -+ if (err && !dd->pio_only) { -+ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); -+ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, -+ DMA_FROM_DEVICE); -+ } -+ -+ return err; -+} -+ -+static void omap_des_finish_req(struct omap_des_dev *dd, int err) -+{ -+ struct ablkcipher_request *req = dd->req; -+ -+ pr_debug("err: %d\n", err); -+ -+ pm_runtime_put(dd->dev); -+ dd->flags &= ~FLAGS_BUSY; -+ -+ req->base.complete(&req->base, err); -+} -+ -+static int omap_des_crypt_dma_stop(struct omap_des_dev *dd) -+{ -+ int err = 0; -+ -+ pr_debug("total: %d\n", dd->total); -+ -+ omap_des_dma_stop(dd); -+ -+ dmaengine_terminate_all(dd->dma_lch_in); -+ dmaengine_terminate_all(dd->dma_lch_out); -+ -+ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); -+ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, DMA_FROM_DEVICE); -+ -+ return err; -+} -+ -+int omap_des_copy_needed(struct scatterlist *sg) -+{ -+ while (sg) { -+ if (!IS_ALIGNED(sg->offset, 4)) -+ return -1; -+ if (!IS_ALIGNED(sg->length, DES_BLOCK_SIZE)) -+ return -1; -+ sg = sg_next(sg); -+ } -+ return 0; -+} -+ -+int omap_des_copy_sgs(struct omap_des_dev *dd) -+{ -+ void *buf_in, *buf_out; -+ int pages; -+ -+ pages = dd->total >> PAGE_SHIFT; -+ -+ if (dd->total & (PAGE_SIZE-1)) -+ pages++; -+ -+ BUG_ON(!pages); -+ -+ buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); -+ buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); -+ -+ if (!buf_in || !buf_out) { -+ pr_err("Couldn't allocated pages for unaligned cases.\n"); -+ return -1; -+ } -+ -+ dd->orig_out = dd->out_sg; -+ -+ sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0); -+ -+ sg_init_table(&dd->in_sgl, 1); -+ sg_set_buf(&dd->in_sgl, buf_in, dd->total); -+ dd->in_sg = &dd->in_sgl; -+ -+ sg_init_table(&dd->out_sgl, 1); -+ sg_set_buf(&dd->out_sgl, buf_out, dd->total); -+ dd->out_sg = &dd->out_sgl; -+ -+ return 0; -+} -+ -+static int omap_des_handle_queue(struct omap_des_dev *dd, -+ struct ablkcipher_request *req) -+{ -+ struct crypto_async_request *async_req, *backlog; -+ struct omap_des_ctx *ctx; -+ struct omap_des_reqctx *rctx; -+ unsigned long flags; -+ int err, ret = 0; -+ -+ spin_lock_irqsave(&dd->lock, flags); -+ if (req) -+ ret = ablkcipher_enqueue_request(&dd->queue, req); -+ if (dd->flags & FLAGS_BUSY) { -+ spin_unlock_irqrestore(&dd->lock, flags); -+ return ret; -+ } -+ backlog = crypto_get_backlog(&dd->queue); -+ async_req = crypto_dequeue_request(&dd->queue); -+ if (async_req) -+ dd->flags |= FLAGS_BUSY; -+ spin_unlock_irqrestore(&dd->lock, flags); -+ -+ if (!async_req) -+ return ret; -+ -+ if (backlog) -+ backlog->complete(backlog, -EINPROGRESS); -+ -+ req = ablkcipher_request_cast(async_req); -+ -+ /* assign new request to device */ -+ dd->req = req; -+ dd->total = req->nbytes; -+ dd->total_save = req->nbytes; -+ dd->in_sg = req->src; -+ dd->out_sg = req->dst; -+ -+ if (omap_des_copy_needed(dd->in_sg) || -+ omap_des_copy_needed(dd->out_sg)) { -+ if (omap_des_copy_sgs(dd)) -+ pr_err("Failed to copy SGs for unaligned cases\n"); -+ dd->sgs_copied = 1; -+ } else { -+ dd->sgs_copied = 0; -+ } -+ -+ dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, dd->total); -+ dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, dd->total); -+ BUG_ON(dd->in_sg_len < 0 || dd->out_sg_len < 0); -+ -+ rctx = ablkcipher_request_ctx(req); -+ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); -+ rctx->mode &= FLAGS_MODE_MASK; -+ dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; -+ -+ dd->ctx = ctx; -+ ctx->dd = dd; -+ -+ err = omap_des_write_ctrl(dd); -+ if (!err) -+ err = omap_des_crypt_dma_start(dd); -+ if (err) { -+ /* des_task will not finish it, so do it here */ -+ omap_des_finish_req(dd, err); -+ tasklet_schedule(&dd->queue_task); -+ } -+ -+ return ret; /* return ret, which is enqueue return value */ -+} -+ -+static void omap_des_done_task(unsigned long data) -+{ -+ struct omap_des_dev *dd = (struct omap_des_dev *)data; -+ void *buf_in, *buf_out; -+ int pages; -+ -+ pr_debug("enter done_task\n"); -+ -+ if (!dd->pio_only) { -+ dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len, -+ DMA_FROM_DEVICE); -+ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); -+ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, -+ DMA_FROM_DEVICE); -+ omap_des_crypt_dma_stop(dd); -+ } -+ -+ if (dd->sgs_copied) { -+ buf_in = sg_virt(&dd->in_sgl); -+ buf_out = sg_virt(&dd->out_sgl); -+ -+ sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1); -+ -+ pages = get_order(dd->total_save); -+ free_pages((unsigned long)buf_in, pages); -+ free_pages((unsigned long)buf_out, pages); -+ } -+ -+ omap_des_finish_req(dd, 0); -+ omap_des_handle_queue(dd, NULL); -+ -+ pr_debug("exit\n"); -+} -+ -+static void omap_des_queue_task(unsigned long data) -+{ -+ struct omap_des_dev *dd = (struct omap_des_dev *)data; -+ -+ omap_des_handle_queue(dd, NULL); -+} -+ -+static int omap_des_crypt(struct ablkcipher_request *req, unsigned long mode) -+{ -+ struct omap_des_ctx *ctx = crypto_ablkcipher_ctx( -+ crypto_ablkcipher_reqtfm(req)); -+ struct omap_des_reqctx *rctx = ablkcipher_request_ctx(req); -+ struct omap_des_dev *dd; -+ -+ pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, -+ !!(mode & FLAGS_ENCRYPT), -+ !!(mode & FLAGS_CBC)); -+ -+ if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { -+ pr_err("request size is not exact amount of DES blocks\n"); -+ return -EINVAL; -+ } -+ -+ dd = omap_des_find_dev(ctx); -+ if (!dd) -+ return -ENODEV; -+ -+ rctx->mode = mode; -+ -+ return omap_des_handle_queue(dd, req); -+} -+ -+/* ********************** ALG API ************************************ */ -+ -+static int omap_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen) -+{ -+ struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(tfm); -+ -+ if (keylen != DES_KEY_SIZE && keylen != (3*DES_KEY_SIZE)) -+ return -EINVAL; -+ -+ pr_debug("enter, keylen: %d\n", keylen); -+ -+ memcpy(ctx->key, key, keylen); -+ ctx->keylen = keylen; -+ -+ return 0; -+} -+ -+static int omap_des_ecb_encrypt(struct ablkcipher_request *req) -+{ -+ return omap_des_crypt(req, FLAGS_ENCRYPT); -+} -+ -+static int omap_des_ecb_decrypt(struct ablkcipher_request *req) -+{ -+ return omap_des_crypt(req, 0); -+} -+ -+static int omap_des_cbc_encrypt(struct ablkcipher_request *req) -+{ -+ return omap_des_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); -+} -+ -+static int omap_des_cbc_decrypt(struct ablkcipher_request *req) -+{ -+ return omap_des_crypt(req, FLAGS_CBC); -+} -+ -+static int omap_des_cra_init(struct crypto_tfm *tfm) -+{ -+ pr_debug("enter\n"); -+ -+ tfm->crt_ablkcipher.reqsize = sizeof(struct omap_des_reqctx); -+ -+ return 0; -+} -+ -+static void omap_des_cra_exit(struct crypto_tfm *tfm) -+{ -+ pr_debug("enter\n"); -+} -+ -+/* ********************** ALGS ************************************ */ -+ -+static struct crypto_alg algs_ecb_cbc[] = { -+{ -+ .cra_name = "ecb(des)", -+ .cra_driver_name = "ecb-des-omap", -+ .cra_priority = 100, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ASYNC, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct omap_des_ctx), -+ .cra_alignmask = 0, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_module = THIS_MODULE, -+ .cra_init = omap_des_cra_init, -+ .cra_exit = omap_des_cra_exit, -+ .cra_u.ablkcipher = { -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ .setkey = omap_des_setkey, -+ .encrypt = omap_des_ecb_encrypt, -+ .decrypt = omap_des_ecb_decrypt, -+ } -+}, -+{ -+ .cra_name = "cbc(des)", -+ .cra_driver_name = "cbc-des-omap", -+ .cra_priority = 100, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ASYNC, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct omap_des_ctx), -+ .cra_alignmask = 0, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_module = THIS_MODULE, -+ .cra_init = omap_des_cra_init, -+ .cra_exit = omap_des_cra_exit, -+ .cra_u.ablkcipher = { -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ .ivsize = DES_BLOCK_SIZE, -+ .setkey = omap_des_setkey, -+ .encrypt = omap_des_cbc_encrypt, -+ .decrypt = omap_des_cbc_decrypt, -+ } -+}, -+{ -+ .cra_name = "ecb(des3_ede)", -+ .cra_driver_name = "ecb-des3-omap", -+ .cra_priority = 100, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ASYNC, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct omap_des_ctx), -+ .cra_alignmask = 0, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_module = THIS_MODULE, -+ .cra_init = omap_des_cra_init, -+ .cra_exit = omap_des_cra_exit, -+ .cra_u.ablkcipher = { -+ .min_keysize = 3*DES_KEY_SIZE, -+ .max_keysize = 3*DES_KEY_SIZE, -+ .setkey = omap_des_setkey, -+ .encrypt = omap_des_ecb_encrypt, -+ .decrypt = omap_des_ecb_decrypt, -+ } -+}, -+{ -+ .cra_name = "cbc(des3_ede)", -+ .cra_driver_name = "cbc-des3-omap", -+ .cra_priority = 100, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ASYNC, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct omap_des_ctx), -+ .cra_alignmask = 0, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_module = THIS_MODULE, -+ .cra_init = omap_des_cra_init, -+ .cra_exit = omap_des_cra_exit, -+ .cra_u.ablkcipher = { -+ .min_keysize = 3*DES_KEY_SIZE, -+ .max_keysize = 3*DES_KEY_SIZE, -+ .ivsize = DES_BLOCK_SIZE, -+ .setkey = omap_des_setkey, -+ .encrypt = omap_des_cbc_encrypt, -+ .decrypt = omap_des_cbc_decrypt, -+ } -+} -+}; -+ -+static struct omap_des_algs_info omap_des_algs_info_ecb_cbc[] = { -+ { -+ .algs_list = algs_ecb_cbc, -+ .size = ARRAY_SIZE(algs_ecb_cbc), -+ }, -+}; -+ -+#ifdef CONFIG_OF -+static const struct omap_des_pdata omap_des_pdata_omap4 = { -+ .algs_info = omap_des_algs_info_ecb_cbc, -+ .algs_info_size = ARRAY_SIZE(omap_des_algs_info_ecb_cbc), -+ .trigger = omap_des_dma_trigger_omap4, -+ .key_ofs = 0x14, -+ .iv_ofs = 0x18, -+ .ctrl_ofs = 0x20, -+ .data_ofs = 0x28, -+ .rev_ofs = 0x30, -+ .mask_ofs = 0x34, -+ .irq_status_ofs = 0x3c, -+ .irq_enable_ofs = 0x40, -+ .dma_enable_in = BIT(5), -+ .dma_enable_out = BIT(6), -+ .major_mask = 0x0700, -+ .major_shift = 8, -+ .minor_mask = 0x003f, -+ .minor_shift = 0, -+}; -+ -+static irqreturn_t omap_des_irq(int irq, void *dev_id) -+{ -+ struct omap_des_dev *dd = dev_id; -+ u32 status, i; -+ u32 *src, *dst; -+ -+ status = omap_des_read(dd, DES_REG_IRQ_STATUS(dd)); -+ if (status & DES_REG_IRQ_DATA_IN) { -+ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x0); -+ -+ BUG_ON(!dd->in_sg); -+ -+ BUG_ON(_calc_walked(in) > dd->in_sg->length); -+ -+ src = sg_virt(dd->in_sg) + _calc_walked(in); -+ -+ for (i = 0; i < DES_BLOCK_WORDS; i++) { -+ omap_des_write(dd, DES_REG_DATA_N(dd, i), *src); -+ -+ scatterwalk_advance(&dd->in_walk, 4); -+ if (dd->in_sg->length == _calc_walked(in)) { -+ dd->in_sg = scatterwalk_sg_next(dd->in_sg); -+ if (dd->in_sg) { -+ scatterwalk_start(&dd->in_walk, -+ dd->in_sg); -+ src = sg_virt(dd->in_sg) + -+ _calc_walked(in); -+ } -+ } else { -+ src++; -+ } -+ } -+ -+ /* Clear IRQ status */ -+ status &= ~DES_REG_IRQ_DATA_IN; -+ omap_des_write(dd, DES_REG_IRQ_STATUS(dd), status); -+ -+ /* Enable DATA_OUT interrupt */ -+ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x4); -+ -+ } else if (status & DES_REG_IRQ_DATA_OUT) { -+ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x0); -+ -+ BUG_ON(!dd->out_sg); -+ -+ BUG_ON(_calc_walked(out) > dd->out_sg->length); -+ -+ dst = sg_virt(dd->out_sg) + _calc_walked(out); -+ -+ for (i = 0; i < DES_BLOCK_WORDS; i++) { -+ *dst = omap_des_read(dd, DES_REG_DATA_N(dd, i)); -+ scatterwalk_advance(&dd->out_walk, 4); -+ if (dd->out_sg->length == _calc_walked(out)) { -+ dd->out_sg = scatterwalk_sg_next(dd->out_sg); -+ if (dd->out_sg) { -+ scatterwalk_start(&dd->out_walk, -+ dd->out_sg); -+ dst = sg_virt(dd->out_sg) + -+ _calc_walked(out); -+ } -+ } else { -+ dst++; -+ } -+ } -+ -+ dd->total -= DES_BLOCK_SIZE; -+ -+ BUG_ON(dd->total < 0); -+ -+ /* Clear IRQ status */ -+ status &= ~DES_REG_IRQ_DATA_OUT; -+ omap_des_write(dd, DES_REG_IRQ_STATUS(dd), status); -+ -+ if (!dd->total) -+ /* All bytes read! */ -+ tasklet_schedule(&dd->done_task); -+ else -+ /* Enable DATA_IN interrupt for next block */ -+ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x2); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static const struct of_device_id omap_des_of_match[] = { -+ { -+ .compatible = "ti,omap4-des", -+ .data = &omap_des_pdata_omap4, -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, omap_des_of_match); -+ -+static int omap_des_get_res_of(struct omap_des_dev *dd, -+ struct device *dev, struct resource *res) -+{ -+ struct device_node *node = dev->of_node; -+ const struct of_device_id *match; -+ int err = 0; -+ -+ match = of_match_device(of_match_ptr(omap_des_of_match), dev); -+ if (!match) { -+ dev_err(dev, "no compatible OF match\n"); -+ err = -EINVAL; -+ goto err; -+ } -+ -+ err = of_address_to_resource(node, 0, res); -+ if (err < 0) { -+ dev_err(dev, "can't translate OF node address\n"); -+ err = -EINVAL; -+ goto err; -+ } -+ -+ dd->dma_out = -1; /* Dummy value that's unused */ -+ dd->dma_in = -1; /* Dummy value that's unused */ -+ -+ dd->pdata = match->data; -+ -+err: -+ return err; -+} -+#else -+static const struct of_device_id omap_des_of_match[] = { -+ {}, -+}; -+ -+static int omap_des_get_res_of(struct omap_des_dev *dd, -+ struct device *dev, struct resource *res) -+{ -+ return -EINVAL; -+} -+#endif -+ -+static int omap_des_get_res_pdev(struct omap_des_dev *dd, -+ struct platform_device *pdev, struct resource *res) -+{ -+ struct device *dev = &pdev->dev; -+ struct resource *r; -+ int err = 0; -+ -+ /* Get the base address */ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!r) { -+ dev_err(dev, "no MEM resource info\n"); -+ err = -ENODEV; -+ goto err; -+ } -+ memcpy(res, r, sizeof(*res)); -+ -+ /* Get the DMA out channel */ -+ r = platform_get_resource(pdev, IORESOURCE_DMA, 0); -+ if (!r) { -+ dev_err(dev, "no DMA out resource info\n"); -+ err = -ENODEV; -+ goto err; -+ } -+ dd->dma_out = r->start; -+ -+ /* Get the DMA in channel */ -+ r = platform_get_resource(pdev, IORESOURCE_DMA, 1); -+ if (!r) { -+ dev_err(dev, "no DMA in resource info\n"); -+ err = -ENODEV; -+ goto err; -+ } -+ dd->dma_in = r->start; -+ -+ /* non-DT devices get pdata from pdev */ -+ dd->pdata = pdev->dev.platform_data; -+ -+err: -+ return err; -+} -+ -+static int omap_des_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct omap_des_dev *dd; -+ struct crypto_alg *algp; -+ struct resource res; -+ int err = -ENOMEM, i, j, irq = -1; -+ u32 reg; -+ -+ dd = devm_kzalloc(dev, sizeof(struct omap_des_dev), GFP_KERNEL); -+ if (dd == NULL) { -+ dev_err(dev, "unable to alloc data struct.\n"); -+ goto err_data; -+ } -+ dd->dev = dev; -+ platform_set_drvdata(pdev, dd); -+ -+ spin_lock_init(&dd->lock); -+ crypto_init_queue(&dd->queue, OMAP_DES_QUEUE_LENGTH); -+ -+ err = (dev->of_node) ? omap_des_get_res_of(dd, dev, &res) : -+ omap_des_get_res_pdev(dd, pdev, &res); -+ if (err) -+ goto err_res; -+ -+ dd->io_base = devm_request_and_ioremap(dev, &res); -+ if (!dd->io_base) { -+ dev_err(dev, "can't ioremap\n"); -+ err = -ENOMEM; -+ goto err_res; -+ } -+ dd->phys_base = res.start; -+ -+ pm_runtime_enable(dev); -+ pm_runtime_get_sync(dev); -+ -+ omap_des_dma_stop(dd); -+ -+ reg = omap_des_read(dd, DES_REG_REV(dd)); -+ -+ pm_runtime_put_sync(dev); -+ -+ dev_info(dev, "OMAP DES hw accel rev: %u.%u\n", -+ (reg & dd->pdata->major_mask) >> dd->pdata->major_shift, -+ (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift); -+ -+ tasklet_init(&dd->done_task, omap_des_done_task, (unsigned long)dd); -+ tasklet_init(&dd->queue_task, omap_des_queue_task, (unsigned long)dd); -+ -+ err = omap_des_dma_init(dd); -+ if (err && DES_REG_IRQ_STATUS(dd) && DES_REG_IRQ_ENABLE(dd)) { -+ dd->pio_only = 1; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(dev, "can't get IRQ resource\n"); -+ goto err_irq; -+ } -+ -+ err = devm_request_irq(dev, irq, omap_des_irq, 0, -+ dev_name(dev), dd); -+ if (err) { -+ dev_err(dev, "Unable to grab omap-des IRQ\n"); -+ goto err_irq; -+ } -+ } -+ -+ -+ INIT_LIST_HEAD(&dd->list); -+ spin_lock(&list_lock); -+ list_add_tail(&dd->list, &dev_list); -+ spin_unlock(&list_lock); -+ -+ for (i = 0; i < dd->pdata->algs_info_size; i++) { -+ for (j = 0; j < dd->pdata->algs_info[i].size; j++) { -+ algp = &dd->pdata->algs_info[i].algs_list[j]; -+ -+ pr_debug("reg alg: %s\n", algp->cra_name); -+ INIT_LIST_HEAD(&algp->cra_list); -+ -+ err = crypto_register_alg(algp); -+ if (err) -+ goto err_algs; -+ -+ dd->pdata->algs_info[i].registered++; -+ } -+ } -+ -+ return 0; -+err_algs: -+ for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) -+ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) -+ crypto_unregister_alg( -+ &dd->pdata->algs_info[i].algs_list[j]); -+ if (!dd->pio_only) -+ omap_des_dma_cleanup(dd); -+err_irq: -+ tasklet_kill(&dd->done_task); -+ tasklet_kill(&dd->queue_task); -+ pm_runtime_disable(dev); -+err_res: -+ dd = NULL; -+err_data: -+ dev_err(dev, "initialization failed.\n"); -+ return err; -+} -+ -+static int omap_des_remove(struct platform_device *pdev) -+{ -+ struct omap_des_dev *dd = platform_get_drvdata(pdev); -+ int i, j; -+ -+ if (!dd) -+ return -ENODEV; -+ -+ spin_lock(&list_lock); -+ list_del(&dd->list); -+ spin_unlock(&list_lock); -+ -+ for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) -+ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) -+ crypto_unregister_alg( -+ &dd->pdata->algs_info[i].algs_list[j]); -+ -+ tasklet_kill(&dd->done_task); -+ tasklet_kill(&dd->queue_task); -+ omap_des_dma_cleanup(dd); -+ pm_runtime_disable(dd->dev); -+ dd = NULL; -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static int omap_des_suspend(struct device *dev) -+{ -+ pm_runtime_put_sync(dev); -+ return 0; -+} -+ -+static int omap_des_resume(struct device *dev) -+{ -+ pm_runtime_get_sync(dev); -+ return 0; -+} -+#endif -+ -+static const struct dev_pm_ops omap_des_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(omap_des_suspend, omap_des_resume) -+}; -+ -+static struct platform_driver omap_des_driver = { -+ .probe = omap_des_probe, -+ .remove = omap_des_remove, -+ .driver = { -+ .name = "omap-des", -+ .owner = THIS_MODULE, -+ .pm = &omap_des_pm_ops, -+ .of_match_table = omap_des_of_match, -+ }, -+}; -+ -+module_platform_driver(omap_des_driver); -+ -+MODULE_DESCRIPTION("OMAP DES hw acceleration support."); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Joel Fernandes <joelf@ti.com>"); ---- a/drivers/dma/amba-pl08x.c -+++ b/drivers/dma/amba-pl08x.c -@@ -2133,8 +2133,7 @@ static int pl08x_probe(struct amba_devic - writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR); - writel(0x000000FF, pl08x->base + PL080_TC_CLEAR); - -- ret = request_irq(adev->irq[0], pl08x_irq, IRQF_DISABLED, -- DRIVER_NAME, pl08x); -+ ret = request_irq(adev->irq[0], pl08x_irq, 0, DRIVER_NAME, pl08x); - if (ret) { - dev_err(&adev->dev, "%s failed to request interrupt %d\n", - __func__, adev->irq[0]); ---- a/drivers/dma/coh901318.c -+++ b/drivers/dma/coh901318.c -@@ -2694,7 +2694,7 @@ static int __init coh901318_probe(struct - if (irq < 0) - return irq; - -- err = devm_request_irq(&pdev->dev, irq, dma_irq_handler, IRQF_DISABLED, -+ err = devm_request_irq(&pdev->dev, irq, dma_irq_handler, 0, - "coh901318", base); - if (err) - return err; ---- a/drivers/dma/cppi41.c -+++ b/drivers/dma/cppi41.c -@@ -141,6 +141,9 @@ struct cppi41_dd { - const struct chan_queues *queues_rx; - const struct chan_queues *queues_tx; - struct chan_queues td_queue; -+ -+ /* context for suspend/resume */ -+ unsigned int dma_tdfdq; - }; - - #define FIST_COMPLETION_QUEUE 93 -@@ -263,6 +266,15 @@ static u32 pd_trans_len(u32 val) - return val & ((1 << (DESC_LENGTH_BITS_NUM + 1)) - 1); - } - -+static u32 cppi41_pop_desc(struct cppi41_dd *cdd, unsigned queue_num) -+{ -+ u32 desc; -+ -+ desc = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(queue_num)); -+ desc &= ~0x1f; -+ return desc; -+} -+ - static irqreturn_t cppi41_irq(int irq, void *data) - { - struct cppi41_dd *cdd = data; -@@ -300,8 +312,7 @@ static irqreturn_t cppi41_irq(int irq, v - q_num = __fls(val); - val &= ~(1 << q_num); - q_num += 32 * i; -- desc = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(q_num)); -- desc &= ~0x1f; -+ desc = cppi41_pop_desc(cdd, q_num); - c = desc_to_chan(cdd, desc); - if (WARN_ON(!c)) { - pr_err("%s() q %d desc %08x\n", __func__, -@@ -517,15 +528,6 @@ static void cppi41_compute_td_desc(struc - d->pd0 = DESC_TYPE_TEARD << DESC_TYPE; - } - --static u32 cppi41_pop_desc(struct cppi41_dd *cdd, unsigned queue_num) --{ -- u32 desc; -- -- desc = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(queue_num)); -- desc &= ~0x1f; -- return desc; --} -- - static int cppi41_tear_down_chan(struct cppi41_channel *c) - { - struct cppi41_dd *cdd = c->cdd; -@@ -561,36 +563,26 @@ static int cppi41_tear_down_chan(struct - c->td_retry = 100; - } - -- if (!c->td_seen) { -- unsigned td_comp_queue; -+ if (!c->td_seen || !c->td_desc_seen) { - -- if (c->is_tx) -- td_comp_queue = cdd->td_queue.complete; -- else -- td_comp_queue = c->q_comp_num; -+ desc_phys = cppi41_pop_desc(cdd, cdd->td_queue.complete); -+ if (!desc_phys) -+ desc_phys = cppi41_pop_desc(cdd, c->q_comp_num); - -- desc_phys = cppi41_pop_desc(cdd, td_comp_queue); -- if (desc_phys) { -- __iormb(); -+ if (desc_phys == c->desc_phys) { -+ c->td_desc_seen = 1; -+ -+ } else if (desc_phys == td_desc_phys) { -+ u32 pd0; - -- if (desc_phys == td_desc_phys) { -- u32 pd0; -- pd0 = td->pd0; -- WARN_ON((pd0 >> DESC_TYPE) != DESC_TYPE_TEARD); -- WARN_ON(!c->is_tx && !(pd0 & TD_DESC_IS_RX)); -- WARN_ON((pd0 & 0x1f) != c->port_num); -- } else { -- WARN_ON_ONCE(1); -- } -- c->td_seen = 1; -- } -- } -- if (!c->td_desc_seen) { -- desc_phys = cppi41_pop_desc(cdd, c->q_comp_num); -- if (desc_phys) { - __iormb(); -- WARN_ON(c->desc_phys != desc_phys); -- c->td_desc_seen = 1; -+ pd0 = td->pd0; -+ WARN_ON((pd0 >> DESC_TYPE) != DESC_TYPE_TEARD); -+ WARN_ON(!c->is_tx && !(pd0 & TD_DESC_IS_RX)); -+ WARN_ON((pd0 & 0x1f) != c->port_num); -+ c->td_seen = 1; -+ } else if (desc_phys) { -+ WARN_ON_ONCE(1); - } - } - c->td_retry--; -@@ -609,7 +601,7 @@ static int cppi41_tear_down_chan(struct - - WARN_ON(!c->td_retry); - if (!c->td_desc_seen) { -- desc_phys = cppi_readl(cdd->qmgr_mem + QMGR_QUEUE_D(c->q_num)); -+ desc_phys = cppi41_pop_desc(cdd, c->q_num); - WARN_ON(!desc_phys); - } - -@@ -674,14 +666,14 @@ static void cleanup_chans(struct cppi41_ - } - } - --static int cppi41_add_chans(struct platform_device *pdev, struct cppi41_dd *cdd) -+static int cppi41_add_chans(struct device *dev, struct cppi41_dd *cdd) - { - struct cppi41_channel *cchan; - int i; - int ret; - u32 n_chans; - -- ret = of_property_read_u32(pdev->dev.of_node, "#dma-channels", -+ ret = of_property_read_u32(dev->of_node, "#dma-channels", - &n_chans); - if (ret) - return ret; -@@ -719,7 +711,7 @@ err: - return -ENOMEM; - } - --static void purge_descs(struct platform_device *pdev, struct cppi41_dd *cdd) -+static void purge_descs(struct device *dev, struct cppi41_dd *cdd) - { - unsigned int mem_decs; - int i; -@@ -731,7 +723,7 @@ static void purge_descs(struct platform_ - cppi_writel(0, cdd->qmgr_mem + QMGR_MEMBASE(i)); - cppi_writel(0, cdd->qmgr_mem + QMGR_MEMCTRL(i)); - -- dma_free_coherent(&pdev->dev, mem_decs, cdd->cd, -+ dma_free_coherent(dev, mem_decs, cdd->cd, - cdd->descs_phys); - } - } -@@ -741,19 +733,19 @@ static void disable_sched(struct cppi41_ - cppi_writel(0, cdd->sched_mem + DMA_SCHED_CTRL); - } - --static void deinit_cpii41(struct platform_device *pdev, struct cppi41_dd *cdd) -+static void deinit_cppi41(struct device *dev, struct cppi41_dd *cdd) - { - disable_sched(cdd); - -- purge_descs(pdev, cdd); -+ purge_descs(dev, cdd); - - cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); - cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM0_BASE); -- dma_free_coherent(&pdev->dev, QMGR_SCRATCH_SIZE, cdd->qmgr_scratch, -+ dma_free_coherent(dev, QMGR_SCRATCH_SIZE, cdd->qmgr_scratch, - cdd->scratch_phys); - } - --static int init_descs(struct platform_device *pdev, struct cppi41_dd *cdd) -+static int init_descs(struct device *dev, struct cppi41_dd *cdd) - { - unsigned int desc_size; - unsigned int mem_decs; -@@ -777,7 +769,7 @@ static int init_descs(struct platform_de - reg |= ilog2(ALLOC_DECS_NUM) - 5; - - BUILD_BUG_ON(DESCS_AREAS != 1); -- cdd->cd = dma_alloc_coherent(&pdev->dev, mem_decs, -+ cdd->cd = dma_alloc_coherent(dev, mem_decs, - &cdd->descs_phys, GFP_KERNEL); - if (!cdd->cd) - return -ENOMEM; -@@ -813,12 +805,12 @@ static void init_sched(struct cppi41_dd - cppi_writel(reg, cdd->sched_mem + DMA_SCHED_CTRL); - } - --static int init_cppi41(struct platform_device *pdev, struct cppi41_dd *cdd) -+static int init_cppi41(struct device *dev, struct cppi41_dd *cdd) - { - int ret; - - BUILD_BUG_ON(QMGR_SCRATCH_SIZE > ((1 << 14) - 1)); -- cdd->qmgr_scratch = dma_alloc_coherent(&pdev->dev, QMGR_SCRATCH_SIZE, -+ cdd->qmgr_scratch = dma_alloc_coherent(dev, QMGR_SCRATCH_SIZE, - &cdd->scratch_phys, GFP_KERNEL); - if (!cdd->qmgr_scratch) - return -ENOMEM; -@@ -827,7 +819,7 @@ static int init_cppi41(struct platform_d - cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); - cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); - -- ret = init_descs(pdev, cdd); -+ ret = init_descs(dev, cdd); - if (ret) - goto err_td; - -@@ -835,7 +827,7 @@ static int init_cppi41(struct platform_d - init_sched(cdd); - return 0; - err_td: -- deinit_cpii41(pdev, cdd); -+ deinit_cppi41(dev, cdd); - return ret; - } - -@@ -914,11 +906,11 @@ static const struct of_device_id cppi41_ - }; - MODULE_DEVICE_TABLE(of, cppi41_dma_ids); - --static const struct cppi_glue_infos *get_glue_info(struct platform_device *pdev) -+static const struct cppi_glue_infos *get_glue_info(struct device *dev) - { - const struct of_device_id *of_id; - -- of_id = of_match_node(cppi41_dma_ids, pdev->dev.of_node); -+ of_id = of_match_node(cppi41_dma_ids, dev->of_node); - if (!of_id) - return NULL; - return of_id->data; -@@ -927,11 +919,12 @@ static const struct cppi_glue_infos *get - static int cppi41_dma_probe(struct platform_device *pdev) - { - struct cppi41_dd *cdd; -+ struct device *dev = &pdev->dev; - const struct cppi_glue_infos *glue_info; - int irq; - int ret; - -- glue_info = get_glue_info(pdev); -+ glue_info = get_glue_info(dev); - if (!glue_info) - return -EINVAL; - -@@ -946,14 +939,14 @@ static int cppi41_dma_probe(struct platf - cdd->ddev.device_issue_pending = cppi41_dma_issue_pending; - cdd->ddev.device_prep_slave_sg = cppi41_dma_prep_slave_sg; - cdd->ddev.device_control = cppi41_dma_control; -- cdd->ddev.dev = &pdev->dev; -+ cdd->ddev.dev = dev; - INIT_LIST_HEAD(&cdd->ddev.channels); - cpp41_dma_info.dma_cap = cdd->ddev.cap_mask; - -- cdd->usbss_mem = of_iomap(pdev->dev.of_node, 0); -- cdd->ctrl_mem = of_iomap(pdev->dev.of_node, 1); -- cdd->sched_mem = of_iomap(pdev->dev.of_node, 2); -- cdd->qmgr_mem = of_iomap(pdev->dev.of_node, 3); -+ cdd->usbss_mem = of_iomap(dev->of_node, 0); -+ cdd->ctrl_mem = of_iomap(dev->of_node, 1); -+ cdd->sched_mem = of_iomap(dev->of_node, 2); -+ cdd->qmgr_mem = of_iomap(dev->of_node, 3); - - if (!cdd->usbss_mem || !cdd->ctrl_mem || !cdd->sched_mem || - !cdd->qmgr_mem) { -@@ -961,31 +954,31 @@ static int cppi41_dma_probe(struct platf - goto err_remap; - } - -- pm_runtime_enable(&pdev->dev); -- ret = pm_runtime_get_sync(&pdev->dev); -- if (ret) -+ pm_runtime_enable(dev); -+ ret = pm_runtime_get_sync(dev); -+ if (ret < 0) - goto err_get_sync; - - cdd->queues_rx = glue_info->queues_rx; - cdd->queues_tx = glue_info->queues_tx; - cdd->td_queue = glue_info->td_queue; - -- ret = init_cppi41(pdev, cdd); -+ ret = init_cppi41(dev, cdd); - if (ret) - goto err_init_cppi; - -- ret = cppi41_add_chans(pdev, cdd); -+ ret = cppi41_add_chans(dev, cdd); - if (ret) - goto err_chans; - -- irq = irq_of_parse_and_map(pdev->dev.of_node, 0); -+ irq = irq_of_parse_and_map(dev->of_node, 0); - if (!irq) - goto err_irq; - - cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); - - ret = request_irq(irq, glue_info->isr, IRQF_SHARED, -- dev_name(&pdev->dev), cdd); -+ dev_name(dev), cdd); - if (ret) - goto err_irq; - cdd->irq = irq; -@@ -994,7 +987,7 @@ static int cppi41_dma_probe(struct platf - if (ret) - goto err_dma_reg; - -- ret = of_dma_controller_register(pdev->dev.of_node, -+ ret = of_dma_controller_register(dev->of_node, - cppi41_dma_xlate, &cpp41_dma_info); - if (ret) - goto err_of; -@@ -1009,11 +1002,11 @@ err_irq: - cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); - cleanup_chans(cdd); - err_chans: -- deinit_cpii41(pdev, cdd); -+ deinit_cppi41(dev, cdd); - err_init_cppi: -- pm_runtime_put(&pdev->dev); -+ pm_runtime_put(dev); - err_get_sync: -- pm_runtime_disable(&pdev->dev); -+ pm_runtime_disable(dev); - iounmap(cdd->usbss_mem); - iounmap(cdd->ctrl_mem); - iounmap(cdd->sched_mem); -@@ -1033,7 +1026,7 @@ static int cppi41_dma_remove(struct plat - cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); - free_irq(cdd->irq, cdd); - cleanup_chans(cdd); -- deinit_cpii41(pdev, cdd); -+ deinit_cppi41(&pdev->dev, cdd); - iounmap(cdd->usbss_mem); - iounmap(cdd->ctrl_mem); - iounmap(cdd->sched_mem); -@@ -1044,12 +1037,53 @@ static int cppi41_dma_remove(struct plat - return 0; - } - -+#ifdef CONFIG_PM_SLEEP -+static int cppi41_suspend(struct device *dev) -+{ -+ struct cppi41_dd *cdd = dev_get_drvdata(dev); -+ -+ cdd->dma_tdfdq = cppi_readl(cdd->ctrl_mem + DMA_TDFDQ); -+ cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); -+ disable_sched(cdd); -+ -+ return 0; -+} -+ -+static int cppi41_resume(struct device *dev) -+{ -+ struct cppi41_dd *cdd = dev_get_drvdata(dev); -+ struct cppi41_channel *c; -+ int i; -+ -+ for (i = 0; i < DESCS_AREAS; i++) -+ cppi_writel(cdd->descs_phys, cdd->qmgr_mem + QMGR_MEMBASE(i)); -+ -+ list_for_each_entry(c, &cdd->ddev.channels, chan.device_node) -+ if (!c->is_tx) -+ cppi_writel(c->q_num, c->gcr_reg + RXHPCRA0); -+ -+ init_sched(cdd); -+ -+ cppi_writel(cdd->dma_tdfdq, cdd->ctrl_mem + DMA_TDFDQ); -+ cppi_writel(cdd->scratch_phys, cdd->qmgr_mem + QMGR_LRAM0_BASE); -+ cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); -+ cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); -+ -+ cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); -+ -+ return 0; -+} -+#endif -+ -+static SIMPLE_DEV_PM_OPS(cppi41_pm_ops, cppi41_suspend, cppi41_resume); -+ - static struct platform_driver cpp41_dma_driver = { - .probe = cppi41_dma_probe, - .remove = cppi41_dma_remove, - .driver = { - .name = "cppi41-dma-engine", - .owner = THIS_MODULE, -+ .pm = &cppi41_pm_ops, - .of_match_table = of_match_ptr(cppi41_dma_ids), - }, - }; ---- a/drivers/dma/edma.c -+++ b/drivers/dma/edma.c -@@ -46,8 +46,14 @@ - #define EDMA_CHANS 64 - #endif /* CONFIG_ARCH_DAVINCI_DA8XX */ - --/* Max of 16 segments per channel to conserve PaRAM slots */ --#define MAX_NR_SG 16 -+/* -+ * Max of 20 segments per channel to conserve PaRAM slots -+ * Also note that MAX_NR_SG should be atleast the no.of periods -+ * that are required for ASoC, otherwise DMA prep calls will -+ * fail. Today davinci-pcm is the only user of this driver and -+ * requires atleast 17 slots, so we setup the default to 20. -+ */ -+#define MAX_NR_SG 20 - #define EDMA_MAX_SLOTS MAX_NR_SG - #define EDMA_DESCRIPTORS 16 - -@@ -250,6 +256,117 @@ static int edma_control(struct dma_chan - return ret; - } - -+/* -+ * A PaRAM set configuration abstraction used by other modes -+ * @chan: Channel who's PaRAM set we're configuring -+ * @pset: PaRAM set to initialize and setup. -+ * @src_addr: Source address of the DMA -+ * @dst_addr: Destination address of the DMA -+ * @burst: In units of dev_width, how much to send -+ * @dev_width: How much is the dev_width -+ * @dma_length: Total length of the DMA transfer -+ * @direction: Direction of the transfer -+ */ -+static int edma_config_pset(struct dma_chan *chan, struct edmacc_param *pset, -+ dma_addr_t src_addr, dma_addr_t dst_addr, u32 burst, -+ enum dma_slave_buswidth dev_width, unsigned int dma_length, -+ enum dma_transfer_direction direction) -+{ -+ struct edma_chan *echan = to_edma_chan(chan); -+ struct device *dev = chan->device->dev; -+ int acnt, bcnt, ccnt, cidx; -+ int src_bidx, dst_bidx, src_cidx, dst_cidx; -+ int absync; -+ -+ acnt = dev_width; -+ /* -+ * If the maxburst is equal to the fifo width, use -+ * A-synced transfers. This allows for large contiguous -+ * buffer transfers using only one PaRAM set. -+ */ -+ if (burst == 1) { -+ /* -+ * For the A-sync case, bcnt and ccnt are the remainder -+ * and quotient respectively of the division of: -+ * (dma_length / acnt) by (SZ_64K -1). This is so -+ * that in case bcnt over flows, we have ccnt to use. -+ * Note: In A-sync tranfer only, bcntrld is used, but it -+ * only applies for sg_dma_len(sg) >= SZ_64K. -+ * In this case, the best way adopted is- bccnt for the -+ * first frame will be the remainder below. Then for -+ * every successive frame, bcnt will be SZ_64K-1. This -+ * is assured as bcntrld = 0xffff in end of function. -+ */ -+ absync = false; -+ ccnt = dma_length / acnt / (SZ_64K - 1); -+ bcnt = dma_length / acnt - ccnt * (SZ_64K - 1); -+ /* -+ * If bcnt is non-zero, we have a remainder and hence an -+ * extra frame to transfer, so increment ccnt. -+ */ -+ if (bcnt) -+ ccnt++; -+ else -+ bcnt = SZ_64K - 1; -+ cidx = acnt; -+ } else { -+ /* -+ * If maxburst is greater than the fifo address_width, -+ * use AB-synced transfers where A count is the fifo -+ * address_width and B count is the maxburst. In this -+ * case, we are limited to transfers of C count frames -+ * of (address_width * maxburst) where C count is limited -+ * to SZ_64K-1. This places an upper bound on the length -+ * of an SG segment that can be handled. -+ */ -+ absync = true; -+ bcnt = burst; -+ ccnt = dma_length / (acnt * bcnt); -+ if (ccnt > (SZ_64K - 1)) { -+ dev_err(dev, "Exceeded max SG segment size\n"); -+ return -EINVAL; -+ } -+ cidx = acnt * bcnt; -+ } -+ -+ if (direction == DMA_MEM_TO_DEV) { -+ src_bidx = acnt; -+ src_cidx = cidx; -+ dst_bidx = 0; -+ dst_cidx = 0; -+ } else if (direction == DMA_DEV_TO_MEM) { -+ src_bidx = 0; -+ src_cidx = 0; -+ dst_bidx = acnt; -+ dst_cidx = cidx; -+ } else { -+ dev_err(dev, "%s: direction not implemented yet\n", __func__); -+ return -EINVAL; -+ } -+ -+ pset->opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num)); -+ /* Configure A or AB synchronized transfers */ -+ if (absync) -+ pset->opt |= SYNCDIM; -+ -+ pset->src = src_addr; -+ pset->dst = dst_addr; -+ -+ pset->src_dst_bidx = (dst_bidx << 16) | src_bidx; -+ pset->src_dst_cidx = (dst_cidx << 16) | src_cidx; -+ -+ pset->a_b_cnt = bcnt << 16 | acnt; -+ pset->ccnt = ccnt; -+ /* -+ * Only time when (bcntrld) auto reload is required is for -+ * A-sync case, and in this case, a requirement of reload value -+ * of SZ_64K-1 only is assured. 'link' is initially set to NULL -+ * and then later will be populated by edma_execute. -+ */ -+ pset->link_bcntrld = 0xffffffff; -+ return absync; -+} -+ - static struct dma_async_tx_descriptor *edma_prep_slave_sg( - struct dma_chan *chan, struct scatterlist *sgl, - unsigned int sg_len, enum dma_transfer_direction direction, -@@ -258,23 +375,21 @@ static struct dma_async_tx_descriptor *e - struct edma_chan *echan = to_edma_chan(chan); - struct device *dev = chan->device->dev; - struct edma_desc *edesc; -- dma_addr_t dev_addr; -+ dma_addr_t src_addr = 0, dst_addr = 0; - enum dma_slave_buswidth dev_width; - u32 burst; - struct scatterlist *sg; -- int acnt, bcnt, ccnt, src, dst, cidx; -- int src_bidx, dst_bidx, src_cidx, dst_cidx; -- int i, nslots; -+ int i, nslots, ret; - - if (unlikely(!echan || !sgl || !sg_len)) - return NULL; - - if (direction == DMA_DEV_TO_MEM) { -- dev_addr = echan->cfg.src_addr; -+ src_addr = echan->cfg.src_addr; - dev_width = echan->cfg.src_addr_width; - burst = echan->cfg.src_maxburst; - } else if (direction == DMA_MEM_TO_DEV) { -- dev_addr = echan->cfg.dst_addr; -+ dst_addr = echan->cfg.dst_addr; - dev_width = echan->cfg.dst_addr_width; - burst = echan->cfg.dst_maxburst; - } else { -@@ -315,64 +430,19 @@ static struct dma_async_tx_descriptor *e - - /* Configure PaRAM sets for each SG */ - for_each_sg(sgl, sg, sg_len, i) { -+ /* Get address for each SG */ -+ if (direction == DMA_DEV_TO_MEM) -+ dst_addr = sg_dma_address(sg); -+ else -+ src_addr = sg_dma_address(sg); -+ -+ ret = edma_config_pset(chan, &edesc->pset[i], src_addr, -+ dst_addr, burst, dev_width, -+ sg_dma_len(sg), direction); -+ if (ret < 0) -+ return NULL; - -- acnt = dev_width; -- -- /* -- * If the maxburst is equal to the fifo width, use -- * A-synced transfers. This allows for large contiguous -- * buffer transfers using only one PaRAM set. -- */ -- if (burst == 1) { -- edesc->absync = false; -- ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1); -- bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1); -- if (bcnt) -- ccnt++; -- else -- bcnt = SZ_64K - 1; -- cidx = acnt; -- /* -- * If maxburst is greater than the fifo address_width, -- * use AB-synced transfers where A count is the fifo -- * address_width and B count is the maxburst. In this -- * case, we are limited to transfers of C count frames -- * of (address_width * maxburst) where C count is limited -- * to SZ_64K-1. This places an upper bound on the length -- * of an SG segment that can be handled. -- */ -- } else { -- edesc->absync = true; -- bcnt = burst; -- ccnt = sg_dma_len(sg) / (acnt * bcnt); -- if (ccnt > (SZ_64K - 1)) { -- dev_err(dev, "Exceeded max SG segment size\n"); -- kfree(edesc); -- return NULL; -- } -- cidx = acnt * bcnt; -- } -- -- if (direction == DMA_MEM_TO_DEV) { -- src = sg_dma_address(sg); -- dst = dev_addr; -- src_bidx = acnt; -- src_cidx = cidx; -- dst_bidx = 0; -- dst_cidx = 0; -- } else { -- src = dev_addr; -- dst = sg_dma_address(sg); -- src_bidx = 0; -- src_cidx = 0; -- dst_bidx = acnt; -- dst_cidx = cidx; -- } -- -- edesc->pset[i].opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num)); -- /* Configure A or AB synchronized transfers */ -- if (edesc->absync) -- edesc->pset[i].opt |= SYNCDIM; -+ edesc->absync = ret; - - /* If this is the last in a current SG set of transactions, - enable interrupts so that next set is processed */ -@@ -382,17 +452,6 @@ static struct dma_async_tx_descriptor *e - /* If this is the last set, enable completion interrupt flag */ - if (i == sg_len - 1) - edesc->pset[i].opt |= TCINTEN; -- -- edesc->pset[i].src = src; -- edesc->pset[i].dst = dst; -- -- edesc->pset[i].src_dst_bidx = (dst_bidx << 16) | src_bidx; -- edesc->pset[i].src_dst_cidx = (dst_cidx << 16) | src_cidx; -- -- edesc->pset[i].a_b_cnt = bcnt << 16 | acnt; -- edesc->pset[i].ccnt = ccnt; -- edesc->pset[i].link_bcntrld = 0xffffffff; -- - } - - return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags); ---- a/drivers/dma/k3dma.c -+++ b/drivers/dma/k3dma.c -@@ -693,7 +693,7 @@ static int k3_dma_probe(struct platform_ - - irq = platform_get_irq(op, 0); - ret = devm_request_irq(&op->dev, irq, -- k3_dma_int_handler, IRQF_DISABLED, DRIVER_NAME, d); -+ k3_dma_int_handler, 0, DRIVER_NAME, d); - if (ret) - return ret; - ---- a/drivers/dma/mmp_pdma.c -+++ b/drivers/dma/mmp_pdma.c -@@ -798,8 +798,7 @@ static void dma_do_tasklet(unsigned long - * move the descriptors to a temporary list so we can drop - * the lock during the entire cleanup operation - */ -- list_del(&desc->node); -- list_add(&desc->node, &chain_cleanup); -+ list_move(&desc->node, &chain_cleanup); - - /* - * Look for the first list entry which has the ENDIRQEN flag -@@ -863,7 +862,7 @@ static int mmp_pdma_chan_init(struct mmp - - if (irq) { - ret = devm_request_irq(pdev->dev, irq, -- mmp_pdma_chan_handler, IRQF_DISABLED, "pdma", phy); -+ mmp_pdma_chan_handler, 0, "pdma", phy); - if (ret) { - dev_err(pdev->dev, "channel request irq fail!\n"); - return ret; -@@ -970,7 +969,7 @@ static int mmp_pdma_probe(struct platfor - /* all chan share one irq, demux inside */ - irq = platform_get_irq(op, 0); - ret = devm_request_irq(pdev->dev, irq, -- mmp_pdma_int_handler, IRQF_DISABLED, "pdma", pdev); -+ mmp_pdma_int_handler, 0, "pdma", pdev); - if (ret) - return ret; - } ---- a/drivers/dma/mmp_tdma.c -+++ b/drivers/dma/mmp_tdma.c -@@ -62,6 +62,11 @@ - #define TDCR_BURSTSZ_16B (0x3 << 6) - #define TDCR_BURSTSZ_32B (0x6 << 6) - #define TDCR_BURSTSZ_64B (0x7 << 6) -+#define TDCR_BURSTSZ_SQU_1B (0x5 << 6) -+#define TDCR_BURSTSZ_SQU_2B (0x6 << 6) -+#define TDCR_BURSTSZ_SQU_4B (0x0 << 6) -+#define TDCR_BURSTSZ_SQU_8B (0x1 << 6) -+#define TDCR_BURSTSZ_SQU_16B (0x3 << 6) - #define TDCR_BURSTSZ_SQU_32B (0x7 << 6) - #define TDCR_BURSTSZ_128B (0x5 << 6) - #define TDCR_DSTDIR_MSK (0x3 << 4) /* Dst Direction */ -@@ -228,8 +233,31 @@ static int mmp_tdma_config_chan(struct m - return -EINVAL; - } - } else if (tdmac->type == PXA910_SQU) { -- tdcr |= TDCR_BURSTSZ_SQU_32B; - tdcr |= TDCR_SSPMOD; -+ -+ switch (tdmac->burst_sz) { -+ case 1: -+ tdcr |= TDCR_BURSTSZ_SQU_1B; -+ break; -+ case 2: -+ tdcr |= TDCR_BURSTSZ_SQU_2B; -+ break; -+ case 4: -+ tdcr |= TDCR_BURSTSZ_SQU_4B; -+ break; -+ case 8: -+ tdcr |= TDCR_BURSTSZ_SQU_8B; -+ break; -+ case 16: -+ tdcr |= TDCR_BURSTSZ_SQU_16B; -+ break; -+ case 32: -+ tdcr |= TDCR_BURSTSZ_SQU_32B; -+ break; -+ default: -+ dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n"); -+ return -EINVAL; -+ } - } - - writel(tdcr, tdmac->reg_base + TDCR); -@@ -324,7 +352,7 @@ static int mmp_tdma_alloc_chan_resources - - if (tdmac->irq) { - ret = devm_request_irq(tdmac->dev, tdmac->irq, -- mmp_tdma_chan_handler, IRQF_DISABLED, "tdma", tdmac); -+ mmp_tdma_chan_handler, 0, "tdma", tdmac); - if (ret) - return ret; - } -@@ -559,7 +587,7 @@ static int mmp_tdma_probe(struct platfor - if (irq_num != chan_num) { - irq = platform_get_irq(pdev, 0); - ret = devm_request_irq(&pdev->dev, irq, -- mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev); -+ mmp_tdma_int_handler, 0, "tdma", tdev); - if (ret) - return ret; - } ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -2922,16 +2922,23 @@ pl330_probe(struct amba_device *adev, co - - amba_set_drvdata(adev, pdmac); - -- irq = adev->irq[0]; -- ret = request_irq(irq, pl330_irq_handler, 0, -- dev_name(&adev->dev), pi); -- if (ret) -- return ret; -+ for (i = 0; i <= AMBA_NR_IRQS; i++) { -+ irq = adev->irq[i]; -+ if (irq) { -+ ret = devm_request_irq(&adev->dev, irq, -+ pl330_irq_handler, 0, -+ dev_name(&adev->dev), pi); -+ if (ret) -+ return ret; -+ } else { -+ break; -+ } -+ } - - pi->pcfg.periph_id = adev->periphid; - ret = pl330_add(pi); - if (ret) -- goto probe_err1; -+ return ret; - - INIT_LIST_HEAD(&pdmac->desc_pool); - spin_lock_init(&pdmac->pool_lock); -@@ -3044,8 +3051,6 @@ probe_err3: - } - probe_err2: - pl330_del(pi); --probe_err1: -- free_irq(irq, pi); - - return ret; - } -@@ -3055,7 +3060,6 @@ static int pl330_remove(struct amba_devi - struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev); - struct dma_pl330_chan *pch, *_p; - struct pl330_info *pi; -- int irq; - - if (!pdmac) - return 0; -@@ -3082,9 +3086,6 @@ static int pl330_remove(struct amba_devi - - pl330_del(pi); - -- irq = adev->irq[0]; -- free_irq(irq, pi); -- - return 0; - } - ---- a/drivers/dma/ste_dma40.c -+++ b/drivers/dma/ste_dma40.c -@@ -14,6 +14,7 @@ - #include <linux/platform_device.h> - #include <linux/clk.h> - #include <linux/delay.h> -+#include <linux/log2.h> - #include <linux/pm.h> - #include <linux/pm_runtime.h> - #include <linux/err.h> -@@ -2796,8 +2797,8 @@ static int d40_set_runtime_config(struct - src_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || - dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED || - dst_addr_width > DMA_SLAVE_BUSWIDTH_8_BYTES || -- ((src_addr_width > 1) && (src_addr_width & 1)) || -- ((dst_addr_width > 1) && (dst_addr_width & 1))) -+ !is_power_of_2(src_addr_width) || -+ !is_power_of_2(dst_addr_width)) - return -EINVAL; - - cfg->src_info.data_width = src_addr_width; ---- /dev/null -+++ b/drivers/extcon/extcon-gpio-usbvid.c -@@ -0,0 +1,281 @@ -+/* -+ * Generic USB VBUS-ID pin detection driver -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: George Cherian <george.cherian@ti.com> -+ * -+ * Based on extcon-palmas.c -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ */ -+ -+#include <linux/err.h> -+#include <linux/extcon.h> -+#include <linux/gpio.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_gpio.h> -+#include <linux/of_platform.h> -+#include <linux/platform_device.h> -+ -+struct gpio_usbvid { -+ struct device *dev; -+ -+ struct extcon_dev edev; -+ -+ /* GPIO pin */ -+ int id_gpio; -+ int vbus_gpio; -+ -+ int id_irq; -+ int vbus_irq; -+ int type; -+}; -+ -+static const char *dra7xx_extcon_cable[] = { -+ [0] = "USB", -+ [1] = "USB-HOST", -+ NULL, -+}; -+ -+static const int mutually_exclusive[] = {0x3, 0x0}; -+ -+/* Two types of support are provided. -+ * Systems which has -+ * 1) VBUS and ID pin connected via GPIO -+ * 2) only ID pin connected via GPIO -+ * For Case 1 both the gpios should be provided via DT -+ * Always the first GPIO in dt is considered ID pin GPIO -+ */ -+ -+enum { -+ UNKNOWN = 0, -+ ID_DETECT, -+ VBUS_ID_DETECT, -+}; -+ -+#define ID_GND 0 -+#define ID_FLOAT 1 -+#define VBUS_OFF 0 -+#define VBUS_ON 1 -+ -+static irqreturn_t id_irq_handler(int irq, void *data) -+{ -+ struct gpio_usbvid *gpio_usbvid = (struct gpio_usbvid *)data; -+ int id_current; -+ -+ id_current = gpio_get_value_cansleep(gpio_usbvid->id_gpio); -+ if (id_current == ID_GND) { -+ if (gpio_usbvid->type == ID_DETECT) -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB", false); -+ extcon_set_cable_state(&gpio_usbvid->edev, "USB-HOST", true); -+ } else { -+ extcon_set_cable_state(&gpio_usbvid->edev, "USB-HOST", false); -+ if (gpio_usbvid->type == ID_DETECT) -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB", true); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t vbus_irq_handler(int irq, void *data) -+{ -+ struct gpio_usbvid *gpio_usbvid = (struct gpio_usbvid *)data; -+ int vbus_current; -+ -+ vbus_current = gpio_get_value_cansleep(gpio_usbvid->vbus_gpio); -+ if (vbus_current == VBUS_OFF) -+ extcon_set_cable_state(&gpio_usbvid->edev, "USB", false); -+ else -+ extcon_set_cable_state(&gpio_usbvid->edev, "USB", true); -+ -+ return IRQ_HANDLED; -+} -+ -+static void gpio_usbvid_set_initial_state(struct gpio_usbvid *gpio_usbvid) -+{ -+ int id_current, vbus_current; -+ -+ switch (gpio_usbvid->type) { -+ case ID_DETECT: -+ id_current = gpio_get_value_cansleep(gpio_usbvid->id_gpio); -+ if (!!id_current == ID_FLOAT) { -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB-HOST", false); -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB", true); -+ } else { -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB", false); -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB-HOST", true); -+ } -+ break; -+ -+ case VBUS_ID_DETECT: -+ id_current = gpio_get_value_cansleep(gpio_usbvid->id_gpio); -+ if (!!id_current == ID_FLOAT) -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB-HOST", false); -+ else -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB-HOST", true); -+ -+ vbus_current = gpio_get_value_cansleep(gpio_usbvid->vbus_gpio); -+ if (!!vbus_current == VBUS_ON) -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB", true); -+ else -+ extcon_set_cable_state(&gpio_usbvid->edev, -+ "USB", false); -+ break; -+ -+ default: -+ dev_err(gpio_usbvid->dev, "Unknown VBUS-ID type\n"); -+ } -+} -+ -+static int gpio_usbvid_request_irq(struct gpio_usbvid *gpio_usbvid) -+{ -+ int ret; -+ -+ ret = devm_request_threaded_irq(gpio_usbvid->dev, gpio_usbvid->id_irq, -+ NULL, id_irq_handler, -+ IRQF_ONESHOT | IRQF_TRIGGER_FALLING, -+ dev_name(gpio_usbvid->dev), -+ (void *) gpio_usbvid); -+ if (ret) { -+ dev_err(gpio_usbvid->dev, "failed to request id irq #%d\n", -+ gpio_usbvid->id_irq); -+ return ret; -+ } -+ if (gpio_usbvid->type == VBUS_ID_DETECT) { -+ ret = devm_request_threaded_irq(gpio_usbvid->dev, -+ gpio_usbvid->vbus_irq, NULL, -+ vbus_irq_handler, -+ IRQF_ONESHOT | IRQF_TRIGGER_FALLING, -+ dev_name(gpio_usbvid->dev), -+ (void *) gpio_usbvid); -+ if (ret) -+ dev_err(gpio_usbvid->dev, "failed to request vbus irq #%d\n", -+ gpio_usbvid->vbus_irq); -+ } -+ -+ return ret; -+} -+ -+static int gpio_usbvid_probe(struct platform_device *pdev) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ struct gpio_usbvid *gpio_usbvid; -+ int ret, gpio; -+ -+ gpio_usbvid = devm_kzalloc(&pdev->dev, sizeof(*gpio_usbvid), -+ GFP_KERNEL); -+ if (!gpio_usbvid) -+ return -ENOMEM; -+ -+ gpio_usbvid->dev = &pdev->dev; -+ -+ platform_set_drvdata(pdev, gpio_usbvid); -+ -+ //gpio_usbvid->edev.name = dev_name(&pdev->dev); -+ gpio_usbvid->edev.supported_cable = dra7xx_extcon_cable; -+ gpio_usbvid->edev.mutually_exclusive = mutually_exclusive; -+ -+ if (of_device_is_compatible(node, "ti,gpio-usb-id")) -+ gpio_usbvid->type = ID_DETECT; -+ -+ gpio = of_get_gpio(node, 0); -+ if (gpio_is_valid(gpio)) { -+ gpio_usbvid->id_gpio = gpio; -+ ret = devm_gpio_request(&pdev->dev, gpio_usbvid->id_gpio, -+ "id_gpio"); -+ if (ret) -+ return ret; -+ -+ gpio_usbvid->id_irq = gpio_to_irq(gpio_usbvid->id_gpio); -+ } else { -+ dev_err(&pdev->dev, "failed to get id gpio\n"); -+ return -EPROBE_DEFER; -+ } -+ -+ if (of_device_is_compatible(node, "ti,gpio-usb-vid")) { -+ gpio_usbvid->type = VBUS_ID_DETECT; -+ gpio = of_get_gpio(node, 1); -+ if (gpio_is_valid(gpio)) { -+ gpio_usbvid->vbus_gpio = gpio; -+ ret = devm_gpio_request(&pdev->dev, -+ gpio_usbvid->vbus_gpio, -+ "vbus_gpio"); -+ if (ret) -+ return ret; -+ -+ gpio_usbvid->vbus_irq = -+ gpio_to_irq(gpio_usbvid->vbus_gpio); -+ } else { -+ dev_err(&pdev->dev, "failed to get vbus gpio\n"); -+ return -ENODEV; -+ } -+ } -+ -+ ret = gpio_usbvid_request_irq(gpio_usbvid); -+ if (ret) -+ return ret; -+ -+ ret = extcon_dev_register(&gpio_usbvid->edev, gpio_usbvid->dev); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to register extcon device\n"); -+ return ret; -+ } -+ -+ gpio_usbvid_set_initial_state(gpio_usbvid); -+ -+ return 0; -+ -+} -+ -+static int gpio_usbvid_remove(struct platform_device *pdev) -+{ -+ struct gpio_usbvid *gpio_usbvid = platform_get_drvdata(pdev); -+ -+ extcon_dev_unregister(&gpio_usbvid->edev); -+ return 0; -+} -+ -+static struct of_device_id of_gpio_usbvid_match_tbl[] = { -+ { .compatible = "ti,gpio-usb-vid", }, -+ { .compatible = "ti,gpio-usb-id", }, -+ { /* end */ } -+}; -+ -+static struct platform_driver gpio_usbvid_driver = { -+ .probe = gpio_usbvid_probe, -+ .remove = gpio_usbvid_remove, -+ .driver = { -+ .name = "gpio-usbvid", -+ .of_match_table = of_gpio_usbvid_match_tbl, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(gpio_usbvid_driver); -+ -+MODULE_ALIAS("platform:gpio-usbvid"); -+MODULE_AUTHOR("George Cherian <george.cherian@ti.com>"); -+MODULE_DESCRIPTION("GPIO based USB Connector driver"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, of_gpio_usbvid_match_tbl); ---- a/drivers/extcon/extcon-palmas.c -+++ b/drivers/extcon/extcon-palmas.c -@@ -78,20 +78,24 @@ static irqreturn_t palmas_vbus_irq_handl - - static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) - { -- unsigned int set; -+ unsigned int set, id_src; - struct palmas_usb *palmas_usb = _palmas_usb; - - palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE, - PALMAS_USB_ID_INT_LATCH_SET, &set); -+ palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE, -+ PALMAS_USB_ID_INT_SRC, &id_src); - -- if (set & PALMAS_USB_ID_INT_SRC_ID_GND) { -+ if ((set & PALMAS_USB_ID_INT_SRC_ID_GND) && -+ (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { - palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, - PALMAS_USB_ID_INT_LATCH_CLR, - PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); - palmas_usb->linkstat = PALMAS_USB_STATE_ID; - extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); - dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); -- } else if (set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) { -+ } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) && -+ (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) { - palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, - PALMAS_USB_ID_INT_LATCH_CLR, - PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); -@@ -103,6 +107,11 @@ static irqreturn_t palmas_id_irq_handler - palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; - extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); - dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); -+ } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) && -+ (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { -+ palmas_usb->linkstat = PALMAS_USB_STATE_ID; -+ extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); -+ dev_info(palmas_usb->dev, " USB-HOST cable is attached\n"); - } - - return IRQ_HANDLED; -@@ -268,6 +277,7 @@ static const struct dev_pm_ops palmas_pm - - static struct of_device_id of_palmas_match_tbl[] = { - { .compatible = "ti,palmas-usb", }, -+ { .compatible = "ti,palmas-usb-vid", }, - { .compatible = "ti,twl6035-usb", }, - { /* end */ } - }; ---- a/drivers/extcon/Kconfig -+++ b/drivers/extcon/Kconfig -@@ -64,4 +64,9 @@ config EXTCON_PALMAS - Say Y here to enable support for USB peripheral and USB host - detection by palmas usb. - -+config EXTCON_GPIO_USBVID -+ tristate "Generic USB VBUS/ID detection using GPIO EXTCON support" -+ help -+ Say Y here to enable support for USB VBUS/ID deetction by GPIO. -+ - endif # MULTISTATE_SWITCH ---- a/drivers/extcon/Makefile -+++ b/drivers/extcon/Makefile -@@ -11,3 +11,4 @@ obj-$(CONFIG_EXTCON_MAX77693) += extcon- - obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o - obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o - obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o -+obj-$(CONFIG_EXTCON_GPIO_USBVID) += extcon-gpio-usbvid.o ---- a/drivers/gpio/gpio-pcf857x.c -+++ b/drivers/gpio/gpio-pcf857x.c -@@ -26,9 +26,10 @@ - #include <linux/irqdomain.h> - #include <linux/kernel.h> - #include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_device.h> - #include <linux/slab.h> - #include <linux/spinlock.h> --#include <linux/workqueue.h> - - - static const struct i2c_device_id pcf857x_id[] = { -@@ -50,6 +51,27 @@ static const struct i2c_device_id pcf857 - }; - MODULE_DEVICE_TABLE(i2c, pcf857x_id); - -+#ifdef CONFIG_OF -+static const struct of_device_id pcf857x_of_table[] = { -+ { .compatible = "nxp,pcf8574" }, -+ { .compatible = "nxp,pcf8574a" }, -+ { .compatible = "nxp,pca8574" }, -+ { .compatible = "nxp,pca9670" }, -+ { .compatible = "nxp,pca9672" }, -+ { .compatible = "nxp,pca9674" }, -+ { .compatible = "nxp,pcf8575" }, -+ { .compatible = "nxp,pca8575" }, -+ { .compatible = "nxp,pca9671" }, -+ { .compatible = "nxp,pca9673" }, -+ { .compatible = "nxp,pca9675" }, -+ { .compatible = "maxim,max7328" }, -+ { .compatible = "maxim,max7329" }, -+ { .compatible = "ti,tca9554" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, pcf857x_of_table); -+#endif -+ - /* - * The pcf857x, pca857x, and pca967x chips only expose one read and one - * write register. Writing a "one" bit (to match the reset state) lets -@@ -66,12 +88,11 @@ struct pcf857x { - struct gpio_chip chip; - struct i2c_client *client; - struct mutex lock; /* protect 'out' */ -- struct work_struct work; /* irq demux work */ - struct irq_domain *irq_domain; /* for irq demux */ - spinlock_t slock; /* protect irq demux */ - unsigned out; /* software latch */ - unsigned status; /* current status */ -- int irq; /* real irq number */ -+ unsigned irq_mapped; /* mapped gpio irqs */ - - int (*write)(struct i2c_client *client, unsigned data); - int (*read)(struct i2c_client *client); -@@ -164,48 +185,54 @@ static void pcf857x_set(struct gpio_chip - static int pcf857x_to_irq(struct gpio_chip *chip, unsigned offset) - { - struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); -+ int ret; - -- return irq_create_mapping(gpio->irq_domain, offset); -+ ret = irq_create_mapping(gpio->irq_domain, offset); -+ if (ret > 0) -+ gpio->irq_mapped |= (1 << offset); -+ -+ return ret; - } - --static void pcf857x_irq_demux_work(struct work_struct *work) -+static irqreturn_t pcf857x_irq(int irq, void *data) - { -- struct pcf857x *gpio = container_of(work, -- struct pcf857x, -- work); -+ struct pcf857x *gpio = data; - unsigned long change, i, status, flags; - - status = gpio->read(gpio->client); - - spin_lock_irqsave(&gpio->slock, flags); - -- change = gpio->status ^ status; -+ /* -+ * call the interrupt handler iff gpio is used as -+ * interrupt source, just to avoid bad irqs -+ */ -+ -+ change = ((gpio->status ^ status) & gpio->irq_mapped); - for_each_set_bit(i, &change, gpio->chip.ngpio) - generic_handle_irq(irq_find_mapping(gpio->irq_domain, i)); - gpio->status = status; - - spin_unlock_irqrestore(&gpio->slock, flags); --} -- --static irqreturn_t pcf857x_irq_demux(int irq, void *data) --{ -- struct pcf857x *gpio = data; -- -- /* -- * pcf857x can't read/write data here, -- * since i2c data access might go to sleep. -- */ -- schedule_work(&gpio->work); - - return IRQ_HANDLED; - } - --static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int virq, -+static int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hw) - { -- irq_set_chip_and_handler(virq, -+ struct pcf857x *gpio = domain->host_data; -+ -+ irq_set_chip_and_handler(irq, - &dummy_irq_chip, - handle_level_irq); -+#ifdef CONFIG_ARM -+ set_irq_flags(irq, IRQF_VALID); -+#else -+ irq_set_noprobe(irq); -+#endif -+ gpio->irq_mapped |= (1 << hw); -+ - return 0; - } - -@@ -218,8 +245,6 @@ static void pcf857x_irq_domain_cleanup(s - if (gpio->irq_domain) - irq_domain_remove(gpio->irq_domain); - -- if (gpio->irq) -- free_irq(gpio->irq, gpio); - } - - static int pcf857x_irq_domain_init(struct pcf857x *gpio, -@@ -230,20 +255,21 @@ static int pcf857x_irq_domain_init(struc - gpio->irq_domain = irq_domain_add_linear(client->dev.of_node, - gpio->chip.ngpio, - &pcf857x_irq_domain_ops, -- NULL); -+ gpio); - if (!gpio->irq_domain) - goto fail; - - /* enable real irq */ -- status = request_irq(client->irq, pcf857x_irq_demux, 0, -- dev_name(&client->dev), gpio); -+ status = devm_request_threaded_irq(&client->dev, client->irq, -+ NULL, pcf857x_irq, IRQF_ONESHOT | -+ IRQF_TRIGGER_FALLING, -+ dev_name(&client->dev), gpio); -+ - if (status) - goto fail; - - /* enable gpio_to_irq() */ -- INIT_WORK(&gpio->work, pcf857x_irq_demux_work); - gpio->chip.to_irq = pcf857x_to_irq; -- gpio->irq = client->irq; - - return 0; - -@@ -257,14 +283,18 @@ fail: - static int pcf857x_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { -- struct pcf857x_platform_data *pdata; -+ struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev); -+ struct device_node *np = client->dev.of_node; - struct pcf857x *gpio; -+ unsigned int n_latch = 0; - int status; - -- pdata = dev_get_platdata(&client->dev); -- if (!pdata) { -+ if (IS_ENABLED(CONFIG_OF) && np) -+ of_property_read_u32(np, "lines-initial-states", &n_latch); -+ else if (pdata) -+ n_latch = pdata->n_latch; -+ else - dev_dbg(&client->dev, "no platform data\n"); -- } - - /* Allocate, initialize, and register this gpio_chip. */ - gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL); -@@ -357,11 +387,11 @@ static int pcf857x_probe(struct i2c_clie - * may cause transient glitching since it can't know the last value - * written (some pins may need to be driven low). - * -- * Using pdata->n_latch avoids that trouble. When left initialized -- * to zero, our software copy of the "latch" then matches the chip's -- * all-ones reset state. Otherwise it flags pins to be driven low. -+ * Using n_latch avoids that trouble. When left initialized to zero, -+ * our software copy of the "latch" then matches the chip's all-ones -+ * reset state. Otherwise it flags pins to be driven low. - */ -- gpio->out = pdata ? ~pdata->n_latch : ~0; -+ gpio->out = ~n_latch; - gpio->status = gpio->out; - - status = gpiochip_add(&gpio->chip); -@@ -423,6 +453,7 @@ static struct i2c_driver pcf857x_driver - .driver = { - .name = "pcf857x", - .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(pcf857x_of_table), - }, - .probe = pcf857x_probe, - .remove = pcf857x_remove, ---- a/drivers/gpu/drm/omapdrm/omap_crtc.c -+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c -@@ -411,7 +411,7 @@ static void omap_crtc_error_irq(struct o - struct drm_crtc *crtc = &omap_crtc->base; - DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus); - /* avoid getting in a flood, unregister the irq until next vblank */ -- omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); -+ __omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); - } - - static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) -@@ -421,13 +421,13 @@ static void omap_crtc_apply_irq(struct o - struct drm_crtc *crtc = &omap_crtc->base; - - if (!omap_crtc->error_irq.registered) -- omap_irq_register(crtc->dev, &omap_crtc->error_irq); -+ __omap_irq_register(crtc->dev, &omap_crtc->error_irq); - - if (!dispc_mgr_go_busy(omap_crtc->channel)) { - struct omap_drm_private *priv = - crtc->dev->dev_private; - DBG("%s: apply done", omap_crtc->name); -- omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq); -+ __omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq); - queue_work(priv->wq, &omap_crtc->apply_work); - } - } -@@ -623,6 +623,11 @@ void omap_crtc_pre_init(void) - dss_install_mgr_ops(&mgr_ops); - } - -+void omap_crtc_pre_uninit(void) -+{ -+ dss_uninstall_mgr_ops(); -+} -+ - /* initialize crtc */ - struct drm_crtc *omap_crtc_init(struct drm_device *dev, - struct drm_plane *plane, enum omap_channel channel, int id) ---- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c -+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c -@@ -968,12 +968,23 @@ static const struct dev_pm_ops omap_dmm_ - }; - #endif - -+#if defined(CONFIG_OF) -+static const struct of_device_id dmm_of_match[] = { -+ { .compatible = "ti,omap4-dmm", }, -+ { .compatible = "ti,omap5-dmm", }, -+ {}, -+}; -+#else -+#define dmm_of_match NULL -+#endif -+ - struct platform_driver omap_dmm_driver = { - .probe = omap_dmm_probe, - .remove = omap_dmm_remove, - .driver = { - .owner = THIS_MODULE, - .name = DMM_DRIVER_NAME, -+ .of_match_table = dmm_of_match, - #ifdef CONFIG_PM - .pm = &omap_dmm_pm_ops, - #endif ---- a/drivers/gpu/drm/omapdrm/omap_drv.c -+++ b/drivers/gpu/drm/omapdrm/omap_drv.c -@@ -86,6 +86,47 @@ static bool channel_used(struct drm_devi - - return false; - } -+static void omap_disconnect_dssdevs(void) -+{ -+ struct omap_dss_device *dssdev = NULL; -+ -+ for_each_dss_dev(dssdev) -+ dssdev->driver->disconnect(dssdev); -+} -+ -+static int omap_connect_dssdevs(void) -+{ -+ int r; -+ struct omap_dss_device *dssdev = NULL; -+ bool no_displays = true; -+ -+ for_each_dss_dev(dssdev) { -+ r = dssdev->driver->connect(dssdev); -+ if (r == -EPROBE_DEFER) { -+ omap_dss_put_device(dssdev); -+ goto cleanup; -+ } else if (r) { -+ dev_warn(dssdev->dev, "could not connect display: %s\n", -+ dssdev->name); -+ } else { -+ no_displays = false; -+ } -+ } -+ -+ if (no_displays) -+ return -EPROBE_DEFER; -+ -+ return 0; -+ -+cleanup: -+ /* -+ * if we are deferring probe, we disconnect the devices we previously -+ * connected -+ */ -+ omap_disconnect_dssdevs(); -+ -+ return r; -+} - - static int omap_modeset_init(struct drm_device *dev) - { -@@ -95,9 +136,6 @@ static int omap_modeset_init(struct drm_ - int num_mgrs = dss_feat_get_num_mgrs(); - int num_crtcs; - int i, id = 0; -- int r; -- -- omap_crtc_pre_init(); - - drm_mode_config_init(dev); - -@@ -119,26 +157,8 @@ static int omap_modeset_init(struct drm_ - enum omap_channel channel; - struct omap_overlay_manager *mgr; - -- if (!dssdev->driver) { -- dev_warn(dev->dev, "%s has no driver.. skipping it\n", -- dssdev->name); -- continue; -- } -- -- if (!(dssdev->driver->get_timings || -- dssdev->driver->read_edid)) { -- dev_warn(dev->dev, "%s driver does not support " -- "get_timings or read_edid.. skipping it!\n", -- dssdev->name); -- continue; -- } -- -- r = dssdev->driver->connect(dssdev); -- if (r) { -- dev_err(dev->dev, "could not connect display: %s\n", -- dssdev->name); -+ if (!omapdss_device_is_connected(dssdev)) - continue; -- } - - encoder = omap_encoder_init(dev, dssdev); - -@@ -656,9 +676,19 @@ static void pdev_shutdown(struct platfor - - static int pdev_probe(struct platform_device *device) - { -+ int r; -+ - if (omapdss_is_initialized() == false) - return -EPROBE_DEFER; - -+ omap_crtc_pre_init(); -+ -+ r = omap_connect_dssdevs(); -+ if (r) { -+ omap_crtc_pre_uninit(); -+ return r; -+ } -+ - DBG("%s", device->name); - return drm_platform_init(&omap_drm_driver, device); - } -@@ -668,6 +698,8 @@ static int pdev_remove(struct platform_d - DBG(""); - drm_platform_exit(&omap_drm_driver, device); - -+ omap_disconnect_dssdevs(); -+ - platform_driver_unregister(&omap_dmm_driver); - return 0; - } ---- a/drivers/gpu/drm/omapdrm/omap_drv.h -+++ b/drivers/gpu/drm/omapdrm/omap_drv.h -@@ -145,6 +145,8 @@ irqreturn_t omap_irq_handler(DRM_IRQ_ARG - void omap_irq_preinstall(struct drm_device *dev); - int omap_irq_postinstall(struct drm_device *dev); - void omap_irq_uninstall(struct drm_device *dev); -+void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); -+void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); - void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); - void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); - int omap_drm_irq_uninstall(struct drm_device *dev); -@@ -158,6 +160,7 @@ enum omap_channel omap_crtc_channel(stru - int omap_crtc_apply(struct drm_crtc *crtc, - struct omap_drm_apply *apply); - void omap_crtc_pre_init(void); -+void omap_crtc_pre_uninit(void); - struct drm_crtc *omap_crtc_init(struct drm_device *dev, - struct drm_plane *plane, enum omap_channel channel, int id); - ---- a/drivers/gpu/drm/omapdrm/omap_encoder.c -+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c -@@ -51,6 +51,10 @@ struct omap_dss_device *omap_encoder_get - static void omap_encoder_destroy(struct drm_encoder *encoder) - { - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); -+ struct omap_dss_device *dssdev = omap_encoder->dssdev; -+ -+ dssdev->driver->disable(dssdev); -+ - drm_encoder_cleanup(encoder); - kfree(omap_encoder); - } ---- a/drivers/gpu/drm/omapdrm/omap_irq.c -+++ b/drivers/gpu/drm/omapdrm/omap_irq.c -@@ -45,12 +45,11 @@ static void omap_irq_update(struct drm_d - dispc_read_irqenable(); /* flush posted write */ - } - --void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) -+void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) - { - struct omap_drm_private *priv = dev->dev_private; - unsigned long flags; - -- dispc_runtime_get(); - spin_lock_irqsave(&list_lock, flags); - - if (!WARN_ON(irq->registered)) { -@@ -60,14 +59,21 @@ void omap_irq_register(struct drm_device - } - - spin_unlock_irqrestore(&list_lock, flags); -+} -+ -+void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) -+{ -+ dispc_runtime_get(); -+ -+ __omap_irq_register(dev, irq); -+ - dispc_runtime_put(); - } - --void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) -+void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) - { - unsigned long flags; - -- dispc_runtime_get(); - spin_lock_irqsave(&list_lock, flags); - - if (!WARN_ON(!irq->registered)) { -@@ -77,6 +83,14 @@ void omap_irq_unregister(struct drm_devi - } - - spin_unlock_irqrestore(&list_lock, flags); -+} -+ -+void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) -+{ -+ dispc_runtime_get(); -+ -+ __omap_irq_unregister(dev, irq); -+ - dispc_runtime_put(); - } - ---- a/drivers/gpu/drm/omapdrm/omap_plane.c -+++ b/drivers/gpu/drm/omapdrm/omap_plane.c -@@ -122,6 +122,7 @@ static void omap_plane_pre_apply(struct - enum omap_channel channel; - bool enabled = omap_plane->enabled && crtc; - bool ilace, replication; -+ u32 low, high; - int ret; - - DBG("%s, enabled=%d", omap_plane->name, enabled); -@@ -149,6 +150,10 @@ static void omap_plane_pre_apply(struct - ilace = false; - replication = false; - -+ dispc_ovl_compute_fifo_thresholds(omap_plane->id, &low, &high, -+ false, false); -+ dispc_ovl_set_fifo_threshold(omap_plane->id, low, high); -+ - /* and finally, update omapdss: */ - ret = dispc_ovl_setup(omap_plane->id, info, - replication, omap_crtc_timings(crtc), false); ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -@@ -43,7 +43,7 @@ - * with optimized DDR & EMIF settings tweaked 1920x1080@24 appears to - * be supportable - */ --#define TILCDC_DEFAULT_MAX_BANDWIDTH (1280*1024*60) -+#define TILCDC_DEFAULT_MAX_BANDWIDTH (1680*1050*60) - - - struct tilcdc_drm_private { ---- a/drivers/iio/adc/ti_am335x_adc.c -+++ b/drivers/iio/adc/ti_am335x_adc.c -@@ -154,7 +154,7 @@ static int tiadc_read_raw(struct iio_dev - while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) { - if (time_after(jiffies, timeout)) - return -EAGAIN; -- } -+ } - map_val = chan->channel + TOTAL_CHANNELS; - - /* ---- a/drivers/input/touchscreen/atmel_mxt_ts.c -+++ b/drivers/input/touchscreen/atmel_mxt_ts.c -@@ -20,6 +20,8 @@ - #include <linux/input/mt.h> - #include <linux/interrupt.h> - #include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_device.h> - - /* Version */ - #define MXT_VER_20 20 -@@ -335,6 +337,105 @@ static void mxt_dump_message(struct devi - message->reportid, 7, message->message); - } - -+static int mxt_of_get_platform_info(struct i2c_client *client, -+ struct mxt_platform_data *pdata) -+ -+{ -+ int size, index = 0; -+ u32 val; -+ const __be32 *config_be; -+ u8 *config; -+ const char *pname; -+ struct device_node *node = client->dev.of_node; -+ -+ config_be = of_get_property(node, "atmel,config", &size); -+ if (config_be && size) { -+ size /= sizeof(*config_be); -+ config = devm_kzalloc(&client->dev, size, GFP_KERNEL); -+ if (!config) { -+ dev_err(&client->dev, "Failed to allocate memory\n"); -+ return -ENOMEM; -+ } -+ -+ pdata->config = config; -+ pdata->config_length = size; -+ -+ while (index < size) { -+ config[index] = be32_to_cpup(config_be + index) & 0xFF; -+ index++; -+ } -+ } else { -+ dev_dbg(&client->dev, "%s:no config data specified\n", -+ __func__); -+ } -+ -+ pname = "atmel,x_line"; -+ if (of_property_read_u32(node, pname, &pdata->x_line)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,y_line"; -+ if (of_property_read_u32(node, pname, &pdata->y_line)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,x_size"; -+ if (of_property_read_u32(node, pname, &pdata->x_size)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,y_size"; -+ if (of_property_read_u32(node, pname, &pdata->y_size)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,blen"; -+ if (of_property_read_u32(node, pname, &pdata->blen)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,threshold"; -+ if (of_property_read_u32(node, pname, &pdata->threshold)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,voltage"; -+ if (of_property_read_u32(node, pname, &pdata->voltage)) { -+ dev_err(&client->dev, -+ "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ pname = "atmel,orient"; -+ if (of_property_read_u32(node, pname, &val)) { -+ dev_err(&client->dev, "%s: Failed to read %s property\n", -+ __func__, pname); -+ return -EINVAL; -+ } -+ -+ if (val > 0xFF) { -+ dev_err(&client->dev, "%s: Bad %s property value %d\n", -+ __func__, pname, val); -+ return -EINVAL; -+ } -+ pdata->orient = val & 0xFF; -+ -+ return 0; -+} -+ - static int mxt_check_bootloader(struct i2c_client *client, - unsigned int state) - { -@@ -1127,19 +1228,43 @@ static void mxt_input_close(struct input - mxt_stop(data); - } - -+static const struct of_device_id mxt_dt_ids[] = { -+ { .compatible = "atmel,qt602240_ts", }, -+ { .compatible = "atmel,atmel_mxt_ts", }, -+ { .compatible = "atmel,mXT244", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, mxt_dt_ids); -+ - static int mxt_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { -- const struct mxt_platform_data *pdata = client->dev.platform_data; -+ struct mxt_platform_data *pdata; - struct mxt_data *data; - struct input_dev *input_dev; - int error; - unsigned int num_mt_slots; -+ const struct of_device_id *match; - -- if (!pdata) -- return -EINVAL; -+ match = of_match_device(of_match_ptr(mxt_dt_ids), &client->dev); -+ if (match) { -+ pdata = devm_kzalloc(&client->dev, -+ sizeof(struct mxt_platform_data), -+ GFP_KERNEL); -+ if (!pdata) -+ return -ENOMEM; -+ error = mxt_of_get_platform_info(client, pdata); -+ if (error) -+ return error; -+ } else { -+ pdata = client->dev.platform_data; -+ if (!pdata) { -+ dev_err(&client->dev, "Platform data not populated\n"); -+ return -EINVAL; -+ } -+ } - -- data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); -+ data = devm_kzalloc(&client->dev, sizeof(struct mxt_data), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!data || !input_dev) { - dev_err(&client->dev, "Failed to allocate memory\n"); -@@ -1224,9 +1349,10 @@ static int mxt_probe(struct i2c_client * - input_set_drvdata(input_dev, data); - i2c_set_clientdata(client, data); - -- error = request_threaded_irq(client->irq, NULL, mxt_interrupt, -- pdata->irqflags | IRQF_ONESHOT, -- client->name, data); -+ error = devm_request_threaded_irq(&client->dev, client->irq, -+ NULL, mxt_interrupt, -+ IRQF_ONESHOT, -+ dev_name(&client->dev), data); - if (error) { - dev_err(&client->dev, "Failed to register interrupt\n"); - goto err_free_object; -@@ -1234,11 +1360,11 @@ static int mxt_probe(struct i2c_client * - - error = mxt_make_highchg(data); - if (error) -- goto err_free_irq; -+ goto err_free_object; - - error = input_register_device(input_dev); - if (error) -- goto err_free_irq; -+ goto err_free_object; - - error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); - if (error) -@@ -1249,13 +1375,10 @@ static int mxt_probe(struct i2c_client * - err_unregister_device: - input_unregister_device(input_dev); - input_dev = NULL; --err_free_irq: -- free_irq(client->irq, data); - err_free_object: - kfree(data->object_table); - err_free_mem: - input_free_device(input_dev); -- kfree(data); - return error; - } - -@@ -1264,10 +1387,8 @@ static int mxt_remove(struct i2c_client - struct mxt_data *data = i2c_get_clientdata(client); - - sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); -- free_irq(data->irq, data); - input_unregister_device(data->input_dev); - kfree(data->object_table); -- kfree(data); - - return 0; - } -@@ -1328,6 +1449,7 @@ static struct i2c_driver mxt_driver = { - .name = "atmel_mxt_ts", - .owner = THIS_MODULE, - .pm = &mxt_pm_ops, -+ .of_match_table = mxt_dt_ids, - }, - .probe = mxt_probe, - .remove = mxt_remove, ---- a/drivers/input/touchscreen/pixcir_i2c_ts.c -+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c -@@ -23,170 +23,490 @@ - #include <linux/slab.h> - #include <linux/i2c.h> - #include <linux/input.h> -+#include <linux/input/mt.h> - #include <linux/input/pixcir_ts.h> -+#include <linux/gpio.h> -+#include <linux/of.h> -+#include <linux/of_gpio.h> -+#include <linux/of_device.h> -+ -+#define MAX_FINGERS 5 /* Maximum supported by the driver */ - - struct pixcir_i2c_ts_data { - struct i2c_client *client; - struct input_dev *input; -- const struct pixcir_ts_platform_data *chip; -+ const struct pixcir_ts_platform_data *pdata; - bool exiting; -+ u8 max_fingers; /* Maximum supported by the chip */ - }; - --static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data) -+static void pixcir_ts_typea_report(struct pixcir_i2c_ts_data *tsdata) - { -- struct pixcir_i2c_ts_data *tsdata = data; -+ const struct pixcir_ts_platform_data *pdata = tsdata->pdata; - u8 rdbuf[10], wrbuf[1] = { 0 }; - u8 touch; - int ret; - -- ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf)); -- if (ret != sizeof(wrbuf)) { -- dev_err(&tsdata->client->dev, -- "%s: i2c_master_send failed(), ret=%d\n", -- __func__, ret); -- return; -- } -- -- ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf)); -- if (ret != sizeof(rdbuf)) { -- dev_err(&tsdata->client->dev, -- "%s: i2c_master_recv failed(), ret=%d\n", -- __func__, ret); -- return; -- } -- -- touch = rdbuf[0]; -- if (touch) { -- u16 posx1 = (rdbuf[3] << 8) | rdbuf[2]; -- u16 posy1 = (rdbuf[5] << 8) | rdbuf[4]; -- u16 posx2 = (rdbuf[7] << 8) | rdbuf[6]; -- u16 posy2 = (rdbuf[9] << 8) | rdbuf[8]; -- -- input_report_key(tsdata->input, BTN_TOUCH, 1); -- input_report_abs(tsdata->input, ABS_X, posx1); -- input_report_abs(tsdata->input, ABS_Y, posy1); -- -- input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1); -- input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1); -- input_mt_sync(tsdata->input); -- -- if (touch == 2) { -- input_report_abs(tsdata->input, -- ABS_MT_POSITION_X, posx2); -- input_report_abs(tsdata->input, -- ABS_MT_POSITION_Y, posy2); -+ while (!tsdata->exiting) { -+ -+ ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf)); -+ if (ret != sizeof(wrbuf)) { -+ dev_err(&tsdata->client->dev, -+ "%s: i2c_master_send failed(), ret=%d\n", -+ __func__, ret); -+ return; -+ } -+ -+ ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf)); -+ if (ret != sizeof(rdbuf)) { -+ dev_err(&tsdata->client->dev, -+ "%s: i2c_master_recv failed(), ret=%d\n", -+ __func__, ret); -+ return; -+ } -+ -+ touch = rdbuf[0]; -+ if (touch) { -+ u16 posx1 = (rdbuf[3] << 8) | rdbuf[2]; -+ u16 posy1 = (rdbuf[5] << 8) | rdbuf[4]; -+ u16 posx2 = (rdbuf[7] << 8) | rdbuf[6]; -+ u16 posy2 = (rdbuf[9] << 8) | rdbuf[8]; -+ -+ input_report_key(tsdata->input, BTN_TOUCH, 1); -+ input_report_abs(tsdata->input, ABS_X, posx1); -+ input_report_abs(tsdata->input, ABS_Y, posy1); -+ -+ input_report_abs(tsdata->input, ABS_MT_POSITION_X, -+ posx1); -+ input_report_abs(tsdata->input, ABS_MT_POSITION_Y, -+ posy1); - input_mt_sync(tsdata->input); -+ -+ if (touch == 2) { -+ input_report_abs(tsdata->input, -+ ABS_MT_POSITION_X, posx2); -+ input_report_abs(tsdata->input, -+ ABS_MT_POSITION_Y, posy2); -+ input_mt_sync(tsdata->input); -+ } -+ } else { -+ input_report_key(tsdata->input, BTN_TOUCH, 0); - } -- } else { -- input_report_key(tsdata->input, BTN_TOUCH, 0); -+ -+ input_sync(tsdata->input); -+ -+ if (gpio_get_value(pdata->gpio_attb)) -+ break; -+ -+ msleep(20); - } -+} -+ -+static void pixcir_ts_typeb_report(struct pixcir_i2c_ts_data *ts) -+{ -+ const struct pixcir_ts_platform_data *pdata = ts->pdata; -+ struct device *dev = &ts->client->dev; -+ u8 rdbuf[32], wrbuf[1] = { 0 }; -+ u8 *bufptr; -+ u8 num_fingers; -+ u8 unreliable; -+ int ret, i; -+ -+ while (!ts->exiting) { -+ -+ ret = i2c_master_send(ts->client, wrbuf, sizeof(wrbuf)); -+ if (ret != sizeof(wrbuf)) { -+ dev_err(dev, "%s: i2c_master_send failed(), ret=%d\n", -+ __func__, ret); -+ return; -+ } -+ -+ ret = i2c_master_recv(ts->client, rdbuf, sizeof(rdbuf)); -+ if (ret != sizeof(rdbuf)) { -+ dev_err(dev, "%s: i2c_master_recv failed(), ret=%d\n", -+ __func__, ret); -+ return; -+ } - -- input_sync(tsdata->input); -+ unreliable = rdbuf[0] & 0xe0; -+ -+ if (unreliable) -+ goto next; /* ignore unreliable data */ -+ -+ num_fingers = rdbuf[0] & 0x7; -+ bufptr = &rdbuf[2]; -+ -+ if (num_fingers > ts->max_fingers) { -+ num_fingers = ts->max_fingers; -+ dev_dbg(dev, "limiting num_fingers to %d\n", -+ num_fingers); -+ } -+ -+ for (i = 0; i < num_fingers; i++) { -+ u8 id; -+ unsigned int x, y; -+ int slot; -+ -+ id = bufptr[4]; -+ slot = input_mt_get_slot_by_key(ts->input, id); -+ if (slot < 0) { -+ dev_dbg(dev, "no free slot for id 0x%x\n", id); -+ continue; -+ } -+ -+ -+ x = bufptr[1] << 8 | bufptr[0]; -+ y = bufptr[3] << 8 | bufptr[2]; -+ -+ input_mt_slot(ts->input, slot); -+ input_mt_report_slot_state(ts->input, -+ MT_TOOL_FINGER, true); -+ -+ input_event(ts->input, EV_ABS, ABS_MT_POSITION_X, x); -+ input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y, y); -+ -+ bufptr = &bufptr[5]; -+ dev_dbg(dev, "%d: id 0x%x slot %d, x %d, y %d\n", -+ i, id, slot, x, y); -+ } -+ -+ /* One frame is complete so sync it */ -+ input_mt_sync_frame(ts->input); -+ input_sync(ts->input); -+ -+next: -+ if (gpio_get_value(pdata->gpio_attb)) -+ break; -+ -+ usleep_range(2000, 5000); -+ } - } - - static irqreturn_t pixcir_ts_isr(int irq, void *dev_id) - { - struct pixcir_i2c_ts_data *tsdata = dev_id; - -- while (!tsdata->exiting) { -- pixcir_ts_poscheck(tsdata); -+ if (tsdata->input->mt) -+ pixcir_ts_typeb_report(tsdata); -+ else -+ pixcir_ts_typea_report(tsdata); - -- if (tsdata->chip->attb_read_val()) -- break; -+ return IRQ_HANDLED; -+} - -- msleep(20); -+static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, -+ enum pixcir_power_mode mode) -+{ -+ struct device *dev = &ts->client->dev; -+ int ret; -+ -+ ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE); -+ if (ret < 0) { -+ dev_err(dev, "%s: can't read reg 0x%x : %d\n", -+ __func__, PIXCIR_REG_POWER_MODE, ret); -+ return ret; - } - -- return IRQ_HANDLED; -+ ret &= ~PIXCIR_POWER_MODE_MASK; -+ ret |= mode; -+ -+ /* Always AUTO_IDLE */ -+ ret |= PIXCIR_POWER_ALLOW_IDLE; -+ -+ ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret); -+ if (ret < 0) { -+ dev_err(dev, "%s: can't write reg 0x%x : %d\n", -+ __func__, PIXCIR_REG_POWER_MODE, ret); -+ return ret; -+ } -+ -+ return 0; - } - --#ifdef CONFIG_PM_SLEEP --static int pixcir_i2c_ts_suspend(struct device *dev) -+/* -+ * Set the interrupt mode for the device i.e. ATTB line behaviour -+ * -+ * @polarity : 1 for active high, 0 for active low. -+ */ -+static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, -+ enum pixcir_int_mode mode, -+ bool polarity) - { -- struct i2c_client *client = to_i2c_client(dev); -+ struct device *dev = &ts->client->dev; -+ int ret; - -- if (device_may_wakeup(&client->dev)) -- enable_irq_wake(client->irq); -+ ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); -+ if (ret < 0) { -+ dev_err(dev, "%s: can't read reg 0x%x : %d\n", -+ __func__, PIXCIR_REG_INT_MODE, ret); -+ return ret; -+ } -+ -+ ret &= ~PIXCIR_INT_MODE_MASK; -+ ret |= mode; -+ -+ if (polarity) -+ ret |= PIXCIR_INT_POL_HIGH; -+ else -+ ret &= ~PIXCIR_INT_POL_HIGH; -+ -+ ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); -+ if (ret < 0) { -+ dev_err(dev, "%s: can't write reg 0x%x : %d\n", -+ __func__, PIXCIR_REG_INT_MODE, ret); -+ return ret; -+ } - - return 0; - } - --static int pixcir_i2c_ts_resume(struct device *dev) -+/* -+ * Enable/disable interrupt generation -+ */ -+static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) - { -- struct i2c_client *client = to_i2c_client(dev); -+ struct device *dev = &ts->client->dev; -+ int ret; - -- if (device_may_wakeup(&client->dev)) -- disable_irq_wake(client->irq); -+ ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); -+ if (ret < 0) { -+ dev_err(dev, "%s: can't read reg 0x%x : %d\n", -+ __func__, PIXCIR_REG_INT_MODE, ret); -+ return ret; -+ } -+ -+ if (enable) -+ ret |= PIXCIR_INT_ENABLE; -+ else -+ ret &= ~PIXCIR_INT_ENABLE; -+ -+ ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); -+ if (ret < 0) { -+ dev_err(dev, "%s: can't write reg 0x%x : %d\n", -+ __func__, PIXCIR_REG_INT_MODE, ret); -+ return ret; -+ } - - return 0; - } --#endif - --static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, -- pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); -+static int pixcir_start(struct pixcir_i2c_ts_data *ts) -+{ -+ struct device *dev = &ts->client->dev; -+ int ret; -+ -+ /* LEVEL_TOUCH interrupt with active low polarity */ -+ ret = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0); -+ if (ret) { -+ dev_err(dev, "Failed to set interrupt mode\n"); -+ return ret; -+ } -+ -+ enable_irq(ts->client->irq); -+ -+ /* enable interrupt generation */ -+ ret = pixcir_int_enable(ts, 1); -+ if (ret) { -+ dev_err(dev, "Failed to enable interrupt generation\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int pixcir_stop(struct pixcir_i2c_ts_data *ts) -+{ -+ struct device *dev = &ts->client->dev; -+ int ret; -+ -+ /* disable interrupt generation */ -+ ret = pixcir_int_enable(ts, 0); -+ if (ret) { -+ dev_err(dev, "Failed to disable interrupt generation\n"); -+ return ret; -+ } -+ -+ disable_irq(ts->client->irq); -+ -+ return 0; -+} -+ -+static int pixcir_input_open(struct input_dev *dev) -+{ -+ struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev); -+ -+ return pixcir_start(ts); -+} -+ -+static void pixcir_input_close(struct input_dev *dev) -+{ -+ struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev); -+ -+ pixcir_stop(ts); -+ -+ return; -+} -+ -+#if defined(CONFIG_OF) -+static const struct of_device_id pixcir_of_match[]; -+ -+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev) -+{ -+ struct pixcir_ts_platform_data *pdata; -+ struct device_node *np = dev->of_node; -+ const struct of_device_id *match; -+ -+ match = of_match_device(of_match_ptr(pixcir_of_match), dev); -+ if (!match) -+ return ERR_PTR(-EINVAL); -+ -+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); -+ if (!pdata) -+ return ERR_PTR(-ENOMEM); -+ -+ pdata->chip = *(const struct pixcir_i2c_chip_data *)match->data; -+ -+ pdata->gpio_attb = of_get_named_gpio(np, "attb-gpio", 0); -+ if (!gpio_is_valid(pdata->gpio_attb)) { -+ dev_err(dev, "Failed to get ATTB GPIO\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ if (of_property_read_u32(np, "x-size", &pdata->x_size)) { -+ dev_err(dev, "Failed to get x-size property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ if (of_property_read_u32(np, "y-size", &pdata->y_size)) { -+ dev_err(dev, "Failed to get y-size property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ dev_dbg(dev, "%s: x %d, y %d, gpio %d\n", __func__, -+ pdata->x_size, pdata->y_size, pdata->gpio_attb); -+ -+ return pdata; -+} -+#else -+static struct pixcir_ts_platform_data *pixcir_parse_dt(struct device *dev) -+{ -+ return NULL; -+} -+#endif - - static int pixcir_i2c_ts_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { - const struct pixcir_ts_platform_data *pdata = client->dev.platform_data; -+ struct device *dev = &client->dev; -+ struct device_node *np = dev->of_node; - struct pixcir_i2c_ts_data *tsdata; - struct input_dev *input; - int error; - -- if (!pdata) { -+ if (np) { -+ pdata = pixcir_parse_dt(dev); -+ if (IS_ERR(pdata)) -+ return PTR_ERR(pdata); -+ -+ } else if (!pdata) { - dev_err(&client->dev, "platform data not defined\n"); - return -EINVAL; -+ } else { -+ if (!gpio_is_valid(pdata->gpio_attb)) { -+ dev_err(dev, "Invalid gpio_attb in pdata\n"); -+ return -EINVAL; -+ } - } - -- tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL); -- input = input_allocate_device(); -- if (!tsdata || !input) { -- dev_err(&client->dev, "Failed to allocate driver data!\n"); -- error = -ENOMEM; -- goto err_free_mem; -+ tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL); -+ if (!tsdata) -+ return -ENOMEM; -+ -+ input = devm_input_allocate_device(dev); -+ if (!input) { -+ dev_err(&client->dev, "Failed to allocate input device\n"); -+ return -ENOMEM; - } - - tsdata->client = client; - tsdata->input = input; -- tsdata->chip = pdata; -+ tsdata->pdata = pdata; - - input->name = client->name; - input->id.bustype = BUS_I2C; - input->dev.parent = &client->dev; -+ input->open = pixcir_input_open; -+ input->close = pixcir_input_close; - -- __set_bit(EV_KEY, input->evbit); - __set_bit(EV_ABS, input->evbit); - __set_bit(BTN_TOUCH, input->keybit); -- input_set_abs_params(input, ABS_X, 0, pdata->x_max, 0, 0); -- input_set_abs_params(input, ABS_Y, 0, pdata->y_max, 0, 0); -- input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); -- input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); -+ -+ input_set_abs_params(input, ABS_X, -+ 0, pdata->x_size - 1, 0, 0); -+ input_set_abs_params(input, ABS_Y, -+ 0, pdata->y_size - 1, 0, 0); -+ input_set_abs_params(input, ABS_MT_POSITION_X, -+ 0, pdata->x_size - 1, 0, 0); -+ input_set_abs_params(input, ABS_MT_POSITION_Y, -+ 0, pdata->y_size - 1, 0, 0); -+ -+ /* Type-B Multi-Touch support */ -+ if (pdata->chip.num_report_ids) { -+ const struct pixcir_i2c_chip_data *chip = &pdata->chip; -+ -+ tsdata->max_fingers = chip->num_report_ids; -+ if (tsdata->max_fingers > MAX_FINGERS) { -+ dev_info(dev, "Limiting maximum fingers to %d\n", -+ MAX_FINGERS); -+ tsdata->max_fingers = MAX_FINGERS; -+ } -+ -+ error = input_mt_init_slots(input, tsdata->max_fingers, -+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); -+ if (error) { -+ dev_err(dev, "Error initializing Multi-Touch slots\n"); -+ return error; -+ } -+ } - - input_set_drvdata(input, tsdata); - -- error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr, -+ error = devm_gpio_request_one(dev, pdata->gpio_attb, -+ GPIOF_DIR_IN, "pixcir_i2c_attb"); -+ if (error) { -+ dev_err(dev, "Failed to request ATTB gpio\n"); -+ return error; -+ } -+ -+ error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - client->name, tsdata); - if (error) { -- dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); -- goto err_free_mem; -+ dev_err(dev, "failed to request irq %d\n", client->irq); -+ return error; - } - -+ /* Always be in IDLE mode to save power, device supports auto wake */ -+ error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE); -+ if (error) { -+ dev_err(dev, "Failed to set IDLE mode\n"); -+ return error; -+ } -+ -+ /* Stop device till opened */ -+ error = pixcir_stop(tsdata); -+ if (error) -+ return error; -+ - error = input_register_device(input); - if (error) -- goto err_free_irq; -+ return error; - - i2c_set_clientdata(client, tsdata); - device_init_wakeup(&client->dev, 1); - - return 0; -- --err_free_irq: -- free_irq(client->irq, tsdata); --err_free_mem: -- input_free_device(input); -- kfree(tsdata); -- return error; - } - - static int pixcir_i2c_ts_remove(struct i2c_client *client) -@@ -197,25 +517,99 @@ static int pixcir_i2c_ts_remove(struct i - - tsdata->exiting = true; - mb(); -- free_irq(client->irq, tsdata); -- -- input_unregister_device(tsdata->input); -- kfree(tsdata); - - return 0; - } - -+#ifdef CONFIG_PM_SLEEP -+static int pixcir_i2c_ts_suspend(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); -+ struct input_dev *input = ts->input; -+ int ret = 0; -+ -+ mutex_lock(&input->mutex); -+ -+ if (device_may_wakeup(&client->dev)) { -+ /* need to start device if not open, to be wakeup source */ -+ if (!input->users) { -+ ret = pixcir_start(ts); -+ if (ret) -+ goto unlock; -+ } -+ -+ enable_irq_wake(client->irq); -+ -+ } else if (input->users) { -+ ret = pixcir_stop(ts); -+ } -+ -+unlock: -+ mutex_unlock(&input->mutex); -+ -+ return ret; -+} -+ -+static int pixcir_i2c_ts_resume(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); -+ struct input_dev *input = ts->input; -+ int ret = 0; -+ -+ mutex_lock(&input->mutex); -+ -+ if (device_may_wakeup(&client->dev)) { -+ disable_irq_wake(client->irq); -+ -+ /* need to stop device if it was not open on suspend */ -+ if (!input->users) { -+ ret = pixcir_stop(ts); -+ if (ret) -+ goto unlock; -+ } -+ -+ } else if (input->users) { -+ ret = pixcir_start(ts); -+ } -+ -+unlock: -+ mutex_unlock(&input->mutex); -+ -+ return ret; -+} -+#endif -+ -+static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, -+ pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); -+ - static const struct i2c_device_id pixcir_i2c_ts_id[] = { - { "pixcir_ts", 0 }, -+ { "pixcir_tangoc", 0}, - { } - }; - MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id); - -+#if defined(CONFIG_OF) -+static const struct pixcir_i2c_chip_data tangoc_data = { -+ .num_report_ids = 5, -+}; -+ -+static const struct of_device_id pixcir_of_match[] = { -+ { .compatible = "pixcir,pixcir_ts", }, -+ { .compatible = "pixcir,pixcir_tangoc", .data = &tangoc_data, }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, pixcir_of_match); -+#endif -+ - static struct i2c_driver pixcir_i2c_ts_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "pixcir_ts", - .pm = &pixcir_dev_pm_ops, -+ .of_match_table = of_match_ptr(pixcir_of_match), - }, - .probe = pixcir_i2c_ts_probe, - .remove = pixcir_i2c_ts_remove, ---- a/drivers/input/touchscreen/ti_am335x_tsc.c -+++ b/drivers/input/touchscreen/ti_am335x_tsc.c -@@ -348,9 +348,16 @@ static int titsc_parse_dt(struct platfor - if (err < 0) - return err; - -- err = of_property_read_u32(node, "ti,coordiante-readouts", -+ /* -+ * try with new binding first. If it fails, still try with -+ * bogus, miss-spelled version. -+ */ -+ err = of_property_read_u32(node, "ti,coordinate-readouts", - &ts_dev->coordinate_readouts); - if (err < 0) -+ err = of_property_read_u32(node, "ti,coordiante-readouts", -+ &ts_dev->coordinate_readouts); -+ if (err < 0) - return err; - - return of_property_read_u32_array(node, "ti,wire-config", ---- a/drivers/Kconfig -+++ b/drivers/Kconfig -@@ -166,4 +166,6 @@ source "drivers/reset/Kconfig" - - source "drivers/fmc/Kconfig" - -+source "drivers/phy/Kconfig" -+ - endmenu ---- a/drivers/mailbox/mailbox-omap1.c -+++ b/drivers/mailbox/mailbox-omap1.c -@@ -13,6 +13,7 @@ - #include <linux/interrupt.h> - #include <linux/platform_device.h> - #include <linux/io.h> -+#include <linux/delay.h> - - #include "omap-mbox.h" - -@@ -26,7 +27,7 @@ - #define MAILBOX_DSP2ARM1_Flag 0x1c - #define MAILBOX_DSP2ARM2_Flag 0x20 - --static void __iomem *mbox_base; -+static struct omap_mbox_device omap1_mbox_device; - - struct omap_mbox1_fifo { - unsigned long cmd; -@@ -37,16 +38,17 @@ struct omap_mbox1_fifo { - struct omap_mbox1_priv { - struct omap_mbox1_fifo tx_fifo; - struct omap_mbox1_fifo rx_fifo; -+ bool empty_flag; - }; - - static inline int mbox_read_reg(size_t ofs) - { -- return __raw_readw(mbox_base + ofs); -+ return __raw_readw(omap1_mbox_device.mbox_base + ofs); - } - - static inline void mbox_write_reg(u32 val, size_t ofs) - { -- __raw_writew(val, mbox_base + ofs); -+ __raw_writew(val, omap1_mbox_device.mbox_base + ofs); - } - - /* msg */ -@@ -59,6 +61,7 @@ static mbox_msg_t omap1_mbox_fifo_read(s - msg = mbox_read_reg(fifo->data); - msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16; - -+ (struct omap_mbox1_priv *)(mbox->priv)->empty_flag = false; - return msg; - } - -@@ -74,7 +77,9 @@ omap1_mbox_fifo_write(struct omap_mbox * - - static int omap1_mbox_fifo_empty(struct omap_mbox *mbox) - { -- return 0; -+ struct omap_mbox1_priv *priv = (struct omap_mbox1_priv *)mbox->priv; -+ -+ return priv->empty_flag ? 0 : 1; - } - - static int omap1_mbox_fifo_full(struct omap_mbox *mbox) -@@ -85,6 +90,18 @@ static int omap1_mbox_fifo_full(struct o - return mbox_read_reg(fifo->flag); - } - -+static int omap1_mbox_poll_for_space(struct omap_mbox *mbox) -+{ -+ int i = 1000; -+ -+ while (omap1_mbox_fifo_full(mbox)) { -+ if (--i == 0) -+ return -1; -+ udelay(1); -+ } -+ return 0; -+} -+ - /* irq */ - static void - omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -@@ -103,17 +120,21 @@ omap1_mbox_disable_irq(struct omap_mbox - static int - omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) - { -+ struct omap_mbox1_priv *priv = (struct omap_mbox1_priv *)mbox->priv; -+ - if (irq == IRQ_TX) - return 0; -+ if (irq == IRQ_RX) -+ priv->empty_flag = true; -+ - return 1; - } - - static struct omap_mbox_ops omap1_mbox_ops = { -- .type = OMAP_MBOX_TYPE1, - .fifo_read = omap1_mbox_fifo_read, - .fifo_write = omap1_mbox_fifo_write, - .fifo_empty = omap1_mbox_fifo_empty, -- .fifo_full = omap1_mbox_fifo_full, -+ .poll_for_space = omap1_mbox_poll_for_space, - .enable_irq = omap1_mbox_enable_irq, - .disable_irq = omap1_mbox_disable_irq, - .is_irq = omap1_mbox_is_irq, -@@ -139,6 +160,7 @@ static struct omap_mbox mbox_dsp_info = - .name = "dsp", - .ops = &omap1_mbox_ops, - .priv = &omap1_mbox_dsp_priv, -+ .parent = &omap1_mbox_device, - }; - - static struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL }; -@@ -148,6 +170,7 @@ static int omap1_mbox_probe(struct platf - struct resource *mem; - int ret; - struct omap_mbox **list; -+ struct omap_mbox_device *mdev = &omap1_mbox_device; - - list = omap1_mboxes; - list[0]->irq = platform_get_irq_byname(pdev, "dsp"); -@@ -156,13 +179,18 @@ static int omap1_mbox_probe(struct platf - if (!mem) - return -ENOENT; - -- mbox_base = ioremap(mem->start, resource_size(mem)); -- if (!mbox_base) -+ mdev->mbox_base = ioremap(mem->start, resource_size(mem)); -+ if (!mdev->mbox_base) - return -ENOMEM; -+ mutex_init(&mdev->cfg_lock); -+ mdev->dev = &pdev->dev; -+ mdev->mboxes = omap1_mboxes; -+ mdev->num_users = 2; -+ mdev->num_fifos = 4; - -- ret = omap_mbox_register(&pdev->dev, list); -+ ret = omap_mbox_register(mdev); - if (ret) { -- iounmap(mbox_base); -+ iounmap(mdev->mbox_base); - return ret; - } - -@@ -171,8 +199,14 @@ static int omap1_mbox_probe(struct platf - - static int omap1_mbox_remove(struct platform_device *pdev) - { -- omap_mbox_unregister(); -- iounmap(mbox_base); -+ struct omap_mbox_device *mdev = &omap1_mbox_device; -+ -+ omap_mbox_unregister(mdev); -+ iounmap(mdev->mbox_base); -+ mdev->mbox_base = NULL; -+ mdev->mboxes = NULL; -+ mdev->dev = NULL; -+ - return 0; - } - ---- a/drivers/mailbox/mailbox-omap2.c -+++ b/drivers/mailbox/mailbox-omap2.c -@@ -14,6 +14,7 @@ - #include <linux/slab.h> - #include <linux/clk.h> - #include <linux/err.h> -+#include <linux/of_device.h> - #include <linux/platform_device.h> - #include <linux/io.h> - #include <linux/pm_runtime.h> -@@ -35,6 +36,8 @@ - #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) - #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) - -+#define AM33X_MBOX_WKUPM3_USR 3 -+ - #define MBOX_REG_SIZE 0x120 - - #define OMAP4_MBOX_REG_SIZE 0x130 -@@ -42,8 +45,6 @@ - #define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32)) - #define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32)) - --static void __iomem *mbox_base; -- - struct omap_mbox2_fifo { - unsigned long msg; - unsigned long fifo_stat; -@@ -62,34 +63,38 @@ struct omap_mbox2_priv { - u32 intr_type; - }; - --static inline unsigned int mbox_read_reg(size_t ofs) -+static inline -+unsigned int mbox_read_reg(struct omap_mbox_device *mdev, size_t ofs) - { -- return __raw_readl(mbox_base + ofs); -+ return __raw_readl(mdev->mbox_base + ofs); - } - --static inline void mbox_write_reg(u32 val, size_t ofs) -+static inline -+void mbox_write_reg(struct omap_mbox_device *mdev, u32 val, size_t ofs) - { -- __raw_writel(val, mbox_base + ofs); -+ __raw_writel(val, mdev->mbox_base + ofs); - } - - /* Mailbox H/W preparations */ - static int omap2_mbox_startup(struct omap_mbox *mbox) - { -- u32 l; -- -- pm_runtime_enable(mbox->dev->parent); -- pm_runtime_get_sync(mbox->dev->parent); -+ pm_runtime_get_sync(mbox->parent->dev); - -- l = mbox_read_reg(MAILBOX_REVISION); -- pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); -+ /* -+ * just print the raw revision register, the format is not -+ * uniform across all SoCs -+ */ -+ if (!mbox->use_count) { -+ u32 l = mbox_read_reg(mbox->parent, MAILBOX_REVISION); -+ pr_debug("omap mailbox rev 0x%x\n", l); -+ } - - return 0; - } - - static void omap2_mbox_shutdown(struct omap_mbox *mbox) - { -- pm_runtime_put_sync(mbox->dev->parent); -- pm_runtime_disable(mbox->dev->parent); -+ pm_runtime_put_sync(mbox->parent->dev); - } - - /* Mailbox FIFO handle functions */ -@@ -97,28 +102,36 @@ static mbox_msg_t omap2_mbox_fifo_read(s - { - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; -- return (mbox_msg_t) mbox_read_reg(fifo->msg); -+ return (mbox_msg_t) mbox_read_reg(mbox->parent, fifo->msg); - } - - static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) - { - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; -- mbox_write_reg(msg, fifo->msg); -+ mbox_write_reg(mbox->parent, msg, fifo->msg); - } - - static int omap2_mbox_fifo_empty(struct omap_mbox *mbox) - { - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; -- return (mbox_read_reg(fifo->msg_stat) == 0); -+ return (mbox_read_reg(mbox->parent, fifo->msg_stat) == 0); - } - - static int omap2_mbox_fifo_full(struct omap_mbox *mbox) - { - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; -- return mbox_read_reg(fifo->fifo_stat); -+ return mbox_read_reg(mbox->parent, fifo->fifo_stat); -+} -+ -+static int omap2_mbox_poll_for_space(struct omap_mbox *mbox) -+{ -+ if (omap2_mbox_fifo_full(mbox)) -+ return -1; -+ -+ return 0; - } - - /* Mailbox IRQ handle functions */ -@@ -127,9 +140,9 @@ static void omap2_mbox_enable_irq(struct - struct omap_mbox2_priv *p = mbox->priv; - u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - -- l = mbox_read_reg(p->irqenable); -+ l = mbox_read_reg(mbox->parent, p->irqenable); - l |= bit; -- mbox_write_reg(l, p->irqenable); -+ mbox_write_reg(mbox->parent, l, p->irqenable); - } - - static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -@@ -142,9 +155,9 @@ static void omap2_mbox_disable_irq(struc - * OMAP4 and later SoCs have a dedicated interrupt disabling register. - */ - if (!p->intr_type) -- bit = mbox_read_reg(p->irqdisable) & ~bit; -+ bit = mbox_read_reg(mbox->parent, p->irqdisable) & ~bit; - -- mbox_write_reg(bit, p->irqdisable); -+ mbox_write_reg(mbox->parent, bit, p->irqdisable); - } - - static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -@@ -152,18 +165,69 @@ static void omap2_mbox_ack_irq(struct om - struct omap_mbox2_priv *p = mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - -- mbox_write_reg(bit, p->irqstatus); -+ mbox_write_reg(mbox->parent, bit, p->irqstatus); - - /* Flush posted write for irq status to avoid spurious interrupts */ -- mbox_read_reg(p->irqstatus); -+ mbox_read_reg(mbox->parent, p->irqstatus); - } - - static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) - { - struct omap_mbox2_priv *p = mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; -- u32 enable = mbox_read_reg(p->irqenable); -- u32 status = mbox_read_reg(p->irqstatus); -+ u32 enable = mbox_read_reg(mbox->parent, p->irqenable); -+ u32 status = mbox_read_reg(mbox->parent, p->irqstatus); -+ -+ return (int)(enable & status & bit); -+} -+ -+static void wkupm3_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -+{ -+ struct omap_mbox2_priv *p = mbox->priv; -+ u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; -+ unsigned long irqenable = ((irq == IRQ_RX) ? -+ OMAP4_MAILBOX_IRQENABLE(AM33X_MBOX_WKUPM3_USR) : p->irqenable); -+ -+ l = mbox_read_reg(mbox->parent, irqenable); -+ l |= bit; -+ mbox_write_reg(mbox->parent, l, irqenable); -+} -+ -+static void wkupm3_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -+{ -+ struct omap_mbox2_priv *p = mbox->priv; -+ u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; -+ unsigned long irqdisable = ((irq == IRQ_RX) ? -+ OMAP4_MAILBOX_IRQENABLE_CLR(AM33X_MBOX_WKUPM3_USR) : p->irqdisable); -+ -+ mbox_write_reg(mbox->parent, bit, irqdisable); -+} -+ -+static void wkupm3_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -+{ -+ struct omap_mbox2_priv *p = mbox->priv; -+ u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; -+ unsigned long irqstatus = ((irq == IRQ_RX) ? -+ OMAP4_MAILBOX_IRQSTATUS(AM33X_MBOX_WKUPM3_USR) : p->irqstatus); -+ -+ mbox_write_reg(mbox->parent, bit, irqstatus); -+ -+ /* Flush posted write for irq status to avoid spurious interrupts */ -+ mbox_read_reg(mbox->parent, irqstatus); -+} -+ -+static int wkupm3_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -+{ -+ struct omap_mbox2_priv *p = mbox->priv; -+ u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; -+ u32 enable, status; -+ -+ /* WkupM3 mailbox does not use a receive queue */ -+ if (irq == IRQ_RX) -+ return 0; -+ -+ enable = mbox_read_reg(mbox->parent, p->irqenable); -+ status = mbox_read_reg(mbox->parent, p->irqstatus); - - return (int)(enable & status & bit); - } -@@ -179,7 +243,7 @@ static void omap2_mbox_save_ctx(struct o - else - nr_regs = MBOX_NR_REGS; - for (i = 0; i < nr_regs; i++) { -- p->ctx[i] = mbox_read_reg(i * sizeof(u32)); -+ p->ctx[i] = mbox_read_reg(mbox->parent, i * sizeof(u32)); - - dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__, - i, p->ctx[i]); -@@ -197,21 +261,34 @@ static void omap2_mbox_restore_ctx(struc - else - nr_regs = MBOX_NR_REGS; - for (i = 0; i < nr_regs; i++) { -- mbox_write_reg(p->ctx[i], i * sizeof(u32)); -+ mbox_write_reg(mbox->parent, p->ctx[i], i * sizeof(u32)); - - dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__, - i, p->ctx[i]); - } - } - -+static void wkupm3_mbox_send_data(struct omap_mbox *mbox, mbox_msg_t msg) -+{ -+ mbox_msg_t rmsg; -+ -+ /* enable the mbox Rx interrupt for WkupM3 only briefly */ -+ wkupm3_mbox_enable_irq(mbox, IRQ_RX); -+ omap2_mbox_fifo_write(mbox, msg); -+ wkupm3_mbox_disable_irq(mbox, IRQ_RX); -+ -+ /* read back the message and ack the interrupt on behalf of WkupM3 */ -+ rmsg = omap2_mbox_fifo_read(mbox); -+ wkupm3_mbox_ack_irq(mbox, IRQ_RX); -+} -+ - static struct omap_mbox_ops omap2_mbox_ops = { -- .type = OMAP_MBOX_TYPE2, - .startup = omap2_mbox_startup, - .shutdown = omap2_mbox_shutdown, - .fifo_read = omap2_mbox_fifo_read, - .fifo_write = omap2_mbox_fifo_write, - .fifo_empty = omap2_mbox_fifo_empty, -- .fifo_full = omap2_mbox_fifo_full, -+ .poll_for_space = omap2_mbox_poll_for_space, - .enable_irq = omap2_mbox_enable_irq, - .disable_irq = omap2_mbox_disable_irq, - .ack_irq = omap2_mbox_ack_irq, -@@ -220,6 +297,36 @@ static struct omap_mbox_ops omap2_mbox_o - .restore_ctx = omap2_mbox_restore_ctx, - }; - -+static struct omap_mbox_ops wkupm3_mbox_ops = { -+ .startup = omap2_mbox_startup, -+ .shutdown = omap2_mbox_shutdown, -+ .fifo_read = omap2_mbox_fifo_read, -+ .fifo_write = wkupm3_mbox_send_data, -+ .fifo_empty = omap2_mbox_fifo_empty, -+ .poll_for_space = omap2_mbox_poll_for_space, -+ .enable_irq = wkupm3_mbox_enable_irq, -+ .disable_irq = wkupm3_mbox_disable_irq, -+ .ack_irq = wkupm3_mbox_ack_irq, -+ .is_irq = wkupm3_mbox_is_irq, -+ .save_ctx = omap2_mbox_save_ctx, -+ .restore_ctx = omap2_mbox_restore_ctx, -+}; -+ -+static const struct of_device_id omap_mailbox_of_match[] = { -+ { -+ .compatible = "ti,omap2-mailbox", -+ .data = (void *) MBOX_INTR_CFG_TYPE1, -+ }, -+ { -+ .compatible = "ti,omap4-mailbox", -+ .data = (void *) MBOX_INTR_CFG_TYPE2, -+ }, -+ { -+ /* end */ -+ }, -+}; -+MODULE_DEVICE_TABLE(of, omap_mailbox_of_match); -+ - static int omap2_mbox_probe(struct platform_device *pdev) - { - struct resource *mem; -@@ -227,40 +334,127 @@ static int omap2_mbox_probe(struct platf - struct omap_mbox **list, *mbox, *mboxblk; - struct omap_mbox2_priv *priv, *privblk; - struct omap_mbox_pdata *pdata = pdev->dev.platform_data; -- struct omap_mbox_dev_info *info; -- int i; -+ struct omap_mbox_device *mdev; -+ struct omap_mbox_dev_info *info, *of_info = NULL; -+ struct device_node *node = pdev->dev.of_node; -+ int i, j; -+ u32 info_count = 0, intr_type = 0; -+ u32 num_users = 0, num_fifos = 0; -+ u32 dlen, dsize = 4; -+ u32 *tmp; -+ const __be32 *mbox_data; - -- if (!pdata || !pdata->info_cnt || !pdata->info) { -+ if (!node && (!pdata || !pdata->info_cnt || !pdata->info)) { - pr_err("%s: platform not supported\n", __func__); - return -ENODEV; - } - -+ if (node) { -+ intr_type = (u32)of_match_device(omap_mailbox_of_match, -+ &pdev->dev)->data; -+ if (intr_type != 0 && intr_type != 1) { -+ dev_err(&pdev->dev, "invalid match data value\n"); -+ return -EINVAL; -+ } -+ -+ if (of_property_read_u32(node, "ti,mbox-num-users", -+ &num_users)) { -+ dev_err(&pdev->dev, -+ "no ti,mbox-num-users configuration found\n"); -+ return -ENODEV; -+ } -+ -+ if (of_property_read_u32(node, "ti,mbox-num-fifos", -+ &num_fifos)) { -+ dev_err(&pdev->dev, -+ "no ti,mbox-num-fifos configuration found\n"); -+ return -ENODEV; -+ } -+ -+ info_count = of_property_count_strings(node, "ti,mbox-names"); -+ if (!info_count) { -+ dev_err(&pdev->dev, "no mbox devices found\n"); -+ return -ENODEV; -+ } -+ -+ mbox_data = of_get_property(node, "ti,mbox-data", &dlen); -+ if (!mbox_data) { -+ dev_err(&pdev->dev, "no mbox device data found\n"); -+ return -ENODEV; -+ } -+ dlen /= sizeof(dsize); -+ if (dlen != dsize * info_count) { -+ dev_err(&pdev->dev, "mbox device data is truncated\n"); -+ return -ENODEV; -+ } -+ -+ of_info = kzalloc(info_count * sizeof(*of_info), GFP_KERNEL); -+ if (!of_info) -+ return -ENOMEM; -+ -+ i = 0; -+ while (i < info_count) { -+ info = of_info + i; -+ if (of_property_read_string_index(node, -+ "ti,mbox-names", i, &info->name)) { -+ dev_err(&pdev->dev, -+ "mbox_name [%d] read failed\n", i); -+ ret = -ENODEV; -+ goto free_of; -+ } -+ -+ tmp = &info->tx_id; -+ for (j = 0; j < dsize; j++) { -+ tmp[j] = of_read_number( -+ mbox_data + j + (i * dsize), 1); -+ } -+ i++; -+ } -+ } -+ -+ if (!node) { /* non-DT device creation */ -+ info_count = pdata->info_cnt; -+ info = pdata->info; -+ intr_type = pdata->intr_type; -+ num_users = pdata->num_users; -+ num_fifos = pdata->num_fifos; -+ } else { -+ info = of_info; -+ } -+ -+ mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); -+ if (!mdev) { -+ ret = -ENOMEM; -+ goto free_of; -+ } -+ - /* allocate one extra for marking end of list */ -- list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL); -- if (!list) -- return -ENOMEM; -+ list = kzalloc((info_count + 1) * sizeof(*list), GFP_KERNEL); -+ if (!list) { -+ ret = -ENOMEM; -+ goto free_mdev; -+ } - -- mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL); -+ mboxblk = mbox = kzalloc(info_count * sizeof(*mbox), GFP_KERNEL); - if (!mboxblk) { - ret = -ENOMEM; - goto free_list; - } - -- privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL); -+ privblk = priv = kzalloc(info_count * sizeof(*priv), GFP_KERNEL); - if (!privblk) { - ret = -ENOMEM; - goto free_mboxblk; - } - -- info = pdata->info; -- for (i = 0; i < pdata->info_cnt; i++, info++, priv++) { -+ for (i = 0; i < info_count; i++, info++, priv++) { - priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id); - priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); - priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id); - priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id); - priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); - priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); -- if (pdata->intr_type) { -+ if (intr_type) { - priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id); - priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id); - priv->irqdisable = -@@ -270,11 +464,15 @@ static int omap2_mbox_probe(struct platf - priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id); - priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id); - } -- priv->intr_type = pdata->intr_type; -+ priv->intr_type = intr_type; - - mbox->priv = priv; -+ mbox->parent = mdev; - mbox->name = info->name; -- mbox->ops = &omap2_mbox_ops; -+ if (!strcmp(mbox->name, "wkup_m3")) -+ mbox->ops = &wkupm3_mbox_ops; -+ else -+ mbox->ops = &omap2_mbox_ops; - mbox->irq = platform_get_irq(pdev, info->irq_id); - if (mbox->irq < 0) { - ret = mbox->irq; -@@ -289,42 +487,58 @@ static int omap2_mbox_probe(struct platf - goto free_privblk; - } - -- mbox_base = ioremap(mem->start, resource_size(mem)); -- if (!mbox_base) { -+ mdev->mbox_base = ioremap(mem->start, resource_size(mem)); -+ if (!mdev->mbox_base) { - ret = -ENOMEM; - goto free_privblk; - } - -- ret = omap_mbox_register(&pdev->dev, list); -+ mutex_init(&mdev->cfg_lock); -+ mdev->dev = &pdev->dev; -+ mdev->num_users = num_users; -+ mdev->num_fifos = num_fifos; -+ mdev->mboxes = list; -+ ret = omap_mbox_register(mdev); - if (ret) - goto unmap_mbox; -- platform_set_drvdata(pdev, list); -+ platform_set_drvdata(pdev, mdev); - -+ pm_runtime_enable(mdev->dev); -+ -+ kfree(of_info); - return 0; - - unmap_mbox: -- iounmap(mbox_base); -+ iounmap(mdev->mbox_base); - free_privblk: - kfree(privblk); - free_mboxblk: - kfree(mboxblk); - free_list: - kfree(list); -+free_mdev: -+ kfree(mdev); -+free_of: -+ kfree(of_info); - return ret; - } - - static int omap2_mbox_remove(struct platform_device *pdev) - { - struct omap_mbox2_priv *privblk; -- struct omap_mbox **list = platform_get_drvdata(pdev); -+ struct omap_mbox_device *mdev = platform_get_drvdata(pdev); -+ struct omap_mbox **list = mdev->mboxes; - struct omap_mbox *mboxblk = list[0]; - -+ pm_runtime_disable(mdev->dev); -+ - privblk = mboxblk->priv; -- omap_mbox_unregister(); -- iounmap(mbox_base); -+ omap_mbox_unregister(mdev); -+ iounmap(mdev->mbox_base); - kfree(privblk); - kfree(mboxblk); - kfree(list); -+ kfree(mdev); - - return 0; - } -@@ -334,6 +548,7 @@ static struct platform_driver omap2_mbox - .remove = omap2_mbox_remove, - .driver = { - .name = "omap-mailbox", -+ .of_match_table = omap_mailbox_of_match, - }, - }; - ---- a/drivers/mailbox/omap-mailbox.c -+++ b/drivers/mailbox/omap-mailbox.c -@@ -24,7 +24,6 @@ - #include <linux/interrupt.h> - #include <linux/spinlock.h> - #include <linux/mutex.h> --#include <linux/delay.h> - #include <linux/slab.h> - #include <linux/kfifo.h> - #include <linux/err.h> -@@ -33,16 +32,16 @@ - - #include "omap-mbox.h" - --static struct omap_mbox **mboxes; -- --static int mbox_configured; --static DEFINE_MUTEX(mbox_configured_lock); -+/* global variables for the mailbox devices */ -+static DEFINE_MUTEX(omap_mbox_devices_lock); -+static LIST_HEAD(omap_mbox_devices); - -+/* default size for the fifos, configured through kernel menuconfig */ - static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE; - module_param(mbox_kfifo_size, uint, S_IRUGO); - MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)"); - --/* Mailbox FIFO handle functions */ -+/* mailbox h/w transport communication handler helper functions */ - static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) - { - return mbox->ops->fifo_read(mbox); -@@ -55,12 +54,16 @@ static inline int mbox_fifo_empty(struct - { - return mbox->ops->fifo_empty(mbox); - } --static inline int mbox_fifo_full(struct omap_mbox *mbox) -+/* -+ * local helper to check if the h/w transport is busy or free. -+ * Returns 0 if free, and non-zero otherwise -+ */ -+static inline int mbox_poll_for_space(struct omap_mbox *mbox) - { -- return mbox->ops->fifo_full(mbox); -+ return mbox->ops->poll_for_space(mbox); - } - --/* Mailbox IRQ handle functions */ -+/* mailbox h/w irq handler helper functions */ - static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) - { - if (mbox->ops->ack_irq) -@@ -71,23 +74,21 @@ static inline int is_mbox_irq(struct oma - return mbox->ops->is_irq(mbox, irq); - } - --/* -- * message sender -+/** -+ * omap_mbox_msg_send() - send a mailbox message -+ * @mbox: handle to the acquired mailbox on which to send the message -+ * @msg: the mailbox message to be sent -+ * -+ * This API is called by a client user to send a mailbox message on an -+ * acquired mailbox. The API transmits the message immediately on the h/w -+ * communication transport if it is available, otherwise buffers the -+ * message for transmission as soon as the h/w transport is ready. -+ * -+ * The only failure from this function is when neither the h/w transport -+ * is available nor the s/w buffer fifo is empty. -+ * -+ * Returns 0 on success, or an error otherwise - */ --static int __mbox_poll_for_space(struct omap_mbox *mbox) --{ -- int ret = 0, i = 1000; -- -- while (mbox_fifo_full(mbox)) { -- if (mbox->ops->type == OMAP_MBOX_TYPE2) -- return -1; -- if (--i == 0) -- return -1; -- udelay(1); -- } -- return ret; --} -- - int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) - { - struct omap_mbox_queue *mq = mbox->txq; -@@ -100,7 +101,7 @@ int omap_mbox_msg_send(struct omap_mbox - goto out; - } - -- if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) { -+ if (kfifo_is_empty(&mq->fifo) && !mbox_poll_for_space(mbox)) { - mbox_fifo_write(mbox, msg); - goto out; - } -@@ -116,6 +117,17 @@ out: - } - EXPORT_SYMBOL(omap_mbox_msg_send); - -+/** -+ * omap_mbox_save_ctx: save the context of a mailbox -+ * @mbox: handle to the acquired mailbox -+ * -+ * This allows a client (controlling a remote) to request a mailbox to -+ * save its context when it is powering down the remote. -+ * -+ * NOTE: This will be eventually deprecated, new clients should not use this. -+ * The same feature can be enabled through runtime_pm enablement of -+ * mailbox. -+ */ - void omap_mbox_save_ctx(struct omap_mbox *mbox) - { - if (!mbox->ops->save_ctx) { -@@ -127,6 +139,18 @@ void omap_mbox_save_ctx(struct omap_mbox - } - EXPORT_SYMBOL(omap_mbox_save_ctx); - -+/** -+ * omap_mbox_restore_ctx: restore the context of a mailbox -+ * @mbox: handle to the acquired mailbox -+ * -+ * This allows a client (controlling a remote) to request a mailbox to -+ * restore its context after restoring the remote, so that it can -+ * communicate with the remote as it would normally. -+ * -+ * NOTE: This will be deprecated, new clients should not use this. -+ * The same feature can be enabled through runtime_pm enablement -+ * of mailbox. -+ */ - void omap_mbox_restore_ctx(struct omap_mbox *mbox) - { - if (!mbox->ops->restore_ctx) { -@@ -138,18 +162,48 @@ void omap_mbox_restore_ctx(struct omap_m - } - EXPORT_SYMBOL(omap_mbox_restore_ctx); - -+/** -+ * omap_mbox_enable_irq: enable a specific mailbox Rx or Tx interrupt source -+ * @mbox: handle to the acquired mailbox -+ * @irq: interrupt type associated with either the Rx or Tx -+ * -+ * This allows a client (having its own shared memory communication protocol -+ * with the remote) to request a mailbox to enable a particular interrupt -+ * signal source of the mailbox, as part of its communication state machine. -+ * -+ * NOTE: This will be deprecated, new clients should not use this. It is -+ * being exported for TI DSP/Bridge driver. -+ */ - void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) - { - mbox->ops->enable_irq(mbox, irq); - } - EXPORT_SYMBOL(omap_mbox_enable_irq); - -+/** -+ * omap_mbox_disable_irq: disable a specific mailbox Rx or Tx interrupt source -+ * @mbox: handle to the acquired mailbox -+ * @irq: interrupt type associated with either the Rx or Tx -+ * -+ * This allows a client (having its own shared memory communication protocal -+ * with the remote) to request a mailbox to disable a particular interrupt -+ * signal source of the mailbox, as part of its communication state machine. -+ * -+ * NOTE: This will be deprecated, new clients should not use this. It is -+ * being exported for TI DSP/Bridge driver. -+ */ - void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) - { - mbox->ops->disable_irq(mbox, irq); - } - EXPORT_SYMBOL(omap_mbox_disable_irq); - -+/* -+ * This is the tasklet function in which all the buffered messages are -+ * sent until the h/w transport is busy again. The tasklet is scheduled -+ * upon receiving an interrupt indicating the availability of the h/w -+ * transport. -+ */ - static void mbox_tx_tasklet(unsigned long tx_data) - { - struct omap_mbox *mbox = (struct omap_mbox *)tx_data; -@@ -158,7 +212,7 @@ static void mbox_tx_tasklet(unsigned lon - int ret; - - while (kfifo_len(&mq->fifo)) { -- if (__mbox_poll_for_space(mbox)) { -+ if (mbox_poll_for_space(mbox)) { - omap_mbox_enable_irq(mbox, IRQ_TX); - break; - } -@@ -172,7 +226,12 @@ static void mbox_tx_tasklet(unsigned lon - } - - /* -- * Message receiver(workqueue) -+ * This is the message receiver workqueue function, which is responsible -+ * for delivering all the received messages stored in the receive kfifo -+ * to the clients. Each message is delivered to all the registered mailbox -+ * clients. It also re-enables the receive interrupt on the mailbox (disabled -+ * when the s/w kfifo is full) after emptying atleast a message from the -+ * fifo. - */ - static void mbox_rx_work(struct work_struct *work) - { -@@ -197,7 +256,9 @@ static void mbox_rx_work(struct work_str - } - - /* -- * Mailbox interrupt handler -+ * Interrupt handler for Tx interrupt source for each of the mailboxes. -+ * This schedules the tasklet to transmit the messages buffered in the -+ * Tx fifo. - */ - static void __mbox_tx_interrupt(struct omap_mbox *mbox) - { -@@ -206,6 +267,12 @@ static void __mbox_tx_interrupt(struct o - tasklet_schedule(&mbox->txq->tasklet); - } - -+/* -+ * Interrupt handler for Rx interrupt source for each of the mailboxes. -+ * This performs the read from the h/w mailbox until the transport is -+ * free of any incoming messages, and buffers the read message. The -+ * buffers are delivered to clients by scheduling a work-queue. -+ */ - static void __mbox_rx_interrupt(struct omap_mbox *mbox) - { - struct omap_mbox_queue *mq = mbox->rxq; -@@ -223,9 +290,6 @@ static void __mbox_rx_interrupt(struct o - - len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); - WARN_ON(len != sizeof(msg)); -- -- if (mbox->ops->type == OMAP_MBOX_TYPE1) -- break; - } - - /* no more messages in the fifo. clear IRQ source. */ -@@ -234,6 +298,10 @@ nomem: - schedule_work(&mbox->rxq->work); - } - -+/* -+ * The core mailbox interrupt handler function. The interrupt core would -+ * call this for each of the mailboxes the interrupt is configured. -+ */ - static irqreturn_t mbox_interrupt(int irq, void *p) - { - struct omap_mbox *mbox = p; -@@ -247,6 +315,12 @@ static irqreturn_t mbox_interrupt(int ir - return IRQ_HANDLED; - } - -+/* -+ * Helper function to allocate a mailbox queue object. This function -+ * also creates either or both of the work-queue or tasklet to -+ * deal with processing of messages on the kfifo associated with -+ * the mailbox queue object. -+ */ - static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox, - void (*work) (struct work_struct *), - void (*tasklet)(unsigned long)) -@@ -273,24 +347,31 @@ error: - return NULL; - } - -+/* -+ * Helper function to free a mailbox queue object. -+ */ - static void mbox_queue_free(struct omap_mbox_queue *q) - { - kfifo_free(&q->fifo); - kfree(q); - } - -+/* -+ * Helper function to initialize a mailbox. This function creates -+ * the mailbox queue objects associated with the mailbox h/w channel -+ * and plugs-in the interrupt associated with the mailbox, when the -+ * mailbox h/w channel is requested for the first time. -+ */ - static int omap_mbox_startup(struct omap_mbox *mbox) - { - int ret = 0; - struct omap_mbox_queue *mq; -+ struct omap_mbox_device *mdev = mbox->parent; - -- mutex_lock(&mbox_configured_lock); -- if (!mbox_configured++) { -- if (likely(mbox->ops->startup)) { -- ret = mbox->ops->startup(mbox); -- if (unlikely(ret)) -- goto fail_startup; -- } else -+ mutex_lock(&mdev->cfg_lock); -+ if (mbox->ops->startup) { -+ ret = mbox->ops->startup(mbox); -+ if (ret) - goto fail_startup; - } - -@@ -319,7 +400,7 @@ static int omap_mbox_startup(struct omap - - omap_mbox_enable_irq(mbox, IRQ_RX); - } -- mutex_unlock(&mbox_configured_lock); -+ mutex_unlock(&mdev->cfg_lock); - return 0; - - fail_request_irq: -@@ -331,14 +412,18 @@ fail_alloc_txq: - mbox->ops->shutdown(mbox); - mbox->use_count--; - fail_startup: -- mbox_configured--; -- mutex_unlock(&mbox_configured_lock); -+ mutex_unlock(&mdev->cfg_lock); - return ret; - } - -+/* -+ * Helper function to de-initialize a mailbox -+ */ - static void omap_mbox_fini(struct omap_mbox *mbox) - { -- mutex_lock(&mbox_configured_lock); -+ struct omap_mbox_device *mdev = mbox->parent; -+ -+ mutex_lock(&mdev->cfg_lock); - - if (!--mbox->use_count) { - omap_mbox_disable_irq(mbox, IRQ_RX); -@@ -349,28 +434,66 @@ static void omap_mbox_fini(struct omap_m - mbox_queue_free(mbox->rxq); - } - -- if (likely(mbox->ops->shutdown)) { -- if (!--mbox_configured) -- mbox->ops->shutdown(mbox); -- } -+ if (mbox->ops->shutdown) -+ mbox->ops->shutdown(mbox); - -- mutex_unlock(&mbox_configured_lock); -+ mutex_unlock(&mdev->cfg_lock); - } - --struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb) -+/* -+ * Helper function to find a mailbox. It is currently assumed that all the -+ * mailbox names are unique among all the mailbox devices. This can be -+ * easily extended if only a particular mailbox device is to searched. -+ */ -+static struct omap_mbox *omap_mbox_device_find(struct omap_mbox_device *mdev, -+ const char *mbox_name) - { - struct omap_mbox *_mbox, *mbox = NULL; -- int i, ret; -+ struct omap_mbox **mboxes = mdev->mboxes; -+ int i; - - if (!mboxes) -- return ERR_PTR(-EINVAL); -+ return NULL; - - for (i = 0; (_mbox = mboxes[i]); i++) { -- if (!strcmp(_mbox->name, name)) { -+ if (!strcmp(_mbox->name, mbox_name)) { - mbox = _mbox; - break; - } - } -+ return mbox; -+} -+ -+/** -+ * omap_mbox_get() - acquire a mailbox -+ * @name: name of the mailbox to acquire -+ * @nb: notifier block to be invoked on received messages -+ * -+ * This API is called by a client user to use a mailbox. The returned handle -+ * needs to be used by the client for invoking any other mailbox API. Any -+ * message received on the mailbox is delivered to the client through the -+ * 'nb' notifier. There are currently no restrictions on multiple clients -+ * acquiring the same mailbox - the same message is delivered to each of the -+ * clients through their respective notifiers. -+ * -+ * The function ensures that the mailbox is put into an operational state -+ * before the function returns. -+ * -+ * Returns a usable mailbox handle on success, or NULL otherwise -+ */ -+struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb) -+{ -+ struct omap_mbox *mbox = NULL; -+ struct omap_mbox_device *mdev; -+ int ret; -+ -+ mutex_lock(&omap_mbox_devices_lock); -+ list_for_each_entry(mdev, &omap_mbox_devices, elem) { -+ mbox = omap_mbox_device_find(mdev, name); -+ if (mbox) -+ break; -+ } -+ mutex_unlock(&omap_mbox_devices_lock); - - if (!mbox) - return ERR_PTR(-ENOENT); -@@ -388,6 +511,18 @@ struct omap_mbox *omap_mbox_get(const ch - } - EXPORT_SYMBOL(omap_mbox_get); - -+/** -+ * omap_mbox_put() - release a mailbox -+ * @mbox: handle to the acquired mailbox -+ * @nb: notifier block used while acquiring the mailbox -+ * -+ * This API is to be called by a client user once it is done using the -+ * mailbox. The particular user's notifier function is removed from the -+ * notifier list of received messages on this mailbox. It also undoes -+ * any h/w configuration done during the acquisition of the mailbox. -+ * -+ * No return value -+ */ - void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb) - { - blocking_notifier_chain_unregister(&mbox->notifier, nb); -@@ -397,19 +532,35 @@ EXPORT_SYMBOL(omap_mbox_put); - - static struct class omap_mbox_class = { .name = "mbox", }; - --int omap_mbox_register(struct device *parent, struct omap_mbox **list) -+/** -+ * omap_mbox_register() - register the list of mailboxes -+ * @mdev: mailbox device handle containing the mailboxes that need to be -+ * with the mailbox core -+ * -+ * This API is to be called by individual mailbox driver implementations -+ * for registering the set of mailboxes contained in a h/w communication -+ * block with the mailbox core. Each of the mailbox represents a h/w -+ * communication channel, contained within the h/w communication block or ip. -+ * -+ * An associated device is also created for each of the mailboxes, and the -+ * mailbox device is added to a global list of registered mailbox devices. -+ * -+ * Return 0 on success, or a failure code otherwise -+ */ -+int omap_mbox_register(struct omap_mbox_device *mdev) - { - int ret; - int i; -+ struct omap_mbox **mboxes; - -- mboxes = list; -- if (!mboxes) -+ if (!mdev || !mdev->mboxes) - return -EINVAL; - -+ mboxes = mdev->mboxes; - for (i = 0; mboxes[i]; i++) { - struct omap_mbox *mbox = mboxes[i]; - mbox->dev = device_create(&omap_mbox_class, -- parent, 0, mbox, "%s", mbox->name); -+ mdev->dev, 0, mbox, "%s", mbox->name); - if (IS_ERR(mbox->dev)) { - ret = PTR_ERR(mbox->dev); - goto err_out; -@@ -417,6 +568,11 @@ int omap_mbox_register(struct device *pa - - BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier); - } -+ -+ mutex_lock(&omap_mbox_devices_lock); -+ list_add(&mdev->elem, &omap_mbox_devices); -+ mutex_unlock(&omap_mbox_devices_lock); -+ - return 0; - - err_out: -@@ -426,16 +582,33 @@ err_out: - } - EXPORT_SYMBOL(omap_mbox_register); - --int omap_mbox_unregister(void) -+/** -+ * omap_mbox_unregister() - unregister the list of mailboxes -+ * @mdev: parent mailbox device handle containing the mailboxes that need -+ * to be unregistered -+ * -+ * This API is to be called by individual mailbox driver implementations -+ * for unregistering the set of mailboxes contained in a h/w communication -+ * block. Once unregistered, these mailboxes are not available for any -+ * client users/drivers. -+ * -+ * Return 0 on success, or a failure code otherwise -+ */ -+int omap_mbox_unregister(struct omap_mbox_device *mdev) - { - int i; -+ struct omap_mbox **mboxes; - -- if (!mboxes) -+ if (!mdev || !mdev->mboxes) - return -EINVAL; - -+ mutex_lock(&omap_mbox_devices_lock); -+ list_del(&mdev->elem); -+ mutex_unlock(&omap_mbox_devices_lock); -+ -+ mboxes = mdev->mboxes; - for (i = 0; mboxes[i]; i++) - device_unregister(mboxes[i]->dev); -- mboxes = NULL; - return 0; - } - EXPORT_SYMBOL(omap_mbox_unregister); ---- a/drivers/mailbox/omap-mbox.h -+++ b/drivers/mailbox/omap-mbox.h -@@ -16,19 +16,58 @@ - #include <linux/workqueue.h> - #include <linux/omap-mailbox.h> - --typedef int __bitwise omap_mbox_type_t; --#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1) --#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2) -- -+/** -+ * struct omap_mbox_ops - function ops specific to a mailbox implementation -+ * @startup: the startup function, essential for making the mailbox active. -+ * This will be called when a client acquires the mailbox. The driver -+ * implementation needs to take care of any refcounting if the same -+ * mailbox is requested by multiple clients. -+ * @shutdown: the shutdown function, essential for making the mailbox inactive -+ * after usage. This will be called when a client releases the -+ * mailbox. The driver implementation needs to take care of any -+ * refcounting if the same mailbox is requested by multiple clients. -+ * @fifo_read: read and return the h/w transport payload message. This hook -+ * provides the omap mailbox core to read all the available messages -+ * upon a Rx interrupt and buffer them. The messages are delivered -+ * to the clients in a workqueue. -+ * @fifo_write: send a mailbox message packet on the h/w transport channel. The -+ * individual drivers are responsible for configuring the h/w -+ * accordingly. -+ * @fifo_empty: check if the h/w Rx transport has more messages. The function -+ * should return 0 if there are no more messages to be read from -+ * the transport, and non-zero if there are available messages. -+ * @poll_for_space: check if the h/w Tx transport is busy. This hook should -+ * return non-zero if the h/w Tx transport is busy, and 0 when -+ * the h/w communication channel is free. -+ * @enable_irq: This hook allows the mailbox core to allow a specific Rx or Tx -+ * interrupt signal to interrupt the processor, based on its state -+ * machine. -+ * @disable_irq: This hooks allows the mailbox core to disable a specific Rx or -+ * Tx interrupt signal from interrupting the processor, based on -+ * its state machine. -+ * @ack_irq: acknowledge the Tx or Rx interrupt signal internal to the mailbox. -+ * This allows the h/w communication block to clear any internal -+ * interrupt source status registers. -+ * @is_irq: check if a particular Tx or Rx interrupt signal on the corresponding -+ * mailbox is set. This hook is used by the mailbox core to process the -+ * interrupt accordingly. -+ * @save_ctx: Called by a client or the mailbox core to allow the individual -+ * driver implementation to save the context of the mailbox registers -+ * before the domain containing the h/w communication block can be -+ * put into a low-power state. -+ * @restore_ctx: Called by a client or the mailbox core to allow the individual -+ * driver implementation to restore the context of the mailbox -+ * registers after the domain containing the h/w communication block -+ * is powered back to active state. -+ */ - struct omap_mbox_ops { -- omap_mbox_type_t type; - int (*startup)(struct omap_mbox *mbox); - void (*shutdown)(struct omap_mbox *mbox); -- /* fifo */ -+ /* mailbox access */ - mbox_msg_t (*fifo_read)(struct omap_mbox *mbox); - void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg); - int (*fifo_empty)(struct omap_mbox *mbox); -- int (*fifo_full)(struct omap_mbox *mbox); -+ int (*poll_for_space)(struct omap_mbox *mbox); - /* irq */ - void (*enable_irq)(struct omap_mbox *mbox, - omap_mbox_irq_t irq); -@@ -36,11 +75,28 @@ struct omap_mbox_ops { - omap_mbox_irq_t irq); - void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq); - int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq); -- /* ctx */ -+ /* context */ - void (*save_ctx)(struct omap_mbox *mbox); - void (*restore_ctx)(struct omap_mbox *mbox); - }; - -+/** -+ * struct omap_mbox_queue - A queue object used for buffering messages -+ * @lock: a spinlock providing synchronization in atomic context -+ * @fifo: a kfifo object for buffering the messages. The size of the kfifo is -+ * is currently configured either at build time using kernel menu -+ * configuration or at runtime through a module parameter. The usage of -+ * the kfifo depends on whether the queue object is for Rx or Tx. For Tx, -+ * a message is buffered into the kfifo if the h/w transport is busy, and -+ * is taken out when the h/w signals Tx readiness. For Rx, the messages -+ * are buffered into the kfifo in the bottom-half processing of a Rx -+ * interrupt, and taken out during the top-half processing. -+ * @work: a workqueue object for scheduling top-half processing of rx messages -+ * @tasklet: a tasklet object for processing tx messages in an atomic context -+ * @mbox: reference to the containing parent mailbox -+ * full: indicates the status of the fifo, and is set to true when there is no -+ * room in the fifo. -+ */ - struct omap_mbox_queue { - spinlock_t lock; - struct kfifo fifo; -@@ -50,18 +106,65 @@ struct omap_mbox_queue { - bool full; - }; - -+/** -+ * struct omap_mbox_device - device structure for storing h/w mailbox block -+ * @dev: reference device pointer of the h/w mailbox block -+ * @cfg_lock: a configuration mutex lock used for protecting the mailbox -+ * device configuration operations -+ * @mbox_base: ioremapped base address of the h/w mailbox block -+ * @num_users: number of output interrupts from the h/w mailbox block, multiple -+ * interrupts can be routed to a particular processor sub-system -+ * @num_fifos: number of individual h/w fifo queues supported within a h/w -+ * mailbox block -+ * @mboxes: array of containing mailboxes within the h/w mailbox block -+ * @elem: list node -+ */ -+struct omap_mbox_device { -+ struct device *dev; -+ struct mutex cfg_lock; -+ void __iomem *mbox_base; -+ u32 num_users; -+ u32 num_fifos; -+ struct omap_mbox **mboxes; -+ struct list_head elem; -+}; -+ -+/** -+ * struct omap_mbox - the base object describing a h/w communication channel. -+ * there can be more than one object in a h/w communication block -+ * @name: a unique name for the mailbox object. Client users acquire a -+ * mailbox object using this name -+ * @irq: IRQ number that the mailbox uses to interrupt the host processor. -+ * the same IRQ number may be shared between different mailboxes -+ * @txq: the mailbox queue object pertaining to Tx -+ * @rxq: the mailbox queue object pertaining to Rx -+ * @ops: function ops specific to the mailbox -+ * @dev: the device pointer representing the mailbox object -+ * @parent: back reference to the containing parent mailbox device object -+ * @priv: a private structure specific to the driver implementation, this will -+ * not be touched by the mailbox core -+ * @use_count: number of current references to the mailbox, useful in -+ * controlling the mailbox state -+ * @notifier: notifier chain of clients, to which a received message is -+ * communicated -+ */ - struct omap_mbox { - const char *name; - unsigned int irq; - struct omap_mbox_queue *txq, *rxq; - struct omap_mbox_ops *ops; - struct device *dev; -+ struct omap_mbox_device *parent; - void *priv; - int use_count; - struct blocking_notifier_head notifier; - }; - --int omap_mbox_register(struct device *parent, struct omap_mbox **); --int omap_mbox_unregister(void); -+/* -+ * mailbox objects registration and de-registration functions with the -+ * mailbox core. -+ */ -+int omap_mbox_register(struct omap_mbox_device *device); -+int omap_mbox_unregister(struct omap_mbox_device *device); - - #endif /* OMAP_MBOX_H */ ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -8,6 +8,8 @@ - obj-y += irqchip/ - obj-y += bus/ - -+obj-$(CONFIG_GENERIC_PHY) += phy/ -+ - # GPIO must come after pinctrl as gpios may need to mux pins etc - obj-y += pinctrl/ - obj-y += gpio/ ---- a/drivers/media/platform/Kconfig -+++ b/drivers/media/platform/Kconfig -@@ -220,6 +220,22 @@ config VIDEO_RENESAS_VSP1 - To compile this driver as a module, choose M here: the module - will be called vsp1. - -+config VIDEO_TI_VPE -+ tristate "TI VPE (Video Processing Engine) driver" -+ depends on VIDEO_DEV && VIDEO_V4L2 && SOC_DRA7XX -+ select VIDEOBUF2_DMA_CONTIG -+ select V4L2_MEM2MEM_DEV -+ default n -+ ---help--- -+ Support for the TI VPE(Video Processing Engine) block -+ found on DRA7XX SoC. -+ -+config VIDEO_TI_VPE_DEBUG -+ bool "VPE debug messages" -+ depends on VIDEO_TI_VPE -+ ---help--- -+ Enable debug messages on VPE driver. -+ - endif # V4L_MEM2MEM_DRIVERS - - menuconfig V4L_TEST_DRIVERS ---- a/drivers/media/platform/Makefile -+++ b/drivers/media/platform/Makefile -@@ -22,6 +22,8 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o - - obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o - -+obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe/ -+ - obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o - obj-$(CONFIG_VIDEO_CODA) += coda.o - ---- /dev/null -+++ b/drivers/media/platform/ti-vpe/Makefile -@@ -0,0 +1,5 @@ -+obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o -+ -+ti-vpe-y := vpe.o vpdma.o -+ -+ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG ---- /dev/null -+++ b/drivers/media/platform/ti-vpe/vpdma.c -@@ -0,0 +1,846 @@ -+/* -+ * VPDMA helper library -+ * -+ * Copyright (c) 2013 Texas Instruments Inc. -+ * -+ * David Griego, <dagriego@biglakesoftware.com> -+ * Dale Farnsworth, <dale@farnsworth.org> -+ * Archit Taneja, <archit@ti.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ */ -+ -+#include <linux/delay.h> -+#include <linux/dma-mapping.h> -+#include <linux/err.h> -+#include <linux/firmware.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/sched.h> -+#include <linux/slab.h> -+#include <linux/videodev2.h> -+ -+#include "vpdma.h" -+#include "vpdma_priv.h" -+ -+#define VPDMA_FIRMWARE "vpdma-1b8.bin" -+ -+const struct vpdma_data_format vpdma_yuv_fmts[] = { -+ [VPDMA_DATA_FMT_Y444] = { -+ .data_type = DATA_TYPE_Y444, -+ .depth = 8, -+ }, -+ [VPDMA_DATA_FMT_Y422] = { -+ .data_type = DATA_TYPE_Y422, -+ .depth = 8, -+ }, -+ [VPDMA_DATA_FMT_Y420] = { -+ .data_type = DATA_TYPE_Y420, -+ .depth = 8, -+ }, -+ [VPDMA_DATA_FMT_C444] = { -+ .data_type = DATA_TYPE_C444, -+ .depth = 8, -+ }, -+ [VPDMA_DATA_FMT_C422] = { -+ .data_type = DATA_TYPE_C422, -+ .depth = 8, -+ }, -+ [VPDMA_DATA_FMT_C420] = { -+ .data_type = DATA_TYPE_C420, -+ .depth = 4, -+ }, -+ [VPDMA_DATA_FMT_YC422] = { -+ .data_type = DATA_TYPE_YC422, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_YC444] = { -+ .data_type = DATA_TYPE_YC444, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_CY422] = { -+ .data_type = DATA_TYPE_CY422, -+ .depth = 16, -+ }, -+}; -+ -+const struct vpdma_data_format vpdma_rgb_fmts[] = { -+ [VPDMA_DATA_FMT_RGB565] = { -+ .data_type = DATA_TYPE_RGB16_565, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_ARGB16_1555] = { -+ .data_type = DATA_TYPE_ARGB_1555, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_ARGB16] = { -+ .data_type = DATA_TYPE_ARGB_4444, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_RGBA16_5551] = { -+ .data_type = DATA_TYPE_RGBA_5551, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_RGBA16] = { -+ .data_type = DATA_TYPE_RGBA_4444, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_ARGB24] = { -+ .data_type = DATA_TYPE_ARGB24_6666, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_RGB24] = { -+ .data_type = DATA_TYPE_RGB24_888, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_ARGB32] = { -+ .data_type = DATA_TYPE_ARGB32_8888, -+ .depth = 32, -+ }, -+ [VPDMA_DATA_FMT_RGBA24] = { -+ .data_type = DATA_TYPE_RGBA24_6666, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_RGBA32] = { -+ .data_type = DATA_TYPE_RGBA32_8888, -+ .depth = 32, -+ }, -+ [VPDMA_DATA_FMT_BGR565] = { -+ .data_type = DATA_TYPE_BGR16_565, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_ABGR16_1555] = { -+ .data_type = DATA_TYPE_ABGR_1555, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_ABGR16] = { -+ .data_type = DATA_TYPE_ABGR_4444, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_BGRA16_5551] = { -+ .data_type = DATA_TYPE_BGRA_5551, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_BGRA16] = { -+ .data_type = DATA_TYPE_BGRA_4444, -+ .depth = 16, -+ }, -+ [VPDMA_DATA_FMT_ABGR24] = { -+ .data_type = DATA_TYPE_ABGR24_6666, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_BGR24] = { -+ .data_type = DATA_TYPE_BGR24_888, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_ABGR32] = { -+ .data_type = DATA_TYPE_ABGR32_8888, -+ .depth = 32, -+ }, -+ [VPDMA_DATA_FMT_BGRA24] = { -+ .data_type = DATA_TYPE_BGRA24_6666, -+ .depth = 24, -+ }, -+ [VPDMA_DATA_FMT_BGRA32] = { -+ .data_type = DATA_TYPE_BGRA32_8888, -+ .depth = 32, -+ }, -+}; -+ -+const struct vpdma_data_format vpdma_misc_fmts[] = { -+ [VPDMA_DATA_FMT_MV] = { -+ .data_type = DATA_TYPE_MV, -+ .depth = 4, -+ }, -+}; -+ -+struct vpdma_channel_info { -+ int num; /* VPDMA channel number */ -+ int cstat_offset; /* client CSTAT register offset */ -+}; -+ -+static const struct vpdma_channel_info chan_info[] = { -+ [VPE_CHAN_LUMA1_IN] = { -+ .num = VPE_CHAN_NUM_LUMA1_IN, -+ .cstat_offset = VPDMA_DEI_LUMA1_CSTAT, -+ }, -+ [VPE_CHAN_CHROMA1_IN] = { -+ .num = VPE_CHAN_NUM_CHROMA1_IN, -+ .cstat_offset = VPDMA_DEI_CHROMA1_CSTAT, -+ }, -+ [VPE_CHAN_LUMA2_IN] = { -+ .num = VPE_CHAN_NUM_LUMA2_IN, -+ .cstat_offset = VPDMA_DEI_LUMA2_CSTAT, -+ }, -+ [VPE_CHAN_CHROMA2_IN] = { -+ .num = VPE_CHAN_NUM_CHROMA2_IN, -+ .cstat_offset = VPDMA_DEI_CHROMA2_CSTAT, -+ }, -+ [VPE_CHAN_LUMA3_IN] = { -+ .num = VPE_CHAN_NUM_LUMA3_IN, -+ .cstat_offset = VPDMA_DEI_LUMA3_CSTAT, -+ }, -+ [VPE_CHAN_CHROMA3_IN] = { -+ .num = VPE_CHAN_NUM_CHROMA3_IN, -+ .cstat_offset = VPDMA_DEI_CHROMA3_CSTAT, -+ }, -+ [VPE_CHAN_MV_IN] = { -+ .num = VPE_CHAN_NUM_MV_IN, -+ .cstat_offset = VPDMA_DEI_MV_IN_CSTAT, -+ }, -+ [VPE_CHAN_MV_OUT] = { -+ .num = VPE_CHAN_NUM_MV_OUT, -+ .cstat_offset = VPDMA_DEI_MV_OUT_CSTAT, -+ }, -+ [VPE_CHAN_LUMA_OUT] = { -+ .num = VPE_CHAN_NUM_LUMA_OUT, -+ .cstat_offset = VPDMA_VIP_UP_Y_CSTAT, -+ }, -+ [VPE_CHAN_CHROMA_OUT] = { -+ .num = VPE_CHAN_NUM_CHROMA_OUT, -+ .cstat_offset = VPDMA_VIP_UP_UV_CSTAT, -+ }, -+ [VPE_CHAN_RGB_OUT] = { -+ .num = VPE_CHAN_NUM_RGB_OUT, -+ .cstat_offset = VPDMA_VIP_UP_Y_CSTAT, -+ }, -+}; -+ -+static u32 read_reg(struct vpdma_data *vpdma, int offset) -+{ -+ return ioread32(vpdma->base + offset); -+} -+ -+static void write_reg(struct vpdma_data *vpdma, int offset, u32 value) -+{ -+ iowrite32(value, vpdma->base + offset); -+} -+ -+static int read_field_reg(struct vpdma_data *vpdma, int offset, -+ u32 mask, int shift) -+{ -+ return (read_reg(vpdma, offset) & (mask << shift)) >> shift; -+} -+ -+static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field, -+ u32 mask, int shift) -+{ -+ u32 val = read_reg(vpdma, offset); -+ -+ val &= ~(mask << shift); -+ val |= (field & mask) << shift; -+ -+ write_reg(vpdma, offset, val); -+} -+ -+void vpdma_dump_regs(struct vpdma_data *vpdma) -+{ -+ struct device *dev = &vpdma->pdev->dev; -+ -+#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r)) -+ -+ dev_dbg(dev, "VPDMA Registers:\n"); -+ -+ DUMPREG(PID); -+ DUMPREG(LIST_ADDR); -+ DUMPREG(LIST_ATTR); -+ DUMPREG(LIST_STAT_SYNC); -+ DUMPREG(BG_RGB); -+ DUMPREG(BG_YUV); -+ DUMPREG(SETUP); -+ DUMPREG(MAX_SIZE1); -+ DUMPREG(MAX_SIZE2); -+ DUMPREG(MAX_SIZE3); -+ -+ /* -+ * dumping registers of only group0 and group3, because VPE channels -+ * lie within group0 and group3 registers -+ */ -+ DUMPREG(INT_CHAN_STAT(0)); -+ DUMPREG(INT_CHAN_MASK(0)); -+ DUMPREG(INT_CHAN_STAT(3)); -+ DUMPREG(INT_CHAN_MASK(3)); -+ DUMPREG(INT_CLIENT0_STAT); -+ DUMPREG(INT_CLIENT0_MASK); -+ DUMPREG(INT_CLIENT1_STAT); -+ DUMPREG(INT_CLIENT1_MASK); -+ DUMPREG(INT_LIST0_STAT); -+ DUMPREG(INT_LIST0_MASK); -+ -+ /* -+ * these are registers specific to VPE clients, we can make this -+ * function dump client registers specific to VPE or VIP based on -+ * who is using it -+ */ -+ DUMPREG(DEI_CHROMA1_CSTAT); -+ DUMPREG(DEI_LUMA1_CSTAT); -+ DUMPREG(DEI_CHROMA2_CSTAT); -+ DUMPREG(DEI_LUMA2_CSTAT); -+ DUMPREG(DEI_CHROMA3_CSTAT); -+ DUMPREG(DEI_LUMA3_CSTAT); -+ DUMPREG(DEI_MV_IN_CSTAT); -+ DUMPREG(DEI_MV_OUT_CSTAT); -+ DUMPREG(VIP_UP_Y_CSTAT); -+ DUMPREG(VIP_UP_UV_CSTAT); -+ DUMPREG(VPI_CTL_CSTAT); -+} -+ -+/* -+ * Allocate a DMA buffer -+ */ -+int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size) -+{ -+ buf->size = size; -+ buf->mapped = false; -+ buf->addr = kzalloc(size, GFP_KERNEL); -+ if (!buf->addr) -+ return -ENOMEM; -+ -+ WARN_ON((u32) buf->addr & VPDMA_DESC_ALIGN); -+ -+ return 0; -+} -+ -+void vpdma_free_desc_buf(struct vpdma_buf *buf) -+{ -+ WARN_ON(buf->mapped); -+ kfree(buf->addr); -+ buf->addr = NULL; -+ buf->size = 0; -+} -+ -+/* -+ * map descriptor/payload DMA buffer, enabling DMA access -+ */ -+int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) -+{ -+ struct device *dev = &vpdma->pdev->dev; -+ -+ WARN_ON(buf->mapped); -+ buf->dma_addr = dma_map_single(dev, buf->addr, buf->size, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, buf->dma_addr)) { -+ dev_err(dev, "failed to map buffer\n"); -+ return -EINVAL; -+ } -+ -+ buf->mapped = true; -+ -+ return 0; -+} -+ -+/* -+ * unmap descriptor/payload DMA buffer, disabling DMA access and -+ * allowing the main processor to acces the data -+ */ -+void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf) -+{ -+ struct device *dev = &vpdma->pdev->dev; -+ -+ if (buf->mapped) -+ dma_unmap_single(dev, buf->dma_addr, buf->size, DMA_TO_DEVICE); -+ -+ buf->mapped = false; -+} -+ -+/* -+ * create a descriptor list, the user of this list will append configuration, -+ * control and data descriptors to this list, this list will be submitted to -+ * VPDMA. VPDMA's list parser will go through each descriptor and perform the -+ * required DMA operations -+ */ -+int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type) -+{ -+ int r; -+ -+ r = vpdma_alloc_desc_buf(&list->buf, size); -+ if (r) -+ return r; -+ -+ list->next = list->buf.addr; -+ -+ list->type = type; -+ -+ return 0; -+} -+ -+/* -+ * once a descriptor list is parsed by VPDMA, we reset the list by emptying it, -+ * to allow new descriptors to be added to the list. -+ */ -+void vpdma_reset_desc_list(struct vpdma_desc_list *list) -+{ -+ list->next = list->buf.addr; -+} -+ -+/* -+ * free the buffer allocated fot the VPDMA descriptor list, this should be -+ * called when the user doesn't want to use VPDMA any more. -+ */ -+void vpdma_free_desc_list(struct vpdma_desc_list *list) -+{ -+ vpdma_free_desc_buf(&list->buf); -+ -+ list->next = NULL; -+} -+ -+static bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num) -+{ -+ return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16); -+} -+ -+/* -+ * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion -+ */ -+int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list) -+{ -+ /* we always use the first list */ -+ int list_num = 0; -+ int list_size; -+ -+ if (vpdma_list_busy(vpdma, list_num)) -+ return -EBUSY; -+ -+ /* 16-byte granularity */ -+ list_size = (list->next - list->buf.addr) >> 4; -+ -+ write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr); -+ -+ write_reg(vpdma, VPDMA_LIST_ATTR, -+ (list_num << VPDMA_LIST_NUM_SHFT) | -+ (list->type << VPDMA_LIST_TYPE_SHFT) | -+ list_size); -+ -+ return 0; -+} -+ -+static void dump_cfd(struct vpdma_cfd *cfd) -+{ -+ int class; -+ -+ class = cfd_get_class(cfd); -+ -+ pr_debug("config descriptor of payload class: %s\n", -+ class == CFD_CLS_BLOCK ? "simple block" : -+ "address data block"); -+ -+ if (class == CFD_CLS_BLOCK) -+ pr_debug("word0: dst_addr_offset = 0x%08x\n", -+ cfd->dest_addr_offset); -+ -+ if (class == CFD_CLS_BLOCK) -+ pr_debug("word1: num_data_wrds = %d\n", cfd->block_len); -+ -+ pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr); -+ -+ pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, " -+ "payload_len = %d\n", cfd_get_pkt_type(cfd), -+ cfd_get_direct(cfd), class, cfd_get_dest(cfd), -+ cfd_get_payload_len(cfd)); -+} -+ -+/* -+ * append a configuration descriptor to the given descriptor list, where the -+ * payload is in the form of a simple data block specified in the descriptor -+ * header, this is used to upload scaler coefficients to the scaler module -+ */ -+void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, -+ struct vpdma_buf *blk, u32 dest_offset) -+{ -+ struct vpdma_cfd *cfd; -+ int len = blk->size; -+ -+ WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN); -+ -+ cfd = list->next; -+ WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size)); -+ -+ cfd->dest_addr_offset = dest_offset; -+ cfd->block_len = len; -+ cfd->payload_addr = (u32) blk->dma_addr; -+ cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK, -+ client, len >> 4); -+ -+ list->next = cfd + 1; -+ -+ dump_cfd(cfd); -+} -+ -+/* -+ * append a configuration descriptor to the given descriptor list, where the -+ * payload is in the address data block format, this is used to a configure a -+ * discontiguous set of MMRs -+ */ -+void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, -+ struct vpdma_buf *adb) -+{ -+ struct vpdma_cfd *cfd; -+ unsigned int len = adb->size; -+ -+ WARN_ON(len & VPDMA_ADB_SIZE_ALIGN); -+ WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN); -+ -+ cfd = list->next; -+ BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size)); -+ -+ cfd->w0 = 0; -+ cfd->w1 = 0; -+ cfd->payload_addr = (u32) adb->dma_addr; -+ cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB, -+ client, len >> 4); -+ -+ list->next = cfd + 1; -+ -+ dump_cfd(cfd); -+}; -+ -+/* -+ * control descriptor format change based on what type of control descriptor it -+ * is, we only use 'sync on channel' control descriptors for now, so assume it's -+ * that -+ */ -+static void dump_ctd(struct vpdma_ctd *ctd) -+{ -+ pr_debug("control descriptor\n"); -+ -+ pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n", -+ ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd)); -+} -+ -+/* -+ * append a 'sync on channel' type control descriptor to the given descriptor -+ * list, this descriptor stalls the VPDMA list till the time DMA is completed -+ * on the specified channel -+ */ -+void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, -+ enum vpdma_channel chan) -+{ -+ struct vpdma_ctd *ctd; -+ -+ ctd = list->next; -+ WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size)); -+ -+ ctd->w0 = 0; -+ ctd->w1 = 0; -+ ctd->w2 = 0; -+ ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num, -+ CTD_TYPE_SYNC_ON_CHANNEL); -+ -+ list->next = ctd + 1; -+ -+ dump_ctd(ctd); -+} -+ -+static void dump_dtd(struct vpdma_dtd *dtd) -+{ -+ int dir, chan; -+ -+ dir = dtd_get_dir(dtd); -+ chan = dtd_get_chan(dtd); -+ -+ pr_debug("%s data transfer descriptor for channel %d\n", -+ dir == DTD_DIR_OUT ? "outbound" : "inbound", chan); -+ -+ pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, " -+ "even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n", -+ dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd), -+ dtd_get_1d(dtd), dtd_get_even_line_skip(dtd), -+ dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd)); -+ -+ if (dir == DTD_DIR_IN) -+ pr_debug("word1: line_length = %d, xfer_height = %d\n", -+ dtd_get_line_length(dtd), dtd_get_xfer_height(dtd)); -+ -+ pr_debug("word2: start_addr = 0x%08x\n", dtd->start_addr); -+ -+ pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, " -+ "pri = %d, next_chan = %d\n", dtd_get_pkt_type(dtd), -+ dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd), -+ dtd_get_next_chan(dtd)); -+ -+ if (dir == DTD_DIR_IN) -+ pr_debug("word4: frame_width = %d, frame_height = %d\n", -+ dtd_get_frame_width(dtd), dtd_get_frame_height(dtd)); -+ else -+ pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, " -+ "drp_data = %d, use_desc_reg = %d\n", -+ dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd), -+ dtd_get_drop_data(dtd), dtd_get_use_desc(dtd)); -+ -+ if (dir == DTD_DIR_IN) -+ pr_debug("word5: hor_start = %d, ver_start = %d\n", -+ dtd_get_h_start(dtd), dtd_get_v_start(dtd)); -+ else -+ pr_debug("word5: max_width %d, max_height %d\n", -+ dtd_get_max_width(dtd), dtd_get_max_height(dtd)); -+ -+ pr_debug("word6: client specfic attr0 = 0x%08x\n", dtd->client_attr0); -+ pr_debug("word7: client specfic attr1 = 0x%08x\n", dtd->client_attr1); -+} -+ -+/* -+ * append an outbound data transfer descriptor to the given descriptor list, -+ * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel -+ */ -+void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, -+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr, -+ enum vpdma_channel chan, u32 flags) -+{ -+ int priority = 0; -+ int field = 0; -+ int notify = 1; -+ int channel, next_chan; -+ int depth = fmt->depth; -+ int stride; -+ struct vpdma_dtd *dtd; -+ -+ channel = next_chan = chan_info[chan].num; -+ -+ if (fmt->data_type == DATA_TYPE_C420) -+ depth = 8; -+ -+ stride = (depth * c_rect->width) >> 3; -+ dma_addr += (c_rect->left * depth) >> 3; -+ -+ dtd = list->next; -+ WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); -+ -+ dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type, -+ notify, -+ field, -+ !!(flags & VPDMA_DATA_FRAME_1D), -+ !!(flags & VPDMA_DATA_EVEN_LINE_SKIP), -+ !!(flags & VPDMA_DATA_ODD_LINE_SKIP), -+ stride); -+ dtd->w1 = 0; -+ dtd->start_addr = (u32) dma_addr; -+ dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), -+ DTD_DIR_OUT, channel, priority, next_chan); -+ dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0); -+ dtd->max_width_height = dtd_max_width_height(MAX_OUT_WIDTH_1920, -+ MAX_OUT_HEIGHT_1080); -+ dtd->client_attr0 = 0; -+ dtd->client_attr1 = 0; -+ -+ list->next = dtd + 1; -+ -+ dump_dtd(dtd); -+} -+ -+/* -+ * append an inbound data transfer descriptor to the given descriptor list, -+ * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel -+ */ -+void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, -+ int frame_height, struct v4l2_rect *c_rect, -+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr, -+ enum vpdma_channel chan, int field, u32 flags) -+{ -+ int priority = 0; -+ int notify = 1; -+ int depth = fmt->depth; -+ int channel, next_chan; -+ int stride; -+ int height = c_rect->height; -+ struct vpdma_dtd *dtd; -+ -+ channel = next_chan = chan_info[chan].num; -+ -+ if (fmt->data_type == DATA_TYPE_C420) { -+ height >>= 1; -+ frame_height >>= 1; -+ depth = 8; -+ } -+ -+ stride = (depth * c_rect->width) >> 3; -+ dma_addr += (c_rect->left * depth) >> 3; -+ -+ dtd = list->next; -+ WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); -+ -+ dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type, -+ notify, -+ field, -+ !!(flags & VPDMA_DATA_FRAME_1D), -+ !!(flags & VPDMA_DATA_EVEN_LINE_SKIP), -+ !!(flags & VPDMA_DATA_ODD_LINE_SKIP), -+ stride); -+ -+ dtd->xfer_length_height = dtd_xfer_length_height(c_rect->width, height); -+ dtd->start_addr = (u32) dma_addr; -+ dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), -+ DTD_DIR_IN, channel, priority, next_chan); -+ dtd->frame_width_height = dtd_frame_width_height(frame_width, -+ frame_height); -+ dtd->start_h_v = dtd_start_h_v(c_rect->left, c_rect->top); -+ dtd->client_attr0 = 0; -+ dtd->client_attr1 = 0; -+ -+ list->next = dtd + 1; -+ -+ dump_dtd(dtd); -+} -+ -+/* set or clear the mask for list complete interrupt */ -+void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, -+ bool enable) -+{ -+ u32 val; -+ -+ val = read_reg(vpdma, VPDMA_INT_LIST0_MASK); -+ if (enable) -+ val |= (1 << (list_num * 2)); -+ else -+ val &= ~(1 << (list_num * 2)); -+ write_reg(vpdma, VPDMA_INT_LIST0_MASK, val); -+} -+ -+/* clear previosuly occured list intterupts in the LIST_STAT register */ -+void vpdma_clear_list_stat(struct vpdma_data *vpdma) -+{ -+ write_reg(vpdma, VPDMA_INT_LIST0_STAT, -+ read_reg(vpdma, VPDMA_INT_LIST0_STAT)); -+} -+ -+/* -+ * configures the output mode of the line buffer for the given client, the -+ * line buffer content can either be mirrored(each line repeated twice) or -+ * passed to the client as is -+ */ -+void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, -+ enum vpdma_channel chan) -+{ -+ int client_cstat = chan_info[chan].cstat_offset; -+ -+ write_field_reg(vpdma, client_cstat, line_mode, -+ VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT); -+} -+ -+/* -+ * configures the event which should trigger VPDMA transfer for the given -+ * client -+ */ -+void vpdma_set_frame_start_event(struct vpdma_data *vpdma, -+ enum vpdma_frame_start_event fs_event, -+ enum vpdma_channel chan) -+{ -+ int client_cstat = chan_info[chan].cstat_offset; -+ -+ write_field_reg(vpdma, client_cstat, fs_event, -+ VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT); -+} -+ -+static void vpdma_firmware_cb(const struct firmware *f, void *context) -+{ -+ struct vpdma_data *vpdma = context; -+ struct vpdma_buf fw_dma_buf; -+ int i, r; -+ -+ dev_dbg(&vpdma->pdev->dev, "firmware callback\n"); -+ -+ if (!f || !f->data) { -+ dev_err(&vpdma->pdev->dev, "couldn't get firmware\n"); -+ return; -+ } -+ -+ /* already initialized */ -+ if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK, -+ VPDMA_LIST_RDY_SHFT)) { -+ vpdma->ready = true; -+ return; -+ } -+ -+ r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size); -+ if (r) { -+ dev_err(&vpdma->pdev->dev, -+ "failed to allocate dma buffer for firmware\n"); -+ goto rel_fw; -+ } -+ -+ memcpy(fw_dma_buf.addr, f->data, f->size); -+ -+ vpdma_map_desc_buf(vpdma, &fw_dma_buf); -+ -+ write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr); -+ -+ for (i = 0; i < 100; i++) { /* max 1 second */ -+ msleep_interruptible(10); -+ -+ if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK, -+ VPDMA_LIST_RDY_SHFT)) -+ break; -+ } -+ -+ if (i == 100) { -+ dev_err(&vpdma->pdev->dev, "firmware upload failed\n"); -+ goto free_buf; -+ } -+ -+ vpdma->ready = true; -+ -+free_buf: -+ vpdma_unmap_desc_buf(vpdma, &fw_dma_buf); -+ -+ vpdma_free_desc_buf(&fw_dma_buf); -+rel_fw: -+ release_firmware(f); -+} -+ -+static int vpdma_load_firmware(struct vpdma_data *vpdma) -+{ -+ int r; -+ struct device *dev = &vpdma->pdev->dev; -+ -+ r = request_firmware_nowait(THIS_MODULE, 1, -+ (const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma, -+ vpdma_firmware_cb); -+ if (r) { -+ dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE); -+ return r; -+ } else { -+ dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE); -+ } -+ -+ return 0; -+} -+ -+struct vpdma_data *vpdma_create(struct platform_device *pdev) -+{ -+ struct resource *res; -+ struct vpdma_data *vpdma; -+ int r; -+ -+ dev_dbg(&pdev->dev, "vpdma_create\n"); -+ -+ vpdma = devm_kzalloc(&pdev->dev, sizeof(*vpdma), GFP_KERNEL); -+ if (!vpdma) { -+ dev_err(&pdev->dev, "couldn't alloc vpdma_dev\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ vpdma->pdev = pdev; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma"); -+ if (res == NULL) { -+ dev_err(&pdev->dev, "missing platform resources data\n"); -+ return ERR_PTR(-ENODEV); -+ } -+ -+ vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); -+ if (!vpdma->base) { -+ dev_err(&pdev->dev, "failed to ioremap\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ r = vpdma_load_firmware(vpdma); -+ if (r) { -+ pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE); -+ return ERR_PTR(r); -+ } -+ -+ return vpdma; -+} -+MODULE_FIRMWARE(VPDMA_FIRMWARE); ---- /dev/null -+++ b/drivers/media/platform/ti-vpe/vpdma.h -@@ -0,0 +1,203 @@ -+/* -+ * Copyright (c) 2013 Texas Instruments Inc. -+ * -+ * David Griego, <dagriego@biglakesoftware.com> -+ * Dale Farnsworth, <dale@farnsworth.org> -+ * Archit Taneja, <archit@ti.com> -+ * -+ * 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. -+ */ -+ -+#ifndef __TI_VPDMA_H_ -+#define __TI_VPDMA_H_ -+ -+/* -+ * A vpdma_buf tracks the size, DMA address and mapping status of each -+ * driver DMA area. -+ */ -+struct vpdma_buf { -+ void *addr; -+ dma_addr_t dma_addr; -+ size_t size; -+ bool mapped; -+}; -+ -+struct vpdma_desc_list { -+ struct vpdma_buf buf; -+ void *next; -+ int type; -+}; -+ -+struct vpdma_data { -+ void __iomem *base; -+ -+ struct platform_device *pdev; -+ -+ /* tells whether vpdma firmware is loaded or not */ -+ bool ready; -+}; -+ -+struct vpdma_data_format { -+ int data_type; -+ u8 depth; -+}; -+ -+#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */ -+ -+#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */ -+#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */ -+ -+#define VPDMA_LIST_TYPE_NORMAL 0 -+#define VPDMA_LIST_TYPE_SELF_MODIFYING 1 -+#define VPDMA_LIST_TYPE_DOORBELL 2 -+ -+enum vpdma_yuv_formats { -+ VPDMA_DATA_FMT_Y444 = 0, -+ VPDMA_DATA_FMT_Y422, -+ VPDMA_DATA_FMT_Y420, -+ VPDMA_DATA_FMT_C444, -+ VPDMA_DATA_FMT_C422, -+ VPDMA_DATA_FMT_C420, -+ VPDMA_DATA_FMT_YC422, -+ VPDMA_DATA_FMT_YC444, -+ VPDMA_DATA_FMT_CY422, -+}; -+ -+enum vpdma_rgb_formats { -+ VPDMA_DATA_FMT_RGB565 = 0, -+ VPDMA_DATA_FMT_ARGB16_1555, -+ VPDMA_DATA_FMT_ARGB16, -+ VPDMA_DATA_FMT_RGBA16_5551, -+ VPDMA_DATA_FMT_RGBA16, -+ VPDMA_DATA_FMT_ARGB24, -+ VPDMA_DATA_FMT_RGB24, -+ VPDMA_DATA_FMT_ARGB32, -+ VPDMA_DATA_FMT_RGBA24, -+ VPDMA_DATA_FMT_RGBA32, -+ VPDMA_DATA_FMT_BGR565, -+ VPDMA_DATA_FMT_ABGR16_1555, -+ VPDMA_DATA_FMT_ABGR16, -+ VPDMA_DATA_FMT_BGRA16_5551, -+ VPDMA_DATA_FMT_BGRA16, -+ VPDMA_DATA_FMT_ABGR24, -+ VPDMA_DATA_FMT_BGR24, -+ VPDMA_DATA_FMT_ABGR32, -+ VPDMA_DATA_FMT_BGRA24, -+ VPDMA_DATA_FMT_BGRA32, -+}; -+ -+enum vpdma_misc_formats { -+ VPDMA_DATA_FMT_MV = 0, -+}; -+ -+extern const struct vpdma_data_format vpdma_yuv_fmts[]; -+extern const struct vpdma_data_format vpdma_rgb_fmts[]; -+extern const struct vpdma_data_format vpdma_misc_fmts[]; -+ -+enum vpdma_frame_start_event { -+ VPDMA_FSEVENT_HDMI_FID = 0, -+ VPDMA_FSEVENT_DVO2_FID, -+ VPDMA_FSEVENT_HDCOMP_FID, -+ VPDMA_FSEVENT_SD_FID, -+ VPDMA_FSEVENT_LM_FID0, -+ VPDMA_FSEVENT_LM_FID1, -+ VPDMA_FSEVENT_LM_FID2, -+ VPDMA_FSEVENT_CHANNEL_ACTIVE, -+}; -+ -+/* -+ * VPDMA channel numbers -+ */ -+enum vpdma_channel { -+ VPE_CHAN_LUMA1_IN, -+ VPE_CHAN_CHROMA1_IN, -+ VPE_CHAN_LUMA2_IN, -+ VPE_CHAN_CHROMA2_IN, -+ VPE_CHAN_LUMA3_IN, -+ VPE_CHAN_CHROMA3_IN, -+ VPE_CHAN_MV_IN, -+ VPE_CHAN_MV_OUT, -+ VPE_CHAN_LUMA_OUT, -+ VPE_CHAN_CHROMA_OUT, -+ VPE_CHAN_RGB_OUT, -+}; -+ -+/* flags for VPDMA data descriptors */ -+#define VPDMA_DATA_ODD_LINE_SKIP (1 << 0) -+#define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1) -+#define VPDMA_DATA_FRAME_1D (1 << 2) -+#define VPDMA_DATA_MODE_TILED (1 << 3) -+ -+/* -+ * client identifiers used for configuration descriptors -+ */ -+#define CFD_MMR_CLIENT 0 -+#define CFD_SC_CLIENT 4 -+ -+/* Address data block header format */ -+struct vpdma_adb_hdr { -+ u32 offset; -+ u32 nwords; -+ u32 reserved0; -+ u32 reserved1; -+}; -+ -+/* helpers for creating ADB headers for config descriptors MMRs as client */ -+#define ADB_ADDR(dma_buf, str, fld) ((dma_buf)->addr + offsetof(str, fld)) -+#define MMR_ADB_ADDR(buf, str, fld) ADB_ADDR(&(buf), struct str, fld) -+ -+#define VPDMA_SET_MMR_ADB_HDR(buf, str, hdr, regs, offset_a) \ -+ do { \ -+ struct vpdma_adb_hdr *h; \ -+ struct str *adb = NULL; \ -+ h = MMR_ADB_ADDR(buf, str, hdr); \ -+ h->offset = (offset_a); \ -+ h->nwords = sizeof(adb->regs) >> 2; \ -+ } while (0) -+ -+/* vpdma descriptor buffer allocation and management */ -+int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size); -+void vpdma_free_desc_buf(struct vpdma_buf *buf); -+int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf); -+void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf); -+ -+/* vpdma descriptor list funcs */ -+int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type); -+void vpdma_reset_desc_list(struct vpdma_desc_list *list); -+void vpdma_free_desc_list(struct vpdma_desc_list *list); -+int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list); -+ -+/* helpers for creating vpdma descriptors */ -+void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client, -+ struct vpdma_buf *blk, u32 dest_offset); -+void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, -+ struct vpdma_buf *adb); -+void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, -+ enum vpdma_channel chan); -+void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, -+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr, -+ enum vpdma_channel chan, u32 flags); -+void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, -+ int frame_height, struct v4l2_rect *c_rect, -+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr, -+ enum vpdma_channel chan, int field, u32 flags); -+ -+/* vpdma list interrupt management */ -+void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, -+ bool enable); -+void vpdma_clear_list_stat(struct vpdma_data *vpdma); -+ -+/* vpdma client configuration */ -+void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode, -+ enum vpdma_channel chan); -+void vpdma_set_frame_start_event(struct vpdma_data *vpdma, -+ enum vpdma_frame_start_event fs_event, enum vpdma_channel chan); -+ -+void vpdma_dump_regs(struct vpdma_data *vpdma); -+ -+/* initialize vpdma, passed with VPE's platform device pointer */ -+struct vpdma_data *vpdma_create(struct platform_device *pdev); -+ -+#endif ---- /dev/null -+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h -@@ -0,0 +1,641 @@ -+/* -+ * Copyright (c) 2013 Texas Instruments Inc. -+ * -+ * David Griego, <dagriego@biglakesoftware.com> -+ * Dale Farnsworth, <dale@farnsworth.org> -+ * Archit Taneja, <archit@ti.com> -+ * -+ * 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. -+ */ -+ -+#ifndef _TI_VPDMA_PRIV_H_ -+#define _TI_VPDMA_PRIV_H_ -+ -+/* -+ * VPDMA Register offsets -+ */ -+ -+/* Top level */ -+#define VPDMA_PID 0x00 -+#define VPDMA_LIST_ADDR 0x04 -+#define VPDMA_LIST_ATTR 0x08 -+#define VPDMA_LIST_STAT_SYNC 0x0c -+#define VPDMA_BG_RGB 0x18 -+#define VPDMA_BG_YUV 0x1c -+#define VPDMA_SETUP 0x30 -+#define VPDMA_MAX_SIZE1 0x34 -+#define VPDMA_MAX_SIZE2 0x38 -+#define VPDMA_MAX_SIZE3 0x3c -+ -+/* Interrupts */ -+#define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8) -+#define VPDMA_INT_CHAN_MASK(grp) (VPDMA_INT_CHAN_STAT(grp) + 4) -+#define VPDMA_INT_CLIENT0_STAT 0x78 -+#define VPDMA_INT_CLIENT0_MASK 0x7c -+#define VPDMA_INT_CLIENT1_STAT 0x80 -+#define VPDMA_INT_CLIENT1_MASK 0x84 -+#define VPDMA_INT_LIST0_STAT 0x88 -+#define VPDMA_INT_LIST0_MASK 0x8c -+ -+#define VPDMA_PERFMON(i) (0x200 + i * 4) -+ -+/* VPE specific client registers */ -+#define VPDMA_DEI_CHROMA1_CSTAT 0x0300 -+#define VPDMA_DEI_LUMA1_CSTAT 0x0304 -+#define VPDMA_DEI_LUMA2_CSTAT 0x0308 -+#define VPDMA_DEI_CHROMA2_CSTAT 0x030c -+#define VPDMA_DEI_LUMA3_CSTAT 0x0310 -+#define VPDMA_DEI_CHROMA3_CSTAT 0x0314 -+#define VPDMA_DEI_MV_IN_CSTAT 0x0330 -+#define VPDMA_DEI_MV_OUT_CSTAT 0x033c -+#define VPDMA_VIP_UP_Y_CSTAT 0x0390 -+#define VPDMA_VIP_UP_UV_CSTAT 0x0394 -+#define VPDMA_VPI_CTL_CSTAT 0x03d0 -+ -+/* Reg field info for VPDMA_CLIENT_CSTAT registers */ -+#define VPDMA_CSTAT_LINE_MODE_MASK 0x03 -+#define VPDMA_CSTAT_LINE_MODE_SHIFT 8 -+#define VPDMA_CSTAT_FRAME_START_MASK 0xf -+#define VPDMA_CSTAT_FRAME_START_SHIFT 10 -+ -+#define VPDMA_LIST_NUM_MASK 0x07 -+#define VPDMA_LIST_NUM_SHFT 24 -+#define VPDMA_LIST_STOP_SHFT 20 -+#define VPDMA_LIST_RDY_MASK 0x01 -+#define VPDMA_LIST_RDY_SHFT 19 -+#define VPDMA_LIST_TYPE_MASK 0x03 -+#define VPDMA_LIST_TYPE_SHFT 16 -+#define VPDMA_LIST_SIZE_MASK 0xffff -+ -+/* VPDMA data type values for data formats */ -+#define DATA_TYPE_Y444 0x0 -+#define DATA_TYPE_Y422 0x1 -+#define DATA_TYPE_Y420 0x2 -+#define DATA_TYPE_C444 0x4 -+#define DATA_TYPE_C422 0x5 -+#define DATA_TYPE_C420 0x6 -+#define DATA_TYPE_YC422 0x7 -+#define DATA_TYPE_YC444 0x8 -+#define DATA_TYPE_CY422 0x23 -+ -+#define DATA_TYPE_RGB16_565 0x0 -+#define DATA_TYPE_ARGB_1555 0x1 -+#define DATA_TYPE_ARGB_4444 0x2 -+#define DATA_TYPE_RGBA_5551 0x3 -+#define DATA_TYPE_RGBA_4444 0x4 -+#define DATA_TYPE_ARGB24_6666 0x5 -+#define DATA_TYPE_RGB24_888 0x6 -+#define DATA_TYPE_ARGB32_8888 0x7 -+#define DATA_TYPE_RGBA24_6666 0x8 -+#define DATA_TYPE_RGBA32_8888 0x9 -+#define DATA_TYPE_BGR16_565 0x10 -+#define DATA_TYPE_ABGR_1555 0x11 -+#define DATA_TYPE_ABGR_4444 0x12 -+#define DATA_TYPE_BGRA_5551 0x13 -+#define DATA_TYPE_BGRA_4444 0x14 -+#define DATA_TYPE_ABGR24_6666 0x15 -+#define DATA_TYPE_BGR24_888 0x16 -+#define DATA_TYPE_ABGR32_8888 0x17 -+#define DATA_TYPE_BGRA24_6666 0x18 -+#define DATA_TYPE_BGRA32_8888 0x19 -+ -+#define DATA_TYPE_MV 0x3 -+ -+/* VPDMA channel numbers(only VPE channels for now) */ -+#define VPE_CHAN_NUM_LUMA1_IN 0 -+#define VPE_CHAN_NUM_CHROMA1_IN 1 -+#define VPE_CHAN_NUM_LUMA2_IN 2 -+#define VPE_CHAN_NUM_CHROMA2_IN 3 -+#define VPE_CHAN_NUM_LUMA3_IN 4 -+#define VPE_CHAN_NUM_CHROMA3_IN 5 -+#define VPE_CHAN_NUM_MV_IN 12 -+#define VPE_CHAN_NUM_MV_OUT 15 -+#define VPE_CHAN_NUM_LUMA_OUT 102 -+#define VPE_CHAN_NUM_CHROMA_OUT 103 -+#define VPE_CHAN_NUM_RGB_OUT 106 -+ -+/* -+ * a VPDMA address data block payload for a configuration descriptor needs to -+ * have each sub block length as a multiple of 16 bytes. Therefore, the overall -+ * size of the payload also needs to be a multiple of 16 bytes. The sub block -+ * lengths should be ensured to be aligned by the VPDMA user. -+ */ -+#define VPDMA_ADB_SIZE_ALIGN 0x0f -+ -+/* -+ * data transfer descriptor -+ */ -+struct vpdma_dtd { -+ u32 type_ctl_stride; -+ union { -+ u32 xfer_length_height; -+ u32 w1; -+ }; -+ dma_addr_t start_addr; -+ u32 pkt_ctl; -+ union { -+ u32 frame_width_height; /* inbound */ -+ dma_addr_t desc_write_addr; /* outbound */ -+ }; -+ union { -+ u32 start_h_v; /* inbound */ -+ u32 max_width_height; /* outbound */ -+ }; -+ u32 client_attr0; -+ u32 client_attr1; -+}; -+ -+/* Data Transfer Descriptor specifics */ -+#define DTD_NO_NOTIFY 0 -+#define DTD_NOTIFY 1 -+ -+#define DTD_PKT_TYPE 0xa -+#define DTD_DIR_IN 0 -+#define DTD_DIR_OUT 1 -+ -+/* type_ctl_stride */ -+#define DTD_DATA_TYPE_MASK 0x3f -+#define DTD_DATA_TYPE_SHFT 26 -+#define DTD_NOTIFY_MASK 0x01 -+#define DTD_NOTIFY_SHFT 25 -+#define DTD_FIELD_MASK 0x01 -+#define DTD_FIELD_SHFT 24 -+#define DTD_1D_MASK 0x01 -+#define DTD_1D_SHFT 23 -+#define DTD_EVEN_LINE_SKIP_MASK 0x01 -+#define DTD_EVEN_LINE_SKIP_SHFT 20 -+#define DTD_ODD_LINE_SKIP_MASK 0x01 -+#define DTD_ODD_LINE_SKIP_SHFT 16 -+#define DTD_LINE_STRIDE_MASK 0xffff -+#define DTD_LINE_STRIDE_SHFT 0 -+ -+/* xfer_length_height */ -+#define DTD_LINE_LENGTH_MASK 0xffff -+#define DTD_LINE_LENGTH_SHFT 16 -+#define DTD_XFER_HEIGHT_MASK 0xffff -+#define DTD_XFER_HEIGHT_SHFT 0 -+ -+/* pkt_ctl */ -+#define DTD_PKT_TYPE_MASK 0x1f -+#define DTD_PKT_TYPE_SHFT 27 -+#define DTD_MODE_MASK 0x01 -+#define DTD_MODE_SHFT 26 -+#define DTD_DIR_MASK 0x01 -+#define DTD_DIR_SHFT 25 -+#define DTD_CHAN_MASK 0x01ff -+#define DTD_CHAN_SHFT 16 -+#define DTD_PRI_MASK 0x0f -+#define DTD_PRI_SHFT 9 -+#define DTD_NEXT_CHAN_MASK 0x01ff -+#define DTD_NEXT_CHAN_SHFT 0 -+ -+/* frame_width_height */ -+#define DTD_FRAME_WIDTH_MASK 0xffff -+#define DTD_FRAME_WIDTH_SHFT 16 -+#define DTD_FRAME_HEIGHT_MASK 0xffff -+#define DTD_FRAME_HEIGHT_SHFT 0 -+ -+/* start_h_v */ -+#define DTD_H_START_MASK 0xffff -+#define DTD_H_START_SHFT 16 -+#define DTD_V_START_MASK 0xffff -+#define DTD_V_START_SHFT 0 -+ -+#define DTD_DESC_START_SHIFT 5 -+#define DTD_WRITE_DESC_MASK 0x01 -+#define DTD_WRITE_DESC_SHIFT 2 -+#define DTD_DROP_DATA_MASK 0x01 -+#define DTD_DROP_DATA_SHIFT 1 -+#define DTD_USE_DESC_MASK 0x01 -+#define DTD_USE_DESC_SHIFT 0 -+ -+/* max_width_height */ -+#define DTD_MAX_WIDTH_MASK 0x07 -+#define DTD_MAX_WIDTH_SHFT 4 -+#define DTD_MAX_HEIGHT_MASK 0x07 -+#define DTD_MAX_HEIGHT_SHFT 0 -+ -+/* max width configurations */ -+ /* unlimited width */ -+#define MAX_OUT_WIDTH_UNLIMITED 0 -+/* as specified in max_size1 reg */ -+#define MAX_OUT_WIDTH_REG1 1 -+/* as specified in max_size2 reg */ -+#define MAX_OUT_WIDTH_REG2 2 -+/* as specified in max_size3 reg */ -+#define MAX_OUT_WIDTH_REG3 3 -+/* maximum of 352 pixels as width */ -+#define MAX_OUT_WIDTH_352 4 -+/* maximum of 768 pixels as width */ -+#define MAX_OUT_WIDTH_768 5 -+/* maximum of 1280 pixels width */ -+#define MAX_OUT_WIDTH_1280 6 -+/* maximum of 1920 pixels as width */ -+#define MAX_OUT_WIDTH_1920 7 -+ -+/* max height configurations */ -+ /* unlimited height */ -+#define MAX_OUT_HEIGHT_UNLIMITED 0 -+/* as specified in max_size1 reg */ -+#define MAX_OUT_HEIGHT_REG1 1 -+/* as specified in max_size2 reg */ -+#define MAX_OUT_HEIGHT_REG2 2 -+/* as specified in max_size3 reg */ -+#define MAX_OUT_HEIGHT_REG3 3 -+/* maximum of 288 lines as height */ -+#define MAX_OUT_HEIGHT_288 4 -+/* maximum of 576 lines as height */ -+#define MAX_OUT_HEIGHT_576 5 -+/* maximum of 720 lines as height */ -+#define MAX_OUT_HEIGHT_720 6 -+/* maximum of 1080 lines as height */ -+#define MAX_OUT_HEIGHT_1080 7 -+ -+static inline u32 dtd_type_ctl_stride(int type, bool notify, int field, -+ bool one_d, bool even_line_skip, bool odd_line_skip, -+ int line_stride) -+{ -+ return (type << DTD_DATA_TYPE_SHFT) | (notify << DTD_NOTIFY_SHFT) | -+ (field << DTD_FIELD_SHFT) | (one_d << DTD_1D_SHFT) | -+ (even_line_skip << DTD_EVEN_LINE_SKIP_SHFT) | -+ (odd_line_skip << DTD_ODD_LINE_SKIP_SHFT) | -+ line_stride; -+} -+ -+static inline u32 dtd_xfer_length_height(int line_length, int xfer_height) -+{ -+ return (line_length << DTD_LINE_LENGTH_SHFT) | xfer_height; -+} -+ -+static inline u32 dtd_pkt_ctl(bool mode, bool dir, int chan, int pri, -+ int next_chan) -+{ -+ return (DTD_PKT_TYPE << DTD_PKT_TYPE_SHFT) | (mode << DTD_MODE_SHFT) | -+ (dir << DTD_DIR_SHFT) | (chan << DTD_CHAN_SHFT) | -+ (pri << DTD_PRI_SHFT) | next_chan; -+} -+ -+static inline u32 dtd_frame_width_height(int width, int height) -+{ -+ return (width << DTD_FRAME_WIDTH_SHFT) | height; -+} -+ -+static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc, -+ bool drop_data, bool use_desc) -+{ -+ return (addr << DTD_DESC_START_SHIFT) | -+ (write_desc << DTD_WRITE_DESC_SHIFT) | -+ (drop_data << DTD_DROP_DATA_SHIFT) | -+ use_desc; -+} -+ -+static inline u32 dtd_start_h_v(int h_start, int v_start) -+{ -+ return (h_start << DTD_H_START_SHFT) | v_start; -+} -+ -+static inline u32 dtd_max_width_height(int max_width, int max_height) -+{ -+ return (max_width << DTD_MAX_WIDTH_SHFT) | max_height; -+} -+ -+static inline int dtd_get_data_type(struct vpdma_dtd *dtd) -+{ -+ return dtd->type_ctl_stride >> DTD_DATA_TYPE_SHFT; -+} -+ -+static inline bool dtd_get_notify(struct vpdma_dtd *dtd) -+{ -+ return (dtd->type_ctl_stride >> DTD_NOTIFY_SHFT) & DTD_NOTIFY_MASK; -+} -+ -+static inline int dtd_get_field(struct vpdma_dtd *dtd) -+{ -+ return (dtd->type_ctl_stride >> DTD_FIELD_SHFT) & DTD_FIELD_MASK; -+} -+ -+static inline bool dtd_get_1d(struct vpdma_dtd *dtd) -+{ -+ return (dtd->type_ctl_stride >> DTD_1D_SHFT) & DTD_1D_MASK; -+} -+ -+static inline bool dtd_get_even_line_skip(struct vpdma_dtd *dtd) -+{ -+ return (dtd->type_ctl_stride >> DTD_EVEN_LINE_SKIP_SHFT) -+ & DTD_EVEN_LINE_SKIP_MASK; -+} -+ -+static inline bool dtd_get_odd_line_skip(struct vpdma_dtd *dtd) -+{ -+ return (dtd->type_ctl_stride >> DTD_ODD_LINE_SKIP_SHFT) -+ & DTD_ODD_LINE_SKIP_MASK; -+} -+ -+static inline int dtd_get_line_stride(struct vpdma_dtd *dtd) -+{ -+ return dtd->type_ctl_stride & DTD_LINE_STRIDE_MASK; -+} -+ -+static inline int dtd_get_line_length(struct vpdma_dtd *dtd) -+{ -+ return dtd->xfer_length_height >> DTD_LINE_LENGTH_SHFT; -+} -+ -+static inline int dtd_get_xfer_height(struct vpdma_dtd *dtd) -+{ -+ return dtd->xfer_length_height & DTD_XFER_HEIGHT_MASK; -+} -+ -+static inline int dtd_get_pkt_type(struct vpdma_dtd *dtd) -+{ -+ return dtd->pkt_ctl >> DTD_PKT_TYPE_SHFT; -+} -+ -+static inline bool dtd_get_mode(struct vpdma_dtd *dtd) -+{ -+ return (dtd->pkt_ctl >> DTD_MODE_SHFT) & DTD_MODE_MASK; -+} -+ -+static inline bool dtd_get_dir(struct vpdma_dtd *dtd) -+{ -+ return (dtd->pkt_ctl >> DTD_DIR_SHFT) & DTD_DIR_MASK; -+} -+ -+static inline int dtd_get_chan(struct vpdma_dtd *dtd) -+{ -+ return (dtd->pkt_ctl >> DTD_CHAN_SHFT) & DTD_CHAN_MASK; -+} -+ -+static inline int dtd_get_priority(struct vpdma_dtd *dtd) -+{ -+ return (dtd->pkt_ctl >> DTD_PRI_SHFT) & DTD_PRI_MASK; -+} -+ -+static inline int dtd_get_next_chan(struct vpdma_dtd *dtd) -+{ -+ return (dtd->pkt_ctl >> DTD_NEXT_CHAN_SHFT) & DTD_NEXT_CHAN_MASK; -+} -+ -+static inline int dtd_get_frame_width(struct vpdma_dtd *dtd) -+{ -+ return dtd->frame_width_height >> DTD_FRAME_WIDTH_SHFT; -+} -+ -+static inline int dtd_get_frame_height(struct vpdma_dtd *dtd) -+{ -+ return dtd->frame_width_height & DTD_FRAME_HEIGHT_MASK; -+} -+ -+static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd) -+{ -+ return dtd->desc_write_addr >> DTD_DESC_START_SHIFT; -+} -+ -+static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd) -+{ -+ return (dtd->desc_write_addr >> DTD_WRITE_DESC_SHIFT) & -+ DTD_WRITE_DESC_MASK; -+} -+ -+static inline bool dtd_get_drop_data(struct vpdma_dtd *dtd) -+{ -+ return (dtd->desc_write_addr >> DTD_DROP_DATA_SHIFT) & -+ DTD_DROP_DATA_MASK; -+} -+ -+static inline bool dtd_get_use_desc(struct vpdma_dtd *dtd) -+{ -+ return dtd->desc_write_addr & DTD_USE_DESC_MASK; -+} -+ -+static inline int dtd_get_h_start(struct vpdma_dtd *dtd) -+{ -+ return dtd->start_h_v >> DTD_H_START_SHFT; -+} -+ -+static inline int dtd_get_v_start(struct vpdma_dtd *dtd) -+{ -+ return dtd->start_h_v & DTD_V_START_MASK; -+} -+ -+static inline int dtd_get_max_width(struct vpdma_dtd *dtd) -+{ -+ return (dtd->max_width_height >> DTD_MAX_WIDTH_SHFT) & -+ DTD_MAX_WIDTH_MASK; -+} -+ -+static inline int dtd_get_max_height(struct vpdma_dtd *dtd) -+{ -+ return (dtd->max_width_height >> DTD_MAX_HEIGHT_SHFT) & -+ DTD_MAX_HEIGHT_MASK; -+} -+ -+/* -+ * configuration descriptor -+ */ -+struct vpdma_cfd { -+ union { -+ u32 dest_addr_offset; -+ u32 w0; -+ }; -+ union { -+ u32 block_len; /* in words */ -+ u32 w1; -+ }; -+ u32 payload_addr; -+ u32 ctl_payload_len; /* in words */ -+}; -+ -+/* Configuration descriptor specifics */ -+ -+#define CFD_PKT_TYPE 0xb -+ -+#define CFD_DIRECT 1 -+#define CFD_INDIRECT 0 -+#define CFD_CLS_ADB 0 -+#define CFD_CLS_BLOCK 1 -+ -+/* block_len */ -+#define CFD__BLOCK_LEN_MASK 0xffff -+#define CFD__BLOCK_LEN_SHFT 0 -+ -+/* ctl_payload_len */ -+#define CFD_PKT_TYPE_MASK 0x1f -+#define CFD_PKT_TYPE_SHFT 27 -+#define CFD_DIRECT_MASK 0x01 -+#define CFD_DIRECT_SHFT 26 -+#define CFD_CLASS_MASK 0x03 -+#define CFD_CLASS_SHFT 24 -+#define CFD_DEST_MASK 0xff -+#define CFD_DEST_SHFT 16 -+#define CFD_PAYLOAD_LEN_MASK 0xffff -+#define CFD_PAYLOAD_LEN_SHFT 0 -+ -+static inline u32 cfd_pkt_payload_len(bool direct, int cls, int dest, -+ int payload_len) -+{ -+ return (CFD_PKT_TYPE << CFD_PKT_TYPE_SHFT) | -+ (direct << CFD_DIRECT_SHFT) | -+ (cls << CFD_CLASS_SHFT) | -+ (dest << CFD_DEST_SHFT) | -+ payload_len; -+} -+ -+static inline int cfd_get_pkt_type(struct vpdma_cfd *cfd) -+{ -+ return cfd->ctl_payload_len >> CFD_PKT_TYPE_SHFT; -+} -+ -+static inline bool cfd_get_direct(struct vpdma_cfd *cfd) -+{ -+ return (cfd->ctl_payload_len >> CFD_DIRECT_SHFT) & CFD_DIRECT_MASK; -+} -+ -+static inline bool cfd_get_class(struct vpdma_cfd *cfd) -+{ -+ return (cfd->ctl_payload_len >> CFD_CLASS_SHFT) & CFD_CLASS_MASK; -+} -+ -+static inline int cfd_get_dest(struct vpdma_cfd *cfd) -+{ -+ return (cfd->ctl_payload_len >> CFD_DEST_SHFT) & CFD_DEST_MASK; -+} -+ -+static inline int cfd_get_payload_len(struct vpdma_cfd *cfd) -+{ -+ return cfd->ctl_payload_len & CFD_PAYLOAD_LEN_MASK; -+} -+ -+/* -+ * control descriptor -+ */ -+struct vpdma_ctd { -+ union { -+ u32 timer_value; -+ u32 list_addr; -+ u32 w0; -+ }; -+ union { -+ u32 pixel_line_count; -+ u32 list_size; -+ u32 w1; -+ }; -+ union { -+ u32 event; -+ u32 fid_ctl; -+ u32 w2; -+ }; -+ u32 type_source_ctl; -+}; -+ -+/* control descriptor types */ -+#define CTD_TYPE_SYNC_ON_CLIENT 0 -+#define CTD_TYPE_SYNC_ON_LIST 1 -+#define CTD_TYPE_SYNC_ON_EXT 2 -+#define CTD_TYPE_SYNC_ON_LM_TIMER 3 -+#define CTD_TYPE_SYNC_ON_CHANNEL 4 -+#define CTD_TYPE_CHNG_CLIENT_IRQ 5 -+#define CTD_TYPE_SEND_IRQ 6 -+#define CTD_TYPE_RELOAD_LIST 7 -+#define CTD_TYPE_ABORT_CHANNEL 8 -+ -+#define CTD_PKT_TYPE 0xc -+ -+/* timer_value */ -+#define CTD_TIMER_VALUE_MASK 0xffff -+#define CTD_TIMER_VALUE_SHFT 0 -+ -+/* pixel_line_count */ -+#define CTD_PIXEL_COUNT_MASK 0xffff -+#define CTD_PIXEL_COUNT_SHFT 16 -+#define CTD_LINE_COUNT_MASK 0xffff -+#define CTD_LINE_COUNT_SHFT 0 -+ -+/* list_size */ -+#define CTD_LIST_SIZE_MASK 0xffff -+#define CTD_LIST_SIZE_SHFT 0 -+ -+/* event */ -+#define CTD_EVENT_MASK 0x0f -+#define CTD_EVENT_SHFT 0 -+ -+/* fid_ctl */ -+#define CTD_FID2_MASK 0x03 -+#define CTD_FID2_SHFT 4 -+#define CTD_FID1_MASK 0x03 -+#define CTD_FID1_SHFT 2 -+#define CTD_FID0_MASK 0x03 -+#define CTD_FID0_SHFT 0 -+ -+/* type_source_ctl */ -+#define CTD_PKT_TYPE_MASK 0x1f -+#define CTD_PKT_TYPE_SHFT 27 -+#define CTD_SOURCE_MASK 0xff -+#define CTD_SOURCE_SHFT 16 -+#define CTD_CONTROL_MASK 0x0f -+#define CTD_CONTROL_SHFT 0 -+ -+static inline u32 ctd_pixel_line_count(int pixel_count, int line_count) -+{ -+ return (pixel_count << CTD_PIXEL_COUNT_SHFT) | line_count; -+} -+ -+static inline u32 ctd_set_fid_ctl(int fid0, int fid1, int fid2) -+{ -+ return (fid2 << CTD_FID2_SHFT) | (fid1 << CTD_FID1_SHFT) | fid0; -+} -+ -+static inline u32 ctd_type_source_ctl(int source, int control) -+{ -+ return (CTD_PKT_TYPE << CTD_PKT_TYPE_SHFT) | -+ (source << CTD_SOURCE_SHFT) | control; -+} -+ -+static inline u32 ctd_get_pixel_count(struct vpdma_ctd *ctd) -+{ -+ return ctd->pixel_line_count >> CTD_PIXEL_COUNT_SHFT; -+} -+ -+static inline int ctd_get_line_count(struct vpdma_ctd *ctd) -+{ -+ return ctd->pixel_line_count & CTD_LINE_COUNT_MASK; -+} -+ -+static inline int ctd_get_event(struct vpdma_ctd *ctd) -+{ -+ return ctd->event & CTD_EVENT_MASK; -+} -+ -+static inline int ctd_get_fid2_ctl(struct vpdma_ctd *ctd) -+{ -+ return (ctd->fid_ctl >> CTD_FID2_SHFT) & CTD_FID2_MASK; -+} -+ -+static inline int ctd_get_fid1_ctl(struct vpdma_ctd *ctd) -+{ -+ return (ctd->fid_ctl >> CTD_FID1_SHFT) & CTD_FID1_MASK; -+} -+ -+static inline int ctd_get_fid0_ctl(struct vpdma_ctd *ctd) -+{ -+ return ctd->fid_ctl & CTD_FID2_MASK; -+} -+ -+static inline int ctd_get_pkt_type(struct vpdma_ctd *ctd) -+{ -+ return ctd->type_source_ctl >> CTD_PKT_TYPE_SHFT; -+} -+ -+static inline int ctd_get_source(struct vpdma_ctd *ctd) -+{ -+ return (ctd->type_source_ctl >> CTD_SOURCE_SHFT) & CTD_SOURCE_MASK; -+} -+ -+static inline int ctd_get_ctl(struct vpdma_ctd *ctd) -+{ -+ return ctd->type_source_ctl & CTD_CONTROL_MASK; -+} -+ -+#endif ---- /dev/null -+++ b/drivers/media/platform/ti-vpe/vpe.c -@@ -0,0 +1,2074 @@ -+/* -+ * TI VPE mem2mem driver, based on the virtual v4l2-mem2mem example driver -+ * -+ * Copyright (c) 2013 Texas Instruments Inc. -+ * David Griego, <dagriego@biglakesoftware.com> -+ * Dale Farnsworth, <dale@farnsworth.org> -+ * Archit Taneja, <archit@ti.com> -+ * -+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. -+ * Pawel Osciak, <pawel@osciak.com> -+ * Marek Szyprowski, <m.szyprowski@samsung.com> -+ * -+ * Based on the virtual v4l2-mem2mem example device -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation -+ */ -+ -+#include <linux/delay.h> -+#include <linux/dma-mapping.h> -+#include <linux/err.h> -+#include <linux/fs.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/ioctl.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/sched.h> -+#include <linux/slab.h> -+#include <linux/videodev2.h> -+ -+#include <media/v4l2-common.h> -+#include <media/v4l2-ctrls.h> -+#include <media/v4l2-device.h> -+#include <media/v4l2-event.h> -+#include <media/v4l2-ioctl.h> -+#include <media/v4l2-mem2mem.h> -+#include <media/videobuf2-core.h> -+#include <media/videobuf2-dma-contig.h> -+ -+#include "vpdma.h" -+#include "vpe_regs.h" -+ -+#define VPE_MODULE_NAME "vpe" -+ -+/* minimum and maximum frame sizes */ -+#define MIN_W 128 -+#define MIN_H 128 -+#define MAX_W 1920 -+#define MAX_H 1080 -+ -+/* required alignments */ -+#define S_ALIGN 0 /* multiple of 1 */ -+#define H_ALIGN 1 /* multiple of 2 */ -+#define W_ALIGN 1 /* multiple of 2 */ -+ -+/* multiple of 128 bits, line stride, 16 bytes */ -+#define L_ALIGN 4 -+ -+/* flags that indicate a format can be used for capture/output */ -+#define VPE_FMT_TYPE_CAPTURE (1 << 0) -+#define VPE_FMT_TYPE_OUTPUT (1 << 1) -+ -+/* used as plane indices */ -+#define VPE_MAX_PLANES 2 -+#define VPE_LUMA 0 -+#define VPE_CHROMA 1 -+ -+/* per m2m context info */ -+#define VPE_MAX_SRC_BUFS 3 /* need 3 src fields to de-interlace */ -+ -+#define VPE_DEF_BUFS_PER_JOB 1 /* default one buffer per batch job */ -+ -+/* -+ * each VPE context can need up to 3 config desciptors, 7 input descriptors, -+ * 3 output descriptors, and 10 control descriptors -+ */ -+#define VPE_DESC_LIST_SIZE (10 * VPDMA_DTD_DESC_SIZE + \ -+ 13 * VPDMA_CFD_CTD_DESC_SIZE) -+ -+#define vpe_dbg(vpedev, fmt, arg...) \ -+ dev_dbg((vpedev)->v4l2_dev.dev, fmt, ##arg) -+#define vpe_err(vpedev, fmt, arg...) \ -+ dev_err((vpedev)->v4l2_dev.dev, fmt, ##arg) -+ -+struct vpe_us_coeffs { -+ unsigned short anchor_fid0_c0; -+ unsigned short anchor_fid0_c1; -+ unsigned short anchor_fid0_c2; -+ unsigned short anchor_fid0_c3; -+ unsigned short interp_fid0_c0; -+ unsigned short interp_fid0_c1; -+ unsigned short interp_fid0_c2; -+ unsigned short interp_fid0_c3; -+ unsigned short anchor_fid1_c0; -+ unsigned short anchor_fid1_c1; -+ unsigned short anchor_fid1_c2; -+ unsigned short anchor_fid1_c3; -+ unsigned short interp_fid1_c0; -+ unsigned short interp_fid1_c1; -+ unsigned short interp_fid1_c2; -+ unsigned short interp_fid1_c3; -+}; -+ -+/* -+ * Default upsampler coefficients -+ */ -+static const struct vpe_us_coeffs us_coeffs[] = { -+ { -+ /* Coefficients for progressive input */ -+ 0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8, -+ 0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8, -+ }, -+ { -+ /* Coefficients for Top Field Interlaced input */ -+ 0x0051, 0x03D5, 0x3FE3, 0x3FF7, 0x3FB5, 0x02E9, 0x018F, 0x3FD3, -+ /* Coefficients for Bottom Field Interlaced input */ -+ 0x016B, 0x0247, 0x00B1, 0x3F9D, 0x3FCF, 0x03DB, 0x005D, 0x3FF9, -+ }, -+}; -+ -+/* -+ * the following registers are for configuring some of the parameters of the -+ * motion and edge detection blocks inside DEI, these generally remain the same, -+ * these could be passed later via userspace if some one needs to tweak these. -+ */ -+struct vpe_dei_regs { -+ unsigned long mdt_spacial_freq_thr_reg; /* VPE_DEI_REG2 */ -+ unsigned long edi_config_reg; /* VPE_DEI_REG3 */ -+ unsigned long edi_lut_reg0; /* VPE_DEI_REG4 */ -+ unsigned long edi_lut_reg1; /* VPE_DEI_REG5 */ -+ unsigned long edi_lut_reg2; /* VPE_DEI_REG6 */ -+ unsigned long edi_lut_reg3; /* VPE_DEI_REG7 */ -+}; -+ -+/* -+ * default expert DEI register values, unlikely to be modified. -+ */ -+static const struct vpe_dei_regs dei_regs = { -+ 0x020C0804u, -+ 0x0118100Fu, -+ 0x08040200u, -+ 0x1010100Cu, -+ 0x10101010u, -+ 0x10101010u, -+}; -+ -+/* -+ * The port_data structure contains per-port data. -+ */ -+struct vpe_port_data { -+ enum vpdma_channel channel; /* VPDMA channel */ -+ u8 vb_index; /* input frame f, f-1, f-2 index */ -+ u8 vb_part; /* plane index for co-panar formats */ -+}; -+ -+/* -+ * Define indices into the port_data tables -+ */ -+#define VPE_PORT_LUMA1_IN 0 -+#define VPE_PORT_CHROMA1_IN 1 -+#define VPE_PORT_LUMA2_IN 2 -+#define VPE_PORT_CHROMA2_IN 3 -+#define VPE_PORT_LUMA3_IN 4 -+#define VPE_PORT_CHROMA3_IN 5 -+#define VPE_PORT_MV_IN 6 -+#define VPE_PORT_MV_OUT 7 -+#define VPE_PORT_LUMA_OUT 8 -+#define VPE_PORT_CHROMA_OUT 9 -+#define VPE_PORT_RGB_OUT 10 -+ -+static const struct vpe_port_data port_data[11] = { -+ [VPE_PORT_LUMA1_IN] = { -+ .channel = VPE_CHAN_LUMA1_IN, -+ .vb_index = 0, -+ .vb_part = VPE_LUMA, -+ }, -+ [VPE_PORT_CHROMA1_IN] = { -+ .channel = VPE_CHAN_CHROMA1_IN, -+ .vb_index = 0, -+ .vb_part = VPE_CHROMA, -+ }, -+ [VPE_PORT_LUMA2_IN] = { -+ .channel = VPE_CHAN_LUMA2_IN, -+ .vb_index = 1, -+ .vb_part = VPE_LUMA, -+ }, -+ [VPE_PORT_CHROMA2_IN] = { -+ .channel = VPE_CHAN_CHROMA2_IN, -+ .vb_index = 1, -+ .vb_part = VPE_CHROMA, -+ }, -+ [VPE_PORT_LUMA3_IN] = { -+ .channel = VPE_CHAN_LUMA3_IN, -+ .vb_index = 2, -+ .vb_part = VPE_LUMA, -+ }, -+ [VPE_PORT_CHROMA3_IN] = { -+ .channel = VPE_CHAN_CHROMA3_IN, -+ .vb_index = 2, -+ .vb_part = VPE_CHROMA, -+ }, -+ [VPE_PORT_MV_IN] = { -+ .channel = VPE_CHAN_MV_IN, -+ }, -+ [VPE_PORT_MV_OUT] = { -+ .channel = VPE_CHAN_MV_OUT, -+ }, -+ [VPE_PORT_LUMA_OUT] = { -+ .channel = VPE_CHAN_LUMA_OUT, -+ .vb_part = VPE_LUMA, -+ }, -+ [VPE_PORT_CHROMA_OUT] = { -+ .channel = VPE_CHAN_CHROMA_OUT, -+ .vb_part = VPE_CHROMA, -+ }, -+ [VPE_PORT_RGB_OUT] = { -+ .channel = VPE_CHAN_RGB_OUT, -+ .vb_part = VPE_LUMA, -+ }, -+}; -+ -+ -+/* driver info for each of the supported video formats */ -+struct vpe_fmt { -+ char *name; /* human-readable name */ -+ u32 fourcc; /* standard format identifier */ -+ u8 types; /* CAPTURE and/or OUTPUT */ -+ u8 coplanar; /* set for unpacked Luma and Chroma */ -+ /* vpdma format info for each plane */ -+ struct vpdma_data_format const *vpdma_fmt[VPE_MAX_PLANES]; -+}; -+ -+static struct vpe_fmt vpe_formats[] = { -+ { -+ .name = "YUV 422 co-planar", -+ .fourcc = V4L2_PIX_FMT_NV16, -+ .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, -+ .coplanar = 1, -+ .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y444], -+ &vpdma_yuv_fmts[VPDMA_DATA_FMT_C444], -+ }, -+ }, -+ { -+ .name = "YUV 420 co-planar", -+ .fourcc = V4L2_PIX_FMT_NV12, -+ .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, -+ .coplanar = 1, -+ .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420], -+ &vpdma_yuv_fmts[VPDMA_DATA_FMT_C420], -+ }, -+ }, -+ { -+ .name = "YUYV 422 packed", -+ .fourcc = V4L2_PIX_FMT_YUYV, -+ .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, -+ .coplanar = 0, -+ .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YC422], -+ }, -+ }, -+ { -+ .name = "UYVY 422 packed", -+ .fourcc = V4L2_PIX_FMT_UYVY, -+ .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, -+ .coplanar = 0, -+ .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422], -+ }, -+ }, -+}; -+ -+/* -+ * per-queue, driver-specific private data. -+ * there is one source queue and one destination queue for each m2m context. -+ */ -+struct vpe_q_data { -+ unsigned int width; /* frame width */ -+ unsigned int height; /* frame height */ -+ unsigned int bytesperline[VPE_MAX_PLANES]; /* bytes per line in memory */ -+ enum v4l2_colorspace colorspace; -+ enum v4l2_field field; /* supported field value */ -+ unsigned int flags; -+ unsigned int sizeimage[VPE_MAX_PLANES]; /* image size in memory */ -+ struct v4l2_rect c_rect; /* crop/compose rectangle */ -+ struct vpe_fmt *fmt; /* format info */ -+}; -+ -+/* vpe_q_data flag bits */ -+#define Q_DATA_FRAME_1D (1 << 0) -+#define Q_DATA_MODE_TILED (1 << 1) -+#define Q_DATA_INTERLACED (1 << 2) -+ -+enum { -+ Q_DATA_SRC = 0, -+ Q_DATA_DST = 1, -+}; -+ -+/* find our format description corresponding to the passed v4l2_format */ -+static struct vpe_fmt *find_format(struct v4l2_format *f) -+{ -+ struct vpe_fmt *fmt; -+ unsigned int k; -+ -+ for (k = 0; k < ARRAY_SIZE(vpe_formats); k++) { -+ fmt = &vpe_formats[k]; -+ if (fmt->fourcc == f->fmt.pix.pixelformat) -+ return fmt; -+ } -+ -+ return NULL; -+} -+ -+/* -+ * there is one vpe_dev structure in the driver, it is shared by -+ * all instances. -+ */ -+struct vpe_dev { -+ struct v4l2_device v4l2_dev; -+ struct video_device vfd; -+ struct v4l2_m2m_dev *m2m_dev; -+ -+ atomic_t num_instances; /* count of driver instances */ -+ dma_addr_t loaded_mmrs; /* shadow mmrs in device */ -+ struct mutex dev_mutex; -+ spinlock_t lock; -+ -+ int irq; -+ void __iomem *base; -+ -+ struct vb2_alloc_ctx *alloc_ctx; -+ struct vpdma_data *vpdma; /* vpdma data handle */ -+}; -+ -+/* -+ * There is one vpe_ctx structure for each m2m context. -+ */ -+struct vpe_ctx { -+ struct v4l2_fh fh; -+ struct vpe_dev *dev; -+ struct v4l2_m2m_ctx *m2m_ctx; -+ struct v4l2_ctrl_handler hdl; -+ -+ unsigned int field; /* current field */ -+ unsigned int sequence; /* current frame/field seq */ -+ unsigned int aborting; /* abort after next irq */ -+ -+ unsigned int bufs_per_job; /* input buffers per batch */ -+ unsigned int bufs_completed; /* bufs done in this batch */ -+ -+ struct vpe_q_data q_data[2]; /* src & dst queue data */ -+ struct vb2_buffer *src_vbs[VPE_MAX_SRC_BUFS]; -+ struct vb2_buffer *dst_vb; -+ -+ dma_addr_t mv_buf_dma[2]; /* dma addrs of motion vector in/out bufs */ -+ void *mv_buf[2]; /* virtual addrs of motion vector bufs */ -+ size_t mv_buf_size; /* current motion vector buffer size */ -+ struct vpdma_buf mmr_adb; /* shadow reg addr/data block */ -+ struct vpdma_desc_list desc_list; /* DMA descriptor list */ -+ -+ bool deinterlacing; /* using de-interlacer */ -+ bool load_mmrs; /* have new shadow reg values */ -+ -+ unsigned int src_mv_buf_selector; -+}; -+ -+ -+/* -+ * M2M devices get 2 queues. -+ * Return the queue given the type. -+ */ -+static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx, -+ enum v4l2_buf_type type) -+{ -+ switch (type) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: -+ return &ctx->q_data[Q_DATA_SRC]; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: -+ return &ctx->q_data[Q_DATA_DST]; -+ default: -+ BUG(); -+ } -+ return NULL; -+} -+ -+static u32 read_reg(struct vpe_dev *dev, int offset) -+{ -+ return ioread32(dev->base + offset); -+} -+ -+static void write_reg(struct vpe_dev *dev, int offset, u32 value) -+{ -+ iowrite32(value, dev->base + offset); -+} -+ -+/* register field read/write helpers */ -+static int get_field(u32 value, u32 mask, int shift) -+{ -+ return (value & (mask << shift)) >> shift; -+} -+ -+static int read_field_reg(struct vpe_dev *dev, int offset, u32 mask, int shift) -+{ -+ return get_field(read_reg(dev, offset), mask, shift); -+} -+ -+static void write_field(u32 *valp, u32 field, u32 mask, int shift) -+{ -+ u32 val = *valp; -+ -+ val &= ~(mask << shift); -+ val |= (field & mask) << shift; -+ *valp = val; -+} -+ -+static void write_field_reg(struct vpe_dev *dev, int offset, u32 field, -+ u32 mask, int shift) -+{ -+ u32 val = read_reg(dev, offset); -+ -+ write_field(&val, field, mask, shift); -+ -+ write_reg(dev, offset, val); -+} -+ -+/* -+ * DMA address/data block for the shadow registers -+ */ -+struct vpe_mmr_adb { -+ struct vpdma_adb_hdr out_fmt_hdr; -+ u32 out_fmt_reg[1]; -+ u32 out_fmt_pad[3]; -+ struct vpdma_adb_hdr us1_hdr; -+ u32 us1_regs[8]; -+ struct vpdma_adb_hdr us2_hdr; -+ u32 us2_regs[8]; -+ struct vpdma_adb_hdr us3_hdr; -+ u32 us3_regs[8]; -+ struct vpdma_adb_hdr dei_hdr; -+ u32 dei_regs[8]; -+ struct vpdma_adb_hdr sc_hdr; -+ u32 sc_regs[1]; -+ u32 sc_pad[3]; -+ struct vpdma_adb_hdr csc_hdr; -+ u32 csc_regs[6]; -+ u32 csc_pad[2]; -+}; -+ -+#define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a) \ -+ VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a) -+/* -+ * Set the headers for all of the address/data block structures. -+ */ -+static void init_adb_hdrs(struct vpe_ctx *ctx) -+{ -+ VPE_SET_MMR_ADB_HDR(ctx, out_fmt_hdr, out_fmt_reg, VPE_CLK_FORMAT_SELECT); -+ VPE_SET_MMR_ADB_HDR(ctx, us1_hdr, us1_regs, VPE_US1_R0); -+ VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0); -+ VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0); -+ VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE); -+ VPE_SET_MMR_ADB_HDR(ctx, sc_hdr, sc_regs, VPE_SC_MP_SC0); -+ VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs, VPE_CSC_CSC00); -+}; -+ -+/* -+ * Allocate or re-allocate the motion vector DMA buffers -+ * There are two buffers, one for input and one for output. -+ * However, the roles are reversed after each field is processed. -+ * In other words, after each field is processed, the previous -+ * output (dst) MV buffer becomes the new input (src) MV buffer. -+ */ -+static int realloc_mv_buffers(struct vpe_ctx *ctx, size_t size) -+{ -+ struct device *dev = ctx->dev->v4l2_dev.dev; -+ -+ if (ctx->mv_buf_size == size) -+ return 0; -+ -+ if (ctx->mv_buf[0]) -+ dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[0], -+ ctx->mv_buf_dma[0]); -+ -+ if (ctx->mv_buf[1]) -+ dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[1], -+ ctx->mv_buf_dma[1]); -+ -+ if (size == 0) -+ return 0; -+ -+ ctx->mv_buf[0] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[0], -+ GFP_KERNEL); -+ if (!ctx->mv_buf[0]) { -+ vpe_err(ctx->dev, "failed to allocate motion vector buffer\n"); -+ return -ENOMEM; -+ } -+ -+ ctx->mv_buf[1] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[1], -+ GFP_KERNEL); -+ if (!ctx->mv_buf[1]) { -+ vpe_err(ctx->dev, "failed to allocate motion vector buffer\n"); -+ dma_free_coherent(dev, size, ctx->mv_buf[0], -+ ctx->mv_buf_dma[0]); -+ -+ return -ENOMEM; -+ } -+ -+ ctx->mv_buf_size = size; -+ ctx->src_mv_buf_selector = 0; -+ -+ return 0; -+} -+ -+static void free_mv_buffers(struct vpe_ctx *ctx) -+{ -+ realloc_mv_buffers(ctx, 0); -+} -+ -+/* -+ * While de-interlacing, we keep the two most recent input buffers -+ * around. This function frees those two buffers when we have -+ * finished processing the current stream. -+ */ -+static void free_vbs(struct vpe_ctx *ctx) -+{ -+ struct vpe_dev *dev = ctx->dev; -+ unsigned long flags; -+ -+ if (ctx->src_vbs[2] == NULL) -+ return; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ if (ctx->src_vbs[2]) { -+ v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE); -+ v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE); -+ } -+ spin_unlock_irqrestore(&dev->lock, flags); -+} -+ -+/* -+ * Enable or disable the VPE clocks -+ */ -+static void vpe_set_clock_enable(struct vpe_dev *dev, bool on) -+{ -+ u32 val = 0; -+ -+ if (on) -+ val = VPE_DATA_PATH_CLK_ENABLE | VPE_VPEDMA_CLK_ENABLE; -+ write_reg(dev, VPE_CLK_ENABLE, val); -+} -+ -+static void vpe_top_reset(struct vpe_dev *dev) -+{ -+ -+ write_field_reg(dev, VPE_CLK_RESET, 1, VPE_DATA_PATH_CLK_RESET_MASK, -+ VPE_DATA_PATH_CLK_RESET_SHIFT); -+ -+ usleep_range(100, 150); -+ -+ write_field_reg(dev, VPE_CLK_RESET, 0, VPE_DATA_PATH_CLK_RESET_MASK, -+ VPE_DATA_PATH_CLK_RESET_SHIFT); -+} -+ -+static void vpe_top_vpdma_reset(struct vpe_dev *dev) -+{ -+ write_field_reg(dev, VPE_CLK_RESET, 1, VPE_VPDMA_CLK_RESET_MASK, -+ VPE_VPDMA_CLK_RESET_SHIFT); -+ -+ usleep_range(100, 150); -+ -+ write_field_reg(dev, VPE_CLK_RESET, 0, VPE_VPDMA_CLK_RESET_MASK, -+ VPE_VPDMA_CLK_RESET_SHIFT); -+} -+ -+/* -+ * Load the correct of upsampler coefficients into the shadow MMRs -+ */ -+static void set_us_coefficients(struct vpe_ctx *ctx) -+{ -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; -+ u32 *us1_reg = &mmr_adb->us1_regs[0]; -+ u32 *us2_reg = &mmr_adb->us2_regs[0]; -+ u32 *us3_reg = &mmr_adb->us3_regs[0]; -+ const unsigned short *cp, *end_cp; -+ -+ cp = &us_coeffs[0].anchor_fid0_c0; -+ -+ if (s_q_data->flags & Q_DATA_INTERLACED) /* interlaced */ -+ cp += sizeof(us_coeffs[0]) / sizeof(*cp); -+ -+ end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp); -+ -+ while (cp < end_cp) { -+ write_field(us1_reg, *cp++, VPE_US_C0_MASK, VPE_US_C0_SHIFT); -+ write_field(us1_reg, *cp++, VPE_US_C1_MASK, VPE_US_C1_SHIFT); -+ *us2_reg++ = *us1_reg; -+ *us3_reg++ = *us1_reg++; -+ } -+ ctx->load_mmrs = true; -+} -+ -+/* -+ * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs. -+ */ -+static void set_cfg_and_line_modes(struct vpe_ctx *ctx) -+{ -+ struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt; -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ u32 *us1_reg0 = &mmr_adb->us1_regs[0]; -+ u32 *us2_reg0 = &mmr_adb->us2_regs[0]; -+ u32 *us3_reg0 = &mmr_adb->us3_regs[0]; -+ int line_mode = 1; -+ int cfg_mode = 1; -+ -+ /* -+ * Cfg Mode 0: YUV420 source, enable upsampler, DEI is de-interlacing. -+ * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing. -+ */ -+ -+ if (fmt->fourcc == V4L2_PIX_FMT_NV12) { -+ cfg_mode = 0; -+ line_mode = 0; /* double lines to line buffer */ -+ } -+ -+ write_field(us1_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); -+ write_field(us2_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); -+ write_field(us3_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT); -+ -+ /* regs for now */ -+ vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN); -+ vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN); -+ vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA3_IN); -+ -+ /* frame start for input luma */ -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_LUMA1_IN); -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_LUMA2_IN); -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_LUMA3_IN); -+ -+ /* frame start for input chroma */ -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_CHROMA1_IN); -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_CHROMA2_IN); -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_CHROMA3_IN); -+ -+ /* frame start for MV in client */ -+ vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE, -+ VPE_CHAN_MV_IN); -+ -+ ctx->load_mmrs = true; -+} -+ -+/* -+ * Set the shadow registers that are modified when the source -+ * format changes. -+ */ -+static void set_src_registers(struct vpe_ctx *ctx) -+{ -+ set_us_coefficients(ctx); -+} -+ -+/* -+ * Set the shadow registers that are modified when the destination -+ * format changes. -+ */ -+static void set_dst_registers(struct vpe_ctx *ctx) -+{ -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt; -+ u32 val = 0; -+ -+ /* select RGB path when color space conversion is supported in future */ -+ if (fmt->fourcc == V4L2_PIX_FMT_RGB24) -+ val |= VPE_RGB_OUT_SELECT | VPE_CSC_SRC_DEI_SCALER; -+ else if (fmt->fourcc == V4L2_PIX_FMT_NV16) -+ val |= VPE_COLOR_SEPARATE_422; -+ -+ /* The source of CHR_DS is always the scaler, whether it's used or not */ -+ val |= VPE_DS_SRC_DEI_SCALER; -+ -+ if (fmt->fourcc != V4L2_PIX_FMT_NV12) -+ val |= VPE_DS_BYPASS; -+ -+ mmr_adb->out_fmt_reg[0] = val; -+ -+ ctx->load_mmrs = true; -+} -+ -+/* -+ * Set the de-interlacer shadow register values -+ */ -+static void set_dei_regs(struct vpe_ctx *ctx) -+{ -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; -+ unsigned int src_h = s_q_data->c_rect.height; -+ unsigned int src_w = s_q_data->c_rect.width; -+ u32 *dei_mmr0 = &mmr_adb->dei_regs[0]; -+ bool deinterlace = true; -+ u32 val = 0; -+ -+ /* -+ * according to TRM, we should set DEI in progressive bypass mode when -+ * the input content is progressive, however, DEI is bypassed correctly -+ * for both progressive and interlace content in interlace bypass mode. -+ * It has been recommended not to use progressive bypass mode. -+ */ -+ if ((!ctx->deinterlacing && (s_q_data->flags & Q_DATA_INTERLACED)) || -+ !(s_q_data->flags & Q_DATA_INTERLACED)) { -+ deinterlace = false; -+ val = VPE_DEI_INTERLACE_BYPASS; -+ } -+ -+ src_h = deinterlace ? src_h * 2 : src_h; -+ -+ val |= (src_h << VPE_DEI_HEIGHT_SHIFT) | -+ (src_w << VPE_DEI_WIDTH_SHIFT) | -+ VPE_DEI_FIELD_FLUSH; -+ -+ *dei_mmr0 = val; -+ -+ ctx->load_mmrs = true; -+} -+ -+static void set_dei_shadow_registers(struct vpe_ctx *ctx) -+{ -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ u32 *dei_mmr = &mmr_adb->dei_regs[0]; -+ const struct vpe_dei_regs *cur = &dei_regs; -+ -+ dei_mmr[2] = cur->mdt_spacial_freq_thr_reg; -+ dei_mmr[3] = cur->edi_config_reg; -+ dei_mmr[4] = cur->edi_lut_reg0; -+ dei_mmr[5] = cur->edi_lut_reg1; -+ dei_mmr[6] = cur->edi_lut_reg2; -+ dei_mmr[7] = cur->edi_lut_reg3; -+ -+ ctx->load_mmrs = true; -+} -+ -+static void set_csc_coeff_bypass(struct vpe_ctx *ctx) -+{ -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ u32 *shadow_csc_reg5 = &mmr_adb->csc_regs[5]; -+ -+ *shadow_csc_reg5 |= VPE_CSC_BYPASS; -+ -+ ctx->load_mmrs = true; -+} -+ -+static void set_sc_regs_bypass(struct vpe_ctx *ctx) -+{ -+ struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; -+ u32 *sc_reg0 = &mmr_adb->sc_regs[0]; -+ u32 val = 0; -+ -+ val |= VPE_SC_BYPASS; -+ *sc_reg0 = val; -+ -+ ctx->load_mmrs = true; -+} -+ -+/* -+ * Set the shadow registers whose values are modified when either the -+ * source or destination format is changed. -+ */ -+static int set_srcdst_params(struct vpe_ctx *ctx) -+{ -+ struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; -+ struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; -+ size_t mv_buf_size; -+ int ret; -+ -+ ctx->sequence = 0; -+ ctx->field = V4L2_FIELD_TOP; -+ -+ if ((s_q_data->flags & Q_DATA_INTERLACED) && -+ !(d_q_data->flags & Q_DATA_INTERLACED)) { -+ const struct vpdma_data_format *mv = -+ &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; -+ -+ ctx->deinterlacing = 1; -+ mv_buf_size = -+ (s_q_data->width * s_q_data->height * mv->depth) >> 3; -+ } else { -+ ctx->deinterlacing = 0; -+ mv_buf_size = 0; -+ } -+ -+ free_vbs(ctx); -+ -+ ret = realloc_mv_buffers(ctx, mv_buf_size); -+ if (ret) -+ return ret; -+ -+ set_cfg_and_line_modes(ctx); -+ set_dei_regs(ctx); -+ set_csc_coeff_bypass(ctx); -+ set_sc_regs_bypass(ctx); -+ -+ return 0; -+} -+ -+/* -+ * Return the vpe_ctx structure for a given struct file -+ */ -+static struct vpe_ctx *file2ctx(struct file *file) -+{ -+ return container_of(file->private_data, struct vpe_ctx, fh); -+} -+ -+/* -+ * mem2mem callbacks -+ */ -+ -+/** -+ * job_ready() - check whether an instance is ready to be scheduled to run -+ */ -+static int job_ready(void *priv) -+{ -+ struct vpe_ctx *ctx = priv; -+ int needed = ctx->bufs_per_job; -+ -+ if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) -+ needed += 2; /* need additional two most recent fields */ -+ -+ if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) < needed) -+ return 0; -+ -+ return 1; -+} -+ -+static void job_abort(void *priv) -+{ -+ struct vpe_ctx *ctx = priv; -+ -+ /* Will cancel the transaction in the next interrupt handler */ -+ ctx->aborting = 1; -+} -+ -+/* -+ * Lock access to the device -+ */ -+static void vpe_lock(void *priv) -+{ -+ struct vpe_ctx *ctx = priv; -+ struct vpe_dev *dev = ctx->dev; -+ mutex_lock(&dev->dev_mutex); -+} -+ -+static void vpe_unlock(void *priv) -+{ -+ struct vpe_ctx *ctx = priv; -+ struct vpe_dev *dev = ctx->dev; -+ mutex_unlock(&dev->dev_mutex); -+} -+ -+static void vpe_dump_regs(struct vpe_dev *dev) -+{ -+#define DUMPREG(r) vpe_dbg(dev, "%-35s %08x\n", #r, read_reg(dev, VPE_##r)) -+ -+ vpe_dbg(dev, "VPE Registers:\n"); -+ -+ DUMPREG(PID); -+ DUMPREG(SYSCONFIG); -+ DUMPREG(INT0_STATUS0_RAW); -+ DUMPREG(INT0_STATUS0); -+ DUMPREG(INT0_ENABLE0); -+ DUMPREG(INT0_STATUS1_RAW); -+ DUMPREG(INT0_STATUS1); -+ DUMPREG(INT0_ENABLE1); -+ DUMPREG(CLK_ENABLE); -+ DUMPREG(CLK_RESET); -+ DUMPREG(CLK_FORMAT_SELECT); -+ DUMPREG(CLK_RANGE_MAP); -+ DUMPREG(US1_R0); -+ DUMPREG(US1_R1); -+ DUMPREG(US1_R2); -+ DUMPREG(US1_R3); -+ DUMPREG(US1_R4); -+ DUMPREG(US1_R5); -+ DUMPREG(US1_R6); -+ DUMPREG(US1_R7); -+ DUMPREG(US2_R0); -+ DUMPREG(US2_R1); -+ DUMPREG(US2_R2); -+ DUMPREG(US2_R3); -+ DUMPREG(US2_R4); -+ DUMPREG(US2_R5); -+ DUMPREG(US2_R6); -+ DUMPREG(US2_R7); -+ DUMPREG(US3_R0); -+ DUMPREG(US3_R1); -+ DUMPREG(US3_R2); -+ DUMPREG(US3_R3); -+ DUMPREG(US3_R4); -+ DUMPREG(US3_R5); -+ DUMPREG(US3_R6); -+ DUMPREG(US3_R7); -+ DUMPREG(DEI_FRAME_SIZE); -+ DUMPREG(MDT_BYPASS); -+ DUMPREG(MDT_SF_THRESHOLD); -+ DUMPREG(EDI_CONFIG); -+ DUMPREG(DEI_EDI_LUT_R0); -+ DUMPREG(DEI_EDI_LUT_R1); -+ DUMPREG(DEI_EDI_LUT_R2); -+ DUMPREG(DEI_EDI_LUT_R3); -+ DUMPREG(DEI_FMD_WINDOW_R0); -+ DUMPREG(DEI_FMD_WINDOW_R1); -+ DUMPREG(DEI_FMD_CONTROL_R0); -+ DUMPREG(DEI_FMD_CONTROL_R1); -+ DUMPREG(DEI_FMD_STATUS_R0); -+ DUMPREG(DEI_FMD_STATUS_R1); -+ DUMPREG(DEI_FMD_STATUS_R2); -+ DUMPREG(SC_MP_SC0); -+ DUMPREG(SC_MP_SC1); -+ DUMPREG(SC_MP_SC2); -+ DUMPREG(SC_MP_SC3); -+ DUMPREG(SC_MP_SC4); -+ DUMPREG(SC_MP_SC5); -+ DUMPREG(SC_MP_SC6); -+ DUMPREG(SC_MP_SC8); -+ DUMPREG(SC_MP_SC9); -+ DUMPREG(SC_MP_SC10); -+ DUMPREG(SC_MP_SC11); -+ DUMPREG(SC_MP_SC12); -+ DUMPREG(SC_MP_SC13); -+ DUMPREG(SC_MP_SC17); -+ DUMPREG(SC_MP_SC18); -+ DUMPREG(SC_MP_SC19); -+ DUMPREG(SC_MP_SC20); -+ DUMPREG(SC_MP_SC21); -+ DUMPREG(SC_MP_SC22); -+ DUMPREG(SC_MP_SC23); -+ DUMPREG(SC_MP_SC24); -+ DUMPREG(SC_MP_SC25); -+ DUMPREG(CSC_CSC00); -+ DUMPREG(CSC_CSC01); -+ DUMPREG(CSC_CSC02); -+ DUMPREG(CSC_CSC03); -+ DUMPREG(CSC_CSC04); -+ DUMPREG(CSC_CSC05); -+#undef DUMPREG -+} -+ -+static void add_out_dtd(struct vpe_ctx *ctx, int port) -+{ -+ struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST]; -+ const struct vpe_port_data *p_data = &port_data[port]; -+ struct vb2_buffer *vb = ctx->dst_vb; -+ struct v4l2_rect *c_rect = &q_data->c_rect; -+ struct vpe_fmt *fmt = q_data->fmt; -+ const struct vpdma_data_format *vpdma_fmt; -+ int mv_buf_selector = !ctx->src_mv_buf_selector; -+ dma_addr_t dma_addr; -+ u32 flags = 0; -+ -+ if (port == VPE_PORT_MV_OUT) { -+ vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; -+ dma_addr = ctx->mv_buf_dma[mv_buf_selector]; -+ } else { -+ /* to incorporate interleaved formats */ -+ int plane = fmt->coplanar ? p_data->vb_part : 0; -+ -+ vpdma_fmt = fmt->vpdma_fmt[plane]; -+ dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); -+ if (!dma_addr) { -+ vpe_err(ctx->dev, -+ "acquiring output buffer(%d) dma_addr failed\n", -+ port); -+ return; -+ } -+ } -+ -+ if (q_data->flags & Q_DATA_FRAME_1D) -+ flags |= VPDMA_DATA_FRAME_1D; -+ if (q_data->flags & Q_DATA_MODE_TILED) -+ flags |= VPDMA_DATA_MODE_TILED; -+ -+ vpdma_add_out_dtd(&ctx->desc_list, c_rect, vpdma_fmt, dma_addr, -+ p_data->channel, flags); -+} -+ -+static void add_in_dtd(struct vpe_ctx *ctx, int port) -+{ -+ struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC]; -+ const struct vpe_port_data *p_data = &port_data[port]; -+ struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index]; -+ struct v4l2_rect *c_rect = &q_data->c_rect; -+ struct vpe_fmt *fmt = q_data->fmt; -+ const struct vpdma_data_format *vpdma_fmt; -+ int mv_buf_selector = ctx->src_mv_buf_selector; -+ int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM; -+ dma_addr_t dma_addr; -+ u32 flags = 0; -+ -+ if (port == VPE_PORT_MV_IN) { -+ vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; -+ dma_addr = ctx->mv_buf_dma[mv_buf_selector]; -+ } else { -+ /* to incorporate interleaved formats */ -+ int plane = fmt->coplanar ? p_data->vb_part : 0; -+ -+ vpdma_fmt = fmt->vpdma_fmt[plane]; -+ -+ dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane); -+ if (!dma_addr) { -+ vpe_err(ctx->dev, -+ "acquiring input buffer(%d) dma_addr failed\n", -+ port); -+ return; -+ } -+ } -+ -+ if (q_data->flags & Q_DATA_FRAME_1D) -+ flags |= VPDMA_DATA_FRAME_1D; -+ if (q_data->flags & Q_DATA_MODE_TILED) -+ flags |= VPDMA_DATA_MODE_TILED; -+ -+ vpdma_add_in_dtd(&ctx->desc_list, q_data->width, q_data->height, -+ c_rect, vpdma_fmt, dma_addr, p_data->channel, field, flags); -+} -+ -+/* -+ * Enable the expected IRQ sources -+ */ -+static void enable_irqs(struct vpe_ctx *ctx) -+{ -+ write_reg(ctx->dev, VPE_INT0_ENABLE0_SET, VPE_INT0_LIST0_COMPLETE); -+ write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT | -+ VPE_DS1_UV_ERROR_INT); -+ -+ vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, true); -+} -+ -+static void disable_irqs(struct vpe_ctx *ctx) -+{ -+ write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff); -+ write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff); -+ -+ vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, false); -+} -+ -+/* device_run() - prepares and starts the device -+ * -+ * This function is only called when both the source and destination -+ * buffers are in place. -+ */ -+static void device_run(void *priv) -+{ -+ struct vpe_ctx *ctx = priv; -+ struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; -+ -+ if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) { -+ ctx->src_vbs[2] = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); -+ WARN_ON(ctx->src_vbs[2] == NULL); -+ ctx->src_vbs[1] = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); -+ WARN_ON(ctx->src_vbs[1] == NULL); -+ } -+ -+ ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); -+ WARN_ON(ctx->src_vbs[0] == NULL); -+ ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); -+ WARN_ON(ctx->dst_vb == NULL); -+ -+ /* config descriptors */ -+ if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) { -+ vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb); -+ vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb); -+ ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr; -+ ctx->load_mmrs = false; -+ } -+ -+ /* output data descriptors */ -+ if (ctx->deinterlacing) -+ add_out_dtd(ctx, VPE_PORT_MV_OUT); -+ -+ add_out_dtd(ctx, VPE_PORT_LUMA_OUT); -+ if (d_q_data->fmt->coplanar) -+ add_out_dtd(ctx, VPE_PORT_CHROMA_OUT); -+ -+ /* input data descriptors */ -+ if (ctx->deinterlacing) { -+ add_in_dtd(ctx, VPE_PORT_LUMA3_IN); -+ add_in_dtd(ctx, VPE_PORT_CHROMA3_IN); -+ -+ add_in_dtd(ctx, VPE_PORT_LUMA2_IN); -+ add_in_dtd(ctx, VPE_PORT_CHROMA2_IN); -+ } -+ -+ add_in_dtd(ctx, VPE_PORT_LUMA1_IN); -+ add_in_dtd(ctx, VPE_PORT_CHROMA1_IN); -+ -+ if (ctx->deinterlacing) -+ add_in_dtd(ctx, VPE_PORT_MV_IN); -+ -+ /* sync on channel control descriptors for input ports */ -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA1_IN); -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA1_IN); -+ -+ if (ctx->deinterlacing) { -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, -+ VPE_CHAN_LUMA2_IN); -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, -+ VPE_CHAN_CHROMA2_IN); -+ -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, -+ VPE_CHAN_LUMA3_IN); -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, -+ VPE_CHAN_CHROMA3_IN); -+ -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_IN); -+ } -+ -+ /* sync on channel control descriptors for output ports */ -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA_OUT); -+ if (d_q_data->fmt->coplanar) -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA_OUT); -+ -+ if (ctx->deinterlacing) -+ vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT); -+ -+ enable_irqs(ctx); -+ -+ vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf); -+ vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list); -+} -+ -+static void dei_error(struct vpe_ctx *ctx) -+{ -+ dev_warn(ctx->dev->v4l2_dev.dev, -+ "received DEI error interrupt\n"); -+} -+ -+static void ds1_uv_error(struct vpe_ctx *ctx) -+{ -+ dev_warn(ctx->dev->v4l2_dev.dev, -+ "received downsampler error interrupt\n"); -+} -+ -+static irqreturn_t vpe_irq(int irq_vpe, void *data) -+{ -+ struct vpe_dev *dev = (struct vpe_dev *)data; -+ struct vpe_ctx *ctx; -+ struct vpe_q_data *d_q_data; -+ struct vb2_buffer *s_vb, *d_vb; -+ struct v4l2_buffer *s_buf, *d_buf; -+ unsigned long flags; -+ u32 irqst0, irqst1; -+ -+ irqst0 = read_reg(dev, VPE_INT0_STATUS0); -+ if (irqst0) { -+ write_reg(dev, VPE_INT0_STATUS0_CLR, irqst0); -+ vpe_dbg(dev, "INT0_STATUS0 = 0x%08x\n", irqst0); -+ } -+ -+ irqst1 = read_reg(dev, VPE_INT0_STATUS1); -+ if (irqst1) { -+ write_reg(dev, VPE_INT0_STATUS1_CLR, irqst1); -+ vpe_dbg(dev, "INT0_STATUS1 = 0x%08x\n", irqst1); -+ } -+ -+ ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); -+ if (!ctx) { -+ vpe_err(dev, "instance released before end of transaction\n"); -+ goto handled; -+ } -+ -+ if (irqst1) { -+ if (irqst1 & VPE_DEI_ERROR_INT) { -+ irqst1 &= ~VPE_DEI_ERROR_INT; -+ dei_error(ctx); -+ } -+ if (irqst1 & VPE_DS1_UV_ERROR_INT) { -+ irqst1 &= ~VPE_DS1_UV_ERROR_INT; -+ ds1_uv_error(ctx); -+ } -+ } -+ -+ if (irqst0) { -+ if (irqst0 & VPE_INT0_LIST0_COMPLETE) -+ vpdma_clear_list_stat(ctx->dev->vpdma); -+ -+ irqst0 &= ~(VPE_INT0_LIST0_COMPLETE); -+ } -+ -+ if (irqst0 | irqst1) { -+ dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: " -+ "INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n", -+ irqst0, irqst1); -+ } -+ -+ disable_irqs(ctx); -+ -+ vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); -+ vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb); -+ -+ vpdma_reset_desc_list(&ctx->desc_list); -+ -+ /* the previous dst mv buffer becomes the next src mv buffer */ -+ ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector; -+ -+ if (ctx->aborting) -+ goto finished; -+ -+ s_vb = ctx->src_vbs[0]; -+ d_vb = ctx->dst_vb; -+ s_buf = &s_vb->v4l2_buf; -+ d_buf = &d_vb->v4l2_buf; -+ -+ d_buf->timestamp = s_buf->timestamp; -+ if (s_buf->flags & V4L2_BUF_FLAG_TIMECODE) { -+ d_buf->flags |= V4L2_BUF_FLAG_TIMECODE; -+ d_buf->timecode = s_buf->timecode; -+ } -+ d_buf->sequence = ctx->sequence; -+ d_buf->field = ctx->field; -+ -+ d_q_data = &ctx->q_data[Q_DATA_DST]; -+ if (d_q_data->flags & Q_DATA_INTERLACED) { -+ if (ctx->field == V4L2_FIELD_BOTTOM) { -+ ctx->sequence++; -+ ctx->field = V4L2_FIELD_TOP; -+ } else { -+ WARN_ON(ctx->field != V4L2_FIELD_TOP); -+ ctx->field = V4L2_FIELD_BOTTOM; -+ } -+ } else { -+ ctx->sequence++; -+ } -+ -+ if (ctx->deinterlacing) -+ s_vb = ctx->src_vbs[2]; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE); -+ v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_DONE); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ if (ctx->deinterlacing) { -+ ctx->src_vbs[2] = ctx->src_vbs[1]; -+ ctx->src_vbs[1] = ctx->src_vbs[0]; -+ } -+ -+ ctx->bufs_completed++; -+ if (ctx->bufs_completed < ctx->bufs_per_job) { -+ device_run(ctx); -+ goto handled; -+ } -+ -+finished: -+ vpe_dbg(ctx->dev, "finishing transaction\n"); -+ ctx->bufs_completed = 0; -+ v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx); -+handled: -+ return IRQ_HANDLED; -+} -+ -+/* -+ * video ioctls -+ */ -+static int vpe_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ strncpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver) - 1); -+ strncpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card) - 1); -+ strlcpy(cap->bus_info, VPE_MODULE_NAME, sizeof(cap->bus_info)); -+ cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; -+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; -+ return 0; -+} -+ -+static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type) -+{ -+ int i, index; -+ struct vpe_fmt *fmt = NULL; -+ -+ index = 0; -+ for (i = 0; i < ARRAY_SIZE(vpe_formats); ++i) { -+ if (vpe_formats[i].types & type) { -+ if (index == f->index) { -+ fmt = &vpe_formats[i]; -+ break; -+ } -+ index++; -+ } -+ } -+ -+ if (!fmt) -+ return -EINVAL; -+ -+ strncpy(f->description, fmt->name, sizeof(f->description) - 1); -+ f->pixelformat = fmt->fourcc; -+ return 0; -+} -+ -+static int vpe_enum_fmt(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ if (V4L2_TYPE_IS_OUTPUT(f->type)) -+ return __enum_fmt(f, VPE_FMT_TYPE_OUTPUT); -+ -+ return __enum_fmt(f, VPE_FMT_TYPE_CAPTURE); -+} -+ -+static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; -+ struct vpe_ctx *ctx = file2ctx(file); -+ struct vb2_queue *vq; -+ struct vpe_q_data *q_data; -+ int i; -+ -+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); -+ if (!vq) -+ return -EINVAL; -+ -+ q_data = get_q_data(ctx, f->type); -+ -+ pix->width = q_data->width; -+ pix->height = q_data->height; -+ pix->pixelformat = q_data->fmt->fourcc; -+ pix->field = q_data->field; -+ pix->colorspace = q_data->colorspace; -+ pix->num_planes = q_data->fmt->coplanar ? 2 : 1; -+ -+ for (i = 0; i < pix->num_planes; i++) { -+ pix->plane_fmt[i].bytesperline = q_data->bytesperline[i]; -+ pix->plane_fmt[i].sizeimage = q_data->sizeimage[i]; -+ } -+ -+ return 0; -+} -+ -+static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, -+ struct vpe_fmt *fmt, int type) -+{ -+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; -+ struct v4l2_plane_pix_format *plane_fmt; -+ int i; -+ -+ if (!fmt || !(fmt->types & type)) { -+ vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", -+ pix->pixelformat); -+ return -EINVAL; -+ } -+ -+ if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE) -+ pix->field = V4L2_FIELD_NONE; -+ -+ v4l_bound_align_image(&pix->width, MIN_W, MAX_W, W_ALIGN, -+ &pix->height, MIN_H, MAX_H, H_ALIGN, -+ S_ALIGN); -+ -+ pix->num_planes = fmt->coplanar ? 2 : 1; -+ pix->pixelformat = fmt->fourcc; -+ pix->colorspace = fmt->fourcc == V4L2_PIX_FMT_RGB24 ? -+ V4L2_COLORSPACE_SRGB : V4L2_COLORSPACE_SMPTE170M; -+ -+ for (i = 0; i < pix->num_planes; i++) { -+ int depth; -+ -+ plane_fmt = &pix->plane_fmt[i]; -+ depth = fmt->vpdma_fmt[i]->depth; -+ -+ if (i == VPE_LUMA) -+ plane_fmt->bytesperline = -+ round_up((pix->width * depth) >> 3, -+ 1 << L_ALIGN); -+ else -+ plane_fmt->bytesperline = pix->width; -+ -+ plane_fmt->sizeimage = -+ (pix->height * pix->width * depth) >> 3; -+ } -+ -+ return 0; -+} -+ -+static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ struct vpe_fmt *fmt = find_format(f); -+ -+ if (V4L2_TYPE_IS_OUTPUT(f->type)) -+ return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_OUTPUT); -+ else -+ return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_CAPTURE); -+} -+ -+static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; -+ struct v4l2_plane_pix_format *plane_fmt; -+ struct vpe_q_data *q_data; -+ struct vb2_queue *vq; -+ int i; -+ -+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); -+ if (!vq) -+ return -EINVAL; -+ -+ if (vb2_is_busy(vq)) { -+ vpe_err(ctx->dev, "queue busy\n"); -+ return -EBUSY; -+ } -+ -+ q_data = get_q_data(ctx, f->type); -+ if (!q_data) -+ return -EINVAL; -+ -+ q_data->fmt = find_format(f); -+ q_data->width = pix->width; -+ q_data->height = pix->height; -+ q_data->colorspace = pix->colorspace; -+ q_data->field = pix->field; -+ -+ for (i = 0; i < pix->num_planes; i++) { -+ plane_fmt = &pix->plane_fmt[i]; -+ -+ q_data->bytesperline[i] = plane_fmt->bytesperline; -+ q_data->sizeimage[i] = plane_fmt->sizeimage; -+ } -+ -+ q_data->c_rect.left = 0; -+ q_data->c_rect.top = 0; -+ q_data->c_rect.width = q_data->width; -+ q_data->c_rect.height = q_data->height; -+ -+ if (q_data->field == V4L2_FIELD_ALTERNATE) -+ q_data->flags |= Q_DATA_INTERLACED; -+ else -+ q_data->flags &= ~Q_DATA_INTERLACED; -+ -+ vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d", -+ f->type, q_data->width, q_data->height, q_data->fmt->fourcc, -+ q_data->bytesperline[VPE_LUMA]); -+ if (q_data->fmt->coplanar) -+ vpe_dbg(ctx->dev, " bpl_uv %d\n", -+ q_data->bytesperline[VPE_CHROMA]); -+ -+ return 0; -+} -+ -+static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f) -+{ -+ int ret; -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ ret = vpe_try_fmt(file, priv, f); -+ if (ret) -+ return ret; -+ -+ ret = __vpe_s_fmt(ctx, f); -+ if (ret) -+ return ret; -+ -+ if (V4L2_TYPE_IS_OUTPUT(f->type)) -+ set_src_registers(ctx); -+ else -+ set_dst_registers(ctx); -+ -+ return set_srcdst_params(ctx); -+} -+ -+static int vpe_reqbufs(struct file *file, void *priv, -+ struct v4l2_requestbuffers *reqbufs) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); -+} -+ -+static int vpe_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); -+} -+ -+static int vpe_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); -+} -+ -+static int vpe_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); -+} -+ -+static int vpe_streamon(struct file *file, void *priv, enum v4l2_buf_type type) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); -+} -+ -+static int vpe_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ vpe_dump_regs(ctx->dev); -+ vpdma_dump_regs(ctx->dev->vpdma); -+ -+ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); -+} -+ -+#define V4L2_CID_VPE_BUFS_PER_JOB (V4L2_CID_USER_TI_VPE_BASE + 0) -+ -+static int vpe_s_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct vpe_ctx *ctx = -+ container_of(ctrl->handler, struct vpe_ctx, hdl); -+ -+ switch (ctrl->id) { -+ case V4L2_CID_VPE_BUFS_PER_JOB: -+ ctx->bufs_per_job = ctrl->val; -+ break; -+ -+ default: -+ vpe_err(ctx->dev, "Invalid control\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct v4l2_ctrl_ops vpe_ctrl_ops = { -+ .s_ctrl = vpe_s_ctrl, -+}; -+ -+static const struct v4l2_ioctl_ops vpe_ioctl_ops = { -+ .vidioc_querycap = vpe_querycap, -+ -+ .vidioc_enum_fmt_vid_cap_mplane = vpe_enum_fmt, -+ .vidioc_g_fmt_vid_cap_mplane = vpe_g_fmt, -+ .vidioc_try_fmt_vid_cap_mplane = vpe_try_fmt, -+ .vidioc_s_fmt_vid_cap_mplane = vpe_s_fmt, -+ -+ .vidioc_enum_fmt_vid_out_mplane = vpe_enum_fmt, -+ .vidioc_g_fmt_vid_out_mplane = vpe_g_fmt, -+ .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt, -+ .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt, -+ -+ .vidioc_reqbufs = vpe_reqbufs, -+ .vidioc_querybuf = vpe_querybuf, -+ -+ .vidioc_qbuf = vpe_qbuf, -+ .vidioc_dqbuf = vpe_dqbuf, -+ -+ .vidioc_streamon = vpe_streamon, -+ .vidioc_streamoff = vpe_streamoff, -+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+}; -+ -+/* -+ * Queue operations -+ */ -+static int vpe_queue_setup(struct vb2_queue *vq, -+ const struct v4l2_format *fmt, -+ unsigned int *nbuffers, unsigned int *nplanes, -+ unsigned int sizes[], void *alloc_ctxs[]) -+{ -+ int i; -+ struct vpe_ctx *ctx = vb2_get_drv_priv(vq); -+ struct vpe_q_data *q_data; -+ -+ q_data = get_q_data(ctx, vq->type); -+ -+ *nplanes = q_data->fmt->coplanar ? 2 : 1; -+ -+ for (i = 0; i < *nplanes; i++) { -+ sizes[i] = q_data->sizeimage[i]; -+ alloc_ctxs[i] = ctx->dev->alloc_ctx; -+ } -+ -+ vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers, -+ sizes[VPE_LUMA]); -+ if (q_data->fmt->coplanar) -+ vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]); -+ -+ return 0; -+} -+ -+static int vpe_buf_prepare(struct vb2_buffer *vb) -+{ -+ struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ struct vpe_q_data *q_data; -+ int i, num_planes; -+ -+ vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type); -+ -+ q_data = get_q_data(ctx, vb->vb2_queue->type); -+ num_planes = q_data->fmt->coplanar ? 2 : 1; -+ -+ for (i = 0; i < num_planes; i++) { -+ if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { -+ vpe_err(ctx->dev, -+ "data will not fit into plane (%lu < %lu)\n", -+ vb2_plane_size(vb, i), -+ (long) q_data->sizeimage[i]); -+ return -EINVAL; -+ } -+ } -+ -+ for (i = 0; i < num_planes; i++) -+ vb2_set_plane_payload(vb, i, q_data->sizeimage[i]); -+ -+ return 0; -+} -+ -+static void vpe_buf_queue(struct vb2_buffer *vb) -+{ -+ struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); -+} -+ -+static void vpe_wait_prepare(struct vb2_queue *q) -+{ -+ struct vpe_ctx *ctx = vb2_get_drv_priv(q); -+ vpe_unlock(ctx); -+} -+ -+static void vpe_wait_finish(struct vb2_queue *q) -+{ -+ struct vpe_ctx *ctx = vb2_get_drv_priv(q); -+ vpe_lock(ctx); -+} -+ -+static struct vb2_ops vpe_qops = { -+ .queue_setup = vpe_queue_setup, -+ .buf_prepare = vpe_buf_prepare, -+ .buf_queue = vpe_buf_queue, -+ .wait_prepare = vpe_wait_prepare, -+ .wait_finish = vpe_wait_finish, -+}; -+ -+static int queue_init(void *priv, struct vb2_queue *src_vq, -+ struct vb2_queue *dst_vq) -+{ -+ struct vpe_ctx *ctx = priv; -+ int ret; -+ -+ memset(src_vq, 0, sizeof(*src_vq)); -+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ src_vq->io_modes = VB2_MMAP; -+ src_vq->drv_priv = ctx; -+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); -+ src_vq->ops = &vpe_qops; -+ src_vq->mem_ops = &vb2_dma_contig_memops; -+ src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ -+ ret = vb2_queue_init(src_vq); -+ if (ret) -+ return ret; -+ -+ memset(dst_vq, 0, sizeof(*dst_vq)); -+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ dst_vq->io_modes = VB2_MMAP; -+ dst_vq->drv_priv = ctx; -+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); -+ dst_vq->ops = &vpe_qops; -+ dst_vq->mem_ops = &vb2_dma_contig_memops; -+ dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ -+ return vb2_queue_init(dst_vq); -+} -+ -+static const struct v4l2_ctrl_config vpe_bufs_per_job = { -+ .ops = &vpe_ctrl_ops, -+ .id = V4L2_CID_VPE_BUFS_PER_JOB, -+ .name = "Buffers Per Transaction", -+ .type = V4L2_CTRL_TYPE_INTEGER, -+ .def = VPE_DEF_BUFS_PER_JOB, -+ .min = 1, -+ .max = VIDEO_MAX_FRAME, -+ .step = 1, -+}; -+ -+/* -+ * File operations -+ */ -+static int vpe_open(struct file *file) -+{ -+ struct vpe_dev *dev = video_drvdata(file); -+ struct vpe_ctx *ctx = NULL; -+ struct vpe_q_data *s_q_data; -+ struct v4l2_ctrl_handler *hdl; -+ int ret; -+ -+ vpe_dbg(dev, "vpe_open\n"); -+ -+ if (!dev->vpdma->ready) { -+ vpe_err(dev, "vpdma firmware not loaded\n"); -+ return -ENODEV; -+ } -+ -+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ -+ ctx->dev = dev; -+ -+ if (mutex_lock_interruptible(&dev->dev_mutex)) { -+ ret = -ERESTARTSYS; -+ goto free_ctx; -+ } -+ -+ ret = vpdma_create_desc_list(&ctx->desc_list, VPE_DESC_LIST_SIZE, -+ VPDMA_LIST_TYPE_NORMAL); -+ if (ret != 0) -+ goto unlock; -+ -+ ret = vpdma_alloc_desc_buf(&ctx->mmr_adb, sizeof(struct vpe_mmr_adb)); -+ if (ret != 0) -+ goto free_desc_list; -+ -+ init_adb_hdrs(ctx); -+ -+ v4l2_fh_init(&ctx->fh, video_devdata(file)); -+ file->private_data = &ctx->fh; -+ -+ hdl = &ctx->hdl; -+ v4l2_ctrl_handler_init(hdl, 1); -+ v4l2_ctrl_new_custom(hdl, &vpe_bufs_per_job, NULL); -+ if (hdl->error) { -+ ret = hdl->error; -+ goto exit_fh; -+ } -+ ctx->fh.ctrl_handler = hdl; -+ v4l2_ctrl_handler_setup(hdl); -+ -+ s_q_data = &ctx->q_data[Q_DATA_SRC]; -+ s_q_data->fmt = &vpe_formats[2]; -+ s_q_data->width = 1920; -+ s_q_data->height = 1080; -+ s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height * -+ s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; -+ s_q_data->colorspace = V4L2_COLORSPACE_SMPTE240M; -+ s_q_data->field = V4L2_FIELD_NONE; -+ s_q_data->c_rect.left = 0; -+ s_q_data->c_rect.top = 0; -+ s_q_data->c_rect.width = s_q_data->width; -+ s_q_data->c_rect.height = s_q_data->height; -+ s_q_data->flags = 0; -+ -+ ctx->q_data[Q_DATA_DST] = *s_q_data; -+ -+ set_dei_shadow_registers(ctx); -+ set_src_registers(ctx); -+ set_dst_registers(ctx); -+ ret = set_srcdst_params(ctx); -+ if (ret) -+ goto exit_fh; -+ -+ ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); -+ -+ if (IS_ERR(ctx->m2m_ctx)) { -+ ret = PTR_ERR(ctx->m2m_ctx); -+ goto exit_fh; -+ } -+ -+ v4l2_fh_add(&ctx->fh); -+ -+ /* -+ * for now, just report the creation of the first instance, we can later -+ * optimize the driver to enable or disable clocks when the first -+ * instance is created or the last instance released -+ */ -+ if (atomic_inc_return(&dev->num_instances) == 1) -+ vpe_dbg(dev, "first instance created\n"); -+ -+ ctx->bufs_per_job = VPE_DEF_BUFS_PER_JOB; -+ -+ ctx->load_mmrs = true; -+ -+ vpe_dbg(dev, "created instance %p, m2m_ctx: %p\n", -+ ctx, ctx->m2m_ctx); -+ -+ mutex_unlock(&dev->dev_mutex); -+ -+ return 0; -+exit_fh: -+ v4l2_ctrl_handler_free(hdl); -+ v4l2_fh_exit(&ctx->fh); -+ vpdma_free_desc_buf(&ctx->mmr_adb); -+free_desc_list: -+ vpdma_free_desc_list(&ctx->desc_list); -+unlock: -+ mutex_unlock(&dev->dev_mutex); -+free_ctx: -+ kfree(ctx); -+ return ret; -+} -+ -+static int vpe_release(struct file *file) -+{ -+ struct vpe_dev *dev = video_drvdata(file); -+ struct vpe_ctx *ctx = file2ctx(file); -+ -+ vpe_dbg(dev, "releasing instance %p\n", ctx); -+ -+ mutex_lock(&dev->dev_mutex); -+ free_vbs(ctx); -+ free_mv_buffers(ctx); -+ vpdma_free_desc_list(&ctx->desc_list); -+ vpdma_free_desc_buf(&ctx->mmr_adb); -+ -+ v4l2_fh_del(&ctx->fh); -+ v4l2_fh_exit(&ctx->fh); -+ v4l2_ctrl_handler_free(&ctx->hdl); -+ v4l2_m2m_ctx_release(ctx->m2m_ctx); -+ -+ kfree(ctx); -+ -+ /* -+ * for now, just report the release of the last instance, we can later -+ * optimize the driver to enable or disable clocks when the first -+ * instance is created or the last instance released -+ */ -+ if (atomic_dec_return(&dev->num_instances) == 0) -+ vpe_dbg(dev, "last instance released\n"); -+ -+ mutex_unlock(&dev->dev_mutex); -+ -+ return 0; -+} -+ -+static unsigned int vpe_poll(struct file *file, -+ struct poll_table_struct *wait) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ struct vpe_dev *dev = ctx->dev; -+ int ret; -+ -+ mutex_lock(&dev->dev_mutex); -+ ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait); -+ mutex_unlock(&dev->dev_mutex); -+ return ret; -+} -+ -+static int vpe_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ struct vpe_ctx *ctx = file2ctx(file); -+ struct vpe_dev *dev = ctx->dev; -+ int ret; -+ -+ if (mutex_lock_interruptible(&dev->dev_mutex)) -+ return -ERESTARTSYS; -+ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); -+ mutex_unlock(&dev->dev_mutex); -+ return ret; -+} -+ -+static const struct v4l2_file_operations vpe_fops = { -+ .owner = THIS_MODULE, -+ .open = vpe_open, -+ .release = vpe_release, -+ .poll = vpe_poll, -+ .unlocked_ioctl = video_ioctl2, -+ .mmap = vpe_mmap, -+}; -+ -+static struct video_device vpe_videodev = { -+ .name = VPE_MODULE_NAME, -+ .fops = &vpe_fops, -+ .ioctl_ops = &vpe_ioctl_ops, -+ .minor = -1, -+ .release = video_device_release, -+ .vfl_dir = VFL_DIR_M2M, -+}; -+ -+static struct v4l2_m2m_ops m2m_ops = { -+ .device_run = device_run, -+ .job_ready = job_ready, -+ .job_abort = job_abort, -+ .lock = vpe_lock, -+ .unlock = vpe_unlock, -+}; -+ -+static int vpe_runtime_get(struct platform_device *pdev) -+{ -+ int r; -+ -+ dev_dbg(&pdev->dev, "vpe_runtime_get\n"); -+ -+ r = pm_runtime_get_sync(&pdev->dev); -+ WARN_ON(r < 0); -+ return r < 0 ? r : 0; -+} -+ -+static void vpe_runtime_put(struct platform_device *pdev) -+{ -+ -+ int r; -+ -+ dev_dbg(&pdev->dev, "vpe_runtime_put\n"); -+ -+ r = pm_runtime_put_sync(&pdev->dev); -+ WARN_ON(r < 0 && r != -ENOSYS); -+} -+ -+static int vpe_probe(struct platform_device *pdev) -+{ -+ struct vpe_dev *dev; -+ struct video_device *vfd; -+ struct resource *res; -+ int ret, irq, func; -+ -+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); -+ if (IS_ERR(dev)) -+ return PTR_ERR(dev); -+ -+ spin_lock_init(&dev->lock); -+ -+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); -+ if (ret) -+ return ret; -+ -+ atomic_set(&dev->num_instances, 0); -+ mutex_init(&dev->dev_mutex); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpe_top"); -+ /* -+ * HACK: we get resource info from device tree in the form of a list of -+ * VPE sub blocks, the driver currently uses only the base of vpe_top -+ * for register access, the driver should be changed later to access -+ * registers based on the sub block base addresses -+ */ -+ dev->base = devm_ioremap(&pdev->dev, res->start, SZ_32K); -+ if (IS_ERR(dev->base)) { -+ ret = PTR_ERR(dev->base); -+ goto v4l2_dev_unreg; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(&pdev->dev, irq, vpe_irq, 0, VPE_MODULE_NAME, -+ dev); -+ if (ret) -+ goto v4l2_dev_unreg; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); -+ if (IS_ERR(dev->alloc_ctx)) { -+ vpe_err(dev, "Failed to alloc vb2 context\n"); -+ ret = PTR_ERR(dev->alloc_ctx); -+ goto v4l2_dev_unreg; -+ } -+ -+ dev->m2m_dev = v4l2_m2m_init(&m2m_ops); -+ if (IS_ERR(dev->m2m_dev)) { -+ vpe_err(dev, "Failed to init mem2mem device\n"); -+ ret = PTR_ERR(dev->m2m_dev); -+ goto rel_ctx; -+ } -+ -+ pm_runtime_enable(&pdev->dev); -+ -+ ret = vpe_runtime_get(pdev); -+ if (ret) -+ goto rel_m2m; -+ -+ /* Perform clk enable followed by reset */ -+ vpe_set_clock_enable(dev, 1); -+ -+ vpe_top_reset(dev); -+ -+ func = read_field_reg(dev, VPE_PID, VPE_PID_FUNC_MASK, -+ VPE_PID_FUNC_SHIFT); -+ vpe_dbg(dev, "VPE PID function %x\n", func); -+ -+ vpe_top_vpdma_reset(dev); -+ -+ dev->vpdma = vpdma_create(pdev); -+ if (IS_ERR(dev->vpdma)) -+ goto runtime_put; -+ -+ vfd = &dev->vfd; -+ *vfd = vpe_videodev; -+ vfd->lock = &dev->dev_mutex; -+ vfd->v4l2_dev = &dev->v4l2_dev; -+ -+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); -+ if (ret) { -+ vpe_err(dev, "Failed to register video device\n"); -+ goto runtime_put; -+ } -+ -+ video_set_drvdata(vfd, dev); -+ snprintf(vfd->name, sizeof(vfd->name), "%s", vpe_videodev.name); -+ dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n", -+ vfd->num); -+ -+ return 0; -+ -+runtime_put: -+ vpe_runtime_put(pdev); -+rel_m2m: -+ pm_runtime_disable(&pdev->dev); -+ v4l2_m2m_release(dev->m2m_dev); -+rel_ctx: -+ vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); -+v4l2_dev_unreg: -+ v4l2_device_unregister(&dev->v4l2_dev); -+ -+ return ret; -+} -+ -+static int vpe_remove(struct platform_device *pdev) -+{ -+ struct vpe_dev *dev = -+ (struct vpe_dev *) platform_get_drvdata(pdev); -+ -+ v4l2_info(&dev->v4l2_dev, "Removing " VPE_MODULE_NAME); -+ -+ v4l2_m2m_release(dev->m2m_dev); -+ video_unregister_device(&dev->vfd); -+ v4l2_device_unregister(&dev->v4l2_dev); -+ vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); -+ -+ vpe_set_clock_enable(dev, 0); -+ vpe_runtime_put(pdev); -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+#if defined(CONFIG_OF) -+static const struct of_device_id vpe_of_match[] = { -+ { -+ .compatible = "ti,vpe", -+ }, -+ {}, -+}; -+#else -+#define vpe_of_match NULL -+#endif -+ -+static struct platform_driver vpe_pdrv = { -+ .probe = vpe_probe, -+ .remove = vpe_remove, -+ .driver = { -+ .name = VPE_MODULE_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = vpe_of_match, -+ }, -+}; -+ -+static void __exit vpe_exit(void) -+{ -+ platform_driver_unregister(&vpe_pdrv); -+} -+ -+static int __init vpe_init(void) -+{ -+ return platform_driver_register(&vpe_pdrv); -+} -+ -+module_init(vpe_init); -+module_exit(vpe_exit); -+ -+MODULE_DESCRIPTION("TI VPE driver"); -+MODULE_AUTHOR("Dale Farnsworth, <dale@farnsworth.org>"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/media/platform/ti-vpe/vpe_regs.h -@@ -0,0 +1,496 @@ -+/* -+ * Copyright (c) 2013 Texas Instruments Inc. -+ * -+ * David Griego, <dagriego@biglakesoftware.com> -+ * Dale Farnsworth, <dale@farnsworth.org> -+ * Archit Taneja, <archit@ti.com> -+ * -+ * 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. -+ */ -+ -+#ifndef __TI_VPE_REGS_H -+#define __TI_VPE_REGS_H -+ -+/* VPE register offsets and field selectors */ -+ -+/* VPE top level regs */ -+#define VPE_PID 0x0000 -+#define VPE_PID_MINOR_MASK 0x3f -+#define VPE_PID_MINOR_SHIFT 0 -+#define VPE_PID_CUSTOM_MASK 0x03 -+#define VPE_PID_CUSTOM_SHIFT 6 -+#define VPE_PID_MAJOR_MASK 0x07 -+#define VPE_PID_MAJOR_SHIFT 8 -+#define VPE_PID_RTL_MASK 0x1f -+#define VPE_PID_RTL_SHIFT 11 -+#define VPE_PID_FUNC_MASK 0xfff -+#define VPE_PID_FUNC_SHIFT 16 -+#define VPE_PID_SCHEME_MASK 0x03 -+#define VPE_PID_SCHEME_SHIFT 30 -+ -+#define VPE_SYSCONFIG 0x0010 -+#define VPE_SYSCONFIG_IDLE_MASK 0x03 -+#define VPE_SYSCONFIG_IDLE_SHIFT 2 -+#define VPE_SYSCONFIG_STANDBY_MASK 0x03 -+#define VPE_SYSCONFIG_STANDBY_SHIFT 4 -+#define VPE_FORCE_IDLE_MODE 0 -+#define VPE_NO_IDLE_MODE 1 -+#define VPE_SMART_IDLE_MODE 2 -+#define VPE_SMART_IDLE_WAKEUP_MODE 3 -+#define VPE_FORCE_STANDBY_MODE 0 -+#define VPE_NO_STANDBY_MODE 1 -+#define VPE_SMART_STANDBY_MODE 2 -+#define VPE_SMART_STANDBY_WAKEUP_MODE 3 -+ -+#define VPE_INT0_STATUS0_RAW_SET 0x0020 -+#define VPE_INT0_STATUS0_RAW VPE_INT0_STATUS0_RAW_SET -+#define VPE_INT0_STATUS0_CLR 0x0028 -+#define VPE_INT0_STATUS0 VPE_INT0_STATUS0_CLR -+#define VPE_INT0_ENABLE0_SET 0x0030 -+#define VPE_INT0_ENABLE0 VPE_INT0_ENABLE0_SET -+#define VPE_INT0_ENABLE0_CLR 0x0038 -+#define VPE_INT0_LIST0_COMPLETE (1 << 0) -+#define VPE_INT0_LIST0_NOTIFY (1 << 1) -+#define VPE_INT0_LIST1_COMPLETE (1 << 2) -+#define VPE_INT0_LIST1_NOTIFY (1 << 3) -+#define VPE_INT0_LIST2_COMPLETE (1 << 4) -+#define VPE_INT0_LIST2_NOTIFY (1 << 5) -+#define VPE_INT0_LIST3_COMPLETE (1 << 6) -+#define VPE_INT0_LIST3_NOTIFY (1 << 7) -+#define VPE_INT0_LIST4_COMPLETE (1 << 8) -+#define VPE_INT0_LIST4_NOTIFY (1 << 9) -+#define VPE_INT0_LIST5_COMPLETE (1 << 10) -+#define VPE_INT0_LIST5_NOTIFY (1 << 11) -+#define VPE_INT0_LIST6_COMPLETE (1 << 12) -+#define VPE_INT0_LIST6_NOTIFY (1 << 13) -+#define VPE_INT0_LIST7_COMPLETE (1 << 14) -+#define VPE_INT0_LIST7_NOTIFY (1 << 15) -+#define VPE_INT0_DESCRIPTOR (1 << 16) -+#define VPE_DEI_FMD_INT (1 << 18) -+ -+#define VPE_INT0_STATUS1_RAW_SET 0x0024 -+#define VPE_INT0_STATUS1_RAW VPE_INT0_STATUS1_RAW_SET -+#define VPE_INT0_STATUS1_CLR 0x002c -+#define VPE_INT0_STATUS1 VPE_INT0_STATUS1_CLR -+#define VPE_INT0_ENABLE1_SET 0x0034 -+#define VPE_INT0_ENABLE1 VPE_INT0_ENABLE1_SET -+#define VPE_INT0_ENABLE1_CLR 0x003c -+#define VPE_INT0_CHANNEL_GROUP0 (1 << 0) -+#define VPE_INT0_CHANNEL_GROUP1 (1 << 1) -+#define VPE_INT0_CHANNEL_GROUP2 (1 << 2) -+#define VPE_INT0_CHANNEL_GROUP3 (1 << 3) -+#define VPE_INT0_CHANNEL_GROUP4 (1 << 4) -+#define VPE_INT0_CHANNEL_GROUP5 (1 << 5) -+#define VPE_INT0_CLIENT (1 << 7) -+#define VPE_DEI_ERROR_INT (1 << 16) -+#define VPE_DS1_UV_ERROR_INT (1 << 22) -+ -+#define VPE_INTC_EOI 0x00a0 -+ -+#define VPE_CLK_ENABLE 0x0100 -+#define VPE_VPEDMA_CLK_ENABLE (1 << 0) -+#define VPE_DATA_PATH_CLK_ENABLE (1 << 1) -+ -+#define VPE_CLK_RESET 0x0104 -+#define VPE_VPDMA_CLK_RESET_MASK 0x1 -+#define VPE_VPDMA_CLK_RESET_SHIFT 0 -+#define VPE_DATA_PATH_CLK_RESET_MASK 0x1 -+#define VPE_DATA_PATH_CLK_RESET_SHIFT 1 -+#define VPE_MAIN_RESET_MASK 0x1 -+#define VPE_MAIN_RESET_SHIFT 31 -+ -+#define VPE_CLK_FORMAT_SELECT 0x010c -+#define VPE_CSC_SRC_SELECT_MASK 0x03 -+#define VPE_CSC_SRC_SELECT_SHIFT 0 -+#define VPE_RGB_OUT_SELECT (1 << 8) -+#define VPE_DS_SRC_SELECT_MASK 0x07 -+#define VPE_DS_SRC_SELECT_SHIFT 9 -+#define VPE_DS_BYPASS (1 << 16) -+#define VPE_COLOR_SEPARATE_422 (1 << 18) -+ -+#define VPE_DS_SRC_DEI_SCALER (5 << VPE_DS_SRC_SELECT_SHIFT) -+#define VPE_CSC_SRC_DEI_SCALER (3 << VPE_CSC_SRC_SELECT_SHIFT) -+ -+#define VPE_CLK_RANGE_MAP 0x011c -+#define VPE_RANGE_RANGE_MAP_Y_MASK 0x07 -+#define VPE_RANGE_RANGE_MAP_Y_SHIFT 0 -+#define VPE_RANGE_RANGE_MAP_UV_MASK 0x07 -+#define VPE_RANGE_RANGE_MAP_UV_SHIFT 3 -+#define VPE_RANGE_MAP_ON (1 << 6) -+#define VPE_RANGE_REDUCTION_ON (1 << 28) -+ -+/* VPE chrominance upsampler regs */ -+#define VPE_US1_R0 0x0304 -+#define VPE_US2_R0 0x0404 -+#define VPE_US3_R0 0x0504 -+#define VPE_US_C1_MASK 0x3fff -+#define VPE_US_C1_SHIFT 2 -+#define VPE_US_C0_MASK 0x3fff -+#define VPE_US_C0_SHIFT 18 -+#define VPE_US_MODE_MASK 0x03 -+#define VPE_US_MODE_SHIFT 16 -+#define VPE_ANCHOR_FID0_C1_MASK 0x3fff -+#define VPE_ANCHOR_FID0_C1_SHIFT 2 -+#define VPE_ANCHOR_FID0_C0_MASK 0x3fff -+#define VPE_ANCHOR_FID0_C0_SHIFT 18 -+ -+#define VPE_US1_R1 0x0308 -+#define VPE_US2_R1 0x0408 -+#define VPE_US3_R1 0x0508 -+#define VPE_ANCHOR_FID0_C3_MASK 0x3fff -+#define VPE_ANCHOR_FID0_C3_SHIFT 2 -+#define VPE_ANCHOR_FID0_C2_MASK 0x3fff -+#define VPE_ANCHOR_FID0_C2_SHIFT 18 -+ -+#define VPE_US1_R2 0x030c -+#define VPE_US2_R2 0x040c -+#define VPE_US3_R2 0x050c -+#define VPE_INTERP_FID0_C1_MASK 0x3fff -+#define VPE_INTERP_FID0_C1_SHIFT 2 -+#define VPE_INTERP_FID0_C0_MASK 0x3fff -+#define VPE_INTERP_FID0_C0_SHIFT 18 -+ -+#define VPE_US1_R3 0x0310 -+#define VPE_US2_R3 0x0410 -+#define VPE_US3_R3 0x0510 -+#define VPE_INTERP_FID0_C3_MASK 0x3fff -+#define VPE_INTERP_FID0_C3_SHIFT 2 -+#define VPE_INTERP_FID0_C2_MASK 0x3fff -+#define VPE_INTERP_FID0_C2_SHIFT 18 -+ -+#define VPE_US1_R4 0x0314 -+#define VPE_US2_R4 0x0414 -+#define VPE_US3_R4 0x0514 -+#define VPE_ANCHOR_FID1_C1_MASK 0x3fff -+#define VPE_ANCHOR_FID1_C1_SHIFT 2 -+#define VPE_ANCHOR_FID1_C0_MASK 0x3fff -+#define VPE_ANCHOR_FID1_C0_SHIFT 18 -+ -+#define VPE_US1_R5 0x0318 -+#define VPE_US2_R5 0x0418 -+#define VPE_US3_R5 0x0518 -+#define VPE_ANCHOR_FID1_C3_MASK 0x3fff -+#define VPE_ANCHOR_FID1_C3_SHIFT 2 -+#define VPE_ANCHOR_FID1_C2_MASK 0x3fff -+#define VPE_ANCHOR_FID1_C2_SHIFT 18 -+ -+#define VPE_US1_R6 0x031c -+#define VPE_US2_R6 0x041c -+#define VPE_US3_R6 0x051c -+#define VPE_INTERP_FID1_C1_MASK 0x3fff -+#define VPE_INTERP_FID1_C1_SHIFT 2 -+#define VPE_INTERP_FID1_C0_MASK 0x3fff -+#define VPE_INTERP_FID1_C0_SHIFT 18 -+ -+#define VPE_US1_R7 0x0320 -+#define VPE_US2_R7 0x0420 -+#define VPE_US3_R7 0x0520 -+#define VPE_INTERP_FID0_C3_MASK 0x3fff -+#define VPE_INTERP_FID0_C3_SHIFT 2 -+#define VPE_INTERP_FID0_C2_MASK 0x3fff -+#define VPE_INTERP_FID0_C2_SHIFT 18 -+ -+/* VPE de-interlacer regs */ -+#define VPE_DEI_FRAME_SIZE 0x0600 -+#define VPE_DEI_WIDTH_MASK 0x07ff -+#define VPE_DEI_WIDTH_SHIFT 0 -+#define VPE_DEI_HEIGHT_MASK 0x07ff -+#define VPE_DEI_HEIGHT_SHIFT 16 -+#define VPE_DEI_INTERLACE_BYPASS (1 << 29) -+#define VPE_DEI_FIELD_FLUSH (1 << 30) -+#define VPE_DEI_PROGRESSIVE (1 << 31) -+ -+#define VPE_MDT_BYPASS 0x0604 -+#define VPE_MDT_TEMPMAX_BYPASS (1 << 0) -+#define VPE_MDT_SPATMAX_BYPASS (1 << 1) -+ -+#define VPE_MDT_SF_THRESHOLD 0x0608 -+#define VPE_MDT_SF_SC_THR1_MASK 0xff -+#define VPE_MDT_SF_SC_THR1_SHIFT 0 -+#define VPE_MDT_SF_SC_THR2_MASK 0xff -+#define VPE_MDT_SF_SC_THR2_SHIFT 0 -+#define VPE_MDT_SF_SC_THR3_MASK 0xff -+#define VPE_MDT_SF_SC_THR3_SHIFT 0 -+ -+#define VPE_EDI_CONFIG 0x060c -+#define VPE_EDI_INP_MODE_MASK 0x03 -+#define VPE_EDI_INP_MODE_SHIFT 0 -+#define VPE_EDI_ENABLE_3D (1 << 2) -+#define VPE_EDI_ENABLE_CHROMA_3D (1 << 3) -+#define VPE_EDI_CHROMA3D_COR_THR_MASK 0xff -+#define VPE_EDI_CHROMA3D_COR_THR_SHIFT 8 -+#define VPE_EDI_DIR_COR_LOWER_THR_MASK 0xff -+#define VPE_EDI_DIR_COR_LOWER_THR_SHIFT 16 -+#define VPE_EDI_COR_SCALE_FACTOR_MASK 0xff -+#define VPE_EDI_COR_SCALE_FACTOR_SHIFT 23 -+ -+#define VPE_DEI_EDI_LUT_R0 0x0610 -+#define VPE_EDI_LUT0_MASK 0x1f -+#define VPE_EDI_LUT0_SHIFT 0 -+#define VPE_EDI_LUT1_MASK 0x1f -+#define VPE_EDI_LUT1_SHIFT 8 -+#define VPE_EDI_LUT2_MASK 0x1f -+#define VPE_EDI_LUT2_SHIFT 16 -+#define VPE_EDI_LUT3_MASK 0x1f -+#define VPE_EDI_LUT3_SHIFT 24 -+ -+#define VPE_DEI_EDI_LUT_R1 0x0614 -+#define VPE_EDI_LUT0_MASK 0x1f -+#define VPE_EDI_LUT0_SHIFT 0 -+#define VPE_EDI_LUT1_MASK 0x1f -+#define VPE_EDI_LUT1_SHIFT 8 -+#define VPE_EDI_LUT2_MASK 0x1f -+#define VPE_EDI_LUT2_SHIFT 16 -+#define VPE_EDI_LUT3_MASK 0x1f -+#define VPE_EDI_LUT3_SHIFT 24 -+ -+#define VPE_DEI_EDI_LUT_R2 0x0618 -+#define VPE_EDI_LUT4_MASK 0x1f -+#define VPE_EDI_LUT4_SHIFT 0 -+#define VPE_EDI_LUT5_MASK 0x1f -+#define VPE_EDI_LUT5_SHIFT 8 -+#define VPE_EDI_LUT6_MASK 0x1f -+#define VPE_EDI_LUT6_SHIFT 16 -+#define VPE_EDI_LUT7_MASK 0x1f -+#define VPE_EDI_LUT7_SHIFT 24 -+ -+#define VPE_DEI_EDI_LUT_R3 0x061c -+#define VPE_EDI_LUT8_MASK 0x1f -+#define VPE_EDI_LUT8_SHIFT 0 -+#define VPE_EDI_LUT9_MASK 0x1f -+#define VPE_EDI_LUT9_SHIFT 8 -+#define VPE_EDI_LUT10_MASK 0x1f -+#define VPE_EDI_LUT10_SHIFT 16 -+#define VPE_EDI_LUT11_MASK 0x1f -+#define VPE_EDI_LUT11_SHIFT 24 -+ -+#define VPE_DEI_FMD_WINDOW_R0 0x0620 -+#define VPE_FMD_WINDOW_MINX_MASK 0x07ff -+#define VPE_FMD_WINDOW_MINX_SHIFT 0 -+#define VPE_FMD_WINDOW_MAXX_MASK 0x07ff -+#define VPE_FMD_WINDOW_MAXX_SHIFT 16 -+#define VPE_FMD_WINDOW_ENABLE (1 << 31) -+ -+#define VPE_DEI_FMD_WINDOW_R1 0x0624 -+#define VPE_FMD_WINDOW_MINY_MASK 0x07ff -+#define VPE_FMD_WINDOW_MINY_SHIFT 0 -+#define VPE_FMD_WINDOW_MAXY_MASK 0x07ff -+#define VPE_FMD_WINDOW_MAXY_SHIFT 16 -+ -+#define VPE_DEI_FMD_CONTROL_R0 0x0628 -+#define VPE_FMD_ENABLE (1 << 0) -+#define VPE_FMD_LOCK (1 << 1) -+#define VPE_FMD_JAM_DIR (1 << 2) -+#define VPE_FMD_BED_ENABLE (1 << 3) -+#define VPE_FMD_CAF_FIELD_THR_MASK 0xff -+#define VPE_FMD_CAF_FIELD_THR_SHIFT 16 -+#define VPE_FMD_CAF_LINE_THR_MASK 0xff -+#define VPE_FMD_CAF_LINE_THR_SHIFT 24 -+ -+#define VPE_DEI_FMD_CONTROL_R1 0x062c -+#define VPE_FMD_CAF_THR_MASK 0x000fffff -+#define VPE_FMD_CAF_THR_SHIFT 0 -+ -+#define VPE_DEI_FMD_STATUS_R0 0x0630 -+#define VPE_FMD_CAF_MASK 0x000fffff -+#define VPE_FMD_CAF_SHIFT 0 -+#define VPE_FMD_RESET (1 << 24) -+ -+#define VPE_DEI_FMD_STATUS_R1 0x0634 -+#define VPE_FMD_FIELD_DIFF_MASK 0x0fffffff -+#define VPE_FMD_FIELD_DIFF_SHIFT 0 -+ -+#define VPE_DEI_FMD_STATUS_R2 0x0638 -+#define VPE_FMD_FRAME_DIFF_MASK 0x000fffff -+#define VPE_FMD_FRAME_DIFF_SHIFT 0 -+ -+/* VPE scaler regs */ -+#define VPE_SC_MP_SC0 0x0700 -+#define VPE_INTERLACE_O (1 << 0) -+#define VPE_LINEAR (1 << 1) -+#define VPE_SC_BYPASS (1 << 2) -+#define VPE_INVT_FID (1 << 3) -+#define VPE_USE_RAV (1 << 4) -+#define VPE_ENABLE_EV (1 << 5) -+#define VPE_AUTO_HS (1 << 6) -+#define VPE_DCM_2X (1 << 7) -+#define VPE_DCM_4X (1 << 8) -+#define VPE_HP_BYPASS (1 << 9) -+#define VPE_INTERLACE_I (1 << 10) -+#define VPE_ENABLE_SIN2_VER_INTP (1 << 11) -+#define VPE_Y_PK_EN (1 << 14) -+#define VPE_TRIM (1 << 15) -+#define VPE_SELFGEN_FID (1 << 16) -+ -+#define VPE_SC_MP_SC1 0x0704 -+#define VPE_ROW_ACC_INC_MASK 0x07ffffff -+#define VPE_ROW_ACC_INC_SHIFT 0 -+ -+#define VPE_SC_MP_SC2 0x0708 -+#define VPE_ROW_ACC_OFFSET_MASK 0x0fffffff -+#define VPE_ROW_ACC_OFFSET_SHIFT 0 -+ -+#define VPE_SC_MP_SC3 0x070c -+#define VPE_ROW_ACC_OFFSET_B_MASK 0x0fffffff -+#define VPE_ROW_ACC_OFFSET_B_SHIFT 0 -+ -+#define VPE_SC_MP_SC4 0x0710 -+#define VPE_TAR_H_MASK 0x07ff -+#define VPE_TAR_H_SHIFT 0 -+#define VPE_TAR_W_MASK 0x07ff -+#define VPE_TAR_W_SHIFT 12 -+#define VPE_LIN_ACC_INC_U_MASK 0x07 -+#define VPE_LIN_ACC_INC_U_SHIFT 24 -+#define VPE_NLIN_ACC_INIT_U_MASK 0x07 -+#define VPE_NLIN_ACC_INIT_U_SHIFT 28 -+ -+#define VPE_SC_MP_SC5 0x0714 -+#define VPE_SRC_H_MASK 0x07ff -+#define VPE_SRC_H_SHIFT 0 -+#define VPE_SRC_W_MASK 0x07ff -+#define VPE_SRC_W_SHIFT 12 -+#define VPE_NLIN_ACC_INC_U_MASK 0x07 -+#define VPE_NLIN_ACC_INC_U_SHIFT 24 -+ -+#define VPE_SC_MP_SC6 0x0718 -+#define VPE_ROW_ACC_INIT_RAV_MASK 0x03ff -+#define VPE_ROW_ACC_INIT_RAV_SHIFT 0 -+#define VPE_ROW_ACC_INIT_RAV_B_MASK 0x03ff -+#define VPE_ROW_ACC_INIT_RAV_B_SHIFT 10 -+ -+#define VPE_SC_MP_SC8 0x0720 -+#define VPE_NLIN_LEFT_MASK 0x07ff -+#define VPE_NLIN_LEFT_SHIFT 0 -+#define VPE_NLIN_RIGHT_MASK 0x07ff -+#define VPE_NLIN_RIGHT_SHIFT 12 -+ -+#define VPE_SC_MP_SC9 0x0724 -+#define VPE_LIN_ACC_INC VPE_SC_MP_SC9 -+ -+#define VPE_SC_MP_SC10 0x0728 -+#define VPE_NLIN_ACC_INIT VPE_SC_MP_SC10 -+ -+#define VPE_SC_MP_SC11 0x072c -+#define VPE_NLIN_ACC_INC VPE_SC_MP_SC11 -+ -+#define VPE_SC_MP_SC12 0x0730 -+#define VPE_COL_ACC_OFFSET_MASK 0x01ffffff -+#define VPE_COL_ACC_OFFSET_SHIFT 0 -+ -+#define VPE_SC_MP_SC13 0x0734 -+#define VPE_SC_FACTOR_RAV_MASK 0x03ff -+#define VPE_SC_FACTOR_RAV_SHIFT 0 -+#define VPE_CHROMA_INTP_THR_MASK 0x03ff -+#define VPE_CHROMA_INTP_THR_SHIFT 12 -+#define VPE_DELTA_CHROMA_THR_MASK 0x0f -+#define VPE_DELTA_CHROMA_THR_SHIFT 24 -+ -+#define VPE_SC_MP_SC17 0x0744 -+#define VPE_EV_THR_MASK 0x03ff -+#define VPE_EV_THR_SHIFT 12 -+#define VPE_DELTA_LUMA_THR_MASK 0x0f -+#define VPE_DELTA_LUMA_THR_SHIFT 24 -+#define VPE_DELTA_EV_THR_MASK 0x0f -+#define VPE_DELTA_EV_THR_SHIFT 28 -+ -+#define VPE_SC_MP_SC18 0x0748 -+#define VPE_HS_FACTOR_MASK 0x03ff -+#define VPE_HS_FACTOR_SHIFT 0 -+#define VPE_CONF_DEFAULT_MASK 0x01ff -+#define VPE_CONF_DEFAULT_SHIFT 16 -+ -+#define VPE_SC_MP_SC19 0x074c -+#define VPE_HPF_COEFF0_MASK 0xff -+#define VPE_HPF_COEFF0_SHIFT 0 -+#define VPE_HPF_COEFF1_MASK 0xff -+#define VPE_HPF_COEFF1_SHIFT 8 -+#define VPE_HPF_COEFF2_MASK 0xff -+#define VPE_HPF_COEFF2_SHIFT 16 -+#define VPE_HPF_COEFF3_MASK 0xff -+#define VPE_HPF_COEFF3_SHIFT 23 -+ -+#define VPE_SC_MP_SC20 0x0750 -+#define VPE_HPF_COEFF4_MASK 0xff -+#define VPE_HPF_COEFF4_SHIFT 0 -+#define VPE_HPF_COEFF5_MASK 0xff -+#define VPE_HPF_COEFF5_SHIFT 8 -+#define VPE_HPF_NORM_SHIFT_MASK 0x07 -+#define VPE_HPF_NORM_SHIFT_SHIFT 16 -+#define VPE_NL_LIMIT_MASK 0x1ff -+#define VPE_NL_LIMIT_SHIFT 20 -+ -+#define VPE_SC_MP_SC21 0x0754 -+#define VPE_NL_LO_THR_MASK 0x01ff -+#define VPE_NL_LO_THR_SHIFT 0 -+#define VPE_NL_LO_SLOPE_MASK 0xff -+#define VPE_NL_LO_SLOPE_SHIFT 16 -+ -+#define VPE_SC_MP_SC22 0x0758 -+#define VPE_NL_HI_THR_MASK 0x01ff -+#define VPE_NL_HI_THR_SHIFT 0 -+#define VPE_NL_HI_SLOPE_SH_MASK 0x07 -+#define VPE_NL_HI_SLOPE_SH_SHIFT 16 -+ -+#define VPE_SC_MP_SC23 0x075c -+#define VPE_GRADIENT_THR_MASK 0x07ff -+#define VPE_GRADIENT_THR_SHIFT 0 -+#define VPE_GRADIENT_THR_RANGE_MASK 0x0f -+#define VPE_GRADIENT_THR_RANGE_SHIFT 12 -+#define VPE_MIN_GY_THR_MASK 0xff -+#define VPE_MIN_GY_THR_SHIFT 16 -+#define VPE_MIN_GY_THR_RANGE_MASK 0x0f -+#define VPE_MIN_GY_THR_RANGE_SHIFT 28 -+ -+#define VPE_SC_MP_SC24 0x0760 -+#define VPE_ORG_H_MASK 0x07ff -+#define VPE_ORG_H_SHIFT 0 -+#define VPE_ORG_W_MASK 0x07ff -+#define VPE_ORG_W_SHIFT 16 -+ -+#define VPE_SC_MP_SC25 0x0764 -+#define VPE_OFF_H_MASK 0x07ff -+#define VPE_OFF_H_SHIFT 0 -+#define VPE_OFF_W_MASK 0x07ff -+#define VPE_OFF_W_SHIFT 16 -+ -+/* VPE color space converter regs */ -+#define VPE_CSC_CSC00 0x5700 -+#define VPE_CSC_A0_MASK 0x1fff -+#define VPE_CSC_A0_SHIFT 0 -+#define VPE_CSC_B0_MASK 0x1fff -+#define VPE_CSC_B0_SHIFT 16 -+ -+#define VPE_CSC_CSC01 0x5704 -+#define VPE_CSC_C0_MASK 0x1fff -+#define VPE_CSC_C0_SHIFT 0 -+#define VPE_CSC_A1_MASK 0x1fff -+#define VPE_CSC_A1_SHIFT 16 -+ -+#define VPE_CSC_CSC02 0x5708 -+#define VPE_CSC_B1_MASK 0x1fff -+#define VPE_CSC_B1_SHIFT 0 -+#define VPE_CSC_C1_MASK 0x1fff -+#define VPE_CSC_C1_SHIFT 16 -+ -+#define VPE_CSC_CSC03 0x570c -+#define VPE_CSC_A2_MASK 0x1fff -+#define VPE_CSC_A2_SHIFT 0 -+#define VPE_CSC_B2_MASK 0x1fff -+#define VPE_CSC_B2_SHIFT 16 -+ -+#define VPE_CSC_CSC04 0x5710 -+#define VPE_CSC_C2_MASK 0x1fff -+#define VPE_CSC_C2_SHIFT 0 -+#define VPE_CSC_D0_MASK 0x0fff -+#define VPE_CSC_D0_SHIFT 16 -+ -+#define VPE_CSC_CSC05 0x5714 -+#define VPE_CSC_D1_MASK 0x0fff -+#define VPE_CSC_D1_SHIFT 0 -+#define VPE_CSC_D2_MASK 0x0fff -+#define VPE_CSC_D2_SHIFT 16 -+#define VPE_CSC_BYPASS (1 << 28) -+ -+#endif ---- a/drivers/memory/emif.h -+++ b/drivers/memory/emif.h -@@ -12,548 +12,7 @@ - #ifndef __EMIF_H - #define __EMIF_H - --/* -- * Maximum number of different frequencies supported by EMIF driver -- * Determines the number of entries in the pointer array for register -- * cache -- */ --#define EMIF_MAX_NUM_FREQUENCIES 6 -- --/* State of the core voltage */ --#define DDR_VOLTAGE_STABLE 0 --#define DDR_VOLTAGE_RAMPING 1 -- --/* Defines for timing De-rating */ --#define EMIF_NORMAL_TIMINGS 0 --#define EMIF_DERATED_TIMINGS 1 -- --/* Length of the forced read idle period in terms of cycles */ --#define EMIF_READ_IDLE_LEN_VAL 5 -- --/* -- * forced read idle interval to be used when voltage -- * is changed as part of DVFS/DPS - 1ms -- */ --#define READ_IDLE_INTERVAL_DVFS (1*1000000) -- --/* -- * Forced read idle interval to be used when voltage is stable -- * 50us - or maximum value will do -- */ --#define READ_IDLE_INTERVAL_NORMAL (50*1000000) -- --/* DLL calibration interval when voltage is NOT stable - 1us */ --#define DLL_CALIB_INTERVAL_DVFS (1*1000000) -- --#define DLL_CALIB_ACK_WAIT_VAL 5 -- --/* Interval between ZQCS commands - hw team recommended value */ --#define EMIF_ZQCS_INTERVAL_US (50*1000) --/* Enable ZQ Calibration on exiting Self-refresh */ --#define ZQ_SFEXITEN_ENABLE 1 --/* -- * ZQ Calibration simultaneously on both chip-selects: -- * Needs one calibration resistor per CS -- */ --#define ZQ_DUALCALEN_DISABLE 0 --#define ZQ_DUALCALEN_ENABLE 1 -- --#define T_ZQCS_DEFAULT_NS 90 --#define T_ZQCL_DEFAULT_NS 360 --#define T_ZQINIT_DEFAULT_NS 1000 -- --/* DPD_EN */ --#define DPD_DISABLE 0 --#define DPD_ENABLE 1 -- --/* -- * Default values for the low-power entry to be used if not provided by user. -- * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512 -- * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz -- */ --#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE 2048 --#define EMIF_LP_MODE_TIMEOUT_POWER 512 --#define EMIF_LP_MODE_FREQ_THRESHOLD 400000000 -- --/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */ --#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY 0x049FF000 --#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY 0x41 --#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY 0x80 --#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF -- --/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */ --#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY 0x0E084200 --#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS 10000 -- --/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */ --#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS 360 -- --#define EMIF_T_CSTA 3 --#define EMIF_T_PDLL_UL 128 -- --/* External PHY control registers magic values */ --#define EMIF_EXT_PHY_CTRL_1_VAL 0x04020080 --#define EMIF_EXT_PHY_CTRL_5_VAL 0x04010040 --#define EMIF_EXT_PHY_CTRL_6_VAL 0x01004010 --#define EMIF_EXT_PHY_CTRL_7_VAL 0x00001004 --#define EMIF_EXT_PHY_CTRL_8_VAL 0x04010040 --#define EMIF_EXT_PHY_CTRL_9_VAL 0x01004010 --#define EMIF_EXT_PHY_CTRL_10_VAL 0x00001004 --#define EMIF_EXT_PHY_CTRL_11_VAL 0x00000000 --#define EMIF_EXT_PHY_CTRL_12_VAL 0x00000000 --#define EMIF_EXT_PHY_CTRL_13_VAL 0x00000000 --#define EMIF_EXT_PHY_CTRL_14_VAL 0x80080080 --#define EMIF_EXT_PHY_CTRL_15_VAL 0x00800800 --#define EMIF_EXT_PHY_CTRL_16_VAL 0x08102040 --#define EMIF_EXT_PHY_CTRL_17_VAL 0x00000001 --#define EMIF_EXT_PHY_CTRL_18_VAL 0x540A8150 --#define EMIF_EXT_PHY_CTRL_19_VAL 0xA81502A0 --#define EMIF_EXT_PHY_CTRL_20_VAL 0x002A0540 --#define EMIF_EXT_PHY_CTRL_21_VAL 0x00000000 --#define EMIF_EXT_PHY_CTRL_22_VAL 0x00000000 --#define EMIF_EXT_PHY_CTRL_23_VAL 0x00000000 --#define EMIF_EXT_PHY_CTRL_24_VAL 0x00000077 -- --#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS 1200 -- --/* Registers offset */ --#define EMIF_MODULE_ID_AND_REVISION 0x0000 --#define EMIF_STATUS 0x0004 --#define EMIF_SDRAM_CONFIG 0x0008 --#define EMIF_SDRAM_CONFIG_2 0x000c --#define EMIF_SDRAM_REFRESH_CONTROL 0x0010 --#define EMIF_SDRAM_REFRESH_CTRL_SHDW 0x0014 --#define EMIF_SDRAM_TIMING_1 0x0018 --#define EMIF_SDRAM_TIMING_1_SHDW 0x001c --#define EMIF_SDRAM_TIMING_2 0x0020 --#define EMIF_SDRAM_TIMING_2_SHDW 0x0024 --#define EMIF_SDRAM_TIMING_3 0x0028 --#define EMIF_SDRAM_TIMING_3_SHDW 0x002c --#define EMIF_LPDDR2_NVM_TIMING 0x0030 --#define EMIF_LPDDR2_NVM_TIMING_SHDW 0x0034 --#define EMIF_POWER_MANAGEMENT_CONTROL 0x0038 --#define EMIF_POWER_MANAGEMENT_CTRL_SHDW 0x003c --#define EMIF_LPDDR2_MODE_REG_DATA 0x0040 --#define EMIF_LPDDR2_MODE_REG_CONFIG 0x0050 --#define EMIF_OCP_CONFIG 0x0054 --#define EMIF_OCP_CONFIG_VALUE_1 0x0058 --#define EMIF_OCP_CONFIG_VALUE_2 0x005c --#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL 0x0060 --#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT 0x0064 --#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT 0x0068 --#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1 0x006c --#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2 0x0070 --#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3 0x0074 --#define EMIF_PERFORMANCE_COUNTER_1 0x0080 --#define EMIF_PERFORMANCE_COUNTER_2 0x0084 --#define EMIF_PERFORMANCE_COUNTER_CONFIG 0x0088 --#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT 0x008c --#define EMIF_PERFORMANCE_COUNTER_TIME 0x0090 --#define EMIF_MISC_REG 0x0094 --#define EMIF_DLL_CALIB_CTRL 0x0098 --#define EMIF_DLL_CALIB_CTRL_SHDW 0x009c --#define EMIF_END_OF_INTERRUPT 0x00a0 --#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS 0x00a4 --#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS 0x00a8 --#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS 0x00ac --#define EMIF_LL_OCP_INTERRUPT_STATUS 0x00b0 --#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET 0x00b4 --#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET 0x00b8 --#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR 0x00bc --#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR 0x00c0 --#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG 0x00c8 --#define EMIF_TEMPERATURE_ALERT_CONFIG 0x00cc --#define EMIF_OCP_ERROR_LOG 0x00d0 --#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW 0x00d4 --#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL 0x00d8 --#define EMIF_READ_WRITE_LEVELING_CONTROL 0x00dc --#define EMIF_DDR_PHY_CTRL_1 0x00e4 --#define EMIF_DDR_PHY_CTRL_1_SHDW 0x00e8 --#define EMIF_DDR_PHY_CTRL_2 0x00ec --#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING 0x0100 --#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104 --#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108 --#define EMIF_READ_WRITE_EXECUTION_THRESHOLD 0x0120 --#define EMIF_COS_CONFIG 0x0124 --#define EMIF_PHY_STATUS_1 0x0140 --#define EMIF_PHY_STATUS_2 0x0144 --#define EMIF_PHY_STATUS_3 0x0148 --#define EMIF_PHY_STATUS_4 0x014c --#define EMIF_PHY_STATUS_5 0x0150 --#define EMIF_PHY_STATUS_6 0x0154 --#define EMIF_PHY_STATUS_7 0x0158 --#define EMIF_PHY_STATUS_8 0x015c --#define EMIF_PHY_STATUS_9 0x0160 --#define EMIF_PHY_STATUS_10 0x0164 --#define EMIF_PHY_STATUS_11 0x0168 --#define EMIF_PHY_STATUS_12 0x016c --#define EMIF_PHY_STATUS_13 0x0170 --#define EMIF_PHY_STATUS_14 0x0174 --#define EMIF_PHY_STATUS_15 0x0178 --#define EMIF_PHY_STATUS_16 0x017c --#define EMIF_PHY_STATUS_17 0x0180 --#define EMIF_PHY_STATUS_18 0x0184 --#define EMIF_PHY_STATUS_19 0x0188 --#define EMIF_PHY_STATUS_20 0x018c --#define EMIF_PHY_STATUS_21 0x0190 --#define EMIF_EXT_PHY_CTRL_1 0x0200 --#define EMIF_EXT_PHY_CTRL_1_SHDW 0x0204 --#define EMIF_EXT_PHY_CTRL_2 0x0208 --#define EMIF_EXT_PHY_CTRL_2_SHDW 0x020c --#define EMIF_EXT_PHY_CTRL_3 0x0210 --#define EMIF_EXT_PHY_CTRL_3_SHDW 0x0214 --#define EMIF_EXT_PHY_CTRL_4 0x0218 --#define EMIF_EXT_PHY_CTRL_4_SHDW 0x021c --#define EMIF_EXT_PHY_CTRL_5 0x0220 --#define EMIF_EXT_PHY_CTRL_5_SHDW 0x0224 --#define EMIF_EXT_PHY_CTRL_6 0x0228 --#define EMIF_EXT_PHY_CTRL_6_SHDW 0x022c --#define EMIF_EXT_PHY_CTRL_7 0x0230 --#define EMIF_EXT_PHY_CTRL_7_SHDW 0x0234 --#define EMIF_EXT_PHY_CTRL_8 0x0238 --#define EMIF_EXT_PHY_CTRL_8_SHDW 0x023c --#define EMIF_EXT_PHY_CTRL_9 0x0240 --#define EMIF_EXT_PHY_CTRL_9_SHDW 0x0244 --#define EMIF_EXT_PHY_CTRL_10 0x0248 --#define EMIF_EXT_PHY_CTRL_10_SHDW 0x024c --#define EMIF_EXT_PHY_CTRL_11 0x0250 --#define EMIF_EXT_PHY_CTRL_11_SHDW 0x0254 --#define EMIF_EXT_PHY_CTRL_12 0x0258 --#define EMIF_EXT_PHY_CTRL_12_SHDW 0x025c --#define EMIF_EXT_PHY_CTRL_13 0x0260 --#define EMIF_EXT_PHY_CTRL_13_SHDW 0x0264 --#define EMIF_EXT_PHY_CTRL_14 0x0268 --#define EMIF_EXT_PHY_CTRL_14_SHDW 0x026c --#define EMIF_EXT_PHY_CTRL_15 0x0270 --#define EMIF_EXT_PHY_CTRL_15_SHDW 0x0274 --#define EMIF_EXT_PHY_CTRL_16 0x0278 --#define EMIF_EXT_PHY_CTRL_16_SHDW 0x027c --#define EMIF_EXT_PHY_CTRL_17 0x0280 --#define EMIF_EXT_PHY_CTRL_17_SHDW 0x0284 --#define EMIF_EXT_PHY_CTRL_18 0x0288 --#define EMIF_EXT_PHY_CTRL_18_SHDW 0x028c --#define EMIF_EXT_PHY_CTRL_19 0x0290 --#define EMIF_EXT_PHY_CTRL_19_SHDW 0x0294 --#define EMIF_EXT_PHY_CTRL_20 0x0298 --#define EMIF_EXT_PHY_CTRL_20_SHDW 0x029c --#define EMIF_EXT_PHY_CTRL_21 0x02a0 --#define EMIF_EXT_PHY_CTRL_21_SHDW 0x02a4 --#define EMIF_EXT_PHY_CTRL_22 0x02a8 --#define EMIF_EXT_PHY_CTRL_22_SHDW 0x02ac --#define EMIF_EXT_PHY_CTRL_23 0x02b0 --#define EMIF_EXT_PHY_CTRL_23_SHDW 0x02b4 --#define EMIF_EXT_PHY_CTRL_24 0x02b8 --#define EMIF_EXT_PHY_CTRL_24_SHDW 0x02bc --#define EMIF_EXT_PHY_CTRL_25 0x02c0 --#define EMIF_EXT_PHY_CTRL_25_SHDW 0x02c4 --#define EMIF_EXT_PHY_CTRL_26 0x02c8 --#define EMIF_EXT_PHY_CTRL_26_SHDW 0x02cc --#define EMIF_EXT_PHY_CTRL_27 0x02d0 --#define EMIF_EXT_PHY_CTRL_27_SHDW 0x02d4 --#define EMIF_EXT_PHY_CTRL_28 0x02d8 --#define EMIF_EXT_PHY_CTRL_28_SHDW 0x02dc --#define EMIF_EXT_PHY_CTRL_29 0x02e0 --#define EMIF_EXT_PHY_CTRL_29_SHDW 0x02e4 --#define EMIF_EXT_PHY_CTRL_30 0x02e8 --#define EMIF_EXT_PHY_CTRL_30_SHDW 0x02ec -- --/* Registers shifts and masks */ -- --/* EMIF_MODULE_ID_AND_REVISION */ --#define SCHEME_SHIFT 30 --#define SCHEME_MASK (0x3 << 30) --#define MODULE_ID_SHIFT 16 --#define MODULE_ID_MASK (0xfff << 16) --#define RTL_VERSION_SHIFT 11 --#define RTL_VERSION_MASK (0x1f << 11) --#define MAJOR_REVISION_SHIFT 8 --#define MAJOR_REVISION_MASK (0x7 << 8) --#define MINOR_REVISION_SHIFT 0 --#define MINOR_REVISION_MASK (0x3f << 0) -- --/* STATUS */ --#define BE_SHIFT 31 --#define BE_MASK (1 << 31) --#define DUAL_CLK_MODE_SHIFT 30 --#define DUAL_CLK_MODE_MASK (1 << 30) --#define FAST_INIT_SHIFT 29 --#define FAST_INIT_MASK (1 << 29) --#define RDLVLGATETO_SHIFT 6 --#define RDLVLGATETO_MASK (1 << 6) --#define RDLVLTO_SHIFT 5 --#define RDLVLTO_MASK (1 << 5) --#define WRLVLTO_SHIFT 4 --#define WRLVLTO_MASK (1 << 4) --#define PHY_DLL_READY_SHIFT 2 --#define PHY_DLL_READY_MASK (1 << 2) -- --/* SDRAM_CONFIG */ --#define SDRAM_TYPE_SHIFT 29 --#define SDRAM_TYPE_MASK (0x7 << 29) --#define IBANK_POS_SHIFT 27 --#define IBANK_POS_MASK (0x3 << 27) --#define DDR_TERM_SHIFT 24 --#define DDR_TERM_MASK (0x7 << 24) --#define DDR2_DDQS_SHIFT 23 --#define DDR2_DDQS_MASK (1 << 23) --#define DYN_ODT_SHIFT 21 --#define DYN_ODT_MASK (0x3 << 21) --#define DDR_DISABLE_DLL_SHIFT 20 --#define DDR_DISABLE_DLL_MASK (1 << 20) --#define SDRAM_DRIVE_SHIFT 18 --#define SDRAM_DRIVE_MASK (0x3 << 18) --#define CWL_SHIFT 16 --#define CWL_MASK (0x3 << 16) --#define NARROW_MODE_SHIFT 14 --#define NARROW_MODE_MASK (0x3 << 14) --#define CL_SHIFT 10 --#define CL_MASK (0xf << 10) --#define ROWSIZE_SHIFT 7 --#define ROWSIZE_MASK (0x7 << 7) --#define IBANK_SHIFT 4 --#define IBANK_MASK (0x7 << 4) --#define EBANK_SHIFT 3 --#define EBANK_MASK (1 << 3) --#define PAGESIZE_SHIFT 0 --#define PAGESIZE_MASK (0x7 << 0) -- --/* SDRAM_CONFIG_2 */ --#define CS1NVMEN_SHIFT 30 --#define CS1NVMEN_MASK (1 << 30) --#define EBANK_POS_SHIFT 27 --#define EBANK_POS_MASK (1 << 27) --#define RDBNUM_SHIFT 4 --#define RDBNUM_MASK (0x3 << 4) --#define RDBSIZE_SHIFT 0 --#define RDBSIZE_MASK (0x7 << 0) -- --/* SDRAM_REFRESH_CONTROL */ --#define INITREF_DIS_SHIFT 31 --#define INITREF_DIS_MASK (1 << 31) --#define SRT_SHIFT 29 --#define SRT_MASK (1 << 29) --#define ASR_SHIFT 28 --#define ASR_MASK (1 << 28) --#define PASR_SHIFT 24 --#define PASR_MASK (0x7 << 24) --#define REFRESH_RATE_SHIFT 0 --#define REFRESH_RATE_MASK (0xffff << 0) -- --/* SDRAM_TIMING_1 */ --#define T_RTW_SHIFT 29 --#define T_RTW_MASK (0x7 << 29) --#define T_RP_SHIFT 25 --#define T_RP_MASK (0xf << 25) --#define T_RCD_SHIFT 21 --#define T_RCD_MASK (0xf << 21) --#define T_WR_SHIFT 17 --#define T_WR_MASK (0xf << 17) --#define T_RAS_SHIFT 12 --#define T_RAS_MASK (0x1f << 12) --#define T_RC_SHIFT 6 --#define T_RC_MASK (0x3f << 6) --#define T_RRD_SHIFT 3 --#define T_RRD_MASK (0x7 << 3) --#define T_WTR_SHIFT 0 --#define T_WTR_MASK (0x7 << 0) -- --/* SDRAM_TIMING_2 */ --#define T_XP_SHIFT 28 --#define T_XP_MASK (0x7 << 28) --#define T_ODT_SHIFT 25 --#define T_ODT_MASK (0x7 << 25) --#define T_XSNR_SHIFT 16 --#define T_XSNR_MASK (0x1ff << 16) --#define T_XSRD_SHIFT 6 --#define T_XSRD_MASK (0x3ff << 6) --#define T_RTP_SHIFT 3 --#define T_RTP_MASK (0x7 << 3) --#define T_CKE_SHIFT 0 --#define T_CKE_MASK (0x7 << 0) -- --/* SDRAM_TIMING_3 */ --#define T_PDLL_UL_SHIFT 28 --#define T_PDLL_UL_MASK (0xf << 28) --#define T_CSTA_SHIFT 24 --#define T_CSTA_MASK (0xf << 24) --#define T_CKESR_SHIFT 21 --#define T_CKESR_MASK (0x7 << 21) --#define ZQ_ZQCS_SHIFT 15 --#define ZQ_ZQCS_MASK (0x3f << 15) --#define T_TDQSCKMAX_SHIFT 13 --#define T_TDQSCKMAX_MASK (0x3 << 13) --#define T_RFC_SHIFT 4 --#define T_RFC_MASK (0x1ff << 4) --#define T_RAS_MAX_SHIFT 0 --#define T_RAS_MAX_MASK (0xf << 0) -- --/* POWER_MANAGEMENT_CONTROL */ --#define PD_TIM_SHIFT 12 --#define PD_TIM_MASK (0xf << 12) --#define DPD_EN_SHIFT 11 --#define DPD_EN_MASK (1 << 11) --#define LP_MODE_SHIFT 8 --#define LP_MODE_MASK (0x7 << 8) --#define SR_TIM_SHIFT 4 --#define SR_TIM_MASK (0xf << 4) --#define CS_TIM_SHIFT 0 --#define CS_TIM_MASK (0xf << 0) -- --/* LPDDR2_MODE_REG_DATA */ --#define VALUE_0_SHIFT 0 --#define VALUE_0_MASK (0x7f << 0) -- --/* LPDDR2_MODE_REG_CONFIG */ --#define CS_SHIFT 31 --#define CS_MASK (1 << 31) --#define REFRESH_EN_SHIFT 30 --#define REFRESH_EN_MASK (1 << 30) --#define ADDRESS_SHIFT 0 --#define ADDRESS_MASK (0xff << 0) -- --/* OCP_CONFIG */ --#define SYS_THRESH_MAX_SHIFT 24 --#define SYS_THRESH_MAX_MASK (0xf << 24) --#define MPU_THRESH_MAX_SHIFT 20 --#define MPU_THRESH_MAX_MASK (0xf << 20) --#define LL_THRESH_MAX_SHIFT 16 --#define LL_THRESH_MAX_MASK (0xf << 16) -- --/* PERFORMANCE_COUNTER_1 */ --#define COUNTER1_SHIFT 0 --#define COUNTER1_MASK (0xffffffff << 0) -- --/* PERFORMANCE_COUNTER_2 */ --#define COUNTER2_SHIFT 0 --#define COUNTER2_MASK (0xffffffff << 0) -- --/* PERFORMANCE_COUNTER_CONFIG */ --#define CNTR2_MCONNID_EN_SHIFT 31 --#define CNTR2_MCONNID_EN_MASK (1 << 31) --#define CNTR2_REGION_EN_SHIFT 30 --#define CNTR2_REGION_EN_MASK (1 << 30) --#define CNTR2_CFG_SHIFT 16 --#define CNTR2_CFG_MASK (0xf << 16) --#define CNTR1_MCONNID_EN_SHIFT 15 --#define CNTR1_MCONNID_EN_MASK (1 << 15) --#define CNTR1_REGION_EN_SHIFT 14 --#define CNTR1_REGION_EN_MASK (1 << 14) --#define CNTR1_CFG_SHIFT 0 --#define CNTR1_CFG_MASK (0xf << 0) -- --/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */ --#define MCONNID2_SHIFT 24 --#define MCONNID2_MASK (0xff << 24) --#define REGION_SEL2_SHIFT 16 --#define REGION_SEL2_MASK (0x3 << 16) --#define MCONNID1_SHIFT 8 --#define MCONNID1_MASK (0xff << 8) --#define REGION_SEL1_SHIFT 0 --#define REGION_SEL1_MASK (0x3 << 0) -- --/* PERFORMANCE_COUNTER_TIME */ --#define TOTAL_TIME_SHIFT 0 --#define TOTAL_TIME_MASK (0xffffffff << 0) -- --/* DLL_CALIB_CTRL */ --#define ACK_WAIT_SHIFT 16 --#define ACK_WAIT_MASK (0xf << 16) --#define DLL_CALIB_INTERVAL_SHIFT 0 --#define DLL_CALIB_INTERVAL_MASK (0x1ff << 0) -- --/* END_OF_INTERRUPT */ --#define EOI_SHIFT 0 --#define EOI_MASK (1 << 0) -- --/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */ --#define DNV_SYS_SHIFT 2 --#define DNV_SYS_MASK (1 << 2) --#define TA_SYS_SHIFT 1 --#define TA_SYS_MASK (1 << 1) --#define ERR_SYS_SHIFT 0 --#define ERR_SYS_MASK (1 << 0) -- --/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */ --#define DNV_LL_SHIFT 2 --#define DNV_LL_MASK (1 << 2) --#define TA_LL_SHIFT 1 --#define TA_LL_MASK (1 << 1) --#define ERR_LL_SHIFT 0 --#define ERR_LL_MASK (1 << 0) -- --/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */ --#define EN_DNV_SYS_SHIFT 2 --#define EN_DNV_SYS_MASK (1 << 2) --#define EN_TA_SYS_SHIFT 1 --#define EN_TA_SYS_MASK (1 << 1) --#define EN_ERR_SYS_SHIFT 0 --#define EN_ERR_SYS_MASK (1 << 0) -- --/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */ --#define EN_DNV_LL_SHIFT 2 --#define EN_DNV_LL_MASK (1 << 2) --#define EN_TA_LL_SHIFT 1 --#define EN_TA_LL_MASK (1 << 1) --#define EN_ERR_LL_SHIFT 0 --#define EN_ERR_LL_MASK (1 << 0) -- --/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */ --#define ZQ_CS1EN_SHIFT 31 --#define ZQ_CS1EN_MASK (1 << 31) --#define ZQ_CS0EN_SHIFT 30 --#define ZQ_CS0EN_MASK (1 << 30) --#define ZQ_DUALCALEN_SHIFT 29 --#define ZQ_DUALCALEN_MASK (1 << 29) --#define ZQ_SFEXITEN_SHIFT 28 --#define ZQ_SFEXITEN_MASK (1 << 28) --#define ZQ_ZQINIT_MULT_SHIFT 18 --#define ZQ_ZQINIT_MULT_MASK (0x3 << 18) --#define ZQ_ZQCL_MULT_SHIFT 16 --#define ZQ_ZQCL_MULT_MASK (0x3 << 16) --#define ZQ_REFINTERVAL_SHIFT 0 --#define ZQ_REFINTERVAL_MASK (0xffff << 0) -- --/* TEMPERATURE_ALERT_CONFIG */ --#define TA_CS1EN_SHIFT 31 --#define TA_CS1EN_MASK (1 << 31) --#define TA_CS0EN_SHIFT 30 --#define TA_CS0EN_MASK (1 << 30) --#define TA_SFEXITEN_SHIFT 28 --#define TA_SFEXITEN_MASK (1 << 28) --#define TA_DEVWDT_SHIFT 26 --#define TA_DEVWDT_MASK (0x3 << 26) --#define TA_DEVCNT_SHIFT 24 --#define TA_DEVCNT_MASK (0x3 << 24) --#define TA_REFINTERVAL_SHIFT 0 --#define TA_REFINTERVAL_MASK (0x3fffff << 0) -- --/* OCP_ERROR_LOG */ --#define MADDRSPACE_SHIFT 14 --#define MADDRSPACE_MASK (0x3 << 14) --#define MBURSTSEQ_SHIFT 11 --#define MBURSTSEQ_MASK (0x7 << 11) --#define MCMD_SHIFT 8 --#define MCMD_MASK (0x7 << 8) --#define MCONNID_SHIFT 0 --#define MCONNID_MASK (0xff << 0) -- --/* DDR_PHY_CTRL_1 - EMIF4D */ --#define DLL_SLAVE_DLY_CTRL_SHIFT_4D 4 --#define DLL_SLAVE_DLY_CTRL_MASK_4D (0xFF << 4) --#define READ_LATENCY_SHIFT_4D 0 --#define READ_LATENCY_MASK_4D (0xf << 0) -- --/* DDR_PHY_CTRL_1 - EMIF4D5 */ --#define DLL_HALF_DELAY_SHIFT_4D5 21 --#define DLL_HALF_DELAY_MASK_4D5 (1 << 21) --#define READ_LATENCY_SHIFT_4D5 0 --#define READ_LATENCY_MASK_4D5 (0x1f << 0) -- --/* DDR_PHY_CTRL_1_SHDW */ --#define DDR_PHY_CTRL_1_SHDW_SHIFT 5 --#define DDR_PHY_CTRL_1_SHDW_MASK (0x7ffffff << 5) --#define READ_LATENCY_SHDW_SHIFT 0 --#define READ_LATENCY_SHDW_MASK (0x1f << 0) -+#include <linux/ti_emif.h> - - #ifndef __ASSEMBLY__ - /* ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -821,6 +821,17 @@ config MFD_TPS65217 - This driver can also be built as a module. If so, the module - will be called tps65217. - -+config MFD_TPS65218 -+ bool "TI TPS65218 Power Management chips" -+ depends on I2C -+ select MFD_CORE -+ select REGMAP_I2C -+ help -+ If you say yes here you get support for the TPS65218 series of -+ Power Management chips. -+ These include voltage regulators, gpio and other features -+ that are often used in portable devices. -+ - config MFD_TPS6586X - bool "TI TPS6586x Power Management chips" - depends on I2C=y ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -62,6 +62,7 @@ obj-$(CONFIG_TPS6105X) += tps6105x.o - obj-$(CONFIG_TPS65010) += tps65010.o - obj-$(CONFIG_TPS6507X) += tps6507x.o - obj-$(CONFIG_MFD_TPS65217) += tps65217.o -+obj-$(CONFIG_MFD_TPS65218) += tps65218.o - obj-$(CONFIG_MFD_TPS65910) += tps65910.o - tps65912-objs := tps65912-core.o tps65912-irq.o - obj-$(CONFIG_MFD_TPS65912) += tps65912.o ---- a/drivers/mfd/omap-usb-host.c -+++ b/drivers/mfd/omap-usb-host.c -@@ -328,13 +328,13 @@ static int usbhs_runtime_resume(struct d - omap_tll_enable(pdata); - - if (!IS_ERR(omap->ehci_logic_fck)) -- clk_enable(omap->ehci_logic_fck); -+ clk_prepare_enable(omap->ehci_logic_fck); - - for (i = 0; i < omap->nports; i++) { - switch (pdata->port_mode[i]) { - case OMAP_EHCI_PORT_MODE_HSIC: - if (!IS_ERR(omap->hsic60m_clk[i])) { -- r = clk_enable(omap->hsic60m_clk[i]); -+ r = clk_prepare_enable(omap->hsic60m_clk[i]); - if (r) { - dev_err(dev, - "Can't enable port %d hsic60m clk:%d\n", -@@ -343,7 +343,7 @@ static int usbhs_runtime_resume(struct d - } - - if (!IS_ERR(omap->hsic480m_clk[i])) { -- r = clk_enable(omap->hsic480m_clk[i]); -+ r = clk_prepare_enable(omap->hsic480m_clk[i]); - if (r) { - dev_err(dev, - "Can't enable port %d hsic480m clk:%d\n", -@@ -354,7 +354,7 @@ static int usbhs_runtime_resume(struct d - - case OMAP_EHCI_PORT_MODE_TLL: - if (!IS_ERR(omap->utmi_clk[i])) { -- r = clk_enable(omap->utmi_clk[i]); -+ r = clk_prepare_enable(omap->utmi_clk[i]); - if (r) { - dev_err(dev, - "Can't enable port %d clk : %d\n", -@@ -382,15 +382,15 @@ static int usbhs_runtime_suspend(struct - switch (pdata->port_mode[i]) { - case OMAP_EHCI_PORT_MODE_HSIC: - if (!IS_ERR(omap->hsic60m_clk[i])) -- clk_disable(omap->hsic60m_clk[i]); -+ clk_disable_unprepare(omap->hsic60m_clk[i]); - - if (!IS_ERR(omap->hsic480m_clk[i])) -- clk_disable(omap->hsic480m_clk[i]); -+ clk_disable_unprepare(omap->hsic480m_clk[i]); - /* Fall through as utmi_clks were used in HSIC mode */ - - case OMAP_EHCI_PORT_MODE_TLL: - if (!IS_ERR(omap->utmi_clk[i])) -- clk_disable(omap->utmi_clk[i]); -+ clk_disable_unprepare(omap->utmi_clk[i]); - break; - default: - break; -@@ -398,7 +398,7 @@ static int usbhs_runtime_suspend(struct - } - - if (!IS_ERR(omap->ehci_logic_fck)) -- clk_disable(omap->ehci_logic_fck); -+ clk_disable_unprepare(omap->ehci_logic_fck); - - omap_tll_disable(pdata); - ---- a/drivers/mfd/omap-usb-tll.c -+++ b/drivers/mfd/omap-usb-tll.c -@@ -429,7 +429,7 @@ int omap_tll_enable(struct usbhs_omap_pl - if (IS_ERR(tll->ch_clk[i])) - continue; - -- r = clk_enable(tll->ch_clk[i]); -+ r = clk_prepare_enable(tll->ch_clk[i]); - if (r) { - dev_err(tll_dev, - "Error enabling ch %d clock: %d\n", i, r); -@@ -460,7 +460,7 @@ int omap_tll_disable(struct usbhs_omap_p - for (i = 0; i < tll->nch; i++) { - if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { - if (!IS_ERR(tll->ch_clk[i])) -- clk_disable(tll->ch_clk[i]); -+ clk_disable_unprepare(tll->ch_clk[i]); - } - } - ---- a/drivers/mfd/ti_am335x_tscadc.c -+++ b/drivers/mfd/ti_am335x_tscadc.c -@@ -56,21 +56,25 @@ EXPORT_SYMBOL_GPL(am335x_tsc_se_update); - - void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val) - { -- spin_lock(&tsadc->reg_lock); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tsadc->reg_lock, flags); - tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE); - tsadc->reg_se_cache |= val; - am335x_tsc_se_update(tsadc); -- spin_unlock(&tsadc->reg_lock); -+ spin_unlock_irqrestore(&tsadc->reg_lock, flags); - } - EXPORT_SYMBOL_GPL(am335x_tsc_se_set); - - void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val) - { -- spin_lock(&tsadc->reg_lock); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&tsadc->reg_lock, flags); - tsadc->reg_se_cache = tscadc_readl(tsadc, REG_SE); - tsadc->reg_se_cache &= ~val; - am335x_tsc_se_update(tsadc); -- spin_unlock(&tsadc->reg_lock); -+ spin_unlock_irqrestore(&tsadc->reg_lock, flags); - } - EXPORT_SYMBOL_GPL(am335x_tsc_se_clr); - ---- /dev/null -+++ b/drivers/mfd/tps65218.c -@@ -0,0 +1,275 @@ -+/* -+ * TPS65218 chip family multi-function driver -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether expressed or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License version 2 for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/device.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/init.h> -+#include <linux/i2c.h> -+#include <linux/slab.h> -+#include <linux/regmap.h> -+#include <linux/err.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/mutex.h> -+ -+#include <linux/mfd/core.h> -+#include <linux/mfd/tps65218.h> -+ -+#define TPS65218_PASSWORD_REGS_UNLOCK 0x7D -+ -+/** -+ * tps65218_reg_read: Read a single tps65218 register. -+ * -+ * @tps: Device to read from. -+ * @reg: Register to read. -+ * @val: Contians the value -+ */ -+int tps65218_reg_read(struct tps65218 *tps, unsigned int reg, -+ unsigned int *val) -+{ -+ return regmap_read(tps->regmap, reg, val); -+} -+EXPORT_SYMBOL_GPL(tps65218_reg_read); -+ -+/** -+ * tps65218_reg_write: Write a single tps65218 register. -+ * -+ * @tps65218: Device to write to. -+ * @reg: Register to write to. -+ * @val: Value to write. -+ * @level: Password protected level -+ */ -+int tps65218_reg_write(struct tps65218 *tps, unsigned int reg, -+ unsigned int val, unsigned int level) -+{ -+ int ret; -+ unsigned int xor_reg_val; -+ -+ switch (level) { -+ case TPS65218_PROTECT_NONE: -+ return regmap_write(tps->regmap, reg, val); -+ case TPS65218_PROTECT_L1: -+ xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK; -+ ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD, -+ xor_reg_val); -+ if (ret < 0) -+ return ret; -+ -+ return regmap_write(tps->regmap, reg, val); -+ default: -+ return -EINVAL; -+ } -+} -+EXPORT_SYMBOL_GPL(tps65218_reg_write); -+ -+/** -+ * tps65218_update_bits: Modify bits w.r.t mask, val and level. -+ * -+ * @tps65218: Device to write to. -+ * @reg: Register to read-write to. -+ * @mask: Mask. -+ * @val: Value to write. -+ * @level: Password protected level -+ */ -+static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg, -+ unsigned int mask, unsigned int val, unsigned int level) -+{ -+ int ret; -+ unsigned int data; -+ -+ ret = tps65218_reg_read(tps, reg, &data); -+ if (ret) { -+ dev_err(tps->dev, "Read from reg 0x%x failed\n", reg); -+ return ret; -+ } -+ -+ data &= ~mask; -+ data |= val & mask; -+ -+ mutex_lock(&tps->tps_lock); -+ ret = tps65218_reg_write(tps, reg, data, level); -+ if (ret) -+ dev_err(tps->dev, "Write for reg 0x%x failed\n", reg); -+ mutex_unlock(&tps->tps_lock); -+ -+ return ret; -+} -+ -+int tps65218_set_bits(struct tps65218 *tps, unsigned int reg, -+ unsigned int mask, unsigned int val, unsigned int level) -+{ -+ return tps65218_update_bits(tps, reg, mask, val, level); -+} -+EXPORT_SYMBOL_GPL(tps65218_set_bits); -+ -+int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, -+ unsigned int mask, unsigned int level) -+{ -+ return tps65218_update_bits(tps, reg, mask, 0, level); -+} -+EXPORT_SYMBOL_GPL(tps65218_clear_bits); -+ -+static struct regmap_config tps65218_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+}; -+ -+static const struct regmap_irq tps65218_irqs[] = { -+ /* INT1 IRQs */ -+ [TPS65218_PRGC_IRQ] = { -+ .mask = TPS65218_INT1_PRGC, -+ }, -+ [TPS65218_CC_AQC_IRQ] = { -+ .mask = TPS65218_INT1_CC_AQC, -+ }, -+ [TPS65218_HOT_IRQ] = { -+ .mask = TPS65218_INT1_HOT, -+ }, -+ [TPS65218_PB_IRQ] = { -+ .mask = TPS65218_INT1_PB, -+ }, -+ [TPS65218_AC_IRQ] = { -+ .mask = TPS65218_INT1_AC, -+ }, -+ [TPS65218_VPRG_IRQ] = { -+ .mask = TPS65218_INT1_VPRG, -+ }, -+ [TPS65218_INVALID1_IRQ] = { -+ }, -+ [TPS65218_INVALID2_IRQ] = { -+ }, -+ /* INT2 IRQs*/ -+ [TPS65218_LS1_I_IRQ] = { -+ .mask = TPS65218_INT2_LS1_I, -+ .reg_offset = 1, -+ }, -+ [TPS65218_LS2_I_IRQ] = { -+ .mask = TPS65218_INT2_LS2_I, -+ .reg_offset = 1, -+ }, -+ [TPS65218_LS3_I_IRQ] = { -+ .mask = TPS65218_INT2_LS3_I, -+ .reg_offset = 1, -+ }, -+ [TPS65218_LS1_F_IRQ] = { -+ .mask = TPS65218_INT2_LS1_F, -+ .reg_offset = 1, -+ }, -+ [TPS65218_LS2_F_IRQ] = { -+ .mask = TPS65218_INT2_LS2_F, -+ .reg_offset = 1, -+ }, -+ [TPS65218_LS3_F_IRQ] = { -+ .mask = TPS65218_INT2_LS3_F, -+ .reg_offset = 1, -+ }, -+ [TPS65218_INVALID3_IRQ] = { -+ }, -+ [TPS65218_INVALID4_IRQ] = { -+ }, -+}; -+ -+static struct regmap_irq_chip tps65218_irq_chip = { -+ .name = "tps65218", -+ .irqs = tps65218_irqs, -+ .num_irqs = ARRAY_SIZE(tps65218_irqs), -+ -+ .num_regs = 2, -+ .mask_base = TPS65218_REG_INT_MASK1, -+}; -+ -+static const struct of_device_id of_tps65218_match_table[] = { -+ { .compatible = "ti,tps65218", }, -+ { /* end */ } -+}; -+ -+static int tps65218_probe(struct i2c_client *client, -+ const struct i2c_device_id *ids) -+{ -+ struct tps65218 *tps; -+ const struct of_device_id *match; -+ int ret; -+ -+ match = of_match_device(of_tps65218_match_table, &client->dev); -+ if (!match) { -+ dev_err(&client->dev, -+ "Failed to find matching dt id\n"); -+ return -EINVAL; -+ } -+ -+ tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); -+ if (!tps) -+ return -ENOMEM; -+ -+ i2c_set_clientdata(client, tps); -+ tps->dev = &client->dev; -+ -+ tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config); -+ if (IS_ERR(tps->regmap)) { -+ ret = PTR_ERR(tps->regmap); -+ dev_err(tps->dev, "Failed to allocate register map: %d\n", -+ ret); -+ return ret; -+ } -+ -+ mutex_init(&tps->tps_lock); -+ -+ ret = regmap_add_irq_chip(tps->regmap, tps->irq, -+ IRQF_ONESHOT, 0, &tps65218_irq_chip, -+ &tps->irq_data); -+ if (ret < 0) -+ return ret; -+ -+ ret = of_platform_populate(client->dev.of_node, NULL, NULL, -+ &client->dev); -+ if (ret < 0) -+ goto err_irq; -+ -+ return 0; -+ -+err_irq: -+ regmap_del_irq_chip(tps->irq, tps->irq_data); -+ -+ return ret; -+} -+ -+static int tps65218_remove(struct i2c_client *client) -+{ -+ struct tps65218 *tps = i2c_get_clientdata(client); -+ -+ regmap_del_irq_chip(tps->irq, tps->irq_data); -+ -+ return 0; -+} -+ -+static struct i2c_driver tps65218_driver = { -+ .driver = { -+ .name = "tps65218", -+ .owner = THIS_MODULE, -+ .of_match_table = of_tps65218_match_table, -+ }, -+ .probe = tps65218_probe, -+ .remove = tps65218_remove, -+}; -+ -+module_i2c_driver(tps65218_driver); -+ -+MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); -+MODULE_DESCRIPTION("TPS65218 chip family multi-function driver"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/mfd/twl6040.c -+++ b/drivers/mfd/twl6040.c -@@ -238,6 +238,8 @@ int twl6040_power(struct twl6040 *twl604 - if (twl6040->power_count++) - goto out; - -+ clk_prepare_enable(twl6040->clk32k); -+ - if (gpio_is_valid(twl6040->audpwron)) { - /* use automatic power-up sequence */ - ret = twl6040_power_up_automatic(twl6040); -@@ -281,6 +283,8 @@ int twl6040_power(struct twl6040 *twl604 - } - twl6040->sysclk = 0; - twl6040->mclk = 0; -+ -+ clk_disable_unprepare(twl6040->clk32k); - } - - out: -@@ -559,6 +563,12 @@ static int twl6040_probe(struct i2c_clie - - i2c_set_clientdata(client, twl6040); - -+ twl6040->clk32k = devm_clk_get(&client->dev, "clk32k"); -+ if (IS_ERR(twl6040->clk32k)) { -+ dev_info(&client->dev, "clk32k is not handled\n"); -+ twl6040->clk32k = NULL; -+ } -+ - twl6040->supplies[0].supply = "vio"; - twl6040->supplies[1].supply = "v2v1"; - ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, ---- /dev/null -+++ b/drivers/misc/crossbar.c -@@ -0,0 +1,258 @@ -+/* -+ * IRQ/DMA CROSSBAR DRIVER -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * Sricharan R <r.sricharan@ti.com> -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -+ * USA -+ */ -+#include <linux/crossbar.h> -+#include <linux/regmap.h> -+ -+static LIST_HEAD(cb_devlist); -+ -+static struct regmap_config cb_regmap_config = { -+ .reg_bits = 32, -+}; -+ -+static unsigned cb_entry_read(struct cb_line *tmp, const void *cbs) -+{ -+ unsigned index = 0; -+ -+ tmp->cb_name = cbs; -+ index = strlen(tmp->cb_name) + 1; -+ -+ tmp->dev_name = cbs + index; -+ index += strlen(tmp->dev_name) + 1; -+ -+ tmp->int_no = be32_to_cpup(cbs + index); -+ index += sizeof(tmp->int_no); -+ -+ tmp->cb_no = be32_to_cpup(cbs + index); -+ index += sizeof(tmp->cb_no); -+ -+ tmp->offset = be32_to_cpup(cbs + index); -+ index += sizeof(tmp->offset); -+ -+ return index; -+} -+ -+int crossbar_unmap(struct device_node *cbdev_node, unsigned index) -+{ -+ const void *cbs; -+ unsigned size = 0, i = 0; -+ struct cb_line tmp; -+ struct cb_device *cbdev; -+ struct cb_entry *cbentry, *p; -+ -+ cbs = of_get_property(cbdev_node, "crossbar-lines", &size); -+ if (!cbs) -+ return -ENOENT; -+ -+ size = 0; -+ -+ while (i++ < index) -+ size += cb_entry_read(&tmp, cbs + size); -+ -+ cb_entry_read(&tmp, cbs + size); -+ -+ list_for_each_entry(cbdev, &cb_devlist, node) { -+ if (strcmp(cbdev->name, tmp.cb_name)) -+ continue; -+ -+ mutex_lock(&cbdev->cb_lock); -+ list_for_each_entry_safe(cbentry, p, &cbdev->cb_entries, -+ cb_list) { -+ if ((cbentry->line.cb_no == tmp.cb_no) && -+ (cbentry->line.int_no == tmp.int_no)) { -+ list_del(&cbentry->cb_list); -+ mutex_unlock(&cbdev->cb_lock); -+ dev_warn(cbdev->dev, -+ "unmapped int_no %x mapped to cb %x\n", -+ tmp.int_no, tmp.cb_no); -+ return 0; -+ } -+ } -+ mutex_unlock(&cbdev->cb_lock); -+ break; -+ } -+ -+ dev_warn(cbdev->dev, "%s cb entry %d not found\n", -+ __func__, tmp.cb_no); -+ return -ENOENT; -+} -+EXPORT_SYMBOL(crossbar_unmap); -+ -+const int cb_map(struct cb_line cbl) -+{ -+ struct cb_device *cbdev; -+ struct cb_entry *cbentry, *tmp; -+ unsigned val; -+ -+ /* Get corresponding device pointer */ -+ list_for_each_entry(cbdev, &cb_devlist, node) { -+ if (strcmp(cbdev->name, cbl.cb_name)) -+ continue; -+ -+ mutex_lock(&cbdev->cb_lock); -+ -+ /* Check for invalid and duplicate mapping */ -+ list_for_each_entry_safe(cbentry, tmp, &cbdev->cb_entries, -+ cb_list) { -+ if ((cbentry->line.cb_no == cbl.cb_no) && -+ (cbentry->line.int_no != cbl.int_no)) { -+ dev_warn(cbdev->dev, -+ "%s irq already mapped to irq no %d", -+ cbentry->line.dev_name, -+ cbentry->line.int_no); -+ mutex_unlock(&cbdev->cb_lock); -+ return -EINVAL; -+ } -+ if ((cbentry->line.cb_no == cbl.cb_no) && -+ (cbentry->line.int_no == cbl.int_no)) { -+ mutex_unlock(&cbdev->cb_lock); -+ return 0; -+ } -+ if ((cbentry->line.int_no == cbl.int_no) && -+ (cbentry->line.cb_no != cbl.cb_no)) { -+ dev_warn(cbdev->dev, -+ "%s irq replaced by %s irq\n", -+ cbentry->line.dev_name, -+ cbl.dev_name); -+ list_del(&(cbentry->cb_list)); -+ break; -+ } -+ } -+ -+ cbentry = devm_kzalloc(cbdev->dev, sizeof(struct cb_entry), -+ GFP_KERNEL); -+ cbentry->line = cbl; -+ list_add_tail(&(cbentry->cb_list), &cbdev->cb_entries); -+ -+ regmap_read(cbdev->cb_regmap, cbl.offset, &val); -+ -+ /* Print the replaced entry and map the new one */ -+ dev_warn(cbdev->dev, -+ "replacing irq %d mapped to cb input %d with cb input %d\n", -+ cbl.int_no, val, cbl.cb_no); -+ -+ regmap_write(cbdev->cb_regmap, cbl.offset, cbl.cb_no); -+ mutex_unlock(&cbdev->cb_lock); -+ return 0; -+ } -+ -+ dev_warn(cbdev->dev, "crossbar device %s not found", cbl.cb_name); -+ return -ENODEV; -+} -+ -+int crossbar_map(struct device_node *cbdev_node) -+{ -+ const void *cbs; -+ unsigned size = 0, index = 0; -+ int err; -+ -+ cbs = of_get_property(cbdev_node, "crossbar-lines", &size); -+ if (!cbs) -+ return -ENOENT; -+ -+ while (index < size) { -+ struct cb_line tmp; -+ -+ index += cb_entry_read(&tmp, cbs + index); -+ -+ err = cb_map(tmp); -+ if (IS_ERR_VALUE(err)) -+ return err; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(crossbar_map); -+ -+static int crossbar_probe(struct platform_device *pdev) -+{ -+ struct cb_device *cbdev; -+ unsigned width; -+ struct device_node *cbdev_node = pdev->dev.of_node; -+ int err; -+ struct resource *res; -+ -+ cbdev = devm_kzalloc(&pdev->dev, sizeof(struct cb_device), GFP_KERNEL); -+ if (!cbdev) -+ return -ENOMEM; -+ -+ /* Get the device resources */ -+ of_property_read_string(cbdev_node, "crossbar-name", &(cbdev->name)); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) -+ return -ENOENT; -+ -+ cbdev->base = devm_ioremap_resource(&pdev->dev, res); -+ if (!cbdev->base) -+ return -ENOMEM; -+ -+ cbdev->dev = &pdev->dev; -+ -+ of_property_read_u32(cbdev_node, "reg-width", &width); -+ -+ cb_regmap_config.val_bits = width; -+ cb_regmap_config.reg_stride = width >> 3; -+ -+ cbdev->cb_regmap = devm_regmap_init_mmio(cbdev->dev, cbdev->base, -+ &cb_regmap_config); -+ -+ if (IS_ERR(cbdev->cb_regmap)) { -+ dev_err(&pdev->dev, "regmap init failed\n"); -+ err = PTR_ERR(cbdev->cb_regmap); -+ return err; -+ } -+ -+ platform_set_drvdata(pdev, cbdev); -+ list_add_tail(&cbdev->node, &cb_devlist); -+ -+ /* INIT LIST HEAD */ -+ INIT_LIST_HEAD(&cbdev->cb_entries); -+ -+ mutex_init(&cbdev->cb_lock); -+ -+ /* map the cross bar entries passed as default from DT */ -+ err = crossbar_map(cbdev_node); -+ -+ return err; -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id crossbar_match[] = { -+ {.compatible = "crossbar", }, -+ {}, -+}; -+#endif -+ -+static struct platform_driver crossbar_driver = { -+ .probe = crossbar_probe, -+ .driver = { -+ .name = "crossbar", -+ .owner = THIS_MODULE, -+ .of_match_table = crossbar_match, -+ }, -+}; -+ -+static int __init crossbar_init(void) -+{ -+ return platform_driver_register(&crossbar_driver); -+} -+postcore_initcall(crossbar_init); ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -528,6 +528,14 @@ config SRAM - the genalloc API. It is supposed to be used for small on-chip SRAM - areas found on many SoCs. - -+config CROSSBAR -+ bool "on-chip crossbar driver" -+ select REGMAP_MMIO -+ help -+ This driver is for IRQ/DMA crossbar devices which is responsible for -+ muxing the irq/dma requests from external peripherals to the corresponding -+ controller's inputs. -+ - source "drivers/misc/c2port/Kconfig" - source "drivers/misc/eeprom/Kconfig" - source "drivers/misc/cb710/Kconfig" ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ - obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ - obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o - obj-$(CONFIG_SRAM) += sram.o -+obj-$(CONFIG_CROSSBAR) += crossbar.o ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1512,14 +1512,6 @@ static int mmc_suspend(struct mmc_host * - } - - /* -- * Shutdown callback -- */ --static int mmc_shutdown(struct mmc_host *host) --{ -- return _mmc_suspend(host, false); --} -- --/* - * Resume callback from host. - * - * This function tries to determine if the same card is still present -@@ -1608,7 +1600,6 @@ static const struct mmc_bus_ops mmc_ops - .resume = NULL, - .power_restore = mmc_power_restore, - .alive = mmc_alive, -- .shutdown = mmc_shutdown, - }; - - static const struct mmc_bus_ops mmc_ops_unsafe = { -@@ -1620,7 +1611,6 @@ static const struct mmc_bus_ops mmc_ops_ - .runtime_resume = mmc_runtime_resume, - .power_restore = mmc_power_restore, - .alive = mmc_alive, -- .shutdown = mmc_shutdown, - }; - - static void mmc_attach_bus_ops(struct mmc_host *host) ---- a/drivers/mmc/core/sd.c -+++ b/drivers/mmc/core/sd.c -@@ -1173,7 +1173,6 @@ static const struct mmc_bus_ops mmc_sd_o - .resume = NULL, - .power_restore = mmc_sd_power_restore, - .alive = mmc_sd_alive, -- .shutdown = mmc_sd_suspend, - }; - - static const struct mmc_bus_ops mmc_sd_ops_unsafe = { -@@ -1185,7 +1184,6 @@ static const struct mmc_bus_ops mmc_sd_o - .resume = mmc_sd_resume, - .power_restore = mmc_sd_power_restore, - .alive = mmc_sd_alive, -- .shutdown = mmc_sd_suspend, - }; - - static void mmc_sd_attach_bus_ops(struct mmc_host *host) ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -45,6 +45,7 @@ - /* OMAP HSMMC Host Controller Registers */ - #define OMAP_HSMMC_SYSSTATUS 0x0014 - #define OMAP_HSMMC_CON 0x002C -+#define OMAP_HSMMC_SDMASA 0x0100 - #define OMAP_HSMMC_BLK 0x0104 - #define OMAP_HSMMC_ARG 0x0108 - #define OMAP_HSMMC_CMD 0x010C -@@ -58,7 +59,9 @@ - #define OMAP_HSMMC_STAT 0x0130 - #define OMAP_HSMMC_IE 0x0134 - #define OMAP_HSMMC_ISE 0x0138 -+#define OMAP_HSMMC_AC12 0x013C - #define OMAP_HSMMC_CAPA 0x0140 -+#define OMAP_HSMMC_REV 0x01FC - - #define VS18 (1 << 26) - #define VS30 (1 << 25) -@@ -75,11 +78,14 @@ - #define ICE 0x1 - #define ICS 0x2 - #define CEN (1 << 2) -+#define CLKD_MAX 0x3FF /* max clock divisor: 1023 */ - #define CLKD_MASK 0x0000FFC0 - #define CLKD_SHIFT 6 - #define DTO_MASK 0x000F0000 - #define DTO_SHIFT 16 - #define INIT_STREAM (1 << 1) -+#define ACEN_ACMD12 (1 << 2) -+#define ACEN_ACMD23 (2 << 2) - #define DP_SELECT (1 << 21) - #define DDIR (1 << 4) - #define DMAE 0x1 -@@ -111,6 +117,7 @@ - #define DTO_EN (1 << 20) - #define DCRC_EN (1 << 21) - #define DEB_EN (1 << 22) -+#define ACE_EN (1 << 24) - #define CERR_EN (1 << 28) - #define BADA_EN (1 << 29) - -@@ -118,12 +125,27 @@ - DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ - BRR_EN | BWR_EN | TC_EN | CC_EN) - -+#define CNI (1 << 7) -+#define ACIE (1 << 4) -+#define ACEB (1 << 3) -+#define ACCE (1 << 2) -+#define ACTO (1 << 1) -+#define ACNE (1 << 0) -+ - #define MMC_AUTOSUSPEND_DELAY 100 - #define MMC_TIMEOUT_MS 20 -+#define MMC_TIMEOUT_US 20000 - #define OMAP_MMC_MIN_CLOCK 400000 - #define OMAP_MMC_MAX_CLOCK 52000000 - #define DRIVER_NAME "omap_hsmmc" - -+#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ -+#define AUTO_CMD23 (1 << 1) /* Auto CMD23 support */ -+ -+#define OMAP_HSMMC_REV_SHIFT 24 -+/* HSMMC controller revision on OMAP5, DRA7 */ -+#define OMAP_HSMMC_REV_33 0x33 -+ - /* - * One controller can have multiple slots, like on some omap boards using - * omap.c controller driver. Luckily this is not currently done on any known -@@ -171,6 +193,10 @@ struct omap_hsmmc_host { - unsigned char bus_mode; - unsigned char power_mode; - int suspended; -+ u32 con; -+ u32 hctl; -+ u32 sysctl; -+ u32 capa; - int irq; - int use_dma, dma_ch; - struct dma_chan *tx_chan; -@@ -182,11 +208,19 @@ struct omap_hsmmc_host { - int reqs_blocked; - int use_reg; - int req_in_progress; -+ unsigned long clk_rate; -+ unsigned int flags; - struct omap_hsmmc_next next_data; -- - struct omap_mmc_platform_data *pdata; - }; - -+static int -+omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req); -+ -+static void set_data_timeout(struct omap_hsmmc_host *host, -+ unsigned int timeout_ns, -+ unsigned int timeout_clks); -+ - static int omap_hsmmc_card_detect(struct device *dev, int slot) - { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); -@@ -407,6 +441,9 @@ static int omap_hsmmc_gpio_init(struct o - ret = gpio_direction_input(pdata->slots[0].switch_pin); - if (ret) - goto err_free_sp; -+ ret = gpio_set_debounce(pdata->slots[0].switch_pin, 50000); -+ if (ret) -+ goto err_free_sp; - } else - pdata->slots[0].switch_pin = -EINVAL; - -@@ -493,8 +530,8 @@ static u16 calc_divisor(struct omap_hsmm - - if (ios->clock) { - dsor = DIV_ROUND_UP(clk_get_rate(host->fclk), ios->clock); -- if (dsor > 250) -- dsor = 250; -+ if (dsor > CLKD_MAX) -+ dsor = CLKD_MAX; - } - - return dsor; -@@ -597,25 +634,20 @@ static void omap_hsmmc_set_bus_mode(stru - static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) - { - struct mmc_ios *ios = &host->mmc->ios; -- struct omap_mmc_platform_data *pdata = host->pdata; -- int context_loss = 0; - u32 hctl, capa; - unsigned long timeout; - -- if (pdata->get_context_loss_count) { -- context_loss = pdata->get_context_loss_count(host->dev); -- if (context_loss < 0) -- return 1; -- } -- -- dev_dbg(mmc_dev(host->mmc), "context was %slost\n", -- context_loss == host->context_loss ? "not " : ""); -- if (host->context_loss == context_loss) -- return 1; -- - if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) - return 1; - -+ if (host->con == OMAP_HSMMC_READ(host->base, CON) && -+ host->hctl == OMAP_HSMMC_READ(host->base, HCTL) && -+ host->sysctl == OMAP_HSMMC_READ(host->base, SYSCTL) && -+ host->capa == OMAP_HSMMC_READ(host->base, CAPA)) -+ return 0; -+ -+ host->context_loss++; -+ - if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { - if (host->power_mode != MMC_POWER_OFF && - (1 << ios->vdd) <= MMC_VDD_23_24) -@@ -655,9 +687,8 @@ static int omap_hsmmc_context_restore(st - omap_hsmmc_set_bus_mode(host); - - out: -- host->context_loss = context_loss; -- -- dev_dbg(mmc_dev(host->mmc), "context is restored\n"); -+ dev_dbg(mmc_dev(host->mmc), "context is restored: restore count %d\n", -+ host->context_loss); - return 0; - } - -@@ -666,15 +697,10 @@ out: - */ - static void omap_hsmmc_context_save(struct omap_hsmmc_host *host) - { -- struct omap_mmc_platform_data *pdata = host->pdata; -- int context_loss; -- -- if (pdata->get_context_loss_count) { -- context_loss = pdata->get_context_loss_count(host->dev); -- if (context_loss < 0) -- return; -- host->context_loss = context_loss; -- } -+ host->con = OMAP_HSMMC_READ(host->base, CON); -+ host->hctl = OMAP_HSMMC_READ(host->base, HCTL); -+ host->sysctl = OMAP_HSMMC_READ(host->base, SYSCTL); -+ host->capa = OMAP_HSMMC_READ(host->base, CAPA); - } - - #else -@@ -762,7 +788,7 @@ static DEVICE_ATTR(slot_name, S_IRUGO, o - */ - static void - omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, -- struct mmc_data *data) -+ struct mmc_data *data, bool autocmd12) - { - int cmdreg = 0, resptype = 0, cmdtype = 0; - -@@ -792,6 +818,13 @@ omap_hsmmc_start_command(struct omap_hsm - cmdtype = 0x3; - - cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); -+ if ((host->flags & AUTO_CMD23) && mmc_op_multi(cmd->opcode) && -+ host->mrq->sbc) { -+ cmdreg |= ACEN_ACMD23; -+ OMAP_HSMMC_WRITE(host->base, SDMASA, host->mrq->sbc->arg); -+ } else if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode) && -+ autocmd12) -+ cmdreg |= ACEN_ACMD12; - - if (data) { - cmdreg |= DP_SELECT | MSBS | BCE; -@@ -870,11 +903,38 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_h - else - data->bytes_xfered = 0; - -- if (!data->stop) { -+ if (data->stop && (data->error || (!(host->flags & AUTO_CMD12) && -+ !host->mrq->sbc))) { -+ /* -+ * If there is any error or open-end read/write with autocmd12 -+ * disabled -+ */ -+ omap_hsmmc_start_command(host, data->stop, NULL, 0); -+ } else { -+ /* status update for autocmd12 of open-end read/write */ -+ if (data->stop && !host->mrq->sbc) -+ data->stop->resp[0] = OMAP_HSMMC_READ(host->base, -+ RSP76); - omap_hsmmc_request_done(host, data->mrq); -- return; - } -- omap_hsmmc_start_command(host, data->stop, NULL); -+ -+ return; -+} -+ -+static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host) -+{ -+ struct mmc_request *req; -+ struct dma_chan *chan; -+ req = host->mrq; -+ -+ if (!req->data) -+ return; -+ OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) -+ | (req->data->blocks << 16)); -+ set_data_timeout(host, req->data->timeout_ns, -+ req->data->timeout_clks); -+ chan = omap_hsmmc_get_dma_chan(host, req->data); -+ dma_async_issue_pending(chan); - } - - /* -@@ -883,6 +943,18 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_h - static void - omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) - { -+ struct mmc_request *req; -+ req = host->mrq; -+ -+ if (host->mrq->sbc && (host->cmd == host->mrq->sbc) && -+ !host->mrq->sbc->error && !(host->flags & AUTO_CMD23)) { -+ host->cmd = NULL; -+ omap_hsmmc_start_dma_transfer(host); -+ omap_hsmmc_start_command(host, host->mrq->cmd, -+ host->mrq->data, 0); -+ return; -+ } -+ - host->cmd = NULL; - - if (cmd->flags & MMC_RSP_PRESENT) { -@@ -975,8 +1047,7 @@ static inline void omap_hsmmc_reset_cont - unsigned long bit) - { - unsigned long i = 0; -- unsigned long limit = (loops_per_jiffy * -- msecs_to_jiffies(MMC_TIMEOUT_MS)); -+ unsigned long limit = MMC_TIMEOUT_US; - - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, SYSCTL) | bit); -@@ -988,13 +1059,14 @@ static inline void omap_hsmmc_reset_cont - if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { - while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit)) - && (i++ < limit)) -- cpu_relax(); -+ udelay(1); - } -+ - i = 0; - - while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) && - (i++ < limit)) -- cpu_relax(); -+ udelay(1); - - if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit) - dev_err(mmc_dev(host->mmc), -@@ -1022,6 +1094,7 @@ static void omap_hsmmc_do_irq(struct oma - { - struct mmc_data *data; - int end_cmd = 0, end_trans = 0; -+ int error = 0; - - data = host->data; - dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); -@@ -1036,6 +1109,29 @@ static void omap_hsmmc_do_irq(struct oma - else if (status & (CCRC_EN | DCRC_EN)) - hsmmc_command_incomplete(host, -EILSEQ, end_cmd); - -+ if (status & ACE_EN) { -+ u32 ac12; -+ ac12 = OMAP_HSMMC_READ(host->base, AC12); -+ if (!(ac12 & ACNE) && host->mrq->sbc) { -+ end_cmd = 1; -+ if (ac12 & ACTO) -+ error = -ETIMEDOUT; -+ else if (ac12 & (ACCE | ACEB | ACIE)) -+ error = -EILSEQ; -+ host->mrq->sbc->error = error; -+ hsmmc_command_incomplete(host, error, end_cmd); -+ } -+ if (!(ac12 & ACNE) && !host->mrq->sbc && -+ host->mrq->data) { -+ end_trans = 1; -+ if (ac12 & ACTO) -+ host->mrq->data->error = -ETIMEDOUT; -+ else if (ac12 & (ACCE | ACEB | ACIE)) -+ host->mrq->data->error = -EILSEQ; -+ omap_hsmmc_reset_controller_fsm(host, SRC); -+ } -+ dev_dbg(mmc_dev(host->mmc), "AC12 err: 0x%x\n", ac12); -+ } - if (host->data || host->response_busy) { - end_trans = !end_cmd; - host->response_busy = 0; -@@ -1272,7 +1368,7 @@ static int omap_hsmmc_pre_dma_transfer(s - /* - * Routine to configure and start DMA for the MMC card - */ --static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, -+static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, - struct mmc_request *req) - { - struct dma_slave_config cfg; -@@ -1331,8 +1427,6 @@ static int omap_hsmmc_start_dma_transfer - - host->dma_ch = 1; - -- dma_async_issue_pending(chan); -- - return 0; - } - -@@ -1348,7 +1442,7 @@ static void set_data_timeout(struct omap - if (clkd == 0) - clkd = 1; - -- cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd); -+ cycle_ns = 1000000000 / (host->clk_rate / clkd); - timeout = timeout_ns / cycle_ns; - timeout += timeout_clks; - if (timeout) { -@@ -1393,12 +1487,8 @@ omap_hsmmc_prepare_data(struct omap_hsmm - return 0; - } - -- OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) -- | (req->data->blocks << 16)); -- set_data_timeout(host, req->data->timeout_ns, req->data->timeout_clks); -- - if (host->use_dma) { -- ret = omap_hsmmc_start_dma_transfer(host, req); -+ ret = omap_hsmmc_setup_dma_transfer(host, req); - if (ret != 0) { - dev_err(mmc_dev(host->mmc), "MMC start dma failure\n"); - return ret; -@@ -1472,6 +1562,7 @@ static void omap_hsmmc_request(struct mm - host->reqs_blocked = 0; - WARN_ON(host->mrq != NULL); - host->mrq = req; -+ host->clk_rate = clk_get_rate(host->fclk); - err = omap_hsmmc_prepare_data(host, req); - if (err) { - req->cmd->error = err; -@@ -1481,8 +1572,12 @@ static void omap_hsmmc_request(struct mm - mmc_request_done(mmc, req); - return; - } -- -- omap_hsmmc_start_command(host, req->cmd, req->data); -+ if (req->sbc && !(host->flags & AUTO_CMD23)) { -+ omap_hsmmc_start_command(host, req->sbc, NULL, 0); -+ return; -+ } -+ omap_hsmmc_start_dma_transfer(host); -+ omap_hsmmc_start_command(host, req->cmd, req->data, 1); - } - - /* Routine to configure clock values. Exposed API to core */ -@@ -1635,13 +1730,9 @@ static int omap_hsmmc_regs_show(struct s - { - struct mmc_host *mmc = s->private; - struct omap_hsmmc_host *host = mmc_priv(mmc); -- int context_loss = 0; - -- if (host->pdata->get_context_loss_count) -- context_loss = host->pdata->get_context_loss_count(host->dev); -- -- seq_printf(s, "mmc%d:\n ctx_loss:\t%d:%d\n\nregs:\n", -- mmc->index, host->context_loss, context_loss); -+ seq_printf(s, "mmc%d:\n ctx_loss:\t%d\n\nregs:\n", -+ mmc->index, host->context_loss); - - if (host->suspended) { - seq_printf(s, "host suspended, can't read registers\n"); -@@ -1778,6 +1869,7 @@ static int omap_hsmmc_probe(struct platf - dma_cap_mask_t mask; - unsigned tx_req, rx_req; - struct pinctrl *pinctrl; -+ u32 revision; - - match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); - if (match) { -@@ -1874,7 +1966,7 @@ static int omap_hsmmc_probe(struct platf - omap_hsmmc_context_save(host); - - /* This can be removed once we support PBIAS with DT */ -- if (host->dev->of_node && host->mapbase == 0x4809c000) -+ if (host->dev->of_node && res->start == 0x4809c000) - host->pbias_disable = 1; - - host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); -@@ -1976,6 +2068,12 @@ static int omap_hsmmc_probe(struct platf - host->use_reg = 1; - } - -+ revision = OMAP_HSMMC_READ(host->base, REV); -+ if ((revision >> OMAP_HSMMC_REV_SHIFT) >= OMAP_HSMMC_REV_33) { -+ mmc->caps |= MMC_CAP_CMD23; -+ host->flags |= AUTO_CMD23; -+ } -+ - mmc->ocr_avail = mmc_slot(host).ocr_mask; - - /* Request IRQ for card detect */ ---- a/drivers/mtd/devices/elm.c -+++ b/drivers/mtd/devices/elm.c -@@ -22,8 +22,11 @@ - #include <linux/of.h> - #include <linux/sched.h> - #include <linux/pm_runtime.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/nand.h> - #include <linux/platform_data/elm.h> - -+#define DRIVER_NAME "omap-elm" - #define ELM_SYSCONFIG 0x010 - #define ELM_IRQSTATUS 0x018 - #define ELM_IRQENABLE 0x01c -@@ -82,8 +85,10 @@ struct elm_info { - void __iomem *elm_base; - struct completion elm_completion; - struct list_head list; -+ struct mtd_info *mtd; - enum bch_ecc bch_type; - struct elm_registers elm_regs; -+ int eccsteps; - }; - - static LIST_HEAD(elm_devices); -@@ -103,19 +108,42 @@ static u32 elm_read_reg(struct elm_info - * @dev: ELM device - * @bch_type: Type of BCH ecc - */ --int elm_config(struct device *dev, enum bch_ecc bch_type) -+int elm_config(struct device *dev, struct mtd_info *mtd, -+ enum bch_ecc bch_type) - { - u32 reg_val; -- struct elm_info *info = dev_get_drvdata(dev); -- -+ struct elm_info *info; -+ struct nand_chip *chip; -+ if (!dev) { -+ pr_err("%s: ELM device not found\n", DRIVER_NAME); -+ return -ENODEV; -+ } -+ info = dev_get_drvdata(dev); - if (!info) { -- dev_err(dev, "Unable to configure elm - device not probed?\n"); -+ pr_err("%s: ELM device data not found\n", DRIVER_NAME); - return -ENODEV; - } -- -+ if (!mtd) { -+ pr_err("%s: MTD device not found\n", DRIVER_NAME); -+ return -ENODEV; -+ } -+ chip = mtd->priv; -+ /* ELM supports error correction in chunks of 512bytes of data only -+ * where each 512bytes of data has its own ECC syndrome */ -+ if (chip->ecc.size != 512) { -+ pr_err("%s: invalid ecc_size configuration", DRIVER_NAME); -+ return -EINVAL; -+ } -+ if (mtd->writesize > 4096) { -+ pr_err("%s: page-size > 4096 is not supported", DRIVER_NAME); -+ return -EINVAL; -+ } -+ /* ELM eccsteps required to decode complete NAND page */ -+ info->mtd = mtd; -+ info->bch_type = bch_type; -+ info->eccsteps = mtd->writesize / chip->ecc.size; - reg_val = (bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16); - elm_write_reg(info, ELM_LOCATION_CONFIG, reg_val); -- info->bch_type = bch_type; - - return 0; - } -@@ -152,55 +180,80 @@ static void elm_configure_page_mode(stru - * Load syndrome fragment registers with calculated ecc in reverse order. - */ - static void elm_load_syndrome(struct elm_info *info, -- struct elm_errorvec *err_vec, u8 *ecc) -+ struct elm_errorvec *err_vec, u8 *ecc_calc) - { -+ struct nand_chip *chip = info->mtd->priv; -+ unsigned int eccbytes = chip->ecc.bytes; -+ u8 *ecc = ecc_calc; - int i, offset; - u32 val; - -- for (i = 0; i < ERROR_VECTOR_MAX; i++) { -- -+ for (i = 0; i < info->eccsteps; i++) { - /* Check error reported */ - if (err_vec[i].error_reported) { - elm_configure_page_mode(info, i, true); -- offset = ELM_SYNDROME_FRAGMENT_0 + -- SYNDROME_FRAGMENT_REG_SIZE * i; -- -- /* BCH8 */ -- if (info->bch_type) { -- -- /* syndrome fragment 0 = ecc[9-12B] */ -- val = cpu_to_be32(*(u32 *) &ecc[9]); -- elm_write_reg(info, offset, val); -- -- /* syndrome fragment 1 = ecc[5-8B] */ -- offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[5]); -- elm_write_reg(info, offset, val); -- -- /* syndrome fragment 2 = ecc[1-4B] */ -- offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[1]); -- elm_write_reg(info, offset, val); -- -- /* syndrome fragment 3 = ecc[0B] */ -- offset += 4; -- val = ecc[0]; -- elm_write_reg(info, offset, val); -- } else { -- /* syndrome fragment 0 = ecc[20-52b] bits */ -- val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | -- ((ecc[2] & 0xf) << 28); -- elm_write_reg(info, offset, val); -- -- /* syndrome fragment 1 = ecc[0-20b] bits */ -- offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; -- elm_write_reg(info, offset, val); -+ offset = SYNDROME_FRAGMENT_REG_SIZE * i; -+ ecc = ecc_calc + (i * eccbytes); -+ switch (info->bch_type) { -+ case BCH4_ECC: -+ val = ((*(ecc + 6) >> 4) & 0x0F) | -+ *(ecc + 5) << 4 | *(ecc + 4) << 12 | -+ *(ecc + 3) << 20 | *(ecc + 2) << 28; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_0 + -+ offset), cpu_to_le32(val)); -+ val = ((*(ecc + 2) >> 4) & 0x0F) | -+ *(ecc + 1) << 4 | *(ecc + 0) << 12; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_1 + -+ offset), cpu_to_le32(val)); -+ break; -+ case BCH8_ECC: -+ val = *(ecc + 12) << 0 | *(ecc + 11) << 8 | -+ *(ecc + 10) << 16 | *(ecc + 9) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_0 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 8) << 0 | *(ecc + 7) << 8 | -+ *(ecc + 6) << 16 | *(ecc + 5) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_1 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 4) << 0 | *(ecc + 3) << 8 | -+ *(ecc + 2) << 16 | *(ecc + 1) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_2 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 0) << 0 & 0x000000FF; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_3 + -+ offset), cpu_to_le32(val)); -+ break; -+ case BCH16_ECC: -+ val = *(ecc + 25) << 0 | *(ecc + 24) << 8 | -+ *(ecc + 23) << 16 | *(ecc + 22) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_0 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 21) << 0 | *(ecc + 20) << 8 | -+ *(ecc + 19) << 16 | *(ecc + 18) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_1 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 17) << 0 | *(ecc + 16) << 8 | -+ *(ecc + 15) << 16 | *(ecc + 14) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_2 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 13) << 0 | *(ecc + 12) << 8 | -+ *(ecc + 11) << 16 | *(ecc + 10) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_3 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 9) << 0 | *(ecc + 8) << 8 | -+ *(ecc + 7) << 16 | *(ecc + 6) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_4 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 5) << 0 | *(ecc + 4) << 8 | -+ *(ecc + 3) << 16 | *(ecc + 2) << 24; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_5 + -+ offset), cpu_to_le32(val)); -+ val = *(ecc + 1) << 0 | *(ecc + 0) << 8; -+ elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_6 + -+ offset), cpu_to_le32(val)); -+ break; - } - } -- -- /* Update ecc pointer with ecc byte size */ -- ecc += info->bch_type ? BCH8_SIZE : BCH4_SIZE; - } - } - -@@ -223,7 +276,7 @@ static void elm_start_processing(struct - * Set syndrome vector valid, so that ELM module - * will process it for vectors error is reported - */ -- for (i = 0; i < ERROR_VECTOR_MAX; i++) { -+ for (i = 0; i < info->eccsteps; i++) { - if (err_vec[i].error_reported) { - offset = ELM_SYNDROME_FRAGMENT_6 + - SYNDROME_FRAGMENT_REG_SIZE * i; -@@ -252,7 +305,7 @@ static void elm_error_correction(struct - int offset; - u32 reg_val; - -- for (i = 0; i < ERROR_VECTOR_MAX; i++) { -+ for (i = 0; i < info->eccsteps; i++) { - - /* Check error reported */ - if (err_vec[i].error_reported) { -@@ -263,14 +316,12 @@ static void elm_error_correction(struct - if (reg_val & ECC_CORRECTABLE_MASK) { - offset = ELM_ERROR_LOCATION_0 + - ERROR_LOCATION_SIZE * i; -- - /* Read count of correctable errors */ - err_vec[i].error_count = reg_val & - ECC_NB_ERRORS_MASK; - - /* Update the error locations in error vector */ - for (j = 0; j < err_vec[i].error_count; j++) { -- - reg_val = elm_read_reg(info, offset); - err_vec[i].error_loc[j] = reg_val & - ECC_ERROR_LOCATION_MASK; ---- a/drivers/mtd/devices/Kconfig -+++ b/drivers/mtd/devices/Kconfig -@@ -95,13 +95,6 @@ config MTD_M25P80 - if you want to specify device partitioning or to use a device which - doesn't support the JEDEC ID instruction. - --config M25PXX_USE_FAST_READ -- bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz" -- depends on MTD_M25P80 -- default y -- help -- This option enables FAST_READ access supported by ST M25Pxx. -- - config MTD_SPEAR_SMI - tristate "SPEAR MTD NOR Support through SMI controller" - depends on PLAT_SPEAR ---- a/drivers/mtd/devices/m25p80.c -+++ b/drivers/mtd/devices/m25p80.c -@@ -41,6 +41,7 @@ - #define OPCODE_WRSR 0x01 /* Write status register 1 byte */ - #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ - #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ -+#define OPCODE_QUAD_READ 0x6b /* QUAD READ */ - #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ - #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ - #define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ -@@ -48,10 +49,12 @@ - #define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ - #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ - #define OPCODE_RDID 0x9f /* Read JEDEC ID */ -+#define OPCODE_RDCR 0x35 /* Read configuration register */ - - /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ - #define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */ - #define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */ -+#define OPCODE_QUAD_READ_4B 0x6c /* Read data bytes */ - #define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */ - #define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */ - -@@ -76,9 +79,13 @@ - #define SR_BP2 0x10 /* Block protect 2 */ - #define SR_SRWD 0x80 /* SR write protect */ - -+/* Configuration Register bits. */ -+#define CR_QUAD_EN_SPAN 0x2 /* Spansion Quad I/O */ -+#define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */ -+ - /* Define max times to check status register before we give up. */ - #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ --#define MAX_CMD_SIZE 5 -+#define MAX_CMD_SIZE 6 - - #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) - -@@ -101,6 +108,8 @@ struct m25p { - u8 program_opcode; - u8 *command; - bool fast_read; -+ bool quad_read; -+ bool mmap; - }; - - static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) -@@ -137,6 +146,26 @@ static int read_sr(struct m25p *flash) - } - - /* -+ * Read the configuration register, returning its value in the location -+ * Return the configuration register value. -+ * Returns negative if error occurred. -+ */ -+static int read_cr(struct m25p *flash) -+{ -+ u8 code = OPCODE_RDCR; -+ int ret; -+ u8 val; -+ -+ ret = spi_write_then_read(flash->spi, &code, 1, &val, 1); -+ if (ret < 0) { -+ dev_err(&flash->spi->dev, "error %d reading CR\n", ret); -+ return ret; -+ } -+ -+ return val; -+} -+ -+/* - * Write status register 1 byte - * Returns negative if error occurred. - */ -@@ -226,6 +255,93 @@ static int wait_till_ready(struct m25p * - } - - /* -+ * It should be something like this. Note the asterisk alignment. You -+ * also could wrap the right edge neatly to nearly 80 characters. -+ */ -+static int write_sr_cr(struct m25p *flash, u16 val) -+{ -+ flash->command[0] = OPCODE_WRSR; -+ flash->command[1] = val & 0xff; -+ flash->command[2] = (val >> 8); -+ -+ return spi_write(flash->spi, flash->command, 3); -+} -+ -+static int macronix_quad_enable(struct m25p *flash) -+{ -+ int ret, val; -+ u8 cmd[2]; -+ cmd[0] = OPCODE_WRSR; -+ -+ val = read_sr(flash); -+ cmd[1] = val | SR_QUAD_EN_MX; -+ write_enable(flash); -+ -+ spi_write(flash->spi, &cmd, 2); -+ -+ if (wait_till_ready(flash)) -+ return 1; -+ -+ ret = read_sr(flash); -+ if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { -+ dev_err(&flash->spi->dev, -+ "Macronix Quad bit not set"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int spansion_quad_enable(struct m25p *flash) -+{ -+ int ret; -+ int quad_en = CR_QUAD_EN_SPAN << 8; -+ -+ write_enable(flash); -+ -+ ret = write_sr_cr(flash, quad_en); -+ if (ret < 0) { -+ dev_err(&flash->spi->dev, -+ "error while writing configuration register"); -+ return -EINVAL; -+ } -+ -+ /* read back and check it */ -+ ret = read_cr(flash); -+ if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { -+ dev_err(&flash->spi->dev, -+ "Spansion Quad bit not set"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static inline int set_quad_mode(struct m25p *flash, u32 jedec_id, int enable) -+{ -+ int status; -+ -+ switch (JEDEC_MFR(jedec_id)) { -+ case CFI_MFR_MACRONIX: -+ status = macronix_quad_enable(flash); -+ if (status) { -+ dev_err(&flash->spi->dev, -+ "Macronix quad not enable"); -+ return -EINVAL; -+ } -+ return status; -+ default: -+ status = spansion_quad_enable(flash); -+ if (status) { -+ dev_err(&flash->spi->dev, -+ "Spansion quad not enable"); -+ return -EINVAL; -+ } -+ return status; -+ } -+} -+ -+/* - * Erase the whole flash memory - * - * Returns 0 if successful, non-zero otherwise. -@@ -355,6 +471,13 @@ static int m25p80_erase(struct mtd_info - return 0; - } - -+static inline int m25p80_dummy_cycles_read(struct m25p *flash) -+{ -+ if (flash->quad_read || flash->fast_read) -+ return 1; -+ return 0; -+} -+ - /* - * Read an address range from the flash chip. The address range - * may be any size provided it is within the physical boundaries. -@@ -373,14 +496,14 @@ static int m25p80_read(struct mtd_info * - spi_message_init(&m); - memset(t, 0, (sizeof t)); - -- /* NOTE: -- * OPCODE_FAST_READ (if available) is faster. -- * Should add 1 byte DUMMY_BYTE. -- */ -+ t[0].memory_map = 1; - t[0].tx_buf = flash->command; -- t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); -+ t[0].len = flash->mmap ? from : m25p_cmdsz(flash) + -+ m25p80_dummy_cycles_read(flash); - spi_message_add_tail(&t[0], &m); - -+ t[1].memory_map = 1; -+ t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1; - t[1].rx_buf = buf; - t[1].len = len; - spi_message_add_tail(&t[1], &m); -@@ -394,11 +517,6 @@ static int m25p80_read(struct mtd_info * - return 1; - } - -- /* FIXME switch to OPCODE_FAST_READ. It's required for higher -- * clocks; and at this writing, every chip this driver handles -- * supports that opcode. -- */ -- - /* Set up the write data buffer. */ - opcode = flash->read_opcode; - flash->command[0] = opcode; -@@ -406,8 +524,8 @@ static int m25p80_read(struct mtd_info * - - spi_sync(flash->spi, &m); - -- *retlen = m.actual_length - m25p_cmdsz(flash) - -- (flash->fast_read ? 1 : 0); -+ *retlen = flash->mmap ? len : m.actual_length - m25p_cmdsz(flash) - -+ m25p80_dummy_cycles_read(flash); - - mutex_unlock(&flash->lock); - -@@ -713,6 +831,7 @@ struct flash_info { - #define SST_WRITE 0x04 /* use SST byte programming */ - #define M25P_NO_FR 0x08 /* Can't do fastread */ - #define SECT_4K_PMC 0x10 /* OPCODE_BE_4K_PMC works uniformly */ -+#define M25P80_QUAD_READ 0x20 /* Flash supports Quad Read */ - }; - - #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ -@@ -789,7 +908,7 @@ static const struct spi_device_id m25p_i - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, -- { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) }, -+ { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) }, - - /* Micron */ - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, -@@ -808,7 +927,7 @@ static const struct spi_device_id m25p_i - { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 0) }, - { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) }, - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, -- { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) }, -+ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, M25P80_QUAD_READ) }, - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) }, - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, -@@ -821,7 +940,7 @@ static const struct spi_device_id m25p_i - { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, - { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K) }, -- { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "s25fl064k", INFO(0xef4017, 0x4d01, 64 * 1024, 128, SECT_4K) }, - - /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, -@@ -949,12 +1068,8 @@ static int m25p_probe(struct spi_device - struct flash_info *info; - unsigned i; - struct mtd_part_parser_data ppdata; -- struct device_node __maybe_unused *np = spi->dev.of_node; -- --#ifdef CONFIG_MTD_OF_PARTS -- if (!of_device_is_available(np)) -- return -ENODEV; --#endif -+ struct device_node *np = spi->dev.of_node; -+ int ret; - - /* Platform data helps sort out which chip type we have, as - * well as how this board partitions it. If we don't have -@@ -1001,15 +1116,14 @@ static int m25p_probe(struct spi_device - } - } - -- flash = kzalloc(sizeof *flash, GFP_KERNEL); -+ flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); - if (!flash) - return -ENOMEM; -- flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0), -- GFP_KERNEL); -- if (!flash->command) { -- kfree(flash); -+ -+ -+ flash->command = devm_kzalloc(&spi->dev, MAX_CMD_SIZE, GFP_KERNEL); -+ if (!flash->command) - return -ENOMEM; -- } - - flash->spi = spi; - mutex_init(&flash->lock); -@@ -1039,6 +1153,15 @@ static int m25p_probe(struct spi_device - flash->mtd._erase = m25p80_erase; - flash->mtd._read = m25p80_read; - -+ if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) { -+ ret = set_quad_mode(flash, info->jedec_id, 1); -+ if (ret) { -+ dev_err(&flash->spi->dev, "quad mode not supported\n"); -+ return ret; -+ } -+ flash->quad_read = true; -+ } -+ - /* flash protection support for STmicro chips */ - if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) { - flash->mtd._lock = m25p80_lock; -@@ -1071,18 +1194,21 @@ static int m25p_probe(struct spi_device - flash->page_size = info->page_size; - flash->mtd.writebufsize = flash->page_size; - -- flash->fast_read = false; -- if (np && of_property_read_bool(np, "m25p,fast-read")) -+ if (np) -+ /* If we were instantiated by DT, use it */ -+ flash->fast_read = of_property_read_bool(np, "m25p,fast-read"); -+ else -+ /* If we weren't instantiated by DT, default to fast-read */ - flash->fast_read = true; - --#ifdef CONFIG_M25PXX_USE_FAST_READ -- flash->fast_read = true; --#endif -+ /* Some devices cannot do fast-read, no matter what DT tells us */ - if (info->flags & M25P_NO_FR) - flash->fast_read = false; - - /* Default commands */ -- if (flash->fast_read) -+ if (flash->quad_read) -+ flash->read_opcode = OPCODE_QUAD_READ; -+ else if (flash->fast_read) - flash->read_opcode = OPCODE_FAST_READ; - else - flash->read_opcode = OPCODE_NORM_READ; -@@ -1094,21 +1220,14 @@ static int m25p_probe(struct spi_device - else if (flash->mtd.size > 0x1000000) { - /* enable 4-byte addressing if the device exceeds 16MiB */ - flash->addr_width = 4; -- if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { -- /* Dedicated 4-byte command set */ -- flash->read_opcode = flash->fast_read ? -- OPCODE_FAST_READ_4B : -- OPCODE_NORM_READ_4B; -- flash->program_opcode = OPCODE_PP_4B; -- /* No small sector erase for 4-byte command set */ -- flash->erase_opcode = OPCODE_SE_4B; -- flash->mtd.erasesize = info->sector_size; -- } else -- set_4byte(flash, info->jedec_id, 1); -+ set_4byte(flash, info->jedec_id, 1); - } else { - flash->addr_width = 3; - } - -+ if (spi->mode & SPI_RX_MMAP) -+ flash->mmap = true; -+ - dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name, - (long long)flash->mtd.size >> 10); - -@@ -1142,14 +1261,10 @@ static int m25p_probe(struct spi_device - static int m25p_remove(struct spi_device *spi) - { - struct m25p *flash = spi_get_drvdata(spi); -- int status; - - /* Clean up MTD stuff. */ -- status = mtd_device_unregister(&flash->mtd); -- if (status == 0) { -- kfree(flash->command); -- kfree(flash); -- } -+ mtd_device_unregister(&flash->mtd); -+ - return 0; - } - ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -96,35 +96,13 @@ config MTD_NAND_OMAP2 - - config MTD_NAND_OMAP_BCH - depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3 -- tristate "Enable support for hardware BCH error correction" -+ tristate "Support hardware based BCH error correction" - default n - select BCH -- select BCH_CONST_PARAMS - help -- Support for hardware BCH error correction. -- --choice -- prompt "BCH error correction capability" -- depends on MTD_NAND_OMAP_BCH -- --config MTD_NAND_OMAP_BCH8 -- bool "8 bits / 512 bytes (recommended)" -- help -- Support correcting up to 8 bitflips per 512-byte block. -- This will use 13 bytes of spare area per 512 bytes of page data. -- This is the recommended mode, as 4-bit mode does not work -- on some OMAP3 revisions, due to a hardware bug. -- --config MTD_NAND_OMAP_BCH4 -- bool "4 bits / 512 bytes" -- help -- Support correcting up to 4 bitflips per 512-byte block. -- This will use 7 bytes of spare area per 512 bytes of page data. -- Note that this mode does not work on some OMAP3 revisions, due to a -- hardware bug. Please check your OMAP datasheet before selecting this -- mode. -- --endchoice -+ Some devices have built-in ELM hardware engine, which can be used to -+ locate and correct errors when using BCH ECC scheme. This enables the -+ driver support for same. - - if MTD_NAND_OMAP_BCH - config BCH_CONST_M ---- a/drivers/mtd/nand/omap2.c -+++ b/drivers/mtd/nand/omap2.c -@@ -25,8 +25,11 @@ - #include <linux/of.h> - #include <linux/of_device.h> - --#ifdef CONFIG_MTD_NAND_OMAP_BCH -+#ifdef CONFIG_MTD_NAND_ECC_BCH - #include <linux/bch.h> -+#include <linux/mtd/nand_bch.h> -+#endif -+#ifdef CONFIG_MTD_NAND_OMAP_BCH - #include <linux/platform_data/elm.h> - #endif - -@@ -35,6 +38,10 @@ - #define DRIVER_NAME "omap2-nand" - #define OMAP_NAND_TIMEOUT_MS 5000 - -+#define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ -+#define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ -+#define GPMC_ECC_READSYN 2 /* Reset before syndrom is read back */ -+ - #define NAND_Ecc_P1e (1 << 0) - #define NAND_Ecc_P2e (1 << 1) - #define NAND_Ecc_P4e (1 << 2) -@@ -103,13 +110,9 @@ - #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) - - #define PREFETCH_CONFIG1_CS_SHIFT 24 --#define ECC_CONFIG_CS_SHIFT 1 - #define CS_MASK 0x7 - #define ENABLE_PREFETCH (0x1 << 7) - #define DMA_MPU_MODE_SHIFT 2 --#define ECCSIZE0_SHIFT 12 --#define ECCSIZE1_SHIFT 22 --#define ECC1RESULTSIZE 0x1 - #define ECCCLEAR 0x100 - #define ECC1 0x1 - #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 -@@ -120,33 +123,24 @@ - - #define OMAP24XX_DMA_GPMC 4 - --#define BCH8_MAX_ERROR 8 /* upto 8 bit correctable */ --#define BCH4_MAX_ERROR 4 /* upto 4 bit correctable */ -- - #define SECTOR_BYTES 512 - /* 4 bit padding to make byte aligned, 56 = 52 + 4 */ - #define BCH4_BIT_PAD 4 --#define BCH8_ECC_MAX ((SECTOR_BYTES + BCH8_ECC_OOB_BYTES) * 8) --#define BCH4_ECC_MAX ((SECTOR_BYTES + BCH4_ECC_OOB_BYTES) * 8) - --/* GPMC ecc engine settings for read */ --#define BCH_WRAPMODE_1 1 /* BCH wrap mode 1 */ --#define BCH8R_ECC_SIZE0 0x1a /* ecc_size0 = 26 */ --#define BCH8R_ECC_SIZE1 0x2 /* ecc_size1 = 2 */ --#define BCH4R_ECC_SIZE0 0xd /* ecc_size0 = 13 */ --#define BCH4R_ECC_SIZE1 0x3 /* ecc_size1 = 3 */ -- --/* GPMC ecc engine settings for write */ --#define BCH_WRAPMODE_6 6 /* BCH wrap mode 6 */ --#define BCH_ECC_SIZE0 0x0 /* ecc_size0 = 0, no oob protection */ --#define BCH_ECC_SIZE1 0x20 /* ecc_size1 = 32 */ -+#define BADBLOCK_MARKER_LENGTH 0x2 - - #ifdef CONFIG_MTD_NAND_OMAP_BCH --static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, -- 0xac, 0x6b, 0xff, 0x99, 0x7b}; --static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; -+static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10}; -+static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, -+ 0xac, 0x6b, 0xff, 0x99, 0x7b}; -+static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55, -+ 0x2e, 0x2c, 0x86, 0xa3, 0xed, 0x36, 0x1b, 0x78, -+ 0x48, 0x76, 0xa9, 0x3b, 0x97, 0xd1, 0x7a, 0x93, -+ 0x07, 0x0e}; - #endif -- -+static u8 bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f}; -+static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2, -+ 0x97, 0x79, 0xe5, 0x24, 0xb5}; - /* oob info generated runtime depending on ecc algorithm and layout selected */ - static struct nand_ecclayout omap_oobinfo; - /* Define some generic bad / good block scan pattern which are used -@@ -171,6 +165,7 @@ struct omap_nand_info { - int gpmc_cs; - unsigned long phys_base; - unsigned long mem_size; -+ enum omap_ecc ecc_opt; - struct completion comp; - struct dma_chan *dma; - int gpmc_irq_fifo; -@@ -180,16 +175,11 @@ struct omap_nand_info { - OMAP_NAND_IO_WRITE, /* write */ - } iomode; - u_char *buf; -- int buf_len; -+ int buf_len; - struct gpmc_nand_regs reg; -- --#ifdef CONFIG_MTD_NAND_OMAP_BCH -- struct bch_control *bch; -- struct nand_ecclayout ecclayout; -- bool is_elm_used; -+ /* fields specific for BCHx_HW ECC scheme */ - struct device *elm_dev; - struct device_node *of_node; --#endif - }; - - /** -@@ -948,9 +938,11 @@ static int omap_calculate_ecc(struct mtd - u32 val; - - val = readl(info->reg.gpmc_ecc_config); -- if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) -+ if (((val >> 1) & 0x7) != info->gpmc_cs) { -+ pr_err("%s: invalid ECC configuration for chip-select=%d", -+ DRIVER_NAME, info->gpmc_cs); - return -EINVAL; -- -+ } - /* read ecc result */ - val = readl(info->reg.gpmc_ecc1_result); - *ecc_code++ = val; /* P128e, ..., P1e */ -@@ -962,47 +954,6 @@ static int omap_calculate_ecc(struct mtd - } - - /** -- * omap_enable_hwecc - This function enables the hardware ecc functionality -- * @mtd: MTD device structure -- * @mode: Read/Write mode -- */ --static void omap_enable_hwecc(struct mtd_info *mtd, int mode) --{ -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); -- struct nand_chip *chip = mtd->priv; -- unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; -- u32 val; -- -- /* clear ecc and enable bits */ -- val = ECCCLEAR | ECC1; -- writel(val, info->reg.gpmc_ecc_control); -- -- /* program ecc and result sizes */ -- val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | -- ECC1RESULTSIZE); -- writel(val, info->reg.gpmc_ecc_size_config); -- -- switch (mode) { -- case NAND_ECC_READ: -- case NAND_ECC_WRITE: -- writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); -- break; -- case NAND_ECC_READSYN: -- writel(ECCCLEAR, info->reg.gpmc_ecc_control); -- break; -- default: -- dev_info(&info->pdev->dev, -- "error: unrecognized Mode[%d]!\n", mode); -- break; -- } -- -- /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ -- val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); -- writel(val, info->reg.gpmc_ecc_config); --} -- --/** - * omap_wait - wait until the command is done - * @mtd: MTD device structure - * @chip: NAND Chip structure -@@ -1058,496 +1009,357 @@ static int omap_dev_ready(struct mtd_inf - } - } - --#ifdef CONFIG_MTD_NAND_OMAP_BCH -- - /** -- * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction -+ * omap_enable_hwecc - Configure OMAP GPMC to perform ECC calculation - * @mtd: MTD device structure - * @mode: Read/Write mode -- * -- * When using BCH, sector size is hardcoded to 512 bytes. -- * Using wrapping mode 6 both for reading and writing if ELM module not uses -- * for error correction. -- * On writing, -- * eccsize0 = 0 (no additional protected byte in spare area) -- * eccsize1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area) -+ * Configurations for eccsize0, eccsize1, and bch_wrapmode are based on -+ * GPMC function spec: -+ * Section 4.6.3.2.3: Supported NAND page mappings and ECC schemes - */ --static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode) -+static void omap_enable_hwecc(struct mtd_info *mtd, int mode) - { -- int nerrors; -- unsigned int dev_width, nsectors; - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); - struct nand_chip *chip = mtd->priv; -- u32 val, wr_mode; -- unsigned int ecc_size1, ecc_size0; -- -- /* Using wrapping mode 6 for writing */ -- wr_mode = BCH_WRAPMODE_6; -- -- /* -- * ECC engine enabled for valid ecc_size0 nibbles -- * and disabled for ecc_size1 nibbles. -- */ -- ecc_size0 = BCH_ECC_SIZE0; -- ecc_size1 = BCH_ECC_SIZE1; -- -- /* Perform ecc calculation on 512-byte sector */ -- nsectors = 1; -- -- /* Update number of error correction */ -- nerrors = info->nand.ecc.strength; -- -- /* Multi sector reading/writing for NAND flash with page size < 4096 */ -- if (info->is_elm_used && (mtd->writesize <= 4096)) { -- if (mode == NAND_ECC_READ) { -- /* Using wrapping mode 1 for reading */ -- wr_mode = BCH_WRAPMODE_1; -- -- /* -- * ECC engine enabled for ecc_size0 nibbles -- * and disabled for ecc_size1 nibbles. -- */ -- ecc_size0 = (nerrors == 8) ? -- BCH8R_ECC_SIZE0 : BCH4R_ECC_SIZE0; -- ecc_size1 = (nerrors == 8) ? -- BCH8R_ECC_SIZE1 : BCH4R_ECC_SIZE1; -+ unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; -+ unsigned int nsectors = (mtd->writesize / SECTOR_BYTES); -+ unsigned int ecc_algo = 0; -+ unsigned int bch_type = 0; -+ unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00; -+ u32 ecc_size_config_val = 0; -+ u32 ecc_config_val = 0; -+ -+ switch (info->ecc_opt) { -+ case OMAP_ECC_HAMMING_CODE_HW: -+ ecc_algo = 0x0; -+ bch_wrapmode = 0x00; -+ eccsize0 = (chip->ecc.size >> 1) - 1; -+ eccsize1 = 0; -+ nsectors = 0; -+ break; -+ case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: -+ case OMAP_ECC_BCH4_CODE_HW: -+ ecc_algo = 0x1; -+ bch_type = 0x0; -+ if (mode == GPMC_ECC_READ) { -+ bch_wrapmode = 0x01; -+ eccsize0 = 13; /* ECC bits in nibbles per sector */ -+ eccsize1 = 3; /* non-ECC bits in nibbles per sector */ -+ } else if (mode == GPMC_ECC_WRITE) { -+ eccsize0 = 0; /* extra bits in nibbles per sector */ -+ eccsize1 = 32; /* OOB bits in nibbles per sector */ -+ bch_wrapmode = 0x06; - } -- -- /* Perform ecc calculation for one page (< 4096) */ -- nsectors = info->nand.ecc.steps; -+ break; -+ case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: -+ case OMAP_ECC_BCH8_CODE_HW: -+ ecc_algo = 0x1; -+ bch_type = 0x1; -+ if (mode == GPMC_ECC_READ) { -+ bch_wrapmode = 0x01; -+ eccsize0 = 26; /* ECC bits in nibbles per sector */ -+ eccsize1 = 2; /* non-ECC bits in nibbles per sector */ -+ } else if (mode == GPMC_ECC_WRITE) { -+ bch_wrapmode = 0x01; -+ eccsize0 = 0; /* extra bits in nibbles per sector */ -+ eccsize1 = 28; /* OOB bits in nibbles per sector */ -+ } -+ break; -+ case OMAP_ECC_BCH16_CODE_HW: -+ ecc_algo = 0x1; -+ bch_type = 0x2; -+ if (mode == GPMC_ECC_READ) { -+ bch_wrapmode = 0x01; -+ eccsize0 = 52; /* ECC bits in nibbles per sector */ -+ eccsize1 = 0; /* non-ECC bits in nibbles per sector */ -+ } else if (mode == GPMC_ECC_WRITE) { -+ bch_wrapmode = 0x01; -+ eccsize0 = 0; /* extra bits in nibbles per sector */ -+ eccsize1 = 52; /* OOB bits in nibbles per sector */ -+ } -+ break; -+ default: -+ pr_err("selected ECC scheme not supported or not enabled\n"); - } -- -- writel(ECC1, info->reg.gpmc_ecc_control); -- -- /* Configure ecc size for BCH */ -- val = (ecc_size1 << ECCSIZE1_SHIFT) | (ecc_size0 << ECCSIZE0_SHIFT); -- writel(val, info->reg.gpmc_ecc_size_config); -- -- dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; -- -- /* BCH configuration */ -- val = ((1 << 16) | /* enable BCH */ -- (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */ -- (wr_mode << 8) | /* wrap mode */ -- (dev_width << 7) | /* bus width */ -- (((nsectors-1) & 0x7) << 4) | /* number of sectors */ -- (info->gpmc_cs << 1) | /* ECC CS */ -- (0x1)); /* enable ECC */ -- -- writel(val, info->reg.gpmc_ecc_config); -- - /* Clear ecc and enable bits */ - writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); -+ /* Configure ecc size for BCH */ -+ ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12); -+ writel(ecc_size_config_val, info->reg.gpmc_ecc_size_config); -+ /* Configure device details for BCH engine */ -+ ecc_config_val = ((ecc_algo << 16) | /* HAM1 | BCHx */ -+ (bch_type << 12) | /* BCH4/BCH8/BCH16 */ -+ (bch_wrapmode << 8) | /* wrap mode */ -+ (dev_width << 7) | /* bus width */ -+ (((nsectors-1) & 0x7) << 4) | /* number of sectors */ -+ (info->gpmc_cs << 1) | /* ECC CS */ -+ (0x0)); /* disable ECC */ -+ writel(ecc_config_val, info->reg.gpmc_ecc_config); -+ /* enable ECC engine */ -+ writel(ecc_config_val | 0x1, info->reg.gpmc_ecc_config); -+ /* Clear ECC and enable bits */ -+ writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); - } - -+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH) - /** -- * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes -- * @mtd: MTD device structure -- * @dat: The pointer to data on which ecc is computed -- * @ecc_code: The ecc_code buffer -- */ --static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat, -- u_char *ecc_code) --{ -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); -- unsigned long nsectors, val1, val2; -- int i; -- -- nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; -- -- for (i = 0; i < nsectors; i++) { -- -- /* Read hw-computed remainder */ -- val1 = readl(info->reg.gpmc_bch_result0[i]); -- val2 = readl(info->reg.gpmc_bch_result1[i]); -- -- /* -- * Add constant polynomial to remainder, in order to get an ecc -- * sequence of 0xFFs for a buffer filled with 0xFFs; and -- * left-justify the resulting polynomial. -- */ -- *ecc_code++ = 0x28 ^ ((val2 >> 12) & 0xFF); -- *ecc_code++ = 0x13 ^ ((val2 >> 4) & 0xFF); -- *ecc_code++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF)); -- *ecc_code++ = 0x39 ^ ((val1 >> 20) & 0xFF); -- *ecc_code++ = 0x96 ^ ((val1 >> 12) & 0xFF); -- *ecc_code++ = 0xac ^ ((val1 >> 4) & 0xFF); -- *ecc_code++ = 0x7f ^ ((val1 & 0xF) << 4); -- } -- -- return 0; --} -- --/** -- * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes -- * @mtd: MTD device structure -- * @dat: The pointer to data on which ecc is computed -- * @ecc_code: The ecc_code buffer -- */ --static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat, -- u_char *ecc_code) --{ -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); -- unsigned long nsectors, val1, val2, val3, val4; -- int i; -- -- nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; -- -- for (i = 0; i < nsectors; i++) { -- -- /* Read hw-computed remainder */ -- val1 = readl(info->reg.gpmc_bch_result0[i]); -- val2 = readl(info->reg.gpmc_bch_result1[i]); -- val3 = readl(info->reg.gpmc_bch_result2[i]); -- val4 = readl(info->reg.gpmc_bch_result3[i]); -- -- /* -- * Add constant polynomial to remainder, in order to get an ecc -- * sequence of 0xFFs for a buffer filled with 0xFFs. -- */ -- *ecc_code++ = 0xef ^ (val4 & 0xFF); -- *ecc_code++ = 0x51 ^ ((val3 >> 24) & 0xFF); -- *ecc_code++ = 0x2e ^ ((val3 >> 16) & 0xFF); -- *ecc_code++ = 0x09 ^ ((val3 >> 8) & 0xFF); -- *ecc_code++ = 0xed ^ (val3 & 0xFF); -- *ecc_code++ = 0x93 ^ ((val2 >> 24) & 0xFF); -- *ecc_code++ = 0x9a ^ ((val2 >> 16) & 0xFF); -- *ecc_code++ = 0xc2 ^ ((val2 >> 8) & 0xFF); -- *ecc_code++ = 0x97 ^ (val2 & 0xFF); -- *ecc_code++ = 0x79 ^ ((val1 >> 24) & 0xFF); -- *ecc_code++ = 0xe5 ^ ((val1 >> 16) & 0xFF); -- *ecc_code++ = 0x24 ^ ((val1 >> 8) & 0xFF); -- *ecc_code++ = 0xb5 ^ (val1 & 0xFF); -- } -- -- return 0; --} -- --/** -- * omap3_calculate_ecc_bch - Generate bytes of ECC bytes -+ * omap_calculate_ecc_bch - Generate bytes of ECC bytes - * @mtd: MTD device structure - * @dat: The pointer to data on which ecc is computed - * @ecc_code: The ecc_code buffer - * - * Support calculating of BCH4/8 ecc vectors for the page - */ --static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat, -- u_char *ecc_code) -+static int omap_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat, -+ u_char *ecc_calc) - { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); -- unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4; -- int i, eccbchtsel; -+ struct nand_chip *chip = mtd->priv; -+ enum omap_ecc ecc_opt = info->ecc_opt; -+ struct gpmc_nand_regs *gpmc_regs = &info->reg; -+ u32 eccbytes = chip->ecc.bytes; -+ u_char *ecc_ptr; -+ u32 nsectors; -+ int i, val; - -- nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; -- /* -- * find BCH scheme used -- * 0 -> BCH4 -- * 1 -> BCH8 -- */ -- eccbchtsel = ((readl(info->reg.gpmc_ecc_config) >> 12) & 0x3); -+ val = readl(info->reg.gpmc_ecc_config); -+ if (((val >> 1) & 0x07) != info->gpmc_cs) { -+ pr_err("%s: invalid ECC configuration for chip-select=%d", -+ DRIVER_NAME, info->gpmc_cs); -+ return -EINVAL; -+ } -+ nsectors = ((readl(gpmc_regs->gpmc_ecc_config) >> 4) & 0x7) + 1; - - for (i = 0; i < nsectors; i++) { -- -- /* Read hw-computed remainder */ -- bch_val1 = readl(info->reg.gpmc_bch_result0[i]); -- bch_val2 = readl(info->reg.gpmc_bch_result1[i]); -- if (eccbchtsel) { -- bch_val3 = readl(info->reg.gpmc_bch_result2[i]); -- bch_val4 = readl(info->reg.gpmc_bch_result3[i]); -- } -- -- if (eccbchtsel) { -- /* BCH8 ecc scheme */ -- *ecc_code++ = (bch_val4 & 0xFF); -- *ecc_code++ = ((bch_val3 >> 24) & 0xFF); -- *ecc_code++ = ((bch_val3 >> 16) & 0xFF); -- *ecc_code++ = ((bch_val3 >> 8) & 0xFF); -- *ecc_code++ = (bch_val3 & 0xFF); -- *ecc_code++ = ((bch_val2 >> 24) & 0xFF); -- *ecc_code++ = ((bch_val2 >> 16) & 0xFF); -- *ecc_code++ = ((bch_val2 >> 8) & 0xFF); -- *ecc_code++ = (bch_val2 & 0xFF); -- *ecc_code++ = ((bch_val1 >> 24) & 0xFF); -- *ecc_code++ = ((bch_val1 >> 16) & 0xFF); -- *ecc_code++ = ((bch_val1 >> 8) & 0xFF); -- *ecc_code++ = (bch_val1 & 0xFF); -- /* -- * Setting 14th byte to zero to handle -- * erased page & maintain compatibility -- * with RBL -- */ -- *ecc_code++ = 0x0; -- } else { -- /* BCH4 ecc scheme */ -- *ecc_code++ = ((bch_val2 >> 12) & 0xFF); -- *ecc_code++ = ((bch_val2 >> 4) & 0xFF); -- *ecc_code++ = ((bch_val2 & 0xF) << 4) | -- ((bch_val1 >> 28) & 0xF); -- *ecc_code++ = ((bch_val1 >> 20) & 0xFF); -- *ecc_code++ = ((bch_val1 >> 12) & 0xFF); -- *ecc_code++ = ((bch_val1 >> 4) & 0xFF); -- *ecc_code++ = ((bch_val1 & 0xF) << 4); -- /* -- * Setting 8th byte to zero to handle -- * erased page -- */ -- *ecc_code++ = 0x0; -+ ecc_ptr = ecc_calc; -+ switch (ecc_opt) { -+ case OMAP_ECC_HAMMING_CODE_HW: -+ return -EINVAL; -+ case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: -+ case OMAP_ECC_BCH4_CODE_HW: -+ val = readl(gpmc_regs->gpmc_bch_result1[i]); -+ *(ecc_ptr++) = ((val >> 12) & 0xFF); -+ *(ecc_ptr++) = ((val >> 4) & 0xFF); -+ *(ecc_ptr) = ((val >> 0) << 4) & 0xF0; -+ val = readl(gpmc_regs->gpmc_bch_result0[i]); -+ *(ecc_ptr) = ((val >> 28) & 0x0F) | *(ecc_ptr); -+ ecc_ptr++; -+ *(ecc_ptr++) = ((val >> 20) & 0xFF); -+ *(ecc_ptr++) = ((val >> 12) & 0xFF); -+ *(ecc_ptr++) = ((val >> 4) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) << 4) & 0xF0; -+ break; -+ case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: -+ case OMAP_ECC_BCH8_CODE_HW: -+ val = readl(gpmc_regs->gpmc_bch_result3[i]); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result2[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result1[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result0[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ break; -+ case OMAP_ECC_BCH16_CODE_HW: -+ val = readl(gpmc_regs->gpmc_bch_result6[i]); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result5[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result4[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result3[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result2[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result1[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ val = readl(gpmc_regs->gpmc_bch_result0[i]); -+ *(ecc_ptr++) = ((val >> 24) & 0xFF); -+ *(ecc_ptr++) = ((val >> 16) & 0xFF); -+ *(ecc_ptr++) = ((val >> 8) & 0xFF); -+ *(ecc_ptr++) = ((val >> 0) & 0xFF); -+ break; -+ default: -+ return -EINVAL; - } -+ /* ECC scheme specific syndrome customizations */ -+ switch (ecc_opt) { -+ case OMAP_ECC_HAMMING_CODE_HW: -+ return -EINVAL; -+ case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: -+ for (i = 0; i < eccbytes; i++) -+ *(ecc_calc + i) = *(ecc_calc + i) ^ -+ bch4_polynomial[i]; -+ break; -+ case OMAP_ECC_BCH4_CODE_HW: -+ *(ecc_ptr++) = 0x00; -+ break; -+ case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: -+ for (i = 0; i < eccbytes; i++) -+ *(ecc_calc + i) = *(ecc_calc + i) ^ -+ bch8_polynomial[i]; -+ break; -+ case OMAP_ECC_BCH8_CODE_HW: -+ *(ecc_ptr++) = 0x00; -+ break; -+ case OMAP_ECC_BCH16_CODE_HW: -+ break; -+ } -+ /* update pointer to next sector */ -+ ecc_calc += eccbytes; - } -- - return 0; - } -+#endif /*defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)*/ - --/** -- * erased_sector_bitflips - count bit flips -- * @data: data sector buffer -- * @oob: oob buffer -- * @info: omap_nand_info -- * -- * Check the bit flips in erased page falls below correctable level. -- * If falls below, report the page as erased with correctable bit -- * flip, else report as uncorrectable page. -- */ --static int erased_sector_bitflips(u_char *data, u_char *oob, -- struct omap_nand_info *info) --{ -- int flip_bits = 0, i; -- -- for (i = 0; i < info->nand.ecc.size; i++) { -- flip_bits += hweight8(~data[i]); -- if (flip_bits > info->nand.ecc.strength) -- return 0; -- } -- -- for (i = 0; i < info->nand.ecc.bytes - 1; i++) { -- flip_bits += hweight8(~oob[i]); -- if (flip_bits > info->nand.ecc.strength) -- return 0; -- } -- -- /* -- * Bit flips falls in correctable level. -- * Fill data area with 0xFF -- */ -- if (flip_bits) { -- memset(data, 0xFF, info->nand.ecc.size); -- memset(oob, 0xFF, info->nand.ecc.bytes); -- } -- -- return flip_bits; --} -- -+#ifdef CONFIG_MTD_NAND_OMAP_BCH - /** - * omap_elm_correct_data - corrects page data area in case error reported - * @mtd: MTD device structure - * @data: page data - * @read_ecc: ecc read from nand flash -- * @calc_ecc: ecc read from HW ECC registers -- * -- * Calculated ecc vector reported as zero in case of non-error pages. -- * In case of error/erased pages non-zero error vector is reported. -- * In case of non-zero ecc vector, check read_ecc at fixed offset -- * (x = 13/7 in case of BCH8/4 == 0) to find page programmed or not. -- * To handle bit flips in this data, count the number of 0's in -- * read_ecc[x] and check if it greater than 4. If it is less, it is -- * programmed page, else erased page. -- * -- * 1. If page is erased, check with standard ecc vector (ecc vector -- * for erased page to find any bit flip). If check fails, bit flip -- * is present in erased page. Count the bit flips in erased page and -- * if it falls under correctable level, report page with 0xFF and -- * update the correctable bit information. -- * 2. If error is reported on programmed page, update elm error -- * vector and correct the page with ELM error correction routine. -- * -+ * @calc_ecc: ecc calculated after reading Data and OOB regions from flash -+ * As calc_ecc is calculated over both main & oob, so calc_ecc would be -+ * non-zero only in following cases: -+ * - bit-flips in data or oob region -+ * - erase page, where no ECC is written in OOB area -+ * However, erased_pages can be differentiated from corrupted pages -+ * by comparing the calculated ECC with pre-defined syndrome ECC_of_ALL(0xFF) -+ * Bit-flips in erased-pages would also be caught by comparing, calc_ecc -+ * with ECC_of_ALL(0xFF) - */ - static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, - u_char *read_ecc, u_char *calc_ecc) - { - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); -- int eccsteps = info->nand.ecc.steps; -- int i , j, stat = 0; -- int eccsize, eccflag, ecc_vector_size; -+ enum omap_ecc ecc_opt = info->ecc_opt; -+ struct nand_chip *chip = mtd->priv; -+ int eccsteps = chip->ecc.steps; -+ int eccsize = chip->ecc.size; -+ int eccbytes = chip->ecc.bytes; -+ int i , j, stat = 0, ret = 0, flag_read_ecc; - struct elm_errorvec err_vec[ERROR_VECTOR_MAX]; -- u_char *ecc_vec = calc_ecc; -- u_char *spare_ecc = read_ecc; -- u_char *erased_ecc_vec; -- enum bch_ecc type; -+ u_char *ecc; - bool is_error_reported = false; -+ u32 bit_pos, byte_pos, error_max, pos; - - /* Initialize elm error vector to zero */ - memset(err_vec, 0, sizeof(err_vec)); -- -- if (info->nand.ecc.strength == BCH8_MAX_ERROR) { -- type = BCH8_ECC; -- erased_ecc_vec = bch8_vector; -- } else { -- type = BCH4_ECC; -- erased_ecc_vec = bch4_vector; -- } -- -- ecc_vector_size = info->nand.ecc.bytes; -- -- /* -- * Remove extra byte padding for BCH8 RBL -- * compatibility and erased page handling -- */ -- eccsize = ecc_vector_size - 1; -- - for (i = 0; i < eccsteps ; i++) { -- eccflag = 0; /* initialize eccflag */ -- -- /* -- * Check any error reported, -- * In case of error, non zero ecc reported. -- */ -- -- for (j = 0; (j < eccsize); j++) { -- if (calc_ecc[j] != 0) { -- eccflag = 1; /* non zero ecc, error present */ -+ flag_read_ecc = 0; -+ ecc = calc_ecc + (i * eccbytes); -+ /* check calc_ecc */ -+ for (j = 0; j < eccbytes; j++) { -+ if (*(ecc + j) != 0x00) { -+ flag_read_ecc = 1; - break; - } - } -- -- if (eccflag == 1) { -- /* -- * Set threshold to minimum of 4, half of ecc.strength/2 -- * to allow max bit flip in byte to 4 -- */ -- unsigned int threshold = min_t(unsigned int, 4, -- info->nand.ecc.strength / 2); -- -- /* -- * Check data area is programmed by counting -- * number of 0's at fixed offset in spare area. -- * Checking count of 0's against threshold. -- * In case programmed page expects at least threshold -- * zeros in byte. -- * If zeros are less than threshold for programmed page/ -- * zeros are more than threshold erased page, either -- * case page reported as uncorrectable. -- */ -- if (hweight8(~read_ecc[eccsize]) >= threshold) { -- /* -- * Update elm error vector as -- * data area is programmed -- */ -- err_vec[i].error_reported = true; -- is_error_reported = true; -- } else { -- /* Error reported in erased page */ -- int bitflip_count; -- u_char *buf = &data[info->nand.ecc.size * i]; -- -- if (memcmp(calc_ecc, erased_ecc_vec, eccsize)) { -- bitflip_count = erased_sector_bitflips( -- buf, read_ecc, info); -- -- if (bitflip_count) -- stat += bitflip_count; -- else -- return -EINVAL; -- } -+ /* check if its a erased-page */ -+ if (flag_read_ecc) { -+ switch (ecc_opt) { -+ case OMAP_ECC_BCH4_CODE_HW: -+ if (memcmp(ecc, bch4_vector, eccbytes)) -+ err_vec[i].error_reported = true; -+ break; -+ case OMAP_ECC_BCH8_CODE_HW: -+ if (memcmp(ecc, bch8_vector, eccbytes)) -+ err_vec[i].error_reported = true; -+ break; -+ case OMAP_ECC_BCH16_CODE_HW: -+ if (memcmp(ecc, bch16_vector, eccbytes)) -+ err_vec[i].error_reported = true; -+ break; -+ default: -+ pr_err("%s: invalid configuration", -+ DRIVER_NAME); -+ return -EINVAL; - } - } -- -- /* Update the ecc vector */ -- calc_ecc += ecc_vector_size; -- read_ecc += ecc_vector_size; -+ /* page definitely has bit-flips */ -+ if (err_vec[i].error_reported) -+ is_error_reported = true; - } - -- /* Check if any error reported */ - if (!is_error_reported) - return 0; -+ /* detect bit-flips using ELM module */ -+ elm_decode_bch_error_page(info->elm_dev, calc_ecc, err_vec); - -- /* Decode BCH error using ELM module */ -- elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec); -- -+ /* correct bit-flip */ - for (i = 0; i < eccsteps; i++) { -- if (err_vec[i].error_reported) { -+ if (err_vec[i].error_uncorrectable) { -+ ret = -EBADMSG; -+ } else if (err_vec[i].error_reported) { - for (j = 0; j < err_vec[i].error_count; j++) { -- u32 bit_pos, byte_pos, error_max, pos; -- -- if (type == BCH8_ECC) -- error_max = BCH8_ECC_MAX; -- else -- error_max = BCH4_ECC_MAX; -- -- if (info->nand.ecc.strength == BCH8_MAX_ERROR) -- pos = err_vec[i].error_loc[j]; -- else -+ switch (ecc_opt) { -+ case OMAP_ECC_BCH4_CODE_HW: -+ error_max = SECTOR_BYTES + -+ (eccbytes - 1); - /* Add 4 to take care 4 bit padding */ - pos = err_vec[i].error_loc[j] + -- BCH4_BIT_PAD; -- -- /* Calculate bit position of error */ -+ BCH4_BIT_PAD; -+ break; -+ case OMAP_ECC_BCH8_CODE_HW: -+ error_max = SECTOR_BYTES + -+ (eccbytes - 1); -+ pos = err_vec[i].error_loc[j]; -+ break; -+ case OMAP_ECC_BCH16_CODE_HW: -+ error_max = SECTOR_BYTES + eccbytes; -+ pos = err_vec[i].error_loc[j]; -+ break; -+ default: -+ return -EINVAL; -+ } -+ /* Calculate bit & byte bit-flip position */ - bit_pos = pos % 8; -- -- /* Calculate byte position of error */ -- byte_pos = (error_max - pos - 1) / 8; -- -- if (pos < error_max) { -- if (byte_pos < 512) -- data[byte_pos] ^= 1 << bit_pos; -- else -- spare_ecc[byte_pos - 512] ^= -+ byte_pos = error_max - (pos / 8) - 1; -+ if (byte_pos < SECTOR_BYTES) -+ data[byte_pos] ^= 1 << bit_pos; -+ else if (byte_pos < error_max) -+ read_ecc[byte_pos - SECTOR_BYTES] ^= - 1 << bit_pos; -- } -- /* else, not interested to correct ecc */ -+ else -+ ret = -EBADMSG; - } - } -- - /* Update number of correctable errors */ - stat += err_vec[i].error_count; -- - /* Update page data with sector size */ -- data += info->nand.ecc.size; -- spare_ecc += ecc_vector_size; -+ data += eccsize; -+ read_ecc += eccbytes; - } - -- for (i = 0; i < eccsteps; i++) -- /* Return error if uncorrectable error present */ -- if (err_vec[i].error_uncorrectable) -- return -EINVAL; -- -- return stat; --} -- --/** -- * omap3_correct_data_bch - Decode received data and correct errors -- * @mtd: MTD device structure -- * @data: page data -- * @read_ecc: ecc read from nand flash -- * @calc_ecc: ecc read from HW ECC registers -- */ --static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data, -- u_char *read_ecc, u_char *calc_ecc) --{ -- int i, count; -- /* cannot correct more than 8 errors */ -- unsigned int errloc[8]; -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); -- -- count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL, -- errloc); -- if (count > 0) { -- /* correct errors */ -- for (i = 0; i < count; i++) { -- /* correct data only, not ecc bytes */ -- if (errloc[i] < 8*512) -- data[errloc[i]/8] ^= 1 << (errloc[i] & 7); -- pr_debug("corrected bitflip %u\n", errloc[i]); -- } -- } else if (count < 0) { -- pr_err("ecc unrecoverable error\n"); -- } -- return count; -+ return (ret < 0) ? ret : stat; - } - - /** -@@ -1637,186 +1449,30 @@ static int omap_read_page_bch(struct mtd - } - - /** -- * omap3_free_bch - Release BCH ecc resources -- * @mtd: MTD device structure -- */ --static void omap3_free_bch(struct mtd_info *mtd) --{ -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); -- if (info->bch) { -- free_bch(info->bch); -- info->bch = NULL; -- } --} -- --/** -- * omap3_init_bch - Initialize BCH ECC -- * @mtd: MTD device structure -- * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW) -- */ --static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt) --{ -- int max_errors; -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); --#ifdef CONFIG_MTD_NAND_OMAP_BCH8 -- const int hw_errors = BCH8_MAX_ERROR; --#else -- const int hw_errors = BCH4_MAX_ERROR; --#endif -- enum bch_ecc bch_type; -- const __be32 *parp; -- int lenp; -- struct device_node *elm_node; -- -- info->bch = NULL; -- -- max_errors = (ecc_opt == OMAP_ECC_BCH8_CODE_HW) ? -- BCH8_MAX_ERROR : BCH4_MAX_ERROR; -- if (max_errors != hw_errors) { -- pr_err("cannot configure %d-bit BCH ecc, only %d-bit supported", -- max_errors, hw_errors); -- goto fail; -- } -- -- info->nand.ecc.size = 512; -- info->nand.ecc.hwctl = omap3_enable_hwecc_bch; -- info->nand.ecc.mode = NAND_ECC_HW; -- info->nand.ecc.strength = max_errors; -- -- if (hw_errors == BCH8_MAX_ERROR) -- bch_type = BCH8_ECC; -- else -- bch_type = BCH4_ECC; -- -- /* Detect availability of ELM module */ -- parp = of_get_property(info->of_node, "elm_id", &lenp); -- if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) { -- pr_err("Missing elm_id property, fall back to Software BCH\n"); -- info->is_elm_used = false; -- } else { -- struct platform_device *pdev; -- -- elm_node = of_find_node_by_phandle(be32_to_cpup(parp)); -- pdev = of_find_device_by_node(elm_node); -- info->elm_dev = &pdev->dev; -- -- if (elm_config(info->elm_dev, bch_type) == 0) -- info->is_elm_used = true; -- } -- -- if (info->is_elm_used && (mtd->writesize <= 4096)) { -- -- if (hw_errors == BCH8_MAX_ERROR) -- info->nand.ecc.bytes = BCH8_SIZE; -- else -- info->nand.ecc.bytes = BCH4_SIZE; -- -- info->nand.ecc.correct = omap_elm_correct_data; -- info->nand.ecc.calculate = omap3_calculate_ecc_bch; -- info->nand.ecc.read_page = omap_read_page_bch; -- info->nand.ecc.write_page = omap_write_page_bch; -- } else { -- /* -- * software bch library is only used to detect and -- * locate errors -- */ -- info->bch = init_bch(13, max_errors, -- 0x201b /* hw polynomial */); -- if (!info->bch) -- goto fail; -- -- info->nand.ecc.correct = omap3_correct_data_bch; -- -- /* -- * The number of corrected errors in an ecc block that will -- * trigger block scrubbing defaults to the ecc strength (4 or 8) -- * Set mtd->bitflip_threshold here to define a custom threshold. -- */ -- -- if (max_errors == 8) { -- info->nand.ecc.bytes = 13; -- info->nand.ecc.calculate = omap3_calculate_ecc_bch8; -- } else { -- info->nand.ecc.bytes = 7; -- info->nand.ecc.calculate = omap3_calculate_ecc_bch4; -- } -- } -- -- pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors); -- return 0; --fail: -- omap3_free_bch(mtd); -- return -1; --} -- --/** -- * omap3_init_bch_tail - Build an oob layout for BCH ECC correction. -- * @mtd: MTD device structure -- */ --static int omap3_init_bch_tail(struct mtd_info *mtd) --{ -- int i, steps, offset; -- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -- mtd); -- struct nand_ecclayout *layout = &info->ecclayout; -- -- /* build oob layout */ -- steps = mtd->writesize/info->nand.ecc.size; -- layout->eccbytes = steps*info->nand.ecc.bytes; -- -- /* do not bother creating special oob layouts for small page devices */ -- if (mtd->oobsize < 64) { -- pr_err("BCH ecc is not supported on small page devices\n"); -- goto fail; -+ * is_elm_present - checks for presence of ELM module by scanning DT nodes -+ * @omap_nand_info: NAND device structure containing platform data -+ * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16 -+ */ -+static int is_elm_present(struct omap_nand_info *info, -+ struct device_node *elm_node, enum bch_ecc bch_type) -+{ -+ struct platform_device *pdev; -+ /* check whether elm-id is passed via DT */ -+ if (!elm_node) { -+ pr_err("nand: error: ELM DT node not found\n"); -+ return -ENODEV; - } -- -- /* reserve 2 bytes for bad block marker */ -- if (layout->eccbytes+2 > mtd->oobsize) { -- pr_err("no oob layout available for oobsize %d eccbytes %u\n", -- mtd->oobsize, layout->eccbytes); -- goto fail; -+ pdev = of_find_device_by_node(elm_node); -+ /* check whether ELM device is registered */ -+ if (!pdev) { -+ pr_err("nand: error: ELM device not found\n"); -+ return -ENODEV; - } -- -- /* ECC layout compatible with RBL for BCH8 */ -- if (info->is_elm_used && (info->nand.ecc.bytes == BCH8_SIZE)) -- offset = 2; -- else -- offset = mtd->oobsize - layout->eccbytes; -- -- /* put ecc bytes at oob tail */ -- for (i = 0; i < layout->eccbytes; i++) -- layout->eccpos[i] = offset + i; -- -- if (info->is_elm_used && (info->nand.ecc.bytes == BCH8_SIZE)) -- layout->oobfree[0].offset = 2 + layout->eccbytes * steps; -- else -- layout->oobfree[0].offset = 2; -- -- layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes; -- info->nand.ecc.layout = layout; -- -- if (!(info->nand.options & NAND_BUSWIDTH_16)) -- info->nand.badblock_pattern = &bb_descrip_flashbased; -+ /* ELM module available, now configure it */ -+ info->elm_dev = &pdev->dev; -+ if (elm_config(info->elm_dev, &info->mtd, bch_type)) -+ return -ENODEV; - return 0; --fail: -- omap3_free_bch(mtd); -- return -1; --} -- --#else --static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt) --{ -- pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n"); -- return -1; --} --static int omap3_init_bch_tail(struct mtd_info *mtd) --{ -- return -1; --} --static void omap3_free_bch(struct mtd_info *mtd) --{ - } - #endif /* CONFIG_MTD_NAND_OMAP_BCH */ - -@@ -1824,10 +1480,13 @@ static int omap_nand_probe(struct platfo - { - struct omap_nand_info *info; - struct omap_nand_platform_data *pdata; -+ struct mtd_info *mtd; -+ struct nand_chip *chip; -+ struct nand_ecclayout *ecclayout; - int err; -- int i, offset; -- dma_cap_mask_t mask; -- unsigned sig; -+ int i; -+ dma_cap_mask_t mask; -+ unsigned sig; - struct resource *res; - struct mtd_part_parser_data ppdata = {}; - -@@ -1846,20 +1505,22 @@ static int omap_nand_probe(struct platfo - spin_lock_init(&info->controller.lock); - init_waitqueue_head(&info->controller.wq); - -- info->pdev = pdev; -+ mtd = &info->mtd; -+ mtd->name = dev_name(&pdev->dev); -+ mtd->owner = THIS_MODULE; -+ mtd->priv = &info->nand; -+ chip = mtd->priv; -+ chip->ecc.priv = NULL; - -+ info->pdev = pdev; - info->gpmc_cs = pdata->cs; - info->reg = pdata->reg; -+ info->ecc_opt = pdata->ecc_opt; - -- info->mtd.priv = &info->nand; -- info->mtd.name = dev_name(&pdev->dev); -- info->mtd.owner = THIS_MODULE; -- -- info->nand.options = pdata->devsize; -+ info->nand.options = NAND_BUSWIDTH_AUTO; - info->nand.options |= NAND_SKIP_BBTSCAN; --#ifdef CONFIG_MTD_NAND_OMAP_BCH - info->of_node = pdata->of_node; --#endif -+ - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { -@@ -1903,6 +1564,30 @@ static int omap_nand_probe(struct platfo - info->nand.chip_delay = 50; - } - -+ /* scan NAND device conncted to controller */ -+ if (nand_scan_ident(mtd, 1, NULL)) { -+ err = -ENXIO; -+ goto out_release_mem_region; -+ } -+ pr_info("%s: detected %s NAND flash\n", DRIVER_NAME, -+ (info->nand.options & NAND_BUSWIDTH_16) ? "x16" : "x8"); -+ if ((info->nand.options & NAND_BUSWIDTH_16) != -+ (pdata->devsize & NAND_BUSWIDTH_16)) { -+ pr_err("%s: but incorrectly configured as %s", DRIVER_NAME, -+ (pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+ } -+ -+ /* check for small page devices */ -+ if ((mtd->oobsize < 64) && -+ (pdata->ecc_opt != OMAP_ECC_HAMMING_CODE_HW)) { -+ pr_err("small page devices are not supported\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+ } -+ -+ /* populate read & write API based on xfer_type selected */ - switch (pdata->xfer_type) { - case NAND_OMAP_PREFETCH_POLLED: - info->nand.read_buf = omap_read_buf_pref; -@@ -1992,64 +1677,218 @@ static int omap_nand_probe(struct platfo - goto out_release_mem_region; - } - -- /* select the ecc type */ -- if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) -- info->nand.ecc.mode = NAND_ECC_SOFT; -- else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || -- (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { -+ /* populate MTD interface based on ECC scheme */ -+ chip->ecclayout = &omap_oobinfo; -+ chip->ecc.layout = &omap_oobinfo; -+ ecclayout = &omap_oobinfo; -+ switch (pdata->ecc_opt) { -+ case OMAP_ECC_HAMMING_CODE_HW: -+ pr_info("nand: using OMAP_ECC_HAMMING_CODE_HW\n"); -+ info->nand.ecc.mode = NAND_ECC_HW; - info->nand.ecc.bytes = 3; - info->nand.ecc.size = 512; - info->nand.ecc.strength = 1; - info->nand.ecc.calculate = omap_calculate_ecc; - info->nand.ecc.hwctl = omap_enable_hwecc; - info->nand.ecc.correct = omap_correct_data; -- info->nand.ecc.mode = NAND_ECC_HW; -- } else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) || -- (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) { -- err = omap3_init_bch(&info->mtd, pdata->ecc_opt); -- if (err) { -+ /* define custom ECC layout */ -+ ecclayout->eccbytes = info->nand.ecc.bytes * -+ (mtd->writesize / -+ info->nand.ecc.size); -+ if (info->nand.options & NAND_BUSWIDTH_16) -+ ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; -+ else -+ ecclayout->eccpos[0] = 1; -+ ecclayout->oobfree->offset = ecclayout->eccpos[0] + -+ ecclayout->eccbytes; -+ goto custom_ecc_layout; -+ break; -+ case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: -+#ifdef CONFIG_MTD_NAND_ECC_BCH -+ pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n"); -+ info->nand.ecc.mode = NAND_ECC_HW; -+ info->nand.ecc.size = 512; -+ info->nand.ecc.bytes = 7; -+ info->nand.ecc.strength = 4; -+ info->nand.ecc.hwctl = omap_enable_hwecc; -+ info->nand.ecc.correct = nand_bch_correct_data; -+ info->nand.ecc.calculate = omap_calculate_ecc_bch; -+ /* define custom ECC layout */ -+ ecclayout->eccbytes = info->nand.ecc.bytes * -+ (mtd->writesize / -+ info->nand.ecc.size); -+ ecclayout->eccpos[0] = info->mtd.oobsize - -+ ecclayout->eccbytes; -+ ecclayout->oobfree->offset = BADBLOCK_MARKER_LENGTH; -+ /* software bch library is used for locating errors */ -+ info->nand.ecc.priv = nand_bch_init(mtd, -+ info->nand.ecc.size, -+ info->nand.ecc.bytes, -+ &info->nand.ecc.layout); -+ if (!info->nand.ecc.priv) { -+ pr_err("nand: error: unable to use s/w BCH library\n"); - err = -EINVAL; - goto out_release_mem_region; - } -- } -- -- /* DIP switches on some boards change between 8 and 16 bit -- * bus widths for flash. Try the other width if the first try fails. -- */ -- if (nand_scan_ident(&info->mtd, 1, NULL)) { -- info->nand.options ^= NAND_BUSWIDTH_16; -- if (nand_scan_ident(&info->mtd, 1, NULL)) { -- err = -ENXIO; -+ goto custom_ecc_layout; -+#else -+ pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+#endif -+ break; -+ case OMAP_ECC_BCH4_CODE_HW: -+#ifdef CONFIG_MTD_NAND_OMAP_BCH -+ pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n"); -+ info->nand.ecc.mode = NAND_ECC_HW; -+ info->nand.ecc.size = 512; -+ /* 14th bit is kept reserved for ROM-code compatibility */ -+ info->nand.ecc.bytes = 7 + 1; -+ info->nand.ecc.strength = 4; -+ info->nand.ecc.hwctl = omap_enable_hwecc; -+ info->nand.ecc.correct = omap_elm_correct_data; -+ info->nand.ecc.calculate = omap_calculate_ecc_bch; -+ info->nand.ecc.read_page = omap_read_page_bch; -+ info->nand.ecc.write_page = omap_write_page_bch; -+ /* This ECC scheme requires ELM H/W block */ -+ if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { -+ pr_err("nand: error: could not initialize ELM\n"); -+ err = -ENODEV; - goto out_release_mem_region; - } -- } -- -- /* rom code layout */ -- if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { -- -- if (info->nand.options & NAND_BUSWIDTH_16) -- offset = 2; -- else { -- offset = 1; -- info->nand.badblock_pattern = &bb_descrip_flashbased; -- } -- omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); -- for (i = 0; i < omap_oobinfo.eccbytes; i++) -- omap_oobinfo.eccpos[i] = i+offset; -- -- omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; -- omap_oobinfo.oobfree->length = info->mtd.oobsize - -- (offset + omap_oobinfo.eccbytes); -- -- info->nand.ecc.layout = &omap_oobinfo; -- } else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) || -- (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) { -- /* build OOB layout for BCH ECC correction */ -- err = omap3_init_bch_tail(&info->mtd); -- if (err) { -+ /* define custom ECC layout */ -+ ecclayout->eccbytes = info->nand.ecc.bytes * -+ (mtd->writesize / -+ info->nand.ecc.size); -+ ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; -+ ecclayout->oobfree->offset = ecclayout->eccpos[0] + -+ ecclayout->eccbytes; -+ goto custom_ecc_layout; -+#else -+ pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+#endif -+ break; -+ case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: -+#ifdef CONFIG_MTD_NAND_ECC_BCH -+ pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); -+ info->nand.ecc.mode = NAND_ECC_HW; -+ info->nand.ecc.size = 512; -+ info->nand.ecc.bytes = 13; -+ info->nand.ecc.strength = 8; -+ info->nand.ecc.hwctl = omap_enable_hwecc; -+ info->nand.ecc.correct = nand_bch_correct_data; -+ info->nand.ecc.calculate = omap_calculate_ecc_bch; -+ /* define custom ECC layout */ -+ ecclayout->eccbytes = info->nand.ecc.bytes * -+ (mtd->writesize / -+ info->nand.ecc.size); -+ ecclayout->eccpos[0] = info->mtd.oobsize - -+ ecclayout->eccbytes; -+ ecclayout->oobfree->offset = BADBLOCK_MARKER_LENGTH; -+ /* software bch library is used for locating errors */ -+ info->nand.ecc.priv = nand_bch_init(mtd, -+ info->nand.ecc.size, -+ info->nand.ecc.bytes, -+ &info->nand.ecc.layout); -+ if (!info->nand.ecc.priv) { -+ pr_err("nand: error: unable to use s/w BCH library\n"); - err = -EINVAL; - goto out_release_mem_region; - } -+ goto custom_ecc_layout; -+#else -+ pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+#endif -+ break; -+ case OMAP_ECC_BCH8_CODE_HW: -+#ifdef CONFIG_MTD_NAND_OMAP_BCH -+ pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n"); -+ info->nand.ecc.mode = NAND_ECC_HW; -+ info->nand.ecc.size = 512; -+ /* 14th bit is kept reserved for ROM-code compatibility */ -+ info->nand.ecc.bytes = 13 + 1; -+ info->nand.ecc.strength = 8; -+ info->nand.ecc.hwctl = omap_enable_hwecc; -+ info->nand.ecc.correct = omap_elm_correct_data; -+ info->nand.ecc.calculate = omap_calculate_ecc_bch; -+ info->nand.ecc.read_page = omap_read_page_bch; -+ info->nand.ecc.write_page = omap_write_page_bch; -+ /* This ECC scheme requires ELM H/W block */ -+ if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) { -+ pr_err("nand: error: could not initialize ELM\n"); -+ err = -ENODEV; -+ goto out_release_mem_region; -+ } -+ /* define custom ECC layout */ -+ ecclayout->eccbytes = info->nand.ecc.bytes * -+ (mtd->writesize / -+ info->nand.ecc.size); -+ ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; -+ ecclayout->oobfree->offset = ecclayout->eccpos[0] + -+ ecclayout->eccbytes; -+ goto custom_ecc_layout; -+#else -+ pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+#endif -+ break; -+ case OMAP_ECC_BCH16_CODE_HW: -+#ifdef CONFIG_MTD_NAND_OMAP_BCH -+ pr_info("using OMAP_ECC_BCH16_CODE_HW ECC scheme\n"); -+ chip->ecc.mode = NAND_ECC_HW; -+ chip->ecc.size = 512; -+ /* 14th bit is kept reserved for ROM-code compatibility */ -+ chip->ecc.bytes = 26; -+ chip->ecc.strength = 16; -+ chip->ecc.hwctl = omap_enable_hwecc; -+ chip->ecc.correct = omap_elm_correct_data; -+ chip->ecc.calculate = omap_calculate_ecc_bch; -+ chip->ecc.read_page = omap_read_page_bch; -+ chip->ecc.write_page = omap_write_page_bch; -+ /* ELM H/W engine is used for locating errors */ -+ if (is_elm_present(info, pdata->elm_of_node, BCH16_ECC) < 0) { -+ pr_err("ELM module not detected, required for ECC\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+ } -+ /* define custom ECC layout */ -+ omap_oobinfo.eccbytes = chip->ecc.bytes * -+ (mtd->writesize / chip->ecc.size); -+ omap_oobinfo.eccpos[0] = BADBLOCK_MARKER_LENGTH; -+ omap_oobinfo.oobfree->offset = omap_oobinfo.eccpos[0] + -+ omap_oobinfo.eccbytes; -+ goto custom_ecc_layout; -+#else -+ pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+#endif -+ default: -+ pr_err("nand: error: invalid or unsupported ECC scheme\n"); -+ err = -EINVAL; -+ goto out_release_mem_region; -+ } -+ -+custom_ecc_layout: -+ /* populate remaining info for custom ecc layout */ -+ pr_info("%s: using custom ecc layout\n", DRIVER_NAME); -+ ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH -+ - ecclayout->eccbytes; -+ if (!(info->nand.options & NAND_BUSWIDTH_16)) -+ info->nand.badblock_pattern = &bb_descrip_flashbased; -+ for (i = 1; i < ecclayout->eccbytes; i++) -+ ecclayout->eccpos[i] = ecclayout->eccpos[0] + i; -+ /* check if NAND OOBSIZE meets ECC scheme requirement */ -+ if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { -+ pr_err("not enough OOB bytes required = %d, available=%d\n", -+ ecclayout->eccbytes, mtd->oobsize); -+ err = -EINVAL; -+ goto out_release_mem_region; - } - - /* second phase scan */ -@@ -2074,7 +1913,14 @@ out_release_mem_region: - if (info->gpmc_irq_fifo > 0) - free_irq(info->gpmc_irq_fifo, info); - release_mem_region(info->phys_base, info->mem_size); -+ - out_free_info: -+#ifdef CONFIG_MTD_NAND_ECC_BCH -+ if (info->nand.ecc.priv) { -+ nand_bch_free(info->nand.ecc.priv); -+ info->nand.ecc.priv = NULL; -+ } -+#endif - kfree(info); - - return err; -@@ -2085,8 +1931,12 @@ static int omap_nand_remove(struct platf - struct mtd_info *mtd = platform_get_drvdata(pdev); - struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, - mtd); -- omap3_free_bch(&info->mtd); -- -+#ifdef CONFIG_MTD_NAND_ECC_BCH -+ if (info->nand.ecc.priv) { -+ nand_bch_free(info->nand.ecc.priv); -+ info->nand.ecc.priv = NULL; -+ } -+#endif - if (info->dma) - dma_release_channel(info->dma); - ---- a/drivers/mtd/tests/oobtest.c -+++ b/drivers/mtd/tests/oobtest.c -@@ -210,11 +210,29 @@ static int verify_eraseblock(int ebnum) - static int verify_eraseblock_in_one_go(int ebnum) - { - struct mtd_oob_ops ops; -- int err = 0; -+ int i, err = 0; - loff_t addr = ebnum * mtd->erasesize; - size_t len = mtd->ecclayout->oobavail * pgcnt; - -- prandom_bytes_state(&rnd_state, writebuf, len); -+ /* -+ * if mtd->ecclayout->oobavail is not a multiple of 4 then -+ * while generating psuedo random numbers to write to flash -+ * prandom_bytes_state () generates the extra random bytes -+ * which wont be done if we do for the whole length. So check -+ * for mtd->ecclayout->oobavail if its multiple of 4 then -+ * generate for full len (mtd->ecclayout->oobavail * pgcnt) -+ * else generate prandom of mtd->ecclayout->oobavail bytes -+ * pgcnt times. -+ */ -+ -+ if (mtd->ecclayout->oobavail % sizeof(u32)) { -+ for (i = 0; i < len; i += mtd->ecclayout->oobavail) -+ prandom_bytes_state(&rnd_state, writebuf + i, -+ mtd->ecclayout->oobavail); -+ } else { -+ prandom_bytes_state(&rnd_state, writebuf, len); -+ } -+ - ops.mode = MTD_OPS_AUTO_OOB; - ops.len = 0; - ops.retlen = 0; -@@ -266,7 +284,7 @@ static int verify_all_eraseblocks(void) - static int __init mtd_oobtest_init(void) - { - int err = 0; -- unsigned int i; -+ unsigned int i, j; - uint64_t tmp; - struct mtd_oob_ops ops; - loff_t addr = 0, addr0; -@@ -341,7 +359,6 @@ static int __init mtd_oobtest_init(void) - err = verify_all_eraseblocks(); - if (err) - goto out; -- - /* - * Second test: write all OOB, a block at a time, read it back and - * verify. -@@ -591,10 +608,26 @@ static int __init mtd_oobtest_init(void) - prandom_seed_state(&rnd_state, 11); - pr_info("verifying all eraseblocks\n"); - for (i = 0; i < ebcnt - 1; ++i) { -+ size_t sz = mtd->ecclayout->oobavail; - if (bbt[i] || bbt[i + 1]) - continue; -- prandom_bytes_state(&rnd_state, writebuf, -- mtd->ecclayout->oobavail * 2); -+ /* -+ * if mtd->ecclayout->oobavail is not a multiple of 4 then -+ * while generating psuedo random numbers to write to flash -+ * prandom_bytes_state () generates the extra random bytes -+ * which wont be done if we do for the whole length. So check -+ * for mtd->ecclayout->oobavail if its multiple of 4 then -+ * generate for full len (mtd->ecclayout->oobavail * pgcnt) -+ * else generate prandom of mtd->ecclayout->oobavail bytes -+ * pgcnt times. -+ */ -+ if (sz % sizeof(u32)) { -+ for (j = 0; j < sz * 2; j += sz) -+ prandom_bytes_state(&rnd_state, -+ writebuf + j , sz); -+ } else { -+ prandom_bytes_state(&rnd_state, writebuf, sz * 2); -+ } - addr = (i + 1) * mtd->erasesize - mtd->writesize; - ops.mode = MTD_OPS_AUTO_OOB; - ops.len = 0; ---- a/drivers/net/ethernet/ti/cpsw.c -+++ b/drivers/net/ethernet/ti/cpsw.c -@@ -367,8 +367,6 @@ struct cpsw_priv { - spinlock_t lock; - struct platform_device *pdev; - struct net_device *ndev; -- struct resource *cpsw_res; -- struct resource *cpsw_wr_res; - struct napi_struct napi; - struct device *dev; - struct cpsw_platform_data data; -@@ -1016,6 +1014,10 @@ static void cpsw_slave_open(struct cpsw_ - dev_info(priv->dev, "phy found : id is : 0x%x\n", - slave->phy->phy_id); - phy_start(slave->phy); -+ -+ /* Configure GMII_SEL register */ -+ cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, -+ slave->slave_num); - } - } - -@@ -1705,62 +1707,55 @@ static int cpsw_probe_dt(struct cpsw_pla - - if (of_property_read_u32(node, "active_slave", &prop)) { - pr_err("Missing active_slave property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->active_slave = prop; - - if (of_property_read_u32(node, "cpts_clock_mult", &prop)) { - pr_err("Missing cpts_clock_mult property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->cpts_clock_mult = prop; - - if (of_property_read_u32(node, "cpts_clock_shift", &prop)) { - pr_err("Missing cpts_clock_shift property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->cpts_clock_shift = prop; - -- data->slave_data = kcalloc(data->slaves, sizeof(struct cpsw_slave_data), -- GFP_KERNEL); -+ data->slave_data = devm_kzalloc(&pdev->dev, data->slaves -+ * sizeof(struct cpsw_slave_data), -+ GFP_KERNEL); - if (!data->slave_data) -- return -EINVAL; -+ return -ENOMEM; - - if (of_property_read_u32(node, "cpdma_channels", &prop)) { - pr_err("Missing cpdma_channels property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->channels = prop; - - if (of_property_read_u32(node, "ale_entries", &prop)) { - pr_err("Missing ale_entries property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->ale_entries = prop; - - if (of_property_read_u32(node, "bd_ram_size", &prop)) { - pr_err("Missing bd_ram_size property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->bd_ram_size = prop; - - if (of_property_read_u32(node, "rx_descs", &prop)) { - pr_err("Missing rx_descs property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->rx_descs = prop; - - if (of_property_read_u32(node, "mac_control", &prop)) { - pr_err("Missing mac_control property in the DT.\n"); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - data->mac_control = prop; - -@@ -1791,8 +1786,7 @@ static int cpsw_probe_dt(struct cpsw_pla - parp = of_get_property(slave_node, "phy_id", &lenp); - if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { - pr_err("Missing slave[%d] phy_id property\n", i); -- ret = -EINVAL; -- goto error_ret; -+ return -EINVAL; - } - mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); - phyid = be32_to_cpup(parp+1); -@@ -1822,10 +1816,6 @@ static int cpsw_probe_dt(struct cpsw_pla - } - - return 0; -- --error_ret: -- kfree(data->slave_data); -- return ret; - } - - static int cpsw_probe_dual_emac(struct platform_device *pdev, -@@ -1867,7 +1857,6 @@ static int cpsw_probe_dual_emac(struct p - priv_sl2->coal_intvl = 0; - priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; - -- priv_sl2->cpsw_res = priv->cpsw_res; - priv_sl2->regs = priv->regs; - priv_sl2->host_port = priv->host_port; - priv_sl2->host_port_regs = priv->host_port_regs; -@@ -1911,8 +1900,8 @@ static int cpsw_probe(struct platform_de - struct cpsw_priv *priv; - struct cpdma_params dma_params; - struct cpsw_ale_params ale_params; -- void __iomem *ss_regs, *wr_regs; -- struct resource *res; -+ void __iomem *ss_regs; -+ struct resource *res, *ss_res; - u32 slave_offset, sliver_offset, slave_size; - int ret = 0, i, k = 0; - -@@ -1948,7 +1937,7 @@ static int cpsw_probe(struct platform_de - if (cpsw_probe_dt(&priv->data, pdev)) { - pr_err("cpsw: platform data missing\n"); - ret = -ENODEV; -- goto clean_ndev_ret; -+ goto clean_runtime_disable_ret; - } - data = &priv->data; - -@@ -1962,11 +1951,12 @@ static int cpsw_probe(struct platform_de - - memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); - -- priv->slaves = kzalloc(sizeof(struct cpsw_slave) * data->slaves, -- GFP_KERNEL); -+ priv->slaves = devm_kzalloc(&pdev->dev, -+ sizeof(struct cpsw_slave) * data->slaves, -+ GFP_KERNEL); - if (!priv->slaves) { -- ret = -EBUSY; -- goto clean_ndev_ret; -+ ret = -ENOMEM; -+ goto clean_runtime_disable_ret; - } - for (i = 0; i < data->slaves; i++) - priv->slaves[i].slave_num = i; -@@ -1974,55 +1964,31 @@ static int cpsw_probe(struct platform_de - priv->slaves[0].ndev = ndev; - priv->emac_port = 0; - -- priv->clk = clk_get(&pdev->dev, "fck"); -+ priv->clk = devm_clk_get(&pdev->dev, "fck"); - if (IS_ERR(priv->clk)) { -- dev_err(&pdev->dev, "fck is not found\n"); -+ dev_err(priv->dev, "fck is not found\n"); - ret = -ENODEV; -- goto clean_slave_ret; -+ goto clean_runtime_disable_ret; - } - priv->coal_intvl = 0; - priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000; - -- priv->cpsw_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!priv->cpsw_res) { -- dev_err(priv->dev, "error getting i/o resource\n"); -- ret = -ENOENT; -- goto clean_clk_ret; -- } -- if (!request_mem_region(priv->cpsw_res->start, -- resource_size(priv->cpsw_res), ndev->name)) { -- dev_err(priv->dev, "failed request i/o region\n"); -- ret = -ENXIO; -- goto clean_clk_ret; -- } -- ss_regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); -- if (!ss_regs) { -- dev_err(priv->dev, "unable to map i/o region\n"); -- goto clean_cpsw_iores_ret; -+ ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ ss_regs = devm_ioremap_resource(&pdev->dev, ss_res); -+ if (IS_ERR(ss_regs)) { -+ ret = PTR_ERR(ss_regs); -+ goto clean_runtime_disable_ret; - } - priv->regs = ss_regs; - priv->version = __raw_readl(&priv->regs->id_ver); - priv->host_port = HOST_PORT_NUM; - -- priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -- if (!priv->cpsw_wr_res) { -- dev_err(priv->dev, "error getting i/o resource\n"); -- ret = -ENOENT; -- goto clean_iomap_ret; -- } -- if (!request_mem_region(priv->cpsw_wr_res->start, -- resource_size(priv->cpsw_wr_res), ndev->name)) { -- dev_err(priv->dev, "failed request i/o region\n"); -- ret = -ENXIO; -- goto clean_iomap_ret; -- } -- wr_regs = ioremap(priv->cpsw_wr_res->start, -- resource_size(priv->cpsw_wr_res)); -- if (!wr_regs) { -- dev_err(priv->dev, "unable to map i/o region\n"); -- goto clean_cpsw_wr_iores_ret; -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->wr_regs)) { -+ ret = PTR_ERR(priv->wr_regs); -+ goto clean_runtime_disable_ret; - } -- priv->wr_regs = wr_regs; - - memset(&dma_params, 0, sizeof(dma_params)); - memset(&ale_params, 0, sizeof(ale_params)); -@@ -2053,12 +2019,12 @@ static int cpsw_probe(struct platform_de - slave_size = CPSW2_SLAVE_SIZE; - sliver_offset = CPSW2_SLIVER_OFFSET; - dma_params.desc_mem_phys = -- (u32 __force) priv->cpsw_res->start + CPSW2_BD_OFFSET; -+ (u32 __force) ss_res->start + CPSW2_BD_OFFSET; - break; - default: - dev_err(priv->dev, "unknown version 0x%08x\n", priv->version); - ret = -ENODEV; -- goto clean_cpsw_wr_iores_ret; -+ goto clean_runtime_disable_ret; - } - for (i = 0; i < priv->data.slaves; i++) { - struct cpsw_slave *slave = &priv->slaves[i]; -@@ -2086,7 +2052,7 @@ static int cpsw_probe(struct platform_de - if (!priv->dma) { - dev_err(priv->dev, "error initializing dma\n"); - ret = -ENOMEM; -- goto clean_wr_iomap_ret; -+ goto clean_runtime_disable_ret; - } - - priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), -@@ -2121,8 +2087,8 @@ static int cpsw_probe(struct platform_de - - while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) { - for (i = res->start; i <= res->end; i++) { -- if (request_irq(i, cpsw_interrupt, 0, -- dev_name(&pdev->dev), priv)) { -+ if (devm_request_irq(&pdev->dev, i, cpsw_interrupt, 0, -+ dev_name(priv->dev), priv)) { - dev_err(priv->dev, "error attaching irq\n"); - goto clean_ale_ret; - } -@@ -2144,7 +2110,7 @@ static int cpsw_probe(struct platform_de - if (ret) { - dev_err(priv->dev, "error registering net device\n"); - ret = -ENODEV; -- goto clean_irq_ret; -+ goto clean_ale_ret; - } - - if (cpts_register(&pdev->dev, priv->cpts, -@@ -2152,44 +2118,27 @@ static int cpsw_probe(struct platform_de - dev_err(priv->dev, "error registering cpts device\n"); - - cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n", -- priv->cpsw_res->start, ndev->irq); -+ ss_res->start, ndev->irq); - - if (priv->data.dual_emac) { - ret = cpsw_probe_dual_emac(pdev, priv); - if (ret) { - cpsw_err(priv, probe, "error probe slave 2 emac interface\n"); -- goto clean_irq_ret; -+ goto clean_ale_ret; - } - } - - return 0; - --clean_irq_ret: -- for (i = 0; i < priv->num_irqs; i++) -- free_irq(priv->irqs_table[i], priv); - clean_ale_ret: - cpsw_ale_destroy(priv->ale); - clean_dma_ret: - cpdma_chan_destroy(priv->txch); - cpdma_chan_destroy(priv->rxch); - cpdma_ctlr_destroy(priv->dma); --clean_wr_iomap_ret: -- iounmap(priv->wr_regs); --clean_cpsw_wr_iores_ret: -- release_mem_region(priv->cpsw_wr_res->start, -- resource_size(priv->cpsw_wr_res)); --clean_iomap_ret: -- iounmap(priv->regs); --clean_cpsw_iores_ret: -- release_mem_region(priv->cpsw_res->start, -- resource_size(priv->cpsw_res)); --clean_clk_ret: -- clk_put(priv->clk); --clean_slave_ret: -+clean_runtime_disable_ret: - pm_runtime_disable(&pdev->dev); -- kfree(priv->slaves); - clean_ndev_ret: -- kfree(priv->data.slave_data); - free_netdev(priv->ndev); - return ret; - } -@@ -2198,30 +2147,18 @@ static int cpsw_remove(struct platform_d - { - struct net_device *ndev = platform_get_drvdata(pdev); - struct cpsw_priv *priv = netdev_priv(ndev); -- int i; - - if (priv->data.dual_emac) - unregister_netdev(cpsw_get_slave_ndev(priv, 1)); - unregister_netdev(ndev); - - cpts_unregister(priv->cpts); -- for (i = 0; i < priv->num_irqs; i++) -- free_irq(priv->irqs_table[i], priv); - - cpsw_ale_destroy(priv->ale); - cpdma_chan_destroy(priv->txch); - cpdma_chan_destroy(priv->rxch); - cpdma_ctlr_destroy(priv->dma); -- iounmap(priv->regs); -- release_mem_region(priv->cpsw_res->start, -- resource_size(priv->cpsw_res)); -- iounmap(priv->wr_regs); -- release_mem_region(priv->cpsw_wr_res->start, -- resource_size(priv->cpsw_wr_res)); - pm_runtime_disable(&pdev->dev); -- clk_put(priv->clk); -- kfree(priv->slaves); -- kfree(priv->data.slave_data); - if (priv->data.dual_emac) - free_netdev(cpsw_get_slave_ndev(priv, 1)); - free_netdev(ndev); ---- a/drivers/net/ethernet/ti/cpsw.h -+++ b/drivers/net/ethernet/ti/cpsw.h -@@ -39,4 +39,6 @@ struct cpsw_platform_data { - bool dual_emac; /* Enable Dual EMAC mode */ - }; - -+void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave); -+ - #endif /* __CPSW_H__ */ ---- /dev/null -+++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c -@@ -0,0 +1,161 @@ -+/* Texas Instruments Ethernet Switch Driver -+ * -+ * Copyright (C) 2013 Texas Instruments -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/platform_device.h> -+#include <linux/module.h> -+#include <linux/netdevice.h> -+#include <linux/phy.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+ -+#include "cpsw.h" -+ -+/* AM33xx SoC specific definitions for the CONTROL port */ -+#define AM33XX_GMII_SEL_MODE_MII 0 -+#define AM33XX_GMII_SEL_MODE_RMII 1 -+#define AM33XX_GMII_SEL_MODE_RGMII 2 -+ -+#define AM33XX_GMII_SEL_RMII2_IO_CLK_EN BIT(7) -+#define AM33XX_GMII_SEL_RMII1_IO_CLK_EN BIT(6) -+ -+struct cpsw_phy_sel_priv { -+ struct device *dev; -+ u32 __iomem *gmii_sel; -+ bool rmii_clock_external; -+ void (*cpsw_phy_sel)(struct cpsw_phy_sel_priv *priv, -+ phy_interface_t phy_mode, int slave); -+}; -+ -+ -+static void cpsw_gmii_sel_am3352(struct cpsw_phy_sel_priv *priv, -+ phy_interface_t phy_mode, int slave) -+{ -+ u32 reg; -+ u32 mask; -+ u32 mode = 0; -+ -+ reg = readl(priv->gmii_sel); -+ -+ switch (phy_mode) { -+ case PHY_INTERFACE_MODE_RMII: -+ mode = AM33XX_GMII_SEL_MODE_RMII; -+ break; -+ -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ mode = AM33XX_GMII_SEL_MODE_RGMII; -+ break; -+ -+ case PHY_INTERFACE_MODE_MII: -+ default: -+ mode = AM33XX_GMII_SEL_MODE_MII; -+ break; -+ }; -+ -+ mask = 0x3 << (slave * 2) | BIT(slave + 6); -+ mode <<= slave * 2; -+ -+ if (priv->rmii_clock_external) { -+ if (slave == 0) -+ mode |= AM33XX_GMII_SEL_RMII1_IO_CLK_EN; -+ else -+ mode |= AM33XX_GMII_SEL_RMII2_IO_CLK_EN; -+ } -+ -+ reg &= ~mask; -+ reg |= mode; -+ -+ writel(reg, priv->gmii_sel); -+} -+ -+static struct platform_driver cpsw_phy_sel_driver; -+static int match(struct device *dev, void *data) -+{ -+ struct device_node *node = (struct device_node *)data; -+ return dev->of_node == node && -+ dev->driver == &cpsw_phy_sel_driver.driver; -+} -+ -+void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave) -+{ -+ struct device_node *node; -+ struct cpsw_phy_sel_priv *priv; -+ -+ node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel"); -+ if (!node) { -+ dev_err(dev, "Phy mode driver DT not found\n"); -+ return; -+ } -+ -+ dev = bus_find_device(&platform_bus_type, NULL, node, match); -+ priv = dev_get_drvdata(dev); -+ -+ priv->cpsw_phy_sel(priv, phy_mode, slave); -+} -+EXPORT_SYMBOL_GPL(cpsw_phy_sel); -+ -+static const struct of_device_id cpsw_phy_sel_id_table[] = { -+ { -+ .compatible = "ti,am3352-cpsw-phy-sel", -+ .data = &cpsw_gmii_sel_am3352, -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, cpsw_phy_sel_id_table); -+ -+static int cpsw_phy_sel_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ const struct of_device_id *of_id; -+ struct cpsw_phy_sel_priv *priv; -+ -+ of_id = of_match_node(cpsw_phy_sel_id_table, pdev->dev.of_node); -+ if (!of_id) -+ return -EINVAL; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) { -+ dev_err(&pdev->dev, "unable to alloc memory for cpsw phy sel\n"); -+ return -ENOMEM; -+ } -+ -+ priv->cpsw_phy_sel = of_id->data; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gmii-sel"); -+ priv->gmii_sel = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->gmii_sel)) -+ return PTR_ERR(priv->gmii_sel); -+ -+ if (of_find_property(pdev->dev.of_node, "rmii-clock-ext", NULL)) -+ priv->rmii_clock_external = true; -+ -+ dev_set_drvdata(&pdev->dev, priv); -+ -+ return 0; -+} -+ -+static struct platform_driver cpsw_phy_sel_driver = { -+ .probe = cpsw_phy_sel_probe, -+ .driver = { -+ .name = "cpsw-phy-sel", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(cpsw_phy_sel_id_table), -+ }, -+}; -+ -+module_platform_driver(cpsw_phy_sel_driver); -+MODULE_AUTHOR("Mugunthan V N <mugunthanvnm@ti.com>"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/net/ethernet/ti/Kconfig -+++ b/drivers/net/ethernet/ti/Kconfig -@@ -49,11 +49,19 @@ config TI_DAVINCI_CPDMA - To compile this driver as a module, choose M here: the module - will be called davinci_cpdma. This is recommended. - -+config TI_CPSW_PHY_SEL -+ boolean "TI CPSW Switch Phy sel Support" -+ depends on TI_CPSW -+ ---help--- -+ This driver supports configuring of the phy mode connected to -+ the CPSW. -+ - config TI_CPSW - tristate "TI CPSW Switch Support" - depends on ARM && (ARCH_DAVINCI || SOC_AM33XX) - select TI_DAVINCI_CPDMA - select TI_DAVINCI_MDIO -+ select TI_CPSW_PHY_SEL - ---help--- - This driver supports TI's CPSW Ethernet Switch. - ---- a/drivers/net/ethernet/ti/Makefile -+++ b/drivers/net/ethernet/ti/Makefile -@@ -7,5 +7,6 @@ obj-$(CONFIG_CPMAC) += cpmac.o - obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o - obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o - obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o -+obj-$(CONFIG_TI_CPSW_PHY_SEL) += cpsw-phy-sel.o - obj-$(CONFIG_TI_CPSW) += ti_cpsw.o - ti_cpsw-y := cpsw_ale.o cpsw.o cpts.o ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -31,6 +31,9 @@ - #include <linux/crc32.h> - #include <linux/usb/usbnet.h> - #include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_net.h> -+ - #include "smsc95xx.h" - - #define SMSC_CHIPNAME "smsc95xx" -@@ -62,6 +65,8 @@ - #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ - SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) - -+#define SMSC95XX_OF_NAME "/smsc95xx@" -+ - struct smsc95xx_priv { - u32 mac_cr; - u32 hash_hi; -@@ -767,6 +772,10 @@ static int smsc95xx_ioctl(struct net_dev - - static void smsc95xx_init_mac_address(struct usbnet *dev) - { -+ struct device_node *ap = NULL; -+ const char *mac = NULL; -+ char *of_name = SMSC95XX_OF_NAME; -+ - /* try reading mac address from EEPROM */ - if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, - dev->net->dev_addr) == 0) { -@@ -777,6 +786,20 @@ static void smsc95xx_init_mac_address(st - } - } - -+#ifdef CONFIG_OF -+ sprintf(of_name, "%s%i", SMSC95XX_OF_NAME, dev->udev->dev.id); -+ ap = of_find_node_by_path(of_name); -+ if (ap) { -+ mac = of_get_mac_address(ap); -+ if ((mac != NULL) && (is_valid_ether_addr(mac))) { -+ /* Device tree has a mac for this so use that */ -+ memcpy(dev->net->dev_addr, mac, ETH_ALEN); -+ netif_dbg(dev, ifup, dev->net, "MAC address read from DTB\n"); -+ return; -+ } -+ } -+#endif -+ - /* no eeprom, or eeprom values are invalid. generate random MAC */ - eth_hw_addr_random(dev->net); - netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); ---- /dev/null -+++ b/drivers/phy/Kconfig -@@ -0,0 +1,63 @@ -+# -+# PHY -+# -+ -+menu "PHY Subsystem" -+ -+config GENERIC_PHY -+ tristate "PHY Core" -+ help -+ Generic PHY support. -+ -+ This framework is designed to provide a generic interface for PHY -+ devices present in the kernel. This layer will have the generic -+ API by which phy drivers can create PHY using the phy framework and -+ phy users can obtain reference to the PHY. All the users of this -+ framework should select this config. -+ -+config OMAP_CONTROL_PHY -+ tristate "OMAP CONTROL PHY Driver" -+ help -+ Enable this to add support for the PHY part present in the control -+ module. This driver has API to power on the USB2 PHY and to write to -+ the mailbox. The mailbox is present only in omap4 and the register to -+ power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an -+ additional register to power on USB3 PHY/SATA PHY/PCIE PHY -+ (PIPE3 PHY). -+ -+config OMAP_USB2 -+ tristate "OMAP USB2 PHY Driver" -+ depends on ARCH_OMAP2PLUS -+ depends on USB_SUPPORT -+ select GENERIC_PHY -+ select USB_PHY -+ select OMAP_CONTROL_PHY -+ help -+ Enable this to support the transceiver that is part of SOC. This -+ driver takes care of all the PHY functionality apart from comparator. -+ The USB OTG controller communicates with the comparator using this -+ driver. -+ -+config OMAP_PIPE3 -+ tristate "OMAP PIPE3 PHY Driver" -+ select GENERIC_PHY -+ select OMAP_CONTROL_PHY -+ help -+ Enable this to support the PIPE3 PHY that is part of SOC. This -+ driver takes care of all the PHY functionality apart from comparator. -+ This driver interacts with the "OMAP Control PHY Driver" to power -+ on/off the PHY. -+ -+config TWL4030_USB -+ tristate "TWL4030 USB Transceiver Driver" -+ depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS -+ depends on USB_SUPPORT -+ select GENERIC_PHY -+ select USB_PHY -+ help -+ Enable this to support the USB OTG transceiver on TWL4030 -+ family chips (including the TWL5030 and TPS659x0 devices). -+ This transceiver supports high and full speed devices plus, -+ in host mode, low speed. -+ -+endmenu ---- /dev/null -+++ b/drivers/phy/Makefile -@@ -0,0 +1,9 @@ -+# -+# Makefile for the phy drivers. -+# -+ -+obj-$(CONFIG_GENERIC_PHY) += phy-core.o -+obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o -+obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o -+obj-$(CONFIG_OMAP_PIPE3) += phy-omap-pipe3.o -+obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o ---- /dev/null -+++ b/drivers/phy/phy-core.c -@@ -0,0 +1,698 @@ -+/* -+ * phy-core.c -- Generic Phy framework. -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/export.h> -+#include <linux/module.h> -+#include <linux/err.h> -+#include <linux/device.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/phy/phy.h> -+#include <linux/idr.h> -+#include <linux/pm_runtime.h> -+ -+static struct class *phy_class; -+static DEFINE_MUTEX(phy_provider_mutex); -+static LIST_HEAD(phy_provider_list); -+static DEFINE_IDA(phy_ida); -+ -+static void devm_phy_release(struct device *dev, void *res) -+{ -+ struct phy *phy = *(struct phy **)res; -+ -+ phy_put(phy); -+} -+ -+static void devm_phy_provider_release(struct device *dev, void *res) -+{ -+ struct phy_provider *phy_provider = *(struct phy_provider **)res; -+ -+ of_phy_provider_unregister(phy_provider); -+} -+ -+static void devm_phy_consume(struct device *dev, void *res) -+{ -+ struct phy *phy = *(struct phy **)res; -+ -+ phy_destroy(phy); -+} -+ -+static int devm_phy_match(struct device *dev, void *res, void *match_data) -+{ -+ return res == match_data; -+} -+ -+static struct phy *phy_lookup(struct device *device, const char *port) -+{ -+ unsigned int count; -+ struct phy *phy; -+ struct device *dev; -+ struct phy_consumer *consumers; -+ struct class_dev_iter iter; -+ -+ class_dev_iter_init(&iter, phy_class, NULL, NULL); -+ while ((dev = class_dev_iter_next(&iter))) { -+ phy = to_phy(dev); -+ count = phy->init_data->num_consumers; -+ consumers = phy->init_data->consumers; -+ while (count--) { -+ if (!strcmp(consumers->dev_name, dev_name(device)) && -+ !strcmp(consumers->port, port)) { -+ class_dev_iter_exit(&iter); -+ return phy; -+ } -+ consumers++; -+ } -+ } -+ -+ class_dev_iter_exit(&iter); -+ return ERR_PTR(-ENODEV); -+} -+ -+static struct phy_provider *of_phy_provider_lookup(struct device_node *node) -+{ -+ struct phy_provider *phy_provider; -+ -+ list_for_each_entry(phy_provider, &phy_provider_list, list) { -+ if (phy_provider->dev->of_node == node) -+ return phy_provider; -+ } -+ -+ return ERR_PTR(-EPROBE_DEFER); -+} -+ -+int phy_pm_runtime_get(struct phy *phy) -+{ -+ if (!pm_runtime_enabled(&phy->dev)) -+ return -ENOTSUPP; -+ -+ return pm_runtime_get(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_pm_runtime_get); -+ -+int phy_pm_runtime_get_sync(struct phy *phy) -+{ -+ if (!pm_runtime_enabled(&phy->dev)) -+ return -ENOTSUPP; -+ -+ return pm_runtime_get_sync(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync); -+ -+int phy_pm_runtime_put(struct phy *phy) -+{ -+ if (!pm_runtime_enabled(&phy->dev)) -+ return -ENOTSUPP; -+ -+ return pm_runtime_put(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_pm_runtime_put); -+ -+int phy_pm_runtime_put_sync(struct phy *phy) -+{ -+ if (!pm_runtime_enabled(&phy->dev)) -+ return -ENOTSUPP; -+ -+ return pm_runtime_put_sync(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_pm_runtime_put_sync); -+ -+void phy_pm_runtime_allow(struct phy *phy) -+{ -+ if (!pm_runtime_enabled(&phy->dev)) -+ return; -+ -+ pm_runtime_allow(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_pm_runtime_allow); -+ -+void phy_pm_runtime_forbid(struct phy *phy) -+{ -+ if (!pm_runtime_enabled(&phy->dev)) -+ return; -+ -+ pm_runtime_forbid(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_pm_runtime_forbid); -+ -+int phy_init(struct phy *phy) -+{ -+ int ret; -+ -+ ret = phy_pm_runtime_get_sync(phy); -+ if (ret < 0 && ret != -ENOTSUPP) -+ return ret; -+ -+ mutex_lock(&phy->mutex); -+ if (phy->init_count++ == 0 && phy->ops->init) { -+ ret = phy->ops->init(phy); -+ if (ret < 0) { -+ dev_err(&phy->dev, "phy init failed --> %d\n", ret); -+ goto out; -+ } -+ } -+ -+out: -+ mutex_unlock(&phy->mutex); -+ phy_pm_runtime_put(phy); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phy_init); -+ -+int phy_exit(struct phy *phy) -+{ -+ int ret; -+ -+ ret = phy_pm_runtime_get_sync(phy); -+ if (ret < 0 && ret != -ENOTSUPP) -+ return ret; -+ -+ mutex_lock(&phy->mutex); -+ if (--phy->init_count == 0 && phy->ops->exit) { -+ ret = phy->ops->exit(phy); -+ if (ret < 0) { -+ dev_err(&phy->dev, "phy exit failed --> %d\n", ret); -+ goto out; -+ } -+ } -+ -+out: -+ mutex_unlock(&phy->mutex); -+ phy_pm_runtime_put(phy); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phy_exit); -+ -+int phy_power_on(struct phy *phy) -+{ -+ int ret = -ENOTSUPP; -+ -+ ret = phy_pm_runtime_get_sync(phy); -+ if (ret < 0 && ret != -ENOTSUPP) -+ return ret; -+ -+ mutex_lock(&phy->mutex); -+ if (phy->power_count++ == 0 && phy->ops->power_on) { -+ ret = phy->ops->power_on(phy); -+ if (ret < 0) { -+ dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); -+ goto out; -+ } -+ } -+ -+out: -+ mutex_unlock(&phy->mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phy_power_on); -+ -+int phy_power_off(struct phy *phy) -+{ -+ int ret = -ENOTSUPP; -+ -+ mutex_lock(&phy->mutex); -+ if (--phy->power_count == 0 && phy->ops->power_off) { -+ ret = phy->ops->power_off(phy); -+ if (ret < 0) { -+ dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret); -+ goto out; -+ } -+ } -+ -+out: -+ mutex_unlock(&phy->mutex); -+ phy_pm_runtime_put(phy); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phy_power_off); -+ -+/** -+ * of_phy_get() - lookup and obtain a reference to a phy by phandle -+ * @dev: device that requests this phy -+ * @index: the index of the phy -+ * -+ * Returns the phy associated with the given phandle value, -+ * after getting a refcount to it or -ENODEV if there is no such phy or -+ * -EPROBE_DEFER if there is a phandle to the phy, but the device is -+ * not yet loaded. This function uses of_xlate call back function provided -+ * while registering the phy_provider to find the phy instance. -+ */ -+static struct phy *of_phy_get(struct device *dev, int index) -+{ -+ int ret; -+ struct phy_provider *phy_provider; -+ struct phy *phy = NULL; -+ struct of_phandle_args args; -+ -+ ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells", -+ index, &args); -+ if (ret) { -+ dev_dbg(dev, "failed to get phy in %s node\n", -+ dev->of_node->full_name); -+ return ERR_PTR(-ENODEV); -+ } -+ -+ mutex_lock(&phy_provider_mutex); -+ phy_provider = of_phy_provider_lookup(args.np); -+ if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { -+ phy = ERR_PTR(-EPROBE_DEFER); -+ goto err0; -+ } -+ -+ phy = phy_provider->of_xlate(phy_provider->dev, &args); -+ module_put(phy_provider->owner); -+ -+err0: -+ mutex_unlock(&phy_provider_mutex); -+ of_node_put(args.np); -+ -+ return phy; -+} -+ -+/** -+ * phy_put() - release the PHY -+ * @phy: the phy returned by phy_get() -+ * -+ * Releases a refcount the caller received from phy_get(). -+ */ -+void phy_put(struct phy *phy) -+{ -+ if (IS_ERR(phy)) -+ return; -+ -+ module_put(phy->ops->owner); -+ put_device(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_put); -+ -+/** -+ * devm_phy_put() - release the PHY -+ * @dev: device that wants to release this phy -+ * @phy: the phy returned by devm_phy_get() -+ * -+ * destroys the devres associated with this phy and invokes phy_put -+ * to release the phy. -+ */ -+void devm_phy_put(struct device *dev, struct phy *phy) -+{ -+ int r; -+ -+ r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); -+ dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); -+} -+EXPORT_SYMBOL_GPL(devm_phy_put); -+ -+/** -+ * of_phy_simple_xlate() - returns the phy instance from phy provider -+ * @dev: the PHY provider device -+ * @args: of_phandle_args (not used here) -+ * -+ * Intended to be used by phy provider for the common case where #phy-cells is -+ * 0. For other cases where #phy-cells is greater than '0', the phy provider -+ * should provide a custom of_xlate function that reads the *args* and returns -+ * the appropriate phy. -+ */ -+struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args -+ *args) -+{ -+ struct phy *phy; -+ struct class_dev_iter iter; -+ struct device_node *node = dev->of_node; -+ -+ class_dev_iter_init(&iter, phy_class, NULL, NULL); -+ while ((dev = class_dev_iter_next(&iter))) { -+ phy = to_phy(dev); -+ if (node != phy->dev.of_node) -+ continue; -+ -+ class_dev_iter_exit(&iter); -+ return phy; -+ } -+ -+ class_dev_iter_exit(&iter); -+ return ERR_PTR(-ENODEV); -+} -+EXPORT_SYMBOL_GPL(of_phy_simple_xlate); -+ -+/** -+ * phy_get() - lookup and obtain a reference to a phy. -+ * @dev: device that requests this phy -+ * @string: the phy name as given in the dt data or the name of the controller -+ * port for non-dt case -+ * -+ * Returns the phy driver, after getting a refcount to it; or -+ * -ENODEV if there is no such phy. The caller is responsible for -+ * calling phy_put() to release that count. -+ */ -+struct phy *phy_get(struct device *dev, const char *string) -+{ -+ int index = 0; -+ struct phy *phy = NULL; -+ -+ if (string == NULL) { -+ dev_WARN(dev, "missing string\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ if (dev->of_node) { -+ index = of_property_match_string(dev->of_node, "phy-names", -+ string); -+ phy = of_phy_get(dev, index); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "unable to find phy\n"); -+ return phy; -+ } -+ } else { -+ phy = phy_lookup(dev, string); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "unable to find phy\n"); -+ return phy; -+ } -+ } -+ -+ if (!try_module_get(phy->ops->owner)) -+ return ERR_PTR(-EPROBE_DEFER); -+ -+ get_device(&phy->dev); -+ -+ return phy; -+} -+EXPORT_SYMBOL_GPL(phy_get); -+ -+/** -+ * devm_phy_get() - lookup and obtain a reference to a phy. -+ * @dev: device that requests this phy -+ * @string: the phy name as given in the dt data or phy device name -+ * for non-dt case -+ * -+ * Gets the phy using phy_get(), and associates a device with it using -+ * devres. On driver detach, release function is invoked on the devres data, -+ * then, devres data is freed. -+ */ -+struct phy *devm_phy_get(struct device *dev, const char *string) -+{ -+ struct phy **ptr, *phy; -+ -+ ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ phy = phy_get(dev, string); -+ if (!IS_ERR(phy)) { -+ *ptr = phy; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return phy; -+} -+EXPORT_SYMBOL_GPL(devm_phy_get); -+ -+/** -+ * phy_create() - create a new phy -+ * @dev: device that is creating the new phy -+ * @ops: function pointers for performing phy operations -+ * @init_data: contains the list of PHY consumers or NULL -+ * -+ * Called to create a phy using phy framework. -+ */ -+struct phy *phy_create(struct device *dev, const struct phy_ops *ops, -+ struct phy_init_data *init_data) -+{ -+ int ret; -+ int id; -+ struct phy *phy; -+ -+ if (!dev) { -+ dev_WARN(dev, "no device provided for PHY\n"); -+ ret = -EINVAL; -+ goto err0; -+ } -+ -+ phy = kzalloc(sizeof(*phy), GFP_KERNEL); -+ if (!phy) { -+ ret = -ENOMEM; -+ goto err0; -+ } -+ -+ id = ida_simple_get(&phy_ida, 0, 0, GFP_KERNEL); -+ if (id < 0) { -+ dev_err(dev, "unable to get id\n"); -+ ret = id; -+ goto err0; -+ } -+ -+ device_initialize(&phy->dev); -+ mutex_init(&phy->mutex); -+ -+ phy->dev.class = phy_class; -+ phy->dev.parent = dev; -+ phy->dev.of_node = dev->of_node; -+ phy->id = id; -+ phy->ops = ops; -+ phy->init_data = init_data; -+ -+ ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id); -+ if (ret) -+ goto err1; -+ -+ ret = device_add(&phy->dev); -+ if (ret) -+ goto err1; -+ -+ if (pm_runtime_enabled(dev)) { -+ pm_runtime_enable(&phy->dev); -+ pm_runtime_no_callbacks(&phy->dev); -+ } -+ -+ return phy; -+ -+err1: -+ ida_remove(&phy_ida, phy->id); -+ put_device(&phy->dev); -+ kfree(phy); -+ -+err0: -+ return ERR_PTR(ret); -+} -+EXPORT_SYMBOL_GPL(phy_create); -+ -+/** -+ * devm_phy_create() - create a new phy -+ * @dev: device that is creating the new phy -+ * @ops: function pointers for performing phy operations -+ * @init_data: contains the list of PHY consumers or NULL -+ * -+ * Creates a new PHY device adding it to the PHY class. -+ * While at that, it also associates the device with the phy using devres. -+ * On driver detach, release function is invoked on the devres data, -+ * then, devres data is freed. -+ */ -+struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops, -+ struct phy_init_data *init_data) -+{ -+ struct phy **ptr, *phy; -+ -+ ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ phy = phy_create(dev, ops, init_data); -+ if (!IS_ERR(phy)) { -+ *ptr = phy; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return phy; -+} -+EXPORT_SYMBOL_GPL(devm_phy_create); -+ -+/** -+ * phy_destroy() - destroy the phy -+ * @phy: the phy to be destroyed -+ * -+ * Called to destroy the phy. -+ */ -+void phy_destroy(struct phy *phy) -+{ -+ pm_runtime_disable(&phy->dev); -+ device_unregister(&phy->dev); -+} -+EXPORT_SYMBOL_GPL(phy_destroy); -+ -+/** -+ * devm_phy_destroy() - destroy the PHY -+ * @dev: device that wants to release this phy -+ * @phy: the phy returned by devm_phy_get() -+ * -+ * destroys the devres associated with this phy and invokes phy_destroy -+ * to destroy the phy. -+ */ -+void devm_phy_destroy(struct device *dev, struct phy *phy) -+{ -+ int r; -+ -+ r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy); -+ dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); -+} -+EXPORT_SYMBOL_GPL(devm_phy_destroy); -+ -+/** -+ * __of_phy_provider_register() - create/register phy provider with the framework -+ * @dev: struct device of the phy provider -+ * @owner: the module owner containing of_xlate -+ * @of_xlate: function pointer to obtain phy instance from phy provider -+ * -+ * Creates struct phy_provider from dev and of_xlate function pointer. -+ * This is used in the case of dt boot for finding the phy instance from -+ * phy provider. -+ */ -+struct phy_provider *__of_phy_provider_register(struct device *dev, -+ struct module *owner, struct phy * (*of_xlate)(struct device *dev, -+ struct of_phandle_args *args)) -+{ -+ struct phy_provider *phy_provider; -+ -+ phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL); -+ if (!phy_provider) -+ return ERR_PTR(-ENOMEM); -+ -+ phy_provider->dev = dev; -+ phy_provider->owner = owner; -+ phy_provider->of_xlate = of_xlate; -+ -+ mutex_lock(&phy_provider_mutex); -+ list_add_tail(&phy_provider->list, &phy_provider_list); -+ mutex_unlock(&phy_provider_mutex); -+ -+ return phy_provider; -+} -+EXPORT_SYMBOL_GPL(__of_phy_provider_register); -+ -+/** -+ * __devm_of_phy_provider_register() - create/register phy provider with the -+ * framework -+ * @dev: struct device of the phy provider -+ * @owner: the module owner containing of_xlate -+ * @of_xlate: function pointer to obtain phy instance from phy provider -+ * -+ * Creates struct phy_provider from dev and of_xlate function pointer. -+ * This is used in the case of dt boot for finding the phy instance from -+ * phy provider. While at that, it also associates the device with the -+ * phy provider using devres. On driver detach, release function is invoked -+ * on the devres data, then, devres data is freed. -+ */ -+struct phy_provider *__devm_of_phy_provider_register(struct device *dev, -+ struct module *owner, struct phy * (*of_xlate)(struct device *dev, -+ struct of_phandle_args *args)) -+{ -+ struct phy_provider **ptr, *phy_provider; -+ -+ ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ phy_provider = __of_phy_provider_register(dev, owner, of_xlate); -+ if (!IS_ERR(phy_provider)) { -+ *ptr = phy_provider; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return phy_provider; -+} -+EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register); -+ -+/** -+ * of_phy_provider_unregister() - unregister phy provider from the framework -+ * @phy_provider: phy provider returned by of_phy_provider_register() -+ * -+ * Removes the phy_provider created using of_phy_provider_register(). -+ */ -+void of_phy_provider_unregister(struct phy_provider *phy_provider) -+{ -+ if (IS_ERR(phy_provider)) -+ return; -+ -+ mutex_lock(&phy_provider_mutex); -+ list_del(&phy_provider->list); -+ kfree(phy_provider); -+ mutex_unlock(&phy_provider_mutex); -+} -+EXPORT_SYMBOL_GPL(of_phy_provider_unregister); -+ -+/** -+ * devm_of_phy_provider_unregister() - remove phy provider from the framework -+ * @dev: struct device of the phy provider -+ * -+ * destroys the devres associated with this phy provider and invokes -+ * of_phy_provider_unregister to unregister the phy provider. -+ */ -+void devm_of_phy_provider_unregister(struct device *dev, -+ struct phy_provider *phy_provider) { -+ int r; -+ -+ r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match, -+ phy_provider); -+ dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n"); -+} -+EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister); -+ -+/** -+ * phy_release() - release the phy -+ * @dev: the dev member within phy -+ * -+ * When the last reference to the device is removed, it is called -+ * from the embedded kobject as release method. -+ */ -+static void phy_release(struct device *dev) -+{ -+ struct phy *phy; -+ -+ phy = to_phy(dev); -+ dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); -+ ida_remove(&phy_ida, phy->id); -+ kfree(phy); -+} -+ -+static int __init phy_core_init(void) -+{ -+ phy_class = class_create(THIS_MODULE, "phy"); -+ if (IS_ERR(phy_class)) { -+ pr_err("failed to create phy class --> %ld\n", -+ PTR_ERR(phy_class)); -+ return PTR_ERR(phy_class); -+ } -+ -+ phy_class->dev_release = phy_release; -+ -+ return 0; -+} -+module_init(phy_core_init); -+ -+static void __exit phy_core_exit(void) -+{ -+ class_destroy(phy_class); -+} -+module_exit(phy_core_exit); -+ -+MODULE_DESCRIPTION("Generic PHY Framework"); -+MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/phy/phy-omap-control.c -@@ -0,0 +1,319 @@ -+/* -+ * omap-control-phy.c - The PHY part of control module. -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/clk.h> -+#include <linux/phy/omap_control_phy.h> -+ -+/** -+ * omap_control_phy_power - power on/off the phy using control module reg -+ * @dev: the control module device -+ * @on: 0 or 1, based on powering on or off the PHY -+ */ -+void omap_control_phy_power(struct device *dev, int on) -+{ -+ u32 val; -+ unsigned long rate; -+ struct omap_control_phy *control_phy; -+ -+ if (IS_ERR(dev) || !dev) { -+ pr_err("%s: invalid device\n", __func__); -+ return; -+ } -+ -+ control_phy = dev_get_drvdata(dev); -+ if (!control_phy) { -+ dev_err(dev, "%s: invalid control phy device\n", __func__); -+ return; -+ } -+ -+ if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) -+ return; -+ -+ val = readl(control_phy->power); -+ -+ switch (control_phy->type) { -+ case OMAP_CTRL_TYPE_USB2: -+ if (on) -+ val &= ~OMAP_CTRL_DEV_PHY_PD; -+ else -+ val |= OMAP_CTRL_DEV_PHY_PD; -+ break; -+ -+ case OMAP_CTRL_TYPE_PIPE3: -+ rate = clk_get_rate(control_phy->sys_clk); -+ rate = rate/1000000; -+ -+ if (on) { -+ val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | -+ OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK); -+ val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON << -+ OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; -+ val |= rate << -+ OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; -+ } else { -+ val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; -+ val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF << -+ OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; -+ } -+ break; -+ -+ case OMAP_CTRL_TYPE_DRA7USB2: -+ if (on) -+ val &= ~OMAP_CTRL_USB2_PHY_PD; -+ else -+ val |= OMAP_CTRL_USB2_PHY_PD; -+ break; -+ -+ case OMAP_CTRL_TYPE_AM437USB2: -+ if (on) { -+ val &= ~(AM437X_CTRL_USB2_PHY_PD | -+ AM437X_CTRL_USB2_OTG_PD); -+ val |= (AM437X_CTRL_USB2_OTGVDET_EN | -+ AM437X_CTRL_USB2_OTGSESSEND_EN); -+ } else { -+ val &= ~(AM437X_CTRL_USB2_OTGVDET_EN | -+ AM437X_CTRL_USB2_OTGSESSEND_EN); -+ val |= (AM437X_CTRL_USB2_PHY_PD | -+ AM437X_CTRL_USB2_OTG_PD); -+ } -+ break; -+ default: -+ dev_err(dev, "%s: type %d not recognized\n", -+ __func__, control_phy->type); -+ break; -+ } -+ -+ writel(val, control_phy->power); -+} -+EXPORT_SYMBOL_GPL(omap_control_phy_power); -+ -+/** -+ * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded -+ * @ctrl_phy: struct omap_control_phy * -+ * -+ * Writes to the mailbox register to notify the usb core that a usb -+ * device has been connected. -+ */ -+static void omap_control_usb_host_mode(struct omap_control_phy *ctrl_phy) -+{ -+ u32 val; -+ -+ val = readl(ctrl_phy->otghs_control); -+ val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); -+ val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; -+ writel(val, ctrl_phy->otghs_control); -+} -+ -+/** -+ * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high -+ * impedance -+ * @ctrl_phy: struct omap_control_phy * -+ * -+ * Writes to the mailbox register to notify the usb core that it has been -+ * connected to a usb host. -+ */ -+static void omap_control_usb_device_mode(struct omap_control_phy *ctrl_phy) -+{ -+ u32 val; -+ -+ val = readl(ctrl_phy->otghs_control); -+ val &= ~OMAP_CTRL_DEV_SESSEND; -+ val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | -+ OMAP_CTRL_DEV_VBUSVALID; -+ writel(val, ctrl_phy->otghs_control); -+} -+ -+/** -+ * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high -+ * impedance -+ * @ctrl_phy: struct omap_control_phy * -+ * -+ * Writes to the mailbox register to notify the usb core it's now in -+ * disconnected state. -+ */ -+static void omap_control_usb_set_sessionend(struct omap_control_phy *ctrl_phy) -+{ -+ u32 val; -+ -+ val = readl(ctrl_phy->otghs_control); -+ val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); -+ val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; -+ writel(val, ctrl_phy->otghs_control); -+} -+ -+/** -+ * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode -+ * or device mode or to denote disconnected state -+ * @dev: the control module device -+ * @mode: The mode to which usb should be configured -+ * -+ * This is an API to write to the mailbox register to notify the usb core that -+ * a usb device has been connected. -+ */ -+void omap_control_usb_set_mode(struct device *dev, -+ enum omap_control_usb_mode mode) -+{ -+ struct omap_control_phy *ctrl_phy; -+ -+ if (IS_ERR(dev) || !dev) -+ return; -+ -+ ctrl_phy = dev_get_drvdata(dev); -+ -+ if (!ctrl_phy) { -+ dev_err(dev, "Invalid control phy device\n"); -+ return; -+ } -+ -+ if (ctrl_phy->type != OMAP_CTRL_TYPE_OTGHS) -+ return; -+ -+ switch (mode) { -+ case USB_MODE_HOST: -+ omap_control_usb_host_mode(ctrl_phy); -+ break; -+ case USB_MODE_DEVICE: -+ omap_control_usb_device_mode(ctrl_phy); -+ break; -+ case USB_MODE_DISCONNECT: -+ omap_control_usb_set_sessionend(ctrl_phy); -+ break; -+ default: -+ dev_vdbg(dev, "invalid omap control usb mode\n"); -+ } -+} -+EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); -+ -+#ifdef CONFIG_OF -+ -+static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; -+static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; -+static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; -+static const enum omap_control_phy_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2; -+static const enum omap_control_phy_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2; -+ -+static const struct of_device_id omap_control_phy_id_table[] = { -+ { -+ .compatible = "ti,control-phy-otghs", -+ .data = &otghs_data, -+ }, -+ { -+ .compatible = "ti,control-phy-usb2", -+ .data = &usb2_data, -+ }, -+ { -+ .compatible = "ti,control-phy-pipe3", -+ .data = &pipe3_data, -+ }, -+ { -+ .compatible = "ti,control-phy-dra7usb2", -+ .data = &dra7usb2_data, -+ }, -+ { -+ .compatible = "ti,control-phy-am437usb2", -+ .data = &am437usb2_data, -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); -+#endif -+ -+static int omap_control_phy_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ const struct of_device_id *of_id; -+ struct omap_control_phy *control_phy; -+ -+ of_id = of_match_device(of_match_ptr(omap_control_phy_id_table), -+ &pdev->dev); -+ if (!of_id) -+ return -EINVAL; -+ -+ control_phy = devm_kzalloc(&pdev->dev, sizeof(*control_phy), -+ GFP_KERNEL); -+ if (!control_phy) { -+ dev_err(&pdev->dev, "unable to alloc memory for control phy\n"); -+ return -ENOMEM; -+ } -+ -+ control_phy->dev = &pdev->dev; -+ control_phy->type = *(enum omap_control_phy_type *)of_id->data; -+ -+ if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) { -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ "otghs_control"); -+ control_phy->otghs_control = devm_ioremap_resource( -+ &pdev->dev, res); -+ if (IS_ERR(control_phy->otghs_control)) -+ return PTR_ERR(control_phy->otghs_control); -+ } else { -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ "power"); -+ control_phy->power = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(control_phy->power)) { -+ dev_err(&pdev->dev, "Couldn't get power register\n"); -+ return PTR_ERR(control_phy->power); -+ } -+ } -+ -+ if (control_phy->type == OMAP_CTRL_TYPE_PIPE3) { -+ control_phy->sys_clk = devm_clk_get(control_phy->dev, -+ "sys_clkin"); -+ if (IS_ERR(control_phy->sys_clk)) { -+ pr_err("%s: unable to get sys_clkin\n", __func__); -+ return -EINVAL; -+ } -+ } -+ -+ dev_set_drvdata(control_phy->dev, control_phy); -+ -+ return 0; -+} -+ -+static struct platform_driver omap_control_phy_driver = { -+ .probe = omap_control_phy_probe, -+ .driver = { -+ .name = "omap-control-phy", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(omap_control_phy_id_table), -+ }, -+}; -+ -+static int __init omap_control_phy_init(void) -+{ -+ return platform_driver_register(&omap_control_phy_driver); -+} -+subsys_initcall(omap_control_phy_init); -+ -+static void __exit omap_control_phy_exit(void) -+{ -+ platform_driver_unregister(&omap_control_phy_driver); -+} -+module_exit(omap_control_phy_exit); -+ -+MODULE_ALIAS("platform: omap_control_phy"); -+MODULE_AUTHOR("Texas Instruments Inc."); -+MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/phy/phy-omap-pipe3.c -@@ -0,0 +1,430 @@ -+/* -+ * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <linux/phy/omap_pipe3.h> -+#include <linux/phy/phy.h> -+#include <linux/of.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/pm_runtime.h> -+#include <linux/delay.h> -+#include <linux/phy/omap_control_phy.h> -+#include <linux/of_platform.h> -+ -+#define PLL_STATUS 0x00000004 -+#define PLL_GO 0x00000008 -+#define PLL_CONFIGURATION1 0x0000000C -+#define PLL_CONFIGURATION2 0x00000010 -+#define PLL_CONFIGURATION3 0x00000014 -+#define PLL_CONFIGURATION4 0x00000020 -+ -+#define PLL_REGM_MASK 0x001FFE00 -+#define PLL_REGM_SHIFT 9 -+#define PLL_REGM_F_MASK 0x0003FFFF -+#define PLL_REGM_F_SHIFT 0 -+#define PLL_REGN_MASK 0x000001FE -+#define PLL_REGN_SHIFT 1 -+#define PLL_SELFREQDCO_MASK 0x0000000E -+#define PLL_SELFREQDCO_SHIFT 1 -+#define PLL_SD_MASK 0x0003FC00 -+#define PLL_SD_SHIFT 10 -+#define SET_PLL_GO 0x1 -+#define PLL_TICOPWDN 0x10000 -+#define PLL_LOCK 0x2 -+#define PLL_IDLE 0x1 -+ -+/* -+ * This is an Empirical value that works, need to confirm the actual -+ * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status -+ * to be correctly reflected in the PIPE3PHY_PLL_STATUS register. -+ */ -+# define PLL_IDLE_TIME 100; -+ -+static struct pipe3_dpll_map dpll_map_usb[] = { -+ {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ -+ {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ -+ {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ -+ {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ -+ {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ -+ {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ -+ { }, /* Terminator */ -+}; -+ -+static struct pipe3_dpll_map dpll_map_sata[] = { -+ {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */ -+ {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */ -+ {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */ -+ {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */ -+ {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */ -+ {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */ -+ { }, /* Terminator */ -+}; -+ -+static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(struct omap_pipe3 -+ *pipe3) -+{ -+ unsigned long rate; -+ struct pipe3_dpll_map *dpll_map = pipe3->dpll_map; -+ -+ rate = clk_get_rate(pipe3->sys_clk); -+ -+ for (; dpll_map->rate; dpll_map++) { -+ if (rate == dpll_map->rate) -+ return &dpll_map->params; -+ } -+ -+ dev_err(pipe3->dev, -+ "No DPLL configuration for %lu Hz SYS CLK\n", rate); -+ return 0; -+} -+ -+static int omap_pipe3_power_off(struct phy *x) -+{ -+ struct omap_pipe3 *phy = phy_get_drvdata(x); -+ int val; -+ int timeout = PLL_IDLE_TIME; -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); -+ val |= PLL_IDLE; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); -+ -+ do { -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); -+ if (val & PLL_TICOPWDN) -+ break; -+ udelay(1); -+ } while (--timeout); -+ -+ omap_control_phy_power(phy->control_dev, 0); -+ -+ return 0; -+} -+ -+static int omap_pipe3_power_on(struct phy *x) -+{ -+ struct omap_pipe3 *phy = phy_get_drvdata(x); -+ int val; -+ int timeout = PLL_IDLE_TIME; -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); -+ val &= ~PLL_IDLE; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); -+ -+ do { -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); -+ if (!(val & PLL_TICOPWDN)) -+ break; -+ udelay(1); -+ } while (--timeout); -+ -+ msleep(100); -+ -+ return 0; -+} -+ -+static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy) -+{ -+ u32 val; -+ unsigned long timeout; -+ -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); -+ -+ timeout = jiffies + msecs_to_jiffies(20); -+ do { -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); -+ if (val & PLL_LOCK) -+ break; -+ } while (!WARN_ON(time_after(jiffies, timeout))); -+} -+ -+static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy) -+{ -+ u32 val; -+ unsigned long rate; -+ struct pipe3_dpll_params *dpll_params; -+ -+ rate = clk_get_rate(phy->sys_clk); -+ dpll_params = omap_pipe3_get_dpll_params(phy); -+ if (!dpll_params) { -+ return -EINVAL; -+ } -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); -+ val &= ~PLL_REGN_MASK; -+ val |= dpll_params->n << PLL_REGN_SHIFT; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); -+ val &= ~PLL_SELFREQDCO_MASK; -+ val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); -+ val &= ~PLL_REGM_MASK; -+ val |= dpll_params->m << PLL_REGM_SHIFT; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); -+ val &= ~PLL_REGM_F_MASK; -+ val |= dpll_params->mf << PLL_REGM_F_SHIFT; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); -+ -+ val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); -+ val &= ~PLL_SD_MASK; -+ val |= dpll_params->sd << PLL_SD_SHIFT; -+ omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); -+ -+ omap_pipe3_dpll_relock(phy); -+ -+ return 0; -+} -+ -+static int omap_pipe3_init(struct phy *x) -+{ -+ struct omap_pipe3 *phy = phy_get_drvdata(x); -+ int ret; -+ -+ ret = omap_pipe3_dpll_lock(phy); -+ if (ret) -+ return ret; -+ -+ omap_control_phy_power(phy->control_dev, 1); -+ -+ return 0; -+} -+ -+static struct phy_ops ops = { -+ .init = omap_pipe3_init, -+ .power_on = omap_pipe3_power_on, -+ .power_off = omap_pipe3_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+#ifdef CONFIG_OF -+static const struct of_device_id omap_pipe3_id_table[] = { -+ { -+ .compatible = "ti,phy-pipe3-usb3", -+ .data = dpll_map_usb, -+ }, -+ { -+ .compatible = "ti,phy-pipe3-sata", -+ .data = dpll_map_sata, -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, omap_pipe3_id_table); -+#endif -+ -+static int omap_pipe3_probe(struct platform_device *pdev) -+{ -+ struct omap_pipe3 *phy; -+ struct phy *generic_phy; -+ struct phy_provider *phy_provider; -+ struct resource *res; -+ struct device_node *node = pdev->dev.of_node; -+ struct device_node *control_node; -+ struct platform_device *control_pdev; -+ const struct of_device_id *match; -+ -+ match = of_match_device(of_match_ptr(omap_pipe3_id_table), &pdev->dev); -+ if (!match) -+ return -EINVAL; -+ -+ phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); -+ if (!phy) { -+ dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n"); -+ return -ENOMEM; -+ } -+ -+ phy->dpll_map = (struct pipe3_dpll_map *)match->data; -+ if (!phy->dpll_map) { -+ dev_err(&pdev->dev, "no dpll data\n"); -+ return -EINVAL; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); -+ phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(phy->pll_ctrl_base)) -+ return PTR_ERR(phy->pll_ctrl_base); -+ -+ phy->dev = &pdev->dev; -+ -+ phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); -+ if (IS_ERR(phy->wkupclk)) -+ dev_dbg(&pdev->dev, "unable to get wkupclk\n"); -+ else -+ clk_prepare(phy->wkupclk); -+ -+ phy->optclk = devm_clk_get(phy->dev, "refclk"); -+ if (IS_ERR(phy->optclk)) -+ dev_dbg(&pdev->dev, "unable to get refclk\n"); -+ else -+ clk_prepare(phy->optclk); -+ -+ phy->optclk2 = devm_clk_get(phy->dev, "refclk2"); -+ if (IS_ERR(phy->optclk2)) -+ dev_dbg(&pdev->dev, "unable to get refclk2\n"); -+ else -+ clk_prepare(phy->optclk2); -+ -+ phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); -+ if (IS_ERR(phy->sys_clk)) { -+ pr_err("%s: unable to get sys_clkin\n", __func__); -+ return -EINVAL; -+ } -+ -+ control_node = of_parse_phandle(node, "ctrl-module", 0); -+ if (!control_node) { -+ dev_err(&pdev->dev, "Failed to get control device phandle\n"); -+ return -EINVAL; -+ } -+ -+ phy_provider = devm_of_phy_provider_register(phy->dev, -+ of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) -+ return PTR_ERR(phy_provider); -+ -+ control_pdev = of_find_device_by_node(control_node); -+ if (!control_pdev) { -+ dev_err(&pdev->dev, "Failed to get control device\n"); -+ return -EINVAL; -+ } -+ -+ phy->control_dev = &control_pdev->dev; -+ -+ omap_control_phy_power(phy->control_dev, 0); -+ -+ platform_set_drvdata(pdev, phy); -+ pm_runtime_enable(phy->dev); -+ -+ generic_phy = devm_phy_create(phy->dev, &ops, NULL); -+ if (IS_ERR(generic_phy)) -+ return PTR_ERR(generic_phy); -+ -+ phy_set_drvdata(generic_phy, phy); -+ -+ pm_runtime_get(&pdev->dev); -+ -+ return 0; -+} -+ -+static int omap_pipe3_remove(struct platform_device *pdev) -+{ -+ struct omap_pipe3 *phy = platform_get_drvdata(pdev); -+ -+ if (!IS_ERR(phy->wkupclk)) -+ clk_unprepare(phy->wkupclk); -+ if (!IS_ERR(phy->optclk)) -+ clk_unprepare(phy->optclk); -+ if (!IS_ERR(phy->optclk2)) -+ clk_unprepare(phy->optclk2); -+ if (!pm_runtime_suspended(&pdev->dev)) -+ pm_runtime_put(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_RUNTIME -+ -+static int omap_pipe3_runtime_suspend(struct device *dev) -+{ -+ struct omap_pipe3 *phy = dev_get_drvdata(dev); -+ -+ if (!IS_ERR(phy->wkupclk)) -+ clk_disable(phy->wkupclk); -+ if (!IS_ERR(phy->optclk)) -+ clk_disable(phy->optclk); -+ if (!IS_ERR(phy->optclk2)) -+ clk_disable(phy->optclk2); -+ -+ return 0; -+} -+ -+static int omap_pipe3_runtime_resume(struct device *dev) -+{ -+ u32 ret = 0; -+ struct omap_pipe3 *phy = dev_get_drvdata(dev); -+ -+ if (!IS_ERR(phy->optclk)) { -+ ret = clk_enable(phy->optclk); -+ if (ret) { -+ dev_err(phy->dev, "Failed to enable optclk %d\n", ret); -+ goto err1; -+ } -+ } -+ -+ if (!IS_ERR(phy->wkupclk)) { -+ ret = clk_enable(phy->wkupclk); -+ if (ret) { -+ dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); -+ goto err2; -+ } -+ } -+ -+ if (!IS_ERR(phy->optclk2)) { -+ ret = clk_enable(phy->optclk2); -+ if (ret) { -+ dev_err(phy->dev, "Failed to enable optclk2 %d\n", ret); -+ goto err3; -+ } -+ } -+ -+ return 0; -+ -+err3: -+ if (!IS_ERR(phy->wkupclk)) -+ clk_disable(phy->wkupclk); -+err2: -+ if (!IS_ERR(phy->optclk)) -+ clk_disable(phy->optclk); -+ -+err1: -+ return ret; -+} -+ -+static const struct dev_pm_ops omap_pipe3_pm_ops = { -+ SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend, -+ omap_pipe3_runtime_resume, NULL) -+}; -+ -+#define DEV_PM_OPS (&omap_pipe3_pm_ops) -+#else -+#define DEV_PM_OPS NULL -+#endif -+ -+static struct platform_driver omap_pipe3_driver = { -+ .probe = omap_pipe3_probe, -+ .remove = omap_pipe3_remove, -+ .driver = { -+ .name = "omap-pipe3", -+ .owner = THIS_MODULE, -+ .pm = DEV_PM_OPS, -+ .of_match_table = of_match_ptr(omap_pipe3_id_table), -+ }, -+}; -+ -+module_platform_driver(omap_pipe3_driver); -+ -+MODULE_ALIAS("platform: omap_pipe3"); -+MODULE_AUTHOR("Texas Instruments Inc."); -+MODULE_DESCRIPTION("OMAP PIPE3 phy driver"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/phy/phy-omap-usb2.c -@@ -0,0 +1,326 @@ -+/* -+ * omap-usb2.c - USB PHY, talking to musb controller in OMAP. -+ * -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/io.h> -+#include <linux/phy/omap_usb.h> -+#include <linux/usb/phy_companion.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/pm_runtime.h> -+#include <linux/delay.h> -+#include <linux/phy/omap_control_phy.h> -+#include <linux/phy/phy.h> -+#include <linux/of_platform.h> -+#include <linux/phy/phy.h> -+#include <linux/of_platform.h> -+ -+/** -+ * omap_usb2_set_comparator - links the comparator present in the sytem with -+ * this phy -+ * @comparator - the companion phy(comparator) for this phy -+ * -+ * The phy companion driver should call this API passing the phy_companion -+ * filled with set_vbus and start_srp to be used by usb phy. -+ * -+ * For use by phy companion driver -+ */ -+int omap_usb2_set_comparator(struct phy_companion *comparator) -+{ -+ struct omap_usb *phy; -+ struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2); -+ -+ if (IS_ERR(x)) -+ return -ENODEV; -+ -+ phy = phy_to_omapusb(x); -+ phy->comparator = comparator; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); -+ -+static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) -+{ -+ struct omap_usb *phy = phy_to_omapusb(otg->phy); -+ -+ if (!phy->comparator) -+ return -ENODEV; -+ -+ return phy->comparator->set_vbus(phy->comparator, enabled); -+} -+ -+static int omap_usb_start_srp(struct usb_otg *otg) -+{ -+ struct omap_usb *phy = phy_to_omapusb(otg->phy); -+ -+ if (!phy->comparator) -+ return -ENODEV; -+ -+ return phy->comparator->start_srp(phy->comparator); -+} -+ -+static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) -+{ -+ struct usb_phy *phy = otg->phy; -+ -+ otg->host = host; -+ if (!host) -+ phy->state = OTG_STATE_UNDEFINED; -+ -+ return 0; -+} -+ -+static int omap_usb_set_peripheral(struct usb_otg *otg, -+ struct usb_gadget *gadget) -+{ -+ struct usb_phy *phy = otg->phy; -+ -+ otg->gadget = gadget; -+ if (!gadget) -+ phy->state = OTG_STATE_UNDEFINED; -+ -+ return 0; -+} -+ -+static int omap_usb_power_off(struct phy *x) -+{ -+ struct omap_usb *phy = phy_get_drvdata(x); -+ -+ omap_control_phy_power(phy->control_dev, 0); -+ -+ return 0; -+} -+ -+static int omap_usb_power_on(struct phy *x) -+{ -+ struct omap_usb *phy = phy_get_drvdata(x); -+ -+ omap_control_phy_power(phy->control_dev, 1); -+ -+ return 0; -+} -+ -+static struct phy_ops ops = { -+ .power_on = omap_usb_power_on, -+ .power_off = omap_usb_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+#ifdef CONFIG_OF -+static const struct usb_phy_data omap_usb2_data = { -+ .label = "omap_usb2", -+ .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, -+}; -+ -+static const struct usb_phy_data am437x_usb2_data = { -+ .label = "am437x_usb2", -+ .flags = 0, -+}; -+ -+static const struct of_device_id omap_usb2_id_table[] = { -+ { -+ .compatible = "ti,omap-usb2", -+ .data = &omap_usb2_data, -+ }, -+ { -+ .compatible = "ti,am437x-usb2", -+ .data = &am437x_usb2_data, -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, omap_usb2_id_table); -+#endif -+ -+static int omap_usb2_probe(struct platform_device *pdev) -+{ -+ struct omap_usb *phy; -+ struct usb_otg *otg; -+ struct device_node *node = pdev->dev.of_node; -+ struct device_node *control_node; -+ struct platform_device *control_pdev; -+ struct phy *generic_phy; -+ struct phy_provider *phy_provider; -+ const struct of_device_id *of_id; -+ struct usb_phy_data *phy_data; -+ -+ of_id = of_match_device(of_match_ptr(omap_usb2_id_table), &pdev->dev); -+ -+ if (!of_id) -+ return -EINVAL; -+ phy_data = (struct usb_phy_data *)of_id->data; -+ -+ phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); -+ if (!phy) { -+ dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); -+ return -ENOMEM; -+ } -+ -+ otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); -+ if (!otg) { -+ dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); -+ return -ENOMEM; -+ } -+ -+ phy->dev = &pdev->dev; -+ -+ phy->phy.dev = phy->dev; -+ phy->phy.label = phy_data->label; -+ phy->phy.otg = otg; -+ phy->phy.type = USB_PHY_TYPE_USB2; -+ -+ phy_provider = devm_of_phy_provider_register(phy->dev, -+ of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) -+ return PTR_ERR(phy_provider); -+ -+ control_node = of_parse_phandle(node, "ctrl-module", 0); -+ if (!control_node) { -+ dev_err(&pdev->dev, "Failed to get control device phandle\n"); -+ return -EINVAL; -+ } -+ -+ control_pdev = of_find_device_by_node(control_node); -+ if (!control_pdev) { -+ dev_err(&pdev->dev, "Failed to get control device\n"); -+ return -EINVAL; -+ } -+ -+ phy->control_dev = &control_pdev->dev; -+ -+ omap_control_phy_power(phy->control_dev, 0); -+ -+ otg->set_host = omap_usb_set_host; -+ otg->set_peripheral = omap_usb_set_peripheral; -+ if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) -+ otg->set_vbus = omap_usb_set_vbus; -+ if (phy_data->flags & OMAP_USB2_HAS_START_SRP) -+ otg->start_srp = omap_usb_start_srp; -+ otg->phy = &phy->phy; -+ -+ platform_set_drvdata(pdev, phy); -+ pm_runtime_enable(phy->dev); -+ -+ generic_phy = devm_phy_create(phy->dev, &ops, NULL); -+ if (IS_ERR(generic_phy)) -+ return PTR_ERR(generic_phy); -+ -+ phy_set_drvdata(generic_phy, phy); -+ -+ phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); -+ if (IS_ERR(phy->wkupclk)) { -+ dev_err(&pdev->dev, "unable to get wkupclk\n"); -+ return PTR_ERR(phy->wkupclk); -+ } -+ clk_prepare(phy->wkupclk); -+ -+ phy->optclk = devm_clk_get(phy->dev, "refclk"); -+ if (IS_ERR(phy->optclk)) -+ dev_dbg(&pdev->dev, "unable to get refclk\n"); -+ else -+ clk_prepare(phy->optclk); -+ -+ usb_add_phy_dev(&phy->phy); -+ -+ return 0; -+} -+ -+static int omap_usb2_remove(struct platform_device *pdev) -+{ -+ struct omap_usb *phy = platform_get_drvdata(pdev); -+ -+ clk_unprepare(phy->wkupclk); -+ if (!IS_ERR(phy->optclk)) -+ clk_unprepare(phy->optclk); -+ usb_remove_phy(&phy->phy); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_RUNTIME -+ -+static int omap_usb2_runtime_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct omap_usb *phy = platform_get_drvdata(pdev); -+ -+ clk_disable(phy->wkupclk); -+ if (!IS_ERR(phy->optclk)) -+ clk_disable(phy->optclk); -+ -+ return 0; -+} -+ -+static int omap_usb2_runtime_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct omap_usb *phy = platform_get_drvdata(pdev); -+ int ret; -+ -+ ret = clk_enable(phy->wkupclk); -+ if (ret < 0) { -+ dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); -+ goto err0; -+ } -+ -+ if (!IS_ERR(phy->optclk)) { -+ ret = clk_enable(phy->optclk); -+ if (ret < 0) { -+ dev_err(phy->dev, "Failed to enable optclk %d\n", ret); -+ goto err1; -+ } -+ } -+ -+ return 0; -+ -+err1: -+ clk_disable(phy->wkupclk); -+ -+err0: -+ return ret; -+} -+ -+static const struct dev_pm_ops omap_usb2_pm_ops = { -+ SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume, -+ NULL) -+}; -+ -+#define DEV_PM_OPS (&omap_usb2_pm_ops) -+#else -+#define DEV_PM_OPS NULL -+#endif -+ -+static struct platform_driver omap_usb2_driver = { -+ .probe = omap_usb2_probe, -+ .remove = omap_usb2_remove, -+ .driver = { -+ .name = "omap-usb2", -+ .owner = THIS_MODULE, -+ .pm = DEV_PM_OPS, -+ .of_match_table = of_match_ptr(omap_usb2_id_table), -+ }, -+}; -+ -+module_platform_driver(omap_usb2_driver); -+ -+MODULE_ALIAS("platform: omap_usb2"); -+MODULE_AUTHOR("Texas Instruments Inc."); -+MODULE_DESCRIPTION("OMAP USB2 phy driver"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/phy/phy-twl4030-usb.c -@@ -0,0 +1,815 @@ -+/* -+ * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller -+ * -+ * Copyright (C) 2004-2007 Texas Instruments -+ * Copyright (C) 2008 Nokia Corporation -+ * Contact: Felipe Balbi <felipe.balbi@nokia.com> -+ * -+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * Current status: -+ * - HS USB ULPI mode works. -+ * - 3-pin mode support may be added in future. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/platform_device.h> -+#include <linux/spinlock.h> -+#include <linux/workqueue.h> -+#include <linux/io.h> -+#include <linux/delay.h> -+#include <linux/usb/otg.h> -+#include <linux/phy/phy.h> -+#include <linux/usb/musb-omap.h> -+#include <linux/usb/ulpi.h> -+#include <linux/i2c/twl.h> -+#include <linux/regulator/consumer.h> -+#include <linux/err.h> -+#include <linux/slab.h> -+ -+/* Register defines */ -+ -+#define MCPC_CTRL 0x30 -+#define MCPC_CTRL_RTSOL (1 << 7) -+#define MCPC_CTRL_EXTSWR (1 << 6) -+#define MCPC_CTRL_EXTSWC (1 << 5) -+#define MCPC_CTRL_VOICESW (1 << 4) -+#define MCPC_CTRL_OUT64K (1 << 3) -+#define MCPC_CTRL_RTSCTSSW (1 << 2) -+#define MCPC_CTRL_HS_UART (1 << 0) -+ -+#define MCPC_IO_CTRL 0x33 -+#define MCPC_IO_CTRL_MICBIASEN (1 << 5) -+#define MCPC_IO_CTRL_CTS_NPU (1 << 4) -+#define MCPC_IO_CTRL_RXD_PU (1 << 3) -+#define MCPC_IO_CTRL_TXDTYP (1 << 2) -+#define MCPC_IO_CTRL_CTSTYP (1 << 1) -+#define MCPC_IO_CTRL_RTSTYP (1 << 0) -+ -+#define MCPC_CTRL2 0x36 -+#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) -+ -+#define OTHER_FUNC_CTRL 0x80 -+#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) -+#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) -+ -+#define OTHER_IFC_CTRL 0x83 -+#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) -+#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) -+#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) -+#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) -+#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) -+#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) -+ -+#define OTHER_INT_EN_RISE 0x86 -+#define OTHER_INT_EN_FALL 0x89 -+#define OTHER_INT_STS 0x8C -+#define OTHER_INT_LATCH 0x8D -+#define OTHER_INT_VB_SESS_VLD (1 << 7) -+#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ -+#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ -+#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ -+#define OTHER_INT_MANU (1 << 1) -+#define OTHER_INT_ABNORMAL_STRESS (1 << 0) -+ -+#define ID_STATUS 0x96 -+#define ID_RES_FLOAT (1 << 4) -+#define ID_RES_440K (1 << 3) -+#define ID_RES_200K (1 << 2) -+#define ID_RES_102K (1 << 1) -+#define ID_RES_GND (1 << 0) -+ -+#define POWER_CTRL 0xAC -+#define POWER_CTRL_OTG_ENAB (1 << 5) -+ -+#define OTHER_IFC_CTRL2 0xAF -+#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) -+#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) -+#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) -+#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ -+#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) -+#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) -+ -+#define REG_CTRL_EN 0xB2 -+#define REG_CTRL_ERROR 0xB5 -+#define ULPI_I2C_CONFLICT_INTEN (1 << 0) -+ -+#define OTHER_FUNC_CTRL2 0xB8 -+#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) -+ -+/* following registers do not have separate _clr and _set registers */ -+#define VBUS_DEBOUNCE 0xC0 -+#define ID_DEBOUNCE 0xC1 -+#define VBAT_TIMER 0xD3 -+#define PHY_PWR_CTRL 0xFD -+#define PHY_PWR_PHYPWD (1 << 0) -+#define PHY_CLK_CTRL 0xFE -+#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) -+#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) -+#define REQ_PHY_DPLL_CLK (1 << 0) -+#define PHY_CLK_CTRL_STS 0xFF -+#define PHY_DPLL_CLK (1 << 0) -+ -+/* In module TWL_MODULE_PM_MASTER */ -+#define STS_HW_CONDITIONS 0x0F -+ -+/* In module TWL_MODULE_PM_RECEIVER */ -+#define VUSB_DEDICATED1 0x7D -+#define VUSB_DEDICATED2 0x7E -+#define VUSB1V5_DEV_GRP 0x71 -+#define VUSB1V5_TYPE 0x72 -+#define VUSB1V5_REMAP 0x73 -+#define VUSB1V8_DEV_GRP 0x74 -+#define VUSB1V8_TYPE 0x75 -+#define VUSB1V8_REMAP 0x76 -+#define VUSB3V1_DEV_GRP 0x77 -+#define VUSB3V1_TYPE 0x78 -+#define VUSB3V1_REMAP 0x79 -+ -+/* In module TWL4030_MODULE_INTBR */ -+#define PMBR1 0x0D -+#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) -+ -+struct twl4030_usb { -+ struct usb_phy phy; -+ struct device *dev; -+ -+ /* TWL4030 internal USB regulator supplies */ -+ struct regulator *usb1v5; -+ struct regulator *usb1v8; -+ struct regulator *usb3v1; -+ -+ /* for vbus reporting with irqs disabled */ -+ spinlock_t lock; -+ -+ /* pin configuration */ -+ enum twl4030_usb_mode usb_mode; -+ -+ int irq; -+ enum omap_musb_vbus_id_status linkstat; -+ bool vbus_supplied; -+ u8 asleep; -+ bool irq_enabled; -+ -+ struct delayed_work id_workaround_work; -+}; -+ -+/* internal define on top of container_of */ -+#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) -+ -+/*-------------------------------------------------------------------------*/ -+ -+static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, -+ u8 module, u8 data, u8 address) -+{ -+ u8 check; -+ -+ if ((twl_i2c_write_u8(module, data, address) >= 0) && -+ (twl_i2c_read_u8(module, &check, address) >= 0) && -+ (check == data)) -+ return 0; -+ dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", -+ 1, module, address, check, data); -+ -+ /* Failed once: Try again */ -+ if ((twl_i2c_write_u8(module, data, address) >= 0) && -+ (twl_i2c_read_u8(module, &check, address) >= 0) && -+ (check == data)) -+ return 0; -+ dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", -+ 2, module, address, check, data); -+ -+ /* Failed again: Return error */ -+ return -EBUSY; -+} -+ -+#define twl4030_usb_write_verify(twl, address, data) \ -+ twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) -+ -+static inline int twl4030_usb_write(struct twl4030_usb *twl, -+ u8 address, u8 data) -+{ -+ int ret = 0; -+ -+ ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); -+ if (ret < 0) -+ dev_dbg(twl->dev, -+ "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); -+ return ret; -+} -+ -+static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) -+{ -+ u8 data; -+ int ret = 0; -+ -+ ret = twl_i2c_read_u8(module, &data, address); -+ if (ret >= 0) -+ ret = data; -+ else -+ dev_dbg(twl->dev, -+ "TWL4030:readb[0x%x,0x%x] Error %d\n", -+ module, address, ret); -+ -+ return ret; -+} -+ -+static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) -+{ -+ return twl4030_readb(twl, TWL_MODULE_USB, address); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static inline int -+twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -+{ -+ return twl4030_usb_write(twl, ULPI_SET(reg), bits); -+} -+ -+static inline int -+twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) -+{ -+ return twl4030_usb_write(twl, ULPI_CLR(reg), bits); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static bool twl4030_is_driving_vbus(struct twl4030_usb *twl) -+{ -+ int ret; -+ -+ ret = twl4030_usb_read(twl, PHY_CLK_CTRL_STS); -+ if (ret < 0 || !(ret & PHY_DPLL_CLK)) -+ /* -+ * if clocks are off, registers are not updated, -+ * but we can assume we don't drive VBUS in this case -+ */ -+ return false; -+ -+ ret = twl4030_usb_read(twl, ULPI_OTG_CTRL); -+ if (ret < 0) -+ return false; -+ -+ return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false; -+} -+ -+static enum omap_musb_vbus_id_status -+ twl4030_usb_linkstat(struct twl4030_usb *twl) -+{ -+ int status; -+ enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; -+ -+ twl->vbus_supplied = false; -+ -+ /* -+ * For ID/VBUS sensing, see manual section 15.4.8 ... -+ * except when using only battery backup power, two -+ * comparators produce VBUS_PRES and ID_PRES signals, -+ * which don't match docs elsewhere. But ... BIT(7) -+ * and BIT(2) of STS_HW_CONDITIONS, respectively, do -+ * seem to match up. If either is true the USB_PRES -+ * signal is active, the OTG module is activated, and -+ * its interrupt may be raised (may wake the system). -+ */ -+ status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); -+ if (status < 0) -+ dev_err(twl->dev, "USB link status err %d\n", status); -+ else if (status & (BIT(7) | BIT(2))) { -+ if (status & BIT(7)) { -+ if (twl4030_is_driving_vbus(twl)) -+ status &= ~BIT(7); -+ else -+ twl->vbus_supplied = true; -+ } -+ -+ if (status & BIT(2)) -+ linkstat = OMAP_MUSB_ID_GROUND; -+ else if (status & BIT(7)) -+ linkstat = OMAP_MUSB_VBUS_VALID; -+ else -+ linkstat = OMAP_MUSB_VBUS_OFF; -+ } else { -+ if (twl->linkstat != OMAP_MUSB_UNKNOWN) -+ linkstat = OMAP_MUSB_VBUS_OFF; -+ } -+ -+ dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", -+ status, status, linkstat); -+ -+ /* REVISIT this assumes host and peripheral controllers -+ * are registered, and that both are active... -+ */ -+ -+ return linkstat; -+} -+ -+static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) -+{ -+ twl->usb_mode = mode; -+ -+ switch (mode) { -+ case T2_USB_MODE_ULPI: -+ twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, -+ ULPI_IFC_CTRL_CARKITMODE); -+ twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); -+ twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, -+ ULPI_FUNC_CTRL_XCVRSEL_MASK | -+ ULPI_FUNC_CTRL_OPMODE_MASK); -+ break; -+ case -1: -+ /* FIXME: power on defaults */ -+ break; -+ default: -+ dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", -+ mode); -+ break; -+ }; -+} -+ -+static void twl4030_i2c_access(struct twl4030_usb *twl, int on) -+{ -+ unsigned long timeout; -+ int val = twl4030_usb_read(twl, PHY_CLK_CTRL); -+ -+ if (val >= 0) { -+ if (on) { -+ /* enable DPLL to access PHY registers over I2C */ -+ val |= REQ_PHY_DPLL_CLK; -+ WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, -+ (u8)val) < 0); -+ -+ timeout = jiffies + HZ; -+ while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & -+ PHY_DPLL_CLK) -+ && time_before(jiffies, timeout)) -+ udelay(10); -+ if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & -+ PHY_DPLL_CLK)) -+ dev_err(twl->dev, "Timeout setting T2 HSUSB " -+ "PHY DPLL clock\n"); -+ } else { -+ /* let ULPI control the DPLL clock */ -+ val &= ~REQ_PHY_DPLL_CLK; -+ WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, -+ (u8)val) < 0); -+ } -+ } -+} -+ -+static void __twl4030_phy_power(struct twl4030_usb *twl, int on) -+{ -+ u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); -+ -+ if (on) -+ pwr &= ~PHY_PWR_PHYPWD; -+ else -+ pwr |= PHY_PWR_PHYPWD; -+ -+ WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); -+} -+ -+static void twl4030_phy_power(struct twl4030_usb *twl, int on) -+{ -+ int ret; -+ -+ if (on) { -+ ret = regulator_enable(twl->usb3v1); -+ if (ret) -+ dev_err(twl->dev, "Failed to enable usb3v1\n"); -+ -+ ret = regulator_enable(twl->usb1v8); -+ if (ret) -+ dev_err(twl->dev, "Failed to enable usb1v8\n"); -+ -+ /* -+ * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP -+ * in twl4030) resets the VUSB_DEDICATED2 register. This reset -+ * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to -+ * SLEEP. We work around this by clearing the bit after usv3v1 -+ * is re-activated. This ensures that VUSB3V1 is really active. -+ */ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); -+ -+ ret = regulator_enable(twl->usb1v5); -+ if (ret) -+ dev_err(twl->dev, "Failed to enable usb1v5\n"); -+ -+ __twl4030_phy_power(twl, 1); -+ twl4030_usb_write(twl, PHY_CLK_CTRL, -+ twl4030_usb_read(twl, PHY_CLK_CTRL) | -+ (PHY_CLK_CTRL_CLOCKGATING_EN | -+ PHY_CLK_CTRL_CLK32K_EN)); -+ } else { -+ __twl4030_phy_power(twl, 0); -+ regulator_disable(twl->usb1v5); -+ regulator_disable(twl->usb1v8); -+ regulator_disable(twl->usb3v1); -+ } -+} -+ -+static int twl4030_phy_power_off(struct phy *phy) -+{ -+ struct twl4030_usb *twl = phy_get_drvdata(phy); -+ -+ if (twl->asleep) -+ return 0; -+ -+ twl4030_phy_power(twl, 0); -+ twl->asleep = 1; -+ dev_dbg(twl->dev, "%s\n", __func__); -+ return 0; -+} -+ -+static void __twl4030_phy_power_on(struct twl4030_usb *twl) -+{ -+ twl4030_phy_power(twl, 1); -+ twl4030_i2c_access(twl, 1); -+ twl4030_usb_set_mode(twl, twl->usb_mode); -+ if (twl->usb_mode == T2_USB_MODE_ULPI) -+ twl4030_i2c_access(twl, 0); -+} -+ -+static int twl4030_phy_power_on(struct phy *phy) -+{ -+ struct twl4030_usb *twl = phy_get_drvdata(phy); -+ -+ if (!twl->asleep) -+ return 0; -+ __twl4030_phy_power_on(twl); -+ twl->asleep = 0; -+ dev_dbg(twl->dev, "%s\n", __func__); -+ -+ /* -+ * XXX When VBUS gets driven after musb goes to A mode, -+ * ID_PRES related interrupts no longer arrive, why? -+ * Register itself is updated fine though, so we must poll. -+ */ -+ if (twl->linkstat == OMAP_MUSB_ID_GROUND) { -+ cancel_delayed_work(&twl->id_workaround_work); -+ schedule_delayed_work(&twl->id_workaround_work, HZ); -+ } -+ return 0; -+} -+ -+static int twl4030_usb_ldo_init(struct twl4030_usb *twl) -+{ -+ /* Enable writing to power configuration registers */ -+ twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, -+ TWL4030_PM_MASTER_PROTECT_KEY); -+ -+ twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, -+ TWL4030_PM_MASTER_PROTECT_KEY); -+ -+ /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ -+ /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ -+ -+ /* input to VUSB3V1 LDO is from VBAT, not VBUS */ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); -+ -+ /* Initialize 3.1V regulator */ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); -+ -+ twl->usb3v1 = devm_regulator_get(twl->dev, "usb3v1"); -+ if (IS_ERR(twl->usb3v1)) -+ return -ENODEV; -+ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); -+ -+ /* Initialize 1.5V regulator */ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); -+ -+ twl->usb1v5 = devm_regulator_get(twl->dev, "usb1v5"); -+ if (IS_ERR(twl->usb1v5)) -+ return -ENODEV; -+ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); -+ -+ /* Initialize 1.8V regulator */ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); -+ -+ twl->usb1v8 = devm_regulator_get(twl->dev, "usb1v8"); -+ if (IS_ERR(twl->usb1v8)) -+ return -ENODEV; -+ -+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); -+ -+ /* disable access to power configuration registers */ -+ twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, -+ TWL4030_PM_MASTER_PROTECT_KEY); -+ -+ return 0; -+} -+ -+static ssize_t twl4030_usb_vbus_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct twl4030_usb *twl = dev_get_drvdata(dev); -+ unsigned long flags; -+ int ret = -EINVAL; -+ -+ spin_lock_irqsave(&twl->lock, flags); -+ ret = sprintf(buf, "%s\n", -+ twl->vbus_supplied ? "on" : "off"); -+ spin_unlock_irqrestore(&twl->lock, flags); -+ -+ return ret; -+} -+static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); -+ -+static irqreturn_t twl4030_usb_irq(int irq, void *_twl) -+{ -+ struct twl4030_usb *twl = _twl; -+ enum omap_musb_vbus_id_status status; -+ bool status_changed = false; -+ -+ status = twl4030_usb_linkstat(twl); -+ -+ spin_lock_irq(&twl->lock); -+ if (status >= 0 && status != twl->linkstat) { -+ twl->linkstat = status; -+ status_changed = true; -+ } -+ spin_unlock_irq(&twl->lock); -+ -+ if (status_changed) { -+ /* FIXME add a set_power() method so that B-devices can -+ * configure the charger appropriately. It's not always -+ * correct to consume VBUS power, and how much current to -+ * consume is a function of the USB configuration chosen -+ * by the host. -+ * -+ * REVISIT usb_gadget_vbus_connect(...) as needed, ditto -+ * its disconnect() sibling, when changing to/from the -+ * USB_LINK_VBUS state. musb_hdrc won't care until it -+ * starts to handle softconnect right. -+ */ -+ omap_musb_mailbox(status); -+ } -+ sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -+ -+ return IRQ_HANDLED; -+} -+ -+static void twl4030_id_workaround_work(struct work_struct *work) -+{ -+ struct twl4030_usb *twl = container_of(work, struct twl4030_usb, -+ id_workaround_work.work); -+ enum omap_musb_vbus_id_status status; -+ bool status_changed = false; -+ -+ status = twl4030_usb_linkstat(twl); -+ -+ spin_lock_irq(&twl->lock); -+ if (status >= 0 && status != twl->linkstat) { -+ twl->linkstat = status; -+ status_changed = true; -+ } -+ spin_unlock_irq(&twl->lock); -+ -+ if (status_changed) { -+ dev_dbg(twl->dev, "handle missing status change to %d\n", -+ status); -+ omap_musb_mailbox(status); -+ } -+ -+ /* don't schedule during sleep - irq works right then */ -+ if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { -+ cancel_delayed_work(&twl->id_workaround_work); -+ schedule_delayed_work(&twl->id_workaround_work, HZ); -+ } -+} -+ -+static int twl4030_phy_init(struct phy *phy) -+{ -+ struct twl4030_usb *twl = phy_get_drvdata(phy); -+ enum omap_musb_vbus_id_status status; -+ -+ /* -+ * Start in sleep state, we'll get called through set_suspend() -+ * callback when musb is runtime resumed and it's time to start. -+ */ -+ __twl4030_phy_power(twl, 0); -+ twl->asleep = 1; -+ -+ status = twl4030_usb_linkstat(twl); -+ twl->linkstat = status; -+ -+ if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { -+ omap_musb_mailbox(twl->linkstat); -+ twl4030_phy_power_on(phy); -+ } -+ -+ sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -+ return 0; -+} -+ -+static int twl4030_set_peripheral(struct usb_otg *otg, -+ struct usb_gadget *gadget) -+{ -+ if (!otg) -+ return -ENODEV; -+ -+ otg->gadget = gadget; -+ if (!gadget) -+ otg->phy->state = OTG_STATE_UNDEFINED; -+ -+ return 0; -+} -+ -+static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) -+{ -+ if (!otg) -+ return -ENODEV; -+ -+ otg->host = host; -+ if (!host) -+ otg->phy->state = OTG_STATE_UNDEFINED; -+ -+ return 0; -+} -+ -+static const struct phy_ops ops = { -+ .init = twl4030_phy_init, -+ .power_on = twl4030_phy_power_on, -+ .power_off = twl4030_phy_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+static int twl4030_usb_probe(struct platform_device *pdev) -+{ -+ struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); -+ struct twl4030_usb *twl; -+ struct phy *phy; -+ int status, err; -+ struct usb_otg *otg; -+ struct device_node *np = pdev->dev.of_node; -+ struct phy_provider *phy_provider; -+ struct phy_init_data *init_data = NULL; -+ -+ twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); -+ if (!twl) -+ return -ENOMEM; -+ -+ if (np) -+ of_property_read_u32(np, "usb_mode", -+ (enum twl4030_usb_mode *)&twl->usb_mode); -+ else if (pdata) { -+ twl->usb_mode = pdata->usb_mode; -+ init_data = pdata->init_data; -+ } else { -+ dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); -+ return -EINVAL; -+ } -+ -+ otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); -+ if (!otg) -+ return -ENOMEM; -+ -+ twl->dev = &pdev->dev; -+ twl->irq = platform_get_irq(pdev, 0); -+ twl->vbus_supplied = false; -+ twl->asleep = 1; -+ twl->linkstat = OMAP_MUSB_UNKNOWN; -+ -+ twl->phy.dev = twl->dev; -+ twl->phy.label = "twl4030"; -+ twl->phy.otg = otg; -+ twl->phy.type = USB_PHY_TYPE_USB2; -+ -+ otg->phy = &twl->phy; -+ otg->set_host = twl4030_set_host; -+ otg->set_peripheral = twl4030_set_peripheral; -+ -+ phy_provider = devm_of_phy_provider_register(twl->dev, -+ of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) -+ return PTR_ERR(phy_provider); -+ -+ phy = devm_phy_create(twl->dev, &ops, init_data); -+ if (IS_ERR(phy)) { -+ dev_dbg(&pdev->dev, "Failed to create PHY\n"); -+ return PTR_ERR(phy); -+ } -+ -+ phy_set_drvdata(phy, twl); -+ -+ /* init spinlock for workqueue */ -+ spin_lock_init(&twl->lock); -+ -+ INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); -+ -+ err = twl4030_usb_ldo_init(twl); -+ if (err) { -+ dev_err(&pdev->dev, "ldo init failed\n"); -+ return err; -+ } -+ usb_add_phy_dev(&twl->phy); -+ -+ platform_set_drvdata(pdev, twl); -+ if (device_create_file(&pdev->dev, &dev_attr_vbus)) -+ dev_warn(&pdev->dev, "could not create sysfs file\n"); -+ -+ ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); -+ -+ /* Our job is to use irqs and status from the power module -+ * to keep the transceiver disabled when nothing's connected. -+ * -+ * FIXME we actually shouldn't start enabling it until the -+ * USB controller drivers have said they're ready, by calling -+ * set_host() and/or set_peripheral() ... OTG_capable boards -+ * need both handles, otherwise just one suffices. -+ */ -+ twl->irq_enabled = true; -+ status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, -+ twl4030_usb_irq, IRQF_TRIGGER_FALLING | -+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); -+ if (status < 0) { -+ dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", -+ twl->irq, status); -+ return status; -+ } -+ -+ dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); -+ return 0; -+} -+ -+static int twl4030_usb_remove(struct platform_device *pdev) -+{ -+ struct twl4030_usb *twl = platform_get_drvdata(pdev); -+ int val; -+ -+ cancel_delayed_work(&twl->id_workaround_work); -+ device_remove_file(twl->dev, &dev_attr_vbus); -+ -+ /* set transceiver mode to power on defaults */ -+ twl4030_usb_set_mode(twl, -1); -+ -+ /* autogate 60MHz ULPI clock, -+ * clear dpll clock request for i2c access, -+ * disable 32KHz -+ */ -+ val = twl4030_usb_read(twl, PHY_CLK_CTRL); -+ if (val >= 0) { -+ val |= PHY_CLK_CTRL_CLOCKGATING_EN; -+ val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); -+ twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); -+ } -+ -+ /* disable complete OTG block */ -+ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); -+ -+ if (!twl->asleep) -+ twl4030_phy_power(twl, 0); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id twl4030_usb_id_table[] = { -+ { .compatible = "ti,twl4030-usb" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); -+#endif -+ -+static struct platform_driver twl4030_usb_driver = { -+ .probe = twl4030_usb_probe, -+ .remove = twl4030_usb_remove, -+ .driver = { -+ .name = "twl4030_usb", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(twl4030_usb_id_table), -+ }, -+}; -+ -+static int __init twl4030_usb_init(void) -+{ -+ return platform_driver_register(&twl4030_usb_driver); -+} -+subsys_initcall(twl4030_usb_init); -+ -+static void __exit twl4030_usb_exit(void) -+{ -+ platform_driver_unregister(&twl4030_usb_driver); -+} -+module_exit(twl4030_usb_exit); -+ -+MODULE_ALIAS("platform:twl4030_usb"); -+MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); -+MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); -+MODULE_LICENSE("GPL"); ---- a/drivers/regulator/core.c -+++ b/drivers/regulator/core.c -@@ -124,6 +124,51 @@ static const char *rdev_get_name(struct - return ""; - } - -+static void regulator_lock(struct regulator_dev *rdev) -+{ -+ struct regulator_dev *locking_rdev = rdev; -+ -+ while (locking_rdev->supply) -+ locking_rdev = locking_rdev->supply->rdev; -+ -+ if (!mutex_trylock(&locking_rdev->mutex)) { -+ if (locking_rdev->lock_owner == current) { -+ locking_rdev->lock_count++; -+ dev_dbg(&locking_rdev->dev, -+ "Is locked. locking %s (ref=%u)\n", -+ rdev_get_name(rdev), -+ locking_rdev->lock_count); -+ return; -+ } -+ mutex_lock(&locking_rdev->mutex); -+ } -+ -+ WARN_ON_ONCE(locking_rdev->lock_owner != NULL); -+ WARN_ON_ONCE(locking_rdev->lock_count != 0); -+ -+ locking_rdev->lock_count = 1; -+ locking_rdev->lock_owner = current; -+ dev_dbg(&locking_rdev->dev, "Is locked. locking %s\n", -+ rdev_get_name(rdev)); -+} -+ -+static void regulator_unlock(struct regulator_dev *rdev) -+{ -+ struct regulator_dev *locking_rdev = rdev; -+ -+ while (locking_rdev->supply) -+ locking_rdev = locking_rdev->supply->rdev; -+ -+ dev_dbg(&locking_rdev->dev, "Is unlocked. unlocking %s (ref=%u)\n", -+ rdev_get_name(rdev), locking_rdev->lock_count); -+ -+ if (--locking_rdev->lock_count) -+ return; -+ -+ locking_rdev->lock_owner = NULL; -+ mutex_unlock(&locking_rdev->mutex); -+} -+ - /** - * of_get_regulator - get a regulator device node based on supply name - * @dev: Device pointer for the consumer (of regulator) device -@@ -306,9 +351,9 @@ static ssize_t regulator_uV_show(struct - struct regulator_dev *rdev = dev_get_drvdata(dev); - ssize_t ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev)); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - return ret; - } -@@ -372,9 +417,9 @@ static ssize_t regulator_state_show(stru - struct regulator_dev *rdev = dev_get_drvdata(dev); - ssize_t ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - ret = regulator_print_state(buf, _regulator_is_enabled(rdev)); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - return ret; - } -@@ -482,10 +527,10 @@ static ssize_t regulator_total_uA_show(s - struct regulator *regulator; - int uA = 0; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - list_for_each_entry(regulator, &rdev->consumer_list, list) - uA += regulator->uA_load; -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return sprintf(buf, "%d\n", uA); - } - static DEVICE_ATTR(requested_microamps, 0444, regulator_total_uA_show, NULL); -@@ -1123,7 +1168,7 @@ static struct regulator *create_regulato - if (regulator == NULL) - return NULL; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - regulator->rdev = rdev; - list_add(®ulator->list, &rdev->consumer_list); - -@@ -1175,12 +1220,12 @@ static struct regulator *create_regulato - _regulator_is_enabled(rdev)) - regulator->always_on = true; - -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return regulator; - overflow_err: - list_del(®ulator->list); - kfree(regulator); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return NULL; - } - -@@ -1774,9 +1819,9 @@ int regulator_enable(struct regulator *r - return ret; - } - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - ret = _regulator_enable(rdev); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - if (ret != 0 && rdev->supply) - regulator_disable(rdev->supply); -@@ -1866,9 +1911,9 @@ int regulator_disable(struct regulator * - if (regulator->always_on) - return 0; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - ret = _regulator_disable(rdev); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - if (ret == 0 && rdev->supply) - regulator_disable(rdev->supply); -@@ -1912,10 +1957,10 @@ int regulator_force_disable(struct regul - struct regulator_dev *rdev = regulator->rdev; - int ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - regulator->uA_load = 0; - ret = _regulator_force_disable(regulator->rdev); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - if (rdev->supply) - while (rdev->open_count--) -@@ -1931,7 +1976,7 @@ static void regulator_disable_work(struc - disable_work.work); - int count, i, ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - BUG_ON(!rdev->deferred_disables); - -@@ -1944,7 +1989,7 @@ static void regulator_disable_work(struc - rdev_err(rdev, "Deferred disable failed: %d\n", ret); - } - -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - if (rdev->supply) { - for (i = 0; i < count; i++) { -@@ -1980,9 +2025,9 @@ int regulator_disable_deferred(struct re - if (!ms) - return regulator_disable(regulator); - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - rdev->deferred_disables++; -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - ret = queue_delayed_work(system_power_efficient_wq, - &rdev->disable_work, -@@ -2026,9 +2071,9 @@ int regulator_is_enabled(struct regulato - if (regulator->always_on) - return 1; - -- mutex_lock(®ulator->rdev->mutex); -+ regulator_lock(regulator->rdev); - ret = _regulator_is_enabled(regulator->rdev); -- mutex_unlock(®ulator->rdev->mutex); -+ regulator_unlock(regulator->rdev); - - return ret; - } -@@ -2097,9 +2142,9 @@ int regulator_list_voltage(struct regula - if (!ops->list_voltage || selector >= rdev->desc->n_voltages) - return -EINVAL; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - ret = ops->list_voltage(rdev, selector); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - if (ret > 0) { - if (ret < rdev->constraints->min_uV) -@@ -2298,7 +2343,7 @@ int regulator_set_voltage(struct regulat - int ret = 0; - int old_min_uV, old_max_uV; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - /* If we're setting the same range as last time the change - * should be a noop (some cpufreq implementations use the same -@@ -2334,12 +2379,12 @@ int regulator_set_voltage(struct regulat - goto out2; - - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - out2: - regulator->min_uV = old_min_uV; - regulator->max_uV = old_max_uV; -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - EXPORT_SYMBOL_GPL(regulator_set_voltage); -@@ -2442,7 +2487,7 @@ int regulator_sync_voltage(struct regula - struct regulator_dev *rdev = regulator->rdev; - int ret, min_uV, max_uV; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - if (!rdev->desc->ops->set_voltage && - !rdev->desc->ops->set_voltage_sel) { -@@ -2471,7 +2516,7 @@ int regulator_sync_voltage(struct regula - ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); - - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - EXPORT_SYMBOL_GPL(regulator_sync_voltage); -@@ -2511,11 +2556,11 @@ int regulator_get_voltage(struct regulat - { - int ret; - -- mutex_lock(®ulator->rdev->mutex); -+ regulator_lock(regulator->rdev); - - ret = _regulator_get_voltage(regulator->rdev); - -- mutex_unlock(®ulator->rdev->mutex); -+ regulator_unlock(regulator->rdev); - - return ret; - } -@@ -2543,7 +2588,7 @@ int regulator_set_current_limit(struct r - struct regulator_dev *rdev = regulator->rdev; - int ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - /* sanity check */ - if (!rdev->desc->ops->set_current_limit) { -@@ -2558,7 +2603,7 @@ int regulator_set_current_limit(struct r - - ret = rdev->desc->ops->set_current_limit(rdev, min_uA, max_uA); - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - EXPORT_SYMBOL_GPL(regulator_set_current_limit); -@@ -2567,7 +2612,7 @@ static int _regulator_get_current_limit( - { - int ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - /* sanity check */ - if (!rdev->desc->ops->get_current_limit) { -@@ -2577,7 +2622,7 @@ static int _regulator_get_current_limit( - - ret = rdev->desc->ops->get_current_limit(rdev); - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - -@@ -2613,7 +2658,7 @@ int regulator_set_mode(struct regulator - int ret; - int regulator_curr_mode; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - /* sanity check */ - if (!rdev->desc->ops->set_mode) { -@@ -2637,7 +2682,7 @@ int regulator_set_mode(struct regulator - - ret = rdev->desc->ops->set_mode(rdev, mode); - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - EXPORT_SYMBOL_GPL(regulator_set_mode); -@@ -2646,7 +2691,7 @@ static unsigned int _regulator_get_mode( - { - int ret; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - /* sanity check */ - if (!rdev->desc->ops->get_mode) { -@@ -2656,7 +2701,7 @@ static unsigned int _regulator_get_mode( - - ret = rdev->desc->ops->get_mode(rdev); - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - -@@ -2708,7 +2753,7 @@ int regulator_set_optimum_mode(struct re - if (rdev->supply) - input_uV = regulator_get_voltage(rdev->supply); - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - /* - * first check to see if we can set modes at all, otherwise just -@@ -2769,7 +2814,7 @@ int regulator_set_optimum_mode(struct re - } - ret = mode; - out: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - return ret; - } - EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); -@@ -2797,7 +2842,7 @@ int regulator_allow_bypass(struct regula - !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS)) - return 0; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - if (enable && !regulator->bypass) { - rdev->bypass_count++; -@@ -2821,7 +2866,7 @@ int regulator_allow_bypass(struct regula - if (ret == 0) - regulator->bypass = enable; - -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - return ret; - } -@@ -3540,9 +3585,9 @@ int regulator_suspend_prepare(suspend_st - mutex_lock(®ulator_list_mutex); - list_for_each_entry(rdev, ®ulator_list, list) { - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - ret = suspend_prepare(rdev, state); -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - - if (ret < 0) { - rdev_err(rdev, "failed to prepare\n"); -@@ -3570,7 +3615,7 @@ int regulator_suspend_finish(void) - list_for_each_entry(rdev, ®ulator_list, list) { - struct regulator_ops *ops = rdev->desc->ops; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - if ((rdev->use_count > 0 || rdev->constraints->always_on) && - ops->enable) { - error = ops->enable(rdev); -@@ -3589,7 +3634,7 @@ int regulator_suspend_finish(void) - ret = error; - } - unlock: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - } - mutex_unlock(®ulator_list_mutex); - return ret; -@@ -3777,7 +3822,7 @@ static int __init regulator_init_complet - if (!ops->disable || (c && c->always_on)) - continue; - -- mutex_lock(&rdev->mutex); -+ regulator_lock(rdev); - - if (rdev->use_count) - goto unlock; -@@ -3809,7 +3854,7 @@ static int __init regulator_init_complet - } - - unlock: -- mutex_unlock(&rdev->mutex); -+ regulator_unlock(rdev); - } - - mutex_unlock(®ulator_list_mutex); ---- a/drivers/regulator/Kconfig -+++ b/drivers/regulator/Kconfig -@@ -492,6 +492,15 @@ config REGULATOR_TPS65217 - voltage regulators. It supports software based voltage control - for different voltage domains - -+config REGULATOR_TPS65218 -+ tristate "TI TPS65218 Power regulators" -+ depends on MFD_TPS65218 -+ help -+ This driver supports TPS65218 voltage regulator chips. TPS65218 -+ provides six step-down converters and one general-purpose LDO -+ voltage regulators. It supports software based voltage control -+ for different voltage domains -+ - config REGULATOR_TPS6524X - tristate "TI TPS6524X Power regulators" - depends on SPI -@@ -571,5 +580,19 @@ config REGULATOR_WM8994 - This driver provides support for the voltage regulators on the - WM8994 CODEC. - -+config REGULATOR_TIAVSCLASS0 -+ tristate "Adaptive Voltage Scaling class 0 support for TI SoCs" -+ depends on ARCH_OMAP2PLUS -+ help -+ AVS is a power management technique which finely controls the -+ operating voltage of a device in order to optimize (i.e. reduce) -+ its power consumption. -+ At a given operating point, the voltage is adapted depending on -+ static factors (chip manufacturing process) and this adapted -+ voltage is made available in an efuse offset. -+ AVS is also called SmartReflex on OMAP devices. -+ -+ Say Y here to enable Adaptive Voltage Scaling class 0 support. -+ - endif - ---- a/drivers/regulator/Makefile -+++ b/drivers/regulator/Makefile -@@ -63,6 +63,7 @@ obj-$(CONFIG_REGULATOR_TPS65023) += tps6 - obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o - obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o - obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o -+obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o - obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o - obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o - obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o -@@ -76,6 +77,7 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x - obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o - obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o - obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o -+obj-$(CONFIG_REGULATOR_TIAVSCLASS0) += ti-avs-class0-regulator.o - - - ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG ---- /dev/null -+++ b/drivers/regulator/ti-avs-class0-regulator.c -@@ -0,0 +1,349 @@ -+/* -+ * Texas Instrument SmartReflex AVS Class 0 driver -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * Nishanth Menon -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#define pr_fmt(fmt) KBUILD_MODNAME ": %s(): " fmt, __func__ -+ -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/of_device.h> -+#include <linux/of.h> -+#include <linux/platform_device.h> -+#include <linux/regulator/consumer.h> -+#include <linux/regulator/driver.h> -+#include <linux/regulator/machine.h> -+#include <linux/regulator/of_regulator.h> -+#include <linux/slab.h> -+#include <linux/string.h> -+ -+/** -+ * struct tiavs_class0_data - class data for the regulator instance -+ * @desc: regulator descriptor -+ * @reg: regulator that will actually set the voltage -+ * @volt_set_table: voltage to set data table -+ * @current_idx: current index -+ * @voltage_tolerance: % tolerance for voltage(optional) -+ */ -+struct tiavs_class0_data { -+ struct regulator_desc desc; -+ struct regulator *reg; -+ unsigned int *volt_set_table; -+ int current_idx; -+ u32 voltage_tolerance; -+}; -+ -+/** -+ * tiavs_class0_set_voltage_sel() - set voltage -+ * @rdev: regulator device -+ * @sel: set voltage corresponding to selector -+ * -+ * This searches for a best case match and uses the child regulator to set -+ * appropriate voltage -+ * -+ * Return: -ENODEV if no proper regulator data/-EINVAL if no match,bad efuse -+ * else returns regulator set result -+ */ -+static int tiavs_class0_set_voltage_sel(struct regulator_dev *rdev, -+ unsigned sel) -+{ -+ struct tiavs_class0_data *data = rdev_get_drvdata(rdev); -+ const struct regulator_desc *desc = rdev->desc; -+ struct regulator *reg; -+ int vset, ret, tol; -+ -+ if (!data) { -+ pr_err("No regulator drvdata\n"); -+ return -ENODEV; -+ } -+ -+ reg = data->reg; -+ if (!reg) { -+ pr_err("No regulator\n"); -+ return -ENODEV; -+ } -+ -+ if (!desc->n_voltages || !data->volt_set_table) { -+ pr_err("No valid voltage table entries?\n"); -+ return -EINVAL; -+ } -+ -+ if (sel >= desc->n_voltages) { -+ pr_err("sel(%d) > max voltage table entries(%d)\n", sel, -+ desc->n_voltages); -+ return -EINVAL; -+ } -+ -+ vset = data->volt_set_table[sel]; -+ -+ /* Adjust for % tolerance needed */ -+ tol = DIV_ROUND_UP(vset * data->voltage_tolerance, 100); -+ ret = regulator_set_voltage_tol(reg, vset, tol); -+ if (!ret) -+ data->current_idx = sel; -+ -+ return ret; -+} -+ -+/** -+ * tiavs_class0_get_voltage_sel() - Get voltage selector -+ * @rdev: regulator device -+ * -+ * Return: -ENODEV if no proper regulator data/-EINVAL if no data, -+ * else returns current index. -+ */ -+static int tiavs_class0_get_voltage_sel(struct regulator_dev *rdev) -+{ -+ const struct regulator_desc *desc = rdev->desc; -+ struct tiavs_class0_data *data = rdev_get_drvdata(rdev); -+ -+ if (!data) { -+ pr_err("No regulator drvdata\n"); -+ return -ENODEV; -+ } -+ -+ if (!desc->n_voltages || !data->volt_set_table) { -+ pr_err("No valid voltage table entries?\n"); -+ return -EINVAL; -+ } -+ -+ if (data->current_idx > desc->n_voltages) { -+ pr_err("Corrupted data structure?? idx(%d) > n_voltages(%d)\n", -+ data->current_idx, desc->n_voltages); -+ return -EINVAL; -+ } -+ -+ return data->current_idx; -+} -+ -+static struct regulator_ops tiavs_class0_ops = { -+ .list_voltage = regulator_list_voltage_table, -+ -+ .set_voltage_sel = tiavs_class0_set_voltage_sel, -+ .get_voltage_sel = tiavs_class0_get_voltage_sel, -+ -+}; -+ -+static const struct of_device_id tiavs_class0_of_match[] = { -+ {.compatible = "ti,avsclass0",}, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, tiavs_class0_of_match); -+ -+/** -+ * tiavs_class0_probe() - AVS class 0 probe -+ * @pdev: matching platform device -+ * -+ * We support only device tree provided data here. Once we find a regulator, -+ * efuse offsets, we pick up the efuse register voltages store them per -+ * instance. -+ * -+ * Return: if everything goes through, we return 0, else corresponding error -+ * value is returned. -+ */ -+static int tiavs_class0_probe(struct platform_device *pdev) -+{ -+ const struct of_device_id *match; -+ struct device_node *np = pdev->dev.of_node; -+ struct property *prop; -+ struct resource *res; -+ struct regulator *reg; -+ struct regulator_init_data *initdata = NULL; -+ struct regulator_config config = { }; -+ struct regulation_constraints *c; -+ struct regulator_dev *rdev; -+ struct regulator_desc *desc; -+ struct tiavs_class0_data *data; -+ void __iomem *base; -+ const __be32 *val; -+ unsigned int *volt_table; -+ bool efuse_is_uV = false; -+ int proplen, i, ret; -+ int reg_v, min_uV = INT_MAX, max_uV = 0; -+ int best_val = INT_MAX, choice = -EINVAL; -+ -+ match = of_match_device(tiavs_class0_of_match, &pdev->dev); -+ if (match) -+ initdata = of_get_regulator_init_data(&pdev->dev, np); -+ if (!initdata) { -+ dev_err(&pdev->dev, "No proper OF?\n"); -+ return -ENODEV; -+ } -+ -+ /* look for avs-supply */ -+ reg = devm_regulator_get(&pdev->dev, "avs"); -+ if (IS_ERR(reg)) { -+ ret = PTR_ERR(reg); -+ reg = NULL; -+ dev_err(&pdev->dev, "avs_class0 regulator not available(%d)\n", -+ ret); -+ return ret; -+ } -+ -+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -+ if (!data) { -+ dev_err(&pdev->dev, "No memory to alloc data!\n"); -+ return -ENOMEM; -+ } -+ data->reg = reg; -+ -+ desc = &data->desc; -+ desc->name = dev_name(&pdev->dev); -+ desc->owner = THIS_MODULE; -+ desc->type = REGULATOR_VOLTAGE; -+ desc->ops = &tiavs_class0_ops; -+ -+ /* pick up optional properties */ -+ of_property_read_u32(np, "voltage-tolerance", &data->voltage_tolerance); -+ efuse_is_uV = of_property_read_bool(np, -+ "ti,avsclass0-microvolt-values"); -+ -+ /* pick up Efuse based voltages */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "Unable to get IO resource\n"); -+ return -ENODEV; -+ } -+ -+ base = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); -+ if (!base) { -+ dev_err(&pdev->dev, "Unable to map Efuse registers\n"); -+ return -ENOMEM; -+ } -+ -+ /* Fetch efuse-settings. */ -+ prop = of_find_property(np, "efuse-settings", NULL); -+ if (!prop) { -+ dev_err(&pdev->dev, "No 'efuse-settings' property found\n"); -+ return -EINVAL; -+ } -+ -+ proplen = prop->length / sizeof(int); -+ -+ data->volt_set_table = -+ devm_kzalloc(&pdev->dev, sizeof(unsigned int) * (proplen / 2), -+ GFP_KERNEL); -+ if (!data->volt_set_table) { -+ dev_err(&pdev->dev, "Unable to Allocate voltage set table\n"); -+ return -ENOMEM; -+ } -+ -+ volt_table = -+ devm_kzalloc(&pdev->dev, sizeof(unsigned int) * (proplen / 2), -+ GFP_KERNEL); -+ if (!volt_table) { -+ dev_err(&pdev->dev, -+ "Unable to Allocate voltage lookup table\n"); -+ return -ENOMEM; -+ } -+ -+ val = prop->value; -+ for (i = 0; i < proplen / 2; i++) { -+ u32 efuse_offset; -+ -+ volt_table[i] = be32_to_cpup(val++); -+ efuse_offset = be32_to_cpup(val++); -+ -+ data->volt_set_table[i] = efuse_is_uV ? -+ readl(base + efuse_offset) : -+ readw(base + efuse_offset) * 1000; -+ -+ /* Find min/max for the voltage sets */ -+ if (min_uV > volt_table[i]) -+ min_uV = volt_table[i]; -+ if (max_uV < volt_table[i]) -+ max_uV = volt_table[i]; -+ -+ dev_dbg(&pdev->dev, "[%d] efuse=0x%08x volt_table=%d vset=%d\n", -+ i, efuse_offset, volt_table[i], -+ data->volt_set_table[i]); -+ } -+ desc->n_voltages = i; -+ desc->volt_table = volt_table; -+ -+ /* Search for a best match voltage */ -+ reg_v = regulator_get_voltage(reg); -+ if (reg_v < 0) { -+ dev_err(&pdev->dev, "Regulator error %d for get_voltage!\n", -+ reg_v); -+ return reg_v; -+ } -+ -+ for (i = 0; i < desc->n_voltages; i++) -+ if (data->volt_set_table[i] < best_val && -+ data->volt_set_table[i] >= reg_v) { -+ best_val = data->volt_set_table[i]; -+ choice = i; -+ } -+ -+ if (choice == -EINVAL) { -+ dev_err(&pdev->dev, "No match regulator V=%d\n", reg_v); -+ return -EINVAL; -+ } -+ data->current_idx = choice; -+ -+ /* -+ * Constrain board-specific capabilities according to what -+ * this driver can actually do. -+ */ -+ c = &initdata->constraints; -+ if (desc->n_voltages > 1) -+ c->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; -+ c->always_on = true; -+ -+ c->min_uV = min_uV; -+ c->max_uV = max_uV; -+ -+ config.dev = &pdev->dev; -+ config.init_data = initdata; -+ config.driver_data = data; -+ config.of_node = pdev->dev.of_node; -+ -+ rdev = regulator_register(desc, &config); -+ if (IS_ERR(rdev)) { -+ dev_err(&pdev->dev, "can't register %s, %ld\n", -+ desc->name, PTR_ERR(rdev)); -+ return PTR_ERR(rdev); -+ } -+ platform_set_drvdata(pdev, rdev); -+ -+ return 0; -+} -+ -+static int tiavs_class0_remove(struct platform_device *pdev) -+{ -+ struct regulator_dev *rdev = platform_get_drvdata(pdev); -+ -+ regulator_unregister(rdev); -+ return 0; -+} -+ -+MODULE_ALIAS("platform:tiavs_class0"); -+ -+static struct platform_driver tiavs_class0_driver = { -+ .probe = tiavs_class0_probe, -+ .remove = tiavs_class0_remove, -+ .driver = { -+ .name = "tiavs_class0", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(tiavs_class0_of_match), -+ }, -+}; -+module_platform_driver(tiavs_class0_driver); -+ -+MODULE_DESCRIPTION("TI SmartReflex AVS class 0 regulator driver"); -+MODULE_AUTHOR("Texas Instruments Inc."); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/regulator/tps65218-regulator.c -@@ -0,0 +1,392 @@ -+/* -+ * tps65218-regulator.c -+ * -+ * Regulator driver for TPS65218 PMIC -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether expressed or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License version 2 for more details. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/device.h> -+#include <linux/init.h> -+#include <linux/err.h> -+#include <linux/platform_device.h> -+#include <linux/of_device.h> -+#include <linux/regulator/of_regulator.h> -+#include <linux/regulator/driver.h> -+#include <linux/regulator/machine.h> -+#include <linux/mfd/tps65218.h> -+ -+static unsigned int tps65218_ramp_delay = 4000; -+ -+#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t) \ -+ { \ -+ .name = _name, \ -+ .id = _id, \ -+ .ops = &_ops, \ -+ .n_voltages = _n, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .owner = THIS_MODULE, \ -+ .vsel_reg = _vr, \ -+ .vsel_mask = _vm, \ -+ .enable_reg = _er, \ -+ .enable_mask = _em, \ -+ .volt_table = _t, \ -+ } \ -+ -+#define TPS65218_INFO(_id, _nm, _min, _max, _f1, _f2) \ -+ { \ -+ .id = _id, \ -+ .name = _nm, \ -+ .min_uV = _min, \ -+ .max_uV = _max, \ -+ .vsel_to_uv = _f1, \ -+ .uv_to_vsel = _f2, \ -+ } -+ -+static int tps65218_ldo1_dcdc3_vsel_to_uv(unsigned int vsel) -+{ -+ int uV = 0; -+ -+ if (vsel <= 26) -+ uV = vsel * 25000 + 900000; -+ else -+ uV = (vsel - 26) * 50000 + 1550000; -+ -+ return uV; -+} -+ -+static int tps65218_ldo1_dcdc3_uv_to_vsel(int uV, unsigned int *vsel) -+{ -+ if (uV <= 15500000) -+ *vsel = DIV_ROUND_UP(uV - 900000, 25000); -+ else -+ *vsel = 26 + DIV_ROUND_UP(uV - 1550000, 50000); -+ -+ return 0; -+} -+ -+static int tps65218_dcdc1_2_vsel_to_uv(unsigned int vsel) -+{ -+ int uV = 0; -+ -+ if (vsel <= 50) -+ uV = vsel * 10000 + 850000; -+ else -+ uV = (vsel - 50) * 25000 + 1350000; -+ -+ return uV; -+} -+ -+static int tps65218_dcdc1_2_uv_to_vsel(int uV, unsigned int *vsel) -+{ -+ if (uV <= 13500000) -+ *vsel = DIV_ROUND_UP(uV - 850000, 10000); -+ else -+ *vsel = 50 + DIV_ROUND_UP(uV - 1350000, 25000); -+ -+ return 0; -+} -+ -+static int tps65218_dcd4_vsel_to_uv(unsigned int vsel) -+{ -+ int uV = 0; -+ -+ if (vsel <= 15) -+ uV = vsel * 25000 + 1175000; -+ else -+ uV = (vsel - 15) * 50000 + 1550000; -+ -+ return uV; -+} -+ -+static int tps65218_dcdc4_uv_to_vsel(int uV, unsigned int *vsel) -+{ -+ if (uV <= 15500000) -+ *vsel = DIV_ROUND_UP(uV - 1175000, 25000); -+ else -+ *vsel = 15 + DIV_ROUND_UP(uV - 1550000, 50000); -+ -+ return 0; -+} -+ -+static struct tps_info tps65218_pmic_regs[] = { -+ TPS65218_INFO(0, "DCDC1", 850000, 1675000, tps65218_dcdc1_2_vsel_to_uv, -+ tps65218_dcdc1_2_uv_to_vsel), -+ TPS65218_INFO(1, "DCDC2", 850000, 1675000, tps65218_dcdc1_2_vsel_to_uv, -+ tps65218_dcdc1_2_uv_to_vsel), -+ TPS65218_INFO(2, "DCDC3", 900000, 3400000, -+ tps65218_ldo1_dcdc3_vsel_to_uv, -+ tps65218_ldo1_dcdc3_uv_to_vsel), -+ TPS65218_INFO(3, "DCDC4", 1175000, 3400000, tps65218_dcd4_vsel_to_uv, -+ tps65218_dcdc4_uv_to_vsel), -+ TPS65218_INFO(4, "DCDC5", 1000000, 1000000, NULL, NULL), -+ TPS65218_INFO(5, "DCDC6", 1800000, 1800000, NULL, NULL), -+ TPS65218_INFO(6, "LDO1", 900000, 3400000, -+ tps65218_ldo1_dcdc3_vsel_to_uv, -+ tps65218_ldo1_dcdc3_uv_to_vsel), -+}; -+ -+#define TPS65218_OF_MATCH(comp, label) \ -+ { \ -+ .compatible = comp, \ -+ .data = &label, \ -+ } -+ -+static const struct of_device_id tps65218_of_match[] = { -+ TPS65218_OF_MATCH("ti,tps65218-dcdc1", tps65218_pmic_regs[0]), -+ TPS65218_OF_MATCH("ti,tps65218-dcdc2", tps65218_pmic_regs[1]), -+ TPS65218_OF_MATCH("ti,tps65218-dcdc3", tps65218_pmic_regs[2]), -+ TPS65218_OF_MATCH("ti,tps65218-dcdc4", tps65218_pmic_regs[3]), -+ TPS65218_OF_MATCH("ti,tps65218-dcdc5", tps65218_pmic_regs[4]), -+ TPS65218_OF_MATCH("ti,tps65218-dcdc6", tps65218_pmic_regs[5]), -+ TPS65218_OF_MATCH("ti,tps65218-ldo1", tps65218_pmic_regs[6]), -+}; -+MODULE_DEVICE_TABLE(of, tps65218_of_match); -+ -+static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev, -+ unsigned selector) -+{ -+ int ret; -+ struct tps65218 *tps = rdev_get_drvdata(dev); -+ unsigned int rid = rdev_get_id(dev); -+ -+ /* Set the voltage based on vsel value and write protect level is 2 */ -+ ret = tps65218_set_bits(tps, dev->desc->vsel_reg, dev->desc->vsel_mask, -+ selector, TPS65218_PROTECT_L1); -+ -+ /* Set GO bit for DCDC1/2 to initiate voltage transistion */ -+ switch (rid) { -+ case TPS65218_DCDC_1: -+ case TPS65218_DCDC_2: -+ ret = tps65218_set_bits(tps, TPS65218_REG_CONTRL_SLEW_RATE, -+ TPS65218_SLEW_RATE_GO, -+ TPS65218_SLEW_RATE_GO, -+ TPS65218_PROTECT_L1); -+ break; -+ } -+ -+ return ret; -+} -+ -+static int tps65218_pmic_map_voltage(struct regulator_dev *dev, -+ int min_uV, int max_uV) -+{ -+ struct tps65218 *tps = rdev_get_drvdata(dev); -+ unsigned int sel, rid = rdev_get_id(dev); -+ int ret; -+ -+ if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) -+ return -EINVAL; -+ -+ if (min_uV < tps->info[rid]->min_uV) -+ min_uV = tps->info[rid]->min_uV; -+ -+ if (max_uV < tps->info[rid]->min_uV || min_uV > tps->info[rid]->max_uV) -+ return -EINVAL; -+ -+ ret = tps->info[rid]->uv_to_vsel(min_uV, &sel); -+ if (ret) -+ return ret; -+ -+ return sel; -+} -+ -+static int tps65218_pmic_list_voltage(struct regulator_dev *dev, -+ unsigned selector) -+{ -+ struct tps65218 *tps = rdev_get_drvdata(dev); -+ unsigned int rid = rdev_get_id(dev); -+ -+ if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) -+ return -EINVAL; -+ -+ if (selector >= dev->desc->n_voltages) -+ return -EINVAL; -+ -+ return tps->info[rid]->vsel_to_uv(selector); -+} -+ -+static int tps65218_pmic_enable(struct regulator_dev *dev) -+{ -+ struct tps65218 *tps = rdev_get_drvdata(dev); -+ unsigned int rid = rdev_get_id(dev); -+ -+ if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) -+ return -EINVAL; -+ -+ /* Enable the regulator and password protection is level 1 */ -+ return tps65218_set_bits(tps, dev->desc->enable_reg, -+ dev->desc->enable_mask, dev->desc->enable_mask, -+ TPS65218_PROTECT_L1); -+} -+ -+static int tps65218_pmic_disable(struct regulator_dev *dev) -+{ -+ struct tps65218 *tps = rdev_get_drvdata(dev); -+ unsigned int rid = rdev_get_id(dev); -+ -+ if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) -+ return -EINVAL; -+ -+ /* Disable the regulator and password protection is level 1 */ -+ return tps65218_clear_bits(tps, dev->desc->enable_reg, -+ dev->desc->enable_mask, TPS65218_PROTECT_L1); -+} -+ -+static int tps65218_set_voltage_time_sel(struct regulator_dev *rdev, -+ unsigned int old_selector, unsigned int new_selector) -+{ -+ int old_uv, new_uv; -+ -+ old_uv = tps65218_pmic_list_voltage(rdev, old_selector); -+ if (old_uv < 0) -+ return old_uv; -+ -+ new_uv = tps65218_pmic_list_voltage(rdev, new_selector); -+ if (new_uv < 0) -+ return new_uv; -+ -+ return DIV_ROUND_UP(abs(old_uv - new_uv), tps65218_ramp_delay); -+} -+ -+/* Operations permitted on DCDC1, DCDC2 */ -+static struct regulator_ops tps65218_dcdc12_ops = { -+ .is_enabled = regulator_is_enabled_regmap, -+ .enable = tps65218_pmic_enable, -+ .disable = tps65218_pmic_disable, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .set_voltage_sel = tps65218_pmic_set_voltage_sel, -+ .list_voltage = tps65218_pmic_list_voltage, -+ .map_voltage = tps65218_pmic_map_voltage, -+ .set_voltage_time_sel = tps65218_set_voltage_time_sel, -+}; -+ -+/* Operations permitted on DCDC3, DCDC4 and LDO1 */ -+static struct regulator_ops tps65218_ldo1_dcdc34_ops = { -+ .is_enabled = regulator_is_enabled_regmap, -+ .enable = tps65218_pmic_enable, -+ .disable = tps65218_pmic_disable, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .set_voltage_sel = tps65218_pmic_set_voltage_sel, -+ .list_voltage = tps65218_pmic_list_voltage, -+ .map_voltage = tps65218_pmic_map_voltage, -+}; -+ -+/* Operations permitted on DCDC5, DCDC6 */ -+static struct regulator_ops tps65218_dcdc56_pmic_ops = { -+ .is_enabled = regulator_is_enabled_regmap, -+ .enable = tps65218_pmic_enable, -+ .disable = tps65218_pmic_disable, -+}; -+ -+static const struct regulator_desc regulators[] = { -+ TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64, -+ TPS65218_REG_CONTROL_DCDC1, -+ TPS65218_CONTROL_DCDC1_MASK, -+ TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL), -+ TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, -+ TPS65218_REG_CONTROL_DCDC2, -+ TPS65218_CONTROL_DCDC2_MASK, -+ TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL), -+ TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, -+ 64, TPS65218_REG_CONTROL_DCDC3, -+ TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, -+ TPS65218_ENABLE1_DC3_EN, NULL), -+ TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, -+ 53, TPS65218_REG_CONTROL_DCDC4, -+ TPS65218_CONTROL_DCDC4_MASK, -+ TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL), -+ TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, -+ 1, -1, -1, TPS65218_REG_ENABLE1, -+ TPS65218_ENABLE1_DC5_EN, NULL), -+ TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, -+ 1, -1, -1, TPS65218_REG_ENABLE1, -+ TPS65218_ENABLE1_DC6_EN, NULL), -+ TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, -+ TPS65218_REG_CONTROL_DCDC4, -+ TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, -+ TPS65218_ENABLE2_LDO1_EN, NULL), -+}; -+ -+static int tps65218_regulator_probe(struct platform_device *pdev) -+{ -+ struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent); -+ struct regulator_init_data *init_data; -+ const struct tps_info *template; -+ struct regulator_dev *rdev; -+ const struct of_device_id *match; -+ struct regulator_config config = { }; -+ int id; -+ -+ match = of_match_device(tps65218_of_match, &pdev->dev); -+ if (match) { -+ template = match->data; -+ id = template->id; -+ init_data = of_get_regulator_init_data(&pdev->dev, -+ pdev->dev.of_node); -+ } else { -+ return -ENODEV; -+ } -+ -+ platform_set_drvdata(pdev, tps); -+ -+ tps->info[id] = &tps65218_pmic_regs[id]; -+ config.dev = &pdev->dev; -+ config.init_data = init_data; -+ config.driver_data = tps; -+ config.regmap = tps->regmap; -+ -+ rdev = regulator_register(®ulators[id], &config); -+ if (IS_ERR(rdev)) { -+ dev_err(tps->dev, "failed to register %s regulator\n", -+ pdev->name); -+ return PTR_ERR(rdev); -+ } -+ -+ /* Save regulator */ -+ tps->rdev[id] = rdev; -+ -+ return 0; -+} -+ -+static int tps65218_regulator_remove(struct platform_device *pdev) -+{ -+ struct tps65218 *tps = platform_get_drvdata(pdev); -+ const struct of_device_id *match; -+ const struct tps_info *template; -+ -+ match = of_match_device(tps65218_of_match, &pdev->dev); -+ template = match->data; -+ regulator_unregister(tps->rdev[template->id]); -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+static struct platform_driver tps65218_regulator_driver = { -+ .driver = { -+ .name = "tps65218-pmic", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(tps65218_of_match), -+ }, -+ .probe = tps65218_regulator_probe, -+ .remove = tps65218_regulator_remove, -+}; -+ -+module_platform_driver(tps65218_regulator_driver); -+ -+MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); -+MODULE_DESCRIPTION("TPS65218 voltage regulator driver"); -+MODULE_ALIAS("platform:tps65218-pmic"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/reset/core.c -+++ b/drivers/reset/core.c -@@ -127,6 +127,38 @@ int reset_control_deassert(struct reset_ - EXPORT_SYMBOL_GPL(reset_control_deassert); - - /** -+ * reset_control_is_reset - check reset status -+ * @rstc: reset controller -+ * -+ * Returns a boolean or negative error code -+ * -+ */ -+int reset_control_is_reset(struct reset_control *rstc) -+{ -+ if (rstc->rcdev->ops->is_reset) -+ return rstc->rcdev->ops->is_reset(rstc->rcdev, rstc->id); -+ -+ return -ENOSYS; -+} -+EXPORT_SYMBOL_GPL(reset_control_is_reset); -+ -+/** -+ * reset_control_clear_reset - clear the reset -+ * @rstc: reset controller -+ * -+ * Returns zero on success or negative error code -+ * -+ */ -+int reset_control_clear_reset(struct reset_control *rstc) -+{ -+ if (rstc->rcdev->ops->clear_reset) -+ return rstc->rcdev->ops->clear_reset(rstc->rcdev, rstc->id); -+ -+ return -ENOSYS; -+} -+EXPORT_SYMBOL_GPL(reset_control_clear_reset); -+ -+/** - * reset_control_get - Lookup and obtain a reference to a reset controller. - * @dev: device to be reset by the controller - * @id: reset line name ---- a/drivers/reset/Kconfig -+++ b/drivers/reset/Kconfig -@@ -11,3 +11,17 @@ menuconfig RESET_CONTROLLER - via GPIOs or SoC-internal reset controller modules. - - If unsure, say no. -+ -+if RESET_CONTROLLER -+ -+config RESET_TI -+ bool "TI reset controller" -+ help -+ Reset controller support for TI SoC's -+ -+ Reset controller found in TI's AM series of SoC's like -+ AM335x and AM43x and OMAP SoC's like OMAP5 and DRA7 -+ -+ If unsure, say no. -+ -+endif ---- a/drivers/reset/Makefile -+++ b/drivers/reset/Makefile -@@ -1 +1,2 @@ - obj-$(CONFIG_RESET_CONTROLLER) += core.o -+obj-$(CONFIG_RESET_TI) += ti_reset.o ---- /dev/null -+++ b/drivers/reset/ti_reset.c -@@ -0,0 +1,172 @@ -+/* -+ * PRCM reset driver for TI SoC's -+ * -+ * 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. -+ */ -+#include <linux/device.h> -+#include <linux/err.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/of_device.h> -+#include <linux/reset.h> -+#include <linux/reset-controller.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+ -+#define DRIVER_NAME "ti_reset" -+ -+struct ti_reset_reg_data { -+ u32 rstctrl_offs; -+ u32 rstst_offs; -+ u8 rstctrl_bit; -+ u8 rstst_bit; -+}; -+ -+struct ti_reset_data { -+ struct ti_reset_reg_data *reg_data; -+ u8 nr_resets; -+}; -+ -+static void __iomem *reg_base; -+static const struct ti_reset_data *reset_data; -+ -+static struct ti_reset_reg_data am335x_reset_reg_data[] = { -+ { -+ .rstctrl_offs = 0x1104, -+ .rstst_offs = 0x1114, -+ .rstctrl_bit = 0, -+ .rstst_bit = 0, -+ }, -+}; -+ -+static struct ti_reset_data am335x_reset_data = { -+ .reg_data = am335x_reset_reg_data, -+ .nr_resets = ARRAY_SIZE(am335x_reset_reg_data), -+}; -+ -+static struct ti_reset_reg_data am43x_reset_reg_data[] = { -+ { -+ .rstctrl_offs = 0x410, -+ .rstst_offs = 0x414, -+ .rstctrl_bit = 0, -+ .rstst_bit = 0, -+ }, -+}; -+ -+static struct ti_reset_data am43x_reset_data = { -+ .reg_data = am43x_reset_reg_data, -+ .nr_resets = ARRAY_SIZE(am43x_reset_reg_data), -+}; -+ -+static struct ti_reset_reg_data dra7_reset_reg_data[] = { -+ { -+ .rstctrl_offs = 0x1310, -+ .rstst_offs = 0x1314, -+ .rstctrl_bit = 0, -+ .rstst_bit = 0, -+ }, -+}; -+ -+static struct ti_reset_data dra7_reset_data = { -+ .reg_data = dra7_reset_reg_data, -+ .nr_resets = ARRAY_SIZE(dra7_reset_reg_data), -+}; -+ -+static int ti_reset_clear_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ void __iomem *reg = reset_data->reg_data[id].rstst_offs + reg_base; -+ u8 bit = reset_data->reg_data[id].rstst_bit; -+ u32 val = readl(reg); -+ -+ val &= ~(1 << bit); -+ val |= 1 << bit; -+ writel(val, reg); -+ return 0; -+} -+ -+static int ti_reset_is_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ void __iomem *reg = reset_data->reg_data[id].rstst_offs + reg_base; -+ u8 bit = reset_data->reg_data[id].rstst_bit; -+ u32 val = readl(reg); -+ -+ val &= (1 << bit); -+ return !!val; -+} -+ -+static int ti_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ void __iomem *reg = reset_data->reg_data[id].rstctrl_offs + -+ reg_base; -+ u8 bit = reset_data->reg_data[id].rstctrl_bit; -+ u32 val = readl(reg); -+ -+ val &= ~(1 << bit); -+ writel(val, reg); -+ return 0; -+} -+ -+static struct reset_control_ops ti_reset_ops = { -+ .deassert = ti_reset_deassert, -+ .is_reset = ti_reset_is_reset, -+ .clear_reset = ti_reset_clear_reset, -+}; -+ -+static struct reset_controller_dev ti_reset_controller = { -+ .ops = &ti_reset_ops, -+}; -+ -+static const struct of_device_id ti_reset_of_match[] = { -+ { .compatible = "ti,am3352-prcm", .data = &am335x_reset_data,}, -+ { .compatible = "ti,am4372-prcm", .data = &am43x_reset_data,}, -+ { .compatible = "ti,dra7-prcm", .data = &dra7_reset_data,}, -+ {}, -+}; -+ -+static int ti_reset_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ const struct of_device_id *id; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ reg_base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(reg_base)) -+ return PTR_ERR(reg_base); -+ -+ ti_reset_controller.of_node = pdev->dev.of_node; -+ id = of_match_device(ti_reset_of_match, &pdev->dev); -+ reset_data = id->data; -+ ti_reset_controller.nr_resets = reset_data->nr_resets; -+ -+ reset_controller_register(&ti_reset_controller); -+ -+ return 0; -+} -+ -+static int ti_reset_remove(struct platform_device *pdev) -+{ -+ reset_controller_unregister(&ti_reset_controller); -+ -+ return 0; -+} -+ -+static struct platform_driver ti_reset_driver = { -+ .probe = ti_reset_probe, -+ .remove = ti_reset_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(ti_reset_of_match), -+ }, -+}; -+module_platform_driver(ti_reset_driver); -+ -+MODULE_DESCRIPTION("PRCM reset driver for TI SoC's"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRIVER_NAME); ---- a/drivers/rtc/rtc-omap.c -+++ b/drivers/rtc/rtc-omap.c -@@ -393,6 +393,10 @@ static int __init omap_rtc_probe(struct - */ - rtc_write(0, OMAP_RTC_INTERRUPTS_REG); - -+ /* Selecting CLK cource for RTC */ -+ rtc_writel((1 << 3) | (1 << 6), OMAP_RTC_OSC_REG); -+ rtc_writel(0x3, OMAP_RTC_IRQWAKEEN); -+ - /* clear old status */ - reg = rtc_read(OMAP_RTC_STATUS_REG); - if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) { ---- a/drivers/spi/spi-ti-qspi.c -+++ b/drivers/spi/spi-ti-qspi.c -@@ -41,14 +41,13 @@ struct ti_qspi_regs { - struct ti_qspi { - struct completion transfer_complete; - -- /* IRQ synchronization */ -- spinlock_t lock; -- - /* list synchronization */ - struct mutex list_lock; - - struct spi_master *master; - void __iomem *base; -+ void __iomem *ctrl_base; -+ void __iomem *mmap_base; - struct clk *fclk; - struct device *dev; - -@@ -57,7 +56,9 @@ struct ti_qspi { - u32 spi_max_frequency; - u32 cmd; - u32 dc; -- u32 stat; -+ -+ bool memory_mapped; -+ bool ctrl_mod; - }; - - #define QSPI_PID (0x0) -@@ -113,6 +114,23 @@ struct ti_qspi { - #define QSPI_CSPOL(n) (1 << (1 + n * 8)) - #define QSPI_CKPOL(n) (1 << (n * 8)) - -+#define MM_SWITCH 0x01 -+#define MEM_CS 0x100 -+#define MEM_CS_DIS 0xfffff0ff -+ -+#define QSPI_CMD_RD (0x3 << 0) -+#define QSPI_CMD_DUAL_RD (0x3b << 0) -+#define QSPI_CMD_QUAD_RD (0x6b << 0) -+#define QSPI_CMD_READ_FAST (0x0b << 0) -+#define QSPI_SETUP0_A_BYTES (0x3 << 8) -+#define QSPI_SETUP0_NO_BITS (0x0 << 10) -+#define QSPI_SETUP0_8_BITS (0x1 << 10) -+#define QSPI_SETUP0_RD_NORMAL (0x0 << 12) -+#define QSPI_SETUP0_RD_DUAL (0x1 << 12) -+#define QSPI_SETUP0_RD_QUAD (0x3 << 12) -+#define QSPI_CMD_WRITE (0x2 << 16) -+#define QSPI_NUM_DUMMY_BITS (0x0 << 24) -+ - #define QSPI_FRAME 4096 - - #define QSPI_AUTOSUSPEND_TIMEOUT 2000 -@@ -129,12 +147,37 @@ static inline void ti_qspi_write(struct - writel(val, qspi->base + reg); - } - -+void enable_qspi_memory_mapped(struct ti_qspi *qspi) -+{ -+ u32 val; -+ -+ ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG); -+ if (qspi->ctrl_mod) { -+ val = readl(qspi->ctrl_base); -+ val |= MEM_CS; -+ writel(val, qspi->ctrl_base); -+ } -+} -+ -+void disable_qspi_memory_mapped(struct ti_qspi *qspi) -+{ -+ u32 val; -+ -+ ti_qspi_write(qspi, ~MM_SWITCH, QSPI_SPI_SWITCH_REG); -+ if (qspi->ctrl_mod) { -+ val = readl(qspi->ctrl_base); -+ val |= MEM_CS_DIS; -+ writel(val, qspi->ctrl_base); -+ } -+} -+ - static int ti_qspi_setup(struct spi_device *spi) - { - struct ti_qspi *qspi = spi_master_get_devdata(spi->master); - struct ti_qspi_regs *ctx_reg = &qspi->ctx_reg; - int clk_div = 0, ret; -- u32 clk_ctrl_reg, clk_rate, clk_mask; -+ u32 clk_ctrl_reg, clk_rate, clk_mask, memval = 0; -+ qspi->dc = 0; - - if (spi->master->busy) { - dev_dbg(qspi->dev, "master busy doing other trasnfers\n"); -@@ -182,6 +225,37 @@ static int ti_qspi_setup(struct spi_devi - ti_qspi_write(qspi, clk_mask, QSPI_SPI_CLOCK_CNTRL_REG); - ctx_reg->clkctrl = clk_mask; - -+ if (spi->mode & SPI_CPHA) -+ qspi->dc |= QSPI_CKPHA(spi->chip_select); -+ if (spi->mode & SPI_CPOL) -+ qspi->dc |= QSPI_CKPOL(spi->chip_select); -+ if (spi->mode & SPI_CS_HIGH) -+ qspi->dc |= QSPI_CSPOL(spi->chip_select); -+ -+ ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); -+ -+ if (qspi->memory_mapped) { -+ switch (spi->mode) { -+ case SPI_TX_DUAL: -+ memval |= (QSPI_CMD_DUAL_RD | QSPI_SETUP0_A_BYTES | -+ QSPI_SETUP0_8_BITS | QSPI_SETUP0_RD_DUAL | -+ QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS); -+ break; -+ case SPI_TX_QUAD: -+ memval |= (QSPI_CMD_QUAD_RD | QSPI_SETUP0_A_BYTES | -+ QSPI_SETUP0_8_BITS | QSPI_SETUP0_RD_QUAD | -+ QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS); -+ break; -+ default: -+ memval |= (QSPI_CMD_RD | QSPI_SETUP0_A_BYTES | -+ QSPI_SETUP0_NO_BITS | QSPI_SETUP0_RD_NORMAL | -+ QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS); -+ break; -+ } -+ ti_qspi_write(qspi, memval, QSPI_SPI_SETUP0_REG); -+ spi->mode |= SPI_RX_MMAP; -+ } -+ - pm_runtime_mark_last_busy(qspi->dev); - ret = pm_runtime_put_autosuspend(qspi->dev); - if (ret < 0) { -@@ -344,16 +418,7 @@ static int ti_qspi_start_transfer_one(st - struct spi_transfer *t; - int status = 0, ret; - int frame_length; -- -- /* setup device control reg */ -- qspi->dc = 0; -- -- if (spi->mode & SPI_CPHA) -- qspi->dc |= QSPI_CKPHA(spi->chip_select); -- if (spi->mode & SPI_CPOL) -- qspi->dc |= QSPI_CKPOL(spi->chip_select); -- if (spi->mode & SPI_CS_HIGH) -- qspi->dc |= QSPI_CSPOL(spi->chip_select); -+ size_t from = 0; - - frame_length = (m->frame_length << 3) / spi->bits_per_word; - -@@ -366,11 +431,20 @@ static int ti_qspi_start_transfer_one(st - qspi->cmd |= QSPI_WC_CMD_INT_EN; - - ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); -- ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); - - mutex_lock(&qspi->list_lock); - - list_for_each_entry(t, &m->transfers, transfer_list) { -+ if (t->memory_map) { -+ if (t->tx_buf) { -+ from = t->len; -+ continue; -+ } -+ enable_qspi_memory_mapped(qspi); -+ memcpy(t->rx_buf, qspi->mmap_base + from, t->len); -+ disable_qspi_memory_mapped(qspi); -+ goto out; -+ } - qspi->cmd |= QSPI_WLEN(t->bits_per_word); - - ret = qspi_transfer_msg(qspi, t); -@@ -383,6 +457,7 @@ static int ti_qspi_start_transfer_one(st - m->actual_length += t->len; - } - -+out: - mutex_unlock(&qspi->list_lock); - - m->status = status; -@@ -397,13 +472,12 @@ static irqreturn_t ti_qspi_isr(int irq, - { - struct ti_qspi *qspi = dev_id; - u16 int_stat; -+ u32 stat; - - irqreturn_t ret = IRQ_HANDLED; - -- spin_lock(&qspi->lock); -- - int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); -- qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); -+ stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); - - if (!int_stat) { - dev_dbg(qspi->dev, "No IRQ triggered\n"); -@@ -411,35 +485,14 @@ static irqreturn_t ti_qspi_isr(int irq, - goto out; - } - -- ret = IRQ_WAKE_THREAD; -- -- ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); - ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, - QSPI_INTR_STATUS_ENABLED_CLEAR); -- -+ if (stat & WC) -+ complete(&qspi->transfer_complete); - out: -- spin_unlock(&qspi->lock); -- - return ret; - } - --static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id) --{ -- struct ti_qspi *qspi = dev_id; -- unsigned long flags; -- -- spin_lock_irqsave(&qspi->lock, flags); -- -- if (qspi->stat & WC) -- complete(&qspi->transfer_complete); -- -- spin_unlock_irqrestore(&qspi->lock, flags); -- -- ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); -- -- return IRQ_HANDLED; --} -- - static int ti_qspi_runtime_resume(struct device *dev) - { - struct ti_qspi *qspi; -@@ -463,7 +516,7 @@ static int ti_qspi_probe(struct platform - { - struct ti_qspi *qspi; - struct spi_master *master; -- struct resource *r; -+ struct resource *r, *res_ctrl, *res_mmap; - struct device_node *np = pdev->dev.of_node; - u32 max_freq; - int ret = 0, num_cs, irq; -@@ -472,7 +525,7 @@ static int ti_qspi_probe(struct platform - if (!master) - return -ENOMEM; - -- master->mode_bits = SPI_CPOL | SPI_CPHA; -+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_QUAD | SPI_RX_MMAP; - - master->bus_num = -1; - master->flags = SPI_MASTER_HALF_DUPLEX; -@@ -491,7 +544,16 @@ static int ti_qspi_probe(struct platform - qspi->master = master; - qspi->dev = &pdev->dev; - -- r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base"); -+ if (r == NULL) { -+ dev_err(&pdev->dev, "missing platform resources data\n"); -+ return -ENODEV; -+ } -+ -+ res_mmap = platform_get_resource_byname(pdev, -+ IORESOURCE_MEM, "qspi_mmap"); -+ res_ctrl = platform_get_resource_byname(pdev, -+ IORESOURCE_MEM, "qspi_ctrlmod"); - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { -@@ -499,7 +561,6 @@ static int ti_qspi_probe(struct platform - return irq; - } - -- spin_lock_init(&qspi->lock); - mutex_init(&qspi->list_lock); - - qspi->base = devm_ioremap_resource(&pdev->dev, r); -@@ -508,8 +569,24 @@ static int ti_qspi_probe(struct platform - goto free_master; - } - -- ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr, -- ti_qspi_threaded_isr, 0, -+ if (res_ctrl) { -+ qspi->ctrl_mod = true; -+ qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl); -+ if (IS_ERR(qspi->ctrl_base)) { -+ ret = PTR_ERR(qspi->ctrl_base); -+ goto free_master; -+ } -+ } -+ -+ if (res_mmap) { -+ qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap); -+ if (IS_ERR(qspi->mmap_base)) { -+ ret = PTR_ERR(qspi->mmap_base); -+ goto free_master; -+ } -+ } -+ -+ ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, - dev_name(&pdev->dev), qspi); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", -@@ -532,6 +609,9 @@ static int ti_qspi_probe(struct platform - if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) - qspi->spi_max_frequency = max_freq; - -+ if (of_property_read_bool(np, "mmap_read")) -+ qspi->memory_mapped = true; -+ - ret = spi_register_master(master); - if (ret) - goto free_master; -@@ -547,6 +627,7 @@ static int ti_qspi_remove(struct platfor - { - struct ti_qspi *qspi = platform_get_drvdata(pdev); - -+ ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); - spi_unregister_master(qspi->master); - - return 0; ---- a/drivers/tty/serial/omap-serial.c -+++ b/drivers/tty/serial/omap-serial.c -@@ -240,8 +240,8 @@ serial_omap_baud_is_mode16(struct uart_p - { - unsigned int n13 = port->uartclk / (13 * baud); - unsigned int n16 = port->uartclk / (16 * baud); -- int baudAbsDiff13 = baud - (port->uartclk / (13 * n13)); -- int baudAbsDiff16 = baud - (port->uartclk / (16 * n16)); -+ int baudAbsDiff13 = n13 ? (baud - (port->uartclk / (13 * n13))) : INT_MAX; -+ int baudAbsDiff16 = n16 ? (baud - (port->uartclk / (16 * n16))) : INT_MAX; - if(baudAbsDiff13 < 0) - baudAbsDiff13 = -baudAbsDiff13; - if(baudAbsDiff16 < 0) ---- a/drivers/usb/dwc3/core.c -+++ b/drivers/usb/dwc3/core.c -@@ -80,8 +80,6 @@ static void dwc3_core_soft_reset(struct - reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); - -- usb_phy_init(dwc->usb2_phy); -- usb_phy_init(dwc->usb3_phy); - mdelay(100); - - /* Clear USB3 PHY reset */ -@@ -343,6 +341,11 @@ static void dwc3_core_exit(struct dwc3 * - { - usb_phy_shutdown(dwc->usb2_phy); - usb_phy_shutdown(dwc->usb3_phy); -+ -+ if (dwc->usb2_generic_phy) -+ phy_power_off(dwc->usb2_generic_phy); -+ if (dwc->usb3_generic_phy) -+ phy_power_off(dwc->usb3_generic_phy); - } - - #define DWC3_ALIGN_MASK (16 - 1) -@@ -387,16 +390,102 @@ static int dwc3_probe(struct platform_de - if (node) { - dwc->maximum_speed = of_usb_get_maximum_speed(node); - -- dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); -- dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); -+ switch (dwc->maximum_speed) { -+ case USB_SPEED_SUPER: -+ if (of_property_read_bool(node, "usb-phy")) { -+ dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, -+ "usb-phy", 0); -+ if (IS_ERR(dwc->usb2_phy)) -+ return PTR_ERR(dwc->usb2_phy); -+ dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, -+ "usb-phy", 1); -+ if (IS_ERR(dwc->usb3_phy)) -+ return PTR_ERR(dwc->usb3_phy); -+ } else { -+ dwc->usb2_phy = NULL; -+ dwc->usb3_phy = NULL; -+ } -+ -+ if (of_property_read_bool(node, "phys")) { -+ dwc->usb2_generic_phy = devm_phy_get(dev, -+ "usb2-phy"); -+ if (IS_ERR(dwc->usb2_generic_phy)) { -+ dev_err(dev, "no usb2 phy configured"); -+ return PTR_ERR(dwc->usb2_generic_phy); -+ } -+ -+ dwc->usb3_generic_phy = devm_phy_get(dev, -+ "usb3-phy"); -+ if (IS_ERR(dwc->usb3_generic_phy)) { -+ dev_err(dev, "no usb3 phy configured"); -+ return PTR_ERR(dwc->usb3_generic_phy); -+ } -+ } else { -+ dwc->usb2_generic_phy = NULL; -+ dwc->usb3_generic_phy = NULL; -+ } -+ break; -+ case USB_SPEED_HIGH: -+ case USB_SPEED_FULL: -+ case USB_SPEED_LOW: -+ dwc->usb3_phy = NULL; -+ dwc->usb3_generic_phy = NULL; -+ if (of_property_read_bool(node, "usb-phy")) { -+ dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, -+ "usb-phy", 0); -+ if (IS_ERR(dwc->usb2_phy)) -+ return PTR_ERR(dwc->usb2_phy); -+ } else { -+ dwc->usb2_phy = NULL; -+ } -+ if (of_property_read_bool(node, "phys")) { -+ dwc->usb2_generic_phy = devm_phy_get(dev, -+ "usb2-phy"); -+ if (IS_ERR(dwc->usb2_generic_phy)) { -+ dev_err(dev, "no usb2 phy configured"); -+ return PTR_ERR(dwc->usb2_generic_phy); -+ } -+ } else { -+ dwc->usb2_generic_phy = NULL; -+ } -+ break; -+ } - - dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); - dwc->dr_mode = of_usb_get_dr_mode(node); - } else if (pdata) { - dwc->maximum_speed = pdata->maximum_speed; - -- dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); -- dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); -+ switch (dwc->maximum_speed) { -+ case USB_SPEED_SUPER: -+ if (pdata->has_phy) { -+ dwc->usb2_phy = devm_usb_get_phy(dev, -+ USB_PHY_TYPE_USB2); -+ if (IS_ERR(dwc->usb2_phy)) -+ return PTR_ERR(dwc->usb2_phy); -+ dwc->usb3_phy = devm_usb_get_phy(dev, -+ USB_PHY_TYPE_USB3); -+ if (IS_ERR(dwc->usb3_phy)) -+ return PTR_ERR(dwc->usb3_phy); -+ } else { -+ dwc->usb2_phy = NULL; -+ dwc->usb3_phy = NULL; -+ } -+ break; -+ case USB_SPEED_HIGH: -+ case USB_SPEED_FULL: -+ case USB_SPEED_LOW: -+ dwc->usb3_phy = NULL; -+ if (pdata->has_phy) { -+ dwc->usb2_phy = devm_usb_get_phy(dev, -+ USB_PHY_TYPE_USB2); -+ if (IS_ERR(dwc->usb2_phy)) -+ return PTR_ERR(dwc->usb2_phy); -+ } else { -+ dwc->usb2_phy = NULL; -+ } -+ break; -+ } - - dwc->needs_fifo_resize = pdata->tx_fifo_resize; - dwc->dr_mode = pdata->dr_mode; -@@ -409,36 +498,6 @@ static int dwc3_probe(struct platform_de - if (dwc->maximum_speed == USB_SPEED_UNKNOWN) - dwc->maximum_speed = USB_SPEED_SUPER; - -- if (IS_ERR(dwc->usb2_phy)) { -- ret = PTR_ERR(dwc->usb2_phy); -- -- /* -- * if -ENXIO is returned, it means PHY layer wasn't -- * enabled, so it makes no sense to return -EPROBE_DEFER -- * in that case, since no PHY driver will ever probe. -- */ -- if (ret == -ENXIO) -- return ret; -- -- dev_err(dev, "no usb2 phy configured\n"); -- return -EPROBE_DEFER; -- } -- -- if (IS_ERR(dwc->usb3_phy)) { -- ret = PTR_ERR(dwc->usb3_phy); -- -- /* -- * if -ENXIO is returned, it means PHY layer wasn't -- * enabled, so it makes no sense to return -EPROBE_DEFER -- * in that case, since no PHY driver will ever probe. -- */ -- if (ret == -ENXIO) -- return ret; -- -- dev_err(dev, "no usb3 phy configured\n"); -- return -EPROBE_DEFER; -- } -- - dwc->xhci_resources[0].start = res->start; - dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + - DWC3_XHCI_REGS_END; -@@ -455,9 +514,20 @@ static int dwc3_probe(struct platform_de - if (IS_ERR(regs)) - return PTR_ERR(regs); - -+ usb_phy_init(dwc->usb2_phy); -+ usb_phy_init(dwc->usb3_phy); - usb_phy_set_suspend(dwc->usb2_phy, 0); - usb_phy_set_suspend(dwc->usb3_phy, 0); - -+ if (dwc->usb2_generic_phy) { -+ phy_init(dwc->usb2_generic_phy); -+ phy_power_on(dwc->usb2_generic_phy); -+ } -+ if (dwc->usb3_generic_phy) { -+ phy_init(dwc->usb3_generic_phy); -+ phy_power_on(dwc->usb3_generic_phy); -+ } -+ - spin_lock_init(&dwc->lock); - platform_set_drvdata(pdev, dwc); - -@@ -584,7 +654,12 @@ static int dwc3_remove(struct platform_d - usb_phy_set_suspend(dwc->usb2_phy, 1); - usb_phy_set_suspend(dwc->usb3_phy, 1); - -- pm_runtime_put(&pdev->dev); -+ if (dwc->usb2_generic_phy) -+ phy_power_off(dwc->usb2_generic_phy); -+ if (dwc->usb3_generic_phy) -+ phy_power_off(dwc->usb3_generic_phy); -+ -+ pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - - dwc3_debugfs_exit(dwc); -@@ -681,6 +756,11 @@ static int dwc3_suspend(struct device *d - usb_phy_shutdown(dwc->usb3_phy); - usb_phy_shutdown(dwc->usb2_phy); - -+ if (dwc->usb2_generic_phy) -+ phy_exit(dwc->usb2_generic_phy); -+ if (dwc->usb3_generic_phy) -+ phy_exit(dwc->usb3_generic_phy); -+ - return 0; - } - -@@ -691,6 +771,12 @@ static int dwc3_resume(struct device *de - - usb_phy_init(dwc->usb3_phy); - usb_phy_init(dwc->usb2_phy); -+ -+ if (dwc->usb2_generic_phy) -+ phy_init(dwc->usb2_generic_phy); -+ if (dwc->usb3_generic_phy) -+ phy_init(dwc->usb3_generic_phy); -+ - msleep(100); - - spin_lock_irqsave(&dwc->lock, flags); ---- a/drivers/usb/dwc3/core.h -+++ b/drivers/usb/dwc3/core.h -@@ -31,6 +31,8 @@ - #include <linux/usb/gadget.h> - #include <linux/usb/otg.h> - -+#include <linux/phy/phy.h> -+ - /* Global constants */ - #define DWC3_EP0_BOUNCE_SIZE 512 - #define DWC3_ENDPOINTS_NUM 32 -@@ -613,6 +615,8 @@ struct dwc3_scratchpad_array { - * @dr_mode: requested mode of operation - * @usb2_phy: pointer to USB2 PHY - * @usb3_phy: pointer to USB3 PHY -+ * @usb2_generic_phy: pointer to USB2 PHY -+ * @usb3_generic_phy: pointer to USB3 PHY - * @dcfg: saved contents of DCFG register - * @gctl: saved contents of GCTL register - * @is_selfpowered: true when we are selfpowered -@@ -665,6 +669,9 @@ struct dwc3 { - struct usb_phy *usb2_phy; - struct usb_phy *usb3_phy; - -+ struct phy *usb2_generic_phy; -+ struct phy *usb3_generic_phy; -+ - void __iomem *regs; - size_t regs_size; - ---- a/drivers/usb/dwc3/dwc3-omap.c -+++ b/drivers/usb/dwc3/dwc3-omap.c -@@ -535,7 +535,7 @@ static int dwc3_omap_probe(struct platfo - edev = of_extcon_get_extcon_dev(dev, 0); - if (IS_ERR(edev)) { - dev_vdbg(dev, "couldn't get extcon device\n"); -- ret = PTR_ERR(edev); -+ ret = -EPROBE_DEFER; - goto err2; - } - ---- a/drivers/usb/dwc3/dwc3-pci.c -+++ b/drivers/usb/dwc3/dwc3-pci.c -@@ -165,7 +165,6 @@ static int dwc3_pci_probe(struct pci_dev - return 0; - - err3: -- pci_set_drvdata(pci, NULL); - platform_device_put(dwc3); - err1: - pci_disable_device(pci); -@@ -180,7 +179,6 @@ static void dwc3_pci_remove(struct pci_d - platform_device_unregister(glue->dwc3); - platform_device_unregister(glue->usb2_phy); - platform_device_unregister(glue->usb3_phy); -- pci_set_drvdata(pci, NULL); - pci_disable_device(pci); - } - ---- a/drivers/usb/dwc3/Kconfig -+++ b/drivers/usb/dwc3/Kconfig -@@ -1,6 +1,9 @@ - config USB_DWC3 - tristate "DesignWare USB3 DRD Core Support" - depends on (USB || USB_GADGET) && HAS_DMA -+ depends on EXTCON -+ select USB_PHY -+ select GENERIC_PHY - select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD - help - Say Y or M here if your system has a Dual Role SuperSpeed ---- a/drivers/usb/dwc3/platform_data.h -+++ b/drivers/usb/dwc3/platform_data.h -@@ -24,4 +24,5 @@ struct dwc3_platform_data { - enum usb_device_speed maximum_speed; - enum usb_dr_mode dr_mode; - bool tx_fifo_resize; -+ bool has_phy; - }; ---- a/drivers/usb/gadget/acm_ms.c -+++ b/drivers/usb/gadget/acm_ms.c -@@ -31,16 +31,7 @@ - #define ACM_MS_VENDOR_NUM 0x1d6b /* Linux Foundation */ - #define ACM_MS_PRODUCT_NUM 0x0106 /* Composite Gadget: ACM + MS*/ - --/*-------------------------------------------------------------------------*/ -- --/* -- * Kbuild is not very cooperative with respect to linking separately -- * compiled library objects into one module. So for now we won't use -- * separate compilation ... ensuring init/exit sections work to shrink -- * the runtime footprint, and giving us at least some parts of what -- * a "gcc --combine ... part1.c part2.c part3.c ... " build would. -- */ --#include "f_mass_storage.c" -+#include "f_mass_storage.h" - - /*-------------------------------------------------------------------------*/ - USB_GADGET_COMPOSITE_OPTIONS(); -@@ -104,18 +95,35 @@ static struct usb_gadget_strings *dev_st - /****************************** Configurations ******************************/ - - static struct fsg_module_parameters fsg_mod_data = { .stall = 1 }; --FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+ -+static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; - --static struct fsg_common fsg_common; -+#else -+ -+/* -+ * Number of buffers we will use. -+ * 2 is usually enough for good buffering pipeline -+ */ -+#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS -+ -+#endif /* CONFIG_USB_DEBUG */ -+ -+FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); - - /*-------------------------------------------------------------------------*/ - static struct usb_function *f_acm; - static struct usb_function_instance *f_acm_inst; -+ -+static struct usb_function_instance *fi_msg; -+static struct usb_function *f_msg; -+ - /* - * We _always_ have both ACM and mass storage functions. - */ - static int __init acm_ms_do_config(struct usb_configuration *c) - { -+ struct fsg_opts *opts; - int status; - - if (gadget_is_otg(c->cdev->gadget)) { -@@ -123,31 +131,37 @@ static int __init acm_ms_do_config(struc - c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - -- f_acm_inst = usb_get_function_instance("acm"); -- if (IS_ERR(f_acm_inst)) -- return PTR_ERR(f_acm_inst); -+ opts = fsg_opts_from_func_inst(fi_msg); - - f_acm = usb_get_function(f_acm_inst); -- if (IS_ERR(f_acm)) { -- status = PTR_ERR(f_acm); -- goto err_func; -+ if (IS_ERR(f_acm)) -+ return PTR_ERR(f_acm); -+ -+ f_msg = usb_get_function(fi_msg); -+ if (IS_ERR(f_msg)) { -+ status = PTR_ERR(f_msg); -+ goto put_acm; - } - - status = usb_add_function(c, f_acm); - if (status < 0) -- goto err_conf; -+ goto put_msg; - -- status = fsg_bind_config(c->cdev, c, &fsg_common); -- if (status < 0) -- goto err_fsg; -+ status = fsg_common_run_thread(opts->common); -+ if (status) -+ goto remove_acm; -+ -+ status = usb_add_function(c, f_msg); -+ if (status) -+ goto remove_acm; - - return 0; --err_fsg: -+remove_acm: - usb_remove_function(c, f_acm); --err_conf: -+put_msg: -+ usb_put_function(f_msg); -+put_acm: - usb_put_function(f_acm); --err_func: -- usb_put_function_instance(f_acm_inst); - return status; - } - -@@ -163,45 +177,82 @@ static struct usb_configuration acm_ms_c - static int __init acm_ms_bind(struct usb_composite_dev *cdev) - { - struct usb_gadget *gadget = cdev->gadget; -+ struct fsg_opts *opts; -+ struct fsg_config config; - int status; -- void *retp; - -- /* set up mass storage function */ -- retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data); -- if (IS_ERR(retp)) { -- status = PTR_ERR(retp); -- return PTR_ERR(retp); -+ f_acm_inst = usb_get_function_instance("acm"); -+ if (IS_ERR(f_acm_inst)) -+ return PTR_ERR(f_acm_inst); -+ -+ fi_msg = usb_get_function_instance("mass_storage"); -+ if (IS_ERR(fi_msg)) { -+ status = PTR_ERR(fi_msg); -+ goto fail_get_msg; - } - -+ /* set up mass storage function */ -+ fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers); -+ opts = fsg_opts_from_func_inst(fi_msg); -+ -+ opts->no_configfs = true; -+ status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers); -+ if (status) -+ goto fail; -+ -+ status = fsg_common_set_nluns(opts->common, config.nluns); -+ if (status) -+ goto fail_set_nluns; -+ -+ status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); -+ if (status) -+ goto fail_set_cdev; -+ -+ fsg_common_set_sysfs(opts->common, true); -+ status = fsg_common_create_luns(opts->common, &config); -+ if (status) -+ goto fail_set_cdev; -+ -+ fsg_common_set_inquiry_string(opts->common, config.vendor_name, -+ config.product_name); - /* - * Allocate string descriptor numbers ... note that string - * contents can be overridden by the composite_dev glue. - */ - status = usb_string_ids_tab(cdev, strings_dev); - if (status < 0) -- goto fail1; -+ goto fail_string_ids; - device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; - - /* register our configuration */ - status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config); - if (status < 0) -- goto fail1; -+ goto fail_string_ids; - - usb_composite_overwrite_options(cdev, &coverwrite); - dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", - DRIVER_DESC); -- fsg_common_put(&fsg_common); - return 0; - - /* error recovery */ --fail1: -- fsg_common_put(&fsg_common); -+fail_string_ids: -+ fsg_common_remove_luns(opts->common); -+fail_set_cdev: -+ fsg_common_free_luns(opts->common); -+fail_set_nluns: -+ fsg_common_free_buffers(opts->common); -+fail: -+ usb_put_function_instance(fi_msg); -+fail_get_msg: -+ usb_put_function_instance(f_acm_inst); - return status; - } - - static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) - { -+ usb_put_function(f_msg); -+ usb_put_function_instance(fi_msg); - usb_put_function(f_acm); - usb_put_function_instance(f_acm_inst); - return 0; ---- a/drivers/usb/gadget/amd5536udc.c -+++ b/drivers/usb/gadget/amd5536udc.c -@@ -3078,8 +3078,6 @@ static void udc_pci_remove(struct pci_de - if (dev->active) - pci_disable_device(pdev); - -- pci_set_drvdata(pdev, NULL); -- - udc_remove(dev); - } - ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -557,7 +557,7 @@ static struct config_group *function_mak - - fi = usb_get_function_instance(func_name); - if (IS_ERR(fi)) -- return ERR_PTR(PTR_ERR(fi)); -+ return ERR_CAST(fi); - - ret = config_item_set_name(&fi->group.cg_item, name); - if (ret) { -@@ -991,6 +991,14 @@ static struct configfs_subsystem gadget_ - .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex), - }; - -+void unregister_gadget_item(struct config_item *item) -+{ -+ struct gadget_info *gi = to_gadget_info(item); -+ -+ unregister_gadget(gi); -+} -+EXPORT_SYMBOL(unregister_gadget_item); -+ - static int __init gadget_cfs_init(void) - { - int ret; ---- /dev/null -+++ b/drivers/usb/gadget/configfs.h -@@ -0,0 +1,6 @@ -+#ifndef USB__GADGET__CONFIGFS__H -+#define USB__GADGET__CONFIGFS__H -+ -+void unregister_gadget_item(struct config_item *item); -+ -+#endif /* USB__GADGET__CONFIGFS__H */ ---- a/drivers/usb/gadget/f_mass_storage.c -+++ b/drivers/usb/gadget/f_mass_storage.c -@@ -213,12 +213,14 @@ - #include <linux/spinlock.h> - #include <linux/string.h> - #include <linux/freezer.h> -+#include <linux/module.h> - - #include <linux/usb/ch9.h> - #include <linux/usb/gadget.h> - #include <linux/usb/composite.h> - - #include "gadget_chips.h" -+#include "configfs.h" - - - /*------------------------------------------------------------------------*/ -@@ -228,26 +230,30 @@ - - static const char fsg_string_interface[] = "Mass Storage"; - --#include "storage_common.c" -+#include "storage_common.h" -+#include "f_mass_storage.h" - -+/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ -+static struct usb_string fsg_strings[] = { -+ {FSG_STRING_INTERFACE, fsg_string_interface}, -+ {} -+}; -+ -+static struct usb_gadget_strings fsg_stringtab = { -+ .language = 0x0409, /* en-us */ -+ .strings = fsg_strings, -+}; -+ -+static struct usb_gadget_strings *fsg_strings_array[] = { -+ &fsg_stringtab, -+ NULL, -+}; - - /*-------------------------------------------------------------------------*/ - - struct fsg_dev; - struct fsg_common; - --/* FSF callback functions */ --struct fsg_operations { -- /* -- * Callback function to call when thread exits. If no -- * callback is set or it returns value lower then zero MSF -- * will force eject all LUNs it operates on (including those -- * marked as non-removable or with prevent_medium_removal flag -- * set). -- */ -- int (*thread_exits)(struct fsg_common *common); --}; -- - /* Data shared by all the FSG instances. */ - struct fsg_common { - struct usb_gadget *gadget; -@@ -268,13 +274,14 @@ struct fsg_common { - struct fsg_buffhd *next_buffhd_to_fill; - struct fsg_buffhd *next_buffhd_to_drain; - struct fsg_buffhd *buffhds; -+ unsigned int fsg_num_buffers; - - int cmnd_size; - u8 cmnd[MAX_COMMAND_SIZE]; - - unsigned int nluns; - unsigned int lun; -- struct fsg_lun *luns; -+ struct fsg_lun **luns; - struct fsg_lun *curlun; - - unsigned int bulk_out_maxpacket; -@@ -294,6 +301,7 @@ struct fsg_common { - unsigned int short_packet_received:1; - unsigned int bad_lun_okay:1; - unsigned int running:1; -+ unsigned int sysfs:1; - - int thread_wakeup_needed; - struct completion thread_notifier; -@@ -313,27 +321,6 @@ struct fsg_common { - struct kref ref; - }; - --struct fsg_config { -- unsigned nluns; -- struct fsg_lun_config { -- const char *filename; -- char ro; -- char removable; -- char cdrom; -- char nofua; -- } luns[FSG_MAX_LUNS]; -- -- /* Callback functions. */ -- const struct fsg_operations *ops; -- /* Gadget's private data. */ -- void *private_data; -- -- const char *vendor_name; /* 8 characters or less */ -- const char *product_name; /* 16 characters or less */ -- -- char can_stall; --}; -- - struct fsg_dev { - struct usb_function function; - struct usb_gadget *gadget; /* Copy of cdev->gadget */ -@@ -615,13 +602,14 @@ static bool start_out_transfer(struct fs - return true; - } - --static int sleep_thread(struct fsg_common *common) -+static int sleep_thread(struct fsg_common *common, bool can_freeze) - { - int rc = 0; - - /* Wait until a signal arrives or we are woken up */ - for (;;) { -- try_to_freeze(); -+ if (can_freeze) -+ try_to_freeze(); - set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) { - rc = -EINTR; -@@ -695,7 +683,7 @@ static int do_read(struct fsg_common *co - /* Wait for the next buffer to become available */ - bh = common->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { -- rc = sleep_thread(common); -+ rc = sleep_thread(common, false); - if (rc) - return rc; - } -@@ -950,7 +938,7 @@ static int do_write(struct fsg_common *c - } - - /* Wait for something to happen */ -- rc = sleep_thread(common); -+ rc = sleep_thread(common, false); - if (rc) - return rc; - } -@@ -1517,7 +1505,7 @@ static int throw_away_data(struct fsg_co - } - - /* Otherwise wait for something to happen */ -- rc = sleep_thread(common); -+ rc = sleep_thread(common, true); - if (rc) - return rc; - } -@@ -1638,7 +1626,7 @@ static int send_status(struct fsg_common - /* Wait for the next buffer to become available */ - bh = common->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { -- rc = sleep_thread(common); -+ rc = sleep_thread(common, true); - if (rc) - return rc; - } -@@ -1841,7 +1829,7 @@ static int do_scsi_command(struct fsg_co - bh = common->next_buffhd_to_fill; - common->next_buffhd_to_drain = bh; - while (bh->state != BUF_STATE_EMPTY) { -- rc = sleep_thread(common); -+ rc = sleep_thread(common, true); - if (rc) - return rc; - } -@@ -2172,7 +2160,7 @@ static int received_cbw(struct fsg_dev * - common->data_dir = DATA_DIR_NONE; - common->lun = cbw->Lun; - if (common->lun < common->nluns) -- common->curlun = &common->luns[common->lun]; -+ common->curlun = common->luns[common->lun]; - else - common->curlun = NULL; - common->tag = cbw->Tag; -@@ -2187,7 +2175,7 @@ static int get_next_command(struct fsg_c - /* Wait for the next buffer to become available */ - bh = common->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { -- rc = sleep_thread(common); -+ rc = sleep_thread(common, true); - if (rc) - return rc; - } -@@ -2206,7 +2194,7 @@ static int get_next_command(struct fsg_c - - /* Wait for the CBW to arrive */ - while (bh->state != BUF_STATE_FULL) { -- rc = sleep_thread(common); -+ rc = sleep_thread(common, true); - if (rc) - return rc; - } -@@ -2244,7 +2232,7 @@ reset: - if (common->fsg) { - fsg = common->fsg; - -- for (i = 0; i < fsg_num_buffers; ++i) { -+ for (i = 0; i < common->fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &common->buffhds[i]; - - if (bh->inreq) { -@@ -2303,7 +2291,7 @@ reset: - clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - - /* Allocate the requests */ -- for (i = 0; i < fsg_num_buffers; ++i) { -+ for (i = 0; i < common->fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &common->buffhds[i]; - - rc = alloc_request(common, fsg->bulk_in, &bh->inreq); -@@ -2320,7 +2308,9 @@ reset: - - common->running = 1; - for (i = 0; i < common->nluns; ++i) -- common->luns[i].unit_attention_data = SS_RESET_OCCURRED; -+ if (common->luns[i]) -+ common->luns[i]->unit_attention_data = -+ SS_RESET_OCCURRED; - return rc; - } - -@@ -2372,7 +2362,7 @@ static void handle_exception(struct fsg_ - - /* Cancel all the pending transfers */ - if (likely(common->fsg)) { -- for (i = 0; i < fsg_num_buffers; ++i) { -+ for (i = 0; i < common->fsg_num_buffers; ++i) { - bh = &common->buffhds[i]; - if (bh->inreq_busy) - usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); -@@ -2384,13 +2374,13 @@ static void handle_exception(struct fsg_ - /* Wait until everything is idle */ - for (;;) { - int num_active = 0; -- for (i = 0; i < fsg_num_buffers; ++i) { -+ for (i = 0; i < common->fsg_num_buffers; ++i) { - bh = &common->buffhds[i]; - num_active += bh->inreq_busy + bh->outreq_busy; - } - if (num_active == 0) - break; -- if (sleep_thread(common)) -+ if (sleep_thread(common, true)) - return; - } - -@@ -2407,7 +2397,7 @@ static void handle_exception(struct fsg_ - */ - spin_lock_irq(&common->lock); - -- for (i = 0; i < fsg_num_buffers; ++i) { -+ for (i = 0; i < common->fsg_num_buffers; ++i) { - bh = &common->buffhds[i]; - bh->state = BUF_STATE_EMPTY; - } -@@ -2420,7 +2410,9 @@ static void handle_exception(struct fsg_ - common->state = FSG_STATE_STATUS_PHASE; - else { - for (i = 0; i < common->nluns; ++i) { -- curlun = &common->luns[i]; -+ curlun = common->luns[i]; -+ if (!curlun) -+ continue; - curlun->prevent_medium_removal = 0; - curlun->sense_data = SS_NO_SENSE; - curlun->unit_attention_data = SS_NO_SENSE; -@@ -2462,8 +2454,9 @@ static void handle_exception(struct fsg_ - * CONFIG_CHANGE cases. - */ - /* for (i = 0; i < common->nluns; ++i) */ -- /* common->luns[i].unit_attention_data = */ -- /* SS_RESET_OCCURRED; */ -+ /* if (common->luns[i]) */ -+ /* common->luns[i]->unit_attention_data = */ -+ /* SS_RESET_OCCURRED; */ - break; - - case FSG_STATE_CONFIG_CHANGE: -@@ -2524,7 +2517,7 @@ static int fsg_main_thread(void *common_ - } - - if (!common->running) { -- sleep_thread(common); -+ sleep_thread(common, true); - continue; - } - -@@ -2559,12 +2552,13 @@ static int fsg_main_thread(void *common_ - - if (!common->ops || !common->ops->thread_exits - || common->ops->thread_exits(common) < 0) { -- struct fsg_lun *curlun = common->luns; -+ struct fsg_lun **curlun_it = common->luns; - unsigned i = common->nluns; - - down_write(&common->filesem); -- for (; i--; ++curlun) { -- if (!fsg_lun_is_open(curlun)) -+ for (; i--; ++curlun_it) { -+ struct fsg_lun *curlun = *curlun_it; -+ if (!curlun || !fsg_lun_is_open(curlun)) - continue; - - fsg_lun_close(curlun); -@@ -2580,6 +2574,56 @@ static int fsg_main_thread(void *common_ - - /*************************** DEVICE ATTRIBUTES ***************************/ - -+static ssize_t ro_show(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct fsg_lun *curlun = fsg_lun_from_dev(dev); -+ -+ return fsg_show_ro(curlun, buf); -+} -+ -+static ssize_t nofua_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct fsg_lun *curlun = fsg_lun_from_dev(dev); -+ -+ return fsg_show_nofua(curlun, buf); -+} -+ -+static ssize_t file_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct fsg_lun *curlun = fsg_lun_from_dev(dev); -+ struct rw_semaphore *filesem = dev_get_drvdata(dev); -+ -+ return fsg_show_file(curlun, filesem, buf); -+} -+ -+static ssize_t ro_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct fsg_lun *curlun = fsg_lun_from_dev(dev); -+ struct rw_semaphore *filesem = dev_get_drvdata(dev); -+ -+ return fsg_store_ro(curlun, filesem, buf, count); -+} -+ -+static ssize_t nofua_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct fsg_lun *curlun = fsg_lun_from_dev(dev); -+ -+ return fsg_store_nofua(curlun, buf, count); -+} -+ -+static ssize_t file_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct fsg_lun *curlun = fsg_lun_from_dev(dev); -+ struct rw_semaphore *filesem = dev_get_drvdata(dev); -+ -+ return fsg_store_file(curlun, filesem, buf, count); -+} -+ - static DEVICE_ATTR_RW(ro); - static DEVICE_ATTR_RW(nofua); - static DEVICE_ATTR_RW(file); -@@ -2597,221 +2641,422 @@ static void fsg_lun_release(struct devic - /* Nothing needs to be done */ - } - --static inline void fsg_common_get(struct fsg_common *common) -+void fsg_common_get(struct fsg_common *common) - { - kref_get(&common->ref); - } -+EXPORT_SYMBOL_GPL(fsg_common_get); - --static inline void fsg_common_put(struct fsg_common *common) -+void fsg_common_put(struct fsg_common *common) - { - kref_put(&common->ref, fsg_common_release); - } -+EXPORT_SYMBOL_GPL(fsg_common_put); - --static struct fsg_common *fsg_common_init(struct fsg_common *common, -- struct usb_composite_dev *cdev, -- struct fsg_config *cfg) --{ -- struct usb_gadget *gadget = cdev->gadget; -- struct fsg_buffhd *bh; -- struct fsg_lun *curlun; -- struct fsg_lun_config *lcfg; -- int nluns, i, rc; -- char *pathbuf; -- -- rc = fsg_num_buffers_validate(); -- if (rc != 0) -- return ERR_PTR(rc); -- -- /* Find out how many LUNs there should be */ -- nluns = cfg->nluns; -- if (nluns < 1 || nluns > FSG_MAX_LUNS) { -- dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns); -- return ERR_PTR(-EINVAL); -- } -+/* check if fsg_num_buffers is within a valid range */ -+static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) -+{ -+ if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) -+ return 0; -+ pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", -+ fsg_num_buffers, 2, 4); -+ return -EINVAL; -+} - -- /* Allocate? */ -+static struct fsg_common *fsg_common_setup(struct fsg_common *common) -+{ - if (!common) { -- common = kzalloc(sizeof *common, GFP_KERNEL); -+ common = kzalloc(sizeof(*common), GFP_KERNEL); - if (!common) - return ERR_PTR(-ENOMEM); - common->free_storage_on_release = 1; - } else { -- memset(common, 0, sizeof *common); - common->free_storage_on_release = 0; - } -+ init_rwsem(&common->filesem); -+ spin_lock_init(&common->lock); -+ kref_init(&common->ref); -+ init_completion(&common->thread_notifier); -+ init_waitqueue_head(&common->fsg_wait); -+ common->state = FSG_STATE_TERMINATED; - -- common->buffhds = kcalloc(fsg_num_buffers, -- sizeof *(common->buffhds), GFP_KERNEL); -- if (!common->buffhds) { -- if (common->free_storage_on_release) -- kfree(common); -- return ERR_PTR(-ENOMEM); -+ return common; -+} -+ -+void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs) -+{ -+ common->sysfs = sysfs; -+} -+EXPORT_SYMBOL_GPL(fsg_common_set_sysfs); -+ -+static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n) -+{ -+ if (buffhds) { -+ struct fsg_buffhd *bh = buffhds; -+ while (n--) { -+ kfree(bh->buf); -+ ++bh; -+ } -+ kfree(buffhds); - } -+} - -- common->ops = cfg->ops; -- common->private_data = cfg->private_data; -+int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n) -+{ -+ struct fsg_buffhd *bh, *buffhds; -+ int i, rc; - -- common->gadget = gadget; -- common->ep0 = gadget->ep0; -- common->ep0req = cdev->req; -- common->cdev = cdev; -+ rc = fsg_num_buffers_validate(n); -+ if (rc != 0) -+ return rc; - -- /* Maybe allocate device-global string IDs, and patch descriptors */ -- if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { -- rc = usb_string_id(cdev); -- if (unlikely(rc < 0)) -+ buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL); -+ if (!buffhds) -+ return -ENOMEM; -+ -+ /* Data buffers cyclic list */ -+ bh = buffhds; -+ i = n; -+ goto buffhds_first_it; -+ do { -+ bh->next = bh + 1; -+ ++bh; -+buffhds_first_it: -+ bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); -+ if (unlikely(!bh->buf)) - goto error_release; -- fsg_strings[FSG_STRING_INTERFACE].id = rc; -- fsg_intf_desc.iInterface = rc; -- } -+ } while (--i); -+ bh->next = buffhds; -+ -+ _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); -+ common->fsg_num_buffers = n; -+ common->buffhds = buffhds; -+ -+ return 0; - -+error_release: - /* -- * Create the LUNs, open their backing files, and register the -- * LUN devices in sysfs. -+ * "buf"s pointed to by heads after n - i are NULL -+ * so releasing them won't hurt - */ -- curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); -- if (unlikely(!curlun)) { -- rc = -ENOMEM; -- goto error_release; -- } -- common->luns = curlun; -+ _fsg_common_free_buffers(buffhds, n); - -- init_rwsem(&common->filesem); -+ return -ENOMEM; -+} -+EXPORT_SYMBOL_GPL(fsg_common_set_num_buffers); - -- for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { -- curlun->cdrom = !!lcfg->cdrom; -- curlun->ro = lcfg->cdrom || lcfg->ro; -- curlun->initially_ro = curlun->ro; -- curlun->removable = lcfg->removable; -- curlun->dev.release = fsg_lun_release; -- curlun->dev.parent = &gadget->dev; -- /* curlun->dev.driver = &fsg_driver.driver; XXX */ -- dev_set_drvdata(&curlun->dev, &common->filesem); -- dev_set_name(&curlun->dev, "lun%d", i); -+static inline void fsg_common_remove_sysfs(struct fsg_lun *lun) -+{ -+ device_remove_file(&lun->dev, &dev_attr_nofua); -+ /* -+ * device_remove_file() => -+ * -+ * here the attr (e.g. dev_attr_ro) is only used to be passed to: -+ * -+ * sysfs_remove_file() => -+ * -+ * here e.g. both dev_attr_ro_cdrom and dev_attr_ro are in -+ * the same namespace and -+ * from here only attr->name is passed to: -+ * -+ * sysfs_hash_and_remove() -+ * -+ * attr->name is the same for dev_attr_ro_cdrom and -+ * dev_attr_ro -+ * attr->name is the same for dev_attr_file and -+ * dev_attr_file_nonremovable -+ * -+ * so we don't differentiate between removing e.g. dev_attr_ro_cdrom -+ * and dev_attr_ro -+ */ -+ device_remove_file(&lun->dev, &dev_attr_ro); -+ device_remove_file(&lun->dev, &dev_attr_file); -+} - -- rc = device_register(&curlun->dev); -- if (rc) { -- INFO(common, "failed to register LUN%d: %d\n", i, rc); -- common->nluns = i; -- put_device(&curlun->dev); -- goto error_release; -- } -+void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs) -+{ -+ if (sysfs) { -+ fsg_common_remove_sysfs(lun); -+ device_unregister(&lun->dev); -+ } -+ fsg_lun_close(lun); -+ kfree(lun); -+} -+EXPORT_SYMBOL_GPL(fsg_common_remove_lun); - -- rc = device_create_file(&curlun->dev, -- curlun->cdrom -- ? &dev_attr_ro_cdrom -- : &dev_attr_ro); -- if (rc) -- goto error_luns; -- rc = device_create_file(&curlun->dev, -- curlun->removable -- ? &dev_attr_file -- : &dev_attr_file_nonremovable); -- if (rc) -- goto error_luns; -- rc = device_create_file(&curlun->dev, &dev_attr_nofua); -- if (rc) -- goto error_luns; -+static void _fsg_common_remove_luns(struct fsg_common *common, int n) -+{ -+ int i; - -- if (lcfg->filename) { -- rc = fsg_lun_open(curlun, lcfg->filename); -- if (rc) -- goto error_luns; -- } else if (!curlun->removable) { -- ERROR(common, "no file given for LUN%d\n", i); -- rc = -EINVAL; -- goto error_luns; -+ for (i = 0; i < n; ++i) -+ if (common->luns[i]) { -+ fsg_common_remove_lun(common->luns[i], common->sysfs); -+ common->luns[i] = NULL; - } -+} -+EXPORT_SYMBOL_GPL(fsg_common_remove_luns); -+ -+void fsg_common_remove_luns(struct fsg_common *common) -+{ -+ _fsg_common_remove_luns(common, common->nluns); -+} -+ -+void fsg_common_free_luns(struct fsg_common *common) -+{ -+ fsg_common_remove_luns(common); -+ kfree(common->luns); -+ common->luns = NULL; -+} -+EXPORT_SYMBOL_GPL(fsg_common_free_luns); -+ -+int fsg_common_set_nluns(struct fsg_common *common, int nluns) -+{ -+ struct fsg_lun **curlun; -+ -+ /* Find out how many LUNs there should be */ -+ if (nluns < 1 || nluns > FSG_MAX_LUNS) { -+ pr_err("invalid number of LUNs: %u\n", nluns); -+ return -EINVAL; - } -+ -+ curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); -+ if (unlikely(!curlun)) -+ return -ENOMEM; -+ -+ if (common->luns) -+ fsg_common_free_luns(common); -+ -+ common->luns = curlun; - common->nluns = nluns; - -- /* Data buffers cyclic list */ -- bh = common->buffhds; -- i = fsg_num_buffers; -- goto buffhds_first_it; -- do { -- bh->next = bh + 1; -- ++bh; --buffhds_first_it: -- bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); -- if (unlikely(!bh->buf)) { -- rc = -ENOMEM; -- goto error_release; -- } -- } while (--i); -- bh->next = common->buffhds; -+ pr_info("Number of LUNs=%d\n", common->nluns); - -- /* Prepare inquiryString */ -- i = get_default_bcdDevice(); -- snprintf(common->inquiry_string, sizeof common->inquiry_string, -- "%-8s%-16s%04x", cfg->vendor_name ?: "Linux", -- /* Assume product name dependent on the first LUN */ -- cfg->product_name ?: (common->luns->cdrom -- ? "File-CD Gadget" -- : "File-Stor Gadget"), -- i); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(fsg_common_set_nluns); -+ -+void fsg_common_set_ops(struct fsg_common *common, -+ const struct fsg_operations *ops) -+{ -+ common->ops = ops; -+} -+EXPORT_SYMBOL_GPL(fsg_common_set_ops); -+ -+void fsg_common_free_buffers(struct fsg_common *common) -+{ -+ _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); -+ common->buffhds = NULL; -+} -+EXPORT_SYMBOL_GPL(fsg_common_free_buffers); -+ -+int fsg_common_set_cdev(struct fsg_common *common, -+ struct usb_composite_dev *cdev, bool can_stall) -+{ -+ struct usb_string *us; -+ -+ common->gadget = cdev->gadget; -+ common->ep0 = cdev->gadget->ep0; -+ common->ep0req = cdev->req; -+ common->cdev = cdev; -+ -+ us = usb_gstrings_attach(cdev, fsg_strings_array, -+ ARRAY_SIZE(fsg_strings)); -+ if (IS_ERR(us)) -+ return PTR_ERR(us); -+ -+ fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id; - - /* - * Some peripheral controllers are known not to be able to - * halt bulk endpoints correctly. If one of them is present, - * disable stalls. - */ -- common->can_stall = cfg->can_stall && -- !(gadget_is_at91(common->gadget)); -+ common->can_stall = can_stall && !(gadget_is_at91(common->gadget)); - -- spin_lock_init(&common->lock); -- kref_init(&common->ref); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(fsg_common_set_cdev); - -- /* Tell the thread to start working */ -- common->thread_task = -- kthread_create(fsg_main_thread, common, "file-storage"); -- if (IS_ERR(common->thread_task)) { -- rc = PTR_ERR(common->thread_task); -- goto error_release; -+static inline int fsg_common_add_sysfs(struct fsg_common *common, -+ struct fsg_lun *lun) -+{ -+ int rc; -+ -+ rc = device_register(&lun->dev); -+ if (rc) { -+ put_device(&lun->dev); -+ return rc; - } -- init_completion(&common->thread_notifier); -- init_waitqueue_head(&common->fsg_wait); - -- /* Information */ -- INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); -- INFO(common, "Number of LUNs=%d\n", common->nluns); -+ rc = device_create_file(&lun->dev, -+ lun->cdrom -+ ? &dev_attr_ro_cdrom -+ : &dev_attr_ro); -+ if (rc) -+ goto error; -+ rc = device_create_file(&lun->dev, -+ lun->removable -+ ? &dev_attr_file -+ : &dev_attr_file_nonremovable); -+ if (rc) -+ goto error; -+ rc = device_create_file(&lun->dev, &dev_attr_nofua); -+ if (rc) -+ goto error; -+ -+ return 0; -+ -+error: -+ /* removing nonexistent files is a no-op */ -+ fsg_common_remove_sysfs(lun); -+ device_unregister(&lun->dev); -+ return rc; -+} -+ -+int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, -+ unsigned int id, const char *name, -+ const char **name_pfx) -+{ -+ struct fsg_lun *lun; -+ char *pathbuf, *p; -+ int rc = -ENOMEM; -+ -+ if (!common->nluns || !common->luns) -+ return -ENODEV; -+ -+ if (common->luns[id]) -+ return -EBUSY; -+ -+ if (!cfg->filename && !cfg->removable) { -+ pr_err("no file given for LUN%d\n", id); -+ return -EINVAL; -+ } -+ -+ lun = kzalloc(sizeof(*lun), GFP_KERNEL); -+ if (!lun) -+ return -ENOMEM; -+ -+ lun->name_pfx = name_pfx; -+ -+ lun->cdrom = !!cfg->cdrom; -+ lun->ro = cfg->cdrom || cfg->ro; -+ lun->initially_ro = lun->ro; -+ lun->removable = !!cfg->removable; -+ -+ if (!common->sysfs) { -+ /* we DON'T own the name!*/ -+ lun->name = name; -+ } else { -+ lun->dev.release = fsg_lun_release; -+ lun->dev.parent = &common->gadget->dev; -+ dev_set_drvdata(&lun->dev, &common->filesem); -+ dev_set_name(&lun->dev, name); -+ lun->name = dev_name(&lun->dev); -+ -+ rc = fsg_common_add_sysfs(common, lun); -+ if (rc) { -+ pr_info("failed to register LUN%d: %d\n", id, rc); -+ goto error_sysfs; -+ } -+ } -+ -+ common->luns[id] = lun; -+ -+ if (cfg->filename) { -+ rc = fsg_lun_open(lun, cfg->filename); -+ if (rc) -+ goto error_lun; -+ } - - pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); -- for (i = 0, nluns = common->nluns, curlun = common->luns; -- i < nluns; -- ++curlun, ++i) { -- char *p = "(no medium)"; -- if (fsg_lun_is_open(curlun)) { -- p = "(error)"; -- if (pathbuf) { -- p = d_path(&curlun->filp->f_path, -- pathbuf, PATH_MAX); -- if (IS_ERR(p)) -- p = "(error)"; -- } -+ p = "(no medium)"; -+ if (fsg_lun_is_open(lun)) { -+ p = "(error)"; -+ if (pathbuf) { -+ p = d_path(&lun->filp->f_path, pathbuf, PATH_MAX); -+ if (IS_ERR(p)) -+ p = "(error)"; - } -- LINFO(curlun, "LUN: %s%s%sfile: %s\n", -- curlun->removable ? "removable " : "", -- curlun->ro ? "read only " : "", -- curlun->cdrom ? "CD-ROM " : "", -- p); - } -+ pr_info("LUN: %s%s%sfile: %s\n", -+ lun->removable ? "removable " : "", -+ lun->ro ? "read only " : "", -+ lun->cdrom ? "CD-ROM " : "", -+ p); - kfree(pathbuf); - -+ return 0; -+ -+error_lun: -+ if (common->sysfs) { -+ fsg_common_remove_sysfs(lun); -+ device_unregister(&lun->dev); -+ } -+ fsg_lun_close(lun); -+ common->luns[id] = NULL; -+error_sysfs: -+ kfree(lun); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(fsg_common_create_lun); -+ -+int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg) -+{ -+ char buf[8]; /* enough for 100000000 different numbers, decimal */ -+ int i, rc; -+ -+ for (i = 0; i < common->nluns; ++i) { -+ snprintf(buf, sizeof(buf), "lun%d", i); -+ rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL); -+ if (rc) -+ goto fail; -+ } -+ -+ pr_info("Number of LUNs=%d\n", common->nluns); -+ -+ return 0; -+ -+fail: -+ _fsg_common_remove_luns(common, i); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(fsg_common_create_luns); -+ -+void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, -+ const char *pn) -+{ -+ int i; -+ -+ /* Prepare inquiryString */ -+ i = get_default_bcdDevice(); -+ snprintf(common->inquiry_string, sizeof(common->inquiry_string), -+ "%-8s%-16s%04x", vn ?: "Linux", -+ /* Assume product name dependent on the first LUN */ -+ pn ?: ((*common->luns)->cdrom -+ ? "File-CD Gadget" -+ : "File-Stor Gadget"), -+ i); -+} -+EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string); -+ -+int fsg_common_run_thread(struct fsg_common *common) -+{ -+ common->state = FSG_STATE_IDLE; -+ /* Tell the thread to start working */ -+ common->thread_task = -+ kthread_create(fsg_main_thread, common, "file-storage"); -+ if (IS_ERR(common->thread_task)) { -+ common->state = FSG_STATE_TERMINATED; -+ return PTR_ERR(common->thread_task); -+ } -+ - DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); - - wake_up_process(common->thread_task); - -- return common; -- --error_luns: -- common->nluns = i + 1; --error_release: -- common->state = FSG_STATE_TERMINATED; /* The thread is dead */ -- /* Call fsg_common_release() directly, ref might be not initialised. */ -- fsg_common_release(&common->ref); -- return ERR_PTR(rc); -+ return 0; - } -+EXPORT_SYMBOL_GPL(fsg_common_run_thread); - - static void fsg_common_release(struct kref *ref) - { -@@ -2824,36 +3069,26 @@ static void fsg_common_release(struct kr - } - - if (likely(common->luns)) { -- struct fsg_lun *lun = common->luns; -+ struct fsg_lun **lun_it = common->luns; - unsigned i = common->nluns; - - /* In error recovery common->nluns may be zero. */ -- for (; i; --i, ++lun) { -- device_remove_file(&lun->dev, &dev_attr_nofua); -- device_remove_file(&lun->dev, -- lun->cdrom -- ? &dev_attr_ro_cdrom -- : &dev_attr_ro); -- device_remove_file(&lun->dev, -- lun->removable -- ? &dev_attr_file -- : &dev_attr_file_nonremovable); -+ for (; i; --i, ++lun_it) { -+ struct fsg_lun *lun = *lun_it; -+ if (!lun) -+ continue; -+ if (common->sysfs) -+ fsg_common_remove_sysfs(lun); - fsg_lun_close(lun); -- device_unregister(&lun->dev); -+ if (common->sysfs) -+ device_unregister(&lun->dev); -+ kfree(lun); - } - - kfree(common->luns); - } - -- { -- struct fsg_buffhd *bh = common->buffhds; -- unsigned i = fsg_num_buffers; -- do { -- kfree(bh->buf); -- } while (++bh, --i); -- } -- -- kfree(common->buffhds); -+ _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); - if (common->free_storage_on_release) - kfree(common); - } -@@ -2861,24 +3096,6 @@ static void fsg_common_release(struct kr - - /*-------------------------------------------------------------------------*/ - --static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) --{ -- struct fsg_dev *fsg = fsg_from_func(f); -- struct fsg_common *common = fsg->common; -- -- DBG(fsg, "unbind\n"); -- if (fsg->common->fsg == fsg) { -- fsg->common->new_fsg = NULL; -- raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); -- /* FIXME: make interruptible or killable somehow? */ -- wait_event(common->fsg_wait, common->fsg != fsg); -- } -- -- fsg_common_put(common); -- usb_free_all_descriptors(&fsg->function); -- kfree(fsg); --} -- - static int fsg_bind(struct usb_configuration *c, struct usb_function *f) - { - struct fsg_dev *fsg = fsg_from_func(f); -@@ -2887,6 +3104,19 @@ static int fsg_bind(struct usb_configura - struct usb_ep *ep; - unsigned max_burst; - int ret; -+ struct fsg_opts *opts; -+ -+ opts = fsg_opts_from_func_inst(f->fi); -+ if (!opts->no_configfs) { -+ ret = fsg_common_set_cdev(fsg->common, c->cdev, -+ fsg->common->can_stall); -+ if (ret) -+ return ret; -+ fsg_common_set_inquiry_string(fsg->common, 0, 0); -+ ret = fsg_common_run_thread(fsg->common); -+ if (ret) -+ return ret; -+ } - - fsg->gadget = gadget; - -@@ -2939,95 +3169,472 @@ autoconf_fail: - return -ENOTSUPP; - } - --/****************************** ADD FUNCTION ******************************/ -+/****************************** ALLOCATE FUNCTION *************************/ - --static struct usb_gadget_strings *fsg_strings_array[] = { -- &fsg_stringtab, -+static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) -+{ -+ struct fsg_dev *fsg = fsg_from_func(f); -+ struct fsg_common *common = fsg->common; -+ -+ DBG(fsg, "unbind\n"); -+ if (fsg->common->fsg == fsg) { -+ fsg->common->new_fsg = NULL; -+ raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); -+ /* FIXME: make interruptible or killable somehow? */ -+ wait_event(common->fsg_wait, common->fsg != fsg); -+ } -+ -+ usb_free_all_descriptors(&fsg->function); -+} -+ -+static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item) -+{ -+ return container_of(to_config_group(item), struct fsg_lun_opts, group); -+} -+ -+static inline struct fsg_opts *to_fsg_opts(struct config_item *item) -+{ -+ return container_of(to_config_group(item), struct fsg_opts, -+ func_inst.group); -+} -+ -+CONFIGFS_ATTR_STRUCT(fsg_lun_opts); -+CONFIGFS_ATTR_OPS(fsg_lun_opts); -+ -+static void fsg_lun_attr_release(struct config_item *item) -+{ -+ struct fsg_lun_opts *lun_opts; -+ -+ lun_opts = to_fsg_lun_opts(item); -+ kfree(lun_opts); -+} -+ -+static struct configfs_item_operations fsg_lun_item_ops = { -+ .release = fsg_lun_attr_release, -+ .show_attribute = fsg_lun_opts_attr_show, -+ .store_attribute = fsg_lun_opts_attr_store, -+}; -+ -+static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page) -+{ -+ struct fsg_opts *fsg_opts; -+ -+ fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); -+ -+ return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page); -+} -+ -+static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts, -+ const char *page, size_t len) -+{ -+ struct fsg_opts *fsg_opts; -+ -+ fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); -+ -+ return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len); -+} -+ -+static struct fsg_lun_opts_attribute fsg_lun_opts_file = -+ __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show, -+ fsg_lun_opts_file_store); -+ -+static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page) -+{ -+ return fsg_show_ro(opts->lun, page); -+} -+ -+static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts, -+ const char *page, size_t len) -+{ -+ struct fsg_opts *fsg_opts; -+ -+ fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); -+ -+ return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len); -+} -+ -+static struct fsg_lun_opts_attribute fsg_lun_opts_ro = -+ __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show, -+ fsg_lun_opts_ro_store); -+ -+static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts, -+ char *page) -+{ -+ return fsg_show_removable(opts->lun, page); -+} -+ -+static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts, -+ const char *page, size_t len) -+{ -+ return fsg_store_removable(opts->lun, page, len); -+} -+ -+static struct fsg_lun_opts_attribute fsg_lun_opts_removable = -+ __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR, -+ fsg_lun_opts_removable_show, -+ fsg_lun_opts_removable_store); -+ -+static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page) -+{ -+ return fsg_show_cdrom(opts->lun, page); -+} -+ -+static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts, -+ const char *page, size_t len) -+{ -+ struct fsg_opts *fsg_opts; -+ -+ fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); -+ -+ return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page, -+ len); -+} -+ -+static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom = -+ __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show, -+ fsg_lun_opts_cdrom_store); -+ -+static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page) -+{ -+ return fsg_show_nofua(opts->lun, page); -+} -+ -+static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts, -+ const char *page, size_t len) -+{ -+ return fsg_store_nofua(opts->lun, page, len); -+} -+ -+static struct fsg_lun_opts_attribute fsg_lun_opts_nofua = -+ __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show, -+ fsg_lun_opts_nofua_store); -+ -+static struct configfs_attribute *fsg_lun_attrs[] = { -+ &fsg_lun_opts_file.attr, -+ &fsg_lun_opts_ro.attr, -+ &fsg_lun_opts_removable.attr, -+ &fsg_lun_opts_cdrom.attr, -+ &fsg_lun_opts_nofua.attr, - NULL, - }; - --static int fsg_bind_config(struct usb_composite_dev *cdev, -- struct usb_configuration *c, -- struct fsg_common *common) -+static struct config_item_type fsg_lun_type = { -+ .ct_item_ops = &fsg_lun_item_ops, -+ .ct_attrs = fsg_lun_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_group *fsg_lun_make(struct config_group *group, -+ const char *name) - { -- struct fsg_dev *fsg; -+ struct fsg_lun_opts *opts; -+ struct fsg_opts *fsg_opts; -+ struct fsg_lun_config config; -+ char *num_str; -+ u8 num; -+ int ret; -+ -+ num_str = strchr(name, '.'); -+ if (!num_str) { -+ pr_err("Unable to locate . in LUN.NUMBER\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ num_str++; -+ -+ ret = kstrtou8(num_str, 0, &num); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ fsg_opts = to_fsg_opts(&group->cg_item); -+ if (num >= FSG_MAX_LUNS) -+ return ERR_PTR(-ERANGE); -+ -+ mutex_lock(&fsg_opts->lock); -+ if (fsg_opts->refcnt || fsg_opts->common->luns[num]) { -+ ret = -EBUSY; -+ goto out; -+ } -+ -+ opts = kzalloc(sizeof(*opts), GFP_KERNEL); -+ if (!opts) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memset(&config, 0, sizeof(config)); -+ config.removable = true; -+ -+ ret = fsg_common_create_lun(fsg_opts->common, &config, num, name, -+ (const char **)&group->cg_item.ci_name); -+ if (ret) { -+ kfree(opts); -+ goto out; -+ } -+ opts->lun = fsg_opts->common->luns[num]; -+ opts->lun_id = num; -+ mutex_unlock(&fsg_opts->lock); -+ -+ config_group_init_type_name(&opts->group, name, &fsg_lun_type); -+ -+ return &opts->group; -+out: -+ mutex_unlock(&fsg_opts->lock); -+ return ERR_PTR(ret); -+} -+ -+static void fsg_lun_drop(struct config_group *group, struct config_item *item) -+{ -+ struct fsg_lun_opts *lun_opts; -+ struct fsg_opts *fsg_opts; -+ -+ lun_opts = to_fsg_lun_opts(item); -+ fsg_opts = to_fsg_opts(&group->cg_item); -+ -+ mutex_lock(&fsg_opts->lock); -+ if (fsg_opts->refcnt) { -+ struct config_item *gadget; -+ -+ gadget = group->cg_item.ci_parent->ci_parent; -+ unregister_gadget_item(gadget); -+ } -+ -+ fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs); -+ fsg_opts->common->luns[lun_opts->lun_id] = NULL; -+ lun_opts->lun_id = 0; -+ mutex_unlock(&fsg_opts->lock); -+ -+ config_item_put(item); -+} -+ -+CONFIGFS_ATTR_STRUCT(fsg_opts); -+CONFIGFS_ATTR_OPS(fsg_opts); -+ -+static void fsg_attr_release(struct config_item *item) -+{ -+ struct fsg_opts *opts = to_fsg_opts(item); -+ -+ usb_put_function_instance(&opts->func_inst); -+} -+ -+static struct configfs_item_operations fsg_item_ops = { -+ .release = fsg_attr_release, -+ .show_attribute = fsg_opts_attr_show, -+ .store_attribute = fsg_opts_attr_store, -+}; -+ -+static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page) -+{ -+ int result; -+ -+ mutex_lock(&opts->lock); -+ result = sprintf(page, "%d", opts->common->can_stall); -+ mutex_unlock(&opts->lock); -+ -+ return result; -+} -+ -+static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page, -+ size_t len) -+{ -+ int ret; -+ bool stall; -+ -+ mutex_lock(&opts->lock); -+ -+ if (opts->refcnt) { -+ mutex_unlock(&opts->lock); -+ return -EBUSY; -+ } -+ -+ ret = strtobool(page, &stall); -+ if (!ret) { -+ opts->common->can_stall = stall; -+ ret = len; -+ } -+ -+ mutex_unlock(&opts->lock); -+ -+ return ret; -+} -+ -+static struct fsg_opts_attribute fsg_opts_stall = -+ __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show, -+ fsg_opts_stall_store); -+ -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page) -+{ -+ int result; -+ -+ mutex_lock(&opts->lock); -+ result = sprintf(page, "%d", opts->common->fsg_num_buffers); -+ mutex_unlock(&opts->lock); -+ -+ return result; -+} -+ -+static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts, -+ const char *page, size_t len) -+{ -+ int ret; -+ u8 num; -+ -+ mutex_lock(&opts->lock); -+ if (opts->refcnt) { -+ ret = -EBUSY; -+ goto end; -+ } -+ ret = kstrtou8(page, 0, &num); -+ if (ret) -+ goto end; -+ -+ ret = fsg_num_buffers_validate(num); -+ if (ret) -+ goto end; -+ -+ fsg_common_set_num_buffers(opts->common, num); -+ ret = len; -+ -+end: -+ mutex_unlock(&opts->lock); -+ return ret; -+} -+ -+static struct fsg_opts_attribute fsg_opts_num_buffers = -+ __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR, -+ fsg_opts_num_buffers_show, -+ fsg_opts_num_buffers_store); -+ -+#endif -+ -+static struct configfs_attribute *fsg_attrs[] = { -+ &fsg_opts_stall.attr, -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+ &fsg_opts_num_buffers.attr, -+#endif -+ NULL, -+}; -+ -+static struct configfs_group_operations fsg_group_ops = { -+ .make_group = fsg_lun_make, -+ .drop_item = fsg_lun_drop, -+}; -+ -+static struct config_item_type fsg_func_type = { -+ .ct_item_ops = &fsg_item_ops, -+ .ct_group_ops = &fsg_group_ops, -+ .ct_attrs = fsg_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static void fsg_free_inst(struct usb_function_instance *fi) -+{ -+ struct fsg_opts *opts; -+ -+ opts = fsg_opts_from_func_inst(fi); -+ fsg_common_put(opts->common); -+ kfree(opts); -+} -+ -+static struct usb_function_instance *fsg_alloc_inst(void) -+{ -+ struct fsg_opts *opts; -+ struct fsg_lun_config config; - int rc; - -- fsg = kzalloc(sizeof *fsg, GFP_KERNEL); -+ opts = kzalloc(sizeof(*opts), GFP_KERNEL); -+ if (!opts) -+ return ERR_PTR(-ENOMEM); -+ mutex_init(&opts->lock); -+ opts->func_inst.free_func_inst = fsg_free_inst; -+ opts->common = fsg_common_setup(opts->common); -+ if (IS_ERR(opts->common)) { -+ rc = PTR_ERR(opts->common); -+ goto release_opts; -+ } -+ rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS); -+ if (rc) -+ goto release_opts; -+ -+ rc = fsg_common_set_num_buffers(opts->common, -+ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS); -+ if (rc) -+ goto release_luns; -+ -+ pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); -+ -+ memset(&config, 0, sizeof(config)); -+ config.removable = true; -+ rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0", -+ (const char **)&opts->func_inst.group.cg_item.ci_name); -+ opts->lun0.lun = opts->common->luns[0]; -+ opts->lun0.lun_id = 0; -+ config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type); -+ opts->default_groups[0] = &opts->lun0.group; -+ opts->func_inst.group.default_groups = opts->default_groups; -+ -+ config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type); -+ -+ return &opts->func_inst; -+ -+release_luns: -+ kfree(opts->common->luns); -+release_opts: -+ kfree(opts); -+ return ERR_PTR(rc); -+} -+ -+static void fsg_free(struct usb_function *f) -+{ -+ struct fsg_dev *fsg; -+ struct fsg_opts *opts; -+ -+ fsg = container_of(f, struct fsg_dev, function); -+ opts = container_of(f->fi, struct fsg_opts, func_inst); -+ -+ mutex_lock(&opts->lock); -+ opts->refcnt--; -+ mutex_unlock(&opts->lock); -+ -+ kfree(fsg); -+} -+ -+static struct usb_function *fsg_alloc(struct usb_function_instance *fi) -+{ -+ struct fsg_opts *opts = fsg_opts_from_func_inst(fi); -+ struct fsg_common *common = opts->common; -+ struct fsg_dev *fsg; -+ -+ fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); - if (unlikely(!fsg)) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); - -- fsg->function.name = FSG_DRIVER_DESC; -- fsg->function.strings = fsg_strings_array; -- fsg->function.bind = fsg_bind; -- fsg->function.unbind = fsg_unbind; -- fsg->function.setup = fsg_setup; -- fsg->function.set_alt = fsg_set_alt; -- fsg->function.disable = fsg_disable; -+ mutex_lock(&opts->lock); -+ opts->refcnt++; -+ mutex_unlock(&opts->lock); -+ fsg->function.name = FSG_DRIVER_DESC; -+ fsg->function.bind = fsg_bind; -+ fsg->function.unbind = fsg_unbind; -+ fsg->function.setup = fsg_setup; -+ fsg->function.set_alt = fsg_set_alt; -+ fsg->function.disable = fsg_disable; -+ fsg->function.free_func = fsg_free; - - fsg->common = common; -- /* -- * Our caller holds a reference to common structure so we -- * don't have to be worry about it being freed until we return -- * from this function. So instead of incrementing counter now -- * and decrement in error recovery we increment it only when -- * call to usb_add_function() was successful. -- */ - -- rc = usb_add_function(c, &fsg->function); -- if (unlikely(rc)) -- kfree(fsg); -- else -- fsg_common_get(fsg->common); -- return rc; -+ return &fsg->function; - } - -+DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Michal Nazarewicz"); - - /************************* Module parameters *************************/ - --struct fsg_module_parameters { -- char *file[FSG_MAX_LUNS]; -- bool ro[FSG_MAX_LUNS]; -- bool removable[FSG_MAX_LUNS]; -- bool cdrom[FSG_MAX_LUNS]; -- bool nofua[FSG_MAX_LUNS]; -- -- unsigned int file_count, ro_count, removable_count, cdrom_count; -- unsigned int nofua_count; -- unsigned int luns; /* nluns */ -- bool stall; /* can_stall */ --}; - --#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ -- module_param_array_named(prefix ## name, params.name, type, \ -- &prefix ## params.name ## _count, \ -- S_IRUGO); \ -- MODULE_PARM_DESC(prefix ## name, desc) -- --#define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \ -- module_param_named(prefix ## name, params.name, type, \ -- S_IRUGO); \ -- MODULE_PARM_DESC(prefix ## name, desc) -- --#define FSG_MODULE_PARAMETERS(prefix, params) \ -- _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \ -- "names of backing files or devices"); \ -- _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \ -- "true to force read-only"); \ -- _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \ -- "true to simulate removable media"); \ -- _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \ -- "true to simulate CD-ROM instead of disk"); \ -- _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \ -- "true to ignore SCSI WRITE(10,12) FUA bit"); \ -- _FSG_MODULE_PARAM(prefix, params, luns, uint, \ -- "number of LUNs"); \ -- _FSG_MODULE_PARAM(prefix, params, stall, bool, \ -- "false to prevent bulk stalls") -- --static void --fsg_config_from_params(struct fsg_config *cfg, -- const struct fsg_module_parameters *params) -+void fsg_config_from_params(struct fsg_config *cfg, -+ const struct fsg_module_parameters *params, -+ unsigned int fsg_num_buffers) - { - struct fsg_lun_config *lun; - unsigned i; -@@ -3055,19 +3662,7 @@ fsg_config_from_params(struct fsg_config - - /* Finalise */ - cfg->can_stall = params->stall; -+ cfg->fsg_num_buffers = fsg_num_buffers; - } -+EXPORT_SYMBOL_GPL(fsg_config_from_params); - --static inline struct fsg_common * --fsg_common_from_params(struct fsg_common *common, -- struct usb_composite_dev *cdev, -- const struct fsg_module_parameters *params) -- __attribute__((unused)); --static inline struct fsg_common * --fsg_common_from_params(struct fsg_common *common, -- struct usb_composite_dev *cdev, -- const struct fsg_module_parameters *params) --{ -- struct fsg_config cfg; -- fsg_config_from_params(&cfg, params); -- return fsg_common_init(common, cdev, &cfg); --} ---- /dev/null -+++ b/drivers/usb/gadget/f_mass_storage.h -@@ -0,0 +1,166 @@ -+#ifndef USB_F_MASS_STORAGE_H -+#define USB_F_MASS_STORAGE_H -+ -+#include <linux/usb/composite.h> -+#include "storage_common.h" -+ -+struct fsg_module_parameters { -+ char *file[FSG_MAX_LUNS]; -+ bool ro[FSG_MAX_LUNS]; -+ bool removable[FSG_MAX_LUNS]; -+ bool cdrom[FSG_MAX_LUNS]; -+ bool nofua[FSG_MAX_LUNS]; -+ -+ unsigned int file_count, ro_count, removable_count, cdrom_count; -+ unsigned int nofua_count; -+ unsigned int luns; /* nluns */ -+ bool stall; /* can_stall */ -+}; -+ -+#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ -+ module_param_array_named(prefix ## name, params.name, type, \ -+ &prefix ## params.name ## _count, \ -+ S_IRUGO); \ -+ MODULE_PARM_DESC(prefix ## name, desc) -+ -+#define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \ -+ module_param_named(prefix ## name, params.name, type, \ -+ S_IRUGO); \ -+ MODULE_PARM_DESC(prefix ## name, desc) -+ -+#define __FSG_MODULE_PARAMETERS(prefix, params) \ -+ _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \ -+ "names of backing files or devices"); \ -+ _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \ -+ "true to force read-only"); \ -+ _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \ -+ "true to simulate removable media"); \ -+ _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \ -+ "true to simulate CD-ROM instead of disk"); \ -+ _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \ -+ "true to ignore SCSI WRITE(10,12) FUA bit"); \ -+ _FSG_MODULE_PARAM(prefix, params, luns, uint, \ -+ "number of LUNs"); \ -+ _FSG_MODULE_PARAM(prefix, params, stall, bool, \ -+ "false to prevent bulk stalls") -+ -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+ -+#define FSG_MODULE_PARAMETERS(prefix, params) \ -+ __FSG_MODULE_PARAMETERS(prefix, params); \ -+ module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\ -+ MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers") -+#else -+ -+#define FSG_MODULE_PARAMETERS(prefix, params) \ -+ __FSG_MODULE_PARAMETERS(prefix, params) -+ -+#endif -+ -+struct fsg_common; -+ -+/* FSF callback functions */ -+struct fsg_operations { -+ /* -+ * Callback function to call when thread exits. If no -+ * callback is set or it returns value lower then zero MSF -+ * will force eject all LUNs it operates on (including those -+ * marked as non-removable or with prevent_medium_removal flag -+ * set). -+ */ -+ int (*thread_exits)(struct fsg_common *common); -+}; -+ -+struct fsg_lun_opts { -+ struct config_group group; -+ struct fsg_lun *lun; -+ int lun_id; -+}; -+ -+struct fsg_opts { -+ struct fsg_common *common; -+ struct usb_function_instance func_inst; -+ struct fsg_lun_opts lun0; -+ struct config_group *default_groups[2]; -+ bool no_configfs; /* for legacy gadgets */ -+ -+ /* -+ * Read/write access to configfs attributes is handled by configfs. -+ * -+ * This is to protect the data from concurrent access by read/write -+ * and create symlink/remove symlink. -+ */ -+ struct mutex lock; -+ int refcnt; -+}; -+ -+struct fsg_lun_config { -+ const char *filename; -+ char ro; -+ char removable; -+ char cdrom; -+ char nofua; -+}; -+ -+struct fsg_config { -+ unsigned nluns; -+ struct fsg_lun_config luns[FSG_MAX_LUNS]; -+ -+ /* Callback functions. */ -+ const struct fsg_operations *ops; -+ /* Gadget's private data. */ -+ void *private_data; -+ -+ const char *vendor_name; /* 8 characters or less */ -+ const char *product_name; /* 16 characters or less */ -+ -+ char can_stall; -+ unsigned int fsg_num_buffers; -+}; -+ -+static inline struct fsg_opts * -+fsg_opts_from_func_inst(const struct usb_function_instance *fi) -+{ -+ return container_of(fi, struct fsg_opts, func_inst); -+} -+ -+void fsg_common_get(struct fsg_common *common); -+ -+void fsg_common_put(struct fsg_common *common); -+ -+void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs); -+ -+int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n); -+ -+void fsg_common_free_buffers(struct fsg_common *common); -+ -+int fsg_common_set_cdev(struct fsg_common *common, -+ struct usb_composite_dev *cdev, bool can_stall); -+ -+void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs); -+ -+void fsg_common_remove_luns(struct fsg_common *common); -+ -+void fsg_common_free_luns(struct fsg_common *common); -+ -+int fsg_common_set_nluns(struct fsg_common *common, int nluns); -+ -+void fsg_common_set_ops(struct fsg_common *common, -+ const struct fsg_operations *ops); -+ -+int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, -+ unsigned int id, const char *name, -+ const char **name_pfx); -+ -+int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg); -+ -+void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, -+ const char *pn); -+ -+int fsg_common_run_thread(struct fsg_common *common); -+ -+void fsg_config_from_params(struct fsg_config *cfg, -+ const struct fsg_module_parameters *params, -+ unsigned int fsg_num_buffers); -+ -+#endif /* USB_F_MASS_STORAGE_H */ ---- a/drivers/usb/gadget/g_ffs.c -+++ b/drivers/usb/gadget/g_ffs.c -@@ -76,7 +76,9 @@ struct gfs_ffs_obj { - - USB_GADGET_COMPOSITE_OPTIONS(); - -+#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS - USB_ETHERNET_MODULE_PARAMETERS(); -+#endif - - static struct usb_device_descriptor gfs_dev_desc = { - .bLength = sizeof gfs_dev_desc, ---- a/drivers/usb/gadget/goku_udc.c -+++ b/drivers/usb/gadget/goku_udc.c -@@ -1701,7 +1701,6 @@ static void goku_remove(struct pci_dev * - if (dev->enabled) - pci_disable_device(pdev); - -- pci_set_drvdata(pdev, NULL); - dev->regs = NULL; - - INFO(dev, "unbind\n"); ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -58,6 +58,20 @@ config USB_GADGET_DEBUG - trying to track down. Never enable these messages for a - production build. - -+config USB_GADGET_VERBOSE -+ bool "Verbose debugging Messages (DEVELOPMENT)" -+ depends on USB_GADGET_DEBUG -+ help -+ Many controller and gadget drivers will print verbose debugging -+ messages if you use this option to ask for those messages. -+ -+ Avoid enabling these messages, even if you're actively -+ debugging such a driver. Many drivers will emit so many -+ messages that the driver timings are affected, which will -+ either create new failure modes or remove the one you're -+ trying to track down. Never enable these messages for a -+ production build. -+ - config USB_GADGET_DEBUG_FILES - boolean "Debugging information files (DEVELOPMENT)" - depends on PROC_FS -@@ -525,6 +539,9 @@ config USB_F_SUBSET - config USB_F_RNDIS - tristate - -+config USB_F_MASS_STORAGE -+ tristate -+ - choice - tristate "USB Gadget Drivers" - default USB_ETH -@@ -662,6 +679,16 @@ config USB_CONFIGFS_PHONET - help - The Phonet protocol implementation for USB device. - -+config USB_CONFIGFS_MASS_STORAGE -+ boolean "Mass storage" -+ depends on USB_CONFIGFS -+ select USB_F_MASS_STORAGE -+ help -+ The Mass Storage Gadget acts as a USB Mass Storage disk drive. -+ As its storage repository it can use a regular file or a block -+ device (in much the same way as the "loop" device driver), -+ specified as a module parameter or sysfs option. -+ - config USB_ZERO - tristate "Gadget Zero (DEVELOPMENT)" - select USB_LIBCOMPOSITE -@@ -878,6 +905,7 @@ config USB_MASS_STORAGE - tristate "Mass Storage Gadget" - depends on BLOCK - select USB_LIBCOMPOSITE -+ select USB_F_MASS_STORAGE - help - The Mass Storage Gadget acts as a USB Mass Storage disk drive. - As its storage repository it can use a regular file or a block -@@ -1001,6 +1029,7 @@ config USB_G_ACM_MS - select USB_LIBCOMPOSITE - select USB_U_SERIAL - select USB_F_ACM -+ select USB_F_MASS_STORAGE - help - This driver provides two functions in one configuration: - a mass storage, and a CDC ACM (serial port) link. -@@ -1015,8 +1044,8 @@ config USB_G_MULTI - select USB_LIBCOMPOSITE - select USB_U_SERIAL - select USB_U_ETHER -- select USB_U_RNDIS - select USB_F_ACM -+ select USB_F_MASS_STORAGE - help - The Multifunction Composite Gadget provides Ethernet (RNDIS - and/or CDC Ethernet), mass storage and ACM serial link -@@ -1035,6 +1064,8 @@ config USB_G_MULTI - config USB_G_MULTI_RNDIS - bool "RNDIS + CDC Serial + Storage configuration" - depends on USB_G_MULTI -+ select USB_U_RNDIS -+ select USB_F_RNDIS - default y - help - This option enables a configuration with RNDIS, CDC Serial and -@@ -1048,6 +1079,7 @@ config USB_G_MULTI_CDC - bool "CDC Ethernet + CDC Serial + Storage configuration" - depends on USB_G_MULTI - default n -+ select USB_F_ECM - help - This option enables a configuration with CDC Ethernet (ECM), CDC - Serial and Mass Storage functions available in the Multifunction ---- a/drivers/usb/gadget/Makefile -+++ b/drivers/usb/gadget/Makefile -@@ -1,7 +1,8 @@ - # - # USB peripheral controller drivers - # --ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG -+ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG -+ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG - - obj-$(CONFIG_USB_GADGET) += udc-core.o - obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o -@@ -60,6 +61,8 @@ usb_f_ecm_subset-y := f_subset.o - obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o - usb_f_rndis-y := f_rndis.o - obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o -+usb_f_mass_storage-y := f_mass_storage.o storage_common.o -+obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o - - # - # USB gadget drivers ---- a/drivers/usb/gadget/mass_storage.c -+++ b/drivers/usb/gadget/mass_storage.c -@@ -37,16 +37,16 @@ - #define DRIVER_DESC "Mass Storage Gadget" - #define DRIVER_VERSION "2009/09/11" - --/*-------------------------------------------------------------------------*/ -- - /* -- * kbuild is not very cooperative with respect to linking separately -- * compiled library objects into one module. So for now we won't use -- * separate compilation ... ensuring init/exit sections work to shrink -- * the runtime footprint, and giving us at least some parts of what -- * a "gcc --combine ... part1.c part2.c part3.c ... " build would. -+ * Thanks to NetChip Technologies for donating this product ID. -+ * -+ * DO NOT REUSE THESE IDs with any other driver!! Ever!! -+ * Instead: allocate your own, using normal USB-IF procedures. - */ --#include "f_mass_storage.c" -+#define FSG_VENDOR_ID 0x0525 /* NetChip */ -+#define FSG_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */ -+ -+#include "f_mass_storage.h" - - /*-------------------------------------------------------------------------*/ - USB_GADGET_COMPOSITE_OPTIONS(); -@@ -97,11 +97,28 @@ static struct usb_gadget_strings *dev_st - NULL, - }; - -+static struct usb_function_instance *fi_msg; -+static struct usb_function *f_msg; -+ - /****************************** Configurations ******************************/ - - static struct fsg_module_parameters mod_data = { - .stall = 1 - }; -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+ -+static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; -+ -+#else -+ -+/* -+ * Number of buffers we will use. -+ * 2 is usually enough for good buffering pipeline -+ */ -+#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS -+ -+#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ -+ - FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); - - static unsigned long msg_registered; -@@ -115,13 +132,7 @@ static int msg_thread_exits(struct fsg_c - - static int __init msg_do_config(struct usb_configuration *c) - { -- static const struct fsg_operations ops = { -- .thread_exits = msg_thread_exits, -- }; -- static struct fsg_common common; -- -- struct fsg_common *retp; -- struct fsg_config config; -+ struct fsg_opts *opts; - int ret; - - if (gadget_is_otg(c->cdev->gadget)) { -@@ -129,15 +140,24 @@ static int __init msg_do_config(struct u - c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - -- fsg_config_from_params(&config, &mod_data); -- config.ops = &ops; -+ opts = fsg_opts_from_func_inst(fi_msg); - -- retp = fsg_common_init(&common, c->cdev, &config); -- if (IS_ERR(retp)) -- return PTR_ERR(retp); -+ f_msg = usb_get_function(fi_msg); -+ if (IS_ERR(f_msg)) -+ return PTR_ERR(f_msg); -+ -+ ret = fsg_common_run_thread(opts->common); -+ if (ret) -+ goto put_func; -+ -+ ret = usb_add_function(c, f_msg); -+ if (ret) -+ goto put_func; - -- ret = fsg_bind_config(c->cdev, c, &common); -- fsg_common_put(&common); -+ return 0; -+ -+put_func: -+ usb_put_function(f_msg); - return ret; - } - -@@ -152,23 +172,79 @@ static struct usb_configuration msg_conf - - static int __init msg_bind(struct usb_composite_dev *cdev) - { -+ static const struct fsg_operations ops = { -+ .thread_exits = msg_thread_exits, -+ }; -+ struct fsg_opts *opts; -+ struct fsg_config config; - int status; - -+ fi_msg = usb_get_function_instance("mass_storage"); -+ if (IS_ERR(fi_msg)) -+ return PTR_ERR(fi_msg); -+ -+ fsg_config_from_params(&config, &mod_data, fsg_num_buffers); -+ opts = fsg_opts_from_func_inst(fi_msg); -+ -+ opts->no_configfs = true; -+ status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers); -+ if (status) -+ goto fail; -+ -+ status = fsg_common_set_nluns(opts->common, config.nluns); -+ if (status) -+ goto fail_set_nluns; -+ -+ fsg_common_set_ops(opts->common, &ops); -+ -+ status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); -+ if (status) -+ goto fail_set_cdev; -+ -+ fsg_common_set_sysfs(opts->common, true); -+ status = fsg_common_create_luns(opts->common, &config); -+ if (status) -+ goto fail_set_cdev; -+ -+ fsg_common_set_inquiry_string(opts->common, config.vendor_name, -+ config.product_name); -+ - status = usb_string_ids_tab(cdev, strings_dev); - if (status < 0) -- return status; -+ goto fail_string_ids; - msg_device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; - - status = usb_add_config(cdev, &msg_config_driver, msg_do_config); - if (status < 0) -- return status; -+ goto fail_string_ids; -+ - usb_composite_overwrite_options(cdev, &coverwrite); - dev_info(&cdev->gadget->dev, - DRIVER_DESC ", version: " DRIVER_VERSION "\n"); - set_bit(0, &msg_registered); - return 0; -+ -+fail_string_ids: -+ fsg_common_remove_luns(opts->common); -+fail_set_cdev: -+ fsg_common_free_luns(opts->common); -+fail_set_nluns: -+ fsg_common_free_buffers(opts->common); -+fail: -+ usb_put_function_instance(fi_msg); -+ return status; - } - -+static int msg_unbind(struct usb_composite_dev *cdev) -+{ -+ if (!IS_ERR(f_msg)) -+ usb_put_function(f_msg); -+ -+ if (!IS_ERR(fi_msg)) -+ usb_put_function_instance(fi_msg); -+ -+ return 0; -+} - - /****************************** Some noise ******************************/ - -@@ -179,6 +255,7 @@ static __refdata struct usb_composite_dr - .needs_serial = 1, - .strings = dev_strings, - .bind = msg_bind, -+ .unbind = msg_unbind, - }; - - MODULE_DESCRIPTION(DRIVER_DESC); ---- a/drivers/usb/gadget/multi.c -+++ b/drivers/usb/gadget/multi.c -@@ -15,6 +15,7 @@ - - #include <linux/kernel.h> - #include <linux/module.h> -+#include <linux/netdevice.h> - - #include "u_serial.h" - #if defined USB_ETH_RNDIS -@@ -32,22 +33,11 @@ MODULE_AUTHOR("Michal Nazarewicz"); - MODULE_LICENSE("GPL"); - - --/***************************** All the files... *****************************/ -+#include "f_mass_storage.h" - --/* -- * kbuild is not very cooperative with respect to linking separately -- * compiled library objects into one module. So for now we won't use -- * separate compilation ... ensuring init/exit sections work to shrink -- * the runtime footprint, and giving us at least some parts of what -- * a "gcc --combine ... part1.c part2.c part3.c ... " build would. -- */ --#include "f_mass_storage.c" -- --#define USBF_ECM_INCLUDED --#include "f_ecm.c" -+#include "u_ecm.h" - #ifdef USB_ETH_RNDIS --# define USB_FRNDIS_INCLUDED --# include "f_rndis.c" -+# include "u_rndis.h" - # include "rndis.h" - #endif - #include "u_ether.h" -@@ -132,22 +122,36 @@ static struct usb_gadget_strings *dev_st - /****************************** Configurations ******************************/ - - static struct fsg_module_parameters fsg_mod_data = { .stall = 1 }; --FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+ -+static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; -+ -+#else -+ -+/* -+ * Number of buffers we will use. -+ * 2 is usually enough for good buffering pipeline -+ */ -+#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS - --static struct fsg_common fsg_common; -+#endif /* CONFIG_USB_DEBUG */ - --static u8 host_mac[ETH_ALEN]; -+FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); - - static struct usb_function_instance *fi_acm; --static struct eth_dev *the_dev; -+static struct usb_function_instance *fi_msg; - - /********** RNDIS **********/ - - #ifdef USB_ETH_RNDIS -+static struct usb_function_instance *fi_rndis; - static struct usb_function *f_acm_rndis; -+static struct usb_function *f_rndis; -+static struct usb_function *f_msg_rndis; - - static __init int rndis_do_config(struct usb_configuration *c) - { -+ struct fsg_opts *fsg_opts; - int ret; - - if (gadget_is_otg(c->cdev->gadget)) { -@@ -155,27 +159,50 @@ static __init int rndis_do_config(struct - c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - -- ret = rndis_bind_config(c, host_mac, the_dev); -+ f_rndis = usb_get_function(fi_rndis); -+ if (IS_ERR(f_rndis)) -+ return PTR_ERR(f_rndis); -+ -+ ret = usb_add_function(c, f_rndis); - if (ret < 0) -- return ret; -+ goto err_func_rndis; - - f_acm_rndis = usb_get_function(fi_acm); -- if (IS_ERR(f_acm_rndis)) -- return PTR_ERR(f_acm_rndis); -+ if (IS_ERR(f_acm_rndis)) { -+ ret = PTR_ERR(f_acm_rndis); -+ goto err_func_acm; -+ } - - ret = usb_add_function(c, f_acm_rndis); - if (ret) - goto err_conf; - -- ret = fsg_bind_config(c->cdev, c, &fsg_common); -- if (ret < 0) -+ f_msg_rndis = usb_get_function(fi_msg); -+ if (IS_ERR(f_msg_rndis)) { -+ ret = PTR_ERR(f_msg_rndis); - goto err_fsg; -+ } -+ -+ fsg_opts = fsg_opts_from_func_inst(fi_msg); -+ ret = fsg_common_run_thread(fsg_opts->common); -+ if (ret) -+ goto err_run; -+ -+ ret = usb_add_function(c, f_msg_rndis); -+ if (ret) -+ goto err_run; - - return 0; -+err_run: -+ usb_put_function(f_msg_rndis); - err_fsg: - usb_remove_function(c, f_acm_rndis); - err_conf: - usb_put_function(f_acm_rndis); -+err_func_acm: -+ usb_remove_function(c, f_rndis); -+err_func_rndis: -+ usb_put_function(f_rndis); - return ret; - } - -@@ -205,10 +232,14 @@ static __ref int rndis_config_register(s - /********** CDC ECM **********/ - - #ifdef CONFIG_USB_G_MULTI_CDC -+static struct usb_function_instance *fi_ecm; - static struct usb_function *f_acm_multi; -+static struct usb_function *f_ecm; -+static struct usb_function *f_msg_multi; - - static __init int cdc_do_config(struct usb_configuration *c) - { -+ struct fsg_opts *fsg_opts; - int ret; - - if (gadget_is_otg(c->cdev->gadget)) { -@@ -216,28 +247,51 @@ static __init int cdc_do_config(struct u - c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - -- ret = ecm_bind_config(c, host_mac, the_dev); -+ f_ecm = usb_get_function(fi_ecm); -+ if (IS_ERR(f_ecm)) -+ return PTR_ERR(f_ecm); -+ -+ ret = usb_add_function(c, f_ecm); - if (ret < 0) -- return ret; -+ goto err_func_ecm; - - /* implicit port_num is zero */ - f_acm_multi = usb_get_function(fi_acm); -- if (IS_ERR(f_acm_multi)) -- return PTR_ERR(f_acm_multi); -+ if (IS_ERR(f_acm_multi)) { -+ ret = PTR_ERR(f_acm_multi); -+ goto err_func_acm; -+ } - - ret = usb_add_function(c, f_acm_multi); - if (ret) - goto err_conf; - -- ret = fsg_bind_config(c->cdev, c, &fsg_common); -- if (ret < 0) -+ f_msg_multi = usb_get_function(fi_msg); -+ if (IS_ERR(f_msg_multi)) { -+ ret = PTR_ERR(f_msg_multi); - goto err_fsg; -+ } -+ -+ fsg_opts = fsg_opts_from_func_inst(fi_msg); -+ ret = fsg_common_run_thread(fsg_opts->common); -+ if (ret) -+ goto err_run; -+ -+ ret = usb_add_function(c, f_msg_multi); -+ if (ret) -+ goto err_run; - - return 0; -+err_run: -+ usb_put_function(f_msg_multi); - err_fsg: - usb_remove_function(c, f_acm_multi); - err_conf: - usb_put_function(f_acm_multi); -+err_func_acm: -+ usb_remove_function(c, f_ecm); -+err_func_ecm: -+ usb_put_function(f_ecm); - return ret; - } - -@@ -270,19 +324,67 @@ static __ref int cdc_config_register(str - static int __ref multi_bind(struct usb_composite_dev *cdev) - { - struct usb_gadget *gadget = cdev->gadget; -+#ifdef CONFIG_USB_G_MULTI_CDC -+ struct f_ecm_opts *ecm_opts; -+#endif -+#ifdef USB_ETH_RNDIS -+ struct f_rndis_opts *rndis_opts; -+#endif -+ struct fsg_opts *fsg_opts; -+ struct fsg_config config; - int status; - - if (!can_support_ecm(cdev->gadget)) { - dev_err(&gadget->dev, "controller '%s' not usable\n", -- gadget->name); -+ gadget->name); - return -EINVAL; - } - -- /* set up network link layer */ -- the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac, -- qmult); -- if (IS_ERR(the_dev)) -- return PTR_ERR(the_dev); -+#ifdef CONFIG_USB_G_MULTI_CDC -+ fi_ecm = usb_get_function_instance("ecm"); -+ if (IS_ERR(fi_ecm)) -+ return PTR_ERR(fi_ecm); -+ -+ ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst); -+ -+ gether_set_qmult(ecm_opts->net, qmult); -+ if (!gether_set_host_addr(ecm_opts->net, host_addr)) -+ pr_info("using host ethernet address: %s", host_addr); -+ if (!gether_set_dev_addr(ecm_opts->net, dev_addr)) -+ pr_info("using self ethernet address: %s", dev_addr); -+#endif -+ -+#ifdef USB_ETH_RNDIS -+ fi_rndis = usb_get_function_instance("rndis"); -+ if (IS_ERR(fi_rndis)) { -+ status = PTR_ERR(fi_rndis); -+ goto fail; -+ } -+ -+ rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst); -+ -+ gether_set_qmult(rndis_opts->net, qmult); -+ if (!gether_set_host_addr(rndis_opts->net, host_addr)) -+ pr_info("using host ethernet address: %s", host_addr); -+ if (!gether_set_dev_addr(rndis_opts->net, dev_addr)) -+ pr_info("using self ethernet address: %s", dev_addr); -+#endif -+ -+#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS) -+ /* -+ * If both ecm and rndis are selected then: -+ * 1) rndis borrows the net interface from ecm -+ * 2) since the interface is shared it must not be bound -+ * twice - in ecm's _and_ rndis' binds, so do it here. -+ */ -+ gether_set_gadget(ecm_opts->net, cdev->gadget); -+ status = gether_register_netdev(ecm_opts->net); -+ if (status) -+ goto fail0; -+ -+ rndis_borrow_net(fi_rndis, ecm_opts->net); -+ ecm_opts->bound = true; -+#endif - - /* set up serial link layer */ - fi_acm = usb_get_function_instance("acm"); -@@ -292,57 +394,102 @@ static int __ref multi_bind(struct usb_c - } - - /* set up mass storage function */ -- { -- void *retp; -- retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data); -- if (IS_ERR(retp)) { -- status = PTR_ERR(retp); -- goto fail1; -- } -+ fi_msg = usb_get_function_instance("mass_storage"); -+ if (IS_ERR(fi_msg)) { -+ status = PTR_ERR(fi_msg); -+ goto fail1; - } -+ fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers); -+ fsg_opts = fsg_opts_from_func_inst(fi_msg); -+ -+ fsg_opts->no_configfs = true; -+ status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers); -+ if (status) -+ goto fail2; -+ -+ status = fsg_common_set_nluns(fsg_opts->common, config.nluns); -+ if (status) -+ goto fail_set_nluns; -+ -+ status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall); -+ if (status) -+ goto fail_set_cdev; -+ -+ fsg_common_set_sysfs(fsg_opts->common, true); -+ status = fsg_common_create_luns(fsg_opts->common, &config); -+ if (status) -+ goto fail_set_cdev; -+ -+ fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name, -+ config.product_name); - - /* allocate string IDs */ - status = usb_string_ids_tab(cdev, strings_dev); - if (unlikely(status < 0)) -- goto fail2; -+ goto fail_string_ids; - device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; - - /* register configurations */ - status = rndis_config_register(cdev); - if (unlikely(status < 0)) -- goto fail2; -+ goto fail_string_ids; - - status = cdc_config_register(cdev); - if (unlikely(status < 0)) -- goto fail2; -+ goto fail_string_ids; - usb_composite_overwrite_options(cdev, &coverwrite); - - /* we're done */ - dev_info(&gadget->dev, DRIVER_DESC "\n"); -- fsg_common_put(&fsg_common); - return 0; - - - /* error recovery */ -+fail_string_ids: -+ fsg_common_remove_luns(fsg_opts->common); -+fail_set_cdev: -+ fsg_common_free_luns(fsg_opts->common); -+fail_set_nluns: -+ fsg_common_free_buffers(fsg_opts->common); - fail2: -- fsg_common_put(&fsg_common); -+ usb_put_function_instance(fi_msg); - fail1: - usb_put_function_instance(fi_acm); - fail0: -- gether_cleanup(the_dev); -+#ifdef USB_ETH_RNDIS -+ usb_put_function_instance(fi_rndis); -+fail: -+#endif -+#ifdef CONFIG_USB_G_MULTI_CDC -+ usb_put_function_instance(fi_ecm); -+#endif - return status; - } - - static int __exit multi_unbind(struct usb_composite_dev *cdev) - { - #ifdef CONFIG_USB_G_MULTI_CDC -+ usb_put_function(f_msg_multi); -+#endif -+#ifdef USB_ETH_RNDIS -+ usb_put_function(f_msg_rndis); -+#endif -+ usb_put_function_instance(fi_msg); -+#ifdef CONFIG_USB_G_MULTI_CDC - usb_put_function(f_acm_multi); - #endif - #ifdef USB_ETH_RNDIS - usb_put_function(f_acm_rndis); - #endif - usb_put_function_instance(fi_acm); -- gether_cleanup(the_dev); -+#ifdef USB_ETH_RNDIS -+ usb_put_function(f_rndis); -+ usb_put_function_instance(fi_rndis); -+#endif -+#ifdef CONFIG_USB_G_MULTI_CDC -+ usb_put_function(f_ecm); -+ usb_put_function_instance(fi_ecm); -+#endif - return 0; - } - ---- a/drivers/usb/gadget/mv_u3d_core.c -+++ b/drivers/usb/gadget/mv_u3d_core.c -@@ -310,6 +310,7 @@ static struct mv_u3d_trb *mv_u3d_build_t - */ - trb_hw = dma_pool_alloc(u3d->trb_pool, GFP_ATOMIC, dma); - if (!trb_hw) { -+ kfree(trb); - dev_err(u3d->dev, - "%s, dma_pool_alloc fail\n", __func__); - return NULL; -@@ -454,6 +455,7 @@ static int mv_u3d_req_to_trb(struct mv_u - - trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC); - if (!trb_hw) { -+ kfree(trb); - dev_err(u3d->dev, - "%s, trb_hw alloc fail\n", __func__); - return -ENOMEM; -@@ -1936,7 +1938,7 @@ static int mv_u3d_probe(struct platform_ - } - u3d->irq = r->start; - if (request_irq(u3d->irq, mv_u3d_irq, -- IRQF_DISABLED | IRQF_SHARED, driver_name, u3d)) { -+ IRQF_SHARED, driver_name, u3d)) { - u3d->irq = 0; - dev_err(&dev->dev, "Request irq %d for u3d failed\n", - u3d->irq); ---- a/drivers/usb/gadget/net2280.c -+++ b/drivers/usb/gadget/net2280.c -@@ -2680,7 +2680,6 @@ static void net2280_remove (struct pci_d - if (dev->enabled) - pci_disable_device (pdev); - device_remove_file (&pdev->dev, &dev_attr_registers); -- pci_set_drvdata (pdev, NULL); - - INFO (dev, "unbind\n"); - } ---- a/drivers/usb/gadget/pch_udc.c -+++ b/drivers/usb/gadget/pch_udc.c -@@ -3080,7 +3080,6 @@ static void pch_udc_remove(struct pci_de - if (dev->active) - pci_disable_device(pdev); - kfree(dev); -- pci_set_drvdata(pdev, NULL); - } - - #ifdef CONFIG_PM ---- a/drivers/usb/gadget/s3c-hsotg.c -+++ b/drivers/usb/gadget/s3c-hsotg.c -@@ -83,9 +83,12 @@ struct s3c_hsotg_req; - * @dir_in: Set to true if this endpoint is of the IN direction, which - * means that it is sending data to the Host. - * @index: The index for the endpoint registers. -+ * @mc: Multi Count - number of transactions per microframe -+ * @interval - Interval for periodic endpoints - * @name: The name array passed to the USB core. - * @halted: Set if the endpoint has been halted. - * @periodic: Set if this is a periodic ep, such as Interrupt -+ * @isochronous: Set if this is a isochronous ep - * @sent_zlp: Set if we've sent a zero-length packet. - * @total_data: The total number of data bytes done. - * @fifo_size: The size of the FIFO (for periodic IN endpoints) -@@ -121,9 +124,12 @@ struct s3c_hsotg_ep { - - unsigned char dir_in; - unsigned char index; -+ unsigned char mc; -+ unsigned char interval; - - unsigned int halted:1; - unsigned int periodic:1; -+ unsigned int isochronous:1; - unsigned int sent_zlp:1; - - char name[10]; -@@ -468,6 +474,7 @@ static int s3c_hsotg_write_fifo(struct s - void *data; - int can_write; - int pkt_round; -+ int max_transfer; - - to_write -= (buf_pos - hs_ep->last_load); - -@@ -535,8 +542,10 @@ static int s3c_hsotg_write_fifo(struct s - can_write *= 4; /* fifo size is in 32bit quantities. */ - } - -- dev_dbg(hsotg->dev, "%s: GNPTXSTS=%08x, can=%d, to=%d, mps %d\n", -- __func__, gnptxsts, can_write, to_write, hs_ep->ep.maxpacket); -+ max_transfer = hs_ep->ep.maxpacket * hs_ep->mc; -+ -+ dev_dbg(hsotg->dev, "%s: GNPTXSTS=%08x, can=%d, to=%d, max_transfer %d\n", -+ __func__, gnptxsts, can_write, to_write, max_transfer); - - /* - * limit to 512 bytes of data, it seems at least on the non-periodic -@@ -551,19 +560,21 @@ static int s3c_hsotg_write_fifo(struct s - * the transfer to return that it did not run out of fifo space - * doing it. - */ -- if (to_write > hs_ep->ep.maxpacket) { -- to_write = hs_ep->ep.maxpacket; -+ if (to_write > max_transfer) { -+ to_write = max_transfer; - -- s3c_hsotg_en_gsint(hsotg, -- periodic ? GINTSTS_PTxFEmp : -- GINTSTS_NPTxFEmp); -+ /* it's needed only when we do not use dedicated fifos */ -+ if (!hsotg->dedicated_fifos) -+ s3c_hsotg_en_gsint(hsotg, -+ periodic ? GINTSTS_PTxFEmp : -+ GINTSTS_NPTxFEmp); - } - - /* see if we can write data */ - - if (to_write > can_write) { - to_write = can_write; -- pkt_round = to_write % hs_ep->ep.maxpacket; -+ pkt_round = to_write % max_transfer; - - /* - * Round the write down to an -@@ -581,9 +592,11 @@ static int s3c_hsotg_write_fifo(struct s - * is more room left. - */ - -- s3c_hsotg_en_gsint(hsotg, -- periodic ? GINTSTS_PTxFEmp : -- GINTSTS_NPTxFEmp); -+ /* it's needed only when we do not use dedicated fifos */ -+ if (!hsotg->dedicated_fifos) -+ s3c_hsotg_en_gsint(hsotg, -+ periodic ? GINTSTS_PTxFEmp : -+ GINTSTS_NPTxFEmp); - } - - dev_dbg(hsotg->dev, "write %d/%d, can_write %d, done %d\n", -@@ -727,8 +740,16 @@ static void s3c_hsotg_start_req(struct s - else - packets = 1; /* send one packet if length is zero. */ - -+ if (hs_ep->isochronous && length > (hs_ep->mc * hs_ep->ep.maxpacket)) { -+ dev_err(hsotg->dev, "req length > maxpacket*mc\n"); -+ return; -+ } -+ - if (dir_in && index != 0) -- epsize = DxEPTSIZ_MC(1); -+ if (hs_ep->isochronous) -+ epsize = DxEPTSIZ_MC(packets); -+ else -+ epsize = DxEPTSIZ_MC(1); - else - epsize = 0; - -@@ -820,6 +841,9 @@ static void s3c_hsotg_start_req(struct s - - dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", - __func__, readl(hsotg->regs + epctrl_reg)); -+ -+ /* enable ep interrupts */ -+ s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1); - } - - /** -@@ -1091,6 +1115,7 @@ static int s3c_hsotg_process_req_feature - bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); - struct s3c_hsotg_ep *ep; - int ret; -+ bool halted; - - dev_dbg(hsotg->dev, "%s: %s_FEATURE\n", - __func__, set ? "SET" : "CLEAR"); -@@ -1105,6 +1130,8 @@ static int s3c_hsotg_process_req_feature - - switch (le16_to_cpu(ctrl->wValue)) { - case USB_ENDPOINT_HALT: -+ halted = ep->halted; -+ - s3c_hsotg_ep_sethalt(&ep->ep, set); - - ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); -@@ -1114,7 +1141,12 @@ static int s3c_hsotg_process_req_feature - return ret; - } - -- if (!set) { -+ /* -+ * we have to complete all requests for ep if it was -+ * halted, and the halt was cleared by CLEAR_FEATURE -+ */ -+ -+ if (!set && halted) { - /* - * If we have request in progress, - * then complete it -@@ -1147,6 +1179,8 @@ static int s3c_hsotg_process_req_feature - return 1; - } - -+static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); -+ - /** - * s3c_hsotg_process_control - process a control request - * @hsotg: The device state -@@ -1246,11 +1280,15 @@ static void s3c_hsotg_process_control(st - * don't believe we need to anything more to get the EP - * to reply with a STALL packet - */ -+ -+ /* -+ * complete won't be called, so we enqueue -+ * setup request here -+ */ -+ s3c_hsotg_enqueue_setup(hsotg); - } - } - --static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); -- - /** - * s3c_hsotg_complete_setup - completion of a setup transfer - * @ep: The endpoint the request was on. -@@ -1698,6 +1736,7 @@ static void s3c_hsotg_set_ep_maxpacket(s - struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep]; - void __iomem *regs = hsotg->regs; - u32 mpsval; -+ u32 mcval; - u32 reg; - - if (ep == 0) { -@@ -1705,15 +1744,19 @@ static void s3c_hsotg_set_ep_maxpacket(s - mpsval = s3c_hsotg_ep0_mps(mps); - if (mpsval > 3) - goto bad_mps; -+ hs_ep->ep.maxpacket = mps; -+ hs_ep->mc = 1; - } else { -- if (mps >= DxEPCTL_MPS_LIMIT+1) -+ mpsval = mps & DxEPCTL_MPS_MASK; -+ if (mpsval > 1024) - goto bad_mps; -- -- mpsval = mps; -+ mcval = ((mps >> 11) & 0x3) + 1; -+ hs_ep->mc = mcval; -+ if (mcval > 3) -+ goto bad_mps; -+ hs_ep->ep.maxpacket = mpsval; - } - -- hs_ep->ep.maxpacket = mps; -- - /* - * update both the in and out endpoint controldir_ registers, even - * if one of the directions may not be in use. -@@ -1782,8 +1825,16 @@ static int s3c_hsotg_trytx(struct s3c_hs - { - struct s3c_hsotg_req *hs_req = hs_ep->req; - -- if (!hs_ep->dir_in || !hs_req) -+ if (!hs_ep->dir_in || !hs_req) { -+ /** -+ * if request is not enqueued, we disable interrupts -+ * for endpoints, excepting ep0 -+ */ -+ if (hs_ep->index != 0) -+ s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, -+ hs_ep->dir_in, 0); - return 0; -+ } - - if (hs_req->req.actual < hs_req->req.length) { - dev_dbg(hsotg->dev, "trying to write more for ep%d\n", -@@ -1887,8 +1938,10 @@ static void s3c_hsotg_epint(struct s3c_h - u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx); - u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx); - u32 ints; -+ u32 ctrl; - - ints = readl(hsotg->regs + epint_reg); -+ ctrl = readl(hsotg->regs + epctl_reg); - - /* Clear endpoint interrupts */ - writel(ints, hsotg->regs + epint_reg); -@@ -1897,6 +1950,14 @@ static void s3c_hsotg_epint(struct s3c_h - __func__, idx, dir_in ? "in" : "out", ints); - - if (ints & DxEPINT_XferCompl) { -+ if (hs_ep->isochronous && hs_ep->interval == 1) { -+ if (ctrl & DxEPCTL_EOFrNum) -+ ctrl |= DxEPCTL_SetEvenFr; -+ else -+ ctrl |= DxEPCTL_SetOddFr; -+ writel(ctrl, hsotg->regs + epctl_reg); -+ } -+ - dev_dbg(hsotg->dev, - "%s: XferCompl: DxEPCTL=0x%08x, DxEPTSIZ=%08x\n", - __func__, readl(hsotg->regs + epctl_reg), -@@ -1963,7 +2024,7 @@ static void s3c_hsotg_epint(struct s3c_h - if (ints & DxEPINT_Back2BackSetup) - dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__); - -- if (dir_in) { -+ if (dir_in && !hs_ep->isochronous) { - /* not sure if this is important, but we'll clear it anyway */ - if (ints & DIEPMSK_INTknTXFEmpMsk) { - dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n", -@@ -2092,12 +2153,14 @@ static void kill_all_requests(struct s3c - } - - #define call_gadget(_hs, _entry) \ -+do { \ - if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ - (_hs)->driver && (_hs)->driver->_entry) { \ - spin_unlock(&_hs->lock); \ - (_hs)->driver->_entry(&(_hs)->gadget); \ - spin_lock(&_hs->lock); \ -- } -+ } \ -+} while (0) - - /** - * s3c_hsotg_disconnect - disconnect service -@@ -2241,15 +2304,19 @@ static void s3c_hsotg_core_init(struct s - GAHBCFG_HBstLen_Incr4, - hsotg->regs + GAHBCFG); - else -- writel(GAHBCFG_GlblIntrEn, hsotg->regs + GAHBCFG); -+ writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NPTxFEmpLvl | -+ GAHBCFG_PTxFEmpLvl) : 0) | -+ GAHBCFG_GlblIntrEn, -+ hsotg->regs + GAHBCFG); - - /* -- * Enabling INTknTXFEmpMsk here seems to be a big mistake, we end -- * up being flooded with interrupts if the host is polling the -- * endpoint to try and read data. -+ * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts -+ * when we have no data to transfer. Otherwise we get being flooded by -+ * interrupts. - */ - -- writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty : 0) | -+ writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty | -+ DIEPMSK_INTknTXFEmpMsk : 0) | - DIEPMSK_EPDisbldMsk | DIEPMSK_XferComplMsk | - DIEPMSK_TimeOUTMsk | DIEPMSK_AHBErrMsk | - DIEPMSK_INTknEPMisMsk, -@@ -2378,10 +2445,14 @@ irq_retry: - - if (gintsts & (GINTSTS_OEPInt | GINTSTS_IEPInt)) { - u32 daint = readl(hsotg->regs + DAINT); -- u32 daint_out = daint >> DAINT_OutEP_SHIFT; -- u32 daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT); -+ u32 daintmsk = readl(hsotg->regs + DAINTMSK); -+ u32 daint_out, daint_in; - int ep; - -+ daint &= daintmsk; -+ daint_out = daint >> DAINT_OutEP_SHIFT; -+ daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT); -+ - dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint); - - for (ep = 0; ep < 15 && daint_out; ep++, daint_out >>= 1) { -@@ -2577,16 +2648,25 @@ static int s3c_hsotg_ep_enable(struct us - epctrl |= DxEPCTL_SNAK; - - /* update the endpoint state */ -- hs_ep->ep.maxpacket = mps; -+ s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps); - - /* default, set to non-periodic */ -+ hs_ep->isochronous = 0; - hs_ep->periodic = 0; -+ hs_ep->halted = 0; -+ hs_ep->interval = desc->bInterval; -+ -+ if (hs_ep->interval > 1 && hs_ep->mc > 1) -+ dev_err(hsotg->dev, "MC > 1 when interval is not 1\n"); - - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_ISOC: -- dev_err(hsotg->dev, "no current ISOC support\n"); -- ret = -EINVAL; -- goto out; -+ epctrl |= DxEPCTL_EPType_Iso; -+ epctrl |= DxEPCTL_SetEvenFr; -+ hs_ep->isochronous = 1; -+ if (dir_in) -+ hs_ep->periodic = 1; -+ break; - - case USB_ENDPOINT_XFER_BULK: - epctrl |= DxEPCTL_EPType_Bulk; -@@ -2634,7 +2714,6 @@ static int s3c_hsotg_ep_enable(struct us - /* enable the endpoint interrupt */ - s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); - --out: - spin_unlock_irqrestore(&hsotg->lock, flags); - return ret; - } -@@ -2776,6 +2855,8 @@ static int s3c_hsotg_ep_sethalt(struct u - - writel(epctl, hs->regs + epreg); - -+ hs_ep->halted = value; -+ - return 0; - } - -@@ -2903,7 +2984,7 @@ static int s3c_hsotg_udc_start(struct us - int ret; - - if (!hsotg) { -- printk(KERN_ERR "%s: called with no device\n", __func__); -+ pr_err("%s: called with no device\n", __func__); - return -ENODEV; - } - -@@ -3066,7 +3147,7 @@ static void s3c_hsotg_initep(struct s3c_ - - hs_ep->parent = hsotg; - hs_ep->ep.name = hs_ep->name; -- hs_ep->ep.maxpacket = epnum ? 512 : EP0_MPS_LIMIT; -+ hs_ep->ep.maxpacket = epnum ? 1024 : EP0_MPS_LIMIT; - hs_ep->ep.ops = &s3c_hsotg_ep_ops; - - /* -@@ -3200,7 +3281,7 @@ static int state_show(struct seq_file *s - readl(regs + GNPTXSTS), - readl(regs + GRXSTSR)); - -- seq_printf(seq, "\nEndpoint status:\n"); -+ seq_puts(seq, "\nEndpoint status:\n"); - - for (idx = 0; idx < 15; idx++) { - u32 in, out; -@@ -3217,7 +3298,7 @@ static int state_show(struct seq_file *s - seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x", - in, out); - -- seq_printf(seq, "\n"); -+ seq_puts(seq, "\n"); - } - - return 0; -@@ -3251,7 +3332,7 @@ static int fifo_show(struct seq_file *se - u32 val; - int idx; - -- seq_printf(seq, "Non-periodic FIFOs:\n"); -+ seq_puts(seq, "Non-periodic FIFOs:\n"); - seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ)); - - val = readl(regs + GNPTXFSIZ); -@@ -3259,7 +3340,7 @@ static int fifo_show(struct seq_file *se - val >> GNPTXFSIZ_NPTxFDep_SHIFT, - val & GNPTXFSIZ_NPTxFStAddr_MASK); - -- seq_printf(seq, "\nPeriodic TXFIFOs:\n"); -+ seq_puts(seq, "\nPeriodic TXFIFOs:\n"); - - for (idx = 1; idx <= 15; idx++) { - val = readl(regs + DPTXFSIZn(idx)); -@@ -3330,7 +3411,7 @@ static int ep_show(struct seq_file *seq, - readl(regs + DIEPTSIZ(index)), - readl(regs + DOEPTSIZ(index))); - -- seq_printf(seq, "\n"); -+ seq_puts(seq, "\n"); - seq_printf(seq, "mps %d\n", ep->ep.maxpacket); - seq_printf(seq, "total_data=%ld\n", ep->total_data); - -@@ -3341,7 +3422,7 @@ static int ep_show(struct seq_file *seq, - - list_for_each_entry(req, &ep->queue, queue) { - if (--show_limit < 0) { -- seq_printf(seq, "not showing more requests...\n"); -+ seq_puts(seq, "not showing more requests...\n"); - break; - } - ---- a/drivers/usb/gadget/storage_common.c -+++ b/drivers/usb/gadget/storage_common.c -@@ -23,242 +23,17 @@ - * The valid range of num_buffers is: num >= 2 && num <= 4. - */ - -+#include <linux/module.h> -+#include <linux/blkdev.h> -+#include <linux/file.h> -+#include <linux/fs.h> -+#include <linux/usb/composite.h> - --#include <linux/usb/storage.h> --#include <scsi/scsi.h> --#include <asm/unaligned.h> -- -- --/* -- * Thanks to NetChip Technologies for donating this product ID. -- * -- * DO NOT REUSE THESE IDs with any other driver!! Ever!! -- * Instead: allocate your own, using normal USB-IF procedures. -- */ --#define FSG_VENDOR_ID 0x0525 /* NetChip */ --#define FSG_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */ -- -- --/*-------------------------------------------------------------------------*/ -- -- --#ifndef DEBUG --#undef VERBOSE_DEBUG --#undef DUMP_MSGS --#endif /* !DEBUG */ -- --#ifdef VERBOSE_DEBUG --#define VLDBG LDBG --#else --#define VLDBG(lun, fmt, args...) do { } while (0) --#endif /* VERBOSE_DEBUG */ -- --#define LDBG(lun, fmt, args...) dev_dbg (&(lun)->dev, fmt, ## args) --#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args) --#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args) --#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args) -- -- --#ifdef DUMP_MSGS -- --# define dump_msg(fsg, /* const char * */ label, \ -- /* const u8 * */ buf, /* unsigned */ length) do { \ -- if (length < 512) { \ -- DBG(fsg, "%s, length %u:\n", label, length); \ -- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \ -- 16, 1, buf, length, 0); \ -- } \ --} while (0) -- --# define dump_cdb(fsg) do { } while (0) -- --#else -- --# define dump_msg(fsg, /* const char * */ label, \ -- /* const u8 * */ buf, /* unsigned */ length) do { } while (0) -- --# ifdef VERBOSE_DEBUG -- --# define dump_cdb(fsg) \ -- print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, \ -- 16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0) \ -- --# else -- --# define dump_cdb(fsg) do { } while (0) -- --# endif /* VERBOSE_DEBUG */ -- --#endif /* DUMP_MSGS */ -- --/*-------------------------------------------------------------------------*/ -- --/* Length of a SCSI Command Data Block */ --#define MAX_COMMAND_SIZE 16 -- --/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ --#define SS_NO_SENSE 0 --#define SS_COMMUNICATION_FAILURE 0x040800 --#define SS_INVALID_COMMAND 0x052000 --#define SS_INVALID_FIELD_IN_CDB 0x052400 --#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 --#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 --#define SS_MEDIUM_NOT_PRESENT 0x023a00 --#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 --#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 --#define SS_RESET_OCCURRED 0x062900 --#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 --#define SS_UNRECOVERED_READ_ERROR 0x031100 --#define SS_WRITE_ERROR 0x030c02 --#define SS_WRITE_PROTECTED 0x072700 -- --#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ --#define ASC(x) ((u8) ((x) >> 8)) --#define ASCQ(x) ((u8) (x)) -- -- --/*-------------------------------------------------------------------------*/ -- -- --struct fsg_lun { -- struct file *filp; -- loff_t file_length; -- loff_t num_sectors; -- -- unsigned int initially_ro:1; -- unsigned int ro:1; -- unsigned int removable:1; -- unsigned int cdrom:1; -- unsigned int prevent_medium_removal:1; -- unsigned int registered:1; -- unsigned int info_valid:1; -- unsigned int nofua:1; -- -- u32 sense_data; -- u32 sense_data_info; -- u32 unit_attention_data; -- -- unsigned int blkbits; /* Bits of logical block size of bound block device */ -- unsigned int blksize; /* logical block size of bound block device */ -- struct device dev; --}; -- --static inline bool fsg_lun_is_open(struct fsg_lun *curlun) --{ -- return curlun->filp != NULL; --} -- --static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev) --{ -- return container_of(dev, struct fsg_lun, dev); --} -- -- --/* Big enough to hold our biggest descriptor */ --#define EP0_BUFSIZE 256 --#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ -- --#ifdef CONFIG_USB_GADGET_DEBUG_FILES -- --static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; --module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO); --MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers"); -- --#else -- --/* -- * Number of buffers we will use. -- * 2 is usually enough for good buffering pipeline -- */ --#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS -- --#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ -- --/* check if fsg_num_buffers is within a valid range */ --static inline int fsg_num_buffers_validate(void) --{ -- if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) -- return 0; -- pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", -- fsg_num_buffers, 2 ,4); -- return -EINVAL; --} -- --/* Default size of buffer length. */ --#define FSG_BUFLEN ((u32)16384) -- --/* Maximal number of LUNs supported in mass storage function */ --#define FSG_MAX_LUNS 8 -- --enum fsg_buffer_state { -- BUF_STATE_EMPTY = 0, -- BUF_STATE_FULL, -- BUF_STATE_BUSY --}; -- --struct fsg_buffhd { -- void *buf; -- enum fsg_buffer_state state; -- struct fsg_buffhd *next; -- -- /* -- * The NetChip 2280 is faster, and handles some protocol faults -- * better, if we don't submit any short bulk-out read requests. -- * So we will record the intended request length here. -- */ -- unsigned int bulk_out_intended_length; -- -- struct usb_request *inreq; -- int inreq_busy; -- struct usb_request *outreq; -- int outreq_busy; --}; -- --enum fsg_state { -- /* This one isn't used anywhere */ -- FSG_STATE_COMMAND_PHASE = -10, -- FSG_STATE_DATA_PHASE, -- FSG_STATE_STATUS_PHASE, -- -- FSG_STATE_IDLE = 0, -- FSG_STATE_ABORT_BULK_OUT, -- FSG_STATE_RESET, -- FSG_STATE_INTERFACE_CHANGE, -- FSG_STATE_CONFIG_CHANGE, -- FSG_STATE_DISCONNECT, -- FSG_STATE_EXIT, -- FSG_STATE_TERMINATED --}; -- --enum data_direction { -- DATA_DIR_UNKNOWN = 0, -- DATA_DIR_FROM_HOST, -- DATA_DIR_TO_HOST, -- DATA_DIR_NONE --}; -- -- --/*-------------------------------------------------------------------------*/ -- -- --static inline u32 get_unaligned_be24(u8 *buf) --{ -- return 0xffffff & (u32) get_unaligned_be32(buf - 1); --} -- -- --/*-------------------------------------------------------------------------*/ -- -- --enum { -- FSG_STRING_INTERFACE --}; -- -+#include "storage_common.h" - - /* There is only one interface. */ - --static struct usb_interface_descriptor --fsg_intf_desc = { -+struct usb_interface_descriptor fsg_intf_desc = { - .bLength = sizeof fsg_intf_desc, - .bDescriptorType = USB_DT_INTERFACE, - -@@ -268,14 +43,14 @@ fsg_intf_desc = { - .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ - .iInterface = FSG_STRING_INTERFACE, - }; -+EXPORT_SYMBOL(fsg_intf_desc); - - /* - * Three full-speed endpoint descriptors: bulk-in, bulk-out, and - * interrupt-in. - */ - --static struct usb_endpoint_descriptor --fsg_fs_bulk_in_desc = { -+struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - -@@ -283,9 +58,9 @@ fsg_fs_bulk_in_desc = { - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ - }; -+EXPORT_SYMBOL(fsg_fs_bulk_in_desc); - --static struct usb_endpoint_descriptor --fsg_fs_bulk_out_desc = { -+struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - -@@ -293,13 +68,15 @@ fsg_fs_bulk_out_desc = { - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ - }; -+EXPORT_SYMBOL(fsg_fs_bulk_out_desc); - --static struct usb_descriptor_header *fsg_fs_function[] = { -+struct usb_descriptor_header *fsg_fs_function[] = { - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, - NULL, - }; -+EXPORT_SYMBOL(fsg_fs_function); - - - /* -@@ -310,8 +87,7 @@ static struct usb_descriptor_header *fsg - * and a "device qualifier" ... plus more construction options - * for the configuration descriptor. - */ --static struct usb_endpoint_descriptor --fsg_hs_bulk_in_desc = { -+struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - -@@ -319,9 +95,9 @@ fsg_hs_bulk_in_desc = { - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), - }; -+EXPORT_SYMBOL(fsg_hs_bulk_in_desc); - --static struct usb_endpoint_descriptor --fsg_hs_bulk_out_desc = { -+struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - -@@ -330,17 +106,18 @@ fsg_hs_bulk_out_desc = { - .wMaxPacketSize = cpu_to_le16(512), - .bInterval = 1, /* NAK every 1 uframe */ - }; -+EXPORT_SYMBOL(fsg_hs_bulk_out_desc); - - --static struct usb_descriptor_header *fsg_hs_function[] = { -+struct usb_descriptor_header *fsg_hs_function[] = { - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, - NULL, - }; -+EXPORT_SYMBOL(fsg_hs_function); - --static struct usb_endpoint_descriptor --fsg_ss_bulk_in_desc = { -+struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - -@@ -348,16 +125,17 @@ fsg_ss_bulk_in_desc = { - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), - }; -+EXPORT_SYMBOL(fsg_ss_bulk_in_desc); - --static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { -+struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { - .bLength = sizeof(fsg_ss_bulk_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /*.bMaxBurst = DYNAMIC, */ - }; -+EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc); - --static struct usb_endpoint_descriptor --fsg_ss_bulk_out_desc = { -+struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - -@@ -365,15 +143,17 @@ fsg_ss_bulk_out_desc = { - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(1024), - }; -+EXPORT_SYMBOL(fsg_ss_bulk_out_desc); - --static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { -+struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { - .bLength = sizeof(fsg_ss_bulk_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - /*.bMaxBurst = DYNAMIC, */ - }; -+EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc); - --static struct usb_descriptor_header *fsg_ss_function[] = { -+struct usb_descriptor_header *fsg_ss_function[] = { - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc, -@@ -381,17 +161,7 @@ static struct usb_descriptor_header *fsg - (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, - NULL, - }; -- --/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ --static struct usb_string fsg_strings[] = { -- {FSG_STRING_INTERFACE, fsg_string_interface}, -- {} --}; -- --static struct usb_gadget_strings fsg_stringtab = { -- .language = 0x0409, /* en-us */ -- .strings = fsg_strings, --}; -+EXPORT_SYMBOL(fsg_ss_function); - - - /*-------------------------------------------------------------------------*/ -@@ -401,7 +171,7 @@ static struct usb_gadget_strings fsg_str - * the caller must own fsg->filesem for writing. - */ - --static void fsg_lun_close(struct fsg_lun *curlun) -+void fsg_lun_close(struct fsg_lun *curlun) - { - if (curlun->filp) { - LDBG(curlun, "close backing file\n"); -@@ -409,9 +179,9 @@ static void fsg_lun_close(struct fsg_lun - curlun->filp = NULL; - } - } -+EXPORT_SYMBOL(fsg_lun_close); - -- --static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) -+int fsg_lun_open(struct fsg_lun *curlun, const char *filename) - { - int ro; - struct file *filp = NULL; -@@ -508,6 +278,7 @@ out: - fput(filp); - return rc; - } -+EXPORT_SYMBOL(fsg_lun_open); - - - /*-------------------------------------------------------------------------*/ -@@ -516,7 +287,7 @@ out: - * Sync the file data, don't bother with the metadata. - * This code was copied from fs/buffer.c:sys_fdatasync(). - */ --static int fsg_lun_fsync_sub(struct fsg_lun *curlun) -+int fsg_lun_fsync_sub(struct fsg_lun *curlun) - { - struct file *filp = curlun->filp; - -@@ -524,8 +295,9 @@ static int fsg_lun_fsync_sub(struct fsg_ - return 0; - return vfs_fsync(filp, 1); - } -+EXPORT_SYMBOL(fsg_lun_fsync_sub); - --static void store_cdrom_address(u8 *dest, int msf, u32 addr) -+void store_cdrom_address(u8 *dest, int msf, u32 addr) - { - if (msf) { - /* Convert to Minutes-Seconds-Frames */ -@@ -542,34 +314,28 @@ static void store_cdrom_address(u8 *dest - put_unaligned_be32(addr, dest); - } - } -- -+EXPORT_SYMBOL(store_cdrom_address); - - /*-------------------------------------------------------------------------*/ - - --static ssize_t ro_show(struct device *dev, struct device_attribute *attr, -- char *buf) -+ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf) - { -- struct fsg_lun *curlun = fsg_lun_from_dev(dev); -- - return sprintf(buf, "%d\n", fsg_lun_is_open(curlun) - ? curlun->ro - : curlun->initially_ro); - } -+EXPORT_SYMBOL(fsg_show_ro); - --static ssize_t nofua_show(struct device *dev, struct device_attribute *attr, -- char *buf) -+ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf) - { -- struct fsg_lun *curlun = fsg_lun_from_dev(dev); -- - return sprintf(buf, "%u\n", curlun->nofua); - } -+EXPORT_SYMBOL(fsg_show_nofua); - --static ssize_t file_show(struct device *dev, struct device_attribute *attr, -- char *buf) -+ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ char *buf) - { -- struct fsg_lun *curlun = fsg_lun_from_dev(dev); -- struct rw_semaphore *filesem = dev_get_drvdata(dev); - char *p; - ssize_t rc; - -@@ -591,17 +357,44 @@ static ssize_t file_show(struct device * - up_read(filesem); - return rc; - } -+EXPORT_SYMBOL(fsg_show_file); - -+ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf) -+{ -+ return sprintf(buf, "%u\n", curlun->cdrom); -+} -+EXPORT_SYMBOL(fsg_show_cdrom); - --static ssize_t ro_store(struct device *dev, struct device_attribute *attr, -- const char *buf, size_t count) -+ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) -+{ -+ return sprintf(buf, "%u\n", curlun->removable); -+} -+EXPORT_SYMBOL(fsg_show_removable); -+ -+/* -+ * The caller must hold fsg->filesem for reading when calling this function. -+ */ -+static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro) -+{ -+ if (fsg_lun_is_open(curlun)) { -+ LDBG(curlun, "read-only status change prevented\n"); -+ return -EBUSY; -+ } -+ -+ curlun->ro = ro; -+ curlun->initially_ro = ro; -+ LDBG(curlun, "read-only status set to %d\n", curlun->ro); -+ -+ return 0; -+} -+ -+ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ const char *buf, size_t count) - { - ssize_t rc; -- struct fsg_lun *curlun = fsg_lun_from_dev(dev); -- struct rw_semaphore *filesem = dev_get_drvdata(dev); -- unsigned ro; -+ bool ro; - -- rc = kstrtouint(buf, 2, &ro); -+ rc = strtobool(buf, &ro); - if (rc) - return rc; - -@@ -610,27 +403,21 @@ static ssize_t ro_store(struct device *d - * backing file is closed. - */ - down_read(filesem); -- if (fsg_lun_is_open(curlun)) { -- LDBG(curlun, "read-only status change prevented\n"); -- rc = -EBUSY; -- } else { -- curlun->ro = ro; -- curlun->initially_ro = ro; -- LDBG(curlun, "read-only status set to %d\n", curlun->ro); -+ rc = _fsg_store_ro(curlun, ro); -+ if (!rc) - rc = count; -- } - up_read(filesem); -+ - return rc; - } -+EXPORT_SYMBOL(fsg_store_ro); - --static ssize_t nofua_store(struct device *dev, struct device_attribute *attr, -- const char *buf, size_t count) -+ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) - { -- struct fsg_lun *curlun = fsg_lun_from_dev(dev); -- unsigned nofua; -+ bool nofua; - int ret; - -- ret = kstrtouint(buf, 2, &nofua); -+ ret = strtobool(buf, &nofua); - if (ret) - return ret; - -@@ -642,12 +429,11 @@ static ssize_t nofua_store(struct device - - return count; - } -+EXPORT_SYMBOL(fsg_store_nofua); - --static ssize_t file_store(struct device *dev, struct device_attribute *attr, -- const char *buf, size_t count) -+ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ const char *buf, size_t count) - { -- struct fsg_lun *curlun = fsg_lun_from_dev(dev); -- struct rw_semaphore *filesem = dev_get_drvdata(dev); - int rc = 0; - - if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { -@@ -674,3 +460,45 @@ static ssize_t file_store(struct device - up_write(filesem); - return (rc < 0 ? rc : count); - } -+EXPORT_SYMBOL(fsg_store_file); -+ -+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ const char *buf, size_t count) -+{ -+ bool cdrom; -+ int ret; -+ -+ ret = strtobool(buf, &cdrom); -+ if (ret) -+ return ret; -+ -+ down_read(filesem); -+ ret = cdrom ? _fsg_store_ro(curlun, true) : 0; -+ -+ if (!ret) { -+ curlun->cdrom = cdrom; -+ ret = count; -+ } -+ up_read(filesem); -+ -+ return ret; -+} -+EXPORT_SYMBOL(fsg_store_cdrom); -+ -+ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, -+ size_t count) -+{ -+ bool removable; -+ int ret; -+ -+ ret = strtobool(buf, &removable); -+ if (ret) -+ return ret; -+ -+ curlun->removable = removable; -+ -+ return count; -+} -+EXPORT_SYMBOL(fsg_store_removable); -+ -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/usb/gadget/storage_common.h -@@ -0,0 +1,229 @@ -+#ifndef USB_STORAGE_COMMON_H -+#define USB_STORAGE_COMMON_H -+ -+#include <linux/device.h> -+#include <linux/usb/storage.h> -+#include <scsi/scsi.h> -+#include <asm/unaligned.h> -+ -+#ifndef DEBUG -+#undef VERBOSE_DEBUG -+#undef DUMP_MSGS -+#endif /* !DEBUG */ -+ -+#ifdef VERBOSE_DEBUG -+#define VLDBG LDBG -+#else -+#define VLDBG(lun, fmt, args...) do { } while (0) -+#endif /* VERBOSE_DEBUG */ -+ -+#define _LMSG(func, lun, fmt, args...) \ -+ do { \ -+ if ((lun)->name_pfx && *(lun)->name_pfx) \ -+ func("%s/%s: " fmt, *(lun)->name_pfx, \ -+ (lun)->name, ## args); \ -+ else \ -+ func("%s: " fmt, (lun)->name, ## args); \ -+ } while (0) -+ -+#define LDBG(lun, fmt, args...) _LMSG(pr_debug, lun, fmt, ## args) -+#define LERROR(lun, fmt, args...) _LMSG(pr_err, lun, fmt, ## args) -+#define LWARN(lun, fmt, args...) _LMSG(pr_warn, lun, fmt, ## args) -+#define LINFO(lun, fmt, args...) _LMSG(pr_info, lun, fmt, ## args) -+ -+ -+#ifdef DUMP_MSGS -+ -+# define dump_msg(fsg, /* const char * */ label, \ -+ /* const u8 * */ buf, /* unsigned */ length) \ -+do { \ -+ if (length < 512) { \ -+ DBG(fsg, "%s, length %u:\n", label, length); \ -+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \ -+ 16, 1, buf, length, 0); \ -+ } \ -+} while (0) -+ -+# define dump_cdb(fsg) do { } while (0) -+ -+#else -+ -+# define dump_msg(fsg, /* const char * */ label, \ -+ /* const u8 * */ buf, /* unsigned */ length) do { } while (0) -+ -+# ifdef VERBOSE_DEBUG -+ -+# define dump_cdb(fsg) \ -+ print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, \ -+ 16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0) \ -+ -+# else -+ -+# define dump_cdb(fsg) do { } while (0) -+ -+# endif /* VERBOSE_DEBUG */ -+ -+#endif /* DUMP_MSGS */ -+ -+/* Length of a SCSI Command Data Block */ -+#define MAX_COMMAND_SIZE 16 -+ -+/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ -+#define SS_NO_SENSE 0 -+#define SS_COMMUNICATION_FAILURE 0x040800 -+#define SS_INVALID_COMMAND 0x052000 -+#define SS_INVALID_FIELD_IN_CDB 0x052400 -+#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 -+#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 -+#define SS_MEDIUM_NOT_PRESENT 0x023a00 -+#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 -+#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 -+#define SS_RESET_OCCURRED 0x062900 -+#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 -+#define SS_UNRECOVERED_READ_ERROR 0x031100 -+#define SS_WRITE_ERROR 0x030c02 -+#define SS_WRITE_PROTECTED 0x072700 -+ -+#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ -+#define ASC(x) ((u8) ((x) >> 8)) -+#define ASCQ(x) ((u8) (x)) -+ -+struct fsg_lun { -+ struct file *filp; -+ loff_t file_length; -+ loff_t num_sectors; -+ -+ unsigned int initially_ro:1; -+ unsigned int ro:1; -+ unsigned int removable:1; -+ unsigned int cdrom:1; -+ unsigned int prevent_medium_removal:1; -+ unsigned int registered:1; -+ unsigned int info_valid:1; -+ unsigned int nofua:1; -+ -+ u32 sense_data; -+ u32 sense_data_info; -+ u32 unit_attention_data; -+ -+ unsigned int blkbits; /* Bits of logical block size -+ of bound block device */ -+ unsigned int blksize; /* logical block size of bound block device */ -+ struct device dev; -+ const char *name; /* "lun.name" */ -+ const char **name_pfx; /* "function.name" */ -+}; -+ -+static inline bool fsg_lun_is_open(struct fsg_lun *curlun) -+{ -+ return curlun->filp != NULL; -+} -+ -+/* Big enough to hold our biggest descriptor */ -+#define EP0_BUFSIZE 256 -+#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */ -+ -+/* Default size of buffer length. */ -+#define FSG_BUFLEN ((u32)16384) -+ -+/* Maximal number of LUNs supported in mass storage function */ -+#define FSG_MAX_LUNS 8 -+ -+enum fsg_buffer_state { -+ BUF_STATE_EMPTY = 0, -+ BUF_STATE_FULL, -+ BUF_STATE_BUSY -+}; -+ -+struct fsg_buffhd { -+ void *buf; -+ enum fsg_buffer_state state; -+ struct fsg_buffhd *next; -+ -+ /* -+ * The NetChip 2280 is faster, and handles some protocol faults -+ * better, if we don't submit any short bulk-out read requests. -+ * So we will record the intended request length here. -+ */ -+ unsigned int bulk_out_intended_length; -+ -+ struct usb_request *inreq; -+ int inreq_busy; -+ struct usb_request *outreq; -+ int outreq_busy; -+}; -+ -+enum fsg_state { -+ /* This one isn't used anywhere */ -+ FSG_STATE_COMMAND_PHASE = -10, -+ FSG_STATE_DATA_PHASE, -+ FSG_STATE_STATUS_PHASE, -+ -+ FSG_STATE_IDLE = 0, -+ FSG_STATE_ABORT_BULK_OUT, -+ FSG_STATE_RESET, -+ FSG_STATE_INTERFACE_CHANGE, -+ FSG_STATE_CONFIG_CHANGE, -+ FSG_STATE_DISCONNECT, -+ FSG_STATE_EXIT, -+ FSG_STATE_TERMINATED -+}; -+ -+enum data_direction { -+ DATA_DIR_UNKNOWN = 0, -+ DATA_DIR_FROM_HOST, -+ DATA_DIR_TO_HOST, -+ DATA_DIR_NONE -+}; -+ -+static inline u32 get_unaligned_be24(u8 *buf) -+{ -+ return 0xffffff & (u32) get_unaligned_be32(buf - 1); -+} -+ -+static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev) -+{ -+ return container_of(dev, struct fsg_lun, dev); -+} -+ -+enum { -+ FSG_STRING_INTERFACE -+}; -+ -+extern struct usb_interface_descriptor fsg_intf_desc; -+ -+extern struct usb_endpoint_descriptor fsg_fs_bulk_in_desc; -+extern struct usb_endpoint_descriptor fsg_fs_bulk_out_desc; -+extern struct usb_descriptor_header *fsg_fs_function[]; -+ -+extern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc; -+extern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc; -+extern struct usb_descriptor_header *fsg_hs_function[]; -+ -+extern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc; -+extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc; -+extern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc; -+extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc; -+extern struct usb_descriptor_header *fsg_ss_function[]; -+ -+void fsg_lun_close(struct fsg_lun *curlun); -+int fsg_lun_open(struct fsg_lun *curlun, const char *filename); -+int fsg_lun_fsync_sub(struct fsg_lun *curlun); -+void store_cdrom_address(u8 *dest, int msf, u32 addr); -+ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf); -+ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf); -+ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ char *buf); -+ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf); -+ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf); -+ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ const char *buf, size_t count); -+ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count); -+ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ const char *buf, size_t count); -+ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, -+ const char *buf, size_t count); -+ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, -+ size_t count); -+ -+#endif /* USB_STORAGE_COMMON_H */ ---- a/drivers/usb/gadget/udc-core.c -+++ b/drivers/usb/gadget/udc-core.c -@@ -356,7 +356,8 @@ static int udc_bind_to_driver(struct usb - kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); - return 0; - err1: -- dev_err(&udc->dev, "failed to start %s: %d\n", -+ if (ret != -EISNAM) -+ dev_err(&udc->dev, "failed to start %s: %d\n", - udc->driver->function, ret); - udc->driver = NULL; - udc->dev.driver = NULL; ---- a/drivers/usb/gadget/zero.c -+++ b/drivers/usb/gadget/zero.c -@@ -95,6 +95,18 @@ unsigned autoresume = DEFAULT_AUTORESUME - module_param(autoresume, uint, S_IRUGO); - MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup"); - -+/* Maximum Autoresume time */ -+unsigned max_autoresume; -+module_param(max_autoresume, uint, S_IRUGO); -+MODULE_PARM_DESC(max_autoresume, "maximum seconds before remote wakeup"); -+ -+/* Interval between two remote wakeups */ -+unsigned autoresume_interval_ms; -+module_param(autoresume_interval_ms, uint, S_IRUGO); -+MODULE_PARM_DESC(autoresume_interval_ms, -+ "milliseconds to increase successive wakeup delays"); -+ -+static unsigned autoresume_step_ms; - /*-------------------------------------------------------------------------*/ - - static struct usb_device_descriptor device_desc = { -@@ -183,8 +195,16 @@ static void zero_suspend(struct usb_comp - return; - - if (autoresume) { -- mod_timer(&autoresume_timer, jiffies + (HZ * autoresume)); -- DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume); -+ if (max_autoresume && -+ (autoresume_step_ms > max_autoresume * 1000)) -+ autoresume_step_ms = autoresume * 1000; -+ -+ mod_timer(&autoresume_timer, jiffies + -+ msecs_to_jiffies(autoresume_step_ms)); -+ DBG(cdev, "suspend, wakeup in %d milliseconds\n", -+ autoresume_step_ms); -+ -+ autoresume_step_ms += autoresume_interval_ms; - } else - DBG(cdev, "%s\n", __func__); - } -@@ -316,6 +336,7 @@ static int __init zero_bind(struct usb_c - if (autoresume) { - sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; -+ autoresume_step_ms = autoresume * 1000; - } - - /* support OTG systems */ ---- a/drivers/usb/misc/usbtest.c -+++ b/drivers/usb/misc/usbtest.c -@@ -120,7 +120,7 @@ get_endpoints(struct usbtest_dev *dev, s - struct usb_host_endpoint *e; - - e = alt->endpoint + ep; -- switch (e->desc.bmAttributes) { -+ switch (usb_endpoint_type(&e->desc)) { - case USB_ENDPOINT_XFER_BULK: - break; - case USB_ENDPOINT_XFER_ISOC: ---- a/drivers/usb/musb/am35x.c -+++ b/drivers/usb/musb/am35x.c -@@ -89,7 +89,6 @@ struct am35x_glue { - struct clk *phy_clk; - struct clk *clk; - }; --#define glue_to_musb(g) platform_get_drvdata(g->musb) - - /* - * am35x_musb_enable - enable interrupts -@@ -452,14 +451,18 @@ static const struct musb_platform_ops am - .set_vbus = am35x_musb_set_vbus, - }; - --static u64 am35x_dmamask = DMA_BIT_MASK(32); -+static const struct platform_device_info am35x_dev_info = { -+ .name = "musb-hdrc", -+ .id = PLATFORM_DEVID_AUTO, -+ .dma_mask = DMA_BIT_MASK(32), -+}; - - static int am35x_probe(struct platform_device *pdev) - { - struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct platform_device *musb; - struct am35x_glue *glue; -- -+ struct platform_device_info pinfo; - struct clk *phy_clk; - struct clk *clk; - -@@ -471,12 +474,6 @@ static int am35x_probe(struct platform_d - goto err0; - } - -- musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); -- if (!musb) { -- dev_err(&pdev->dev, "failed to allocate musb device\n"); -- goto err1; -- } -- - phy_clk = clk_get(&pdev->dev, "fck"); - if (IS_ERR(phy_clk)) { - dev_err(&pdev->dev, "failed to get PHY clock\n"); -@@ -503,12 +500,7 @@ static int am35x_probe(struct platform_d - goto err6; - } - -- musb->dev.parent = &pdev->dev; -- musb->dev.dma_mask = &am35x_dmamask; -- musb->dev.coherent_dma_mask = am35x_dmamask; -- - glue->dev = &pdev->dev; -- glue->musb = musb; - glue->phy_clk = phy_clk; - glue->clk = clk; - -@@ -516,22 +508,17 @@ static int am35x_probe(struct platform_d - - platform_set_drvdata(pdev, glue); - -- ret = platform_device_add_resources(musb, pdev->resource, -- pdev->num_resources); -- if (ret) { -- dev_err(&pdev->dev, "failed to add resources\n"); -- goto err7; -- } -- -- ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add platform_data\n"); -- goto err7; -- } -- -- ret = platform_device_add(musb); -- if (ret) { -- dev_err(&pdev->dev, "failed to register musb device\n"); -+ pinfo = am35x_dev_info; -+ pinfo.parent = &pdev->dev; -+ pinfo.res = pdev->resource; -+ pinfo.num_res = pdev->num_resources; -+ pinfo.data = pdata; -+ pinfo.size_data = sizeof(*pdata); -+ -+ glue->musb = musb = platform_device_register_full(&pinfo); -+ if (IS_ERR(musb)) { -+ ret = PTR_ERR(musb); -+ dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err7; - } - -@@ -550,9 +537,6 @@ err4: - clk_put(phy_clk); - - err3: -- platform_device_put(musb); -- --err1: - kfree(glue); - - err0: -@@ -615,23 +599,16 @@ static int am35x_resume(struct device *d - - return 0; - } -- --static struct dev_pm_ops am35x_pm_ops = { -- .suspend = am35x_suspend, -- .resume = am35x_resume, --}; -- --#define DEV_PM_OPS &am35x_pm_ops --#else --#define DEV_PM_OPS NULL - #endif - -+static SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume); -+ - static struct platform_driver am35x_driver = { - .probe = am35x_probe, - .remove = am35x_remove, - .driver = { - .name = "musb-am35x", -- .pm = DEV_PM_OPS, -+ .pm = &am35x_pm_ops, - }, - }; - ---- a/drivers/usb/musb/blackfin.c -+++ b/drivers/usb/musb/blackfin.c -@@ -561,23 +561,16 @@ static int bfin_resume(struct device *de - - return 0; - } -- --static struct dev_pm_ops bfin_pm_ops = { -- .suspend = bfin_suspend, -- .resume = bfin_resume, --}; -- --#define DEV_PM_OPS &bfin_pm_ops --#else --#define DEV_PM_OPS NULL - #endif - -+static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume); -+ - static struct platform_driver bfin_driver = { - .probe = bfin_probe, - .remove = __exit_p(bfin_remove), - .driver = { - .name = "musb-blackfin", -- .pm = DEV_PM_OPS, -+ .pm = &bfin_pm_ops, - }, - }; - ---- a/drivers/usb/musb/da8xx.c -+++ b/drivers/usb/musb/da8xx.c -@@ -472,7 +472,11 @@ static const struct musb_platform_ops da - .set_vbus = da8xx_musb_set_vbus, - }; - --static u64 da8xx_dmamask = DMA_BIT_MASK(32); -+static const struct platform_device_info da8xx_dev_info = { -+ .name = "musb-hdrc", -+ .id = PLATFORM_DEVID_AUTO, -+ .dma_mask = DMA_BIT_MASK(32), -+}; - - static int da8xx_probe(struct platform_device *pdev) - { -@@ -480,7 +484,7 @@ static int da8xx_probe(struct platform_d - struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct platform_device *musb; - struct da8xx_glue *glue; -- -+ struct platform_device_info pinfo; - struct clk *clk; - - int ret = -ENOMEM; -@@ -491,12 +495,6 @@ static int da8xx_probe(struct platform_d - goto err0; - } - -- musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); -- if (!musb) { -- dev_err(&pdev->dev, "failed to allocate musb device\n"); -- goto err1; -- } -- - clk = clk_get(&pdev->dev, "usb20"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); -@@ -510,12 +508,7 @@ static int da8xx_probe(struct platform_d - goto err4; - } - -- musb->dev.parent = &pdev->dev; -- musb->dev.dma_mask = &da8xx_dmamask; -- musb->dev.coherent_dma_mask = da8xx_dmamask; -- - glue->dev = &pdev->dev; -- glue->musb = musb; - glue->clk = clk; - - pdata->platform_ops = &da8xx_ops; -@@ -535,22 +528,17 @@ static int da8xx_probe(struct platform_d - musb_resources[1].end = pdev->resource[1].end; - musb_resources[1].flags = pdev->resource[1].flags; - -- ret = platform_device_add_resources(musb, musb_resources, -- ARRAY_SIZE(musb_resources)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add resources\n"); -- goto err5; -- } -- -- ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add platform_data\n"); -- goto err5; -- } -- -- ret = platform_device_add(musb); -- if (ret) { -- dev_err(&pdev->dev, "failed to register musb device\n"); -+ pinfo = da8xx_dev_info; -+ pinfo.parent = &pdev->dev; -+ pinfo.res = musb_resources; -+ pinfo.num_res = ARRAY_SIZE(musb_resources); -+ pinfo.data = pdata; -+ pinfo.size_data = sizeof(*pdata); -+ -+ glue->musb = musb = platform_device_register_full(&pinfo); -+ if (IS_ERR(musb)) { -+ ret = PTR_ERR(musb); -+ dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err5; - } - -@@ -563,9 +551,6 @@ err4: - clk_put(clk); - - err3: -- platform_device_put(musb); -- --err1: - kfree(glue); - - err0: ---- a/drivers/usb/musb/davinci.c -+++ b/drivers/usb/musb/davinci.c -@@ -505,14 +505,19 @@ static const struct musb_platform_ops da - .set_vbus = davinci_musb_set_vbus, - }; - --static u64 davinci_dmamask = DMA_BIT_MASK(32); -+static const struct platform_device_info davinci_dev_info = { -+ .name = "musb-hdrc", -+ .id = PLATFORM_DEVID_AUTO, -+ .dma_mask = DMA_BIT_MASK(32), -+}; - - static int davinci_probe(struct platform_device *pdev) - { -- struct resource musb_resources[2]; -+ struct resource musb_resources[3]; - struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct platform_device *musb; - struct davinci_glue *glue; -+ struct platform_device_info pinfo; - struct clk *clk; - - int ret = -ENOMEM; -@@ -523,12 +528,6 @@ static int davinci_probe(struct platform - goto err0; - } - -- musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); -- if (!musb) { -- dev_err(&pdev->dev, "failed to allocate musb device\n"); -- goto err1; -- } -- - clk = clk_get(&pdev->dev, "usb"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); -@@ -542,12 +541,7 @@ static int davinci_probe(struct platform - goto err4; - } - -- musb->dev.parent = &pdev->dev; -- musb->dev.dma_mask = &davinci_dmamask; -- musb->dev.coherent_dma_mask = davinci_dmamask; -- - glue->dev = &pdev->dev; -- glue->musb = musb; - glue->clk = clk; - - pdata->platform_ops = &davinci_ops; -@@ -567,22 +561,26 @@ static int davinci_probe(struct platform - musb_resources[1].end = pdev->resource[1].end; - musb_resources[1].flags = pdev->resource[1].flags; - -- ret = platform_device_add_resources(musb, musb_resources, -- ARRAY_SIZE(musb_resources)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add resources\n"); -- goto err5; -- } -- -- ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add platform_data\n"); -- goto err5; -- } -- -- ret = platform_device_add(musb); -- if (ret) { -- dev_err(&pdev->dev, "failed to register musb device\n"); -+ /* -+ * For DM6467 3 resources are passed. A placeholder for the 3rd -+ * resource is always there, so it's safe to always copy it... -+ */ -+ musb_resources[2].name = pdev->resource[2].name; -+ musb_resources[2].start = pdev->resource[2].start; -+ musb_resources[2].end = pdev->resource[2].end; -+ musb_resources[2].flags = pdev->resource[2].flags; -+ -+ pinfo = davinci_dev_info; -+ pinfo.parent = &pdev->dev; -+ pinfo.res = musb_resources; -+ pinfo.num_res = ARRAY_SIZE(musb_resources); -+ pinfo.data = pdata; -+ pinfo.size_data = sizeof(*pdata); -+ -+ glue->musb = musb = platform_device_register_full(&pinfo); -+ if (IS_ERR(musb)) { -+ ret = PTR_ERR(musb); -+ dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err5; - } - -@@ -595,9 +593,6 @@ err4: - clk_put(clk); - - err3: -- platform_device_put(musb); -- --err1: - kfree(glue); - - err0: ---- a/drivers/usb/musb/Kconfig -+++ b/drivers/usb/musb/Kconfig -@@ -75,6 +75,7 @@ config USB_MUSB_TUSB6010 - config USB_MUSB_OMAP2PLUS - tristate "OMAP2430 and onwards" - depends on ARCH_OMAP2PLUS -+ select GENERIC_PHY - - config USB_MUSB_AM35X - tristate "AM35x" -@@ -90,7 +91,7 @@ config USB_MUSB_BLACKFIN - depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523) - - config USB_MUSB_UX500 -- tristate "U8500 and U5500" -+ tristate "Ux500 platforms" - - endchoice - -@@ -112,7 +113,7 @@ choice - allow using DMA on multiplatform kernels. - - config USB_UX500_DMA -- bool 'ST Ericsson U8500 and U5500' -+ bool 'ST Ericsson Ux500' - depends on USB_MUSB_UX500 - help - Enable DMA transfers on UX500 platforms. ---- a/drivers/usb/musb/musb_am335x.c -+++ b/drivers/usb/musb/musb_am335x.c -@@ -46,7 +46,7 @@ static struct platform_driver am335x_chi - .remove = am335x_child_remove, - .driver = { - .name = "am335x-usb-childs", -- .of_match_table = of_match_ptr(am335x_child_of_match), -+ .of_match_table = am335x_child_of_match, - }, - }; - ---- a/drivers/usb/musb/musb_core.c -+++ b/drivers/usb/musb/musb_core.c -@@ -94,6 +94,7 @@ - #include <linux/sched.h> - #include <linux/slab.h> - #include <linux/init.h> -+#include <linux/idr.h> - #include <linux/list.h> - #include <linux/kobject.h> - #include <linux/prefetch.h> -@@ -120,7 +121,7 @@ MODULE_DESCRIPTION(DRIVER_INFO); - MODULE_AUTHOR(DRIVER_AUTHOR); - MODULE_LICENSE("GPL"); - MODULE_ALIAS("platform:" MUSB_DRIVER_NAME); -- -+static DEFINE_IDA(musb_ida); - - /*-------------------------------------------------------------------------*/ - -@@ -131,6 +132,35 @@ static inline struct musb *dev_to_musb(s - - /*-------------------------------------------------------------------------*/ - -+int musb_get_id(struct device *dev, gfp_t gfp_mask) -+{ -+ int ret; -+ int id; -+ -+ ret = ida_pre_get(&musb_ida, gfp_mask); -+ if (!ret) { -+ dev_err(dev, "failed to reserve resource for id\n"); -+ return -ENOMEM; -+ } -+ -+ ret = ida_get_new(&musb_ida, &id); -+ if (ret < 0) { -+ dev_err(dev, "failed to allocate a new id\n"); -+ return ret; -+ } -+ -+ return id; -+} -+EXPORT_SYMBOL_GPL(musb_get_id); -+ -+void musb_put_id(struct device *dev, int id) -+{ -+ -+ dev_dbg(dev, "removing id %d\n", id); -+ ida_remove(&musb_ida, id); -+} -+EXPORT_SYMBOL_GPL(musb_put_id); -+ - #ifndef CONFIG_BLACKFIN - static int musb_ulpi_read(struct usb_phy *phy, u32 offset) - { -@@ -1809,8 +1839,7 @@ static void musb_free(struct musb *musb) - disable_irq_wake(musb->nIrq); - free_irq(musb->nIrq, musb); - } -- if (musb->dma_controller) -- dma_controller_destroy(musb->dma_controller); -+ cancel_work_sync(&musb->irq_work); - - musb_host_free(musb); - } -@@ -1885,8 +1914,13 @@ musb_init_controller(struct device *dev, - - pm_runtime_get_sync(musb->controller); - -- if (use_dma && dev->dma_mask) -+ if (use_dma && dev->dma_mask) { - musb->dma_controller = dma_controller_create(musb, musb->mregs); -+ if (IS_ERR(musb->dma_controller)) { -+ status = PTR_ERR(musb->dma_controller); -+ goto fail2_5; -+ } -+ } - - /* be sure interrupts are disabled before connecting ISR */ - musb_platform_disable(musb); -@@ -1937,15 +1971,26 @@ musb_init_controller(struct device *dev, - switch (musb->port_mode) { - case MUSB_PORT_MODE_HOST: - status = musb_host_setup(musb, plat->power); -+ if (status < 0) -+ goto fail3; -+ status = musb_platform_set_mode(musb, MUSB_HOST); - break; - case MUSB_PORT_MODE_GADGET: - status = musb_gadget_setup(musb); -+ if (status < 0) -+ goto fail3; -+ status = musb_platform_set_mode(musb, MUSB_PERIPHERAL); - break; - case MUSB_PORT_MODE_DUAL_ROLE: - status = musb_host_setup(musb, plat->power); - if (status < 0) - goto fail3; - status = musb_gadget_setup(musb); -+ if (status) { -+ musb_host_cleanup(musb); -+ goto fail3; -+ } -+ status = musb_platform_set_mode(musb, MUSB_OTG); - break; - default: - dev_err(dev, "unsupported port mode %d\n", musb->port_mode); -@@ -1972,10 +2017,12 @@ fail5: - - fail4: - musb_gadget_cleanup(musb); -+ musb_host_cleanup(musb); - - fail3: - if (musb->dma_controller) - dma_controller_destroy(musb->dma_controller); -+fail2_5: - pm_runtime_put_sync(musb->controller); - - fail2: -@@ -2032,6 +2079,9 @@ static int musb_remove(struct platform_d - musb_exit_debugfs(musb); - musb_shutdown(pdev); - -+ if (musb->dma_controller) -+ dma_controller_destroy(musb->dma_controller); -+ - musb_free(musb); - device_init_wakeup(dev, 0); - return 0; ---- a/drivers/usb/musb/musb_core.h -+++ b/drivers/usb/musb/musb_core.h -@@ -46,6 +46,7 @@ - #include <linux/usb.h> - #include <linux/usb/otg.h> - #include <linux/usb/musb.h> -+#include <linux/phy/phy.h> - - struct musb; - struct musb_hw_ep; -@@ -341,6 +342,7 @@ struct musb { - u16 int_tx; - - struct usb_phy *xceiv; -+ struct phy *phy; - - int nIrq; - unsigned irq_wake:1; -@@ -505,6 +507,9 @@ extern const char musb_driver_name[]; - extern void musb_stop(struct musb *musb); - extern void musb_start(struct musb *musb); - -+extern int musb_get_id(struct device *dev, gfp_t gfp_mask); -+extern void musb_put_id(struct device *dev, int id); -+ - extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src); - extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst); - ---- a/drivers/usb/musb/musb_cppi41.c -+++ b/drivers/usb/musb/musb_cppi41.c -@@ -484,6 +484,7 @@ static int cppi41_dma_controller_start(s - if (ret) - goto err; - -+ ret = -EINVAL; - if (port > MUSB_DMA_NUM_CHANNELS || !port) - goto err; - if (is_tx) -@@ -503,6 +504,7 @@ static int cppi41_dma_controller_start(s - dc = dma_request_slave_channel(dev, str); - if (!dc) { - dev_err(dev, "Falied to request %s.\n", str); -+ ret = -EPROBE_DEFER; - goto err; - } - cppi41_channel->dc = dc; -@@ -510,7 +512,7 @@ static int cppi41_dma_controller_start(s - return 0; - err: - cppi41_release_all_dma_chans(controller); -- return -EINVAL; -+ return ret; - } - - void dma_controller_destroy(struct dma_controller *c) -@@ -526,7 +528,7 @@ struct dma_controller *dma_controller_cr - void __iomem *base) - { - struct cppi41_dma_controller *controller; -- int ret; -+ int ret = 0; - - if (!musb->controller->of_node) { - dev_err(musb->controller, "Need DT for the DMA engine.\n"); -@@ -553,5 +555,7 @@ struct dma_controller *dma_controller_cr - plat_get_fail: - kfree(controller); - kzalloc_fail: -+ if (ret == -EPROBE_DEFER) -+ return ERR_PTR(ret); - return NULL; - } ---- a/drivers/usb/musb/musb_dsps.c -+++ b/drivers/usb/musb/musb_dsps.c -@@ -106,6 +106,7 @@ struct dsps_musb_wrapper { - - /* bit positions for mode */ - unsigned iddig:5; -+ unsigned iddig_mux:5; - /* miscellaneous stuff */ - u8 poll_seconds; - }; -@@ -121,6 +122,43 @@ struct dsps_glue { - unsigned long last_timer; /* last timer data for each instance */ - }; - -+static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) -+{ -+ struct device *dev = musb->controller; -+ struct dsps_glue *glue = dev_get_drvdata(dev->parent); -+ -+ if (timeout == 0) -+ timeout = jiffies + msecs_to_jiffies(3); -+ -+ /* Never idle if active, or when VBUS timeout is not set as host */ -+ if (musb->is_active || (musb->a_wait_bcon == 0 && -+ musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { -+ dev_dbg(musb->controller, "%s active, deleting timer\n", -+ usb_otg_state_string(musb->xceiv->state)); -+ del_timer(&glue->timer); -+ glue->last_timer = jiffies; -+ return; -+ } -+ if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE) -+ return; -+ -+ if (!musb->g.dev.driver) -+ return; -+ -+ if (time_after(glue->last_timer, timeout) && -+ timer_pending(&glue->timer)) { -+ dev_dbg(musb->controller, -+ "Longer idle timer already pending, ignoring...\n"); -+ return; -+ } -+ glue->last_timer = timeout; -+ -+ dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", -+ usb_otg_state_string(musb->xceiv->state), -+ jiffies_to_msecs(timeout - jiffies)); -+ mod_timer(&glue->timer, timeout); -+} -+ - /** - * dsps_musb_enable - enable interrupts - */ -@@ -143,6 +181,7 @@ static void dsps_musb_enable(struct musb - /* Force the DRVVBUS IRQ so we can start polling for ID change. */ - dsps_writel(reg_base, wrp->coreintr_set, - (1 << wrp->drvvbus) << wrp->usb_shift); -+ dsps_musb_try_idle(musb, 0); - } - - /** -@@ -171,6 +210,7 @@ static void otg_timer(unsigned long _mus - const struct dsps_musb_wrapper *wrp = glue->wrp; - u8 devctl; - unsigned long flags; -+ int skip_session = 0; - - /* - * We poll because DSPS IP's won't expose several OTG-critical -@@ -183,10 +223,12 @@ static void otg_timer(unsigned long _mus - spin_lock_irqsave(&musb->lock, flags); - switch (musb->xceiv->state) { - case OTG_STATE_A_WAIT_BCON: -- devctl &= ~MUSB_DEVCTL_SESSION; -- dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl); -+ dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); -+ skip_session = 1; -+ /* fall */ - -- devctl = dsps_readb(musb->mregs, MUSB_DEVCTL); -+ case OTG_STATE_A_IDLE: -+ case OTG_STATE_B_IDLE: - if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); -@@ -194,60 +236,21 @@ static void otg_timer(unsigned long _mus - musb->xceiv->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); - } -+ if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) -+ dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); -+ mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); - break; - case OTG_STATE_A_WAIT_VFALL: - musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; - dsps_writel(musb->ctrl_base, wrp->coreintr_set, - MUSB_INTR_VBUSERROR << wrp->usb_shift); - break; -- case OTG_STATE_B_IDLE: -- devctl = dsps_readb(mregs, MUSB_DEVCTL); -- if (devctl & MUSB_DEVCTL_BDEVICE) -- mod_timer(&glue->timer, -- jiffies + wrp->poll_seconds * HZ); -- else -- musb->xceiv->state = OTG_STATE_A_IDLE; -- break; - default: - break; - } - spin_unlock_irqrestore(&musb->lock, flags); - } - --static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) --{ -- struct device *dev = musb->controller; -- struct dsps_glue *glue = dev_get_drvdata(dev->parent); -- -- if (timeout == 0) -- timeout = jiffies + msecs_to_jiffies(3); -- -- /* Never idle if active, or when VBUS timeout is not set as host */ -- if (musb->is_active || (musb->a_wait_bcon == 0 && -- musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { -- dev_dbg(musb->controller, "%s active, deleting timer\n", -- usb_otg_state_string(musb->xceiv->state)); -- del_timer(&glue->timer); -- glue->last_timer = jiffies; -- return; -- } -- if (musb->port_mode == MUSB_PORT_MODE_HOST) -- return; -- -- if (time_after(glue->last_timer, timeout) && -- timer_pending(&glue->timer)) { -- dev_dbg(musb->controller, -- "Longer idle timer already pending, ignoring...\n"); -- return; -- } -- glue->last_timer = timeout; -- -- dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", -- usb_otg_state_string(musb->xceiv->state), -- jiffies_to_msecs(timeout - jiffies)); -- mod_timer(&glue->timer, timeout); --} -- - static irqreturn_t dsps_interrupt(int irq, void *hci) - { - struct musb *musb = hci; -@@ -404,6 +407,54 @@ static int dsps_musb_exit(struct musb *m - return 0; - } - -+static int dsps_musb_set_mode(struct musb *musb, u8 mode) -+{ -+ struct device *dev = musb->controller; -+ struct dsps_glue *glue = dev_get_drvdata(dev->parent); -+ const struct dsps_musb_wrapper *wrp = glue->wrp; -+ void __iomem *ctrl_base = musb->ctrl_base; -+ void __iomem *base = musb->mregs; -+ u32 reg; -+ -+ reg = dsps_readl(base, wrp->mode); -+ -+ switch (mode) { -+ case MUSB_HOST: -+ reg &= ~(1 << wrp->iddig); -+ -+ /* -+ * if we're setting mode to host-only or device-only, we're -+ * going to ignore whatever the PHY sends us and just force -+ * ID pin status by SW -+ */ -+ reg |= (1 << wrp->iddig_mux); -+ -+ dsps_writel(base, wrp->mode, reg); -+ dsps_writel(ctrl_base, wrp->phy_utmi, 0x02); -+ break; -+ case MUSB_PERIPHERAL: -+ reg |= (1 << wrp->iddig); -+ -+ /* -+ * if we're setting mode to host-only or device-only, we're -+ * going to ignore whatever the PHY sends us and just force -+ * ID pin status by SW -+ */ -+ reg |= (1 << wrp->iddig_mux); -+ -+ dsps_writel(base, wrp->mode, reg); -+ break; -+ case MUSB_OTG: -+ dsps_writel(base, wrp->phy_utmi, 0x02); -+ break; -+ default: -+ dev_err(glue->dev, "unsupported mode %d\n", mode); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static struct musb_platform_ops dsps_ops = { - .init = dsps_musb_init, - .exit = dsps_musb_exit, -@@ -412,6 +463,7 @@ static struct musb_platform_ops dsps_ops - .disable = dsps_musb_disable, - - .try_idle = dsps_musb_try_idle, -+ .set_mode = dsps_musb_set_mode, - }; - - static u64 musb_dmamask = DMA_BIT_MASK(32); -@@ -606,6 +658,7 @@ static const struct dsps_musb_wrapper am - .reset = 0, - .otg_disable = 21, - .iddig = 8, -+ .iddig_mux = 7, - .usb_shift = 0, - .usb_mask = 0x1ff, - .usb_bitmap = (0x1ff << 0), -@@ -631,7 +684,7 @@ static struct platform_driver dsps_usbss - .remove = dsps_remove, - .driver = { - .name = "musb-dsps", -- .of_match_table = of_match_ptr(musb_dsps_of_match), -+ .of_match_table = musb_dsps_of_match, - }, - }; - ---- a/drivers/usb/musb/musb_virthub.c -+++ b/drivers/usb/musb/musb_virthub.c -@@ -220,6 +220,23 @@ int musb_hub_status_data(struct usb_hcd - return retval; - } - -+static int musb_has_gadget(struct musb *musb) -+{ -+ /* -+ * In host-only mode we start a connection right away. In OTG mode -+ * we have to wait until we loaded a gadget. We don't really need a -+ * gadget if we operate as a host but we should not start a session -+ * as a device without a gadget or else we explode. -+ */ -+#ifdef CONFIG_USB_MUSB_HOST -+ return 1; -+#else -+ if (musb->port_mode == MUSB_PORT_MODE_HOST) -+ return 1; -+ return musb->g.dev.driver != NULL; -+#endif -+} -+ - int musb_hub_control( - struct usb_hcd *hcd, - u16 typeReq, -@@ -362,7 +379,7 @@ int musb_hub_control( - * initialization logic, e.g. for OTG, or change any - * logic relating to VBUS power-up. - */ -- if (!hcd->self.is_b_host) -+ if (!hcd->self.is_b_host && musb_has_gadget(musb)) - musb_start(musb); - break; - case USB_PORT_FEAT_RESET: ---- a/drivers/usb/musb/omap2430.c -+++ b/drivers/usb/musb/omap2430.c -@@ -37,7 +37,8 @@ - #include <linux/err.h> - #include <linux/delay.h> - #include <linux/usb/musb-omap.h> --#include <linux/usb/omap_control_usb.h> -+#include <linux/phy/omap_control_phy.h> -+#include <linux/of_platform.h> - - #include "musb_core.h" - #include "omap2430.h" -@@ -305,6 +306,9 @@ static void omap_musb_set_mailbox(struct - default: - dev_dbg(dev, "ID float\n"); - } -+ -+ atomic_notifier_call_chain(&musb->xceiv->notifier, -+ musb->xceiv->last_event, NULL); - } - - -@@ -348,11 +352,21 @@ static int omap2430_musb_init(struct mus - * up through ULPI. TWL4030-family PMICs include one, - * which needs a driver, drivers aren't always needed. - */ -- if (dev->parent->of_node) -+ if (dev->parent->of_node) { -+ musb->phy = devm_phy_get(dev->parent, "usb2-phy"); -+ -+ /* We can't totally remove musb->xceiv as of now because -+ * musb core uses xceiv.state and xceiv.otg. Once we have -+ * a separate state machine to handle otg, these can be moved -+ * out of xceiv and then we can start using the generic PHY -+ * framework -+ */ - musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, - "usb-phy", 0); -- else -+ } else { - musb->xceiv = devm_usb_get_phy_dev(dev, 0); -+ musb->phy = devm_phy_get(dev, "usb"); -+ } - - if (IS_ERR(musb->xceiv)) { - status = PTR_ERR(musb->xceiv); -@@ -364,6 +378,10 @@ static int omap2430_musb_init(struct mus - return -EPROBE_DEFER; - } - -+ if (IS_ERR(musb->phy)) { -+ pr_err("HS USB OTG: no PHY configured\n"); -+ return PTR_ERR(musb->phy); -+ } - musb->isr = omap2430_musb_interrupt; - - status = pm_runtime_get_sync(dev); -@@ -397,7 +415,7 @@ static int omap2430_musb_init(struct mus - if (glue->status != OMAP_MUSB_UNKNOWN) - omap_musb_set_mailbox(glue); - -- usb_phy_init(musb->xceiv); -+ phy_init(musb->phy); - - pm_runtime_put_noidle(musb->controller); - return 0; -@@ -460,6 +478,7 @@ static int omap2430_musb_exit(struct mus - del_timer_sync(&musb_idle_timer); - - omap2430_low_level_exit(musb); -+ phy_exit(musb->phy); - - return 0; - } -@@ -489,6 +508,7 @@ static int omap2430_probe(struct platfor - struct device_node *np = pdev->dev.of_node; - struct musb_hdrc_config *config; - int ret = -ENOMEM; -+ int musbid; - - glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { -@@ -496,10 +516,18 @@ static int omap2430_probe(struct platfor - goto err0; - } - -- musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); -+ /* get the musb id */ -+ musbid = musb_get_id(&pdev->dev, GFP_KERNEL); -+ if (musbid < 0) { -+ dev_err(&pdev->dev, "failed to allocate musb id\n"); -+ ret = -ENOMEM; -+ goto err0; -+ } -+ -+ musb = platform_device_alloc("musb-hdrc", musbid); - if (!musb) { - dev_err(&pdev->dev, "failed to allocate musb device\n"); -- goto err0; -+ goto err1; - } - - musb->dev.parent = &pdev->dev; -@@ -509,8 +537,12 @@ static int omap2430_probe(struct platfor - glue->dev = &pdev->dev; - glue->musb = musb; - glue->status = OMAP_MUSB_UNKNOWN; -+ glue->control_otghs = ERR_PTR(-ENODEV); - - if (np) { -+ struct device_node *control_node; -+ struct platform_device *control_pdev; -+ - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(&pdev->dev, -@@ -539,22 +571,20 @@ static int omap2430_probe(struct platfor - of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); - of_property_read_u32(np, "power", (u32 *)&pdata->power); - config->multipoint = of_property_read_bool(np, "multipoint"); -- pdata->has_mailbox = of_property_read_bool(np, -- "ti,has-mailbox"); - - pdata->board_data = data; - pdata->config = config; -- } - -- if (pdata->has_mailbox) { -- glue->control_otghs = omap_get_control_dev(); -- if (IS_ERR(glue->control_otghs)) { -- dev_vdbg(&pdev->dev, "Failed to get control device\n"); -- ret = PTR_ERR(glue->control_otghs); -- goto err2; -+ control_node = of_parse_phandle(np, "ctrl-module", 0); -+ if (control_node) { -+ control_pdev = of_find_device_by_node(control_node); -+ if (!control_pdev) { -+ dev_err(&pdev->dev, "Failed to get control device\n"); -+ ret = -EINVAL; -+ goto err2; -+ } -+ glue->control_otghs = &control_pdev->dev; - } -- } else { -- glue->control_otghs = ERR_PTR(-ENODEV); - } - pdata->platform_ops = &omap2430_ops; - -@@ -612,6 +642,9 @@ static int omap2430_probe(struct platfor - err2: - platform_device_put(musb); - -+err1: -+ musb_put_id(&pdev->dev, musbid); -+ - err0: - return ret; - } -@@ -638,7 +671,7 @@ static int omap2430_runtime_suspend(stru - OTG_INTERFSEL); - - omap2430_low_level_exit(musb); -- usb_phy_set_suspend(musb->xceiv, 1); -+ phy_power_off(musb->phy); - } - - return 0; -@@ -653,8 +686,7 @@ static int omap2430_runtime_resume(struc - omap2430_low_level_init(musb); - musb_writel(musb->mregs, OTG_INTERFSEL, - musb->context.otg_interfsel); -- -- usb_phy_set_suspend(musb->xceiv, 0); -+ phy_power_on(musb->phy); - } - - return 0; ---- a/drivers/usb/musb/tusb6010.c -+++ b/drivers/usb/musb/tusb6010.c -@@ -1152,7 +1152,11 @@ static const struct musb_platform_ops tu - .set_vbus = tusb_musb_set_vbus, - }; - --static u64 tusb_dmamask = DMA_BIT_MASK(32); -+static const struct platform_device_info tusb_dev_info = { -+ .name = "musb-hdrc", -+ .id = PLATFORM_DEVID_AUTO, -+ .dma_mask = DMA_BIT_MASK(32), -+}; - - static int tusb_probe(struct platform_device *pdev) - { -@@ -1160,7 +1164,7 @@ static int tusb_probe(struct platform_de - struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct platform_device *musb; - struct tusb6010_glue *glue; -- -+ struct platform_device_info pinfo; - int ret = -ENOMEM; - - glue = kzalloc(sizeof(*glue), GFP_KERNEL); -@@ -1169,18 +1173,7 @@ static int tusb_probe(struct platform_de - goto err0; - } - -- musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); -- if (!musb) { -- dev_err(&pdev->dev, "failed to allocate musb device\n"); -- goto err1; -- } -- -- musb->dev.parent = &pdev->dev; -- musb->dev.dma_mask = &tusb_dmamask; -- musb->dev.coherent_dma_mask = tusb_dmamask; -- - glue->dev = &pdev->dev; -- glue->musb = musb; - - pdata->platform_ops = &tusb_ops; - -@@ -1204,31 +1197,23 @@ static int tusb_probe(struct platform_de - musb_resources[2].end = pdev->resource[2].end; - musb_resources[2].flags = pdev->resource[2].flags; - -- ret = platform_device_add_resources(musb, musb_resources, -- ARRAY_SIZE(musb_resources)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add resources\n"); -- goto err3; -- } -- -- ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); -- if (ret) { -- dev_err(&pdev->dev, "failed to add platform_data\n"); -- goto err3; -- } -- -- ret = platform_device_add(musb); -- if (ret) { -- dev_err(&pdev->dev, "failed to register musb device\n"); -+ pinfo = tusb_dev_info; -+ pinfo.parent = &pdev->dev; -+ pinfo.res = musb_resources; -+ pinfo.num_res = ARRAY_SIZE(musb_resources); -+ pinfo.data = pdata; -+ pinfo.size_data = sizeof(*pdata); -+ -+ glue->musb = musb = platform_device_register_full(&pinfo); -+ if (IS_ERR(musb)) { -+ ret = PTR_ERR(musb); -+ dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err3; - } - - return 0; - - err3: -- platform_device_put(musb); -- --err1: - kfree(glue); - - err0: ---- a/drivers/usb/musb/ux500.c -+++ b/drivers/usb/musb/ux500.c -@@ -376,17 +376,10 @@ static int ux500_resume(struct device *d - - return 0; - } -- --static const struct dev_pm_ops ux500_pm_ops = { -- .suspend = ux500_suspend, -- .resume = ux500_resume, --}; -- --#define DEV_PM_OPS (&ux500_pm_ops) --#else --#define DEV_PM_OPS NULL - #endif - -+static SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume); -+ - static const struct of_device_id ux500_match[] = { - { .compatible = "stericsson,db8500-musb", }, - {} -@@ -397,7 +390,7 @@ static struct platform_driver ux500_driv - .remove = ux500_remove, - .driver = { - .name = "musb-ux500", -- .pm = DEV_PM_OPS, -+ .pm = &ux500_pm_ops, - .of_match_table = ux500_match, - }, - }; ---- a/drivers/usb/phy/Kconfig -+++ b/drivers/usb/phy/Kconfig -@@ -56,38 +56,6 @@ config NOP_USB_XCEIV - built-in with usb ip or which are autonomous and doesn't require any - phy programming such as ISP1x04 etc. - --config OMAP_CONTROL_USB -- tristate "OMAP CONTROL USB Driver" -- depends on ARCH_OMAP2PLUS || COMPILE_TEST -- help -- Enable this to add support for the USB part present in the control -- module. This driver has API to power on the USB2 PHY and to write to -- the mailbox. The mailbox is present only in omap4 and the register to -- power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an -- additional register to power on USB3 PHY. -- --config OMAP_USB2 -- tristate "OMAP USB2 PHY Driver" -- depends on ARCH_OMAP2PLUS -- select OMAP_CONTROL_USB -- select USB_PHY -- help -- Enable this to support the transceiver that is part of SOC. This -- driver takes care of all the PHY functionality apart from comparator. -- The USB OTG controller communicates with the comparator using this -- driver. -- --config OMAP_USB3 -- tristate "OMAP USB3 PHY Driver" -- depends on ARCH_OMAP2PLUS || COMPILE_TEST -- select OMAP_CONTROL_USB -- select USB_PHY -- help -- Enable this to support the USB3 PHY that is part of SOC. This -- driver takes care of all the PHY functionality apart from comparator. -- This driver interacts with the "OMAP Control USB Driver" to power -- on/off the PHY. -- - config AM335X_CONTROL_USB - tristate - -@@ -123,16 +91,6 @@ config SAMSUNG_USB3PHY - Enable this to support Samsung USB 3.0 (Super Speed) phy controller - for samsung SoCs. - --config TWL4030_USB -- tristate "TWL4030 USB Transceiver Driver" -- depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS -- select USB_PHY -- help -- Enable this to support the USB OTG transceiver on TWL4030 -- family chips (including the TWL5030 and TPS659x0 devices). -- This transceiver supports high and full speed devices plus, -- in host mode, low speed. -- - config TWL6030_USB - tristate "TWL6030 USB Transceiver Driver" - depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS -@@ -214,6 +172,19 @@ config USB_RCAR_PHY - To compile this driver as a module, choose M here: the - module will be called phy-rcar-usb. - -+config USB_RCAR_GEN2_PHY -+ tristate "Renesas R-Car Gen2 USB PHY support" -+ depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST -+ select USB_PHY -+ help -+ Say Y here to add support for the Renesas R-Car Gen2 USB PHY driver. -+ It is typically used to control internal USB PHY for USBHS, -+ and to configure shared USB channels 0 and 2. -+ This driver supports R8A7790 and R8A7791. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called phy-rcar-gen2-usb. -+ - config USB_ULPI - bool "Generic ULPI Transceiver Driver" - depends on ARM ---- a/drivers/usb/phy/Makefile -+++ b/drivers/usb/phy/Makefile -@@ -12,15 +12,11 @@ obj-$(CONFIG_FSL_USB2_OTG) += phy-fsl-u - obj-$(CONFIG_ISP1301_OMAP) += phy-isp1301-omap.o - obj-$(CONFIG_MV_U3D_PHY) += phy-mv-u3d-usb.o - obj-$(CONFIG_NOP_USB_XCEIV) += phy-generic.o --obj-$(CONFIG_OMAP_CONTROL_USB) += phy-omap-control.o - obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o - obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o --obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o --obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o - obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o - obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o - obj-$(CONFIG_SAMSUNG_USB3PHY) += phy-samsung-usb3.o --obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o - obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o - obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o - obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o -@@ -29,5 +25,6 @@ obj-$(CONFIG_USB_MSM_OTG) += phy-msm-us - obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o - obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o - obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o -+obj-$(CONFIG_USB_RCAR_GEN2_PHY) += phy-rcar-gen2-usb.o - obj-$(CONFIG_USB_ULPI) += phy-ulpi.o - obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o ---- a/drivers/usb/phy/phy-am335x.c -+++ b/drivers/usb/phy/phy-am335x.c -@@ -52,23 +52,19 @@ static int am335x_phy_probe(struct platf - return am_phy->id; - } - -- ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, -- USB_PHY_TYPE_USB2, 0, false, false); -+ ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL); - if (ret) - return ret; - - ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy); - if (ret) -- goto err_add; -+ return ret; - am_phy->usb_phy_gen.phy.init = am335x_init; - am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown; - - platform_set_drvdata(pdev, am_phy); -- return 0; - --err_add: -- usb_phy_gen_cleanup_phy(&am_phy->usb_phy_gen); -- return ret; -+ return 0; - } - - static int am335x_phy_remove(struct platform_device *pdev) -@@ -79,6 +75,40 @@ static int am335x_phy_remove(struct plat - return 0; - } - -+#ifdef CONFIG_PM_RUNTIME -+ -+static int am335x_phy_runtime_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct am335x_phy *am_phy = platform_get_drvdata(pdev); -+ -+ if (device_may_wakeup(dev)) -+ phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true); -+ phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false); -+ return 0; -+} -+ -+static int am335x_phy_runtime_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct am335x_phy *am_phy = platform_get_drvdata(pdev); -+ -+ phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true); -+ if (device_may_wakeup(dev)) -+ phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false); -+ return 0; -+} -+ -+static const struct dev_pm_ops am335x_pm_ops = { -+ SET_RUNTIME_PM_OPS(am335x_phy_runtime_suspend, -+ am335x_phy_runtime_resume, NULL) -+}; -+ -+#define DEV_PM_OPS (&am335x_pm_ops) -+#else -+#define DEV_PM_OPS NULL -+#endif -+ - static const struct of_device_id am335x_phy_ids[] = { - { .compatible = "ti,am335x-usb-phy" }, - { } -@@ -91,7 +121,8 @@ static struct platform_driver am335x_phy - .driver = { - .name = "am335x-phy-driver", - .owner = THIS_MODULE, -- .of_match_table = of_match_ptr(am335x_phy_ids), -+ .pm = DEV_PM_OPS, -+ .of_match_table = am335x_phy_ids, - }, - }; - ---- a/drivers/usb/phy/phy-am335x-control.c -+++ b/drivers/usb/phy/phy-am335x-control.c -@@ -26,6 +26,41 @@ struct am335x_control_usb { - #define USBPHY_OTGVDET_EN (1 << 19) - #define USBPHY_OTGSESSEND_EN (1 << 20) - -+#define AM335X_PHY0_WK_EN (1 << 0) -+#define AM335X_PHY1_WK_EN (1 << 8) -+ -+static void am335x_phy_wkup(struct phy_control *phy_ctrl, u32 id, bool on) -+{ -+ struct am335x_control_usb *usb_ctrl; -+ u32 val; -+ u32 reg; -+ -+ usb_ctrl = container_of(phy_ctrl, struct am335x_control_usb, phy_ctrl); -+ -+ switch (id) { -+ case 0: -+ reg = AM335X_PHY0_WK_EN; -+ break; -+ case 1: -+ reg = AM335X_PHY1_WK_EN; -+ break; -+ default: -+ WARN_ON(1); -+ return; -+ } -+ -+ spin_lock(&usb_ctrl->lock); -+ val = readl(usb_ctrl->wkup); -+ -+ if (on) -+ val |= reg; -+ else -+ val &= ~reg; -+ -+ writel(val, usb_ctrl->wkup); -+ spin_unlock(&usb_ctrl->lock); -+} -+ - static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) - { - struct am335x_control_usb *usb_ctrl; -@@ -59,6 +94,7 @@ static void am335x_phy_power(struct phy_ - - static const struct phy_control ctrl_am335x = { - .phy_power = am335x_phy_power, -+ .phy_wkup = am335x_phy_wkup, - }; - - static const struct of_device_id omap_control_usb_id_table[] = { -@@ -117,6 +153,12 @@ static int am335x_control_usb_probe(stru - ctrl_usb->phy_reg = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(ctrl_usb->phy_reg)) - return PTR_ERR(ctrl_usb->phy_reg); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wakeup"); -+ ctrl_usb->wkup = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(ctrl_usb->wkup)) -+ return PTR_ERR(ctrl_usb->wkup); -+ - spin_lock_init(&ctrl_usb->lock); - ctrl_usb->phy_ctrl = *phy_ctrl; - -@@ -129,7 +171,7 @@ static struct platform_driver am335x_con - .driver = { - .name = "am335x-control-usb", - .owner = THIS_MODULE, -- .of_match_table = of_match_ptr(omap_control_usb_id_table), -+ .of_match_table = omap_control_usb_id_table, - }, - }; - ---- a/drivers/usb/phy/phy.c -+++ b/drivers/usb/phy/phy.c -@@ -98,7 +98,7 @@ struct usb_phy *devm_usb_get_phy(struct - - ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) -- return NULL; -+ return ERR_PTR(-ENOMEM); - - phy = usb_get_phy(type); - if (!IS_ERR(phy)) { ---- a/drivers/usb/phy/phy-fsl-usb.c -+++ b/drivers/usb/phy/phy-fsl-usb.c -@@ -134,7 +134,7 @@ int write_ulpi(u8 addr, u8 data) - /* Operations that will be called from OTG Finite State Machine */ - - /* Charge vbus for vbus pulsing in SRP */ --void fsl_otg_chrg_vbus(int on) -+void fsl_otg_chrg_vbus(struct otg_fsm *fsm, int on) - { - u32 tmp; - -@@ -170,7 +170,7 @@ void fsl_otg_dischrg_vbus(int on) - } - - /* A-device driver vbus, controlled through PP bit in PORTSC */ --void fsl_otg_drv_vbus(int on) -+void fsl_otg_drv_vbus(struct otg_fsm *fsm, int on) - { - u32 tmp; - -@@ -188,7 +188,7 @@ void fsl_otg_drv_vbus(int on) - * Pull-up D+, signalling connect by periperal. Also used in - * data-line pulsing in SRP - */ --void fsl_otg_loc_conn(int on) -+void fsl_otg_loc_conn(struct otg_fsm *fsm, int on) - { - u32 tmp; - -@@ -207,7 +207,7 @@ void fsl_otg_loc_conn(int on) - * port. In host mode, controller will automatically send SOF. - * Suspend will block the data on the port. - */ --void fsl_otg_loc_sof(int on) -+void fsl_otg_loc_sof(struct otg_fsm *fsm, int on) - { - u32 tmp; - -@@ -222,7 +222,7 @@ void fsl_otg_loc_sof(int on) - } - - /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */ --void fsl_otg_start_pulse(void) -+void fsl_otg_start_pulse(struct otg_fsm *fsm) - { - u32 tmp; - -@@ -235,7 +235,7 @@ void fsl_otg_start_pulse(void) - fsl_otg_loc_conn(1); - #endif - -- fsl_otg_add_timer(b_data_pulse_tmr); -+ fsl_otg_add_timer(fsm, b_data_pulse_tmr); - } - - void b_data_pulse_end(unsigned long foo) -@@ -252,14 +252,14 @@ void b_data_pulse_end(unsigned long foo) - void fsl_otg_pulse_vbus(void) - { - srp_wait_done = 0; -- fsl_otg_chrg_vbus(1); -+ fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1); - /* start the timer to end vbus charge */ -- fsl_otg_add_timer(b_vbus_pulse_tmr); -+ fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr); - } - - void b_vbus_pulse_end(unsigned long foo) - { -- fsl_otg_chrg_vbus(0); -+ fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0); - - /* - * As USB3300 using the same a_sess_vld and b_sess_vld voltage -@@ -267,7 +267,7 @@ void b_vbus_pulse_end(unsigned long foo) - * residual voltage of vbus pulsing and A device pull up - */ - fsl_otg_dischrg_vbus(1); -- fsl_otg_add_timer(b_srp_wait_tmr); -+ fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr); - } - - void b_srp_end(unsigned long foo) -@@ -289,7 +289,7 @@ void a_wait_enum(unsigned long foo) - { - VDBG("a_wait_enum timeout\n"); - if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) -- fsl_otg_add_timer(a_wait_enum_tmr); -+ fsl_otg_add_timer(&fsl_otg_dev->fsm, a_wait_enum_tmr); - else - otg_statemachine(&fsl_otg_dev->fsm); - } -@@ -375,8 +375,42 @@ void fsl_otg_uninit_timers(void) - kfree(b_vbus_pulse_tmr); - } - -+static struct fsl_otg_timer *fsl_otg_get_timer(enum otg_fsm_timer t) -+{ -+ struct fsl_otg_timer *timer; -+ -+ /* REVISIT: use array of pointers to timers instead */ -+ switch (t) { -+ case A_WAIT_VRISE: -+ timer = a_wait_vrise_tmr; -+ break; -+ case A_WAIT_BCON: -+ timer = a_wait_vrise_tmr; -+ break; -+ case A_AIDL_BDIS: -+ timer = a_wait_vrise_tmr; -+ break; -+ case B_ASE0_BRST: -+ timer = a_wait_vrise_tmr; -+ break; -+ case B_SE0_SRP: -+ timer = a_wait_vrise_tmr; -+ break; -+ case B_SRP_FAIL: -+ timer = a_wait_vrise_tmr; -+ break; -+ case A_WAIT_ENUM: -+ timer = a_wait_vrise_tmr; -+ break; -+ default: -+ timer = NULL; -+ } -+ -+ return timer; -+} -+ - /* Add timer to timer list */ --void fsl_otg_add_timer(void *gtimer) -+void fsl_otg_add_timer(struct otg_fsm *fsm, void *gtimer) - { - struct fsl_otg_timer *timer = gtimer; - struct fsl_otg_timer *tmp_timer; -@@ -394,8 +428,19 @@ void fsl_otg_add_timer(void *gtimer) - list_add_tail(&timer->list, &active_timers); - } - -+static void fsl_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) -+{ -+ struct fsl_otg_timer *timer; -+ -+ timer = fsl_otg_get_timer(t); -+ if (!timer) -+ return; -+ -+ fsl_otg_add_timer(fsm, timer); -+} -+ - /* Remove timer from the timer list; clear timeout status */ --void fsl_otg_del_timer(void *gtimer) -+void fsl_otg_del_timer(struct otg_fsm *fsm, void *gtimer) - { - struct fsl_otg_timer *timer = gtimer; - struct fsl_otg_timer *tmp_timer, *del_tmp; -@@ -405,6 +450,17 @@ void fsl_otg_del_timer(void *gtimer) - list_del(&timer->list); - } - -+static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) -+{ -+ struct fsl_otg_timer *timer; -+ -+ timer = fsl_otg_get_timer(t); -+ if (!timer) -+ return; -+ -+ fsl_otg_del_timer(fsm, timer); -+} -+ - /* - * Reduce timer count by 1, and find timeout conditions. - * Called by fsl_otg 1ms timer interrupt -@@ -468,7 +524,7 @@ int fsl_otg_start_host(struct otg_fsm *f - retval = dev->driver->pm->resume(dev); - if (fsm->id) { - /* default-b */ -- fsl_otg_drv_vbus(1); -+ fsl_otg_drv_vbus(fsm, 1); - /* - * Workaround: b_host can't driver - * vbus, but PP in PORTSC needs to -@@ -493,7 +549,7 @@ int fsl_otg_start_host(struct otg_fsm *f - retval = dev->driver->pm->suspend(dev); - if (fsm->id) - /* default-b */ -- fsl_otg_drv_vbus(0); -+ fsl_otg_drv_vbus(fsm, 0); - } - otg_dev->host_working = 0; - } -@@ -757,8 +813,8 @@ static struct otg_fsm_ops fsl_otg_ops = - .loc_sof = fsl_otg_loc_sof, - .start_pulse = fsl_otg_start_pulse, - -- .add_timer = fsl_otg_add_timer, -- .del_timer = fsl_otg_del_timer, -+ .add_timer = fsl_otg_fsm_add_timer, -+ .del_timer = fsl_otg_fsm_del_timer, - - .start_host = fsl_otg_start_host, - .start_gadget = fsl_otg_start_gadget, -@@ -1011,7 +1067,7 @@ static int show_fsl_usb2_otg_state(struc - "b_bus_suspend: %d\n" - "b_conn: %d\n" - "b_se0_srp: %d\n" -- "b_sess_end: %d\n" -+ "b_ssend_srp: %d\n" - "b_sess_vld: %d\n" - "id: %d\n", - fsm->a_bus_req, -@@ -1026,7 +1082,7 @@ static int show_fsl_usb2_otg_state(struc - fsm->b_bus_suspend, - fsm->b_conn, - fsm->b_se0_srp, -- fsm->b_sess_end, -+ fsm->b_ssend_srp, - fsm->b_sess_vld, - fsm->id); - size -= t; -@@ -1057,7 +1113,7 @@ static long fsl_otg_ioctl(struct file *f - break; - - case SET_A_SUSPEND_REQ: -- fsl_otg_dev->fsm.a_suspend_req = arg; -+ fsl_otg_dev->fsm.a_suspend_req_inf = arg; - break; - - case SET_A_BUS_DROP: ---- a/drivers/usb/phy/phy-fsl-usb.h -+++ b/drivers/usb/phy/phy-fsl-usb.h -@@ -401,6 +401,6 @@ struct fsl_otg_config { - #define GET_A_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 8, int) - #define GET_B_BUS_REQ _IOR(OTG_IOCTL_MAGIC, 9, int) - --void fsl_otg_add_timer(void *timer); --void fsl_otg_del_timer(void *timer); -+void fsl_otg_add_timer(struct otg_fsm *fsm, void *timer); -+void fsl_otg_del_timer(struct otg_fsm *fsm, void *timer); - void fsl_otg_pulse_vbus(void); ---- a/drivers/usb/phy/phy-fsm-usb.c -+++ b/drivers/usb/phy/phy-fsm-usb.c -@@ -41,17 +41,17 @@ static int otg_set_protocol(struct otg_f - fsm->protocol, protocol); - /* stop old protocol */ - if (fsm->protocol == PROTO_HOST) -- ret = fsm->ops->start_host(fsm, 0); -+ ret = otg_start_host(fsm, 0); - else if (fsm->protocol == PROTO_GADGET) -- ret = fsm->ops->start_gadget(fsm, 0); -+ ret = otg_start_gadget(fsm, 0); - if (ret) - return ret; - - /* start new protocol */ - if (protocol == PROTO_HOST) -- ret = fsm->ops->start_host(fsm, 1); -+ ret = otg_start_host(fsm, 1); - else if (protocol == PROTO_GADGET) -- ret = fsm->ops->start_gadget(fsm, 1); -+ ret = otg_start_gadget(fsm, 1); - if (ret) - return ret; - -@@ -69,42 +69,50 @@ void otg_leave_state(struct otg_fsm *fsm - { - switch (old_state) { - case OTG_STATE_B_IDLE: -- otg_del_timer(fsm, b_se0_srp_tmr); -+ otg_del_timer(fsm, B_SE0_SRP); - fsm->b_se0_srp = 0; -+ fsm->adp_sns = 0; -+ fsm->adp_prb = 0; - break; - case OTG_STATE_B_SRP_INIT: -+ fsm->data_pulse = 0; - fsm->b_srp_done = 0; - break; - case OTG_STATE_B_PERIPHERAL: - break; - case OTG_STATE_B_WAIT_ACON: -- otg_del_timer(fsm, b_ase0_brst_tmr); -+ otg_del_timer(fsm, B_ASE0_BRST); - fsm->b_ase0_brst_tmout = 0; - break; - case OTG_STATE_B_HOST: - break; - case OTG_STATE_A_IDLE: -+ fsm->adp_prb = 0; - break; - case OTG_STATE_A_WAIT_VRISE: -- otg_del_timer(fsm, a_wait_vrise_tmr); -+ otg_del_timer(fsm, A_WAIT_VRISE); - fsm->a_wait_vrise_tmout = 0; - break; - case OTG_STATE_A_WAIT_BCON: -- otg_del_timer(fsm, a_wait_bcon_tmr); -+ otg_del_timer(fsm, A_WAIT_BCON); - fsm->a_wait_bcon_tmout = 0; - break; - case OTG_STATE_A_HOST: -- otg_del_timer(fsm, a_wait_enum_tmr); -+ otg_del_timer(fsm, A_WAIT_ENUM); - break; - case OTG_STATE_A_SUSPEND: -- otg_del_timer(fsm, a_aidl_bdis_tmr); -+ otg_del_timer(fsm, A_AIDL_BDIS); - fsm->a_aidl_bdis_tmout = 0; -- fsm->a_suspend_req = 0; -+ fsm->a_suspend_req_inf = 0; - break; - case OTG_STATE_A_PERIPHERAL: -+ otg_del_timer(fsm, A_BIDL_ADIS); -+ fsm->a_bidl_adis_tmout = 0; - break; - case OTG_STATE_A_WAIT_VFALL: -- otg_del_timer(fsm, a_wait_vrise_tmr); -+ otg_del_timer(fsm, A_WAIT_VFALL); -+ fsm->a_wait_vfall_tmout = 0; -+ otg_del_timer(fsm, A_WAIT_VRISE); - break; - case OTG_STATE_A_VBUS_ERR: - break; -@@ -127,14 +135,19 @@ int otg_set_state(struct otg_fsm *fsm, e - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); -+ /* -+ * Driver is responsible for starting ADP probing -+ * if ADP sensing times out. -+ */ -+ otg_start_adp_sns(fsm); - otg_set_protocol(fsm, PROTO_UNDEF); -- otg_add_timer(fsm, b_se0_srp_tmr); -+ otg_add_timer(fsm, B_SE0_SRP); - break; - case OTG_STATE_B_SRP_INIT: - otg_start_pulse(fsm); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_UNDEF); -- otg_add_timer(fsm, b_srp_fail_tmr); -+ otg_add_timer(fsm, B_SRP_FAIL); - break; - case OTG_STATE_B_PERIPHERAL: - otg_chrg_vbus(fsm, 0); -@@ -147,7 +160,7 @@ int otg_set_state(struct otg_fsm *fsm, e - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); -- otg_add_timer(fsm, b_ase0_brst_tmr); -+ otg_add_timer(fsm, B_ASE0_BRST); - fsm->a_bus_suspend = 0; - break; - case OTG_STATE_B_HOST: -@@ -163,6 +176,7 @@ int otg_set_state(struct otg_fsm *fsm, e - otg_chrg_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); -+ otg_start_adp_prb(fsm); - otg_set_protocol(fsm, PROTO_HOST); - break; - case OTG_STATE_A_WAIT_VRISE: -@@ -170,14 +184,14 @@ int otg_set_state(struct otg_fsm *fsm, e - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); -- otg_add_timer(fsm, a_wait_vrise_tmr); -+ otg_add_timer(fsm, A_WAIT_VRISE); - break; - case OTG_STATE_A_WAIT_BCON: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); -- otg_add_timer(fsm, a_wait_bcon_tmr); -+ otg_add_timer(fsm, A_WAIT_BCON); - break; - case OTG_STATE_A_HOST: - otg_drv_vbus(fsm, 1); -@@ -188,15 +202,15 @@ int otg_set_state(struct otg_fsm *fsm, e - * When HNP is triggered while a_bus_req = 0, a_host will - * suspend too fast to complete a_set_b_hnp_en - */ -- if (!fsm->a_bus_req || fsm->a_suspend_req) -- otg_add_timer(fsm, a_wait_enum_tmr); -+ if (!fsm->a_bus_req || fsm->a_suspend_req_inf) -+ otg_add_timer(fsm, A_WAIT_ENUM); - break; - case OTG_STATE_A_SUSPEND: - otg_drv_vbus(fsm, 1); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); -- otg_add_timer(fsm, a_aidl_bdis_tmr); -+ otg_add_timer(fsm, A_AIDL_BDIS); - - break; - case OTG_STATE_A_PERIPHERAL: -@@ -204,12 +218,14 @@ int otg_set_state(struct otg_fsm *fsm, e - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_GADGET); - otg_drv_vbus(fsm, 1); -+ otg_add_timer(fsm, A_BIDL_ADIS); - break; - case OTG_STATE_A_WAIT_VFALL: - otg_drv_vbus(fsm, 0); - otg_loc_conn(fsm, 0); - otg_loc_sof(fsm, 0); - otg_set_protocol(fsm, PROTO_HOST); -+ otg_add_timer(fsm, A_WAIT_VFALL); - break; - case OTG_STATE_A_VBUS_ERR: - otg_drv_vbus(fsm, 0); -@@ -250,7 +266,8 @@ int otg_statemachine(struct otg_fsm *fsm - otg_set_state(fsm, OTG_STATE_A_IDLE); - else if (fsm->b_sess_vld && fsm->otg->gadget) - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); -- else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp) -+ else if ((fsm->b_bus_req || fsm->adp_change || fsm->power_up) && -+ fsm->b_ssend_srp && fsm->b_se0_srp) - otg_set_state(fsm, OTG_STATE_B_SRP_INIT); - break; - case OTG_STATE_B_SRP_INIT: -@@ -277,13 +294,14 @@ int otg_statemachine(struct otg_fsm *fsm - case OTG_STATE_B_HOST: - if (!fsm->id || !fsm->b_sess_vld) - otg_set_state(fsm, OTG_STATE_B_IDLE); -- else if (!fsm->b_bus_req || !fsm->a_conn) -+ else if (!fsm->b_bus_req || !fsm->a_conn || fsm->test_device) - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); - break; - case OTG_STATE_A_IDLE: - if (fsm->id) - otg_set_state(fsm, OTG_STATE_B_IDLE); -- else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) -+ else if (!fsm->a_bus_drop && (fsm->a_bus_req || -+ fsm->a_srp_det || fsm->adp_change || fsm->power_up)) - otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); - break; - case OTG_STATE_A_WAIT_VRISE: -@@ -301,7 +319,7 @@ int otg_statemachine(struct otg_fsm *fsm - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); - break; - case OTG_STATE_A_HOST: -- if ((!fsm->a_bus_req || fsm->a_suspend_req) && -+ if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) && - fsm->otg->host->b_hnp_enable) - otg_set_state(fsm, OTG_STATE_A_SUSPEND); - else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) -@@ -324,14 +342,14 @@ int otg_statemachine(struct otg_fsm *fsm - case OTG_STATE_A_PERIPHERAL: - if (fsm->id || fsm->a_bus_drop) - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); -- else if (fsm->b_bus_suspend) -+ else if (fsm->a_bidl_adis_tmout || fsm->b_bus_suspend) - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); - else if (!fsm->a_vbus_vld) - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); - break; - case OTG_STATE_A_WAIT_VFALL: -- if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld && -- !fsm->b_conn)) -+ if (fsm->a_wait_vfall_tmout || fsm->id || fsm->a_bus_req || -+ (!fsm->a_sess_vld && !fsm->b_conn)) - otg_set_state(fsm, OTG_STATE_A_IDLE); - break; - case OTG_STATE_A_VBUS_ERR: ---- a/drivers/usb/phy/phy-fsm-usb.h -+++ b/drivers/usb/phy/phy-fsm-usb.h -@@ -34,45 +34,76 @@ - #define PROTO_HOST (1) - #define PROTO_GADGET (2) - -+enum otg_fsm_timer { -+ /* Standard OTG timers */ -+ A_WAIT_VRISE, -+ A_WAIT_VFALL, -+ A_WAIT_BCON, -+ A_AIDL_BDIS, -+ B_ASE0_BRST, -+ A_BIDL_ADIS, -+ -+ /* Auxiliary timers */ -+ B_SE0_SRP, -+ B_SRP_FAIL, -+ A_WAIT_ENUM, -+ -+ NUM_OTG_FSM_TIMERS, -+}; -+ - /* OTG state machine according to the OTG spec */ - struct otg_fsm { - /* Input */ -+ int id; -+ int adp_change; -+ int power_up; -+ int test_device; -+ int a_bus_drop; -+ int a_bus_req; -+ int a_srp_det; -+ int a_vbus_vld; -+ int b_conn; - int a_bus_resume; - int a_bus_suspend; - int a_conn; -+ int b_bus_req; -+ int b_se0_srp; -+ int b_ssend_srp; -+ int b_sess_vld; -+ /* Auxilary inputs */ - int a_sess_vld; -- int a_srp_det; -- int a_vbus_vld; - int b_bus_resume; - int b_bus_suspend; -- int b_conn; -- int b_se0_srp; -- int b_sess_end; -- int b_sess_vld; -- int id; -+ -+ /* Output */ -+ int data_pulse; -+ int drv_vbus; -+ int loc_conn; -+ int loc_sof; -+ int adp_prb; -+ int adp_sns; - - /* Internal variables */ - int a_set_b_hnp_en; - int b_srp_done; - int b_hnp_enable; -+ int a_clr_err; -+ -+ /* Informative variables */ -+ int a_bus_drop_inf; -+ int a_bus_req_inf; -+ int a_clr_err_inf; -+ int b_bus_req_inf; -+ /* Auxilary informative variables */ -+ int a_suspend_req_inf; - - /* Timeout indicator for timers */ - int a_wait_vrise_tmout; -+ int a_wait_vfall_tmout; - int a_wait_bcon_tmout; - int a_aidl_bdis_tmout; - int b_ase0_brst_tmout; -- -- /* Informative variables */ -- int a_bus_drop; -- int a_bus_req; -- int a_clr_err; -- int a_suspend_req; -- int b_bus_req; -- -- /* Output */ -- int drv_vbus; -- int loc_conn; -- int loc_sof; -+ int a_bidl_adis_tmout; - - struct otg_fsm_ops *ops; - struct usb_otg *otg; -@@ -83,65 +114,123 @@ struct otg_fsm { - }; - - struct otg_fsm_ops { -- void (*chrg_vbus)(int on); -- void (*drv_vbus)(int on); -- void (*loc_conn)(int on); -- void (*loc_sof)(int on); -- void (*start_pulse)(void); -- void (*add_timer)(void *timer); -- void (*del_timer)(void *timer); -+ void (*chrg_vbus)(struct otg_fsm *fsm, int on); -+ void (*drv_vbus)(struct otg_fsm *fsm, int on); -+ void (*loc_conn)(struct otg_fsm *fsm, int on); -+ void (*loc_sof)(struct otg_fsm *fsm, int on); -+ void (*start_pulse)(struct otg_fsm *fsm); -+ void (*start_adp_prb)(struct otg_fsm *fsm); -+ void (*start_adp_sns)(struct otg_fsm *fsm); -+ void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); -+ void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); - int (*start_host)(struct otg_fsm *fsm, int on); - int (*start_gadget)(struct otg_fsm *fsm, int on); - }; - - --static inline void otg_chrg_vbus(struct otg_fsm *fsm, int on) -+static inline int otg_chrg_vbus(struct otg_fsm *fsm, int on) - { -- fsm->ops->chrg_vbus(on); -+ if (!fsm->ops->chrg_vbus) -+ return -EOPNOTSUPP; -+ fsm->ops->chrg_vbus(fsm, on); -+ return 0; - } - --static inline void otg_drv_vbus(struct otg_fsm *fsm, int on) -+static inline int otg_drv_vbus(struct otg_fsm *fsm, int on) - { -+ if (!fsm->ops->drv_vbus) -+ return -EOPNOTSUPP; - if (fsm->drv_vbus != on) { - fsm->drv_vbus = on; -- fsm->ops->drv_vbus(on); -+ fsm->ops->drv_vbus(fsm, on); - } -+ return 0; - } - --static inline void otg_loc_conn(struct otg_fsm *fsm, int on) -+static inline int otg_loc_conn(struct otg_fsm *fsm, int on) - { -+ if (!fsm->ops->loc_conn) -+ return -EOPNOTSUPP; - if (fsm->loc_conn != on) { - fsm->loc_conn = on; -- fsm->ops->loc_conn(on); -+ fsm->ops->loc_conn(fsm, on); - } -+ return 0; - } - --static inline void otg_loc_sof(struct otg_fsm *fsm, int on) -+static inline int otg_loc_sof(struct otg_fsm *fsm, int on) - { -+ if (!fsm->ops->loc_sof) -+ return -EOPNOTSUPP; - if (fsm->loc_sof != on) { - fsm->loc_sof = on; -- fsm->ops->loc_sof(on); -+ fsm->ops->loc_sof(fsm, on); -+ } -+ return 0; -+} -+ -+static inline int otg_start_pulse(struct otg_fsm *fsm) -+{ -+ if (!fsm->ops->start_pulse) -+ return -EOPNOTSUPP; -+ if (!fsm->data_pulse) { -+ fsm->data_pulse = 1; -+ fsm->ops->start_pulse(fsm); - } -+ return 0; - } - --static inline void otg_start_pulse(struct otg_fsm *fsm) -+static inline int otg_start_adp_prb(struct otg_fsm *fsm) - { -- fsm->ops->start_pulse(); -+ if (!fsm->ops->start_adp_prb) -+ return -EOPNOTSUPP; -+ if (!fsm->adp_prb) { -+ fsm->adp_sns = 0; -+ fsm->adp_prb = 1; -+ fsm->ops->start_adp_prb(fsm); -+ } -+ return 0; - } - --static inline void otg_add_timer(struct otg_fsm *fsm, void *timer) -+static inline int otg_start_adp_sns(struct otg_fsm *fsm) - { -- fsm->ops->add_timer(timer); -+ if (!fsm->ops->start_adp_sns) -+ return -EOPNOTSUPP; -+ if (!fsm->adp_sns) { -+ fsm->adp_sns = 1; -+ fsm->ops->start_adp_sns(fsm); -+ } -+ return 0; - } - --static inline void otg_del_timer(struct otg_fsm *fsm, void *timer) -+static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer) - { -- fsm->ops->del_timer(timer); -+ if (!fsm->ops->add_timer) -+ return -EOPNOTSUPP; -+ fsm->ops->add_timer(fsm, timer); -+ return 0; - } - --int otg_statemachine(struct otg_fsm *fsm); -+static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer) -+{ -+ if (!fsm->ops->del_timer) -+ return -EOPNOTSUPP; -+ fsm->ops->del_timer(fsm, timer); -+ return 0; -+} - --/* Defined by device specific driver, for different timer implementation */ --extern struct fsl_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, -- *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_fail_tmr, -- *a_wait_enum_tmr; -+static inline int otg_start_host(struct otg_fsm *fsm, int on) -+{ -+ if (!fsm->ops->start_host) -+ return -EOPNOTSUPP; -+ return fsm->ops->start_host(fsm, on); -+} -+ -+static inline int otg_start_gadget(struct otg_fsm *fsm, int on) -+{ -+ if (!fsm->ops->start_gadget) -+ return -EOPNOTSUPP; -+ return fsm->ops->start_gadget(fsm, on); -+} -+ -+int otg_statemachine(struct otg_fsm *fsm); ---- a/drivers/usb/phy/phy-generic.c -+++ b/drivers/usb/phy/phy-generic.c -@@ -35,6 +35,9 @@ - #include <linux/clk.h> - #include <linux/regulator/consumer.h> - #include <linux/of.h> -+#include <linux/of_gpio.h> -+#include <linux/gpio.h> -+#include <linux/delay.h> - - #include "phy-generic.h" - -@@ -64,6 +67,23 @@ static int nop_set_suspend(struct usb_ph - return 0; - } - -+static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) -+{ -+ int value; -+ -+ if (!gpio_is_valid(nop->gpio_reset)) -+ return; -+ -+ value = asserted; -+ if (nop->reset_active_low) -+ value = !value; -+ -+ gpio_set_value_cansleep(nop->gpio_reset, value); -+ -+ if (!asserted) -+ usleep_range(10000, 20000); -+} -+ - int usb_gen_phy_init(struct usb_phy *phy) - { - struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); -@@ -74,13 +94,10 @@ int usb_gen_phy_init(struct usb_phy *phy - } - - if (!IS_ERR(nop->clk)) -- clk_enable(nop->clk); -+ clk_prepare_enable(nop->clk); - -- if (!IS_ERR(nop->reset)) { -- /* De-assert RESET */ -- if (regulator_enable(nop->reset)) -- dev_err(phy->dev, "Failed to de-assert reset\n"); -- } -+ /* De-assert RESET */ -+ nop_reset_set(nop, 0); - - return 0; - } -@@ -90,14 +107,11 @@ void usb_gen_phy_shutdown(struct usb_phy - { - struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); - -- if (!IS_ERR(nop->reset)) { -- /* Assert RESET */ -- if (regulator_disable(nop->reset)) -- dev_err(phy->dev, "Failed to assert reset\n"); -- } -+ /* Assert RESET */ -+ nop_reset_set(nop, 1); - - if (!IS_ERR(nop->clk)) -- clk_disable(nop->clk); -+ clk_disable_unprepare(nop->clk); - - if (!IS_ERR(nop->vcc)) { - if (regulator_disable(nop->vcc)) -@@ -136,11 +150,38 @@ static int nop_set_host(struct usb_otg * - } - - int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, -- enum usb_phy_type type, u32 clk_rate, bool needs_vcc, -- bool needs_reset) -+ struct usb_phy_gen_xceiv_platform_data *pdata) - { -+ enum usb_phy_type type = USB_PHY_TYPE_USB2; - int err; - -+ u32 clk_rate = 0; -+ bool needs_vcc = false; -+ -+ nop->reset_active_low = true; /* default behaviour */ -+ -+ if (dev->of_node) { -+ struct device_node *node = dev->of_node; -+ enum of_gpio_flags flags; -+ -+ if (of_property_read_u32(node, "clock-frequency", &clk_rate)) -+ clk_rate = 0; -+ -+ needs_vcc = of_property_read_bool(node, "vcc-supply"); -+ nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios", -+ 0, &flags); -+ if (nop->gpio_reset == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW; -+ -+ } else if (pdata) { -+ type = pdata->type; -+ clk_rate = pdata->clk_rate; -+ needs_vcc = pdata->needs_vcc; -+ nop->gpio_reset = pdata->gpio_reset; -+ } -+ - nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), - GFP_KERNEL); - if (!nop->phy.otg) -@@ -160,14 +201,6 @@ int usb_phy_gen_create_phy(struct device - } - } - -- if (!IS_ERR(nop->clk)) { -- err = clk_prepare(nop->clk); -- if (err) { -- dev_err(dev, "Error preparing clock\n"); -- return err; -- } -- } -- - nop->vcc = devm_regulator_get(dev, "vcc"); - if (IS_ERR(nop->vcc)) { - dev_dbg(dev, "Error getting vcc regulator: %ld\n", -@@ -176,12 +209,22 @@ int usb_phy_gen_create_phy(struct device - return -EPROBE_DEFER; - } - -- nop->reset = devm_regulator_get(dev, "reset"); -- if (IS_ERR(nop->reset)) { -- dev_dbg(dev, "Error getting reset regulator: %ld\n", -- PTR_ERR(nop->reset)); -- if (needs_reset) -- return -EPROBE_DEFER; -+ if (gpio_is_valid(nop->gpio_reset)) { -+ unsigned long gpio_flags; -+ -+ /* Assert RESET */ -+ if (nop->reset_active_low) -+ gpio_flags = GPIOF_OUT_INIT_LOW; -+ else -+ gpio_flags = GPIOF_OUT_INIT_HIGH; -+ -+ err = devm_gpio_request_one(dev, nop->gpio_reset, -+ gpio_flags, dev_name(dev)); -+ if (err) { -+ dev_err(dev, "Error requesting RESET GPIO %d\n", -+ nop->gpio_reset); -+ return err; -+ } - } - - nop->dev = dev; -@@ -200,48 +243,17 @@ int usb_phy_gen_create_phy(struct device - } - EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); - --void usb_phy_gen_cleanup_phy(struct usb_phy_gen_xceiv *nop) --{ -- if (!IS_ERR(nop->clk)) -- clk_unprepare(nop->clk); --} --EXPORT_SYMBOL_GPL(usb_phy_gen_cleanup_phy); -- - static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct usb_phy_gen_xceiv_platform_data *pdata = -- dev_get_platdata(&pdev->dev); - struct usb_phy_gen_xceiv *nop; -- enum usb_phy_type type = USB_PHY_TYPE_USB2; - int err; -- u32 clk_rate = 0; -- bool needs_vcc = false; -- bool needs_reset = false; -- -- if (dev->of_node) { -- struct device_node *node = dev->of_node; -- -- if (of_property_read_u32(node, "clock-frequency", &clk_rate)) -- clk_rate = 0; -- -- needs_vcc = of_property_read_bool(node, "vcc-supply"); -- needs_reset = of_property_read_bool(node, "reset-supply"); -- -- } else if (pdata) { -- type = pdata->type; -- clk_rate = pdata->clk_rate; -- needs_vcc = pdata->needs_vcc; -- needs_reset = pdata->needs_reset; -- } - - nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); - if (!nop) - return -ENOMEM; - -- -- err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc, -- needs_reset); -+ err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev)); - if (err) - return err; - -@@ -252,23 +264,18 @@ static int usb_phy_gen_xceiv_probe(struc - if (err) { - dev_err(&pdev->dev, "can't register transceiver, err: %d\n", - err); -- goto err_add; -+ return err; - } - - platform_set_drvdata(pdev, nop); - - return 0; -- --err_add: -- usb_phy_gen_cleanup_phy(nop); -- return err; - } - - static int usb_phy_gen_xceiv_remove(struct platform_device *pdev) - { - struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev); - -- usb_phy_gen_cleanup_phy(nop); - usb_remove_phy(&nop->phy); - - return 0; ---- a/drivers/usb/phy/phy-generic.h -+++ b/drivers/usb/phy/phy-generic.h -@@ -1,20 +1,21 @@ - #ifndef _PHY_GENERIC_H_ - #define _PHY_GENERIC_H_ - -+#include <linux/usb/usb_phy_gen_xceiv.h> -+ - struct usb_phy_gen_xceiv { - struct usb_phy phy; - struct device *dev; - struct clk *clk; - struct regulator *vcc; -- struct regulator *reset; -+ int gpio_reset; -+ bool reset_active_low; - }; - - int usb_gen_phy_init(struct usb_phy *phy); - void usb_gen_phy_shutdown(struct usb_phy *phy); - - int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, -- enum usb_phy_type type, u32 clk_rate, bool needs_vcc, -- bool needs_reset); --void usb_phy_gen_cleanup_phy(struct usb_phy_gen_xceiv *nop); -+ struct usb_phy_gen_xceiv_platform_data *pdata); - - #endif ---- a/drivers/usb/phy/phy-omap-control.c -+++ /dev/null -@@ -1,290 +0,0 @@ --/* -- * omap-control-usb.c - The USB part of control module. -- * -- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -- * 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. -- * -- * Author: Kishon Vijay Abraham I <kishon@ti.com> -- * -- * 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. -- * -- */ -- --#include <linux/module.h> --#include <linux/platform_device.h> --#include <linux/slab.h> --#include <linux/of.h> --#include <linux/err.h> --#include <linux/io.h> --#include <linux/clk.h> --#include <linux/usb/omap_control_usb.h> -- --static struct omap_control_usb *control_usb; -- --/** -- * omap_get_control_dev - returns the device pointer for this control device -- * -- * This API should be called to get the device pointer for this control -- * module device. This device pointer should be used for called other -- * exported API's in this driver. -- * -- * To be used by PHY driver and glue driver. -- */ --struct device *omap_get_control_dev(void) --{ -- if (!control_usb) -- return ERR_PTR(-ENODEV); -- -- return control_usb->dev; --} --EXPORT_SYMBOL_GPL(omap_get_control_dev); -- --/** -- * omap_control_usb3_phy_power - power on/off the serializer using control -- * module -- * @dev: the control module device -- * @on: 0 to off and 1 to on based on powering on or off the PHY -- * -- * usb3 PHY driver should call this API to power on or off the PHY. -- */ --void omap_control_usb3_phy_power(struct device *dev, bool on) --{ -- u32 val; -- unsigned long rate; -- struct omap_control_usb *control_usb = dev_get_drvdata(dev); -- -- if (control_usb->type != OMAP_CTRL_DEV_TYPE2) -- return; -- -- rate = clk_get_rate(control_usb->sys_clk); -- rate = rate/1000000; -- -- val = readl(control_usb->phy_power); -- -- if (on) { -- val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | -- OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); -- val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << -- OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; -- val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; -- } else { -- val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; -- val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << -- OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; -- } -- -- writel(val, control_usb->phy_power); --} --EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power); -- --/** -- * omap_control_usb_phy_power - power on/off the phy using control module reg -- * @dev: the control module device -- * @on: 0 or 1, based on powering on or off the PHY -- */ --void omap_control_usb_phy_power(struct device *dev, int on) --{ -- u32 val; -- struct omap_control_usb *control_usb = dev_get_drvdata(dev); -- -- val = readl(control_usb->dev_conf); -- -- if (on) -- val &= ~OMAP_CTRL_DEV_PHY_PD; -- else -- val |= OMAP_CTRL_DEV_PHY_PD; -- -- writel(val, control_usb->dev_conf); --} --EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); -- --/** -- * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded -- * @ctrl_usb: struct omap_control_usb * -- * -- * Writes to the mailbox register to notify the usb core that a usb -- * device has been connected. -- */ --static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb) --{ -- u32 val; -- -- val = readl(ctrl_usb->otghs_control); -- val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); -- val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; -- writel(val, ctrl_usb->otghs_control); --} -- --/** -- * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high -- * impedance -- * @ctrl_usb: struct omap_control_usb * -- * -- * Writes to the mailbox register to notify the usb core that it has been -- * connected to a usb host. -- */ --static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb) --{ -- u32 val; -- -- val = readl(ctrl_usb->otghs_control); -- val &= ~OMAP_CTRL_DEV_SESSEND; -- val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | -- OMAP_CTRL_DEV_VBUSVALID; -- writel(val, ctrl_usb->otghs_control); --} -- --/** -- * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high -- * impedance -- * @ctrl_usb: struct omap_control_usb * -- * -- * Writes to the mailbox register to notify the usb core it's now in -- * disconnected state. -- */ --static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb) --{ -- u32 val; -- -- val = readl(ctrl_usb->otghs_control); -- val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); -- val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; -- writel(val, ctrl_usb->otghs_control); --} -- --/** -- * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode -- * or device mode or to denote disconnected state -- * @dev: the control module device -- * @mode: The mode to which usb should be configured -- * -- * This is an API to write to the mailbox register to notify the usb core that -- * a usb device has been connected. -- */ --void omap_control_usb_set_mode(struct device *dev, -- enum omap_control_usb_mode mode) --{ -- struct omap_control_usb *ctrl_usb; -- -- if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1) -- return; -- -- ctrl_usb = dev_get_drvdata(dev); -- -- switch (mode) { -- case USB_MODE_HOST: -- omap_control_usb_host_mode(ctrl_usb); -- break; -- case USB_MODE_DEVICE: -- omap_control_usb_device_mode(ctrl_usb); -- break; -- case USB_MODE_DISCONNECT: -- omap_control_usb_set_sessionend(ctrl_usb); -- break; -- default: -- dev_vdbg(dev, "invalid omap control usb mode\n"); -- } --} --EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); -- --static int omap_control_usb_probe(struct platform_device *pdev) --{ -- struct resource *res; -- struct device_node *np = pdev->dev.of_node; -- struct omap_control_usb_platform_data *pdata = -- dev_get_platdata(&pdev->dev); -- -- control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), -- GFP_KERNEL); -- if (!control_usb) { -- dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); -- return -ENOMEM; -- } -- -- if (np) { -- of_property_read_u32(np, "ti,type", &control_usb->type); -- } else if (pdata) { -- control_usb->type = pdata->type; -- } else { -- dev_err(&pdev->dev, "no pdata present\n"); -- return -EINVAL; -- } -- -- control_usb->dev = &pdev->dev; -- -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -- "control_dev_conf"); -- control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res); -- if (IS_ERR(control_usb->dev_conf)) -- return PTR_ERR(control_usb->dev_conf); -- -- if (control_usb->type == OMAP_CTRL_DEV_TYPE1) { -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -- "otghs_control"); -- control_usb->otghs_control = devm_ioremap_resource( -- &pdev->dev, res); -- if (IS_ERR(control_usb->otghs_control)) -- return PTR_ERR(control_usb->otghs_control); -- } -- -- if (control_usb->type == OMAP_CTRL_DEV_TYPE2) { -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -- "phy_power_usb"); -- control_usb->phy_power = devm_ioremap_resource( -- &pdev->dev, res); -- if (IS_ERR(control_usb->phy_power)) -- return PTR_ERR(control_usb->phy_power); -- -- control_usb->sys_clk = devm_clk_get(control_usb->dev, -- "sys_clkin"); -- if (IS_ERR(control_usb->sys_clk)) { -- pr_err("%s: unable to get sys_clkin\n", __func__); -- return -EINVAL; -- } -- } -- -- -- dev_set_drvdata(control_usb->dev, control_usb); -- -- return 0; --} -- --#ifdef CONFIG_OF --static const struct of_device_id omap_control_usb_id_table[] = { -- { .compatible = "ti,omap-control-usb" }, -- {} --}; --MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); --#endif -- --static struct platform_driver omap_control_usb_driver = { -- .probe = omap_control_usb_probe, -- .driver = { -- .name = "omap-control-usb", -- .owner = THIS_MODULE, -- .of_match_table = of_match_ptr(omap_control_usb_id_table), -- }, --}; -- --static int __init omap_control_usb_init(void) --{ -- return platform_driver_register(&omap_control_usb_driver); --} --subsys_initcall(omap_control_usb_init); -- --static void __exit omap_control_usb_exit(void) --{ -- platform_driver_unregister(&omap_control_usb_driver); --} --module_exit(omap_control_usb_exit); -- --MODULE_ALIAS("platform: omap_control_usb"); --MODULE_AUTHOR("Texas Instruments Inc."); --MODULE_DESCRIPTION("OMAP Control Module USB Driver"); --MODULE_LICENSE("GPL v2"); ---- a/drivers/usb/phy/phy-omap-usb2.c -+++ /dev/null -@@ -1,272 +0,0 @@ --/* -- * omap-usb2.c - USB PHY, talking to musb controller in OMAP. -- * -- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com -- * 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. -- * -- * Author: Kishon Vijay Abraham I <kishon@ti.com> -- * -- * 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. -- * -- */ -- --#include <linux/module.h> --#include <linux/platform_device.h> --#include <linux/slab.h> --#include <linux/of.h> --#include <linux/io.h> --#include <linux/usb/omap_usb.h> --#include <linux/usb/phy_companion.h> --#include <linux/clk.h> --#include <linux/err.h> --#include <linux/pm_runtime.h> --#include <linux/delay.h> --#include <linux/usb/omap_control_usb.h> -- --/** -- * omap_usb2_set_comparator - links the comparator present in the sytem with -- * this phy -- * @comparator - the companion phy(comparator) for this phy -- * -- * The phy companion driver should call this API passing the phy_companion -- * filled with set_vbus and start_srp to be used by usb phy. -- * -- * For use by phy companion driver -- */ --int omap_usb2_set_comparator(struct phy_companion *comparator) --{ -- struct omap_usb *phy; -- struct usb_phy *x = usb_get_phy(USB_PHY_TYPE_USB2); -- -- if (IS_ERR(x)) -- return -ENODEV; -- -- phy = phy_to_omapusb(x); -- phy->comparator = comparator; -- return 0; --} --EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); -- --static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) --{ -- struct omap_usb *phy = phy_to_omapusb(otg->phy); -- -- if (!phy->comparator) -- return -ENODEV; -- -- return phy->comparator->set_vbus(phy->comparator, enabled); --} -- --static int omap_usb_start_srp(struct usb_otg *otg) --{ -- struct omap_usb *phy = phy_to_omapusb(otg->phy); -- -- if (!phy->comparator) -- return -ENODEV; -- -- return phy->comparator->start_srp(phy->comparator); --} -- --static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host) --{ -- struct usb_phy *phy = otg->phy; -- -- otg->host = host; -- if (!host) -- phy->state = OTG_STATE_UNDEFINED; -- -- return 0; --} -- --static int omap_usb_set_peripheral(struct usb_otg *otg, -- struct usb_gadget *gadget) --{ -- struct usb_phy *phy = otg->phy; -- -- otg->gadget = gadget; -- if (!gadget) -- phy->state = OTG_STATE_UNDEFINED; -- -- return 0; --} -- --static int omap_usb2_suspend(struct usb_phy *x, int suspend) --{ -- struct omap_usb *phy = phy_to_omapusb(x); -- int ret; -- -- if (suspend && !phy->is_suspended) { -- omap_control_usb_phy_power(phy->control_dev, 0); -- pm_runtime_put_sync(phy->dev); -- phy->is_suspended = 1; -- } else if (!suspend && phy->is_suspended) { -- ret = pm_runtime_get_sync(phy->dev); -- if (ret < 0) { -- dev_err(phy->dev, "get_sync failed with err %d\n", ret); -- return ret; -- } -- omap_control_usb_phy_power(phy->control_dev, 1); -- phy->is_suspended = 0; -- } -- -- return 0; --} -- --static int omap_usb2_probe(struct platform_device *pdev) --{ -- struct omap_usb *phy; -- struct usb_otg *otg; -- -- phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); -- if (!phy) { -- dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); -- return -ENOMEM; -- } -- -- otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); -- if (!otg) { -- dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); -- return -ENOMEM; -- } -- -- phy->dev = &pdev->dev; -- -- phy->phy.dev = phy->dev; -- phy->phy.label = "omap-usb2"; -- phy->phy.set_suspend = omap_usb2_suspend; -- phy->phy.otg = otg; -- phy->phy.type = USB_PHY_TYPE_USB2; -- -- phy->control_dev = omap_get_control_dev(); -- if (IS_ERR(phy->control_dev)) { -- dev_dbg(&pdev->dev, "Failed to get control device\n"); -- return -ENODEV; -- } -- -- phy->is_suspended = 1; -- omap_control_usb_phy_power(phy->control_dev, 0); -- -- otg->set_host = omap_usb_set_host; -- otg->set_peripheral = omap_usb_set_peripheral; -- otg->set_vbus = omap_usb_set_vbus; -- otg->start_srp = omap_usb_start_srp; -- otg->phy = &phy->phy; -- -- phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); -- if (IS_ERR(phy->wkupclk)) { -- dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); -- return PTR_ERR(phy->wkupclk); -- } -- clk_prepare(phy->wkupclk); -- -- phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); -- if (IS_ERR(phy->optclk)) -- dev_vdbg(&pdev->dev, "unable to get refclk960m\n"); -- else -- clk_prepare(phy->optclk); -- -- usb_add_phy_dev(&phy->phy); -- -- platform_set_drvdata(pdev, phy); -- -- pm_runtime_enable(phy->dev); -- -- return 0; --} -- --static int omap_usb2_remove(struct platform_device *pdev) --{ -- struct omap_usb *phy = platform_get_drvdata(pdev); -- -- clk_unprepare(phy->wkupclk); -- if (!IS_ERR(phy->optclk)) -- clk_unprepare(phy->optclk); -- usb_remove_phy(&phy->phy); -- -- return 0; --} -- --#ifdef CONFIG_PM_RUNTIME -- --static int omap_usb2_runtime_suspend(struct device *dev) --{ -- struct platform_device *pdev = to_platform_device(dev); -- struct omap_usb *phy = platform_get_drvdata(pdev); -- -- clk_disable(phy->wkupclk); -- if (!IS_ERR(phy->optclk)) -- clk_disable(phy->optclk); -- -- return 0; --} -- --static int omap_usb2_runtime_resume(struct device *dev) --{ -- struct platform_device *pdev = to_platform_device(dev); -- struct omap_usb *phy = platform_get_drvdata(pdev); -- int ret; -- -- ret = clk_enable(phy->wkupclk); -- if (ret < 0) { -- dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); -- goto err0; -- } -- -- if (!IS_ERR(phy->optclk)) { -- ret = clk_enable(phy->optclk); -- if (ret < 0) { -- dev_err(phy->dev, "Failed to enable optclk %d\n", ret); -- goto err1; -- } -- } -- -- return 0; -- --err1: -- clk_disable(phy->wkupclk); -- --err0: -- return ret; --} -- --static const struct dev_pm_ops omap_usb2_pm_ops = { -- SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume, -- NULL) --}; -- --#define DEV_PM_OPS (&omap_usb2_pm_ops) --#else --#define DEV_PM_OPS NULL --#endif -- --#ifdef CONFIG_OF --static const struct of_device_id omap_usb2_id_table[] = { -- { .compatible = "ti,omap-usb2" }, -- {} --}; --MODULE_DEVICE_TABLE(of, omap_usb2_id_table); --#endif -- --static struct platform_driver omap_usb2_driver = { -- .probe = omap_usb2_probe, -- .remove = omap_usb2_remove, -- .driver = { -- .name = "omap-usb2", -- .owner = THIS_MODULE, -- .pm = DEV_PM_OPS, -- .of_match_table = of_match_ptr(omap_usb2_id_table), -- }, --}; -- --module_platform_driver(omap_usb2_driver); -- --MODULE_ALIAS("platform: omap_usb2"); --MODULE_AUTHOR("Texas Instruments Inc."); --MODULE_DESCRIPTION("OMAP USB2 phy driver"); --MODULE_LICENSE("GPL v2"); ---- a/drivers/usb/phy/phy-omap-usb3.c -+++ /dev/null -@@ -1,347 +0,0 @@ --/* -- * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP. -- * -- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -- * 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. -- * -- * Author: Kishon Vijay Abraham I <kishon@ti.com> -- * -- * 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. -- * -- */ -- --#include <linux/module.h> --#include <linux/platform_device.h> --#include <linux/slab.h> --#include <linux/usb/omap_usb.h> --#include <linux/of.h> --#include <linux/clk.h> --#include <linux/err.h> --#include <linux/pm_runtime.h> --#include <linux/delay.h> --#include <linux/usb/omap_control_usb.h> -- --#define PLL_STATUS 0x00000004 --#define PLL_GO 0x00000008 --#define PLL_CONFIGURATION1 0x0000000C --#define PLL_CONFIGURATION2 0x00000010 --#define PLL_CONFIGURATION3 0x00000014 --#define PLL_CONFIGURATION4 0x00000020 -- --#define PLL_REGM_MASK 0x001FFE00 --#define PLL_REGM_SHIFT 0x9 --#define PLL_REGM_F_MASK 0x0003FFFF --#define PLL_REGM_F_SHIFT 0x0 --#define PLL_REGN_MASK 0x000001FE --#define PLL_REGN_SHIFT 0x1 --#define PLL_SELFREQDCO_MASK 0x0000000E --#define PLL_SELFREQDCO_SHIFT 0x1 --#define PLL_SD_MASK 0x0003FC00 --#define PLL_SD_SHIFT 0x9 --#define SET_PLL_GO 0x1 --#define PLL_TICOPWDN 0x10000 --#define PLL_LOCK 0x2 --#define PLL_IDLE 0x1 -- --/* -- * This is an Empirical value that works, need to confirm the actual -- * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status -- * to be correctly reflected in the USB3PHY_PLL_STATUS register. -- */ --# define PLL_IDLE_TIME 100; -- --struct usb_dpll_map { -- unsigned long rate; -- struct usb_dpll_params params; --}; -- --static struct usb_dpll_map dpll_map[] = { -- {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ -- {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ -- {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ -- {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ -- {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ -- {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ --}; -- --static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(dpll_map); i++) { -- if (rate == dpll_map[i].rate) -- return &dpll_map[i].params; -- } -- -- return NULL; --} -- --static int omap_usb3_suspend(struct usb_phy *x, int suspend) --{ -- struct omap_usb *phy = phy_to_omapusb(x); -- int val; -- int timeout = PLL_IDLE_TIME; -- -- if (suspend && !phy->is_suspended) { -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); -- val |= PLL_IDLE; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); -- -- do { -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); -- if (val & PLL_TICOPWDN) -- break; -- udelay(1); -- } while (--timeout); -- -- omap_control_usb3_phy_power(phy->control_dev, 0); -- -- phy->is_suspended = 1; -- } else if (!suspend && phy->is_suspended) { -- phy->is_suspended = 0; -- -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); -- val &= ~PLL_IDLE; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); -- -- do { -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); -- if (!(val & PLL_TICOPWDN)) -- break; -- udelay(1); -- } while (--timeout); -- } -- -- return 0; --} -- --static void omap_usb_dpll_relock(struct omap_usb *phy) --{ -- u32 val; -- unsigned long timeout; -- -- omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); -- -- timeout = jiffies + msecs_to_jiffies(20); -- do { -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); -- if (val & PLL_LOCK) -- break; -- } while (!WARN_ON(time_after(jiffies, timeout))); --} -- --static int omap_usb_dpll_lock(struct omap_usb *phy) --{ -- u32 val; -- unsigned long rate; -- struct usb_dpll_params *dpll_params; -- -- rate = clk_get_rate(phy->sys_clk); -- dpll_params = omap_usb3_get_dpll_params(rate); -- if (!dpll_params) { -- dev_err(phy->dev, -- "No DPLL configuration for %lu Hz SYS CLK\n", rate); -- return -EINVAL; -- } -- -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); -- val &= ~PLL_REGN_MASK; -- val |= dpll_params->n << PLL_REGN_SHIFT; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); -- -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); -- val &= ~PLL_SELFREQDCO_MASK; -- val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); -- -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); -- val &= ~PLL_REGM_MASK; -- val |= dpll_params->m << PLL_REGM_SHIFT; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); -- -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); -- val &= ~PLL_REGM_F_MASK; -- val |= dpll_params->mf << PLL_REGM_F_SHIFT; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); -- -- val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); -- val &= ~PLL_SD_MASK; -- val |= dpll_params->sd << PLL_SD_SHIFT; -- omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); -- -- omap_usb_dpll_relock(phy); -- -- return 0; --} -- --static int omap_usb3_init(struct usb_phy *x) --{ -- struct omap_usb *phy = phy_to_omapusb(x); -- int ret; -- -- ret = omap_usb_dpll_lock(phy); -- if (ret) -- return ret; -- -- omap_control_usb3_phy_power(phy->control_dev, 1); -- -- return 0; --} -- --static int omap_usb3_probe(struct platform_device *pdev) --{ -- struct omap_usb *phy; -- struct resource *res; -- -- phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); -- if (!phy) { -- dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n"); -- return -ENOMEM; -- } -- -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); -- phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); -- if (IS_ERR(phy->pll_ctrl_base)) -- return PTR_ERR(phy->pll_ctrl_base); -- -- phy->dev = &pdev->dev; -- -- phy->phy.dev = phy->dev; -- phy->phy.label = "omap-usb3"; -- phy->phy.init = omap_usb3_init; -- phy->phy.set_suspend = omap_usb3_suspend; -- phy->phy.type = USB_PHY_TYPE_USB3; -- -- phy->is_suspended = 1; -- phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); -- if (IS_ERR(phy->wkupclk)) { -- dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); -- return PTR_ERR(phy->wkupclk); -- } -- clk_prepare(phy->wkupclk); -- -- phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); -- if (IS_ERR(phy->optclk)) { -- dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); -- return PTR_ERR(phy->optclk); -- } -- clk_prepare(phy->optclk); -- -- phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); -- if (IS_ERR(phy->sys_clk)) { -- pr_err("%s: unable to get sys_clkin\n", __func__); -- return -EINVAL; -- } -- -- phy->control_dev = omap_get_control_dev(); -- if (IS_ERR(phy->control_dev)) { -- dev_dbg(&pdev->dev, "Failed to get control device\n"); -- return -ENODEV; -- } -- -- omap_control_usb3_phy_power(phy->control_dev, 0); -- usb_add_phy_dev(&phy->phy); -- -- platform_set_drvdata(pdev, phy); -- -- pm_runtime_enable(phy->dev); -- pm_runtime_get(&pdev->dev); -- -- return 0; --} -- --static int omap_usb3_remove(struct platform_device *pdev) --{ -- struct omap_usb *phy = platform_get_drvdata(pdev); -- -- clk_unprepare(phy->wkupclk); -- clk_unprepare(phy->optclk); -- usb_remove_phy(&phy->phy); -- if (!pm_runtime_suspended(&pdev->dev)) -- pm_runtime_put(&pdev->dev); -- pm_runtime_disable(&pdev->dev); -- -- return 0; --} -- --#ifdef CONFIG_PM_RUNTIME -- --static int omap_usb3_runtime_suspend(struct device *dev) --{ -- struct platform_device *pdev = to_platform_device(dev); -- struct omap_usb *phy = platform_get_drvdata(pdev); -- -- clk_disable(phy->wkupclk); -- clk_disable(phy->optclk); -- -- return 0; --} -- --static int omap_usb3_runtime_resume(struct device *dev) --{ -- u32 ret = 0; -- struct platform_device *pdev = to_platform_device(dev); -- struct omap_usb *phy = platform_get_drvdata(pdev); -- -- ret = clk_enable(phy->optclk); -- if (ret) { -- dev_err(phy->dev, "Failed to enable optclk %d\n", ret); -- goto err1; -- } -- -- ret = clk_enable(phy->wkupclk); -- if (ret) { -- dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); -- goto err2; -- } -- -- return 0; -- --err2: -- clk_disable(phy->optclk); -- --err1: -- return ret; --} -- --static const struct dev_pm_ops omap_usb3_pm_ops = { -- SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume, -- NULL) --}; -- --#define DEV_PM_OPS (&omap_usb3_pm_ops) --#else --#define DEV_PM_OPS NULL --#endif -- --#ifdef CONFIG_OF --static const struct of_device_id omap_usb3_id_table[] = { -- { .compatible = "ti,omap-usb3" }, -- {} --}; --MODULE_DEVICE_TABLE(of, omap_usb3_id_table); --#endif -- --static struct platform_driver omap_usb3_driver = { -- .probe = omap_usb3_probe, -- .remove = omap_usb3_remove, -- .driver = { -- .name = "omap-usb3", -- .owner = THIS_MODULE, -- .pm = DEV_PM_OPS, -- .of_match_table = of_match_ptr(omap_usb3_id_table), -- }, --}; -- --module_platform_driver(omap_usb3_driver); -- --MODULE_ALIAS("platform: omap_usb3"); --MODULE_AUTHOR("Texas Instruments Inc."); --MODULE_DESCRIPTION("OMAP USB3 phy driver"); --MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/usb/phy/phy-rcar-gen2-usb.c -@@ -0,0 +1,248 @@ -+/* -+ * Renesas R-Car Gen2 USB phy driver -+ * -+ * Copyright (C) 2013 Renesas Solutions Corp. -+ * Copyright (C) 2013 Cogent Embedded, 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 <linux/clk.h> -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/platform_data/usb-rcar-gen2-phy.h> -+#include <linux/platform_device.h> -+#include <linux/spinlock.h> -+#include <linux/usb/otg.h> -+ -+struct rcar_gen2_usb_phy_priv { -+ struct usb_phy phy; -+ void __iomem *base; -+ struct clk *clk; -+ spinlock_t lock; -+ int usecount; -+ u32 ugctrl2; -+}; -+ -+#define usb_phy_to_priv(p) container_of(p, struct rcar_gen2_usb_phy_priv, phy) -+ -+/* Low Power Status register */ -+#define USBHS_LPSTS_REG 0x02 -+#define USBHS_LPSTS_SUSPM (1 << 14) -+ -+/* USB General control register */ -+#define USBHS_UGCTRL_REG 0x80 -+#define USBHS_UGCTRL_CONNECT (1 << 2) -+#define USBHS_UGCTRL_PLLRESET (1 << 0) -+ -+/* USB General control register 2 */ -+#define USBHS_UGCTRL2_REG 0x84 -+#define USBHS_UGCTRL2_USB0_PCI (1 << 4) -+#define USBHS_UGCTRL2_USB0_HS (3 << 4) -+#define USBHS_UGCTRL2_USB2_PCI (0 << 31) -+#define USBHS_UGCTRL2_USB2_SS (1 << 31) -+ -+/* USB General status register */ -+#define USBHS_UGSTS_REG 0x88 -+#define USBHS_UGSTS_LOCK (3 << 8) -+ -+/* Enable USBHS internal phy */ -+static int __rcar_gen2_usbhs_phy_enable(void __iomem *base) -+{ -+ u32 val; -+ int i; -+ -+ /* USBHS PHY power on */ -+ val = ioread32(base + USBHS_UGCTRL_REG); -+ val &= ~USBHS_UGCTRL_PLLRESET; -+ iowrite32(val, base + USBHS_UGCTRL_REG); -+ -+ val = ioread16(base + USBHS_LPSTS_REG); -+ val |= USBHS_LPSTS_SUSPM; -+ iowrite16(val, base + USBHS_LPSTS_REG); -+ -+ for (i = 0; i < 20; i++) { -+ val = ioread32(base + USBHS_UGSTS_REG); -+ if ((val & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) { -+ val = ioread32(base + USBHS_UGCTRL_REG); -+ val |= USBHS_UGCTRL_CONNECT; -+ iowrite32(val, base + USBHS_UGCTRL_REG); -+ return 0; -+ } -+ udelay(1); -+ } -+ -+ /* Timed out waiting for the PLL lock */ -+ return -ETIMEDOUT; -+} -+ -+/* Disable USBHS internal phy */ -+static int __rcar_gen2_usbhs_phy_disable(void __iomem *base) -+{ -+ u32 val; -+ -+ /* USBHS PHY power off */ -+ val = ioread32(base + USBHS_UGCTRL_REG); -+ val &= ~USBHS_UGCTRL_CONNECT; -+ iowrite32(val, base + USBHS_UGCTRL_REG); -+ -+ val = ioread16(base + USBHS_LPSTS_REG); -+ val &= ~USBHS_LPSTS_SUSPM; -+ iowrite16(val, base + USBHS_LPSTS_REG); -+ -+ val = ioread32(base + USBHS_UGCTRL_REG); -+ val |= USBHS_UGCTRL_PLLRESET; -+ iowrite32(val, base + USBHS_UGCTRL_REG); -+ return 0; -+} -+ -+/* Setup USB channels */ -+static void __rcar_gen2_usb_phy_init(struct rcar_gen2_usb_phy_priv *priv) -+{ -+ u32 val; -+ -+ clk_prepare_enable(priv->clk); -+ -+ /* Set USB channels in the USBHS UGCTRL2 register */ -+ val = ioread32(priv->base); -+ val &= ~(USBHS_UGCTRL2_USB0_HS | USBHS_UGCTRL2_USB2_SS); -+ val |= priv->ugctrl2; -+ iowrite32(val, priv->base); -+} -+ -+/* Shutdown USB channels */ -+static void __rcar_gen2_usb_phy_shutdown(struct rcar_gen2_usb_phy_priv *priv) -+{ -+ __rcar_gen2_usbhs_phy_disable(priv->base); -+ clk_disable_unprepare(priv->clk); -+} -+ -+static int rcar_gen2_usb_phy_set_suspend(struct usb_phy *phy, int suspend) -+{ -+ struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); -+ unsigned long flags; -+ int retval; -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ retval = suspend ? __rcar_gen2_usbhs_phy_disable(priv->base) : -+ __rcar_gen2_usbhs_phy_enable(priv->base); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return retval; -+} -+ -+static int rcar_gen2_usb_phy_init(struct usb_phy *phy) -+{ -+ struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ /* -+ * Enable the clock and setup USB channels -+ * if it's the first user -+ */ -+ if (!priv->usecount++) -+ __rcar_gen2_usb_phy_init(priv); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return 0; -+} -+ -+static void rcar_gen2_usb_phy_shutdown(struct usb_phy *phy) -+{ -+ struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ if (!priv->usecount) { -+ dev_warn(phy->dev, "Trying to disable phy with 0 usecount\n"); -+ goto out; -+ } -+ -+ /* Disable everything if it's the last user */ -+ if (!--priv->usecount) -+ __rcar_gen2_usb_phy_shutdown(priv); -+out: -+ spin_unlock_irqrestore(&priv->lock, flags); -+} -+ -+static int rcar_gen2_usb_phy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct rcar_gen2_phy_platform_data *pdata; -+ struct rcar_gen2_usb_phy_priv *priv; -+ struct resource *res; -+ void __iomem *base; -+ struct clk *clk; -+ int retval; -+ -+ pdata = dev_get_platdata(&pdev->dev); -+ if (!pdata) { -+ dev_err(dev, "No platform data\n"); -+ return -EINVAL; -+ } -+ -+ clk = devm_clk_get(&pdev->dev, "usbhs"); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "Can't get the clock\n"); -+ return PTR_ERR(clk); -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) { -+ dev_err(dev, "Memory allocation failed\n"); -+ return -ENOMEM; -+ } -+ -+ spin_lock_init(&priv->lock); -+ priv->clk = clk; -+ priv->base = base; -+ priv->ugctrl2 = pdata->chan0_pci ? -+ USBHS_UGCTRL2_USB0_PCI : USBHS_UGCTRL2_USB0_HS; -+ priv->ugctrl2 |= pdata->chan2_pci ? -+ USBHS_UGCTRL2_USB2_PCI : USBHS_UGCTRL2_USB2_SS; -+ priv->phy.dev = dev; -+ priv->phy.label = dev_name(dev); -+ priv->phy.init = rcar_gen2_usb_phy_init; -+ priv->phy.shutdown = rcar_gen2_usb_phy_shutdown; -+ priv->phy.set_suspend = rcar_gen2_usb_phy_set_suspend; -+ -+ retval = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); -+ if (retval < 0) { -+ dev_err(dev, "Failed to add USB phy\n"); -+ return retval; -+ } -+ -+ platform_set_drvdata(pdev, priv); -+ -+ return retval; -+} -+ -+static int rcar_gen2_usb_phy_remove(struct platform_device *pdev) -+{ -+ struct rcar_gen2_usb_phy_priv *priv = platform_get_drvdata(pdev); -+ -+ usb_remove_phy(&priv->phy); -+ -+ return 0; -+} -+ -+static struct platform_driver rcar_gen2_usb_phy_driver = { -+ .driver = { -+ .name = "usb_phy_rcar_gen2", -+ }, -+ .probe = rcar_gen2_usb_phy_probe, -+ .remove = rcar_gen2_usb_phy_remove, -+}; -+ -+module_platform_driver(rcar_gen2_usb_phy_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Renesas R-Car Gen2 USB phy"); -+MODULE_AUTHOR("Valentine Barshak <valentine.barshak@cogentembedded.com>"); ---- a/drivers/usb/phy/phy-tegra-usb.c -+++ b/drivers/usb/phy/phy-tegra-usb.c -@@ -1090,7 +1090,7 @@ static struct platform_driver tegra_usb_ - .driver = { - .name = "tegra-phy", - .owner = THIS_MODULE, -- .of_match_table = of_match_ptr(tegra_usb_phy_id_table), -+ .of_match_table = tegra_usb_phy_id_table, - }, - }; - module_platform_driver(tegra_usb_phy_driver); ---- a/drivers/usb/phy/phy-twl4030-usb.c -+++ /dev/null -@@ -1,794 +0,0 @@ --/* -- * twl4030_usb - TWL4030 USB transceiver, talking to OMAP OTG controller -- * -- * Copyright (C) 2004-2007 Texas Instruments -- * Copyright (C) 2008 Nokia Corporation -- * Contact: Felipe Balbi <felipe.balbi@nokia.com> -- * -- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -- * -- * Current status: -- * - HS USB ULPI mode works. -- * - 3-pin mode support may be added in future. -- */ -- --#include <linux/module.h> --#include <linux/init.h> --#include <linux/interrupt.h> --#include <linux/platform_device.h> --#include <linux/spinlock.h> --#include <linux/workqueue.h> --#include <linux/io.h> --#include <linux/delay.h> --#include <linux/usb/otg.h> --#include <linux/usb/musb-omap.h> --#include <linux/usb/ulpi.h> --#include <linux/i2c/twl.h> --#include <linux/regulator/consumer.h> --#include <linux/err.h> --#include <linux/slab.h> -- --/* Register defines */ -- --#define MCPC_CTRL 0x30 --#define MCPC_CTRL_RTSOL (1 << 7) --#define MCPC_CTRL_EXTSWR (1 << 6) --#define MCPC_CTRL_EXTSWC (1 << 5) --#define MCPC_CTRL_VOICESW (1 << 4) --#define MCPC_CTRL_OUT64K (1 << 3) --#define MCPC_CTRL_RTSCTSSW (1 << 2) --#define MCPC_CTRL_HS_UART (1 << 0) -- --#define MCPC_IO_CTRL 0x33 --#define MCPC_IO_CTRL_MICBIASEN (1 << 5) --#define MCPC_IO_CTRL_CTS_NPU (1 << 4) --#define MCPC_IO_CTRL_RXD_PU (1 << 3) --#define MCPC_IO_CTRL_TXDTYP (1 << 2) --#define MCPC_IO_CTRL_CTSTYP (1 << 1) --#define MCPC_IO_CTRL_RTSTYP (1 << 0) -- --#define MCPC_CTRL2 0x36 --#define MCPC_CTRL2_MCPC_CK_EN (1 << 0) -- --#define OTHER_FUNC_CTRL 0x80 --#define OTHER_FUNC_CTRL_BDIS_ACON_EN (1 << 4) --#define OTHER_FUNC_CTRL_FIVEWIRE_MODE (1 << 2) -- --#define OTHER_IFC_CTRL 0x83 --#define OTHER_IFC_CTRL_OE_INT_EN (1 << 6) --#define OTHER_IFC_CTRL_CEA2011_MODE (1 << 5) --#define OTHER_IFC_CTRL_FSLSSERIALMODE_4PIN (1 << 4) --#define OTHER_IFC_CTRL_HIZ_ULPI_60MHZ_OUT (1 << 3) --#define OTHER_IFC_CTRL_HIZ_ULPI (1 << 2) --#define OTHER_IFC_CTRL_ALT_INT_REROUTE (1 << 0) -- --#define OTHER_INT_EN_RISE 0x86 --#define OTHER_INT_EN_FALL 0x89 --#define OTHER_INT_STS 0x8C --#define OTHER_INT_LATCH 0x8D --#define OTHER_INT_VB_SESS_VLD (1 << 7) --#define OTHER_INT_DM_HI (1 << 6) /* not valid for "latch" reg */ --#define OTHER_INT_DP_HI (1 << 5) /* not valid for "latch" reg */ --#define OTHER_INT_BDIS_ACON (1 << 3) /* not valid for "fall" regs */ --#define OTHER_INT_MANU (1 << 1) --#define OTHER_INT_ABNORMAL_STRESS (1 << 0) -- --#define ID_STATUS 0x96 --#define ID_RES_FLOAT (1 << 4) --#define ID_RES_440K (1 << 3) --#define ID_RES_200K (1 << 2) --#define ID_RES_102K (1 << 1) --#define ID_RES_GND (1 << 0) -- --#define POWER_CTRL 0xAC --#define POWER_CTRL_OTG_ENAB (1 << 5) -- --#define OTHER_IFC_CTRL2 0xAF --#define OTHER_IFC_CTRL2_ULPI_STP_LOW (1 << 4) --#define OTHER_IFC_CTRL2_ULPI_TXEN_POL (1 << 3) --#define OTHER_IFC_CTRL2_ULPI_4PIN_2430 (1 << 2) --#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_MASK (3 << 0) /* bits 0 and 1 */ --#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT1N (0 << 0) --#define OTHER_IFC_CTRL2_USB_INT_OUTSEL_INT2N (1 << 0) -- --#define REG_CTRL_EN 0xB2 --#define REG_CTRL_ERROR 0xB5 --#define ULPI_I2C_CONFLICT_INTEN (1 << 0) -- --#define OTHER_FUNC_CTRL2 0xB8 --#define OTHER_FUNC_CTRL2_VBAT_TIMER_EN (1 << 0) -- --/* following registers do not have separate _clr and _set registers */ --#define VBUS_DEBOUNCE 0xC0 --#define ID_DEBOUNCE 0xC1 --#define VBAT_TIMER 0xD3 --#define PHY_PWR_CTRL 0xFD --#define PHY_PWR_PHYPWD (1 << 0) --#define PHY_CLK_CTRL 0xFE --#define PHY_CLK_CTRL_CLOCKGATING_EN (1 << 2) --#define PHY_CLK_CTRL_CLK32K_EN (1 << 1) --#define REQ_PHY_DPLL_CLK (1 << 0) --#define PHY_CLK_CTRL_STS 0xFF --#define PHY_DPLL_CLK (1 << 0) -- --/* In module TWL_MODULE_PM_MASTER */ --#define STS_HW_CONDITIONS 0x0F -- --/* In module TWL_MODULE_PM_RECEIVER */ --#define VUSB_DEDICATED1 0x7D --#define VUSB_DEDICATED2 0x7E --#define VUSB1V5_DEV_GRP 0x71 --#define VUSB1V5_TYPE 0x72 --#define VUSB1V5_REMAP 0x73 --#define VUSB1V8_DEV_GRP 0x74 --#define VUSB1V8_TYPE 0x75 --#define VUSB1V8_REMAP 0x76 --#define VUSB3V1_DEV_GRP 0x77 --#define VUSB3V1_TYPE 0x78 --#define VUSB3V1_REMAP 0x79 -- --/* In module TWL4030_MODULE_INTBR */ --#define PMBR1 0x0D --#define GPIO_USB_4PIN_ULPI_2430C (3 << 0) -- --struct twl4030_usb { -- struct usb_phy phy; -- struct device *dev; -- -- /* TWL4030 internal USB regulator supplies */ -- struct regulator *usb1v5; -- struct regulator *usb1v8; -- struct regulator *usb3v1; -- -- /* for vbus reporting with irqs disabled */ -- spinlock_t lock; -- -- /* pin configuration */ -- enum twl4030_usb_mode usb_mode; -- -- int irq; -- enum omap_musb_vbus_id_status linkstat; -- bool vbus_supplied; -- u8 asleep; -- bool irq_enabled; -- -- struct delayed_work id_workaround_work; --}; -- --/* internal define on top of container_of */ --#define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) -- --/*-------------------------------------------------------------------------*/ -- --static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, -- u8 module, u8 data, u8 address) --{ -- u8 check; -- -- if ((twl_i2c_write_u8(module, data, address) >= 0) && -- (twl_i2c_read_u8(module, &check, address) >= 0) && -- (check == data)) -- return 0; -- dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", -- 1, module, address, check, data); -- -- /* Failed once: Try again */ -- if ((twl_i2c_write_u8(module, data, address) >= 0) && -- (twl_i2c_read_u8(module, &check, address) >= 0) && -- (check == data)) -- return 0; -- dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", -- 2, module, address, check, data); -- -- /* Failed again: Return error */ -- return -EBUSY; --} -- --#define twl4030_usb_write_verify(twl, address, data) \ -- twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) -- --static inline int twl4030_usb_write(struct twl4030_usb *twl, -- u8 address, u8 data) --{ -- int ret = 0; -- -- ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); -- if (ret < 0) -- dev_dbg(twl->dev, -- "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); -- return ret; --} -- --static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) --{ -- u8 data; -- int ret = 0; -- -- ret = twl_i2c_read_u8(module, &data, address); -- if (ret >= 0) -- ret = data; -- else -- dev_dbg(twl->dev, -- "TWL4030:readb[0x%x,0x%x] Error %d\n", -- module, address, ret); -- -- return ret; --} -- --static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) --{ -- return twl4030_readb(twl, TWL_MODULE_USB, address); --} -- --/*-------------------------------------------------------------------------*/ -- --static inline int --twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits) --{ -- return twl4030_usb_write(twl, ULPI_SET(reg), bits); --} -- --static inline int --twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) --{ -- return twl4030_usb_write(twl, ULPI_CLR(reg), bits); --} -- --/*-------------------------------------------------------------------------*/ -- --static bool twl4030_is_driving_vbus(struct twl4030_usb *twl) --{ -- int ret; -- -- ret = twl4030_usb_read(twl, PHY_CLK_CTRL_STS); -- if (ret < 0 || !(ret & PHY_DPLL_CLK)) -- /* -- * if clocks are off, registers are not updated, -- * but we can assume we don't drive VBUS in this case -- */ -- return false; -- -- ret = twl4030_usb_read(twl, ULPI_OTG_CTRL); -- if (ret < 0) -- return false; -- -- return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false; --} -- --static enum omap_musb_vbus_id_status -- twl4030_usb_linkstat(struct twl4030_usb *twl) --{ -- int status; -- enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; -- -- twl->vbus_supplied = false; -- -- /* -- * For ID/VBUS sensing, see manual section 15.4.8 ... -- * except when using only battery backup power, two -- * comparators produce VBUS_PRES and ID_PRES signals, -- * which don't match docs elsewhere. But ... BIT(7) -- * and BIT(2) of STS_HW_CONDITIONS, respectively, do -- * seem to match up. If either is true the USB_PRES -- * signal is active, the OTG module is activated, and -- * its interrupt may be raised (may wake the system). -- */ -- status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); -- if (status < 0) -- dev_err(twl->dev, "USB link status err %d\n", status); -- else if (status & (BIT(7) | BIT(2))) { -- if (status & BIT(7)) { -- if (twl4030_is_driving_vbus(twl)) -- status &= ~BIT(7); -- else -- twl->vbus_supplied = true; -- } -- -- if (status & BIT(2)) -- linkstat = OMAP_MUSB_ID_GROUND; -- else if (status & BIT(7)) -- linkstat = OMAP_MUSB_VBUS_VALID; -- else -- linkstat = OMAP_MUSB_VBUS_OFF; -- } else { -- if (twl->linkstat != OMAP_MUSB_UNKNOWN) -- linkstat = OMAP_MUSB_VBUS_OFF; -- } -- -- dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", -- status, status, linkstat); -- -- /* REVISIT this assumes host and peripheral controllers -- * are registered, and that both are active... -- */ -- -- return linkstat; --} -- --static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) --{ -- twl->usb_mode = mode; -- -- switch (mode) { -- case T2_USB_MODE_ULPI: -- twl4030_usb_clear_bits(twl, ULPI_IFC_CTRL, -- ULPI_IFC_CTRL_CARKITMODE); -- twl4030_usb_set_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); -- twl4030_usb_clear_bits(twl, ULPI_FUNC_CTRL, -- ULPI_FUNC_CTRL_XCVRSEL_MASK | -- ULPI_FUNC_CTRL_OPMODE_MASK); -- break; -- case -1: -- /* FIXME: power on defaults */ -- break; -- default: -- dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", -- mode); -- break; -- }; --} -- --static void twl4030_i2c_access(struct twl4030_usb *twl, int on) --{ -- unsigned long timeout; -- int val = twl4030_usb_read(twl, PHY_CLK_CTRL); -- -- if (val >= 0) { -- if (on) { -- /* enable DPLL to access PHY registers over I2C */ -- val |= REQ_PHY_DPLL_CLK; -- WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, -- (u8)val) < 0); -- -- timeout = jiffies + HZ; -- while (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & -- PHY_DPLL_CLK) -- && time_before(jiffies, timeout)) -- udelay(10); -- if (!(twl4030_usb_read(twl, PHY_CLK_CTRL_STS) & -- PHY_DPLL_CLK)) -- dev_err(twl->dev, "Timeout setting T2 HSUSB " -- "PHY DPLL clock\n"); -- } else { -- /* let ULPI control the DPLL clock */ -- val &= ~REQ_PHY_DPLL_CLK; -- WARN_ON(twl4030_usb_write_verify(twl, PHY_CLK_CTRL, -- (u8)val) < 0); -- } -- } --} -- --static void __twl4030_phy_power(struct twl4030_usb *twl, int on) --{ -- u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); -- -- if (on) -- pwr &= ~PHY_PWR_PHYPWD; -- else -- pwr |= PHY_PWR_PHYPWD; -- -- WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); --} -- --static void twl4030_phy_power(struct twl4030_usb *twl, int on) --{ -- int ret; -- -- if (on) { -- ret = regulator_enable(twl->usb3v1); -- if (ret) -- dev_err(twl->dev, "Failed to enable usb3v1\n"); -- -- ret = regulator_enable(twl->usb1v8); -- if (ret) -- dev_err(twl->dev, "Failed to enable usb1v8\n"); -- -- /* -- * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP -- * in twl4030) resets the VUSB_DEDICATED2 register. This reset -- * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to -- * SLEEP. We work around this by clearing the bit after usv3v1 -- * is re-activated. This ensures that VUSB3V1 is really active. -- */ -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); -- -- ret = regulator_enable(twl->usb1v5); -- if (ret) -- dev_err(twl->dev, "Failed to enable usb1v5\n"); -- -- __twl4030_phy_power(twl, 1); -- twl4030_usb_write(twl, PHY_CLK_CTRL, -- twl4030_usb_read(twl, PHY_CLK_CTRL) | -- (PHY_CLK_CTRL_CLOCKGATING_EN | -- PHY_CLK_CTRL_CLK32K_EN)); -- } else { -- __twl4030_phy_power(twl, 0); -- regulator_disable(twl->usb1v5); -- regulator_disable(twl->usb1v8); -- regulator_disable(twl->usb3v1); -- } --} -- --static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) --{ -- if (twl->asleep) -- return; -- -- twl4030_phy_power(twl, 0); -- twl->asleep = 1; -- dev_dbg(twl->dev, "%s\n", __func__); --} -- --static void __twl4030_phy_resume(struct twl4030_usb *twl) --{ -- twl4030_phy_power(twl, 1); -- twl4030_i2c_access(twl, 1); -- twl4030_usb_set_mode(twl, twl->usb_mode); -- if (twl->usb_mode == T2_USB_MODE_ULPI) -- twl4030_i2c_access(twl, 0); --} -- --static void twl4030_phy_resume(struct twl4030_usb *twl) --{ -- if (!twl->asleep) -- return; -- __twl4030_phy_resume(twl); -- twl->asleep = 0; -- dev_dbg(twl->dev, "%s\n", __func__); -- -- /* -- * XXX When VBUS gets driven after musb goes to A mode, -- * ID_PRES related interrupts no longer arrive, why? -- * Register itself is updated fine though, so we must poll. -- */ -- if (twl->linkstat == OMAP_MUSB_ID_GROUND) { -- cancel_delayed_work(&twl->id_workaround_work); -- schedule_delayed_work(&twl->id_workaround_work, HZ); -- } --} -- --static int twl4030_usb_ldo_init(struct twl4030_usb *twl) --{ -- /* Enable writing to power configuration registers */ -- twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, -- TWL4030_PM_MASTER_PROTECT_KEY); -- -- twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, -- TWL4030_PM_MASTER_PROTECT_KEY); -- -- /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ -- /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ -- -- /* input to VUSB3V1 LDO is from VBAT, not VBUS */ -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); -- -- /* Initialize 3.1V regulator */ -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); -- -- twl->usb3v1 = devm_regulator_get(twl->dev, "usb3v1"); -- if (IS_ERR(twl->usb3v1)) -- return -ENODEV; -- -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); -- -- /* Initialize 1.5V regulator */ -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); -- -- twl->usb1v5 = devm_regulator_get(twl->dev, "usb1v5"); -- if (IS_ERR(twl->usb1v5)) -- return -ENODEV; -- -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); -- -- /* Initialize 1.8V regulator */ -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); -- -- twl->usb1v8 = devm_regulator_get(twl->dev, "usb1v8"); -- if (IS_ERR(twl->usb1v8)) -- return -ENODEV; -- -- twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); -- -- /* disable access to power configuration registers */ -- twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, -- TWL4030_PM_MASTER_PROTECT_KEY); -- -- return 0; --} -- --static ssize_t twl4030_usb_vbus_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- struct twl4030_usb *twl = dev_get_drvdata(dev); -- unsigned long flags; -- int ret = -EINVAL; -- -- spin_lock_irqsave(&twl->lock, flags); -- ret = sprintf(buf, "%s\n", -- twl->vbus_supplied ? "on" : "off"); -- spin_unlock_irqrestore(&twl->lock, flags); -- -- return ret; --} --static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); -- --static irqreturn_t twl4030_usb_irq(int irq, void *_twl) --{ -- struct twl4030_usb *twl = _twl; -- enum omap_musb_vbus_id_status status; -- bool status_changed = false; -- -- status = twl4030_usb_linkstat(twl); -- -- spin_lock_irq(&twl->lock); -- if (status >= 0 && status != twl->linkstat) { -- twl->linkstat = status; -- status_changed = true; -- } -- spin_unlock_irq(&twl->lock); -- -- if (status_changed) { -- /* FIXME add a set_power() method so that B-devices can -- * configure the charger appropriately. It's not always -- * correct to consume VBUS power, and how much current to -- * consume is a function of the USB configuration chosen -- * by the host. -- * -- * REVISIT usb_gadget_vbus_connect(...) as needed, ditto -- * its disconnect() sibling, when changing to/from the -- * USB_LINK_VBUS state. musb_hdrc won't care until it -- * starts to handle softconnect right. -- */ -- omap_musb_mailbox(status); -- } -- sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -- -- return IRQ_HANDLED; --} -- --static void twl4030_id_workaround_work(struct work_struct *work) --{ -- struct twl4030_usb *twl = container_of(work, struct twl4030_usb, -- id_workaround_work.work); -- enum omap_musb_vbus_id_status status; -- bool status_changed = false; -- -- status = twl4030_usb_linkstat(twl); -- -- spin_lock_irq(&twl->lock); -- if (status >= 0 && status != twl->linkstat) { -- twl->linkstat = status; -- status_changed = true; -- } -- spin_unlock_irq(&twl->lock); -- -- if (status_changed) { -- dev_dbg(twl->dev, "handle missing status change to %d\n", -- status); -- omap_musb_mailbox(status); -- } -- -- /* don't schedule during sleep - irq works right then */ -- if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { -- cancel_delayed_work(&twl->id_workaround_work); -- schedule_delayed_work(&twl->id_workaround_work, HZ); -- } --} -- --static int twl4030_usb_phy_init(struct usb_phy *phy) --{ -- struct twl4030_usb *twl = phy_to_twl(phy); -- enum omap_musb_vbus_id_status status; -- -- /* -- * Start in sleep state, we'll get called through set_suspend() -- * callback when musb is runtime resumed and it's time to start. -- */ -- __twl4030_phy_power(twl, 0); -- twl->asleep = 1; -- -- status = twl4030_usb_linkstat(twl); -- twl->linkstat = status; -- -- if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) -- omap_musb_mailbox(twl->linkstat); -- -- sysfs_notify(&twl->dev->kobj, NULL, "vbus"); -- return 0; --} -- --static int twl4030_set_suspend(struct usb_phy *x, int suspend) --{ -- struct twl4030_usb *twl = phy_to_twl(x); -- -- if (suspend) -- twl4030_phy_suspend(twl, 1); -- else -- twl4030_phy_resume(twl); -- -- return 0; --} -- --static int twl4030_set_peripheral(struct usb_otg *otg, -- struct usb_gadget *gadget) --{ -- if (!otg) -- return -ENODEV; -- -- otg->gadget = gadget; -- if (!gadget) -- otg->phy->state = OTG_STATE_UNDEFINED; -- -- return 0; --} -- --static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) --{ -- if (!otg) -- return -ENODEV; -- -- otg->host = host; -- if (!host) -- otg->phy->state = OTG_STATE_UNDEFINED; -- -- return 0; --} -- --static int twl4030_usb_probe(struct platform_device *pdev) --{ -- struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev); -- struct twl4030_usb *twl; -- int status, err; -- struct usb_otg *otg; -- struct device_node *np = pdev->dev.of_node; -- -- twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); -- if (!twl) -- return -ENOMEM; -- -- if (np) -- of_property_read_u32(np, "usb_mode", -- (enum twl4030_usb_mode *)&twl->usb_mode); -- else if (pdata) -- twl->usb_mode = pdata->usb_mode; -- else { -- dev_err(&pdev->dev, "twl4030 initialized without pdata\n"); -- return -EINVAL; -- } -- -- otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); -- if (!otg) -- return -ENOMEM; -- -- twl->dev = &pdev->dev; -- twl->irq = platform_get_irq(pdev, 0); -- twl->vbus_supplied = false; -- twl->asleep = 1; -- twl->linkstat = OMAP_MUSB_UNKNOWN; -- -- twl->phy.dev = twl->dev; -- twl->phy.label = "twl4030"; -- twl->phy.otg = otg; -- twl->phy.type = USB_PHY_TYPE_USB2; -- twl->phy.set_suspend = twl4030_set_suspend; -- twl->phy.init = twl4030_usb_phy_init; -- -- otg->phy = &twl->phy; -- otg->set_host = twl4030_set_host; -- otg->set_peripheral = twl4030_set_peripheral; -- -- /* init spinlock for workqueue */ -- spin_lock_init(&twl->lock); -- -- INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work); -- -- err = twl4030_usb_ldo_init(twl); -- if (err) { -- dev_err(&pdev->dev, "ldo init failed\n"); -- return err; -- } -- usb_add_phy_dev(&twl->phy); -- -- platform_set_drvdata(pdev, twl); -- if (device_create_file(&pdev->dev, &dev_attr_vbus)) -- dev_warn(&pdev->dev, "could not create sysfs file\n"); -- -- /* Our job is to use irqs and status from the power module -- * to keep the transceiver disabled when nothing's connected. -- * -- * FIXME we actually shouldn't start enabling it until the -- * USB controller drivers have said they're ready, by calling -- * set_host() and/or set_peripheral() ... OTG_capable boards -- * need both handles, otherwise just one suffices. -- */ -- twl->irq_enabled = true; -- status = devm_request_threaded_irq(twl->dev, twl->irq, NULL, -- twl4030_usb_irq, IRQF_TRIGGER_FALLING | -- IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_usb", twl); -- if (status < 0) { -- dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", -- twl->irq, status); -- return status; -- } -- -- dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); -- return 0; --} -- --static int twl4030_usb_remove(struct platform_device *pdev) --{ -- struct twl4030_usb *twl = platform_get_drvdata(pdev); -- int val; -- -- cancel_delayed_work(&twl->id_workaround_work); -- device_remove_file(twl->dev, &dev_attr_vbus); -- -- /* set transceiver mode to power on defaults */ -- twl4030_usb_set_mode(twl, -1); -- -- /* autogate 60MHz ULPI clock, -- * clear dpll clock request for i2c access, -- * disable 32KHz -- */ -- val = twl4030_usb_read(twl, PHY_CLK_CTRL); -- if (val >= 0) { -- val |= PHY_CLK_CTRL_CLOCKGATING_EN; -- val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); -- twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); -- } -- -- /* disable complete OTG block */ -- twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); -- -- if (!twl->asleep) -- twl4030_phy_power(twl, 0); -- -- return 0; --} -- --#ifdef CONFIG_OF --static const struct of_device_id twl4030_usb_id_table[] = { -- { .compatible = "ti,twl4030-usb" }, -- {} --}; --MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); --#endif -- --static struct platform_driver twl4030_usb_driver = { -- .probe = twl4030_usb_probe, -- .remove = twl4030_usb_remove, -- .driver = { -- .name = "twl4030_usb", -- .owner = THIS_MODULE, -- .of_match_table = of_match_ptr(twl4030_usb_id_table), -- }, --}; -- --static int __init twl4030_usb_init(void) --{ -- return platform_driver_register(&twl4030_usb_driver); --} --subsys_initcall(twl4030_usb_init); -- --static void __exit twl4030_usb_exit(void) --{ -- platform_driver_unregister(&twl4030_usb_driver); --} --module_exit(twl4030_usb_exit); -- --MODULE_ALIAS("platform:twl4030_usb"); --MODULE_AUTHOR("Texas Instruments, Inc, Nokia Corporation"); --MODULE_DESCRIPTION("TWL4030 USB transceiver driver"); --MODULE_LICENSE("GPL"); ---- a/drivers/usb/phy/phy-twl6030-usb.c -+++ b/drivers/usb/phy/phy-twl6030-usb.c -@@ -26,13 +26,14 @@ - #include <linux/platform_device.h> - #include <linux/io.h> - #include <linux/usb/musb-omap.h> -+#include <linux/phy/omap_usb.h> - #include <linux/usb/phy_companion.h> --#include <linux/usb/omap_usb.h> - #include <linux/i2c/twl.h> - #include <linux/regulator/consumer.h> - #include <linux/err.h> - #include <linux/slab.h> - #include <linux/delay.h> -+#include <linux/of.h> - - /* usb register definitions */ - #define USB_VENDOR_ID_LSB 0x00 ---- a/drivers/video/da8xx-fb.c -+++ b/drivers/video/da8xx-fb.c -@@ -19,6 +19,9 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ - #include <linux/module.h> - #include <linux/kernel.h> - #include <linux/fb.h> -@@ -36,9 +39,16 @@ - #include <linux/slab.h> - #include <linux/delay.h> - #include <linux/lcm.h> -+#include <video/of_display_timing.h> - #include <video/da8xx-fb.h> -+ -+#ifdef CONFIG_FB_DA8XX_TDA998X -+#include <video/da8xx-tda998x-hdmi.h> -+#endif -+ - #include <asm/div64.h> - -+ - #define DRIVER_NAME "da8xx_lcdc" - - #define LCD_VERSION_1 1 -@@ -141,6 +151,32 @@ static irq_handler_t lcdc_irq_handler; - static wait_queue_head_t frame_done_wq; - static int frame_done_flag; - -+static LIST_HEAD(encoder_modules); -+ -+void da8xx_register_encoder(struct da8xx_encoder *encoder) -+{ -+ INIT_LIST_HEAD(&encoder->list); -+ list_add(&encoder->list, &encoder_modules); -+} -+EXPORT_SYMBOL(da8xx_register_encoder); -+ -+void da8xx_unregister_encoder(struct da8xx_encoder *encoder) -+{ -+ list_del(&encoder->list); -+} -+EXPORT_SYMBOL(da8xx_unregister_encoder); -+ -+ -+struct da8xx_encoder *da8xx_get_encoder_from_phandle(struct device_node *node) -+{ -+ struct da8xx_encoder *entry; -+ list_for_each_entry(entry, &encoder_modules, list) -+ if (entry->node == node) -+ return entry; -+ -+ return 0; -+} -+ - static unsigned int lcdc_read(unsigned int addr) - { - return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr)); -@@ -161,6 +197,7 @@ struct da8xx_fb_par { - unsigned int dma_start; - unsigned int dma_end; - struct clk *lcdc_clk; -+ struct clk *disp_clk; - int irq; - unsigned int palette_sz; - int blank; -@@ -182,6 +219,7 @@ struct da8xx_fb_par { - u32 pseudo_palette[16]; - struct fb_videomode mode; - struct lcd_ctrl_config cfg; -+ struct device_node *hdmi_node; - }; - - static struct fb_var_screeninfo da8xx_fb_var; -@@ -197,6 +235,9 @@ static struct fb_fix_screeninfo da8xx_fb - .accel = FB_ACCEL_NONE - }; - -+static vsync_callback_t vsync_cb_handler; -+static void *vsync_cb_arg; -+ - static struct fb_videomode known_lcd_panels[] = { - /* Sharp LCD035Q3DG01 */ - [0] = { -@@ -730,8 +771,8 @@ static int da8xx_fb_config_clk_divider(s - } - - static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par, -- unsigned pixclock, -- unsigned *lcdc_clk_rate) -+ unsigned pixclock, -+ unsigned *lcdc_clk_rate) - { - unsigned lcdc_clk_div; - -@@ -765,7 +806,7 @@ static int da8xx_fb_calc_config_clk_divi - } - - static unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par, -- unsigned pixclock) -+ unsigned pixclock) - { - unsigned lcdc_clk_div, lcdc_clk_rate; - -@@ -778,11 +819,53 @@ static int lcd_init(struct da8xx_fb_par - { - u32 bpp; - int ret = 0; -+ struct da8xx_encoder *enc = 0; - -- ret = da8xx_fb_calc_config_clk_divider(par, panel); -- if (IS_ERR_VALUE(ret)) { -- dev_err(par->dev, "unable to configure clock\n"); -- return ret; -+ if (IS_ENABLED(CONFIG_FB_DA8XX_TDA998X) && par->hdmi_node) { -+ unsigned int div = 0; -+ unsigned long pixclock = 0; -+ -+ pr_debug("pixclock from panel %d\n", panel->pixclock); -+ pixclock = PICOS2KHZ(panel->pixclock) * 1000; -+ pr_debug("pixclock converted to hz %ld\n", pixclock); -+ /* remove any rounding errors as this seems to mess up clk */ -+ pixclock = (pixclock/10000)*10000; -+ pr_debug("rounded clock rate %ld\n", -+ clk_round_rate(par->lcdc_clk, pixclock*2)); -+ /* in raster mode, minimum divisor is 2: */ -+ ret = clk_set_rate(par->disp_clk, pixclock * 2); -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(par->dev, "failed to set display clock rate to: %ld\n", -+ pixclock); -+ return ret; -+ } -+ -+ par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); -+ div = par->lcdc_clk_rate / pixclock; -+ -+ pr_debug("lcd_clk=%u, mode clock=%ld, div=%u\n", -+ par->lcdc_clk_rate, pixclock, div); -+ pr_debug("fck=%lu, dpll_disp_ck=%lu\n", -+ clk_get_rate(par->lcdc_clk), -+ clk_get_rate(par->disp_clk)); -+ -+ /* Configure the LCD clock divisor. */ -+ lcdc_write(LCD_CLK_DIVISOR(div) | -+ (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); -+ -+ if (lcd_revision == LCD_VERSION_2) -+ lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN | -+ LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG); -+ } else { -+ /* -+ * Not using external encoder, using old and more inaccurate -+ * method of setting the clocks. -+ */ -+ ret = da8xx_fb_calc_config_clk_divider(par, panel); -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(par->dev, "unable to configure clock\n"); -+ return ret; -+ } - } - - if (panel->sync & FB_SYNC_CLK_INVERT) -@@ -822,9 +905,45 @@ static int lcd_init(struct da8xx_fb_par - lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) | - (cfg->fdd << 12), LCD_RASTER_CTRL_REG); - -+ if (IS_ENABLED(CONFIG_FB_DA8XX_TDA998X) && par->hdmi_node) { -+ /* -+ * keep doing this lookup, because there is a posibility that -+ * somebody went and unloaded the encoder driver from out -+ * beneath us -+ */ -+ enc = da8xx_get_encoder_from_phandle(par->hdmi_node); -+ if (enc) -+ enc->set_mode(enc, panel); -+ } - return 0; - } - -+int register_vsync_cb(vsync_callback_t handler, void *arg, int idx) -+{ -+ if ((vsync_cb_handler == NULL) && (vsync_cb_arg == NULL)) { -+ vsync_cb_arg = arg; -+ vsync_cb_handler = handler; -+ } else { -+ return -EEXIST; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(register_vsync_cb); -+ -+int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx) -+{ -+ if ((vsync_cb_handler == handler) && (vsync_cb_arg == arg)) { -+ vsync_cb_handler = NULL; -+ vsync_cb_arg = NULL; -+ } else { -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(unregister_vsync_cb); -+ - /* IRQ handler for version 2 of LCDC */ - static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) - { -@@ -862,6 +981,8 @@ static irqreturn_t lcdc_irq_handler_rev0 - LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); - par->vsync_flag = 1; - wake_up_interruptible(&par->vsync_wait); -+ if (vsync_cb_handler) -+ vsync_cb_handler(vsync_cb_arg); - } - - if (stat & LCD_END_OF_FRAME1) { -@@ -872,6 +993,8 @@ static irqreturn_t lcdc_irq_handler_rev0 - LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); - par->vsync_flag = 1; - wake_up_interruptible(&par->vsync_wait); -+ if (vsync_cb_handler) -+ vsync_cb_handler(vsync_cb_arg); - } - - /* Set only when controller is disabled and at the end of -@@ -1032,7 +1155,13 @@ static int fb_check_var(struct fb_var_sc - if (var->yres + var->yoffset > var->yres_virtual) - var->yoffset = var->yres_virtual - var->yres; - -- var->pixclock = da8xx_fb_round_clk(par, var->pixclock); -+ /* -+ * if we don't have an encoder attached, use the legacy -+ * clock setting code that works on da8xx but is a bit -+ * inaccurate for the encoders on AM335x -+ */ -+ if (!IS_ENABLED(CONFIG_FB_DA8XX_TDA998X) || (par->hdmi_node == 0)) -+ var->pixclock = da8xx_fb_round_clk(par, var->pixclock); - - return err; - } -@@ -1312,12 +1441,54 @@ static struct fb_ops da8xx_fb_ops = { - .fb_blank = cfb_blank, - }; - -+static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev) -+{ -+ struct lcd_ctrl_config *cfg; -+ -+ cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL); -+ if (!cfg) -+ return NULL; -+ -+ /* default values */ -+ -+ if (lcd_revision == LCD_VERSION_1) -+ cfg->bpp = 16; -+ else -+ cfg->bpp = 32; -+ -+ /* -+ * For panels so far used with this LCDC, below statement is sufficient. -+ * For new panels, if required, struct lcd_ctrl_cfg fields to be updated -+ * with additional/modified values. Those values would have to be then -+ * obtained from dt(requiring new dt bindings). -+ */ -+ -+ cfg->panel_shade = COLOR_ACTIVE; -+ -+ return cfg; -+} -+ - static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) - { - struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; - struct fb_videomode *lcdc_info; -+ struct device_node *np = dev->dev.of_node; - int i; - -+ if (np) { -+ lcdc_info = devm_kzalloc(&dev->dev, -+ sizeof(struct fb_videomode), -+ GFP_KERNEL); -+ if (!lcdc_info) -+ return NULL; -+ -+ if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) { -+ dev_err(&dev->dev, "timings not available in DT\n"); -+ return NULL; -+ } -+ return lcdc_info; -+ } -+ - for (i = 0, lcdc_info = known_lcd_panels; - i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) { - if (strcmp(fb_pdata->type, lcdc_info->name) == 0) -@@ -1342,15 +1513,28 @@ static int fb_probe(struct platform_devi - struct fb_videomode *lcdc_info; - struct fb_info *da8xx_fb_info; - struct da8xx_fb_par *par; -- struct clk *tmp_lcdc_clk; -+ struct clk *tmp_lcdc_clk, *tmp_disp_clk; - int ret; - unsigned long ulcm; -+ struct device_node *hdmi_node = NULL; -+ - -- if (fb_pdata == NULL) { -+ if (fb_pdata == NULL && !device->dev.of_node) { - dev_err(&device->dev, "Can not get platform data\n"); - return -ENOENT; - } - -+ if (device->dev.of_node) { -+ hdmi_node = of_parse_phandle(device->dev.of_node, -+ "hdmi", 0); -+ if (hdmi_node && -+ (da8xx_get_encoder_from_phandle(hdmi_node) == 0)) { -+ /* i2c encoder has not initialized yet, defer */ -+ of_node_put(hdmi_node); -+ return -EPROBE_DEFER; -+ } -+ } -+ - lcdc_info = da8xx_fb_get_videomode(device); - if (lcdc_info == NULL) - return -ENODEV; -@@ -1366,6 +1550,12 @@ static int fb_probe(struct platform_devi - return PTR_ERR(tmp_lcdc_clk); - } - -+ tmp_disp_clk = devm_clk_get(&device->dev, "dpll_disp_ck"); -+ if (IS_ERR(tmp_disp_clk)) { -+ /* we can live if dpll_disp_ck is not available */ -+ tmp_disp_clk = 0; -+ } -+ - pm_runtime_enable(&device->dev); - pm_runtime_get_sync(&device->dev); - -@@ -1386,7 +1576,10 @@ static int fb_probe(struct platform_devi - break; - } - -- lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; -+ if (device->dev.of_node) -+ lcd_cfg = da8xx_fb_create_cfg(device); -+ else -+ lcd_cfg = fb_pdata->controller_data; - - if (!lcd_cfg) { - ret = -EINVAL; -@@ -1405,11 +1598,16 @@ static int fb_probe(struct platform_devi - par->dev = &device->dev; - par->lcdc_clk = tmp_lcdc_clk; - par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); -- if (fb_pdata->panel_power_ctrl) { -+ par->disp_clk = tmp_disp_clk; -+ -+ if (fb_pdata && fb_pdata->panel_power_ctrl) { - par->panel_power_ctrl = fb_pdata->panel_power_ctrl; - par->panel_power_ctrl(1); - } - -+ if (device->dev.of_node) -+ par->hdmi_node = hdmi_node; -+ - fb_videomode_to_var(&da8xx_fb_var, lcdc_info); - par->cfg = *lcd_cfg; - -@@ -1653,6 +1851,19 @@ static int fb_resume(struct platform_dev - #define fb_resume NULL - #endif - -+#if IS_ENABLED(CONFIG_OF) -+static const struct of_device_id da8xx_fb_of_match[] = { -+ /* -+ * this driver supports version 1 and version 2 of the -+ * Texas Instruments lcd controller (lcdc) hardware block -+ */ -+ {.compatible = "ti,da8xx-tilcdc", }, -+ {.compatible = "ti,am33xx-tilcdc", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, da8xx_fb_of_match); -+#endif -+ - static struct platform_driver da8xx_fb_driver = { - .probe = fb_probe, - .remove = fb_remove, -@@ -1661,6 +1872,7 @@ static struct platform_driver da8xx_fb_d - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(da8xx_fb_of_match), - }, - }; - ---- /dev/null -+++ b/drivers/video/da8xx-tda998x-hdmi.c -@@ -0,0 +1,840 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments -+ * Author: Rob Clark <robdclark@gmail.com> -+ * Author: Darren Etheridge <detheridge@ti.com> -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+ -+#include <linux/module.h> -+#include <linux/i2c.h> -+#include <linux/slab.h> -+#include <linux/delay.h> -+#include <video/da8xx-fb.h> -+#include <video/da8xx-tda998x-hdmi.h> -+ -+#define TDA998X_DEBUG -+ -+#ifdef TDA998X_DEBUG -+#define DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__) -+#else -+#define DBG(fmt, ...) -+#endif -+ -+ -+#define tda998x_encoder da8xx_encoder -+ -+struct tda998x_priv { -+ struct i2c_client *cec; -+ uint16_t rev; -+ uint8_t current_page; -+ int dpms; -+ bool is_hdmi_sink; -+ u8 vip_cntrl_0; -+ u8 vip_cntrl_1; -+ u8 vip_cntrl_2; -+ struct tda998x_encoder_params params; -+}; -+ -+#define to_tda998x_priv(x) ((struct tda998x_priv *)x->priv) -+#define tda998x_i2c_encoder_get_client(x) ((struct i2c_client *)x->client) -+ -+/* The TDA9988 series of devices use a paged register scheme.. to simplify -+ * things we encode the page # in upper bits of the register #. To read/ -+ * write a given register, we need to make sure CURPAGE register is set -+ * appropriately. Which implies reads/writes are not atomic. Fun! -+ */ -+ -+#define REG(page, addr) (((page) << 8) | (addr)) -+#define REG2ADDR(reg) ((reg) & 0xff) -+#define REG2PAGE(reg) (((reg) >> 8) & 0xff) -+ -+#define REG_CURPAGE 0xff /* write */ -+ -+ -+/* Page 00h: General Control */ -+#define REG_VERSION_LSB REG(0x00, 0x00) /* read */ -+#define REG_MAIN_CNTRL0 REG(0x00, 0x01) /* read/write */ -+# define MAIN_CNTRL0_SR (1 << 0) -+# define MAIN_CNTRL0_DECS (1 << 1) -+# define MAIN_CNTRL0_DEHS (1 << 2) -+# define MAIN_CNTRL0_CECS (1 << 3) -+# define MAIN_CNTRL0_CEHS (1 << 4) -+# define MAIN_CNTRL0_SCALER (1 << 7) -+#define REG_VERSION_MSB REG(0x00, 0x02) /* read */ -+#define REG_SOFTRESET REG(0x00, 0x0a) /* write */ -+# define SOFTRESET_AUDIO (1 << 0) -+# define SOFTRESET_I2C_MASTER (1 << 1) -+#define REG_DDC_DISABLE REG(0x00, 0x0b) /* read/write */ -+#define REG_CCLK_ON REG(0x00, 0x0c) /* read/write */ -+#define REG_I2C_MASTER REG(0x00, 0x0d) /* read/write */ -+# define I2C_MASTER_DIS_MM (1 << 0) -+# define I2C_MASTER_DIS_FILT (1 << 1) -+# define I2C_MASTER_APP_STRT_LAT (1 << 2) -+#define REG_FEAT_POWERDOWN REG(0x00, 0x0e) /* read/write */ -+# define FEAT_POWERDOWN_SPDIF (1 << 3) -+#define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */ -+#define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */ -+#define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */ -+# define INT_FLAGS_2_EDID_BLK_RD (1 << 1) -+#define REG_ENA_ACLK REG(0x00, 0x16) /* read/write */ -+#define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */ -+#define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */ -+#define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */ -+#define REG_ENA_AP REG(0x00, 0x1e) /* read/write */ -+#define REG_VIP_CNTRL_0 REG(0x00, 0x20) /* write */ -+# define VIP_CNTRL_0_MIRR_A (1 << 7) -+# define VIP_CNTRL_0_SWAP_A(x) (((x) & 7) << 4) -+# define VIP_CNTRL_0_MIRR_B (1 << 3) -+# define VIP_CNTRL_0_SWAP_B(x) (((x) & 7) << 0) -+#define REG_VIP_CNTRL_1 REG(0x00, 0x21) /* write */ -+# define VIP_CNTRL_1_MIRR_C (1 << 7) -+# define VIP_CNTRL_1_SWAP_C(x) (((x) & 7) << 4) -+# define VIP_CNTRL_1_MIRR_D (1 << 3) -+# define VIP_CNTRL_1_SWAP_D(x) (((x) & 7) << 0) -+#define REG_VIP_CNTRL_2 REG(0x00, 0x22) /* write */ -+# define VIP_CNTRL_2_MIRR_E (1 << 7) -+# define VIP_CNTRL_2_SWAP_E(x) (((x) & 7) << 4) -+# define VIP_CNTRL_2_MIRR_F (1 << 3) -+# define VIP_CNTRL_2_SWAP_F(x) (((x) & 7) << 0) -+#define REG_VIP_CNTRL_3 REG(0x00, 0x23) /* write */ -+# define VIP_CNTRL_3_X_TGL (1 << 0) -+# define VIP_CNTRL_3_H_TGL (1 << 1) -+# define VIP_CNTRL_3_V_TGL (1 << 2) -+# define VIP_CNTRL_3_EMB (1 << 3) -+# define VIP_CNTRL_3_SYNC_DE (1 << 4) -+# define VIP_CNTRL_3_SYNC_HS (1 << 5) -+# define VIP_CNTRL_3_DE_INT (1 << 6) -+# define VIP_CNTRL_3_EDGE (1 << 7) -+#define REG_VIP_CNTRL_4 REG(0x00, 0x24) /* write */ -+# define VIP_CNTRL_4_BLC(x) (((x) & 3) << 0) -+# define VIP_CNTRL_4_BLANKIT(x) (((x) & 3) << 2) -+# define VIP_CNTRL_4_CCIR656 (1 << 4) -+# define VIP_CNTRL_4_656_ALT (1 << 5) -+# define VIP_CNTRL_4_TST_656 (1 << 6) -+# define VIP_CNTRL_4_TST_PAT (1 << 7) -+#define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */ -+# define VIP_CNTRL_5_CKCASE (1 << 0) -+# define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1) -+#define REG_MUX_AP REG(0x00, 0x26) /* read/write */ -+#define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */ -+#define REG_MAT_CONTRL REG(0x00, 0x80) /* write */ -+# define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0) -+# define MAT_CONTRL_MAT_BP (1 << 2) -+#define REG_VIDFORMAT REG(0x00, 0xa0) /* write */ -+#define REG_REFPIX_MSB REG(0x00, 0xa1) /* write */ -+#define REG_REFPIX_LSB REG(0x00, 0xa2) /* write */ -+#define REG_REFLINE_MSB REG(0x00, 0xa3) /* write */ -+#define REG_REFLINE_LSB REG(0x00, 0xa4) /* write */ -+#define REG_NPIX_MSB REG(0x00, 0xa5) /* write */ -+#define REG_NPIX_LSB REG(0x00, 0xa6) /* write */ -+#define REG_NLINE_MSB REG(0x00, 0xa7) /* write */ -+#define REG_NLINE_LSB REG(0x00, 0xa8) /* write */ -+#define REG_VS_LINE_STRT_1_MSB REG(0x00, 0xa9) /* write */ -+#define REG_VS_LINE_STRT_1_LSB REG(0x00, 0xaa) /* write */ -+#define REG_VS_PIX_STRT_1_MSB REG(0x00, 0xab) /* write */ -+#define REG_VS_PIX_STRT_1_LSB REG(0x00, 0xac) /* write */ -+#define REG_VS_LINE_END_1_MSB REG(0x00, 0xad) /* write */ -+#define REG_VS_LINE_END_1_LSB REG(0x00, 0xae) /* write */ -+#define REG_VS_PIX_END_1_MSB REG(0x00, 0xaf) /* write */ -+#define REG_VS_PIX_END_1_LSB REG(0x00, 0xb0) /* write */ -+#define REG_VS_LINE_STRT_2_MSB REG(0x00, 0xb1) /* write */ -+#define REG_VS_LINE_STRT_2_LSB REG(0x00, 0xb2) /* write */ -+#define REG_VS_PIX_STRT_2_MSB REG(0x00, 0xb3) /* write */ -+#define REG_VS_PIX_STRT_2_LSB REG(0x00, 0xb4) /* write */ -+#define REG_VS_LINE_END_2_MSB REG(0x00, 0xb5) /* write */ -+#define REG_VS_LINE_END_2_LSB REG(0x00, 0xb6) /* write */ -+#define REG_VS_PIX_END_2_MSB REG(0x00, 0xb7) /* write */ -+#define REG_VS_PIX_END_2_LSB REG(0x00, 0xb8) /* write */ -+#define REG_HS_PIX_START_MSB REG(0x00, 0xb9) /* write */ -+#define REG_HS_PIX_START_LSB REG(0x00, 0xba) /* write */ -+#define REG_HS_PIX_STOP_MSB REG(0x00, 0xbb) /* write */ -+#define REG_HS_PIX_STOP_LSB REG(0x00, 0xbc) /* write */ -+#define REG_VWIN_START_1_MSB REG(0x00, 0xbd) /* write */ -+#define REG_VWIN_START_1_LSB REG(0x00, 0xbe) /* write */ -+#define REG_VWIN_END_1_MSB REG(0x00, 0xbf) /* write */ -+#define REG_VWIN_END_1_LSB REG(0x00, 0xc0) /* write */ -+#define REG_VWIN_START_2_MSB REG(0x00, 0xc1) /* write */ -+#define REG_VWIN_START_2_LSB REG(0x00, 0xc2) /* write */ -+#define REG_VWIN_END_2_MSB REG(0x00, 0xc3) /* write */ -+#define REG_VWIN_END_2_LSB REG(0x00, 0xc4) /* write */ -+#define REG_DE_START_MSB REG(0x00, 0xc5) /* write */ -+#define REG_DE_START_LSB REG(0x00, 0xc6) /* write */ -+#define REG_DE_STOP_MSB REG(0x00, 0xc7) /* write */ -+#define REG_DE_STOP_LSB REG(0x00, 0xc8) /* write */ -+#define REG_TBG_CNTRL_0 REG(0x00, 0xca) /* write */ -+# define TBG_CNTRL_0_TOP_TGL (1 << 0) -+# define TBG_CNTRL_0_TOP_SEL (1 << 1) -+# define TBG_CNTRL_0_DE_EXT (1 << 2) -+# define TBG_CNTRL_0_TOP_EXT (1 << 3) -+# define TBG_CNTRL_0_FRAME_DIS (1 << 5) -+# define TBG_CNTRL_0_SYNC_MTHD (1 << 6) -+# define TBG_CNTRL_0_SYNC_ONCE (1 << 7) -+#define REG_TBG_CNTRL_1 REG(0x00, 0xcb) /* write */ -+# define TBG_CNTRL_1_H_TGL (1 << 0) -+# define TBG_CNTRL_1_V_TGL (1 << 1) -+# define TBG_CNTRL_1_TGL_EN (1 << 2) -+# define TBG_CNTRL_1_X_EXT (1 << 3) -+# define TBG_CNTRL_1_H_EXT (1 << 4) -+# define TBG_CNTRL_1_V_EXT (1 << 5) -+# define TBG_CNTRL_1_DWIN_DIS (1 << 6) -+#define REG_ENABLE_SPACE REG(0x00, 0xd6) /* write */ -+#define REG_HVF_CNTRL_0 REG(0x00, 0xe4) /* write */ -+# define HVF_CNTRL_0_SM (1 << 7) -+# define HVF_CNTRL_0_RWB (1 << 6) -+# define HVF_CNTRL_0_PREFIL(x) (((x) & 3) << 2) -+# define HVF_CNTRL_0_INTPOL(x) (((x) & 3) << 0) -+#define REG_HVF_CNTRL_1 REG(0x00, 0xe5) /* write */ -+# define HVF_CNTRL_1_FOR (1 << 0) -+# define HVF_CNTRL_1_YUVBLK (1 << 1) -+# define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2) -+# define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) -+# define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) -+#define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ -+#define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ -+# define I2S_FORMAT(x) (((x) & 3) << 0) -+#define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ -+# define AIP_CLKSEL_FS(x) (((x) & 3) << 0) -+# define AIP_CLKSEL_CLK_POL(x) (((x) & 1) << 2) -+# define AIP_CLKSEL_AIP(x) (((x) & 7) << 3) -+ -+ -+/* Page 02h: PLL settings */ -+#define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */ -+# define PLL_SERIAL_1_SRL_FDN (1 << 0) -+# define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) -+# define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) -+#define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ -+# define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) -+# define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) -+#define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ -+# define PLL_SERIAL_3_SRL_CCIR (1 << 0) -+# define PLL_SERIAL_3_SRL_DE (1 << 2) -+# define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4) -+#define REG_SERIALIZER REG(0x02, 0x03) /* read/write */ -+#define REG_BUFFER_OUT REG(0x02, 0x04) /* read/write */ -+#define REG_PLL_SCG1 REG(0x02, 0x05) /* read/write */ -+#define REG_PLL_SCG2 REG(0x02, 0x06) /* read/write */ -+#define REG_PLL_SCGN1 REG(0x02, 0x07) /* read/write */ -+#define REG_PLL_SCGN2 REG(0x02, 0x08) /* read/write */ -+#define REG_PLL_SCGR1 REG(0x02, 0x09) /* read/write */ -+#define REG_PLL_SCGR2 REG(0x02, 0x0a) /* read/write */ -+#define REG_AUDIO_DIV REG(0x02, 0x0e) /* read/write */ -+#define REG_SEL_CLK REG(0x02, 0x11) /* read/write */ -+# define SEL_CLK_SEL_CLK1 (1 << 0) -+# define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1) -+# define SEL_CLK_ENA_SC_CLK (1 << 3) -+#define REG_ANA_GENERAL REG(0x02, 0x12) /* read/write */ -+ -+ -+/* Page 09h: EDID Control */ -+#define REG_EDID_DATA_0 REG(0x09, 0x00) /* read */ -+/* next 127 successive registers are the EDID block */ -+#define REG_EDID_CTRL REG(0x09, 0xfa) /* read/write */ -+#define REG_DDC_ADDR REG(0x09, 0xfb) /* read/write */ -+#define REG_DDC_OFFS REG(0x09, 0xfc) /* read/write */ -+#define REG_DDC_SEGM_ADDR REG(0x09, 0xfd) /* read/write */ -+#define REG_DDC_SEGM REG(0x09, 0xfe) /* read/write */ -+ -+ -+/* Page 10h: information frames and packets */ -+#define REG_IF1_HB0 REG(0x10, 0x20) /* read/write */ -+#define REG_IF2_HB0 REG(0x10, 0x40) /* read/write */ -+#define REG_IF3_HB0 REG(0x10, 0x60) /* read/write */ -+#define REG_IF4_HB0 REG(0x10, 0x80) /* read/write */ -+#define REG_IF5_HB0 REG(0x10, 0xa0) /* read/write */ -+ -+ -+/* Page 11h: audio settings and content info packets */ -+#define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */ -+# define AIP_CNTRL_0_RST_FIFO (1 << 0) -+# define AIP_CNTRL_0_SWAP (1 << 1) -+# define AIP_CNTRL_0_LAYOUT (1 << 2) -+# define AIP_CNTRL_0_ACR_MAN (1 << 5) -+# define AIP_CNTRL_0_RST_CTS (1 << 6) -+#define REG_CA_I2S REG(0x11, 0x01) /* read/write */ -+# define CA_I2S_CA_I2S(x) (((x) & 31) << 0) -+# define CA_I2S_HBR_CHSTAT (1 << 6) -+#define REG_LATENCY_RD REG(0x11, 0x04) /* read/write */ -+#define REG_ACR_CTS_0 REG(0x11, 0x05) /* read/write */ -+#define REG_ACR_CTS_1 REG(0x11, 0x06) /* read/write */ -+#define REG_ACR_CTS_2 REG(0x11, 0x07) /* read/write */ -+#define REG_ACR_N_0 REG(0x11, 0x08) /* read/write */ -+#define REG_ACR_N_1 REG(0x11, 0x09) /* read/write */ -+#define REG_ACR_N_2 REG(0x11, 0x0a) /* read/write */ -+#define REG_CTS_N REG(0x11, 0x0c) /* read/write */ -+# define CTS_N_K(x) (((x) & 7) << 0) -+# define CTS_N_M(x) (((x) & 3) << 4) -+#define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */ -+# define ENC_CNTRL_RST_ENC (1 << 0) -+# define ENC_CNTRL_RST_SEL (1 << 1) -+# define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2) -+#define REG_DIP_FLAGS REG(0x11, 0x0e) /* read/write */ -+# define DIP_FLAGS_ACR (1 << 0) -+# define DIP_FLAGS_GC (1 << 1) -+#define REG_DIP_IF_FLAGS REG(0x11, 0x0f) /* read/write */ -+# define DIP_IF_FLAGS_IF1 (1 << 1) -+# define DIP_IF_FLAGS_IF2 (1 << 2) -+# define DIP_IF_FLAGS_IF3 (1 << 3) -+# define DIP_IF_FLAGS_IF4 (1 << 4) -+# define DIP_IF_FLAGS_IF5 (1 << 5) -+#define REG_CH_STAT_B(x) REG(0x11, 0x14 + (x)) /* read/write */ -+ -+ -+/* Page 12h: HDCP and OTP */ -+#define REG_TX3 REG(0x12, 0x9a) /* read/write */ -+#define REG_TX4 REG(0x12, 0x9b) /* read/write */ -+# define TX4_PD_RAM (1 << 1) -+#define REG_TX33 REG(0x12, 0xb8) /* read/write */ -+# define TX33_HDMI (1 << 1) -+ -+ -+/* Page 13h: Gamut related metadata packets */ -+ -+ -+ -+/* CEC registers: (not paged) -+ */ -+#define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */ -+# define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7) -+# define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6) -+# define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1) -+# define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0) -+#define REG_CEC_RXSHPDLEV 0xfe /* read */ -+# define CEC_RXSHPDLEV_RXSENS (1 << 0) -+# define CEC_RXSHPDLEV_HPD (1 << 1) -+ -+#define REG_CEC_ENAMODS 0xff /* read/write */ -+# define CEC_ENAMODS_DIS_FRO (1 << 6) -+# define CEC_ENAMODS_DIS_CCLK (1 << 5) -+# define CEC_ENAMODS_EN_RXSENS (1 << 2) -+# define CEC_ENAMODS_EN_HDMI (1 << 1) -+# define CEC_ENAMODS_EN_CEC (1 << 0) -+ -+ -+/* Device versions: */ -+#define TDA9989N2 0x0101 -+#define TDA19989 0x0201 -+#define TDA19989N2 0x0202 -+#define TDA19988 0x0301 -+ -+static void -+cec_write(struct tda998x_encoder *encoder, uint16_t addr, uint8_t val) -+{ -+ struct i2c_client *client = to_tda998x_priv(encoder)->cec; -+ uint8_t buf[] = {addr, val}; -+ int ret; -+ -+ ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); -+ if (ret < 0) -+ dev_err(&client->dev, "Error %d writing to cec:0x%x\n", -+ ret, addr); -+} -+ -+static void -+set_page(struct tda998x_encoder *encoder, uint16_t reg) -+{ -+ struct tda998x_priv *priv = to_tda998x_priv(encoder); -+ -+ if (REG2PAGE(reg) != priv->current_page) { -+ struct i2c_client *client = -+ tda998x_i2c_encoder_get_client(encoder); -+ uint8_t buf[] = { -+ REG_CURPAGE, REG2PAGE(reg) -+ }; -+ int ret = i2c_master_send(client, buf, sizeof(buf)); -+ if (ret < 0) -+ dev_err(&client->dev, -+ "Error %d writing to REG_CURPAGE\n", ret); -+ -+ priv->current_page = REG2PAGE(reg); -+ } -+} -+ -+static int -+reg_read_range(struct tda998x_encoder *encoder, -+ uint16_t reg, char *buf, int cnt) -+{ -+ struct i2c_client *client = tda998x_i2c_encoder_get_client(encoder); -+ uint8_t addr = REG2ADDR(reg); -+ int ret; -+ -+ set_page(encoder, reg); -+ -+ ret = i2c_master_send(client, &addr, sizeof(addr)); -+ if (ret < 0) -+ goto fail; -+ -+ ret = i2c_master_recv(client, buf, cnt); -+ if (ret < 0) -+ goto fail; -+ -+ return ret; -+ -+fail: -+ dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); -+ return ret; -+} -+ -+static uint8_t -+reg_read(struct tda998x_encoder *encoder, uint16_t reg) -+{ -+ uint8_t val = 0; -+ reg_read_range(encoder, reg, &val, sizeof(val)); -+ return val; -+} -+ -+static void -+reg_write(struct tda998x_encoder *encoder, uint16_t reg, uint8_t val) -+{ -+ struct i2c_client *client = tda998x_i2c_encoder_get_client(encoder); -+ uint8_t buf[] = {REG2ADDR(reg), val}; -+ int ret; -+ -+ set_page(encoder, reg); -+ -+ ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); -+ if (ret < 0) -+ dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); -+} -+ -+static void -+reg_write16(struct tda998x_encoder *encoder, uint16_t reg, uint16_t val) -+{ -+ struct i2c_client *client = tda998x_i2c_encoder_get_client(encoder); -+ uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; -+ int ret; -+ -+ set_page(encoder, reg); -+ -+ ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); -+ if (ret < 0) -+ dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); -+} -+ -+static void -+reg_set(struct tda998x_encoder *encoder, uint16_t reg, uint8_t val) -+{ -+ reg_write(encoder, reg, reg_read(encoder, reg) | val); -+} -+ -+static void -+reg_clear(struct tda998x_encoder *encoder, uint16_t reg, uint8_t val) -+{ -+ reg_write(encoder, reg, reg_read(encoder, reg) & ~val); -+} -+ -+static void -+tda998x_reset(struct tda998x_encoder *encoder) -+{ -+ /* reset audio and i2c master: */ -+ reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); -+ msleep(50); -+ reg_clear(encoder, REG_SOFTRESET, -+ SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); -+ msleep(50); -+ -+ /* reset transmitter: */ -+ reg_set(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); -+ reg_clear(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); -+ -+ /* PLL registers common configuration */ -+ reg_write(encoder, REG_PLL_SERIAL_1, 0x00); -+ reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); -+ reg_write(encoder, REG_PLL_SERIAL_3, 0x00); -+ reg_write(encoder, REG_SERIALIZER, 0x00); -+ reg_write(encoder, REG_BUFFER_OUT, 0x00); -+ reg_write(encoder, REG_PLL_SCG1, 0x00); -+ reg_write(encoder, REG_AUDIO_DIV, 0x03); -+ reg_write(encoder, REG_SEL_CLK, -+ SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); -+ reg_write(encoder, REG_PLL_SCGN1, 0xfa); -+ reg_write(encoder, REG_PLL_SCGN2, 0x00); -+ reg_write(encoder, REG_PLL_SCGR1, 0x5b); -+ reg_write(encoder, REG_PLL_SCGR2, 0x00); -+ reg_write(encoder, REG_PLL_SCG2, 0x10); -+} -+ -+struct tda_mode { -+ uint32_t clock; -+ uint32_t vrefresh; -+ uint32_t hdisplay; -+ uint32_t hsync_start; -+ uint32_t hsync_end; -+ uint32_t htotal; -+ uint32_t vdisplay; -+ uint32_t vsync_start; -+ uint32_t vsync_end; -+ uint32_t vtotal; -+ uint32_t flags; -+ uint32_t hskew; -+}; -+ -+static void convert_to_display_mode(struct tda_mode *mode, -+ struct fb_videomode *timing) -+{ -+ mode->clock = (PICOS2KHZ(timing->pixclock)/10)*10; -+ mode->vrefresh = timing->refresh; -+ -+ mode->hdisplay = timing->xres; -+ mode->hsync_start = mode->hdisplay + timing->right_margin; -+ mode->hsync_end = mode->hsync_start + timing->hsync_len; -+ mode->htotal = mode->hsync_end + timing->left_margin; -+ -+ mode->vdisplay = timing->yres; -+ mode->vsync_start = mode->vdisplay + timing->lower_margin; -+ mode->vsync_end = mode->vsync_start + timing->vsync_len; -+ mode->vtotal = mode->vsync_end + timing->upper_margin; -+ -+ mode->flags = timing->sync; -+ -+ -+ -+ pr_debug("mode->htotal %d, mode->vtotal %d, mode->flags %x\n", -+ mode->htotal, mode->vtotal, mode->flags); -+ pr_debug("mode->clock %d\n", mode->clock); -+ pr_debug("mode->vrefresh %d\n", mode->vrefresh); -+ pr_debug("mode->hdisplay %d\n", mode->hdisplay); -+ pr_debug("mode->hsync_start %d\n", mode->hsync_start); -+ pr_debug("mode->hsync_end %d\n", mode->hsync_end); -+ pr_debug("mode->vdisplay %d\n", mode->vdisplay); -+ pr_debug("mode->vsync_start %d\n", mode->vsync_start); -+ pr_debug("mode->vsync_end %d\n", mode->vsync_end); -+ -+ /* -+ * this is a workaround to fix up the mode so that the non-vesa -+ * compliant LCD controller can work with the NXP HDMI encoder -+ * we invert the horizontal sync pulse, and then add some hskew -+ * to move the picture to the right on the screen by a sync pulse -+ * worth of pixels -+ */ -+ mode->hskew = mode->hsync_end - mode->hsync_start; -+ mode->flags ^= FB_SYNC_HOR_HIGH_ACT; -+ -+ pr_debug("mode->hskew %d\n", mode->hskew); -+ -+} -+ -+ -+void da8xx_tda998x_setmode(struct tda998x_encoder *encoder, -+ struct fb_videomode *vid_mode) -+{ -+ struct tda998x_priv *priv = to_tda998x_priv(encoder); -+ uint16_t ref_pix, ref_line, n_pix, n_line; -+ uint16_t hs_pix_s, hs_pix_e; -+ uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; -+ uint16_t vs2_pix_s, vs2_pix_e, vs2_line_s, vs2_line_e; -+ uint16_t vwin1_line_s, vwin1_line_e; -+ uint16_t vwin2_line_s, vwin2_line_e; -+ uint16_t de_pix_s, de_pix_e; -+ uint8_t reg, div, rep; -+ struct tda_mode tda_mode; -+ struct tda_mode *mode = &tda_mode; -+ -+ convert_to_display_mode(mode, vid_mode); -+ -+ /* -+ * Internally TDA998x is using ITU-R BT.656 style sync but -+ * we get VESA style sync. TDA998x is using a reference pixel -+ * relative to ITU to sync to the input frame and for output -+ * sync generation. -+ * -+ * Now there is some issues to take care of: -+ * - HDMI data islands require sync-before-active -+ * - TDA998x register values must be > 0 to be enabled -+ * - REFLINE needs an additional offset of +1 -+ * - REFPIX needs an addtional offset of +1 for UYUV and +3 for RGB -+ * -+ * So we add +1 to all horizontal and vertical register values, -+ * plus an additional +3 for REFPIX as we are using RGB input only. -+ */ -+ n_pix = mode->htotal; -+ n_line = mode->vtotal; -+ -+ ref_pix = 3 + mode->hsync_start - mode->hdisplay; -+ -+ /* -+ * handle issue on TILCDC where it is outputing -+ * non-VESA compliant sync signals the workaround -+ * forces us to invert the HSYNC, so need to adjust display to -+ * the left by hskew pixels, provided by the tilcdc driver -+ */ -+ ref_pix += mode->hskew; -+ -+ de_pix_s = mode->htotal - mode->hdisplay; -+ de_pix_e = de_pix_s + mode->hdisplay; -+ hs_pix_s = mode->hsync_start - mode->hdisplay; -+ hs_pix_e = hs_pix_s + mode->hsync_end - mode->hsync_start; -+ -+ ref_line = 1 + mode->vsync_start - mode->vdisplay; -+ vwin1_line_s = mode->vtotal - mode->vdisplay - 1; -+ vwin1_line_e = vwin1_line_s + mode->vdisplay; -+ vs1_pix_s = vs1_pix_e = hs_pix_s; -+ vs1_line_s = mode->vsync_start - mode->vdisplay; -+ -+ vs1_line_e = vs1_line_s + -+ mode->vsync_end - mode->vsync_start; -+ -+ vwin2_line_s = vwin2_line_e = 0; -+ vs2_pix_s = vs2_pix_e = 0; -+ vs2_line_s = vs2_line_e = 0; -+ -+ div = 148500 / mode->clock; -+ -+ /* Setup the VIP mappings, enable audio and video ports */ -+ reg_write(encoder, REG_ENA_AP, 0xff); -+ reg_write(encoder, REG_ENA_VP_0, 0xff); -+ reg_write(encoder, REG_ENA_VP_1, 0xff); -+ reg_write(encoder, REG_ENA_VP_2, 0xff); -+ /* set muxing after enabling ports: */ -+ reg_write(encoder, REG_VIP_CNTRL_0, -+ VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3)); -+ reg_write(encoder, REG_VIP_CNTRL_1, -+ VIP_CNTRL_1_SWAP_C(4) | VIP_CNTRL_1_SWAP_D(5)); -+ reg_write(encoder, REG_VIP_CNTRL_2, -+ VIP_CNTRL_2_SWAP_E(0) | VIP_CNTRL_2_SWAP_F(1)); -+ -+ -+ /* mute the audio FIFO: */ -+ reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); -+ -+ /* set HDMI HDCP mode off: */ -+ reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); -+ reg_clear(encoder, REG_TX33, TX33_HDMI); -+ -+ reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); -+ /* no pre-filter or interpolator: */ -+ reg_write(encoder, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | -+ HVF_CNTRL_0_INTPOL(0)); -+ reg_write(encoder, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); -+ reg_write(encoder, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | -+ VIP_CNTRL_4_BLC(0)); -+ reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); -+ -+ reg_clear(encoder, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); -+ reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); -+ reg_write(encoder, REG_SERIALIZER, 0); -+ reg_write(encoder, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); -+ -+ /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ -+ rep = 0; -+ reg_write(encoder, REG_RPT_CNTRL, 0); -+ reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | -+ SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); -+ -+ reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | -+ PLL_SERIAL_2_SRL_PR(rep)); -+ -+ /* set color matrix bypass flag: */ -+ reg_set(encoder, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); -+ -+ /* set BIAS tmds value: */ -+ reg_write(encoder, REG_ANA_GENERAL, 0x09); -+ -+ reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); -+ -+ /* -+ * Sync on rising HSYNC/VSYNC -+ */ -+ reg_write(encoder, REG_VIP_CNTRL_3, 0); -+ reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); -+ -+ /* -+ * TDA19988 requires high-active sync at input stage, -+ * so invert low-active sync provided by master encoder here -+ */ -+ if ((mode->flags & FB_SYNC_HOR_HIGH_ACT) == 0) -+ reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); -+ if ((mode->flags & FB_SYNC_VERT_HIGH_ACT) == 0) -+ reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); -+ -+ /* -+ * Always generate sync polarity relative to input sync and -+ * revert input stage toggled sync at output stage -+ */ -+ reg = TBG_CNTRL_1_TGL_EN; -+ if ((mode->flags & FB_SYNC_HOR_HIGH_ACT) == 0) -+ reg |= TBG_CNTRL_1_H_TGL; -+ if ((mode->flags & FB_SYNC_VERT_HIGH_ACT) == 0) -+ reg |= TBG_CNTRL_1_V_TGL; -+ reg_write(encoder, REG_TBG_CNTRL_1, reg); -+ -+ reg_write(encoder, REG_VIDFORMAT, 0x00); -+ reg_write16(encoder, REG_REFPIX_MSB, ref_pix); -+ reg_write16(encoder, REG_REFLINE_MSB, ref_line); -+ reg_write16(encoder, REG_NPIX_MSB, n_pix); -+ reg_write16(encoder, REG_NLINE_MSB, n_line); -+ reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, vs1_line_s); -+ reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); -+ reg_write16(encoder, REG_VS_LINE_END_1_MSB, vs1_line_e); -+ reg_write16(encoder, REG_VS_PIX_END_1_MSB, vs1_pix_e); -+ reg_write16(encoder, REG_VS_LINE_STRT_2_MSB, vs2_line_s); -+ reg_write16(encoder, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); -+ reg_write16(encoder, REG_VS_LINE_END_2_MSB, vs2_line_e); -+ reg_write16(encoder, REG_VS_PIX_END_2_MSB, vs2_pix_e); -+ reg_write16(encoder, REG_HS_PIX_START_MSB, hs_pix_s); -+ reg_write16(encoder, REG_HS_PIX_STOP_MSB, hs_pix_e); -+ reg_write16(encoder, REG_VWIN_START_1_MSB, vwin1_line_s); -+ reg_write16(encoder, REG_VWIN_END_1_MSB, vwin1_line_e); -+ reg_write16(encoder, REG_VWIN_START_2_MSB, vwin2_line_s); -+ reg_write16(encoder, REG_VWIN_END_2_MSB, vwin2_line_e); -+ reg_write16(encoder, REG_DE_START_MSB, de_pix_s); -+ reg_write16(encoder, REG_DE_STOP_MSB, de_pix_e); -+ -+ if (priv->rev == TDA19988) { -+ /* let incoming pixels fill the active space (if any) */ -+ reg_write(encoder, REG_ENABLE_SPACE, 0x01); -+ } -+ -+ /* must be last register set: */ -+ reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); -+ -+} -+ -+/* I2C driver functions */ -+static int -+da8xx_tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) -+{ -+ struct tda998x_priv *priv; -+ struct da8xx_encoder *encoder; -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->current_page = 0; -+ -+ encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); -+ if (!encoder) { -+ kfree(priv); -+ return -ENOMEM; -+ } -+ -+ priv->cec = i2c_new_dummy(client->adapter, 0x34); -+ -+ encoder->client = client; -+ encoder->priv = priv; -+ encoder->node = client->dev.of_node; -+ encoder->set_mode = da8xx_tda998x_setmode; -+ -+ -+ /* wake up the device: */ -+ cec_write(encoder, REG_CEC_ENAMODS, -+ CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); -+ -+ tda998x_reset(encoder); -+ -+ /* read version: */ -+ priv->rev = reg_read(encoder, REG_VERSION_LSB) | -+ reg_read(encoder, REG_VERSION_MSB) << 8; -+ -+ /* mask off feature bits: */ -+ priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ -+ -+ switch (priv->rev) { -+ case TDA9989N2: -+ dev_info(&client->dev, "found TDA9989 n2"); -+ break; -+ case TDA19989: -+ dev_info(&client->dev, "found TDA19989"); -+ break; -+ case TDA19989N2: -+ dev_info(&client->dev, "found TDA19989 n2"); -+ break; -+ case TDA19988: -+ dev_info(&client->dev, "found TDA19988"); -+ break; -+ default: -+ DBG("found unsupported device: %04x", priv->rev); -+ goto fail; -+ } -+ -+ da8xx_register_encoder(encoder); -+ -+ /* after reset, enable DDC: */ -+ reg_write(encoder, REG_DDC_DISABLE, 0x00); -+ -+ /* set clock on DDC channel: */ -+ reg_write(encoder, REG_TX3, 39); -+ -+ /* if necessary, disable multi-master: */ -+ if (priv->rev == TDA19989) -+ reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM); -+ -+ cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, -+ CEC_FRO_IM_CLK_CTRL_GHOST_DIS | -+ CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); -+ -+ i2c_set_clientdata(client, encoder); -+ -+ return 0; -+ -+fail: -+ /* if encoder_init fails, the encoder slave is never registered, -+ * so cleanup here: -+ */ -+ if (priv->cec) -+ i2c_unregister_device(priv->cec); -+ -+ kfree(priv); -+ kfree(encoder); -+ return -ENXIO; -+} -+ -+static int -+da8xx_tda998x_remove(struct i2c_client *client) -+{ -+ struct da8xx_encoder *da8xx_encoder; -+ struct tda998x_priv *priv; -+ -+ da8xx_encoder = i2c_get_clientdata(client); -+ if (da8xx_encoder) { -+ da8xx_unregister_encoder(da8xx_encoder); -+ priv = to_tda998x_priv(da8xx_encoder); -+ if (priv->cec) { -+ /* disable the device: */ -+ cec_write(da8xx_encoder, REG_CEC_ENAMODS, 0); -+ i2c_unregister_device(priv->cec); -+ } -+ kfree(da8xx_encoder->priv); -+ kfree(da8xx_encoder); -+ } -+ return 0; -+} -+ -+ -+static struct i2c_device_id da8xx_tda998x_ids[] = { -+ { "tda998x", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, da8xx_tda998x_ids); -+ -+static struct i2c_driver da8xx_tda998x_driver = { -+ .probe = da8xx_tda998x_probe, -+ .remove = da8xx_tda998x_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "tda998x", -+ }, -+ .id_table = da8xx_tda998x_ids, -+}; -+ -+module_i2c_driver(da8xx_tda998x_driver); -+ -+MODULE_DESCRIPTION("NXP TDA998x HDMI encoder driver for TI AM335x/DA8xx"); -+MODULE_AUTHOR("Texas Instruments"); -+MODULE_LICENSE("GPL"); ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -2234,6 +2234,14 @@ config FB_DA8XX - found on DA8xx/OMAP-L1xx/AM335x SoCs. - If unsure, say N. - -+config FB_DA8XX_TDA998X -+ tristate "NXP TDA998x HDMI driver for BeagleBone Black" -+ depends on FB_DA8XX -+ ---help--- -+ This is a driver for NXP TDA998X HDMI as used on the BeagleBone -+ Black. -+ If unsure, say N. -+ - config FB_VIRTUAL - tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" - depends on FB ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -164,6 +164,7 @@ obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin - obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o - obj-$(CONFIG_FB_MX3) += mx3fb.o - obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o -+obj-$(CONFIG_FB_DA8XX_TDA998X) += da8xx-tda998x-hdmi.o - obj-$(CONFIG_FB_MXS) += mxsfb.o - obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o - obj-$(CONFIG_FB_SIMPLE) += simplefb.o ---- a/drivers/video/omap2/displays-new/connector-analog-tv.c -+++ b/drivers/video/omap2/displays-new/connector-analog-tv.c -@@ -12,6 +12,7 @@ - #include <linux/slab.h> - #include <linux/module.h> - #include <linux/platform_device.h> -+#include <linux/of.h> - - #include <video/omapdss.h> - #include <video/omap-panel-data.h> -@@ -42,6 +43,12 @@ static const struct omap_video_timings t - .interlace = true, - }; - -+static const struct of_device_id tvc_of_match[]; -+ -+struct tvc_of_data { -+ enum omap_dss_venc_type connector_type; -+}; -+ - #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) - - static int tvc_connect(struct omap_dss_device *dssdev) -@@ -205,6 +212,36 @@ static int tvc_probe_pdata(struct platfo - return 0; - } - -+static int tvc_probe_of(struct platform_device *pdev, -+ const struct tvc_of_data *data) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ ddata->connector_type = data->connector_type; -+ -+ ddata->invert_polarity = -+ of_property_read_bool(node, "invert-polarity"); -+ -+ return 0; -+} -+ -+ - static int tvc_probe(struct platform_device *pdev) - { - struct panel_drv_data *ddata; -@@ -222,6 +259,18 @@ static int tvc_probe(struct platform_dev - r = tvc_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ const struct of_device_id *match; -+ -+ match = of_match_node(tvc_of_match, pdev->dev.of_node); -+ if (!match) { -+ dev_err(&pdev->dev, "unsupported device\n"); -+ return -ENODEV; -+ } -+ -+ r = tvc_probe_of(pdev, match->data); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -263,12 +312,33 @@ static int __exit tvc_remove(struct plat - return 0; - } - -+static const struct tvc_of_data tv_svideo_data = { -+ .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, -+}; -+ -+static const struct tvc_of_data tv_composite_video_data = { -+ .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE, -+}; -+ -+static const struct of_device_id tvc_of_match[] = { -+ { -+ .compatible = "ti,svideo-connector", -+ .data = &tv_svideo_data, -+ }, -+ { -+ .compatible = "ti,composite-video-connector", -+ .data = &tv_composite_video_data, -+ }, -+ {}, -+}; -+ - static struct platform_driver tvc_connector_driver = { - .probe = tvc_probe, - .remove = __exit_p(tvc_remove), - .driver = { - .name = "connector-analog-tv", - .owner = THIS_MODULE, -+ .of_match_table = tvc_of_match, - }, - }; - ---- a/drivers/video/omap2/displays-new/connector-dvi.c -+++ b/drivers/video/omap2/displays-new/connector-dvi.c -@@ -274,6 +274,42 @@ static int dvic_probe_pdata(struct platf - return 0; - } - -+static int dvic_probe_of(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ struct device_node *adapter_node; -+ struct i2c_adapter *adapter; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ adapter_node = of_parse_phandle(node, "i2c-bus", 0); -+ if (adapter_node) { -+ adapter = of_find_i2c_adapter_by_node(adapter_node); -+ if (adapter == NULL) { -+ dev_err(&pdev->dev, "failed to parse i2c-bus\n"); -+ return -EPROBE_DEFER; -+ } -+ -+ ddata->i2c_adapter = adapter; -+ } -+ -+ return 0; -+} -+ - static int dvic_probe(struct platform_device *pdev) - { - struct panel_drv_data *ddata; -@@ -290,6 +326,10 @@ static int dvic_probe(struct platform_de - r = dvic_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ r = dvic_probe_of(pdev); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -335,12 +375,20 @@ static int __exit dvic_remove(struct pla - return 0; - } - -+static const struct of_device_id dvic_of_match[] = { -+ { .compatible = "ti,dvi_connector", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, dvic_of_match); -+ - static struct platform_driver dvi_connector_driver = { - .probe = dvic_probe, - .remove = __exit_p(dvic_remove), - .driver = { - .name = "connector-dvi", - .owner = THIS_MODULE, -+ .of_match_table = dvic_of_match, - }, - }; - ---- a/drivers/video/omap2/displays-new/connector-hdmi.c -+++ b/drivers/video/omap2/displays-new/connector-hdmi.c -@@ -12,6 +12,7 @@ - #include <linux/slab.h> - #include <linux/module.h> - #include <linux/platform_device.h> -+#include <linux/of.h> - - #include <drm/drm_edid.h> - -@@ -301,6 +302,29 @@ static int hdmic_probe_pdata(struct plat - return 0; - } - -+static int hdmic_probe_of(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ return 0; -+} -+ - static int hdmic_probe(struct platform_device *pdev) - { - struct panel_drv_data *ddata; -@@ -318,6 +342,10 @@ static int hdmic_probe(struct platform_d - r = hdmic_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ r = hdmic_probe_of(pdev); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -359,12 +387,20 @@ static int __exit hdmic_remove(struct pl - return 0; - } - -+static const struct of_device_id hdmic_of_match[] = { -+ { .compatible = "ti,hdmi_connector", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, hdmic_of_match); -+ - static struct platform_driver hdmi_connector_driver = { - .probe = hdmic_probe, - .remove = __exit_p(hdmic_remove), - .driver = { - .name = "connector-hdmi", - .owner = THIS_MODULE, -+ .of_match_table = hdmic_of_match, - }, - }; - ---- /dev/null -+++ b/drivers/video/omap2/displays-new/dra-evm-encoder-tpd12s015.c -@@ -0,0 +1,556 @@ -+/* -+ * TPD12S015 HDMI ESD protection & level shifter chip driver -+ * -+ * Copyright (C) 2013 Texas Instruments -+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ */ -+ -+#include <linux/delay.h> -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/gpio.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <linux/of_gpio.h> -+ -+#include <video/omapdss.h> -+#include <video/omap-panel-data.h> -+ -+#define CLK_BASE 0x4a009000 -+#define MCASP2_BASE 0x48464000 -+#define CTRL_BASE 0x4a003400 -+#define PINMUX_BASE 0x4a003600 -+ -+#define CM_L4PER2_MCASP2_CLKCTRL 0x860 -+#define CM_L4PER2_CLKSTCTRL 0x8fc -+#define MCASP_PFUNC 0x10 -+#define MCASP_PDIR 0x14 -+#define MCASP_PDOUT 0x18 -+#define PAD_I2C2_SDA 0x408 -+#define PAD_I2C2_SCL 0x40c -+ -+#define SEL_I2C2 0 -+#define SEL_HDMI 1 -+ -+struct panel_drv_data { -+ struct omap_dss_device dssdev; -+ struct omap_dss_device *in; -+ -+ int ct_cp_hpd_gpio; -+ int ls_oe_gpio; -+ int hpd_gpio; -+ -+ struct omap_video_timings timings; -+}; -+ -+static void config_sel_hdmi_i2c2(struct device *dev) -+{ -+ void __iomem *clk_base = ioremap(CLK_BASE, SZ_4K); -+ void __iomem *mcasp2_base = ioremap(MCASP2_BASE, SZ_1K); -+ void __iomem *pmux_base = ioremap(PINMUX_BASE, SZ_1K); -+ -+ if (!clk_base) { -+ dev_err(dev, "couldn't ioremap clock domain regs\n"); -+ return; -+ } -+ -+ if (!mcasp2_base) { -+ dev_err(dev, "couldn't ioremap MCASP2 regs\n"); -+ goto mcasp_err; -+ } -+ -+ if (!pmux_base) { -+ dev_err(dev, "couldn't ioremap PMUX regs\n"); -+ goto pmux_err; -+ } -+ -+ iowrite32(0x40000, pmux_base + 0xfc); -+ -+ /* set CM_L4PER2_CLKSTCTRL to sw supervised wkup */ -+ iowrite32(0x2, clk_base + CM_L4PER2_CLKSTCTRL); -+ -+ /* -+ * Enable the MCASP8_AUX_GFCLK[22:23]: 0x0 - use default -+ * CM_L4PER2_MCASP8_CLKCTRL[1:0]: 0x2 - Enable explicitly -+ */ -+ iowrite32(0x2, clk_base + CM_L4PER2_MCASP2_CLKCTRL); -+ -+ dev_dbg(dev, "CM_L4PER2_CLKSTCTRL %08x\n", -+ ioread32(clk_base + CM_L4PER2_CLKSTCTRL)); -+ -+ /* let it propogate */ -+ -+ udelay(5); -+ /* -+ * make mcasp8_axr2 a gpio and set direction to high -+ */ -+ iowrite32(1 << 29, mcasp2_base + MCASP_PFUNC); -+ iowrite32(1 << 29, mcasp2_base + MCASP_PDIR); -+ -+ iounmap(pmux_base); -+pmux_err: -+ iounmap(mcasp2_base); -+mcasp_err: -+ iounmap(clk_base); -+} -+ -+/* -+ * use I2C2 to configure pcf8575@26 to set/unset LS_OE and CT_HPD, use HDMI to -+ * read edid via the HDMI ddc lines, and recieve HPD events -+ */ -+void config_demux(struct device *dev, int sel) -+{ -+ void __iomem *mcasp2_base = ioremap(MCASP2_BASE, SZ_1K); -+ void __iomem *ctrl_base = ioremap(CTRL_BASE, SZ_1K); -+ -+ if (!mcasp2_base) { -+ dev_err(dev, "couldn't ioremap MCASP8 regs\n"); -+ return; -+ } -+ -+ if (!ctrl_base) { -+ dev_err(dev, "couldn't ioremap CTRL base\n"); -+ goto err_ctrl; -+ } -+ -+ /* -+ * switch to I2C2 or HDMI DDC internal pinmux and drive MCASP8_PDOUT -+ * to low or high to select I2C2 or HDMI path respectively -+ */ -+ if (sel == SEL_I2C2) { -+ iowrite32(0x0, mcasp2_base + MCASP_PDOUT); -+ iowrite32(0x60000, ctrl_base + PAD_I2C2_SDA); -+ iowrite32(0x60000, ctrl_base + PAD_I2C2_SCL); -+ } else { -+ iowrite32(1 << 29, mcasp2_base + MCASP_PDOUT); -+ iowrite32(0x60001, ctrl_base + PAD_I2C2_SDA); -+ iowrite32(0x60001, ctrl_base + PAD_I2C2_SCL); -+ } -+ -+ /* let it propogate */ -+ udelay(5); -+ -+ dev_dbg(dev, "select %d, PDOUT %08x\n", sel, -+ ioread32(mcasp2_base + MCASP_PDOUT)); -+ -+ iounmap(ctrl_base); -+err_ctrl: -+ iounmap(mcasp2_base); -+} -+ -+#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) -+ -+static int tpd_connect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ bool hpd; -+ int r; -+ -+ r = in->ops.hdmi->connect(in, dssdev); -+ if (r) -+ return r; -+ -+ dst->src = dssdev; -+ dssdev->dst = dst; -+ -+ config_demux(dssdev->dev, SEL_I2C2); -+ -+ gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1); -+ -+ config_demux(dssdev->dev, SEL_HDMI); -+ -+ /* DC-DC converter needs at max 300us to get to 90% of 5V */ -+ udelay(300); -+ -+ /* -+ * If there's a cable connected, hpd will be up, turn the level shifters -+ * accordingly -+ */ -+ hpd = gpio_get_value_cansleep(ddata->hpd_gpio); -+ -+ config_demux(dssdev->dev, SEL_I2C2); -+ -+ if (gpio_is_valid(ddata->ls_oe_gpio)) { -+ if (hpd) -+ gpio_set_value_cansleep(ddata->ls_oe_gpio, 1); -+ else -+ gpio_set_value_cansleep(ddata->ls_oe_gpio, 0); -+ } -+ -+ config_demux(dssdev->dev, SEL_HDMI); -+ -+ return 0; -+} -+ -+static void tpd_disconnect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ WARN_ON(dst != dssdev->dst); -+ -+ if (dst != dssdev->dst) -+ return; -+ -+ config_demux(dssdev->dev, SEL_I2C2); -+ -+ gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); -+ -+ config_demux(dssdev->dev, SEL_HDMI); -+ -+ dst->src = NULL; -+ dssdev->dst = NULL; -+ -+ in->ops.hdmi->disconnect(in, &ddata->dssdev); -+} -+ -+static int tpd_enable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int r; -+ -+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) -+ return 0; -+ -+ in->ops.hdmi->set_timings(in, &ddata->timings); -+ -+ r = in->ops.hdmi->enable(in); -+ if (r) -+ return r; -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ -+ return r; -+} -+ -+static void tpd_disable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) -+ return; -+ -+ in->ops.hdmi->disable(in); -+ -+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -+} -+ -+static void tpd_set_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ ddata->timings = *timings; -+ dssdev->panel.timings = *timings; -+ -+ in->ops.hdmi->set_timings(in, timings); -+} -+ -+static void tpd_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ -+ *timings = ddata->timings; -+} -+ -+static int tpd_check_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int r; -+ -+ r = in->ops.hdmi->check_timings(in, timings); -+ -+ return r; -+} -+ -+static int tpd_read_edid(struct omap_dss_device *dssdev, -+ u8 *edid, int len) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ if (!gpio_get_value_cansleep(ddata->hpd_gpio)) -+ return -ENODEV; -+ -+ return in->ops.hdmi->read_edid(in, edid, len); -+} -+ -+static bool tpd_detect(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ -+ return gpio_get_value_cansleep(ddata->hpd_gpio); -+} -+ -+static int tpd_audio_enable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ return in->ops.hdmi->audio_enable(in); -+} -+ -+static void tpd_audio_disable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ in->ops.hdmi->audio_disable(in); -+} -+ -+static int tpd_audio_start(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ return in->ops.hdmi->audio_start(in); -+} -+ -+static void tpd_audio_stop(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ in->ops.hdmi->audio_stop(in); -+} -+ -+static bool tpd_audio_supported(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ return in->ops.hdmi->audio_supported(in); -+} -+ -+static int tpd_audio_config(struct omap_dss_device *dssdev, -+ struct omap_dss_audio *audio) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ return in->ops.hdmi->audio_config(in, audio); -+} -+ -+static const struct omapdss_hdmi_ops tpd_hdmi_ops = { -+ .connect = tpd_connect, -+ .disconnect = tpd_disconnect, -+ -+ .enable = tpd_enable, -+ .disable = tpd_disable, -+ -+ .check_timings = tpd_check_timings, -+ .set_timings = tpd_set_timings, -+ .get_timings = tpd_get_timings, -+ -+ .read_edid = tpd_read_edid, -+ .detect = tpd_detect, -+ -+ .audio_enable = tpd_audio_enable, -+ .audio_disable = tpd_audio_disable, -+ .audio_start = tpd_audio_start, -+ .audio_stop = tpd_audio_stop, -+ .audio_supported = tpd_audio_supported, -+ .audio_config = tpd_audio_config, -+}; -+ -+static int tpd_probe_pdata(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct encoder_tpd12s015_platform_data *pdata; -+ struct omap_dss_device *dssdev, *in; -+ -+ pdata = dev_get_platdata(&pdev->dev); -+ -+ ddata->ct_cp_hpd_gpio = pdata->ct_cp_hpd_gpio; -+ ddata->ls_oe_gpio = pdata->ls_oe_gpio; -+ ddata->hpd_gpio = pdata->hpd_gpio; -+ -+ in = omap_dss_find_output(pdata->source); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "Failed to find video source\n"); -+ return -ENODEV; -+ } -+ -+ ddata->in = in; -+ -+ dssdev = &ddata->dssdev; -+ dssdev->name = pdata->name; -+ -+ return 0; -+} -+ -+static int tpd_probe_of(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ int gpio; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ /* CT CP HPD GPIO */ -+ gpio = of_get_gpio(node, 0); -+ if (!gpio_is_valid(gpio)) { -+ dev_err(&pdev->dev, "failed to parse CT CP HPD gpio\n"); -+ return gpio; -+ } -+ ddata->ct_cp_hpd_gpio = gpio; -+ -+ /* LS OE GPIO */ -+ gpio = of_get_gpio(node, 1); -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->ls_oe_gpio = gpio; -+ } else { -+ dev_err(&pdev->dev, "failed to parse LS OE gpio\n"); -+ return gpio; -+ } -+ -+ /* HPD GPIO */ -+ gpio = of_get_gpio(node, 2); -+ if (!gpio_is_valid(gpio)) { -+ dev_err(&pdev->dev, "failed to parse HPD gpio\n"); -+ return gpio; -+ } -+ ddata->hpd_gpio = gpio; -+ -+ return 0; -+} -+ -+static int tpd_probe(struct platform_device *pdev) -+{ -+ struct omap_dss_device *in, *dssdev; -+ struct panel_drv_data *ddata; -+ int r; -+ -+ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); -+ if (!ddata) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, ddata); -+ -+ if (dev_get_platdata(&pdev->dev)) { -+ r = tpd_probe_pdata(pdev); -+ if (r) -+ return r; -+ } else if (pdev->dev.of_node) { -+ r = tpd_probe_of(pdev); -+ if (r) -+ return r; -+ } else { -+ return -ENODEV; -+ } -+ -+ /* configure the SEL_HDMI_I2C2 line going to the demux */ -+ config_sel_hdmi_i2c2(&pdev->dev); -+ -+ config_demux(&pdev->dev, SEL_I2C2); -+ -+ r = devm_gpio_request_one(&pdev->dev, ddata->ct_cp_hpd_gpio, -+ GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd"); -+ if (r) -+ goto err_gpio; -+ -+ if (gpio_is_valid(ddata->ls_oe_gpio)) { -+ r = devm_gpio_request_one(&pdev->dev, ddata->ls_oe_gpio, -+ GPIOF_OUT_INIT_LOW, "hdmi_ls_oe"); -+ if (r) -+ goto err_gpio; -+ } -+ -+ r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio, -+ GPIOF_DIR_IN, "hdmi_hpd"); -+ if (r) -+ goto err_gpio; -+ -+ config_demux(&pdev->dev, SEL_HDMI); -+ -+ dssdev = &ddata->dssdev; -+ dssdev->ops.hdmi = &tpd_hdmi_ops; -+ dssdev->dev = &pdev->dev; -+ dssdev->type = OMAP_DISPLAY_TYPE_HDMI; -+ dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; -+ dssdev->owner = THIS_MODULE; -+ -+ in = ddata->in; -+ -+ r = omapdss_register_output(dssdev); -+ if (r) { -+ dev_err(&pdev->dev, "Failed to register output\n"); -+ goto err_reg; -+ } -+ -+ return 0; -+err_reg: -+err_gpio: -+ omap_dss_put_device(ddata->in); -+ return r; -+} -+ -+static int __exit tpd_remove(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct omap_dss_device *dssdev = &ddata->dssdev; -+ struct omap_dss_device *in = ddata->in; -+ -+ omapdss_unregister_output(&ddata->dssdev); -+ -+ WARN_ON(omapdss_device_is_enabled(dssdev)); -+ if (omapdss_device_is_enabled(dssdev)) -+ tpd_disable(dssdev); -+ -+ WARN_ON(omapdss_device_is_connected(dssdev)); -+ if (omapdss_device_is_connected(dssdev)) -+ tpd_disconnect(dssdev, dssdev->dst); -+ -+ omap_dss_put_device(in); -+ -+ return 0; -+} -+ -+static const struct of_device_id tpd_of_match[] = { -+ { .compatible = "ti,draevm-tpd12s015", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, tpd_of_match); -+ -+static struct platform_driver tpd_driver = { -+ .probe = tpd_probe, -+ .remove = __exit_p(tpd_remove), -+ .driver = { -+ .name = "draevm-tpd12s015", -+ .owner = THIS_MODULE, -+ .of_match_table = tpd_of_match, -+ }, -+}; -+ -+module_platform_driver(tpd_driver); -+ -+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); -+MODULE_DESCRIPTION("DRAEVM-TPD12S015 driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/video/omap2/displays-new/encoder-sil9022.c -@@ -0,0 +1,880 @@ -+/* -+ * Silicon image Sil9022 DPI-to-HDMI encoder driver -+ * -+ * Copyright (C) 2013 Texas Instruments -+ * Author: Sathya Prakash M R <sathyap@ti.com> -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/errno.h> -+#include <linux/string.h> -+#include <linux/types.h> -+#include <linux/slab.h> -+#include <linux/io.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/i2c.h> -+#include <linux/device.h> -+#include <linux/delay.h> -+#include <linux/gpio.h> -+#include <linux/platform_device.h> -+#include <linux/regmap.h> -+#include <linux/of_gpio.h> -+ -+#include <video/omapdss.h> -+#include <video/omap-panel-data.h> -+#include "encoder-sil9022.h" -+ -+struct panel_drv_data { -+ struct omap_dss_device dssdev; -+ struct omap_dss_device *in; -+ struct i2c_client *i2c_client; -+ int reset_gpio; -+ int data_lines; -+ struct regmap *regmap; -+ struct omap_video_timings timings; -+}; -+ -+#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) -+ -+static int sil9022_blockwrite_reg(struct i2c_client *client, -+ u8 reg, u16 alength, u8 *val, u16 *out_len) -+{ -+ int err = 0, i; -+ struct i2c_msg msg[1]; -+ u8 data[2]; -+ -+ if (!client->adapter) { -+ dev_err(&client->dev, "ERROR: No HDMI Device\n"); -+ return -ENODEV; -+ } -+ -+ msg->addr = client->addr; -+ msg->flags = 0; -+ msg->len = 2; -+ msg->buf = data; -+ -+ /* high byte goes out first */ -+ data[0] = reg >> 8; -+ -+ for (i = 0; i < alength - 1; i++) { -+ data[1] = val[i]; -+ err = i2c_transfer(client->adapter, msg, 1); -+ udelay(50); -+ dev_dbg(&client->dev, "i2c Block write at 0x%x, " -+ "*val=%d flags=%d byte[%d] err=%d\n", -+ data[0], data[1], msg->flags, i, err); -+ if (err < 0) -+ break; -+ } -+ /* set the number of bytes written*/ -+ *out_len = i; -+ -+ if (err < 0) { -+ dev_err(&client->dev, "ERROR: i2c Block Write at 0x%x, " -+ "*val=%d flags=%d bytes written=%d " -+ "err=%d\n", -+ data[0], data[1], msg->flags, i, err); -+ return err; -+ } -+ return 0; -+} -+ -+static int sil9022_blockread_reg(struct i2c_client *client, -+ u16 data_length, u16 alength, -+ u8 reg, u8 *val, u16 *out_len) -+{ -+ int err = 0, i; -+ struct i2c_msg msg[1]; -+ u8 data[2]; -+ -+ if (!client->adapter) { -+ dev_err(&client->dev, "ERROR: No HDMI Device\n"); -+ return -ENODEV; -+ } -+ -+ msg->addr = client->addr; -+ msg->flags = 0; -+ msg->len = 1; -+ msg->buf = data; -+ -+ /* High byte goes out first */ -+ data[0] = reg; -+ err = i2c_transfer(client->adapter, msg, 1); -+ dev_dbg(&client->dev, "Block Read1 at 0x%x, " -+ "*val=%d flags=%d err=%d\n", -+ data[0], data[1], msg->flags, err); -+ -+ for (i = 0; i < alength; i++) { -+ if (err >= 0) { -+ mdelay(3); -+ msg->flags = I2C_M_RD; -+ msg->len = data_length; -+ err = i2c_transfer(client->adapter, msg, 1); -+ } else { -+ break; -+ } -+ if (err >= 0) { -+ val[i] = 0; -+ /* High byte comes first */ -+ if (data_length == 1) -+ val[i] = data[0]; -+ else if (data_length == 2) -+ val[i] = data[1] + (data[0] << 8); -+ dev_dbg(&client->dev, "i2c Block Read2 at 0x%x, " -+ "*val=%d flags=%d byte=%d " -+ "err=%d\n", -+ reg, val[i], msg->flags, i, err); -+ } else { -+ break; -+ } -+ } -+ *out_len = i; -+ dev_dbg(&client->dev, "i2c Block Read at 0x%x, bytes read = %d\n", -+ client->addr, *out_len); -+ -+ if (err < 0) { -+ dev_err(&client->dev, "ERROR: i2c Read at 0x%x, " -+ "*val=%d flags=%d bytes read=%d err=%d\n", -+ reg, *val, msg->flags, i, err); -+ return err; -+ } -+ return 0; -+} -+ -+static int sil9022_write_reg(struct omap_dss_device *dssdev, -+ u8 reg, unsigned int val) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct regmap *map = ddata->regmap; -+ int err = 0; -+ err = regmap_write(map, reg, val); -+ return err; -+} -+ -+static int sil9022_read_reg(struct omap_dss_device *dssdev, -+ u8 reg, unsigned int *val) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct regmap *map = ddata->regmap; -+ int err = 0; -+ err = regmap_read(map, reg, val); -+ return err; -+} -+ -+static int sil9022_hw_enable(struct omap_dss_device *dssdev) -+{ -+ int err; -+ u8 vals[14]; -+ unsigned int val; -+ u16 out_len = 0; -+ u16 horizontal_res; -+ u16 vertical_res; -+ u16 pixel_clk; -+ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_video_timings *hdmi_timings = &ddata->timings; -+ struct i2c_client *sil9022_client = ddata->i2c_client; -+ -+ memset(vals, 0, 14); -+ -+ horizontal_res = hdmi_timings->x_res; -+ vertical_res = hdmi_timings->y_res; -+ pixel_clk = hdmi_timings->pixel_clock; -+ -+ dev_info(dssdev->dev, -+ "HW_ENABLE -> Timings\n" -+ "pixel_clk = %d\n" -+ "horizontal res = %d\n" -+ "vertical res = %d\n", -+ hdmi_timings->pixel_clock, -+ hdmi_timings->x_res, -+ hdmi_timings->y_res -+ ); -+ -+ /* Fill the TPI Video Mode Data structure */ -+ vals[0] = (pixel_clk & 0xFF); /* Pixel clock */ -+ vals[1] = ((pixel_clk & 0xFF00) >> 8); -+ vals[2] = VERTICAL_FREQ; /* Vertical freq */ -+ /* register programming information on how vertical freq is to be -+ programmed to Sil9022 not clear. Hence setting to 60 for now */ -+ vals[3] = 0x00; -+ vals[4] = (horizontal_res & 0xFF); /* Horizontal pixels*/ -+ vals[5] = ((horizontal_res & 0xFF00) >> 8); -+ vals[6] = (vertical_res & 0xFF); /* Vertical pixels */ -+ vals[7] = ((vertical_res & 0xFF00) >> 8); -+ -+ /* Write out the TPI Video Mode Data */ -+ out_len = 0; -+ err = sil9022_blockwrite_reg(sil9022_client, -+ HDMI_TPI_VIDEO_DATA_BASE_REG, -+ 8, vals, &out_len); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: writing TPI video mode data\n"); -+ return err; -+ } -+ -+ /* Write out the TPI Input bus and pixel repetition Data: -+ (24 bit wide bus, falling edge, no pixel replication, 1:1 CLK ration) */ -+ val = TPI_AVI_PIXEL_REP_BUS_24BIT | -+ TPI_AVI_PIXEL_REP_FALLING_EDGE | -+ TPI_AVI_PIXEL_REP_NONE | TPI_CLK_RATIO_1X; -+ err = sil9022_write_reg(dssdev, -+ HDMI_TPI_PIXEL_REPETITION_REG, -+ val); -+ -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: writing TPI pixel repetition data\n"); -+ return err; -+ } -+ -+ /* Write out the TPI AVI Input Format */ -+ val = TPI_AVI_INPUT_BITMODE_8BIT | -+ TPI_AVI_INPUT_RANGE_AUTO | -+ TPI_AVI_INPUT_COLORSPACE_RGB; -+ err = sil9022_write_reg(dssdev, -+ HDMI_TPI_AVI_IN_FORMAT_REG, -+ val); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: writing TPI AVI Input format\n"); -+ return err; -+ } -+ -+ /* Write out the TPI AVI Output Format */ -+ val = TPI_AVI_OUTPUT_CONV_BT709 | -+ TPI_AVI_OUTPUT_RANGE_AUTO | -+ TPI_AVI_OUTPUT_COLORSPACE_RGBHDMI; -+ err = sil9022_write_reg(dssdev, -+ HDMI_TPI_AVI_OUT_FORMAT_REG, val); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: writing TPI AVI output format\n"); -+ return err; -+ } -+ -+ /* Write out the TPI System Control Data to power down */ -+ val = TPI_SYS_CTRL_POWER_DOWN; -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: writing TPI power down control data\n"); -+ return err; -+ } -+ -+ /* Move from ENABLED -> FULLY ENABLED Power State */ -+ val = TPI_AVI_POWER_STATE_D0; -+ err = sil9022_write_reg(dssdev, -+ HDMI_TPI_POWER_STATE_CTRL_REG, val); -+ if (err < 0) { -+ dev_err(&sil9022_client->dev, -+ "<%s> ERROR: Setting device power state to D0\n", -+ __func__); -+ return err; -+ } -+ -+ /* Write out the TPI System Control Data to power up and -+ * select output mode -+ */ -+ val = TPI_SYS_CTRL_POWER_ACTIVE | TPI_SYS_CTRL_OUTPUT_MODE_HDMI; -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err < 0) { -+ dev_err(&sil9022_client->dev, -+ "<%s> ERROR: Writing system control data\n", __func__); -+ return err; -+ } -+ -+ /* Read back TPI System Control Data to latch settings */ -+ msleep(20); -+ err = sil9022_read_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, &val); -+ if (err < 0) { -+ dev_err(&sil9022_client->dev, -+ "<%s> ERROR: Writing system control data\n", -+ __func__); -+ return err; -+ } -+ -+ /* HDCP */ -+ val = 0; /* DISABLED */ -+ err = sil9022_write_reg(dssdev, -+ HDMI_TPI_HDCP_CONTROLDATA_REG, val); -+ if (err < 0) { -+ dev_err(&sil9022_client->dev, -+ "<%s> ERROR: Enable (1) / Disable (0) => HDCP: %d\n", -+ __func__, val); -+ return err; -+ } -+ -+ dev_info(&sil9022_client->dev, "<%s> hdmi enabled\n", __func__); -+ return 0; -+ -+} -+ -+static int sil9022_hw_disable(struct omap_dss_device *dssdev) -+{ -+ unsigned int val = 0; -+ int err = 0; -+ -+ /* Write out the TPI System Control Data to power down */ -+ val = TPI_SYS_CTRL_POWER_DOWN; -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: writing control data - power down\n"); -+ return err; -+ } -+ -+ /* Move from FULLY ENABLED -> ENABLED Power state */ -+ val = TPI_AVI_POWER_STATE_D2; -+ err = sil9022_write_reg(dssdev, -+ HDMI_TPI_DEVICE_POWER_STATE_DATA, val); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: Setting device power state to D2\n"); -+ return err; -+ } -+ -+ /* Read back TPI System Control Data to latch settings */ -+ mdelay(10); -+ err = sil9022_read_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, &val); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: Reading System control data " -+ "- latch settings\n"); -+ return err; -+ } -+ -+ dev_info(dssdev->dev, "hdmi disabled\n"); -+ return 0; -+ -+} -+ -+static int sil9022_probe_chip_version(struct omap_dss_device *dssdev) -+{ -+ int err = 0; -+ unsigned int ver; -+ -+ /* probe for sil9022 chip version*/ -+ err = sil9022_write_reg(dssdev, SIL9022_REG_TPI_RQB, 0x00); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: Writing HDMI configuration to " -+ "reg - SI9022_REG_TPI_RQB\n"); -+ err = -ENODEV; -+ return err; -+ } -+ -+ err = sil9022_read_reg(dssdev, SIL9022_REG_CHIPID0, &ver); -+ if (err < 0) { -+ dev_err(dssdev->dev, -+ "ERROR: Reading HDMI version Id\n"); -+ err = -ENODEV; -+ } else if (ver != SIL9022_CHIPID_902x) { -+ dev_err(dssdev->dev, -+ "Not a valid verId: 0x%x\n", ver); -+ err = -ENODEV; -+ } else { -+ dev_info(dssdev->dev, -+ "sil9022 HDMI Chip version = %x\n", ver); -+ } -+ return err; -+} -+ -+/* Hdmi ops */ -+ -+static int sil9022_connect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int err; -+ -+ dev_err(dssdev->dev, "CONNECT\n"); -+ -+ if (omapdss_device_is_connected(dssdev)) -+ return -EBUSY; -+ -+ err = in->ops.dpi->connect(in, dssdev); -+ if (err) -+ return err; -+ -+ dst->src = dssdev; -+ dssdev->dst = dst; -+ -+ /* Move from LOW -> ENABLED Power state */ -+ err = sil9022_write_reg(dssdev, HDMI_TPI_POWER_STATE_CTRL_REG, -+ TPI_AVI_POWER_STATE_D2); -+ if (err < 0) { -+ dev_err(dssdev->dev, "ERROR: Setting device power state to D2\n"); -+ return err; -+ } -+ -+ return 0; -+ -+} -+ -+static void sil9022_disconnect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int err; -+ -+ WARN_ON(!omapdss_device_is_connected(dssdev)); -+ if (!omapdss_device_is_connected(dssdev)) -+ return; -+ -+ WARN_ON(dst != dssdev->dst); -+ if (dst != dssdev->dst) -+ return; -+ -+ dst->src = NULL; -+ dssdev->dst = NULL; -+ -+ /* Move from ENABLED -> LOW Power state */ -+ err = sil9022_write_reg(dssdev, HDMI_TPI_POWER_STATE_CTRL_REG, -+ TPI_AVI_POWER_STATE_D3); -+ if (err < 0) { -+ dev_err(dssdev->dev, "ERROR: Setting device power state to D3\n"); -+ } -+ -+ in->ops.dpi->disconnect(in, &ddata->dssdev); -+ return; -+ -+} -+ -+static int sil9022_enable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int r; -+ -+ dev_err(dssdev->dev, "ENABLE\n"); -+ -+ if (!omapdss_device_is_connected(dssdev)) -+ return -ENODEV; -+ -+ if (omapdss_device_is_enabled(dssdev)) -+ return 0; -+ -+ in->ops.dpi->set_timings(in, &ddata->timings); -+ in->ops.dpi->set_data_lines(in, ddata->data_lines); -+ -+ r = in->ops.dpi->enable(in); -+ if (r) -+ return r; -+ -+ if (gpio_is_valid(ddata->reset_gpio)) -+ gpio_set_value_cansleep(ddata->reset_gpio, 0); -+ -+ r = sil9022_hw_enable(dssdev); -+ if (r) -+ return r; -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ return 0; -+} -+ -+static void sil9022_disable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ if (!omapdss_device_is_enabled(dssdev)) -+ return; -+ -+ if (!sil9022_hw_disable(dssdev)) -+ return; -+ -+ if (gpio_is_valid(ddata->reset_gpio)) -+ gpio_set_value_cansleep(ddata->reset_gpio, 1); -+ -+ in->ops.dpi->disable(in); -+ -+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -+ return; -+} -+ -+static void sil9022_set_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ struct omap_video_timings *sil9022_timings = timings; -+ -+ /* update DPI specific timing info */ -+ sil9022_timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; -+ sil9022_timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; -+ sil9022_timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; -+ ddata->timings = *sil9022_timings; -+ dssdev->panel.timings = *sil9022_timings; -+ -+ in->ops.dpi->set_timings(in, sil9022_timings); -+ return; -+} -+ -+static void sil9022_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ *timings = ddata->timings; -+ return; -+} -+ -+static int sil9022_check_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ struct omap_video_timings *sil9022_timings = timings; -+ -+ /* update DPI specific timing info */ -+ sil9022_timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; -+ sil9022_timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; -+ sil9022_timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; -+ -+ return in->ops.dpi->check_timings(in, sil9022_timings); -+} -+ -+static int sil9022_read_edid(struct omap_dss_device *dssdev, -+ u8 *edid, int len) -+{ -+ -+ int err = 0; -+ unsigned int val = 0; -+ int retries = 0; -+ u16 out_len = 0; -+ int i2c_client_addr; -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct i2c_client *client = ddata->i2c_client; -+ -+ len = (len < HDMI_EDID_MAX_LENGTH) ? len : HDMI_EDID_MAX_LENGTH; -+ -+ /* Request DDC bus access to read EDID info from HDTV */ -+ dev_info(&client->dev, "Reading HDMI EDID\n"); -+ -+ val = 0; -+ err = sil9022_read_reg(dssdev, 0x3D, &val); -+ if (err < 0) { -+ dev_err(&client->dev, -+ "ERROR: Reading Monitor Status register\n"); -+ return err; -+ } -+ -+ if (val & 0x2) -+ dev_err(&client->dev, " MONITOR PRESENT \n"); -+ else -+ dev_err(&client->dev, " MONITOR NOT PRESENT \n"); -+ -+ /* Disable TMDS clock */ -+ val = 0x11; -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err < 0) { -+ dev_err(&client->dev, -+ "ERROR: Failed to disable TMDS clock\n"); -+ return err; -+ } -+ -+ val = 0; -+ -+ /* Read TPI system control register*/ -+ err = sil9022_read_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, &val); -+ if (err < 0) { -+ dev_err(&client->dev, -+ "ERROR: Reading DDC BUS REQUEST\n"); -+ return err; -+ } -+ -+ /* The host writes 0x1A[2]=1 to request the -+ * DDC(Display Data Channel) bus -+ */ -+ val |= TPI_SYS_CTRL_DDC_BUS_REQUEST; -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err < 0) { -+ dev_err(&client->dev, -+ "ERROR: Writing DDC BUS REQUEST\n"); -+ return err; -+ } -+ -+ /* Poll for bus DDC Bus control to be granted */ -+ dev_info(&client->dev, "Poll for DDC bus access\n"); -+ val = 0; -+ do { -+ err = sil9022_read_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, &val); -+ if (retries++ > 100) -+ return err; -+ -+ } while ((val & TPI_SYS_CTRL_DDC_BUS_GRANTED) == 0); -+ -+ /* Close the switch to the DDC */ -+ val |= TPI_SYS_CTRL_DDC_BUS_REQUEST | TPI_SYS_CTRL_DDC_BUS_GRANTED; -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err < 0) { -+ dev_err(&client->dev, -+ "<%s> ERROR: Close switch to DDC BUS REQUEST\n", -+ __func__); -+ return err; -+ } -+ -+ memset(edid, 0, len); -+ /* change I2C SetSlaveAddress to HDMI_I2C_MONITOR_ADDRESS */ -+ /* Read the EDID structure from the monitor I2C address */ -+ i2c_client_addr = client->addr; -+ client->addr = HDMI_I2C_MONITOR_ADDRESS; -+ err = sil9022_blockread_reg(client, 1, len, -+ 0x00, edid, &out_len); -+ if (err < 0 || out_len <= 0) { -+ dev_err(&client->dev, "ERROR: Reading EDID\n"); -+ return err; -+ } -+ -+ /* Release DDC bus access */ -+ client->addr = i2c_client_addr; -+ val &= ~(TPI_SYS_CTRL_DDC_BUS_REQUEST | TPI_SYS_CTRL_DDC_BUS_GRANTED); -+ -+ retries = 0; -+ do { -+ err = sil9022_write_reg(dssdev, HDMI_SYS_CTRL_DATA_REG, val); -+ if (err >= 0) -+ break; -+ retries++; -+ } while (retries < 5); -+ if (err < 0) { -+ dev_err(&client->dev, "ERROR: Releasing DDC Bus Access\n"); -+ return err; -+ } -+ -+ print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_NONE, 16, 1, edid, len, 0); -+ -+ return 0; -+ -+} -+ -+static bool sil9022_detect(struct omap_dss_device *dssdev) -+{ -+ /* Hot plug detection is not implemented */ -+ /* Hence we assume monitor connected */ -+ /* This will be fixed once HPD / polling is implemented */ -+ return true; -+} -+ -+static bool sil9022_audio_supported(struct omap_dss_device *dssdev) -+{ -+ /* Audio configuration not present, hence returning false */ -+ return false; -+} -+ -+static const struct omapdss_hdmi_ops sil9022_hdmi_ops = { -+ .connect = sil9022_connect, -+ .disconnect = sil9022_disconnect, -+ -+ .enable = sil9022_enable, -+ .disable = sil9022_disable, -+ -+ .check_timings = sil9022_check_timings, -+ .set_timings = sil9022_set_timings, -+ .get_timings = sil9022_get_timings, -+ -+ .read_edid = sil9022_read_edid, -+ .detect = sil9022_detect, -+ -+ .audio_supported = sil9022_audio_supported, -+ /* Yet to implement audio ops */ -+ /* For now audio_supported ops to return false */ -+}; -+ -+ -+static int sil9022_probe_of(struct i2c_client *client) -+{ -+ struct panel_drv_data *ddata = dev_get_drvdata(&client->dev); -+ struct device_node *node = client->dev.of_node; -+ struct device_node *src_node; -+ struct omap_dss_device *dssdev, *in; -+ -+ int r, reset_gpio, datalines; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&client->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&client->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ reset_gpio = of_get_named_gpio(node, "reset-gpio", 0); -+ -+ if (gpio_is_valid(reset_gpio) || reset_gpio == -ENOENT) { -+ ddata->reset_gpio = reset_gpio; -+ } else { -+ dev_err(&client->dev, "failed to parse lcdorhdmi gpio\n"); -+ return reset_gpio; -+ } -+ -+ r = of_property_read_u32(node, "data-lines", &datalines); -+ if (r) { -+ dev_err(&client->dev, "failed to parse datalines\n"); -+ return r; -+ } -+ -+ ddata->data_lines = datalines; -+ ddata->reset_gpio = reset_gpio; -+ dssdev = &ddata->dssdev; -+ -+ return 0; -+ -+} -+static int sil9022_probe_pdata(struct i2c_client *client) -+{ -+ struct encoder_sil9022_platform_data *pdata; -+ struct panel_drv_data *ddata = dev_get_drvdata(&client->dev); -+ struct omap_dss_device *dssdev, *in; -+ pdata = dev_get_platdata(&client->dev); -+ -+ ddata->reset_gpio = pdata->reset_gpio; -+ ddata->data_lines = pdata->data_lines; -+ -+ in = omap_dss_find_output(pdata->source); -+ if (in == NULL) { -+ dev_err(&client->dev, "Failed to find video source\n"); -+ return -ENODEV; -+ } -+ -+ ddata->in = in; -+ dssdev = &ddata->dssdev; -+ dssdev->name = pdata->name; -+ -+ return 0; -+} -+ -+static int sil9022_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct panel_drv_data *ddata; -+ struct omap_dss_device *dssdev; -+ struct regmap *regmap; -+ int err = 0; -+ -+ regmap = devm_regmap_init_i2c(client, &sil9022_regmap_config); -+ if (IS_ERR(regmap)) { -+ err = PTR_ERR(regmap); -+ dev_err(&client->dev, "Failed to init regmap: %d\n", err); -+ return err; -+ } -+ -+ ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL); -+ if (ddata == NULL) -+ return -ENOMEM; -+ -+ dev_set_drvdata(&client->dev, ddata); -+ -+ if (dev_get_platdata(&client->dev)) { -+ err = sil9022_probe_pdata(client); -+ if (err) -+ return err; -+ } else if (client->dev.of_node) { -+ err = sil9022_probe_of(client); -+ if (err) -+ return err; -+ } else { -+ return -ENODEV; -+ } -+ -+ if (gpio_is_valid(ddata->reset_gpio)) { -+ err = devm_gpio_request_one(&client->dev, ddata->reset_gpio, -+ GPIOF_OUT_INIT_HIGH, "Sil9022-Encoder"); -+ if (err) -+ goto err_gpio; -+ } -+ -+ ddata->regmap = regmap; -+ ddata->i2c_client = client; -+ dssdev = &ddata->dssdev; -+ dssdev->dev = &client->dev; -+ dssdev->ops.hdmi = &sil9022_hdmi_ops; -+ dssdev->type = OMAP_DISPLAY_TYPE_DPI; -+ dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; -+ dssdev->owner = THIS_MODULE; -+ dssdev->phy.dpi.data_lines = ddata->data_lines; -+ err = omapdss_register_output(dssdev); -+ if (err) { -+ dev_err(&client->dev, "Failed to register output\n"); -+ goto err_reg; -+ } -+ -+ /* Read sil9022 chip version */ -+ err = sil9022_probe_chip_version(dssdev); -+ if (err) { -+ dev_err(&client->dev, "Failed to read CHIP VERSION\n"); -+ goto err_i2c; -+ } -+ -+ return 0; -+ -+err_gpio: -+err_reg: -+err_i2c: -+ omap_dss_put_device(ddata->in); -+ return err; -+} -+ -+ -+static int sil9022_remove(struct i2c_client *client) -+{ -+ struct panel_drv_data *ddata = dev_get_drvdata(&client->dev); -+ struct omap_dss_device *dssdev = &ddata->dssdev; -+ -+ omapdss_unregister_output(&ddata->dssdev); -+ -+ WARN_ON(omapdss_device_is_enabled(dssdev)); -+ if (omapdss_device_is_enabled(dssdev)) -+ sil9022_disable(dssdev); -+ -+ WARN_ON(omapdss_device_is_connected(dssdev)); -+ if (omapdss_device_is_connected(dssdev)) -+ sil9022_disconnect(dssdev, dssdev->dst); -+ -+ omap_dss_put_device(ddata->in); -+ -+ if (!client->adapter) { -+ dev_err(&client->dev, "No HDMI Device\n"); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static const struct i2c_device_id sil9022_id[] = { -+ { SIL9022_DRV_NAME, 0 }, -+ { }, -+}; -+ -+MODULE_DEVICE_TABLE(i2c, sil9022_id); -+ -+static struct i2c_driver sil9022_driver = { -+ .driver = { -+ .name = SIL9022_DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = sil9022_probe, -+ .remove = sil9022_remove, -+ .id_table = sil9022_id, -+}; -+ -+module_i2c_driver(sil9022_driver); -+ -+MODULE_AUTHOR("Sathya Prakash M R <sathyap@ti.com>"); -+MODULE_DESCRIPTION("Sil9022 DPI to HDMI encoder Driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/video/omap2/displays-new/encoder-sil9022.h -@@ -0,0 +1,123 @@ -+/* -+ * drivers/video/omap2/displays-new/encoder-sil9022.c -+ * -+ * Copyright (C) 2013 Texas Instruments -+ * Author : Sathya Prakash M R <sathyap@ti.com> -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ * -+ */ -+ -+#ifndef _SI9022_H_ -+#define _SI9022_H_ -+ -+#define SIL9022_DRV_NAME "sii9022" -+ -+#define SIL9022_REG_CHIPID0 0x1B -+#define SIL9022_REG_TPI_RQB 0xC7 -+#define SIL9022_CHIPID_902x 0xB0 -+ -+#define HDMI_I2C_MONITOR_ADDRESS 0x50 -+ -+/* HDMI EDID Length */ -+#define HDMI_EDID_MAX_LENGTH 256 -+ -+#define VERTICAL_FREQ 0x3C -+ -+/* HDMI TPI Registers */ -+#define HDMI_TPI_VIDEO_DATA_BASE_REG 0x00 -+#define HDMI_TPI_PIXEL_CLK_LSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x00) -+#define HDMI_TPI_PIXEL_CLK_MSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x01) -+#define HDMI_TPI_VFREQ_LSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x02) -+#define HDMI_TPI_VFREQ_MSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x03) -+#define HDMI_TPI_PIXELS_LSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x04) -+#define HDMI_TPI_PIXELS_MSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x05) -+#define HDMI_TPI_LINES_LSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x06) -+#define HDMI_TPI_LINES_MSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x07) -+ -+#define HDMI_TPI_PIXEL_REPETITION_REG 0x08 -+ -+#define HDMI_TPI_AVI_INOUT_BASE_REG 0x09 -+#define HDMI_TPI_AVI_IN_FORMAT_REG (HDMI_TPI_AVI_INOUT_BASE_REG + 0x00) -+#define HDMI_TPI_AVI_OUT_FORMAT_REG (HDMI_TPI_AVI_INOUT_BASE_REG + 0x01) -+ -+#define HDMI_SYS_CTRL_DATA_REG 0x1A -+#define HDMI_TPI_POWER_STATE_CTRL_REG 0x1E -+#define HDMI_TPI_DEVICE_POWER_STATE_DATA 0x1E -+ -+ -+/* HDCP */ -+#define HDMI_TPI_HDCP_QUERYDATA_REG 0x29 -+#define HDMI_TPI_HDCP_CONTROLDATA_REG 0x2A -+ -+/* HDMI_TPI_DEVICE_ID_REG */ -+#define TPI_DEVICE_ID 0xB0 -+ -+/* HDMI_TPI_REVISION_REG */ -+#define TPI_REVISION 0x00 -+ -+/* HDMI_TPI_ID_BYTE2_REG */ -+#define TPI_ID_BYTE2_VALUE 0x00 -+ -+/* HDMI_SYS_CTRL_DATA_REG */ -+#define TPI_SYS_CTRL_POWER_DOWN (1 << 4) -+#define TPI_SYS_CTRL_POWER_ACTIVE (0 << 4) -+#define TPI_SYS_CTRL_AV_MUTE (1 << 3) -+#define TPI_SYS_CTRL_DDC_BUS_REQUEST (1 << 2) -+#define TPI_SYS_CTRL_DDC_BUS_GRANTED (1 << 1) -+#define TPI_SYS_CTRL_OUTPUT_MODE_HDMI (1 << 0) -+#define TPI_SYS_CTRL_OUTPUT_MODE_DVI (0 << 0) -+ -+/* HDMI_TPI_PIXEL_REPETITION */ -+#define TPI_AVI_PIXEL_REP_BUS_24BIT (1 << 5) -+#define TPI_AVI_PIXEL_REP_BUS_12BIT (0 << 5) -+#define TPI_AVI_PIXEL_REP_RISING_EDGE (1 << 4) -+#define TPI_AVI_PIXEL_REP_FALLING_EDGE (0 << 4) -+#define TPI_AVI_PIXEL_REP_4X (3 << 0) -+#define TPI_AVI_PIXEL_REP_2X (1 << 0) -+#define TPI_AVI_PIXEL_REP_NONE (0 << 0) -+ -+/*Ratio of TDMS Clock to input Video Clock*/ -+#define TPI_CLK_RATIO_HALF (0 << 6) -+#define TPI_CLK_RATIO_1X (1 << 6) -+#define TPI_CLK_RATIO_2X (2 << 6) -+#define TPI_CLK_RATIO_4X (3 << 6) -+ -+ -+/* HDMI_TPI_AVI_INPUT_FORMAT */ -+#define TPI_AVI_INPUT_BITMODE_12BIT (1 << 7) -+#define TPI_AVI_INPUT_BITMODE_8BIT (0 << 7) -+#define TPI_AVI_INPUT_DITHER (1 << 6) -+#define TPI_AVI_INPUT_RANGE_LIMITED (2 << 2) -+#define TPI_AVI_INPUT_RANGE_FULL (1 << 2) -+#define TPI_AVI_INPUT_RANGE_AUTO (0 << 2) -+#define TPI_AVI_INPUT_COLORSPACE_BLACK (3 << 0) -+#define TPI_AVI_INPUT_COLORSPACE_YUV422 (2 << 0) -+#define TPI_AVI_INPUT_COLORSPACE_YUV444 (1 << 0) -+#define TPI_AVI_INPUT_COLORSPACE_RGB (0 << 0) -+ -+ -+/* HDMI_TPI_AVI_OUTPUT_FORMAT */ -+#define TPI_AVI_OUTPUT_CONV_BT709 (1 << 4) -+#define TPI_AVI_OUTPUT_CONV_BT601 (0 << 4) -+#define TPI_AVI_OUTPUT_RANGE_LIMITED (2 << 2) -+#define TPI_AVI_OUTPUT_RANGE_FULL (1 << 2) -+#define TPI_AVI_OUTPUT_RANGE_AUTO (0 << 2) -+#define TPI_AVI_OUTPUT_COLORSPACE_RGBDVI (3 << 0) -+#define TPI_AVI_OUTPUT_COLORSPACE_YUV422 (2 << 0) -+#define TPI_AVI_OUTPUT_COLORSPACE_YUV444 (1 << 0) -+#define TPI_AVI_OUTPUT_COLORSPACE_RGBHDMI (0 << 0) -+ -+/* HDMI_TPI_DEVICE_POWER_STATE */ -+#define TPI_AVI_POWER_STATE_D3 (3 << 0) -+#define TPI_AVI_POWER_STATE_D2 (2 << 0) -+#define TPI_AVI_POWER_STATE_D0 (0 << 0) -+ -+struct regmap_config sil9022_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+}; -+ -+#endif ---- a/drivers/video/omap2/displays-new/encoder-tfp410.c -+++ b/drivers/video/omap2/displays-new/encoder-tfp410.c -@@ -13,6 +13,7 @@ - #include <linux/module.h> - #include <linux/platform_device.h> - #include <linux/slab.h> -+#include <linux/of_gpio.h> - - #include <video/omapdss.h> - #include <video/omap-panel-data.h> -@@ -179,6 +180,47 @@ static int tfp410_probe_pdata(struct pla - return 0; - } - -+static int tfp410_probe_of(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ int r, gpio, datalines; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ gpio = of_get_gpio(node, 0); -+ -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->pd_gpio = gpio; -+ } else { -+ dev_err(&pdev->dev, "failed to parse PD gpio\n"); -+ return gpio; -+ } -+ -+ r = of_property_read_u32(node, "data-lines", &datalines); -+ if (r) { -+ dev_err(&pdev->dev, "failed to parse datalines\n"); -+ return r; -+ } -+ -+ ddata->data_lines = datalines; -+ -+ return 0; -+} -+ - static int tfp410_probe(struct platform_device *pdev) - { - struct panel_drv_data *ddata; -@@ -195,6 +237,10 @@ static int tfp410_probe(struct platform_ - r = tfp410_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ r = tfp410_probe_of(pdev); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -251,12 +297,20 @@ static int __exit tfp410_remove(struct p - return 0; - } - -+static const struct of_device_id tfp410_of_match[] = { -+ { .compatible = "ti,tfp410", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, tfp410_of_match); -+ - static struct platform_driver tfp410_driver = { - .probe = tfp410_probe, - .remove = __exit_p(tfp410_remove), - .driver = { - .name = "tfp410", - .owner = THIS_MODULE, -+ .of_match_table = tfp410_of_match, - }, - }; - ---- a/drivers/video/omap2/displays-new/encoder-tpd12s015.c -+++ b/drivers/video/omap2/displays-new/encoder-tpd12s015.c -@@ -15,6 +15,7 @@ - #include <linux/slab.h> - #include <linux/gpio.h> - #include <linux/platform_device.h> -+#include <linux/of_gpio.h> - - #include <video/omapdss.h> - #include <video/omap-panel-data.h> -@@ -289,6 +290,55 @@ static int tpd_probe_pdata(struct platfo - return 0; - } - -+static int tpd_probe_of(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ int gpio; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ /* CT CP HPD GPIO */ -+ gpio = of_get_gpio(node, 0); -+ if (!gpio_is_valid(gpio)) { -+ dev_err(&pdev->dev, "failed to parse CT CP HPD gpio\n"); -+ return gpio; -+ } -+ ddata->ct_cp_hpd_gpio = gpio; -+ -+ /* LS OE GPIO */ -+ gpio = of_get_gpio(node, 1); -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->ls_oe_gpio = gpio; -+ } else { -+ dev_err(&pdev->dev, "failed to parse LS OE gpio\n"); -+ return gpio; -+ } -+ -+ /* HPD GPIO */ -+ gpio = of_get_gpio(node, 2); -+ if (!gpio_is_valid(gpio)) { -+ dev_err(&pdev->dev, "failed to parse HPD gpio\n"); -+ return gpio; -+ } -+ ddata->hpd_gpio = gpio; -+ -+ return 0; -+} -+ - static int tpd_probe(struct platform_device *pdev) - { - struct omap_dss_device *in, *dssdev; -@@ -307,6 +357,10 @@ static int tpd_probe(struct platform_dev - r = tpd_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ r = tpd_probe_of(pdev); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -379,12 +433,20 @@ static int __exit tpd_remove(struct plat - return 0; - } - -+static const struct of_device_id tpd_of_match[] = { -+ { .compatible = "ti,tpd12s015", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, tpd_of_match); -+ - static struct platform_driver tpd_driver = { - .probe = tpd_probe, - .remove = __exit_p(tpd_remove), - .driver = { - .name = "tpd12s015", - .owner = THIS_MODULE, -+ .of_match_table = tpd_of_match, - }, - }; - ---- a/drivers/video/omap2/displays-new/Kconfig -+++ b/drivers/video/omap2/displays-new/Kconfig -@@ -12,6 +12,20 @@ config DISPLAY_ENCODER_TPD12S015 - Driver for TPD12S015, which offers HDMI ESD protection and level - shifting. - -+config DISPLAY_DRA_EVM_ENCODER_TPD12S015 -+ tristate "TPD12S015 HDMI ESD protection and level shifter on DRA7 EVM" -+ help -+ Driver for TPD12S015, which offers HDMI ESD protection and level -+ shifting on DRA EVM. -+ -+config DISPLAY_ENCODER_SIL9022 -+ tristate "Sil9022 DPI to HDMI Encoder" -+ depends on I2C -+ help -+ Driver for Silicon Image Sil9022 DPI to HDMI encoder and -+ a brief about Sil9022 can be found here: -+ http://www.semiconductorstore.com/pdf/newsite/siliconimage/SiI9022a_pb.pdf -+ - config DISPLAY_CONNECTOR_DVI - tristate "DVI Connector" - depends on I2C -@@ -71,4 +85,11 @@ config DISPLAY_PANEL_NEC_NL8048HL11 - This NEC NL8048HL11 panel is TFT LCD used in the - Zoom2/3/3630 sdp boards. - -+config DISPLAY_PANEL_TFCS9700 -+ tristate "Three Five DPI panel" -+ depends on I2C -+ help -+ A TFT LCD DPI panel used on the LCD daughter board -+ of Vayu EVM -+ - endmenu ---- a/drivers/video/omap2/displays-new/Makefile -+++ b/drivers/video/omap2/displays-new/Makefile -@@ -1,5 +1,7 @@ - obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o - obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o -+obj-$(CONFIG_DISPLAY_DRA_EVM_ENCODER_TPD12S015) += dra-evm-encoder-tpd12s015.o -+obj-$(CONFIG_DISPLAY_ENCODER_SIL9022) += encoder-sil9022.o - obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o - obj-$(CONFIG_DISPLAY_CONNECTOR_HDMI) += connector-hdmi.o - obj-$(CONFIG_DISPLAY_CONNECTOR_ANALOG_TV) += connector-analog-tv.o -@@ -10,3 +12,4 @@ obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB0 - obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o - obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o - obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o -+obj-$(CONFIG_DISPLAY_PANEL_TFCS9700) += panel-tfcs9700.o ---- a/drivers/video/omap2/displays-new/panel-dpi.c -+++ b/drivers/video/omap2/displays-new/panel-dpi.c -@@ -13,9 +13,12 @@ - #include <linux/module.h> - #include <linux/platform_device.h> - #include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_gpio.h> - - #include <video/omapdss.h> - #include <video/omap-panel-data.h> -+#include <video/of_display_timing.h> - - struct panel_drv_data { - struct omap_dss_device dssdev; -@@ -26,6 +29,7 @@ struct panel_drv_data { - struct omap_video_timings videomode; - - int backlight_gpio; -+ bool backlight_enable; - int enable_gpio; - }; - -@@ -81,7 +85,7 @@ static int panel_dpi_enable(struct omap_ - gpio_set_value_cansleep(ddata->enable_gpio, 1); - - if (gpio_is_valid(ddata->backlight_gpio)) -- gpio_set_value_cansleep(ddata->backlight_gpio, 1); -+ gpio_set_value_cansleep(ddata->backlight_gpio, ddata->backlight_enable); - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - -@@ -100,7 +104,7 @@ static void panel_dpi_disable(struct oma - gpio_set_value_cansleep(ddata->enable_gpio, 0); - - if (gpio_is_valid(ddata->backlight_gpio)) -- gpio_set_value_cansleep(ddata->backlight_gpio, 0); -+ gpio_set_value_cansleep(ddata->backlight_gpio, ~(ddata->backlight_enable)); - - in->ops.dpi->disable(in); - -@@ -182,6 +186,73 @@ static int panel_dpi_probe_pdata(struct - return 0; - } - -+static int panel_dpi_probe_of(struct platform_device *pdev) -+{ -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct device_node *node = pdev->dev.of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ int r, datalines; -+ struct display_timing timing; -+ struct videomode vm; -+ int gpio; -+ enum of_gpio_flags gpio_flags; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ r = of_property_read_u32(node, "data-lines", &datalines); -+ if (r) { -+ dev_err(&pdev->dev, "failed to parse datalines\n"); -+ return r; -+ } -+ -+ ddata->data_lines = datalines; -+ -+ gpio = of_get_gpio(node, 0); -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->enable_gpio = gpio; -+ } else { -+ dev_err(&pdev->dev, "failed to parse enable gpio\n"); -+ return gpio; -+ } -+ -+ gpio = of_get_gpio_flags(node, 1, &gpio_flags); -+ -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->backlight_gpio = gpio; -+ } else { -+ dev_err(&pdev->dev, "failed to parse backlight gpio\n"); -+ return gpio; -+ } -+ -+ if (gpio_flags == OF_GPIO_ACTIVE_LOW) -+ ddata->backlight_enable = 0; -+ else -+ ddata->backlight_enable = 1; -+ -+ r = of_get_display_timing(node, "panel-timing", &timing); -+ if (r) { -+ dev_err(&pdev->dev, "failed to get video timing\n"); -+ return r; -+ } -+ -+ videomode_from_timing(&timing, &vm); -+ videomode_to_omap_video_timings(&vm, &ddata->videomode); -+ -+ return 0; -+} -+ - static int panel_dpi_probe(struct platform_device *pdev) - { - struct panel_drv_data *ddata; -@@ -198,6 +269,10 @@ static int panel_dpi_probe(struct platfo - r = panel_dpi_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ r = panel_dpi_probe_of(pdev); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -254,12 +329,20 @@ static int __exit panel_dpi_remove(struc - return 0; - } - -+static const struct of_device_id panel_dpi_of_match[] = { -+ { .compatible = "panel-dpi", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, panel_dpi_of_match); -+ - static struct platform_driver panel_dpi_driver = { - .probe = panel_dpi_probe, - .remove = __exit_p(panel_dpi_remove), - .driver = { - .name = "panel-dpi", - .owner = THIS_MODULE, -+ .of_match_table = panel_dpi_of_match, - }, - }; - ---- a/drivers/video/omap2/displays-new/panel-dsi-cm.c -+++ b/drivers/video/omap2/displays-new/panel-dsi-cm.c -@@ -22,6 +22,8 @@ - #include <linux/sched.h> - #include <linux/slab.h> - #include <linux/workqueue.h> -+#include <linux/of_device.h> -+#include <linux/of_gpio.h> - - #include <video/omapdss.h> - #include <video/omap-panel-data.h> -@@ -1156,6 +1158,79 @@ static int dsicm_probe_pdata(struct plat - return 0; - } - -+static int dsicm_probe_of(struct platform_device *pdev) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ struct panel_drv_data *ddata = platform_get_drvdata(pdev); -+ struct omap_dss_device *in; -+ struct property *prop; -+ struct device_node *src_node; -+ u32 lane_arr[10]; -+ int gpio, len, num_pins; -+ int r, i; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(&pdev->dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(&pdev->dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ ddata->in = in; -+ -+ gpio = of_get_gpio(node, 0); -+ if (!gpio_is_valid(gpio)) { -+ dev_err(&pdev->dev, "failed to parse reset gpio\n"); -+ return gpio; -+ } -+ ddata->reset_gpio = gpio; -+ -+ if (of_gpio_count(node) > 1) { -+ gpio = of_get_gpio(node, 1); -+ -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->ext_te_gpio = gpio; -+ } else { -+ dev_err(&pdev->dev, "failed to parse TE gpio\n"); -+ return gpio; -+ } -+ } else { -+ ddata->ext_te_gpio = -1; -+ } -+ -+ prop = of_find_property(node, "lanes", &len); -+ if (prop == NULL) { -+ dev_err(&pdev->dev, "failed to find lane data\n"); -+ return -EINVAL; -+ } -+ -+ num_pins = len / sizeof(u32); -+ -+ if (num_pins < 4 || num_pins % 2 != 0 -+ || num_pins > ARRAY_SIZE(lane_arr)) { -+ dev_err(&pdev->dev, "bad number of lanes\n"); -+ return -EINVAL; -+ } -+ -+ r = of_property_read_u32_array(node, "lanes", lane_arr, num_pins); -+ if (r) { -+ dev_err(&pdev->dev, "failed to read lane data\n"); -+ return r; -+ } -+ -+ ddata->pin_config.num_pins = num_pins; -+ for (i = 0; i < num_pins; ++i) -+ ddata->pin_config.pins[i] = (int)lane_arr[i]; -+ -+ /* TODO: ulps, backlight */ -+ -+ return 0; -+} -+ - static int dsicm_probe(struct platform_device *pdev) - { - struct backlight_properties props; -@@ -1178,6 +1253,10 @@ static int dsicm_probe(struct platform_d - r = dsicm_probe_pdata(pdev); - if (r) - return r; -+ } else if (pdev->dev.of_node) { -+ r = dsicm_probe_of(pdev); -+ if (r) -+ return r; - } else { - return -ENODEV; - } -@@ -1320,12 +1399,20 @@ static int __exit dsicm_remove(struct pl - return 0; - } - -+static const struct of_device_id dsicm_of_match[] = { -+ { .compatible = "panel-dsi-cm", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, dsicm_of_match); -+ - static struct platform_driver dsicm_driver = { - .probe = dsicm_probe, - .remove = __exit_p(dsicm_remove), - .driver = { - .name = "panel-dsi-cm", - .owner = THIS_MODULE, -+ .of_match_table = dsicm_of_match, - }, - }; - ---- /dev/null -+++ b/drivers/video/omap2/displays-new/panel-tfcs9700.c -@@ -0,0 +1,387 @@ -+/* -+ * TLC59108 TFC-S9700 Panel Driver -+ * -+ * Copyright (C) 2013 Texas Instruments -+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ */ -+ -+#include <linux/gpio.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+#include <linux/of_gpio.h> -+#include <linux/i2c.h> -+#include <linux/regmap.h> -+#include <linux/delay.h> -+ -+#include <video/omapdss.h> -+#include <video/omap-panel-data.h> -+#include <video/of_display_timing.h> -+ -+#define TLC_NAME "tlc59108" -+#define TLC_I2C_ADDR 0x40 -+ -+#define TLC59108_MODE1 0x00 -+#define TLC59108_PWM2 0x04 -+#define TLC59108_LEDOUT0 0x0c -+#define TLC59108_LEDOUT1 0x0d -+ -+struct panel_drv_data { -+ struct omap_dss_device dssdev; -+ struct omap_dss_device *in; -+ -+ int data_lines; -+ struct omap_video_timings videomode; -+ -+ int enable_gpio; -+ struct regmap *regmap; -+}; -+ -+static const struct omap_video_timings tfc_s9700_timings = { -+ .x_res = 800, -+ .y_res = 480, -+ -+ .pixel_clock = 29232, -+ -+ .hfp = 41, -+ .hsw = 49, -+ .hbp = 41, -+ -+ .vfp = 13, -+ .vsw = 4, -+ .vbp = 29, -+ -+ .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, -+ .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, -+ .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, -+ .de_level = OMAPDSS_SIG_ACTIVE_HIGH, -+ .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, -+}; -+ -+static int tlc_init(struct panel_drv_data *ddata) -+{ -+ struct regmap *map = ddata->regmap; -+ -+ /* init the TLC chip */ -+ regmap_write(map, TLC59108_MODE1, 0x01); -+ -+ /* -+ * set LED1(AVDD) to ON state(default), enable LED2 in PWM mode, enable -+ * LED0 to OFF state -+ */ -+ regmap_write(map, TLC59108_LEDOUT0, 0x21); -+ -+ /* set LED2 PWM to full freq */ -+ regmap_write(map, TLC59108_PWM2, 0xff); -+ -+ /* set LED4(UPDN) and LED6(MODE3) to OFF state */ -+ regmap_write(map, TLC59108_LEDOUT1, 0x11); -+ -+ return 0; -+} -+ -+static int tlc_uninit(struct panel_drv_data *ddata) -+{ -+ struct regmap *map = ddata->regmap; -+ -+ /* clear TLC chip regs */ -+ regmap_write(map, TLC59108_PWM2, 0x0); -+ regmap_write(map, TLC59108_LEDOUT0, 0x0); -+ regmap_write(map, TLC59108_LEDOUT1, 0x0); -+ -+ regmap_write(map, TLC59108_MODE1, 0x0); -+ -+ return 0; -+} -+ -+#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) -+ -+static int panel_dpi_connect(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int r; -+ -+ if (omapdss_device_is_connected(dssdev)) -+ return 0; -+ -+ r = in->ops.dpi->connect(in, dssdev); -+ if (r) -+ return r; -+ -+ return 0; -+} -+ -+static void panel_dpi_disconnect(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ if (!omapdss_device_is_connected(dssdev)) -+ return; -+ -+ in->ops.dpi->disconnect(in, dssdev); -+} -+ -+static int panel_dpi_enable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ int r; -+ -+ if (!omapdss_device_is_connected(dssdev)) -+ return -ENODEV; -+ -+ if (omapdss_device_is_enabled(dssdev)) -+ return 0; -+ -+ in->ops.dpi->set_data_lines(in, ddata->data_lines); -+ in->ops.dpi->set_timings(in, &ddata->videomode); -+ -+ r = in->ops.dpi->enable(in); -+ if (r) -+ return r; -+ -+ tlc_init(ddata); -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ -+ return 0; -+} -+ -+static void panel_dpi_disable(struct omap_dss_device *dssdev) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ if (!omapdss_device_is_enabled(dssdev)) -+ return; -+ -+ tlc_uninit(ddata); -+ -+ in->ops.dpi->disable(in); -+ -+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -+} -+ -+static void panel_dpi_set_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ ddata->videomode = *timings; -+ dssdev->panel.timings = *timings; -+ -+ in->ops.dpi->set_timings(in, timings); -+} -+ -+static void panel_dpi_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ -+ *timings = ddata->videomode; -+} -+ -+static int panel_dpi_check_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct panel_drv_data *ddata = to_panel_data(dssdev); -+ struct omap_dss_device *in = ddata->in; -+ -+ return in->ops.dpi->check_timings(in, timings); -+} -+ -+static struct omap_dss_driver panel_dpi_ops = { -+ .connect = panel_dpi_connect, -+ .disconnect = panel_dpi_disconnect, -+ -+ .enable = panel_dpi_enable, -+ .disable = panel_dpi_disable, -+ -+ .set_timings = panel_dpi_set_timings, -+ .get_timings = panel_dpi_get_timings, -+ .check_timings = panel_dpi_check_timings, -+ -+ .get_resolution = omapdss_default_get_resolution, -+}; -+ -+static int tlc_probe_of(struct device *dev) -+{ -+ struct panel_drv_data *ddata = dev_get_drvdata(dev); -+ struct device_node *node = dev->of_node; -+ struct omap_dss_device *in; -+ struct device_node *src_node; -+ int r, datalines; -+ int gpio; -+ -+ src_node = of_parse_phandle(node, "video-source", 0); -+ if (!src_node) { -+ dev_err(dev, "failed to parse video source\n"); -+ return -ENODEV; -+ } -+ -+ in = omap_dss_find_output_by_node(src_node); -+ if (in == NULL) { -+ dev_err(dev, "failed to find video source\n"); -+ return -EPROBE_DEFER; -+ } -+ -+ ddata->in = in; -+ -+ r = of_property_read_u32(node, "data-lines", &datalines); -+ if (r) { -+ dev_err(dev, "failed to parse datalines\n"); -+ return r; -+ } -+ -+ ddata->data_lines = datalines; -+ -+ gpio = of_get_gpio(node, 0); -+ if (gpio_is_valid(gpio) || gpio == -ENOENT) { -+ ddata->enable_gpio = gpio; -+ } else { -+ dev_err(dev, "failed to parse enable gpio\n"); -+ return gpio; -+ } -+ -+ return 0; -+} -+ -+struct regmap_config tlc59108_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+}; -+ -+static int tlc59108_i2c_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ int r; -+ struct regmap *regmap; -+ struct panel_drv_data *ddata; -+ struct device *dev = &client->dev; -+ struct omap_dss_device *dssdev; -+ unsigned int val; -+ -+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); -+ if (ddata == NULL) -+ return -ENOMEM; -+ -+ dev_set_drvdata(dev, ddata); -+ -+ r = tlc_probe_of(dev); -+ if (r) -+ return r; -+ -+ ddata->videomode = tfc_s9700_timings; -+ -+ if (gpio_is_valid(ddata->enable_gpio)) { -+ r = devm_gpio_request_one(dev, ddata->enable_gpio, -+ GPIOF_OUT_INIT_LOW, "panel enable"); -+ if (r) -+ goto err_gpio; -+ } -+ -+ regmap = devm_regmap_init_i2c(client, &tlc59108_regmap_config); -+ if (IS_ERR(regmap)) { -+ r = PTR_ERR(regmap); -+ dev_err(dev, "Failed to init regmap: %d\n", r); -+ goto err_gpio; -+ } -+ -+ ddata->regmap = regmap; -+ -+ msleep(10); -+ -+ /* Try to read a TLC register to verify if i2c works */ -+ r = regmap_read(ddata->regmap, TLC59108_MODE1, &val); -+ if (r < 0) { -+ dev_err(dev, "Failed to set MODE1: %d\n", r); -+ return r; -+ } -+ -+ dssdev = &ddata->dssdev; -+ dssdev->dev = dev; -+ dssdev->driver = &panel_dpi_ops; -+ dssdev->type = OMAP_DISPLAY_TYPE_DPI; -+ dssdev->owner = THIS_MODULE; -+ dssdev->panel.timings = ddata->videomode; -+ dssdev->phy.dpi.data_lines = ddata->data_lines; -+ -+ r = omapdss_register_display(dssdev); -+ if (r) { -+ dev_err(dev, "Failed to register panel\n"); -+ goto err_reg; -+ } -+ -+ dev_info(dev, "Successfully initialized %s\n", TLC_NAME); -+ -+ return 0; -+err_reg: -+err_gpio: -+ omap_dss_put_device(ddata->in); -+ return r; -+} -+ -+static int tlc59108_i2c_remove(struct i2c_client *client) -+{ -+ struct panel_drv_data *ddata = dev_get_drvdata(&client->dev); -+ struct omap_dss_device *dssdev = &ddata->dssdev; -+ struct omap_dss_device *in = ddata->in; -+ -+ if (gpio_is_valid(ddata->enable_gpio)) -+ gpio_set_value_cansleep(ddata->enable_gpio, 1); -+ -+ omapdss_unregister_display(dssdev); -+ -+ panel_dpi_disable(dssdev); -+ panel_dpi_disconnect(dssdev); -+ -+ omap_dss_put_device(in); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id tlc59108_id[] = { -+ { TLC_NAME, 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, tlc59108_id); -+ -+static const struct of_device_id tlc59108_of_match[] = { -+ { .compatible = "ti,tlc59108", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, tlc59108_of_match); -+ -+static struct i2c_driver tlc59108_i2c_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = TLC_NAME, -+ .of_match_table = tlc59108_of_match, -+ }, -+ .id_table = tlc59108_id, -+ .probe = tlc59108_i2c_probe, -+ .remove = tlc59108_i2c_remove, -+}; -+ -+static int __init tfc_s9700_init(void) -+{ -+ return i2c_add_driver(&tlc59108_i2c_driver); -+} -+ -+static void __exit tfc_s9700_exit(void) -+{ -+} -+module_init(tfc_s9700_init); -+module_exit(tfc_s9700_exit); -+ -+MODULE_AUTHOR("Archit Taneja <archit@ti.com>"); -+MODULE_DESCRIPTION("TFC-S9700 DPI Panel Driver"); -+MODULE_LICENSE("GPL"); ---- a/drivers/video/omap2/dss/core.c -+++ b/drivers/video/omap2/dss/core.c -@@ -256,6 +256,9 @@ static int (*dss_output_drv_reg_funcs[]) - #ifdef CONFIG_OMAP2_DSS_DPI - dpi_init_platform_driver, - #endif -+#ifdef CONFIG_OMAP2_DSS_DRA7XX_DPI -+ dra7xx_dpi_init_platform_driver, -+#endif - #ifdef CONFIG_OMAP2_DSS_SDI - sdi_init_platform_driver, - #endif -@@ -266,7 +269,10 @@ static int (*dss_output_drv_reg_funcs[]) - venc_init_platform_driver, - #endif - #ifdef CONFIG_OMAP4_DSS_HDMI -- hdmi_init_platform_driver, -+ hdmi4_init_platform_driver, -+#endif -+#ifdef CONFIG_OMAP5_DSS_HDMI -+ hdmi5_init_platform_driver, - #endif - }; - -@@ -277,6 +283,9 @@ static void (*dss_output_drv_unreg_funcs - #ifdef CONFIG_OMAP2_DSS_DPI - dpi_uninit_platform_driver, - #endif -+#ifdef CONFIG_OMAP2_DSS_DRA7XX_DPI -+ dra7xx_dpi_uninit_platform_driver, -+#endif - #ifdef CONFIG_OMAP2_DSS_SDI - sdi_uninit_platform_driver, - #endif -@@ -287,7 +296,10 @@ static void (*dss_output_drv_unreg_funcs - venc_uninit_platform_driver, - #endif - #ifdef CONFIG_OMAP4_DSS_HDMI -- hdmi_uninit_platform_driver, -+ hdmi4_uninit_platform_driver, -+#endif -+#ifdef CONFIG_OMAP5_DSS_HDMI -+ hdmi5_uninit_platform_driver, - #endif - }; - ---- a/drivers/video/omap2/dss/dispc.c -+++ b/drivers/video/omap2/dss/dispc.c -@@ -3622,6 +3622,7 @@ static int __init dispc_init_features(st - case OMAPDSS_VER_OMAP34xx_ES3: - case OMAPDSS_VER_OMAP3630: - case OMAPDSS_VER_AM35xx: -+ case OMAPDSS_VER_AM43xx: - src = &omap34xx_rev3_0_dispc_feats; - break; - -@@ -3632,6 +3633,7 @@ static int __init dispc_init_features(st - break; - - case OMAPDSS_VER_OMAP5: -+ case OMAPDSS_VER_DRA7xx: - src = &omap54xx_dispc_feats; - break; - -@@ -3691,7 +3693,6 @@ static int __init omap_dispchw_probe(str - } - - pm_runtime_enable(&pdev->dev); -- pm_runtime_irq_safe(&pdev->dev); - - r = dispc_runtime_get(); - if (r) -@@ -3744,12 +3745,19 @@ static const struct dev_pm_ops dispc_pm_ - .runtime_resume = dispc_runtime_resume, - }; - -+static const struct of_device_id dispc_of_match[] = { -+ { .compatible = "ti,omap3-dispc", }, -+ { .compatible = "ti,omap4-dispc", }, -+ {}, -+}; -+ - static struct platform_driver omap_dispchw_driver = { - .remove = __exit_p(omap_dispchw_remove), - .driver = { - .name = "omapdss_dispc", - .owner = THIS_MODULE, - .pm = &dispc_pm_ops, -+ .of_match_table = dispc_of_match, - }, - }; - ---- a/drivers/video/omap2/dss/display.c -+++ b/drivers/video/omap2/dss/display.c -@@ -26,6 +26,7 @@ - #include <linux/module.h> - #include <linux/jiffies.h> - #include <linux/platform_device.h> -+#include <linux/of.h> - - #include <video/omapdss.h> - #include "dss.h" -@@ -133,9 +134,27 @@ static int disp_num_counter; - int omapdss_register_display(struct omap_dss_device *dssdev) - { - struct omap_dss_driver *drv = dssdev->driver; -+ int id; - -- snprintf(dssdev->alias, sizeof(dssdev->alias), -- "display%d", disp_num_counter++); -+ /* -+ * Note: this presumes all the displays are either using DT or non-DT, -+ * which normally should be the case. This also presumes that all -+ * displays either have an DT alias, or none has. -+ */ -+ -+ if (dssdev->dev->of_node) { -+ id = of_alias_get_id(dssdev->dev->of_node, "display"); -+ -+ if (id < 0) -+ id = disp_num_counter++; -+ } else { -+ id = disp_num_counter++; -+ } -+ -+ snprintf(dssdev->alias, sizeof(dssdev->alias), "display%d", id); -+ -+ if (dssdev->name == NULL) -+ dssdev->name = dssdev->alias; - - if (drv && drv->get_resolution == NULL) - drv->get_resolution = omapdss_default_get_resolution; ---- a/drivers/video/omap2/dss/display-sysfs.c -+++ b/drivers/video/omap2/dss/display-sysfs.c -@@ -277,7 +277,7 @@ static ssize_t display_wss_store(struct - return size; - } - --static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL); -+static DEVICE_ATTR(disp_name, S_IRUGO, display_name_show, NULL); - static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, - display_enabled_show, display_enabled_store); - static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, -@@ -292,7 +292,7 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, - display_wss_show, display_wss_store); - - static const struct attribute *display_sysfs_attrs[] = { -- &dev_attr_name.attr, -+ &dev_attr_disp_name.attr, - &dev_attr_enabled.attr, - &dev_attr_tear_elim.attr, - &dev_attr_timings.attr, ---- a/drivers/video/omap2/dss/dpi.c -+++ b/drivers/video/omap2/dss/dpi.c -@@ -30,6 +30,7 @@ - #include <linux/platform_device.h> - #include <linux/regulator/consumer.h> - #include <linux/string.h> -+#include <linux/of.h> - - #include <video/omapdss.h> - -@@ -64,6 +65,7 @@ static struct platform_device *dpi_get_d - case OMAPDSS_VER_OMAP34xx_ES3: - case OMAPDSS_VER_OMAP3630: - case OMAPDSS_VER_AM35xx: -+ case OMAPDSS_VER_AM43xx: - return NULL; - - case OMAPDSS_VER_OMAP4430_ES1: -@@ -374,7 +376,7 @@ static int dpi_display_enable(struct oma - if (r) - goto err_get_dispc; - -- r = dss_dpi_select_source(out->manager->id); -+ r = dss_dpi_select_source(0, out->manager->id); - if (r) - goto err_src_sel; - -@@ -593,6 +595,7 @@ static enum omap_channel dpi_get_channel - case OMAPDSS_VER_OMAP34xx_ES3: - case OMAPDSS_VER_OMAP3630: - case OMAPDSS_VER_AM35xx: -+ case OMAPDSS_VER_AM43xx: - return OMAP_DSS_CHANNEL_LCD; - - case OMAPDSS_VER_OMAP4430_ES1: -@@ -708,12 +711,19 @@ static int __exit omap_dpi_remove(struct - return 0; - } - -+static const struct of_device_id dpi_of_match[] = { -+ { .compatible = "ti,omap3-dpi", }, -+ { .compatible = "ti,omap4-dpi", }, -+ {}, -+}; -+ - static struct platform_driver omap_dpi_driver = { - .probe = omap_dpi_probe, - .remove = __exit_p(omap_dpi_remove), - .driver = { - .name = "omapdss_dpi", - .owner = THIS_MODULE, -+ .of_match_table = dpi_of_match, - }, - }; - ---- /dev/null -+++ b/drivers/video/omap2/dss/dra7xx_dpi.c -@@ -0,0 +1,632 @@ -+/* -+ * Some code and ideas taken from drivers/video/omap/ driver -+ * by Imre Deak. -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#define DSS_SUBSYS_NAME "DRA7XX_DPI" -+ -+#include <linux/kernel.h> -+#include <linux/delay.h> -+#include <linux/export.h> -+#include <linux/err.h> -+#include <linux/errno.h> -+#include <linux/platform_device.h> -+#include <linux/regulator/consumer.h> -+#include <linux/string.h> -+#include <linux/slab.h> -+#include <linux/of.h> -+ -+#include <video/omapdss.h> -+ -+#include "dss.h" -+#include "dss_features.h" -+ -+struct dpi_data { -+ enum dss_dpll dpll; -+ -+ struct mutex lock; -+ -+ u32 module_id; -+ enum omap_channel channel; -+ -+ struct omap_video_timings timings; -+ struct dss_lcd_mgr_config mgr_config; -+ int data_lines; -+ -+ struct omap_dss_device output; -+}; -+ -+/* -+ * On DRA7xx, we will try to use the DPLL_VIDEOx PLLs, only if we can't get one, -+ * we will try to modify the DSS_FCLK to get the pixel clock. Leave HDMI PLL out -+ * for now -+ */ -+enum dss_dpll dpi_get_dpll(struct dpi_data *dpi) -+{ -+ switch (dpi->module_id) { -+ case 0: -+ if (dss_dpll_disabled(DSS_DPLL_VIDEO1)) -+ return DSS_DPLL_VIDEO1; -+ else -+ return DSS_DPLL_NONE; -+ case 1: -+ case 2: -+ if (dss_dpll_disabled(DSS_DPLL_VIDEO1)) -+ return DSS_DPLL_VIDEO1; -+ else if (dss_dpll_disabled(DSS_DPLL_VIDEO2)) -+ return DSS_DPLL_VIDEO2; -+ else -+ return DSS_DPLL_NONE; -+ default: -+ return DSS_DPLL_NONE; -+ } -+ -+ return DSS_DPLL_NONE; -+} -+ -+struct dpi_clk_calc_ctx { -+ enum dss_dpll dpll; -+ -+ /* inputs */ -+ unsigned long pck_min, pck_max; -+ -+ /* outputs */ -+ struct dss_dpll_cinfo dpll_cinfo; -+ struct dss_clock_info dss_cinfo; -+ struct dispc_clock_info dispc_cinfo; -+}; -+ -+static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, -+ unsigned long pck, void *data) -+{ -+ struct dpi_clk_calc_ctx *ctx = data; -+ -+ /* -+ * Odd dividers give us uneven duty cycle, causing problem when level -+ * shifted. So skip all odd dividers when the pixel clock is on the -+ * higher side. -+ */ -+ if (ctx->pck_min >= 100000000) { -+ if (lckd > 1 && lckd % 2 != 0) -+ return false; -+ -+ if (pckd > 1 && pckd % 2 != 0) -+ return false; -+ } -+ -+ ctx->dispc_cinfo.lck_div = lckd; -+ ctx->dispc_cinfo.pck_div = pckd; -+ ctx->dispc_cinfo.lck = lck; -+ ctx->dispc_cinfo.pck = pck; -+ -+ return true; -+} -+ -+static bool dpi_calc_hsdiv_cb(int regm_hsdiv, unsigned long dispc, -+ void *data) -+{ -+ struct dpi_clk_calc_ctx *ctx = data; -+ -+ /* -+ * Odd dividers give us uneven duty cycle, causing problem when level -+ * shifted. So skip all odd dividers when the pixel clock is on the -+ * higher side. -+ */ -+ if (regm_hsdiv > 1 && regm_hsdiv % 2 != 0 && ctx->pck_min >= 100000000) -+ return false; -+ -+ ctx->dpll_cinfo.regm_hsdiv = regm_hsdiv; -+ ctx->dpll_cinfo.hsdiv_clk = dispc; -+ -+ return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, -+ dpi_calc_dispc_cb, ctx); -+} -+ -+static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint, -+ unsigned long pll, -+ void *data) -+{ -+ struct dpi_clk_calc_ctx *ctx = data; -+ -+ ctx->dpll_cinfo.regn = regn; -+ ctx->dpll_cinfo.regm = regm; -+ ctx->dpll_cinfo.fint = fint; -+ ctx->dpll_cinfo.clkout = pll; -+ -+ return dss_dpll_hsdiv_calc(ctx->dpll, pll, ctx->pck_min, -+ dpi_calc_hsdiv_cb, ctx); -+} -+ -+static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) -+{ -+ struct dpi_clk_calc_ctx *ctx = data; -+ -+ ctx->dss_cinfo.fck = fck; -+ ctx->dss_cinfo.fck_div = fckd; -+ -+ return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, -+ dpi_calc_dispc_cb, ctx); -+} -+ -+ -+static bool dpi_dpll_clk_calc(enum dss_dpll dpll, unsigned long pck, -+ struct dpi_clk_calc_ctx *ctx) -+{ -+ unsigned long clkin; -+ unsigned long pll_min, pll_max; -+ -+ clkin = dpll_get_clkin(dpll); -+ -+ memset(ctx, 0, sizeof(*ctx)); -+ ctx->dpll = dpll; -+ ctx->pck_min = pck - 1000; -+ ctx->pck_max = pck + 1000; -+ ctx->dpll_cinfo.clkin = clkin; -+ -+ pll_min = 0; -+ pll_max = 0; -+ -+ return dss_dpll_calc(dpll, clkin, pll_min, pll_max, dpi_calc_pll_cb, -+ ctx); -+} -+ -+static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) -+{ -+ int i; -+ -+ /* -+ * DSS fck gives us very few possibilities, so finding a good pixel -+ * clock may not be possible. We try multiple times to find the clock, -+ * each time widening the pixel clock range we look for, up to -+ * +/- ~15MHz. -+ */ -+ -+ for (i = 0; i < 25; ++i) { -+ bool ok; -+ -+ memset(ctx, 0, sizeof(*ctx)); -+ if (pck > 1000 * i * i * i) -+ ctx->pck_min = max(pck - 1000 * i * i * i, 0lu); -+ else -+ ctx->pck_min = 0; -+ ctx->pck_max = pck + 1000 * i * i * i; -+ -+ ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx); -+ if (ok) -+ return ok; -+ } -+ -+ return false; -+} -+ -+static int dpi_set_dss_dpll_clk(struct dpi_data *dpi, unsigned long pck_req, -+ unsigned long *fck, u16 *lck_div, u16 *pck_div) -+{ -+ struct dpi_clk_calc_ctx ctx; -+ int r; -+ bool ok; -+ -+ ok = dpi_dpll_clk_calc(dpi->dpll, pck_req, &ctx); -+ if (!ok) -+ return -EINVAL; -+ -+ r = dss_dpll_set_clock_div(dpi->dpll, &ctx.dpll_cinfo); -+ if (r) -+ return r; -+ -+ dss_use_dpll_lcd(dpi->output.dispc_channel, true); -+ -+ dpi->mgr_config.clock_info = ctx.dispc_cinfo; -+ -+ *fck = ctx.dpll_cinfo.hsdiv_clk; -+ *lck_div = ctx.dispc_cinfo.lck_div; -+ *pck_div = ctx.dispc_cinfo.pck_div; -+ -+ return 0; -+} -+ -+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req, -+ unsigned long *fck, u16 *lck_div, u16 *pck_div) -+{ -+ struct dpi_clk_calc_ctx ctx; -+ int r; -+ bool ok; -+ -+ ok = dpi_dss_clk_calc(pck_req, &ctx); -+ if (!ok) -+ return -EINVAL; -+ -+ r = dss_set_clock_div(&ctx.dss_cinfo); -+ if (r) -+ return r; -+ -+ dpi->mgr_config.clock_info = ctx.dispc_cinfo; -+ -+ *fck = ctx.dss_cinfo.fck; -+ *lck_div = ctx.dispc_cinfo.lck_div; -+ *pck_div = ctx.dispc_cinfo.pck_div; -+ -+ return 0; -+} -+ -+static int dpi_set_mode(struct dpi_data *dpi) -+{ -+ struct omap_overlay_manager *mgr = dpi->output.manager; -+ struct omap_video_timings *t = &dpi->timings; -+ u16 lck_div = 0, pck_div = 0; -+ unsigned long fck = 0; -+ unsigned long pck; -+ int r = 0; -+ -+ if (dpi->dpll != DSS_DPLL_NONE) -+ r = dpi_set_dss_dpll_clk(dpi, t->pixel_clock * 1000, &fck, -+ &lck_div, &pck_div); -+ else -+ r = dpi_set_dispc_clk(dpi, t->pixel_clock * 1000, &fck, -+ &lck_div, &pck_div); -+ if (r) -+ return r; -+ -+ pck = fck / lck_div / pck_div / 1000; -+ -+ if (pck != t->pixel_clock) { -+ DSSWARN("Could not find exact pixel clock. " -+ "Requested %d kHz, got %lu kHz\n", -+ t->pixel_clock, pck); -+ -+ t->pixel_clock = pck; -+ } -+ -+ dss_mgr_set_timings(mgr, t); -+ -+ return 0; -+} -+ -+static void dpi_config_lcd_manager(struct dpi_data *dpi) -+{ -+ struct omap_overlay_manager *mgr = dpi->output.manager; -+ -+ dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; -+ -+ dpi->mgr_config.stallmode = false; -+ dpi->mgr_config.fifohandcheck = false; -+ -+ dpi->mgr_config.video_port_width = dpi->data_lines; -+ -+ dpi->mgr_config.lcden_sig_polarity = 0; -+ -+ dss_mgr_set_lcd_config(mgr, &dpi->mgr_config); -+} -+ -+static int dra7xx_dpi_display_enable(struct omap_dss_device *dssdev) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ struct omap_dss_device *out = &dpi->output; -+ int r; -+ -+ mutex_lock(&dpi->lock); -+ -+ if (out == NULL || out->manager == NULL) { -+ DSSERR("failed to enable display: no output/manager\n"); -+ r = -ENODEV; -+ goto err_no_out_mgr; -+ } -+ -+ r = dispc_runtime_get(); -+ if (r) -+ goto err_get_dispc; -+ -+ r = dss_dpi_select_source(dpi->module_id, out->dispc_channel); -+ if (r) -+ goto err_src_sel; -+ -+ if (dpi->dpll != DSS_DPLL_NONE) { -+ DSSDBG("using DPLL %d for DPI%d\n", dpi->dpll, dpi->module_id); -+ dss_dpll_activate(dpi->dpll); -+ dss_dpll_set_control_mux(out->dispc_channel, dpi->dpll); -+ } -+ -+ r = dpi_set_mode(dpi); -+ if (r) -+ goto err_set_mode; -+ -+ -+ dpi_config_lcd_manager(dpi); -+ -+ mdelay(2); -+ -+ r = dss_mgr_enable(out->manager); -+ if (r) -+ goto err_mgr_enable; -+ -+ mutex_unlock(&dpi->lock); -+ -+ return 0; -+ -+err_mgr_enable: -+err_set_mode: -+ if (dpi->dpll != DSS_DPLL_NONE) -+ dss_dpll_disable(dpi->dpll); -+err_src_sel: -+ dispc_runtime_put(); -+err_get_dispc: -+err_no_out_mgr: -+ mutex_unlock(&dpi->lock); -+ return r; -+} -+ -+static void dra7xx_dpi_display_disable(struct omap_dss_device *dssdev) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ struct omap_overlay_manager *mgr = dpi->output.manager; -+ -+ mutex_lock(&dpi->lock); -+ -+ dss_mgr_disable(mgr); -+ -+ if (dpi->dpll != DSS_DPLL_NONE) { -+ dss_use_dpll_lcd(dssdev->dispc_channel, false); -+ dss_dpll_disable(dpi->dpll); -+ } -+ -+ dispc_runtime_put(); -+ -+ mutex_unlock(&dpi->lock); -+} -+ -+static void dra7xx_dpi_set_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ -+ DSSDBG("set_timings\n"); -+ -+ mutex_lock(&dpi->lock); -+ -+ dpi->timings = *timings; -+ -+ mutex_unlock(&dpi->lock); -+} -+ -+static int dra7xx_dpi_check_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ DSSDBG("check_timings\n"); -+ -+ return 0; -+} -+ -+static void dra7xx_dpi_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ -+ DSSDBG("set_timings\n"); -+ -+ mutex_lock(&dpi->lock); -+ -+ *timings = dpi->timings; -+ -+ mutex_unlock(&dpi->lock); -+} -+ -+static void dra7xx_dpi_set_data_lines(struct omap_dss_device *dssdev, -+ int data_lines) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ -+ mutex_lock(&dpi->lock); -+ -+ dpi->data_lines = data_lines; -+ -+ mutex_unlock(&dpi->lock); -+} -+ -+static int dra7xx_dpi_connect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ struct omap_overlay_manager *mgr; -+ int r; -+ -+ /* try to get a free dpll */ -+ dpi->dpll = dpi_get_dpll(dpi); -+ -+ r = dss_dpll_init_regulator(dpi->dpll); -+ if (r) -+ return r; -+ -+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); -+ if (!mgr) -+ return -ENODEV; -+ -+ r = dss_mgr_connect(mgr, dssdev); -+ if (r) -+ return r; -+ -+ r = omapdss_output_set_device(dssdev, dst); -+ if (r) { -+ DSSERR("failed to connect output to new device: %s\n", -+ dst->name); -+ dss_mgr_disconnect(mgr, dssdev); -+ return r; -+ } -+ -+ return 0; -+} -+ -+static void dra7xx_dpi_disconnect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(dssdev->dev); -+ -+ WARN_ON(dst != dssdev->dst); -+ -+ if (dst != dssdev->dst) -+ return; -+ -+ dpi->dpll = DSS_DPLL_NONE; -+ -+ omapdss_output_unset_device(dssdev); -+ -+ if (dssdev->manager) -+ dss_mgr_disconnect(dssdev->manager, dssdev); -+} -+ -+static const struct omapdss_dpi_ops dra7xx_dpi_ops = { -+ .connect = dra7xx_dpi_connect, -+ .disconnect = dra7xx_dpi_disconnect, -+ -+ .enable = dra7xx_dpi_display_enable, -+ .disable = dra7xx_dpi_display_disable, -+ -+ .check_timings = dra7xx_dpi_check_timings, -+ .set_timings = dra7xx_dpi_set_timings, -+ .get_timings = dra7xx_dpi_get_timings, -+ -+ .set_data_lines = dra7xx_dpi_set_data_lines, -+}; -+ -+static enum omap_channel dra7xx_dpi_get_channel(struct dpi_data *dpi) -+{ -+ switch (dpi->module_id) { -+ case 0: -+ return dpi->channel; -+ case 1: -+ return OMAP_DSS_CHANNEL_LCD2; -+ case 2: -+ return OMAP_DSS_CHANNEL_LCD3; -+ default: -+ DSSWARN("unknown DPI instance\n"); -+ return OMAP_DSS_CHANNEL_LCD; -+ } -+} -+ -+static void dra7xx_dpi_init_output(struct platform_device *pdev) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(&pdev->dev); -+ struct omap_dss_device *out = &dpi->output; -+ char *name; -+ -+ out->dev = &pdev->dev; -+ name = devm_kzalloc(&pdev->dev, 5, GFP_KERNEL); -+ -+ switch (dpi->module_id) { -+ case 0: -+ out->id = OMAP_DSS_OUTPUT_DPI; -+ break; -+ case 1: -+ out->id = OMAP_DSS_OUTPUT_DPI1; -+ break; -+ case 2: -+ out->id = OMAP_DSS_OUTPUT_DPI2; -+ break; -+ }; -+ -+ snprintf(name, 5, "dpi.%d", dpi->module_id); -+ out->name = name; -+ out->output_type = OMAP_DISPLAY_TYPE_DPI; -+ out->dispc_channel = dra7xx_dpi_get_channel(dpi); -+ out->ops.dpi = &dra7xx_dpi_ops; -+ out->owner = THIS_MODULE; -+ -+ omapdss_register_output(out); -+} -+ -+static void __exit dra7xx_dpi_uninit_output(struct platform_device *pdev) -+{ -+ struct dpi_data *dpi = dev_get_drvdata(&pdev->dev); -+ struct omap_dss_device *out = &dpi->output; -+ -+ omapdss_unregister_output(out); -+} -+ -+static int dra7xx_dpi_probe(struct platform_device *pdev) -+{ -+ int r; -+ struct dpi_data *dpi; -+ -+ dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); -+ if (!dpi) -+ return -ENOMEM; -+ -+ dev_set_drvdata(&pdev->dev, dpi); -+ -+ mutex_init(&dpi->lock); -+ -+ if (pdev->dev.of_node) { -+ u32 id; -+ enum omap_channel channel; -+ -+ r = of_property_read_u32(pdev->dev.of_node, "id", &id); -+ if (r) { -+ DSSERR("failed to read DPI module ID\n"); -+ return r; -+ } -+ -+ r = of_property_read_u32(pdev->dev.of_node, "channel", &channel); -+ if (r && id == 0) { -+ DSSERR("failed to read DPI channel\n"); -+ return r; -+ } -+ -+ dpi->module_id = id; -+ dpi->channel = channel; -+ } else { -+ dpi->module_id = pdev->id; -+ } -+ -+ dra7xx_dpi_init_output(pdev); -+ -+ return 0; -+} -+ -+static int __exit dra7xx_dpi_remove(struct platform_device *pdev) -+{ -+ dra7xx_dpi_uninit_output(pdev); -+ -+ return 0; -+} -+ -+#if defined(CONFIG_OF) -+static const struct of_device_id dpi_of_match[] = { -+ { -+ .compatible = "ti,dra7xx-dpi", -+ }, -+ {}, -+}; -+#else -+#define dpi_of_match NULL -+#endif -+ -+static struct platform_driver dra7xx_dpi_driver = { -+ .probe = dra7xx_dpi_probe, -+ .remove = __exit_p(dra7xx_dpi_remove), -+ .driver = { -+ .name = "omapdss_dra7xx_dpi", -+ .owner = THIS_MODULE, -+ .of_match_table = dpi_of_match, -+ }, -+}; -+ -+int __init dra7xx_dpi_init_platform_driver(void) -+{ -+ return platform_driver_register(&dra7xx_dpi_driver); -+} -+ -+void __exit dra7xx_dpi_uninit_platform_driver(void) -+{ -+ platform_driver_unregister(&dra7xx_dpi_driver); -+} ---- a/drivers/video/omap2/dss/dsi.c -+++ b/drivers/video/omap2/dss/dsi.c -@@ -38,6 +38,7 @@ - #include <linux/slab.h> - #include <linux/debugfs.h> - #include <linux/pm_runtime.h> -+#include <linux/of.h> - - #include <video/omapdss.h> - #include <video/mipi_display.h> -@@ -373,6 +374,13 @@ struct dsi_packet_sent_handler_data { - struct completion *completion; - }; - -+struct dsi_module_id_data { -+ u32 address; -+ int id; -+}; -+ -+static const struct of_device_id dsi_of_match[]; -+ - #ifdef DEBUG - static bool dsi_perf; - module_param(dsi_perf, bool, 0644); -@@ -1123,11 +1131,6 @@ static int dsi_regulator_init(struct pla - return 0; - - vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdds_dsi"); -- -- /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ -- if (IS_ERR(vdds_dsi)) -- vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO"); -- - if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); -@@ -5082,6 +5085,7 @@ static enum omap_channel dsi_get_channel - { - switch (omapdss_get_version()) { - case OMAPDSS_VER_OMAP24xx: -+ case OMAPDSS_VER_AM43xx: - DSSWARN("DSI not supported\n"); - return OMAP_DSS_CHANNEL_LCD; - -@@ -5352,7 +5356,6 @@ static int omap_dsihw_probe(struct platf - if (!dsi) - return -ENOMEM; - -- dsi->module_id = dsidev->id; - dsi->pdev = dsidev; - dev_set_drvdata(&dsidev->dev, dsi); - -@@ -5402,6 +5405,31 @@ static int omap_dsihw_probe(struct platf - return r; - } - -+ if (dsidev->dev.of_node) { -+ const struct of_device_id *match; -+ const struct dsi_module_id_data *d; -+ -+ match = of_match_node(dsi_of_match, dsidev->dev.of_node); -+ if (!match) { -+ DSSERR("unsupported DSI module\n"); -+ return -ENODEV; -+ } -+ -+ d = match->data; -+ -+ while (d->address != 0 && d->address != dsi_mem->start) -+ d++; -+ -+ if (d->address == 0) { -+ DSSERR("unsupported DSI module\n"); -+ return -ENODEV; -+ } -+ -+ dsi->module_id = d->id; -+ } else { -+ dsi->module_id = dsidev->id; -+ } -+ - /* DSI VCs initialization */ - for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { - dsi->vc[i].source = DSI_VC_SOURCE_L4; -@@ -5450,6 +5478,7 @@ static int omap_dsihw_probe(struct platf - else if (dsi->module_id == 1) - dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs); - #endif -+ - return 0; - - err_runtime_get: -@@ -5498,6 +5527,23 @@ static const struct dev_pm_ops dsi_pm_op - .runtime_resume = dsi_runtime_resume, - }; - -+static const struct dsi_module_id_data dsi_of_data_omap3[] = { -+ { .address = 0x4804fc00, .id = 0, }, -+ { }, -+}; -+ -+static const struct dsi_module_id_data dsi_of_data_omap4[] = { -+ { .address = 0x58004000, .id = 0, }, -+ { .address = 0x58005000, .id = 1, }, -+ { }, -+}; -+ -+static const struct of_device_id dsi_of_match[] = { -+ { .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, }, -+ { .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, }, -+ {}, -+}; -+ - static struct platform_driver omap_dsihw_driver = { - .probe = omap_dsihw_probe, - .remove = __exit_p(omap_dsihw_remove), -@@ -5505,6 +5551,7 @@ static struct platform_driver omap_dsihw - .name = "omapdss_dsi", - .owner = THIS_MODULE, - .pm = &dsi_pm_ops, -+ .of_match_table = dsi_of_match, - }, - }; - ---- a/drivers/video/omap2/dss/dss.c -+++ b/drivers/video/omap2/dss/dss.c -@@ -23,6 +23,7 @@ - #define DSS_SUBSYS_NAME "DSS" - - #include <linux/kernel.h> -+#include <linux/module.h> - #include <linux/io.h> - #include <linux/export.h> - #include <linux/err.h> -@@ -33,6 +34,7 @@ - #include <linux/pm_runtime.h> - #include <linux/gfp.h> - #include <linux/sizes.h> -+#include <linux/clk-private.h> - - #include <video/omapdss.h> - -@@ -68,7 +70,8 @@ struct dss_features { - u8 fck_div_max; - u8 dss_fck_multiplier; - const char *clk_name; -- int (*dpi_select_source)(enum omap_channel channel); -+ int (*dpi_select_source)(int module_id, enum omap_channel channel); -+ bool dpll_clks; - }; - - static struct { -@@ -428,6 +431,28 @@ void dss_select_lcd_clk_source(enum omap - dss.lcd_clk_source[ix] = clk_src; - } - -+void dss_use_dpll_lcd(enum omap_channel channel, bool use_dpll) -+{ -+ u8 bit; -+ -+ switch (channel) { -+ case OMAP_DSS_CHANNEL_LCD: -+ bit = 0; -+ break; -+ case OMAP_DSS_CHANNEL_LCD2: -+ bit = 12; -+ break; -+ case OMAP_DSS_CHANNEL_LCD3: -+ bit = 19; -+ break; -+ case OMAP_DSS_CHANNEL_DIGIT: -+ default: -+ return; -+ } -+ -+ REG_FLD_MOD(DSS_CONTROL, use_dpll, bit, bit); -+} -+ - enum omap_dss_clk_source dss_get_dispc_clk_source(void) - { - return dss.dispc_clk_source; -@@ -466,7 +491,7 @@ int dss_calc_clock_rates(struct dss_cloc - cinfo->fck = prate / cinfo->fck_div * - dss.feat->dss_fck_multiplier; - } else { -- if (cinfo->fck_div != 0) -+ if (cinfo->fck_div != 1) - return -EINVAL; - cinfo->fck = clk_get_rate(dss.dss_clk); - } -@@ -529,7 +554,7 @@ int dss_set_clock_div(struct dss_clock_i - if (r) - return r; - } else { -- if (cinfo->fck_div != 0) -+ if (cinfo->fck_div != 1) - return -EINVAL; - } - -@@ -635,7 +660,8 @@ enum dss_hdmi_venc_clk_source_select dss - return REG_GET(DSS_CONTROL, 15, 15); - } - --static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel) -+static int dss_dpi_select_source_omap2_omap3(int module_id, -+ enum omap_channel channel) - { - if (channel != OMAP_DSS_CHANNEL_LCD) - return -EINVAL; -@@ -643,7 +669,7 @@ static int dss_dpi_select_source_omap2_o - return 0; - } - --static int dss_dpi_select_source_omap4(enum omap_channel channel) -+static int dss_dpi_select_source_omap4(int module_id, enum omap_channel channel) - { - int val; - -@@ -663,7 +689,7 @@ static int dss_dpi_select_source_omap4(e - return 0; - } - --static int dss_dpi_select_source_omap5(enum omap_channel channel) -+static int dss_dpi_select_source_omap5(int module_id, enum omap_channel channel) - { - int val; - -@@ -689,9 +715,17 @@ static int dss_dpi_select_source_omap5(e - return 0; - } - --int dss_dpi_select_source(enum omap_channel channel) -+static int dss_dpi_select_source_dra7xx(int module_id, enum omap_channel channel) -+{ -+ if (module_id != 0) -+ return 0; -+ -+ return dss_dpi_select_source_omap5(module_id, channel); -+} -+ -+int dss_dpi_select_source(int module_id, enum omap_channel channel) - { -- return dss.feat->dpi_select_source(channel); -+ return dss.feat->dpi_select_source(module_id, channel); - } - - static int dss_get_clocks(void) -@@ -713,11 +747,26 @@ static int dss_get_clocks(void) - return PTR_ERR(clk); - } - } else { -+ int r; -+ -+ DSSDBG("DSS CLOCK HACK\n"); -+ printk("FCK %s\n", clk->name); -+ -+ clk = clk_get_parent(clk); -+ DSSDBG("GATE %s\n", clk->name); -+ -+ clk = clk_get_parent(clk); -+ DSSDBG("PLL %s\n", clk->name); -+ -+ r = clk_set_rate(clk, 150000000); -+ if (!r) -+ DSSERR("SET CLK RATE Failed"); - clk = NULL; - } - - dss.dpll4_m4_ck = clk; - -+ - return 0; - } - -@@ -795,6 +844,21 @@ static const struct dss_features omap54x - .dpi_select_source = &dss_dpi_select_source_omap5, - }; - -+static const struct dss_features dra7xx_dss_feats __initconst = { -+ .fck_div_max = 64, -+ .dss_fck_multiplier = 1, -+ .clk_name = "dpll_per_h12x2_ck", -+ .dpi_select_source = &dss_dpi_select_source_dra7xx, -+ .dpll_clks = true, -+}; -+ -+static const struct dss_features am43xx_dss_feats __initconst = { -+ .fck_div_max = 0, -+ .dss_fck_multiplier = 0, -+ .clk_name = NULL, -+ .dpi_select_source = &dss_dpi_select_source_omap2_omap3, -+}; -+ - static int __init dss_init_features(struct platform_device *pdev) - { - const struct dss_features *src; -@@ -831,6 +895,14 @@ static int __init dss_init_features(stru - src = &omap54xx_dss_feats; - break; - -+ case OMAPDSS_VER_DRA7xx: -+ src = &dra7xx_dss_feats; -+ break; -+ -+ case OMAPDSS_VER_AM43xx: -+ src = &am43xx_dss_feats; -+ break; -+ - default: - return -ENODEV; - } -@@ -907,6 +979,15 @@ static int __init omap_dsshw_probe(struc - - dss_debugfs_create_file("dss", dss_dump_regs); - -+ if (dss.feat->dpll_clks) { -+ r = dss_dpll_configure(pdev); -+ if (r) -+ goto err_runtime_get; -+ r = dss_dpll_configure_ctrl(); -+ if (r) -+ goto err_runtime_get; -+ } -+ - return 0; - - err_runtime_get: -@@ -920,6 +1001,9 @@ static int __exit omap_dsshw_remove(stru - { - pm_runtime_disable(&pdev->dev); - -+ if (dss.feat->dpll_clks) -+ dss_dpll_unconfigure_ctrl(); -+ - dss_put_clocks(); - - return 0; -@@ -955,12 +1039,21 @@ static const struct dev_pm_ops dss_pm_op - .runtime_resume = dss_runtime_resume, - }; - -+static const struct of_device_id dss_of_match[] = { -+ { .compatible = "ti,omap3-dss", }, -+ { .compatible = "ti,omap4-dss", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, dss_of_match); -+ - static struct platform_driver omap_dsshw_driver = { - .remove = __exit_p(omap_dsshw_remove), - .driver = { - .name = "omapdss_dss", - .owner = THIS_MODULE, - .pm = &dss_pm_ops, -+ .of_match_table = dss_of_match, - }, - }; - ---- /dev/null -+++ b/drivers/video/omap2/dss/dss_dpll.c -@@ -0,0 +1,536 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Ltd -+ * -+ * Copy of the DSI PLL code -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/err.h> -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/clk.h> -+#include <linux/platform_device.h> -+#include <linux/regulator/consumer.h> -+#include <linux/sched.h> -+#include <linux/wait.h> -+ -+#include <video/omapdss.h> -+ -+#include "dss.h" -+#include "dss_features.h" -+ -+#define CLK_CTRL 0x054 -+#define PLL_CONTROL 0x300 -+#define PLL_STATUS 0x304 -+#define PLL_GO 0x308 -+#define PLL_CONFIGURATION1 0x30C -+#define PLL_CONFIGURATION2 0x310 -+#define PLL_CONFIGURATION3 0x314 -+#define PLL_SSC_CONFIGURATION1 0x318 -+#define PLL_SSC_CONFIGURATION2 0x31C -+ -+#define CTRL_BASE 0x4a002500 -+#define DSS_PLL_CONTROL 0x38 -+ -+#define REG_GET(dpll, idx, start, end) \ -+ FLD_GET(dpll_read_reg(dpll, idx), start, end) -+ -+#define REG_FLD_MOD(dpll, idx, val, start, end) \ -+ dpll_write_reg(dpll, idx, FLD_MOD(dpll_read_reg(dpll, idx), val, start, end)) -+ -+static struct { -+ struct platform_device *pdev; -+ struct regulator *vdda_video_reg; -+ -+ void __iomem *base[2], *control_base; -+ unsigned scp_refcount[2]; -+ struct clk *sys_clk[2]; -+ bool enabled[3]; -+} dss_dpll; -+ -+static inline u32 dpll_read_reg(enum dss_dpll dpll, u16 offset) -+{ -+ return __raw_readl(dss_dpll.base[dpll] + offset); -+} -+ -+static inline void dpll_write_reg(enum dss_dpll dpll, u16 offset, u32 val) -+{ -+ __raw_writel(val, dss_dpll.base[dpll] + offset); -+} -+ -+#define CTRL_REG_GET(start, end) \ -+ FLD_GET(ctrl_read_reg(), start, end) -+ -+#define CTRL_REG_FLD_MOD(val, start, end) \ -+ ctrl_write_reg(FLD_MOD(ctrl_read_reg(), val, start, end)) -+ -+static inline u32 ctrl_read_reg(void) -+{ -+ return __raw_readl(dss_dpll.control_base + DSS_PLL_CONTROL); -+} -+ -+static inline void ctrl_write_reg(u32 val) -+{ -+ __raw_writel(val, dss_dpll.control_base + DSS_PLL_CONTROL); -+} -+ -+static inline int wait_for_bit_change(enum dss_dpll dpll, -+ const u16 offset, int bitnum, int value) -+{ -+ unsigned long timeout; -+ ktime_t wait; -+ int t; -+ -+ /* first busyloop to see if the bit changes right away */ -+ t = 100; -+ while (t-- > 0) { -+ if (REG_GET(dpll, offset, bitnum, bitnum) == value) -+ return value; -+ } -+ -+ /* then loop for 500ms, sleeping for 1ms in between */ -+ timeout = jiffies + msecs_to_jiffies(500); -+ while (time_before(jiffies, timeout)) { -+ if (REG_GET(dpll, offset, bitnum, bitnum) == value) -+ return value; -+ -+ wait = ns_to_ktime(1000 * 1000); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_hrtimeout(&wait, HRTIMER_MODE_REL); -+ } -+ -+ return !value; -+} -+ -+bool dss_dpll_disabled(enum dss_dpll dpll) -+{ -+ return !dss_dpll.enabled[dpll]; -+} -+ -+unsigned long dpll_get_clkin(enum dss_dpll dpll) -+{ -+ return clk_get_rate(dss_dpll.sys_clk[dpll]); -+} -+ -+bool dss_dpll_calc(enum dss_dpll dpll, unsigned long clkin, -+ unsigned long pll_min, unsigned long pll_max, -+ dss_dpll_calc_func func, void *data) -+{ -+ int regn, regn_start, regn_stop; -+ int regm, regm_start, regm_stop; -+ unsigned long fint, pll; -+ const unsigned long pll_hw_max = 1800000000; -+ unsigned long fint_hw_min, fint_hw_max, regm_max, regn_max; -+ -+ fint_hw_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); -+ fint_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); -+ regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); -+ regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); -+ -+ regn_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); -+ regn_stop = min(clkin / fint_hw_min, regn_max); -+ -+ pll_max = pll_max ? pll_max : ULONG_MAX; -+ -+ for (regn = regn_start; regn <= regn_stop; ++regn) { -+ fint = clkin / regn; -+ -+ regm_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), -+ 1ul); -+ regm_stop = min3(pll_max / fint / 2, -+ pll_hw_max / fint / 2, -+ regm_max); -+ -+ for (regm = regm_start; regm <= regm_stop; ++regm) { -+ pll = 2 * regm * fint; -+ -+ if (func(regn, regm, fint, pll, data)) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+bool dss_dpll_hsdiv_calc(enum dss_dpll dpll, unsigned long pll, -+ unsigned long out_min, dss_dpll_hsdiv_calc_func func, void *data) -+{ -+ int regm, regm_start, regm_stop; -+ unsigned long out_max; -+ unsigned long out; -+ unsigned long regm_dispc_max; -+ -+ regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); -+ -+ out_min = out_min ? out_min : 1; -+ out_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); -+ -+ regm_start = max(DIV_ROUND_UP(pll, out_max), 1ul); -+ regm_stop = min(pll / out_min, regm_dispc_max); -+ -+ for (regm = regm_start; regm <= regm_stop; ++regm) { -+ out = pll / regm; -+ -+ if (func(regm, out, data)) -+ return true; -+ } -+ -+ return false; -+} -+ -+int dss_dpll_set_clock_div(enum dss_dpll dpll, struct dss_dpll_cinfo *cinfo) -+{ -+ int r = 0; -+ u32 l; -+ u8 regn_start, regn_end, regm_start, regm_end; -+ u8 regm_hsdiv_start, regm_hsdiv_end; -+ -+ DSSDBG("DPLL_VIDEO%d clock config starts\n", dpll + 1); -+ -+ DSSDBG("DPLL Fint %ld\n", cinfo->fint); -+ -+ DSSDBG("clkin rate %ld\n", cinfo->clkin); -+ -+ DSSDBG("CLKOUT = 2 * %d / %d * %lu = %lu\n", -+ cinfo->regm, -+ cinfo->regn, -+ cinfo->clkin, -+ cinfo->clkout); -+ -+ DSSDBG("regm_hsdiv = %d\n", cinfo->regm_hsdiv); -+ -+ dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, ®n_start, ®n_end); -+ dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, ®m_start, ®m_end); -+ dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, ®m_hsdiv_start, -+ ®m_hsdiv_end); -+ -+ /* PLL_AUTOMODE = manual */ -+ REG_FLD_MOD(dpll, PLL_CONTROL, 0, 0, 0); -+ -+ /* CONFIGURATION1 */ -+ l = dpll_read_reg(dpll, PLL_CONFIGURATION1); -+ /* PLL_REGN */ -+ l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end); -+ /* PLL_REGM */ -+ l = FLD_MOD(l, cinfo->regm, regm_start, regm_end); -+ /* M4_CLOCK_DIV */ -+ l = FLD_MOD(l, cinfo->regm_hsdiv > 0 ? cinfo->regm_hsdiv - 1 : 0, -+ regm_hsdiv_start, regm_hsdiv_end); -+ dpll_write_reg(dpll, PLL_CONFIGURATION1, l); -+ -+ /* CONFIGURATION3 */ -+ l = dpll_read_reg(dpll, PLL_CONFIGURATION3); -+ /* M6_CLOCK_DIV */ -+ l = FLD_MOD(l, cinfo->regm_hsdiv > 0 ? cinfo->regm_hsdiv - 1 : 0, 4, 0); -+ dpll_write_reg(dpll, PLL_CONFIGURATION3, l); -+ -+ /* CONFIGURATION2 */ -+ l = dpll_read_reg(dpll, PLL_CONFIGURATION2); -+ l = FLD_MOD(l, 1, 13, 13); /* PLL_REFEN */ -+ l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ -+ l = FLD_MOD(l, 1, 20, 20); /* HSDIVBYPASS */ -+ l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */ -+ dpll_write_reg(dpll, PLL_CONFIGURATION2, l); -+ -+ REG_FLD_MOD(dpll, PLL_GO, 1, 0, 0); /* PLL_GO */ -+ -+ if (wait_for_bit_change(dpll, PLL_GO, 0, 0) != 0) { -+ DSSERR("dsi pll go bit not going down.\n"); -+ r = -EIO; -+ goto err; -+ } -+ -+ if (wait_for_bit_change(dpll, PLL_STATUS, 1, 1) != 1) { -+ DSSERR("cannot lock PLL\n"); -+ r = -EIO; -+ goto err; -+ } -+ -+ l = dpll_read_reg(dpll, PLL_CONFIGURATION2); -+ l = FLD_MOD(l, 0, 0, 0); /* PLL_IDLE */ -+ l = FLD_MOD(l, 0, 5, 5); /* PLL_PLLLPMODE */ -+ l = FLD_MOD(l, 0, 6, 6); /* PLL_LOWCURRSTBY */ -+ l = FLD_MOD(l, 0, 7, 7); /* PLL_TIGHTPHASELOCK */ -+ l = FLD_MOD(l, 0, 8, 8); /* PLL_DRIFTGUARDEN */ -+ l = FLD_MOD(l, 0, 10, 9); /* PLL_LOCKSEL */ -+ l = FLD_MOD(l, 1, 13, 13); /* PLL_REFEN */ -+ l = FLD_MOD(l, 1, 14, 14); /* PHY_CLKINEN */ -+ l = FLD_MOD(l, 0, 15, 15); /* BYPASSEN */ -+ l = FLD_MOD(l, 1, 16, 16); /* M4_CLOCK_EN */ -+ l = FLD_MOD(l, 0, 17, 17); /* CLOCK_PWDN */ -+ l = FLD_MOD(l, 1, 18, 18); /* PROTO_CLOCK_EN */ -+ l = FLD_MOD(l, 0, 19, 19); /* PROTO_CLOCK_PWDN */ -+ l = FLD_MOD(l, 0, 20, 20); /* HSDIVBYPASS */ -+ l = FLD_MOD(l, 1, 23, 23); /* M6_CLOCK_EN */ -+ dpll_write_reg(dpll, PLL_CONFIGURATION2, l); -+ -+ DSSDBG("PLL config done\n"); -+ -+err: -+ return r; -+} -+ -+static void dss_dpll_disable_scp_clk(enum dss_dpll dpll) -+{ -+ unsigned *refcount; -+ -+ refcount = &dss_dpll.scp_refcount[dpll]; -+ -+ WARN_ON(*refcount == 0); -+ if (--(*refcount) == 0) -+ REG_FLD_MOD(dpll, CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */ -+} -+ -+static void dss_dpll_enable_scp_clk(enum dss_dpll dpll) -+{ -+ unsigned *refcount; -+ -+ refcount = &dss_dpll.scp_refcount[dpll]; -+ -+ if ((*refcount)++ == 0) -+ REG_FLD_MOD(dpll, CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */ -+} -+ -+static int dpll_power(enum dss_dpll dpll, int state) -+{ -+ int t = 0; -+ /* PLL_PWR_CMD = enable both hsdiv and clkout*/ -+ REG_FLD_MOD(dpll, CLK_CTRL, state, 31, 30); -+ -+ /* PLL_PWR_STATUS: (NOTE: apparently buggy) */ -+ while (FLD_GET(dpll_read_reg(dpll, CLK_CTRL), 29, 28) != state) { -+ if (++t > 1000) { -+ DSSERR("Failed to set DPLL power mode to %d\n", state); -+ /* return -ENODEV; */ -+ return 0; -+ } -+ udelay(1); -+ } -+ -+ return 0; -+} -+ -+void dss_dpll_enable_ctrl(enum dss_dpll dpll, bool enable) -+{ -+ u8 bit; -+ -+ switch (dpll) { -+ case DSS_DPLL_VIDEO1: -+ bit = 0; -+ break; -+ case DSS_DPLL_VIDEO2: -+ bit = 1; -+ break; -+ case DSS_DPLL_HDMI: -+ bit = 2; -+ break; -+ default: -+ DSSERR("invalid dpll\n"); -+ return; -+ } -+ -+ CTRL_REG_FLD_MOD(!enable, bit, bit); -+ -+ dss_dpll.enabled[dpll] = enable; -+} -+ -+static int dpll_init(enum dss_dpll dpll) -+{ -+ int r; -+ -+ clk_prepare_enable(dss_dpll.sys_clk[dpll]); -+ dss_dpll_enable_scp_clk(dpll); -+ -+ r = regulator_enable(dss_dpll.vdda_video_reg); -+ if (r) -+ goto err_reg; -+ -+ if (wait_for_bit_change(dpll, PLL_STATUS, 0, 1) != 1) { -+ DSSERR("PLL not coming out of reset.\n"); -+ r = -ENODEV; -+ goto err_reset; -+ } -+ -+ r = dpll_power(dpll, 0x2); -+ if (r) -+ goto err_reset; -+ -+ return 0; -+ -+err_reset: -+ regulator_disable(dss_dpll.vdda_video_reg); -+err_reg: -+ dss_dpll_disable_scp_clk(dpll); -+ clk_disable_unprepare(dss_dpll.sys_clk[dpll]); -+ -+ return r; -+} -+ -+int dss_dpll_activate(enum dss_dpll dpll) -+{ -+ int r; -+ -+ /* enable from control module */ -+ dss_dpll_enable_ctrl(dpll, true); -+ -+ r = dpll_init(dpll); -+ -+ return r; -+} -+ -+void dss_dpll_set_control_mux(enum omap_channel channel, enum dss_dpll dpll) -+{ -+ u8 start, end; -+ u8 val; -+ -+ if (channel == OMAP_DSS_CHANNEL_LCD) { -+ start = 4; -+ end = 3; -+ -+ switch (dpll) { -+ case DSS_DPLL_VIDEO1: -+ val = 0; -+ break; -+ default: -+ DSSERR("error in mux config for LCD\n"); -+ return; -+ } -+ } else if (channel == OMAP_DSS_CHANNEL_LCD2) { -+ start = 6; -+ end = 5; -+ -+ switch (dpll) { -+ case DSS_DPLL_VIDEO1: -+ val = 0; -+ break; -+ case DSS_DPLL_VIDEO2: -+ val = 1; -+ break; -+ default: -+ DSSERR("error in mux config for LCD2\n"); -+ return; -+ } -+ } else { -+ start = 8; -+ end = 7; -+ -+ switch (dpll) { -+ case DSS_DPLL_VIDEO1: -+ val = 1; -+ break; -+ case DSS_DPLL_VIDEO2: -+ val = 0; -+ break; -+ default: -+ DSSERR("error in mux config for LCD3\n"); -+ return; -+ } -+ } -+ -+ CTRL_REG_FLD_MOD(val, start, end); -+} -+ -+void dss_dpll_disable(enum dss_dpll dpll) -+{ -+ dpll_power(dpll, 0); -+ -+ regulator_disable(dss_dpll.vdda_video_reg); -+ -+ dss_dpll_disable_scp_clk(dpll); -+ clk_disable_unprepare(dss_dpll.sys_clk[dpll]); -+ -+ dss_dpll_enable_ctrl(dpll, false); -+} -+ -+static int dss_dpll_configure_one(struct platform_device *pdev, -+ enum dss_dpll dpll) -+{ -+ struct resource *dpll_mem; -+ -+ dpll_mem = platform_get_resource(pdev, IORESOURCE_MEM, dpll + 1); -+ if (!dpll_mem) { -+ DSSERR("can't get IORESOURCE_MEM for DPLL %d\n", dpll); -+ return -EINVAL; -+ } -+ -+ dss_dpll.base[dpll] = devm_ioremap(&pdev->dev, dpll_mem->start, -+ resource_size(dpll_mem)); -+ if (!dss_dpll.base[dpll]) { -+ DSSERR("can't ioremap DPLL %d\n", dpll); -+ return -ENOMEM; -+ } -+ -+ dss_dpll.sys_clk[dpll] = devm_clk_get(&pdev->dev, -+ dpll == DSS_DPLL_VIDEO1 ? "video1_clk" : "video2_clk"); -+ if (IS_ERR(dss_dpll.sys_clk[dpll])) { -+ DSSERR("can't get sys clock for DPLL_VIDEO%d\n", dpll + 1); -+ return PTR_ERR(dss_dpll.sys_clk[dpll]); -+ } -+ -+ return 0; -+} -+ -+int dss_dpll_init_regulator(enum dss_dpll dpll) -+{ -+ struct regulator *reg; -+ struct platform_device *pdev = dss_dpll.pdev; -+ -+ if (dpll == DSS_DPLL_NONE) -+ return 0; -+ -+ reg = devm_regulator_get(&pdev->dev, "vdda_video"); -+ if (IS_ERR(reg)) { -+ DSSERR("can't get vdda_video regulator\n"); -+ return PTR_ERR(reg); -+ } -+ -+ dss_dpll.vdda_video_reg = reg; -+ -+ return 0; -+} -+ -+int dss_dpll_configure(struct platform_device *pdev) -+{ -+ int r; -+ -+ r = dss_dpll_configure_one(pdev, DSS_DPLL_VIDEO1); -+ if (r) -+ return r; -+ -+ r = dss_dpll_configure_one(pdev, DSS_DPLL_VIDEO2); -+ if (r) -+ return r; -+ -+ dss_dpll.pdev = pdev; -+ -+ return 0; -+} -+ -+int dss_dpll_configure_ctrl(void) -+{ -+ dss_dpll.control_base = ioremap(CTRL_BASE, SZ_1K); -+ -+ if (!dss_dpll.control_base) { -+ DSSERR("can't ioremap control base\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+void dss_dpll_unconfigure_ctrl(void) { -+ if (dss_dpll.control_base) -+ iounmap(dss_dpll.control_base); -+} ---- a/drivers/video/omap2/dss/dss_features.c -+++ b/drivers/video/omap2/dss/dss_features.c -@@ -93,6 +93,17 @@ static const struct dss_reg_field omap3_ - [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 }, - }; - -+static const struct dss_reg_field am43xx_dss_reg_fields[] = { -+ [FEAT_REG_FIRHINC] = { 12, 0 }, -+ [FEAT_REG_FIRVINC] = { 28, 16 }, -+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 }, -+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 }, -+ [FEAT_REG_FIFOSIZE] = { 10, 0 }, -+ [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, -+ [FEAT_REG_VERTICALACCU] = { 25, 16 }, -+ [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, -+}; -+ - static const struct dss_reg_field omap4_dss_reg_fields[] = { - [FEAT_REG_FIRHINC] = { 12, 0 }, - [FEAT_REG_FIRVINC] = { 28, 16 }, -@@ -149,6 +160,11 @@ static const enum omap_display_type omap - OMAP_DISPLAY_TYPE_VENC, - }; - -+static const enum omap_display_type am43xx_dss_supported_displays[] = { -+ /* OMAP_DSS_CHANNEL_LCD */ -+ OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, -+}; -+ - static const enum omap_display_type omap4_dss_supported_displays[] = { - /* OMAP_DSS_CHANNEL_LCD */ - OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, -@@ -174,6 +190,20 @@ static const enum omap_display_type omap - OMAP_DISPLAY_TYPE_DSI, - }; - -+static const enum omap_display_type dra7xx_dss_supported_displays[] = { -+ /* OMAP_DSS_CHANNEL_LCD */ -+ OMAP_DISPLAY_TYPE_DPI, -+ -+ /* OMAP_DSS_CHANNEL_DIGIT */ -+ OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI, -+ -+ /* OMAP_DSS_CHANNEL_LCD2 */ -+ OMAP_DISPLAY_TYPE_DPI, -+ -+ /* OMAP_DSS_CHANNEL_LCD3 */ -+ OMAP_DISPLAY_TYPE_DPI, -+}; -+ - static const enum omap_dss_output_id omap2_dss_supported_outputs[] = { - /* OMAP_DSS_CHANNEL_LCD */ - OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, -@@ -200,6 +230,11 @@ static const enum omap_dss_output_id oma - OMAP_DSS_OUTPUT_VENC, - }; - -+static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = { -+ /* OMAP_DSS_CHANNEL_LCD */ -+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, -+}; -+ - static const enum omap_dss_output_id omap4_dss_supported_outputs[] = { - /* OMAP_DSS_CHANNEL_LCD */ - OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1, -@@ -229,6 +264,20 @@ static const enum omap_dss_output_id oma - OMAP_DSS_OUTPUT_DSI2, - }; - -+static const enum omap_dss_output_id dra7xx_dss_supported_outputs[] = { -+ /* OMAP_DSS_CHANNEL_LCD */ -+ OMAP_DSS_OUTPUT_DPI, -+ -+ /* OMAP_DSS_CHANNEL_DIGIT */ -+ OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI, -+ -+ /* OMAP_DSS_CHANNEL_LCD2 */ -+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DPI1, -+ -+ /* OMAP_DSS_CHANNEL_LCD3 */ -+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DPI2, -+}; -+ - static const enum omap_color_mode omap2_dss_supported_color_modes[] = { - /* OMAP_DSS_GFX */ - OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | -@@ -444,6 +493,13 @@ static const struct dss_param_range omap - [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, - }; - -+static const struct dss_param_range am43xx_dss_param_range[] = { -+ [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, -+ [FEAT_PARAM_DSS_PCD] = { 2, 255 }, -+ [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, -+ [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, -+}; -+ - static const struct dss_param_range omap4_dss_param_range[] = { - [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, - [FEAT_PARAM_DSS_PCD] = { 1, 255 }, -@@ -520,6 +576,21 @@ static const enum dss_feat_id am35xx_dss - FEAT_OMAP3_DSI_FIFO_BUG, - }; - -+static const enum dss_feat_id am43xx_dss_feat_list[] = { -+ FEAT_LCDENABLEPOL, -+ FEAT_LCDENABLESIGNAL, -+ FEAT_PCKFREEENABLE, -+ FEAT_FUNCGATED, -+ FEAT_LINEBUFFERSPLIT, -+ FEAT_ROWREPEATENABLE, -+ FEAT_RESIZECONF, -+ FEAT_CPR, -+ FEAT_PRELOAD, -+ FEAT_FIR_COEF_V, -+ FEAT_ALPHA_FIXED_ZORDER, -+ FEAT_FIFO_MERGE, -+}; -+ - static const enum dss_feat_id omap3630_dss_feat_list[] = { - FEAT_LCDENABLEPOL, - FEAT_LCDENABLESIGNAL, -@@ -595,6 +666,7 @@ static const enum dss_feat_id omap4_dss_ - - static const enum dss_feat_id omap5_dss_feat_list[] = { - FEAT_MGR_LCD2, -+ FEAT_MGR_LCD3, - FEAT_CORE_CLK_DIV, - FEAT_LCD_CLK_SRC, - FEAT_DSI_DCS_CMD_CONFIG_VC, -@@ -681,6 +753,26 @@ static const struct omap_dss_features am - .burst_size_unit = 8, - }; - -+static const struct omap_dss_features am43xx_dss_features = { -+ .reg_fields = am43xx_dss_reg_fields, -+ .num_reg_fields = ARRAY_SIZE(am43xx_dss_reg_fields), -+ -+ .features = am43xx_dss_feat_list, -+ .num_features = ARRAY_SIZE(am43xx_dss_feat_list), -+ -+ .num_mgrs = 1, -+ .num_ovls = 3, -+ .supported_displays = am43xx_dss_supported_displays, -+ .supported_outputs = am43xx_dss_supported_outputs, -+ .supported_color_modes = omap3_dss_supported_color_modes, -+ .overlay_caps = omap3430_dss_overlay_caps, -+ .clksrc_names = omap2_dss_clk_source_names, -+ .dss_params = am43xx_dss_param_range, -+ .supported_rotation_types = OMAP_DSS_ROT_DMA, -+ .buffer_size_unit = 1, -+ .burst_size_unit = 8, -+}; -+ - static const struct omap_dss_features omap3630_dss_features = { - .reg_fields = omap3_dss_reg_fields, - .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), -@@ -789,49 +881,26 @@ static const struct omap_dss_features om - .burst_size_unit = 16, - }; - --#if defined(CONFIG_OMAP4_DSS_HDMI) --/* HDMI OMAP4 Functions*/ --static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { -- -- .video_configure = ti_hdmi_4xxx_basic_configure, -- .phy_enable = ti_hdmi_4xxx_phy_enable, -- .phy_disable = ti_hdmi_4xxx_phy_disable, -- .read_edid = ti_hdmi_4xxx_read_edid, -- .pll_enable = ti_hdmi_4xxx_pll_enable, -- .pll_disable = ti_hdmi_4xxx_pll_disable, -- .video_enable = ti_hdmi_4xxx_wp_video_start, -- .video_disable = ti_hdmi_4xxx_wp_video_stop, -- .dump_wrapper = ti_hdmi_4xxx_wp_dump, -- .dump_core = ti_hdmi_4xxx_core_dump, -- .dump_pll = ti_hdmi_4xxx_pll_dump, -- .dump_phy = ti_hdmi_4xxx_phy_dump, --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -- .audio_enable = ti_hdmi_4xxx_wp_audio_enable, -- .audio_disable = ti_hdmi_4xxx_wp_audio_disable, -- .audio_start = ti_hdmi_4xxx_audio_start, -- .audio_stop = ti_hdmi_4xxx_audio_stop, -- .audio_config = ti_hdmi_4xxx_audio_config, -- .audio_get_dma_port = ti_hdmi_4xxx_audio_get_dma_port, --#endif -- --}; -+/* DRA DSS Features */ -+static const struct omap_dss_features dra7xx_dss_features = { -+ .reg_fields = omap5_dss_reg_fields, -+ .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields), - --void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data, -- enum omapdss_version version) --{ -- switch (version) { -- case OMAPDSS_VER_OMAP4430_ES1: -- case OMAPDSS_VER_OMAP4430_ES2: -- case OMAPDSS_VER_OMAP4: -- ip_data->ops = &omap4_hdmi_functions; -- break; -- default: -- ip_data->ops = NULL; -- } -+ .features = omap5_dss_feat_list, -+ .num_features = ARRAY_SIZE(omap5_dss_feat_list), - -- WARN_ON(ip_data->ops == NULL); --} --#endif -+ .num_mgrs = 4, -+ .num_ovls = 4, -+ .supported_displays = dra7xx_dss_supported_displays, -+ .supported_outputs = dra7xx_dss_supported_outputs, -+ .supported_color_modes = omap4_dss_supported_color_modes, -+ .overlay_caps = omap4_dss_overlay_caps, -+ .clksrc_names = omap5_dss_clk_source_names, -+ .dss_params = omap5_dss_param_range, -+ .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, -+ .buffer_size_unit = 16, -+ .burst_size_unit = 16, -+}; - - /* Functions returning values related to a DSS feature */ - int dss_feat_get_num_mgrs(void) -@@ -967,10 +1036,18 @@ void dss_features_init(enum omapdss_vers - omap_current_dss_features = &omap5_dss_features; - break; - -+ case OMAPDSS_VER_DRA7xx: -+ omap_current_dss_features = &dra7xx_dss_features; -+ break; -+ - case OMAPDSS_VER_AM35xx: - omap_current_dss_features = &am35xx_dss_features; - break; - -+ case OMAPDSS_VER_AM43xx: -+ omap_current_dss_features = &am43xx_dss_features; -+ break; -+ - default: - DSSWARN("Unsupported OMAP version"); - break; ---- a/drivers/video/omap2/dss/dss_features.h -+++ b/drivers/video/omap2/dss/dss_features.h -@@ -20,10 +20,6 @@ - #ifndef __OMAP2_DSS_FEATURES_H - #define __OMAP2_DSS_FEATURES_H - --#if defined(CONFIG_OMAP4_DSS_HDMI) --#include "ti_hdmi.h" --#endif -- - #define MAX_DSS_MANAGERS 4 - #define MAX_DSS_OVERLAYS 4 - #define MAX_DSS_LCD_MANAGERS 3 -@@ -117,8 +113,4 @@ bool dss_feat_rotation_type_supported(en - bool dss_has_feature(enum dss_feat_id id); - void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); - void dss_features_init(enum omapdss_version version); --#if defined(CONFIG_OMAP4_DSS_HDMI) --void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data, -- enum omapdss_version version); --#endif - #endif ---- a/drivers/video/omap2/dss/dss.h -+++ b/drivers/video/omap2/dss/dss.h -@@ -100,6 +100,13 @@ enum dss_writeback_channel { - DSS_WB_LCD3_MGR = 7, - }; - -+enum dss_dpll { -+ DSS_DPLL_VIDEO1 = 0, -+ DSS_DPLL_VIDEO2, -+ DSS_DPLL_HDMI, -+ DSS_DPLL_NONE, -+}; -+ - struct dss_clock_info { - /* rates that we get with dividers below */ - unsigned long fck; -@@ -139,6 +146,12 @@ struct dsi_clock_info { - u16 lp_clk_div; - }; - -+struct dss_dpll_cinfo { -+ unsigned long fint, clkin, clkout, hsdiv_clk; -+ -+ u16 regm, regn, regm_hsdiv; -+}; -+ - struct reg_field { - u16 reg; - u8 high; -@@ -223,9 +236,10 @@ int dss_init_platform_driver(void) __ini - void dss_uninit_platform_driver(void); - - unsigned long dss_get_dispc_clk_rate(void); --int dss_dpi_select_source(enum omap_channel channel); -+int dss_dpi_select_source(int module_id, enum omap_channel channel); - void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); - enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); -+void dss_use_dpll_lcd(enum omap_channel channel, bool use_dpll); - const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); - void dss_dump_clocks(struct seq_file *s); - -@@ -372,6 +386,10 @@ static inline bool dsi_pll_calc(struct p - int dpi_init_platform_driver(void) __init; - void dpi_uninit_platform_driver(void) __exit; - -+/* DRA7x DPI */ -+int dra7xx_dpi_init_platform_driver(void) __init; -+void dra7xx_dpi_uninit_platform_driver(void) __exit; -+ - /* DISPC */ - int dispc_init_platform_driver(void) __init; - void dispc_uninit_platform_driver(void) __exit; -@@ -398,12 +416,6 @@ unsigned long dispc_fclk_rate(void); - int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, - struct dispc_clock_info *cinfo); - -- --void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); --void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, -- u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, -- bool manual_update); -- - unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); - unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); - unsigned long dispc_core_clk_rate(void); -@@ -427,8 +439,11 @@ int venc_init_platform_driver(void) __in - void venc_uninit_platform_driver(void) __exit; - - /* HDMI */ --int hdmi_init_platform_driver(void) __init; --void hdmi_uninit_platform_driver(void) __exit; -+int hdmi4_init_platform_driver(void) __init; -+void hdmi4_uninit_platform_driver(void) __exit; -+ -+int hdmi5_init_platform_driver(void) __init; -+void hdmi5_uninit_platform_driver(void) __exit; - - /* RFBI */ - int rfbi_init_platform_driver(void) __init; -@@ -446,4 +461,27 @@ static inline void dss_collect_irq_stats - } - #endif - -+typedef bool (*dss_dpll_calc_func)(int regn, int regm, unsigned long fint, -+ unsigned long pll, void *data); -+typedef bool (*dss_dpll_hsdiv_calc_func)(int regm_dispc, unsigned long dispc, -+ void *data); -+bool dss_dpll_disabled(enum dss_dpll dpll); -+unsigned long dpll_get_clkin(enum dss_dpll dpll); -+bool dss_dpll_calc(enum dss_dpll dpll, unsigned long clkin, -+ unsigned long pll_min, unsigned long pll_max, -+ dss_dpll_calc_func func, void *data); -+bool dss_dpll_hsdiv_calc(enum dss_dpll dpll, unsigned long pll, -+ unsigned long out_min, dss_dpll_hsdiv_calc_func func, -+ void *data); -+int dss_dpll_set_clock_div(enum dss_dpll dpll, struct dss_dpll_cinfo *cinfo); -+ -+void dss_dpll_enable_ctrl(enum dss_dpll dpll, bool enable); -+int dss_dpll_activate(enum dss_dpll dpll); -+void dss_dpll_set_control_mux(enum omap_channel channel, enum dss_dpll dpll); -+void dss_dpll_disable(enum dss_dpll dpll); -+int dss_dpll_init_regulator(enum dss_dpll dpll); -+int dss_dpll_configure(struct platform_device *pdev); -+int dss_dpll_configure_ctrl(void); -+void dss_dpll_unconfigure_ctrl(void); -+ - #endif ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi4.c -@@ -0,0 +1,761 @@ -+/* -+ * HDMI interface DSS driver for TI's OMAP4 family of SoCs. -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * Authors: Yong Zhi -+ * Mythri pk <mythripk@ti.com> -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#define DSS_SUBSYS_NAME "HDMI" -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/interrupt.h> -+#include <linux/mutex.h> -+#include <linux/delay.h> -+#include <linux/string.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/clk.h> -+#include <linux/gpio.h> -+#include <linux/regulator/consumer.h> -+#include <video/omapdss.h> -+ -+#include "hdmi4_core.h" -+#include "dss.h" -+#include "dss_features.h" -+ -+static struct { -+ struct mutex lock; -+ struct platform_device *pdev; -+ -+ struct hdmi_wp_data wp; -+ struct hdmi_pll_data pll; -+ struct hdmi_phy_data phy; -+ struct hdmi_core_data core; -+ -+ struct hdmi_config cfg; -+ -+ struct clk *sys_clk; -+ struct regulator *vdda_hdmi_dac_reg; -+ -+ bool core_enabled; -+ -+ struct omap_dss_device output; -+} hdmi; -+ -+static int hdmi_runtime_get(void) -+{ -+ int r; -+ -+ DSSDBG("hdmi_runtime_get\n"); -+ -+ r = pm_runtime_get_sync(&hdmi.pdev->dev); -+ WARN_ON(r < 0); -+ if (r < 0) -+ return r; -+ -+ return 0; -+} -+ -+static void hdmi_runtime_put(void) -+{ -+ int r; -+ -+ DSSDBG("hdmi_runtime_put\n"); -+ -+ r = pm_runtime_put_sync(&hdmi.pdev->dev); -+ WARN_ON(r < 0 && r != -ENOSYS); -+} -+ -+static irqreturn_t hdmi_irq_handler(int irq, void *data) -+{ -+ struct hdmi_wp_data *wp = data; -+ u32 irqstatus; -+ -+ irqstatus = hdmi_wp_get_irqstatus(wp); -+ hdmi_wp_set_irqstatus(wp, irqstatus); -+ -+ if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && -+ irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -+ /* -+ * If we get both connect and disconnect interrupts at the same -+ * time, turn off the PHY, clear interrupts, and restart, which -+ * raises connect interrupt if a cable is connected, or nothing -+ * if cable is not connected. -+ */ -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); -+ -+ hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | -+ HDMI_IRQ_LINK_DISCONNECT); -+ -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); -+ } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); -+ } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int hdmi_init_regulator(void) -+{ -+ int r; -+ struct regulator *reg; -+ -+ if (hdmi.vdda_hdmi_dac_reg != NULL) -+ return 0; -+ -+ reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); -+ if (IS_ERR(reg)) { -+ DSSERR("can't get VDDA_HDMI_DAC regulator\n"); -+ return PTR_ERR(reg); -+ } -+ -+ r = regulator_set_voltage(reg, 1800000, 1980000); -+ if (r) -+ DSSWARN("can't set the regulator voltage"); -+ -+ hdmi.vdda_hdmi_dac_reg = reg; -+ -+ return 0; -+} -+ -+static int hdmi_power_on_core(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ r = regulator_enable(hdmi.vdda_hdmi_dac_reg); -+ if (r) -+ return r; -+ -+ r = hdmi_runtime_get(); -+ if (r) -+ goto err_runtime_get; -+ -+ /* Make selection of HDMI in DSS */ -+ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); -+ -+ hdmi.core_enabled = true; -+ -+ return 0; -+ -+err_runtime_get: -+ regulator_disable(hdmi.vdda_hdmi_dac_reg); -+ -+ return r; -+} -+ -+static void hdmi_power_off_core(struct omap_dss_device *dssdev) -+{ -+ hdmi.core_enabled = false; -+ -+ hdmi_runtime_put(); -+ regulator_disable(hdmi.vdda_hdmi_dac_reg); -+} -+ -+static int hdmi_power_on_full(struct omap_dss_device *dssdev) -+{ -+ int r; -+ struct omap_video_timings *p; -+ struct omap_overlay_manager *mgr = hdmi.output.manager; -+ unsigned long phy; -+ struct hdmi_wp_data *wp = &hdmi.wp; -+ -+ r = hdmi_power_on_core(dssdev); -+ if (r) -+ return r; -+ -+ /* disable and clear irqs */ -+ hdmi_wp_clear_irqenable(wp, 0xffffffff); -+ hdmi_wp_set_irqstatus(wp, 0xffffffff); -+ -+ p = &hdmi.cfg.timings; -+ -+ DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); -+ -+ phy = p->pixel_clock; -+ -+ hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy); -+ -+ /* config the PLL and PHY hdmi_set_pll_pwrfirst */ -+ r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp); -+ if (r) { -+ DSSDBG("Failed to lock PLL\n"); -+ goto err_pll_enable; -+ } -+ -+ r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); -+ if (r) { -+ DSSDBG("Failed to configure PHY\n"); -+ goto err_phy_cfg; -+ } -+ -+ r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); -+ if (r) -+ goto err_phy_pwr; -+ -+ hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); -+ -+ /* bypass TV gamma table */ -+ dispc_enable_gamma_table(0); -+ -+ /* tv size */ -+ dss_mgr_set_timings(mgr, p); -+ -+ r = hdmi_wp_video_start(&hdmi.wp); -+ if (r) -+ goto err_vid_enable; -+ -+ r = dss_mgr_enable(mgr); -+ if (r) -+ goto err_mgr_enable; -+ -+ hdmi_wp_set_irqenable(wp, -+ HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); -+ -+ return 0; -+ -+err_mgr_enable: -+ hdmi_wp_video_stop(&hdmi.wp); -+err_vid_enable: -+err_phy_cfg: -+ hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); -+err_phy_pwr: -+ hdmi_pll_disable(&hdmi.pll, &hdmi.wp); -+err_pll_enable: -+ hdmi_power_off_core(dssdev); -+ return -EIO; -+} -+ -+static void hdmi_power_off_full(struct omap_dss_device *dssdev) -+{ -+ struct omap_overlay_manager *mgr = hdmi.output.manager; -+ -+ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); -+ -+ dss_mgr_disable(mgr); -+ -+ hdmi_wp_video_stop(&hdmi.wp); -+ -+ hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); -+ -+ hdmi_pll_disable(&hdmi.pll, &hdmi.wp); -+ -+ hdmi_power_off_core(dssdev); -+} -+ -+static int hdmi_display_check_timing(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct hdmi_cm cm; -+ -+ cm = hdmi_get_code(timings); -+ if (cm.code == -1) -+ return -EINVAL; -+ -+ return 0; -+ -+} -+ -+static void hdmi_display_set_timing(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct hdmi_cm cm; -+ const struct hdmi_config *t; -+ -+ mutex_lock(&hdmi.lock); -+ -+ cm = hdmi_get_code(timings); -+ hdmi.cfg.cm = cm; -+ -+ t = hdmi_get_timings(cm.mode, cm.code); -+ if (t != NULL) { -+ hdmi.cfg = *t; -+ -+ dispc_set_tv_pclk(t->timings.pixel_clock * 1000); -+ } -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+static void hdmi_display_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ const struct hdmi_config *cfg; -+ struct hdmi_cm cm = hdmi.cfg.cm; -+ -+ cfg = hdmi_get_timings(cm.mode, cm.code); -+ if (cfg == NULL) -+ cfg = hdmi_default_timing(); -+ -+ memcpy(timings, &cfg->timings, sizeof(cfg->timings)); -+} -+ -+static void hdmi_dump_regs(struct seq_file *s) -+{ -+ mutex_lock(&hdmi.lock); -+ -+ if (hdmi_runtime_get()) { -+ mutex_unlock(&hdmi.lock); -+ return; -+ } -+ -+ hdmi_wp_dump(&hdmi.wp, s); -+ hdmi_pll_dump(&hdmi.pll, s); -+ hdmi_phy_dump(&hdmi.phy, s); -+ hdmi4_core_dump(&hdmi.core, s); -+ -+ hdmi_runtime_put(); -+ mutex_unlock(&hdmi.lock); -+} -+ -+static int read_edid(u8 *buf, int len) -+{ -+ int r; -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = hdmi_runtime_get(); -+ BUG_ON(r); -+ -+ r = hdmi4_read_edid(&hdmi.core, buf, len); -+ -+ hdmi_runtime_put(); -+ mutex_unlock(&hdmi.lock); -+ -+ return r; -+} -+ -+static int hdmi_display_enable(struct omap_dss_device *dssdev) -+{ -+ struct omap_dss_device *out = &hdmi.output; -+ int r = 0; -+ -+ DSSDBG("ENTER hdmi_display_enable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ if (out == NULL || out->manager == NULL) { -+ DSSERR("failed to enable display: no output/manager\n"); -+ r = -ENODEV; -+ goto err0; -+ } -+ -+ r = hdmi_power_on_full(dssdev); -+ if (r) { -+ DSSERR("failed to power on device\n"); -+ goto err0; -+ } -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err0: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static void hdmi_display_disable(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("Enter hdmi_display_disable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ hdmi_power_off_full(dssdev); -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+static int hdmi_core_enable(struct omap_dss_device *dssdev) -+{ -+ int r = 0; -+ -+ DSSDBG("ENTER omapdss_hdmi_core_enable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = hdmi_power_on_core(dssdev); -+ if (r) { -+ DSSERR("failed to power on device\n"); -+ goto err0; -+ } -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err0: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static void hdmi_core_disable(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("Enter omapdss_hdmi_core_disable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ hdmi_power_off_core(dssdev); -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+static int hdmi_get_clocks(struct platform_device *pdev) -+{ -+ struct clk *clk; -+ -+ clk = devm_clk_get(&pdev->dev, "sys_clk"); -+ if (IS_ERR(clk)) { -+ DSSERR("can't get sys_clk\n"); -+ return PTR_ERR(clk); -+ } -+ -+ hdmi.sys_clk = clk; -+ -+ return 0; -+} -+ -+static int hdmi_connect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct omap_overlay_manager *mgr; -+ int r; -+ -+ r = hdmi_init_regulator(); -+ if (r) -+ return r; -+ -+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); -+ if (!mgr) -+ return -ENODEV; -+ -+ r = dss_mgr_connect(mgr, dssdev); -+ if (r) -+ return r; -+ -+ r = omapdss_output_set_device(dssdev, dst); -+ if (r) { -+ DSSERR("failed to connect output to new device: %s\n", -+ dst->name); -+ dss_mgr_disconnect(mgr, dssdev); -+ return r; -+ } -+ -+ return 0; -+} -+ -+static void hdmi_disconnect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ WARN_ON(dst != dssdev->dst); -+ -+ if (dst != dssdev->dst) -+ return; -+ -+ omapdss_output_unset_device(dssdev); -+ -+ if (dssdev->manager) -+ dss_mgr_disconnect(dssdev->manager, dssdev); -+} -+ -+static int hdmi_read_edid(struct omap_dss_device *dssdev, -+ u8 *edid, int len) -+{ -+ bool need_enable; -+ int r; -+ -+ need_enable = hdmi.core_enabled == false; -+ -+ if (need_enable) { -+ r = hdmi_core_enable(dssdev); -+ if (r) -+ return r; -+ } -+ -+ r = read_edid(edid, len); -+ -+ if (need_enable) -+ hdmi_core_disable(dssdev); -+ -+ return r; -+} -+ -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -+static int hdmi_audio_enable(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ mutex_lock(&hdmi.lock); -+ -+ if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { -+ r = -EPERM; -+ goto err; -+ } -+ -+ r = hdmi_wp_audio_enable(&hdmi.wp, true); -+ if (r) -+ goto err; -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static void hdmi_audio_disable(struct omap_dss_device *dssdev) -+{ -+ hdmi_wp_audio_enable(&hdmi.wp, false); -+} -+ -+static int hdmi_audio_start(struct omap_dss_device *dssdev) -+{ -+ return hdmi4_audio_start(&hdmi.core, &hdmi.wp); -+} -+ -+static void hdmi_audio_stop(struct omap_dss_device *dssdev) -+{ -+ hdmi4_audio_stop(&hdmi.core, &hdmi.wp); -+} -+ -+static bool hdmi_audio_supported(struct omap_dss_device *dssdev) -+{ -+ bool r; -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); -+ -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static int hdmi_audio_config(struct omap_dss_device *dssdev, -+ struct omap_dss_audio *audio) -+{ -+ int r; -+ u32 pclk = hdmi.cfg.timings.pixel_clock; -+ -+ mutex_lock(&hdmi.lock); -+ -+ if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { -+ r = -EPERM; -+ goto err; -+ } -+ -+ r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, audio, pclk); -+ if (r) -+ goto err; -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+#else -+static int hdmi_audio_enable(struct omap_dss_device *dssdev) -+{ -+ return -EPERM; -+} -+ -+static void hdmi_audio_disable(struct omap_dss_device *dssdev) -+{ -+} -+ -+static int hdmi_audio_start(struct omap_dss_device *dssdev) -+{ -+ return -EPERM; -+} -+ -+static void hdmi_audio_stop(struct omap_dss_device *dssdev) -+{ -+} -+ -+static bool hdmi_audio_supported(struct omap_dss_device *dssdev) -+{ -+ return false; -+} -+ -+static int hdmi_audio_config(struct omap_dss_device *dssdev, -+ struct omap_dss_audio *audio) -+{ -+ return -EPERM; -+} -+#endif -+ -+static const struct omapdss_hdmi_ops hdmi_ops = { -+ .connect = hdmi_connect, -+ .disconnect = hdmi_disconnect, -+ -+ .enable = hdmi_display_enable, -+ .disable = hdmi_display_disable, -+ -+ .check_timings = hdmi_display_check_timing, -+ .set_timings = hdmi_display_set_timing, -+ .get_timings = hdmi_display_get_timings, -+ -+ .read_edid = hdmi_read_edid, -+ -+ .audio_enable = hdmi_audio_enable, -+ .audio_disable = hdmi_audio_disable, -+ .audio_start = hdmi_audio_start, -+ .audio_stop = hdmi_audio_stop, -+ .audio_supported = hdmi_audio_supported, -+ .audio_config = hdmi_audio_config, -+}; -+ -+static void hdmi_init_output(struct platform_device *pdev) -+{ -+ struct omap_dss_device *out = &hdmi.output; -+ -+ out->dev = &pdev->dev; -+ out->id = OMAP_DSS_OUTPUT_HDMI; -+ out->output_type = OMAP_DISPLAY_TYPE_HDMI; -+ out->name = "hdmi.0"; -+ out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; -+ out->ops.hdmi = &hdmi_ops; -+ out->owner = THIS_MODULE; -+ -+ omapdss_register_output(out); -+} -+ -+static void __exit hdmi_uninit_output(struct platform_device *pdev) -+{ -+ struct omap_dss_device *out = &hdmi.output; -+ -+ omapdss_unregister_output(out); -+} -+ -+/* HDMI HW IP initialisation */ -+static int omapdss_hdmihw_probe(struct platform_device *pdev) -+{ -+ int r; -+ int irq; -+ -+ hdmi.pdev = pdev; -+ -+ mutex_init(&hdmi.lock); -+ -+ r = hdmi_wp_init(pdev, &hdmi.wp); -+ if (r) -+ return r; -+ -+ r = hdmi_pll_init(pdev, &hdmi.pll); -+ if (r) -+ return r; -+ -+ r = hdmi_phy_init(pdev, &hdmi.phy); -+ if (r) -+ return r; -+ -+ r = hdmi4_core_init(pdev, &hdmi.core); -+ if (r) -+ return r; -+ -+ r = hdmi_get_clocks(pdev); -+ if (r) { -+ DSSERR("can't get clocks\n"); -+ return r; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ DSSERR("platform_get_irq failed\n"); -+ return -ENODEV; -+ } -+ -+ r = devm_request_threaded_irq(&pdev->dev, irq, -+ NULL, hdmi_irq_handler, -+ IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); -+ if (r) { -+ DSSERR("HDMI IRQ request failed\n"); -+ return r; -+ } -+ -+ pm_runtime_enable(&pdev->dev); -+ -+ hdmi_init_output(pdev); -+ -+ dss_debugfs_create_file("hdmi", hdmi_dump_regs); -+ -+ return 0; -+} -+ -+static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) -+{ -+ hdmi_uninit_output(pdev); -+ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+static int hdmi_runtime_suspend(struct device *dev) -+{ -+ clk_disable_unprepare(hdmi.sys_clk); -+ -+ dispc_runtime_put(); -+ -+ return 0; -+} -+ -+static int hdmi_runtime_resume(struct device *dev) -+{ -+ int r; -+ -+ r = dispc_runtime_get(); -+ if (r < 0) -+ return r; -+ -+ clk_prepare_enable(hdmi.sys_clk); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops hdmi_pm_ops = { -+ .runtime_suspend = hdmi_runtime_suspend, -+ .runtime_resume = hdmi_runtime_resume, -+}; -+ -+static const struct of_device_id hdmi_of_match[] = { -+ { .compatible = "ti,omap4-hdmi", }, -+ {}, -+}; -+ -+static struct platform_driver omapdss_hdmihw_driver = { -+ .probe = omapdss_hdmihw_probe, -+ .remove = __exit_p(omapdss_hdmihw_remove), -+ .driver = { -+ .name = "omapdss_hdmi", -+ .owner = THIS_MODULE, -+ .pm = &hdmi_pm_ops, -+ .of_match_table = hdmi_of_match, -+ }, -+}; -+ -+int __init hdmi4_init_platform_driver(void) -+{ -+ return platform_driver_register(&omapdss_hdmihw_driver); -+} -+ -+void __exit hdmi4_uninit_platform_driver(void) -+{ -+ platform_driver_unregister(&omapdss_hdmihw_driver); -+} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi4_core.c -@@ -0,0 +1,1016 @@ -+/* -+ * ti_hdmi_4xxx_ip.c -+ * -+ * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * Authors: Yong Zhi -+ * Mythri pk <mythripk@ti.com> -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/interrupt.h> -+#include <linux/mutex.h> -+#include <linux/delay.h> -+#include <linux/platform_device.h> -+#include <linux/string.h> -+#include <linux/seq_file.h> -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -+#include <sound/asound.h> -+#include <sound/asoundef.h> -+#endif -+ -+#include "hdmi4_core.h" -+#include "dss_features.h" -+ -+#define HDMI_CORE_AV 0x500 -+ -+static inline void __iomem *hdmi_av_base(struct hdmi_core_data *core) -+{ -+ return core->base + HDMI_CORE_AV; -+} -+ -+static int hdmi_core_ddc_init(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ -+ /* Turn on CLK for DDC */ -+ REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0); -+ -+ /* IN_PROG */ -+ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) { -+ /* Abort transaction */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0); -+ /* IN_PROG */ -+ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -+ 4, 4, 0) != 0) { -+ DSSERR("Timeout aborting DDC transaction\n"); -+ return -ETIMEDOUT; -+ } -+ } -+ -+ /* Clk SCL Devices */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0); -+ -+ /* HDMI_CORE_DDC_STATUS_IN_PROG */ -+ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -+ 4, 4, 0) != 0) { -+ DSSERR("Timeout starting SCL clock\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Clear FIFO */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0); -+ -+ /* HDMI_CORE_DDC_STATUS_IN_PROG */ -+ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -+ 4, 4, 0) != 0) { -+ DSSERR("Timeout clearing DDC fifo\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int hdmi_core_ddc_edid(struct hdmi_core_data *core, -+ u8 *pedid, int ext) -+{ -+ void __iomem *base = core->base; -+ u32 i; -+ char checksum; -+ u32 offset = 0; -+ -+ /* HDMI_CORE_DDC_STATUS_IN_PROG */ -+ if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -+ 4, 4, 0) != 0) { -+ DSSERR("Timeout waiting DDC to be ready\n"); -+ return -ETIMEDOUT; -+ } -+ -+ if (ext % 2 != 0) -+ offset = 0x80; -+ -+ /* Load Segment Address Register */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0); -+ -+ /* Load Slave Address Register */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); -+ -+ /* Load Offset Address Register */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0); -+ -+ /* Load Byte Count */ -+ REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); -+ -+ /* Set DDC_CMD */ -+ if (ext) -+ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0); -+ else -+ REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0); -+ -+ /* HDMI_CORE_DDC_STATUS_BUS_LOW */ -+ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) { -+ pr_err("I2C Bus Low?\n"); -+ return -EIO; -+ } -+ /* HDMI_CORE_DDC_STATUS_NO_ACK */ -+ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) { -+ pr_err("I2C No Ack\n"); -+ return -EIO; -+ } -+ -+ for (i = 0; i < 0x80; ++i) { -+ int t; -+ -+ /* IN_PROG */ -+ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) { -+ DSSERR("operation stopped when reading edid\n"); -+ return -EIO; -+ } -+ -+ t = 0; -+ /* FIFO_EMPTY */ -+ while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) { -+ if (t++ > 10000) { -+ DSSERR("timeout reading edid\n"); -+ return -ETIMEDOUT; -+ } -+ udelay(1); -+ } -+ -+ pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); -+ } -+ -+ checksum = 0; -+ for (i = 0; i < 0x80; ++i) -+ checksum += pedid[i]; -+ -+ if (checksum != 0) { -+ pr_err("E-EDID checksum failed!!\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len) -+{ -+ int r, l; -+ -+ if (len < 128) -+ return -EINVAL; -+ -+ r = hdmi_core_ddc_init(core); -+ if (r) -+ return r; -+ -+ r = hdmi_core_ddc_edid(core, edid, 0); -+ if (r) -+ return r; -+ -+ l = 128; -+ -+ if (len >= 128 * 2 && edid[0x7e] > 0) { -+ r = hdmi_core_ddc_edid(core, edid + 0x80, 1); -+ if (r) -+ return r; -+ l += 128; -+ } -+ -+ return l; -+} -+ -+static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, -+ struct hdmi_core_infoframe_avi *avi_cfg, -+ struct hdmi_core_packet_enable_repeat *repeat_cfg) -+{ -+ pr_debug("Enter hdmi_core_init\n"); -+ -+ /* video core */ -+ video_cfg->ip_bus_width = HDMI_INPUT_8BIT; -+ video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT; -+ video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE; -+ video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; -+ video_cfg->hdmi_dvi = HDMI_DVI; -+ video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; -+ -+ /* info frame */ -+ avi_cfg->db1_format = 0; -+ avi_cfg->db1_active_info = 0; -+ avi_cfg->db1_bar_info_dv = 0; -+ avi_cfg->db1_scan_info = 0; -+ avi_cfg->db2_colorimetry = 0; -+ avi_cfg->db2_aspect_ratio = 0; -+ avi_cfg->db2_active_fmt_ar = 0; -+ avi_cfg->db3_itc = 0; -+ avi_cfg->db3_ec = 0; -+ avi_cfg->db3_q_range = 0; -+ avi_cfg->db3_nup_scaling = 0; -+ avi_cfg->db4_videocode = 0; -+ avi_cfg->db5_pixel_repeat = 0; -+ avi_cfg->db6_7_line_eoftop = 0; -+ avi_cfg->db8_9_line_sofbottom = 0; -+ avi_cfg->db10_11_pixel_eofleft = 0; -+ avi_cfg->db12_13_pixel_sofright = 0; -+ -+ /* packet enable and repeat */ -+ repeat_cfg->audio_pkt = 0; -+ repeat_cfg->audio_pkt_repeat = 0; -+ repeat_cfg->avi_infoframe = 0; -+ repeat_cfg->avi_infoframe_repeat = 0; -+ repeat_cfg->gen_cntrl_pkt = 0; -+ repeat_cfg->gen_cntrl_pkt_repeat = 0; -+ repeat_cfg->generic_pkt = 0; -+ repeat_cfg->generic_pkt_repeat = 0; -+} -+ -+static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) -+{ -+ pr_debug("Enter hdmi_core_powerdown_disable\n"); -+ REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0); -+} -+ -+static void hdmi_core_swreset_release(struct hdmi_core_data *core) -+{ -+ pr_debug("Enter hdmi_core_swreset_release\n"); -+ REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0); -+} -+ -+static void hdmi_core_swreset_assert(struct hdmi_core_data *core) -+{ -+ pr_debug("Enter hdmi_core_swreset_assert\n"); -+ REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0); -+} -+ -+/* HDMI_CORE_VIDEO_CONFIG */ -+static void hdmi_core_video_config(struct hdmi_core_data *core, -+ struct hdmi_core_video_config *cfg) -+{ -+ u32 r = 0; -+ void __iomem *core_sys_base = core->base; -+ void __iomem *core_av_base = hdmi_av_base(core); -+ -+ /* sys_ctrl1 default configuration not tunable */ -+ r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1); -+ r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC, 5, 5); -+ r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC, 4, 4); -+ r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS, 2, 2); -+ r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE, 1, 1); -+ hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1, r); -+ -+ REG_FLD_MOD(core_sys_base, -+ HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); -+ -+ /* Vid_Mode */ -+ r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE); -+ -+ /* dither truncation configuration */ -+ if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) { -+ r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6); -+ r = FLD_MOD(r, 1, 5, 5); -+ } else { -+ r = FLD_MOD(r, cfg->op_dither_truc, 7, 6); -+ r = FLD_MOD(r, 0, 5, 5); -+ } -+ hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r); -+ -+ /* HDMI_Ctrl */ -+ r = hdmi_read_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL); -+ r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6); -+ r = FLD_MOD(r, cfg->pkt_mode, 5, 3); -+ r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); -+ hdmi_write_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL, r); -+ -+ /* TMDS_CTRL */ -+ REG_FLD_MOD(core_sys_base, -+ HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); -+} -+ -+static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) -+{ -+ u32 val; -+ char sum = 0, checksum = 0; -+ void __iomem *av_base = hdmi_av_base(core); -+ struct hdmi_core_infoframe_avi info_avi = core->avi_cfg; -+ -+ sum += 0x82 + 0x002 + 0x00D; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D); -+ -+ val = (info_avi.db1_format << 5) | -+ (info_avi.db1_active_info << 4) | -+ (info_avi.db1_bar_info_dv << 2) | -+ (info_avi.db1_scan_info); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val); -+ sum += val; -+ -+ val = (info_avi.db2_colorimetry << 6) | -+ (info_avi.db2_aspect_ratio << 4) | -+ (info_avi.db2_active_fmt_ar); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val); -+ sum += val; -+ -+ val = (info_avi.db3_itc << 7) | -+ (info_avi.db3_ec << 4) | -+ (info_avi.db3_q_range << 2) | -+ (info_avi.db3_nup_scaling); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val); -+ sum += val; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3), -+ info_avi.db4_videocode); -+ sum += info_avi.db4_videocode; -+ -+ val = info_avi.db5_pixel_repeat; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val); -+ sum += val; -+ -+ val = info_avi.db6_7_line_eoftop & 0x00FF; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val); -+ sum += val; -+ -+ val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val); -+ sum += val; -+ -+ val = info_avi.db8_9_line_sofbottom & 0x00FF; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val); -+ sum += val; -+ -+ val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val); -+ sum += val; -+ -+ val = info_avi.db10_11_pixel_eofleft & 0x00FF; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val); -+ sum += val; -+ -+ val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val); -+ sum += val; -+ -+ val = info_avi.db12_13_pixel_sofright & 0x00FF; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val); -+ sum += val; -+ -+ val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val); -+ sum += val; -+ -+ checksum = 0x100 - sum; -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum); -+} -+ -+static void hdmi_core_av_packet_config(struct hdmi_core_data *core, -+ struct hdmi_core_packet_enable_repeat repeat_cfg) -+{ -+ /* enable/repeat the infoframe */ -+ hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL1, -+ (repeat_cfg.audio_pkt << 5) | -+ (repeat_cfg.audio_pkt_repeat << 4) | -+ (repeat_cfg.avi_infoframe << 1) | -+ (repeat_cfg.avi_infoframe_repeat)); -+ -+ /* enable/repeat the packet */ -+ hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL2, -+ (repeat_cfg.gen_cntrl_pkt << 3) | -+ (repeat_cfg.gen_cntrl_pkt_repeat << 2) | -+ (repeat_cfg.generic_pkt << 1) | -+ (repeat_cfg.generic_pkt_repeat)); -+} -+ -+void hdmi4_configure(struct hdmi_core_data *core, -+ struct hdmi_wp_data *wp, struct hdmi_config *cfg) -+{ -+ /* HDMI */ -+ struct omap_video_timings video_timing; -+ struct hdmi_video_format video_format; -+ /* HDMI core */ -+ struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg; -+ struct hdmi_core_video_config v_core_cfg; -+ struct hdmi_core_packet_enable_repeat repeat_cfg; -+ -+ hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); -+ -+ hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); -+ -+ hdmi_wp_video_config_timing(wp, &video_timing); -+ -+ /* video config */ -+ video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; -+ -+ hdmi_wp_video_config_format(wp, &video_format); -+ -+ hdmi_wp_video_config_interface(wp, &video_timing); -+ -+ /* -+ * configure core video part -+ * set software reset in the core -+ */ -+ hdmi_core_swreset_assert(core); -+ -+ /* power down off */ -+ hdmi_core_powerdown_disable(core); -+ -+ v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; -+ v_core_cfg.hdmi_dvi = cfg->cm.mode; -+ -+ hdmi_core_video_config(core, &v_core_cfg); -+ -+ /* release software reset in the core */ -+ hdmi_core_swreset_release(core); -+ -+ /* -+ * configure packet -+ * info frame video see doc CEA861-D page 65 -+ */ -+ avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; -+ avi_cfg->db1_active_info = -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; -+ avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; -+ avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; -+ avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; -+ avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; -+ avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; -+ avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; -+ avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; -+ avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; -+ avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; -+ avi_cfg->db4_videocode = cfg->cm.code; -+ avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; -+ avi_cfg->db6_7_line_eoftop = 0; -+ avi_cfg->db8_9_line_sofbottom = 0; -+ avi_cfg->db10_11_pixel_eofleft = 0; -+ avi_cfg->db12_13_pixel_sofright = 0; -+ -+ hdmi_core_aux_infoframe_avi_config(core); -+ -+ /* enable/repeat the infoframe */ -+ repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; -+ repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; -+ /* wakeup */ -+ repeat_cfg.audio_pkt = HDMI_PACKETENABLE; -+ repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; -+ hdmi_core_av_packet_config(core, repeat_cfg); -+} -+ -+void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s) -+{ -+ int i; -+ -+#define CORE_REG(i, name) name(i) -+#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ -+ hdmi_read_reg(core->base, r)) -+#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ -+ hdmi_read_reg(hdmi_av_base(core), r)) -+#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ -+ (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \ -+ hdmi_read_reg(hdmi_av_base(core), CORE_REG(i, r))) -+ -+ DUMPCORE(HDMI_CORE_SYS_VND_IDL); -+ DUMPCORE(HDMI_CORE_SYS_DEV_IDL); -+ DUMPCORE(HDMI_CORE_SYS_DEV_IDH); -+ DUMPCORE(HDMI_CORE_SYS_DEV_REV); -+ DUMPCORE(HDMI_CORE_SYS_SRST); -+ DUMPCORE(HDMI_CORE_SYS_SYS_CTRL1); -+ DUMPCORE(HDMI_CORE_SYS_SYS_STAT); -+ DUMPCORE(HDMI_CORE_SYS_SYS_CTRL3); -+ DUMPCORE(HDMI_CORE_SYS_DE_DLY); -+ DUMPCORE(HDMI_CORE_SYS_DE_CTRL); -+ DUMPCORE(HDMI_CORE_SYS_DE_TOP); -+ DUMPCORE(HDMI_CORE_SYS_DE_CNTL); -+ DUMPCORE(HDMI_CORE_SYS_DE_CNTH); -+ DUMPCORE(HDMI_CORE_SYS_DE_LINL); -+ DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); -+ DUMPCORE(HDMI_CORE_SYS_HRES_L); -+ DUMPCORE(HDMI_CORE_SYS_HRES_H); -+ DUMPCORE(HDMI_CORE_SYS_VRES_L); -+ DUMPCORE(HDMI_CORE_SYS_VRES_H); -+ DUMPCORE(HDMI_CORE_SYS_IADJUST); -+ DUMPCORE(HDMI_CORE_SYS_POLDETECT); -+ DUMPCORE(HDMI_CORE_SYS_HWIDTH1); -+ DUMPCORE(HDMI_CORE_SYS_HWIDTH2); -+ DUMPCORE(HDMI_CORE_SYS_VWIDTH); -+ DUMPCORE(HDMI_CORE_SYS_VID_CTRL); -+ DUMPCORE(HDMI_CORE_SYS_VID_ACEN); -+ DUMPCORE(HDMI_CORE_SYS_VID_MODE); -+ DUMPCORE(HDMI_CORE_SYS_VID_BLANK1); -+ DUMPCORE(HDMI_CORE_SYS_VID_BLANK3); -+ DUMPCORE(HDMI_CORE_SYS_VID_BLANK1); -+ DUMPCORE(HDMI_CORE_SYS_DC_HEADER); -+ DUMPCORE(HDMI_CORE_SYS_VID_DITHER); -+ DUMPCORE(HDMI_CORE_SYS_RGB2XVYCC_CT); -+ DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_LOW); -+ DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_UP); -+ DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_LOW); -+ DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_UP); -+ DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_LOW); -+ DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_UP); -+ DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_LOW); -+ DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_UP); -+ DUMPCORE(HDMI_CORE_SYS_INTR_STATE); -+ DUMPCORE(HDMI_CORE_SYS_INTR1); -+ DUMPCORE(HDMI_CORE_SYS_INTR2); -+ DUMPCORE(HDMI_CORE_SYS_INTR3); -+ DUMPCORE(HDMI_CORE_SYS_INTR4); -+ DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK1); -+ DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK2); -+ DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK3); -+ DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK4); -+ DUMPCORE(HDMI_CORE_SYS_INTR_CTRL); -+ DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL); -+ -+ DUMPCORE(HDMI_CORE_DDC_ADDR); -+ DUMPCORE(HDMI_CORE_DDC_SEGM); -+ DUMPCORE(HDMI_CORE_DDC_OFFSET); -+ DUMPCORE(HDMI_CORE_DDC_COUNT1); -+ DUMPCORE(HDMI_CORE_DDC_COUNT2); -+ DUMPCORE(HDMI_CORE_DDC_STATUS); -+ DUMPCORE(HDMI_CORE_DDC_CMD); -+ DUMPCORE(HDMI_CORE_DDC_DATA); -+ -+ DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL); -+ DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL); -+ DUMPCOREAV(HDMI_CORE_AV_N_SVAL1); -+ DUMPCOREAV(HDMI_CORE_AV_N_SVAL2); -+ DUMPCOREAV(HDMI_CORE_AV_N_SVAL3); -+ DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1); -+ DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2); -+ DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3); -+ DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1); -+ DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2); -+ DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3); -+ DUMPCOREAV(HDMI_CORE_AV_AUD_MODE); -+ DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL); -+ DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS); -+ DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S); -+ DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5); -+ DUMPCOREAV(HDMI_CORE_AV_ASRC); -+ DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN); -+ DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL); -+ DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT); -+ DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); -+ DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); -+ DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); -+ DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL); -+ DUMPCOREAV(HDMI_CORE_AV_DPD); -+ DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1); -+ DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2); -+ DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE); -+ DUMPCOREAV(HDMI_CORE_AV_AVI_VERS); -+ DUMPCOREAV(HDMI_CORE_AV_AVI_LEN); -+ DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM); -+ -+ for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++) -+ DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE); -+ -+ DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE); -+ DUMPCOREAV(HDMI_CORE_AV_SPD_VERS); -+ DUMPCOREAV(HDMI_CORE_AV_SPD_LEN); -+ DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM); -+ -+ for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++) -+ DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE); -+ -+ DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE); -+ DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS); -+ DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN); -+ DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM); -+ -+ for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++) -+ DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE); -+ -+ DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE); -+ DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS); -+ DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN); -+ DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM); -+ -+ for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++) -+ DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE); -+ -+ for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++) -+ DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE); -+ -+ DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1); -+ -+ for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++) -+ DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE); -+ -+ DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); -+} -+ -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -+static void hdmi_core_audio_config(struct hdmi_core_data *core, -+ struct hdmi_core_audio_config *cfg) -+{ -+ u32 r; -+ void __iomem *av_base = hdmi_av_base(core); -+ -+ /* -+ * Parameters for generation of Audio Clock Recovery packets -+ */ -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); -+ -+ if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) { -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0); -+ REG_FLD_MOD(av_base, -+ HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0); -+ REG_FLD_MOD(av_base, -+ HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); -+ } else { -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, -+ cfg->aud_par_busclk, 7, 0); -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, -+ (cfg->aud_par_busclk >> 8), 7, 0); -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3, -+ (cfg->aud_par_busclk >> 16), 7, 0); -+ } -+ -+ /* Set ACR clock divisor */ -+ REG_FLD_MOD(av_base, -+ HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0); -+ -+ r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); -+ /* -+ * Use TMDS clock for ACR packets. For devices that use -+ * the MCLK, this is the first part of the MCLK initialization. -+ */ -+ r = FLD_MOD(r, 0, 2, 2); -+ -+ r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1); -+ r = FLD_MOD(r, cfg->cts_mode, 0, 0); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r); -+ -+ /* For devices using MCLK, this completes its initialization. */ -+ if (cfg->use_mclk) -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2); -+ -+ /* Override of SPDIF sample frequency with value in I2S_CHST4 */ -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, -+ cfg->fs_override, 1, 1); -+ -+ /* -+ * Set IEC-60958-3 channel status word. It is passed to the IP -+ * just as it is received. The user of the driver is responsible -+ * for its contents. -+ */ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0, -+ cfg->iec60958_cfg->status[0]); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1, -+ cfg->iec60958_cfg->status[1]); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2, -+ cfg->iec60958_cfg->status[2]); -+ /* yes, this is correct: status[3] goes to CHST4 register */ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4, -+ cfg->iec60958_cfg->status[3]); -+ /* yes, this is correct: status[4] goes to CHST5 register */ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, -+ cfg->iec60958_cfg->status[4]); -+ -+ /* set I2S parameters */ -+ r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); -+ r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); -+ r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); -+ r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); -+ r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); -+ r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); -+ -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, -+ cfg->i2s_cfg.in_length_bits, 3, 0); -+ -+ /* Audio channels and mode parameters */ -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1); -+ r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE); -+ r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4); -+ r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3); -+ r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); -+ r = FLD_MOD(r, cfg->en_spdif, 1, 1); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); -+ -+ /* Audio channel mappings */ -+ /* TODO: Make channel mapping dynamic. For now, map channels -+ * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as -+ * HDMI speaker order is different. See CEA-861 Section 6.6.2. -+ */ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78); -+ REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5); -+} -+ -+static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core, -+ struct snd_cea_861_aud_if *info_aud) -+{ -+ u8 sum = 0, checksum = 0; -+ void __iomem *av_base = hdmi_av_base(core); -+ -+ /* -+ * Set audio info frame type, version and length as -+ * described in HDMI 1.4a Section 8.2.2 specification. -+ * Checksum calculation is defined in Section 5.3.5. -+ */ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); -+ sum += 0x84 + 0x001 + 0x00a; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), -+ info_aud->db1_ct_cc); -+ sum += info_aud->db1_ct_cc; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), -+ info_aud->db2_sf_ss); -+ sum += info_aud->db2_sf_ss; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); -+ sum += info_aud->db3; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); -+ sum += info_aud->db4_ca; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), -+ info_aud->db5_dminh_lsv); -+ sum += info_aud->db5_dminh_lsv; -+ -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00); -+ hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00); -+ -+ checksum = 0x100 - sum; -+ hdmi_write_reg(av_base, -+ HDMI_CORE_AV_AUDIO_CHSUM, checksum); -+ -+ /* -+ * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing -+ * is available. -+ */ -+} -+ -+int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct omap_dss_audio *audio, u32 pclk) -+{ -+ struct hdmi_audio_format audio_format; -+ struct hdmi_audio_dma audio_dma; -+ struct hdmi_core_audio_config acore; -+ int err, n, cts, channel_count; -+ unsigned int fs_nr; -+ bool word_length_16b = false; -+ -+ if (!audio || !audio->iec || !audio->cea || !core) -+ return -EINVAL; -+ -+ acore.iec60958_cfg = audio->iec; -+ /* -+ * In the IEC-60958 status word, check if the audio sample word length -+ * is 16-bit as several optimizations can be performed in such case. -+ */ -+ if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)) -+ if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16) -+ word_length_16b = true; -+ -+ /* I2S configuration. See Phillips' specification */ -+ if (word_length_16b) -+ acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; -+ else -+ acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; -+ /* -+ * The I2S input word length is twice the lenght given in the IEC-60958 -+ * status word. If the word size is greater than -+ * 20 bits, increment by one. -+ */ -+ acore.i2s_cfg.in_length_bits = audio->iec->status[4] -+ & IEC958_AES4_CON_WORDLEN; -+ if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) -+ acore.i2s_cfg.in_length_bits++; -+ acore.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; -+ acore.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; -+ acore.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; -+ acore.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; -+ -+ /* convert sample frequency to a number */ -+ switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { -+ case IEC958_AES3_CON_FS_32000: -+ fs_nr = 32000; -+ break; -+ case IEC958_AES3_CON_FS_44100: -+ fs_nr = 44100; -+ break; -+ case IEC958_AES3_CON_FS_48000: -+ fs_nr = 48000; -+ break; -+ case IEC958_AES3_CON_FS_88200: -+ fs_nr = 88200; -+ break; -+ case IEC958_AES3_CON_FS_96000: -+ fs_nr = 96000; -+ break; -+ case IEC958_AES3_CON_FS_176400: -+ fs_nr = 176400; -+ break; -+ case IEC958_AES3_CON_FS_192000: -+ fs_nr = 192000; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ err = hdmi_compute_acr(pclk, fs_nr, &n, &cts); -+ -+ /* Audio clock regeneration settings */ -+ acore.n = n; -+ acore.cts = cts; -+ if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { -+ acore.aud_par_busclk = 0; -+ acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW; -+ acore.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); -+ } else { -+ acore.aud_par_busclk = (((128 * 31) - 1) << 8); -+ acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW; -+ acore.use_mclk = true; -+ } -+ -+ if (acore.use_mclk) -+ acore.mclk_mode = HDMI_AUDIO_MCLK_128FS; -+ -+ /* Audio channels settings */ -+ channel_count = (audio->cea->db1_ct_cc & -+ CEA861_AUDIO_INFOFRAME_DB1CC) + 1; -+ -+ switch (channel_count) { -+ case 2: -+ audio_format.active_chnnls_msk = 0x03; -+ break; -+ case 3: -+ audio_format.active_chnnls_msk = 0x07; -+ break; -+ case 4: -+ audio_format.active_chnnls_msk = 0x0f; -+ break; -+ case 5: -+ audio_format.active_chnnls_msk = 0x1f; -+ break; -+ case 6: -+ audio_format.active_chnnls_msk = 0x3f; -+ break; -+ case 7: -+ audio_format.active_chnnls_msk = 0x7f; -+ break; -+ case 8: -+ audio_format.active_chnnls_msk = 0xff; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* -+ * the HDMI IP needs to enable four stereo channels when transmitting -+ * more than 2 audio channels -+ */ -+ if (channel_count == 2) { -+ audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; -+ acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; -+ acore.layout = HDMI_AUDIO_LAYOUT_2CH; -+ } else { -+ audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS; -+ acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN | -+ HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | -+ HDMI_AUDIO_I2S_SD3_EN; -+ acore.layout = HDMI_AUDIO_LAYOUT_8CH; -+ } -+ -+ acore.en_spdif = false; -+ /* use sample frequency from channel status word */ -+ acore.fs_override = true; -+ /* enable ACR packets */ -+ acore.en_acr_pkt = true; -+ /* disable direct streaming digital audio */ -+ acore.en_dsd_audio = false; -+ /* use parallel audio interface */ -+ acore.en_parallel_aud_input = true; -+ -+ /* DMA settings */ -+ if (word_length_16b) -+ audio_dma.transfer_size = 0x10; -+ else -+ audio_dma.transfer_size = 0x20; -+ audio_dma.block_size = 0xC0; -+ audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; -+ audio_dma.fifo_threshold = 0x20; /* in number of samples */ -+ -+ /* audio FIFO format settings */ -+ if (word_length_16b) { -+ audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; -+ audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; -+ audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; -+ } else { -+ audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; -+ audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; -+ audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; -+ } -+ audio_format.type = HDMI_AUDIO_TYPE_LPCM; -+ audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; -+ /* disable start/stop signals of IEC 60958 blocks */ -+ audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; -+ -+ /* configure DMA and audio FIFO format*/ -+ hdmi_wp_audio_config_dma(wp, &audio_dma); -+ hdmi_wp_audio_config_format(wp, &audio_format); -+ -+ /* configure the core*/ -+ hdmi_core_audio_config(core, &acore); -+ -+ /* configure CEA 861 audio infoframe*/ -+ hdmi_core_audio_infoframe_cfg(core, audio->cea); -+ -+ return 0; -+} -+ -+int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp) -+{ -+ REG_FLD_MOD(hdmi_av_base(core), -+ HDMI_CORE_AV_AUD_MODE, true, 0, 0); -+ -+ hdmi_wp_audio_core_req_enable(wp, true); -+ -+ return 0; -+} -+ -+void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp) -+{ -+ REG_FLD_MOD(hdmi_av_base(core), -+ HDMI_CORE_AV_AUD_MODE, false, 0, 0); -+ -+ hdmi_wp_audio_core_req_enable(wp, false); -+} -+ -+int hdmi4_audio_get_dma_port(u32 *offset, u32 *size) -+{ -+ if (!offset || !size) -+ return -EINVAL; -+ *offset = HDMI_WP_AUDIO_DATA; -+ *size = 4; -+ return 0; -+} -+ -+#endif -+ -+int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) -+{ -+ struct resource *res; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_core"); -+ if (!res) { -+ DSSERR("can't get CORE IORESOURCE_MEM HDMI\n"); -+ return -EINVAL; -+ } -+ -+ core->base = devm_request_and_ioremap(&pdev->dev, res); -+ if (!core->base) { -+ DSSERR("can't ioremap HDMI core\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi4_core.h -@@ -0,0 +1,276 @@ -+/* -+ * HDMI header definition for OMAP4 HDMI core IP -+ * -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef _HDMI4_CORE_H_ -+#define _HDMI4_CORE_H_ -+ -+#include "hdmi.h" -+ -+/* OMAP4 HDMI IP Core System */ -+ -+#define HDMI_CORE_SYS_VND_IDL 0x0 -+#define HDMI_CORE_SYS_DEV_IDL 0x8 -+#define HDMI_CORE_SYS_DEV_IDH 0xC -+#define HDMI_CORE_SYS_DEV_REV 0x10 -+#define HDMI_CORE_SYS_SRST 0x14 -+#define HDMI_CORE_SYS_SYS_CTRL1 0x20 -+#define HDMI_CORE_SYS_SYS_STAT 0x24 -+#define HDMI_CORE_SYS_SYS_CTRL3 0x28 -+#define HDMI_CORE_SYS_DCTL 0x34 -+#define HDMI_CORE_SYS_DE_DLY 0xC8 -+#define HDMI_CORE_SYS_DE_CTRL 0xCC -+#define HDMI_CORE_SYS_DE_TOP 0xD0 -+#define HDMI_CORE_SYS_DE_CNTL 0xD8 -+#define HDMI_CORE_SYS_DE_CNTH 0xDC -+#define HDMI_CORE_SYS_DE_LINL 0xE0 -+#define HDMI_CORE_SYS_DE_LINH_1 0xE4 -+#define HDMI_CORE_SYS_HRES_L 0xE8 -+#define HDMI_CORE_SYS_HRES_H 0xEC -+#define HDMI_CORE_SYS_VRES_L 0xF0 -+#define HDMI_CORE_SYS_VRES_H 0xF4 -+#define HDMI_CORE_SYS_IADJUST 0xF8 -+#define HDMI_CORE_SYS_POLDETECT 0xFC -+#define HDMI_CORE_SYS_HWIDTH1 0x110 -+#define HDMI_CORE_SYS_HWIDTH2 0x114 -+#define HDMI_CORE_SYS_VWIDTH 0x11C -+#define HDMI_CORE_SYS_VID_CTRL 0x120 -+#define HDMI_CORE_SYS_VID_ACEN 0x124 -+#define HDMI_CORE_SYS_VID_MODE 0x128 -+#define HDMI_CORE_SYS_VID_BLANK1 0x12C -+#define HDMI_CORE_SYS_VID_BLANK2 0x130 -+#define HDMI_CORE_SYS_VID_BLANK3 0x134 -+#define HDMI_CORE_SYS_DC_HEADER 0x138 -+#define HDMI_CORE_SYS_VID_DITHER 0x13C -+#define HDMI_CORE_SYS_RGB2XVYCC_CT 0x140 -+#define HDMI_CORE_SYS_R2Y_COEFF_LOW 0x144 -+#define HDMI_CORE_SYS_R2Y_COEFF_UP 0x148 -+#define HDMI_CORE_SYS_G2Y_COEFF_LOW 0x14C -+#define HDMI_CORE_SYS_G2Y_COEFF_UP 0x150 -+#define HDMI_CORE_SYS_B2Y_COEFF_LOW 0x154 -+#define HDMI_CORE_SYS_B2Y_COEFF_UP 0x158 -+#define HDMI_CORE_SYS_R2CB_COEFF_LOW 0x15C -+#define HDMI_CORE_SYS_R2CB_COEFF_UP 0x160 -+#define HDMI_CORE_SYS_G2CB_COEFF_LOW 0x164 -+#define HDMI_CORE_SYS_G2CB_COEFF_UP 0x168 -+#define HDMI_CORE_SYS_B2CB_COEFF_LOW 0x16C -+#define HDMI_CORE_SYS_B2CB_COEFF_UP 0x170 -+#define HDMI_CORE_SYS_R2CR_COEFF_LOW 0x174 -+#define HDMI_CORE_SYS_R2CR_COEFF_UP 0x178 -+#define HDMI_CORE_SYS_G2CR_COEFF_LOW 0x17C -+#define HDMI_CORE_SYS_G2CR_COEFF_UP 0x180 -+#define HDMI_CORE_SYS_B2CR_COEFF_LOW 0x184 -+#define HDMI_CORE_SYS_B2CR_COEFF_UP 0x188 -+#define HDMI_CORE_SYS_RGB_OFFSET_LOW 0x18C -+#define HDMI_CORE_SYS_RGB_OFFSET_UP 0x190 -+#define HDMI_CORE_SYS_Y_OFFSET_LOW 0x194 -+#define HDMI_CORE_SYS_Y_OFFSET_UP 0x198 -+#define HDMI_CORE_SYS_CBCR_OFFSET_LOW 0x19C -+#define HDMI_CORE_SYS_CBCR_OFFSET_UP 0x1A0 -+#define HDMI_CORE_SYS_INTR_STATE 0x1C0 -+#define HDMI_CORE_SYS_INTR1 0x1C4 -+#define HDMI_CORE_SYS_INTR2 0x1C8 -+#define HDMI_CORE_SYS_INTR3 0x1CC -+#define HDMI_CORE_SYS_INTR4 0x1D0 -+#define HDMI_CORE_SYS_INTR_UNMASK1 0x1D4 -+#define HDMI_CORE_SYS_INTR_UNMASK2 0x1D8 -+#define HDMI_CORE_SYS_INTR_UNMASK3 0x1DC -+#define HDMI_CORE_SYS_INTR_UNMASK4 0x1E0 -+#define HDMI_CORE_SYS_INTR_CTRL 0x1E4 -+#define HDMI_CORE_SYS_TMDS_CTRL 0x208 -+ -+/* value definitions for HDMI_CORE_SYS_SYS_CTRL1 fields */ -+#define HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC 0x1 -+#define HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC 0x1 -+#define HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS 0x1 -+#define HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE 0x1 -+ -+/* HDMI DDC E-DID */ -+#define HDMI_CORE_DDC_ADDR 0x3B4 -+#define HDMI_CORE_DDC_SEGM 0x3B8 -+#define HDMI_CORE_DDC_OFFSET 0x3BC -+#define HDMI_CORE_DDC_COUNT1 0x3C0 -+#define HDMI_CORE_DDC_COUNT2 0x3C4 -+#define HDMI_CORE_DDC_STATUS 0x3C8 -+#define HDMI_CORE_DDC_CMD 0x3CC -+#define HDMI_CORE_DDC_DATA 0x3D0 -+ -+/* HDMI IP Core Audio Video */ -+ -+#define HDMI_CORE_AV_ACR_CTRL 0x4 -+#define HDMI_CORE_AV_FREQ_SVAL 0x8 -+#define HDMI_CORE_AV_N_SVAL1 0xC -+#define HDMI_CORE_AV_N_SVAL2 0x10 -+#define HDMI_CORE_AV_N_SVAL3 0x14 -+#define HDMI_CORE_AV_CTS_SVAL1 0x18 -+#define HDMI_CORE_AV_CTS_SVAL2 0x1C -+#define HDMI_CORE_AV_CTS_SVAL3 0x20 -+#define HDMI_CORE_AV_CTS_HVAL1 0x24 -+#define HDMI_CORE_AV_CTS_HVAL2 0x28 -+#define HDMI_CORE_AV_CTS_HVAL3 0x2C -+#define HDMI_CORE_AV_AUD_MODE 0x50 -+#define HDMI_CORE_AV_SPDIF_CTRL 0x54 -+#define HDMI_CORE_AV_HW_SPDIF_FS 0x60 -+#define HDMI_CORE_AV_SWAP_I2S 0x64 -+#define HDMI_CORE_AV_SPDIF_ERTH 0x6C -+#define HDMI_CORE_AV_I2S_IN_MAP 0x70 -+#define HDMI_CORE_AV_I2S_IN_CTRL 0x74 -+#define HDMI_CORE_AV_I2S_CHST0 0x78 -+#define HDMI_CORE_AV_I2S_CHST1 0x7C -+#define HDMI_CORE_AV_I2S_CHST2 0x80 -+#define HDMI_CORE_AV_I2S_CHST4 0x84 -+#define HDMI_CORE_AV_I2S_CHST5 0x88 -+#define HDMI_CORE_AV_ASRC 0x8C -+#define HDMI_CORE_AV_I2S_IN_LEN 0x90 -+#define HDMI_CORE_AV_HDMI_CTRL 0xBC -+#define HDMI_CORE_AV_AUDO_TXSTAT 0xC0 -+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 0xCC -+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 0xD0 -+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 0xD4 -+#define HDMI_CORE_AV_TEST_TXCTRL 0xF0 -+#define HDMI_CORE_AV_DPD 0xF4 -+#define HDMI_CORE_AV_PB_CTRL1 0xF8 -+#define HDMI_CORE_AV_PB_CTRL2 0xFC -+#define HDMI_CORE_AV_AVI_TYPE 0x100 -+#define HDMI_CORE_AV_AVI_VERS 0x104 -+#define HDMI_CORE_AV_AVI_LEN 0x108 -+#define HDMI_CORE_AV_AVI_CHSUM 0x10C -+#define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110) -+#define HDMI_CORE_AV_SPD_TYPE 0x180 -+#define HDMI_CORE_AV_SPD_VERS 0x184 -+#define HDMI_CORE_AV_SPD_LEN 0x188 -+#define HDMI_CORE_AV_SPD_CHSUM 0x18C -+#define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190) -+#define HDMI_CORE_AV_AUDIO_TYPE 0x200 -+#define HDMI_CORE_AV_AUDIO_VERS 0x204 -+#define HDMI_CORE_AV_AUDIO_LEN 0x208 -+#define HDMI_CORE_AV_AUDIO_CHSUM 0x20C -+#define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210) -+#define HDMI_CORE_AV_MPEG_TYPE 0x280 -+#define HDMI_CORE_AV_MPEG_VERS 0x284 -+#define HDMI_CORE_AV_MPEG_LEN 0x288 -+#define HDMI_CORE_AV_MPEG_CHSUM 0x28C -+#define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290) -+#define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300) -+#define HDMI_CORE_AV_CP_BYTE1 0x37C -+#define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380) -+#define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC -+ -+#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 -+#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 -+#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 -+#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 -+ -+#define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15 -+#define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27 -+#define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10 -+#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27 -+#define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31 -+#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31 -+ -+enum hdmi_core_inputbus_width { -+ HDMI_INPUT_8BIT = 0, -+ HDMI_INPUT_10BIT = 1, -+ HDMI_INPUT_12BIT = 2 -+}; -+ -+enum hdmi_core_dither_trunc { -+ HDMI_OUTPUTTRUNCATION_8BIT = 0, -+ HDMI_OUTPUTTRUNCATION_10BIT = 1, -+ HDMI_OUTPUTTRUNCATION_12BIT = 2, -+ HDMI_OUTPUTDITHER_8BIT = 3, -+ HDMI_OUTPUTDITHER_10BIT = 4, -+ HDMI_OUTPUTDITHER_12BIT = 5 -+}; -+ -+enum hdmi_core_deepcolor_ed { -+ HDMI_DEEPCOLORPACKECTDISABLE = 0, -+ HDMI_DEEPCOLORPACKECTENABLE = 1 -+}; -+ -+enum hdmi_core_packet_mode { -+ HDMI_PACKETMODERESERVEDVALUE = 0, -+ HDMI_PACKETMODE24BITPERPIXEL = 4, -+ HDMI_PACKETMODE30BITPERPIXEL = 5, -+ HDMI_PACKETMODE36BITPERPIXEL = 6, -+ HDMI_PACKETMODE48BITPERPIXEL = 7 -+}; -+ -+enum hdmi_core_tclkselclkmult { -+ HDMI_FPLL05IDCK = 0, -+ HDMI_FPLL10IDCK = 1, -+ HDMI_FPLL20IDCK = 2, -+ HDMI_FPLL40IDCK = 3 -+}; -+ -+enum hdmi_core_packet_ctrl { -+ HDMI_PACKETENABLE = 1, -+ HDMI_PACKETDISABLE = 0, -+ HDMI_PACKETREPEATON = 1, -+ HDMI_PACKETREPEATOFF = 0 -+}; -+ -+enum hdmi_audio_i2s_config { -+ HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, -+ HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, -+ HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0, -+ HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1, -+ HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0, -+ HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1, -+ HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0, -+ HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1, -+ HDMI_AUDIO_I2S_SD0_EN = 1, -+ HDMI_AUDIO_I2S_SD1_EN = 1 << 1, -+ HDMI_AUDIO_I2S_SD2_EN = 1 << 2, -+ HDMI_AUDIO_I2S_SD3_EN = 1 << 3, -+}; -+ -+struct hdmi_core_video_config { -+ enum hdmi_core_inputbus_width ip_bus_width; -+ enum hdmi_core_dither_trunc op_dither_truc; -+ enum hdmi_core_deepcolor_ed deep_color_pkt; -+ enum hdmi_core_packet_mode pkt_mode; -+ enum hdmi_core_hdmi_dvi hdmi_dvi; -+ enum hdmi_core_tclkselclkmult tclk_sel_clkmult; -+}; -+ -+struct hdmi_core_packet_enable_repeat { -+ u32 audio_pkt; -+ u32 audio_pkt_repeat; -+ u32 avi_infoframe; -+ u32 avi_infoframe_repeat; -+ u32 gen_cntrl_pkt; -+ u32 gen_cntrl_pkt_repeat; -+ u32 generic_pkt; -+ u32 generic_pkt_repeat; -+}; -+ -+int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len); -+void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct hdmi_config *cfg); -+void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s); -+int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core); -+ -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -+int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); -+void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); -+int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct omap_dss_audio *audio, u32 pclk); -+int hdmi4_audio_get_dma_port(u32 *offset, u32 *size); -+#endif -+ -+#endif ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi5.c -@@ -0,0 +1,786 @@ -+/* -+ * hdmi.c -+ * -+ * HDMI interface DSS driver setting for TI's OMAP4 family of processor. -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * Authors: Yong Zhi -+ * Mythri pk <mythripk@ti.com> -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#define DSS_SUBSYS_NAME "HDMI" -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/interrupt.h> -+#include <linux/mutex.h> -+#include <linux/delay.h> -+#include <linux/string.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/clk.h> -+#include <linux/gpio.h> -+#include <linux/regulator/consumer.h> -+#include <video/omapdss.h> -+ -+#include "hdmi5_core.h" -+#include "dss.h" -+#include "dss_features.h" -+ -+static struct { -+ struct mutex lock; -+ struct platform_device *pdev; -+ -+ struct hdmi_wp_data wp; -+ struct hdmi_pll_data pll; -+ struct hdmi_phy_data phy; -+ struct hdmi_core_data core; -+ -+ struct hdmi_config cfg; -+ -+ struct clk *sys_clk; -+ struct regulator *vdda_hdmi_dac_reg; -+ -+ bool core_enabled; -+ -+ struct omap_dss_device output; -+} hdmi; -+ -+static int hdmi_runtime_get(void) -+{ -+ int r; -+ -+ DSSDBG("hdmi_runtime_get\n"); -+ -+ r = pm_runtime_get_sync(&hdmi.pdev->dev); -+ WARN_ON(r < 0); -+ if (r < 0) -+ return r; -+ -+ return 0; -+} -+ -+static void hdmi_runtime_put(void) -+{ -+ int r; -+ -+ DSSDBG("hdmi_runtime_put\n"); -+ -+ r = pm_runtime_put_sync(&hdmi.pdev->dev); -+ WARN_ON(r < 0 && r != -ENOSYS); -+} -+ -+static irqreturn_t hdmi_irq_handler(int irq, void *data) -+{ -+ struct hdmi_wp_data *wp = data; -+ u32 irqstatus; -+ -+ irqstatus = hdmi_wp_get_irqstatus(wp); -+ hdmi_wp_set_irqstatus(wp, irqstatus); -+ -+ if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && -+ irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -+ u32 v; -+ /* -+ * If we get both connect and disconnect interrupts at the same -+ * time, turn off the PHY, clear interrupts, and restart, which -+ * raises connect interrupt if a cable is connected, or nothing -+ * if cable is not connected. -+ */ -+ -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); -+ -+ /* -+ * We always get bogus CONNECT & DISCONNECT interrupts when -+ * setting the PHY to LDOON. To ignore those, we force the RXDET -+ * line to 0 until the PHY power state has been changed. -+ */ -+ v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); -+ v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ -+ v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ -+ hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); -+ -+ hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | -+ HDMI_IRQ_LINK_DISCONNECT); -+ -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); -+ -+ REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); -+ -+ } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); -+ } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int hdmi_init_regulator(void) -+{ -+ int r; -+ struct regulator *reg; -+ -+ if (hdmi.vdda_hdmi_dac_reg != NULL) -+ return 0; -+ -+ reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); -+ if (IS_ERR(reg)) { -+ DSSERR("can't get VDDA_HDMI_DAC regulator\n"); -+ return PTR_ERR(reg); -+ } -+ -+ r = regulator_set_voltage(reg, 1500000, 1800000); -+ if (r) -+ DSSWARN("can't set the regulator voltage"); -+ -+ hdmi.vdda_hdmi_dac_reg = reg; -+ -+ return 0; -+} -+ -+static int hdmi_power_on_core(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ r = regulator_enable(hdmi.vdda_hdmi_dac_reg); -+ if (r) -+ return r; -+ -+ r = hdmi_runtime_get(); -+ if (r) -+ goto err_runtime_get; -+ -+ /* Make selection of HDMI in DSS */ -+ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); -+ -+ hdmi.core_enabled = true; -+ -+ return 0; -+ -+err_runtime_get: -+ regulator_disable(hdmi.vdda_hdmi_dac_reg); -+ -+ return r; -+} -+ -+static void hdmi_power_off_core(struct omap_dss_device *dssdev) -+{ -+ hdmi.core_enabled = false; -+ -+ hdmi_runtime_put(); -+ regulator_disable(hdmi.vdda_hdmi_dac_reg); -+} -+ -+static int hdmi_power_on_full(struct omap_dss_device *dssdev) -+{ -+ int r; -+ struct omap_video_timings *p; -+ struct omap_overlay_manager *mgr = hdmi.output.manager; -+ unsigned long phy; -+ -+ r = hdmi_power_on_core(dssdev); -+ if (r) -+ return r; -+ -+ p = &hdmi.cfg.timings; -+ -+ DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); -+ -+ phy = p->pixel_clock; -+ -+ hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy); -+ -+ /* disable and clear irqs */ -+ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); -+ hdmi_wp_set_irqstatus(&hdmi.wp, -+ hdmi_wp_get_irqstatus(&hdmi.wp)); -+ -+ /* config the PLL and PHY hdmi_set_pll_pwrfirst */ -+ r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp); -+ if (r) { -+ DSSDBG("Failed to lock PLL\n"); -+ goto err_pll_enable; -+ } -+ -+ r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); -+ if (r) { -+ DSSDBG("Failed to start PHY\n"); -+ goto err_phy_cfg; -+ } -+ -+ r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); -+ if (r) -+ goto err_phy_pwr; -+ -+ hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); -+ -+ /* bypass TV gamma table */ -+ dispc_enable_gamma_table(0); -+ -+ /* tv size */ -+ dss_mgr_set_timings(mgr, p); -+ -+ r = hdmi_wp_video_start(&hdmi.wp); -+ if (r) -+ goto err_vid_enable; -+ -+ r = dss_mgr_enable(mgr); -+ if (r) -+ goto err_mgr_enable; -+ -+ hdmi_wp_set_irqenable(&hdmi.wp, -+ HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); -+ -+ return 0; -+ -+err_mgr_enable: -+ hdmi_wp_video_stop(&hdmi.wp); -+err_vid_enable: -+ hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); -+err_phy_pwr: -+err_phy_cfg: -+ hdmi_pll_disable(&hdmi.pll, &hdmi.wp); -+err_pll_enable: -+ hdmi_power_off_core(dssdev); -+ return -EIO; -+} -+ -+static void hdmi_power_off_full(struct omap_dss_device *dssdev) -+{ -+ struct omap_overlay_manager *mgr = hdmi.output.manager; -+ -+ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); -+ -+ dss_mgr_disable(mgr); -+ -+ hdmi_wp_video_stop(&hdmi.wp); -+ -+ hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); -+ -+ hdmi_pll_disable(&hdmi.pll, &hdmi.wp); -+ -+ hdmi_power_off_core(dssdev); -+} -+ -+static int hdmi_display_check_timing(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct hdmi_cm cm; -+ -+ cm = hdmi_get_code(timings); -+ if (cm.code == -1) { -+ return -EINVAL; -+ } -+ -+ return 0; -+ -+} -+ -+static void hdmi_display_set_timing(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct hdmi_cm cm; -+ const struct hdmi_config *t; -+ -+ mutex_lock(&hdmi.lock); -+ -+ cm = hdmi_get_code(timings); -+ hdmi.cfg.cm = cm; -+ -+ t = hdmi_get_timings(cm.mode, cm.code); -+ if (t != NULL) { -+ hdmi.cfg = *t; -+ -+ dispc_set_tv_pclk(t->timings.pixel_clock * 1000); -+ } -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+static void hdmi_display_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ const struct hdmi_config *cfg; -+ struct hdmi_cm cm = hdmi.cfg.cm; -+ -+ cfg = hdmi_get_timings(cm.mode, cm.code); -+ if (cfg == NULL) -+ cfg = hdmi_default_timing(); -+ -+ memcpy(timings, &cfg->timings, sizeof(cfg->timings)); -+} -+ -+static void hdmi_dump_regs(struct seq_file *s) -+{ -+ mutex_lock(&hdmi.lock); -+ -+ if (hdmi_runtime_get()) { -+ mutex_unlock(&hdmi.lock); -+ return; -+ } -+ -+ hdmi_wp_dump(&hdmi.wp, s); -+ hdmi_pll_dump(&hdmi.pll, s); -+ hdmi_phy_dump(&hdmi.phy, s); -+ hdmi5_core_dump(&hdmi.core, s); -+ -+ hdmi_runtime_put(); -+ mutex_unlock(&hdmi.lock); -+} -+ -+static int read_edid(u8 *buf, int len) -+{ -+ int r; -+ int idlemode; -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = hdmi_runtime_get(); -+ BUG_ON(r); -+ -+ idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); -+ /* No-idle mode */ -+ REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); -+ -+ r = hdmi5_read_edid(&hdmi.core, buf, len); -+ -+ REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); -+ -+ hdmi_runtime_put(); -+ mutex_unlock(&hdmi.lock); -+ -+ return r; -+} -+ -+static int hdmi_display_enable(struct omap_dss_device *dssdev) -+{ -+ struct omap_dss_device *out = &hdmi.output; -+ int r = 0; -+ -+ DSSDBG("ENTER hdmi_display_enable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ if (out == NULL || out->manager == NULL) { -+ DSSERR("failed to enable display: no output/manager\n"); -+ r = -ENODEV; -+ goto err0; -+ } -+ -+ r = hdmi_power_on_full(dssdev); -+ if (r) { -+ DSSERR("failed to power on device\n"); -+ goto err0; -+ } -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err0: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static void hdmi_display_disable(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("Enter hdmi_display_disable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ hdmi_power_off_full(dssdev); -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+static int hdmi_core_enable(struct omap_dss_device *dssdev) -+{ -+ int r = 0; -+ -+ DSSDBG("ENTER omapdss_hdmi_core_enable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = hdmi_power_on_core(dssdev); -+ if (r) { -+ DSSERR("failed to power on device\n"); -+ goto err0; -+ } -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err0: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static void hdmi_core_disable(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("Enter omapdss_hdmi_core_disable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ hdmi_power_off_core(dssdev); -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+static int hdmi_get_clocks(struct platform_device *pdev) -+{ -+ struct clk *clk; -+ -+ clk = devm_clk_get(&pdev->dev, "sys_clk"); -+ if (IS_ERR(clk)) { -+ DSSERR("can't get sys_clk\n"); -+ return PTR_ERR(clk); -+ } -+ -+ hdmi.sys_clk = clk; -+ -+ return 0; -+} -+ -+static int hdmi_connect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ struct omap_overlay_manager *mgr; -+ int r; -+ -+ r = hdmi_init_regulator(); -+ if (r) -+ return r; -+ -+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); -+ if (!mgr) -+ return -ENODEV; -+ -+ r = dss_mgr_connect(mgr, dssdev); -+ if (r) -+ return r; -+ -+ r = omapdss_output_set_device(dssdev, dst); -+ if (r) { -+ DSSERR("failed to connect output to new device: %s\n", -+ dst->name); -+ dss_mgr_disconnect(mgr, dssdev); -+ return r; -+ } -+ -+ return 0; -+} -+ -+static void hdmi_disconnect(struct omap_dss_device *dssdev, -+ struct omap_dss_device *dst) -+{ -+ WARN_ON(dst != dssdev->dst); -+ -+ if (dst != dssdev->dst) -+ return; -+ -+ omapdss_output_unset_device(dssdev); -+ -+ if (dssdev->manager) -+ dss_mgr_disconnect(dssdev->manager, dssdev); -+} -+ -+static int hdmi_read_edid(struct omap_dss_device *dssdev, -+ u8 *edid, int len) -+{ -+ bool need_enable; -+ int r; -+ -+ need_enable = hdmi.core_enabled == false; -+ -+ if (need_enable) { -+ r = hdmi_core_enable(dssdev); -+ if (r) -+ return r; -+ } -+ -+ r = read_edid(edid, len); -+ -+ if (need_enable) -+ hdmi_core_disable(dssdev); -+ -+ return r; -+} -+ -+#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) -+static int hdmi_audio_enable(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ mutex_lock(&hdmi.lock); -+ -+ if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { -+ r = -EPERM; -+ goto err; -+ } -+ -+ r = hdmi_wp_audio_enable(&hdmi.wp, true); -+ if (r) -+ goto err; -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static void hdmi_audio_disable(struct omap_dss_device *dssdev) -+{ -+ hdmi_wp_audio_enable(&hdmi.wp, false); -+} -+ -+static int hdmi_audio_start(struct omap_dss_device *dssdev) -+{ -+ return hdmi_wp_audio_core_req_enable(&hdmi.wp, true); -+} -+ -+static void hdmi_audio_stop(struct omap_dss_device *dssdev) -+{ -+ hdmi_wp_audio_core_req_enable(&hdmi.wp, false); -+} -+ -+static bool hdmi_audio_supported(struct omap_dss_device *dssdev) -+{ -+ bool r; -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); -+ -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+static int hdmi_audio_config(struct omap_dss_device *dssdev, -+ struct omap_dss_audio *audio) -+{ -+ int r; -+ u32 pclk = hdmi.cfg.timings.pixel_clock; -+ -+ mutex_lock(&hdmi.lock); -+ -+ if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { -+ r = -EPERM; -+ goto err; -+ } -+ -+ r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, audio, pclk); -+ if (r) -+ goto err; -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+#else -+static int hdmi_audio_enable(struct omap_dss_device *dssdev) -+{ -+ return -EPERM; -+} -+ -+static void hdmi_audio_disable(struct omap_dss_device *dssdev) -+{ -+} -+ -+static int hdmi_audio_start(struct omap_dss_device *dssdev) -+{ -+ return -EPERM; -+} -+ -+static void hdmi_audio_stop(struct omap_dss_device *dssdev) -+{ -+} -+ -+static bool hdmi_audio_supported(struct omap_dss_device *dssdev) -+{ -+ return false; -+} -+ -+static int hdmi_audio_config(struct omap_dss_device *dssdev, -+ struct omap_dss_audio *audio) -+{ -+ return -EPERM; -+} -+#endif -+ -+static const struct omapdss_hdmi_ops hdmi_ops = { -+ .connect = hdmi_connect, -+ .disconnect = hdmi_disconnect, -+ -+ .enable = hdmi_display_enable, -+ .disable = hdmi_display_disable, -+ -+ .check_timings = hdmi_display_check_timing, -+ .set_timings = hdmi_display_set_timing, -+ .get_timings = hdmi_display_get_timings, -+ -+ .read_edid = hdmi_read_edid, -+ -+ .audio_enable = hdmi_audio_enable, -+ .audio_disable = hdmi_audio_disable, -+ .audio_start = hdmi_audio_start, -+ .audio_stop = hdmi_audio_stop, -+ .audio_supported = hdmi_audio_supported, -+ .audio_config = hdmi_audio_config, -+}; -+ -+static void hdmi_init_output(struct platform_device *pdev) -+{ -+ struct omap_dss_device *out = &hdmi.output; -+ -+ out->dev = &pdev->dev; -+ out->id = OMAP_DSS_OUTPUT_HDMI; -+ out->output_type = OMAP_DISPLAY_TYPE_HDMI; -+ out->name = "hdmi.0"; -+ out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; -+ out->ops.hdmi = &hdmi_ops; -+ out->owner = THIS_MODULE; -+ -+ omapdss_register_output(out); -+} -+ -+static void __exit hdmi_uninit_output(struct platform_device *pdev) -+{ -+ struct omap_dss_device *out = &hdmi.output; -+ -+ omapdss_unregister_output(out); -+} -+ -+/* HDMI HW IP initialisation */ -+static int omapdss_hdmihw_probe(struct platform_device *pdev) -+{ -+ int r; -+ int irq; -+ -+ hdmi.pdev = pdev; -+ -+ mutex_init(&hdmi.lock); -+ -+ r = hdmi_wp_init(pdev, &hdmi.wp); -+ if (r) -+ return r; -+ -+ r = hdmi_pll_init(pdev, &hdmi.pll); -+ if (r) -+ return r; -+ -+ r = hdmi_phy_init(pdev, &hdmi.phy); -+ if (r) -+ return r; -+ -+ r = hdmi5_core_init(pdev, &hdmi.core); -+ if (r) -+ return r; -+ -+ r = hdmi_get_clocks(pdev); -+ if (r) { -+ DSSERR("can't get clocks\n"); -+ return r; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ DSSERR("platform_get_irq failed\n"); -+ return -ENODEV; -+ } -+ -+ r = devm_request_threaded_irq(&pdev->dev, irq, -+ NULL, hdmi_irq_handler, -+ IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); -+ if (r) { -+ DSSERR("HDMI IRQ request failed\n"); -+ return r; -+ } -+ -+ pm_runtime_enable(&pdev->dev); -+ -+ hdmi_init_output(pdev); -+ -+ dss_debugfs_create_file("hdmi", hdmi_dump_regs); -+ -+ return 0; -+} -+ -+static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) -+{ -+ hdmi_uninit_output(pdev); -+ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+static int hdmi_runtime_suspend(struct device *dev) -+{ -+ clk_disable_unprepare(hdmi.sys_clk); -+ -+ dispc_runtime_put(); -+ -+ return 0; -+} -+ -+static int hdmi_runtime_resume(struct device *dev) -+{ -+ int r; -+ -+ r = dispc_runtime_get(); -+ if (r < 0) -+ return r; -+ -+ clk_prepare_enable(hdmi.sys_clk); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops hdmi_pm_ops = { -+ .runtime_suspend = hdmi_runtime_suspend, -+ .runtime_resume = hdmi_runtime_resume, -+}; -+ -+static const struct of_device_id hdmi_of_match[] = { -+ { .compatible = "ti,omap5-hdmi", }, -+ {}, -+}; -+ -+static struct platform_driver omapdss_hdmihw_driver = { -+ .probe = omapdss_hdmihw_probe, -+ .remove = __exit_p(omapdss_hdmihw_remove), -+ .driver = { -+ .name = "omapdss_hdmi5", -+ .owner = THIS_MODULE, -+ .pm = &hdmi_pm_ops, -+ .of_match_table = hdmi_of_match, -+ }, -+}; -+ -+int __init hdmi5_init_platform_driver(void) -+{ -+ return platform_driver_register(&omapdss_hdmihw_driver); -+} -+ -+void __exit hdmi5_uninit_platform_driver(void) -+{ -+ platform_driver_unregister(&omapdss_hdmihw_driver); -+} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi5_core.c -@@ -0,0 +1,915 @@ -+/* -+ * OMAP5 HDMI CORE IP driver Library -+ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * Author: Mythri pk <mythripk@ti.com> -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/delay.h> -+#include <linux/string.h> -+#include <linux/seq_file.h> -+#include <drm/drm_edid.h> -+#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) -+#include <sound/asound.h> -+#include <sound/asoundef.h> -+#endif -+ -+#include "hdmi5_core.h" -+ -+/* only 24 bit color depth used for now */ -+static const struct csc_table csc_table_deepcolor[] = { -+ /* HDMI_DEEP_COLOR_24BIT */ -+ [0] = { 7036, 0, 0, 32, 0, 7036, 0, 32, 0, 0, 7036, 32, }, -+ /* HDMI_DEEP_COLOR_30BIT */ -+ [1] = { 7015, 0, 0, 128, 0, 7015, 0, 128, 0, 0, 7015, 128, }, -+ /* HDMI_DEEP_COLOR_36BIT */ -+ [2] = { 7010, 0, 0, 512, 0, 7010, 0, 512, 0, 0, 7010, 512, }, -+ /* FULL RANGE */ -+ [3] = { 8192, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 8192, 0, }, -+}; -+ -+static void hdmi_core_ddc_init(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ -+ const unsigned ss_scl_high = 4000; /* ns */ -+ const unsigned ss_scl_low = 4700; /* ns */ -+ const unsigned fs_scl_high = 600; /* ns */ -+ const unsigned fs_scl_low = 1300; /* ns */ -+ const unsigned sda_hold = 300; /* ns */ -+ const unsigned sfr_div = 10; -+ unsigned long long sfr; -+ unsigned v; -+ -+ sfr = iclk / sfr_div; /* SFR_DIV */ -+ sfr /= 1000; /* SFR clock in kHz */ -+ -+ /* Reset */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SOFTRSTZ, 0, 0, 0); -+ if (hdmi_wait_for_bit_change(base, HDMI_CORE_I2CM_SOFTRSTZ, -+ 0, 0, 1) != 1) -+ DSSERR("HDMI I2CM reset failed\n"); -+ -+ /* Standard (0) or Fast (1) Mode */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_DIV, 0, 3, 3); -+ -+ /* Standard Mode SCL High counter */ -+ v = DIV_ROUND_UP_ULL(ss_scl_high * sfr, 1000000); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR, -+ (v >> 8) & 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR, -+ v & 0xff, 7, 0); -+ -+ /* Standard Mode SCL Low counter */ -+ v = DIV_ROUND_UP_ULL(ss_scl_low * sfr, 1000000); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR, -+ (v >> 8) & 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR, -+ v & 0xff, 7, 0); -+ -+ /* Fast Mode SCL High Counter */ -+ v = DIV_ROUND_UP_ULL(fs_scl_high * sfr, 1000000); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR, -+ (v >> 8) & 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR, -+ v & 0xff, 7, 0); -+ -+ /* Fast Mode SCL Low Counter */ -+ v = DIV_ROUND_UP_ULL(fs_scl_low * sfr, 1000000); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR, -+ (v >> 8) & 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR, -+ v & 0xff, 7, 0); -+ -+ /* SDA Hold Time */ -+ v = DIV_ROUND_UP_ULL(sda_hold * sfr, 1000000); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SDA_HOLD_ADDR, v & 0xff, 7, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SLAVE, 0x50, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SEGADDR, 0x30, 6, 0); -+ -+ /* NACK_POL to high */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 7, 7); -+ -+ /* NACK_MASK to unmasked */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x0, 6, 6); -+ -+ /* ARBITRATION_POL to high */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 3, 3); -+ -+ /* ARBITRATION_MASK to unmasked */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x0, 2, 2); -+ -+ /* DONE_POL to high */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 3, 3); -+ -+ /* DONE_MASK to unmasked */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x0, 2, 2); -+} -+ -+static void hdmi_core_ddc_uninit(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ -+ /* Mask I2C interrupts */ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 6, 6); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 2, 2); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2); -+} -+ -+static int hdmi_core_ddc_edid(struct hdmi_core_data *core, u8 *pedid, u8 ext) -+{ -+ void __iomem *base = core->base; -+ u8 cur_addr; -+ char checksum = 0; -+ const int retries = 1000; -+ u8 seg_ptr = ext / 2; -+ u8 edidbase = ((ext % 2) * 0x80); -+ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_SEGPTR, seg_ptr, 7, 0); -+ -+ /* -+ * TODO: We use polling here, although we probably should use proper -+ * interrupts. -+ */ -+ for (cur_addr = 0; cur_addr < 128; ++cur_addr) { -+ int i; -+ -+ /* clear ERROR and DONE */ -+ REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0x3, 1, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_ADDRESS, -+ edidbase + cur_addr, 7, 0); -+ -+ if (seg_ptr) -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_OPERATION, 1, 1, 1); -+ else -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_OPERATION, 1, 0, 0); -+ -+ for (i = 0; i < retries; ++i) { -+ u32 stat; -+ -+ stat = REG_GET(base, HDMI_CORE_IH_I2CM_STAT0, 1, 0); -+ -+ /* I2CM_ERROR */ -+ if (stat & 1) { -+ DSSERR("HDMI I2C Master Error\n"); -+ return -EIO; -+ } -+ -+ /* I2CM_DONE */ -+ if (stat & (1 << 1)) -+ break; -+ -+ usleep_range(250, 1000); -+ } -+ -+ if (i == retries) { -+ DSSERR("HDMI I2C timeout reading EDID\n"); -+ return -EIO; -+ } -+ -+ pedid[cur_addr] = REG_GET(base, HDMI_CORE_I2CM_DATAI, 7, 0); -+ checksum += pedid[cur_addr]; -+ } -+ -+ return 0; -+ -+} -+ -+int hdmi5_read_edid(struct hdmi_core_data *core, u8 *edid, int len) -+{ -+ int r, n, i; -+ int max_ext_blocks = (len / 128) - 1; -+ -+ if (len < 128) -+ return -EINVAL; -+ -+ hdmi_core_ddc_init(core); -+ -+ r = hdmi_core_ddc_edid(core, edid, 0); -+ if (r) -+ goto out; -+ -+ n = edid[0x7e]; -+ -+ if (n > max_ext_blocks) -+ n = max_ext_blocks; -+ -+ for (i = 1; i <= n; i++) { -+ r = hdmi_core_ddc_edid(core, edid + i * EDID_LENGTH, i); -+ if (r) -+ goto out; -+ } -+ -+out: -+ hdmi_core_ddc_uninit(core); -+ -+ return r; -+} -+ -+void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s) -+{ -+ -+#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ -+ hdmi_read_reg(core->base, r)) -+ -+ DUMPCORE(HDMI_CORE_FC_INVIDCONF); -+ DUMPCORE(HDMI_CORE_FC_INHACTIV0); -+ DUMPCORE(HDMI_CORE_FC_INHACTIV1); -+ DUMPCORE(HDMI_CORE_FC_INHBLANK0); -+ DUMPCORE(HDMI_CORE_FC_INHBLANK1); -+ DUMPCORE(HDMI_CORE_FC_INVACTIV0); -+ DUMPCORE(HDMI_CORE_FC_INVACTIV1); -+ DUMPCORE(HDMI_CORE_FC_INVBLANK); -+ DUMPCORE(HDMI_CORE_FC_HSYNCINDELAY0); -+ DUMPCORE(HDMI_CORE_FC_HSYNCINDELAY1); -+ DUMPCORE(HDMI_CORE_FC_HSYNCINWIDTH0); -+ DUMPCORE(HDMI_CORE_FC_HSYNCINWIDTH1); -+ DUMPCORE(HDMI_CORE_FC_VSYNCINDELAY); -+ DUMPCORE(HDMI_CORE_FC_VSYNCINWIDTH); -+ DUMPCORE(HDMI_CORE_FC_CTRLDUR); -+ DUMPCORE(HDMI_CORE_FC_EXCTRLDUR); -+ DUMPCORE(HDMI_CORE_FC_EXCTRLSPAC); -+ DUMPCORE(HDMI_CORE_FC_CH0PREAM); -+ DUMPCORE(HDMI_CORE_FC_CH1PREAM); -+ DUMPCORE(HDMI_CORE_FC_CH2PREAM); -+ DUMPCORE(HDMI_CORE_FC_AVICONF0); -+ DUMPCORE(HDMI_CORE_FC_AVICONF1); -+ DUMPCORE(HDMI_CORE_FC_AVICONF2); -+ DUMPCORE(HDMI_CORE_FC_AVIVID); -+ DUMPCORE(HDMI_CORE_FC_PRCONF); -+ -+ DUMPCORE(HDMI_CORE_MC_CLKDIS); -+ DUMPCORE(HDMI_CORE_MC_SWRSTZREQ); -+ DUMPCORE(HDMI_CORE_MC_FLOWCTRL); -+ DUMPCORE(HDMI_CORE_MC_PHYRSTZ); -+ DUMPCORE(HDMI_CORE_MC_LOCKONCLOCK); -+ -+ DUMPCORE(HDMI_CORE_I2CM_SLAVE); -+ DUMPCORE(HDMI_CORE_I2CM_ADDRESS); -+ DUMPCORE(HDMI_CORE_I2CM_DATAO); -+ DUMPCORE(HDMI_CORE_I2CM_DATAI); -+ DUMPCORE(HDMI_CORE_I2CM_OPERATION); -+ DUMPCORE(HDMI_CORE_I2CM_INT); -+ DUMPCORE(HDMI_CORE_I2CM_CTLINT); -+ DUMPCORE(HDMI_CORE_I2CM_DIV); -+ DUMPCORE(HDMI_CORE_I2CM_SEGADDR); -+ DUMPCORE(HDMI_CORE_I2CM_SOFTRSTZ); -+ DUMPCORE(HDMI_CORE_I2CM_SEGPTR); -+ DUMPCORE(HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR); -+ DUMPCORE(HDMI_CORE_I2CM_SDA_HOLD_ADDR); -+} -+ -+static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg, -+ struct hdmi_core_infoframe_avi *avi_cfg, -+ struct hdmi_config *cfg) -+{ -+ DSSDBG("hdmi_core_init\n"); -+ -+ /* video core */ -+ video_cfg->data_enable_pol = 1; /* It is always 1*/ -+ video_cfg->v_fc_config.timings.hsync_level = cfg->timings.hsync_level; -+ video_cfg->v_fc_config.timings.x_res = cfg->timings.x_res; -+ video_cfg->v_fc_config.timings.hsw = cfg->timings.hsw - 1; -+ video_cfg->v_fc_config.timings.hbp = cfg->timings.hbp; -+ video_cfg->v_fc_config.timings.hfp = cfg->timings.hfp; -+ video_cfg->hblank = cfg->timings.hfp + -+ cfg->timings.hbp + cfg->timings.hsw - 1; -+ video_cfg->v_fc_config.timings.vsync_level = cfg->timings.vsync_level; -+ video_cfg->v_fc_config.timings.y_res = cfg->timings.y_res; -+ video_cfg->v_fc_config.timings.vsw = cfg->timings.vsw; -+ video_cfg->v_fc_config.timings.vfp = cfg->timings.vfp; -+ video_cfg->v_fc_config.timings.vbp = cfg->timings.vbp; -+ video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */ -+ video_cfg->vblank = cfg->timings.vsw + -+ cfg->timings.vfp + cfg->timings.vbp; -+ video_cfg->v_fc_config.cm.mode = cfg->cm.mode; -+ video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace; -+ -+ /* info frame */ -+ avi_cfg->db1_format = 0; -+ avi_cfg->db1_active_info = 0; -+ avi_cfg->db1_bar_info_dv = 0; -+ avi_cfg->db1_scan_info = 0; -+ avi_cfg->db2_colorimetry = 0; -+ avi_cfg->db2_aspect_ratio = 0; -+ avi_cfg->db2_active_fmt_ar = 0; -+ avi_cfg->db3_itc = 0; -+ avi_cfg->db3_ec = 0; -+ avi_cfg->db3_q_range = 0; -+ avi_cfg->db3_nup_scaling = 0; -+ avi_cfg->db4_videocode = 0; -+ avi_cfg->db5_pixel_repeat = 0; -+ avi_cfg->db6_7_line_eoftop = 0 ; -+ avi_cfg->db8_9_line_sofbottom = 0; -+ avi_cfg->db10_11_pixel_eofleft = 0; -+ avi_cfg->db12_13_pixel_sofright = 0; -+} -+ -+/* DSS_HDMI_CORE_VIDEO_CONFIG */ -+static void hdmi_core_video_config(struct hdmi_core_data *core, -+ struct hdmi_core_vid_config *cfg) -+{ -+ void __iomem *base = core->base; -+ unsigned char r = 0; -+ bool vsync_pol, hsync_pol; -+ -+ vsync_pol = -+ cfg->v_fc_config.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -+ hsync_pol = -+ cfg->v_fc_config.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -+ -+ /* Set hsync, vsync and data-enable polarity */ -+ r = hdmi_read_reg(base, HDMI_CORE_FC_INVIDCONF); -+ r = FLD_MOD(r, vsync_pol, 6, 6); -+ r = FLD_MOD(r, hsync_pol, 5, 5); -+ r = FLD_MOD(r, cfg->data_enable_pol, 4, 4); -+ r = FLD_MOD(r, cfg->vblank_osc, 1, 1); -+ r = FLD_MOD(r, cfg->v_fc_config.timings.interlace, 0, 0); -+ hdmi_write_reg(base, HDMI_CORE_FC_INVIDCONF, r); -+ -+ /* set x resolution */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_INHACTIV1, -+ cfg->v_fc_config.timings.x_res >> 8, 4, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_INHACTIV0, -+ cfg->v_fc_config.timings.x_res & 0xFF, 7, 0); -+ -+ /* set y resolution */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_INVACTIV1, -+ cfg->v_fc_config.timings.y_res >> 8, 4, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_INVACTIV0, -+ cfg->v_fc_config.timings.y_res & 0xFF, 7, 0); -+ -+ /* set horizontal blanking pixels */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_INHBLANK1, cfg->hblank >> 8, 4, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_INHBLANK0, cfg->hblank & 0xFF, 7, 0); -+ -+ /* set vertial blanking pixels */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_INVBLANK, cfg->vblank, 7, 0); -+ -+ /* set horizontal sync offset */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINDELAY1, -+ cfg->v_fc_config.timings.hfp >> 8, 4, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINDELAY0, -+ cfg->v_fc_config.timings.hfp & 0xFF, 7, 0); -+ -+ /* set vertical sync offset */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_VSYNCINDELAY, -+ cfg->v_fc_config.timings.vfp, 7, 0); -+ -+ /* set horizontal sync pulse width */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINWIDTH1, -+ (cfg->v_fc_config.timings.hsw >> 8), 1, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINWIDTH0, -+ cfg->v_fc_config.timings.hsw & 0xFF, 7, 0); -+ -+ /* set vertical sync pulse width */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_VSYNCINWIDTH, -+ cfg->v_fc_config.timings.vsw, 5, 0); -+ -+ /* select DVI mode */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF, -+ cfg->v_fc_config.cm.mode, 3, 3); -+} -+ -+static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ int clr_depth = 0; /* 24 bit color depth */ -+ -+ /* COLOR_DEPTH */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_PR_CD, clr_depth, 7, 4); -+ /* BYPASS_EN */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 0 : 1, 6, 6); -+ /* PP_EN */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 1 : 0, 5, 5); -+ /* YCC422_EN */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_CONF, 0, 3, 3); -+ /* PP_STUFFING */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_STUFF, clr_depth ? 1 : 0, 1, 1); -+ /* YCC422_STUFFING */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_STUFF, 1, 2, 2); -+ /* OUTPUT_SELECTOR */ -+ REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 0 : 2, 1, 0); -+} -+ -+static void hdmi_core_config_csc(struct hdmi_core_data *core) -+{ -+ int clr_depth = 0; /* 24 bit color depth */ -+ -+ /* CSC_COLORDEPTH */ -+ REG_FLD_MOD(core->base, HDMI_CORE_CSC_SCALE, clr_depth, 7, 4); -+} -+ -+static void hdmi_core_config_video_sampler(struct hdmi_core_data *core) -+{ -+ int video_mapping = 1; /* for 24 bit color depth */ -+ -+ /* VIDEO_MAPPING */ -+ REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0); -+} -+ -+static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ struct hdmi_core_infoframe_avi avi = core->avi_cfg; -+ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0); -+} -+ -+static void hdmi_core_csc_config(struct hdmi_core_data *core, -+ struct csc_table csc_coeff) -+{ -+ void __iomem *base = core->base; -+ -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A1_MSB, csc_coeff.a1 >> 8 , 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A1_LSB, csc_coeff.a1, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A2_MSB, csc_coeff.a2 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A2_LSB, csc_coeff.a2, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A3_MSB, csc_coeff.a3 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A3_LSB, csc_coeff.a3, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A4_MSB, csc_coeff.a4 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A4_LSB, csc_coeff.a4, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B1_MSB, csc_coeff.b1 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B1_LSB, csc_coeff.b1, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B2_MSB, csc_coeff.b2 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B2_LSB, csc_coeff.b2, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B3_MSB, csc_coeff.b3 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B3_LSB, csc_coeff.b3, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B4_MSB, csc_coeff.b4 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B4_LSB, csc_coeff.b4, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C1_MSB, csc_coeff.c1 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C1_LSB, csc_coeff.c1, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C2_MSB, csc_coeff.c2 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C2_LSB, csc_coeff.c2, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C3_MSB, csc_coeff.c3 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C3_LSB, csc_coeff.c3, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C4_MSB, csc_coeff.c4 >> 8, 6, 0); -+ REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C4_LSB, csc_coeff.c4, 7, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_MC_FLOWCTRL, 0x1, 0, 0); -+} -+ -+static void hdmi_core_configure_range(struct hdmi_core_data *core) -+{ -+ struct csc_table csc_coeff = { 0 }; -+ -+ /* support limited range with 24 bit color depth for now */ -+ csc_coeff = csc_table_deepcolor[0]; -+ core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR; -+ -+ hdmi_core_csc_config(core, csc_coeff); -+ hdmi_core_aux_infoframe_avi_config(core); -+} -+ -+static void hdmi_core_enable_video_path(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ -+ DSSDBG("hdmi_core_enable_video_path\n"); -+ -+ REG_FLD_MOD(base, HDMI_CORE_FC_CTRLDUR, 0x0C, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_EXCTRLDUR, 0x20, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_EXCTRLSPAC, 0x01, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_CH0PREAM, 0x0B, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_CH1PREAM, 0x16, 5, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_CH2PREAM, 0x21, 5, 0); -+ REG_FLD_MOD(base, HDMI_CORE_MC_CLKDIS, 0x00, 0, 0); -+ REG_FLD_MOD(base, HDMI_CORE_MC_CLKDIS, 0x00, 1, 1); -+} -+ -+static void hdmi_core_mask_interrupts(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ -+ /* Master IRQ mask */ -+ REG_FLD_MOD(base, HDMI_CORE_IH_MUTE, 0x3, 1, 0); -+ -+ /* Mask all the interrupts in HDMI core */ -+ -+ REG_FLD_MOD(base, HDMI_CORE_VP_MASK, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_MASK0, 0xe7, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_MASK1, 0xfb, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_MASK2, 0x3, 1, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_INT, 0x3, 3, 2); -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_MASK, 0x3, 1, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_CEC_MASK, 0x7f, 6, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 6, 6); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 2, 2); -+ REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2); -+ -+ REG_FLD_MOD(base, HDMI_CORE_PHY_MASK0, 0xf3, 7, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); -+ -+ /* Clear all the current interrupt bits */ -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_VP_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT0, 0xe7, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT1, 0xfb, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT2, 0x3, 1, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_AS_STAT0, 0x7, 2, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_CEC_STAT0, 0x7f, 6, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0x3, 1, 0); -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); -+} -+ -+static void hdmi_core_enable_interrupts(struct hdmi_core_data *core) -+{ -+ /* Unmute interrupts */ -+ REG_FLD_MOD(core->base, HDMI_CORE_IH_MUTE, 0x0, 1, 0); -+} -+ -+int hdmi5_core_handle_irqs(struct hdmi_core_data *core) -+{ -+ void __iomem *base = core->base; -+ -+ REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT1, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT2, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_AS_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_CEC_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_VP_STAT0, 0xff, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_IH_I2CMPHY_STAT0, 0xff, 7, 0); -+ -+ return 0; -+} -+ -+void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct hdmi_config *cfg) -+{ -+ struct omap_video_timings video_timing; -+ struct hdmi_video_format video_format; -+ struct hdmi_core_vid_config v_core_cfg; -+ struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg; -+ -+ hdmi_core_mask_interrupts(core); -+ -+ hdmi_core_init(&v_core_cfg, avi_cfg, cfg); -+ -+ hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); -+ -+ hdmi_wp_video_config_timing(wp, &video_timing); -+ -+ /* video config */ -+ video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; -+ -+ hdmi_wp_video_config_format(wp, &video_format); -+ -+ hdmi_wp_video_config_interface(wp, &video_timing); -+ -+ hdmi_core_configure_range(core); -+ -+ /* -+ * configure core video part, set software reset in the core -+ */ -+ v_core_cfg.packet_mode = HDMI_PACKETMODE24BITPERPIXEL; -+ -+ hdmi_core_video_config(core, &v_core_cfg); -+ -+ hdmi_core_config_video_packetizer(core); -+ hdmi_core_config_csc(core); -+ hdmi_core_config_video_sampler(core); -+ -+ /* -+ * configure packet info frame video see doc CEA861-D page 65 -+ */ -+ avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; -+ avi_cfg->db1_active_info = -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; -+ avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; -+ avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; -+ avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; -+ avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; -+ avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; -+ avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; -+ avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; -+ avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; -+ avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; -+ avi_cfg->db4_videocode = cfg->cm.code; -+ avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; -+ avi_cfg->db6_7_line_eoftop = 0; -+ avi_cfg->db8_9_line_sofbottom = 0; -+ avi_cfg->db10_11_pixel_eofleft = 0; -+ avi_cfg->db12_13_pixel_sofright = 0; -+ -+ hdmi_core_aux_infoframe_avi_config(core); -+ -+ hdmi_core_enable_video_path(core); -+ -+ hdmi_core_enable_interrupts(core); -+} -+ -+ -+#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) -+ -+static void hdmi5_core_audio_config(struct hdmi_core_data *core, -+ struct hdmi_core_audio_config *cfg) -+{ -+ void __iomem *base = core->base; -+ u8 val; -+ -+ /* Mute audio before configuring */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0xf, 7, 4); -+ -+ /* Set the N parameter */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_N1, cfg->n, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_AUD_N2, cfg->n >> 8, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_AUD_N3, cfg->n >> 16, 3, 0); -+ -+ /* -+ * CTS manual mode. Automatic mode is not supported when using audio -+ * parallel interface. -+ */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CTS3, 1, 4, 4); -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CTS1, cfg->cts, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CTS2, cfg->cts >> 8, 7, 0); -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CTS3, cfg->cts >> 16, 3, 0); -+ -+ /* Layout of Audio Sample Packets: 2-channel or multichannels */ -+ if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0, 0, 0); -+ else -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 1, 0, 0); -+ -+ /* Configure IEC-609580 Validity bits */ -+ /* Channel 0 is valid */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, 0, 0, 0); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, 0, 4, 4); -+ -+ if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) -+ val = 1; -+ else -+ val = 0; -+ -+ /* Channels 1, 2 setting */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 1, 1); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 5, 5); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 2, 2); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 6, 6); -+ /* Channel 3 setting */ -+ if (cfg->layout == HDMI_AUDIO_LAYOUT_6CH) -+ val = 1; -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 3, 3); -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 7, 7); -+ -+ /* Configure IEC-60958 User bits */ -+ /* TODO: should be set by user. */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSU, 0, 7, 0); -+ -+ /* Configure IEC-60958 Channel Status word */ -+ /* CGMSA */ -+ val = cfg->iec60958_cfg->status[5] & IEC958_AES5_CON_CGMSA; -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(0), val, 5, 4); -+ -+ /* Copyright */ -+ val = (cfg->iec60958_cfg->status[0] & -+ IEC958_AES0_CON_NOT_COPYRIGHT) >> 2; -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(0), val, 0, 0); -+ -+ /* Category */ -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(1), -+ cfg->iec60958_cfg->status[1]); -+ -+ /* PCM audio mode */ -+ val = (cfg->iec60958_cfg->status[0] & IEC958_AES0_CON_MODE) >> 6; -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 6, 4); -+ -+ /* Source number */ -+ val = cfg->iec60958_cfg->status[2] & IEC958_AES2_CON_SOURCE; -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 4); -+ -+ /* Channel number right 0 */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 2, 3, 0); -+ /* Channel number right 1*/ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 4, 7, 4); -+ /* Channel number right 2 */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(4), 6, 3, 0); -+ /* Channel number right 3*/ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(4), 8, 7, 4); -+ /* Channel number left 0 */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(5), 1, 3, 0); -+ /* Channel number left 1*/ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(5), 3, 7, 4); -+ /* Channel number left 2 */ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(6), 5, 3, 0); -+ /* Channel number left 3*/ -+ REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(6), 7, 7, 4); -+ -+ /* Clock accuracy and sample rate */ -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(7), -+ cfg->iec60958_cfg->status[3]); -+ -+ /* Original sample rate and word length */ -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(8), -+ cfg->iec60958_cfg->status[4]); -+ -+ /* Enable FIFO empty and full interrupts */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_INT, 3, 3, 2); -+ -+ /* Configure GPA */ -+ /* select HBR/SPDIF interfaces */ -+ if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) { -+ /* select HBR/SPDIF interfaces */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); -+ /* enable two channels in GPA */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 3, 7, 0); -+ } else if (cfg->layout == HDMI_AUDIO_LAYOUT_6CH) { -+ /* select HBR/SPDIF interfaces */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); -+ /* enable six channels in GPA */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 0x3F, 7, 0); -+ } else { -+ /* select HBR/SPDIF interfaces */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); -+ /* enable eight channels in GPA */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 0xFF, 7, 0); -+ } -+ -+ /* disable HBR */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF2, 0, 0, 0); -+ /* enable PCUV */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF2, 1, 1, 1); -+ /* enable GPA FIFO full and empty mask */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_MASK, 3, 1, 0); -+ /* set polarity of GPA FIFO empty interrupts */ -+ REG_FLD_MOD(base, HDMI_CORE_AUD_GP_POL, 1, 0, 0); -+ -+ /* unmute audio */ -+ REG_FLD_MOD(core_sys_base, HDMI_CORE_FC_AUDSCONF, 0, 7, 4); -+} -+ -+static void hdmi5_core_audio_infoframe_cfg(struct hdmi_core_data *core, -+ struct snd_cea_861_aud_if *info_aud) -+{ -+ void __iomem *base = core->base; -+ -+ /* channel count and coding type fields in AUDICONF0 are swapped */ -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF0, -+ (info_aud->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CC) << 4 | -+ (info_aud->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CT) >> 4); -+ -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss); -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca); -+ hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3, info_aud->db5_dminh_lsv); -+} -+ -+int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct omap_dss_audio *audio, u32 pclk) -+{ -+ struct hdmi_audio_format audio_format; -+ struct hdmi_audio_dma audio_dma; -+ struct hdmi_core_audio_config core_cfg; -+ int err, n, cts, channel_count; -+ unsigned int fs_nr; -+ bool word_length_16b = false; -+ -+ if (!audio || !audio->iec || !audio->cea || !core) -+ return -EINVAL; -+ -+ core_cfg.iec60958_cfg = audio->iec; -+ -+ if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) && -+ (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16)) -+ word_length_16b = true; -+ -+ /* only 16-bit word length supported atm */ -+ if (!word_length_16b) -+ return -EINVAL; -+ -+ switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { -+ case IEC958_AES3_CON_FS_32000: -+ fs_nr = 32000; -+ break; -+ case IEC958_AES3_CON_FS_44100: -+ fs_nr = 44100; -+ break; -+ case IEC958_AES3_CON_FS_48000: -+ fs_nr = 48000; -+ break; -+ case IEC958_AES3_CON_FS_88200: -+ fs_nr = 88200; -+ break; -+ case IEC958_AES3_CON_FS_96000: -+ fs_nr = 96000; -+ break; -+ case IEC958_AES3_CON_FS_176400: -+ fs_nr = 176400; -+ break; -+ case IEC958_AES3_CON_FS_192000: -+ fs_nr = 192000; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ err = hdmi_compute_acr(pclk, fs_nr, &n, &cts); -+ core_cfg.n = n; -+ core_cfg.cts = cts; -+ -+ /* Audio channels settings */ -+ channel_count = (audio->cea->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CC) -+ + 1; -+ -+ if (channel_count == 2) -+ core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; -+ else if (channel_count == 6) -+ core_cfg.layout = HDMI_AUDIO_LAYOUT_6CH; -+ else -+ core_cfg.layout = HDMI_AUDIO_LAYOUT_8CH; -+ -+ /* DMA settings */ -+ if (word_length_16b) -+ audio_dma.transfer_size = 0x10; -+ else -+ audio_dma.transfer_size = 0x20; -+ audio_dma.block_size = 0xC0; -+ audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; -+ audio_dma.fifo_threshold = 0x20; /* in number of samples */ -+ -+ /* audio FIFO format settings for 16-bit samples*/ -+ audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; -+ audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; -+ audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; -+ -+ /* only LPCM atm */ -+ audio_format.type = HDMI_AUDIO_TYPE_LPCM; -+ -+ /* disable start/stop signals of IEC 60958 blocks */ -+ audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; -+ -+ /* configure DMA and audio FIFO format*/ -+ hdmi_wp_audio_config_dma(wp, &audio_dma); -+ hdmi_wp_audio_config_format(wp, &audio_format); -+ -+ /* configure the core */ -+ hdmi5_core_audio_config(core, &core_cfg); -+ -+ /* configure CEA 861 audio infoframe */ -+ hdmi5_core_audio_infoframe_cfg(core, audio->cea); -+ -+ return 0; -+} -+#endif -+ -+int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core) -+{ -+ struct resource *res; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_core"); -+ if (!res) { -+ DSSERR("can't get CORE IORESOURCE_MEM HDMI\n"); -+ return -EINVAL; -+ } -+ -+ core->base = devm_request_and_ioremap(&pdev->dev, res); -+ if (!core->base) { -+ DSSERR("can't ioremap HDMI core\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi5_core.h -@@ -0,0 +1,306 @@ -+/* -+ * HDMI driver definition for TI OMAP5 processors. -+ * -+ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef _HDMI5_CORE_H_ -+#define _HDMI5_CORE_H_ -+ -+#include "hdmi.h" -+ -+/* HDMI IP Core System */ -+ -+/* HDMI Identification */ -+#define HDMI_CORE_DESIGN_ID 0x00000 -+#define HDMI_CORE_REVISION_ID 0x00004 -+#define HDMI_CORE_PRODUCT_ID0 0x00008 -+#define HDMI_CORE_PRODUCT_ID1 0x0000C -+#define HDMI_CORE_CONFIG0_ID 0x00010 -+#define HDMI_CORE_CONFIG1_ID 0x00014 -+#define HDMI_CORE_CONFIG2_ID 0x00018 -+#define HDMI_CORE_CONFIG3_ID 0x0001C -+ -+/* HDMI Interrupt */ -+#define HDMI_CORE_IH_FC_STAT0 0x00400 -+#define HDMI_CORE_IH_FC_STAT1 0x00404 -+#define HDMI_CORE_IH_FC_STAT2 0x00408 -+#define HDMI_CORE_IH_AS_STAT0 0x0040C -+#define HDMI_CORE_IH_PHY_STAT0 0x00410 -+#define HDMI_CORE_IH_I2CM_STAT0 0x00414 -+#define HDMI_CORE_IH_CEC_STAT0 0x00418 -+#define HDMI_CORE_IH_VP_STAT0 0x0041C -+#define HDMI_CORE_IH_I2CMPHY_STAT0 0x00420 -+#define HDMI_CORE_IH_MUTE 0x007FC -+ -+/* HDMI Video Sampler */ -+#define HDMI_CORE_TX_INVID0 0x00800 -+#define HDMI_CORE_TX_INSTUFFING 0x00804 -+#define HDMI_CORE_TX_RGYDATA0 0x00808 -+#define HDMI_CORE_TX_RGYDATA1 0x0080C -+#define HDMI_CORE_TX_RCRDATA0 0x00810 -+#define HDMI_CORE_TX_RCRDATA1 0x00814 -+#define HDMI_CORE_TX_BCBDATA0 0x00818 -+#define HDMI_CORE_TX_BCBDATA1 0x0081C -+ -+/* HDMI Video Packetizer */ -+#define HDMI_CORE_VP_STATUS 0x02000 -+#define HDMI_CORE_VP_PR_CD 0x02004 -+#define HDMI_CORE_VP_STUFF 0x02008 -+#define HDMI_CORE_VP_REMAP 0x0200C -+#define HDMI_CORE_VP_CONF 0x02010 -+#define HDMI_CORE_VP_STAT 0x02014 -+#define HDMI_CORE_VP_INT 0x02018 -+#define HDMI_CORE_VP_MASK 0x0201C -+#define HDMI_CORE_VP_POL 0x02020 -+ -+/* Frame Composer */ -+#define HDMI_CORE_FC_INVIDCONF 0x04000 -+#define HDMI_CORE_FC_INHACTIV0 0x04004 -+#define HDMI_CORE_FC_INHACTIV1 0x04008 -+#define HDMI_CORE_FC_INHBLANK0 0x0400C -+#define HDMI_CORE_FC_INHBLANK1 0x04010 -+#define HDMI_CORE_FC_INVACTIV0 0x04014 -+#define HDMI_CORE_FC_INVACTIV1 0x04018 -+#define HDMI_CORE_FC_INVBLANK 0x0401C -+#define HDMI_CORE_FC_HSYNCINDELAY0 0x04020 -+#define HDMI_CORE_FC_HSYNCINDELAY1 0x04024 -+#define HDMI_CORE_FC_HSYNCINWIDTH0 0x04028 -+#define HDMI_CORE_FC_HSYNCINWIDTH1 0x0402C -+#define HDMI_CORE_FC_VSYNCINDELAY 0x04030 -+#define HDMI_CORE_FC_VSYNCINWIDTH 0x04034 -+#define HDMI_CORE_FC_INFREQ0 0x04038 -+#define HDMI_CORE_FC_INFREQ1 0x0403C -+#define HDMI_CORE_FC_INFREQ2 0x04040 -+#define HDMI_CORE_FC_CTRLDUR 0x04044 -+#define HDMI_CORE_FC_EXCTRLDUR 0x04048 -+#define HDMI_CORE_FC_EXCTRLSPAC 0x0404C -+#define HDMI_CORE_FC_CH0PREAM 0x04050 -+#define HDMI_CORE_FC_CH1PREAM 0x04054 -+#define HDMI_CORE_FC_CH2PREAM 0x04058 -+#define HDMI_CORE_FC_AVICONF3 0x0405C -+#define HDMI_CORE_FC_GCP 0x04060 -+#define HDMI_CORE_FC_AVICONF0 0x04064 -+#define HDMI_CORE_FC_AVICONF1 0x04068 -+#define HDMI_CORE_FC_AVICONF2 0x0406C -+#define HDMI_CORE_FC_AVIVID 0x04070 -+#define HDMI_CORE_FC_AVIETB0 0x04074 -+#define HDMI_CORE_FC_AVIETB1 0x04078 -+#define HDMI_CORE_FC_AVISBB0 0x0407C -+#define HDMI_CORE_FC_AVISBB1 0x04080 -+#define HDMI_CORE_FC_AVIELB0 0x04084 -+#define HDMI_CORE_FC_AVIELB1 0x04088 -+#define HDMI_CORE_FC_AVISRB0 0x0408C -+#define HDMI_CORE_FC_AVISRB1 0x04090 -+#define HDMI_CORE_FC_AUDICONF0 0x04094 -+#define HDMI_CORE_FC_AUDICONF1 0x04098 -+#define HDMI_CORE_FC_AUDICONF2 0x0409C -+#define HDMI_CORE_FC_AUDICONF3 0x040A0 -+#define HDMI_CORE_FC_VSDIEEEID0 0x040A4 -+#define HDMI_CORE_FC_VSDSIZE 0x040A8 -+#define HDMI_CORE_FC_VSDIEEEID1 0x040C0 -+#define HDMI_CORE_FC_VSDIEEEID2 0x040C4 -+#define HDMI_CORE_FC_VSDPAYLOAD(n) (n * 4 + 0x040C8) -+#define HDMI_CORE_FC_SPDVENDORNAME(n) (n * 4 + 0x04128) -+#define HDMI_CORE_FC_SPDPRODUCTNAME(n) (n * 4 + 0x04148) -+#define HDMI_CORE_FC_SPDDEVICEINF 0x04188 -+#define HDMI_CORE_FC_AUDSCONF 0x0418C -+#define HDMI_CORE_FC_AUDSSTAT 0x04190 -+#define HDMI_CORE_FC_AUDSV 0x04194 -+#define HDMI_CORE_FC_AUDSU 0x04198 -+#define HDMI_CORE_FC_AUDSCHNLS(n) (n * 4 + 0x0419C) -+#define HDMI_CORE_FC_CTRLQHIGH 0x041CC -+#define HDMI_CORE_FC_CTRLQLOW 0x041D0 -+#define HDMI_CORE_FC_ACP0 0x041D4 -+#define HDMI_CORE_FC_ACP(n) ((16-n) * 4 + 0x04208) -+#define HDMI_CORE_FC_ISCR1_0 0x04248 -+#define HDMI_CORE_FC_ISCR1(n) ((16-n) * 4 + 0x0424C) -+#define HDMI_CORE_FC_ISCR2(n) ((15-n) * 4 + 0x0428C) -+#define HDMI_CORE_FC_DATAUTO0 0x042CC -+#define HDMI_CORE_FC_DATAUTO1 0x042D0 -+#define HDMI_CORE_FC_DATAUTO2 0x042D4 -+#define HDMI_CORE_FC_DATMAN 0x042D8 -+#define HDMI_CORE_FC_DATAUTO3 0x042DC -+#define HDMI_CORE_FC_RDRB(n) (n * 4 + 0x042E0) -+#define HDMI_CORE_FC_STAT0 0x04340 -+#define HDMI_CORE_FC_INT0 0x04344 -+#define HDMI_CORE_FC_MASK0 0x04348 -+#define HDMI_CORE_FC_POL0 0x0434C -+#define HDMI_CORE_FC_STAT1 0x04350 -+#define HDMI_CORE_FC_INT1 0x04354 -+#define HDMI_CORE_FC_MASK1 0x04358 -+#define HDMI_CORE_FC_POL1 0x0435C -+#define HDMI_CORE_FC_STAT2 0x04360 -+#define HDMI_CORE_FC_INT2 0x04364 -+#define HDMI_CORE_FC_MASK2 0x04368 -+#define HDMI_CORE_FC_POL2 0x0436C -+#define HDMI_CORE_FC_PRCONF 0x04380 -+#define HDMI_CORE_FC_GMD_STAT 0x04400 -+#define HDMI_CORE_FC_GMD_EN 0x04404 -+#define HDMI_CORE_FC_GMD_UP 0x04408 -+#define HDMI_CORE_FC_GMD_CONF 0x0440C -+#define HDMI_CORE_FC_GMD_HB 0x04410 -+#define HDMI_CORE_FC_GMD_PB(n) (n * 4 + 0x04414) -+#define HDMI_CORE_FC_DBGFORCE 0x04800 -+#define HDMI_CORE_FC_DBGAUD0CH0 0x04804 -+#define HDMI_CORE_FC_DBGAUD1CH0 0x04808 -+#define HDMI_CORE_FC_DBGAUD2CH0 0x0480C -+#define HDMI_CORE_FC_DBGAUD0CH1 0x04810 -+#define HDMI_CORE_FC_DBGAUD1CH1 0x04814 -+#define HDMI_CORE_FC_DBGAUD2CH1 0x04818 -+#define HDMI_CORE_FC_DBGAUD0CH2 0x0481C -+#define HDMI_CORE_FC_DBGAUD1CH2 0x04820 -+#define HDMI_CORE_FC_DBGAUD2CH2 0x04824 -+#define HDMI_CORE_FC_DBGAUD0CH3 0x04828 -+#define HDMI_CORE_FC_DBGAUD1CH3 0x0482C -+#define HDMI_CORE_FC_DBGAUD2CH3 0x04830 -+#define HDMI_CORE_FC_DBGAUD0CH4 0x04834 -+#define HDMI_CORE_FC_DBGAUD1CH4 0x04838 -+#define HDMI_CORE_FC_DBGAUD2CH4 0x0483C -+#define HDMI_CORE_FC_DBGAUD0CH5 0x04840 -+#define HDMI_CORE_FC_DBGAUD1CH5 0x04844 -+#define HDMI_CORE_FC_DBGAUD2CH5 0x04848 -+#define HDMI_CORE_FC_DBGAUD0CH6 0x0484C -+#define HDMI_CORE_FC_DBGAUD1CH6 0x04850 -+#define HDMI_CORE_FC_DBGAUD2CH6 0x04854 -+#define HDMI_CORE_FC_DBGAUD0CH7 0x04858 -+#define HDMI_CORE_FC_DBGAUD1CH7 0x0485C -+#define HDMI_CORE_FC_DBGAUD2CH7 0x04860 -+#define HDMI_CORE_FC_DBGTMDS0 0x04864 -+#define HDMI_CORE_FC_DBGTMDS1 0x04868 -+#define HDMI_CORE_FC_DBGTMDS2 0x0486C -+#define HDMI_CORE_PHY_MASK0 0x0C018 -+#define HDMI_CORE_PHY_I2CM_INT_ADDR 0x0C09C -+#define HDMI_CORE_PHY_I2CM_CTLINT_ADDR 0x0C0A0 -+ -+/* HDMI Audio */ -+#define HDMI_CORE_AUD_CONF0 0x0C400 -+#define HDMI_CORE_AUD_CONF1 0x0C404 -+#define HDMI_CORE_AUD_INT 0x0C408 -+#define HDMI_CORE_AUD_N1 0x0C800 -+#define HDMI_CORE_AUD_N2 0x0C804 -+#define HDMI_CORE_AUD_N3 0x0C808 -+#define HDMI_CORE_AUD_CTS1 0x0C80C -+#define HDMI_CORE_AUD_CTS2 0x0C810 -+#define HDMI_CORE_AUD_CTS3 0x0C814 -+#define HDMI_CORE_AUD_INCLKFS 0x0C818 -+#define HDMI_CORE_AUD_CC08 0x0CC08 -+#define HDMI_CORE_AUD_GP_CONF0 0x0D400 -+#define HDMI_CORE_AUD_GP_CONF1 0x0D404 -+#define HDMI_CORE_AUD_GP_CONF2 0x0D408 -+#define HDMI_CORE_AUD_D010 0x0D010 -+#define HDMI_CORE_AUD_GP_STAT 0x0D40C -+#define HDMI_CORE_AUD_GP_INT 0x0D410 -+#define HDMI_CORE_AUD_GP_POL 0x0D414 -+#define HDMI_CORE_AUD_GP_MASK 0x0D418 -+ -+/* HDMI Main Controller */ -+#define HDMI_CORE_MC_CLKDIS 0x10004 -+#define HDMI_CORE_MC_SWRSTZREQ 0x10008 -+#define HDMI_CORE_MC_FLOWCTRL 0x10010 -+#define HDMI_CORE_MC_PHYRSTZ 0x10014 -+#define HDMI_CORE_MC_LOCKONCLOCK 0x10018 -+ -+/* HDMI COLOR SPACE CONVERTER */ -+#define HDMI_CORE_CSC_CFG 0x10400 -+#define HDMI_CORE_CSC_SCALE 0x10404 -+#define HDMI_CORE_CSC_COEF_A1_MSB 0x10408 -+#define HDMI_CORE_CSC_COEF_A1_LSB 0x1040C -+#define HDMI_CORE_CSC_COEF_A2_MSB 0x10410 -+#define HDMI_CORE_CSC_COEF_A2_LSB 0x10414 -+#define HDMI_CORE_CSC_COEF_A3_MSB 0x10418 -+#define HDMI_CORE_CSC_COEF_A3_LSB 0x1041C -+#define HDMI_CORE_CSC_COEF_A4_MSB 0x10420 -+#define HDMI_CORE_CSC_COEF_A4_LSB 0x10424 -+#define HDMI_CORE_CSC_COEF_B1_MSB 0x10428 -+#define HDMI_CORE_CSC_COEF_B1_LSB 0x1042C -+#define HDMI_CORE_CSC_COEF_B2_MSB 0x10430 -+#define HDMI_CORE_CSC_COEF_B2_LSB 0x10434 -+#define HDMI_CORE_CSC_COEF_B3_MSB 0x10438 -+#define HDMI_CORE_CSC_COEF_B3_LSB 0x1043C -+#define HDMI_CORE_CSC_COEF_B4_MSB 0x10440 -+#define HDMI_CORE_CSC_COEF_B4_LSB 0x10444 -+#define HDMI_CORE_CSC_COEF_C1_MSB 0x10448 -+#define HDMI_CORE_CSC_COEF_C1_LSB 0x1044C -+#define HDMI_CORE_CSC_COEF_C2_MSB 0x10450 -+#define HDMI_CORE_CSC_COEF_C2_LSB 0x10454 -+#define HDMI_CORE_CSC_COEF_C3_MSB 0x10458 -+#define HDMI_CORE_CSC_COEF_C3_LSB 0x1045C -+#define HDMI_CORE_CSC_COEF_C4_MSB 0x10460 -+#define HDMI_CORE_CSC_COEF_C4_LSB 0x10464 -+ -+/* HDMI HDCP */ -+#define HDMI_CORE_HDCP_MASK 0x14020 -+ -+/* HDMI CEC */ -+#define HDMI_CORE_CEC_MASK 0x17408 -+ -+/* HDMI I2C Master */ -+#define HDMI_CORE_I2CM_SLAVE 0x157C8 -+#define HDMI_CORE_I2CM_ADDRESS 0x157CC -+#define HDMI_CORE_I2CM_DATAO 0x157D0 -+#define HDMI_CORE_I2CM_DATAI 0X157D4 -+#define HDMI_CORE_I2CM_OPERATION 0x157D8 -+#define HDMI_CORE_I2CM_INT 0x157DC -+#define HDMI_CORE_I2CM_CTLINT 0x157E0 -+#define HDMI_CORE_I2CM_DIV 0x157E4 -+#define HDMI_CORE_I2CM_SEGADDR 0x157E8 -+#define HDMI_CORE_I2CM_SOFTRSTZ 0x157EC -+#define HDMI_CORE_I2CM_SEGPTR 0x157F0 -+#define HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR 0x157F4 -+#define HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR 0x157F8 -+#define HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR 0x157FC -+#define HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR 0x15800 -+#define HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR 0x15804 -+#define HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR 0x15808 -+#define HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR 0x1580C -+#define HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR 0x15810 -+#define HDMI_CORE_I2CM_SDA_HOLD_ADDR 0x15814 -+ -+enum hdmi_core_packet_mode { -+ HDMI_PACKETMODERESERVEDVALUE = 0, -+ HDMI_PACKETMODE24BITPERPIXEL = 4, -+ HDMI_PACKETMODE30BITPERPIXEL = 5, -+ HDMI_PACKETMODE36BITPERPIXEL = 6, -+ HDMI_PACKETMODE48BITPERPIXEL = 7, -+}; -+ -+struct hdmi_core_vid_config { -+ struct hdmi_config v_fc_config; -+ enum hdmi_core_packet_mode packet_mode; -+ int data_enable_pol; -+ int vblank_osc; -+ int hblank; -+ int vblank; -+}; -+ -+struct csc_table { -+ u16 a1, a2, a3, a4; -+ u16 b1, b2, b3, b4; -+ u16 c1, c2, c3, c4; -+}; -+ -+int hdmi5_read_edid(struct hdmi_core_data *core, u8 *edid, int len); -+void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s); -+int hdmi5_core_handle_irqs(struct hdmi_core_data *core); -+void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct hdmi_config *cfg); -+int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core); -+ -+#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) -+int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, -+ struct omap_dss_audio *audio, u32 pclk); -+#endif -+#endif ---- a/drivers/video/omap2/dss/hdmi.c -+++ /dev/null -@@ -1,1184 +0,0 @@ --/* -- * hdmi.c -- * -- * HDMI interface DSS driver setting for TI's OMAP4 family of processor. -- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -- * Authors: Yong Zhi -- * Mythri pk <mythripk@ti.com> -- * -- * 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. -- * -- * 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, see <http://www.gnu.org/licenses/>. -- */ -- --#define DSS_SUBSYS_NAME "HDMI" -- --#include <linux/kernel.h> --#include <linux/module.h> --#include <linux/err.h> --#include <linux/io.h> --#include <linux/interrupt.h> --#include <linux/mutex.h> --#include <linux/delay.h> --#include <linux/string.h> --#include <linux/platform_device.h> --#include <linux/pm_runtime.h> --#include <linux/clk.h> --#include <linux/gpio.h> --#include <linux/regulator/consumer.h> --#include <video/omapdss.h> -- --#include "ti_hdmi.h" --#include "dss.h" --#include "dss_features.h" -- --#define HDMI_WP 0x0 --#define HDMI_CORE_SYS 0x400 --#define HDMI_CORE_AV 0x900 --#define HDMI_PLLCTRL 0x200 --#define HDMI_PHY 0x300 -- --/* HDMI EDID Length move this */ --#define HDMI_EDID_MAX_LENGTH 256 --#define EDID_TIMING_DESCRIPTOR_SIZE 0x12 --#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36 --#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80 --#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 --#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 -- --#define HDMI_DEFAULT_REGN 16 --#define HDMI_DEFAULT_REGM2 1 -- --static struct { -- struct mutex lock; -- struct platform_device *pdev; -- -- struct hdmi_ip_data ip_data; -- -- struct clk *sys_clk; -- struct regulator *vdda_hdmi_dac_reg; -- -- bool core_enabled; -- -- struct omap_dss_device output; --} hdmi; -- --/* -- * Logic for the below structure : -- * user enters the CEA or VESA timings by specifying the HDMI/DVI code. -- * There is a correspondence between CEA/VESA timing and code, please -- * refer to section 6.3 in HDMI 1.3 specification for timing code. -- * -- * In the below structure, cea_vesa_timings corresponds to all OMAP4 -- * supported CEA and VESA timing values.code_cea corresponds to the CEA -- * code, It is used to get the timing from cea_vesa_timing array.Similarly -- * with code_vesa. Code_index is used for back mapping, that is once EDID -- * is read from the TV, EDID is parsed to find the timing values and then -- * map it to corresponding CEA or VESA index. -- */ -- --static const struct hdmi_config cea_timings[] = { -- { -- { 640, 480, 25200, 96, 16, 48, 2, 10, 33, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 1, HDMI_HDMI }, -- }, -- { -- { 720, 480, 27027, 62, 16, 60, 6, 9, 30, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 2, HDMI_HDMI }, -- }, -- { -- { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 4, HDMI_HDMI }, -- }, -- { -- { 1920, 540, 74250, 44, 88, 148, 5, 2, 15, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- true, }, -- { 5, HDMI_HDMI }, -- }, -- { -- { 1440, 240, 27027, 124, 38, 114, 3, 4, 15, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- true, }, -- { 6, HDMI_HDMI }, -- }, -- { -- { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 16, HDMI_HDMI }, -- }, -- { -- { 720, 576, 27000, 64, 12, 68, 5, 5, 39, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 17, HDMI_HDMI }, -- }, -- { -- { 1280, 720, 74250, 40, 440, 220, 5, 5, 20, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 19, HDMI_HDMI }, -- }, -- { -- { 1920, 540, 74250, 44, 528, 148, 5, 2, 15, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- true, }, -- { 20, HDMI_HDMI }, -- }, -- { -- { 1440, 288, 27000, 126, 24, 138, 3, 2, 19, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- true, }, -- { 21, HDMI_HDMI }, -- }, -- { -- { 1440, 576, 54000, 128, 24, 136, 5, 5, 39, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 29, HDMI_HDMI }, -- }, -- { -- { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 31, HDMI_HDMI }, -- }, -- { -- { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 32, HDMI_HDMI }, -- }, -- { -- { 2880, 480, 108108, 248, 64, 240, 6, 9, 30, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 35, HDMI_HDMI }, -- }, -- { -- { 2880, 576, 108000, 256, 48, 272, 5, 5, 39, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 37, HDMI_HDMI }, -- }, --}; -- --static const struct hdmi_config vesa_timings[] = { --/* VESA From Here */ -- { -- { 640, 480, 25175, 96, 16, 48, 2, 11, 31, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 4, HDMI_DVI }, -- }, -- { -- { 800, 600, 40000, 128, 40, 88, 4, 1, 23, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 9, HDMI_DVI }, -- }, -- { -- { 848, 480, 33750, 112, 16, 112, 8, 6, 23, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0xE, HDMI_DVI }, -- }, -- { -- { 1280, 768, 79500, 128, 64, 192, 7, 3, 20, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 0x17, HDMI_DVI }, -- }, -- { -- { 1280, 800, 83500, 128, 72, 200, 6, 3, 22, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 0x1C, HDMI_DVI }, -- }, -- { -- { 1360, 768, 85500, 112, 64, 256, 6, 3, 18, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x27, HDMI_DVI }, -- }, -- { -- { 1280, 960, 108000, 112, 96, 312, 3, 1, 36, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x20, HDMI_DVI }, -- }, -- { -- { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x23, HDMI_DVI }, -- }, -- { -- { 1024, 768, 65000, 136, 24, 160, 6, 3, 29, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 0x10, HDMI_DVI }, -- }, -- { -- { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 0x2A, HDMI_DVI }, -- }, -- { -- { 1440, 900, 106500, 152, 80, 232, 6, 3, 25, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 0x2F, HDMI_DVI }, -- }, -- { -- { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -- false, }, -- { 0x3A, HDMI_DVI }, -- }, -- { -- { 1366, 768, 85500, 143, 70, 213, 3, 3, 24, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x51, HDMI_DVI }, -- }, -- { -- { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x52, HDMI_DVI }, -- }, -- { -- { 1280, 768, 68250, 32, 48, 80, 7, 3, 12, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x16, HDMI_DVI }, -- }, -- { -- { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x29, HDMI_DVI }, -- }, -- { -- { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x39, HDMI_DVI }, -- }, -- { -- { 1280, 800, 79500, 32, 48, 80, 6, 3, 14, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x1B, HDMI_DVI }, -- }, -- { -- { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, -- OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x55, HDMI_DVI }, -- }, -- { -- { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26, -- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -- false, }, -- { 0x44, HDMI_DVI }, -- }, --}; -- --static int hdmi_runtime_get(void) --{ -- int r; -- -- DSSDBG("hdmi_runtime_get\n"); -- -- r = pm_runtime_get_sync(&hdmi.pdev->dev); -- WARN_ON(r < 0); -- if (r < 0) -- return r; -- -- return 0; --} -- --static void hdmi_runtime_put(void) --{ -- int r; -- -- DSSDBG("hdmi_runtime_put\n"); -- -- r = pm_runtime_put_sync(&hdmi.pdev->dev); -- WARN_ON(r < 0 && r != -ENOSYS); --} -- --static int hdmi_init_regulator(void) --{ -- struct regulator *reg; -- -- if (hdmi.vdda_hdmi_dac_reg != NULL) -- return 0; -- -- reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); -- -- /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */ -- if (IS_ERR(reg)) -- reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC"); -- -- if (IS_ERR(reg)) { -- DSSERR("can't get VDDA_HDMI_DAC regulator\n"); -- return PTR_ERR(reg); -- } -- -- hdmi.vdda_hdmi_dac_reg = reg; -- -- return 0; --} -- --static const struct hdmi_config *hdmi_find_timing( -- const struct hdmi_config *timings_arr, -- int len) --{ -- int i; -- -- for (i = 0; i < len; i++) { -- if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code) -- return &timings_arr[i]; -- } -- return NULL; --} -- --static const struct hdmi_config *hdmi_get_timings(void) --{ -- const struct hdmi_config *arr; -- int len; -- -- if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) { -- arr = vesa_timings; -- len = ARRAY_SIZE(vesa_timings); -- } else { -- arr = cea_timings; -- len = ARRAY_SIZE(cea_timings); -- } -- -- return hdmi_find_timing(arr, len); --} -- --static bool hdmi_timings_compare(struct omap_video_timings *timing1, -- const struct omap_video_timings *timing2) --{ -- int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; -- -- if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) == -- DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) && -- (timing2->x_res == timing1->x_res) && -- (timing2->y_res == timing1->y_res)) { -- -- timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; -- timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; -- timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; -- timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; -- -- DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ -- "timing2_hsync = %d timing2_vsync = %d\n", -- timing1_hsync, timing1_vsync, -- timing2_hsync, timing2_vsync); -- -- if ((timing1_hsync == timing2_hsync) && -- (timing1_vsync == timing2_vsync)) { -- return true; -- } -- } -- return false; --} -- --static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) --{ -- int i; -- struct hdmi_cm cm = {-1}; -- DSSDBG("hdmi_get_code\n"); -- -- for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { -- if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { -- cm = cea_timings[i].cm; -- goto end; -- } -- } -- for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { -- if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { -- cm = vesa_timings[i].cm; -- goto end; -- } -- } -- --end: return cm; -- --} -- --static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, -- struct hdmi_pll_info *pi) --{ -- unsigned long clkin, refclk; -- u32 mf; -- -- clkin = clk_get_rate(hdmi.sys_clk) / 10000; -- /* -- * Input clock is predivided by N + 1 -- * out put of which is reference clk -- */ -- -- pi->regn = HDMI_DEFAULT_REGN; -- -- refclk = clkin / pi->regn; -- -- pi->regm2 = HDMI_DEFAULT_REGM2; -- -- /* -- * multiplier is pixel_clk/ref_clk -- * Multiplying by 100 to avoid fractional part removal -- */ -- pi->regm = phy * pi->regm2 / refclk; -- -- /* -- * fractional multiplier is remainder of the difference between -- * multiplier and actual phy(required pixel clock thus should be -- * multiplied by 2^18(262144) divided by the reference clock -- */ -- mf = (phy - pi->regm / pi->regm2 * refclk) * 262144; -- pi->regmf = pi->regm2 * mf / refclk; -- -- /* -- * Dcofreq should be set to 1 if required pixel clock -- * is greater than 1000MHz -- */ -- pi->dcofreq = phy > 1000 * 100; -- pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10; -- -- /* Set the reference clock to sysclk reference */ -- pi->refsel = HDMI_REFSEL_SYSCLK; -- -- DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); -- DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); --} -- --static int hdmi_power_on_core(struct omap_dss_device *dssdev) --{ -- int r; -- -- r = regulator_enable(hdmi.vdda_hdmi_dac_reg); -- if (r) -- return r; -- -- r = hdmi_runtime_get(); -- if (r) -- goto err_runtime_get; -- -- /* Make selection of HDMI in DSS */ -- dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); -- -- hdmi.core_enabled = true; -- -- return 0; -- --err_runtime_get: -- regulator_disable(hdmi.vdda_hdmi_dac_reg); -- -- return r; --} -- --static void hdmi_power_off_core(struct omap_dss_device *dssdev) --{ -- hdmi.core_enabled = false; -- -- hdmi_runtime_put(); -- regulator_disable(hdmi.vdda_hdmi_dac_reg); --} -- --static int hdmi_power_on_full(struct omap_dss_device *dssdev) --{ -- int r; -- struct omap_video_timings *p; -- struct omap_overlay_manager *mgr = hdmi.output.manager; -- unsigned long phy; -- -- r = hdmi_power_on_core(dssdev); -- if (r) -- return r; -- -- dss_mgr_disable(mgr); -- -- p = &hdmi.ip_data.cfg.timings; -- -- DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); -- -- phy = p->pixel_clock; -- -- hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); -- -- hdmi.ip_data.ops->video_disable(&hdmi.ip_data); -- -- /* config the PLL and PHY hdmi_set_pll_pwrfirst */ -- r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); -- if (r) { -- DSSDBG("Failed to lock PLL\n"); -- goto err_pll_enable; -- } -- -- r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); -- if (r) { -- DSSDBG("Failed to start PHY\n"); -- goto err_phy_enable; -- } -- -- hdmi.ip_data.ops->video_configure(&hdmi.ip_data); -- -- /* bypass TV gamma table */ -- dispc_enable_gamma_table(0); -- -- /* tv size */ -- dss_mgr_set_timings(mgr, p); -- -- r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); -- if (r) -- goto err_vid_enable; -- -- r = dss_mgr_enable(mgr); -- if (r) -- goto err_mgr_enable; -- -- return 0; -- --err_mgr_enable: -- hdmi.ip_data.ops->video_disable(&hdmi.ip_data); --err_vid_enable: -- hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); --err_phy_enable: -- hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); --err_pll_enable: -- hdmi_power_off_core(dssdev); -- return -EIO; --} -- --static void hdmi_power_off_full(struct omap_dss_device *dssdev) --{ -- struct omap_overlay_manager *mgr = hdmi.output.manager; -- -- dss_mgr_disable(mgr); -- -- hdmi.ip_data.ops->video_disable(&hdmi.ip_data); -- hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); -- hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); -- -- hdmi_power_off_core(dssdev); --} -- --static int hdmi_display_check_timing(struct omap_dss_device *dssdev, -- struct omap_video_timings *timings) --{ -- struct hdmi_cm cm; -- -- cm = hdmi_get_code(timings); -- if (cm.code == -1) { -- return -EINVAL; -- } -- -- return 0; -- --} -- --static void hdmi_display_set_timing(struct omap_dss_device *dssdev, -- struct omap_video_timings *timings) --{ -- struct hdmi_cm cm; -- const struct hdmi_config *t; -- -- mutex_lock(&hdmi.lock); -- -- cm = hdmi_get_code(timings); -- hdmi.ip_data.cfg.cm = cm; -- -- t = hdmi_get_timings(); -- if (t != NULL) { -- hdmi.ip_data.cfg = *t; -- -- dispc_set_tv_pclk(t->timings.pixel_clock * 1000); -- } -- -- mutex_unlock(&hdmi.lock); --} -- --static void hdmi_display_get_timings(struct omap_dss_device *dssdev, -- struct omap_video_timings *timings) --{ -- const struct hdmi_config *cfg; -- -- cfg = hdmi_get_timings(); -- if (cfg == NULL) -- cfg = &vesa_timings[0]; -- -- memcpy(timings, &cfg->timings, sizeof(cfg->timings)); --} -- --static void hdmi_dump_regs(struct seq_file *s) --{ -- mutex_lock(&hdmi.lock); -- -- if (hdmi_runtime_get()) { -- mutex_unlock(&hdmi.lock); -- return; -- } -- -- hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); -- hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); -- hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s); -- hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s); -- -- hdmi_runtime_put(); -- mutex_unlock(&hdmi.lock); --} -- --static int read_edid(u8 *buf, int len) --{ -- int r; -- -- mutex_lock(&hdmi.lock); -- -- r = hdmi_runtime_get(); -- BUG_ON(r); -- -- r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len); -- -- hdmi_runtime_put(); -- mutex_unlock(&hdmi.lock); -- -- return r; --} -- --static int hdmi_display_enable(struct omap_dss_device *dssdev) --{ -- struct omap_dss_device *out = &hdmi.output; -- int r = 0; -- -- DSSDBG("ENTER hdmi_display_enable\n"); -- -- mutex_lock(&hdmi.lock); -- -- if (out == NULL || out->manager == NULL) { -- DSSERR("failed to enable display: no output/manager\n"); -- r = -ENODEV; -- goto err0; -- } -- -- r = hdmi_power_on_full(dssdev); -- if (r) { -- DSSERR("failed to power on device\n"); -- goto err0; -- } -- -- mutex_unlock(&hdmi.lock); -- return 0; -- --err0: -- mutex_unlock(&hdmi.lock); -- return r; --} -- --static void hdmi_display_disable(struct omap_dss_device *dssdev) --{ -- DSSDBG("Enter hdmi_display_disable\n"); -- -- mutex_lock(&hdmi.lock); -- -- hdmi_power_off_full(dssdev); -- -- mutex_unlock(&hdmi.lock); --} -- --static int hdmi_core_enable(struct omap_dss_device *dssdev) --{ -- int r = 0; -- -- DSSDBG("ENTER omapdss_hdmi_core_enable\n"); -- -- mutex_lock(&hdmi.lock); -- -- r = hdmi_power_on_core(dssdev); -- if (r) { -- DSSERR("failed to power on device\n"); -- goto err0; -- } -- -- mutex_unlock(&hdmi.lock); -- return 0; -- --err0: -- mutex_unlock(&hdmi.lock); -- return r; --} -- --static void hdmi_core_disable(struct omap_dss_device *dssdev) --{ -- DSSDBG("Enter omapdss_hdmi_core_disable\n"); -- -- mutex_lock(&hdmi.lock); -- -- hdmi_power_off_core(dssdev); -- -- mutex_unlock(&hdmi.lock); --} -- --static int hdmi_get_clocks(struct platform_device *pdev) --{ -- struct clk *clk; -- -- clk = devm_clk_get(&pdev->dev, "sys_clk"); -- if (IS_ERR(clk)) { -- DSSERR("can't get sys_clk\n"); -- return PTR_ERR(clk); -- } -- -- hdmi.sys_clk = clk; -- -- return 0; --} -- --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) --int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) --{ -- u32 deep_color; -- bool deep_color_correct = false; -- u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock; -- -- if (n == NULL || cts == NULL) -- return -EINVAL; -- -- /* TODO: When implemented, query deep color mode here. */ -- deep_color = 100; -- -- /* -- * When using deep color, the default N value (as in the HDMI -- * specification) yields to an non-integer CTS. Hence, we -- * modify it while keeping the restrictions described in -- * section 7.2.1 of the HDMI 1.4a specification. -- */ -- switch (sample_freq) { -- case 32000: -- case 48000: -- case 96000: -- case 192000: -- if (deep_color == 125) -- if (pclk == 27027 || pclk == 74250) -- deep_color_correct = true; -- if (deep_color == 150) -- if (pclk == 27027) -- deep_color_correct = true; -- break; -- case 44100: -- case 88200: -- case 176400: -- if (deep_color == 125) -- if (pclk == 27027) -- deep_color_correct = true; -- break; -- default: -- return -EINVAL; -- } -- -- if (deep_color_correct) { -- switch (sample_freq) { -- case 32000: -- *n = 8192; -- break; -- case 44100: -- *n = 12544; -- break; -- case 48000: -- *n = 8192; -- break; -- case 88200: -- *n = 25088; -- break; -- case 96000: -- *n = 16384; -- break; -- case 176400: -- *n = 50176; -- break; -- case 192000: -- *n = 32768; -- break; -- default: -- return -EINVAL; -- } -- } else { -- switch (sample_freq) { -- case 32000: -- *n = 4096; -- break; -- case 44100: -- *n = 6272; -- break; -- case 48000: -- *n = 6144; -- break; -- case 88200: -- *n = 12544; -- break; -- case 96000: -- *n = 12288; -- break; -- case 176400: -- *n = 25088; -- break; -- case 192000: -- *n = 24576; -- break; -- default: -- return -EINVAL; -- } -- } -- /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ -- *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); -- -- return 0; --} -- --static bool hdmi_mode_has_audio(void) --{ -- if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) -- return true; -- else -- return false; --} -- --#endif -- --static int hdmi_connect(struct omap_dss_device *dssdev, -- struct omap_dss_device *dst) --{ -- struct omap_overlay_manager *mgr; -- int r; -- -- dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); -- -- r = hdmi_init_regulator(); -- if (r) -- return r; -- -- mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); -- if (!mgr) -- return -ENODEV; -- -- r = dss_mgr_connect(mgr, dssdev); -- if (r) -- return r; -- -- r = omapdss_output_set_device(dssdev, dst); -- if (r) { -- DSSERR("failed to connect output to new device: %s\n", -- dst->name); -- dss_mgr_disconnect(mgr, dssdev); -- return r; -- } -- -- return 0; --} -- --static void hdmi_disconnect(struct omap_dss_device *dssdev, -- struct omap_dss_device *dst) --{ -- WARN_ON(dst != dssdev->dst); -- -- if (dst != dssdev->dst) -- return; -- -- omapdss_output_unset_device(dssdev); -- -- if (dssdev->manager) -- dss_mgr_disconnect(dssdev->manager, dssdev); --} -- --static int hdmi_read_edid(struct omap_dss_device *dssdev, -- u8 *edid, int len) --{ -- bool need_enable; -- int r; -- -- need_enable = hdmi.core_enabled == false; -- -- if (need_enable) { -- r = hdmi_core_enable(dssdev); -- if (r) -- return r; -- } -- -- r = read_edid(edid, len); -- -- if (need_enable) -- hdmi_core_disable(dssdev); -- -- return r; --} -- --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) --static int hdmi_audio_enable(struct omap_dss_device *dssdev) --{ -- int r; -- -- mutex_lock(&hdmi.lock); -- -- if (!hdmi_mode_has_audio()) { -- r = -EPERM; -- goto err; -- } -- -- -- r = hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); -- if (r) -- goto err; -- -- mutex_unlock(&hdmi.lock); -- return 0; -- --err: -- mutex_unlock(&hdmi.lock); -- return r; --} -- --static void hdmi_audio_disable(struct omap_dss_device *dssdev) --{ -- hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); --} -- --static int hdmi_audio_start(struct omap_dss_device *dssdev) --{ -- return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); --} -- --static void hdmi_audio_stop(struct omap_dss_device *dssdev) --{ -- hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); --} -- --static bool hdmi_audio_supported(struct omap_dss_device *dssdev) --{ -- bool r; -- -- mutex_lock(&hdmi.lock); -- -- r = hdmi_mode_has_audio(); -- -- mutex_unlock(&hdmi.lock); -- return r; --} -- --static int hdmi_audio_config(struct omap_dss_device *dssdev, -- struct omap_dss_audio *audio) --{ -- int r; -- -- mutex_lock(&hdmi.lock); -- -- if (!hdmi_mode_has_audio()) { -- r = -EPERM; -- goto err; -- } -- -- r = hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); -- if (r) -- goto err; -- -- mutex_unlock(&hdmi.lock); -- return 0; -- --err: -- mutex_unlock(&hdmi.lock); -- return r; --} --#else --static int hdmi_audio_enable(struct omap_dss_device *dssdev) --{ -- return -EPERM; --} -- --static void hdmi_audio_disable(struct omap_dss_device *dssdev) --{ --} -- --static int hdmi_audio_start(struct omap_dss_device *dssdev) --{ -- return -EPERM; --} -- --static void hdmi_audio_stop(struct omap_dss_device *dssdev) --{ --} -- --static bool hdmi_audio_supported(struct omap_dss_device *dssdev) --{ -- return false; --} -- --static int hdmi_audio_config(struct omap_dss_device *dssdev, -- struct omap_dss_audio *audio) --{ -- return -EPERM; --} --#endif -- --static const struct omapdss_hdmi_ops hdmi_ops = { -- .connect = hdmi_connect, -- .disconnect = hdmi_disconnect, -- -- .enable = hdmi_display_enable, -- .disable = hdmi_display_disable, -- -- .check_timings = hdmi_display_check_timing, -- .set_timings = hdmi_display_set_timing, -- .get_timings = hdmi_display_get_timings, -- -- .read_edid = hdmi_read_edid, -- -- .audio_enable = hdmi_audio_enable, -- .audio_disable = hdmi_audio_disable, -- .audio_start = hdmi_audio_start, -- .audio_stop = hdmi_audio_stop, -- .audio_supported = hdmi_audio_supported, -- .audio_config = hdmi_audio_config, --}; -- --static void hdmi_init_output(struct platform_device *pdev) --{ -- struct omap_dss_device *out = &hdmi.output; -- -- out->dev = &pdev->dev; -- out->id = OMAP_DSS_OUTPUT_HDMI; -- out->output_type = OMAP_DISPLAY_TYPE_HDMI; -- out->name = "hdmi.0"; -- out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; -- out->ops.hdmi = &hdmi_ops; -- out->owner = THIS_MODULE; -- -- omapdss_register_output(out); --} -- --static void __exit hdmi_uninit_output(struct platform_device *pdev) --{ -- struct omap_dss_device *out = &hdmi.output; -- -- omapdss_unregister_output(out); --} -- --/* HDMI HW IP initialisation */ --static int omapdss_hdmihw_probe(struct platform_device *pdev) --{ -- struct resource *res; -- int r; -- -- hdmi.pdev = pdev; -- -- mutex_init(&hdmi.lock); -- mutex_init(&hdmi.ip_data.lock); -- -- res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); -- -- /* Base address taken from platform */ -- hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res); -- if (IS_ERR(hdmi.ip_data.base_wp)) -- return PTR_ERR(hdmi.ip_data.base_wp); -- -- hdmi.ip_data.irq = platform_get_irq(pdev, 0); -- if (hdmi.ip_data.irq < 0) { -- DSSERR("platform_get_irq failed\n"); -- return -ENODEV; -- } -- -- r = hdmi_get_clocks(pdev); -- if (r) { -- DSSERR("can't get clocks\n"); -- return r; -- } -- -- pm_runtime_enable(&pdev->dev); -- -- hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS; -- hdmi.ip_data.core_av_offset = HDMI_CORE_AV; -- hdmi.ip_data.pll_offset = HDMI_PLLCTRL; -- hdmi.ip_data.phy_offset = HDMI_PHY; -- -- hdmi_init_output(pdev); -- -- dss_debugfs_create_file("hdmi", hdmi_dump_regs); -- -- return 0; --} -- --static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) --{ -- hdmi_uninit_output(pdev); -- -- pm_runtime_disable(&pdev->dev); -- -- return 0; --} -- --static int hdmi_runtime_suspend(struct device *dev) --{ -- clk_disable_unprepare(hdmi.sys_clk); -- -- dispc_runtime_put(); -- -- return 0; --} -- --static int hdmi_runtime_resume(struct device *dev) --{ -- int r; -- -- r = dispc_runtime_get(); -- if (r < 0) -- return r; -- -- clk_prepare_enable(hdmi.sys_clk); -- -- return 0; --} -- --static const struct dev_pm_ops hdmi_pm_ops = { -- .runtime_suspend = hdmi_runtime_suspend, -- .runtime_resume = hdmi_runtime_resume, --}; -- --static struct platform_driver omapdss_hdmihw_driver = { -- .probe = omapdss_hdmihw_probe, -- .remove = __exit_p(omapdss_hdmihw_remove), -- .driver = { -- .name = "omapdss_hdmi", -- .owner = THIS_MODULE, -- .pm = &hdmi_pm_ops, -- }, --}; -- --int __init hdmi_init_platform_driver(void) --{ -- return platform_driver_register(&omapdss_hdmihw_driver); --} -- --void __exit hdmi_uninit_platform_driver(void) --{ -- platform_driver_unregister(&omapdss_hdmihw_driver); --} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi_common.c -@@ -0,0 +1,423 @@ -+ -+/* -+ * Logic for the below structure : -+ * user enters the CEA or VESA timings by specifying the HDMI/DVI code. -+ * There is a correspondence between CEA/VESA timing and code, please -+ * refer to section 6.3 in HDMI 1.3 specification for timing code. -+ * -+ * In the below structure, cea_vesa_timings corresponds to all OMAP4 -+ * supported CEA and VESA timing values.code_cea corresponds to the CEA -+ * code, It is used to get the timing from cea_vesa_timing array.Similarly -+ * with code_vesa. Code_index is used for back mapping, that is once EDID -+ * is read from the TV, EDID is parsed to find the timing values and then -+ * map it to corresponding CEA or VESA index. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/err.h> -+#include <video/omapdss.h> -+ -+#include "hdmi.h" -+ -+static const struct hdmi_config cea_timings[] = { -+ { -+ { 640, 480, 25200, 96, 16, 48, 2, 10, 33, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 1, HDMI_HDMI }, -+ }, -+ { -+ { 720, 480, 27027, 62, 16, 60, 6, 9, 30, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 2, HDMI_HDMI }, -+ }, -+ { -+ { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 4, HDMI_HDMI }, -+ }, -+ { -+ { 1920, 540, 74250, 44, 88, 148, 5, 2, 15, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ true, }, -+ { 5, HDMI_HDMI }, -+ }, -+ { -+ { 1440, 240, 27027, 124, 38, 114, 3, 4, 15, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ true, }, -+ { 6, HDMI_HDMI }, -+ }, -+ { -+ { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 16, HDMI_HDMI }, -+ }, -+ { -+ { 720, 576, 27000, 64, 12, 68, 5, 5, 39, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 17, HDMI_HDMI }, -+ }, -+ { -+ { 1280, 720, 74250, 40, 440, 220, 5, 5, 20, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 19, HDMI_HDMI }, -+ }, -+ { -+ { 1920, 540, 74250, 44, 528, 148, 5, 2, 15, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ true, }, -+ { 20, HDMI_HDMI }, -+ }, -+ { -+ { 1440, 288, 27000, 126, 24, 138, 3, 2, 19, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ true, }, -+ { 21, HDMI_HDMI }, -+ }, -+ { -+ { 1440, 576, 54000, 128, 24, 136, 5, 5, 39, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 29, HDMI_HDMI }, -+ }, -+ { -+ { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 31, HDMI_HDMI }, -+ }, -+ { -+ { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 32, HDMI_HDMI }, -+ }, -+ { -+ { 2880, 480, 108108, 248, 64, 240, 6, 9, 30, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 35, HDMI_HDMI }, -+ }, -+ { -+ { 2880, 576, 108000, 256, 48, 272, 5, 5, 39, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 37, HDMI_HDMI }, -+ }, -+}; -+ -+static const struct hdmi_config vesa_timings[] = { -+/* VESA From Here */ -+ { -+ { 640, 480, 25175, 96, 16, 48, 2, 11, 31, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 4, HDMI_DVI }, -+ }, -+ { -+ { 800, 600, 40000, 128, 40, 88, 4, 1, 23, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 9, HDMI_DVI }, -+ }, -+ { -+ { 848, 480, 33750, 112, 16, 112, 8, 6, 23, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0xE, HDMI_DVI }, -+ }, -+ { -+ { 1280, 768, 79500, 128, 64, 192, 7, 3, 20, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 0x17, HDMI_DVI }, -+ }, -+ { -+ { 1280, 800, 83500, 128, 72, 200, 6, 3, 22, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 0x1C, HDMI_DVI }, -+ }, -+ { -+ { 1360, 768, 85500, 112, 64, 256, 6, 3, 18, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x27, HDMI_DVI }, -+ }, -+ { -+ { 1280, 960, 108000, 112, 96, 312, 3, 1, 36, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x20, HDMI_DVI }, -+ }, -+ { -+ { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x23, HDMI_DVI }, -+ }, -+ { -+ { 1024, 768, 65000, 136, 24, 160, 6, 3, 29, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 0x10, HDMI_DVI }, -+ }, -+ { -+ { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 0x2A, HDMI_DVI }, -+ }, -+ { -+ { 1440, 900, 106500, 152, 80, 232, 6, 3, 25, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 0x2F, HDMI_DVI }, -+ }, -+ { -+ { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -+ false, }, -+ { 0x3A, HDMI_DVI }, -+ }, -+ { -+ { 1366, 768, 85500, 143, 70, 213, 3, 3, 24, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x51, HDMI_DVI }, -+ }, -+ { -+ { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x52, HDMI_DVI }, -+ }, -+ { -+ { 1280, 768, 68250, 32, 48, 80, 7, 3, 12, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x16, HDMI_DVI }, -+ }, -+ { -+ { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x29, HDMI_DVI }, -+ }, -+ { -+ { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x39, HDMI_DVI }, -+ }, -+ { -+ { 1280, 800, 79500, 32, 48, 80, 6, 3, 14, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x1B, HDMI_DVI }, -+ }, -+ { -+ { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, -+ OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x55, HDMI_DVI }, -+ }, -+ { -+ { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26, -+ OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -+ false, }, -+ { 0x44, HDMI_DVI }, -+ }, -+}; -+ -+const struct hdmi_config *hdmi_default_timing(void) -+{ -+ return &vesa_timings[0]; -+} -+ -+static const struct hdmi_config *hdmi_find_timing(int code, -+ const struct hdmi_config *timings_arr, int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i++) { -+ if (timings_arr[i].cm.code == code) -+ return &timings_arr[i]; -+ } -+ -+ return NULL; -+} -+ -+const struct hdmi_config *hdmi_get_timings(int mode, int code) -+{ -+ const struct hdmi_config *arr; -+ int len; -+ -+ if (mode == HDMI_DVI) { -+ arr = vesa_timings; -+ len = ARRAY_SIZE(vesa_timings); -+ } else { -+ arr = cea_timings; -+ len = ARRAY_SIZE(cea_timings); -+ } -+ -+ return hdmi_find_timing(code, arr, len); -+} -+ -+static bool hdmi_timings_compare(struct omap_video_timings *timing1, -+ const struct omap_video_timings *timing2) -+{ -+ int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; -+ -+ if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) == -+ DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) && -+ (timing2->x_res == timing1->x_res) && -+ (timing2->y_res == timing1->y_res)) { -+ -+ timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; -+ timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; -+ timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; -+ timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; -+ -+ DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ -+ "timing2_hsync = %d timing2_vsync = %d\n", -+ timing1_hsync, timing1_vsync, -+ timing2_hsync, timing2_vsync); -+ -+ if ((timing1_hsync == timing2_hsync) && -+ (timing1_vsync == timing2_vsync)) { -+ return true; -+ } -+ } -+ return false; -+} -+ -+struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) -+{ -+ int i; -+ struct hdmi_cm cm = {-1}; -+ DSSDBG("hdmi_get_code\n"); -+ -+ for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { -+ if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { -+ cm = cea_timings[i].cm; -+ goto end; -+ } -+ } -+ for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { -+ if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { -+ cm = vesa_timings[i].cm; -+ goto end; -+ } -+ } -+ -+end: -+ return cm; -+} -+ -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -+int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) -+{ -+ u32 deep_color; -+ bool deep_color_correct = false; -+ -+ if (n == NULL || cts == NULL) -+ return -EINVAL; -+ -+ /* TODO: When implemented, query deep color mode here. */ -+ deep_color = 100; -+ -+ /* -+ * When using deep color, the default N value (as in the HDMI -+ * specification) yields to an non-integer CTS. Hence, we -+ * modify it while keeping the restrictions described in -+ * section 7.2.1 of the HDMI 1.4a specification. -+ */ -+ switch (sample_freq) { -+ case 32000: -+ case 48000: -+ case 96000: -+ case 192000: -+ if (deep_color == 125) -+ if (pclk == 27027 || pclk == 74250) -+ deep_color_correct = true; -+ if (deep_color == 150) -+ if (pclk == 27027) -+ deep_color_correct = true; -+ break; -+ case 44100: -+ case 88200: -+ case 176400: -+ if (deep_color == 125) -+ if (pclk == 27027) -+ deep_color_correct = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (deep_color_correct) { -+ switch (sample_freq) { -+ case 32000: -+ *n = 8192; -+ break; -+ case 44100: -+ *n = 12544; -+ break; -+ case 48000: -+ *n = 8192; -+ break; -+ case 88200: -+ *n = 25088; -+ break; -+ case 96000: -+ *n = 16384; -+ break; -+ case 176400: -+ *n = 50176; -+ break; -+ case 192000: -+ *n = 32768; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ switch (sample_freq) { -+ case 32000: -+ *n = 4096; -+ break; -+ case 44100: -+ *n = 6272; -+ break; -+ case 48000: -+ *n = 6144; -+ break; -+ case 88200: -+ *n = 12544; -+ break; -+ case 96000: -+ *n = 12288; -+ break; -+ case 176400: -+ *n = 25088; -+ break; -+ case 192000: -+ *n = 24576; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ -+ *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); -+ -+ return 0; -+} -+#endif ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi.h -@@ -0,0 +1,441 @@ -+/* -+ * HDMI driver definition for TI OMAP4 Processor. -+ * -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * -+ * 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, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef _HDMI_H -+#define _HDMI_H -+ -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <video/omapdss.h> -+ -+#include "dss.h" -+ -+/* HDMI Wrapper */ -+ -+#define HDMI_WP_REVISION 0x0 -+#define HDMI_WP_SYSCONFIG 0x10 -+#define HDMI_WP_IRQSTATUS_RAW 0x24 -+#define HDMI_WP_IRQSTATUS 0x28 -+#define HDMI_WP_IRQENABLE_SET 0x2C -+#define HDMI_WP_IRQENABLE_CLR 0x30 -+#define HDMI_WP_IRQWAKEEN 0x34 -+#define HDMI_WP_PWR_CTRL 0x40 -+#define HDMI_WP_DEBOUNCE 0x44 -+#define HDMI_WP_VIDEO_CFG 0x50 -+#define HDMI_WP_VIDEO_SIZE 0x60 -+#define HDMI_WP_VIDEO_TIMING_H 0x68 -+#define HDMI_WP_VIDEO_TIMING_V 0x6C -+#define HDMI_WP_CLK 0x70 -+#define HDMI_WP_AUDIO_CFG 0x80 -+#define HDMI_WP_AUDIO_CFG2 0x84 -+#define HDMI_WP_AUDIO_CTRL 0x88 -+#define HDMI_WP_AUDIO_DATA 0x8C -+ -+/* HDMI WP IRQ flags */ -+#define HDMI_IRQ_CORE (1 << 0) -+#define HDMI_IRQ_OCP_TIMEOUT (1 << 4) -+#define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW (1 << 8) -+#define HDMI_IRQ_AUDIO_FIFO_OVERFLOW (1 << 9) -+#define HDMI_IRQ_AUDIO_FIFO_SAMPLE_REQ (1 << 10) -+#define HDMI_IRQ_VIDEO_VSYNC (1 << 16) -+#define HDMI_IRQ_VIDEO_FRAME_DONE (1 << 17) -+#define HDMI_IRQ_PHY_LINE5V_ASSERT (1 << 24) -+#define HDMI_IRQ_LINK_CONNECT (1 << 25) -+#define HDMI_IRQ_LINK_DISCONNECT (1 << 26) -+#define HDMI_IRQ_PLL_LOCK (1 << 29) -+#define HDMI_IRQ_PLL_UNLOCK (1 << 30) -+#define HDMI_IRQ_PLL_RECAL (1 << 31) -+ -+/* HDMI PLL */ -+ -+#define PLLCTRL_PLL_CONTROL 0x0 -+#define PLLCTRL_PLL_STATUS 0x4 -+#define PLLCTRL_PLL_GO 0x8 -+#define PLLCTRL_CFG1 0xC -+#define PLLCTRL_CFG2 0x10 -+#define PLLCTRL_CFG3 0x14 -+#define PLLCTRL_SSC_CFG1 0x18 -+#define PLLCTRL_SSC_CFG2 0x1C -+#define PLLCTRL_CFG4 0x20 -+ -+/* HDMI PHY */ -+ -+#define HDMI_TXPHY_TX_CTRL 0x0 -+#define HDMI_TXPHY_DIGITAL_CTRL 0x4 -+#define HDMI_TXPHY_POWER_CTRL 0x8 -+#define HDMI_TXPHY_PAD_CFG_CTRL 0xC -+#define HDMI_TXPHY_BIST_CONTROL 0x1C -+ -+enum hdmi_pll_pwr { -+ HDMI_PLLPWRCMD_ALLOFF = 0, -+ HDMI_PLLPWRCMD_PLLONLY = 1, -+ HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2, -+ HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 -+}; -+ -+enum hdmi_phy_pwr { -+ HDMI_PHYPWRCMD_OFF = 0, -+ HDMI_PHYPWRCMD_LDOON = 1, -+ HDMI_PHYPWRCMD_TXON = 2 -+}; -+ -+enum hdmi_core_hdmi_dvi { -+ HDMI_DVI = 0, -+ HDMI_HDMI = 1 -+}; -+ -+enum hdmi_clk_refsel { -+ HDMI_REFSEL_PCLK = 0, -+ HDMI_REFSEL_REF1 = 1, -+ HDMI_REFSEL_REF2 = 2, -+ HDMI_REFSEL_SYSCLK = 3 -+}; -+ -+enum hdmi_packing_mode { -+ HDMI_PACK_10b_RGB_YUV444 = 0, -+ HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, -+ HDMI_PACK_20b_YUV422 = 2, -+ HDMI_PACK_ALREADYPACKED = 7 -+}; -+ -+enum hdmi_stereo_channels { -+ HDMI_AUDIO_STEREO_NOCHANNELS = 0, -+ HDMI_AUDIO_STEREO_ONECHANNEL = 1, -+ HDMI_AUDIO_STEREO_TWOCHANNELS = 2, -+ HDMI_AUDIO_STEREO_THREECHANNELS = 3, -+ HDMI_AUDIO_STEREO_FOURCHANNELS = 4 -+}; -+ -+enum hdmi_audio_type { -+ HDMI_AUDIO_TYPE_LPCM = 0, -+ HDMI_AUDIO_TYPE_IEC = 1 -+}; -+ -+enum hdmi_audio_justify { -+ HDMI_AUDIO_JUSTIFY_LEFT = 0, -+ HDMI_AUDIO_JUSTIFY_RIGHT = 1 -+}; -+ -+enum hdmi_audio_sample_order { -+ HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, -+ HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 -+}; -+ -+enum hdmi_audio_samples_perword { -+ HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, -+ HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 -+}; -+ -+enum hdmi_audio_sample_size { -+ HDMI_AUDIO_SAMPLE_16BITS = 0, -+ HDMI_AUDIO_SAMPLE_24BITS = 1 -+}; -+ -+enum hdmi_audio_transf_mode { -+ HDMI_AUDIO_TRANSF_DMA = 0, -+ HDMI_AUDIO_TRANSF_IRQ = 1 -+}; -+ -+enum hdmi_audio_blk_strt_end_sig { -+ HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, -+ HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 -+}; -+ -+enum hdmi_core_audio_layout { -+ HDMI_AUDIO_LAYOUT_2CH = 0, -+ HDMI_AUDIO_LAYOUT_8CH = 1 -+}; -+ -+enum hdmi_core_cts_mode { -+ HDMI_AUDIO_CTS_MODE_HW = 0, -+ HDMI_AUDIO_CTS_MODE_SW = 1 -+}; -+ -+enum hdmi_audio_mclk_mode { -+ HDMI_AUDIO_MCLK_128FS = 0, -+ HDMI_AUDIO_MCLK_256FS = 1, -+ HDMI_AUDIO_MCLK_384FS = 2, -+ HDMI_AUDIO_MCLK_512FS = 3, -+ HDMI_AUDIO_MCLK_768FS = 4, -+ HDMI_AUDIO_MCLK_1024FS = 5, -+ HDMI_AUDIO_MCLK_1152FS = 6, -+ HDMI_AUDIO_MCLK_192FS = 7 -+}; -+ -+/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */ -+enum hdmi_core_infoframe { -+ HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, -+ HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, -+ HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1, -+ HDMI_INFOFRAME_AVI_DB1B_NO = 0, -+ HDMI_INFOFRAME_AVI_DB1B_VERT = 1, -+ HDMI_INFOFRAME_AVI_DB1B_HORI = 2, -+ HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, -+ HDMI_INFOFRAME_AVI_DB1S_0 = 0, -+ HDMI_INFOFRAME_AVI_DB1S_1 = 1, -+ HDMI_INFOFRAME_AVI_DB1S_2 = 2, -+ HDMI_INFOFRAME_AVI_DB2C_NO = 0, -+ HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, -+ HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, -+ HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, -+ HDMI_INFOFRAME_AVI_DB2M_NO = 0, -+ HDMI_INFOFRAME_AVI_DB2M_43 = 1, -+ HDMI_INFOFRAME_AVI_DB2M_169 = 2, -+ HDMI_INFOFRAME_AVI_DB2R_SAME = 8, -+ HDMI_INFOFRAME_AVI_DB2R_43 = 9, -+ HDMI_INFOFRAME_AVI_DB2R_169 = 10, -+ HDMI_INFOFRAME_AVI_DB2R_149 = 11, -+ HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, -+ HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, -+ HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, -+ HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, -+ HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, -+ HDMI_INFOFRAME_AVI_DB3Q_LR = 1, -+ HDMI_INFOFRAME_AVI_DB3Q_FR = 2, -+ HDMI_INFOFRAME_AVI_DB3SC_NO = 0, -+ HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, -+ HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, -+ HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, -+ HDMI_INFOFRAME_AVI_DB5PR_NO = 0, -+ HDMI_INFOFRAME_AVI_DB5PR_2 = 1, -+ HDMI_INFOFRAME_AVI_DB5PR_3 = 2, -+ HDMI_INFOFRAME_AVI_DB5PR_4 = 3, -+ HDMI_INFOFRAME_AVI_DB5PR_5 = 4, -+ HDMI_INFOFRAME_AVI_DB5PR_6 = 5, -+ HDMI_INFOFRAME_AVI_DB5PR_7 = 6, -+ HDMI_INFOFRAME_AVI_DB5PR_8 = 7, -+ HDMI_INFOFRAME_AVI_DB5PR_9 = 8, -+ HDMI_INFOFRAME_AVI_DB5PR_10 = 9, -+}; -+ -+struct hdmi_cm { -+ int code; -+ int mode; -+}; -+ -+struct hdmi_video_format { -+ enum hdmi_packing_mode packing_mode; -+ u32 y_res; /* Line per panel */ -+ u32 x_res; /* pixel per line */ -+}; -+ -+struct hdmi_config { -+ struct omap_video_timings timings; -+ struct hdmi_cm cm; -+}; -+ -+/* HDMI PLL structure */ -+struct hdmi_pll_info { -+ u16 regn; -+ u16 regm; -+ u32 regmf; -+ u16 regm2; -+ u16 regsd; -+ u16 dcofreq; -+ enum hdmi_clk_refsel refsel; -+}; -+ -+struct hdmi_audio_format { -+ enum hdmi_stereo_channels stereo_channels; -+ u8 active_chnnls_msk; -+ enum hdmi_audio_type type; -+ enum hdmi_audio_justify justification; -+ enum hdmi_audio_sample_order sample_order; -+ enum hdmi_audio_samples_perword samples_per_word; -+ enum hdmi_audio_sample_size sample_size; -+ enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; -+}; -+ -+struct hdmi_audio_dma { -+ u8 transfer_size; -+ u8 block_size; -+ enum hdmi_audio_transf_mode mode; -+ u16 fifo_threshold; -+}; -+ -+struct hdmi_core_audio_i2s_config { -+ u8 in_length_bits; -+ u8 justification; -+ u8 sck_edge_mode; -+ u8 vbit; -+ u8 direction; -+ u8 shift; -+ u8 active_sds; -+}; -+ -+struct hdmi_core_audio_config { -+ struct hdmi_core_audio_i2s_config i2s_cfg; -+ struct snd_aes_iec958 *iec60958_cfg; -+ bool fs_override; -+ u32 n; -+ u32 cts; -+ u32 aud_par_busclk; -+ enum hdmi_core_audio_layout layout; -+ enum hdmi_core_cts_mode cts_mode; -+ bool use_mclk; -+ enum hdmi_audio_mclk_mode mclk_mode; -+ bool en_acr_pkt; -+ bool en_dsd_audio; -+ bool en_parallel_aud_input; -+ bool en_spdif; -+}; -+ -+/* -+ * Refer to section 8.2 in HDMI 1.3 specification for -+ * details about infoframe databytes -+ */ -+struct hdmi_core_infoframe_avi { -+ /* Y0, Y1 rgb,yCbCr */ -+ u8 db1_format; -+ /* A0 Active information Present */ -+ u8 db1_active_info; -+ /* B0, B1 Bar info data valid */ -+ u8 db1_bar_info_dv; -+ /* S0, S1 scan information */ -+ u8 db1_scan_info; -+ /* C0, C1 colorimetry */ -+ u8 db2_colorimetry; -+ /* M0, M1 Aspect ratio (4:3, 16:9) */ -+ u8 db2_aspect_ratio; -+ /* R0...R3 Active format aspect ratio */ -+ u8 db2_active_fmt_ar; -+ /* ITC IT content. */ -+ u8 db3_itc; -+ /* EC0, EC1, EC2 Extended colorimetry */ -+ u8 db3_ec; -+ /* Q1, Q0 Quantization range */ -+ u8 db3_q_range; -+ /* SC1, SC0 Non-uniform picture scaling */ -+ u8 db3_nup_scaling; -+ /* VIC0..6 Video format identification */ -+ u8 db4_videocode; -+ /* PR0..PR3 Pixel repetition factor */ -+ u8 db5_pixel_repeat; -+ /* Line number end of top bar */ -+ u16 db6_7_line_eoftop; -+ /* Line number start of bottom bar */ -+ u16 db8_9_line_sofbottom; -+ /* Pixel number end of left bar */ -+ u16 db10_11_pixel_eofleft; -+ /* Pixel number start of right bar */ -+ u16 db12_13_pixel_sofright; -+}; -+ -+struct hdmi_wp_data { -+ void __iomem *base; -+}; -+ -+struct hdmi_pll_data { -+ void __iomem *base; -+ -+ struct hdmi_pll_info info; -+}; -+ -+struct hdmi_phy_data { -+ void __iomem *base; -+}; -+ -+struct hdmi_core_data { -+ void __iomem *base; -+ -+ struct hdmi_core_infoframe_avi avi_cfg; -+}; -+ -+static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, -+ u32 val) -+{ -+ __raw_writel(val, base_addr + idx); -+} -+ -+static inline u32 hdmi_read_reg(void __iomem *base_addr, const u32 idx) -+{ -+ return __raw_readl(base_addr + idx); -+} -+ -+#define REG_FLD_MOD(base, idx, val, start, end) \ -+ hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ -+ val, start, end)) -+#define REG_GET(base, idx, start, end) \ -+ FLD_GET(hdmi_read_reg(base, idx), start, end) -+ -+static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, -+ const u32 idx, int b2, int b1, u32 val) -+{ -+ u32 t = 0, v; -+ while (val != (v = REG_GET(base_addr, idx, b2, b1))) { -+ if (t++ > 10000) -+ return v; -+ udelay(1); -+ } -+ return v; -+} -+ -+/* HDMI wrapper funcs */ -+int hdmi_wp_video_start(struct hdmi_wp_data *wp); -+void hdmi_wp_video_stop(struct hdmi_wp_data *wp); -+void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s); -+u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp); -+void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus); -+void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask); -+void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask); -+int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val); -+int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val); -+void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, -+ struct hdmi_video_format *video_fmt); -+void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, -+ struct omap_video_timings *timings); -+void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, -+ struct omap_video_timings *timings); -+void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, -+ struct omap_video_timings *timings, struct hdmi_config *param); -+int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); -+ -+/* HDMI PLL funcs */ -+int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp); -+void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp); -+void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); -+void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy); -+int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll); -+ -+/* HDMI PHY funcs */ -+int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg); -+void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s); -+int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); -+ -+/* HDMI common funcs */ -+const struct hdmi_config *hdmi_default_timing(void); -+const struct hdmi_config *hdmi_get_timings(int mode, int code); -+struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing); -+ -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) -+int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); -+int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); -+int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); -+void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, -+ struct hdmi_audio_format *aud_fmt); -+void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, -+ struct hdmi_audio_dma *aud_dma); -+static inline bool hdmi_mode_has_audio(int mode) -+{ -+ return mode == HDMI_HDMI ? true : false; -+} -+#endif -+#endif ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi_phy.c -@@ -0,0 +1,167 @@ -+/* -+ * HDMI PHY -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+#include <video/omapdss.h> -+ -+#include "dss.h" -+#include "hdmi.h" -+ -+struct hdmi_phy_features { -+ bool bist_ctrl; -+ bool calc_freqout; -+ bool ldo_voltage; -+ unsigned long dcofreq_min; /* in KHz */ -+ unsigned long max_phy; /* in KHz */ -+}; -+ -+static const struct hdmi_phy_features *phy_feat; -+ -+void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) -+{ -+#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ -+ hdmi_read_reg(phy->base, r)) -+ -+ DUMPPHY(HDMI_TXPHY_TX_CTRL); -+ DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); -+ DUMPPHY(HDMI_TXPHY_POWER_CTRL); -+ DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); -+ if (phy_feat->bist_ctrl) -+ DUMPPHY(HDMI_TXPHY_BIST_CONTROL); -+} -+ -+int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) -+{ -+ u8 freqout; -+ -+ /* -+ * Read address 0 in order to get the SCP reset done completed -+ * Dummy access performed to make sure reset is done -+ */ -+ hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); -+ -+ /* -+ * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the -+ * HDMI_PHYPWRCMD_LDOON command. -+ */ -+ if (phy_feat->bist_ctrl) -+ REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); -+ -+ if (phy_feat->calc_freqout) { -+ /* DCOCLK/10 is pixel clock, compare pclk with DCOCLK_MIN/10 */ -+ u32 dco_min = phy_feat->dcofreq_min / 10; -+ u32 pclk = cfg->timings.pixel_clock; -+ -+ if (pclk < dco_min) { -+ freqout = 0; -+ } else if ((pclk >= dco_min) && (pclk < phy_feat->max_phy)) { -+ freqout = 1; -+ } else { -+ freqout = 2; -+ } -+ } else { -+ freqout = 1; -+ } -+ -+ /* -+ * Write to phy address 0 to configure the clock -+ * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field -+ */ -+ REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, freqout, 31, 30); -+ -+ /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ -+ hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); -+ -+ /* Setup max LDO voltage */ -+ if (phy_feat->ldo_voltage) -+ REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); -+ -+ /* Write to phy address 3 to change the polarity control */ -+ REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); -+ -+ return 0; -+} -+ -+static const struct hdmi_phy_features omap44xx_phy_feats = { -+ .bist_ctrl = false, -+ .calc_freqout = false, -+ .ldo_voltage = true, -+ .dcofreq_min = 500000, -+ .max_phy = 185675, -+}; -+ -+static const struct hdmi_phy_features omap54xx_phy_feats = { -+ .bist_ctrl = true, -+ .calc_freqout = true, -+ .ldo_voltage = false, -+ .dcofreq_min = 750000, -+ .max_phy = 186000, -+}; -+ -+static int hdmi_phy_init_features(struct platform_device *pdev) -+{ -+ struct hdmi_phy_features *dst; -+ const struct hdmi_phy_features *src; -+ -+ dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); -+ if (!dst) { -+ dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); -+ return -ENOMEM; -+ } -+ -+ switch (omapdss_get_version()) { -+ case OMAPDSS_VER_OMAP4430_ES1: -+ case OMAPDSS_VER_OMAP4430_ES2: -+ case OMAPDSS_VER_OMAP4: -+ src = &omap44xx_phy_feats; -+ break; -+ -+ case OMAPDSS_VER_OMAP5: -+ case OMAPDSS_VER_DRA7xx: -+ src = &omap54xx_phy_feats; -+ break; -+ -+ default: -+ return -ENODEV; -+ } -+ -+ memcpy(dst, src, sizeof(*dst)); -+ phy_feat = dst; -+ -+ return 0; -+} -+ -+int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy) -+{ -+ int r; -+ struct resource *res; -+ -+ r = hdmi_phy_init_features(pdev); -+ if (r) -+ return r; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_txphy"); -+ if (!res) { -+ DSSERR("can't get PLL CTRL IORESOURCE_MEM HDMI\n"); -+ return -EINVAL; -+ } -+ -+ phy->base = devm_request_and_ioremap(&pdev->dev, res); -+ if (!phy->base) { -+ DSSERR("can't ioremap PLL ctrl\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi_pll.c -@@ -0,0 +1,315 @@ -+/* -+ * HDMI PLL -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <video/omapdss.h> -+ -+#include "dss.h" -+#include "hdmi.h" -+ -+#define HDMI_DEFAULT_REGN 16 -+#define HDMI_DEFAULT_REGM2 1 -+ -+struct hdmi_pll_features { -+ bool sys_reset; -+ /* this is a hack, need to replace it with a better computation of M2 */ -+ bool bound_dcofreq; -+ bool ext_mux_ctrl; -+ -+ unsigned long fint_min, fint_max; -+ u16 regm_max; -+ unsigned long dcofreq_low_min, dcofreq_low_max; -+ unsigned long dcofreq_high_min, dcofreq_high_max; -+}; -+ -+static const struct hdmi_pll_features *pll_feat; -+ -+void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) -+{ -+#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ -+ hdmi_read_reg(pll->base, r)) -+ -+ DUMPPLL(PLLCTRL_PLL_CONTROL); -+ DUMPPLL(PLLCTRL_PLL_STATUS); -+ DUMPPLL(PLLCTRL_PLL_GO); -+ DUMPPLL(PLLCTRL_CFG1); -+ DUMPPLL(PLLCTRL_CFG2); -+ DUMPPLL(PLLCTRL_CFG3); -+ DUMPPLL(PLLCTRL_SSC_CFG1); -+ DUMPPLL(PLLCTRL_SSC_CFG2); -+ DUMPPLL(PLLCTRL_CFG4); -+} -+ -+void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy) -+{ -+ struct hdmi_pll_info *pi = &pll->info; -+ unsigned long refclk; -+ u32 mf; -+ -+ /* use our funky units */ -+ clkin /= 10000; -+ -+ /* -+ * Input clock is predivided by N + 1 -+ * out put of which is reference clk -+ */ -+ -+ pi->regn = HDMI_DEFAULT_REGN; -+ -+ refclk = clkin / pi->regn; -+ -+ /* temorary hack to make sure DCO freq isn't calculated too low */ -+ if (pll_feat->bound_dcofreq && phy <= 65000) -+ pi->regm2 = 3; -+ else -+ pi->regm2 = HDMI_DEFAULT_REGM2; -+ -+ /* -+ * multiplier is pixel_clk/ref_clk -+ * Multiplying by 100 to avoid fractional part removal -+ */ -+ pi->regm = phy * pi->regm2 / refclk; -+ -+ /* -+ * fractional multiplier is remainder of the difference between -+ * multiplier and actual phy(required pixel clock thus should be -+ * multiplied by 2^18(262144) divided by the reference clock -+ */ -+ mf = (phy - pi->regm / pi->regm2 * refclk) * 262144; -+ pi->regmf = pi->regm2 * mf / refclk; -+ -+ /* -+ * Dcofreq should be set to 1 if required pixel clock -+ * is greater than 1000MHz -+ */ -+ pi->dcofreq = phy > 1000 * 100; -+ pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10; -+ -+ /* Set the reference clock to sysclk reference */ -+ pi->refsel = HDMI_REFSEL_SYSCLK; -+ -+ DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); -+ DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); -+} -+ -+ -+static int hdmi_pll_config(struct hdmi_pll_data *pll) -+{ -+ u32 r; -+ struct hdmi_pll_info *fmt = &pll->info; -+ -+ /* PLL start always use manual mode */ -+ REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); -+ -+ r = hdmi_read_reg(pll->base, PLLCTRL_CFG1); -+ r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ -+ r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */ -+ hdmi_write_reg(pll->base, PLLCTRL_CFG1, r); -+ -+ r = hdmi_read_reg(pll->base, PLLCTRL_CFG2); -+ -+ r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ -+ r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ -+ r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ -+ r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */ -+ -+ if (fmt->dcofreq) { -+ /* divider programming for frequency beyond 1000Mhz */ -+ REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10); -+ r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ -+ } else { -+ r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ -+ } -+ -+ hdmi_write_reg(pll->base, PLLCTRL_CFG2, r); -+ -+ r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); -+ r = FLD_MOD(r, fmt->regm2, 24, 18); -+ r = FLD_MOD(r, fmt->regmf, 17, 0); -+ hdmi_write_reg(pll->base, PLLCTRL_CFG4, r); -+ -+ /* go now */ -+ REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0); -+ -+ /* wait for bit change */ -+ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, -+ 0, 0, 1) != 1) { -+ pr_err("PLL GO bit not set\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Wait till the lock bit is set in PLL status */ -+ if (hdmi_wait_for_bit_change(pll->base, -+ PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { -+ pr_err("cannot lock PLL\n"); -+ pr_err("CFG1 0x%x\n", -+ hdmi_read_reg(pll->base, PLLCTRL_CFG1)); -+ pr_err("CFG2 0x%x\n", -+ hdmi_read_reg(pll->base, PLLCTRL_CFG2)); -+ pr_err("CFG4 0x%x\n", -+ hdmi_read_reg(pll->base, PLLCTRL_CFG4)); -+ return -ETIMEDOUT; -+ } -+ -+ pr_debug("PLL locked!\n"); -+ -+ return 0; -+} -+ -+static int hdmi_pll_reset(struct hdmi_pll_data *pll) -+{ -+ /* SYSRESET controlled by power FSM */ -+ REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3); -+ -+ /* READ 0x0 reset is in progress */ -+ if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1) -+ != 1) { -+ pr_err("Failed to sysreset PLL\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) -+{ -+ u16 r = 0; -+ -+ if (pll_feat->ext_mux_ctrl) -+ dss_dpll_enable_ctrl(DSS_DPLL_HDMI, true); -+ -+ r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); -+ if (r) -+ return r; -+ -+ r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); -+ if (r) -+ return r; -+ -+ r = hdmi_pll_reset(pll); -+ if (r) -+ return r; -+ -+ r = hdmi_pll_config(pll); -+ if (r) -+ return r; -+ -+ return 0; -+} -+ -+void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) -+{ -+ if (pll_feat->ext_mux_ctrl) -+ dss_dpll_enable_ctrl(DSS_DPLL_HDMI, false); -+ -+ hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); -+} -+ -+static const struct hdmi_pll_features omap44xx_pll_feats = { -+ .sys_reset = false, -+ .bound_dcofreq = false, -+ .ext_mux_ctrl = false, -+ .fint_min = 500000, -+ .fint_max = 2500000, -+ .regm_max = 4095, -+ .dcofreq_low_min = 500000000, -+ .dcofreq_low_max = 1000000000, -+ .dcofreq_high_min = 1000000000, -+ .dcofreq_high_max = 2000000000, -+}; -+ -+static const struct hdmi_pll_features omap54xx_pll_feats = { -+ .sys_reset = true, -+ .bound_dcofreq = true, -+ .ext_mux_ctrl = false, -+ .fint_min = 620000, -+ .fint_max = 2500000, -+ .regm_max = 2046, -+ .dcofreq_low_min = 750000000, -+ .dcofreq_low_max = 1500000000, -+ .dcofreq_high_min = 1250000000, -+ .dcofreq_high_max = 2500000000UL, -+}; -+ -+static const struct hdmi_pll_features dra7xx_pll_feats = { -+ .sys_reset = true, -+ .bound_dcofreq = true, -+ .ext_mux_ctrl = true, -+ .fint_min = 620000, -+ .fint_max = 2500000, -+ .regm_max = 2046, -+ .dcofreq_low_min = 750000000, -+ .dcofreq_low_max = 1500000000, -+ .dcofreq_high_min = 1250000000, -+ .dcofreq_high_max = 2500000000UL, -+}; -+ -+static int hdmi_pll_init_features(struct platform_device *pdev) -+{ -+ struct hdmi_pll_features *dst; -+ const struct hdmi_pll_features *src; -+ -+ dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); -+ if (!dst) { -+ dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); -+ return -ENOMEM; -+ } -+ -+ switch (omapdss_get_version()) { -+ case OMAPDSS_VER_OMAP4430_ES1: -+ case OMAPDSS_VER_OMAP4430_ES2: -+ case OMAPDSS_VER_OMAP4: -+ src = &omap44xx_pll_feats; -+ break; -+ -+ case OMAPDSS_VER_OMAP5: -+ src = &omap54xx_pll_feats; -+ break; -+ case OMAPDSS_VER_DRA7xx: -+ src = &dra7xx_pll_feats; -+ break; -+ -+ default: -+ return -ENODEV; -+ } -+ -+ memcpy(dst, src, sizeof(*dst)); -+ pll_feat = dst; -+ -+ return 0; -+} -+ -+int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll) -+{ -+ int r; -+ struct resource *res; -+ -+ r = hdmi_pll_init_features(pdev); -+ if (r) -+ return r; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_pllctrl"); -+ if (!res) { -+ DSSERR("can't get PLL CTRL IORESOURCE_MEM HDMI\n"); -+ return -EINVAL; -+ } -+ -+ pll->base = devm_request_and_ioremap(&pdev->dev, res); -+ if (!pll->base) { -+ DSSERR("can't ioremap PLL ctrl\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi_wp.c -@@ -0,0 +1,254 @@ -+/* -+ * HDMI wrapper -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <video/omapdss.h> -+ -+#include "dss.h" -+#include "hdmi.h" -+ -+void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s) -+{ -+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, hdmi_read_reg(wp->base, r)) -+ -+ DUMPREG(HDMI_WP_REVISION); -+ DUMPREG(HDMI_WP_SYSCONFIG); -+ DUMPREG(HDMI_WP_IRQSTATUS_RAW); -+ DUMPREG(HDMI_WP_IRQSTATUS); -+ DUMPREG(HDMI_WP_IRQENABLE_SET); -+ DUMPREG(HDMI_WP_IRQENABLE_CLR); -+ DUMPREG(HDMI_WP_IRQWAKEEN); -+ DUMPREG(HDMI_WP_PWR_CTRL); -+ DUMPREG(HDMI_WP_DEBOUNCE); -+ DUMPREG(HDMI_WP_VIDEO_CFG); -+ DUMPREG(HDMI_WP_VIDEO_SIZE); -+ DUMPREG(HDMI_WP_VIDEO_TIMING_H); -+ DUMPREG(HDMI_WP_VIDEO_TIMING_V); -+ DUMPREG(HDMI_WP_CLK); -+ DUMPREG(HDMI_WP_AUDIO_CFG); -+ DUMPREG(HDMI_WP_AUDIO_CFG2); -+ DUMPREG(HDMI_WP_AUDIO_CTRL); -+ DUMPREG(HDMI_WP_AUDIO_DATA); -+} -+ -+u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp) -+{ -+ return hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS); -+} -+ -+void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus) -+{ -+ hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, irqstatus); -+ /* flush posted write */ -+ hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS); -+} -+ -+void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask) -+{ -+ hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_SET, mask); -+} -+ -+void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask) -+{ -+ hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_CLR, mask); -+} -+ -+/* PHY_PWR_CMD */ -+int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val) -+{ -+ /* Return if already the state */ -+ if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val) -+ return 0; -+ -+ /* Command for power control of HDMI PHY */ -+ REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6); -+ -+ /* Status of the power control of HDMI PHY */ -+ if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val) -+ != val) { -+ pr_err("Failed to set PHY power mode to %d\n", val); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+/* PLL_PWR_CMD */ -+int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val) -+{ -+ /* Command for power control of HDMI PLL */ -+ REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2); -+ -+ /* wait till PHY_PWR_STATUS is set */ -+ if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val) -+ != val) { -+ pr_err("Failed to set PLL_PWR_STATUS\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+int hdmi_wp_video_start(struct hdmi_wp_data *wp) -+{ -+ REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, true, 31, 31); -+ -+ return 0; -+} -+ -+void hdmi_wp_video_stop(struct hdmi_wp_data *wp) -+{ -+ REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31); -+} -+ -+void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, -+ struct hdmi_video_format *video_fmt) -+{ -+ u32 l = 0; -+ -+ REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, -+ 10, 8); -+ -+ l |= FLD_VAL(video_fmt->y_res, 31, 16); -+ l |= FLD_VAL(video_fmt->x_res, 15, 0); -+ hdmi_write_reg(wp->base, HDMI_WP_VIDEO_SIZE, l); -+} -+ -+void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, -+ struct omap_video_timings *timings) -+{ -+ u32 r; -+ bool vsync_pol, hsync_pol; -+ pr_debug("Enter hdmi_wp_video_config_interface\n"); -+ -+ vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -+ hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -+ -+ r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG); -+ r = FLD_MOD(r, vsync_pol, 7, 7); -+ r = FLD_MOD(r, hsync_pol, 6, 6); -+ r = FLD_MOD(r, timings->interlace, 3, 3); -+ r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ -+ hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r); -+} -+ -+void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, -+ struct omap_video_timings *timings) -+{ -+ u32 timing_h = 0; -+ u32 timing_v = 0; -+ -+ pr_debug("Enter hdmi_wp_video_config_timing\n"); -+ -+ timing_h |= FLD_VAL(timings->hbp, 31, 20); -+ timing_h |= FLD_VAL(timings->hfp, 19, 8); -+ timing_h |= FLD_VAL(timings->hsw, 7, 0); -+ hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_H, timing_h); -+ -+ timing_v |= FLD_VAL(timings->vbp, 31, 20); -+ timing_v |= FLD_VAL(timings->vfp, 19, 8); -+ timing_v |= FLD_VAL(timings->vsw, 7, 0); -+ hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_V, timing_v); -+} -+ -+void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, -+ struct omap_video_timings *timings, struct hdmi_config *param) -+{ -+ pr_debug("Enter hdmi_wp_video_init_format\n"); -+ -+ video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; -+ video_fmt->y_res = param->timings.y_res; -+ video_fmt->x_res = param->timings.x_res; -+ -+ timings->hbp = param->timings.hbp; -+ timings->hfp = param->timings.hfp; -+ timings->hsw = param->timings.hsw; -+ timings->vbp = param->timings.vbp; -+ timings->vfp = param->timings.vfp; -+ timings->vsw = param->timings.vsw; -+ timings->vsync_level = param->timings.vsync_level; -+ timings->hsync_level = param->timings.hsync_level; -+ timings->interlace = param->timings.interlace; -+} -+ -+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) -+void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, -+ struct hdmi_audio_format *aud_fmt) -+{ -+ u32 r; -+ -+ DSSDBG("Enter hdmi_wp_audio_config_format\n"); -+ -+ r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG); -+ r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); -+ r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); -+ r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); -+ r = FLD_MOD(r, aud_fmt->type, 4, 4); -+ r = FLD_MOD(r, aud_fmt->justification, 3, 3); -+ r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); -+ r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); -+ r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); -+ hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG, r); -+} -+ -+void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, -+ struct hdmi_audio_dma *aud_dma) -+{ -+ u32 r; -+ -+ DSSDBG("Enter hdmi_wp_audio_config_dma\n"); -+ -+ r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG2); -+ r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); -+ r = FLD_MOD(r, aud_dma->block_size, 7, 0); -+ hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG2, r); -+ -+ r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CTRL); -+ r = FLD_MOD(r, aud_dma->mode, 9, 9); -+ r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); -+ hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CTRL, r); -+} -+ -+int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable) -+{ -+ REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 31, 31); -+ -+ return 0; -+} -+ -+int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable) -+{ -+ REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 30, 30); -+ -+ return 0; -+} -+#endif -+ -+int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) -+{ -+ struct resource *res; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_wp"); -+ if (!res) { -+ DSSERR("can't get WP IORESOURCE_MEM HDMI\n"); -+ return -EINVAL; -+ } -+ -+ wp->base = devm_request_and_ioremap(&pdev->dev, res); -+ if (!wp->base) { -+ DSSERR("can't ioremap HDMI wrapper\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} ---- a/drivers/video/omap2/dss/Kconfig -+++ b/drivers/video/omap2/dss/Kconfig -@@ -40,6 +40,12 @@ config OMAP2_DSS_DPI - help - DPI Interface. This is the Parallel Display Interface. - -+config OMAP2_DSS_DRA7XX_DPI -+ bool "DRA75X DPI support" -+ default y -+ help -+ Vayu DPI Interface. This is the Parallel Display Interface. -+ - config OMAP2_DSS_RFBI - bool "RFBI support" - depends on BROKEN -@@ -69,6 +75,18 @@ config OMAP4_DSS_HDMI - config OMAP4_DSS_HDMI_AUDIO - bool - -+config OMAP5_DSS_HDMI -+ bool "OMAP5 HDMI support" -+ default y -+ help -+ HDMI Interface for OMAP5 and similar cores. This adds the High -+ Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI -+ specification. -+ -+config OMAP5_DSS_HDMI_AUDIO -+ depends on OMAP5_DSS_HDMI -+ bool -+ - config OMAP2_DSS_SDI - bool "SDI support" - default n ---- a/drivers/video/omap2/dss/Makefile -+++ b/drivers/video/omap2/dss/Makefile -@@ -1,14 +1,18 @@ - obj-$(CONFIG_OMAP2_DSS) += omapdss.o - # Core DSS files --omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ -- output.o -+omapdss-y := core.o dss.o dss_dpll.o dss_features.o dispc.o dispc_coefs.o \ -+ display.o output.o - # DSS compat layer files - omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ - dispc-compat.o display-sysfs.o - omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o -+omapdss-$(CONFIG_OMAP2_DSS_DRA7XX_DPI) += dra7xx_dpi.o - omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o - omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o - omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o - omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o --omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o ti_hdmi_4xxx_ip.o -+omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi_common.o hdmi_wp.o hdmi_pll.o \ -+ hdmi_phy.o hdmi4_core.o -+omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi_common.o hdmi_wp.o hdmi_pll.o \ -+ hdmi_phy.o hdmi5_core.o - ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG ---- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c -+++ /dev/null -@@ -1,1427 +0,0 @@ --/* -- * ti_hdmi_4xxx_ip.c -- * -- * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library -- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -- * Authors: Yong Zhi -- * Mythri pk <mythripk@ti.com> -- * -- * 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. -- * -- * 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, see <http://www.gnu.org/licenses/>. -- */ -- --#include <linux/kernel.h> --#include <linux/module.h> --#include <linux/err.h> --#include <linux/io.h> --#include <linux/interrupt.h> --#include <linux/mutex.h> --#include <linux/delay.h> --#include <linux/string.h> --#include <linux/seq_file.h> --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) --#include <sound/asound.h> --#include <sound/asoundef.h> --#endif -- --#include "ti_hdmi_4xxx_ip.h" --#include "dss.h" --#include "dss_features.h" -- --#define HDMI_IRQ_LINK_CONNECT (1 << 25) --#define HDMI_IRQ_LINK_DISCONNECT (1 << 26) -- --static inline void hdmi_write_reg(void __iomem *base_addr, -- const u16 idx, u32 val) --{ -- __raw_writel(val, base_addr + idx); --} -- --static inline u32 hdmi_read_reg(void __iomem *base_addr, -- const u16 idx) --{ -- return __raw_readl(base_addr + idx); --} -- --static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data) --{ -- return ip_data->base_wp; --} -- --static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data) --{ -- return ip_data->base_wp + ip_data->phy_offset; --} -- --static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data) --{ -- return ip_data->base_wp + ip_data->pll_offset; --} -- --static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data) --{ -- return ip_data->base_wp + ip_data->core_av_offset; --} -- --static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data) --{ -- return ip_data->base_wp + ip_data->core_sys_offset; --} -- --static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, -- const u16 idx, -- int b2, int b1, u32 val) --{ -- u32 t = 0; -- while (val != REG_GET(base_addr, idx, b2, b1)) { -- udelay(1); -- if (t++ > 10000) -- return !val; -- } -- return val; --} -- --static int hdmi_pll_init(struct hdmi_ip_data *ip_data) --{ -- u32 r; -- void __iomem *pll_base = hdmi_pll_base(ip_data); -- struct hdmi_pll_info *fmt = &ip_data->pll_data; -- -- /* PLL start always use manual mode */ -- REG_FLD_MOD(pll_base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); -- -- r = hdmi_read_reg(pll_base, PLLCTRL_CFG1); -- r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ -- r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */ -- -- hdmi_write_reg(pll_base, PLLCTRL_CFG1, r); -- -- r = hdmi_read_reg(pll_base, PLLCTRL_CFG2); -- -- r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ -- r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ -- r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ -- r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */ -- -- if (fmt->dcofreq) { -- /* divider programming for frequency beyond 1000Mhz */ -- REG_FLD_MOD(pll_base, PLLCTRL_CFG3, fmt->regsd, 17, 10); -- r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ -- } else { -- r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ -- } -- -- hdmi_write_reg(pll_base, PLLCTRL_CFG2, r); -- -- r = hdmi_read_reg(pll_base, PLLCTRL_CFG4); -- r = FLD_MOD(r, fmt->regm2, 24, 18); -- r = FLD_MOD(r, fmt->regmf, 17, 0); -- -- hdmi_write_reg(pll_base, PLLCTRL_CFG4, r); -- -- /* go now */ -- REG_FLD_MOD(pll_base, PLLCTRL_PLL_GO, 0x1, 0, 0); -- -- /* wait for bit change */ -- if (hdmi_wait_for_bit_change(pll_base, PLLCTRL_PLL_GO, -- 0, 0, 1) != 1) { -- pr_err("PLL GO bit not set\n"); -- return -ETIMEDOUT; -- } -- -- /* Wait till the lock bit is set in PLL status */ -- if (hdmi_wait_for_bit_change(pll_base, -- PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { -- pr_err("cannot lock PLL\n"); -- pr_err("CFG1 0x%x\n", -- hdmi_read_reg(pll_base, PLLCTRL_CFG1)); -- pr_err("CFG2 0x%x\n", -- hdmi_read_reg(pll_base, PLLCTRL_CFG2)); -- pr_err("CFG4 0x%x\n", -- hdmi_read_reg(pll_base, PLLCTRL_CFG4)); -- return -ETIMEDOUT; -- } -- -- pr_debug("PLL locked!\n"); -- -- return 0; --} -- --/* PHY_PWR_CMD */ --static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) --{ -- /* Return if already the state */ -- if (REG_GET(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, 5, 4) == val) -- return 0; -- -- /* Command for power control of HDMI PHY */ -- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); -- -- /* Status of the power control of HDMI PHY */ -- if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), -- HDMI_WP_PWR_CTRL, 5, 4, val) != val) { -- pr_err("Failed to set PHY power mode to %d\n", val); -- return -ETIMEDOUT; -- } -- -- return 0; --} -- --/* PLL_PWR_CMD */ --static int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val) --{ -- /* Command for power control of HDMI PLL */ -- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2); -- -- /* wait till PHY_PWR_STATUS is set */ -- if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, -- 1, 0, val) != val) { -- pr_err("Failed to set PLL_PWR_STATUS\n"); -- return -ETIMEDOUT; -- } -- -- return 0; --} -- --static int hdmi_pll_reset(struct hdmi_ip_data *ip_data) --{ -- /* SYSRESET controlled by power FSM */ -- REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 3, 3); -- -- /* READ 0x0 reset is in progress */ -- if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data), -- PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) { -- pr_err("Failed to sysreset PLL\n"); -- return -ETIMEDOUT; -- } -- -- return 0; --} -- --int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data) --{ -- u16 r = 0; -- -- r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); -- if (r) -- return r; -- -- r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); -- if (r) -- return r; -- -- r = hdmi_pll_reset(ip_data); -- if (r) -- return r; -- -- r = hdmi_pll_init(ip_data); -- if (r) -- return r; -- -- return 0; --} -- --void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data) --{ -- hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); --} -- --static irqreturn_t hdmi_irq_handler(int irq, void *data) --{ -- struct hdmi_ip_data *ip_data = data; -- void __iomem *wp_base = hdmi_wp_base(ip_data); -- u32 irqstatus; -- -- irqstatus = hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); -- hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, irqstatus); -- /* flush posted write */ -- hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); -- -- if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && -- irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -- /* -- * If we get both connect and disconnect interrupts at the same -- * time, turn off the PHY, clear interrupts, and restart, which -- * raises connect interrupt if a cable is connected, or nothing -- * if cable is not connected. -- */ -- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); -- -- hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, -- HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); -- /* flush posted write */ -- hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); -- -- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); -- } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { -- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); -- } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); -- } -- -- return IRQ_HANDLED; --} -- --int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) --{ -- u16 r = 0; -- void __iomem *phy_base = hdmi_phy_base(ip_data); -- -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_CLR, -- 0xffffffff); -- -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQSTATUS, -- HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); -- -- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); -- if (r) -- return r; -- -- /* -- * Read address 0 in order to get the SCP reset done completed -- * Dummy access performed to make sure reset is done -- */ -- hdmi_read_reg(phy_base, HDMI_TXPHY_TX_CTRL); -- -- /* -- * Write to phy address 0 to configure the clock -- * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field -- */ -- REG_FLD_MOD(phy_base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); -- -- /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ -- hdmi_write_reg(phy_base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); -- -- /* Setup max LDO voltage */ -- REG_FLD_MOD(phy_base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); -- -- /* Write to phy address 3 to change the polarity control */ -- REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); -- -- r = request_threaded_irq(ip_data->irq, NULL, hdmi_irq_handler, -- IRQF_ONESHOT, "OMAP HDMI", ip_data); -- if (r) { -- DSSERR("HDMI IRQ request failed\n"); -- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); -- return r; -- } -- -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_SET, -- HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); -- -- return 0; --} -- --void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) --{ -- free_irq(ip_data->irq, ip_data); -- -- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); --} -- --static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) --{ -- void __iomem *base = hdmi_core_sys_base(ip_data); -- -- /* Turn on CLK for DDC */ -- REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0); -- -- /* IN_PROG */ -- if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) { -- /* Abort transaction */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0); -- /* IN_PROG */ -- if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -- 4, 4, 0) != 0) { -- DSSERR("Timeout aborting DDC transaction\n"); -- return -ETIMEDOUT; -- } -- } -- -- /* Clk SCL Devices */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0); -- -- /* HDMI_CORE_DDC_STATUS_IN_PROG */ -- if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -- 4, 4, 0) != 0) { -- DSSERR("Timeout starting SCL clock\n"); -- return -ETIMEDOUT; -- } -- -- /* Clear FIFO */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0); -- -- /* HDMI_CORE_DDC_STATUS_IN_PROG */ -- if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -- 4, 4, 0) != 0) { -- DSSERR("Timeout clearing DDC fifo\n"); -- return -ETIMEDOUT; -- } -- -- return 0; --} -- --static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data, -- u8 *pedid, int ext) --{ -- void __iomem *base = hdmi_core_sys_base(ip_data); -- u32 i; -- char checksum; -- u32 offset = 0; -- -- /* HDMI_CORE_DDC_STATUS_IN_PROG */ -- if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS, -- 4, 4, 0) != 0) { -- DSSERR("Timeout waiting DDC to be ready\n"); -- return -ETIMEDOUT; -- } -- -- if (ext % 2 != 0) -- offset = 0x80; -- -- /* Load Segment Address Register */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0); -- -- /* Load Slave Address Register */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); -- -- /* Load Offset Address Register */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0); -- -- /* Load Byte Count */ -- REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); -- REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); -- -- /* Set DDC_CMD */ -- if (ext) -- REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0); -- else -- REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0); -- -- /* HDMI_CORE_DDC_STATUS_BUS_LOW */ -- if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) { -- pr_err("I2C Bus Low?\n"); -- return -EIO; -- } -- /* HDMI_CORE_DDC_STATUS_NO_ACK */ -- if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) { -- pr_err("I2C No Ack\n"); -- return -EIO; -- } -- -- for (i = 0; i < 0x80; ++i) { -- int t; -- -- /* IN_PROG */ -- if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) { -- DSSERR("operation stopped when reading edid\n"); -- return -EIO; -- } -- -- t = 0; -- /* FIFO_EMPTY */ -- while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) { -- if (t++ > 10000) { -- DSSERR("timeout reading edid\n"); -- return -ETIMEDOUT; -- } -- udelay(1); -- } -- -- pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); -- } -- -- checksum = 0; -- for (i = 0; i < 0x80; ++i) -- checksum += pedid[i]; -- -- if (checksum != 0) { -- pr_err("E-EDID checksum failed!!\n"); -- return -EIO; -- } -- -- return 0; --} -- --int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, -- u8 *edid, int len) --{ -- int r, l; -- -- if (len < 128) -- return -EINVAL; -- -- r = hdmi_core_ddc_init(ip_data); -- if (r) -- return r; -- -- r = hdmi_core_ddc_edid(ip_data, edid, 0); -- if (r) -- return r; -- -- l = 128; -- -- if (len >= 128 * 2 && edid[0x7e] > 0) { -- r = hdmi_core_ddc_edid(ip_data, edid + 0x80, 1); -- if (r) -- return r; -- l += 128; -- } -- -- return l; --} -- --static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, -- struct hdmi_core_infoframe_avi *avi_cfg, -- struct hdmi_core_packet_enable_repeat *repeat_cfg) --{ -- pr_debug("Enter hdmi_core_init\n"); -- -- /* video core */ -- video_cfg->ip_bus_width = HDMI_INPUT_8BIT; -- video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT; -- video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE; -- video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; -- video_cfg->hdmi_dvi = HDMI_DVI; -- video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; -- -- /* info frame */ -- avi_cfg->db1_format = 0; -- avi_cfg->db1_active_info = 0; -- avi_cfg->db1_bar_info_dv = 0; -- avi_cfg->db1_scan_info = 0; -- avi_cfg->db2_colorimetry = 0; -- avi_cfg->db2_aspect_ratio = 0; -- avi_cfg->db2_active_fmt_ar = 0; -- avi_cfg->db3_itc = 0; -- avi_cfg->db3_ec = 0; -- avi_cfg->db3_q_range = 0; -- avi_cfg->db3_nup_scaling = 0; -- avi_cfg->db4_videocode = 0; -- avi_cfg->db5_pixel_repeat = 0; -- avi_cfg->db6_7_line_eoftop = 0 ; -- avi_cfg->db8_9_line_sofbottom = 0; -- avi_cfg->db10_11_pixel_eofleft = 0; -- avi_cfg->db12_13_pixel_sofright = 0; -- -- /* packet enable and repeat */ -- repeat_cfg->audio_pkt = 0; -- repeat_cfg->audio_pkt_repeat = 0; -- repeat_cfg->avi_infoframe = 0; -- repeat_cfg->avi_infoframe_repeat = 0; -- repeat_cfg->gen_cntrl_pkt = 0; -- repeat_cfg->gen_cntrl_pkt_repeat = 0; -- repeat_cfg->generic_pkt = 0; -- repeat_cfg->generic_pkt_repeat = 0; --} -- --static void hdmi_core_powerdown_disable(struct hdmi_ip_data *ip_data) --{ -- pr_debug("Enter hdmi_core_powerdown_disable\n"); -- REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, 0x0, 0, 0); --} -- --static void hdmi_core_swreset_release(struct hdmi_ip_data *ip_data) --{ -- pr_debug("Enter hdmi_core_swreset_release\n"); -- REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x0, 0, 0); --} -- --static void hdmi_core_swreset_assert(struct hdmi_ip_data *ip_data) --{ -- pr_debug("Enter hdmi_core_swreset_assert\n"); -- REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x1, 0, 0); --} -- --/* HDMI_CORE_VIDEO_CONFIG */ --static void hdmi_core_video_config(struct hdmi_ip_data *ip_data, -- struct hdmi_core_video_config *cfg) --{ -- u32 r = 0; -- void __iomem *core_sys_base = hdmi_core_sys_base(ip_data); -- -- /* sys_ctrl1 default configuration not tunable */ -- r = hdmi_read_reg(core_sys_base, HDMI_CORE_CTRL1); -- r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5); -- r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4); -- r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2); -- r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1); -- hdmi_write_reg(core_sys_base, HDMI_CORE_CTRL1, r); -- -- REG_FLD_MOD(core_sys_base, -- HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); -- -- /* Vid_Mode */ -- r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE); -- -- /* dither truncation configuration */ -- if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) { -- r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6); -- r = FLD_MOD(r, 1, 5, 5); -- } else { -- r = FLD_MOD(r, cfg->op_dither_truc, 7, 6); -- r = FLD_MOD(r, 0, 5, 5); -- } -- hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r); -- -- /* HDMI_Ctrl */ -- r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL); -- r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6); -- r = FLD_MOD(r, cfg->pkt_mode, 5, 3); -- r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); -- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL, r); -- -- /* TMDS_CTRL */ -- REG_FLD_MOD(core_sys_base, -- HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); --} -- --static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data) --{ -- u32 val; -- char sum = 0, checksum = 0; -- void __iomem *av_base = hdmi_av_base(ip_data); -- struct hdmi_core_infoframe_avi info_avi = ip_data->avi_cfg; -- -- sum += 0x82 + 0x002 + 0x00D; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D); -- -- val = (info_avi.db1_format << 5) | -- (info_avi.db1_active_info << 4) | -- (info_avi.db1_bar_info_dv << 2) | -- (info_avi.db1_scan_info); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val); -- sum += val; -- -- val = (info_avi.db2_colorimetry << 6) | -- (info_avi.db2_aspect_ratio << 4) | -- (info_avi.db2_active_fmt_ar); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val); -- sum += val; -- -- val = (info_avi.db3_itc << 7) | -- (info_avi.db3_ec << 4) | -- (info_avi.db3_q_range << 2) | -- (info_avi.db3_nup_scaling); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val); -- sum += val; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3), -- info_avi.db4_videocode); -- sum += info_avi.db4_videocode; -- -- val = info_avi.db5_pixel_repeat; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val); -- sum += val; -- -- val = info_avi.db6_7_line_eoftop & 0x00FF; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val); -- sum += val; -- -- val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val); -- sum += val; -- -- val = info_avi.db8_9_line_sofbottom & 0x00FF; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val); -- sum += val; -- -- val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val); -- sum += val; -- -- val = info_avi.db10_11_pixel_eofleft & 0x00FF; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val); -- sum += val; -- -- val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val); -- sum += val; -- -- val = info_avi.db12_13_pixel_sofright & 0x00FF; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val); -- sum += val; -- -- val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val); -- sum += val; -- -- checksum = 0x100 - sum; -- hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum); --} -- --static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data, -- struct hdmi_core_packet_enable_repeat repeat_cfg) --{ -- /* enable/repeat the infoframe */ -- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL1, -- (repeat_cfg.audio_pkt << 5) | -- (repeat_cfg.audio_pkt_repeat << 4) | -- (repeat_cfg.avi_infoframe << 1) | -- (repeat_cfg.avi_infoframe_repeat)); -- -- /* enable/repeat the packet */ -- hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL2, -- (repeat_cfg.gen_cntrl_pkt << 3) | -- (repeat_cfg.gen_cntrl_pkt_repeat << 2) | -- (repeat_cfg.generic_pkt << 1) | -- (repeat_cfg.generic_pkt_repeat)); --} -- --static void hdmi_wp_init(struct omap_video_timings *timings, -- struct hdmi_video_format *video_fmt) --{ -- pr_debug("Enter hdmi_wp_init\n"); -- -- timings->hbp = 0; -- timings->hfp = 0; -- timings->hsw = 0; -- timings->vbp = 0; -- timings->vfp = 0; -- timings->vsw = 0; -- -- video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; -- video_fmt->y_res = 0; -- video_fmt->x_res = 0; -- --} -- --int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data) --{ -- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, true, 31, 31); -- return 0; --} -- --void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data) --{ -- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, false, 31, 31); --} -- --static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, -- struct omap_video_timings *timings, struct hdmi_config *param) --{ -- pr_debug("Enter hdmi_wp_video_init_format\n"); -- -- video_fmt->y_res = param->timings.y_res; -- video_fmt->x_res = param->timings.x_res; -- -- timings->hbp = param->timings.hbp; -- timings->hfp = param->timings.hfp; -- timings->hsw = param->timings.hsw; -- timings->vbp = param->timings.vbp; -- timings->vfp = param->timings.vfp; -- timings->vsw = param->timings.vsw; --} -- --static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, -- struct hdmi_video_format *video_fmt) --{ -- u32 l = 0; -- -- REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, -- video_fmt->packing_mode, 10, 8); -- -- l |= FLD_VAL(video_fmt->y_res, 31, 16); -- l |= FLD_VAL(video_fmt->x_res, 15, 0); -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); --} -- --static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) --{ -- u32 r; -- bool vsync_pol, hsync_pol; -- pr_debug("Enter hdmi_wp_video_config_interface\n"); -- -- vsync_pol = ip_data->cfg.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -- hsync_pol = ip_data->cfg.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -- -- r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); -- r = FLD_MOD(r, vsync_pol, 7, 7); -- r = FLD_MOD(r, hsync_pol, 6, 6); -- r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); -- r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); --} -- --static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data, -- struct omap_video_timings *timings) --{ -- u32 timing_h = 0; -- u32 timing_v = 0; -- -- pr_debug("Enter hdmi_wp_video_config_timing\n"); -- -- timing_h |= FLD_VAL(timings->hbp, 31, 20); -- timing_h |= FLD_VAL(timings->hfp, 19, 8); -- timing_h |= FLD_VAL(timings->hsw, 7, 0); -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h); -- -- timing_v |= FLD_VAL(timings->vbp, 31, 20); -- timing_v |= FLD_VAL(timings->vfp, 19, 8); -- timing_v |= FLD_VAL(timings->vsw, 7, 0); -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v); --} -- --void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) --{ -- /* HDMI */ -- struct omap_video_timings video_timing; -- struct hdmi_video_format video_format; -- /* HDMI core */ -- struct hdmi_core_infoframe_avi *avi_cfg = &ip_data->avi_cfg; -- struct hdmi_core_video_config v_core_cfg; -- struct hdmi_core_packet_enable_repeat repeat_cfg; -- struct hdmi_config *cfg = &ip_data->cfg; -- -- hdmi_wp_init(&video_timing, &video_format); -- -- hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); -- -- hdmi_wp_video_init_format(&video_format, &video_timing, cfg); -- -- hdmi_wp_video_config_timing(ip_data, &video_timing); -- -- /* video config */ -- video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; -- -- hdmi_wp_video_config_format(ip_data, &video_format); -- -- hdmi_wp_video_config_interface(ip_data); -- -- /* -- * configure core video part -- * set software reset in the core -- */ -- hdmi_core_swreset_assert(ip_data); -- -- /* power down off */ -- hdmi_core_powerdown_disable(ip_data); -- -- v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; -- v_core_cfg.hdmi_dvi = cfg->cm.mode; -- -- hdmi_core_video_config(ip_data, &v_core_cfg); -- -- /* release software reset in the core */ -- hdmi_core_swreset_release(ip_data); -- -- /* -- * configure packet -- * info frame video see doc CEA861-D page 65 -- */ -- avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; -- avi_cfg->db1_active_info = -- HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; -- avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; -- avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; -- avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; -- avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; -- avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; -- avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; -- avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; -- avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; -- avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; -- avi_cfg->db4_videocode = cfg->cm.code; -- avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; -- avi_cfg->db6_7_line_eoftop = 0; -- avi_cfg->db8_9_line_sofbottom = 0; -- avi_cfg->db10_11_pixel_eofleft = 0; -- avi_cfg->db12_13_pixel_sofright = 0; -- -- hdmi_core_aux_infoframe_avi_config(ip_data); -- -- /* enable/repeat the infoframe */ -- repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; -- repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; -- /* wakeup */ -- repeat_cfg.audio_pkt = HDMI_PACKETENABLE; -- repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; -- hdmi_core_av_packet_config(ip_data, repeat_cfg); --} -- --void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) --{ --#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r,\ -- hdmi_read_reg(hdmi_wp_base(ip_data), r)) -- -- DUMPREG(HDMI_WP_REVISION); -- DUMPREG(HDMI_WP_SYSCONFIG); -- DUMPREG(HDMI_WP_IRQSTATUS_RAW); -- DUMPREG(HDMI_WP_IRQSTATUS); -- DUMPREG(HDMI_WP_PWR_CTRL); -- DUMPREG(HDMI_WP_IRQENABLE_SET); -- DUMPREG(HDMI_WP_VIDEO_CFG); -- DUMPREG(HDMI_WP_VIDEO_SIZE); -- DUMPREG(HDMI_WP_VIDEO_TIMING_H); -- DUMPREG(HDMI_WP_VIDEO_TIMING_V); -- DUMPREG(HDMI_WP_WP_CLK); -- DUMPREG(HDMI_WP_AUDIO_CFG); -- DUMPREG(HDMI_WP_AUDIO_CFG2); -- DUMPREG(HDMI_WP_AUDIO_CTRL); -- DUMPREG(HDMI_WP_AUDIO_DATA); --} -- --void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) --{ --#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ -- hdmi_read_reg(hdmi_pll_base(ip_data), r)) -- -- DUMPPLL(PLLCTRL_PLL_CONTROL); -- DUMPPLL(PLLCTRL_PLL_STATUS); -- DUMPPLL(PLLCTRL_PLL_GO); -- DUMPPLL(PLLCTRL_CFG1); -- DUMPPLL(PLLCTRL_CFG2); -- DUMPPLL(PLLCTRL_CFG3); -- DUMPPLL(PLLCTRL_CFG4); --} -- --void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) --{ -- int i; -- --#define CORE_REG(i, name) name(i) --#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ -- hdmi_read_reg(hdmi_core_sys_base(ip_data), r)) --#define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ -- hdmi_read_reg(hdmi_av_base(ip_data), r)) --#define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \ -- (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \ -- hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r))) -- -- DUMPCORE(HDMI_CORE_SYS_VND_IDL); -- DUMPCORE(HDMI_CORE_SYS_DEV_IDL); -- DUMPCORE(HDMI_CORE_SYS_DEV_IDH); -- DUMPCORE(HDMI_CORE_SYS_DEV_REV); -- DUMPCORE(HDMI_CORE_SYS_SRST); -- DUMPCORE(HDMI_CORE_CTRL1); -- DUMPCORE(HDMI_CORE_SYS_SYS_STAT); -- DUMPCORE(HDMI_CORE_SYS_DE_DLY); -- DUMPCORE(HDMI_CORE_SYS_DE_CTRL); -- DUMPCORE(HDMI_CORE_SYS_DE_TOP); -- DUMPCORE(HDMI_CORE_SYS_DE_CNTL); -- DUMPCORE(HDMI_CORE_SYS_DE_CNTH); -- DUMPCORE(HDMI_CORE_SYS_DE_LINL); -- DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); -- DUMPCORE(HDMI_CORE_SYS_VID_ACEN); -- DUMPCORE(HDMI_CORE_SYS_VID_MODE); -- DUMPCORE(HDMI_CORE_SYS_INTR_STATE); -- DUMPCORE(HDMI_CORE_SYS_INTR1); -- DUMPCORE(HDMI_CORE_SYS_INTR2); -- DUMPCORE(HDMI_CORE_SYS_INTR3); -- DUMPCORE(HDMI_CORE_SYS_INTR4); -- DUMPCORE(HDMI_CORE_SYS_UMASK1); -- DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL); -- -- DUMPCORE(HDMI_CORE_DDC_ADDR); -- DUMPCORE(HDMI_CORE_DDC_SEGM); -- DUMPCORE(HDMI_CORE_DDC_OFFSET); -- DUMPCORE(HDMI_CORE_DDC_COUNT1); -- DUMPCORE(HDMI_CORE_DDC_COUNT2); -- DUMPCORE(HDMI_CORE_DDC_STATUS); -- DUMPCORE(HDMI_CORE_DDC_CMD); -- DUMPCORE(HDMI_CORE_DDC_DATA); -- -- DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL); -- DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL); -- DUMPCOREAV(HDMI_CORE_AV_N_SVAL1); -- DUMPCOREAV(HDMI_CORE_AV_N_SVAL2); -- DUMPCOREAV(HDMI_CORE_AV_N_SVAL3); -- DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1); -- DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2); -- DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3); -- DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1); -- DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2); -- DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3); -- DUMPCOREAV(HDMI_CORE_AV_AUD_MODE); -- DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL); -- DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS); -- DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S); -- DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH); -- DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP); -- DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL); -- DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0); -- DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1); -- DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2); -- DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4); -- DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5); -- DUMPCOREAV(HDMI_CORE_AV_ASRC); -- DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN); -- DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL); -- DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT); -- DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1); -- DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2); -- DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3); -- DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL); -- DUMPCOREAV(HDMI_CORE_AV_DPD); -- DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1); -- DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2); -- DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE); -- DUMPCOREAV(HDMI_CORE_AV_AVI_VERS); -- DUMPCOREAV(HDMI_CORE_AV_AVI_LEN); -- DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM); -- -- for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++) -- DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE); -- -- DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE); -- DUMPCOREAV(HDMI_CORE_AV_SPD_VERS); -- DUMPCOREAV(HDMI_CORE_AV_SPD_LEN); -- DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM); -- -- for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++) -- DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE); -- -- DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE); -- DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS); -- DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN); -- DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM); -- -- for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++) -- DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE); -- -- DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE); -- DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS); -- DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN); -- DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM); -- -- for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++) -- DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE); -- -- for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++) -- DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE); -- -- DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1); -- -- for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++) -- DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE); -- -- DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); --} -- --void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) --{ --#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ -- hdmi_read_reg(hdmi_phy_base(ip_data), r)) -- -- DUMPPHY(HDMI_TXPHY_TX_CTRL); -- DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); -- DUMPPHY(HDMI_TXPHY_POWER_CTRL); -- DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); --} -- --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) --static void ti_hdmi_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data, -- struct hdmi_audio_format *aud_fmt) --{ -- u32 r; -- -- DSSDBG("Enter hdmi_wp_audio_config_format\n"); -- -- r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG); -- r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); -- r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); -- r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); -- r = FLD_MOD(r, aud_fmt->type, 4, 4); -- r = FLD_MOD(r, aud_fmt->justification, 3, 3); -- r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); -- r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); -- r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); --} -- --static void ti_hdmi_4xxx_wp_audio_config_dma(struct hdmi_ip_data *ip_data, -- struct hdmi_audio_dma *aud_dma) --{ -- u32 r; -- -- DSSDBG("Enter hdmi_wp_audio_config_dma\n"); -- -- r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2); -- r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); -- r = FLD_MOD(r, aud_dma->block_size, 7, 0); -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r); -- -- r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL); -- r = FLD_MOD(r, aud_dma->mode, 9, 9); -- r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); -- hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); --} -- --static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, -- struct hdmi_core_audio_config *cfg) --{ -- u32 r; -- void __iomem *av_base = hdmi_av_base(ip_data); -- -- /* -- * Parameters for generation of Audio Clock Recovery packets -- */ -- REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); -- REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); -- REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); -- -- if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) { -- REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0); -- REG_FLD_MOD(av_base, -- HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0); -- REG_FLD_MOD(av_base, -- HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); -- } else { -- REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, -- cfg->aud_par_busclk, 7, 0); -- REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, -- (cfg->aud_par_busclk >> 8), 7, 0); -- REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3, -- (cfg->aud_par_busclk >> 16), 7, 0); -- } -- -- /* Set ACR clock divisor */ -- REG_FLD_MOD(av_base, -- HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0); -- -- r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); -- /* -- * Use TMDS clock for ACR packets. For devices that use -- * the MCLK, this is the first part of the MCLK initialization. -- */ -- r = FLD_MOD(r, 0, 2, 2); -- -- r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1); -- r = FLD_MOD(r, cfg->cts_mode, 0, 0); -- hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r); -- -- /* For devices using MCLK, this completes its initialization. */ -- if (cfg->use_mclk) -- REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2); -- -- /* Override of SPDIF sample frequency with value in I2S_CHST4 */ -- REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, -- cfg->fs_override, 1, 1); -- -- /* -- * Set IEC-60958-3 channel status word. It is passed to the IP -- * just as it is received. The user of the driver is responsible -- * for its contents. -- */ -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST0, -- cfg->iec60958_cfg->status[0]); -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST1, -- cfg->iec60958_cfg->status[1]); -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST2, -- cfg->iec60958_cfg->status[2]); -- /* yes, this is correct: status[3] goes to CHST4 register */ -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST4, -- cfg->iec60958_cfg->status[3]); -- /* yes, this is correct: status[4] goes to CHST5 register */ -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, -- cfg->iec60958_cfg->status[4]); -- -- /* set I2S parameters */ -- r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL); -- r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6); -- r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4); -- r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2); -- r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1); -- r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0); -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r); -- -- REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN, -- cfg->i2s_cfg.in_length_bits, 3, 0); -- -- /* Audio channels and mode parameters */ -- REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1); -- r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE); -- r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4); -- r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3); -- r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2); -- r = FLD_MOD(r, cfg->en_spdif, 1, 1); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r); -- -- /* Audio channel mappings */ -- /* TODO: Make channel mapping dynamic. For now, map channels -- * in the ALSA order: FL/FR/RL/RR/C/LFE/SL/SR. Remapping is needed as -- * HDMI speaker order is different. See CEA-861 Section 6.6.2. -- */ -- hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_MAP, 0x78); -- REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5); --} -- --static void ti_hdmi_4xxx_core_audio_infoframe_cfg(struct hdmi_ip_data *ip_data, -- struct snd_cea_861_aud_if *info_aud) --{ -- u8 sum = 0, checksum = 0; -- void __iomem *av_base = hdmi_av_base(ip_data); -- -- /* -- * Set audio info frame type, version and length as -- * described in HDMI 1.4a Section 8.2.2 specification. -- * Checksum calculation is defined in Section 5.3.5. -- */ -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a); -- sum += 0x84 + 0x001 + 0x00a; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), -- info_aud->db1_ct_cc); -- sum += info_aud->db1_ct_cc; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), -- info_aud->db2_sf_ss); -- sum += info_aud->db2_sf_ss; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); -- sum += info_aud->db3; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); -- sum += info_aud->db4_ca; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), -- info_aud->db5_dminh_lsv); -- sum += info_aud->db5_dminh_lsv; -- -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00); -- hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00); -- -- checksum = 0x100 - sum; -- hdmi_write_reg(av_base, -- HDMI_CORE_AV_AUDIO_CHSUM, checksum); -- -- /* -- * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing -- * is available. -- */ --} -- --int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, -- struct omap_dss_audio *audio) --{ -- struct hdmi_audio_format audio_format; -- struct hdmi_audio_dma audio_dma; -- struct hdmi_core_audio_config core; -- int err, n, cts, channel_count; -- unsigned int fs_nr; -- bool word_length_16b = false; -- -- if (!audio || !audio->iec || !audio->cea || !ip_data) -- return -EINVAL; -- -- core.iec60958_cfg = audio->iec; -- /* -- * In the IEC-60958 status word, check if the audio sample word length -- * is 16-bit as several optimizations can be performed in such case. -- */ -- if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24)) -- if (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16) -- word_length_16b = true; -- -- /* I2S configuration. See Phillips' specification */ -- if (word_length_16b) -- core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; -- else -- core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; -- /* -- * The I2S input word length is twice the lenght given in the IEC-60958 -- * status word. If the word size is greater than -- * 20 bits, increment by one. -- */ -- core.i2s_cfg.in_length_bits = audio->iec->status[4] -- & IEC958_AES4_CON_WORDLEN; -- if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) -- core.i2s_cfg.in_length_bits++; -- core.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; -- core.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; -- core.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; -- core.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; -- -- /* convert sample frequency to a number */ -- switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { -- case IEC958_AES3_CON_FS_32000: -- fs_nr = 32000; -- break; -- case IEC958_AES3_CON_FS_44100: -- fs_nr = 44100; -- break; -- case IEC958_AES3_CON_FS_48000: -- fs_nr = 48000; -- break; -- case IEC958_AES3_CON_FS_88200: -- fs_nr = 88200; -- break; -- case IEC958_AES3_CON_FS_96000: -- fs_nr = 96000; -- break; -- case IEC958_AES3_CON_FS_176400: -- fs_nr = 176400; -- break; -- case IEC958_AES3_CON_FS_192000: -- fs_nr = 192000; -- break; -- default: -- return -EINVAL; -- } -- -- err = hdmi_compute_acr(fs_nr, &n, &cts); -- -- /* Audio clock regeneration settings */ -- core.n = n; -- core.cts = cts; -- if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { -- core.aud_par_busclk = 0; -- core.cts_mode = HDMI_AUDIO_CTS_MODE_SW; -- core.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); -- } else { -- core.aud_par_busclk = (((128 * 31) - 1) << 8); -- core.cts_mode = HDMI_AUDIO_CTS_MODE_HW; -- core.use_mclk = true; -- } -- -- if (core.use_mclk) -- core.mclk_mode = HDMI_AUDIO_MCLK_128FS; -- -- /* Audio channels settings */ -- channel_count = (audio->cea->db1_ct_cc & -- CEA861_AUDIO_INFOFRAME_DB1CC) + 1; -- -- switch (channel_count) { -- case 2: -- audio_format.active_chnnls_msk = 0x03; -- break; -- case 3: -- audio_format.active_chnnls_msk = 0x07; -- break; -- case 4: -- audio_format.active_chnnls_msk = 0x0f; -- break; -- case 5: -- audio_format.active_chnnls_msk = 0x1f; -- break; -- case 6: -- audio_format.active_chnnls_msk = 0x3f; -- break; -- case 7: -- audio_format.active_chnnls_msk = 0x7f; -- break; -- case 8: -- audio_format.active_chnnls_msk = 0xff; -- break; -- default: -- return -EINVAL; -- } -- -- /* -- * the HDMI IP needs to enable four stereo channels when transmitting -- * more than 2 audio channels -- */ -- if (channel_count == 2) { -- audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; -- core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; -- core.layout = HDMI_AUDIO_LAYOUT_2CH; -- } else { -- audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS; -- core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN | -- HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | -- HDMI_AUDIO_I2S_SD3_EN; -- core.layout = HDMI_AUDIO_LAYOUT_8CH; -- } -- -- core.en_spdif = false; -- /* use sample frequency from channel status word */ -- core.fs_override = true; -- /* enable ACR packets */ -- core.en_acr_pkt = true; -- /* disable direct streaming digital audio */ -- core.en_dsd_audio = false; -- /* use parallel audio interface */ -- core.en_parallel_aud_input = true; -- -- /* DMA settings */ -- if (word_length_16b) -- audio_dma.transfer_size = 0x10; -- else -- audio_dma.transfer_size = 0x20; -- audio_dma.block_size = 0xC0; -- audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; -- audio_dma.fifo_threshold = 0x20; /* in number of samples */ -- -- /* audio FIFO format settings */ -- if (word_length_16b) { -- audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; -- audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; -- audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; -- } else { -- audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; -- audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; -- audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; -- } -- audio_format.type = HDMI_AUDIO_TYPE_LPCM; -- audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; -- /* disable start/stop signals of IEC 60958 blocks */ -- audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; -- -- /* configure DMA and audio FIFO format*/ -- ti_hdmi_4xxx_wp_audio_config_dma(ip_data, &audio_dma); -- ti_hdmi_4xxx_wp_audio_config_format(ip_data, &audio_format); -- -- /* configure the core*/ -- ti_hdmi_4xxx_core_audio_config(ip_data, &core); -- -- /* configure CEA 861 audio infoframe*/ -- ti_hdmi_4xxx_core_audio_infoframe_cfg(ip_data, audio->cea); -- -- return 0; --} -- --int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data) --{ -- REG_FLD_MOD(hdmi_wp_base(ip_data), -- HDMI_WP_AUDIO_CTRL, true, 31, 31); -- return 0; --} -- --void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data) --{ -- REG_FLD_MOD(hdmi_wp_base(ip_data), -- HDMI_WP_AUDIO_CTRL, false, 31, 31); --} -- --int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data) --{ -- REG_FLD_MOD(hdmi_av_base(ip_data), -- HDMI_CORE_AV_AUD_MODE, true, 0, 0); -- REG_FLD_MOD(hdmi_wp_base(ip_data), -- HDMI_WP_AUDIO_CTRL, true, 30, 30); -- return 0; --} -- --void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data) --{ -- REG_FLD_MOD(hdmi_av_base(ip_data), -- HDMI_CORE_AV_AUD_MODE, false, 0, 0); -- REG_FLD_MOD(hdmi_wp_base(ip_data), -- HDMI_WP_AUDIO_CTRL, false, 30, 30); --} -- --int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size) --{ -- if (!offset || !size) -- return -EINVAL; -- *offset = HDMI_WP_AUDIO_DATA; -- *size = 4; -- return 0; --} --#endif ---- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h -+++ /dev/null -@@ -1,437 +0,0 @@ --/* -- * ti_hdmi_4xxx_ip.h -- * -- * HDMI header definition for DM81xx, DM38xx, TI OMAP4 etc processors. -- * -- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -- * -- * 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. -- * -- * 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, see <http://www.gnu.org/licenses/>. -- */ -- --#ifndef _HDMI_TI_4xxx_H_ --#define _HDMI_TI_4xxx_H_ -- --#include <linux/string.h> --#include <video/omapdss.h> --#include "ti_hdmi.h" -- --/* HDMI Wrapper */ -- --#define HDMI_WP_REVISION 0x0 --#define HDMI_WP_SYSCONFIG 0x10 --#define HDMI_WP_IRQSTATUS_RAW 0x24 --#define HDMI_WP_IRQSTATUS 0x28 --#define HDMI_WP_PWR_CTRL 0x40 --#define HDMI_WP_IRQENABLE_SET 0x2C --#define HDMI_WP_IRQENABLE_CLR 0x30 --#define HDMI_WP_VIDEO_CFG 0x50 --#define HDMI_WP_VIDEO_SIZE 0x60 --#define HDMI_WP_VIDEO_TIMING_H 0x68 --#define HDMI_WP_VIDEO_TIMING_V 0x6C --#define HDMI_WP_WP_CLK 0x70 --#define HDMI_WP_AUDIO_CFG 0x80 --#define HDMI_WP_AUDIO_CFG2 0x84 --#define HDMI_WP_AUDIO_CTRL 0x88 --#define HDMI_WP_AUDIO_DATA 0x8C -- --/* HDMI IP Core System */ -- --#define HDMI_CORE_SYS_VND_IDL 0x0 --#define HDMI_CORE_SYS_DEV_IDL 0x8 --#define HDMI_CORE_SYS_DEV_IDH 0xC --#define HDMI_CORE_SYS_DEV_REV 0x10 --#define HDMI_CORE_SYS_SRST 0x14 --#define HDMI_CORE_CTRL1 0x20 --#define HDMI_CORE_SYS_SYS_STAT 0x24 --#define HDMI_CORE_SYS_DE_DLY 0xC8 --#define HDMI_CORE_SYS_DE_CTRL 0xCC --#define HDMI_CORE_SYS_DE_TOP 0xD0 --#define HDMI_CORE_SYS_DE_CNTL 0xD8 --#define HDMI_CORE_SYS_DE_CNTH 0xDC --#define HDMI_CORE_SYS_DE_LINL 0xE0 --#define HDMI_CORE_SYS_DE_LINH_1 0xE4 --#define HDMI_CORE_SYS_VID_ACEN 0x124 --#define HDMI_CORE_SYS_VID_MODE 0x128 --#define HDMI_CORE_SYS_INTR_STATE 0x1C0 --#define HDMI_CORE_SYS_INTR1 0x1C4 --#define HDMI_CORE_SYS_INTR2 0x1C8 --#define HDMI_CORE_SYS_INTR3 0x1CC --#define HDMI_CORE_SYS_INTR4 0x1D0 --#define HDMI_CORE_SYS_UMASK1 0x1D4 --#define HDMI_CORE_SYS_TMDS_CTRL 0x208 -- --#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1 --#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1 --#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 --#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1 -- --/* HDMI DDC E-DID */ --#define HDMI_CORE_DDC_ADDR 0x3B4 --#define HDMI_CORE_DDC_SEGM 0x3B8 --#define HDMI_CORE_DDC_OFFSET 0x3BC --#define HDMI_CORE_DDC_COUNT1 0x3C0 --#define HDMI_CORE_DDC_COUNT2 0x3C4 --#define HDMI_CORE_DDC_STATUS 0x3C8 --#define HDMI_CORE_DDC_CMD 0x3CC --#define HDMI_CORE_DDC_DATA 0x3D0 -- --/* HDMI IP Core Audio Video */ -- --#define HDMI_CORE_AV_ACR_CTRL 0x4 --#define HDMI_CORE_AV_FREQ_SVAL 0x8 --#define HDMI_CORE_AV_N_SVAL1 0xC --#define HDMI_CORE_AV_N_SVAL2 0x10 --#define HDMI_CORE_AV_N_SVAL3 0x14 --#define HDMI_CORE_AV_CTS_SVAL1 0x18 --#define HDMI_CORE_AV_CTS_SVAL2 0x1C --#define HDMI_CORE_AV_CTS_SVAL3 0x20 --#define HDMI_CORE_AV_CTS_HVAL1 0x24 --#define HDMI_CORE_AV_CTS_HVAL2 0x28 --#define HDMI_CORE_AV_CTS_HVAL3 0x2C --#define HDMI_CORE_AV_AUD_MODE 0x50 --#define HDMI_CORE_AV_SPDIF_CTRL 0x54 --#define HDMI_CORE_AV_HW_SPDIF_FS 0x60 --#define HDMI_CORE_AV_SWAP_I2S 0x64 --#define HDMI_CORE_AV_SPDIF_ERTH 0x6C --#define HDMI_CORE_AV_I2S_IN_MAP 0x70 --#define HDMI_CORE_AV_I2S_IN_CTRL 0x74 --#define HDMI_CORE_AV_I2S_CHST0 0x78 --#define HDMI_CORE_AV_I2S_CHST1 0x7C --#define HDMI_CORE_AV_I2S_CHST2 0x80 --#define HDMI_CORE_AV_I2S_CHST4 0x84 --#define HDMI_CORE_AV_I2S_CHST5 0x88 --#define HDMI_CORE_AV_ASRC 0x8C --#define HDMI_CORE_AV_I2S_IN_LEN 0x90 --#define HDMI_CORE_AV_HDMI_CTRL 0xBC --#define HDMI_CORE_AV_AUDO_TXSTAT 0xC0 --#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 0xCC --#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 0xD0 --#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 0xD4 --#define HDMI_CORE_AV_TEST_TXCTRL 0xF0 --#define HDMI_CORE_AV_DPD 0xF4 --#define HDMI_CORE_AV_PB_CTRL1 0xF8 --#define HDMI_CORE_AV_PB_CTRL2 0xFC --#define HDMI_CORE_AV_AVI_TYPE 0x100 --#define HDMI_CORE_AV_AVI_VERS 0x104 --#define HDMI_CORE_AV_AVI_LEN 0x108 --#define HDMI_CORE_AV_AVI_CHSUM 0x10C --#define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110) --#define HDMI_CORE_AV_SPD_TYPE 0x180 --#define HDMI_CORE_AV_SPD_VERS 0x184 --#define HDMI_CORE_AV_SPD_LEN 0x188 --#define HDMI_CORE_AV_SPD_CHSUM 0x18C --#define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190) --#define HDMI_CORE_AV_AUDIO_TYPE 0x200 --#define HDMI_CORE_AV_AUDIO_VERS 0x204 --#define HDMI_CORE_AV_AUDIO_LEN 0x208 --#define HDMI_CORE_AV_AUDIO_CHSUM 0x20C --#define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210) --#define HDMI_CORE_AV_MPEG_TYPE 0x280 --#define HDMI_CORE_AV_MPEG_VERS 0x284 --#define HDMI_CORE_AV_MPEG_LEN 0x288 --#define HDMI_CORE_AV_MPEG_CHSUM 0x28C --#define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290) --#define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300) --#define HDMI_CORE_AV_CP_BYTE1 0x37C --#define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380) --#define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC -- --#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 --#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 --#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 --#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 -- --#define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15 --#define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27 --#define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10 --#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27 --#define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31 --#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31 -- --/* PLL */ -- --#define PLLCTRL_PLL_CONTROL 0x0 --#define PLLCTRL_PLL_STATUS 0x4 --#define PLLCTRL_PLL_GO 0x8 --#define PLLCTRL_CFG1 0xC --#define PLLCTRL_CFG2 0x10 --#define PLLCTRL_CFG3 0x14 --#define PLLCTRL_CFG4 0x20 -- --/* HDMI PHY */ -- --#define HDMI_TXPHY_TX_CTRL 0x0 --#define HDMI_TXPHY_DIGITAL_CTRL 0x4 --#define HDMI_TXPHY_POWER_CTRL 0x8 --#define HDMI_TXPHY_PAD_CFG_CTRL 0xC -- --#define REG_FLD_MOD(base, idx, val, start, end) \ -- hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ -- val, start, end)) --#define REG_GET(base, idx, start, end) \ -- FLD_GET(hdmi_read_reg(base, idx), start, end) -- --enum hdmi_phy_pwr { -- HDMI_PHYPWRCMD_OFF = 0, -- HDMI_PHYPWRCMD_LDOON = 1, -- HDMI_PHYPWRCMD_TXON = 2 --}; -- --enum hdmi_core_inputbus_width { -- HDMI_INPUT_8BIT = 0, -- HDMI_INPUT_10BIT = 1, -- HDMI_INPUT_12BIT = 2 --}; -- --enum hdmi_core_dither_trunc { -- HDMI_OUTPUTTRUNCATION_8BIT = 0, -- HDMI_OUTPUTTRUNCATION_10BIT = 1, -- HDMI_OUTPUTTRUNCATION_12BIT = 2, -- HDMI_OUTPUTDITHER_8BIT = 3, -- HDMI_OUTPUTDITHER_10BIT = 4, -- HDMI_OUTPUTDITHER_12BIT = 5 --}; -- --enum hdmi_core_deepcolor_ed { -- HDMI_DEEPCOLORPACKECTDISABLE = 0, -- HDMI_DEEPCOLORPACKECTENABLE = 1 --}; -- --enum hdmi_core_packet_mode { -- HDMI_PACKETMODERESERVEDVALUE = 0, -- HDMI_PACKETMODE24BITPERPIXEL = 4, -- HDMI_PACKETMODE30BITPERPIXEL = 5, -- HDMI_PACKETMODE36BITPERPIXEL = 6, -- HDMI_PACKETMODE48BITPERPIXEL = 7 --}; -- --enum hdmi_core_tclkselclkmult { -- HDMI_FPLL05IDCK = 0, -- HDMI_FPLL10IDCK = 1, -- HDMI_FPLL20IDCK = 2, -- HDMI_FPLL40IDCK = 3 --}; -- --enum hdmi_core_packet_ctrl { -- HDMI_PACKETENABLE = 1, -- HDMI_PACKETDISABLE = 0, -- HDMI_PACKETREPEATON = 1, -- HDMI_PACKETREPEATOFF = 0 --}; -- --/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */ --enum hdmi_core_infoframe { -- HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, -- HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, -- HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, -- HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, -- HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1, -- HDMI_INFOFRAME_AVI_DB1B_NO = 0, -- HDMI_INFOFRAME_AVI_DB1B_VERT = 1, -- HDMI_INFOFRAME_AVI_DB1B_HORI = 2, -- HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, -- HDMI_INFOFRAME_AVI_DB1S_0 = 0, -- HDMI_INFOFRAME_AVI_DB1S_1 = 1, -- HDMI_INFOFRAME_AVI_DB1S_2 = 2, -- HDMI_INFOFRAME_AVI_DB2C_NO = 0, -- HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, -- HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, -- HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, -- HDMI_INFOFRAME_AVI_DB2M_NO = 0, -- HDMI_INFOFRAME_AVI_DB2M_43 = 1, -- HDMI_INFOFRAME_AVI_DB2M_169 = 2, -- HDMI_INFOFRAME_AVI_DB2R_SAME = 8, -- HDMI_INFOFRAME_AVI_DB2R_43 = 9, -- HDMI_INFOFRAME_AVI_DB2R_169 = 10, -- HDMI_INFOFRAME_AVI_DB2R_149 = 11, -- HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, -- HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, -- HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, -- HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, -- HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, -- HDMI_INFOFRAME_AVI_DB3Q_LR = 1, -- HDMI_INFOFRAME_AVI_DB3Q_FR = 2, -- HDMI_INFOFRAME_AVI_DB3SC_NO = 0, -- HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, -- HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, -- HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, -- HDMI_INFOFRAME_AVI_DB5PR_NO = 0, -- HDMI_INFOFRAME_AVI_DB5PR_2 = 1, -- HDMI_INFOFRAME_AVI_DB5PR_3 = 2, -- HDMI_INFOFRAME_AVI_DB5PR_4 = 3, -- HDMI_INFOFRAME_AVI_DB5PR_5 = 4, -- HDMI_INFOFRAME_AVI_DB5PR_6 = 5, -- HDMI_INFOFRAME_AVI_DB5PR_7 = 6, -- HDMI_INFOFRAME_AVI_DB5PR_8 = 7, -- HDMI_INFOFRAME_AVI_DB5PR_9 = 8, -- HDMI_INFOFRAME_AVI_DB5PR_10 = 9, --}; -- --enum hdmi_packing_mode { -- HDMI_PACK_10b_RGB_YUV444 = 0, -- HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, -- HDMI_PACK_20b_YUV422 = 2, -- HDMI_PACK_ALREADYPACKED = 7 --}; -- --enum hdmi_core_audio_layout { -- HDMI_AUDIO_LAYOUT_2CH = 0, -- HDMI_AUDIO_LAYOUT_8CH = 1 --}; -- --enum hdmi_core_cts_mode { -- HDMI_AUDIO_CTS_MODE_HW = 0, -- HDMI_AUDIO_CTS_MODE_SW = 1 --}; -- --enum hdmi_stereo_channels { -- HDMI_AUDIO_STEREO_NOCHANNELS = 0, -- HDMI_AUDIO_STEREO_ONECHANNEL = 1, -- HDMI_AUDIO_STEREO_TWOCHANNELS = 2, -- HDMI_AUDIO_STEREO_THREECHANNELS = 3, -- HDMI_AUDIO_STEREO_FOURCHANNELS = 4 --}; -- --enum hdmi_audio_type { -- HDMI_AUDIO_TYPE_LPCM = 0, -- HDMI_AUDIO_TYPE_IEC = 1 --}; -- --enum hdmi_audio_justify { -- HDMI_AUDIO_JUSTIFY_LEFT = 0, -- HDMI_AUDIO_JUSTIFY_RIGHT = 1 --}; -- --enum hdmi_audio_sample_order { -- HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, -- HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 --}; -- --enum hdmi_audio_samples_perword { -- HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, -- HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 --}; -- --enum hdmi_audio_sample_size { -- HDMI_AUDIO_SAMPLE_16BITS = 0, -- HDMI_AUDIO_SAMPLE_24BITS = 1 --}; -- --enum hdmi_audio_transf_mode { -- HDMI_AUDIO_TRANSF_DMA = 0, -- HDMI_AUDIO_TRANSF_IRQ = 1 --}; -- --enum hdmi_audio_blk_strt_end_sig { -- HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, -- HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 --}; -- --enum hdmi_audio_i2s_config { -- HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, -- HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, -- HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0, -- HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1, -- HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0, -- HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1, -- HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0, -- HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1, -- HDMI_AUDIO_I2S_SD0_EN = 1, -- HDMI_AUDIO_I2S_SD1_EN = 1 << 1, -- HDMI_AUDIO_I2S_SD2_EN = 1 << 2, -- HDMI_AUDIO_I2S_SD3_EN = 1 << 3, --}; -- --enum hdmi_audio_mclk_mode { -- HDMI_AUDIO_MCLK_128FS = 0, -- HDMI_AUDIO_MCLK_256FS = 1, -- HDMI_AUDIO_MCLK_384FS = 2, -- HDMI_AUDIO_MCLK_512FS = 3, -- HDMI_AUDIO_MCLK_768FS = 4, -- HDMI_AUDIO_MCLK_1024FS = 5, -- HDMI_AUDIO_MCLK_1152FS = 6, -- HDMI_AUDIO_MCLK_192FS = 7 --}; -- --struct hdmi_core_video_config { -- enum hdmi_core_inputbus_width ip_bus_width; -- enum hdmi_core_dither_trunc op_dither_truc; -- enum hdmi_core_deepcolor_ed deep_color_pkt; -- enum hdmi_core_packet_mode pkt_mode; -- enum hdmi_core_hdmi_dvi hdmi_dvi; -- enum hdmi_core_tclkselclkmult tclk_sel_clkmult; --}; -- --struct hdmi_core_packet_enable_repeat { -- u32 audio_pkt; -- u32 audio_pkt_repeat; -- u32 avi_infoframe; -- u32 avi_infoframe_repeat; -- u32 gen_cntrl_pkt; -- u32 gen_cntrl_pkt_repeat; -- u32 generic_pkt; -- u32 generic_pkt_repeat; --}; -- --struct hdmi_video_format { -- enum hdmi_packing_mode packing_mode; -- u32 y_res; /* Line per panel */ -- u32 x_res; /* pixel per line */ --}; -- --struct hdmi_audio_format { -- enum hdmi_stereo_channels stereo_channels; -- u8 active_chnnls_msk; -- enum hdmi_audio_type type; -- enum hdmi_audio_justify justification; -- enum hdmi_audio_sample_order sample_order; -- enum hdmi_audio_samples_perword samples_per_word; -- enum hdmi_audio_sample_size sample_size; -- enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; --}; -- --struct hdmi_audio_dma { -- u8 transfer_size; -- u8 block_size; -- enum hdmi_audio_transf_mode mode; -- u16 fifo_threshold; --}; -- --struct hdmi_core_audio_i2s_config { -- u8 in_length_bits; -- u8 justification; -- u8 sck_edge_mode; -- u8 vbit; -- u8 direction; -- u8 shift; -- u8 active_sds; --}; -- --struct hdmi_core_audio_config { -- struct hdmi_core_audio_i2s_config i2s_cfg; -- struct snd_aes_iec958 *iec60958_cfg; -- bool fs_override; -- u32 n; -- u32 cts; -- u32 aud_par_busclk; -- enum hdmi_core_audio_layout layout; -- enum hdmi_core_cts_mode cts_mode; -- bool use_mclk; -- enum hdmi_audio_mclk_mode mclk_mode; -- bool en_acr_pkt; -- bool en_dsd_audio; -- bool en_parallel_aud_input; -- bool en_spdif; --}; -- --#endif ---- a/drivers/video/omap2/dss/ti_hdmi.h -+++ /dev/null -@@ -1,187 +0,0 @@ --/* -- * ti_hdmi.h -- * -- * HDMI driver definition for TI OMAP4, DM81xx, DM38xx Processor. -- * -- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -- * -- * 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. -- * -- * 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, see <http://www.gnu.org/licenses/>. -- */ -- --#ifndef _TI_HDMI_H --#define _TI_HDMI_H -- --struct hdmi_ip_data; -- --enum hdmi_pll_pwr { -- HDMI_PLLPWRCMD_ALLOFF = 0, -- HDMI_PLLPWRCMD_PLLONLY = 1, -- HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2, -- HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 --}; -- --enum hdmi_core_hdmi_dvi { -- HDMI_DVI = 0, -- HDMI_HDMI = 1 --}; -- --enum hdmi_clk_refsel { -- HDMI_REFSEL_PCLK = 0, -- HDMI_REFSEL_REF1 = 1, -- HDMI_REFSEL_REF2 = 2, -- HDMI_REFSEL_SYSCLK = 3 --}; -- --struct hdmi_cm { -- int code; -- int mode; --}; -- --struct hdmi_config { -- struct omap_video_timings timings; -- struct hdmi_cm cm; --}; -- --/* HDMI PLL structure */ --struct hdmi_pll_info { -- u16 regn; -- u16 regm; -- u32 regmf; -- u16 regm2; -- u16 regsd; -- u16 dcofreq; -- enum hdmi_clk_refsel refsel; --}; -- --struct ti_hdmi_ip_ops { -- -- void (*video_configure)(struct hdmi_ip_data *ip_data); -- -- int (*phy_enable)(struct hdmi_ip_data *ip_data); -- -- void (*phy_disable)(struct hdmi_ip_data *ip_data); -- -- int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len); -- -- int (*pll_enable)(struct hdmi_ip_data *ip_data); -- -- void (*pll_disable)(struct hdmi_ip_data *ip_data); -- -- int (*video_enable)(struct hdmi_ip_data *ip_data); -- -- void (*video_disable)(struct hdmi_ip_data *ip_data); -- -- void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s); -- -- void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s); -- -- void (*dump_pll)(struct hdmi_ip_data *ip_data, struct seq_file *s); -- -- void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); -- --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -- int (*audio_enable)(struct hdmi_ip_data *ip_data); -- -- void (*audio_disable)(struct hdmi_ip_data *ip_data); -- -- int (*audio_start)(struct hdmi_ip_data *ip_data); -- -- void (*audio_stop)(struct hdmi_ip_data *ip_data); -- -- int (*audio_config)(struct hdmi_ip_data *ip_data, -- struct omap_dss_audio *audio); -- -- int (*audio_get_dma_port)(u32 *offset, u32 *size); --#endif -- --}; -- --/* -- * Refer to section 8.2 in HDMI 1.3 specification for -- * details about infoframe databytes -- */ --struct hdmi_core_infoframe_avi { -- /* Y0, Y1 rgb,yCbCr */ -- u8 db1_format; -- /* A0 Active information Present */ -- u8 db1_active_info; -- /* B0, B1 Bar info data valid */ -- u8 db1_bar_info_dv; -- /* S0, S1 scan information */ -- u8 db1_scan_info; -- /* C0, C1 colorimetry */ -- u8 db2_colorimetry; -- /* M0, M1 Aspect ratio (4:3, 16:9) */ -- u8 db2_aspect_ratio; -- /* R0...R3 Active format aspect ratio */ -- u8 db2_active_fmt_ar; -- /* ITC IT content. */ -- u8 db3_itc; -- /* EC0, EC1, EC2 Extended colorimetry */ -- u8 db3_ec; -- /* Q1, Q0 Quantization range */ -- u8 db3_q_range; -- /* SC1, SC0 Non-uniform picture scaling */ -- u8 db3_nup_scaling; -- /* VIC0..6 Video format identification */ -- u8 db4_videocode; -- /* PR0..PR3 Pixel repetition factor */ -- u8 db5_pixel_repeat; -- /* Line number end of top bar */ -- u16 db6_7_line_eoftop; -- /* Line number start of bottom bar */ -- u16 db8_9_line_sofbottom; -- /* Pixel number end of left bar */ -- u16 db10_11_pixel_eofleft; -- /* Pixel number start of right bar */ -- u16 db12_13_pixel_sofright; --}; -- --struct hdmi_ip_data { -- void __iomem *base_wp; /* HDMI wrapper */ -- unsigned long core_sys_offset; -- unsigned long core_av_offset; -- unsigned long pll_offset; -- unsigned long phy_offset; -- int irq; -- const struct ti_hdmi_ip_ops *ops; -- struct hdmi_config cfg; -- struct hdmi_pll_info pll_data; -- struct hdmi_core_infoframe_avi avi_cfg; -- -- /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ -- struct mutex lock; --}; --int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); --int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); --int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); --int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); --void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); --void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); --void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); --#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) --int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); --int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data); --int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data); --void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data); --int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, -- struct omap_dss_audio *audio); --int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size); --#endif --#endif ---- a/drivers/video/omap2/dss/venc.c -+++ b/drivers/video/omap2/dss/venc.c -@@ -894,6 +894,12 @@ static const struct dev_pm_ops venc_pm_o - .runtime_resume = venc_runtime_resume, - }; - -+ -+static const struct of_device_id venc_of_match[] = { -+ { .compatible = "ti,omap3-venc", }, -+ {}, -+}; -+ - static struct platform_driver omap_venchw_driver = { - .probe = omap_venchw_probe, - .remove = __exit_p(omap_venchw_remove), -@@ -901,6 +907,7 @@ static struct platform_driver omap_vench - .name = "omapdss_venc", - .owner = THIS_MODULE, - .pm = &venc_pm_ops, -+ .of_match_table = venc_of_match, - }, - }; - ---- a/drivers/video/omap2/omapfb/omapfb-main.c -+++ b/drivers/video/omap2/omapfb/omapfb-main.c -@@ -2407,6 +2407,55 @@ static int omapfb_init_connections(struc - return 0; - } - -+static struct omap_dss_device * -+omapfb_find_default_display(struct omapfb2_device *fbdev) -+{ -+ const char *def_name; -+ int i; -+ -+ /* -+ * Search with the display name from the user or the board file, -+ * comparing to display names and aliases -+ */ -+ -+ def_name = omapdss_get_default_display_name(); -+ -+ if (def_name) { -+ for (i = 0; i < fbdev->num_displays; ++i) { -+ struct omap_dss_device *dssdev; -+ -+ dssdev = fbdev->displays[i].dssdev; -+ -+ if (dssdev->name && strcmp(def_name, dssdev->name) == 0) -+ return dssdev; -+ -+ if (strcmp(def_name, dssdev->alias) == 0) -+ return dssdev; -+ } -+ -+ /* def_name given but not found */ -+ return NULL; -+ } -+ -+ /* then look for DT alias display0 */ -+ for (i = 0; i < fbdev->num_displays; ++i) { -+ struct omap_dss_device *dssdev; -+ int id; -+ -+ dssdev = fbdev->displays[i].dssdev; -+ -+ if (dssdev->dev->of_node == NULL) -+ continue; -+ -+ id = of_alias_get_id(dssdev->dev->of_node, "display"); -+ if (id == 0) -+ return dssdev; -+ } -+ -+ /* return the first display we have in the list */ -+ return fbdev->displays[0].dssdev; -+} -+ - static int omapfb_probe(struct platform_device *pdev) - { - struct omapfb2_device *fbdev = NULL; -@@ -2484,23 +2533,7 @@ static int omapfb_probe(struct platform_ - for (i = 0; i < fbdev->num_managers; i++) - fbdev->managers[i] = omap_dss_get_overlay_manager(i); - -- def_display = NULL; -- -- for (i = 0; i < fbdev->num_displays; ++i) { -- struct omap_dss_device *dssdev; -- const char *def_name; -- -- def_name = omapdss_get_default_display_name(); -- -- dssdev = fbdev->displays[i].dssdev; -- -- if (def_name == NULL || -- (dssdev->name && strcmp(def_name, dssdev->name) == 0)) { -- def_display = dssdev; -- break; -- } -- } -- -+ def_display = omapfb_find_default_display(fbdev); - if (def_display == NULL) { - dev_err(fbdev->dev, "failed to find default display\n"); - r = -EPROBE_DEFER; ---- a/drivers/watchdog/omap_wdt.c -+++ b/drivers/watchdog/omap_wdt.c -@@ -41,7 +41,9 @@ - #include <linux/io.h> - #include <linux/slab.h> - #include <linux/pm_runtime.h> -+#include <linux/interrupt.h> - #include <linux/platform_data/omap-wd-timer.h> -+#include <linux/of.h> - - #include "omap_wdt.h" - -@@ -54,6 +56,10 @@ static unsigned timer_margin; - module_param(timer_margin, uint, 0); - MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); - -+static int kernelpet = 1; -+module_param(kernelpet, int, 0); -+MODULE_PARM_DESC(kernelpet, "pet watchdog in kernel via irq"); -+ - struct omap_wdt_dev { - void __iomem *base; /* physical */ - struct device *dev; -@@ -112,6 +118,7 @@ static void omap_wdt_set_timer(struct om - unsigned int timeout) - { - u32 pre_margin = GET_WLDR_VAL(timeout); -+ u32 delay_period = GET_WLDR_VAL(timeout / 2); - void __iomem *base = wdev->base; - - /* just count up at 32 KHz */ -@@ -121,6 +128,26 @@ static void omap_wdt_set_timer(struct om - __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR); - while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) - cpu_relax(); -+ -+ /* Set delay interrupt to half the watchdog interval. */ -+ while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 1 << 5) -+ cpu_relax(); -+ __raw_writel(delay_period, base + OMAP_WATCHDOG_WDLY); -+} -+ -+static irqreturn_t omap_wdt_interrupt(int irq, void *dev_id) -+{ -+ struct watchdog_device *wdog = dev_id; -+ struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); -+ void __iomem *base = wdev->base; -+ u32 i; -+ -+ i = __raw_readl(base + OMAP_WATCHDOG_WIRQSTAT); -+ __raw_writel(i, base + OMAP_WATCHDOG_WIRQSTAT); -+ -+ omap_wdt_reload(wdev); -+ -+ return IRQ_HANDLED; - } - - static int omap_wdt_start(struct watchdog_device *wdog) -@@ -144,6 +171,13 @@ static int omap_wdt_start(struct watchdo - - omap_wdt_set_timer(wdev, wdog->timeout); - omap_wdt_reload(wdev); /* trigger loading of new timeout value */ -+ -+ /* Enable delay interrupt */ -+ if (kernelpet) { -+ __raw_writel(0x2, base + OMAP_WATCHDOG_WIRQENSET); -+ __raw_writel(0x2, base + OMAP_WATCHDOG_WIRQWAKEEN); -+ } -+ - omap_wdt_enable(wdev); - - mutex_unlock(&wdev->lock); -@@ -154,9 +188,16 @@ static int omap_wdt_start(struct watchdo - static int omap_wdt_stop(struct watchdog_device *wdog) - { - struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); -+ void __iomem *base = wdev->base; - - mutex_lock(&wdev->lock); - omap_wdt_disable(wdev); -+ /* Disable delay interrupt */ -+ if (kernelpet) { -+ __raw_writel(0x0, base + OMAP_WATCHDOG_WIRQWAKEEN); -+ __raw_writel(0x2, base + OMAP_WATCHDOG_WIRQENCLR); -+ } -+ - pm_runtime_put_sync(wdev->dev); - wdev->omap_wdt_users = false; - mutex_unlock(&wdev->lock); -@@ -167,6 +208,11 @@ static int omap_wdt_ping(struct watchdog - { - struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); - -+ if (kernelpet) { -+ pr_info("Hw ping is enabled,Skipping userspace ping\n"); -+ return 0; -+ } -+ - mutex_lock(&wdev->lock); - omap_wdt_reload(wdev); - mutex_unlock(&wdev->lock); -@@ -210,7 +256,7 @@ static int omap_wdt_probe(struct platfor - struct resource *res, *mem; - struct omap_wdt_dev *wdev; - u32 rs; -- int ret; -+ int ret, irq; - - omap_wdt = devm_kzalloc(&pdev->dev, sizeof(*omap_wdt), GFP_KERNEL); - if (!omap_wdt) -@@ -240,6 +286,23 @@ static int omap_wdt_probe(struct platfor - if (!wdev->base) - return -ENOMEM; - -+ if (pdev->dev.of_node) { -+ if (of_device_is_compatible(pdev->dev.of_node, "ti,omap3-wdt")) -+ kernelpet = 0; -+ } else { -+ if (pdata->ip_rev == WDTIMER2_IP3) -+ kernelpet = 0; -+ } -+ -+ if (kernelpet) { -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(&pdev->dev, irq, omap_wdt_interrupt, 0, -+ dev_name(&pdev->dev), omap_wdt); -+ if (ret < 0) -+ dev_err(&pdev->dev, "can't get irq %d, err %d\n", -+ irq, ret); -+ } -+ - omap_wdt->info = &omap_wdt_info; - omap_wdt->ops = &omap_wdt_ops; - omap_wdt->min_timeout = TIMER_MARGIN_MIN; -@@ -280,6 +343,12 @@ static int omap_wdt_probe(struct platfor - - pm_runtime_put_sync(wdev->dev); - -+ if (kernelpet) { -+ ret = omap_wdt_start(omap_wdt); -+ if (ret == 0) -+ set_bit(WDOG_ACTIVE, &omap_wdt->status); -+ } -+ - return 0; - } - -@@ -300,6 +369,13 @@ static int omap_wdt_remove(struct platfo - { - struct watchdog_device *wdog = platform_get_drvdata(pdev); - struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog); -+ int ret; -+ -+ if (kernelpet) { -+ ret = omap_wdt_stop(wdog); -+ if (ret == 0) -+ clear_bit(WDOG_ACTIVE, &wdog->status); -+ } - - pm_runtime_disable(wdev->dev); - watchdog_unregister_device(wdog); -@@ -352,7 +428,8 @@ static int omap_wdt_resume(struct platfo - #endif - - static const struct of_device_id omap_wdt_of_match[] = { -- { .compatible = "ti,omap3-wdt", }, -+ { .compatible = "ti,omap3-wdt" }, -+ { .compatible = "ti,omap4-wdt" }, - {}, - }; - MODULE_DEVICE_TABLE(of, omap_wdt_of_match); ---- a/drivers/watchdog/omap_wdt.h -+++ b/drivers/watchdog/omap_wdt.h -@@ -38,7 +38,12 @@ - #define OMAP_WATCHDOG_LDR (0x2c) - #define OMAP_WATCHDOG_TGR (0x30) - #define OMAP_WATCHDOG_WPS (0x34) -+#define OMAP_WATCHDOG_WDLY (0x44) - #define OMAP_WATCHDOG_SPR (0x48) -+#define OMAP_WATCHDOG_WIRQSTAT (0x58) -+#define OMAP_WATCHDOG_WIRQENSET (0x5c) -+#define OMAP_WATCHDOG_WIRQENCLR (0x60) -+#define OMAP_WATCHDOG_WIRQWAKEEN (0x64) - - /* Using the prescaler, the OMAP watchdog could go for many - * months before firing. These limits work without scaling, ---- /dev/null -+++ b/include/dt-bindings/mfd/palmas.h -@@ -0,0 +1,18 @@ -+/* -+ * This header provides macros for Palmas device bindings. -+ * -+ * Copyright (c) 2013, NVIDIA Corporation. -+ * -+ * Author: Laxman Dewangan <ldewangan@nvidia.com> -+ * -+ */ -+ -+#ifndef __DT_BINDINGS_PALMAS_H__ -+#define __DT_BINDINGS_PALMAS_H -+ -+/* External control pins */ -+#define PALMAS_EXT_CONTROL_PIN_ENABLE1 1 -+#define PALMAS_EXT_CONTROL_PIN_ENABLE2 2 -+#define PALMAS_EXT_CONTROL_PIN_NSLEEP 3 -+ -+#endif /* __DT_BINDINGS_PALMAS_H */ ---- /dev/null -+++ b/include/dt-bindings/pinctrl/am43xx.h -@@ -0,0 +1,30 @@ -+/* -+ * This header provides constants specific to AM43XX pinctrl bindings. -+ */ -+ -+#ifndef _DT_BINDINGS_PINCTRL_AM43XX_H -+#define _DT_BINDINGS_PINCTRL_AM43XX_H -+ -+#define MUX_MODE0 0 -+#define MUX_MODE1 1 -+#define MUX_MODE2 2 -+#define MUX_MODE3 3 -+#define MUX_MODE4 4 -+#define MUX_MODE5 5 -+#define MUX_MODE6 6 -+#define MUX_MODE7 7 -+ -+#define PULL_DISABLE (1 << 16) -+#define PULL_UP (1 << 17) -+#define INPUT_EN (1 << 18) -+#define SLEWCTRL_FAST (1 << 19) -+#define DS0_PULL_UP_DOWN_EN (1 << 27) -+ -+#define PIN_OUTPUT (PULL_DISABLE) -+#define PIN_OUTPUT_PULLUP (PULL_UP) -+#define PIN_OUTPUT_PULLDOWN 0 -+#define PIN_INPUT (INPUT_EN | PULL_DISABLE) -+#define PIN_INPUT_PULLUP (INPUT_EN | PULL_UP) -+#define PIN_INPUT_PULLDOWN (INPUT_EN) -+ -+#endif ---- /dev/null -+++ b/include/dt-bindings/pinctrl/dra7xx.h -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ */ -+/* -+ * This header provides constants specific to DRA7XX pinctrl bindings. -+ */ -+ -+#ifndef _DT_BINDINGS_PINCTRL_DRA7XX_H_ -+#define _DT_BINDINGS_PINCTRL_DRA7XX_H_ -+ -+/* dra7xx specific mux bit defines */ -+#define MUX_MODE0 0 -+#define MUX_MODE1 1 -+#define MUX_MODE2 2 -+#define MUX_MODE3 3 -+#define MUX_MODE4 4 -+#define MUX_MODE5 5 -+#define MUX_MODE6 6 -+#define MUX_MODE7 7 -+ -+#define PULL_ENA (1 << 16) -+#define PULL_UP (1 << 17) -+#define INPUT_EN (1 << 18) -+#define SLEWCTRL_FAST (1 << 19) -+#define WAKEUP_EN (1 << 24) -+#define WAKEUP_EVENT (1 << 25) -+ -+/* Active pin states */ -+#define PIN_OUTPUT 0 -+#define PIN_OUTPUT_PULLUP (PIN_OUTPUT | PULL_ENA | PULL_UP) -+#define PIN_OUTPUT_PULLDOWN (PIN_OUTPUT | PULL_ENA) -+#define PIN_INPUT INPUT_EN -+#define PIN_INPUT_PULLUP (PULL_ENA | INPUT_EN | PULL_UP) -+#define PIN_INPUT_PULLDOWN (PULL_ENA | INPUT_EN) -+ -+/* Off mode states */ -+#define PIN_OFF_NONE 0 -+#define PIN_OFF_OUTPUT_HIGH (OFF_EN | OFFOUT_EN | OFFOUT_VAL) -+#define PIN_OFF_OUTPUT_LOW (OFF_EN | OFFOUT_EN) -+#define PIN_OFF_INPUT_PULLUP (OFF_EN | OFF_PULL_EN | OFF_PULL_UP) -+#define PIN_OFF_INPUT_PULLDOWN (OFF_EN | OFF_PULL_EN) -+#define PIN_OFF_WAKEUPENABLE WAKEUP_EN -+ -+#endif ---- /dev/null -+++ b/include/linux/clk/ti.h -@@ -0,0 +1,245 @@ -+/* -+ * TI clock drivers support -+ * -+ * Copyright (C) 2013 Texas Instruments, 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef __LINUX_CLK_TI_H__ -+#define __LINUX_CLK_TI_H__ -+ -+#include <linux/clkdev.h> -+ -+/** -+ * struct dpll_data - DPLL registers and integration data -+ * @mult_div1_reg: register containing the DPLL M and N bitfields -+ * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg -+ * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg -+ * @clk_bypass: struct clk pointer to the clock's bypass clock input -+ * @clk_ref: struct clk pointer to the clock's reference clock input -+ * @control_reg: register containing the DPLL mode bitfield -+ * @enable_mask: mask of the DPLL mode bitfield in @control_reg -+ * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate() -+ * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate() -+ * @last_rounded_m4xen: cache of the last M4X result of -+ * omap4_dpll_regm4xen_round_rate() -+ * @last_rounded_lpmode: cache of the last lpmode result of -+ * omap4_dpll_lpmode_recalc() -+ * @max_multiplier: maximum valid non-bypass multiplier value (actual) -+ * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate() -+ * @min_divider: minimum valid non-bypass divider value (actual) -+ * @max_divider: maximum valid non-bypass divider value (actual) -+ * @modes: possible values of @enable_mask -+ * @autoidle_reg: register containing the DPLL autoidle mode bitfield -+ * @idlest_reg: register containing the DPLL idle status bitfield -+ * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg -+ * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg -+ * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg -+ * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg -+ * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg -+ * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg -+ * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs -+ * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs -+ * @flags: DPLL type/features (see below) -+ * -+ * Possible values for @flags: -+ * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs) -+ * -+ * @freqsel_mask is only used on the OMAP34xx family and AM35xx. -+ * -+ * XXX Some DPLLs have multiple bypass inputs, so it's not technically -+ * correct to only have one @clk_bypass pointer. -+ * -+ * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m, -+ * @last_rounded_n) should be separated from the runtime-fixed fields -+ * and placed into a different structure, so that the runtime-fixed data -+ * can be placed into read-only space. -+ */ -+struct dpll_data { -+ void __iomem *mult_div1_reg; -+ u32 mult_mask; -+ u32 div1_mask; -+ struct clk *clk_bypass; -+ struct clk *clk_ref; -+ void __iomem *control_reg; -+ u32 enable_mask; -+ unsigned long last_rounded_rate; -+ u16 last_rounded_m; -+ u8 last_rounded_m4xen; -+ u8 last_rounded_lpmode; -+ u16 max_multiplier; -+ u8 last_rounded_n; -+ u8 min_divider; -+ u16 max_divider; -+ u8 modes; -+ void __iomem *autoidle_reg; -+ void __iomem *idlest_reg; -+ u32 autoidle_mask; -+ u32 freqsel_mask; -+ u32 idlest_mask; -+ u32 dco_mask; -+ u32 sddiv_mask; -+ u32 lpmode_mask; -+ u32 m4xen_mask; -+ u8 auto_recal_bit; -+ u8 recal_en_bit; -+ u8 recal_st_bit; -+ u8 flags; -+}; -+ -+struct clk_hw_omap_ops; -+ -+/** -+ * struct clk_hw_omap - OMAP struct clk -+ * @node: list_head connecting this clock into the full clock list -+ * @enable_reg: register to write to enable the clock (see @enable_bit) -+ * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg) -+ * @flags: see "struct clk.flags possibilities" above -+ * @clksel_reg: for clksel clks, register va containing src/divisor select -+ * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector -+ * @clksel: for clksel clks, pointer to struct clksel for this clock -+ * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock -+ * @clkdm_name: clockdomain name that this clock is contained in -+ * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime -+ * @rate_offset: bitshift for rate selection bitfield (OMAP1 only) -+ * @src_offset: bitshift for source selection bitfield (OMAP1 only) -+ * -+ * XXX @rate_offset, @src_offset should probably be removed and OMAP1 -+ * clock code converted to use clksel. -+ * -+ */ -+struct clk_hw_omap { -+ struct clk_hw hw; -+ struct list_head node; -+ unsigned long fixed_rate; -+ u8 fixed_div; -+ void __iomem *enable_reg; -+ u8 enable_bit; -+ u8 flags; -+ void __iomem *clksel_reg; -+ u32 clksel_mask; -+ const struct clksel *clksel; -+ struct dpll_data *dpll_data; -+ const char *clkdm_name; -+ struct clockdomain *clkdm; -+ const struct clk_hw_omap_ops *ops; -+}; -+ -+/* -+ * struct clk_hw_omap.flags possibilities -+ * -+ * XXX document the rest of the clock flags here -+ * -+ * ENABLE_REG_32BIT: (OMAP1 only) clock control register must be accessed -+ * with 32bit ops, by default OMAP1 uses 16bit ops. -+ * CLOCK_IDLE_CONTROL: (OMAP1 only) clock has autoidle support. -+ * CLOCK_NO_IDLE_PARENT: (OMAP1 only) when clock is enabled, its parent -+ * clock is put to no-idle mode. -+ * ENABLE_ON_INIT: Clock is enabled on init. -+ * INVERT_ENABLE: By default, clock enable bit behavior is '1' enable, '0' -+ * disable. This inverts the behavior making '0' enable and '1' disable. -+ * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL -+ * bits share the same register. This flag allows the -+ * omap4_dpllmx*() code to determine which GATE_CTRL bit field -+ * should be used. This is a temporary solution - a better approach -+ * would be to associate clock type-specific data with the clock, -+ * similar to the struct dpll_data approach. -+ */ -+#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ -+#define CLOCK_IDLE_CONTROL (1 << 1) -+#define CLOCK_NO_IDLE_PARENT (1 << 2) -+#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ -+#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ -+#define CLOCK_CLKOUTX2 (1 << 5) -+ -+/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ -+#define DPLL_LOW_POWER_STOP 0x1 -+#define DPLL_LOW_POWER_BYPASS 0x5 -+#define DPLL_LOCKED 0x7 -+ -+/* DPLL Type and DCO Selection Flags */ -+#define DPLL_J_TYPE 0x1 -+ -+/** -+ * struct omap_dt_clk - OMAP DT clock alias declarations -+ * @lk: clock lookup definition -+ * @node_name: clock DT node to map to -+ */ -+struct omap_dt_clk { -+ struct clk_lookup lk; -+ char *node_name; -+}; -+ -+#define DT_CLK(dev, con, name) \ -+ { \ -+ .lk = { \ -+ .dev_id = dev, \ -+ .con_id = con, \ -+ }, \ -+ .node_name = name, \ -+ } -+ -+#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) -+ -+void omap2_init_clk_hw_omap_clocks(struct clk *clk); -+int omap3_noncore_dpll_enable(struct clk_hw *hw); -+void omap3_noncore_dpll_disable(struct clk_hw *hw); -+int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate); -+unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, -+ unsigned long parent_rate); -+long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, -+ unsigned long target_rate, -+ unsigned long *parent_rate); -+u8 omap2_init_dpll_parent(struct clk_hw *hw); -+unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); -+long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, -+ unsigned long *parent_rate); -+void omap2_init_clk_clkdm(struct clk_hw *clk); -+unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, -+ unsigned long parent_rate); -+int omap2_clkops_enable_clkdm(struct clk_hw *hw); -+void omap2_clkops_disable_clkdm(struct clk_hw *hw); -+int omap2_clk_disable_autoidle_all(void); -+void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); -+int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, -+ unsigned long parent_rate); -+int omap2_dflt_clk_enable(struct clk_hw *hw); -+void omap2_dflt_clk_disable(struct clk_hw *hw); -+int omap2_dflt_clk_is_enabled(struct clk_hw *hw); -+void omap3_clk_lock_dpll5(void); -+ -+void omap_dt_clocks_register(struct omap_dt_clk *oclks); -+#ifdef CONFIG_OF -+void of_omap_clk_allow_autoidle_all(void); -+void of_omap_clk_deny_autoidle_all(void); -+#else -+static inline void of_omap_clk_allow_autoidle_all(void) { } -+static inline void of_omap_clk_deny_autoidle_all(void) { } -+#endif -+ -+int omap5xxx_clk_init(void); -+int dra7xx_clk_init(void); -+int am43xx_clk_init(void); -+ -+extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; -+extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; -+extern const struct clk_hw_omap_ops clkhwops_wait; -+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; -+extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; -+extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait; -+ -+extern const struct clk_hw_omap_ops clkhwops_iclk_wait; -+extern const struct clk_hw_omap_ops clkhwops_iclk; -+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; -+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait; -+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait; -+ -+#endif ---- a/include/linux/clk-private.h -+++ b/include/linux/clk-private.h -@@ -122,7 +122,7 @@ struct clk { - }, \ - .reg = _reg, \ - .shift = _shift, \ -- .width = _width, \ -+ .mask = ((1 << _width) - 1), \ - .flags = _divider_flags, \ - .table = _table, \ - .lock = _lock, \ ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -241,6 +241,8 @@ struct clk *clk_register_gate(struct dev - void __iomem *reg, u8 bit_idx, - u8 clk_gate_flags, spinlock_t *lock); - -+void of_gate_clk_setup(struct device_node *node); -+ - struct clk_div_table { - unsigned int val; - unsigned int div; -@@ -280,7 +282,7 @@ struct clk_divider { - struct clk_hw hw; - void __iomem *reg; - u8 shift; -- u8 width; -+ u32 mask; - u8 flags; - const struct clk_div_table *table; - spinlock_t *lock; -@@ -302,6 +304,8 @@ struct clk *clk_register_divider_table(s - u8 clk_divider_flags, const struct clk_div_table *table, - spinlock_t *lock); - -+void of_divider_clk_setup(struct device_node *node); -+ - /** - * struct clk_mux - multiplexer clock - * -@@ -351,7 +355,7 @@ struct clk *clk_register_mux_table(struc - void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock); - --void of_fixed_factor_clk_setup(struct device_node *node); -+void of_mux_clk_setup(struct device_node *node); - - /** - * struct clk_fixed_factor - fixed multiplier and divider clock -@@ -372,10 +376,13 @@ struct clk_fixed_factor { - }; - - extern struct clk_ops clk_fixed_factor_ops; -+ - struct clk *clk_register_fixed_factor(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div); - -+void of_fixed_factor_clk_setup(struct device_node *node); -+ - /*** - * struct clk_composite - aggregate clock of mux, divider and gate clocks - * -@@ -472,6 +479,7 @@ void of_clk_del_provider(struct device_n - struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, - void *data); - struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); -+int of_clk_get_parent_count(struct device_node *np); - const char *of_clk_get_parent_name(struct device_node *np, int index); - - void of_clk_init(const struct of_device_id *matches); ---- /dev/null -+++ b/include/linux/crossbar.h -@@ -0,0 +1,71 @@ -+/* -+ * IRQ/DMA CROSSBAR DRIVER -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ -+ * Sricharan <r.sricharan@ti.com> -+ * -+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -+ * USA -+ */ -+#include <linux/io.h> -+#include <linux/of.h> -+#include <linux/of_irq.h> -+#include <linux/of_address.h> -+#include <linux/list.h> -+#include <linux/err.h> -+#include <linux/gfp.h> -+#include <linux/platform_device.h> -+ -+/* -+ * @base: base address of the crossbar device -+ * @dev: device ptr -+ * @name: name of the crossbar device -+ * @node: list node for the crossbar devices linked list -+ * @cb_entries: list of entries that belong to the crossbar -+ * @cb_lock: mutex -+ * @regmap pointer -+ */ -+struct cb_device { -+ void __iomem *base; -+ struct device *dev; -+ const char *name; -+ struct list_head node; -+ struct list_head cb_entries; -+ struct mutex cb_lock; -+ struct regmap *cb_regmap; -+}; -+ -+/* -+ * @cb_name: name of crossbar target to which this line is mapped -+ * @dev_name: mapped device input request name -+ * @cb_no: crossbar device input number -+ * @int_no: request number to which this input should be routed -+ * @offset: register offset address -+ */ -+struct cb_line { -+ const char *cb_name; -+ const char *dev_name; -+ unsigned cb_no; -+ unsigned int_no; -+ unsigned offset; -+}; -+ -+struct cb_entry { -+ struct cb_line line; -+ struct list_head cb_list; -+}; -+ -+int crossbar_map(struct device_node *cbdev_node); -+int crossbar_unmap(struct device_node *cbdev_node, unsigned index); ---- a/include/linux/i2c/twl.h -+++ b/include/linux/i2c/twl.h -@@ -26,6 +26,7 @@ - #define __TWL_H_ - - #include <linux/types.h> -+#include <linux/phy/phy.h> - #include <linux/input/matrix_keypad.h> - - /* -@@ -615,6 +616,7 @@ enum twl4030_usb_mode { - struct twl4030_usb_data { - enum twl4030_usb_mode usb_mode; - unsigned long features; -+ struct phy_init_data *init_data; - - int (*phy_init)(struct device *dev); - int (*phy_exit)(struct device *dev); ---- a/include/linux/input/pixcir_ts.h -+++ b/include/linux/input/pixcir_ts.h -@@ -1,10 +1,63 @@ - #ifndef _PIXCIR_I2C_TS_H - #define _PIXCIR_I2C_TS_H - -+/* -+ * Register map -+ */ -+#define PIXCIR_REG_POWER_MODE 51 -+#define PIXCIR_REG_INT_MODE 52 -+ -+/* -+ * Power modes: -+ * active: max scan speed -+ * idle: lower scan speed with automatic transition to active on touch -+ * halt: datasheet says sleep but this is more like halt as the chip -+ * clocks are cut and it can only be brought out of this mode -+ * using the RESET pin. -+ */ -+enum pixcir_power_mode { -+ PIXCIR_POWER_ACTIVE, -+ PIXCIR_POWER_IDLE, -+ PIXCIR_POWER_HALT, -+}; -+ -+#define PIXCIR_POWER_MODE_MASK 0x03 -+#define PIXCIR_POWER_ALLOW_IDLE (1UL << 2) -+ -+/* -+ * Interrupt modes: -+ * periodical: interrupt is asserted periodicaly -+ * diff coordinates: interrupt is asserted when coordinates change -+ * level on touch: interrupt level asserted during touch -+ * pulse on touch: interrupt pulse asserted druing touch -+ * -+ */ -+enum pixcir_int_mode { -+ PIXCIR_INT_PERIODICAL, -+ PIXCIR_INT_DIFF_COORD, -+ PIXCIR_INT_LEVEL_TOUCH, -+ PIXCIR_INT_PULSE_TOUCH, -+}; -+ -+#define PIXCIR_INT_MODE_MASK 0x03 -+#define PIXCIR_INT_ENABLE (1UL << 3) -+#define PIXCIR_INT_POL_HIGH (1UL << 2) -+ -+/** -+ * struct pixcir_irc_chip_data - chip related data -+ * @num_report_ids: Max number of finger ids reported simultaneously. -+ * if 0 it means chip doesn't support finger id reporting -+ * and driver will resort to Type A Multi-Touch reporting. -+ */ -+struct pixcir_i2c_chip_data { -+ u8 num_report_ids; -+}; -+ - struct pixcir_ts_platform_data { -- int (*attb_read_val)(void); -- int x_max; -- int y_max; -+ unsigned int x_size; /* X axis resolution */ -+ unsigned int y_size; /* Y axis resolution */ -+ int gpio_attb; /* GPIO connected to ATTB line */ -+ struct pixcir_i2c_chip_data chip; - }; - - #endif ---- /dev/null -+++ b/include/linux/mfd/tps65218.h -@@ -0,0 +1,288 @@ -+/* -+ * linux/mfd/tps65218.h -+ * -+ * Functions to access TPS65219 power management chip. -+ * -+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * 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. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether expressed or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License version 2 for more details. -+ */ -+ -+#ifndef __LINUX_MFD_TPS65218_H -+#define __LINUX_MFD_TPS65218_H -+ -+#include <linux/i2c.h> -+#include <linux/regulator/driver.h> -+#include <linux/regulator/machine.h> -+#include <linux/bitops.h> -+ -+/* TPS chip id list */ -+#define TPS65218 0xF0 -+ -+/* I2C ID for TPS65218 part */ -+#define TPS65218_I2C_ID 0x24 -+ -+/* All register addresses */ -+#define TPS65218_REG_CHIPID 0x00 -+#define TPS65218_REG_INT1 0x01 -+#define TPS65218_REG_INT2 0x02 -+#define TPS65218_REG_INT_MASK1 0x03 -+#define TPS65218_REG_INT_MASK2 0x04 -+#define TPS65218_REG_STATUS 0x05 -+#define TPS65218_REG_CONTROL 0x06 -+#define TPS65218_REG_FLAG 0x07 -+ -+#define TPS65218_REG_PASSWORD 0x10 -+#define TPS65218_REG_ENABLE1 0x11 -+#define TPS65218_REG_ENABLE2 0x12 -+#define TPS65218_REG_CONFIG1 0x13 -+#define TPS65218_REG_CONFIG2 0x14 -+#define TPS65218_REG_CONFIG3 0x15 -+#define TPS65218_REG_CONTROL_DCDC1 0x16 -+#define TPS65218_REG_CONTROL_DCDC2 0x17 -+#define TPS65218_REG_CONTROL_DCDC3 0x18 -+#define TPS65218_REG_CONTROL_DCDC4 0x19 -+#define TPS65218_REG_CONTRL_SLEW_RATE 0x1A -+#define TPS65218_REG_CONTROL_LDO1 0x1B -+#define TPS65218_REG_SEQ1 0x20 -+#define TPS65218_REG_SEQ2 0x21 -+#define TPS65218_REG_SEQ3 0x22 -+#define TPS65218_REG_SEQ4 0x23 -+#define TPS65218_REG_SEQ5 0x24 -+#define TPS65218_REG_SEQ6 0x25 -+#define TPS65218_REG_SEQ7 0x26 -+ -+/* Register field definitions */ -+#define TPS65218_CHIPID_CHIP_MASK 0xF8 -+#define TPS65218_CHIPID_REV_MASK 0x07 -+ -+#define TPS65218_INT1_VPRG BIT(5) -+#define TPS65218_INT1_AC BIT(4) -+#define TPS65218_INT1_PB BIT(3) -+#define TPS65218_INT1_HOT BIT(2) -+#define TPS65218_INT1_CC_AQC BIT(1) -+#define TPS65218_INT1_PRGC BIT(0) -+ -+#define TPS65218_INT2_LS3_F BIT(5) -+#define TPS65218_INT2_LS2_F BIT(4) -+#define TPS65218_INT2_LS1_F BIT(3) -+#define TPS65218_INT2_LS3_I BIT(2) -+#define TPS65218_INT2_LS2_I BIT(1) -+#define TPS65218_INT2_LS1_I BIT(0) -+ -+#define TPS65218_INT_MASK1_VPRG BIT(5) -+#define TPS65218_INT_MASK1_AC BIT(4) -+#define TPS65218_INT_MASK1_PB BIT(3) -+#define TPS65218_INT_MASK1_HOT BIT(2) -+#define TPS65218_INT_MASK1_CC_AQC BIT(1) -+#define TPS65218_INT_MASK1_PRGC BIT(0) -+ -+#define TPS65218_INT_MASK2_LS3_F BIT(5) -+#define TPS65218_INT_MASK2_LS2_F BIT(4) -+#define TPS65218_INT_MASK2_LS1_F BIT(3) -+#define TPS65218_INT_MASK2_LS3_I BIT(2) -+#define TPS65218_INT_MASK2_LS2_I BIT(1) -+#define TPS65218_INT_MASK2_LS1_I BIT(0) -+ -+#define TPS65218_STATUS_FSEAL BIT(7) -+#define TPS65218_STATUS_EE BIT(6) -+#define TPS65218_STATUS_AC_STATE BIT(5) -+#define TPS65218_STATUS_PB_STATE BIT(4) -+#define TPS65218_STATUS_STATE_MASK 0xC -+#define TPS65218_STATUS_CC_STAT 0x3 -+ -+#define TPS65218_CONTROL_OFFNPFO BIT(1) -+#define TPS65218_CONTROL_CC_AQ BIT(0) -+ -+#define TPS65218_FLAG_GPO3_FLG BIT(7) -+#define TPS65218_FLAG_GPO2_FLG BIT(6) -+#define TPS65218_FLAG_GPO1_FLG BIT(5) -+#define TPS65218_FLAG_LDO1_FLG BIT(4) -+#define TPS65218_FLAG_DC4_FLG BIT(3) -+#define TPS65218_FLAG_DC3_FLG BIT(2) -+#define TPS65218_FLAG_DC2_FLG BIT(1) -+#define TPS65218_FLAG_DC1_FLG BIT(0) -+ -+#define TPS65218_ENABLE1_DC6_EN BIT(5) -+#define TPS65218_ENABLE1_DC5_EN BIT(4) -+#define TPS65218_ENABLE1_DC4_EN BIT(3) -+#define TPS65218_ENABLE1_DC3_EN BIT(2) -+#define TPS65218_ENABLE1_DC2_EN BIT(1) -+#define TPS65218_ENABLE1_DC1_EN BIT(0) -+ -+#define TPS65218_ENABLE2_GPIO3 BIT(6) -+#define TPS65218_ENABLE2_GPIO2 BIT(5) -+#define TPS65218_ENABLE2_GPIO1 BIT(4) -+#define TPS65218_ENABLE2_LS3_EN BIT(3) -+#define TPS65218_ENABLE2_LS2_EN BIT(2) -+#define TPS65218_ENABLE2_LS1_EN BIT(1) -+#define TPS65218_ENABLE2_LDO1_EN BIT(0) -+ -+ -+#define TPS65218_CONFIG1_TRST BIT(7) -+#define TPS65218_CONFIG1_GPO2_BUF BIT(6) -+#define TPS65218_CONFIG1_IO1_SEL BIT(5) -+#define TPS65218_CONFIG1_PGDLY_MASK 0x18 -+#define TPS65218_CONFIG1_STRICT BIT(2) -+#define TPS65218_CONFIG1_UVLO_MASK 0x3 -+ -+#define TPS65218_CONFIG2_DC12_RST BIT(7) -+#define TPS65218_CONFIG2_UVLOHYS BIT(6) -+#define TPS65218_CONFIG2_LS3ILIM_MASK 0xC -+#define TPS65218_CONFIG2_LS2ILIM_MASK 0x3 -+ -+#define TPS65218_CONFIG3_LS3NPFO BIT(5) -+#define TPS65218_CONFIG3_LS2NPFO BIT(4) -+#define TPS65218_CONFIG3_LS1NPFO BIT(3) -+#define TPS65218_CONFIG3_LS3DCHRG BIT(2) -+#define TPS65218_CONFIG3_LS2DCHRG BIT(1) -+#define TPS65218_CONFIG3_LS1DCHRG BIT(0) -+ -+#define TPS65218_CONTROL_DCDC1_PFM BIT(7) -+#define TPS65218_CONTROL_DCDC1_MASK 0x7F -+ -+#define TPS65218_CONTROL_DCDC2_PFM BIT(7) -+#define TPS65218_CONTROL_DCDC2_MASK 0x3F -+ -+#define TPS65218_CONTROL_DCDC3_PFM BIT(7) -+#define TPS65218_CONTROL_DCDC3_MASK 0x3F -+ -+#define TPS65218_CONTROL_DCDC4_PFM BIT(7) -+#define TPS65218_CONTROL_DCDC4_MASK 0x3F -+ -+#define TPS65218_SLEW_RATE_GO BIT(7) -+#define TPS65218_SLEW_RATE_GODSBL BIT(6) -+#define TPS65218_SLEW_RATE_SLEW_MASK 0x7 -+ -+#define TPS65218_CONTROL_LDO1_MASK 0x3F -+ -+#define TPS65218_SEQ1_DLY8 BIT(7) -+#define TPS65218_SEQ1_DLY7 BIT(6) -+#define TPS65218_SEQ1_DLY6 BIT(5) -+#define TPS65218_SEQ1_DLY5 BIT(4) -+#define TPS65218_SEQ1_DLY4 BIT(3) -+#define TPS65218_SEQ1_DLY3 BIT(2) -+#define TPS65218_SEQ1_DLY2 BIT(1) -+#define TPS65218_SEQ1_DLY1 BIT(0) -+ -+#define TPS65218_SEQ2_DLYFCTR BIT(7) -+#define TPS65218_SEQ2_DLY9 BIT(0) -+ -+#define TPS65218_SEQ3_DC2_SEQ_MASK 0xF0 -+#define TPS65218_SEQ3_DC1_SEQ_MASK 0xF -+ -+#define TPS65218_SEQ4_DC4_SEQ_MASK 0xF0 -+#define TPS65218_SEQ4_DC3_SEQ_MASK 0xF -+ -+#define TPS65218_SEQ5_DC6_SEQ_MASK 0xF0 -+#define TPS65218_SEQ5_DC5_SEQ_MASK 0xF -+ -+#define TPS65218_SEQ6_LS1_SEQ_MASK 0xF0 -+#define TPS65218_SEQ6_LDO1_SEQ_MASK 0xF -+ -+#define TPS65218_SEQ7_GPO3_SEQ_MASK 0xF0 -+#define TPS65218_SEQ7_GPO1_SEQ_MASK 0xF -+#define TPS65218_PROTECT_NONE 0 -+#define TPS65218_PROTECT_L1 1 -+ -+enum tps65218_regulator_id { -+ /* DCDC's */ -+ TPS65218_DCDC_1, -+ TPS65218_DCDC_2, -+ TPS65218_DCDC_3, -+ TPS65218_DCDC_4, -+ TPS65218_DCDC_5, -+ TPS65218_DCDC_6, -+ /* LDOs */ -+ TPS65218_LDO_1, -+}; -+ -+#define TPS65218_MAX_REG_ID TPS65218_LDO_1 -+ -+/* Number of step-down converters available */ -+#define TPS65218_NUM_DCDC 6 -+/* Number of LDO voltage regulators available */ -+#define TPS65218_NUM_LDO 1 -+/* Number of total regulators available */ -+#define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO) -+ -+/* Define the TPS65218 IRQ numbers */ -+enum tps65218_irqs { -+ /* INT1 registers */ -+ TPS65218_PRGC_IRQ, -+ TPS65218_CC_AQC_IRQ, -+ TPS65218_HOT_IRQ, -+ TPS65218_PB_IRQ, -+ TPS65218_AC_IRQ, -+ TPS65218_VPRG_IRQ, -+ TPS65218_INVALID1_IRQ, -+ TPS65218_INVALID2_IRQ, -+ /* INT2 registers */ -+ TPS65218_LS1_I_IRQ, -+ TPS65218_LS2_I_IRQ, -+ TPS65218_LS3_I_IRQ, -+ TPS65218_LS1_F_IRQ, -+ TPS65218_LS2_F_IRQ, -+ TPS65218_LS3_F_IRQ, -+ TPS65218_INVALID3_IRQ, -+ TPS65218_INVALID4_IRQ, -+}; -+ -+/** -+ * struct tps_info - packages regulator constraints -+ * @id: Id of the regulator -+ * @name: Voltage regulator name -+ * @min_uV: minimum micro volts -+ * @max_uV: minimum micro volts -+ * @vsel_to_uv: Function pointer to get voltage from selector -+ * @uv_to_vsel: Function pointer to get selector from voltage -+ * -+ * This data is used to check the regualtor voltage limits while setting. -+ */ -+struct tps_info { -+ int id; -+ const char *name; -+ int min_uV; -+ int max_uV; -+ int (*vsel_to_uv)(unsigned int vsel); -+ int (*uv_to_vsel)(int uV, unsigned int *vsel); -+}; -+ -+/** -+ * struct tps65218 - tps65218 sub-driver chip access routines -+ * -+ * Device data may be used to access the TPS65218 chip -+ */ -+ -+struct tps65218 { -+ struct device *dev; -+ unsigned int id; -+ -+ struct mutex tps_lock; /* lock guarding the data structure */ -+ /* IRQ Data */ -+ int irq; -+ u32 irq_mask; -+ struct regmap_irq_chip_data *irq_data; -+ struct regulator_desc desc[TPS65218_NUM_REGULATOR]; -+ struct regulator_dev *rdev[TPS65218_NUM_REGULATOR]; -+ struct tps_info *info[TPS65218_NUM_REGULATOR]; -+ struct regmap *regmap; -+}; -+ -+int tps65218_reg_read(struct tps65218 *tps, unsigned int reg, -+ unsigned int *val); -+int tps65218_reg_write(struct tps65218 *tps, unsigned int reg, -+ unsigned int val, unsigned int level); -+int tps65218_set_bits(struct tps65218 *tps, unsigned int reg, -+ unsigned int mask, unsigned int val, unsigned int level); -+int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, -+ unsigned int mask, unsigned int level); -+ -+#endif /* __LINUX_MFD_TPS65218_H */ ---- a/include/linux/mfd/twl6040.h -+++ b/include/linux/mfd/twl6040.h -@@ -28,6 +28,7 @@ - #include <linux/interrupt.h> - #include <linux/mfd/core.h> - #include <linux/regulator/consumer.h> -+#include <linux/clk.h> - - #define TWL6040_REG_ASICID 0x01 - #define TWL6040_REG_ASICREV 0x02 -@@ -222,6 +223,7 @@ struct twl6040 { - struct regmap *regmap; - struct regmap_irq_chip_data *irq_data; - struct regulator_bulk_data supplies[2]; /* supplies for vio, v2v1 */ -+ struct clk *clk32k; - struct mutex mutex; - struct mutex irq_mutex; - struct mfd_cell cells[TWL6040_CELLS]; ---- a/include/linux/omap-mailbox.h -+++ b/include/linux/omap-mailbox.h -@@ -9,20 +9,27 @@ - #ifndef OMAP_MAILBOX_H - #define OMAP_MAILBOX_H - -+/* forward declaration for clients */ - typedef u32 mbox_msg_t; - struct omap_mbox; - -+/* interrupt direction identifiers */ - typedef int __bitwise omap_mbox_irq_t; - #define IRQ_TX ((__force omap_mbox_irq_t) 1) - #define IRQ_RX ((__force omap_mbox_irq_t) 2) - -+/* client api for message transmission */ - int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); - -+/* client api for acquiring and releasing a mailbox */ - struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); - void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); - -+/* client api for saving and restoring context */ - void omap_mbox_save_ctx(struct omap_mbox *mbox); - void omap_mbox_restore_ctx(struct omap_mbox *mbox); -+ -+/* client api for manipulating mailbox interrupts */ - void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); - void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); - ---- /dev/null -+++ b/include/linux/phy/omap_control_phy.h -@@ -0,0 +1,89 @@ -+/* -+ * omap_control_phy.h - Header file for the PHY part of control module. -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __OMAP_CONTROL_PHY_H__ -+#define __OMAP_CONTROL_PHY_H__ -+ -+enum omap_control_phy_type { -+ OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */ -+ OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ -+ OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */ -+ OMAP_CTRL_TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */ -+ OMAP_CTRL_TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ -+}; -+ -+struct omap_control_phy { -+ struct device *dev; -+ -+ u32 __iomem *otghs_control; -+ u32 __iomem *power; -+ u32 __iomem *power_aux; -+ -+ struct clk *sys_clk; -+ -+ enum omap_control_phy_type type; -+}; -+ -+enum omap_control_usb_mode { -+ USB_MODE_UNDEFINED = 0, -+ USB_MODE_HOST, -+ USB_MODE_DEVICE, -+ USB_MODE_DISCONNECT, -+}; -+ -+#define OMAP_CTRL_DEV_PHY_PD BIT(0) -+ -+#define OMAP_CTRL_DEV_AVALID BIT(0) -+#define OMAP_CTRL_DEV_BVALID BIT(1) -+#define OMAP_CTRL_DEV_VBUSVALID BIT(2) -+#define OMAP_CTRL_DEV_SESSEND BIT(3) -+#define OMAP_CTRL_DEV_IDDIG BIT(4) -+ -+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 -+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE -+ -+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 -+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 -+ -+#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 -+#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 -+ -+#define OMAP_CTRL_USB2_PHY_PD BIT(28) -+ -+#define AM437X_CTRL_USB2_PHY_PD BIT(0) -+#define AM437X_CTRL_USB2_OTG_PD BIT(1) -+#define AM437X_CTRL_USB2_OTGVDET_EN BIT(19) -+#define AM437X_CTRL_USB2_OTGSESSEND_EN BIT(20) -+ -+#if IS_ENABLED(CONFIG_OMAP_CONTROL_PHY) -+extern void omap_control_phy_power(struct device *dev, int on); -+extern void omap_control_usb_set_mode(struct device *dev, -+ enum omap_control_usb_mode mode); -+#else -+ -+static inline void omap_control_phy_power(struct device *dev, int on) -+{ -+} -+ -+static inline void omap_control_usb_set_mode(struct device *dev, -+ enum omap_control_usb_mode mode) -+{ -+} -+#endif -+ -+#endif /* __OMAP_CONTROL_PHY_H__ */ ---- /dev/null -+++ b/include/linux/phy/omap_pipe3.h -@@ -0,0 +1,59 @@ -+/* -+ * omap_pipe3.h -- omap pipe3 phy header file -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __DRIVERS_OMAP_PIPE3_H -+#define __DRIVERS_OMAP_PIPE3_H -+ -+#include <linux/io.h> -+ -+struct pipe3_dpll_params { -+ u16 m; -+ u8 n; -+ u8 freq:3; -+ u8 sd; -+ u32 mf; -+}; -+ -+struct pipe3_dpll_map { -+ unsigned long rate; -+ struct pipe3_dpll_params params; -+}; -+ -+struct omap_pipe3 { -+ void __iomem *pll_ctrl_base; -+ struct device *dev; -+ struct device *control_dev; -+ struct clk *wkupclk; -+ struct clk *sys_clk; -+ struct clk *optclk; -+ struct clk *optclk2; -+ struct pipe3_dpll_map *dpll_map; -+}; -+ -+static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset) -+{ -+ return __raw_readl(addr + offset); -+} -+ -+static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset, -+ u32 data) -+{ -+ __raw_writel(data, addr + offset); -+} -+ -+#endif /* __DRIVERS_OMAP_PIPE3_H */ ---- /dev/null -+++ b/include/linux/phy/omap_usb.h -@@ -0,0 +1,74 @@ -+/* -+ * omap_usb.h -- omap usb2 phy header file -+ * -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com -+ * 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. -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __DRIVERS_OMAP_USB2_H -+#define __DRIVERS_OMAP_USB2_H -+ -+#include <linux/io.h> -+#include <linux/usb/otg.h> -+ -+struct usb_dpll_params { -+ u16 m; -+ u8 n; -+ u8 freq:3; -+ u8 sd; -+ u32 mf; -+}; -+ -+struct omap_usb { -+ struct usb_phy phy; -+ struct phy_companion *comparator; -+ struct device *dev; -+ struct device *control_dev; -+ struct clk *wkupclk; -+ struct clk *optclk; -+}; -+ -+struct usb_phy_data { -+ const char *label; -+ u32 flags; -+}; -+ -+enum usb_phy_data_flags { -+ OMAP_USB2_HAS_START_SRP = 1, -+ OMAP_USB2_HAS_SET_VBUS, -+}; -+ -+#define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) -+ -+#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) -+extern int omap_usb2_set_comparator(struct phy_companion *comparator); -+#else -+static inline int omap_usb2_set_comparator(struct phy_companion *comparator) -+{ -+ return -ENODEV; -+} -+#endif -+ -+static inline u32 omap_usb_readl(void __iomem *addr, unsigned offset) -+{ -+ return __raw_readl(addr + offset); -+} -+ -+static inline void omap_usb_writel(void __iomem *addr, unsigned offset, -+ u32 data) -+{ -+ __raw_writel(data, addr + offset); -+} -+ -+#endif /* __DRIVERS_OMAP_USB_H */ ---- /dev/null -+++ b/include/linux/phy/phy.h -@@ -0,0 +1,270 @@ -+/* -+ * phy.h -- generic phy header file -+ * -+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Author: Kishon Vijay Abraham I <kishon@ti.com> -+ * -+ * 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. -+ */ -+ -+#ifndef __DRIVERS_PHY_H -+#define __DRIVERS_PHY_H -+ -+#include <linux/err.h> -+#include <linux/of.h> -+#include <linux/device.h> -+#include <linux/pm_runtime.h> -+ -+struct phy; -+ -+/** -+ * struct phy_ops - set of function pointers for performing phy operations -+ * @init: operation to be performed for initializing phy -+ * @exit: operation to be performed while exiting -+ * @power_on: powering on the phy -+ * @power_off: powering off the phy -+ * @owner: the module owner containing the ops -+ */ -+struct phy_ops { -+ int (*init)(struct phy *phy); -+ int (*exit)(struct phy *phy); -+ int (*power_on)(struct phy *phy); -+ int (*power_off)(struct phy *phy); -+ struct module *owner; -+}; -+ -+/** -+ * struct phy - represents the phy device -+ * @dev: phy device -+ * @id: id of the phy device -+ * @ops: function pointers for performing phy operations -+ * @init_data: list of PHY consumers (non-dt only) -+ * @mutex: mutex to protect phy_ops -+ * @init_count: used to protect when the PHY is used by multiple consumers -+ * @power_count: used to protect when the PHY is used by multiple consumers -+ */ -+struct phy { -+ struct device dev; -+ int id; -+ const struct phy_ops *ops; -+ struct phy_init_data *init_data; -+ struct mutex mutex; -+ int init_count; -+ int power_count; -+}; -+ -+/** -+ * struct phy_provider - represents the phy provider -+ * @dev: phy provider device -+ * @owner: the module owner having of_xlate -+ * @of_xlate: function pointer to obtain phy instance from phy pointer -+ * @list: to maintain a linked list of PHY providers -+ */ -+struct phy_provider { -+ struct device *dev; -+ struct module *owner; -+ struct list_head list; -+ struct phy * (*of_xlate)(struct device *dev, -+ struct of_phandle_args *args); -+}; -+ -+/** -+ * struct phy_consumer - represents the phy consumer -+ * @dev_name: the device name of the controller that will use this PHY device -+ * @port: name given to the consumer port -+ */ -+struct phy_consumer { -+ const char *dev_name; -+ const char *port; -+}; -+ -+/** -+ * struct phy_init_data - contains the list of PHY consumers -+ * @num_consumers: number of consumers for this PHY device -+ * @consumers: list of PHY consumers -+ */ -+struct phy_init_data { -+ unsigned int num_consumers; -+ struct phy_consumer *consumers; -+}; -+ -+#define PHY_CONSUMER(_dev_name, _port) \ -+{ \ -+ .dev_name = _dev_name, \ -+ .port = _port, \ -+} -+ -+#define to_phy(dev) (container_of((dev), struct phy, dev)) -+ -+#define of_phy_provider_register(dev, xlate) \ -+ __of_phy_provider_register((dev), THIS_MODULE, (xlate)) -+ -+#define devm_of_phy_provider_register(dev, xlate) \ -+ __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate)) -+ -+static inline void phy_set_drvdata(struct phy *phy, void *data) -+{ -+ dev_set_drvdata(&phy->dev, data); -+} -+ -+static inline void *phy_get_drvdata(struct phy *phy) -+{ -+ return dev_get_drvdata(&phy->dev); -+} -+ -+#if IS_ENABLED(CONFIG_GENERIC_PHY) -+extern int phy_pm_runtime_get(struct phy *phy); -+extern int phy_pm_runtime_get_sync(struct phy *phy); -+extern int phy_pm_runtime_put(struct phy *phy); -+extern int phy_pm_runtime_put_sync(struct phy *phy); -+extern void phy_pm_runtime_allow(struct phy *phy); -+extern void phy_pm_runtime_forbid(struct phy *phy); -+extern int phy_init(struct phy *phy); -+extern int phy_exit(struct phy *phy); -+extern int phy_power_on(struct phy *phy); -+extern int phy_power_off(struct phy *phy); -+extern struct phy *phy_get(struct device *dev, const char *string); -+extern struct phy *devm_phy_get(struct device *dev, const char *string); -+extern void phy_put(struct phy *phy); -+extern void devm_phy_put(struct device *dev, struct phy *phy); -+extern struct phy *of_phy_simple_xlate(struct device *dev, -+ struct of_phandle_args *args); -+extern struct phy *phy_create(struct device *dev, const struct phy_ops *ops, -+ struct phy_init_data *init_data); -+extern struct phy *devm_phy_create(struct device *dev, -+ const struct phy_ops *ops, struct phy_init_data *init_data); -+extern void phy_destroy(struct phy *phy); -+extern void devm_phy_destroy(struct device *dev, struct phy *phy); -+extern struct phy_provider *__of_phy_provider_register(struct device *dev, -+ struct module *owner, struct phy * (*of_xlate)(struct device *dev, -+ struct of_phandle_args *args)); -+extern struct phy_provider *__devm_of_phy_provider_register(struct device *dev, -+ struct module *owner, struct phy * (*of_xlate)(struct device *dev, -+ struct of_phandle_args *args)); -+extern void of_phy_provider_unregister(struct phy_provider *phy_provider); -+extern void devm_of_phy_provider_unregister(struct device *dev, -+ struct phy_provider *phy_provider); -+#else -+static inline int phy_pm_runtime_get(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline int phy_pm_runtime_get_sync(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline int phy_pm_runtime_put(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline int phy_pm_runtime_put_sync(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline void phy_pm_runtime_allow(struct phy *phy) -+{ -+ return; -+} -+ -+static inline void phy_pm_runtime_forbid(struct phy *phy) -+{ -+ return; -+} -+ -+static inline int phy_init(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline int phy_exit(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline int phy_power_on(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline int phy_power_off(struct phy *phy) -+{ -+ return -ENOSYS; -+} -+ -+static inline struct phy *phy_get(struct device *dev, const char *string) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline struct phy *devm_phy_get(struct device *dev, const char *string) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline void phy_put(struct phy *phy) -+{ -+} -+ -+static inline void devm_phy_put(struct device *dev, struct phy *phy) -+{ -+} -+ -+static inline struct phy *of_phy_simple_xlate(struct device *dev, -+ struct of_phandle_args *args) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline struct phy *phy_create(struct device *dev, -+ const struct phy_ops *ops, struct phy_init_data *init_data) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline struct phy *devm_phy_create(struct device *dev, -+ const struct phy_ops *ops, struct phy_init_data *init_data) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline void phy_destroy(struct phy *phy) -+{ -+} -+ -+static inline void devm_phy_destroy(struct device *dev, struct phy *phy) -+{ -+} -+ -+static inline struct phy_provider *__of_phy_provider_register( -+ struct device *dev, struct module *owner, struct phy * (*of_xlate)( -+ struct device *dev, struct of_phandle_args *args)) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline struct phy_provider *__devm_of_phy_provider_register(struct device -+ *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev, -+ struct of_phandle_args *args)) -+{ -+ return ERR_PTR(-ENOSYS); -+} -+ -+static inline void of_phy_provider_unregister(struct phy_provider *phy_provider) -+{ -+} -+ -+static inline void devm_of_phy_provider_unregister(struct device *dev, -+ struct phy_provider *phy_provider) -+{ -+} -+#endif -+ -+#endif /* __DRIVERS_PHY_H */ ---- a/include/linux/platform_data/davinci_asp.h -+++ b/include/linux/platform_data/davinci_asp.h -@@ -84,6 +84,8 @@ struct snd_platform_data { - u8 version; - u8 txnumevt; - u8 rxnumevt; -+ int tx_dma_channel; -+ int rx_dma_channel; - }; - - enum { ---- a/include/linux/platform_data/elm.h -+++ b/include/linux/platform_data/elm.h -@@ -21,17 +21,12 @@ - enum bch_ecc { - BCH4_ECC = 0, - BCH8_ECC, -+ BCH16_ECC - }; - - /* ELM support 8 error syndrome process */ - #define ERROR_VECTOR_MAX 8 -- --#define BCH8_ECC_OOB_BYTES 13 --#define BCH4_ECC_OOB_BYTES 7 --/* RBL requires 14 byte even though BCH8 uses only 13 byte */ --#define BCH8_SIZE (BCH8_ECC_OOB_BYTES + 1) --/* Uses 1 extra byte to handle erased pages */ --#define BCH4_SIZE (BCH4_ECC_OOB_BYTES + 1) -+#define ELM_MAX_DETECTABLE_ERRORS 16 - - /** - * struct elm_errorvec - error vector for elm -@@ -45,10 +40,11 @@ struct elm_errorvec { - bool error_reported; - bool error_uncorrectable; - int error_count; -- int error_loc[ERROR_VECTOR_MAX]; -+ int error_loc[ELM_MAX_DETECTABLE_ERRORS]; - }; - - void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc, - struct elm_errorvec *err_vec); --int elm_config(struct device *dev, enum bch_ecc bch_type); -+int elm_config(struct device *dev, struct mtd_info *mtd, -+ enum bch_ecc bch_type); - #endif /* __ELM_H */ ---- a/include/linux/platform_data/mtd-nand-omap2.h -+++ b/include/linux/platform_data/mtd-nand-omap2.h -@@ -23,13 +23,18 @@ enum nand_io { - }; - - enum omap_ecc { -- /* 1-bit ecc: stored at end of spare area */ -- OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ -- OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ -- /* 1-bit ecc: stored at beginning of spare area as romcode */ -- OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ -- OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */ -- OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */ -+ /* 1-bit ECC calculation by GPMC, Error detection by Software */ -+ OMAP_ECC_HAMMING_CODE_HW = 0, -+ /* 4-bit ECC calculation by GPMC, Error detection by Software */ -+ OMAP_ECC_BCH4_CODE_HW_DETECTION_SW, -+ /* 4-bit ECC calculation by GPMC, Error detection by ELM */ -+ OMAP_ECC_BCH4_CODE_HW, -+ /* 8-bit ECC calculation by GPMC, Error detection by Software */ -+ OMAP_ECC_BCH8_CODE_HW_DETECTION_SW, -+ /* 8-bit ECC calculation by GPMC, Error detection by ELM */ -+ OMAP_ECC_BCH8_CODE_HW, -+ /* 16-bit ECC calculation by GPMC, Error detection by ELM */ -+ OMAP_ECC_BCH16_CODE_HW, - }; - - struct gpmc_nand_regs { -@@ -49,6 +54,9 @@ struct gpmc_nand_regs { - void __iomem *gpmc_bch_result1[GPMC_BCH_NUM_REMAINDER]; - void __iomem *gpmc_bch_result2[GPMC_BCH_NUM_REMAINDER]; - void __iomem *gpmc_bch_result3[GPMC_BCH_NUM_REMAINDER]; -+ void __iomem *gpmc_bch_result4[GPMC_BCH_NUM_REMAINDER]; -+ void __iomem *gpmc_bch_result5[GPMC_BCH_NUM_REMAINDER]; -+ void __iomem *gpmc_bch_result6[GPMC_BCH_NUM_REMAINDER]; - }; - - struct omap_nand_platform_data { -@@ -63,5 +71,6 @@ struct omap_nand_platform_data { - - /* for passing the partitions */ - struct device_node *of_node; -+ struct device_node *elm_of_node; - }; - #endif ---- a/include/linux/platform_data/omap-wd-timer.h -+++ b/include/linux/platform_data/omap-wd-timer.h -@@ -16,6 +16,14 @@ - #include <linux/types.h> - - /* -+ * WATCHDOG IP Revisions -+ * WDTIMER2_IP3 - Used in OMAP3 -+ * WDTIMER2_IP4 - Used in OMAP4+ Soc's -+ */ -+#define WDTIMER2_IP3 1 -+#define WDTIMER2_IP4 2 -+ -+/* - * Standardized OMAP reset source bits - * - * This is a subset of the ones listed in arch/arm/mach-omap2/prm.h -@@ -33,6 +41,7 @@ - */ - struct omap_wd_timer_platform_data { - u32 (*read_reset_sources)(void); -+ u32 ip_rev; - }; - - #endif ---- /dev/null -+++ b/include/linux/platform_data/usb-rcar-gen2-phy.h -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2013 Renesas Solutions Corp. -+ * Copyright (C) 2013 Cogent Embedded, 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. -+ */ -+ -+#ifndef __USB_RCAR_GEN2_PHY_H -+#define __USB_RCAR_GEN2_PHY_H -+ -+#include <linux/types.h> -+ -+struct rcar_gen2_phy_platform_data { -+ /* USB channel 0 configuration */ -+ bool chan0_pci:1; /* true: PCI USB host 0, false: USBHS */ -+ /* USB channel 2 configuration */ -+ bool chan2_pci:1; /* true: PCI USB host 2, false: USBSS */ -+}; -+ -+#endif ---- a/include/linux/regulator/driver.h -+++ b/include/linux/regulator/driver.h -@@ -316,6 +316,8 @@ struct regulator_dev { - - struct blocking_notifier_head notifier; - struct mutex mutex; /* consumer lock */ -+ struct task_struct *lock_owner; -+ int lock_count; - struct module *owner; - struct device dev; - struct regulation_constraints *constraints; ---- a/include/linux/reset-controller.h -+++ b/include/linux/reset-controller.h -@@ -17,6 +17,8 @@ struct reset_control_ops { - int (*reset)(struct reset_controller_dev *rcdev, unsigned long id); - int (*assert)(struct reset_controller_dev *rcdev, unsigned long id); - int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id); -+ int (*is_reset)(struct reset_controller_dev *rcdev, unsigned long id); -+ int (*clear_reset)(struct reset_controller_dev *rcdev, unsigned long i); - }; - - struct module; ---- a/include/linux/reset.h -+++ b/include/linux/reset.h -@@ -7,6 +7,8 @@ struct reset_control; - int reset_control_reset(struct reset_control *rstc); - int reset_control_assert(struct reset_control *rstc); - int reset_control_deassert(struct reset_control *rstc); -+int reset_control_is_reset(struct reset_control *rstc); -+int reset_control_clear_reset(struct reset_control *rstc); - - struct reset_control *reset_control_get(struct device *dev, const char *id); - void reset_control_put(struct reset_control *rstc); ---- a/include/linux/spi/spi.h -+++ b/include/linux/spi/spi.h -@@ -91,6 +91,7 @@ struct spi_device { - #define SPI_TX_QUAD 0x200 /* transmit with 4 wires */ - #define SPI_RX_DUAL 0x400 /* receive with 2 wires */ - #define SPI_RX_QUAD 0x800 /* receive with 4 wires */ -+#define SPI_RX_MMAP 0x1000 /* Memory mapped Reas */ - u8 bits_per_word; - int irq; - void *controller_state; -@@ -554,6 +555,7 @@ struct spi_transfer { - u8 bits_per_word; - u16 delay_usecs; - u32 speed_hz; -+ bool memory_map; - - struct list_head transfer_list; - }; ---- /dev/null -+++ b/include/linux/ti_emif.h -@@ -0,0 +1,558 @@ -+/* -+ * Register defines for the EMIF driver -+ * -+ * Copyright (C) 2012 Texas Instruments, Inc. -+ * -+ * Benoit Cousson (b-cousson@ti.com) -+ * -+ * 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. -+ */ -+#ifndef __TI_EMIF_H -+#define __TI_EMIF_H -+ -+/* -+ * Maximum number of different frequencies supported by EMIF driver -+ * Determines the number of entries in the pointer array for register -+ * cache -+ */ -+#define EMIF_MAX_NUM_FREQUENCIES 6 -+ -+/* State of the core voltage */ -+#define DDR_VOLTAGE_STABLE 0 -+#define DDR_VOLTAGE_RAMPING 1 -+ -+/* Defines for timing De-rating */ -+#define EMIF_NORMAL_TIMINGS 0 -+#define EMIF_DERATED_TIMINGS 1 -+ -+/* Length of the forced read idle period in terms of cycles */ -+#define EMIF_READ_IDLE_LEN_VAL 5 -+ -+/* -+ * forced read idle interval to be used when voltage -+ * is changed as part of DVFS/DPS - 1ms -+ */ -+#define READ_IDLE_INTERVAL_DVFS (1*1000000) -+ -+/* -+ * Forced read idle interval to be used when voltage is stable -+ * 50us - or maximum value will do -+ */ -+#define READ_IDLE_INTERVAL_NORMAL (50*1000000) -+ -+/* DLL calibration interval when voltage is NOT stable - 1us */ -+#define DLL_CALIB_INTERVAL_DVFS (1*1000000) -+ -+#define DLL_CALIB_ACK_WAIT_VAL 5 -+ -+/* Interval between ZQCS commands - hw team recommended value */ -+#define EMIF_ZQCS_INTERVAL_US (50*1000) -+/* Enable ZQ Calibration on exiting Self-refresh */ -+#define ZQ_SFEXITEN_ENABLE 1 -+/* -+ * ZQ Calibration simultaneously on both chip-selects: -+ * Needs one calibration resistor per CS -+ */ -+#define ZQ_DUALCALEN_DISABLE 0 -+#define ZQ_DUALCALEN_ENABLE 1 -+ -+#define T_ZQCS_DEFAULT_NS 90 -+#define T_ZQCL_DEFAULT_NS 360 -+#define T_ZQINIT_DEFAULT_NS 1000 -+ -+/* DPD_EN */ -+#define DPD_DISABLE 0 -+#define DPD_ENABLE 1 -+ -+/* -+ * Default values for the low-power entry to be used if not provided by user. -+ * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512 -+ * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz -+ */ -+#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE 2048 -+#define EMIF_LP_MODE_TIMEOUT_POWER 512 -+#define EMIF_LP_MODE_FREQ_THRESHOLD 400000000 -+ -+/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */ -+#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY 0x049FF000 -+#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY 0x41 -+#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY 0x80 -+#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF -+ -+/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */ -+#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY 0x0E084200 -+#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS 10000 -+ -+/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */ -+#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS 360 -+ -+#define EMIF_T_CSTA 3 -+#define EMIF_T_PDLL_UL 128 -+ -+/* External PHY control registers magic values */ -+#define EMIF_EXT_PHY_CTRL_1_VAL 0x04020080 -+#define EMIF_EXT_PHY_CTRL_5_VAL 0x04010040 -+#define EMIF_EXT_PHY_CTRL_6_VAL 0x01004010 -+#define EMIF_EXT_PHY_CTRL_7_VAL 0x00001004 -+#define EMIF_EXT_PHY_CTRL_8_VAL 0x04010040 -+#define EMIF_EXT_PHY_CTRL_9_VAL 0x01004010 -+#define EMIF_EXT_PHY_CTRL_10_VAL 0x00001004 -+#define EMIF_EXT_PHY_CTRL_11_VAL 0x00000000 -+#define EMIF_EXT_PHY_CTRL_12_VAL 0x00000000 -+#define EMIF_EXT_PHY_CTRL_13_VAL 0x00000000 -+#define EMIF_EXT_PHY_CTRL_14_VAL 0x80080080 -+#define EMIF_EXT_PHY_CTRL_15_VAL 0x00800800 -+#define EMIF_EXT_PHY_CTRL_16_VAL 0x08102040 -+#define EMIF_EXT_PHY_CTRL_17_VAL 0x00000001 -+#define EMIF_EXT_PHY_CTRL_18_VAL 0x540A8150 -+#define EMIF_EXT_PHY_CTRL_19_VAL 0xA81502A0 -+#define EMIF_EXT_PHY_CTRL_20_VAL 0x002A0540 -+#define EMIF_EXT_PHY_CTRL_21_VAL 0x00000000 -+#define EMIF_EXT_PHY_CTRL_22_VAL 0x00000000 -+#define EMIF_EXT_PHY_CTRL_23_VAL 0x00000000 -+#define EMIF_EXT_PHY_CTRL_24_VAL 0x00000077 -+ -+#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS 1200 -+ -+/* Registers offset */ -+#define EMIF_MODULE_ID_AND_REVISION 0x0000 -+#define EMIF_STATUS 0x0004 -+#define EMIF_SDRAM_CONFIG 0x0008 -+#define EMIF_SDRAM_CONFIG_2 0x000c -+#define EMIF_SDRAM_REFRESH_CONTROL 0x0010 -+#define EMIF_SDRAM_REFRESH_CTRL_SHDW 0x0014 -+#define EMIF_SDRAM_TIMING_1 0x0018 -+#define EMIF_SDRAM_TIMING_1_SHDW 0x001c -+#define EMIF_SDRAM_TIMING_2 0x0020 -+#define EMIF_SDRAM_TIMING_2_SHDW 0x0024 -+#define EMIF_SDRAM_TIMING_3 0x0028 -+#define EMIF_SDRAM_TIMING_3_SHDW 0x002c -+#define EMIF_LPDDR2_NVM_TIMING 0x0030 -+#define EMIF_LPDDR2_NVM_TIMING_SHDW 0x0034 -+#define EMIF_POWER_MANAGEMENT_CONTROL 0x0038 -+#define EMIF_POWER_MANAGEMENT_CTRL_SHDW 0x003c -+#define EMIF_LPDDR2_MODE_REG_DATA 0x0040 -+#define EMIF_LPDDR2_MODE_REG_CONFIG 0x0050 -+#define EMIF_OCP_CONFIG 0x0054 -+#define EMIF_OCP_CONFIG_VALUE_1 0x0058 -+#define EMIF_OCP_CONFIG_VALUE_2 0x005c -+#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL 0x0060 -+#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT 0x0064 -+#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT 0x0068 -+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1 0x006c -+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2 0x0070 -+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3 0x0074 -+#define EMIF_PERFORMANCE_COUNTER_1 0x0080 -+#define EMIF_PERFORMANCE_COUNTER_2 0x0084 -+#define EMIF_PERFORMANCE_COUNTER_CONFIG 0x0088 -+#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT 0x008c -+#define EMIF_PERFORMANCE_COUNTER_TIME 0x0090 -+#define EMIF_MISC_REG 0x0094 -+#define EMIF_DLL_CALIB_CTRL 0x0098 -+#define EMIF_DLL_CALIB_CTRL_SHDW 0x009c -+#define EMIF_END_OF_INTERRUPT 0x00a0 -+#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS 0x00a4 -+#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS 0x00a8 -+#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS 0x00ac -+#define EMIF_LL_OCP_INTERRUPT_STATUS 0x00b0 -+#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET 0x00b4 -+#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET 0x00b8 -+#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR 0x00bc -+#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR 0x00c0 -+#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG 0x00c8 -+#define EMIF_TEMPERATURE_ALERT_CONFIG 0x00cc -+#define EMIF_OCP_ERROR_LOG 0x00d0 -+#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW 0x00d4 -+#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL 0x00d8 -+#define EMIF_READ_WRITE_LEVELING_CONTROL 0x00dc -+#define EMIF_DDR_PHY_CTRL_1 0x00e4 -+#define EMIF_DDR_PHY_CTRL_1_SHDW 0x00e8 -+#define EMIF_DDR_PHY_CTRL_2 0x00ec -+#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING 0x0100 -+#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104 -+#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108 -+#define EMIF_READ_WRITE_EXECUTION_THRESHOLD 0x0120 -+#define EMIF_COS_CONFIG 0x0124 -+#define EMIF_PHY_STATUS_1 0x0140 -+#define EMIF_PHY_STATUS_2 0x0144 -+#define EMIF_PHY_STATUS_3 0x0148 -+#define EMIF_PHY_STATUS_4 0x014c -+#define EMIF_PHY_STATUS_5 0x0150 -+#define EMIF_PHY_STATUS_6 0x0154 -+#define EMIF_PHY_STATUS_7 0x0158 -+#define EMIF_PHY_STATUS_8 0x015c -+#define EMIF_PHY_STATUS_9 0x0160 -+#define EMIF_PHY_STATUS_10 0x0164 -+#define EMIF_PHY_STATUS_11 0x0168 -+#define EMIF_PHY_STATUS_12 0x016c -+#define EMIF_PHY_STATUS_13 0x0170 -+#define EMIF_PHY_STATUS_14 0x0174 -+#define EMIF_PHY_STATUS_15 0x0178 -+#define EMIF_PHY_STATUS_16 0x017c -+#define EMIF_PHY_STATUS_17 0x0180 -+#define EMIF_PHY_STATUS_18 0x0184 -+#define EMIF_PHY_STATUS_19 0x0188 -+#define EMIF_PHY_STATUS_20 0x018c -+#define EMIF_PHY_STATUS_21 0x0190 -+#define EMIF_EXT_PHY_CTRL_1 0x0200 -+#define EMIF_EXT_PHY_CTRL_1_SHDW 0x0204 -+#define EMIF_EXT_PHY_CTRL_2 0x0208 -+#define EMIF_EXT_PHY_CTRL_2_SHDW 0x020c -+#define EMIF_EXT_PHY_CTRL_3 0x0210 -+#define EMIF_EXT_PHY_CTRL_3_SHDW 0x0214 -+#define EMIF_EXT_PHY_CTRL_4 0x0218 -+#define EMIF_EXT_PHY_CTRL_4_SHDW 0x021c -+#define EMIF_EXT_PHY_CTRL_5 0x0220 -+#define EMIF_EXT_PHY_CTRL_5_SHDW 0x0224 -+#define EMIF_EXT_PHY_CTRL_6 0x0228 -+#define EMIF_EXT_PHY_CTRL_6_SHDW 0x022c -+#define EMIF_EXT_PHY_CTRL_7 0x0230 -+#define EMIF_EXT_PHY_CTRL_7_SHDW 0x0234 -+#define EMIF_EXT_PHY_CTRL_8 0x0238 -+#define EMIF_EXT_PHY_CTRL_8_SHDW 0x023c -+#define EMIF_EXT_PHY_CTRL_9 0x0240 -+#define EMIF_EXT_PHY_CTRL_9_SHDW 0x0244 -+#define EMIF_EXT_PHY_CTRL_10 0x0248 -+#define EMIF_EXT_PHY_CTRL_10_SHDW 0x024c -+#define EMIF_EXT_PHY_CTRL_11 0x0250 -+#define EMIF_EXT_PHY_CTRL_11_SHDW 0x0254 -+#define EMIF_EXT_PHY_CTRL_12 0x0258 -+#define EMIF_EXT_PHY_CTRL_12_SHDW 0x025c -+#define EMIF_EXT_PHY_CTRL_13 0x0260 -+#define EMIF_EXT_PHY_CTRL_13_SHDW 0x0264 -+#define EMIF_EXT_PHY_CTRL_14 0x0268 -+#define EMIF_EXT_PHY_CTRL_14_SHDW 0x026c -+#define EMIF_EXT_PHY_CTRL_15 0x0270 -+#define EMIF_EXT_PHY_CTRL_15_SHDW 0x0274 -+#define EMIF_EXT_PHY_CTRL_16 0x0278 -+#define EMIF_EXT_PHY_CTRL_16_SHDW 0x027c -+#define EMIF_EXT_PHY_CTRL_17 0x0280 -+#define EMIF_EXT_PHY_CTRL_17_SHDW 0x0284 -+#define EMIF_EXT_PHY_CTRL_18 0x0288 -+#define EMIF_EXT_PHY_CTRL_18_SHDW 0x028c -+#define EMIF_EXT_PHY_CTRL_19 0x0290 -+#define EMIF_EXT_PHY_CTRL_19_SHDW 0x0294 -+#define EMIF_EXT_PHY_CTRL_20 0x0298 -+#define EMIF_EXT_PHY_CTRL_20_SHDW 0x029c -+#define EMIF_EXT_PHY_CTRL_21 0x02a0 -+#define EMIF_EXT_PHY_CTRL_21_SHDW 0x02a4 -+#define EMIF_EXT_PHY_CTRL_22 0x02a8 -+#define EMIF_EXT_PHY_CTRL_22_SHDW 0x02ac -+#define EMIF_EXT_PHY_CTRL_23 0x02b0 -+#define EMIF_EXT_PHY_CTRL_23_SHDW 0x02b4 -+#define EMIF_EXT_PHY_CTRL_24 0x02b8 -+#define EMIF_EXT_PHY_CTRL_24_SHDW 0x02bc -+#define EMIF_EXT_PHY_CTRL_25 0x02c0 -+#define EMIF_EXT_PHY_CTRL_25_SHDW 0x02c4 -+#define EMIF_EXT_PHY_CTRL_26 0x02c8 -+#define EMIF_EXT_PHY_CTRL_26_SHDW 0x02cc -+#define EMIF_EXT_PHY_CTRL_27 0x02d0 -+#define EMIF_EXT_PHY_CTRL_27_SHDW 0x02d4 -+#define EMIF_EXT_PHY_CTRL_28 0x02d8 -+#define EMIF_EXT_PHY_CTRL_28_SHDW 0x02dc -+#define EMIF_EXT_PHY_CTRL_29 0x02e0 -+#define EMIF_EXT_PHY_CTRL_29_SHDW 0x02e4 -+#define EMIF_EXT_PHY_CTRL_30 0x02e8 -+#define EMIF_EXT_PHY_CTRL_30_SHDW 0x02ec -+ -+/* Registers shifts and masks */ -+ -+/* EMIF_MODULE_ID_AND_REVISION */ -+#define SCHEME_SHIFT 30 -+#define SCHEME_MASK (0x3 << 30) -+#define MODULE_ID_SHIFT 16 -+#define MODULE_ID_MASK (0xfff << 16) -+#define RTL_VERSION_SHIFT 11 -+#define RTL_VERSION_MASK (0x1f << 11) -+#define MAJOR_REVISION_SHIFT 8 -+#define MAJOR_REVISION_MASK (0x7 << 8) -+#define MINOR_REVISION_SHIFT 0 -+#define MINOR_REVISION_MASK (0x3f << 0) -+ -+/* STATUS */ -+#define BE_SHIFT 31 -+#define BE_MASK (1 << 31) -+#define DUAL_CLK_MODE_SHIFT 30 -+#define DUAL_CLK_MODE_MASK (1 << 30) -+#define FAST_INIT_SHIFT 29 -+#define FAST_INIT_MASK (1 << 29) -+#define RDLVLGATETO_SHIFT 6 -+#define RDLVLGATETO_MASK (1 << 6) -+#define RDLVLTO_SHIFT 5 -+#define RDLVLTO_MASK (1 << 5) -+#define WRLVLTO_SHIFT 4 -+#define WRLVLTO_MASK (1 << 4) -+#define PHY_DLL_READY_SHIFT 2 -+#define PHY_DLL_READY_MASK (1 << 2) -+ -+/* SDRAM_CONFIG */ -+#define SDRAM_TYPE_SHIFT 29 -+#define SDRAM_TYPE_MASK (0x7 << 29) -+#define IBANK_POS_SHIFT 27 -+#define IBANK_POS_MASK (0x3 << 27) -+#define DDR_TERM_SHIFT 24 -+#define DDR_TERM_MASK (0x7 << 24) -+#define DDR2_DDQS_SHIFT 23 -+#define DDR2_DDQS_MASK (1 << 23) -+#define DYN_ODT_SHIFT 21 -+#define DYN_ODT_MASK (0x3 << 21) -+#define DDR_DISABLE_DLL_SHIFT 20 -+#define DDR_DISABLE_DLL_MASK (1 << 20) -+#define SDRAM_DRIVE_SHIFT 18 -+#define SDRAM_DRIVE_MASK (0x3 << 18) -+#define CWL_SHIFT 16 -+#define CWL_MASK (0x3 << 16) -+#define NARROW_MODE_SHIFT 14 -+#define NARROW_MODE_MASK (0x3 << 14) -+#define CL_SHIFT 10 -+#define CL_MASK (0xf << 10) -+#define ROWSIZE_SHIFT 7 -+#define ROWSIZE_MASK (0x7 << 7) -+#define IBANK_SHIFT 4 -+#define IBANK_MASK (0x7 << 4) -+#define EBANK_SHIFT 3 -+#define EBANK_MASK (1 << 3) -+#define PAGESIZE_SHIFT 0 -+#define PAGESIZE_MASK (0x7 << 0) -+ -+/* SDRAM_CONFIG_2 */ -+#define CS1NVMEN_SHIFT 30 -+#define CS1NVMEN_MASK (1 << 30) -+#define EBANK_POS_SHIFT 27 -+#define EBANK_POS_MASK (1 << 27) -+#define RDBNUM_SHIFT 4 -+#define RDBNUM_MASK (0x3 << 4) -+#define RDBSIZE_SHIFT 0 -+#define RDBSIZE_MASK (0x7 << 0) -+ -+/* SDRAM_REFRESH_CONTROL */ -+#define INITREF_DIS_SHIFT 31 -+#define INITREF_DIS_MASK (1 << 31) -+#define SRT_SHIFT 29 -+#define SRT_MASK (1 << 29) -+#define ASR_SHIFT 28 -+#define ASR_MASK (1 << 28) -+#define PASR_SHIFT 24 -+#define PASR_MASK (0x7 << 24) -+#define REFRESH_RATE_SHIFT 0 -+#define REFRESH_RATE_MASK (0xffff << 0) -+ -+/* SDRAM_TIMING_1 */ -+#define T_RTW_SHIFT 29 -+#define T_RTW_MASK (0x7 << 29) -+#define T_RP_SHIFT 25 -+#define T_RP_MASK (0xf << 25) -+#define T_RCD_SHIFT 21 -+#define T_RCD_MASK (0xf << 21) -+#define T_WR_SHIFT 17 -+#define T_WR_MASK (0xf << 17) -+#define T_RAS_SHIFT 12 -+#define T_RAS_MASK (0x1f << 12) -+#define T_RC_SHIFT 6 -+#define T_RC_MASK (0x3f << 6) -+#define T_RRD_SHIFT 3 -+#define T_RRD_MASK (0x7 << 3) -+#define T_WTR_SHIFT 0 -+#define T_WTR_MASK (0x7 << 0) -+ -+/* SDRAM_TIMING_2 */ -+#define T_XP_SHIFT 28 -+#define T_XP_MASK (0x7 << 28) -+#define T_ODT_SHIFT 25 -+#define T_ODT_MASK (0x7 << 25) -+#define T_XSNR_SHIFT 16 -+#define T_XSNR_MASK (0x1ff << 16) -+#define T_XSRD_SHIFT 6 -+#define T_XSRD_MASK (0x3ff << 6) -+#define T_RTP_SHIFT 3 -+#define T_RTP_MASK (0x7 << 3) -+#define T_CKE_SHIFT 0 -+#define T_CKE_MASK (0x7 << 0) -+ -+/* SDRAM_TIMING_3 */ -+#define T_PDLL_UL_SHIFT 28 -+#define T_PDLL_UL_MASK (0xf << 28) -+#define T_CSTA_SHIFT 24 -+#define T_CSTA_MASK (0xf << 24) -+#define T_CKESR_SHIFT 21 -+#define T_CKESR_MASK (0x7 << 21) -+#define ZQ_ZQCS_SHIFT 15 -+#define ZQ_ZQCS_MASK (0x3f << 15) -+#define T_TDQSCKMAX_SHIFT 13 -+#define T_TDQSCKMAX_MASK (0x3 << 13) -+#define T_RFC_SHIFT 4 -+#define T_RFC_MASK (0x1ff << 4) -+#define T_RAS_MAX_SHIFT 0 -+#define T_RAS_MAX_MASK (0xf << 0) -+ -+/* POWER_MANAGEMENT_CONTROL */ -+#define PD_TIM_SHIFT 12 -+#define PD_TIM_MASK (0xf << 12) -+#define DPD_EN_SHIFT 11 -+#define DPD_EN_MASK (1 << 11) -+#define LP_MODE_SHIFT 8 -+#define LP_MODE_MASK (0x7 << 8) -+#define SR_TIM_SHIFT 4 -+#define SR_TIM_MASK (0xf << 4) -+#define CS_TIM_SHIFT 0 -+#define CS_TIM_MASK (0xf << 0) -+ -+/* LPDDR2_MODE_REG_DATA */ -+#define VALUE_0_SHIFT 0 -+#define VALUE_0_MASK (0x7f << 0) -+ -+/* LPDDR2_MODE_REG_CONFIG */ -+#define CS_SHIFT 31 -+#define CS_MASK (1 << 31) -+#define REFRESH_EN_SHIFT 30 -+#define REFRESH_EN_MASK (1 << 30) -+#define ADDRESS_SHIFT 0 -+#define ADDRESS_MASK (0xff << 0) -+ -+/* OCP_CONFIG */ -+#define SYS_THRESH_MAX_SHIFT 24 -+#define SYS_THRESH_MAX_MASK (0xf << 24) -+#define MPU_THRESH_MAX_SHIFT 20 -+#define MPU_THRESH_MAX_MASK (0xf << 20) -+#define LL_THRESH_MAX_SHIFT 16 -+#define LL_THRESH_MAX_MASK (0xf << 16) -+ -+/* PERFORMANCE_COUNTER_1 */ -+#define COUNTER1_SHIFT 0 -+#define COUNTER1_MASK (0xffffffff << 0) -+ -+/* PERFORMANCE_COUNTER_2 */ -+#define COUNTER2_SHIFT 0 -+#define COUNTER2_MASK (0xffffffff << 0) -+ -+/* PERFORMANCE_COUNTER_CONFIG */ -+#define CNTR2_MCONNID_EN_SHIFT 31 -+#define CNTR2_MCONNID_EN_MASK (1 << 31) -+#define CNTR2_REGION_EN_SHIFT 30 -+#define CNTR2_REGION_EN_MASK (1 << 30) -+#define CNTR2_CFG_SHIFT 16 -+#define CNTR2_CFG_MASK (0xf << 16) -+#define CNTR1_MCONNID_EN_SHIFT 15 -+#define CNTR1_MCONNID_EN_MASK (1 << 15) -+#define CNTR1_REGION_EN_SHIFT 14 -+#define CNTR1_REGION_EN_MASK (1 << 14) -+#define CNTR1_CFG_SHIFT 0 -+#define CNTR1_CFG_MASK (0xf << 0) -+ -+/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */ -+#define MCONNID2_SHIFT 24 -+#define MCONNID2_MASK (0xff << 24) -+#define REGION_SEL2_SHIFT 16 -+#define REGION_SEL2_MASK (0x3 << 16) -+#define MCONNID1_SHIFT 8 -+#define MCONNID1_MASK (0xff << 8) -+#define REGION_SEL1_SHIFT 0 -+#define REGION_SEL1_MASK (0x3 << 0) -+ -+/* PERFORMANCE_COUNTER_TIME */ -+#define TOTAL_TIME_SHIFT 0 -+#define TOTAL_TIME_MASK (0xffffffff << 0) -+ -+/* DLL_CALIB_CTRL */ -+#define ACK_WAIT_SHIFT 16 -+#define ACK_WAIT_MASK (0xf << 16) -+#define DLL_CALIB_INTERVAL_SHIFT 0 -+#define DLL_CALIB_INTERVAL_MASK (0x1ff << 0) -+ -+/* END_OF_INTERRUPT */ -+#define EOI_SHIFT 0 -+#define EOI_MASK (1 << 0) -+ -+/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */ -+#define DNV_SYS_SHIFT 2 -+#define DNV_SYS_MASK (1 << 2) -+#define TA_SYS_SHIFT 1 -+#define TA_SYS_MASK (1 << 1) -+#define ERR_SYS_SHIFT 0 -+#define ERR_SYS_MASK (1 << 0) -+ -+/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */ -+#define DNV_LL_SHIFT 2 -+#define DNV_LL_MASK (1 << 2) -+#define TA_LL_SHIFT 1 -+#define TA_LL_MASK (1 << 1) -+#define ERR_LL_SHIFT 0 -+#define ERR_LL_MASK (1 << 0) -+ -+/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */ -+#define EN_DNV_SYS_SHIFT 2 -+#define EN_DNV_SYS_MASK (1 << 2) -+#define EN_TA_SYS_SHIFT 1 -+#define EN_TA_SYS_MASK (1 << 1) -+#define EN_ERR_SYS_SHIFT 0 -+#define EN_ERR_SYS_MASK (1 << 0) -+ -+/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */ -+#define EN_DNV_LL_SHIFT 2 -+#define EN_DNV_LL_MASK (1 << 2) -+#define EN_TA_LL_SHIFT 1 -+#define EN_TA_LL_MASK (1 << 1) -+#define EN_ERR_LL_SHIFT 0 -+#define EN_ERR_LL_MASK (1 << 0) -+ -+/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */ -+#define ZQ_CS1EN_SHIFT 31 -+#define ZQ_CS1EN_MASK (1 << 31) -+#define ZQ_CS0EN_SHIFT 30 -+#define ZQ_CS0EN_MASK (1 << 30) -+#define ZQ_DUALCALEN_SHIFT 29 -+#define ZQ_DUALCALEN_MASK (1 << 29) -+#define ZQ_SFEXITEN_SHIFT 28 -+#define ZQ_SFEXITEN_MASK (1 << 28) -+#define ZQ_ZQINIT_MULT_SHIFT 18 -+#define ZQ_ZQINIT_MULT_MASK (0x3 << 18) -+#define ZQ_ZQCL_MULT_SHIFT 16 -+#define ZQ_ZQCL_MULT_MASK (0x3 << 16) -+#define ZQ_REFINTERVAL_SHIFT 0 -+#define ZQ_REFINTERVAL_MASK (0xffff << 0) -+ -+/* TEMPERATURE_ALERT_CONFIG */ -+#define TA_CS1EN_SHIFT 31 -+#define TA_CS1EN_MASK (1 << 31) -+#define TA_CS0EN_SHIFT 30 -+#define TA_CS0EN_MASK (1 << 30) -+#define TA_SFEXITEN_SHIFT 28 -+#define TA_SFEXITEN_MASK (1 << 28) -+#define TA_DEVWDT_SHIFT 26 -+#define TA_DEVWDT_MASK (0x3 << 26) -+#define TA_DEVCNT_SHIFT 24 -+#define TA_DEVCNT_MASK (0x3 << 24) -+#define TA_REFINTERVAL_SHIFT 0 -+#define TA_REFINTERVAL_MASK (0x3fffff << 0) -+ -+/* OCP_ERROR_LOG */ -+#define MADDRSPACE_SHIFT 14 -+#define MADDRSPACE_MASK (0x3 << 14) -+#define MBURSTSEQ_SHIFT 11 -+#define MBURSTSEQ_MASK (0x7 << 11) -+#define MCMD_SHIFT 8 -+#define MCMD_MASK (0x7 << 8) -+#define MCONNID_SHIFT 0 -+#define MCONNID_MASK (0xff << 0) -+ -+/* DDR_PHY_CTRL_1 - EMIF4D */ -+#define DLL_SLAVE_DLY_CTRL_SHIFT_4D 4 -+#define DLL_SLAVE_DLY_CTRL_MASK_4D (0xFF << 4) -+#define READ_LATENCY_SHIFT_4D 0 -+#define READ_LATENCY_MASK_4D (0xf << 0) -+ -+/* DDR_PHY_CTRL_1 - EMIF4D5 */ -+#define DLL_HALF_DELAY_SHIFT_4D5 21 -+#define DLL_HALF_DELAY_MASK_4D5 (1 << 21) -+#define READ_LATENCY_SHIFT_4D5 0 -+#define READ_LATENCY_MASK_4D5 (0x1f << 0) -+ -+/* DDR_PHY_CTRL_1_SHDW */ -+#define DDR_PHY_CTRL_1_SHDW_SHIFT 5 -+#define DDR_PHY_CTRL_1_SHDW_MASK (0x7ffffff << 5) -+#define READ_LATENCY_SHDW_SHIFT 0 -+#define READ_LATENCY_SHDW_MASK (0x1f << 0) -+ -+#endif /* __TI_EMIF_H */ ---- a/include/linux/usb/musb.h -+++ b/include/linux/usb/musb.h -@@ -99,8 +99,6 @@ struct musb_hdrc_platform_data { - /* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */ - u8 mode; - -- u8 has_mailbox:1; -- - /* for clk_get() */ - const char *clock; - ---- a/include/linux/usb/omap_control_usb.h -+++ /dev/null -@@ -1,92 +0,0 @@ --/* -- * omap_control_usb.h - Header file for the USB part of control module. -- * -- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com -- * 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. -- * -- * Author: Kishon Vijay Abraham I <kishon@ti.com> -- * -- * 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. -- * -- */ -- --#ifndef __OMAP_CONTROL_USB_H__ --#define __OMAP_CONTROL_USB_H__ -- --struct omap_control_usb { -- struct device *dev; -- -- u32 __iomem *dev_conf; -- u32 __iomem *otghs_control; -- u32 __iomem *phy_power; -- -- struct clk *sys_clk; -- -- u32 type; --}; -- --struct omap_control_usb_platform_data { -- u8 type; --}; -- --enum omap_control_usb_mode { -- USB_MODE_UNDEFINED = 0, -- USB_MODE_HOST, -- USB_MODE_DEVICE, -- USB_MODE_DISCONNECT, --}; -- --/* To differentiate ctrl module IP having either mailbox or USB3 PHY power */ --#define OMAP_CTRL_DEV_TYPE1 0x1 --#define OMAP_CTRL_DEV_TYPE2 0x2 -- --#define OMAP_CTRL_DEV_PHY_PD BIT(0) -- --#define OMAP_CTRL_DEV_AVALID BIT(0) --#define OMAP_CTRL_DEV_BVALID BIT(1) --#define OMAP_CTRL_DEV_VBUSVALID BIT(2) --#define OMAP_CTRL_DEV_SESSEND BIT(3) --#define OMAP_CTRL_DEV_IDDIG BIT(4) -- --#define OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK 0x003FC000 --#define OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT 0xE -- --#define OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK 0xFFC00000 --#define OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT 0x16 -- --#define OMAP_CTRL_USB3_PHY_TX_RX_POWERON 0x3 --#define OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF 0x0 -- --#if IS_ENABLED(CONFIG_OMAP_CONTROL_USB) --extern struct device *omap_get_control_dev(void); --extern void omap_control_usb_phy_power(struct device *dev, int on); --extern void omap_control_usb3_phy_power(struct device *dev, bool on); --extern void omap_control_usb_set_mode(struct device *dev, -- enum omap_control_usb_mode mode); --#else --static inline struct device *omap_get_control_dev(void) --{ -- return ERR_PTR(-ENODEV); --} -- --static inline void omap_control_usb_phy_power(struct device *dev, int on) --{ --} -- --static inline void omap_control_usb3_phy_power(struct device *dev, int on) --{ --} -- --static inline void omap_control_usb_set_mode(struct device *dev, -- enum omap_control_usb_mode mode) --{ --} --#endif -- --#endif /* __OMAP_CONTROL_USB_H__ */ ---- a/include/linux/usb/omap_usb.h -+++ /dev/null -@@ -1,67 +0,0 @@ --/* -- * omap_usb.h -- omap usb2 phy header file -- * -- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com -- * 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. -- * -- * Author: Kishon Vijay Abraham I <kishon@ti.com> -- * -- * 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. -- * -- */ -- --#ifndef __DRIVERS_OMAP_USB2_H --#define __DRIVERS_OMAP_USB2_H -- --#include <linux/io.h> --#include <linux/usb/otg.h> -- --struct usb_dpll_params { -- u16 m; -- u8 n; -- u8 freq:3; -- u8 sd; -- u32 mf; --}; -- --struct omap_usb { -- struct usb_phy phy; -- struct phy_companion *comparator; -- void __iomem *pll_ctrl_base; -- struct device *dev; -- struct device *control_dev; -- struct clk *wkupclk; -- struct clk *sys_clk; -- struct clk *optclk; -- u8 is_suspended:1; --}; -- --#define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) -- --#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) --extern int omap_usb2_set_comparator(struct phy_companion *comparator); --#else --static inline int omap_usb2_set_comparator(struct phy_companion *comparator) --{ -- return -ENODEV; --} --#endif -- --static inline u32 omap_usb_readl(void __iomem *addr, unsigned offset) --{ -- return __raw_readl(addr + offset); --} -- --static inline void omap_usb_writel(void __iomem *addr, unsigned offset, -- u32 data) --{ -- __raw_writel(data, addr + offset); --} -- --#endif /* __DRIVERS_OMAP_USB_H */ ---- a/include/linux/usb/usb_phy_gen_xceiv.h -+++ b/include/linux/usb/usb_phy_gen_xceiv.h -@@ -9,7 +9,8 @@ struct usb_phy_gen_xceiv_platform_data { - - /* if set fails with -EPROBE_DEFER if can't get regulator */ - unsigned int needs_vcc:1; -- unsigned int needs_reset:1; -+ unsigned int needs_reset:1; /* deprecated */ -+ int gpio_reset; - }; - - #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE)) ---- a/include/uapi/linux/v4l2-controls.h -+++ b/include/uapi/linux/v4l2-controls.h -@@ -160,6 +160,10 @@ enum v4l2_colorfx { - * of controls. Total of 16 controls is reserved for this driver */ - #define V4L2_CID_USER_SI476X_BASE (V4L2_CID_USER_BASE + 0x1040) - -+/* The base for the TI VPE driver controls. Total of 16 controls is reserved for -+ * this driver */ -+#define V4L2_CID_USER_TI_VPE_BASE (V4L2_CID_USER_BASE + 0x1050) -+ - /* MPEG-class control IDs */ - /* The MPEG controls are applicable to all codec controls - * and the 'MPEG' part of the define is historical */ ---- a/include/video/da8xx-fb.h -+++ b/include/video/da8xx-fb.h -@@ -12,6 +12,8 @@ - #ifndef DA8XX_FB_H - #define DA8XX_FB_H - -+#include <linux/fb.h> -+ - enum panel_shade { - MONOCHROME = 0, - COLOR_ACTIVE, -@@ -91,5 +93,22 @@ struct lcd_sync_arg { - /* Proprietary FB_SYNC_ flags */ - #define FB_SYNC_CLK_INVERT 0x40000000 - -+struct da8xx_encoder { -+ struct list_head list; /* internal use only */ -+ struct i2c_client *client; -+ void *priv; -+ void (*set_mode)(struct da8xx_encoder *encoder, -+ struct fb_videomode *panel); -+ struct device_node *node; -+}; -+ -+void da8xx_register_encoder(struct da8xx_encoder *encoder); -+void da8xx_unregister_encoder(struct da8xx_encoder *encoder); -+ -+ -+typedef void (*vsync_callback_t)(void *arg); -+int register_vsync_cb(vsync_callback_t handler, void *arg, int idx); -+int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx); -+ - #endif /* ifndef DA8XX_FB_H */ - ---- /dev/null -+++ b/include/video/da8xx-tda998x-hdmi.h -@@ -0,0 +1,35 @@ -+/* -+ * Header file for TI DA8XX/TDA998x Encoder Driver -+ * -+ * Copyright (C) 2013 Texas Instruments Inc -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+#ifndef DA8XX_TDA998X_HDMI_H -+#define DA8XX_TDA998X_HDMI_H -+ -+#include <linux/fb.h> -+ -+enum tda998x_audio_format { -+ AFMT_I2S, -+ AFMT_SPDIF, -+}; -+ -+struct tda998x_encoder_params { -+ int audio_cfg; -+ int audio_clk_cfg; -+ enum tda998x_audio_format audio_format; -+ int audio_sample_rate; -+ char audio_frame[6]; -+ int swap_a, mirr_a; -+ int swap_b, mirr_b; -+ int swap_c, mirr_c; -+ int swap_d, mirr_d; -+ int swap_e, mirr_e; -+ int swap_f, mirr_f; -+}; -+ -+#endif ---- a/include/video/omapdss.h -+++ b/include/video/omapdss.h -@@ -227,6 +227,8 @@ enum omap_dss_output_id { - OMAP_DSS_OUTPUT_DSI2 = 1 << 4, - OMAP_DSS_OUTPUT_VENC = 1 << 5, - OMAP_DSS_OUTPUT_HDMI = 1 << 6, -+ OMAP_DSS_OUTPUT_DPI1 = 1 << 7, -+ OMAP_DSS_OUTPUT_DPI2 = 1 << 8, - }; - - /* RFBI */ -@@ -319,6 +321,8 @@ enum omapdss_version { - OMAPDSS_VER_OMAP4430_ES2, /* OMAP4430 ES2.0, 2.1, 2.2 */ - OMAPDSS_VER_OMAP4, /* All other OMAP4s */ - OMAPDSS_VER_OMAP5, -+ OMAPDSS_VER_DRA7xx, -+ OMAPDSS_VER_AM43xx, - }; - - /* Board specific data */ -@@ -961,6 +965,10 @@ int dispc_ovl_enable(enum omap_plane pla - bool dispc_ovl_enabled(enum omap_plane plane); - void dispc_ovl_set_channel_out(enum omap_plane plane, - enum omap_channel channel); -+void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, -+ u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, -+ bool manual_update); -+void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); - int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, - bool replication, const struct omap_video_timings *mgr_timings, - bool mem_to_mem); ---- a/include/video/omap-panel-data.h -+++ b/include/video/omap-panel-data.h -@@ -62,6 +62,20 @@ struct encoder_tpd12s015_platform_data { - }; - - /** -+ * encoder_sil9022 platform data -+ * @name: name for this display entity -+ * @res_gpio: Gpio to switch lcd and hdmi. Used as reset for Sil9022 -+ * as a temproary solution. -+ */ -+struct encoder_sil9022_platform_data { -+ const char *name; -+ const char *source; -+ int reset_gpio; -+ int data_lines; -+}; -+ -+ -+/** - * connector_dvi platform data - * @name: name for this display entity - * @source: name of the display entity used as a video source ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -3691,6 +3691,14 @@ S: Maintained - F: include/asm-generic/ - F: include/uapi/asm-generic/ - -+GENERIC PHY FRAMEWORK -+M: Kishon Vijay Abraham I <kishon@ti.com> -+L: linux-kernel@vger.kernel.org -+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git -+S: Supported -+F: drivers/phy/ -+F: include/linux/phy/ -+ - GENERIC UIO DRIVER FOR PCI DEVICES - M: "Michael S. Tsirkin" <mst@redhat.com> - L: kvm@vger.kernel.org ---- a/sound/soc/davinci/davinci-evm.c -+++ b/sound/soc/davinci/davinci-evm.c -@@ -16,6 +16,7 @@ - #include <linux/platform_device.h> - #include <linux/platform_data/edma.h> - #include <linux/i2c.h> -+#include <linux/of_platform.h> - #include <sound/core.h> - #include <sound/pcm.h> - #include <sound/soc.h> -@@ -23,10 +24,16 @@ - #include <asm/dma.h> - #include <asm/mach-types.h> - -+#include <linux/edma.h> -+ - #include "davinci-pcm.h" - #include "davinci-i2s.h" - #include "davinci-mcasp.h" - -+struct snd_soc_card_drvdata_davinci { -+ unsigned sysclk; -+}; -+ - #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ - SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) - static int evm_hw_params(struct snd_pcm_substream *substream, -@@ -35,27 +42,11 @@ static int evm_hw_params(struct snd_pcm_ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_card *soc_card = codec->card; - int ret = 0; -- unsigned sysclk; -- -- /* ASP1 on DM355 EVM is clocked by an external oscillator */ -- if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() || -- machine_is_davinci_dm365_evm()) -- sysclk = 27000000; -- -- /* ASP0 in DM6446 EVM is clocked by U55, as configured by -- * board-dm644x-evm.c using GPIOs from U18. There are six -- * options; here we "know" we use a 48 KHz sample rate. -- */ -- else if (machine_is_davinci_evm()) -- sysclk = 12288000; -- -- else if (machine_is_davinci_da830_evm() || -- machine_is_davinci_da850_evm()) -- sysclk = 24576000; -- -- else -- return -EINVAL; -+ unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *) -+ snd_soc_card_get_drvdata(soc_card))->sysclk; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); -@@ -133,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc - { - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; -+ struct device_node *np = codec->card->dev->of_node; -+ int ret; - - /* Add davinci-evm specific widgets */ - snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, - ARRAY_SIZE(aic3x_dapm_widgets)); - -- /* Set up davinci-evm specific audio path audio_map */ -- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); -+ if (np) { -+ ret = snd_soc_of_parse_audio_routing(codec->card, -+ "ti,audio-routing"); -+ if (ret) -+ return ret; -+ } else { -+ /* Set up davinci-evm specific audio path audio_map */ -+ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); -+ } - - /* not connected */ - snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); -@@ -243,35 +243,65 @@ static struct snd_soc_dai_link da850_evm - }; - - /* davinci dm6446 evm audio machine driver */ -+/* -+ * ASP0 in DM6446 EVM is clocked by U55, as configured by -+ * board-dm644x-evm.c using GPIOs from U18. There are six -+ * options; here we "know" we use a 48 KHz sample rate. -+ */ -+static struct snd_soc_card_drvdata_davinci dm6446_snd_soc_card_drvdata = { -+ .sysclk = 12288000, -+}; -+ - static struct snd_soc_card dm6446_snd_soc_card_evm = { - .name = "DaVinci DM6446 EVM", - .owner = THIS_MODULE, - .dai_link = &dm6446_evm_dai, - .num_links = 1, -+ .drvdata = &dm6446_snd_soc_card_drvdata, - }; - - /* davinci dm355 evm audio machine driver */ -+/* ASP1 on DM355 EVM is clocked by an external oscillator */ -+static struct snd_soc_card_drvdata_davinci dm355_snd_soc_card_drvdata = { -+ .sysclk = 27000000, -+}; -+ - static struct snd_soc_card dm355_snd_soc_card_evm = { - .name = "DaVinci DM355 EVM", - .owner = THIS_MODULE, - .dai_link = &dm355_evm_dai, - .num_links = 1, -+ .drvdata = &dm355_snd_soc_card_drvdata, - }; - - /* davinci dm365 evm audio machine driver */ -+static struct snd_soc_card_drvdata_davinci dm365_snd_soc_card_drvdata = { -+ .sysclk = 27000000, -+}; -+ - static struct snd_soc_card dm365_snd_soc_card_evm = { - .name = "DaVinci DM365 EVM", - .owner = THIS_MODULE, - .dai_link = &dm365_evm_dai, - .num_links = 1, -+ .drvdata = &dm365_snd_soc_card_drvdata, - }; - - /* davinci dm6467 evm audio machine driver */ -+static struct snd_soc_card_drvdata_davinci dm6467_snd_soc_card_drvdata = { -+ .sysclk = 27000000, -+}; -+ - static struct snd_soc_card dm6467_snd_soc_card_evm = { - .name = "DaVinci DM6467 EVM", - .owner = THIS_MODULE, - .dai_link = dm6467_evm_dai, - .num_links = ARRAY_SIZE(dm6467_evm_dai), -+ .drvdata = &dm6467_snd_soc_card_drvdata, -+}; -+ -+static struct snd_soc_card_drvdata_davinci da830_snd_soc_card_drvdata = { -+ .sysclk = 24576000, - }; - - static struct snd_soc_card da830_snd_soc_card = { -@@ -279,6 +309,11 @@ static struct snd_soc_card da830_snd_soc - .owner = THIS_MODULE, - .dai_link = &da830_evm_dai, - .num_links = 1, -+ .drvdata = &da830_snd_soc_card_drvdata, -+}; -+ -+static struct snd_soc_card_drvdata_davinci da850_snd_soc_card_drvdata = { -+ .sysclk = 24576000, - }; - - static struct snd_soc_card da850_snd_soc_card = { -@@ -286,8 +321,101 @@ static struct snd_soc_card da850_snd_soc - .owner = THIS_MODULE, - .dai_link = &da850_evm_dai, - .num_links = 1, -+ .drvdata = &da850_snd_soc_card_drvdata, -+}; -+ -+#if defined(CONFIG_OF) -+ -+/* -+ * The struct is used as place holder. It will be completely -+ * filled with data from dt node. -+ */ -+static struct snd_soc_dai_link evm_dai_tlv320aic3x = { -+ .name = "TLV320AIC3X", -+ .stream_name = "AIC3X", -+ .codec_dai_name = "tlv320aic3x-hifi", -+ .ops = &evm_ops, -+ .init = evm_aic3x_init, -+}; -+ -+static const struct of_device_id davinci_evm_dt_ids[] = { -+ { -+ .compatible = "ti,da830-evm-audio", -+ .data = (void *) &evm_dai_tlv320aic3x, -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids); -+ -+/* davinci evm audio machine driver */ -+static struct snd_soc_card evm_soc_card = { -+ .owner = THIS_MODULE, -+ .num_links = 1, - }; - -+static int davinci_evm_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ const struct of_device_id *match = -+ of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); -+ struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data; -+ struct snd_soc_card_drvdata_davinci *drvdata = NULL; -+ int ret = 0; -+ -+ evm_soc_card.dai_link = dai; -+ -+ dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0); -+ if (!dai->codec_of_node) -+ return -EINVAL; -+ -+ dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0); -+ if (!dai->cpu_of_node) -+ return -EINVAL; -+ -+ dai->platform_of_node = dai->cpu_of_node; -+ -+ evm_soc_card.dev = &pdev->dev; -+ ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); -+ if (ret) -+ return ret; -+ -+ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); -+ if (!drvdata) -+ return -ENOMEM; -+ -+ ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk); -+ if (ret < 0) -+ return -EINVAL; -+ -+ snd_soc_card_set_drvdata(&evm_soc_card, drvdata); -+ ret = snd_soc_register_card(&evm_soc_card); -+ -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); -+ -+ return ret; -+} -+ -+static int davinci_evm_remove(struct platform_device *pdev) -+{ -+ struct snd_soc_card *card = platform_get_drvdata(pdev); -+ -+ snd_soc_unregister_card(card); -+ -+ return 0; -+} -+ -+static struct platform_driver davinci_evm_driver = { -+ .probe = davinci_evm_probe, -+ .remove = davinci_evm_remove, -+ .driver = { -+ .name = "davinci_evm", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(davinci_evm_dt_ids), -+ }, -+}; -+#endif -+ - static struct platform_device *evm_snd_device; - - static int __init evm_init(void) -@@ -296,6 +424,13 @@ static int __init evm_init(void) - int index; - int ret; - -+ /* -+ * If dtb is there, the devices will be created dynamically. -+ * Only register platfrom driver structure. -+ */ -+ if (of_have_populated_dt()) -+ return platform_driver_register(&davinci_evm_driver); -+ - if (machine_is_davinci_evm()) { - evm_snd_dev_data = &dm6446_snd_soc_card_evm; - index = 0; -@@ -331,6 +466,11 @@ static int __init evm_init(void) - - static void __exit evm_exit(void) - { -+ if (of_have_populated_dt()) { -+ platform_driver_unregister(&davinci_evm_driver); -+ return; -+ } -+ - platform_device_unregister(evm_snd_device); - } - ---- a/sound/soc/davinci/davinci-mcasp.c -+++ b/sound/soc/davinci/davinci-mcasp.c -@@ -1001,18 +1001,40 @@ static const struct snd_soc_component_dr - .name = "davinci-mcasp", - }; - -+/* Some HW specific values and defaults. The rest is filled in from DT. */ -+static struct snd_platform_data dm646x_mcasp_pdata = { -+ .tx_dma_offset = 0x400, -+ .rx_dma_offset = 0x400, -+ .asp_chan_q = EVENTQ_0, -+ .version = MCASP_VERSION_1, -+}; -+ -+static struct snd_platform_data da830_mcasp_pdata = { -+ .tx_dma_offset = 0x2000, -+ .rx_dma_offset = 0x2000, -+ .asp_chan_q = EVENTQ_0, -+ .version = MCASP_VERSION_2, -+}; -+ -+static struct snd_platform_data omap2_mcasp_pdata = { -+ .tx_dma_offset = 0, -+ .rx_dma_offset = 0, -+ .asp_chan_q = EVENTQ_0, -+ .version = MCASP_VERSION_3, -+}; -+ - static const struct of_device_id mcasp_dt_ids[] = { - { - .compatible = "ti,dm646x-mcasp-audio", -- .data = (void *)MCASP_VERSION_1, -+ .data = &dm646x_mcasp_pdata, - }, - { - .compatible = "ti,da830-mcasp-audio", -- .data = (void *)MCASP_VERSION_2, -+ .data = &da830_mcasp_pdata, - }, - { - .compatible = "ti,omap2-mcasp-audio", -- .data = (void *)MCASP_VERSION_3, -+ .data = &omap2_mcasp_pdata, - }, - { /* sentinel */ } - }; -@@ -1025,9 +1047,9 @@ static struct snd_platform_data *davinci - struct snd_platform_data *pdata = NULL; - const struct of_device_id *match = - of_match_device(mcasp_dt_ids, &pdev->dev); -+ struct of_phandle_args dma_spec; - - const u32 *of_serial_dir32; -- u8 *of_serial_dir; - u32 val; - int i, ret = 0; - -@@ -1035,20 +1057,13 @@ static struct snd_platform_data *davinci - pdata = pdev->dev.platform_data; - return pdata; - } else if (match) { -- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); -- if (!pdata) { -- ret = -ENOMEM; -- goto nodata; -- } -+ pdata = (struct snd_platform_data *) match->data; - } else { - /* control shouldn't reach here. something is wrong */ - ret = -EINVAL; - goto nodata; - } - -- if (match->data) -- pdata->version = (u8)((int)match->data); -- - ret = of_property_read_u32(np, "op-mode", &val); - if (ret >= 0) - pdata->op_mode = val; -@@ -1065,35 +1080,46 @@ static struct snd_platform_data *davinci - pdata->tdm_slots = val; - } - -- ret = of_property_read_u32(np, "num-serializer", &val); -- if (ret >= 0) -- pdata->num_serializer = val; -- - of_serial_dir32 = of_get_property(np, "serial-dir", &val); - val /= sizeof(u32); -- if (val != pdata->num_serializer) { -- dev_err(&pdev->dev, -- "num-serializer(%d) != serial-dir size(%d)\n", -- pdata->num_serializer, val); -- ret = -EINVAL; -- goto nodata; -- } -- - if (of_serial_dir32) { -- of_serial_dir = devm_kzalloc(&pdev->dev, -- (sizeof(*of_serial_dir) * val), -- GFP_KERNEL); -+ u8 *of_serial_dir = devm_kzalloc(&pdev->dev, -+ (sizeof(*of_serial_dir) * val), -+ GFP_KERNEL); - if (!of_serial_dir) { - ret = -ENOMEM; - goto nodata; - } - -- for (i = 0; i < pdata->num_serializer; i++) -+ for (i = 0; i < val; i++) - of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]); - -+ pdata->num_serializer = val; - pdata->serial_dir = of_serial_dir; - } - -+ ret = of_property_match_string(np, "dma-names", "tx"); -+ if (ret < 0) -+ goto nodata; -+ -+ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, -+ &dma_spec); -+ if (ret < 0) -+ goto nodata; -+ -+ pdata->tx_dma_channel = dma_spec.args[0]; -+ -+ ret = of_property_match_string(np, "dma-names", "rx"); -+ if (ret < 0) -+ goto nodata; -+ -+ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, -+ &dma_spec); -+ if (ret < 0) -+ goto nodata; -+ -+ pdata->rx_dma_channel = dma_spec.args[0]; -+ - ret = of_property_read_u32(np, "tx-num-evt", &val); - if (ret >= 0) - pdata->txnumevt = val; -@@ -1124,7 +1150,7 @@ nodata: - static int davinci_mcasp_probe(struct platform_device *pdev) - { - struct davinci_pcm_dma_params *dma_data; -- struct resource *mem, *ioarea, *res; -+ struct resource *mem, *ioarea, *res, *dma; - struct snd_platform_data *pdata; - struct davinci_audio_dev *dev; - int ret; -@@ -1145,10 +1171,15 @@ static int davinci_mcasp_probe(struct pl - return -EINVAL; - } - -- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); - if (!mem) { -- dev_err(&pdev->dev, "no mem resource?\n"); -- return -ENODEV; -+ dev_warn(dev->dev, -+ "\"mpu\" mem resource not found, using index 0\n"); -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!mem) { -+ dev_err(&pdev->dev, "no mem resource?\n"); -+ return -ENODEV; -+ } - } - - ioarea = devm_request_mem_region(&pdev->dev, mem->start, -@@ -1182,40 +1213,36 @@ static int davinci_mcasp_probe(struct pl - dev->rxnumevt = pdata->rxnumevt; - dev->dev = &pdev->dev; - -+ dma = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); -+ if (!dma) -+ dma = mem; -+ - dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; - dma_data->asp_chan_q = pdata->asp_chan_q; - dma_data->ram_chan_q = pdata->ram_chan_q; - dma_data->sram_pool = pdata->sram_pool; - dma_data->sram_size = pdata->sram_size_playback; -- dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + -- mem->start); -+ dma_data->dma_addr = dma->start + pdata->tx_dma_offset; - -- /* first TX, then RX */ - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); -- if (!res) { -- dev_err(&pdev->dev, "no DMA resource\n"); -- ret = -ENODEV; -- goto err_release_clk; -- } -- -- dma_data->channel = res->start; -+ if (res) -+ dma_data->channel = res->start; -+ else -+ dma_data->channel = pdata->tx_dma_channel; - - dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; - dma_data->asp_chan_q = pdata->asp_chan_q; - dma_data->ram_chan_q = pdata->ram_chan_q; - dma_data->sram_pool = pdata->sram_pool; - dma_data->sram_size = pdata->sram_size_capture; -- dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + -- mem->start); -+ dma_data->dma_addr = dma->start + pdata->rx_dma_offset; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); -- if (!res) { -- dev_err(&pdev->dev, "no DMA resource\n"); -- ret = -ENODEV; -- goto err_release_clk; -- } -+ if (res) -+ dma_data->channel = res->start; -+ else -+ dma_data->channel = pdata->rx_dma_channel; - -- dma_data->channel = res->start; - dev_set_drvdata(&pdev->dev, dev); - ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, - &davinci_mcasp_dai[pdata->op_mode], 1); -@@ -1266,4 +1293,3 @@ module_platform_driver(davinci_mcasp_dri - MODULE_AUTHOR("Steve Chen"); - MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface"); - MODULE_LICENSE("GPL"); -- ---- a/sound/soc/davinci/Kconfig -+++ b/sound/soc/davinci/Kconfig -@@ -1,9 +1,10 @@ - config SND_DAVINCI_SOC -- tristate "SoC Audio for the TI DAVINCI chip" -- depends on ARCH_DAVINCI -+ tristate "SoC Audio for the TI DAVINCI or AM33XX chip" -+ depends on ARCH_DAVINCI || SOC_AM33XX - help -+ Platform driver for daVinci or AM33xx - Say Y or M if you want to add support for codecs attached to -- the DAVINCI AC97 or I2S interface. You will also need -+ the DAVINCI AC97, I2S, or McASP interface. You will also need - to select the audio interfaces to support below. - - config SND_DAVINCI_SOC_I2S -@@ -15,6 +16,17 @@ config SND_DAVINCI_SOC_MCASP - config SND_DAVINCI_SOC_VCIF - tristate - -+config SND_AM33XX_SOC_EVM -+ tristate "SoC Audio for the AM33XX chip based boards" -+ depends on SND_DAVINCI_SOC && SOC_AM33XX -+ select SND_SOC_TLV320AIC3X -+ select SND_DAVINCI_SOC_MCASP -+ help -+ Say Y or M if you want to add support for SoC audio on AM33XX -+ boards using McASP and TLV320AIC3X codec. For example AM335X-EVM, -+ AM335X-EVMSK, and BeagelBone with AudioCape boards have this -+ setup. -+ - config SND_DAVINCI_SOC_EVM - tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" - depends on SND_DAVINCI_SOC ---- a/sound/soc/davinci/Makefile -+++ b/sound/soc/davinci/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += sn - snd-soc-evm-objs := davinci-evm.o - - obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o -+obj-$(CONFIG_SND_AM33XX_SOC_EVM) += snd-soc-evm.o - obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o - obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o - obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o ---- a/sound/soc/omap/Kconfig -+++ b/sound/soc/omap/Kconfig -@@ -87,17 +87,19 @@ config SND_OMAP_SOC_OMAP_TWL4030 - - config SND_OMAP_SOC_OMAP_ABE_TWL6040 - tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" -- depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || COMPILE_TEST) -+ depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || SOC_OMAP5 || COMPILE_TEST) - select SND_OMAP_SOC_DMIC - select SND_OMAP_SOC_MCPDM - select SND_SOC_TWL6040 - select SND_SOC_DMIC -+ select COMMON_CLK_PALMAS if SOC_OMAP5 - help - Say Y if you want to add support for SoC audio on OMAP boards using - ABE and twl6040 codec. This driver currently supports: - - SDP4430/Blaze boards - - PandaBoard (4430) - - PandaBoardES (4460) -+ - omap5-uevm (5432) - - config SND_OMAP_SOC_OMAP_HDMI - tristate "SoC Audio support for Texas Instruments OMAP HDMI" diff --git a/target/linux/omap/patches-3.12/0334-video-da8xx-fb-adding-dt-support.patch b/target/linux/omap/patches-3.12/0334-video-da8xx-fb-adding-dt-support.patch new file mode 100644 index 0000000000..5afe086fe5 --- /dev/null +++ b/target/linux/omap/patches-3.12/0334-video-da8xx-fb-adding-dt-support.patch @@ -0,0 +1,211 @@ +From 884d3962ef4787c8cf0b8a7a673531c623d1dff8 Mon Sep 17 00:00:00 2001 +From: Darren Etheridge <detheridge@ti.com> +Date: Fri, 2 Aug 2013 15:35:36 -0500 +Subject: [PATCH 334/752] video: da8xx-fb: adding dt support + +Enhancing driver to enable probe triggered by a corresponding dt entry. + +Add da8xx-fb.txt documentation to devicetree section. + +Obtain fb_videomode details for the connected lcd panel using the +display timing details present in DT. + +Ensure that platform data is present before checking whether platform +callback is present (the one used to control backlight). So far this +was not an issue as driver was purely non-DT triggered, but now DT +support has been added this check must be performed. + +v2: squashing multiple commits from Afzal Mohammed (afzal@ti.com) +v3: remove superfluous cast +v4: expose both ti,am3352-lcdc and ti,da830-lcdc for .compatible + as driver can use enhanced features of all version of the + silicon block. +v5: addressed review comments from Prabhakar Lad +v6: Changed the .compatible naming to match the existing drm bindings + for am33xx devices +v7: clarify which compatible to use in the documentation for DA850 + +Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> +Signed-off-by: Darren Etheridge <detheridge@ti.com> +--- + .../devicetree/bindings/video/da8xx-fb.txt | 42 +++++++++++++ + drivers/video/da8xx-fb.c | 66 +++++++++++++++++++- + 2 files changed, 105 insertions(+), 3 deletions(-) + create mode 100644 Documentation/devicetree/bindings/video/da8xx-fb.txt + +diff --git a/Documentation/devicetree/bindings/video/da8xx-fb.txt b/Documentation/devicetree/bindings/video/da8xx-fb.txt +new file mode 100644 +index 0000000..d86afe7 +--- /dev/null ++++ b/Documentation/devicetree/bindings/video/da8xx-fb.txt +@@ -0,0 +1,42 @@ ++TI LCD Controller on DA830/DA850/AM335x SoC's ++ ++Required properties: ++- compatible: ++ DA830, DA850 - "ti,da8xx-tilcdc" ++ AM335x SoC's - "ti,am33xx-tilcdc" ++- reg: Address range of lcdc register set ++- interrupts: lcdc interrupt ++- display-timings: typical videomode of lcd panel, represented as child. ++ Refer Documentation/devicetree/bindings/video/display-timing.txt for ++ display timing binding details. If multiple videomodes are mentioned ++ in display timings node, typical videomode has to be mentioned as the ++ native mode or it has to be first child (driver cares only for native ++ videomode). ++ ++Recommended properties: ++- ti,hwmods: Name of the hwmod associated to the LCDC ++ ++Example for am335x SoC's: ++ ++lcdc@4830e000 { ++ compatible = "ti,am33xx-tilcdc"; ++ reg = <0x4830e000 0x1000>; ++ interrupts = <36>; ++ ti,hwmods = "lcdc"; ++ status = "okay"; ++ display-timings { ++ 800x480p62 { ++ clock-frequency = <30000000>; ++ hactive = <800>; ++ vactive = <480>; ++ hfront-porch = <39>; ++ hback-porch = <39>; ++ hsync-len = <47>; ++ vback-porch = <29>; ++ vfront-porch = <13>; ++ vsync-len = <2>; ++ hsync-active = <1>; ++ vsync-active = <1>; ++ }; ++ }; ++}; +diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c +index e030e17..74cc2dc 100644 +--- a/drivers/video/da8xx-fb.c ++++ b/drivers/video/da8xx-fb.c +@@ -36,6 +36,7 @@ + #include <linux/slab.h> + #include <linux/delay.h> + #include <linux/lcm.h> ++#include <video/of_display_timing.h> + #include <video/da8xx-fb.h> + #include <asm/div64.h> + +@@ -1312,12 +1313,54 @@ static struct fb_ops da8xx_fb_ops = { + .fb_blank = cfb_blank, + }; + ++static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev) ++{ ++ struct lcd_ctrl_config *cfg; ++ ++ cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL); ++ if (!cfg) ++ return NULL; ++ ++ /* default values */ ++ ++ if (lcd_revision == LCD_VERSION_1) ++ cfg->bpp = 16; ++ else ++ cfg->bpp = 32; ++ ++ /* ++ * For panels so far used with this LCDC, below statement is sufficient. ++ * For new panels, if required, struct lcd_ctrl_cfg fields to be updated ++ * with additional/modified values. Those values would have to be then ++ * obtained from dt(requiring new dt bindings). ++ */ ++ ++ cfg->panel_shade = COLOR_ACTIVE; ++ ++ return cfg; ++} ++ + static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) + { + struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; + struct fb_videomode *lcdc_info; ++ struct device_node *np = dev->dev.of_node; + int i; + ++ if (np) { ++ lcdc_info = devm_kzalloc(&dev->dev, ++ sizeof(struct fb_videomode), ++ GFP_KERNEL); ++ if (!lcdc_info) ++ return NULL; ++ ++ if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) { ++ dev_err(&dev->dev, "timings not available in DT\n"); ++ return NULL; ++ } ++ return lcdc_info; ++ } ++ + for (i = 0, lcdc_info = known_lcd_panels; + i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) { + if (strcmp(fb_pdata->type, lcdc_info->name) == 0) +@@ -1346,7 +1389,7 @@ static int fb_probe(struct platform_device *device) + int ret; + unsigned long ulcm; + +- if (fb_pdata == NULL) { ++ if (fb_pdata == NULL && !device->dev.of_node) { + dev_err(&device->dev, "Can not get platform data\n"); + return -ENOENT; + } +@@ -1386,7 +1429,10 @@ static int fb_probe(struct platform_device *device) + break; + } + +- lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; ++ if (device->dev.of_node) ++ lcd_cfg = da8xx_fb_create_cfg(device); ++ else ++ lcd_cfg = fb_pdata->controller_data; + + if (!lcd_cfg) { + ret = -EINVAL; +@@ -1405,7 +1451,7 @@ static int fb_probe(struct platform_device *device) + par->dev = &device->dev; + par->lcdc_clk = tmp_lcdc_clk; + par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); +- if (fb_pdata->panel_power_ctrl) { ++ if (fb_pdata && fb_pdata->panel_power_ctrl) { + par->panel_power_ctrl = fb_pdata->panel_power_ctrl; + par->panel_power_ctrl(1); + } +@@ -1653,6 +1699,19 @@ static int fb_resume(struct platform_device *dev) + #define fb_resume NULL + #endif + ++#if IS_ENABLED(CONFIG_OF) ++static const struct of_device_id da8xx_fb_of_match[] = { ++ /* ++ * this driver supports version 1 and version 2 of the ++ * Texas Instruments lcd controller (lcdc) hardware block ++ */ ++ {.compatible = "ti,da8xx-tilcdc", }, ++ {.compatible = "ti,am33xx-tilcdc", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, da8xx_fb_of_match); ++#endif ++ + static struct platform_driver da8xx_fb_driver = { + .probe = fb_probe, + .remove = fb_remove, +@@ -1661,6 +1720,7 @@ static struct platform_driver da8xx_fb_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(da8xx_fb_of_match), + }, + }; + +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/0343-video-da8xx-fb-Add-API-to-register-wait-for-vsync-ca.patch b/target/linux/omap/patches-3.12/0343-video-da8xx-fb-Add-API-to-register-wait-for-vsync-ca.patch new file mode 100644 index 0000000000..ee7e6ea427 --- /dev/null +++ b/target/linux/omap/patches-3.12/0343-video-da8xx-fb-Add-API-to-register-wait-for-vsync-ca.patch @@ -0,0 +1,98 @@ +From 9a1a810516ae9cb3259b898b6879901c5b44fa90 Mon Sep 17 00:00:00 2001 +From: Prathap M S <msprathap@ti.com> +Date: Mon, 2 Sep 2013 12:05:23 +0530 +Subject: [PATCH 343/752] video: da8xx-fb: Add API to register wait for vsync + callback + +This patch adds APIs to register and unregister wait for vsync callback. +This is derived from commit id 2d44302545da24fd22912d964102bc31a7489e97 +This commit id was part of 3.2 kernel sources. + +Signed-off-by: Prathap M S <msprathap@ti.com> +--- + drivers/video/da8xx-fb.c | 33 +++++++++++++++++++++++++++++++++ + include/video/da8xx-fb.h | 4 ++++ + 2 files changed, 37 insertions(+) + +diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c +index c534d45..77dc477 100644 +--- a/drivers/video/da8xx-fb.c ++++ b/drivers/video/da8xx-fb.c +@@ -235,6 +235,9 @@ static struct fb_fix_screeninfo da8xx_fb_fix = { + .accel = FB_ACCEL_NONE + }; + ++static vsync_callback_t vsync_cb_handler; ++static void *vsync_cb_arg; ++ + static struct fb_videomode known_lcd_panels[] = { + /* Sharp LCD035Q3DG01 */ + [0] = { +@@ -916,6 +919,32 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, + return 0; + } + ++int register_vsync_cb(vsync_callback_t handler, void *arg, int idx) ++{ ++ if ((vsync_cb_handler == NULL) && (vsync_cb_arg == NULL)) { ++ vsync_cb_arg = arg; ++ vsync_cb_handler = handler; ++ } else { ++ return -EEXIST; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(register_vsync_cb); ++ ++int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx) ++{ ++ if ((vsync_cb_handler == handler) && (vsync_cb_arg == arg)) { ++ vsync_cb_handler = NULL; ++ vsync_cb_arg = NULL; ++ } else { ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(unregister_vsync_cb); ++ + /* IRQ handler for version 2 of LCDC */ + static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) + { +@@ -953,6 +982,8 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) + LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); ++ if (vsync_cb_handler) ++ vsync_cb_handler(vsync_cb_arg); + } + + if (stat & LCD_END_OF_FRAME1) { +@@ -1028,6 +1059,8 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); ++ if (vsync_cb_handler) ++ vsync_cb_handler(vsync_cb_arg); + } + } + +diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h +index 74c986a..2a0c739 100644 +--- a/include/video/da8xx-fb.h ++++ b/include/video/da8xx-fb.h +@@ -106,5 +106,9 @@ void da8xx_register_encoder(struct da8xx_encoder *encoder); + void da8xx_unregister_encoder(struct da8xx_encoder *encoder); + + ++typedef void (*vsync_callback_t)(void *arg); ++int register_vsync_cb(vsync_callback_t handler, void *arg, int idx); ++int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx); ++ + #endif /* ifndef DA8XX_FB_H */ + +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/0752-video-da8xx-fb-fix-defect-with-vsync-callback-invoca.patch b/target/linux/omap/patches-3.12/0752-video-da8xx-fb-fix-defect-with-vsync-callback-invoca.patch new file mode 100644 index 0000000000..698ed3973d --- /dev/null +++ b/target/linux/omap/patches-3.12/0752-video-da8xx-fb-fix-defect-with-vsync-callback-invoca.patch @@ -0,0 +1,43 @@ +From c99bd415829ef29adf71bb1e1b577650f10e93f5 Mon Sep 17 00:00:00 2001 +From: Darren Etheridge <detheridge@ti.com> +Date: Mon, 4 Nov 2013 12:27:40 -0600 +Subject: [PATCH 752/752] video/da8xx-fb fix defect with vsync callback + invocation + +Fix defect where SGX is running at half of the expected framerate. +The original patch (@ commit ID 9a1a810516ae9cb3259b898b6879901c5b44fa90) +seems to have a mistake where it only calls the callback +for the even or the odd frames depending on the revision of the LCD controller +This patch corrects this and invokes the callback for both odd and even frame +for just the Rev02 version of the LCDC (won't find an SGX GPU on a Rev01). + +Signed-off-by: Darren Etheridge <detheridge@ti.com> +--- + drivers/video/da8xx-fb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c +index 212d2ac..d6825e4 100644 +--- a/drivers/video/da8xx-fb.c ++++ b/drivers/video/da8xx-fb.c +@@ -993,6 +993,8 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); ++ if (vsync_cb_handler) ++ vsync_cb_handler(vsync_cb_arg); + } + + /* Set only when controller is disabled and at the end of +@@ -1058,8 +1060,6 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); +- if (vsync_cb_handler) +- vsync_cb_handler(vsync_cb_arg); + } + } + +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/100-ARM-dts-add-AM33XX-EDMA-support.patch b/target/linux/omap/patches-3.12/100-ARM-dts-add-AM33XX-EDMA-support.patch new file mode 100644 index 0000000000..f474eb812b --- /dev/null +++ b/target/linux/omap/patches-3.12/100-ARM-dts-add-AM33XX-EDMA-support.patch @@ -0,0 +1,38 @@ +Adds AM33XX EDMA support to the am33xx.dtsi as documented in +Documentation/devicetree/bindings/dma/ti-edma.txt + +[Joel Fernandes <joelf@ti.com>] +Drop DT entries that are non-hardware-description as discussed in [1] + +[1] https://patchwork.kernel.org/patch/2226761/ + +Signed-off-by: Matt Porter <mporter@ti.com> +Signed-off-by: Joel A Fernandes <joelagnel@ti.com> + +--- +arch/arm/boot/dts/am33xx.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index f9c5da9..19a1c1d 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -100,6 +100,18 @@ + reg = <0x48200000 0x1000>; + }; + ++ edma: edma@49000000 { ++ compatible = "ti,edma3"; ++ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; ++ reg = <0x49000000 0x10000>, ++ <0x44e10f90 0x10>; ++ interrupts = <12 13 14>; ++ #dma-cells = <1>; ++ dma-channels = <64>; ++ ti,edma-regions = <4>; ++ ti,edma-slots = <256>; ++ }; ++ + gpio0: gpio@44e07000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio1"; diff --git a/target/linux/omap/patches-3.12/101-ARM-dts-add-AM33XX-SPI-DMA-support.patch b/target/linux/omap/patches-3.12/101-ARM-dts-add-AM33XX-SPI-DMA-support.patch new file mode 100644 index 0000000000..afce86e4f4 --- /dev/null +++ b/target/linux/omap/patches-3.12/101-ARM-dts-add-AM33XX-SPI-DMA-support.patch @@ -0,0 +1,37 @@ +Adds DMA resources to the AM33XX SPI nodes. + +Signed-off-by: Matt Porter <mporter@ti.com> +Signed-off-by: Joel A Fernandes <joelagnel@ti.com> + +--- +arch/arm/boot/dts/am33xx.dtsi | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 19a1c1d..9ce85e5 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -335,6 +335,11 @@ + interrupts = <65>; + ti,spi-num-cs = <2>; + ti,hwmods = "spi0"; ++ dmas = <&edma 16 ++ &edma 17 ++ &edma 18 ++ &edma 19>; ++ dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + }; + +@@ -346,6 +351,11 @@ + interrupts = <125>; + ti,spi-num-cs = <2>; + ti,hwmods = "spi1"; ++ dmas = <&edma 42 ++ &edma 43 ++ &edma 44 ++ &edma 45>; ++ dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + }; + diff --git a/target/linux/omap/patches-3.12/103-ARM-dts-add-AM33XX-MMC-support-and-documentation.patch b/target/linux/omap/patches-3.12/103-ARM-dts-add-AM33XX-MMC-support-and-documentation.patch new file mode 100644 index 0000000000..b4585b1dfe --- /dev/null +++ b/target/linux/omap/patches-3.12/103-ARM-dts-add-AM33XX-MMC-support-and-documentation.patch @@ -0,0 +1,176 @@ +Adds AM33XX MMC support for am335x-bone, am335x-evm and am335x-evmsk boards. + +Also added is the DMA binding definitions based on the generic DMA request +binding. + +Additional changes made to DTS: +* Interrupt, reg and compatible properties added +* ti,needs-special-hs-handling added + +Signed-off-by: Matt Porter <mporter@ti.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Joel Fernandes <joelf@ti.com> + +--- +.../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 26 ++++++++++++++- + arch/arm/boot/dts/am335x-bone.dts | 11 +++++++ + arch/arm/boot/dts/am335x-evm.dts | 7 ++++ + arch/arm/boot/dts/am335x-evmsk.dts | 7 ++++ + arch/arm/boot/dts/am33xx.dtsi | 38 ++++++++++++++++++++++ + 5 files changed, 88 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +index ed271fc..8c8908a 100644 +--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt ++++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +@@ -20,8 +20,29 @@ ti,dual-volt: boolean, supports dual voltage cards + ti,non-removable: non-removable slot (like eMMC) + ti,needs-special-reset: Requires a special softreset sequence + ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed ++dmas: List of DMA specifiers with the controller specific format ++as described in the generic DMA client binding. A tx and rx ++specifier is required. ++dma-names: List of DMA request names. These strings correspond ++1:1 with the DMA specifiers listed in dmas. The string naming is ++to be "rx" and "tx" for RX and TX DMA requests, respectively. ++ ++Examples: ++ ++[hwmod populated DMA resources] ++ ++ mmc1: mmc@0x4809c000 { ++ compatible = "ti,omap4-hsmmc"; ++ reg = <0x4809c000 0x400>; ++ ti,hwmods = "mmc1"; ++ ti,dual-volt; ++ bus-width = <4>; ++ vmmc-supply = <&vmmc>; /* phandle to regulator node */ ++ ti,non-removable; ++ }; ++ ++[generic DMA request binding] + +-Example: + mmc1: mmc@0x4809c000 { + compatible = "ti,omap4-hsmmc"; + reg = <0x4809c000 0x400>; +@@ -30,4 +51,7 @@ Example: + bus-width = <4>; + vmmc-supply = <&vmmc>; /* phandle to regulator node */ + ti,non-removable; ++ dmas = <&edma 24 ++ &edma 25>; ++ dma-names = "tx", "rx"; + }; +diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts +index 7993c48..d5f43fe 100644 +--- a/arch/arm/boot/dts/am335x-bone.dts ++++ b/arch/arm/boot/dts/am335x-bone.dts +@@ -9,3 +9,14 @@ + + #include "am33xx.dtsi" + #include "am335x-bone-common.dtsi" ++ ++&ldo3_reg { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++}; ++ ++&mmc1 { ++ status = "okay"; ++ vmmc-supply = <&ldo3_reg>; ++}; +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index e8ec875..bc4a69d 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -477,6 +477,8 @@ + }; + + vmmc_reg: regulator@12 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +@@ -517,3 +519,8 @@ + ti,adc-channels = <4 5 6 7>; + }; + }; ++ ++&mmc1 { ++ status = "okay"; ++ vmmc-supply = <&vmmc_reg>; ++}; +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index 4f339fa..55fd194 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -393,6 +393,8 @@ + }; + + vmmc_reg: regulator@12 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +@@ -419,3 +421,8 @@ + phy_id = <&davinci_mdio>, <1>; + phy-mode = "rgmii-txid"; + }; ++ ++&mmc1 { ++ status = "okay"; ++ vmmc-supply = <&vmmc_reg>; ++}; +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 9ce85e5..0a82fca 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -240,6 +240,44 @@ + status = "disabled"; + }; + ++ mmc1: mmc@48060000 { ++ compatible = "ti,omap4-hsmmc"; ++ ti,hwmods = "mmc1"; ++ ti,dual-volt; ++ ti,needs-special-reset; ++ ti,needs-special-hs-handling; ++ dmas = <&edma 24 ++ &edma 25>; ++ dma-names = "tx", "rx"; ++ interrupts = <64>; ++ interrupt-parent = <&intc>; ++ reg = <0x48060000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ mmc2: mmc@481d8000 { ++ compatible = "ti,omap4-hsmmc"; ++ ti,hwmods = "mmc2"; ++ ti,needs-special-reset; ++ dmas = <&edma 2 ++ &edma 3>; ++ dma-names = "tx", "rx"; ++ interrupts = <28>; ++ interrupt-parent = <&intc>; ++ reg = <0x481d8000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ mmc3: mmc@47810000 { ++ compatible = "ti,omap4-hsmmc"; ++ ti,hwmods = "mmc3"; ++ ti,needs-special-reset; ++ interrupts = <29>; ++ interrupt-parent = <&intc>; ++ reg = <0x47810000 0x1000>; ++ status = "disabled"; ++ }; ++ + wdt2: wdt@44e35000 { + compatible = "ti,omap3-wdt"; + ti,hwmods = "wd_timer2"; diff --git a/target/linux/omap/patches-3.12/200-ARM-OMAP2-hwmod-cleanup-HWMOD_INIT_NO_RESET-usage.patch b/target/linux/omap/patches-3.12/200-ARM-OMAP2-hwmod-cleanup-HWMOD_INIT_NO_RESET-usage.patch new file mode 100644 index 0000000000..a0b6174cd0 --- /dev/null +++ b/target/linux/omap/patches-3.12/200-ARM-OMAP2-hwmod-cleanup-HWMOD_INIT_NO_RESET-usage.patch @@ -0,0 +1,165 @@ +For modules/IPs/hwmods which do not have +-1- sys->class->reset() +and +-2- hardreset lines +and +-3- No way to do an ocp reset (no sysc control) +the flag 'HWMOD_INIT_NO_RESET' is not much useful. + +Cleanup all such instances across various hwmod data files. + +Signed-off-by: Rajendra Nayak <rnayak@ti.com> + +--- +arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 18 +++++++++--------- + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 6 +++--- + arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 6 +++--- + 3 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +index 215894f..2815a91 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +@@ -52,7 +52,7 @@ static struct omap_hwmod am33xx_emif_hwmod = { + .name = "emif", + .class = &am33xx_emif_hwmod_class, + .clkdm_name = "l3_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_ddr_m2_div2_ck", + .prcm = { + .omap4 = { +@@ -74,7 +74,7 @@ static struct omap_hwmod am33xx_l3_main_hwmod = { + .name = "l3_main", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { +@@ -96,7 +96,7 @@ static struct omap_hwmod am33xx_l3_instr_hwmod = { + .name = "l3_instr", + .class = &am33xx_l3_hwmod_class, + .clkdm_name = "l3_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { +@@ -119,7 +119,7 @@ static struct omap_hwmod am33xx_l4_ls_hwmod = { + .name = "l4_ls", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4ls_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { +@@ -134,7 +134,7 @@ static struct omap_hwmod am33xx_l4_hs_hwmod = { + .name = "l4_hs", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4hs_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l4hs_gclk", + .prcm = { + .omap4 = { +@@ -150,7 +150,7 @@ static struct omap_hwmod am33xx_l4_wkup_hwmod = { + .name = "l4_wkup", + .class = &am33xx_l4_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, +@@ -170,7 +170,7 @@ static struct omap_hwmod am33xx_mpu_hwmod = { + .name = "mpu", + .class = &am33xx_mpu_hwmod_class, + .clkdm_name = "mpu_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { +@@ -450,7 +450,7 @@ static struct omap_hwmod am33xx_ocmcram_hwmod = { + .name = "ocmcram", + .class = &am33xx_ocmcram_hwmod_class, + .clkdm_name = "l3_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { +@@ -532,7 +532,7 @@ static struct omap_hwmod am33xx_control_hwmod = { + .name = "control", + .class = &am33xx_control_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_m4_div2_ck", + .prcm = { + .omap4 = { +diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +index 9c3b504..1e5b12c 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +@@ -914,7 +914,7 @@ static struct omap_hwmod omap44xx_emif1_hwmod = { + .name = "emif1", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { +@@ -930,7 +930,7 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { + .name = "emif2", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { +@@ -2193,7 +2193,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { + .name = "mpu", + .class = &omap44xx_mpu_hwmod_class, + .clkdm_name = "mpuss_clkdm", +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { +diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +index cde4155..e3caee1 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +@@ -352,7 +352,7 @@ static struct omap_hwmod omap54xx_emif1_hwmod = { + .name = "emif1", + .class = &omap54xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_h11x2_ck", + .prcm = { + .omap4 = { +@@ -368,7 +368,7 @@ static struct omap_hwmod omap54xx_emif2_hwmod = { + .name = "emif2", + .class = &omap54xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_h11x2_ck", + .prcm = { + .omap4 = { +@@ -1135,7 +1135,7 @@ static struct omap_hwmod omap54xx_mpu_hwmod = { + .name = "mpu", + .class = &omap54xx_mpu_hwmod_class, + .clkdm_name = "mpu_clkdm", +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_mpu_m2_ck", + .prcm = { + .omap4 = { diff --git a/target/linux/omap/patches-3.12/201-ARM-dts-omap-Add-new-bindings-for-OMAP.patch b/target/linux/omap/patches-3.12/201-ARM-dts-omap-Add-new-bindings-for-OMAP.patch new file mode 100644 index 0000000000..7dd44772c2 --- /dev/null +++ b/target/linux/omap/patches-3.12/201-ARM-dts-omap-Add-new-bindings-for-OMAP.patch @@ -0,0 +1,105 @@ +On OMAP we have co-processor IPs, memory controllers, +GPIOs which control regulators and power switches to +PMIC, and SoC internal Bus IPs, some or most of which +should either not be reset or idled or both at init. +(In some cases there are erratas which prevent an IP +from being reset) +Have a way to pass this information from DT. + +Update the am33xx/omap4 and omap5 dtsi files with the +new bindings for modules which either should not be +idled. reset or both. A later patch would cleanup the +same information that exists today as part of the hwmod +data files. + +Signed-off-by: Rajendra Nayak <rnayak@ti.com> + +--- +.../devicetree/bindings/arm/omap/omap.txt | 3 ++- + arch/arm/boot/dts/am33xx.dtsi | 2 ++ + arch/arm/boot/dts/omap4.dtsi | 3 +++ + arch/arm/boot/dts/omap5.dtsi | 2 ++ + 4 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt +index 91b7049..808c154 100644 +--- a/Documentation/devicetree/bindings/arm/omap/omap.txt ++++ b/Documentation/devicetree/bindings/arm/omap/omap.txt +@@ -21,7 +21,8 @@ Required properties: + Optional properties: + - ti,no_idle_on_suspend: When present, it prevents the PM to idle the module + during suspend. +- ++- ti,no-reset-on-init: When present, the module should not be reset at init ++- ti,no-idle-on-init: When present, the module should not be idled at init + + Example: + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index f9c5da9..ec33ea0 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -607,6 +607,7 @@ + reg = <0x44d00000 0x4000 /* M3 UMEM */ + 0x44d80000 0x2000>; /* M3 DMEM */ + ti,hwmods = "wkup_m3"; ++ ti,no-reset-on-init; + }; + + elm: elm@48080000 { +@@ -637,6 +638,7 @@ + gpmc: gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + ti,hwmods = "gpmc"; ++ ti,no-idle-on-init; + reg = <0x50000000 0x2000>; + interrupts = <100>; + gpmc,num-cs = <7>; +diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi +index 22d9f2b..e8fe797 100644 +--- a/arch/arm/boot/dts/omap4.dtsi ++++ b/arch/arm/boot/dts/omap4.dtsi +@@ -214,6 +214,7 @@ + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + ti,hwmods = "gpmc"; ++ ti,no-idle-on-init; + }; + + uart1: serial@4806a000 { +@@ -492,6 +493,7 @@ + reg = <0x4c000000 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "emif1"; ++ ti,no-idle-on-init; + phy-type = <1>; + hw-caps-read-idle-ctrl; + hw-caps-ll-interface; +@@ -503,6 +505,7 @@ + reg = <0x4d000000 0x100>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + ti,hwmods = "emif2"; ++ ti,no-idle-on-init; + phy-type = <1>; + hw-caps-read-idle-ctrl; + hw-caps-ll-interface; +diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi +index 7cdea1b..a9d49df 100644 +--- a/arch/arm/boot/dts/omap5.dtsi ++++ b/arch/arm/boot/dts/omap5.dtsi +@@ -607,6 +607,7 @@ + emif1: emif@0x4c000000 { + compatible = "ti,emif-4d5"; + ti,hwmods = "emif1"; ++ ti,no-idle-on-init; + phy-type = <2>; /* DDR PHY type: Intelli PHY */ + reg = <0x4c000000 0x400>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; +@@ -618,6 +619,7 @@ + emif2: emif@0x4d000000 { + compatible = "ti,emif-4d5"; + ti,hwmods = "emif2"; ++ ti,no-idle-on-init; + phy-type = <2>; /* DDR PHY type: Intelli PHY */ + reg = <0x4d000000 0x400>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; diff --git a/target/linux/omap/patches-3.12/202-ARM-OMAP2-hwmod-Extract-no-idle-and-no-reset-info-from-DT.patch b/target/linux/omap/patches-3.12/202-ARM-OMAP2-hwmod-Extract-no-idle-and-no-reset-info-from-DT.patch new file mode 100644 index 0000000000..129f895fd1 --- /dev/null +++ b/target/linux/omap/patches-3.12/202-ARM-OMAP2-hwmod-Extract-no-idle-and-no-reset-info-from-DT.patch @@ -0,0 +1,75 @@ +Now that we have DT bindings to specify which devices should not +be reset and idled during init, make hwmod extract the information +(and store them in internal flags) from Device tree. + +Signed-off-by: Rajendra Nayak <rnayak@ti.com> + +--- +arch/arm/mach-omap2/omap_hwmod.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c +index d9ee0ff..b55923a 100644 +--- a/arch/arm/mach-omap2/omap_hwmod.c ++++ b/arch/arm/mach-omap2/omap_hwmod.c +@@ -2363,11 +2363,11 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np, + * are part of the device's address space can be ioremapped properly. + * No return value. + */ +-static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) ++static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, ++ struct device_node *np) + { + struct omap_hwmod_addr_space *mem; + void __iomem *va_start = NULL; +- struct device_node *np; + + if (!oh) + return; +@@ -2383,12 +2383,10 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) + oh->name); + + /* Extract the IO space from device tree blob */ +- if (!of_have_populated_dt()) ++ if (!np) + return; + +- np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); +- if (np) +- va_start = of_iomap(np, oh->mpu_rt_idx); ++ va_start = of_iomap(np, oh->mpu_rt_idx); + } else { + va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); + } +@@ -2420,12 +2418,16 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) + static int __init _init(struct omap_hwmod *oh, void *data) + { + int r; ++ struct device_node *np = NULL; + + if (oh->_state != _HWMOD_STATE_REGISTERED) + return 0; + ++ if (of_have_populated_dt()) ++ np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); ++ + if (oh->class->sysc) +- _init_mpu_rt_base(oh, NULL); ++ _init_mpu_rt_base(oh, NULL, np); + + r = _init_clocks(oh, NULL); + if (r < 0) { +@@ -2433,6 +2435,13 @@ static int __init _init(struct omap_hwmod *oh, void *data) + return -EINVAL; + } + ++ if (np) { ++ if (of_find_property(np, "ti,no-reset-on-init", NULL)) ++ oh->flags |= HWMOD_INIT_NO_RESET; ++ if (of_find_property(np, "ti,no-idle-on-init", NULL)) ++ oh->flags |= HWMOD_INIT_NO_IDLE; ++ } ++ + oh->_state = _HWMOD_STATE_INITIALIZED; + + return 0; diff --git a/target/linux/omap/patches-3.12/203-ARM-OMAP2-hwmod-Cleanup-usag~RESET-and-HWMOD_INIT_NO_IDLE.patch b/target/linux/omap/patches-3.12/203-ARM-OMAP2-hwmod-Cleanup-usag~RESET-and-HWMOD_INIT_NO_IDLE.patch new file mode 100644 index 0000000000..c014311969 --- /dev/null +++ b/target/linux/omap/patches-3.12/203-ARM-OMAP2-hwmod-Cleanup-usag~RESET-and-HWMOD_INIT_NO_IDLE.patch @@ -0,0 +1,92 @@ +With DT bindings to specify which devices should not be idled and reset +at init being in place, and the corresponding dtsi files for am33xx/omap4 +and omap5 updated using those bindings, we can now clean up hwmod internal +flags for HWMOD_INIT_NO_RESET and HWMOD_INIT_NO_IDLE which were infact used +to specify the exact same information. + +For GPMC, the HWMOD_INIT_NO_RESET flag seems to be added in hwmod not due to +any errata around the GPMC IP, but rather because any timings +set by the bootloader are not being correctly programmed by the kernel. +This seems like something that needs to be fixed as part of GPMC driver +in the kernel, and hence the flag is left as is in hwmod, which can be +removed once the driver does what its expected to. + +Signed-off-by: Rajendra Nayak <rnayak@ti.com> + +--- +arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 4 ++-- + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 4 +--- + arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 2 -- + 3 files changed, 3 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +index 2815a91..e8dc72d 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +@@ -198,7 +198,7 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = { + .class = &am33xx_wkup_m3_hwmod_class, + .clkdm_name = "l4_wkup_aon_clkdm", + /* Keep hardreset asserted */ +- .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, ++ .flags = HWMOD_NO_IDLEST, + .main_clk = "dpll_core_m4_div2_ck", + .prcm = { + .omap4 = { +@@ -932,7 +932,7 @@ static struct omap_hwmod am33xx_gpmc_hwmod = { + .name = "gpmc", + .class = &am33xx_gpmc_hwmod_class, + .clkdm_name = "l3s_clkdm", +- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), ++ .flags = HWMOD_INIT_NO_RESET, + .main_clk = "l3s_gclk", + .prcm = { + .omap4 = { +diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +index 1e5b12c..a507a70 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +@@ -914,7 +914,6 @@ static struct omap_hwmod omap44xx_emif1_hwmod = { + .name = "emif1", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { +@@ -930,7 +929,6 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { + .name = "emif2", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { +@@ -1184,7 +1182,7 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = { + * the kernel from the board file or DT data. + * HWMOD_INIT_NO_RESET should be removed ASAP. + */ +- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, ++ .flags = HWMOD_INIT_NO_RESET, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, +diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +index e3caee1..e47f24d 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +@@ -352,7 +352,6 @@ static struct omap_hwmod omap54xx_emif1_hwmod = { + .name = "emif1", + .class = &omap54xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_h11x2_ck", + .prcm = { + .omap4 = { +@@ -368,7 +367,6 @@ static struct omap_hwmod omap54xx_emif2_hwmod = { + .name = "emif2", + .class = &omap54xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", +- .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_core_h11x2_ck", + .prcm = { + .omap4 = { diff --git a/target/linux/omap/patches-3.12/204-ARM-dts-AM335x-evmsk-Do-not-reset-gpio0.patch b/target/linux/omap/patches-3.12/204-ARM-dts-AM335x-evmsk-Do-not-reset-gpio0.patch new file mode 100644 index 0000000000..fce95abeca --- /dev/null +++ b/target/linux/omap/patches-3.12/204-ARM-dts-AM335x-evmsk-Do-not-reset-gpio0.patch @@ -0,0 +1,24 @@ +Do not reset GPIO0 at boot-up because GPIO0 is used +on AM335x EVM-SK to control VTT regulators on DDR3. + +Without this EVM-SK boards fail to boot-up because +of DDR3 corruption. + +Signed-off-by: Rajendra Nayak <rnayak@ti.com> + +--- +arch/arm/boot/dts/am335x-evmsk.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index 4f339fa..0e44d29 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -419,3 +419,7 @@ + phy_id = <&davinci_mdio>, <1>; + phy-mode = "rgmii-txid"; + }; ++ ++&gpio0 { ++ ti,no-reset-on-init; ++}; diff --git a/target/linux/omap/patches-3.12/300-ARM-dts-AM33XX-Add-SHAM-data-and-documentation.patch b/target/linux/omap/patches-3.12/300-ARM-dts-AM33XX-Add-SHAM-data-and-documentation.patch new file mode 100644 index 0000000000..c4525c46bd --- /dev/null +++ b/target/linux/omap/patches-3.12/300-ARM-dts-AM33XX-Add-SHAM-data-and-documentation.patch @@ -0,0 +1,108 @@ +Add the generic AM33XX SHAM module's device tree data and +enable it for the am335x-evm, am335x-evmsk, and am335x-bone +platforms. Also add Documentation file describing the data +for the SHAM module. + +[joelf@ti.com: Dropped interrupt-parrent property, documentation fixups] +CC: Paul Walmsley <paul@pwsan.com> +Signed-off-by: Mark A. Greer <mgreer@animalcreek.com> +Acked-by: Mark Rutland <mark.rutland@arm.com> + +--- +.../devicetree/bindings/crypto/omap-sham.txt | 28 ++++++++++++++++++++++ + arch/arm/boot/dts/am335x-bone.dts | 4 ++++ + arch/arm/boot/dts/am335x-evm.dts | 4 ++++ + arch/arm/boot/dts/am335x-evmsk.dts | 4 ++++ + arch/arm/boot/dts/am33xx.dtsi | 9 +++++++ + 5 files changed, 49 insertions(+) + create mode 100644 Documentation/devicetree/bindings/crypto/omap-sham.txt + +diff --git a/Documentation/devicetree/bindings/crypto/omap-sham.txt b/Documentation/devicetree/bindings/crypto/omap-sham.txt +new file mode 100644 +index 0000000..f839acd +--- /dev/null ++++ b/Documentation/devicetree/bindings/crypto/omap-sham.txt +@@ -0,0 +1,28 @@ ++OMAP SoC SHA crypto Module ++ ++Required properties: ++ ++- compatible : Should contain entries for this and backward compatible ++ SHAM versions: ++ - "ti,omap2-sham" for OMAP2 & OMAP3. ++ - "ti,omap4-sham" for OMAP4 and AM33XX. ++ Note that these two versions are incompatible. ++- ti,hwmods: Name of the hwmod associated with the SHAM module ++- reg : Offset and length of the register set for the module ++- interrupts : the interrupt-specifier for the SHAM module. ++ ++Optional properties: ++- dmas: DMA specifiers for the rx dma. See the DMA client binding, ++ Documentation/devicetree/bindings/dma/dma.txt ++- dma-names: DMA request name. Should be "rx" if a dma is present. ++ ++Example: ++ /* AM335x */ ++ sham: sham@53100000 { ++ compatible = "ti,omap4-sham"; ++ ti,hwmods = "sham"; ++ reg = <0x53100000 0x200>; ++ interrupts = <109>; ++ dmas = <&edma 36>; ++ dma-names = "rx"; ++ }; +diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts +index 0d63348..8a9802e 100644 +--- a/arch/arm/boot/dts/am335x-bone.dts ++++ b/arch/arm/boot/dts/am335x-bone.dts +@@ -19,3 +19,7 @@ + &mmc1 { + vmmc-supply = <&ldo3_reg>; + }; ++ ++&sham { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index 23b0a3e..d59e51c 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -522,3 +522,7 @@ + status = "okay"; + vmmc-supply = <&vmmc_reg>; + }; ++ ++&sham { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index bc93895..d45a330 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -424,3 +424,7 @@ + status = "okay"; + vmmc-supply = <&vmmc_reg>; + }; ++ ++&sham { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 553adc6..299710b 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -710,5 +710,14 @@ + #size-cells = <1>; + status = "disabled"; + }; ++ ++ sham: sham@53100000 { ++ compatible = "ti,omap4-sham"; ++ ti,hwmods = "sham"; ++ reg = <0x53100000 0x200>; ++ interrupts = <109>; ++ dmas = <&edma 36>; ++ dma-names = "rx"; ++ }; + }; + }; diff --git a/target/linux/omap/patches-3.12/301-ARM-dts-AM33XX-Add-AES-data-and-documentation.patch b/target/linux/omap/patches-3.12/301-ARM-dts-AM33XX-Add-AES-data-and-documentation.patch new file mode 100644 index 0000000000..52763c304d --- /dev/null +++ b/target/linux/omap/patches-3.12/301-ARM-dts-AM33XX-Add-AES-data-and-documentation.patch @@ -0,0 +1,112 @@ +Add the generic AM33XX AES module's device tree data and +enable it for the am335x-evm, am335x-evmsk, and am335x-bone +platforms. Also add Documentation file describing the data +for the AES module. + +[joelf@ti.com: Dropped interrupt-parent propert, documentation fixups] + +CC: Paul Walmsley <paul@pwsan.com> +Signed-off-by: Mark A. Greer <mgreer@animalcreek.com> + +--- +.../devicetree/bindings/crypto/omap-aes.txt | 31 ++++++++++++++++++++++ + arch/arm/boot/dts/am335x-bone.dts | 4 +++ + arch/arm/boot/dts/am335x-evm.dts | 4 +++ + arch/arm/boot/dts/am335x-evmsk.dts | 4 +++ + arch/arm/boot/dts/am33xx.dtsi | 10 +++++++ + 5 files changed, 53 insertions(+) + create mode 100644 Documentation/devicetree/bindings/crypto/omap-aes.txt + +diff --git a/Documentation/devicetree/bindings/crypto/omap-aes.txt b/Documentation/devicetree/bindings/crypto/omap-aes.txt +new file mode 100644 +index 0000000..fd97176 +--- /dev/null ++++ b/Documentation/devicetree/bindings/crypto/omap-aes.txt +@@ -0,0 +1,31 @@ ++OMAP SoC AES crypto Module ++ ++Required properties: ++ ++- compatible : Should contain entries for this and backward compatible ++ AES versions: ++ - "ti,omap2-aes" for OMAP2. ++ - "ti,omap3-aes" for OMAP3. ++ - "ti,omap4-aes" for OMAP4 and AM33XX. ++ Note that the OMAP2 and 3 versions are compatible (OMAP3 supports ++ more algorithms) but they are incompatible with OMAP4. ++- ti,hwmods: Name of the hwmod associated with the AES module ++- reg : Offset and length of the register set for the module ++- interrupts : the interrupt-specifier for the AES module. ++ ++Optional properties: ++- dmas: DMA specifiers for tx and rx dma. See the DMA client binding, ++ Documentation/devicetree/bindings/dma/dma.txt ++- dma-names: DMA request names should include "tx" and "rx" if present. ++ ++Example: ++ /* AM335x */ ++ aes: aes@53500000 { ++ compatible = "ti,omap4-aes"; ++ ti,hwmods = "aes"; ++ reg = <0x53500000 0xa0>; ++ interrupts = <102>; ++ dmas = <&edma 6>, ++ <&edma 5>; ++ dma-names = "tx", "rx"; ++ }; +diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts +index 8a9802e..94ee427 100644 +--- a/arch/arm/boot/dts/am335x-bone.dts ++++ b/arch/arm/boot/dts/am335x-bone.dts +@@ -23,3 +23,7 @@ + &sham { + status = "okay"; + }; ++ ++&aes { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index d59e51c..86463fa 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -526,3 +526,7 @@ + &sham { + status = "okay"; + }; ++ ++&aes { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index d45a330..f577e65 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -428,3 +428,7 @@ + &sham { + status = "okay"; + }; ++ ++&aes { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 299710b..2664da9 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -719,5 +719,15 @@ + dmas = <&edma 36>; + dma-names = "rx"; + }; ++ ++ aes: aes@53500000 { ++ compatible = "ti,omap4-aes"; ++ ti,hwmods = "aes"; ++ reg = <0x53500000 0xa0>; ++ interrupts = <102>; ++ dmas = <&edma 6>, ++ <&edma 5>; ++ dma-names = "tx", "rx"; ++ }; + }; + }; diff --git a/target/linux/omap/patches-3.12/302-ARM-dts-AM33XX-Fix-AES-interrupt-number.patch b/target/linux/omap/patches-3.12/302-ARM-dts-AM33XX-Fix-AES-interrupt-number.patch new file mode 100644 index 0000000000..1a2517ef7d --- /dev/null +++ b/target/linux/omap/patches-3.12/302-ARM-dts-AM33XX-Fix-AES-interrupt-number.patch @@ -0,0 +1,23 @@ +AES interrupts were previously not used, but after recent changes to omap-aes +driver, its being used. We correct the interrupt number to have working PIO +mode. + +Signed-off-by: Joel Fernandes <joelf@ti.com> + +--- +arch/arm/boot/dts/am33xx.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 2664da9..5c2d6c1 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -724,7 +724,7 @@ + compatible = "ti,omap4-aes"; + ti,hwmods = "aes"; + reg = <0x53500000 0xa0>; +- interrupts = <102>; ++ interrupts = <103>; + dmas = <&edma 6>, + <&edma 5>; + dma-names = "tx", "rx"; diff --git a/target/linux/omap/patches-3.12/350-ARM-AM33xx-hwmod-Add-RNG-module-data.patch b/target/linux/omap/patches-3.12/350-ARM-AM33xx-hwmod-Add-RNG-module-data.patch new file mode 100644 index 0000000000..5ca27904c9 --- /dev/null +++ b/target/linux/omap/patches-3.12/350-ARM-AM33xx-hwmod-Add-RNG-module-data.patch @@ -0,0 +1,64 @@ +Add RNG hwmod data for AM33xx SoC. + +Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> + +--- +* Made am33xx_l4_per__rng structure as static to fix sparse warning + + arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 36 ++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +index 215894f..3e32f45 100644 +--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c ++++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +@@ -2480,6 +2480,41 @@ static struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = { + .user = OCP_USER_MPU | OCP_USER_SDMA, + }; + ++/* rng */ ++static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = { ++ .rev_offs = 0x1fe0, ++ .sysc_offs = 0x1fe4, ++ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE, ++ .idlemodes = SIDLE_FORCE | SIDLE_NO, ++ .sysc_fields = &omap_hwmod_sysc_type1, ++}; ++ ++static struct omap_hwmod_class am33xx_rng_hwmod_class = { ++ .name = "rng", ++ .sysc = &am33xx_rng_sysc, ++}; ++ ++static struct omap_hwmod am33xx_rng_hwmod = { ++ .name = "rng", ++ .class = &am33xx_rng_hwmod_class, ++ .clkdm_name = "l4ls_clkdm", ++ .flags = HWMOD_SWSUP_SIDLE, ++ .main_clk = "rng_fck", ++ .prcm = { ++ .omap4 = { ++ .clkctrl_offs = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET, ++ .modulemode = MODULEMODE_SWCTRL, ++ }, ++ }, ++}; ++ ++static struct omap_hwmod_ocp_if am33xx_l4_per__rng = { ++ .master = &am33xx_l4_ls_hwmod, ++ .slave = &am33xx_rng_hwmod, ++ .clk = "rng_fck", ++ .user = OCP_USER_MPU, ++}; ++ + static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { + &am33xx_l3_main__emif, + &am33xx_mpu__l3_main, +@@ -2559,6 +2594,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { + &am33xx_cpgmac0__mdio, + &am33xx_l3_main__sha0, + &am33xx_l3_main__aes0, ++ &am33xx_l4_per__rng, + NULL, + }; + diff --git a/target/linux/omap/patches-3.12/400-ASoC-davinci-evm-Move-sysclk-logic-away-from-evm_hw_.patch b/target/linux/omap/patches-3.12/400-ASoC-davinci-evm-Move-sysclk-logic-away-from-evm_hw_.patch new file mode 100644 index 0000000000..292fda8eb8 --- /dev/null +++ b/target/linux/omap/patches-3.12/400-ASoC-davinci-evm-Move-sysclk-logic-away-from-evm_hw_.patch @@ -0,0 +1,150 @@ +From 13254d51149ce1a0fdbb38fa229c6cc91bcbe6ec Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Fri, 13 Sep 2013 17:43:18 +0300 +Subject: [PATCH 211/752] ASoC: davinci-evm: Move sysclk logic away from + evm_hw_params + +The sysclk rate does not change runtime so it should be initialized at +init time. + +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + sound/soc/davinci/davinci-evm.c | 64 +++++++++++++++++++++++++++------------ + 1 file changed, 44 insertions(+), 20 deletions(-) + +diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c +index fd7c45b..2f8161c 100644 +--- a/sound/soc/davinci/davinci-evm.c ++++ b/sound/soc/davinci/davinci-evm.c +@@ -27,6 +27,10 @@ + #include "davinci-i2s.h" + #include "davinci-mcasp.h" + ++struct snd_soc_card_drvdata_davinci { ++ unsigned sysclk; ++}; ++ + #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ + SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) + static int evm_hw_params(struct snd_pcm_substream *substream, +@@ -35,27 +39,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream, + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ struct snd_soc_codec *codec = rtd->codec; ++ struct snd_soc_card *soc_card = codec->card; + int ret = 0; +- unsigned sysclk; +- +- /* ASP1 on DM355 EVM is clocked by an external oscillator */ +- if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() || +- machine_is_davinci_dm365_evm()) +- sysclk = 27000000; +- +- /* ASP0 in DM6446 EVM is clocked by U55, as configured by +- * board-dm644x-evm.c using GPIOs from U18. There are six +- * options; here we "know" we use a 48 KHz sample rate. +- */ +- else if (machine_is_davinci_evm()) +- sysclk = 12288000; +- +- else if (machine_is_davinci_da830_evm() || +- machine_is_davinci_da850_evm()) +- sysclk = 24576000; +- +- else +- return -EINVAL; ++ unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *) ++ snd_soc_card_get_drvdata(soc_card))->sysclk; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); +@@ -243,35 +231,65 @@ static struct snd_soc_dai_link da850_evm_dai = { + }; + + /* davinci dm6446 evm audio machine driver */ ++/* ++ * ASP0 in DM6446 EVM is clocked by U55, as configured by ++ * board-dm644x-evm.c using GPIOs from U18. There are six ++ * options; here we "know" we use a 48 KHz sample rate. ++ */ ++static struct snd_soc_card_drvdata_davinci dm6446_snd_soc_card_drvdata = { ++ .sysclk = 12288000, ++}; ++ + static struct snd_soc_card dm6446_snd_soc_card_evm = { + .name = "DaVinci DM6446 EVM", + .owner = THIS_MODULE, + .dai_link = &dm6446_evm_dai, + .num_links = 1, ++ .drvdata = &dm6446_snd_soc_card_drvdata, + }; + + /* davinci dm355 evm audio machine driver */ ++/* ASP1 on DM355 EVM is clocked by an external oscillator */ ++static struct snd_soc_card_drvdata_davinci dm355_snd_soc_card_drvdata = { ++ .sysclk = 27000000, ++}; ++ + static struct snd_soc_card dm355_snd_soc_card_evm = { + .name = "DaVinci DM355 EVM", + .owner = THIS_MODULE, + .dai_link = &dm355_evm_dai, + .num_links = 1, ++ .drvdata = &dm355_snd_soc_card_drvdata, + }; + + /* davinci dm365 evm audio machine driver */ ++static struct snd_soc_card_drvdata_davinci dm365_snd_soc_card_drvdata = { ++ .sysclk = 27000000, ++}; ++ + static struct snd_soc_card dm365_snd_soc_card_evm = { + .name = "DaVinci DM365 EVM", + .owner = THIS_MODULE, + .dai_link = &dm365_evm_dai, + .num_links = 1, ++ .drvdata = &dm365_snd_soc_card_drvdata, + }; + + /* davinci dm6467 evm audio machine driver */ ++static struct snd_soc_card_drvdata_davinci dm6467_snd_soc_card_drvdata = { ++ .sysclk = 27000000, ++}; ++ + static struct snd_soc_card dm6467_snd_soc_card_evm = { + .name = "DaVinci DM6467 EVM", + .owner = THIS_MODULE, + .dai_link = dm6467_evm_dai, + .num_links = ARRAY_SIZE(dm6467_evm_dai), ++ .drvdata = &dm6467_snd_soc_card_drvdata, ++}; ++ ++static struct snd_soc_card_drvdata_davinci da830_snd_soc_card_drvdata = { ++ .sysclk = 24576000, + }; + + static struct snd_soc_card da830_snd_soc_card = { +@@ -279,6 +297,11 @@ static struct snd_soc_card da830_snd_soc_card = { + .owner = THIS_MODULE, + .dai_link = &da830_evm_dai, + .num_links = 1, ++ .drvdata = &da830_snd_soc_card_drvdata, ++}; ++ ++static struct snd_soc_card_drvdata_davinci da850_snd_soc_card_drvdata = { ++ .sysclk = 24576000, + }; + + static struct snd_soc_card da850_snd_soc_card = { +@@ -286,6 +309,7 @@ static struct snd_soc_card da850_snd_soc_card = { + .owner = THIS_MODULE, + .dai_link = &da850_evm_dai, + .num_links = 1, ++ .drvdata = &da850_snd_soc_card_drvdata, + }; + + static struct platform_device *evm_snd_device; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/401-ASoC-davinci-evm-Add-device-tree-binding.patch b/target/linux/omap/patches-3.12/401-ASoC-davinci-evm-Add-device-tree-binding.patch new file mode 100644 index 0000000000..a3cbfb7bc5 --- /dev/null +++ b/target/linux/omap/patches-3.12/401-ASoC-davinci-evm-Add-device-tree-binding.patch @@ -0,0 +1,261 @@ +From af9ef849e8700327b807361344427a43c38e823a Mon Sep 17 00:00:00 2001 +From: "Hebbar, Gururaja" <gururaja.hebbar@ti.com> +Date: Tue, 31 Jul 2012 21:25:38 +0530 +Subject: [PATCH 212/752] ASoC: davinci-evm: Add device tree binding + +Device tree support for Davinci Machine driver + +When the board boots with device tree, the driver will receive card, +codec, dai interface details (like the card name, DAPM routing map, +phandle for the audio components described in the dts file, codec mclk +speed). The card will be set up based on this information. Since the +routing is provided via DT we can mark the card fully routed so core +can take care of disconnecting the unused pins. + +Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com> +Signed-off-by: Darren Etheridge <detheridge@ti.com> +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + .../bindings/sound/davinci-evm-audio.txt | 58 ++++++++++ + sound/soc/davinci/davinci-evm.c | 120 +++++++++++++++++++- + 2 files changed, 176 insertions(+), 2 deletions(-) + create mode 100644 Documentation/devicetree/bindings/sound/davinci-evm-audio.txt + +diff --git a/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt +new file mode 100644 +index 0000000..e6b61ff +--- /dev/null ++++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt +@@ -0,0 +1,58 @@ ++* Texas Instruments SoC audio setups with TLV320AIC3X Codec ++ ++Required properties: ++- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx ++- ti,model : The user-visible name of this sound complex. ++- ti,audio-codec : The phandle of the TLV320AIC3x audio codec ++- ti,mcasp-controller : The phandle of the McASP controller ++- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec ++- ti,audio-routing : A list of the connections between audio components. ++ Each entry is a pair of strings, the first being the connection's sink, ++ the second being the connection's source. Valid names for sources and ++ sinks are the codec's pins, and the jacks on the board: ++ ++ TLV320AIC3X pins: ++ ++ * LLOUT ++ * RLOUT ++ * MONO_LOUT ++ * HPLOUT ++ * HPROUT ++ * HPLCOM ++ * HPRCOM ++ * MIC3L ++ * MIC3R ++ * LINE1L ++ * LINE2L ++ * LINE1R ++ * LINE2R ++ ++ Board connectors: ++ ++ * Headphone Jack ++ * Line Out ++ * Mic Jack ++ * Line In ++ ++ ++Example: ++ ++sound { ++ compatible = "ti,da830-evm-audio"; ++ ti,model = "DA830 EVM"; ++ ti,audio-codec = <&tlv320aic3x>; ++ ti,mcasp-controller = <&mcasp1>; ++ ti,codec-clock-rate = <12000000>; ++ ti,audio-routing = ++ "Headphone Jack", "HPLOUT", ++ "Headphone Jack", "HPROUT", ++ "Line Out", "LLOUT", ++ "Line Out", "RLOUT", ++ "MIC3L", "Mic Bias 2V", ++ "MIC3R", "Mic Bias 2V", ++ "Mic Bias 2V", "Mic Jack", ++ "LINE1L", "Line In", ++ "LINE2L", "Line In", ++ "LINE1R", "Line In", ++ "LINE2R", "Line In"; ++}; +diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c +index 2f8161c..340a68d 100644 +--- a/sound/soc/davinci/davinci-evm.c ++++ b/sound/soc/davinci/davinci-evm.c +@@ -16,6 +16,7 @@ + #include <linux/platform_device.h> + #include <linux/platform_data/edma.h> + #include <linux/i2c.h> ++#include <linux/of_platform.h> + #include <sound/core.h> + #include <sound/pcm.h> + #include <sound/soc.h> +@@ -23,6 +24,8 @@ + #include <asm/dma.h> + #include <asm/mach-types.h> + ++#include <linux/edma.h> ++ + #include "davinci-pcm.h" + #include "davinci-i2s.h" + #include "davinci-mcasp.h" +@@ -121,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) + { + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; ++ struct device_node *np = codec->card->dev->of_node; ++ int ret; + + /* Add davinci-evm specific widgets */ + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, + ARRAY_SIZE(aic3x_dapm_widgets)); + +- /* Set up davinci-evm specific audio path audio_map */ +- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); ++ if (np) { ++ ret = snd_soc_of_parse_audio_routing(codec->card, ++ "ti,audio-routing"); ++ if (ret) ++ return ret; ++ } else { ++ /* Set up davinci-evm specific audio path audio_map */ ++ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); ++ } + + /* not connected */ + snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); +@@ -312,6 +324,98 @@ static struct snd_soc_card da850_snd_soc_card = { + .drvdata = &da850_snd_soc_card_drvdata, + }; + ++#if defined(CONFIG_OF) ++ ++/* ++ * The struct is used as place holder. It will be completely ++ * filled with data from dt node. ++ */ ++static struct snd_soc_dai_link evm_dai_tlv320aic3x = { ++ .name = "TLV320AIC3X", ++ .stream_name = "AIC3X", ++ .codec_dai_name = "tlv320aic3x-hifi", ++ .ops = &evm_ops, ++ .init = evm_aic3x_init, ++}; ++ ++static const struct of_device_id davinci_evm_dt_ids[] = { ++ { ++ .compatible = "ti,da830-evm-audio", ++ .data = (void *) &evm_dai_tlv320aic3x, ++ }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids); ++ ++/* davinci evm audio machine driver */ ++static struct snd_soc_card evm_soc_card = { ++ .owner = THIS_MODULE, ++ .num_links = 1, ++}; ++ ++static int davinci_evm_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ const struct of_device_id *match = ++ of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); ++ struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data; ++ struct snd_soc_card_drvdata_davinci *drvdata = NULL; ++ int ret = 0; ++ ++ evm_soc_card.dai_link = dai; ++ ++ dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0); ++ if (!dai->codec_of_node) ++ return -EINVAL; ++ ++ dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0); ++ if (!dai->cpu_of_node) ++ return -EINVAL; ++ ++ dai->platform_of_node = dai->cpu_of_node; ++ ++ evm_soc_card.dev = &pdev->dev; ++ ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); ++ if (ret) ++ return ret; ++ ++ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); ++ if (!drvdata) ++ return -ENOMEM; ++ ++ ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk); ++ if (ret < 0) ++ return -EINVAL; ++ ++ snd_soc_card_set_drvdata(&evm_soc_card, drvdata); ++ ret = snd_soc_register_card(&evm_soc_card); ++ ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); ++ ++ return ret; ++} ++ ++static int davinci_evm_remove(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = platform_get_drvdata(pdev); ++ ++ snd_soc_unregister_card(card); ++ ++ return 0; ++} ++ ++static struct platform_driver davinci_evm_driver = { ++ .probe = davinci_evm_probe, ++ .remove = davinci_evm_remove, ++ .driver = { ++ .name = "davinci_evm", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(davinci_evm_dt_ids), ++ }, ++}; ++#endif ++ + static struct platform_device *evm_snd_device; + + static int __init evm_init(void) +@@ -320,6 +424,13 @@ static int __init evm_init(void) + int index; + int ret; + ++ /* ++ * If dtb is there, the devices will be created dynamically. ++ * Only register platfrom driver structure. ++ */ ++ if (of_have_populated_dt()) ++ return platform_driver_register(&davinci_evm_driver); ++ + if (machine_is_davinci_evm()) { + evm_snd_dev_data = &dm6446_snd_soc_card_evm; + index = 0; +@@ -355,6 +466,11 @@ static int __init evm_init(void) + + static void __exit evm_exit(void) + { ++ if (of_have_populated_dt()) { ++ platform_driver_unregister(&davinci_evm_driver); ++ return; ++ } ++ + platform_device_unregister(evm_snd_device); + } + +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/402-ASoC-davinci-mcasp-Add-DMA-register-locations-to-DT.patch b/target/linux/omap/patches-3.12/402-ASoC-davinci-mcasp-Add-DMA-register-locations-to-DT.patch new file mode 100644 index 0000000000..2a99a5aad7 --- /dev/null +++ b/target/linux/omap/patches-3.12/402-ASoC-davinci-mcasp-Add-DMA-register-locations-to-DT.patch @@ -0,0 +1,178 @@ +From fb2002dbc326d2e408698038b668b19741567a48 Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Fri, 6 Sep 2013 12:15:00 +0300 +Subject: [PATCH 213/752] ASoC: davinci-mcasp: Add DMA register locations to + DT + +This patch adds DMA register location to mcasp DT bindings. On am33xx +SoCs the McASP registers are mapped trough L4 interconnect, which is +not accessible by the DMA controller, so McASP data port is mapped +trough L3 to a different location. + +Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com> +Signed-off-by: Darren Etheridge <detheridge@ti.com> +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + .../bindings/sound/davinci-mcasp-audio.txt | 8 ++- + sound/soc/davinci/davinci-mcasp.c | 59 +++++++++++++------- + 2 files changed, 46 insertions(+), 21 deletions(-) + +diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +index 374e145..63b67ae 100644 +--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt ++++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +@@ -6,7 +6,11 @@ Required properties: + "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms + "ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx) + +-- reg : Should contain McASP registers offset and length ++- reg : Should contain McASP registers address and length for mpu and ++ optionally for dma controller access. ++- reg-names : The mandatory reg-range must be named "mpu" and the optional DMA ++ reg-range must be named "dma". For backward compatibility it is ++ good to keep "mpu" first in the list. + - interrupts : Interrupt number for McASP + - op-mode : I2S/DIT ops mode. + - tdm-slots : Slots for TDM operation. +@@ -15,7 +19,6 @@ Required properties: + to "num-serializer" parameter. Each entry is a number indication + serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX) + +- + Optional properties: + + - ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0 +@@ -31,6 +34,7 @@ mcasp0: mcasp0@1d00000 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x100000 0x3000>; ++ reg-names "mpu"; + interrupts = <82 83>; + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; +diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c +index 32ddb7f..a056fc5 100644 +--- a/sound/soc/davinci/davinci-mcasp.c ++++ b/sound/soc/davinci/davinci-mcasp.c +@@ -1001,18 +1001,40 @@ static const struct snd_soc_component_driver davinci_mcasp_component = { + .name = "davinci-mcasp", + }; + ++/* Some HW specific values and defaults. The rest is filled in from DT. */ ++static struct snd_platform_data dm646x_mcasp_pdata = { ++ .tx_dma_offset = 0x400, ++ .rx_dma_offset = 0x400, ++ .asp_chan_q = EVENTQ_0, ++ .version = MCASP_VERSION_1, ++}; ++ ++static struct snd_platform_data da830_mcasp_pdata = { ++ .tx_dma_offset = 0x2000, ++ .rx_dma_offset = 0x2000, ++ .asp_chan_q = EVENTQ_0, ++ .version = MCASP_VERSION_2, ++}; ++ ++static struct snd_platform_data omap2_mcasp_pdata = { ++ .tx_dma_offset = 0, ++ .rx_dma_offset = 0, ++ .asp_chan_q = EVENTQ_0, ++ .version = MCASP_VERSION_3, ++}; ++ + static const struct of_device_id mcasp_dt_ids[] = { + { + .compatible = "ti,dm646x-mcasp-audio", +- .data = (void *)MCASP_VERSION_1, ++ .data = &dm646x_mcasp_pdata, + }, + { + .compatible = "ti,da830-mcasp-audio", +- .data = (void *)MCASP_VERSION_2, ++ .data = &da830_mcasp_pdata, + }, + { + .compatible = "ti,omap2-mcasp-audio", +- .data = (void *)MCASP_VERSION_3, ++ .data = &omap2_mcasp_pdata, + }, + { /* sentinel */ } + }; +@@ -1035,20 +1057,13 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( + pdata = pdev->dev.platform_data; + return pdata; + } else if (match) { +- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); +- if (!pdata) { +- ret = -ENOMEM; +- goto nodata; +- } ++ pdata = (struct snd_platform_data *) match->data; + } else { + /* control shouldn't reach here. something is wrong */ + ret = -EINVAL; + goto nodata; + } + +- if (match->data) +- pdata->version = (u8)((int)match->data); +- + ret = of_property_read_u32(np, "op-mode", &val); + if (ret >= 0) + pdata->op_mode = val; +@@ -1145,10 +1160,15 @@ static int davinci_mcasp_probe(struct platform_device *pdev) + return -EINVAL; + } + +- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); + if (!mem) { +- dev_err(&pdev->dev, "no mem resource?\n"); +- return -ENODEV; ++ dev_warn(dev->dev, ++ "\"mpu\" mem resource not found, using index 0\n"); ++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!mem) { ++ dev_err(&pdev->dev, "no mem resource?\n"); ++ return -ENODEV; ++ } + } + + ioarea = devm_request_mem_region(&pdev->dev, mem->start, +@@ -1182,13 +1202,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev) + dev->rxnumevt = pdata->rxnumevt; + dev->dev = &pdev->dev; + ++ dma = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); ++ if (!dma) ++ dma = mem; ++ + dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; + dma_data->asp_chan_q = pdata->asp_chan_q; + dma_data->ram_chan_q = pdata->ram_chan_q; + dma_data->sram_pool = pdata->sram_pool; + dma_data->sram_size = pdata->sram_size_playback; +- dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + +- mem->start); ++ dma_data->dma_addr = dma->start + pdata->tx_dma_offset; + + /* first TX, then RX */ + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); +@@ -1205,8 +1228,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) + dma_data->ram_chan_q = pdata->ram_chan_q; + dma_data->sram_pool = pdata->sram_pool; + dma_data->sram_size = pdata->sram_size_capture; +- dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + +- mem->start); ++ dma_data->dma_addr = dma->start + pdata->rx_dma_offset; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { +@@ -1266,4 +1288,3 @@ module_platform_driver(davinci_mcasp_driver); + MODULE_AUTHOR("Steve Chen"); + MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface"); + MODULE_LICENSE("GPL"); +- +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/403-ASoC-davinci-mcasp-Extract-DMA-channels-directly-fro.patch b/target/linux/omap/patches-3.12/403-ASoC-davinci-mcasp-Extract-DMA-channels-directly-fro.patch new file mode 100644 index 0000000000..5fc2f1368f --- /dev/null +++ b/target/linux/omap/patches-3.12/403-ASoC-davinci-mcasp-Extract-DMA-channels-directly-fro.patch @@ -0,0 +1,137 @@ +From ad5d3e5a1218a599ec02c81a3bd599acedeea00f Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Tue, 17 Sep 2013 12:09:30 +0300 +Subject: [PATCH 214/752] ASoC: davinci-mcasp: Extract DMA channels directly + from DT + +Extract DMA channels directly from DT as they can not be found from +platform resources anymore. This is a work-around until davinci audio +driver is updated to use dmaengine. + +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + .../bindings/sound/davinci-mcasp-audio.txt | 5 +++ + include/linux/platform_data/davinci_asp.h | 2 + + sound/soc/davinci/davinci-mcasp.c | 47 +++++++++++++------- + 3 files changed, 39 insertions(+), 15 deletions(-) + +diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +index 63b67ae..68e0f47 100644 +--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt ++++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +@@ -18,6 +18,11 @@ Required properties: + - serial-dir : A list of serializer pin mode. The list number should be equal + to "num-serializer" parameter. Each entry is a number indication + serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX) ++- dmas: two element list of DMA controller phandles and DMA request line ++ ordered pairs. ++- dma-names: identifier string for each DMA request line in the dmas property. ++ These strings correspond 1:1 with the ordered pairs in dmas. The dma ++ identifiers must be "rx" and "tx". + + Optional properties: + +diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h +index 8db5ae0..689a856 100644 +--- a/include/linux/platform_data/davinci_asp.h ++++ b/include/linux/platform_data/davinci_asp.h +@@ -84,6 +84,8 @@ struct snd_platform_data { + u8 version; + u8 txnumevt; + u8 rxnumevt; ++ int tx_dma_channel; ++ int rx_dma_channel; + }; + + enum { +diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c +index a056fc5..acbf5f8 100644 +--- a/sound/soc/davinci/davinci-mcasp.c ++++ b/sound/soc/davinci/davinci-mcasp.c +@@ -1047,6 +1047,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( + struct snd_platform_data *pdata = NULL; + const struct of_device_id *match = + of_match_device(mcasp_dt_ids, &pdev->dev); ++ struct of_phandle_args dma_spec; + + const u32 *of_serial_dir32; + u8 *of_serial_dir; +@@ -1109,6 +1110,28 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( + pdata->serial_dir = of_serial_dir; + } + ++ ret = of_property_match_string(np, "dma-names", "tx"); ++ if (ret < 0) ++ goto nodata; ++ ++ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, ++ &dma_spec); ++ if (ret < 0) ++ goto nodata; ++ ++ pdata->tx_dma_channel = dma_spec.args[0]; ++ ++ ret = of_property_match_string(np, "dma-names", "rx"); ++ if (ret < 0) ++ goto nodata; ++ ++ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, ++ &dma_spec); ++ if (ret < 0) ++ goto nodata; ++ ++ pdata->rx_dma_channel = dma_spec.args[0]; ++ + ret = of_property_read_u32(np, "tx-num-evt", &val); + if (ret >= 0) + pdata->txnumevt = val; +@@ -1139,7 +1162,7 @@ nodata: + static int davinci_mcasp_probe(struct platform_device *pdev) + { + struct davinci_pcm_dma_params *dma_data; +- struct resource *mem, *ioarea, *res; ++ struct resource *mem, *ioarea, *res, *dma; + struct snd_platform_data *pdata; + struct davinci_audio_dev *dev; + int ret; +@@ -1213,15 +1236,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) + dma_data->sram_size = pdata->sram_size_playback; + dma_data->dma_addr = dma->start + pdata->tx_dma_offset; + +- /* first TX, then RX */ + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); +- if (!res) { +- dev_err(&pdev->dev, "no DMA resource\n"); +- ret = -ENODEV; +- goto err_release_clk; +- } +- +- dma_data->channel = res->start; ++ if (res) ++ dma_data->channel = res->start; ++ else ++ dma_data->channel = pdata->tx_dma_channel; + + dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; + dma_data->asp_chan_q = pdata->asp_chan_q; +@@ -1231,13 +1250,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev) + dma_data->dma_addr = dma->start + pdata->rx_dma_offset; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); +- if (!res) { +- dev_err(&pdev->dev, "no DMA resource\n"); +- ret = -ENODEV; +- goto err_release_clk; +- } ++ if (res) ++ dma_data->channel = res->start; ++ else ++ dma_data->channel = pdata->rx_dma_channel; + +- dma_data->channel = res->start; + dev_set_drvdata(&pdev->dev, dev); + ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, + &davinci_mcasp_dai[pdata->op_mode], 1); +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/404-ASoC-davinci-mcasp-Interrupts-property-to-optional-a.patch b/target/linux/omap/patches-3.12/404-ASoC-davinci-mcasp-Interrupts-property-to-optional-a.patch new file mode 100644 index 0000000000..9bf4d98178 --- /dev/null +++ b/target/linux/omap/patches-3.12/404-ASoC-davinci-mcasp-Interrupts-property-to-optional-a.patch @@ -0,0 +1,47 @@ +From 0ecb275625447180dd615256d0c324a0c0c6e76a Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Thu, 19 Sep 2013 13:20:26 +0300 +Subject: [PATCH 215/752] ASoC: davinci-mcasp: Interrupts property to optional + and add interrupt-names + +Makes interrupts property optional as the interrupts are not currently +used by the driver and adds interrupt-names property to name listed +interrupts. Currently know interrupt names are "tx" and "rx". + +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +index 68e0f47..2fd0bf2 100644 +--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt ++++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +@@ -11,7 +11,6 @@ Required properties: + - reg-names : The mandatory reg-range must be named "mpu" and the optional DMA + reg-range must be named "dma". For backward compatibility it is + good to keep "mpu" first in the list. +-- interrupts : Interrupt number for McASP + - op-mode : I2S/DIT ops mode. + - tdm-slots : Slots for TDM operation. + - num-serializer : Serializers used by McASP. +@@ -31,6 +30,8 @@ Optional properties: + - rx-num-evt : FIFO levels. + - sram-size-playback : size of sram to be allocated during playback + - sram-size-capture : size of sram to be allocated during capture ++- interrupts : Interrupt numbers for McASP, currently not used by the driver ++- interrupt-names : Known interrupt names are "tx" and "rx" + + Example: + +@@ -41,6 +42,7 @@ mcasp0: mcasp0@1d00000 { + reg = <0x100000 0x3000>; + reg-names "mpu"; + interrupts = <82 83>; ++ interrupts-names = "tx", "rx"; + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + num-serializer = <16>; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/405-ASoC-davinci-Add-support-for-AM33xx-SoC-Audio.patch b/target/linux/omap/patches-3.12/405-ASoC-davinci-Add-support-for-AM33xx-SoC-Audio.patch new file mode 100644 index 0000000000..2e27a2dde6 --- /dev/null +++ b/target/linux/omap/patches-3.12/405-ASoC-davinci-Add-support-for-AM33xx-SoC-Audio.patch @@ -0,0 +1,67 @@ +From 8f3e1fa024017a6b3d7fd8c2a75ee6ff5e4127f8 Mon Sep 17 00:00:00 2001 +From: "Hebbar, Gururaja" <gururaja.hebbar@ti.com> +Date: Wed, 1 Aug 2012 12:04:22 +0530 +Subject: [PATCH 216/752] ASoC: davinci: Add support for AM33xx SoC Audio + +AM33xx uses same McASP IP as the Davinci Platform. This patch updates +Kconfig and makefile to enable build for McASP, PCM & Codec drivers. + +Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com> +Signed-off-by: Darren Etheridge <detheridge@ti.com> +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + sound/soc/davinci/Kconfig | 18 +++++++++++++++--- + sound/soc/davinci/Makefile | 1 + + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig +index c82f89c..95970f5 100644 +--- a/sound/soc/davinci/Kconfig ++++ b/sound/soc/davinci/Kconfig +@@ -1,9 +1,10 @@ + config SND_DAVINCI_SOC +- tristate "SoC Audio for the TI DAVINCI chip" +- depends on ARCH_DAVINCI ++ tristate "SoC Audio for the TI DAVINCI or AM33XX chip" ++ depends on ARCH_DAVINCI || SOC_AM33XX + help ++ Platform driver for daVinci or AM33xx + Say Y or M if you want to add support for codecs attached to +- the DAVINCI AC97 or I2S interface. You will also need ++ the DAVINCI AC97, I2S, or McASP interface. You will also need + to select the audio interfaces to support below. + + config SND_DAVINCI_SOC_I2S +@@ -15,6 +16,17 @@ config SND_DAVINCI_SOC_MCASP + config SND_DAVINCI_SOC_VCIF + tristate + ++config SND_AM33XX_SOC_EVM ++ tristate "SoC Audio for the AM33XX chip based boards" ++ depends on SND_DAVINCI_SOC && SOC_AM33XX ++ select SND_SOC_TLV320AIC3X ++ select SND_DAVINCI_SOC_MCASP ++ help ++ Say Y or M if you want to add support for SoC audio on AM33XX ++ boards using McASP and TLV320AIC3X codec. For example AM335X-EVM, ++ AM335X-EVMSK, and BeagelBone with AudioCape boards have this ++ setup. ++ + config SND_DAVINCI_SOC_EVM + tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" + depends on SND_DAVINCI_SOC +diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile +index a396ab6..bc81e79 100644 +--- a/sound/soc/davinci/Makefile ++++ b/sound/soc/davinci/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o + snd-soc-evm-objs := davinci-evm.o + + obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o ++obj-$(CONFIG_SND_AM33XX_SOC_EVM) += snd-soc-evm.o + obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o + obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o + obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/406-ASoC-tlv320aic3x-Add-regulators-to-DT-bindings-docum.patch b/target/linux/omap/patches-3.12/406-ASoC-tlv320aic3x-Add-regulators-to-DT-bindings-docum.patch new file mode 100644 index 0000000000..6dae77b68a --- /dev/null +++ b/target/linux/omap/patches-3.12/406-ASoC-tlv320aic3x-Add-regulators-to-DT-bindings-docum.patch @@ -0,0 +1,38 @@ +From 2e8f45c820bc025bac3a5257478f16f73b38d54c Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Wed, 11 Sep 2013 15:04:56 +0300 +Subject: [PATCH 217/752] ASoC: tlv320aic3x: Add regulators to DT bindings + document + +Add regulator properties to tlv320aic3x DT bindings document. + +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + Documentation/devicetree/bindings/sound/tlv320aic3x.txt | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +index 705a6b1..ba26477 100644 +--- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt ++++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +@@ -24,10 +24,17 @@ Optional properties: + 3 - MICBIAS output is connected to AVDD, + If this node is not mentioned or if the value is incorrect, then MicBias + is powered down. ++- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the ++ device as covered in Documentation/devicetree/bindings/regulator/regulator.txt + + Example: + + tlv320aic3x: tlv320aic3x@1b { + compatible = "ti,tlv320aic3x"; + reg = <0x1b>; ++ ++ AVDD-supply = <®ulator>; ++ IOVDD-supply = <®ulator>; ++ DRVDD-supply = <®ulator>; ++ DVDD-supply = <®ulator>; + }; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/407-ASoC-tlv320aic3x-Add-codec-pins-to-DT-bindings-docum.patch b/target/linux/omap/patches-3.12/407-ASoC-tlv320aic3x-Add-codec-pins-to-DT-bindings-docum.patch new file mode 100644 index 0000000000..af86233a84 --- /dev/null +++ b/target/linux/omap/patches-3.12/407-ASoC-tlv320aic3x-Add-codec-pins-to-DT-bindings-docum.patch @@ -0,0 +1,46 @@ +From 6afd5cb1f92a1965ffa3c0f304f95ab19b49fa84 Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Thu, 12 Sep 2013 14:37:08 +0300 +Subject: [PATCH 218/752] ASoC: tlv320aic3x: Add codec pins to DT bindings + document + +Add list of codec pins to tlv320aic3x DT bindings document. + +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + .../devicetree/bindings/sound/tlv320aic3x.txt | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +index ba26477..5e6040c 100644 +--- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt ++++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +@@ -27,6 +27,25 @@ Optional properties: + - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the + device as covered in Documentation/devicetree/bindings/regulator/regulator.txt + ++CODEC output pins: ++ * LLOUT ++ * RLOUT ++ * MONO_LOUT ++ * HPLOUT ++ * HPROUT ++ * HPLCOM ++ * HPRCOM ++ ++CODEC input pins: ++ * MIC3L ++ * MIC3R ++ * LINE1L ++ * LINE2L ++ * LINE1R ++ * LINE2R ++ ++The pins can be used in referring sound node's audio-routing property. ++ + Example: + + tlv320aic3x: tlv320aic3x@1b { +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/408-ARM-dts-am33xx-Add-mcasp0-and-mcasp1-device-tree-ent.patch b/target/linux/omap/patches-3.12/408-ARM-dts-am33xx-Add-mcasp0-and-mcasp1-device-tree-ent.patch new file mode 100644 index 0000000000..d53516c39e --- /dev/null +++ b/target/linux/omap/patches-3.12/408-ARM-dts-am33xx-Add-mcasp0-and-mcasp1-device-tree-ent.patch @@ -0,0 +1,48 @@ +From a049ce751e60451b47fa744342db84db44883e57 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <panto@antoniou-consulting.com> +Date: Thu, 10 Jan 2013 20:37:45 +0200 +Subject: [PATCH 219/752] ARM/dts: am33xx: Add mcasp0 and mcasp1 device tree + entries + +Add missing mcasp entries in the am33xx.dtsi include file. + +Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com> +Signed-off-by: Darren Etheridge <detheridge@ti.com> +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + arch/arm/boot/dts/am33xx.dtsi | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 6eb809c..4fb3521 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -839,6 +839,25 @@ + clocks = <&rng_fck>; + clock-names = "fck"; + }; ++ ++ mcasp0: mcasp@48038000 { ++ compatible = "ti,omap2-mcasp-audio"; ++ ti,hwmods = "mcasp0"; ++ reg = <0x48038000 0x2000>; ++ interrupts = <80 81>; ++ interrupts-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ mcasp1: mcasp@4803C000 { ++ compatible = "ti,omap2-mcasp-audio"; ++ ti,hwmods = "mcasp1"; ++ reg = <0x4803C000 0x2000>; ++ interrupts = <82 83>; ++ interrupts-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ + }; + + clocks { +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/409-ARM-dts-am33xx-mcasp-Add-new-dma-register-location-t.patch b/target/linux/omap/patches-3.12/409-ARM-dts-am33xx-mcasp-Add-new-dma-register-location-t.patch new file mode 100644 index 0000000000..f0e5758126 --- /dev/null +++ b/target/linux/omap/patches-3.12/409-ARM-dts-am33xx-mcasp-Add-new-dma-register-location-t.patch @@ -0,0 +1,56 @@ +From 15ffa765da3f2427b506472baa72d0f3a90b6be5 Mon Sep 17 00:00:00 2001 +From: Jyri Sarha <jsarha@ti.com> +Date: Thu, 5 Sep 2013 21:49:35 +0300 +Subject: [PATCH 220/752] ARM/dts: am33xx: mcasp: Add new dma register + location to reg-property + +This patch adds an optional address range to reg property. The range +describes the register location for DMA controller on am33xx. The both +address ranges are named accordingly in the reg-names property. + +Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com> +Signed-off-by: Darren Etheridge <detheridge@ti.com> +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + arch/arm/boot/dts/am33xx.dtsi | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 4fb3521..b9e2ff3 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -843,19 +843,29 @@ + mcasp0: mcasp@48038000 { + compatible = "ti,omap2-mcasp-audio"; + ti,hwmods = "mcasp0"; +- reg = <0x48038000 0x2000>; ++ reg = <0x48038000 0x2000>, ++ <0x46400000 0x400000>; ++ reg-names = "mpu", "dma"; + interrupts = <80 81>; + interrupts-names = "tx", "rx"; + status = "disabled"; ++ dmas = <&edma 8 ++ &edma 9>; ++ dma-names = "tx", "rx"; + }; + + mcasp1: mcasp@4803C000 { + compatible = "ti,omap2-mcasp-audio"; + ti,hwmods = "mcasp1"; +- reg = <0x4803C000 0x2000>; ++ reg = <0x4803C000 0x2000>, ++ <0x46400000 0x400000>; ++ reg-names = "mpu", "dma"; + interrupts = <82 83>; + interrupts-names = "tx", "rx"; + status = "disabled"; ++ dmas = <&edma 10 ++ &edma 11>; ++ dma-names = "tx", "rx"; + }; + + }; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/410-ARM-dts-am335x-evm-Add-audio-support-for-am335x-evm.patch b/target/linux/omap/patches-3.12/410-ARM-dts-am335x-evm-Add-audio-support-for-am335x-evm.patch new file mode 100644 index 0000000000..6283c948d1 --- /dev/null +++ b/target/linux/omap/patches-3.12/410-ARM-dts-am335x-evm-Add-audio-support-for-am335x-evm.patch @@ -0,0 +1,106 @@ +From 2bf66a74b322deebc7c8bba11cab58c18b745608 Mon Sep 17 00:00:00 2001 +From: Darren Etheridge <detheridge@ti.com> +Date: Wed, 31 Jul 2013 12:38:26 -0500 +Subject: [PATCH 221/752] ARM/dts: am335x-evm: Add audio support for + am335x-evm.dts + +Adds sound, tlv320aic3x, mcasp1, and am335x_evm_audio_pin nodes. + +Signed-off-by: Darren Etheridge <detheridge@ti.com> +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +Signed-off-by: Jyri Sarha <jsarha@ti.com> +--- + arch/arm/boot/dts/am335x-evm.dts | 56 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index bc4a69d..664fa2a 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -149,6 +149,16 @@ + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; ++ ++ am335x_evm_audio_pins: am335x_evm_audio_pins { ++ pinctrl-single,pins = < ++ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */ ++ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */ ++ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ ++ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ ++ >; ++ }; ++ + }; + + ocp { +@@ -244,6 +254,19 @@ + compatible = "ti,tmp275"; + reg = <0x48>; + }; ++ ++ tlv320aic3x: tlv320aic3x@1b { ++ compatible = "ti,tlv320aic3x"; ++ reg = <0x1b>; ++ status = "okay"; ++ ++ /* Regulators */ ++ AVDD-supply = <&vaux2_reg>; ++ IOVDD-supply = <&vaux2_reg>; ++ DRVDD-supply = <&vaux2_reg>; ++ DVDD-supply = <&vbat>; ++ }; ++ + }; + + elm: elm@48080000 { +@@ -340,6 +363,20 @@ + }; + }; + }; ++ ++ sound { ++ compatible = "ti,da830-evm-audio"; ++ ti,model = "DA830 EVM"; ++ ti,audio-codec = <&tlv320aic3x>; ++ ti,mcasp-controller = <&mcasp1>; ++ ti,codec-clock-rate = <12000000>; ++ ti,audio-routing = ++ "Headphone Jack", "HPLOUT", ++ "Headphone Jack", "HPROUT", ++ "LINE1L", "Line In", ++ "LINE1R", "Line In"; ++ }; ++ + }; + + vbat: fixedregulator@0 { +@@ -407,6 +444,25 @@ + + #include "tps65910.dtsi" + ++&mcasp1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&am335x_evm_audio_pins>; ++ ++ status = "okay"; ++ ++ op-mode = <0>; /* MCASP_IIS_MODE */ ++ tdm-slots = <2>; ++ num-serializer = <16>; ++ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ ++ 0 0 1 2 ++ 0 0 0 0 ++ 0 0 0 0 ++ 0 0 0 0 ++ >; ++ tx-num-evt = <1>; ++ rx-num-evt = <1>; ++}; ++ + &tps { + vcc1-supply = <&vbat>; + vcc2-supply = <&vbat>; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/411-ARM-dts-am335x-evm-Remove-blank-lines.patch b/target/linux/omap/patches-3.12/411-ARM-dts-am335x-evm-Remove-blank-lines.patch new file mode 100644 index 0000000000..77c50066d7 --- /dev/null +++ b/target/linux/omap/patches-3.12/411-ARM-dts-am335x-evm-Remove-blank-lines.patch @@ -0,0 +1,35 @@ +From 76b54fecdd214b32f568b2f97102fc1ab5745fa1 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 10:34:06 +0300 +Subject: [PATCH 222/752] ARM/dts: am335x-evm: Remove blank lines + +Clean up the blank lines where they are not needed. + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + arch/arm/boot/dts/am335x-evm.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index 664fa2a..baeb805 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -266,7 +266,6 @@ + DRVDD-supply = <&vaux2_reg>; + DVDD-supply = <&vbat>; + }; +- + }; + + elm: elm@48080000 { +@@ -376,7 +375,6 @@ + "LINE1L", "Line In", + "LINE1R", "Line In"; + }; +- + }; + + vbat: fixedregulator@0 { +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/412-ARM-dts-am335x-evm-Clarify-the-audio-codec-node.patch b/target/linux/omap/patches-3.12/412-ARM-dts-am335x-evm-Clarify-the-audio-codec-node.patch new file mode 100644 index 0000000000..53ab24e5dc --- /dev/null +++ b/target/linux/omap/patches-3.12/412-ARM-dts-am335x-evm-Clarify-the-audio-codec-node.patch @@ -0,0 +1,40 @@ +From df3fbecdac2b46b7716c16c185cba357cc55d00a Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 10:34:07 +0300 +Subject: [PATCH 223/752] ARM/dts: am335x-evm: Clarify the audio codec node + +The board have tlv320aic3106 codec. Use this name in the dts file instead +of the generic ltv320aic3x. + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + arch/arm/boot/dts/am335x-evm.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index baeb805..e52d09c 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -255,8 +255,8 @@ + reg = <0x48>; + }; + +- tlv320aic3x: tlv320aic3x@1b { +- compatible = "ti,tlv320aic3x"; ++ tlv320aic3106: tlv320aic3106@1b { ++ compatible = "ti,tlv320aic3106"; + reg = <0x1b>; + status = "okay"; + +@@ -366,7 +366,7 @@ + sound { + compatible = "ti,da830-evm-audio"; + ti,model = "DA830 EVM"; +- ti,audio-codec = <&tlv320aic3x>; ++ ti,audio-codec = <&tlv320aic3106>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; + ti,audio-routing = +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/413-ARM-dts-am335x-evm-Add-unique-name-for-the-sound-car.patch b/target/linux/omap/patches-3.12/413-ARM-dts-am335x-evm-Add-unique-name-for-the-sound-car.patch new file mode 100644 index 0000000000..02cf3d8bd4 --- /dev/null +++ b/target/linux/omap/patches-3.12/413-ARM-dts-am335x-evm-Add-unique-name-for-the-sound-car.patch @@ -0,0 +1,32 @@ +From d4b7ebbadccb4632ad16f07a19cee57aa7b73cdb Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 10:34:08 +0300 +Subject: [PATCH 224/752] ARM/dts: am335x-evm: Add unique name for the sound + card + +Change the name of the sound card to 'AM335x-EVM' from 'DA830 EVM'. +User space might need to differentiate between the boards when it comes to +audio setup (mixer config, PCM lookup, etc). +It is better to use unique name for different boards. + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + arch/arm/boot/dts/am335x-evm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index e52d09c..47613fd 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -365,7 +365,7 @@ + + sound { + compatible = "ti,da830-evm-audio"; +- ti,model = "DA830 EVM"; ++ ti,model = "AM335x-EVM"; + ti,audio-codec = <&tlv320aic3106>; + ti,mcasp-controller = <&mcasp1>; + ti,codec-clock-rate = <12000000>; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/414-ARM-dts-am335x-evmsk-Audio-support.patch b/target/linux/omap/patches-3.12/414-ARM-dts-am335x-evmsk-Audio-support.patch new file mode 100644 index 0000000000..113e1df4f5 --- /dev/null +++ b/target/linux/omap/patches-3.12/414-ARM-dts-am335x-evmsk-Audio-support.patch @@ -0,0 +1,100 @@ +From d4c71e652f457077eac1ad83a9e32d3f11fc99b2 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 10:34:09 +0300 +Subject: [PATCH 225/752] ARM/dts: am335x-evmsk: Audio support + +AM335x EVM-SK have only support for audio playback (stereo jack on the +board) via tlv320aic3106 codec connected to McASP1. +Enable the support for audio playback on the board: +- McASP1 configuration +- tlv320aic3106 configuration +- Machine driver. + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + arch/arm/boot/dts/am335x-evmsk.dts | 51 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index 879981d..b87ce7f 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -158,6 +158,15 @@ + 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) + >; + }; ++ ++ mcasp1_pins: mcasp1_pins { ++ pinctrl-single,pins = < ++ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */ ++ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */ ++ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ ++ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ ++ >; ++ }; + }; + + ocp { +@@ -206,6 +215,18 @@ + st,max-limit-y = <550>; + st,max-limit-z = <750>; + }; ++ ++ tlv320aic3106: tlv320aic3106@1b { ++ compatible = "ti,tlv320aic3106"; ++ reg = <0x1b>; ++ status = "okay"; ++ ++ /* Regulators */ ++ AVDD-supply = <&vaux2_reg>; ++ IOVDD-supply = <&vaux2_reg>; ++ DRVDD-supply = <&vaux2_reg>; ++ DVDD-supply = <&vbat>; ++ }; + }; + + musb: usb@47400000 { +@@ -233,6 +254,17 @@ + pinctrl-0 = <&ecap2_pins>; + }; + }; ++ ++ sound { ++ compatible = "ti,da830-evm-audio"; ++ ti,model = "AM335x-EVMSK"; ++ ti,audio-codec = <&tlv320aic3106>; ++ ti,mcasp-controller = <&mcasp1>; ++ ti,codec-clock-rate = <24576000>; ++ ti,audio-routing = ++ "Headphone Jack", "HPLOUT", ++ "Headphone Jack", "HPROUT"; ++ }; + }; + + vbat: fixedregulator@0 { +@@ -430,3 +462,22 @@ + status = "okay"; + vmmc-supply = <&vmmc_reg>; + }; ++ ++&mcasp1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcasp1_pins>; ++ ++ status = "okay"; ++ ++ op-mode = <0>; /* MCASP_IIS_MODE */ ++ tdm-slots = <2>; ++ num-serializer = <16>; ++ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ ++ 0 0 1 2 ++ 0 0 0 0 ++ 0 0 0 0 ++ 0 0 0 0 ++ >; ++ tx-num-evt = <1>; ++ rx-num-evt = <1>; ++}; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/415-ASoC-davinci-mcasp-Remove-redundant-num-serializer-D.patch b/target/linux/omap/patches-3.12/415-ASoC-davinci-mcasp-Remove-redundant-num-serializer-D.patch new file mode 100644 index 0000000000..e377cb264d --- /dev/null +++ b/target/linux/omap/patches-3.12/415-ASoC-davinci-mcasp-Remove-redundant-num-serializer-D.patch @@ -0,0 +1,97 @@ +From fdb8d3521ecae71865df66a84a1cbe13f7daa6f5 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 11:25:02 +0300 +Subject: [PATCH 226/752] ASoC: davinci: mcasp: Remove redundant + num-serializer DT parameter + +The serial-dir array gives this information so there is no need to have the +num-serializer property in DT description. +Just ignore the property in the driver the DTS files can be updated +separately without regression. +Update the documentation at the same time for davinci-mcasp + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + .../bindings/sound/davinci-mcasp-audio.txt | 8 +++---- + sound/soc/davinci/davinci-mcasp.c | 22 +++++--------------- + 2 files changed, 8 insertions(+), 22 deletions(-) + +diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +index 2fd0bf2..be6cf94 100644 +--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt ++++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +@@ -13,10 +13,9 @@ Required properties: + good to keep "mpu" first in the list. + - op-mode : I2S/DIT ops mode. + - tdm-slots : Slots for TDM operation. +-- num-serializer : Serializers used by McASP. +-- serial-dir : A list of serializer pin mode. The list number should be equal +- to "num-serializer" parameter. Each entry is a number indication +- serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX) ++- serial-dir : A list of serializer configuration. Each entry is a number ++ indication serializer pin direction. ++ (0 - INACTIVE, 1 - TX, 2 - RX) + - dmas: two element list of DMA controller phandles and DMA request line + ordered pairs. + - dma-names: identifier string for each DMA request line in the dmas property. +@@ -45,7 +44,6 @@ mcasp0: mcasp0@1d00000 { + interrupts-names = "tx", "rx"; + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; +- num-serializer = <16>; + serial-dir = < + 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 0 0 +diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c +index acbf5f8..69e662e 100644 +--- a/sound/soc/davinci/davinci-mcasp.c ++++ b/sound/soc/davinci/davinci-mcasp.c +@@ -1050,7 +1050,6 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( + struct of_phandle_args dma_spec; + + const u32 *of_serial_dir32; +- u8 *of_serial_dir; + u32 val; + int i, ret = 0; + +@@ -1081,32 +1080,21 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( + pdata->tdm_slots = val; + } + +- ret = of_property_read_u32(np, "num-serializer", &val); +- if (ret >= 0) +- pdata->num_serializer = val; +- + of_serial_dir32 = of_get_property(np, "serial-dir", &val); + val /= sizeof(u32); +- if (val != pdata->num_serializer) { +- dev_err(&pdev->dev, +- "num-serializer(%d) != serial-dir size(%d)\n", +- pdata->num_serializer, val); +- ret = -EINVAL; +- goto nodata; +- } +- + if (of_serial_dir32) { +- of_serial_dir = devm_kzalloc(&pdev->dev, +- (sizeof(*of_serial_dir) * val), +- GFP_KERNEL); ++ u8 *of_serial_dir = devm_kzalloc(&pdev->dev, ++ (sizeof(*of_serial_dir) * val), ++ GFP_KERNEL); + if (!of_serial_dir) { + ret = -ENOMEM; + goto nodata; + } + +- for (i = 0; i < pdata->num_serializer; i++) ++ for (i = 0; i < val; i++) + of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]); + ++ pdata->num_serializer = val; + pdata->serial_dir = of_serial_dir; + } + +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/416-ARM-dts-am335x-evm-Remove-num-serializer-property-fo.patch b/target/linux/omap/patches-3.12/416-ARM-dts-am335x-evm-Remove-num-serializer-property-fo.patch new file mode 100644 index 0000000000..b6f2e85ea0 --- /dev/null +++ b/target/linux/omap/patches-3.12/416-ARM-dts-am335x-evm-Remove-num-serializer-property-fo.patch @@ -0,0 +1,29 @@ +From 7fd70076a17c2a5b1b4bac0175a25e5d04075e43 Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 11:25:03 +0300 +Subject: [PATCH 227/752] ARM/dts: am335x-evm: Remove num-serializer property + for mcasp node + +The num-serializer property is redundant and the driver no longer needs it. + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + arch/arm/boot/dts/am335x-evm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index 47613fd..c4494a2 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -450,7 +450,7 @@ + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; +- num-serializer = <16>; ++ /* 16 serializer */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 + 0 0 0 0 +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/417-ARM-dts-am335x-evmsk-Remove-num-serializer-property.patch b/target/linux/omap/patches-3.12/417-ARM-dts-am335x-evmsk-Remove-num-serializer-property.patch new file mode 100644 index 0000000000..abf7690a83 --- /dev/null +++ b/target/linux/omap/patches-3.12/417-ARM-dts-am335x-evmsk-Remove-num-serializer-property.patch @@ -0,0 +1,29 @@ +From 97977a1534ef27247acc9549f5433ef288f208eb Mon Sep 17 00:00:00 2001 +From: Peter Ujfalusi <peter.ujfalusi@ti.com> +Date: Mon, 23 Sep 2013 11:25:04 +0300 +Subject: [PATCH 228/752] ARM/dts: am335x-evmsk: Remove num-serializer + property for mcasp node + +The num-serializer property is redundant and the driver no longer needs it. + +Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> +--- + arch/arm/boot/dts/am335x-evmsk.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index b87ce7f..354c0e5 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -471,7 +471,7 @@ + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; +- num-serializer = <16>; ++ /* 16 serializer */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 + 0 0 0 0 +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/500-ARM-dts-AM33XX-Add-LCDC-info-into-am335x-evm.patch b/target/linux/omap/patches-3.12/500-ARM-dts-AM33XX-Add-LCDC-info-into-am335x-evm.patch new file mode 100644 index 0000000000..6542010f92 --- /dev/null +++ b/target/linux/omap/patches-3.12/500-ARM-dts-AM33XX-Add-LCDC-info-into-am335x-evm.patch @@ -0,0 +1,18 @@ +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -682,6 +682,15 @@ + status = "disabled"; + }; + ++ lcdc: lcdc@4830e000 { ++ compatible = "ti,am33xx-tilcdc"; ++ reg = <0x4830e000 0x1000>; ++ interrupt-parent = <&intc>; ++ interrupts = <36>; ++ ti,hwmods = "lcdc"; ++ status = "disabled"; ++ }; ++ + tscadc: tscadc@44e0d000 { + compatible = "ti,am3359-tscadc"; + reg = <0x44e0d000 0x1000>; diff --git a/target/linux/omap/patches-3.12/600-crypto-omap-des-Add-omap-des-driver-for-OMAP4-AM43xx.patch b/target/linux/omap/patches-3.12/600-crypto-omap-des-Add-omap-des-driver-for-OMAP4-AM43xx.patch new file mode 100644 index 0000000000..14e3fbe746 --- /dev/null +++ b/target/linux/omap/patches-3.12/600-crypto-omap-des-Add-omap-des-driver-for-OMAP4-AM43xx.patch @@ -0,0 +1,1233 @@ +From patchwork Thu Aug 29 23:27:51 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [1/3] crypto: omap-des: Add omap-des driver for OMAP4/AM43xx +From: Joel Fernandes <joelf@ti.com> +X-Patchwork-Id: 2851675 +Message-Id: <1377818873-21174-2-git-send-email-joelf@ti.com> +To: Herbert Xu <herbert@gondor.hengli.com.au>, "David S. Miller" + <davem@davemloft.net>, Mark Greer <mgreer@animalcreek.com>, Tony Lindgren + <tony@atomide.com>, Lokesh Vutla <lokeshvutla@ti.com> +Cc: Joel Fernandes <joelf@ti.com>, + Linux OMAP List <linux-omap@vger.kernel.org>, + Linux Kernel Mailing List <linux-kernel@vger.kernel.org>, + Linux ARM Kernel List <linux-arm-kernel@lists.infradead.org>, + Linux Crypto Mailing List <linux-crypto@vger.kernel.org> +Date: Thu, 29 Aug 2013 18:27:51 -0500 + +Add omap-des driver with platform data for OMAP4. Support added for DES +ECB and CBC modes. + +Where possible, code is reused from omap-aes driver with changes made for +adjusting key size, block size, removing non-existent encryption modes +and adding support for OMAP4 platform data and offsets. + +Tests have been conducted with the CRYPTO test manager, and functionality +is verified at different page length alignments. + +Signed-off-by: Joel Fernandes <joelf@ti.com> + +--- +drivers/crypto/omap-des.c | 1192 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 1192 insertions(+) + create mode 100644 drivers/crypto/omap-des.c + +diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c +new file mode 100644 +index 0000000..6a9a25f +--- /dev/null ++++ b/drivers/crypto/omap-des.c +@@ -0,0 +1,1192 @@ ++/* ++ * Cryptographic API. ++ * ++ * Support for OMAP DES and Triple DES HW acceleration. ++ * ++ * Copyright (c) 2012 Texas Instruments Incorporated ++ * Author: Joel Fernandes <joelf@ti.com> ++ * ++ * 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. ++ * ++ */ ++ ++#define pr_fmt(fmt) "%s: " fmt, __func__ ++ ++#ifdef DEBUG ++#define prn(num) printk(#num "=%d\n", num) ++#define prx(num) printk(#num "=%x\n", num) ++#else ++#define prn(num) do { } while (0) ++#define prx(num) do { } while (0) ++#endif ++ ++#include <linux/err.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/errno.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/scatterlist.h> ++#include <linux/dma-mapping.h> ++#include <linux/dmaengine.h> ++#include <linux/omap-dma.h> ++#include <linux/pm_runtime.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/of_address.h> ++#include <linux/io.h> ++#include <linux/crypto.h> ++#include <linux/interrupt.h> ++#include <crypto/scatterwalk.h> ++#include <crypto/des.h> ++ ++#define DST_MAXBURST 2 ++ ++#define DES_BLOCK_WORDS (DES_BLOCK_SIZE >> 2) ++ ++#define _calc_walked(inout) (dd->inout##_walk.offset - dd->inout##_sg->offset) ++ ++#define DES_REG_KEY(dd, x) ((dd)->pdata->key_ofs - \ ++ ((x ^ 0x01) * 0x04)) ++ ++#define DES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04)) ++ ++#define DES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs) ++#define DES_REG_CTRL_CBC (1 << 4) ++#define DES_REG_CTRL_TDES (1 << 3) ++#define DES_REG_CTRL_DIRECTION (1 << 2) ++#define DES_REG_CTRL_INPUT_READY (1 << 1) ++#define DES_REG_CTRL_OUTPUT_READY (1 << 0) ++ ++#define DES_REG_DATA_N(dd, x) ((dd)->pdata->data_ofs + ((x) * 0x04)) ++ ++#define DES_REG_REV(dd) ((dd)->pdata->rev_ofs) ++ ++#define DES_REG_MASK(dd) ((dd)->pdata->mask_ofs) ++ ++#define DES_REG_LENGTH_N(x) (0x24 + ((x) * 0x04)) ++ ++#define DES_REG_IRQ_STATUS(dd) ((dd)->pdata->irq_status_ofs) ++#define DES_REG_IRQ_ENABLE(dd) ((dd)->pdata->irq_enable_ofs) ++#define DES_REG_IRQ_DATA_IN BIT(1) ++#define DES_REG_IRQ_DATA_OUT BIT(2) ++ ++#define FLAGS_MODE_MASK 0x000f ++#define FLAGS_ENCRYPT BIT(0) ++#define FLAGS_CBC BIT(1) ++#define FLAGS_INIT BIT(4) ++#define FLAGS_BUSY BIT(6) ++ ++struct omap_des_ctx { ++ struct omap_des_dev *dd; ++ ++ int keylen; ++ u32 key[DES_KEY_SIZE / sizeof(u32)]; ++ unsigned long flags; ++}; ++ ++struct omap_des_reqctx { ++ unsigned long mode; ++}; ++ ++#define OMAP_DES_QUEUE_LENGTH 1 ++#define OMAP_DES_CACHE_SIZE 0 ++ ++struct omap_des_algs_info { ++ struct crypto_alg *algs_list; ++ unsigned int size; ++ unsigned int registered; ++}; ++ ++struct omap_des_pdata { ++ struct omap_des_algs_info *algs_info; ++ unsigned int algs_info_size; ++ ++ void (*trigger)(struct omap_des_dev *dd, int length); ++ ++ u32 key_ofs; ++ u32 iv_ofs; ++ u32 ctrl_ofs; ++ u32 data_ofs; ++ u32 rev_ofs; ++ u32 mask_ofs; ++ u32 irq_enable_ofs; ++ u32 irq_status_ofs; ++ ++ u32 dma_enable_in; ++ u32 dma_enable_out; ++ u32 dma_start; ++ ++ u32 major_mask; ++ u32 major_shift; ++ u32 minor_mask; ++ u32 minor_shift; ++}; ++ ++struct omap_des_dev { ++ struct list_head list; ++ unsigned long phys_base; ++ void __iomem *io_base; ++ struct omap_des_ctx *ctx; ++ struct device *dev; ++ unsigned long flags; ++ int err; ++ ++ /* spinlock used for queues */ ++ spinlock_t lock; ++ struct crypto_queue queue; ++ ++ struct tasklet_struct done_task; ++ struct tasklet_struct queue_task; ++ ++ struct ablkcipher_request *req; ++ /* ++ * total is used by PIO mode for book keeping so introduce ++ * variable total_save as need it to calc page_order ++ */ ++ size_t total; ++ size_t total_save; ++ ++ struct scatterlist *in_sg; ++ struct scatterlist *out_sg; ++ ++ /* Buffers for copying for unaligned cases */ ++ struct scatterlist in_sgl; ++ struct scatterlist out_sgl; ++ struct scatterlist *orig_out; ++ int sgs_copied; ++ ++ struct scatter_walk in_walk; ++ struct scatter_walk out_walk; ++ int dma_in; ++ struct dma_chan *dma_lch_in; ++ int dma_out; ++ struct dma_chan *dma_lch_out; ++ int in_sg_len; ++ int out_sg_len; ++ int pio_only; ++ const struct omap_des_pdata *pdata; ++}; ++ ++/* keep registered devices data here */ ++static LIST_HEAD(dev_list); ++static DEFINE_SPINLOCK(list_lock); ++ ++#ifdef DEBUG ++#define omap_des_read(dd, offset) \ ++ ({ \ ++ int _read_ret; \ ++ _read_ret = __raw_readl(dd->io_base + offset); \ ++ pr_err("omap_des_read(" #offset "=%#x)= %#x\n", \ ++ offset, _read_ret); \ ++ _read_ret; \ ++ }) ++#else ++static inline u32 omap_des_read(struct omap_des_dev *dd, u32 offset) ++{ ++ return __raw_readl(dd->io_base + offset); ++} ++#endif ++ ++#ifdef DEBUG ++#define omap_des_write(dd, offset, value) \ ++ do { \ ++ pr_err("omap_des_write(" #offset "=%#x) value=%#x\n", \ ++ offset, value); \ ++ __raw_writel(value, dd->io_base + offset); \ ++ } while (0) ++#else ++static inline void omap_des_write(struct omap_des_dev *dd, u32 offset, ++ u32 value) ++{ ++ __raw_writel(value, dd->io_base + offset); ++} ++#endif ++ ++static inline void omap_des_write_mask(struct omap_des_dev *dd, u32 offset, ++ u32 value, u32 mask) ++{ ++ u32 val; ++ ++ val = omap_des_read(dd, offset); ++ val &= ~mask; ++ val |= value; ++ omap_des_write(dd, offset, val); ++} ++ ++static void omap_des_write_n(struct omap_des_dev *dd, u32 offset, ++ u32 *value, int count) ++{ ++ for (; count--; value++, offset += 4) ++ omap_des_write(dd, offset, *value); ++} ++ ++static int omap_des_hw_init(struct omap_des_dev *dd) ++{ ++ /* ++ * clocks are enabled when request starts and disabled when finished. ++ * It may be long delays between requests. ++ * Device might go to off mode to save power. ++ */ ++ pm_runtime_get_sync(dd->dev); ++ ++ if (!(dd->flags & FLAGS_INIT)) { ++ dd->flags |= FLAGS_INIT; ++ dd->err = 0; ++ } ++ ++ return 0; ++} ++ ++static int omap_des_write_ctrl(struct omap_des_dev *dd) ++{ ++ unsigned int key32; ++ int i, err; ++ u32 val = 0, mask = 0; ++ ++ err = omap_des_hw_init(dd); ++ if (err) ++ return err; ++ ++ key32 = dd->ctx->keylen / sizeof(u32); ++ ++ /* it seems a key should always be set even if it has not changed */ ++ for (i = 0; i < key32; i++) { ++ omap_des_write(dd, DES_REG_KEY(dd, i), ++ __le32_to_cpu(dd->ctx->key[i])); ++ } ++ ++ if ((dd->flags & FLAGS_CBC) && dd->req->info) ++ omap_des_write_n(dd, DES_REG_IV(dd, 0), dd->req->info, 2); ++ ++ if (dd->flags & FLAGS_CBC) ++ val |= DES_REG_CTRL_CBC; ++ if (dd->flags & FLAGS_ENCRYPT) ++ val |= DES_REG_CTRL_DIRECTION; ++ ++ mask |= DES_REG_CTRL_CBC | DES_REG_CTRL_DIRECTION; ++ ++ omap_des_write_mask(dd, DES_REG_CTRL(dd), val, mask); ++ ++ return 0; ++} ++ ++static void omap_des_dma_trigger_omap4(struct omap_des_dev *dd, int length) ++{ ++ u32 mask, val; ++ ++ omap_des_write(dd, DES_REG_LENGTH_N(0), length); ++ ++ val = dd->pdata->dma_start; ++ ++ if (dd->dma_lch_out != NULL) ++ val |= dd->pdata->dma_enable_out; ++ if (dd->dma_lch_in != NULL) ++ val |= dd->pdata->dma_enable_in; ++ ++ mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in | ++ dd->pdata->dma_start; ++ ++ omap_des_write_mask(dd, DES_REG_MASK(dd), val, mask); ++} ++ ++static void omap_des_dma_stop(struct omap_des_dev *dd) ++{ ++ u32 mask; ++ ++ mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in | ++ dd->pdata->dma_start; ++ ++ omap_des_write_mask(dd, DES_REG_MASK(dd), 0, mask); ++} ++ ++static struct omap_des_dev *omap_des_find_dev(struct omap_des_ctx *ctx) ++{ ++ struct omap_des_dev *dd = NULL, *tmp; ++ ++ spin_lock_bh(&list_lock); ++ if (!ctx->dd) { ++ list_for_each_entry(tmp, &dev_list, list) { ++ /* FIXME: take fist available des core */ ++ dd = tmp; ++ break; ++ } ++ ctx->dd = dd; ++ } else { ++ /* already found before */ ++ dd = ctx->dd; ++ } ++ spin_unlock_bh(&list_lock); ++ ++ return dd; ++} ++ ++static void omap_des_dma_out_callback(void *data) ++{ ++ struct omap_des_dev *dd = data; ++ ++ /* dma_lch_out - completed */ ++ tasklet_schedule(&dd->done_task); ++} ++ ++static int omap_des_dma_init(struct omap_des_dev *dd) ++{ ++ int err = -ENOMEM; ++ dma_cap_mask_t mask; ++ ++ dd->dma_lch_out = NULL; ++ dd->dma_lch_in = NULL; ++ ++ dma_cap_zero(mask); ++ dma_cap_set(DMA_SLAVE, mask); ++ ++ dd->dma_lch_in = dma_request_slave_channel_compat(mask, ++ omap_dma_filter_fn, ++ &dd->dma_in, ++ dd->dev, "rx"); ++ if (!dd->dma_lch_in) { ++ dev_err(dd->dev, "Unable to request in DMA channel\n"); ++ goto err_dma_in; ++ } ++ ++ dd->dma_lch_out = dma_request_slave_channel_compat(mask, ++ omap_dma_filter_fn, ++ &dd->dma_out, ++ dd->dev, "tx"); ++ if (!dd->dma_lch_out) { ++ dev_err(dd->dev, "Unable to request out DMA channel\n"); ++ goto err_dma_out; ++ } ++ ++ return 0; ++ ++err_dma_out: ++ dma_release_channel(dd->dma_lch_in); ++err_dma_in: ++ if (err) ++ pr_err("error: %d\n", err); ++ return err; ++} ++ ++static void omap_des_dma_cleanup(struct omap_des_dev *dd) ++{ ++ dma_release_channel(dd->dma_lch_out); ++ dma_release_channel(dd->dma_lch_in); ++} ++ ++static void sg_copy_buf(void *buf, struct scatterlist *sg, ++ unsigned int start, unsigned int nbytes, int out) ++{ ++ struct scatter_walk walk; ++ ++ if (!nbytes) ++ return; ++ ++ scatterwalk_start(&walk, sg); ++ scatterwalk_advance(&walk, start); ++ scatterwalk_copychunks(buf, &walk, nbytes, out); ++ scatterwalk_done(&walk, out, 0); ++} ++ ++static int omap_des_crypt_dma(struct crypto_tfm *tfm, ++ struct scatterlist *in_sg, struct scatterlist *out_sg, ++ int in_sg_len, int out_sg_len) ++{ ++ struct omap_des_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct omap_des_dev *dd = ctx->dd; ++ struct dma_async_tx_descriptor *tx_in, *tx_out; ++ struct dma_slave_config cfg; ++ int ret; ++ ++ if (dd->pio_only) { ++ scatterwalk_start(&dd->in_walk, dd->in_sg); ++ scatterwalk_start(&dd->out_walk, dd->out_sg); ++ ++ /* Enable DATAIN interrupt and let it take ++ care of the rest */ ++ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x2); ++ return 0; ++ } ++ ++ dma_sync_sg_for_device(dd->dev, dd->in_sg, in_sg_len, DMA_TO_DEVICE); ++ ++ memset(&cfg, 0, sizeof(cfg)); ++ ++ cfg.src_addr = dd->phys_base + DES_REG_DATA_N(dd, 0); ++ cfg.dst_addr = dd->phys_base + DES_REG_DATA_N(dd, 0); ++ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ cfg.src_maxburst = DST_MAXBURST; ++ cfg.dst_maxburst = DST_MAXBURST; ++ ++ /* IN */ ++ ret = dmaengine_slave_config(dd->dma_lch_in, &cfg); ++ if (ret) { ++ dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n", ++ ret); ++ return ret; ++ } ++ ++ tx_in = dmaengine_prep_slave_sg(dd->dma_lch_in, in_sg, in_sg_len, ++ DMA_MEM_TO_DEV, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ if (!tx_in) { ++ dev_err(dd->dev, "IN prep_slave_sg() failed\n"); ++ return -EINVAL; ++ } ++ ++ /* No callback necessary */ ++ tx_in->callback_param = dd; ++ ++ /* OUT */ ++ ret = dmaengine_slave_config(dd->dma_lch_out, &cfg); ++ if (ret) { ++ dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n", ++ ret); ++ return ret; ++ } ++ ++ tx_out = dmaengine_prep_slave_sg(dd->dma_lch_out, out_sg, out_sg_len, ++ DMA_DEV_TO_MEM, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ if (!tx_out) { ++ dev_err(dd->dev, "OUT prep_slave_sg() failed\n"); ++ return -EINVAL; ++ } ++ ++ tx_out->callback = omap_des_dma_out_callback; ++ tx_out->callback_param = dd; ++ ++ dmaengine_submit(tx_in); ++ dmaengine_submit(tx_out); ++ ++ dma_async_issue_pending(dd->dma_lch_in); ++ dma_async_issue_pending(dd->dma_lch_out); ++ ++ /* start DMA */ ++ dd->pdata->trigger(dd, dd->total); ++ ++ return 0; ++} ++ ++static int omap_des_crypt_dma_start(struct omap_des_dev *dd) ++{ ++ struct crypto_tfm *tfm = crypto_ablkcipher_tfm( ++ crypto_ablkcipher_reqtfm(dd->req)); ++ int err; ++ ++ pr_debug("total: %d\n", dd->total); ++ ++ if (!dd->pio_only) { ++ err = dma_map_sg(dd->dev, dd->in_sg, dd->in_sg_len, ++ DMA_TO_DEVICE); ++ if (!err) { ++ dev_err(dd->dev, "dma_map_sg() error\n"); ++ return -EINVAL; ++ } ++ ++ err = dma_map_sg(dd->dev, dd->out_sg, dd->out_sg_len, ++ DMA_FROM_DEVICE); ++ if (!err) { ++ dev_err(dd->dev, "dma_map_sg() error\n"); ++ return -EINVAL; ++ } ++ } ++ ++ err = omap_des_crypt_dma(tfm, dd->in_sg, dd->out_sg, dd->in_sg_len, ++ dd->out_sg_len); ++ if (err && !dd->pio_only) { ++ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); ++ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, ++ DMA_FROM_DEVICE); ++ } ++ ++ return err; ++} ++ ++static void omap_des_finish_req(struct omap_des_dev *dd, int err) ++{ ++ struct ablkcipher_request *req = dd->req; ++ ++ pr_debug("err: %d\n", err); ++ ++ pm_runtime_put(dd->dev); ++ dd->flags &= ~FLAGS_BUSY; ++ ++ req->base.complete(&req->base, err); ++} ++ ++static int omap_des_crypt_dma_stop(struct omap_des_dev *dd) ++{ ++ int err = 0; ++ ++ pr_debug("total: %d\n", dd->total); ++ ++ omap_des_dma_stop(dd); ++ ++ dmaengine_terminate_all(dd->dma_lch_in); ++ dmaengine_terminate_all(dd->dma_lch_out); ++ ++ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); ++ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, DMA_FROM_DEVICE); ++ ++ return err; ++} ++ ++int omap_des_copy_needed(struct scatterlist *sg) ++{ ++ while (sg) { ++ if (!IS_ALIGNED(sg->offset, 4)) ++ return -1; ++ if (!IS_ALIGNED(sg->length, DES_BLOCK_SIZE)) ++ return -1; ++ sg = sg_next(sg); ++ } ++ return 0; ++} ++ ++int omap_des_copy_sgs(struct omap_des_dev *dd) ++{ ++ void *buf_in, *buf_out; ++ int pages; ++ ++ pages = dd->total >> PAGE_SHIFT; ++ ++ if (dd->total & (PAGE_SIZE-1)) ++ pages++; ++ ++ BUG_ON(!pages); ++ ++ buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); ++ buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); ++ ++ if (!buf_in || !buf_out) { ++ pr_err("Couldn't allocated pages for unaligned cases.\n"); ++ return -1; ++ } ++ ++ dd->orig_out = dd->out_sg; ++ ++ sg_copy_buf(buf_in, dd->in_sg, 0, dd->total, 0); ++ ++ sg_init_table(&dd->in_sgl, 1); ++ sg_set_buf(&dd->in_sgl, buf_in, dd->total); ++ dd->in_sg = &dd->in_sgl; ++ ++ sg_init_table(&dd->out_sgl, 1); ++ sg_set_buf(&dd->out_sgl, buf_out, dd->total); ++ dd->out_sg = &dd->out_sgl; ++ ++ return 0; ++} ++ ++static int omap_des_handle_queue(struct omap_des_dev *dd, ++ struct ablkcipher_request *req) ++{ ++ struct crypto_async_request *async_req, *backlog; ++ struct omap_des_ctx *ctx; ++ struct omap_des_reqctx *rctx; ++ unsigned long flags; ++ int err, ret = 0; ++ ++ spin_lock_irqsave(&dd->lock, flags); ++ if (req) ++ ret = ablkcipher_enqueue_request(&dd->queue, req); ++ if (dd->flags & FLAGS_BUSY) { ++ spin_unlock_irqrestore(&dd->lock, flags); ++ return ret; ++ } ++ backlog = crypto_get_backlog(&dd->queue); ++ async_req = crypto_dequeue_request(&dd->queue); ++ if (async_req) ++ dd->flags |= FLAGS_BUSY; ++ spin_unlock_irqrestore(&dd->lock, flags); ++ ++ if (!async_req) ++ return ret; ++ ++ if (backlog) ++ backlog->complete(backlog, -EINPROGRESS); ++ ++ req = ablkcipher_request_cast(async_req); ++ ++ /* assign new request to device */ ++ dd->req = req; ++ dd->total = req->nbytes; ++ dd->total_save = req->nbytes; ++ dd->in_sg = req->src; ++ dd->out_sg = req->dst; ++ ++ if (omap_des_copy_needed(dd->in_sg) || ++ omap_des_copy_needed(dd->out_sg)) { ++ if (omap_des_copy_sgs(dd)) ++ pr_err("Failed to copy SGs for unaligned cases\n"); ++ dd->sgs_copied = 1; ++ } else { ++ dd->sgs_copied = 0; ++ } ++ ++ dd->in_sg_len = scatterwalk_bytes_sglen(dd->in_sg, dd->total); ++ dd->out_sg_len = scatterwalk_bytes_sglen(dd->out_sg, dd->total); ++ BUG_ON(dd->in_sg_len < 0 || dd->out_sg_len < 0); ++ ++ rctx = ablkcipher_request_ctx(req); ++ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); ++ rctx->mode &= FLAGS_MODE_MASK; ++ dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; ++ ++ dd->ctx = ctx; ++ ctx->dd = dd; ++ ++ err = omap_des_write_ctrl(dd); ++ if (!err) ++ err = omap_des_crypt_dma_start(dd); ++ if (err) { ++ /* des_task will not finish it, so do it here */ ++ omap_des_finish_req(dd, err); ++ tasklet_schedule(&dd->queue_task); ++ } ++ ++ return ret; /* return ret, which is enqueue return value */ ++} ++ ++static void omap_des_done_task(unsigned long data) ++{ ++ struct omap_des_dev *dd = (struct omap_des_dev *)data; ++ void *buf_in, *buf_out; ++ int pages; ++ ++ pr_debug("enter done_task\n"); ++ ++ if (!dd->pio_only) { ++ dma_sync_sg_for_device(dd->dev, dd->out_sg, dd->out_sg_len, ++ DMA_FROM_DEVICE); ++ dma_unmap_sg(dd->dev, dd->in_sg, dd->in_sg_len, DMA_TO_DEVICE); ++ dma_unmap_sg(dd->dev, dd->out_sg, dd->out_sg_len, ++ DMA_FROM_DEVICE); ++ omap_des_crypt_dma_stop(dd); ++ } ++ ++ if (dd->sgs_copied) { ++ buf_in = sg_virt(&dd->in_sgl); ++ buf_out = sg_virt(&dd->out_sgl); ++ ++ sg_copy_buf(buf_out, dd->orig_out, 0, dd->total_save, 1); ++ ++ pages = get_order(dd->total_save); ++ free_pages((unsigned long)buf_in, pages); ++ free_pages((unsigned long)buf_out, pages); ++ } ++ ++ omap_des_finish_req(dd, 0); ++ omap_des_handle_queue(dd, NULL); ++ ++ pr_debug("exit\n"); ++} ++ ++static void omap_des_queue_task(unsigned long data) ++{ ++ struct omap_des_dev *dd = (struct omap_des_dev *)data; ++ ++ omap_des_handle_queue(dd, NULL); ++} ++ ++static int omap_des_crypt(struct ablkcipher_request *req, unsigned long mode) ++{ ++ struct omap_des_ctx *ctx = crypto_ablkcipher_ctx( ++ crypto_ablkcipher_reqtfm(req)); ++ struct omap_des_reqctx *rctx = ablkcipher_request_ctx(req); ++ struct omap_des_dev *dd; ++ ++ pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, ++ !!(mode & FLAGS_ENCRYPT), ++ !!(mode & FLAGS_CBC)); ++ ++ if (!IS_ALIGNED(req->nbytes, DES_BLOCK_SIZE)) { ++ pr_err("request size is not exact amount of DES blocks\n"); ++ return -EINVAL; ++ } ++ ++ dd = omap_des_find_dev(ctx); ++ if (!dd) ++ return -ENODEV; ++ ++ rctx->mode = mode; ++ ++ return omap_des_handle_queue(dd, req); ++} ++ ++/* ********************** ALG API ************************************ */ ++ ++static int omap_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, ++ unsigned int keylen) ++{ ++ struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(tfm); ++ ++ if (keylen != DES_KEY_SIZE) ++ return -EINVAL; ++ ++ pr_debug("enter, keylen: %d\n", keylen); ++ ++ memcpy(ctx->key, key, keylen); ++ ctx->keylen = keylen; ++ ++ return 0; ++} ++ ++static int omap_des_ecb_encrypt(struct ablkcipher_request *req) ++{ ++ return omap_des_crypt(req, FLAGS_ENCRYPT); ++} ++ ++static int omap_des_ecb_decrypt(struct ablkcipher_request *req) ++{ ++ return omap_des_crypt(req, 0); ++} ++ ++static int omap_des_cbc_encrypt(struct ablkcipher_request *req) ++{ ++ return omap_des_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); ++} ++ ++static int omap_des_cbc_decrypt(struct ablkcipher_request *req) ++{ ++ return omap_des_crypt(req, FLAGS_CBC); ++} ++ ++static int omap_des_cra_init(struct crypto_tfm *tfm) ++{ ++ pr_debug("enter\n"); ++ ++ tfm->crt_ablkcipher.reqsize = sizeof(struct omap_des_reqctx); ++ ++ return 0; ++} ++ ++static void omap_des_cra_exit(struct crypto_tfm *tfm) ++{ ++ pr_debug("enter\n"); ++} ++ ++/* ********************** ALGS ************************************ */ ++ ++static struct crypto_alg algs_ecb_cbc[] = { ++{ ++ .cra_name = "ecb(des)", ++ .cra_driver_name = "ecb-des-omap", ++ .cra_priority = 100, ++ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_ASYNC, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct omap_des_ctx), ++ .cra_alignmask = 0, ++ .cra_type = &crypto_ablkcipher_type, ++ .cra_module = THIS_MODULE, ++ .cra_init = omap_des_cra_init, ++ .cra_exit = omap_des_cra_exit, ++ .cra_u.ablkcipher = { ++ .min_keysize = DES_KEY_SIZE, ++ .max_keysize = DES_KEY_SIZE, ++ .setkey = omap_des_setkey, ++ .encrypt = omap_des_ecb_encrypt, ++ .decrypt = omap_des_ecb_decrypt, ++ } ++}, ++{ ++ .cra_name = "cbc(des)", ++ .cra_driver_name = "cbc-des-omap", ++ .cra_priority = 100, ++ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_ASYNC, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct omap_des_ctx), ++ .cra_alignmask = 0, ++ .cra_type = &crypto_ablkcipher_type, ++ .cra_module = THIS_MODULE, ++ .cra_init = omap_des_cra_init, ++ .cra_exit = omap_des_cra_exit, ++ .cra_u.ablkcipher = { ++ .min_keysize = DES_KEY_SIZE, ++ .max_keysize = DES_KEY_SIZE, ++ .ivsize = DES_BLOCK_SIZE, ++ .setkey = omap_des_setkey, ++ .encrypt = omap_des_cbc_encrypt, ++ .decrypt = omap_des_cbc_decrypt, ++ } ++} ++}; ++ ++static struct omap_des_algs_info omap_des_algs_info_ecb_cbc[] = { ++ { ++ .algs_list = algs_ecb_cbc, ++ .size = ARRAY_SIZE(algs_ecb_cbc), ++ }, ++}; ++ ++#ifdef CONFIG_OF ++static const struct omap_des_pdata omap_des_pdata_omap4 = { ++ .algs_info = omap_des_algs_info_ecb_cbc, ++ .algs_info_size = ARRAY_SIZE(omap_des_algs_info_ecb_cbc), ++ .trigger = omap_des_dma_trigger_omap4, ++ .key_ofs = 0x14, ++ .iv_ofs = 0x18, ++ .ctrl_ofs = 0x20, ++ .data_ofs = 0x28, ++ .rev_ofs = 0x30, ++ .mask_ofs = 0x34, ++ .irq_status_ofs = 0x3c, ++ .irq_enable_ofs = 0x40, ++ .dma_enable_in = BIT(5), ++ .dma_enable_out = BIT(6), ++ .major_mask = 0x0700, ++ .major_shift = 8, ++ .minor_mask = 0x003f, ++ .minor_shift = 0, ++}; ++ ++static irqreturn_t omap_des_irq(int irq, void *dev_id) ++{ ++ struct omap_des_dev *dd = dev_id; ++ u32 status, i; ++ u32 *src, *dst; ++ ++ status = omap_des_read(dd, DES_REG_IRQ_STATUS(dd)); ++ if (status & DES_REG_IRQ_DATA_IN) { ++ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x0); ++ ++ BUG_ON(!dd->in_sg); ++ ++ BUG_ON(_calc_walked(in) > dd->in_sg->length); ++ ++ src = sg_virt(dd->in_sg) + _calc_walked(in); ++ ++ for (i = 0; i < DES_BLOCK_WORDS; i++) { ++ omap_des_write(dd, DES_REG_DATA_N(dd, i), *src); ++ ++ scatterwalk_advance(&dd->in_walk, 4); ++ if (dd->in_sg->length == _calc_walked(in)) { ++ dd->in_sg = scatterwalk_sg_next(dd->in_sg); ++ if (dd->in_sg) { ++ scatterwalk_start(&dd->in_walk, ++ dd->in_sg); ++ src = sg_virt(dd->in_sg) + ++ _calc_walked(in); ++ } ++ } else { ++ src++; ++ } ++ } ++ ++ /* Clear IRQ status */ ++ status &= ~DES_REG_IRQ_DATA_IN; ++ omap_des_write(dd, DES_REG_IRQ_STATUS(dd), status); ++ ++ /* Enable DATA_OUT interrupt */ ++ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x4); ++ ++ } else if (status & DES_REG_IRQ_DATA_OUT) { ++ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x0); ++ ++ BUG_ON(!dd->out_sg); ++ ++ BUG_ON(_calc_walked(out) > dd->out_sg->length); ++ ++ dst = sg_virt(dd->out_sg) + _calc_walked(out); ++ ++ for (i = 0; i < DES_BLOCK_WORDS; i++) { ++ *dst = omap_des_read(dd, DES_REG_DATA_N(dd, i)); ++ scatterwalk_advance(&dd->out_walk, 4); ++ if (dd->out_sg->length == _calc_walked(out)) { ++ dd->out_sg = scatterwalk_sg_next(dd->out_sg); ++ if (dd->out_sg) { ++ scatterwalk_start(&dd->out_walk, ++ dd->out_sg); ++ dst = sg_virt(dd->out_sg) + ++ _calc_walked(out); ++ } ++ } else { ++ dst++; ++ } ++ } ++ ++ dd->total -= DES_BLOCK_SIZE; ++ ++ BUG_ON(dd->total < 0); ++ ++ /* Clear IRQ status */ ++ status &= ~DES_REG_IRQ_DATA_OUT; ++ omap_des_write(dd, DES_REG_IRQ_STATUS(dd), status); ++ ++ if (!dd->total) ++ /* All bytes read! */ ++ tasklet_schedule(&dd->done_task); ++ else ++ /* Enable DATA_IN interrupt for next block */ ++ omap_des_write(dd, DES_REG_IRQ_ENABLE(dd), 0x2); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static const struct of_device_id omap_des_of_match[] = { ++ { ++ .compatible = "ti,omap4-des", ++ .data = &omap_des_pdata_omap4, ++ }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, omap_des_of_match); ++ ++static int omap_des_get_res_of(struct omap_des_dev *dd, ++ struct device *dev, struct resource *res) ++{ ++ struct device_node *node = dev->of_node; ++ const struct of_device_id *match; ++ int err = 0; ++ ++ match = of_match_device(of_match_ptr(omap_des_of_match), dev); ++ if (!match) { ++ dev_err(dev, "no compatible OF match\n"); ++ err = -EINVAL; ++ goto err; ++ } ++ ++ err = of_address_to_resource(node, 0, res); ++ if (err < 0) { ++ dev_err(dev, "can't translate OF node address\n"); ++ err = -EINVAL; ++ goto err; ++ } ++ ++ dd->dma_out = -1; /* Dummy value that's unused */ ++ dd->dma_in = -1; /* Dummy value that's unused */ ++ ++ dd->pdata = match->data; ++ ++err: ++ return err; ++} ++#else ++static const struct of_device_id omap_des_of_match[] = { ++ {}, ++}; ++ ++static int omap_des_get_res_of(struct omap_des_dev *dd, ++ struct device *dev, struct resource *res) ++{ ++ return -EINVAL; ++} ++#endif ++ ++static int omap_des_get_res_pdev(struct omap_des_dev *dd, ++ struct platform_device *pdev, struct resource *res) ++{ ++ struct device *dev = &pdev->dev; ++ struct resource *r; ++ int err = 0; ++ ++ /* Get the base address */ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!r) { ++ dev_err(dev, "no MEM resource info\n"); ++ err = -ENODEV; ++ goto err; ++ } ++ memcpy(res, r, sizeof(*res)); ++ ++ /* Get the DMA out channel */ ++ r = platform_get_resource(pdev, IORESOURCE_DMA, 0); ++ if (!r) { ++ dev_err(dev, "no DMA out resource info\n"); ++ err = -ENODEV; ++ goto err; ++ } ++ dd->dma_out = r->start; ++ ++ /* Get the DMA in channel */ ++ r = platform_get_resource(pdev, IORESOURCE_DMA, 1); ++ if (!r) { ++ dev_err(dev, "no DMA in resource info\n"); ++ err = -ENODEV; ++ goto err; ++ } ++ dd->dma_in = r->start; ++ ++ /* non-DT devices get pdata from pdev */ ++ dd->pdata = pdev->dev.platform_data; ++ ++err: ++ return err; ++} ++ ++static int omap_des_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct omap_des_dev *dd; ++ struct crypto_alg *algp; ++ struct resource res; ++ int err = -ENOMEM, i, j, irq = -1; ++ u32 reg; ++ ++ dd = devm_kzalloc(dev, sizeof(struct omap_des_dev), GFP_KERNEL); ++ if (dd == NULL) { ++ dev_err(dev, "unable to alloc data struct.\n"); ++ goto err_data; ++ } ++ dd->dev = dev; ++ platform_set_drvdata(pdev, dd); ++ ++ spin_lock_init(&dd->lock); ++ crypto_init_queue(&dd->queue, OMAP_DES_QUEUE_LENGTH); ++ ++ err = (dev->of_node) ? omap_des_get_res_of(dd, dev, &res) : ++ omap_des_get_res_pdev(dd, pdev, &res); ++ if (err) ++ goto err_res; ++ ++ dd->io_base = devm_request_and_ioremap(dev, &res); ++ if (!dd->io_base) { ++ dev_err(dev, "can't ioremap\n"); ++ err = -ENOMEM; ++ goto err_res; ++ } ++ dd->phys_base = res.start; ++ ++ pm_runtime_enable(dev); ++ pm_runtime_get_sync(dev); ++ ++ omap_des_dma_stop(dd); ++ ++ reg = omap_des_read(dd, DES_REG_REV(dd)); ++ ++ pm_runtime_put_sync(dev); ++ ++ dev_info(dev, "OMAP DES hw accel rev: %u.%u\n", ++ (reg & dd->pdata->major_mask) >> dd->pdata->major_shift, ++ (reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift); ++ ++ tasklet_init(&dd->done_task, omap_des_done_task, (unsigned long)dd); ++ tasklet_init(&dd->queue_task, omap_des_queue_task, (unsigned long)dd); ++ ++ err = omap_des_dma_init(dd); ++ if (err && DES_REG_IRQ_STATUS(dd) && DES_REG_IRQ_ENABLE(dd)) { ++ dd->pio_only = 1; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "can't get IRQ resource\n"); ++ goto err_irq; ++ } ++ ++ err = devm_request_irq(dev, irq, omap_des_irq, 0, ++ dev_name(dev), dd); ++ if (err) { ++ dev_err(dev, "Unable to grab omap-des IRQ\n"); ++ goto err_irq; ++ } ++ } ++ ++ ++ INIT_LIST_HEAD(&dd->list); ++ spin_lock(&list_lock); ++ list_add_tail(&dd->list, &dev_list); ++ spin_unlock(&list_lock); ++ ++ for (i = 0; i < dd->pdata->algs_info_size; i++) { ++ for (j = 0; j < dd->pdata->algs_info[i].size; j++) { ++ algp = &dd->pdata->algs_info[i].algs_list[j]; ++ ++ pr_debug("reg alg: %s\n", algp->cra_name); ++ INIT_LIST_HEAD(&algp->cra_list); ++ ++ err = crypto_register_alg(algp); ++ if (err) ++ goto err_algs; ++ ++ dd->pdata->algs_info[i].registered++; ++ } ++ } ++ ++ return 0; ++err_algs: ++ for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) ++ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) ++ crypto_unregister_alg( ++ &dd->pdata->algs_info[i].algs_list[j]); ++ if (!dd->pio_only) ++ omap_des_dma_cleanup(dd); ++err_irq: ++ tasklet_kill(&dd->done_task); ++ tasklet_kill(&dd->queue_task); ++ pm_runtime_disable(dev); ++err_res: ++ dd = NULL; ++err_data: ++ dev_err(dev, "initialization failed.\n"); ++ return err; ++} ++ ++static int omap_des_remove(struct platform_device *pdev) ++{ ++ struct omap_des_dev *dd = platform_get_drvdata(pdev); ++ int i, j; ++ ++ if (!dd) ++ return -ENODEV; ++ ++ spin_lock(&list_lock); ++ list_del(&dd->list); ++ spin_unlock(&list_lock); ++ ++ for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) ++ for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) ++ crypto_unregister_alg( ++ &dd->pdata->algs_info[i].algs_list[j]); ++ ++ tasklet_kill(&dd->done_task); ++ tasklet_kill(&dd->queue_task); ++ omap_des_dma_cleanup(dd); ++ pm_runtime_disable(dd->dev); ++ dd = NULL; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static int omap_des_suspend(struct device *dev) ++{ ++ pm_runtime_put_sync(dev); ++ return 0; ++} ++ ++static int omap_des_resume(struct device *dev) ++{ ++ pm_runtime_get_sync(dev); ++ return 0; ++} ++#endif ++ ++static const struct dev_pm_ops omap_des_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(omap_des_suspend, omap_des_resume) ++}; ++ ++static struct platform_driver omap_des_driver = { ++ .probe = omap_des_probe, ++ .remove = omap_des_remove, ++ .driver = { ++ .name = "omap-des", ++ .owner = THIS_MODULE, ++ .pm = &omap_des_pm_ops, ++ .of_match_table = omap_des_of_match, ++ }, ++}; ++ ++module_platform_driver(omap_des_driver); ++ ++MODULE_DESCRIPTION("OMAP DES hw acceleration support."); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Joel Fernandes <joelf@ti.com>"); diff --git a/target/linux/omap/patches-3.12/601-crypto-omap-des-Add-config-and-build-options.patch b/target/linux/omap/patches-3.12/601-crypto-omap-des-Add-config-and-build-options.patch new file mode 100644 index 0000000000..495e1a24de --- /dev/null +++ b/target/linux/omap/patches-3.12/601-crypto-omap-des-Add-config-and-build-options.patch @@ -0,0 +1,61 @@ +From patchwork Thu Aug 29 23:27:52 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [2/3] crypto: omap-des: Add config and build options +From: Joel Fernandes <joelf@ti.com> +X-Patchwork-Id: 2851671 +Message-Id: <1377818873-21174-3-git-send-email-joelf@ti.com> +To: Herbert Xu <herbert@gondor.hengli.com.au>, "David S. Miller" + <davem@davemloft.net>, Mark Greer <mgreer@animalcreek.com>, Tony Lindgren + <tony@atomide.com>, Lokesh Vutla <lokeshvutla@ti.com> +Cc: Joel Fernandes <joelf@ti.com>, + Linux OMAP List <linux-omap@vger.kernel.org>, + Linux Kernel Mailing List <linux-kernel@vger.kernel.org>, + Linux ARM Kernel List <linux-arm-kernel@lists.infradead.org>, + Linux Crypto Mailing List <linux-crypto@vger.kernel.org> +Date: Thu, 29 Aug 2013 18:27:52 -0500 + +Add config and build options for the newly added omap-des driver. + +Signed-off-by: Joel Fernandes <joelf@ti.com> + +--- +drivers/crypto/Kconfig | 11 +++++++++++ + drivers/crypto/Makefile | 1 + + 2 files changed, 12 insertions(+) + +diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig +index e289afa..119a8e5 100644 +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -259,6 +259,17 @@ config CRYPTO_DEV_OMAP_AES + OMAP processors have AES module accelerator. Select this if you + want to use the OMAP module for AES algorithms. + ++config CRYPTO_DEV_OMAP_DES ++ tristate "Support for OMAP DES3DES hw engine" ++ depends on ARCH_OMAP2PLUS ++ select CRYPTO_DES ++ select CRYPTO_BLKCIPHER2 ++ help ++ OMAP processors have DES/3DES module accelerator. Select this if you ++ want to use the OMAP module for DES and 3DES algorithms. Currently ++ the ECB and CBC modes of operation supported by the driver. Also ++ accesses made on unaligned boundaries are also supported. ++ + config CRYPTO_DEV_PICOXCELL + tristate "Support for picoXcell IPSEC and Layer2 crypto engines" + depends on ARCH_PICOXCELL && HAVE_CLK +diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile +index 38ce13d..ada440f 100644 +--- a/drivers/crypto/Makefile ++++ b/drivers/crypto/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o + obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ + obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o + obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o ++obj-$(CONFIG_CRYPTO_DEV_OMAP_DES) += omap-des.o + obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o + obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o + obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o diff --git a/target/linux/omap/patches-3.12/602-crypto-omap-des-Add-triple-DES-des3_ede-support-to-driver.patch b/target/linux/omap/patches-3.12/602-crypto-omap-des-Add-triple-DES-des3_ede-support-to-driver.patch new file mode 100644 index 0000000000..f94e0f52bf --- /dev/null +++ b/target/linux/omap/patches-3.12/602-crypto-omap-des-Add-triple-DES-des3_ede-support-to-driver.patch @@ -0,0 +1,113 @@ +From patchwork Thu Aug 29 23:27:53 2013 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [3/3] crypto: omap-des: Add triple DES (des3_ede) support to driver +From: Joel Fernandes <joelf@ti.com> +X-Patchwork-Id: 2851679 +Message-Id: <1377818873-21174-4-git-send-email-joelf@ti.com> +To: Herbert Xu <herbert@gondor.hengli.com.au>, "David S. Miller" + <davem@davemloft.net>, Mark Greer <mgreer@animalcreek.com>, Tony Lindgren + <tony@atomide.com>, Lokesh Vutla <lokeshvutla@ti.com> +Cc: Joel Fernandes <joelf@ti.com>, + Linux OMAP List <linux-omap@vger.kernel.org>, + Linux Kernel Mailing List <linux-kernel@vger.kernel.org>, + Linux ARM Kernel List <linux-arm-kernel@lists.infradead.org>, + Linux Crypto Mailing List <linux-crypto@vger.kernel.org> +Date: Thu, 29 Aug 2013 18:27:53 -0500 + +OMAP DES module supports 3DES operation where 3 64-bit keys are used to +perform a DES encrypt-decrypt-encrypt (ede) operation on a buffer. + +Signed-off-by: Joel Fernandes <joelf@ti.com> + +--- +drivers/crypto/omap-des.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 50 insertions(+), 3 deletions(-) + +diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c +index 6a9a25f..0df60cb 100644 +--- a/drivers/crypto/omap-des.c ++++ b/drivers/crypto/omap-des.c +@@ -83,7 +83,7 @@ struct omap_des_ctx { + struct omap_des_dev *dd; + + int keylen; +- u32 key[DES_KEY_SIZE / sizeof(u32)]; ++ u32 key[(3 * DES_KEY_SIZE) / sizeof(u32)]; + unsigned long flags; + }; + +@@ -265,8 +265,10 @@ static int omap_des_write_ctrl(struct omap_des_dev *dd) + val |= DES_REG_CTRL_CBC; + if (dd->flags & FLAGS_ENCRYPT) + val |= DES_REG_CTRL_DIRECTION; ++ if (key32 == 6) ++ val |= DES_REG_CTRL_TDES; + +- mask |= DES_REG_CTRL_CBC | DES_REG_CTRL_DIRECTION; ++ mask |= DES_REG_CTRL_CBC | DES_REG_CTRL_DIRECTION | DES_REG_CTRL_TDES; + + omap_des_write_mask(dd, DES_REG_CTRL(dd), val, mask); + +@@ -725,7 +727,7 @@ static int omap_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + { + struct omap_des_ctx *ctx = crypto_ablkcipher_ctx(tfm); + +- if (keylen != DES_KEY_SIZE) ++ if (keylen != DES_KEY_SIZE && keylen != (3*DES_KEY_SIZE)) + return -EINVAL; + + pr_debug("enter, keylen: %d\n", keylen); +@@ -817,6 +819,51 @@ static struct crypto_alg algs_ecb_cbc[] = { + .encrypt = omap_des_cbc_encrypt, + .decrypt = omap_des_cbc_decrypt, + } ++}, ++{ ++ .cra_name = "ecb(des3_ede)", ++ .cra_driver_name = "ecb-des3-omap", ++ .cra_priority = 100, ++ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_ASYNC, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct omap_des_ctx), ++ .cra_alignmask = 0, ++ .cra_type = &crypto_ablkcipher_type, ++ .cra_module = THIS_MODULE, ++ .cra_init = omap_des_cra_init, ++ .cra_exit = omap_des_cra_exit, ++ .cra_u.ablkcipher = { ++ .min_keysize = 3*DES_KEY_SIZE, ++ .max_keysize = 3*DES_KEY_SIZE, ++ .setkey = omap_des_setkey, ++ .encrypt = omap_des_ecb_encrypt, ++ .decrypt = omap_des_ecb_decrypt, ++ } ++}, ++{ ++ .cra_name = "cbc(des3_ede)", ++ .cra_driver_name = "cbc-des3-omap", ++ .cra_priority = 100, ++ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | ++ CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_ASYNC, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct omap_des_ctx), ++ .cra_alignmask = 0, ++ .cra_type = &crypto_ablkcipher_type, ++ .cra_module = THIS_MODULE, ++ .cra_init = omap_des_cra_init, ++ .cra_exit = omap_des_cra_exit, ++ .cra_u.ablkcipher = { ++ .min_keysize = 3*DES_KEY_SIZE, ++ .max_keysize = 3*DES_KEY_SIZE, ++ .ivsize = DES_BLOCK_SIZE, ++ .setkey = omap_des_setkey, ++ .encrypt = omap_des_cbc_encrypt, ++ .decrypt = omap_des_cbc_decrypt, ++ } + } + }; + diff --git a/target/linux/omap/patches-3.12/797-ARM_dts_omap4-panda-es_Do_not_reset_gpio1.patch b/target/linux/omap/patches-3.12/797-ARM_dts_omap4-panda-es_Do_not_reset_gpio1.patch new file mode 100644 index 0000000000..580bcce3c4 --- /dev/null +++ b/target/linux/omap/patches-3.12/797-ARM_dts_omap4-panda-es_Do_not_reset_gpio1.patch @@ -0,0 +1,30 @@ +From c1bac171c4f203101611110869bd2511c8153974 Mon Sep 17 00:00:00 2001 +From: Nishanth Menon <nm@ti.com> +Date: Thu, 10 Oct 2013 16:44:41 +0000 +Subject: ARM: dts: omap4-panda-es: Do not reset gpio1 + +Do not reset GPIO1 at boot-up because GPIO 7 in GPIO1 block is used on +OMAP4460 PandaBoard-ES to select voltage register in TPS62361 which +supplies VDD_MPU. + +Without this, OMAP4460 PandaBoard-ES boards fail to boot-up because +MPU voltage switches over to VSET0 voltage value (boot voltage) which +is not sufficient to operate the device at OPP100. + +Signed-off-by: Nishanth Menon <nm@ti.com> +Signed-off-by: Benoit Cousson <bcousson@baylibre.com> +--- +diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts +index 56c4354..816d1c9 100644 +--- a/arch/arm/boot/dts/omap4-panda-es.dts ++++ b/arch/arm/boot/dts/omap4-panda-es.dts +@@ -62,3 +62,7 @@ + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + }; + }; ++ ++&gpio1 { ++ ti,no-reset-on-init; ++}; +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/800-ARM_OMAP2plus_irq_AM33XX_add_missing_register_check.patch b/target/linux/omap/patches-3.12/800-ARM_OMAP2plus_irq_AM33XX_add_missing_register_check.patch new file mode 100644 index 0000000000..a6c80a2d9b --- /dev/null +++ b/target/linux/omap/patches-3.12/800-ARM_OMAP2plus_irq_AM33XX_add_missing_register_check.patch @@ -0,0 +1,28 @@ +From 0bebda684857f76548ea48c8886785198701d8d3 Mon Sep 17 00:00:00 2001 +From: Markus Pargmann <mpa@pengutronix.de> +Date: Thu, 17 Oct 2013 07:18:38 +0000 +Subject: ARM: OMAP2+: irq, AM33XX add missing register check + +am33xx has a INTC_PENDING_IRQ3 register that is not checked for pending +interrupts. This patch adds AM33XX to the ifdef of SOCs that have to +check this register. + +Cc: stable@vger.kernel.org +Signed-off-by: Markus Pargmann <mpa@pengutronix.de> +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- +diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c +index 3926f37..e022a86 100644 +--- a/arch/arm/mach-omap2/irq.c ++++ b/arch/arm/mach-omap2/irq.c +@@ -233,7 +233,7 @@ static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs + goto out; + + irqnr = readl_relaxed(base_addr + 0xd8); +-#ifdef CONFIG_SOC_TI81XX ++#if IS_ENABLED(CONFIG_SOC_TI81XX) || IS_ENABLED(CONFIG_SOC_AM33XX) + if (irqnr) + goto out; + irqnr = readl_relaxed(base_addr + 0xf8); +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/801-ARM_dts_am33xx_change_usb_ctrl_module_label.patch b/target/linux/omap/patches-3.12/801-ARM_dts_am33xx_change_usb_ctrl_module_label.patch new file mode 100644 index 0000000000..590fe5f373 --- /dev/null +++ b/target/linux/omap/patches-3.12/801-ARM_dts_am33xx_change_usb_ctrl_module_label.patch @@ -0,0 +1,44 @@ +From e7243b7673a20ac28cfdc78c8862587ea8173a39 Mon Sep 17 00:00:00 2001 +From: Markus Pargmann <mpa@pengutronix.de> +Date: Mon, 14 Oct 2013 12:49:21 +0000 +Subject: ARM: dts: am33xx, change usb ctrl module label + +Control module is not usb specific. +Changes the label to usb_ctrl_mod. + +Signed-off-by: Markus Pargmann <mpa@pengutronix.de> +Signed-off-by: Benoit Cousson <bcousson@baylibre.com> +--- +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 97f5019..0ca13ad 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -416,7 +416,7 @@ + ti,hwmods = "usb_otg_hs"; + status = "disabled"; + +- ctrl_mod: control@44e10000 { ++ usb_ctrl_mod: control@44e10000 { + compatible = "ti,am335x-usb-ctrl-module"; + reg = <0x44e10620 0x10 + 0x44e10648 0x4>; +@@ -429,7 +429,7 @@ + reg = <0x47401300 0x100>; + reg-names = "phy"; + status = "disabled"; +- ti,ctrl_mod = <&ctrl_mod>; ++ ti,ctrl_mod = <&usb_ctrl_mod>; + }; + + usb0: usb@47401000 { +@@ -477,7 +477,7 @@ + reg = <0x47401b00 0x100>; + reg-names = "phy"; + status = "disabled"; +- ti,ctrl_mod = <&ctrl_mod>; ++ ti,ctrl_mod = <&usb_ctrl_mod>; + }; + + usb1: usb@47401800 { +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/802-ARM_OMAP3plus_do_not register_non-dt_OPP_tables_for_device_tree_boot.patch b/target/linux/omap/patches-3.12/802-ARM_OMAP3plus_do_not register_non-dt_OPP_tables_for_device_tree_boot.patch new file mode 100644 index 0000000000..48bd156632 --- /dev/null +++ b/target/linux/omap/patches-3.12/802-ARM_OMAP3plus_do_not register_non-dt_OPP_tables_for_device_tree_boot.patch @@ -0,0 +1,40 @@ +From 92d51856d7405fa55bcf3d6f20d7e97e0bf2656c Mon Sep 17 00:00:00 2001 +From: Nishanth Menon <nm@ti.com> +Date: Wed, 16 Oct 2013 15:39:01 +0000 +Subject: ARM: OMAP3+: do not register non-dt OPP tables for device tree boot + +OMAP3+ supports both device tree and non-device tree boot. +Device tree bindings for OMAP3+ is supposed to be added via dts following: +Documentation/devicetree/bindings/power/opp.txt + +Since we now have device tree entries for OMAP3+ cpu OPPs, +The current code wrongly adds duplicate OPPs. So, dont register OPPs +when booting using device tree. + +Signed-off-by: Nishanth Menon <nm@ti.com> +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- +diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c +index bd41d59..82fd8c7 100644 +--- a/arch/arm/mach-omap2/opp.c ++++ b/arch/arm/mach-omap2/opp.c +@@ -17,6 +17,7 @@ + * GNU General Public License for more details. + */ + #include <linux/module.h> ++#include <linux/of.h> + #include <linux/opp.h> + #include <linux/cpu.h> + +@@ -40,6 +41,9 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, + { + int i, r; + ++ if (of_have_populated_dt()) ++ return -EINVAL; ++ + if (!opp_def || !opp_def_size) { + pr_err("%s: invalid params!\n", __func__); + return -EINVAL; +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/803-ARM_OMAP2plus_add_missing_lateinit_hook_for_calling_pm_late_init.patch b/target/linux/omap/patches-3.12/803-ARM_OMAP2plus_add_missing_lateinit_hook_for_calling_pm_late_init.patch new file mode 100644 index 0000000000..052d364cf3 --- /dev/null +++ b/target/linux/omap/patches-3.12/803-ARM_OMAP2plus_add_missing_lateinit_hook_for_calling_pm_late_init.patch @@ -0,0 +1,135 @@ +From 765e7a067eebf372687048ba0242e27f43cf0d71 Mon Sep 17 00:00:00 2001 +From: Nishanth Menon <nm@ti.com> +Date: Wed, 16 Oct 2013 15:39:02 +0000 +Subject: ARM: OMAP2+: add missing lateinit hook for calling pm late init + +AM335x, AM43xx, OMAP5 and DRA7 have missing late init hook. Introduce +SoC specific hook with a call to OMAP2+ generic lateinit hook. This +allows the generic late initializations such as cpufreq hooks to be +active. + +Based on out-of-tree patches that need to be introduced in +mainline, this introduction allows us to provide the foundation for +further SoC specific features as they are developed. + +Cc: Benoit Cousson <bcousson@baylibre.com> +Cc: Kevin Hilman <khilman@deeprootsystems.com> +Cc: Paul Walmsley <paul@pwsan.com> +Cc: Tony Lindgren <tony@atomide.com> +Signed-off-by: Nishanth Menon <nm@ti.com> +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- +diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c +index 3896b12..19f1652 100644 +--- a/arch/arm/mach-omap2/board-generic.c ++++ b/arch/arm/mach-omap2/board-generic.c +@@ -146,6 +146,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap_generic_init, ++ .init_late = am33xx_init_late, + .init_time = omap3_gptimer_timer_init, + .dt_compat = am33xx_boards_compat, + .restart = am33xx_restart, +@@ -185,6 +186,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)") + .init_early = omap5_init_early, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, ++ .init_late = omap5_init_late, + .init_time = omap5_realtime_timer_init, + .dt_compat = omap5_boards_compat, + .restart = omap44xx_restart, +@@ -200,6 +202,7 @@ static const char *am43_boards_compat[] __initdata = { + DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") + .map_io = am33xx_map_io, + .init_early = am43xx_init_early, ++ .init_late = am43xx_init_late, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, + .init_time = omap3_sync32k_timer_init, +@@ -218,6 +221,7 @@ DT_MACHINE_START(DRA7XX_DT, "Generic DRA7XX (Flattened Device Tree)") + .smp = smp_ops(omap4_smp_ops), + .map_io = omap5_map_io, + .init_early = dra7xx_init_early, ++ .init_late = dra7xx_init_late, + .init_irq = omap_gic_of_init, + .init_machine = omap_generic_init, + .init_time = omap5_realtime_timer_init, +diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h +index c6aebf0..f7644fe 100644 +--- a/arch/arm/mach-omap2/common.h ++++ b/arch/arm/mach-omap2/common.h +@@ -98,6 +98,7 @@ void am35xx_init_early(void); + void ti81xx_init_early(void); + void am33xx_init_early(void); + void am43xx_init_early(void); ++void am43xx_init_late(void); + void omap4430_init_early(void); + void omap5_init_early(void); + void omap3_init_late(void); /* Do not use this one */ +@@ -109,8 +110,11 @@ void omap35xx_init_late(void); + void omap3630_init_late(void); + void am35xx_init_late(void); + void ti81xx_init_late(void); ++void am33xx_init_late(void); ++void omap5_init_late(void); + int omap2_common_pm_late_init(void); + void dra7xx_init_early(void); ++void dra7xx_init_late(void); + + #ifdef CONFIG_SOC_BUS + void omap_soc_device_init(void); +diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c +index ff2113c..a2cbb44 100644 +--- a/arch/arm/mach-omap2/io.c ++++ b/arch/arm/mach-omap2/io.c +@@ -583,6 +583,11 @@ void __init am33xx_init_early(void) + omap_hwmod_init_postsetup(); + omap_clk_init = am33xx_clk_init; + } ++ ++void __init am33xx_init_late(void) ++{ ++ omap_common_late_init(); ++} + #endif + + #ifdef CONFIG_SOC_AM43XX +@@ -596,6 +601,11 @@ void __init am43xx_init_early(void) + omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE), NULL); + omap3xxx_check_revision(); + } ++ ++void __init am43xx_init_late(void) ++{ ++ omap_common_late_init(); ++} + #endif + + #ifdef CONFIG_ARCH_OMAP4 +@@ -651,6 +661,11 @@ void __init omap5_init_early(void) + omap54xx_hwmod_init(); + omap_hwmod_init_postsetup(); + } ++ ++void __init omap5_init_late(void) ++{ ++ omap_common_late_init(); ++} + #endif + + #ifdef CONFIG_SOC_DRA7XX +@@ -671,6 +686,11 @@ void __init dra7xx_init_early(void) + dra7xx_hwmod_init(); + omap_hwmod_init_postsetup(); + } ++ ++void __init dra7xx_init_late(void) ++{ ++ omap_common_late_init(); ++} + #endif + + +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/804-ARM_OMAP3plus_use_cpu0-cpufreq_driver_in_device_tree_supported_boot.patch b/target/linux/omap/patches-3.12/804-ARM_OMAP3plus_use_cpu0-cpufreq_driver_in_device_tree_supported_boot.patch new file mode 100644 index 0000000000..600fd1a174 --- /dev/null +++ b/target/linux/omap/patches-3.12/804-ARM_OMAP3plus_use_cpu0-cpufreq_driver_in_device_tree_supported_boot.patch @@ -0,0 +1,50 @@ +From 60c5fc86d01154e2a005bf701f495426ebc81f73 Mon Sep 17 00:00:00 2001 +From: Nishanth Menon <nm@ti.com> +Date: Wed, 16 Oct 2013 15:39:03 +0000 +Subject: ARM: OMAP3+: use cpu0-cpufreq driver in device tree supported boot + +With OMAP3+ and AM33xx supported SoC having defined CPU device tree +entries with operating-points and clock nodes defined, we can now use +the SoC generic cpufreq-cpu0 driver by registering appropriate device. + +Cc: Benoit Cousson <bcousson@baylibre.com> +Cc: Kevin Hilman <khilman@deeprootsystems.com> +Cc: Paul Walmsley <paul@pwsan.com> +Cc: Tony Lindgren <tony@atomide.com> +Signed-off-by: Nishanth Menon <nm@ti.com> +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- +diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c +index e742118..360b2da 100644 +--- a/arch/arm/mach-omap2/pm.c ++++ b/arch/arm/mach-omap2/pm.c +@@ -266,7 +266,12 @@ static void __init omap4_init_voltages(void) + + static inline void omap_init_cpufreq(void) + { +- struct platform_device_info devinfo = { .name = "omap-cpufreq", }; ++ struct platform_device_info devinfo = { }; ++ ++ if (!of_have_populated_dt()) ++ devinfo.name = "omap-cpufreq"; ++ else ++ devinfo.name = "cpufreq-cpu0"; + platform_device_register_full(&devinfo); + } + +@@ -300,10 +305,11 @@ int __init omap2_common_pm_late_init(void) + /* Smartreflex device init */ + omap_devinit_smartreflex(); + +- /* cpufreq dummy device instantiation */ +- omap_init_cpufreq(); + } + ++ /* cpufreq dummy device instantiation */ ++ omap_init_cpufreq(); ++ + #ifdef CONFIG_SUSPEND + suspend_set_ops(&omap_pm_ops); + #endif +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/805-ARM_dts_TWL4030_Add_missing_regulators.patch b/target/linux/omap/patches-3.12/805-ARM_dts_TWL4030_Add_missing_regulators.patch new file mode 100644 index 0000000000..22d6f95157 --- /dev/null +++ b/target/linux/omap/patches-3.12/805-ARM_dts_TWL4030_Add_missing_regulators.patch @@ -0,0 +1,82 @@ +From b86684d70f1e45cae4a85686e6f78d5db341fa85 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel <sre@debian.org> +Date: Tue, 22 Oct 2013 22:49:37 +0000 +Subject: ARM: dts: TWL4030: Add missing regulators + +The twl4030.dtsi is missing some regulators. This patch adds +the missing ones and orders the regulators alphabetically. + +Signed-off-by: Sebastian Reichel <sre@debian.org> +Signed-off-by: Benoit Cousson <bcousson@baylibre.com> +--- +diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi +index ae6a17a..cb5afcd 100644 +--- a/arch/arm/boot/dts/twl4030.dtsi ++++ b/arch/arm/boot/dts/twl4030.dtsi +@@ -23,6 +23,22 @@ + compatible = "ti,twl4030-wdt"; + }; + ++ vaux1: regulator-vaux1 { ++ compatible = "ti,twl4030-vaux1"; ++ }; ++ ++ vaux2: regulator-vaux2 { ++ compatible = "ti,twl4030-vaux2"; ++ }; ++ ++ vaux3: regulator-vaux3 { ++ compatible = "ti,twl4030-vaux3"; ++ }; ++ ++ vaux4: regulator-vaux4 { ++ compatible = "ti,twl4030-vaux4"; ++ }; ++ + vcc: regulator-vdd1 { + compatible = "ti,twl4030-vdd1"; + regulator-min-microvolt = <600000>; +@@ -35,10 +51,20 @@ + regulator-max-microvolt = <1800000>; + }; + +- vpll2: regulator-vpll2 { +- compatible = "ti,twl4030-vpll2"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; ++ vio: regulator-vio { ++ compatible = "ti,twl4030-vio"; ++ }; ++ ++ vintana1: regulator-vintana1 { ++ compatible = "ti,twl4030-vintana1"; ++ }; ++ ++ vintana2: regulator-vintana2 { ++ compatible = "ti,twl4030-vintana2"; ++ }; ++ ++ vintdig: regulator-vintdig { ++ compatible = "ti,twl4030-vintdig"; + }; + + vmmc1: regulator-vmmc1 { +@@ -65,6 +91,16 @@ + compatible = "ti,twl4030-vusb3v1"; + }; + ++ vpll1: regulator-vpll1 { ++ compatible = "ti,twl4030-vpll1"; ++ }; ++ ++ vpll2: regulator-vpll2 { ++ compatible = "ti,twl4030-vpll2"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ + vsim: regulator-vsim { + compatible = "ti,twl4030-vsim"; + regulator-min-microvolt = <1800000>; +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/806-ARM_dts_TWL4030_Add_power_button_support.patch b/target/linux/omap/patches-3.12/806-ARM_dts_TWL4030_Add_power_button_support.patch new file mode 100644 index 0000000000..a47a822c46 --- /dev/null +++ b/target/linux/omap/patches-3.12/806-ARM_dts_TWL4030_Add_power_button_support.patch @@ -0,0 +1,26 @@ +From a3317d4f2fcd064071bc188cbbc2769dda73e487 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel <sre@debian.org> +Date: Tue, 22 Oct 2013 22:49:43 +0000 +Subject: ARM: dts: TWL4030: Add power button support + +Enable support for the power button. + +Signed-off-by: Sebastian Reichel <sre@debian.org> +Signed-off-by: Benoit Cousson <bcousson@baylibre.com> +--- +diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi +index cb5afcd..af7fa40 100644 +--- a/arch/arm/boot/dts/twl4030.dtsi ++++ b/arch/arm/boot/dts/twl4030.dtsi +@@ -133,4 +133,9 @@ + compatible = "ti,twl4030-pwmled"; + #pwm-cells = <2>; + }; ++ ++ twl_pwrbutton: pwrbutton { ++ compatible = "ti,twl4030-pwrbutton"; ++ interrupts = <8>; ++ }; + }; +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/807-ARM_dts_AM33XX_Add_hwspinlock_node.patch b/target/linux/omap/patches-3.12/807-ARM_dts_AM33XX_Add_hwspinlock_node.patch new file mode 100644 index 0000000000..2815a70d33 --- /dev/null +++ b/target/linux/omap/patches-3.12/807-ARM_dts_AM33XX_Add_hwspinlock_node.patch @@ -0,0 +1,30 @@ +From d4cbe80db468dcfaa058f9f00a332784e5dff316 Mon Sep 17 00:00:00 2001 +From: Suman Anna <s-anna@ti.com> +Date: Thu, 10 Oct 2013 21:15:35 +0000 +Subject: ARM: dts: AM33XX: Add hwspinlock node + +Add the hwspinlock device tree node for AM33xx family +of SoCs. + +Signed-off-by: Suman Anna <s-anna@ti.com> +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 0ca13ad..9ae258e 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -288,6 +288,12 @@ + status = "disabled"; + }; + ++ hwspinlock: spinlock@480ca000 { ++ compatible = "ti,omap4-hwspinlock"; ++ reg = <0x480ca000 0x1000>; ++ ti,hwmods = "spinlock"; ++ }; ++ + wdt2: wdt@44e35000 { + compatible = "ti,omap3-wdt"; + ti,hwmods = "wd_timer2"; +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/808-ARM_dts_AM33xx_Add_RNG_node.patch b/target/linux/omap/patches-3.12/808-ARM_dts_AM33xx_Add_RNG_node.patch new file mode 100644 index 0000000000..8b3603f74e --- /dev/null +++ b/target/linux/omap/patches-3.12/808-ARM_dts_AM33xx_Add_RNG_node.patch @@ -0,0 +1,60 @@ +From ed845d6b78bf32b396f7f1278eed0b87446934b1 Mon Sep 17 00:00:00 2001 +From: Lokesh Vutla <lokeshvutla@ti.com> +Date: Thu, 29 Aug 2013 12:52:09 +0000 +Subject: ARM: dts: AM33xx: Add RNG node + +Add the AM33xx RNG module's device tree data. +Also add Documentation file describing the data +for the RNG module. + +Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> +Signed-off-by: Tony Lindgren <tony@atomide.com> +--- +diff --git a/Documentation/devicetree/bindings/hwrng/omap_rng.txt b/Documentation/devicetree/bindings/hwrng/omap_rng.txt +new file mode 100644 +index 0000000..6a62acd +--- /dev/null ++++ b/Documentation/devicetree/bindings/hwrng/omap_rng.txt +@@ -0,0 +1,22 @@ ++OMAP SoC HWRNG Module ++ ++Required properties: ++ ++- compatible : Should contain entries for this and backward compatible ++ RNG versions: ++ - "ti,omap2-rng" for OMAP2. ++ - "ti,omap4-rng" for OMAP4, OMAP5 and AM33XX. ++ Note that these two versions are incompatible. ++- ti,hwmods: Name of the hwmod associated with the RNG module ++- reg : Offset and length of the register set for the module ++- interrupts : the interrupt number for the RNG module. ++ Only used for "ti,omap4-rng". ++ ++Example: ++/* AM335x */ ++rng: rng@48310000 { ++ compatible = "ti,omap4-rng"; ++ ti,hwmods = "rng"; ++ reg = <0x48310000 0x2000>; ++ interrupts = <111>; ++}; +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 9ae258e..fcb9c8e 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -750,5 +750,12 @@ + <&edma 11>; + dma-names = "tx", "rx"; + }; ++ ++ rng: rng@48310000 { ++ compatible = "ti,omap4-rng"; ++ ti,hwmods = "rng"; ++ reg = <0x48310000 0x2000>; ++ interrupts = <111>; ++ }; + + }; + }; +-- +cgit v0.9.2 diff --git a/target/linux/omap/patches-3.12/900-arm-dts-am335x-evmsk-add-support-for-lcd-panel.patch b/target/linux/omap/patches-3.12/900-arm-dts-am335x-evmsk-add-support-for-lcd-panel.patch new file mode 100644 index 0000000000..0a2c1c266f --- /dev/null +++ b/target/linux/omap/patches-3.12/900-arm-dts-am335x-evmsk-add-support-for-lcd-panel.patch @@ -0,0 +1,86 @@ +From 157c4071cb8a588c4e619b69447010a0ee68d844 Mon Sep 17 00:00:00 2001 +From: Darren Etheridge <detheridge@ti.com> +Date: Thu, 17 Oct 2013 14:53:37 -0500 +Subject: [PATCH 568/752] arm: dts: am335x-evmsk: add support for lcd panel + +Add the necessary DT entries for probing the LCDC in fbdev and +setting the correct timings for the NHD-4.3 LCD panel. +--- + arch/arm/boot/dts/am335x-evmsk.dts | 54 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index 354c0e5..ae18889 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -35,6 +35,39 @@ + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>; + ++ lcd_pins_s0: lcd_pins_s0 { ++ pinctrl-single,pins = < ++ 0x20 0x01 /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */ ++ 0x24 0x01 /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */ ++ 0x28 0x01 /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */ ++ 0x2c 0x01 /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */ ++ 0x30 0x01 /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */ ++ 0x34 0x01 /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */ ++ 0x38 0x01 /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */ ++ 0x3c 0x01 /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */ ++ 0xa0 0x00 /* lcd_data0.lcd_data0, OUTPUT | MODE0 */ ++ 0xa4 0x00 /* lcd_data1.lcd_data1, OUTPUT | MODE0 */ ++ 0xa8 0x00 /* lcd_data2.lcd_data2, OUTPUT | MODE0 */ ++ 0xac 0x00 /* lcd_data3.lcd_data3, OUTPUT | MODE0 */ ++ 0xb0 0x00 /* lcd_data4.lcd_data4, OUTPUT | MODE0 */ ++ 0xb4 0x00 /* lcd_data5.lcd_data5, OUTPUT | MODE0 */ ++ 0xb8 0x00 /* lcd_data6.lcd_data6, OUTPUT | MODE0 */ ++ 0xbc 0x00 /* lcd_data7.lcd_data7, OUTPUT | MODE0 */ ++ 0xc0 0x00 /* lcd_data8.lcd_data8, OUTPUT | MODE0 */ ++ 0xc4 0x00 /* lcd_data9.lcd_data9, OUTPUT | MODE0 */ ++ 0xc8 0x00 /* lcd_data10.lcd_data10, OUTPUT | MODE0 */ ++ 0xcc 0x00 /* lcd_data11.lcd_data11, OUTPUT | MODE0 */ ++ 0xd0 0x00 /* lcd_data12.lcd_data12, OUTPUT | MODE0 */ ++ 0xd4 0x00 /* lcd_data13.lcd_data13, OUTPUT | MODE0 */ ++ 0xd8 0x00 /* lcd_data14.lcd_data14, OUTPUT | MODE0 */ ++ 0xdc 0x00 /* lcd_data15.lcd_data15, OUTPUT | MODE0 */ ++ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */ ++ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */ ++ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */ ++ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */ ++ >; ++ }; ++ + user_leds_s0: user_leds_s0 { + pinctrl-single,pins = < + 0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad4.gpio1_4 */ +@@ -255,6 +288,27 @@ + }; + }; + ++ lcdc: lcdc@4830e000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lcd_pins_s0>; ++ status = "okay"; ++ display-timings { ++ 480x272 { ++ hactive = <480>; ++ vactive = <272>; ++ hback-porch = <43>; ++ hfront-porch = <8>; ++ hsync-len = <4>; ++ vback-porch = <12>; ++ vfront-porch = <4>; ++ vsync-len = <10>; ++ clock-frequency = <9000000>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ }; ++ }; ++ }; ++ + sound { + compatible = "ti,da830-evm-audio"; + ti,model = "AM335x-EVMSK"; +-- +1.7.10.4 + diff --git a/target/linux/omap/patches-3.12/901-arm-dts-am335x-sk-add-touchscreen-support.patch b/target/linux/omap/patches-3.12/901-arm-dts-am335x-sk-add-touchscreen-support.patch new file mode 100644 index 0000000000..ed6200699e --- /dev/null +++ b/target/linux/omap/patches-3.12/901-arm-dts-am335x-sk-add-touchscreen-support.patch @@ -0,0 +1,37 @@ +From 588b7a5db74c02bcf0b3ac57b6391debffbff74c Mon Sep 17 00:00:00 2001 +From: Felipe Balbi <balbi@ti.com> +Date: Mon, 21 Oct 2013 15:06:54 -0500 +Subject: [PATCH 582/752] arm: dts: am335x sk: add touchscreen support + +Add missing nodes for the touchscreen available +on AM335x EVM SK. + +Signed-off-by: Felipe Balbi <balbi@ti.com> +--- + arch/arm/boot/dts/am335x-evmsk.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index 7fae4e0..ddbf6ca 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -454,6 +454,16 @@ + phy-mode = "rgmii-txid"; + }; + ++&tscadc { ++ status = "okay"; ++ tsc { ++ ti,wires = <4>; ++ ti,x-plate-resistance = <200>; ++ ti,coordinate-readouts = <5>; ++ ti,wire-config = <0x00 0x11 0x22 0x33>; ++ }; ++}; ++ + &gpio0 { + ti,no-reset; + }; +-- +1.7.10.4 + |