diff options
Diffstat (limited to 'arch')
22 files changed, 2601 insertions, 44 deletions
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 30bbc3746130..a5738197983a 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -357,7 +357,11 @@ dtb-$(CONFIG_SOC_LS1021A) += \ dtb-$(CONFIG_SOC_VF610) += \ vf500-colibri-eval-v3.dtb \ vf610-colibri-eval-v3.dtb \ + vf500-colibri-aster.dtb \ + vf610-colibri-aster.dtb \ vf610m4-colibri.dtb \ + vf500-colibri-dual-eth.dtb \ + vf610-colibri-dual-eth.dtb \ vf610-cosmic.dtb \ vf610-twr.dtb dtb-$(CONFIG_ARCH_MXS) += \ diff --git a/arch/arm/boot/dts/vf-colibri-aster.dtsi b/arch/arm/boot/dts/vf-colibri-aster.dtsi new file mode 100644 index 000000000000..0e93826d5fd8 --- /dev/null +++ b/arch/arm/boot/dts/vf-colibri-aster.dtsi @@ -0,0 +1,199 @@ +/* + * Copyright 2018 Toradex AG + * + * 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 <dt-bindings/input/input.h> + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = &fec1; + ethernet1 = &fec0; + }; + + panel: panel { + compatible = "edt,et057090dhu"; + backlight = <&bl>; + power-supply = <®_3v3>; + }; + + extcon_usbc_det: usbc_det { + compatible = "linux,extcon-usb-gpio"; + debounce = <25>; + id-gpio = <&gpio3 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbc_det>; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1_reg>; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; /* USBH_PEN resp. USBH_P_EN */ + vin-supply = <®_5v0>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiokeys>; + + power { + label = "Wake-Up"; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + linux,code = <KEY_WAKEUP>; + debounce-interval = <10>; + gpio-key,wakeup; + }; + }; +}; + +&bl { + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + power-supply = <®_3v3>; + status = "okay"; +}; + +&dcu0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dcu0_1>; + fsl,panel = <&panel>; + status = "okay"; +}; + +&dspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_aster_dspi1 &pinctrl_aster_spi_gpio>; + status = "okay"; + + spidev0: spidev@0 { + compatible = "toradex,evalspi"; + reg = <0>; + spi-max-frequency = <50000000>; + }; +}; + +&esdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_esdhc1>; + bus-width = <4>; + status = "okay"; +}; + +&fec1 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + /* Atmel maxtouch controller */ + atmel_mxt_ts: atmel_mxt_ts@4a { + compatible = "atmel,maxtouch"; + reg = <0x4a>; + interrupt-parent = <&gpio2>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + /* M41T0M6 real time clock on carrier board */ + rtc: m41t0m6@68 { + compatible = "st,m41t0"; + reg = <0x68>; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +®_module_3v3 { + vin-supply = <®_3v3>; +}; + +&tcon0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usbdev0 { + extcon = <&extcon_usbc_det>, <&extcon_usbc_det>; +}; + +&usbh1 { + vbus-supply = <®_usbh_vbus>; +}; + +&iomuxc { + vf610-colibri { + pinctrl_gpiokeys: gpiokeys { + fsl,pins = < + VF610_PAD_PTB19__GPIO_41 0x218d + >; + }; + + pinctrl_aster_dspi1: dspi1grp { + fsl,pins = < + VF610_PAD_PTD6__DSPI1_SIN 0x33e1 + VF610_PAD_PTD7__DSPI1_SOUT 0x33e2 + VF610_PAD_PTD8__DSPI1_SCK 0x33e2 + >; + }; + + pinctrl_aster_spi_gpio: spigpios { + fsl,pins = < + /* CS0 */ + VF610_PAD_PTD5__GPIO_84 0x22ed + /* CS1 */ + VF610_PAD_PTB18__GPIO_40 0x22ed + >; + }; + }; +}; diff --git a/arch/arm/boot/dts/vf-colibri-dual-eth.dtsi b/arch/arm/boot/dts/vf-colibri-dual-eth.dtsi new file mode 100644 index 000000000000..dfa19d6fb2ab --- /dev/null +++ b/arch/arm/boot/dts/vf-colibri-dual-eth.dtsi @@ -0,0 +1,93 @@ +/* + * Copyright 2014 Toradex AG + * + * 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. + */ + +/ { + chosen { + bootargs = "console=ttyLP0,115200"; + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = &fec0; + ethernet1 = &fec1; + }; +}; + +&fec0 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec0>; + status = "okay"; +}; + +&fec1 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&iomuxc { + pinctrl-0 = <&pinctrl_hog_1>; + + vf610-colibri { + pinctrl_fec0: fec0grp { + fsl,pins = < + VF610_PAD_PTA9__RMII_CLKOUT 0x30d2 + VF610_PAD_PTC0__ENET_RMII0_MDC 0x30d2 + VF610_PAD_PTC1__ENET_RMII0_MDIO 0x30d3 + VF610_PAD_PTC2__ENET_RMII0_CRS 0x30d1 + VF610_PAD_PTC3__ENET_RMII0_RXD1 0x30d1 + VF610_PAD_PTC4__ENET_RMII0_RXD0 0x30d1 + VF610_PAD_PTC5__ENET_RMII0_RXER 0x30d1 + VF610_PAD_PTC6__ENET_RMII0_TXD1 0x30d2 + VF610_PAD_PTC7__ENET_RMII0_TXD0 0x30d2 + VF610_PAD_PTC8__ENET_RMII0_TXEN 0x30d2 + /* Disable pads multiplexed with PTC7/PTC6 */ + VF610_PAD_PTB0__GPIO_22 0x0000 + VF610_PAD_PTB9__GPIO_31 0x0000 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + VF610_PAD_PTA20__UART3_TX 0x21a2 + VF610_PAD_PTA21__UART3_RX 0x21a1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + VF610_PAD_PTA28__UART4_TX 0x21a2 + VF610_PAD_PTA29__UART4_RX 0x21a1 + >; + }; + }; +}; diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index ed65e0f7dfc0..2a78d10896cf 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2014 Toradex AG + * Copyright 2018 Toradex AG * * 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 @@ -7,42 +7,76 @@ * (at your option) any later version. */ +#include <dt-bindings/input/input.h> + / { chosen { stdout-path = "serial0:115200n8"; }; + aliases { + ethernet0 = &fec1; + ethernet1 = &fec0; + }; + clk16m: clk16m { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <16000000>; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - sys_5v0_reg: regulator@0 { - compatible = "regulator-fixed"; - reg = <0>; - regulator-name = "5v0"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - }; + panel: panel { + compatible = "edt,et057090dhu"; + backlight = <&bl>; + power-supply = <®_3v3>; + }; + + extcon_usbc_det: usbc_det { + compatible = "linux,extcon-usb-gpio"; + debounce = <25>; + id-gpio = <&gpio3 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbc_det>; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; - /* USBH_PEN */ - usbh_vbus_reg: regulator@1 { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbh1_reg>; - reg = <1>; - regulator-name = "usbh_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; - vin-supply = <&sys_5v0_reg>; + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1_reg>; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; /* USBH_PEN resp. USBH_P_EN */ + vin-supply = <®_5v0>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiokeys>; + + power { + label = "Wake-Up"; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + linux,code = <KEY_WAKEUP>; + debounce-interval = <10>; + gpio-key,wakeup; }; }; }; @@ -50,9 +84,18 @@ &bl { brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; + power-supply = <®_3v3>; status = "okay"; }; +&dcu0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dcu0_1>; + fsl,panel = <&panel>; + status = "okay"; +}; + +/* Colibri SPI */ &dspi1 { status = "okay"; @@ -62,9 +105,17 @@ pinctrl-0 = <&pinctrl_can_int>; reg = <0>; clocks = <&clk16m>; - spi-max-frequency = <10000000>; interrupt-parent = <&gpio1>; interrupts = <11 GPIO_ACTIVE_LOW>; + spi-max-frequency = <10000000>; + status = "okay"; + }; + + spidev0: spidev@0 { + compatible = "toradex,evalspi"; + reg = <0>; + spi-max-frequency = <50000000>; + status = "disabled"; }; }; @@ -85,9 +136,33 @@ &i2c0 { status = "okay"; + /* Atmel maxtouch controller */ + atmel_mxt_ts: atmel_mxt_ts@4a { + compatible = "atmel,maxtouch"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiotouch>; + reg = <0x4a>; + interrupt-parent = <&gpio0>; + interrupts = <30 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + /* TouchRevolution Fusion 7 and 10 multi-touch controller */ + touch: touchrevf0710a@10 { + compatible = "touchrevolution,fusion-f0710a"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpiotouch>; + reg = <0x10>; + gpios = <&gpio0 30 GPIO_ACTIVE_HIGH /* SO-DIMM 28, Pen down interrupt */ + &gpio0 23 GPIO_ACTIVE_LOW /* SO-DIMM 30, Reset interrupt */ + >; + status = "disabled"; + }; + /* M41T0M6 real time clock on carrier board */ rtc: m41t0m6@68 { - compatible = "st,m41t00"; + compatible = "st,m41t0"; reg = <0x68>; }; }; @@ -100,6 +175,14 @@ status = "okay"; }; +®_module_3v3 { + vin-supply = <®_3v3>; +}; + +&tcon0 { + status = "okay"; +}; + &uart0 { status = "okay"; }; @@ -112,8 +195,12 @@ status = "okay"; }; +&usbdev0 { + extcon = <&extcon_usbc_det>, <&extcon_usbc_det>; +}; + &usbh1 { - vbus-supply = <&usbh_vbus_reg>; + vbus-supply = <®_usbh_vbus>; }; &iomuxc { @@ -123,5 +210,18 @@ VF610_PAD_PTB21__GPIO_43 0x22ed >; }; + + pinctrl_gpiokeys: gpiokeys { + fsl,pins = < + VF610_PAD_PTB19__GPIO_41 0x218d + >; + }; + + pinctrl_gpiotouch: touchgpios { + fsl,pins = < + VF610_PAD_PTB8__GPIO_30 0x6d + VF610_PAD_PTB1__GPIO_23 0x4d + >; + }; }; }; diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index e5949b934945..cca8f38facb7 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -10,17 +10,61 @@ / { bl: backlight { compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_bl_on>; pwms = <&pwm0 0 5000000 0>; + enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; status = "disabled"; }; + + reg_module_3v3: regulator-module-3v3 { + compatible = "regulator-fixed"; + regulator-name = "+V3.3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_module_3v3_avdd: regulator-module-3v3-avdd { + compatible = "regulator-fixed"; + regulator-name = "+V3.3_AVDD_AUDIO"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + soc { + fsl,use-lpm-poweroff; + }; }; &adc0 { status = "okay"; + vref-supply = <®_module_3v3_avdd>; }; &adc1 { status = "okay"; + vref-supply = <®_module_3v3_avdd>; +}; + +&can0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan0>; + status = "disabled"; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + status = "disabled"; +}; + +&clks { + assigned-clocks = <&clks VF610_CLK_ENET_SEL>, + <&clks VF610_CLK_ENET_TS_SEL>; + assigned-clock-parents = <&clks VF610_CLK_ENET_50M>, + <&clks VF610_CLK_ENET_50M>; }; &dspi1 { @@ -33,17 +77,34 @@ status = "okay"; }; +&edma1 { + status = "okay"; +}; + &esdhc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + disable-wp; }; &fec1 { phy-mode = "rmii"; + phy-handle = <ðphy>; + phy-supply = <®_module_3v3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@0 { + reg = <0>; + micrel,led-mode = <0>; + }; + }; }; &i2c0 { @@ -53,8 +114,6 @@ }; &nfc { - assigned-clocks = <&clks VF610_CLK_NFC>; - assigned-clock-rates = <33000000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nfc>; status = "okay"; @@ -74,12 +133,12 @@ &pwm0 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm0>; + pinctrl-0 = <&pinctrl_pwm0_a &pinctrl_pwm0_c>; }; &pwm1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm1>; + pinctrl-0 = <&pinctrl_pwm1_b &pinctrl_pwm1_d>; }; &uart0 { @@ -99,6 +158,7 @@ &usbdev0 { disable-over-current; + dr_mode = "otg"; status = "okay"; }; @@ -124,12 +184,54 @@ }; &iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_0 &pinctrl_hog_1>; + vf610-colibri { - pinctrl_gpio_ext: gpio_ext { + pinctrl_flexcan0: can0grp { + fsl,pins = < + VF610_PAD_PTB14__CAN0_RX 0x31F1 + VF610_PAD_PTB15__CAN0_TX 0x31F2 + >; + }; + + pinctrl_flexcan1: can1grp { + fsl,pins = < + VF610_PAD_PTB16__CAN1_RX 0x31F1 + VF610_PAD_PTB17__CAN1_TX 0x31F2 + >; + }; + + pinctrl_dcu0_1: dcu0grp_1 { fsl,pins = < - VF610_PAD_PTD10__GPIO_89 0x22ed /* EXT_IO_0 */ - VF610_PAD_PTD9__GPIO_88 0x22ed /* EXT_IO_1 */ - VF610_PAD_PTD26__GPIO_68 0x22ed /* EXT_IO_2 */ + VF610_PAD_PTE0__DCU0_HSYNC 0x1902 + VF610_PAD_PTE1__DCU0_VSYNC 0x1902 + VF610_PAD_PTE2__DCU0_PCLK 0x1902 + VF610_PAD_PTE4__DCU0_DE 0x1902 + VF610_PAD_PTE5__DCU0_R0 0x1902 + VF610_PAD_PTE6__DCU0_R1 0x1902 + VF610_PAD_PTE7__DCU0_R2 0x1902 + VF610_PAD_PTE8__DCU0_R3 0x1902 + VF610_PAD_PTE9__DCU0_R4 0x1902 + VF610_PAD_PTE10__DCU0_R5 0x1902 + VF610_PAD_PTE11__DCU0_R6 0x1902 + VF610_PAD_PTE12__DCU0_R7 0x1902 + VF610_PAD_PTE13__DCU0_G0 0x1902 + VF610_PAD_PTE14__DCU0_G1 0x1902 + VF610_PAD_PTE15__DCU0_G2 0x1902 + VF610_PAD_PTE16__DCU0_G3 0x1902 + VF610_PAD_PTE17__DCU0_G4 0x1902 + VF610_PAD_PTE18__DCU0_G5 0x1902 + VF610_PAD_PTE19__DCU0_G6 0x1902 + VF610_PAD_PTE20__DCU0_G7 0x1902 + VF610_PAD_PTE21__DCU0_B0 0x1902 + VF610_PAD_PTE22__DCU0_B1 0x1902 + VF610_PAD_PTE23__DCU0_B2 0x1902 + VF610_PAD_PTE24__DCU0_B3 0x1902 + VF610_PAD_PTE25__DCU0_B4 0x1902 + VF610_PAD_PTE26__DCU0_B5 0x1902 + VF610_PAD_PTE27__DCU0_B6 0x1902 + VF610_PAD_PTE28__DCU0_B7 0x1902 >; }; @@ -169,6 +271,67 @@ >; }; + pinctrl_gpio_bl_on: gpio_bl_on { + fsl,pins = < + VF610_PAD_PTC0__GPIO_45 0x22ef + >; + }; + + pinctrl_hog_0: hoggrp-0 { + fsl,pins = < + VF610_PAD_PTA12__GPIO_5 0x22ed + VF610_PAD_PTA17__GPIO_7 0x22ed + VF610_PAD_PTA20__GPIO_10 0x22ed + VF610_PAD_PTA21__GPIO_11 0x22ed + VF610_PAD_PTA30__GPIO_20 0x22ed + VF610_PAD_PTA31__GPIO_21 0x22ed + VF610_PAD_PTB6__GPIO_28 0x22ed + VF610_PAD_PTB7__GPIO_29 0x22ed + VF610_PAD_PTB16__GPIO_38 0x22ed + VF610_PAD_PTB17__GPIO_39 0x22ed + VF610_PAD_PTB18__GPIO_40 0x22ed + VF610_PAD_PTB21__GPIO_43 0x22ed + VF610_PAD_PTB22__GPIO_44 0x22ed + VF610_PAD_PTC1__GPIO_46 0x22ed + VF610_PAD_PTC2__GPIO_47 0x22ed + VF610_PAD_PTC3__GPIO_48 0x22ed + VF610_PAD_PTC4__GPIO_49 0x22ed + VF610_PAD_PTC5__GPIO_50 0x22ed + VF610_PAD_PTC6__GPIO_51 0x22ed + VF610_PAD_PTC7__GPIO_52 0x22ed + VF610_PAD_PTC8__GPIO_53 0x22ed + VF610_PAD_PTD30__GPIO_64 0x22ed + VF610_PAD_PTD29__GPIO_65 0x22ed + VF610_PAD_PTD28__GPIO_66 0x22ed + VF610_PAD_PTD26__GPIO_68 0x22ed + VF610_PAD_PTD25__GPIO_69 0x22ed + VF610_PAD_PTD24__GPIO_70 0x22ed + VF610_PAD_PTD9__GPIO_88 0x22ed + VF610_PAD_PTD10__GPIO_89 0x22ed + VF610_PAD_PTD11__GPIO_90 0x22ed + VF610_PAD_PTD12__GPIO_91 0x22ed + VF610_PAD_PTD13__GPIO_92 0x22ed + VF610_PAD_PTB26__GPIO_96 0x22ed + VF610_PAD_PTB28__GPIO_98 0x22ed + VF610_PAD_PTC30__GPIO_103 0x22ed + VF610_PAD_PTA7__GPIO_134 0x22ed + >; + }; + + pinctrl_hog_1: hoggrp-1 { /* ATMEL MXT TOUCH */ + fsl,pins = < + VF610_PAD_PTD27__GPIO_67 0x22ed + VF610_PAD_PTD31__GPIO_63 0x22ed + >; + }; + + pinctrl_hog_2: hoggrp-2 { + fsl,pins = < + VF610_PAD_PTB12__GPIO_34 0x22ed + VF610_PAD_PTB13__GPIO_35 0x22ed + >; + }; + pinctrl_i2c0: i2c0grp { fsl,pins = < VF610_PAD_PTB14__I2C0_SCL 0x37ff @@ -195,16 +358,26 @@ >; }; - pinctrl_pwm0: pwm0grp { + pinctrl_pwm0_a: pwm0agrp { fsl,pins = < VF610_PAD_PTB0__FTM0_CH0 0x1182 + >; + }; + + pinctrl_pwm0_c: pwm0cgrp { + fsl,pins = < VF610_PAD_PTB1__FTM0_CH1 0x1182 >; }; - pinctrl_pwm1: pwm1grp { + pinctrl_pwm1_b: pwm1bgrp { fsl,pins = < VF610_PAD_PTB8__FTM1_CH0 0x1182 + >; + }; + + pinctrl_pwm1_d: pwm1dgrp { + fsl,pins = < VF610_PAD_PTB9__FTM1_CH1 0x1182 >; }; @@ -213,6 +386,8 @@ fsl,pins = < VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 >; }; @@ -232,6 +407,12 @@ >; }; + pinctrl_usbc_det: gpio_usbc_det { + fsl,pins = < + VF610_PAD_PTC29__GPIO_102 0x22cd + >; + }; + pinctrl_usbh1_reg: gpio_usb_vbus { fsl,pins = < VF610_PAD_PTD4__GPIO_83 0x22ed diff --git a/arch/arm/boot/dts/vf500-colibri-aster.dts b/arch/arm/boot/dts/vf500-colibri-aster.dts new file mode 100644 index 000000000000..e314a7ab67ae --- /dev/null +++ b/arch/arm/boot/dts/vf500-colibri-aster.dts @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Toradex AG + * + * 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. + */ + +/dts-v1/; +#include "vf500-colibri.dtsi" +#include "vf-colibri-aster.dtsi" + +/ { + model = "Toradex Colibri VF50 on Colibri Aster Board"; + compatible = "toradex,vf500-colibri_vf50-on-aster", "toradex,vf500-colibri_vf50", "fsl,vf500"; +}; + +&touchscreen { + vf50-ts-min-pressure = <200>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/vf500-colibri-dual-eth.dts b/arch/arm/boot/dts/vf500-colibri-dual-eth.dts new file mode 100644 index 000000000000..24990e241e0e --- /dev/null +++ b/arch/arm/boot/dts/vf500-colibri-dual-eth.dts @@ -0,0 +1,17 @@ +/* + * Copyright 2014 Toradex AG + * + * 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. + */ + +/dts-v1/; +#include "vf500-colibri.dtsi" +#include "vf-colibri-dual-eth.dtsi" + +/ { + model = "Toradex Colibri VF50 on Dual Ethernet Board"; + compatible = "toradex,vf500-colibri_vf50-on-dual-eth-board", "toradex,vf500-colibri_vf50", "fsl,vf500"; +}; diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi index 84f091d1fcf2..731ff0091c9d 100644 --- a/arch/arm/boot/dts/vf500-colibri.dtsi +++ b/arch/arm/boot/dts/vf500-colibri.dtsi @@ -37,6 +37,11 @@ }; }; +&nfc { + assigned-clocks = <&clks VF610_CLK_NFC>; + assigned-clock-rates = <33000000>; +}; + &iomuxc { vf610-colibri { pinctrl_touchctrl_idle: touchctrl_idle { diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi index e976d2fa1527..f2be079aae51 100644 --- a/arch/arm/boot/dts/vf500.dtsi +++ b/arch/arm/boot/dts/vf500.dtsi @@ -43,6 +43,16 @@ clocks = <&clks VF610_CLK_PLATFORM_BUS>; }; }; + + aips-bus@40080000 { + + pmu@40089000 { + compatible = "arm,cortex-a5-pmu"; + interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&a5_cpu>; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/vf610-colibri-aster.dts b/arch/arm/boot/dts/vf610-colibri-aster.dts new file mode 100644 index 000000000000..55efc161001e --- /dev/null +++ b/arch/arm/boot/dts/vf610-colibri-aster.dts @@ -0,0 +1,17 @@ +/* + * Copyright 2017 Toradex AG + * + * 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. + */ + +/dts-v1/; +#include "vf610-colibri.dtsi" +#include "vf-colibri-aster.dtsi" + +/ { + model = "Toradex Colibri VF61 on Colibri Aster Board"; + compatible = "toradex,vf610-colibri_vf61-on-aster", "toradex,vf610-colibri_vf61", "fsl,vf610"; +}; diff --git a/arch/arm/boot/dts/vf610-colibri-dual-eth.dts b/arch/arm/boot/dts/vf610-colibri-dual-eth.dts new file mode 100644 index 000000000000..a2eff553956c --- /dev/null +++ b/arch/arm/boot/dts/vf610-colibri-dual-eth.dts @@ -0,0 +1,17 @@ +/* + * Copyright 2014 Toradex AG + * + * 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. + */ + +/dts-v1/; +#include "vf610-colibri.dtsi" +#include "vf-colibri-dual-eth.dtsi" + +/ { + model = "Toradex Colibri VF61 on Dual Ethernet Board"; + compatible = "toradex,vf610-colibri_vf61-on-dual-eth-board", "toradex,vf610-colibri_vf61", "fsl,vf610"; +}; diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi index 2d7eab755210..a8d59f7bef06 100644 --- a/arch/arm/boot/dts/vf610-colibri.dtsi +++ b/arch/arm/boot/dts/vf610-colibri.dtsi @@ -17,4 +17,115 @@ memory { reg = <0x80000000 0x10000000>; }; + + sound { + compatible = "fsl,fsl-sai-audio-wm9712"; + fsl,ac97-controller = <&sai2>; + + fsl,model = "Colibri VF61 AC97 Audio"; + + fsl,audio-routing = + "Headphone", "HPOUTL", + "Headphone", "HPOUTR", + "LINEINL", "LineIn", + "LINEINR", "LineIn", + "MIC1", "Mic"; + }; +}; + +&nfc { + assigned-clocks = <&clks VF610_CLK_NFC>; + assigned-clock-rates = <50000000>; +}; + +&sai0 { + compatible = "fsl,vf610-sai-clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai0>; + status = "okay"; +}; + +&sai2 { + compatible = "fsl,vf610-sai-ac97"; + #sound-dai-cells = <0>; + pinctrl-names = "default", "sleep", "ac97-running", "ac97-reset", + "ac97-warm-reset"; + pinctrl-0 = <&pinctrl_sai2_ac97_default>; + pinctrl-1 = <&pinctrl_sai2_ac97_sleep>; + pinctrl-2 = <&pinctrl_sai2_ac97_running>; + pinctrl-3 = <&pinctrl_sai2_ac97_reset>; + pinctrl-4 = <&pinctrl_sai2_ac97_warm_reset>; + ac97-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH &gpio0 8 GPIO_ACTIVE_HIGH + &gpio0 13 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&iomuxc { + vf610-colibri { + pinctrl_sai0: sai0grp_1 { + fsl,pins = < + VF610_PAD_PTB23__SAI0_TX_BCLK 0x31C3 + >; + }; + + pinctrl_sai2_ac97_default: sai2grp_1 { + fsl,pins = < + /* Pen-down */ + VF610_PAD_PTA11__GPIO_4 0x22ed + + /* GenIRQ */ + VF610_PAD_PTB2__GPIO_24 0x22e1 + >; + }; + + pinctrl_sai2_ac97_sleep: sai2grp_2 { + fsl,pins = < + /* AC97 Reset (cold reset) floating */ + VF610_PAD_PTA23__GPIO_13 0x22c1 + >; + }; + + pinctrl_sai2_ac97_running: sai2grp_3 { + fsl,pins = < + /* AC97 Bit clock */ + VF610_PAD_PTA16__SAI2_TX_BCLK 0x31C3 + + /* AC97 SData Out */ + VF610_PAD_PTA18__SAI2_TX_DATA 0x31C2 + + /* AC97 Sync */ + VF610_PAD_PTA19__SAI2_TX_SYNC 0x31C3 + + /* AC97 SData In */ + VF610_PAD_PTA22__SAI2_RX_DATA 0x0041 + >; + }; + + pinctrl_sai2_ac97_reset: sai2grp_4 { + fsl,pins = < + VF610_PAD_PTA16__SAI2_TX_BCLK 0x31C1 + + /* AC97 SData Out (test mode selection) */ + VF610_PAD_PTA18__GPIO_8 0x22c1 + + /* AC97 Sync (warm reset) */ + VF610_PAD_PTA19__GPIO_9 0x22c1 + + /* AC97 Reset (cold reset) */ + VF610_PAD_PTA23__GPIO_13 0x22c1 + >; + }; + + pinctrl_sai2_ac97_warm_reset: sai2grp_5 { + fsl,pins = < + /* AC97 SData Out (test mode selection) */ + VF610_PAD_PTA18__GPIO_8 0x22c1 + + /* AC97 Sync (warm reset) */ + VF610_PAD_PTA19__GPIO_9 0x22c1 + >; + }; + + + }; }; diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 5438ee4be2ec..8419c0607f9b 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -96,6 +96,10 @@ &clks { clocks = <&sxosc>, <&fxosc>, <&enet_ext>, <&audio_ext>; clock-names = "sxosc", "fxosc", "enet_ext", "audio_ext"; + assigned-clocks = <&clks VF610_CLK_ENET_SEL>, + <&clks VF610_CLK_ENET_TS_SEL>; + assigned-clock-parents = <&clks VF610_CLK_ENET_EXT>, + <&clks VF610_CLK_ENET_EXT>; }; &dspi0 { diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index 58bc6e448be5..f731b598e2c5 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -22,4 +22,31 @@ arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; }; + + sema4: sema4@4001D000 { + compatible = "fsl,vf610-sema4"; + reg = <0x4001D000 0x1000>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + }; + + CM4: cortexm4 { + compatible = "simple-bus"; + ranges = <0x1f000000 0x3f000000 0x80000 + 0x3f000000 0x3f000000 0x80000>; + #address-cells = <1>; + #size-cells = <1>; + + cortexm4core { + compatible = "fsl,vf610-m4"; + reg = <0x1f000000 0x80000>, + <0x3f000000 0x80000>; + reg-names = "pc_ocram", "ps_ocram"; + fsl,firmware = "freertos-rpmsg.elf"; + }; + }; + + rpmsg: rpmsg { + compatible = "fsl,vf610-rpmsg"; + status = "okay"; + }; }; diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index 3cd1b27f2697..bf4e8048fac8 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -16,6 +16,8 @@ aliases { can0 = &can0; can1 = &can1; + ethernet0 = &fec0; + ethernet1 = &fec1; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -53,9 +55,56 @@ soc { #address-cells = <1>; #size-cells = <1>; - compatible = "simple-bus"; - interrupt-parent = <&mscm_ir>; + compatible = "fsl,vf610-soc-bus", "simple-bus"; + interrupt-parent = <&gpc>; ranges; + fsl,rom-revision = <&ocrom 0x80>; + fsl,cpu-count = <&mscm_cpucfg 0x2C>; + fsl,l2-size = <&mscm_cpucfg 0x14>; + nvmem-cells = <&ocotp_cfg0>, <&ocotp_cfg1>; + nvmem-cell-names = "cfg0", "cfg1"; + + ocrom: ocrom@00000000 { + compatible = "fsl,vf610-ocrom", "syscon"; + reg = <0x00000000 0x18000>; + }; + + ocram0: sram@3f000000 { + compatible = "mmio-sram"; + reg = <0x3f000000 0x40000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x3f000000 0x40000>; + + stbyram1@0 { + reg = <0x0 0x4000>; + label = "stbyram1"; + pool; + }; + + stbyram2@4000 { + reg = <0x4000 0xc000>; + label = "stbyram2"; + pool; + }; + }; + + ocram1: sram@3f040000 { + compatible = "mmio-sram"; + reg = <0x3f040000 0x40000>; + }; + + gfxram0: sram@3f400000 { + compatible = "mmio-sram"; + reg = <0x3f400000 0x80000>; + }; + + /* used by L2 cache */ + gfxram1: sram@3f480000 { + compatible = "mmio-sram"; + reg = <0x3f480000 0x80000>; + }; aips0: aips-bus@40000000 { compatible = "fsl,aips-bus", "simple-bus"; @@ -70,10 +119,22 @@ mscm_ir: interrupt-controller@40001800 { compatible = "fsl,vf610-mscm-ir"; + #address-cells = <1>; + #size-cells = <1>; reg = <0x40001800 0x400>; fsl,cpucfg = <&mscm_cpucfg>; interrupt-controller; #interrupt-cells = <2>; + + cpu2cpu@40001800 { + reg = <0x40001800 0x40>; + interrupt-parent = <&mscm_ir>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, + <1 IRQ_TYPE_LEVEL_HIGH>, + <2 IRQ_TYPE_LEVEL_HIGH>, + <3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1", "int2", "int3"; + }; }; edma0: dma-controller@40018000 { @@ -159,6 +220,9 @@ clocks = <&clks VF610_CLK_DSPI0>; clock-names = "dspi"; spi-num-chipselects = <6>; + dmas = <&edma1 1 12>, + <&edma1 1 13>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -171,6 +235,37 @@ clocks = <&clks VF610_CLK_DSPI1>; clock-names = "dspi"; spi-num-chipselects = <4>; + dmas = <&edma1 1 14>, + <&edma1 1 15>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai0: sai@4002f000 { + compatible = "fsl,vf610-sai"; + reg = <0x4002f000 0x1000>; + interrupts = <84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI0>, + <&clks VF610_CLK_SAI0_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 17>, + <&edma0 0 16>; + status = "disabled"; + }; + + sai1: sai@40030000 { + compatible = "fsl,vf610-sai"; + reg = <0x40030000 0x1000>; + interrupts = <85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI1>, + <&clks VF610_CLK_SAI1_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 19>, + <&edma0 0 18>; status = "disabled"; }; @@ -188,6 +283,20 @@ status = "disabled"; }; + sai3: sai@40032000 { + compatible = "fsl,vf610-sai"; + reg = <0x40032000 0x1000>; + interrupts = <87 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI3>, + <&clks VF610_CLK_SAI3_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 1 9>, + <&edma0 1 8>; + status = "disabled"; + }; + pit: pit@40037000 { compatible = "fsl,vf610-pit"; reg = <0x40037000 0x1000>; @@ -234,6 +343,14 @@ <20000000>; }; + tcon0: timing-controller@4003d000 { + compatible = "fsl,vf610-tcon"; + reg = <0x4003d000 0x1000>; + clocks = <&clks VF610_CLK_TCON0>; + clock-names = "ipg"; + status = "disabled"; + }; + wdoga5: wdog@4003e000 { compatible = "fsl,vf610-wdt", "fsl,imx21-wdt"; reg = <0x4003e000 0x1000>; @@ -270,6 +387,7 @@ interrupt-controller; #interrupt-cells = <2>; gpio-ranges = <&iomuxc 0 0 32>; + fsl,gpio-wakeup = <&wakeup 22 0 8>; /* PTB0...PTB7 */ }; gpio1: gpio@4004a000 { @@ -281,6 +399,10 @@ interrupt-controller; #interrupt-cells = <2>; gpio-ranges = <&iomuxc 0 32 32>; + fsl,gpio-wakeup = <&wakeup 1 8 2>, /* PTB11, PTB12 (NMI)*/ + <&wakeup 4 10 1>, /* PTB14 */ + <&wakeup 6 11 1>, /* PTB16 */ + <&wakeup 9 12 2>; /* PTB19, PTB20 */ }; gpio2: gpio@4004b000 { @@ -303,6 +425,9 @@ interrupt-controller; #interrupt-cells = <2>; gpio-ranges = <&iomuxc 0 96 32>; + fsl,gpio-wakeup = <&wakeup 1 14 1>, /* PTB27 */ + <&wakeup 7 15 1>, /* PTC30 */ + <&wakeup 29 16 1>; /* PTE20 */ }; gpio4: gpio@4004d000 { @@ -321,6 +446,11 @@ reg = <0x40050000 0x400>; }; + scsc: scsc@40052000 { + compatible = "fsl,vf610-scsc"; + reg = <0x40052000 0x1000>; + }; + usbphy0: usbphy@40050800 { compatible = "fsl,vf610-usbphy"; reg = <0x40050800 0x400>; @@ -339,6 +469,17 @@ status = "disabled"; }; + dcu0: dcu@40058000 { + compatible = "fsl,vf610-dcu"; + reg = <0x40058000 0x1200>; + interrupts = <30 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_DCU0>, + <&clks VF610_CLK_DCU0_DIV>; + clock-names = "dcu", "pix"; + fsl,tcon = <&tcon0>; + status = "disabled"; + }; + i2c0: i2c@40066000 { #address-cells = <1>; #size-cells = <0>; @@ -367,8 +508,15 @@ status = "disabled"; }; + wakeup: wkpu@4006a000 { + compatible = "fsl,vf610-wkpu"; + reg = <0x4006a000 0x1000>; + interrupts = <92 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_WKPU>; + }; + clks: ccm@4006b000 { - compatible = "fsl,vf610-ccm"; + compatible = "fsl,vf610-ccm", "syscon"; reg = <0x4006b000 0x1000>; clocks = <&sxosc>, <&fxosc>; clock-names = "sxosc", "fxosc"; @@ -376,7 +524,7 @@ }; usbdev0: usb@40034000 { - compatible = "fsl,vf610-usb", "fsl,imx27-usb"; + compatible = "fsl,vf610-usb"; reg = <0x40034000 0x800>; interrupts = <75 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks VF610_CLK_USBC0>; @@ -399,6 +547,14 @@ reg = <0x4006e000 0x1000>; interrupts = <96 IRQ_TYPE_LEVEL_HIGH>; }; + + gpc: gpc@4006c000 { + compatible = "fsl,vf610-gpc"; + reg = <0x4006c000 0x1000>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&mscm_ir>; + }; }; aips1: aips-bus@40080000 { @@ -423,6 +579,22 @@ status = "disabled"; }; + ocotp@400a5000 { + compatible = "fsl,vf610-ocotp"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x400a5000 0xCF0>; + clocks = <&clks VF610_CLK_OCOTP>; + + ocotp_cfg0: cfg0@410 { + reg = <0x410 0x4>; + }; + + ocotp_cfg1: cfg1@420 { + reg = <0x420 0x4>; + }; + }; + snvs0: snvs@400a7000 { compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd"; reg = <0x400a7000 0x2000>; @@ -455,6 +627,43 @@ status = "disabled"; }; + dspi2: dspi2@400ac000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,vf610-dspi"; + reg = <0x400ac000 0x1000>; + interrupts = <69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_DSPI2>; + clock-names = "dspi"; + spi-num-chipselects = <2>; + dmas = <&edma1 0 10>, + <&edma1 0 11>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + dspi3: dspi3@400ad000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,vf610-dspi"; + reg = <0x400ad000 0x1000>; + interrupts = <70 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_DSPI3>; + clock-names = "dspi"; + spi-num-chipselects = <2>; + dmas = <&edma1 0 12>, + <&edma1 0 13>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + ddrmc: ddrmc@400ae000 { + compatible = "fsl,vf610-ddrmc"; + reg = <0x400ae000 0x400>; + clocks = <&clks VF610_CLK_DDRMC>; + clock-names = "ddrc"; + }; + adc1: adc@400bb000 { compatible = "fsl,vf610-adc"; reg = <0x400bb000 0x1000>; @@ -490,7 +699,7 @@ }; usbh1: usb@400b4000 { - compatible = "fsl,vf610-usb", "fsl,imx27-usb"; + compatible = "fsl,vf610-usb"; reg = <0x400b4000 0x800>; interrupts = <76 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks VF610_CLK_USBC1>; @@ -534,6 +743,24 @@ status = "disabled"; }; + dac0: dac@400cc000 { + compatible = "fsl,vf610-dac"; + reg = <0x400cc000 1000>; + interrupts = <55 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dac"; + clocks = <&clks VF610_CLK_DAC0>; + status = "disabled"; + }; + + dac1: dac@400cd000 { + compatible = "fsl,vf610-dac"; + reg = <0x400cd000 1000>; + interrupts = <56 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dac"; + clocks = <&clks VF610_CLK_DAC1>; + status = "disabled"; + }; + fec0: ethernet@400d0000 { compatible = "fsl,mvf600-fec"; reg = <0x400d0000 0x1000>; @@ -577,6 +804,18 @@ status = "disabled"; }; + esw: l2-switch@400e8000 { + compatible = "fsl,eth-switch"; + reg = <0x400e8000 0x1000 0x400d0000 0x2000>; + interrupts = <82 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_ESW>, + <&clks VF610_CLK_ENET>, + <&clks VF610_CLK_ENET0>, + <&clks VF610_CLK_ENET1>; + clock-names = "esw", "enet", "enet0", "enet1"; + status = "disabled"; + }; + i2c2: i2c@400e6000 { #address-cells = <1>; #size-cells = <0>; @@ -605,5 +844,10 @@ status = "disabled"; }; }; + + adc_hwmon: iio_hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc0 16>, <&adc1 16>; + }; }; }; diff --git a/arch/arm/configs/colibri_vf_defconfig b/arch/arm/configs/colibri_vf_defconfig new file mode 100644 index 000000000000..316576de6d26 --- /dev/null +++ b/arch/arm/configs/colibri_vf_defconfig @@ -0,0 +1,333 @@ +CONFIG_KERNEL_LZO=y +CONFIG_SYSVIPC=y +CONFIG_FHANDLE=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_CGROUPS=y +CONFIG_NAMESPACES=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_ARCH_MXC=y +CONFIG_SOC_VF610=y +CONFIG_SWP_EMULATE=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_AEABI=y +CONFIG_CMA=y +CONFIG_KEXEC=y +# CONFIG_ATAGS_PROC is not set +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_BINFMT_MISC=y +CONFIG_PM_WAKELOCKS=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPGRE_DEMUX=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_IPV6_SIT=m +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_TABLES=y +CONFIG_NF_TABLES_INET=y +CONFIG_NFT_MASQ=y +CONFIG_NFT_NAT=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_NFACCT=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NFT_CHAIN_NAT_IPV4=y +CONFIG_NFT_MASQ_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_NF_TABLES_BRIDGE=y +CONFIG_L2TP=m +CONFIG_BRIDGE=y +# CONFIG_BRIDGE_IGMP_SNOOPING is not set +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_CAN=m +CONFIG_CAN_FLEXCAN=m +CONFIG_CAN_MCP251X=m +CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_DMA_CMA=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VF610_NFC=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_FASTMAP=y +CONFIG_MTD_UBI_BLOCK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +CONFIG_FSL_L2_SWITCH=y +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_MICREL_PHY=y +CONFIG_PPP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_MPPE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_USBNET=m +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_WLAN is not set +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_FUSION_F0710A=m +CONFIG_TOUCHSCREEN_WM97XX=y +# CONFIG_TOUCHSCREEN_WM9705 is not set +# CONFIG_TOUCHSCREEN_WM9713 is not set +CONFIG_TOUCHSCREEN_COLIBRI_VF50=y +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_VF610_SEMA4=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_HW_RANDOM=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_IMX=y +CONFIG_SPI=y +CONFIG_SPI_FSL_DSPI=y +CONFIG_SPI_SPIDEV=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_SENSORS_IIO_HWMON=y +CONFIG_WATCHDOG=y +CONFIG_IMX2_WDT=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ANATOP=y +CONFIG_REGULATOR_GPIO=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +# CONFIG_RC_MAP is not set +# CONFIG_RC_DECODERS is not set +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +# CONFIG_USB_GSPCA is not set +CONFIG_DRM=y +CONFIG_DRM_FSL_DCU=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_LCD_CLASS_DEVICE is not set +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_IMX_SOC=y +CONFIG_SND_SOC_FSL_SAI_WM9712=y +CONFIG_SND_SOC_AC97_CODEC=y +CONFIG_HIDRAW=y +CONFIG_HID_MULTITOUCH=m +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=m +CONFIG_USB_WDM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_FTDI_SIO=y +CONFIG_USB_SERIAL_PL2303=y +CONFIG_USB_SERIAL_OPTION=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MXS_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_FSL_USB2=y +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_SNVS=y +CONFIG_DMADEVICES=y +CONFIG_FSL_EDMA=y +# CONFIG_MX3_IPU is not set +CONFIG_ARM_TIMER_SP804=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_VF610_CM4_RPROC=m +CONFIG_IMX_RPMSG_PINGPONG=m +CONFIG_IMX_RPMSG_TTY=m +CONFIG_VF610_RPMSG=m +CONFIG_SOC_BUS_VF610=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_IIO=y +CONFIG_VF610_ADC=y +CONFIG_VF610_DAC=y +CONFIG_IIO_SYSFS_TRIGGER=y +CONFIG_PWM=y +CONFIG_PWM_FSL_FTM=y +CONFIG_NVMEM=y +CONFIG_NVMEM_VF610_OCOTP=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_OVERLAY_FS=y +CONFIG_VFAT_FS=y +CONFIG_NTFS_FS=y +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_CIFS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FTRACE is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_USER=y +CONFIG_SECURITYFS=y +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_HW is not set +CONFIG_CRC_CCITT=y +CONFIG_CRC_T10DIF=y +CONFIG_XZ_DEC=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 900c591913d5..5b07c7a31c31 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -94,7 +94,7 @@ void __init init_IRQ(void) outer_cache.write_sec = machine_desc->l2c_write_sec; ret = l2x0_of_init(machine_desc->l2c_aux_val, machine_desc->l2c_aux_mask); - if (ret) + if (ret && ret != -ENODEV) pr_err("L2C: failed to init: %d\n", ret); } diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index fb689d813b09..1fffae129a4a 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -90,8 +90,11 @@ ifeq ($(CONFIG_SUSPEND),y) AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o +AFLAGS_suspend-vf610.o :=-Wa,-march=armv7-a +obj-$(CONFIG_SOC_VF610) += suspend-vf610.o endif obj-$(CONFIG_SOC_IMX6) += pm-imx6.o +obj-$(CONFIG_SOC_VF610) += pm-vf610.o obj-$(CONFIG_SOC_IMX50) += mach-imx50.o obj-$(CONFIG_SOC_IMX51) += mach-imx51.o diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index e2d53839fceb..94d93a3b3b58 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -75,6 +75,13 @@ enum mxc_cpu_pwr_mode { STOP_POWER_OFF, /* STOP + SRPG */ }; +enum vf610_cpu_pwr_mode { + VF610_RUN, + VF610_LP_RUN, + VF610_STOP, + VF610_LP_STOP, +}; + enum mx3_cpu_pwr_mode { MX3_RUN, MX3_WAIT, @@ -119,11 +126,13 @@ void v7_cpu_resume(void); void imx53_suspend(void __iomem *ocram_vbase); extern const u32 imx53_suspend_sz; void imx6_suspend(void __iomem *ocram_vbase); +void vf610_suspend(void __iomem *ocram_vbase); #else static inline void v7_cpu_resume(void) {} static inline void imx53_suspend(void __iomem *ocram_vbase) {} static const u32 imx53_suspend_sz; static inline void imx6_suspend(void __iomem *ocram_vbase) {} +static inline void vf610_suspend(void __iomem *ocram_vbase) {} #endif void imx6_pm_ccm_init(const char *ccm_compat); @@ -132,6 +141,7 @@ void imx6dl_pm_init(void); void imx6sl_pm_init(void); void imx6sx_pm_init(void); void imx6ul_pm_init(void); +void vf610_pm_init(void); #ifdef CONFIG_PM void imx51_pm_init(void); diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c index b20f6c14eda5..5ba668feea65 100644 --- a/arch/arm/mach-imx/mach-vf610.c +++ b/arch/arm/mach-imx/mach-vf610.c @@ -11,6 +11,13 @@ #include <linux/irqchip.h> #include <asm/mach/arch.h> #include <asm/hardware/cache-l2x0.h> +#include "common.h" + +static void __init vf610_init_machine(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + vf610_pm_init(); +} static const char * const vf610_dt_compat[] __initconst = { "fsl,vf500", @@ -24,5 +31,6 @@ static const char * const vf610_dt_compat[] __initconst = { DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF5xx/VF6xx (Device Tree)") .l2c_aux_val = 0, .l2c_aux_mask = ~0, + .init_machine = vf610_init_machine, .dt_compat = vf610_dt_compat, MACHINE_END diff --git a/arch/arm/mach-imx/pm-vf610.c b/arch/arm/mach-imx/pm-vf610.c new file mode 100644 index 000000000000..5a3df0caf23a --- /dev/null +++ b/arch/arm/mach-imx/pm-vf610.c @@ -0,0 +1,704 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2014 Toradex AG + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifdef DEBUG +#define pr_pmdebug(fmt, ...) pr_info("PM: VF610: " fmt "\n", ##__VA_ARGS__) +#else +#define pr_pmdebug(fmt, ...) +#endif +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/genalloc.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/regmap.h> +#include <linux/slab.h> +#include <linux/suspend.h> +#include <linux/clk.h> +#include <asm/cacheflush.h> +#include <asm/fncpy.h> +#include <asm/proc-fns.h> +#include <asm/suspend.h> +#include <asm/tlb.h> + +#include "common.h" + +#define DDRMC_PHY_OFFSET 0x400 + +#define CCR 0x0 +#define BM_CCR_FIRC_EN (0x1 << 16) +#define BM_CCR_FXOSC_EN (0x1 << 12) + +#define CCSR 0x8 +#define BM_CCSR_DDRC_CLK_SEL (0x1 << 6) +#define BM_CCSR_FAST_CLK_SEL (0x1 << 5) +#define BM_CCSR_SLOW_CLK_SEL (0x1 << 4) +#define BM_CCSR_SYS_CLK_SEL_MASK (0x7 << 0) + +#define CACRR 0xc + +#define CLPCR 0x2c +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) +#define BM_CLPCR_SBYOS (0x1 << 6) +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define BM_CLPCR_ANADIG_STOP_MODE (0x1 << 8) +#define BM_CLPCR_FXOSC_BYPSEN (0x1 << 10) +#define BM_CLPCR_FXOSC_PWRDWN (0x1 << 11) +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 24) +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 25) + +#define CGPR 0x64 +#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17) + +#define GPC_PGCR 0x0 +#define BM_PGCR_DS_STOP (0x1 << 7) +#define BM_PGCR_DS_LPSTOP (0x1 << 6) +#define BM_PGCR_WB_STOP (0x1 << 4) +#define BM_PGCR_HP_OFF (0x1 << 3) +#define BM_PGCR_PG_PD1 (0x1 << 0) + +#define GPC_LPMR 0x40 +#define BM_LPMR_RUN 0x0 +#define BM_LPMR_STOP 0x2 + +#define ANATOP_PLL1_CTRL 0x270 +#define ANATOP_PLL2_CTRL 0x30 +#define ANATOP_PLL2_PFD 0x100 +#define BM_PLL_POWERDOWN (0x1 << 12) +#define BM_PLL_ENABLE (0x1 << 13) +#define BM_PLL_BYPASS (0x1 << 16) +#define BM_PLL_LOCK (0x1 << 31) +#define BM_PLL_PFD2_CLKGATE (0x1 << 15) +#define BM_PLL_USB_POWER (0x1 << 12) +#define BM_PLL_EN_USB_CLKS (0x1 << 6) + +#define VF610_DDRMC_IO_NUM 94 +#define VF610_IOMUX_DDR_IO_NUM 48 +#define VF610_ANATOP_IO_NUM 2 + +static struct vf610_cpu_pm_info *pm_info; +static void __iomem *suspend_ocram_base; +static void (*vf610_suspend_in_ocram_fn)(void __iomem *ocram_vbase); +static bool mem_suspend_available; + +#ifdef DEBUG +static void __iomem *uart_membase; +static unsigned long uart_clk; +#endif + +static const u32 vf610_iomuxc_ddr_io_offset[] __initconst = { + 0x220, 0x224, 0x228, 0x22c, 0x230, 0x234, 0x238, 0x23c, + 0x240, 0x244, 0x248, 0x24c, 0x250, 0x254, 0x258, 0x25c, + 0x260, 0x264, 0x268, 0x26c, 0x270, 0x274, 0x278, 0x27c, + 0x280, 0x284, 0x288, 0x28c, 0x290, 0x294, 0x298, 0x29c, + 0x2a0, 0x2a4, 0x2a8, 0x2ac, 0x2b0, 0x2b4, 0x2b8, 0x2bc, + 0x2c0, 0x2c4, 0x2c8, 0x2cc, 0x2d0, 0x2d4, 0x2d8, 0x21c, +}; + + +static const u32 vf610_ddrmc_io_offset[] __initconst = { + 0x00, 0x08, 0x28, 0x2c, 0x30, 0x34, 0x38, + 0x40, 0x44, 0x48, 0x50, 0x54, 0x58, 0x5c, + 0x60, 0x64, 0x68, 0x70, 0x74, 0x78, 0x7c, + 0x84, 0x88, 0x98, 0x9c, 0xa4, 0xc0, + 0x108, 0x10c, 0x114, 0x118, 0x120, 0x124, + 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, + 0x148, 0x15c, 0x160, 0x164, 0x16c, 0x180, + 0x184, 0x188, 0x18c, 0x198, 0x1a4, 0x1a8, + 0x1b8, 0x1d4, 0x1d8, 0x1e0, 0x1e4, 0x1e8, + 0x1ec, 0x1f0, 0x1f8, 0x210, 0x224, 0x228, + 0x22c, 0x230, 0x23c, 0x240, 0x244, 0x248, + 0x24c, 0x250, 0x25c, 0x268, 0x26c, 0x278, + 0x268 +}; + +static const u32 vf610_ddrmc_phy_io_offset[] __initconst = { + 0x00, 0x04, 0x08, 0x0c, 0x10, + 0x40, 0x44, 0x48, 0x4c, 0x50, + 0x80, 0x84, 0x88, 0x8c, 0x90, + 0xc4, 0xc8, 0xd0 +}; + +/* + * suspend ocram space layout: + * ======================== high address ====================== + * . + * . + * . + * ^ + * ^ + * ^ + * vf610_suspend code + * PM_INFO structure(vf610_cpu_pm_info) + * ======================== low address ======================= + */ + +struct vf610_pm_base { + phys_addr_t pbase; + void __iomem *vbase; +}; + +struct vf610_pm_socdata { + const char *anatop_compat; + const char *scsc_compat; + const char *wkpu_compat; + const char *ccm_compat; + const char *gpc_compat; + const char *src_compat; + const char *ddrmc_compat; + const char *iomuxc_compat; +}; + +static const struct vf610_pm_socdata vf610_pm_data __initconst = { + .anatop_compat = "fsl,vf610-anatop", + .scsc_compat = "fsl,vf610-scsc", + .wkpu_compat = "fsl,vf610-wkpu", + .ccm_compat = "fsl,vf610-ccm", + .gpc_compat = "fsl,vf610-gpc", + .src_compat = "fsl,vf610-src", + .ddrmc_compat = "fsl,vf610-ddrmc", + .iomuxc_compat = "fsl,vf610-iomuxc", +}; + +/* + * This structure is for passing necessary data for low level ocram + * suspend code(arch/arm/mach-imx/suspend-vf610.S), if this struct + * definition is changed, the offset definition in + * arch/arm/mach-imx/suspend-vf610.S must be also changed accordingly, + * otherwise, the suspend to ocram function will be broken! + */ +struct vf610_cpu_pm_info { + phys_addr_t pbase; /* The physical address of pm_info. */ + phys_addr_t resume_addr; /* The physical resume address for asm code */ + u32 cpu_type; /* Currently not used, leave it for alignment */ + u32 pm_info_size; /* Size of pm_info. */ + struct vf610_pm_base anatop_base; + struct vf610_pm_base scsc_base; + struct vf610_pm_base wkpu_base; + struct vf610_pm_base ccm_base; + struct vf610_pm_base gpc_base; + struct vf610_pm_base src_base; + struct vf610_pm_base ddrmc_base; + struct vf610_pm_base iomuxc_base; + struct vf610_pm_base l2_base; + u32 ccm_cacrr; + u32 ccm_ccsr; + u32 ddrmc_io_num; /* Number of MMDC IOs which need saved/restored. */ + u32 ddrmc_io_val[VF610_DDRMC_IO_NUM][2]; /* To save offset and value */ + u32 iomux_ddr_io_num; + u32 iomux_ddr_io_val[VF610_IOMUX_DDR_IO_NUM][2]; +} __aligned(8); + +#ifdef DEBUG +static void vf610_uart_reinit(unsigned long int rate, unsigned long int baud) +{ + u8 tmp, c2; + u16 sbr, brfa; + + /* UART_C2 */ + c2 = __raw_readb(uart_membase + 0x3); + __raw_writeb(0, uart_membase + 0x3); + + sbr = (u16) (rate / (baud * 16)); + brfa = (rate / baud) - (sbr * 16); + + tmp = ((sbr & 0x1f00) >> 8); + __raw_writeb(tmp, uart_membase + 0x0); + tmp = sbr & 0x00ff; + __raw_writeb(tmp, uart_membase + 0x1); + + /* UART_C4 */ + __raw_writeb(brfa & 0xf, uart_membase + 0xa); + + __raw_writeb(c2, uart_membase + 0x3); +} +#else +#define vf610_uart_reinit(rate, baud) +#endif + +static void vf610_set(void __iomem *pll_base, u32 mask) +{ + writel(readl(pll_base) | mask, pll_base); +} + +static void vf610_clr(void __iomem *pll_base, u32 mask) +{ + writel(readl(pll_base) & ~mask, pll_base); +} + +int vf610_set_lpm(enum vf610_cpu_pwr_mode mode) +{ + void __iomem *ccm_base = pm_info->ccm_base.vbase; + void __iomem *gpc_base = pm_info->gpc_base.vbase; + void __iomem *anatop = pm_info->anatop_base.vbase; + u32 ccr = readl_relaxed(ccm_base + CCR); + u32 ccsr = readl_relaxed(ccm_base + CCSR); + u32 cacrr = readl_relaxed(ccm_base + CACRR); + u32 cclpcr = 0; + u32 gpc_pgcr = 0; + + switch (mode) { + case VF610_LP_STOP: + /* Store clock settings */ + pm_info->ccm_ccsr = ccsr; + pm_info->ccm_cacrr = cacrr; + + ccr |= BM_CCR_FIRC_EN; + writel_relaxed(ccr, ccm_base + CCR); + + cclpcr |= BM_CLPCR_ANADIG_STOP_MODE; + cclpcr |= BM_CLPCR_SBYOS; + + cclpcr |= BM_CLPCR_MASK_SCU_IDLE; + cclpcr |= BM_CLPCR_MASK_L2CC_IDLE; + cclpcr |= BM_CLPCR_MASK_CORE1_WFI; + writel_relaxed(cclpcr, ccm_base + CLPCR); + + gpc_pgcr |= BM_PGCR_DS_STOP; + gpc_pgcr |= BM_PGCR_DS_LPSTOP; + gpc_pgcr |= BM_PGCR_WB_STOP; + gpc_pgcr |= BM_PGCR_HP_OFF; + gpc_pgcr |= BM_PGCR_PG_PD1; + writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR); + break; + case VF610_STOP: + cclpcr &= ~BM_CLPCR_ANADIG_STOP_MODE; + cclpcr |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; + cclpcr |= BM_CLPCR_SBYOS; + writel_relaxed(cclpcr, ccm_base + CLPCR); + + gpc_pgcr |= BM_PGCR_DS_STOP; + gpc_pgcr |= BM_PGCR_HP_OFF; + writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR); + + /* fall-through */ + case VF610_LP_RUN: + /* Store clock settings */ + pm_info->ccm_ccsr = ccsr; + pm_info->ccm_cacrr = cacrr; + + ccr |= BM_CCR_FIRC_EN; + writel_relaxed(ccr, ccm_base + CCR); + + /* Enable PLL2 for DDR clock */ + vf610_set(anatop + ANATOP_PLL2_CTRL, BM_PLL_ENABLE); + vf610_clr(anatop + ANATOP_PLL2_CTRL, BM_PLL_POWERDOWN); + vf610_clr(anatop + ANATOP_PLL2_CTRL, BM_PLL_BYPASS); + while (!(readl(anatop + ANATOP_PLL2_CTRL) & BM_PLL_LOCK)); + vf610_clr(anatop + ANATOP_PLL2_PFD, BM_PLL_PFD2_CLKGATE); + + /* Switch internal OSC's */ + ccsr &= ~BM_CCSR_FAST_CLK_SEL; + ccsr &= ~BM_CCSR_SLOW_CLK_SEL; + + /* Select PLL2 as DDR clock */ + ccsr &= ~BM_CCSR_DDRC_CLK_SEL; + writel_relaxed(ccsr, ccm_base + CCSR); + + ccsr &= ~BM_CCSR_SYS_CLK_SEL_MASK; + writel_relaxed(ccsr, ccm_base + CCSR); + vf610_uart_reinit(4000000UL, 115200); + + vf610_set(anatop + ANATOP_PLL1_CTRL, BM_PLL_BYPASS); + writel_relaxed(BM_LPMR_STOP, gpc_base + GPC_LPMR); + break; + case VF610_RUN: + writel_relaxed(BM_LPMR_RUN, gpc_base + GPC_LPMR); + + vf610_clr(anatop + ANATOP_PLL1_CTRL, BM_PLL_BYPASS); + while(!(readl(anatop + ANATOP_PLL1_CTRL) & BM_PLL_LOCK)); + + /* Restore clock settings */ + writel(pm_info->ccm_ccsr, ccm_base + CCSR); + + vf610_uart_reinit(uart_clk, 115200); + pr_pmdebug("resuming, uart_reinit done"); + + /* Disable PLL2 if not needed */ + if (pm_info->ccm_ccsr & BM_CCSR_DDRC_CLK_SEL) + vf610_set(anatop + ANATOP_PLL2_CTRL, BM_PLL_POWERDOWN); + + break; + default: + return -EINVAL; + } + + return 0; +} + +static int vf610_suspend_finish(unsigned long val) +{ + if (!vf610_suspend_in_ocram_fn) { + cpu_do_idle(); + } else { + /* + * call low level suspend function in ocram, + * as we need to float DDR IO. + */ + local_flush_tlb_all(); + flush_cache_all(); + outer_flush_all(); + vf610_suspend_in_ocram_fn(suspend_ocram_base); + } + + return 0; +} + +static int vf610_pm_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + vf610_set_lpm(VF610_STOP); + flush_cache_all(); + + /* zzZZZzzz */ + cpu_do_idle(); + + vf610_set_lpm(VF610_RUN); + break; + case PM_SUSPEND_MEM: + vf610_set_lpm(VF610_LP_STOP); + + cpu_suspend(0, vf610_suspend_finish); + outer_resume(); + + vf610_set_lpm(VF610_RUN); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int vf610_pm_valid(suspend_state_t state) +{ + return (state == PM_SUSPEND_STANDBY || + (state == PM_SUSPEND_MEM && mem_suspend_available)); +} + +static const struct platform_suspend_ops vf610_pm_ops = { + .enter = vf610_pm_enter, + .valid = vf610_pm_valid, +}; + +static int __init imx_pm_get_base(struct vf610_pm_base *base, + const char *compat) +{ + struct device_node *node; + struct resource res; + int ret = 0; + + node = of_find_compatible_node(NULL, NULL, compat); + if (!node) { + ret = -ENODEV; + goto out; + } + + ret = of_address_to_resource(node, 0, &res); + if (ret) + goto put_node; + + base->pbase = res.start; + base->vbase = ioremap(res.start, resource_size(&res)); + + if (!base->vbase) + ret = -ENOMEM; + +put_node: + of_node_put(node); +out: + return ret; +} + +#ifdef DEBUG +static int __init vf610_uart_init(void) +{ + struct device_node *dn; + const char *name; + struct clk *clk; + int ret; + + name = of_get_property(of_chosen, "stdout-path", NULL); + if (name == NULL) + return -ENODEV; + + dn = of_find_node_by_path(name); + if (!dn) + return -ENODEV; + + clk = of_clk_get(dn, 0); + + if (!clk) { + ret = PTR_ERR(clk); + goto put_node; + } + + uart_clk = clk_get_rate(clk); + + uart_membase = of_iomap(dn, 0); + if (!clk) { + ret = -ENOMEM; + goto put_node; + } + + ret = 0; + +put_node: + of_node_put(dn); + return ret; +} +#endif + +static void vf610_power_off(void) +{ + void __iomem *gpc_base = pm_info->gpc_base.vbase; + u32 gpc_pgcr; + + /* + * Power gate Power Domain 1 + */ + gpc_pgcr = readl_relaxed(gpc_base + GPC_PGCR); + gpc_pgcr |= BM_PGCR_PG_PD1; + writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR); + + /* Set low power mode */ + vf610_set_lpm(VF610_STOP); +} + +static int __init vf610_suspend_mem_init(const struct vf610_pm_socdata *socdata) +{ + struct device_node *node; + struct platform_device *pdev; + bool has_cke_reset_pulls = false; + phys_addr_t ocram_pbase; + struct gen_pool *ocram_pool; + size_t ocram_size; + unsigned long ocram_base; + int ret = 0, reg = 0; + int i; + + node = of_find_compatible_node(NULL, NULL, socdata->ddrmc_compat); + if (node) { + has_cke_reset_pulls = + of_property_read_bool(node, "fsl,has-cke-reset-pulls"); + + of_node_put(node); + } + + if (!has_cke_reset_pulls) { + pr_info("PM: No CKE/RESET pulls, disable Suspend-to-RAM\n"); + return -ENODEV; + } + + node = of_find_compatible_node(NULL, NULL, "mmio-sram"); + if (!node) { + pr_warn("%s: failed to find ocram node!\n", __func__); + return -ENODEV; + } + + pdev = of_find_device_by_node(node); + if (!pdev) { + pr_warn("%s: failed to find ocram device!\n", __func__); + ret = -ENODEV; + goto put_node; + } + + ocram_pool = gen_pool_get(&pdev->dev, "stbyram1"); + if (!ocram_pool) { + pr_warn("%s: ocram pool unavailable!\n", __func__); + ret = -ENODEV; + goto put_node; + } + + ocram_size = gen_pool_size(ocram_pool); + ocram_base = gen_pool_alloc(ocram_pool, ocram_size); + if (!ocram_base) { + pr_warn("%s: unable to alloc ocram!\n", __func__); + ret = -ENOMEM; + goto put_node; + } + + ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base); + + suspend_ocram_base = __arm_ioremap_exec(ocram_pbase, ocram_size, false); + + pm_info = suspend_ocram_base; + pm_info->pbase = ocram_pbase; + pm_info->resume_addr = virt_to_phys(cpu_resume); + + pm_info->ddrmc_io_num = VF610_DDRMC_IO_NUM; + + ret = imx_pm_get_base(&pm_info->ddrmc_base, socdata->ddrmc_compat); + if (ret) { + pr_warn("%s: failed to get ddrmc base %d!\n", __func__, ret); + goto put_node; + } + + ret = imx_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat); + if (ret) { + pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret); + goto iomuxc_map_failed; + } + + /* Store DDRMC registers */ + for (i = 0; i < ARRAY_SIZE(vf610_ddrmc_io_offset); i++, reg++) { + pm_info->ddrmc_io_val[reg][0] = vf610_ddrmc_io_offset[i]; + pm_info->ddrmc_io_val[reg][1] = + readl_relaxed(pm_info->ddrmc_base.vbase + + vf610_ddrmc_io_offset[i]); + } + + /* Store DDRMC PHY registers */ + for (i = 0; i < ARRAY_SIZE(vf610_ddrmc_phy_io_offset); i++, reg++) { + pm_info->ddrmc_io_val[reg][0] = vf610_ddrmc_phy_io_offset[i] + + DDRMC_PHY_OFFSET; + pm_info->ddrmc_io_val[reg][1] = + readl_relaxed(pm_info->ddrmc_base.vbase + + DDRMC_PHY_OFFSET + vf610_ddrmc_phy_io_offset[i]); + } + + /* Store IOMUX DDR pad registers */ + pm_info->iomux_ddr_io_num = VF610_IOMUX_DDR_IO_NUM; + for (i = 0; i < ARRAY_SIZE(vf610_iomuxc_ddr_io_offset); i++) { + pm_info->iomux_ddr_io_val[i][0] = vf610_iomuxc_ddr_io_offset[i]; + pm_info->iomux_ddr_io_val[i][1] = + readl_relaxed(pm_info->iomuxc_base.vbase + + vf610_iomuxc_ddr_io_offset[i]); + } + + vf610_suspend_in_ocram_fn = fncpy( + suspend_ocram_base + sizeof(*pm_info), + &vf610_suspend, ocram_size - sizeof(*pm_info)); + + pr_info("PM: CKE/RESET pulls available, enable Suspend-to-RAM\n"); + goto put_node; + +iomuxc_map_failed: + iounmap(pm_info->ddrmc_base.vbase); +put_node: + of_node_put(node); + + return ret; +} + +static int __init vf610_suspend_init(const struct vf610_pm_socdata *socdata) +{ + int ret; + struct device_node *soc_node; + +#ifdef DEBUG + ret = vf610_uart_init(); + if (ret < 0) + return ret; +#endif + + soc_node = of_find_node_by_path("/soc"); + if (soc_node == NULL) + return -ENODEV; + + if (of_property_read_bool(soc_node, "fsl,use-lpm-poweroff")) + pm_power_off = vf610_power_off; + + if (vf610_suspend_mem_init(socdata)) { + /* + * Suspend to memory for some reason not available, use DDR + * for standby mode + */ + pm_info = kzalloc(sizeof(*pm_info), GFP_KERNEL); + } else { + mem_suspend_available = true; + } + + pm_info->pm_info_size = sizeof(*pm_info); + + ret = imx_pm_get_base(&pm_info->anatop_base, socdata->anatop_compat); + if (ret) { + pr_warn("%s: failed to get anatop base %d!\n", __func__, ret); + return ret; + } + + ret = imx_pm_get_base(&pm_info->scsc_base, socdata->scsc_compat); + if (ret) { + pr_warn("%s: failed to get scsc base %d!\n", __func__, ret); + goto scsc_map_failed; + } + + ret = imx_pm_get_base(&pm_info->ccm_base, socdata->ccm_compat); + if (ret) { + pr_warn("%s: failed to get ccm base %d!\n", __func__, ret); + goto ccm_map_failed; + } + + ret = imx_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat); + if (ret) { + pr_warn("%s: failed to get gpc base %d!\n", __func__, ret); + goto gpc_map_failed; + } + + ret = imx_pm_get_base(&pm_info->src_base, socdata->src_compat); + if (ret) { + pr_warn("%s: failed to get src base %d!\n", __func__, ret); + goto src_map_failed; + } + + ret = imx_pm_get_base(&pm_info->l2_base, "arm,pl310-cache"); + if (ret == -ENODEV) + ret = 0; + if (ret) { + pr_warn("%s: failed to get pl310-cache base %d!\n", + __func__, ret); + goto pl310_cache_map_failed; + } + + suspend_set_ops(&vf610_pm_ops); + + return 0; + +pl310_cache_map_failed: + iounmap(pm_info->src_base.vbase); +src_map_failed: + iounmap(pm_info->gpc_base.vbase); +gpc_map_failed: + iounmap(pm_info->ccm_base.vbase); +ccm_map_failed: + iounmap(pm_info->scsc_base.vbase); +scsc_map_failed: + iounmap(pm_info->anatop_base.vbase); + + if (mem_suspend_available) { + iounmap(pm_info->ddrmc_base.vbase); + iounmap(pm_info->iomuxc_base.vbase); + } + + return ret; +} + +void __init vf610_pm_init(void) +{ + int ret; + + if (IS_ENABLED(CONFIG_SUSPEND)) { + ret = vf610_suspend_init(&vf610_pm_data); + if (ret) + pr_warn("%s: No DDR LPM support with suspend %d!\n", + __func__, ret); + } +} + diff --git a/arch/arm/mach-imx/suspend-vf610.S b/arch/arm/mach-imx/suspend-vf610.S new file mode 100644 index 000000000000..595dd4e2c74c --- /dev/null +++ b/arch/arm/mach-imx/suspend-vf610.S @@ -0,0 +1,448 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2015 Toradex AG + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/asm-offsets.h> +#include <asm/hardware/cache-l2x0.h> + +/* + * ==================== low level suspend ==================== + * + * Better to follow below rules to use ARM registers: + * r0: pm_info structure address; + * r1 ~ r4: for saving pm_info members; + * r5 ~ r10: free registers; + * r11: io base address. + * + * suspend ocram space layout: + * ======================== high address ====================== + * . + * . + * . + * ^ + * ^ + * ^ + * vf610_suspend code + * PM_INFO structure(vf610_cpu_pm_info) + * ======================== low address ======================= + */ + +/* + * Below offsets are based on struct vf610_cpu_pm_info + * which defined in arch/arm/mach-imx/pm-vf610.c, this + * structure contains necessary pm info for low level + * suspend related code. + */ +#define PM_INFO_PBASE_OFFSET 0x0 +#define PM_INFO_RESUME_ADDR_OFFSET 0x4 +#define PM_INFO_CPU_TYPE_OFFSET 0x8 +#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC +#define PM_INFO_VF610_ANATOP_P_OFFSET 0x10 +#define PM_INFO_VF610_ANATOP_V_OFFSET 0x14 +#define PM_INFO_VF610_SCSC_P_OFFSET 0x18 +#define PM_INFO_VF610_SCSC_V_OFFSET 0x1C +#define PM_INFO_VF610_WKPU_P_OFFSET 0x20 +#define PM_INFO_VF610_WKPU_V_OFFSET 0x24 +#define PM_INFO_VF610_CCM_P_OFFSET 0x28 +#define PM_INFO_VF610_CCM_V_OFFSET 0x2C +#define PM_INFO_VF610_GPC_P_OFFSET 0x30 +#define PM_INFO_VF610_GPC_V_OFFSET 0x34 +#define PM_INFO_VF610_SRC_P_OFFSET 0x38 +#define PM_INFO_VF610_SRC_V_OFFSET 0x3C +#define PM_INFO_VF610_DDRMC_P_OFFSET 0x40 +#define PM_INFO_VF610_DDRMC_V_OFFSET 0x44 +#define PM_INFO_VF610_IOMUXC_P_OFFSET 0x48 +#define PM_INFO_VF610_IOMUXC_V_OFFSET 0x4c +#define PM_INFO_VF610_L2_P_OFFSET 0x50 +#define PM_INFO_VF610_L2_V_OFFSET 0x54 +#define PM_INFO_CCM_CACRR 0x58 +#define PM_INFO_CCM_CCSR 0x5c +#define PM_INFO_DDRMC_IO_NUM_OFFSET 0x60 +#define PM_INFO_DDRMC_IO_VAL_OFFSET 0x64 +#define PM_INFO_IOMUXC_DDR_IO_NUM_OFFSET (0x64 + 94 * 2 * 4) +#define PM_INFO_IOMUXC_DDR_IO_VAL_OFFSET (0x68 + 94 * 2 * 4) + +#define VF610_ANADIG_PLL2_CTRL 0x30 + +#define VF610_ANADIG_MISC0 0x150 +#define VF610_ANADIG_MISC0_CLK_24M_IRC_XTAL_SEL (0x1 < 13) + +#define VF610_ANADIG_PLL1_CTRL 0x270 + +#define VF610_ANADIG_POWERDOWN (1 << 12) +#define VF610_ANADIG_ENABLE (1 << 13) +#define VF610_ANADIG_BYPASS (1 << 16) +#define VF610_ANADIG_LOCK (1 << 31) + +#define VF610_SCSC_SIRC 0x0 +#define VF610_SCSC_SIRC_SIRC_EN (0x1 << 0) +#define VF610_SCSC_SOSC 0x4 +#define VF610_SCSC_SOSC_SOSC_EN (0x1 << 0) + +#define VF610_GPC_PGCR 0x0 +#define VF610_GPC_LPMR 0x40 + +#define VF610_CCM_CCR 0x00 +#define VF610_CCM_CCR_FXOSC_EN (0x1 << 12) + +#define VF610_CCM_CCSR 0x08 +#define VF610_CCM_CCSR_DDRC_CLK_SEL (0x1 << 6) +#define VF610_CCM_CCSR_FAST_CLK_SEL (0x1 << 5) + +#define VF610_CCM_CACRR 0x0C + +#define VF610_CCM_CLPCR 0x2C +#define VF610_CCM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define VF610_CCM_CLPCR_FXOSC_PWRDWN (0x1 << 11) + +#define VF610_CCM_CCGR0 0x40 +#define VF610_CCM_CCGR2 0x48 +#define VF610_CCM_CCGR3 0x4C +#define VF610_CCM_CCGR4 0x50 +#define VF610_CCM_CCGR6 0x58 + +#define VF610_SRC_GPR0 0x20 +#define VF610_SRC_GPR1 0x24 +#define VF610_SRC_MISC2 0x54 + +#define VF610_DDRMC_CR00 0x0 +#define VF610_DDRMC_CR00_START (0x1 << 0) + +#define VF610_DDRMC_CR33 0x84 +#define VF610_DDRMC_CR33_PWUP_SREF_EX (0x1 << 0) + +#define VF610_DDRMC_CR34 0x88 + +#define VF610_DDRMC_CR35 0x8C +#define VF610_DDRMC_CR35_LP_CMD(cmd) ((cmd) << 8) + +#define VF610_DDRMC_CR80 0x140 +#define VF610_DDRMC_CR80_LP_COMPLETE (0x1 << 9) +#define VF610_DDRMC_CR80_INIT_COMPLETE (0x1 << 8) +#define VF610_DDRMC_CR81 0x144 + + .align 3 + + /* + * Take DDR RAM out of Low-Power mode + */ + .macro resume_ddrmc ddrmc_base + + /* Clear low power complete flag... */ + ldr r6, =VF610_DDRMC_CR80_LP_COMPLETE + str r6, [\ddrmc_base, #VF610_DDRMC_CR81] + + ldr r6, [\ddrmc_base, #VF610_DDRMC_CR35] + orr r6, r6, #VF610_DDRMC_CR35_LP_CMD(0x9) + str r6, [\ddrmc_base, #VF610_DDRMC_CR35] + +1: + ldr r5, [\ddrmc_base, #VF610_DDRMC_CR80] + ands r5, r5, #VF610_DDRMC_CR80_LP_COMPLETE + beq 1b + + .endm + + .macro enable_syspll pll_base + + ldr r5, [\pll_base] + orr r5, r5, #VF610_ANADIG_ENABLE + bic r5, r5, #VF610_ANADIG_POWERDOWN + bic r5, r5, #VF610_ANADIG_BYPASS + str r5, [\pll_base] + +1: + ldr r5, [\pll_base] + tst r5, #VF610_ANADIG_LOCK + beq 1b + + .endm + +ENTRY(vf610_suspend) + ldr r1, [r0, #PM_INFO_PBASE_OFFSET] + ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET] + ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] + ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET] + + /* + * make sure TLB contain the addr we want, + * as we will access them after MMDC IO floated. + */ + + ldr r11, [r0, #PM_INFO_VF610_DDRMC_V_OFFSET] + ldr r6, [r11, #0x0] + ldr r11, [r0, #PM_INFO_VF610_GPC_V_OFFSET] + ldr r6, [r11, #0x0] + ldr r11, [r0, #PM_INFO_VF610_SRC_V_OFFSET] + ldr r6, [r11, #0x0] + ldr r11, [r0, #PM_INFO_VF610_CCM_V_OFFSET] + ldr r6, [r11, #0x0] + + ldr r11, [r0, #PM_INFO_VF610_SRC_V_OFFSET] + + /* Disable DDR RESET */ + ldr r6, [r11, #VF610_SRC_MISC2] + orr r6, r6, #0x1 + str r6, [r11, #VF610_SRC_MISC2] + + /* Set ENTRY/ARGUMENT register */ + ldr r6, =vf610_suspend + ldr r7, =resume + sub r7, r7, r6 + add r8, r1, r4 + add r9, r8, r7 + str r9, [r11, #VF610_SRC_GPR0] + str r1, [r11, #VF610_SRC_GPR1] + + /* Put memory in self refresh... */ + ldr r11, [r0, #PM_INFO_VF610_DDRMC_V_OFFSET] + + ldr r6, =VF610_DDRMC_CR80_LP_COMPLETE + str r6, [r11, #VF610_DDRMC_CR81] + + ldr r6, [r11, #VF610_DDRMC_CR35] + orr r6, r6, #VF610_DDRMC_CR35_LP_CMD(0xA) + str r6, [r11, #VF610_DDRMC_CR35] + +ddrmc_cmd_complete: + /* A Unfixed module seems to hang at this read.... */ + ldr r5, [r11, #VF610_DDRMC_CR80] + ands r5, r5, #VF610_DDRMC_CR80_LP_COMPLETE + beq ddrmc_cmd_complete + + /* switch to internal FIRC */ + ldr r11, [r0, #PM_INFO_VF610_CCM_V_OFFSET] + ldr r5, [r11, #VF610_CCM_CCSR] + bic r5, r5, #0x30 /* FAST_/SLOW_CLK_SEL */ + str r5, [r11, #VF610_CCM_CCSR] + bic r5, r5, #0x07 /* SYS_CLK_SEL */ + str r5, [r11, #VF610_CCM_CCSR] + + /* LP-Mode: STOP */ + ldr r11, [r0, #PM_INFO_VF610_GPC_V_OFFSET] + ldr r6, =0x02 + str r6, [r11, #VF610_GPC_LPMR] + + /* Zzz, enter stop mode */ + wfi + nop + nop + nop + nop + + /* If we get here, there is already an interrupt pending. Restore... */ + ldr r6, =0x00 + str r6, [r11, #VF610_GPC_LPMR] + + /* Get previous CCSR/CACRR settings */ + ldr r11, [r0, #PM_INFO_VF610_CCM_V_OFFSET] + ldr r5, [r0, #PM_INFO_CCM_CCSR] + str r5, [r11, #VF610_CCM_CCSR] + + ldr r5, [r0, #PM_INFO_CCM_CACRR] + str r5, [r11, #VF610_CCM_CACRR] + + ldr r11, [r0, #PM_INFO_VF610_DDRMC_V_OFFSET] + resume_ddrmc r11 + + ret lr + +/* Resume path if CPU uses the SRC_GPR0 (PERSISTENT_ENTRY0) */ +resume: + /* invalidate L1 I-cache first */ + mov r6, #0x0 + mcr p15, 0, r6, c7, c5, 0 + mcr p15, 0, r6, c7, c5, 6 + + /* enable the Icache and branch prediction */ + mov r6, #0x1800 + mcr p15, 0, r6, c1, c0, 0 + isb + + ldr r11, [r0, #PM_INFO_VF610_CCM_P_OFFSET] + + ldr r5, [r11, #VF610_CCM_CCSR] + orr r5, r5, #(1 << 13) + str r5, [r11, #VF610_CCM_CCSR] + + /* enable UART0 */ + ldr r5, [r11, #VF610_CCM_CCGR0] + orr r5, r5, #0xC000 + str r5, [r11, #VF610_CCM_CCGR0] + + /* enable IOMUX, PORT A-E */ + ldr r5, [r11, #VF610_CCM_CCGR2] + ldr r6, =0xFFF0000 + orr r5, r5, r6 + str r5, [r11, #VF610_CCM_CCGR2] + + /* enable ANADIG and SCSM */ + ldr r5, [r11, #VF610_CCM_CCGR3] + orr r5, r5, #0x33 + str r5, [r11, #VF610_CCM_CCGR3] + + /* enable GPC, CCM and WKUP */ + ldr r5, [r11, #VF610_CCM_CCGR4] + orr r5, r5, #0x3f00000 + str r5, [r11, #VF610_CCM_CCGR4] + + /* enable mmdc */ + ldr r5, [r11, #VF610_CCM_CCGR6] + orr r5, r5, #0x30000000 + str r5, [r11, #VF610_CCM_CCGR6] + + /* Mux UART0 */ + ldr r5,=0x1021a2 + ldr r6,=0x40048080 + str r5, [r6, #0x0] + ldr r5,=0x1021a1 + ldr r6,=0x40048084 + str r5, [r6, #0x0] + + /* Set IOMUX for DDR pads */ + ldr r11, [r0, #PM_INFO_VF610_IOMUXC_P_OFFSET] + + ldr r6, [r0, #PM_INFO_IOMUXC_DDR_IO_NUM_OFFSET] + ldr r7, =PM_INFO_IOMUXC_DDR_IO_VAL_OFFSET + add r7, r7, r0 + +loop_iomuxc_ddr_restore: + ldr r8, [r7], #0x4 + ldr r9, [r7], #0x4 + str r9, [r11, r8] + subs r6, r6, #0x1 + bne loop_iomuxc_ddr_restore + + + /* Enable slow oscilators */ + ldr r11, [r0, #PM_INFO_VF610_SCSC_P_OFFSET] + + ldr r5, [r11, #VF610_SCSC_SOSC] + orr r5, r5, #VF610_SCSC_SOSC_SOSC_EN + str r5, [r11, #VF610_SCSC_SOSC] + + ldr r5, [r11, #VF610_SCSC_SIRC] + orr r5, r5, #VF610_SCSC_SIRC_SIRC_EN + str r5, [r11, #VF610_SCSC_SIRC] + + /* Enable fast osciallator */ + ldr r11, [r0, #PM_INFO_VF610_CCM_P_OFFSET] + + ldr r5, [r11, #VF610_CCM_CLPCR] + bic r5, r5, #VF610_CCM_CLPCR_DIS_REF_OSC + bic r5, r5, #VF610_CCM_CLPCR_FXOSC_PWRDWN + str r5, [r11, #VF610_CCM_CLPCR] + + ldr r5, [r11, #VF610_CCM_CCR] + orr r5, r5, #VF610_CCM_CCR_FXOSC_EN + str r5, [r11, #VF610_CCM_CCR] + + ldr r5, [r11, #VF610_CCM_CCSR] + orr r5, r5, #VF610_CCM_CCSR_FAST_CLK_SEL + str r5, [r11, #VF610_CCM_CCSR] + + ldr r11, [r0, #PM_INFO_VF610_ANATOP_P_OFFSET] + + /* Select external FXOSC */ + ldr r5, [r11, #VF610_ANADIG_MISC0] + bic r5, r5, #VF610_ANADIG_MISC0_CLK_24M_IRC_XTAL_SEL + str r5, [r11, #VF610_ANADIG_MISC0] + + /* pll1 enable */ + add r6, r11, #VF610_ANADIG_PLL1_CTRL + enable_syspll r6 + + /* enable pll2 only if required for DDR */ + ldr r5, [r0, #PM_INFO_CCM_CCSR] + tst r5, #VF610_CCM_CCSR_DDRC_CLK_SEL + bne switch_sysclk + + /* pll2 enable */ + add r6, r11, #VF610_ANADIG_PLL2_CTRL + enable_syspll r6 + +switch_sysclk: + + /* Enable PFD and switch to fast clock */ + ldr r11, [r0, #PM_INFO_VF610_CCM_P_OFFSET] + + /* Get previous CCSR/CACRR settings */ + ldr r5, [r0, #PM_INFO_CCM_CCSR] + str r5, [r11, #VF610_CCM_CCSR] + + ldr r5, [r0, #PM_INFO_CCM_CACRR] + str r5, [r11, #VF610_CCM_CACRR] + + /* Restore memory configuration */ + ldr r11, [r0, #PM_INFO_VF610_DDRMC_P_OFFSET] + + ldr r6, [r0, #PM_INFO_DDRMC_IO_NUM_OFFSET] + ldr r7, =PM_INFO_DDRMC_IO_VAL_OFFSET + add r7, r7, r0 + + /* Clear start bit of first memory register, do not start yet... */ + ldr r8, [r7], #0x4 + ldr r9, [r7], #0x4 + bic r9, r9, #VF610_DDRMC_CR00_START + str r9, [r11, r8] + subs r6, r6, #0x1 + +loop_ddrmc_restore: + ldr r8, [r7], #0x4 + ldr r9, [r7], #0x4 + str r9, [r11, r8] + subs r6, r6, #0x1 + bne loop_ddrmc_restore + + /* Set PWUP_SREF_EX to avoid a full memory initialization */ + ldr r6, [r11, #VF610_DDRMC_CR33] + orr r6, r6, #VF610_DDRMC_CR33_PWUP_SREF_EX + str r6, [r11, #VF610_DDRMC_CR33] + + /* Start initialization */ + ldr r6, =VF610_DDRMC_CR80_INIT_COMPLETE + str r6, [r11, #VF610_DDRMC_CR81] + + ldr r6, [r11, #VF610_DDRMC_CR00] + orr r6, r6, #VF610_DDRMC_CR00_START + str r6, [r11, #VF610_DDRMC_CR00] + +ddrmc_initializing: + ldr r5, [r11, #VF610_DDRMC_CR80] + ands r5, r5, #VF610_DDRMC_CR80_INIT_COMPLETE + beq ddrmc_initializing + + resume_ddrmc r11 + + /* LP-Mode: RUN */ + ldr r11, [r0, #PM_INFO_VF610_GPC_P_OFFSET] + ldr r5, =0x0 + str r5, [r11, #VF610_GPC_LPMR] + + /* Enable SNVS */ + ldr r3, [r0, #PM_INFO_VF610_CCM_P_OFFSET] + ldr r4, [r3, #VF610_CCM_CCGR6] + orr r4, r4, #0x0000C000 + str r4, [r3, #VF610_CCM_CCGR6] + + /* Enable SNVS access (RTC) */ + ldr r11, =0x400a7000 + ldr r4, =0x80000100 + str r4, [r11, #0x4] + + /* get physical resume address from pm_info. */ + ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET] + + ret lr +ENDPROC(vf610_suspend) + |