diff options
Diffstat (limited to 'arch')
131 files changed, 3505 insertions, 2178 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993c..6cdf8bd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -9,7 +9,7 @@ config ARM select BUILDTIME_EXTABLE_SORT if MMU select CPU_PM if (SUSPEND || CPU_IDLE) select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU - select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) + select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -366,11 +366,12 @@ config ARCH_CLPS711X select ARCH_REQUIRE_GPIOLIB select AUTO_ZRELADDR select CLKDEV_LOOKUP + select CLKSRC_MMIO select COMMON_CLK select CPU_ARM720T select GENERIC_CLOCKEVENTS + select MFD_SYSCON select MULTI_IRQ_HANDLER - select NEED_MACH_MEMORY_H select SPARSE_IRQ help Support for Cirrus Logic 711x/721x/731x based boards. @@ -502,6 +503,7 @@ config ARCH_DOVE config ARCH_KIRKWOOD bool "Marvell Kirkwood" + select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select GENERIC_CLOCKEVENTS @@ -645,7 +647,7 @@ config ARCH_SHMOBILE select MULTI_IRQ_HANDLER select NEED_MACH_MEMORY_H select NO_IOPORT - select PINCTRL if ARCH_WANT_OPTIONAL_GPIOLIB + select PINCTRL select PM_GENERIC_DOMAINS if PM select SPARSE_IRQ help @@ -1585,7 +1587,7 @@ config SCHED_HRTICK config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY - depends on CPU_V7 && !CPU_V6 && !CPU_V6K + depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K default y if CPU_THUMBONLY select AEABI select ARM_ASM_UNIFIED diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index 2cef8e1..c859495 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -28,7 +28,7 @@ config FLASH_SIZE config PROCESSOR_ID hex 'Hard wire the processor ID' default 0x00007700 - depends on !CPU_CP15 + depends on !(CPU_CP15 || CPU_V7M) help If processor has no CP15 register, this processor ID is used instead of the auto-probing which utilizes the register. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1ba358b..3380c4f 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -59,6 +59,7 @@ comma = , # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes # testing for a specific architecture or later rather impossible. +arch-$(CONFIG_CPU_32v7M) :=-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) # Only override the compiler option if ARMv6. The ARMv6K extensions are diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index f0895c5..3844ef2 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -64,6 +64,8 @@ dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ integratorcp.dtb dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \ + kirkwood-db-88f6281.dtb \ + kirkwood-db-88f6282.dtb \ kirkwood-dns320.dtb \ kirkwood-dns325.dtb \ kirkwood-dockstar.dtb \ diff --git a/arch/arm/boot/dts/kirkwood-6281.dtsi b/arch/arm/boot/dts/kirkwood-6281.dtsi index d6c9d65..5137668 100644 --- a/arch/arm/boot/dts/kirkwood-6281.dtsi +++ b/arch/arm/boot/dts/kirkwood-6281.dtsi @@ -40,5 +40,36 @@ marvell,function = "sdio"; }; }; + + pcie-controller { + compatible = "marvell,kirkwood-pcie"; + status = "disabled"; + device_type = "pci"; + + #address-cells = <3>; + #size-cells = <2>; + + bus-range = <0x00 0xff>; + + ranges = <0x82000000 0 0x00040000 0x00040000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ + 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &intc 9>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gate_clk 2>; + status = "disabled"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-6282.dtsi b/arch/arm/boot/dts/kirkwood-6282.dtsi index 23991e4..66a751a 100644 --- a/arch/arm/boot/dts/kirkwood-6282.dtsi +++ b/arch/arm/boot/dts/kirkwood-6282.dtsi @@ -65,5 +65,53 @@ clocks = <&gate_clk 7>; status = "disabled"; }; + + pcie-controller { + compatible = "marvell,kirkwood-pcie"; + status = "disabled"; + device_type = "pci"; + + #address-cells = <3>; + #size-cells = <2>; + + bus-range = <0x00 0xff>; + + ranges = <0x82000000 0 0x00040000 0x00040000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0 0x00044000 0x00044000 0 0x00002000 /* Port 1.0 registers */ + 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ + 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &intc 9>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gate_clk 2>; + status = "disabled"; + }; + + pcie@2,0 { + device_type = "pci"; + assigned-addresses = <0x82001000 0 0x00044000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &intc 10>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <0>; + clocks = <&gate_clk 18>; + status = "disabled"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-db-88f6281.dts b/arch/arm/boot/dts/kirkwood-db-88f6281.dts new file mode 100644 index 0000000..9d777ed --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-db-88f6281.dts @@ -0,0 +1,30 @@ +/* + * Marvell DB-88F6281-BP Development Board Setup + * + * Saeed Bishara <saeed@marvell.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.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. + */ + +/dts-v1/; + +/include/ "kirkwood-db.dtsi" +/include/ "kirkwood-6281.dtsi" + +/ { + model = "Marvell DB-88F6281-BP Development Board"; + compatible = "marvell,db-88f6281-bp", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + ocp@f1000000 { + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-db-88f6282.dts b/arch/arm/boot/dts/kirkwood-db-88f6282.dts new file mode 100644 index 0000000..f4c8528 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-db-88f6282.dts @@ -0,0 +1,34 @@ +/* + * Marvell DB-88F6282-BP Development Board Setup + * + * Saeed Bishara <saeed@marvell.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.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. + */ + +/dts-v1/; + +/include/ "kirkwood-db.dtsi" +/include/ "kirkwood-6282.dtsi" + +/ { + model = "Marvell DB-88F6282-BP Development Board"; + compatible = "marvell,db-88f6282-bp", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + ocp@f1000000 { + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + + pcie@2,0 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-db.dtsi b/arch/arm/boot/dts/kirkwood-db.dtsi new file mode 100644 index 0000000..c87cfb8 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-db.dtsi @@ -0,0 +1,89 @@ +/* + * Marvell DB-{88F6281,88F6282}-BP Development Board Setup + * + * Saeed Bishara <saeed@marvell.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.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. + * + * This file contains the definitions that are common between the 6281 + * and 6282 variants of the Marvell Kirkwood Development Board. + */ + +/include/ "kirkwood.dtsi" + +/ { + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512 MB */ + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + }; + + ocp@f1000000 { + pinctrl@10000 { + pmx_sdio_gpios: pmx-sdio-gpios { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "gpio"; + }; + }; + + serial@12000 { + pinctrl-0 = <&pmx_uart0>; + pinctrl-names = "default"; + clock-frequency = <200000000>; + status = "ok"; + }; + + nand@3000000 { + pinctrl-0 = <&pmx_nand>; + pinctrl-names = "default"; + chip-delay = <25>; + status = "okay"; + + partition@0 { + label = "uboot"; + reg = <0x0 0x100000>; + }; + + partition@100000 { + label = "uImage"; + reg = <0x100000 0x400000>; + }; + + partition@500000 { + label = "root"; + reg = <0x500000 0x1fb00000>; + }; + }; + + sata@80000 { + nr-ports = <2>; + status = "okay"; + }; + + ehci@50000 { + status = "okay"; + }; + + mvsdio@90000 { + pinctrl-0 = <&pmx_sdio_gpios>; + pinctrl-names = "default"; + wp-gpios = <&gpio1 5 0>; + cd-gpios = <&gpio1 6 0>; + status = "okay"; + }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 12ccf74..e591d5d 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -109,6 +109,14 @@ reg = <0x980000 0x1f400000>; }; }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; }; gpio-leds { diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts index 7588241..90501cf 100644 --- a/arch/arm/boot/dts/kirkwood-mplcec4.dts +++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts @@ -139,6 +139,14 @@ cd-gpios = <&gpio1 15 0>; /* No WP GPIO */ }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; }; gpio-leds { diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts index 1ca66ab..0f852b4 100644 --- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts +++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts @@ -111,6 +111,14 @@ status = "okay"; nr-ports = <2>; }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; }; gpio-leds { diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts index a7412b9..9ddf218 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -176,6 +176,14 @@ reg = <0x5040000 0x2fc0000>; }; }; + + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; }; gpio_keys { diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts index 8295c83..42648ab 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6281.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts @@ -1,7 +1,8 @@ /dts-v1/; -/include/ "kirkwood-ts219.dtsi" +/include/ "kirkwood.dtsi" /include/ "kirkwood-6281.dtsi" +/include/ "kirkwood-ts219.dtsi" / { ocp@f1000000 { diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts index df3f95d..95ceeb9 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts @@ -1,7 +1,8 @@ /dts-v1/; -/include/ "kirkwood-ts219.dtsi" +/include/ "kirkwood.dtsi" /include/ "kirkwood-6282.dtsi" +/include/ "kirkwood-ts219.dtsi" / { ocp@f1000000 { diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi index 64ea27c..7c022fd 100644 --- a/arch/arm/boot/dts/kirkwood-ts219.dtsi +++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi @@ -1,5 +1,3 @@ -/include/ "kirkwood.dtsi" - / { model = "QNAP TS219 family"; compatible = "qnap,ts219", "marvell,kirkwood"; @@ -74,5 +72,12 @@ status = "okay"; nr-ports = <2>; }; + pcie-controller { + status = "okay"; + + pcie@1,0 { + status = "okay"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index fada7e6..7eef88f 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -19,6 +19,7 @@ ocp@f1000000 { compatible = "simple-bus"; ranges = <0x00000000 0xf1000000 0x4000000 + 0xe0000000 0xe0000000 0x8100000 /* PCIE */ 0xf5000000 0xf5000000 0x0000400>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index 14fb2e6..0dbee2c 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -49,16 +49,18 @@ uart0: uart@e0000000 { compatible = "xlnx,xuartps"; + clocks = <&clkc 23>, <&clkc 40>; + clock-names = "ref_clk", "aper_clk"; reg = <0xE0000000 0x1000>; interrupts = <0 27 4>; - clocks = <&uart_clk 0>; }; uart1: uart@e0001000 { compatible = "xlnx,xuartps"; + clocks = <&clkc 24>, <&clkc 41>; + clock-names = "ref_clk", "aper_clk"; reg = <0xE0001000 0x1000>; interrupts = <0 50 4>; - clocks = <&uart_clk 1>; }; slcr: slcr@f8000000 { @@ -69,50 +71,21 @@ #address-cells = <1>; #size-cells = <0>; - ps_clk: ps_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - /* clock-frequency set in board-specific file */ - clock-output-names = "ps_clk"; - }; - armpll: armpll { - #clock-cells = <0>; - compatible = "xlnx,zynq-pll"; - clocks = <&ps_clk>; - reg = <0x100 0x110>; - clock-output-names = "armpll"; - }; - ddrpll: ddrpll { - #clock-cells = <0>; - compatible = "xlnx,zynq-pll"; - clocks = <&ps_clk>; - reg = <0x104 0x114>; - clock-output-names = "ddrpll"; - }; - iopll: iopll { - #clock-cells = <0>; - compatible = "xlnx,zynq-pll"; - clocks = <&ps_clk>; - reg = <0x108 0x118>; - clock-output-names = "iopll"; - }; - uart_clk: uart_clk { - #clock-cells = <1>; - compatible = "xlnx,zynq-periph-clock"; - clocks = <&iopll &armpll &ddrpll>; - reg = <0x154>; - clock-output-names = "uart0_ref_clk", - "uart1_ref_clk"; - }; - cpu_clk: cpu_clk { + clkc: clkc { #clock-cells = <1>; - compatible = "xlnx,zynq-cpu-clock"; - clocks = <&iopll &armpll &ddrpll>; - reg = <0x120 0x1C4>; - clock-output-names = "cpu_6x4x", - "cpu_3x2x", - "cpu_2x", - "cpu_1x"; + compatible = "xlnx,ps7-clkc"; + ps-clk-frequency = <33333333>; + clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", + "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", + "dci", "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", + "dma", "usb0_aper", "usb1_aper", "gem0_aper", + "gem1_aper", "sdio0_aper", "sdio1_aper", + "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", + "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", + "gpio_aper", "lqspi_aper", "smc_aper", "swdt", + "dbg_trc", "dbg_apb"; }; }; }; @@ -121,9 +94,8 @@ interrupt-parent = <&intc>; interrupts = < 0 10 4 0 11 4 0 12 4 >; compatible = "cdns,ttc"; + clocks = <&clkc 6>; reg = <0xF8001000 0x1000>; - clocks = <&cpu_clk 3>; - clock-names = "cpu_1x"; clock-ranges; }; @@ -131,9 +103,8 @@ interrupt-parent = <&intc>; interrupts = < 0 37 4 0 38 4 0 39 4 >; compatible = "cdns,ttc"; + clocks = <&clkc 6>; reg = <0xF8002000 0x1000>; - clocks = <&cpu_clk 3>; - clock-names = "cpu_1x"; clock-ranges; }; scutimer: scutimer@f8f00600 { @@ -141,7 +112,7 @@ interrupts = < 1 13 0x301 >; compatible = "arm,cortex-a9-twd-timer"; reg = < 0xf8f00600 0x20 >; - clocks = <&cpu_clk 1>; + clocks = <&clkc 4>; } ; }; }; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index 86f44d5..e25a307 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -28,7 +28,3 @@ }; }; - -&ps_clk { - clock-frequency = <33333330>; -}; diff --git a/arch/arm/configs/clps711x_defconfig b/arch/arm/configs/clps711x_defconfig index 1cd94c3..9e8c831 100644 --- a/arch/arm/configs/clps711x_defconfig +++ b/arch/arm/configs/clps711x_defconfig @@ -31,21 +31,18 @@ CONFIG_EP7211_DONGLE=y # CONFIG_WIRELESS is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_AUTCPU12=y CONFIG_MTD_PLATRAM=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_GPIO=y CONFIG_NETDEVICES=y # CONFIG_NET_CADENCE is not set # CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_CHELSIO is not set CONFIG_CS89x0=y CONFIG_CS89x0_PLATFORM=y # CONFIG_NET_VENDOR_FARADAY is not set @@ -63,7 +60,11 @@ CONFIG_CS89x0_PLATFORM=y # CONFIG_VT is not set CONFIG_SERIAL_CLPS711X_CONSOLE=y # CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_GPIO=y CONFIG_SPI=y +CONFIG_SPI_CLPS711X=y +CONFIG_GPIO_CLPS711X=y CONFIG_GPIO_GENERIC_PLATFORM=y # CONFIG_HWMON is not set CONFIG_FB=y @@ -87,4 +88,3 @@ CONFIG_DEBUG_LL=y CONFIG_EARLY_PRINTK=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set -# CONFIG_CRC32 is not set diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index a1d8252..0f2aa61 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -31,6 +30,7 @@ CONFIG_MACH_T5325=y CONFIG_MACH_TS219=y CONFIG_MACH_TS41X=y CONFIG_MACH_CLOUDBOX_DT=y +CONFIG_MACH_DB88F628X_BP_DT=y CONFIG_MACH_DLINK_KIRKWOOD_DT=y CONFIG_MACH_DOCKSTAR_DT=y CONFIG_MACH_DREAMPLUG_DT=y @@ -50,14 +50,19 @@ CONFIG_MACH_NETSPACE_V2_DT=y CONFIG_MACH_NSA310_DT=y CONFIG_MACH_OPENBLOCKS_A6_DT=y CONFIG_MACH_READYNAS_DT=y +CONFIG_MACH_SHEEVAPLUG_DT=y CONFIG_MACH_TOPKICK_DT=y CONFIG_MACH_TS219_DT=y # CONFIG_CPU_FEROCEON_OLD_ID is not set +CONFIG_PCI_MVEBU=y CONFIG_PREEMPT=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_IDLE=y CONFIG_NET=y CONFIG_PACKET=y @@ -68,14 +73,12 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set -CONFIG_NET_DSA=y CONFIG_NET_PKTGEN=m CONFIG_CFG80211=y CONFIG_MAC80211=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y @@ -140,6 +143,7 @@ CONFIG_HID_TOPSEED=y CONFIG_HID_THRUSTMASTER=y CONFIG_HID_ZEROPLUS=y CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_PRINTER=m diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index f3e8ae0..804b1da 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -13,6 +13,8 @@ CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_XP=y # CONFIG_CACHE_L2X0 is not set # CONFIG_SWP_EMULATE is not set +CONFIG_PCI=y +CONFIG_PCI_MVEBU=y CONFIG_SMP=y CONFIG_AEABI=y CONFIG_HIGHMEM=y @@ -60,6 +62,8 @@ CONFIG_USB_SUPPORT=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_STORAGE=y +CONFIG_USB_XHCI_HCD=y CONFIG_MMC=y CONFIG_MMC_MVSDIO=y CONFIG_NEW_LEDS=y diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 05ee9ee..a5fef71 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -136,7 +136,11 @@ * assumes FIQs are enabled, and that the processor is in SVC mode. */ .macro save_and_disable_irqs, oldcpsr +#ifdef CONFIG_CPU_V7M + mrs \oldcpsr, primask +#else mrs \oldcpsr, cpsr +#endif disable_irq .endm @@ -150,7 +154,11 @@ * guarantee that this will preserve the flags. */ .macro restore_irqs_notrace, oldcpsr +#ifdef CONFIG_CPU_V7M + msr primask, \oldcpsr +#else msr cpsr_c, \oldcpsr +#endif .endm .macro restore_irqs, oldcpsr @@ -229,7 +237,14 @@ #endif .endm -#ifdef CONFIG_THUMB2_KERNEL +#if defined(CONFIG_CPU_V7M) + /* + * setmode is used to assert to be in svc mode during boot. For v7-M + * this is done in __v7m_setup, so setmode can be empty here. + */ + .macro setmode, mode, reg + .endm +#elif defined(CONFIG_THUMB2_KERNEL) .macro setmode, mode, reg mov \reg, #\mode msr cpsr_c, \reg diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h index 1f3262e..cedd372 100644 --- a/arch/arm/include/asm/cp15.h +++ b/arch/arm/include/asm/cp15.h @@ -61,6 +61,20 @@ static inline void set_cr(unsigned int val) isb(); } +static inline unsigned int get_auxcr(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 1 @ get AUXCR" : "=r" (val)); + return val; +} + +static inline void set_auxcr(unsigned int val) +{ + asm volatile("mcr p15, 0, %0, c1, c0, 1 @ set AUXCR" + : : "r" (val)); + isb(); +} + #ifndef CONFIG_SMP extern void adjust_cr(unsigned long mask, unsigned long set); #endif diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 7652712..ec635ff 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -10,6 +10,22 @@ #define CPUID_TLBTYPE 3 #define CPUID_MPIDR 5 +#ifdef CONFIG_CPU_V7M +#define CPUID_EXT_PFR0 0x40 +#define CPUID_EXT_PFR1 0x44 +#define CPUID_EXT_DFR0 0x48 +#define CPUID_EXT_AFR0 0x4c +#define CPUID_EXT_MMFR0 0x50 +#define CPUID_EXT_MMFR1 0x54 +#define CPUID_EXT_MMFR2 0x58 +#define CPUID_EXT_MMFR3 0x5c +#define CPUID_EXT_ISAR0 0x60 +#define CPUID_EXT_ISAR1 0x64 +#define CPUID_EXT_ISAR2 0x68 +#define CPUID_EXT_ISAR3 0x6c +#define CPUID_EXT_ISAR4 0x70 +#define CPUID_EXT_ISAR5 0x74 +#else #define CPUID_EXT_PFR0 "c1, 0" #define CPUID_EXT_PFR1 "c1, 1" #define CPUID_EXT_DFR0 "c1, 2" @@ -24,6 +40,7 @@ #define CPUID_EXT_ISAR3 "c2, 3" #define CPUID_EXT_ISAR4 "c2, 4" #define CPUID_EXT_ISAR5 "c2, 5" +#endif #define MPIDR_SMP_BITMASK (0x3 << 30) #define MPIDR_SMP_VALUE (0x2 << 30) @@ -79,7 +96,23 @@ extern unsigned int processor_id; __val; \ }) -#else /* ifdef CONFIG_CPU_CP15 */ +#elif defined(CONFIG_CPU_V7M) + +#include <asm/io.h> +#include <asm/v7m.h> + +#define read_cpuid(reg) \ + ({ \ + WARN_ON_ONCE(1); \ + 0; \ + }) + +static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset) +{ + return readl(BASEADDR_V7M_SCB + offset); +} + +#else /* ifdef CONFIG_CPU_CP15 / elif defined (CONFIG_CPU_V7M) */ /* * read_cpuid and read_cpuid_ext should only ever be called on machines that @@ -106,7 +139,14 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void) return read_cpuid(CPUID_ID); } -#else /* ifdef CONFIG_CPU_CP15 */ +#elif defined(CONFIG_CPU_V7M) + +static inline unsigned int __attribute_const__ read_cpuid_id(void) +{ + return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID); +} + +#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */ static inline unsigned int __attribute_const__ read_cpuid_id(void) { diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index ea289e1..c81adc0 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h @@ -117,10 +117,37 @@ # endif #endif +#if defined(CONFIG_CPU_V7M) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE nop +# endif +#endif + #if !defined(_CACHE) && !defined(MULTI_CACHE) #error Unknown cache maintenance model #endif +#ifndef __ASSEMBLER__ +extern inline void nop_flush_icache_all(void) { } +extern inline void nop_flush_kern_cache_all(void) { } +extern inline void nop_flush_kern_cache_louis(void) { } +extern inline void nop_flush_user_cache_all(void) { } +extern inline void nop_flush_user_cache_range(unsigned long a, + unsigned long b, unsigned int c) { } + +extern inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { } +extern inline int nop_coherent_user_range(unsigned long a, + unsigned long b) { return 0; } +extern inline void nop_flush_kern_dcache_area(void *a, size_t s) { } + +extern inline void nop_dma_flush_range(const void *a, const void *b) { } + +extern inline void nop_dma_map_area(const void *s, size_t l, int f) { } +extern inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } +#endif + #ifndef MULTI_CACHE #define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all) #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h index b6e9f2c..6b70f1b 100644 --- a/arch/arm/include/asm/glue-df.h +++ b/arch/arm/include/asm/glue-df.h @@ -95,6 +95,14 @@ # endif #endif +#ifdef CONFIG_CPU_ABRT_NOMMU +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER nommu_early_abort +# endif +#endif + #ifndef CPU_DABORT_HANDLER #error Unknown data abort handler type #endif diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h index ac1dd54..f2f39bc 100644 --- a/arch/arm/include/asm/glue-proc.h +++ b/arch/arm/include/asm/glue-proc.h @@ -230,6 +230,15 @@ # endif #endif +#ifdef CONFIG_CPU_V7M +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_v7m +# endif +#endif + #ifndef MULTI_CPU #define cpu_proc_init __glue(CPU_NAME,_proc_init) #define cpu_proc_fin __glue(CPU_NAME,_proc_fin) diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h index 1e6cca5..3b763d6 100644 --- a/arch/arm/include/asm/irqflags.h +++ b/arch/arm/include/asm/irqflags.h @@ -8,6 +8,16 @@ /* * CPU interrupt mask handling. */ +#ifdef CONFIG_CPU_V7M +#define IRQMASK_REG_NAME_R "primask" +#define IRQMASK_REG_NAME_W "primask" +#define IRQMASK_I_BIT 1 +#else +#define IRQMASK_REG_NAME_R "cpsr" +#define IRQMASK_REG_NAME_W "cpsr_c" +#define IRQMASK_I_BIT PSR_I_BIT +#endif + #if __LINUX_ARM_ARCH__ >= 6 static inline unsigned long arch_local_irq_save(void) @@ -15,7 +25,7 @@ static inline unsigned long arch_local_irq_save(void) unsigned long flags; asm volatile( - " mrs %0, cpsr @ arch_local_irq_save\n" + " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n" " cpsid i" : "=r" (flags) : : "memory", "cc"); return flags; @@ -129,7 +139,7 @@ static inline unsigned long arch_local_save_flags(void) { unsigned long flags; asm volatile( - " mrs %0, cpsr @ local_save_flags" + " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags" : "=r" (flags) : : "memory", "cc"); return flags; } @@ -140,7 +150,7 @@ static inline unsigned long arch_local_save_flags(void) static inline void arch_local_irq_restore(unsigned long flags) { asm volatile( - " msr cpsr_c, %0 @ local_irq_restore" + " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" : : "r" (flags) : "memory", "cc"); @@ -148,8 +158,8 @@ static inline void arch_local_irq_restore(unsigned long flags) static inline int arch_irqs_disabled_flags(unsigned long flags) { - return flags & PSR_I_BIT; + return flags & IRQMASK_I_BIT; } -#endif -#endif +#endif /* ifdef __KERNEL__ */ +#endif /* ifndef __ASM_ARM_IRQFLAGS_H */ diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 308ad7d..75bf079 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -8,6 +8,8 @@ * published by the Free Software Foundation. */ +#include <linux/types.h> + #ifndef __ASSEMBLY__ struct tag; @@ -16,8 +18,10 @@ struct pt_regs; struct smp_operations; #ifdef CONFIG_SMP #define smp_ops(ops) (&(ops)) +#define smp_init_ops(ops) (&(ops)) #else #define smp_ops(ops) (struct smp_operations *)NULL +#define smp_init_ops(ops) (bool (*)(void))NULL #endif struct machine_desc { @@ -41,6 +45,7 @@ struct machine_desc { unsigned char reserve_lp2 :1; /* never has lp2 */ char restart_mode; /* default restart mode */ struct smp_operations *smp; /* SMP operations */ + bool (*smp_init)(void); void (*fixup)(struct tag *, char **, struct meminfo *); void (*reserve)(void);/* reserve mem blocks */ diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index ce0dbe7..c4ae171 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -32,5 +32,14 @@ struct psci_operations { }; extern struct psci_operations psci_ops; +extern struct smp_operations psci_smp_ops; + +#ifdef CONFIG_ARM_PSCI +void psci_init(void); +bool psci_smp_available(void); +#else +static inline void psci_init(void) { } +static inline bool psci_smp_available(void) { return false; } +#endif #endif /* __ASM_ARM_PSCI_H */ diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 3d52ee1..04c99f3 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -45,6 +45,7 @@ struct pt_regs { */ static inline int valid_user_regs(struct pt_regs *regs) { +#ifndef CONFIG_CPU_V7M unsigned long mode = regs->ARM_cpsr & MODE_MASK; /* @@ -67,6 +68,9 @@ static inline int valid_user_regs(struct pt_regs *regs) regs->ARM_cpsr |= USR_MODE; return 0; +#else /* ifndef CONFIG_CPU_V7M */ + return 1; +#endif } static inline long regs_return_value(struct pt_regs *regs) diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h index dfd386d..720ea03 100644 --- a/arch/arm/include/asm/system_info.h +++ b/arch/arm/include/asm/system_info.h @@ -11,6 +11,7 @@ #define CPU_ARCH_ARMv5TEJ 7 #define CPU_ARCH_ARMv6 8 #define CPU_ARCH_ARMv7 9 +#define CPU_ARCH_ARMv7M 10 #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h new file mode 100644 index 0000000..fa88d09 --- /dev/null +++ b/arch/arm/include/asm/v7m.h @@ -0,0 +1,44 @@ +/* + * Common defines for v7m cpus + */ +#define V7M_SCS_ICTR IOMEM(0xe000e004) +#define V7M_SCS_ICTR_INTLINESNUM_MASK 0x0000000f + +#define BASEADDR_V7M_SCB IOMEM(0xe000ed00) + +#define V7M_SCB_CPUID 0x00 + +#define V7M_SCB_ICSR 0x04 +#define V7M_SCB_ICSR_PENDSVSET (1 << 28) +#define V7M_SCB_ICSR_PENDSVCLR (1 << 27) +#define V7M_SCB_ICSR_RETTOBASE (1 << 11) + +#define V7M_SCB_VTOR 0x08 + +#define V7M_SCB_SCR 0x10 +#define V7M_SCB_SCR_SLEEPDEEP (1 << 2) + +#define V7M_SCB_CCR 0x14 +#define V7M_SCB_CCR_STKALIGN (1 << 9) + +#define V7M_SCB_SHPR2 0x1c +#define V7M_SCB_SHPR3 0x20 + +#define V7M_SCB_SHCSR 0x24 +#define V7M_SCB_SHCSR_USGFAULTENA (1 << 18) +#define V7M_SCB_SHCSR_BUSFAULTENA (1 << 17) +#define V7M_SCB_SHCSR_MEMFAULTENA (1 << 16) + +#define V7M_xPSR_FRAMEPTRALIGN 0x00000200 +#define V7M_xPSR_EXCEPTIONNO 0x000001ff + +/* + * When branching to an address that has bits [31:28] == 0xf an exception return + * occurs. Bits [27:5] are reserved (SBOP). If the processor implements the FP + * extension Bit [4] defines if the exception frame has space allocated for FP + * state information, SBOP otherwise. Bit [3] defines the mode that is returned + * to (0 -> handler mode; 1 -> thread mode). Bit [2] defines which sp is used + * (0 -> msp; 1 -> psp). Bits [1:0] are fixed to 0b01. + */ +#define EXC_RET_STACK_MASK 0x00000004 +#define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h index 96ee092..5af0ed1 100644 --- a/arch/arm/include/uapi/asm/ptrace.h +++ b/arch/arm/include/uapi/asm/ptrace.h @@ -34,28 +34,47 @@ /* * PSR bits + * Note on V7M there is no mode contained in the PSR */ #define USR26_MODE 0x00000000 #define FIQ26_MODE 0x00000001 #define IRQ26_MODE 0x00000002 #define SVC26_MODE 0x00000003 +#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M) +/* + * Use 0 here to get code right that creates a userspace + * or kernel space thread. + */ +#define USR_MODE 0x00000000 +#define SVC_MODE 0x00000000 +#else #define USR_MODE 0x00000010 +#define SVC_MODE 0x00000013 +#endif #define FIQ_MODE 0x00000011 #define IRQ_MODE 0x00000012 -#define SVC_MODE 0x00000013 #define ABT_MODE 0x00000017 #define HYP_MODE 0x0000001a #define UND_MODE 0x0000001b #define SYSTEM_MODE 0x0000001f #define MODE32_BIT 0x00000010 #define MODE_MASK 0x0000001f -#define PSR_T_BIT 0x00000020 -#define PSR_F_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_A_BIT 0x00000100 -#define PSR_E_BIT 0x00000200 -#define PSR_J_BIT 0x01000000 -#define PSR_Q_BIT 0x08000000 + +#define V4_PSR_T_BIT 0x00000020 /* >= V4T, but not V7M */ +#define V7M_PSR_T_BIT 0x01000000 +#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M) +#define PSR_T_BIT V7M_PSR_T_BIT +#else +/* for compatibility */ +#define PSR_T_BIT V4_PSR_T_BIT +#endif + +#define PSR_F_BIT 0x00000040 /* >= V4, but not V7M */ +#define PSR_I_BIT 0x00000080 /* >= V4, but not V7M */ +#define PSR_A_BIT 0x00000100 /* >= V6, but not V7M */ +#define PSR_E_BIT 0x00000200 /* >= V6, but not V7M */ +#define PSR_J_BIT 0x01000000 /* >= V5J, but not V7M */ +#define PSR_Q_BIT 0x08000000 /* >= V5E, including V7M */ #define PSR_V_BIT 0x10000000 #define PSR_C_BIT 0x20000000 #define PSR_Z_BIT 0x40000000 diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5f3338e..f4285b5 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,7 +15,7 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ +obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o sched_clock.o \ setup.o signal.o stacktrace.o sys_arm.o time.o traps.o @@ -23,6 +23,12 @@ obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o +ifeq ($(CONFIG_CPU_V7M),y) +obj-y += entry-v7m.o +else +obj-y += entry-armv.o +endif + obj-$(CONFIG_OC_ETM) += etm.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ISA_DMA_API) += dma.o @@ -82,6 +88,9 @@ obj-$(CONFIG_DEBUG_LL) += debug.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o -obj-$(CONFIG_ARM_PSCI) += psci.o +ifeq ($(CONFIG_ARM_PSCI),y) +obj-y += psci.o +obj-$(CONFIG_SMP) += psci_smp.o +endif extra-y := $(head-y) vmlinux.lds diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index bc5bc0a..85a72b0 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -350,6 +350,9 @@ ENDPROC(ftrace_stub) .align 5 ENTRY(vector_swi) +#ifdef CONFIG_CPU_V7M + v7m_exception_entry +#else sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0 - r12 ARM( add r8, sp, #S_PC ) @@ -360,6 +363,7 @@ ENTRY(vector_swi) str lr, [sp, #S_PC] @ Save calling PC str r8, [sp, #S_PSR] @ Save CPSR str r0, [sp, #S_OLD_R0] @ Save OLD_R0 +#endif zero_fp /* diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 160f337..de23a9b 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -5,6 +5,7 @@ #include <asm/asm-offsets.h> #include <asm/errno.h> #include <asm/thread_info.h> +#include <asm/v7m.h> @ Bad Abort numbers @ ----------------- @@ -44,6 +45,116 @@ #endif .endm +#ifdef CONFIG_CPU_V7M +/* + * ARMv7-M exception entry/exit macros. + * + * xPSR, ReturnAddress(), LR (R14), R12, R3, R2, R1, and R0 are + * automatically saved on the current stack (32 words) before + * switching to the exception stack (SP_main). + * + * If exception is taken while in user mode, SP_main is + * empty. Otherwise, SP_main is aligned to 64 bit automatically + * (CCR.STKALIGN set). + * + * Linux assumes that the interrupts are disabled when entering an + * exception handler and it may BUG if this is not the case. Interrupts + * are disabled during entry and reenabled in the exit macro. + * + * v7m_exception_slow_exit is used when returning from SVC or PendSV. + * When returning to kernel mode, we don't return from exception. + */ + .macro v7m_exception_entry + @ determine the location of the registers saved by the core during + @ exception entry. Depending on the mode the cpu was in when the + @ exception happend that is either on the main or the process stack. + @ Bit 2 of EXC_RETURN stored in the lr register specifies which stack + @ was used. + tst lr, #EXC_RET_STACK_MASK + mrsne r12, psp + moveq r12, sp + + @ we cannot rely on r0-r3 and r12 matching the value saved in the + @ exception frame because of tail-chaining. So these have to be + @ reloaded. + ldmia r12!, {r0-r3} + + @ Linux expects to have irqs off. Do it here before taking stack space + cpsid i + + sub sp, #S_FRAME_SIZE-S_IP + stmdb sp!, {r0-r11} + + @ load saved r12, lr, return address and xPSR. + @ r0-r7 are used for signals and never touched from now on. Clobbering + @ r8-r12 is OK. + mov r9, r12 + ldmia r9!, {r8, r10-r12} + + @ calculate the original stack pointer value. + @ r9 currently points to the memory location just above the auto saved + @ xPSR. + @ The cpu might automatically 8-byte align the stack. Bit 9 + @ of the saved xPSR specifies if stack aligning took place. In this case + @ another 32-bit value is included in the stack. + + tst r12, V7M_xPSR_FRAMEPTRALIGN + addne r9, r9, #4 + + @ store saved r12 using str to have a register to hold the base for stm + str r8, [sp, #S_IP] + add r8, sp, #S_SP + @ store r13-r15, xPSR + stmia r8!, {r9-r12} + @ store old_r0 + str r0, [r8] + .endm + + /* + * PENDSV and SVCALL are configured to have the same exception + * priorities. As a kernel thread runs at SVCALL execution priority it + * can never be preempted and so we will never have to return to a + * kernel thread here. + */ + .macro v7m_exception_slow_exit ret_r0 + cpsid i + ldr lr, =EXC_RET_THREADMODE_PROCESSSTACK + + @ read original r12, sp, lr, pc and xPSR + add r12, sp, #S_IP + ldmia r12, {r1-r5} + + @ an exception frame is always 8-byte aligned. To tell the hardware if + @ the sp to be restored is aligned or not set bit 9 of the saved xPSR + @ accordingly. + tst r2, #4 + subne r2, r2, #4 + orrne r5, V7M_xPSR_FRAMEPTRALIGN + biceq r5, V7M_xPSR_FRAMEPTRALIGN + + @ write basic exception frame + stmdb r2!, {r1, r3-r5} + ldmia sp, {r1, r3-r5} + .if \ret_r0 + stmdb r2!, {r0, r3-r5} + .else + stmdb r2!, {r1, r3-r5} + .endif + + @ restore process sp + msr psp, r2 + + @ restore original r4-r11 + ldmia sp!, {r0-r11} + + @ restore main sp + add sp, sp, #S_FRAME_SIZE-S_IP + + cpsie i + bx lr + .endm +#endif /* CONFIG_CPU_V7M */ + @ @ Store/load the USER SP and LR registers by switching to the SYS @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not @@ -165,6 +276,18 @@ rfeia sp! .endm +#ifdef CONFIG_CPU_V7M + /* + * Note we don't need to do clrex here as clearing the local monitor is + * part of each exception entry and exit sequence. + */ + .macro restore_user_regs, fast = 0, offset = 0 + .if \offset + add sp, #\offset + .endif + v7m_exception_slow_exit ret_r0 = \fast + .endm +#else /* ifdef CONFIG_CPU_V7M */ .macro restore_user_regs, fast = 0, offset = 0 clrex @ clear the exclusive monitor mov r2, sp @@ -181,6 +304,7 @@ add sp, sp, #S_FRAME_SIZE - S_SP movs pc, lr @ return & move spsr_svc into cpsr .endm +#endif /* ifdef CONFIG_CPU_V7M / else */ .macro get_thread_info, rd mov \rd, sp diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S new file mode 100644 index 0000000..e00621f --- /dev/null +++ b/arch/arm/kernel/entry-v7m.S @@ -0,0 +1,143 @@ +/* + * linux/arch/arm/kernel/entry-v7m.S + * + * Copyright (C) 2008 ARM Ltd. + * + * 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. + * + * Low-level vector interface routines for the ARMv7-M architecture + */ +#include <asm/memory.h> +#include <asm/glue.h> +#include <asm/thread_notify.h> +#include <asm/v7m.h> + +#include <mach/entry-macro.S> + +#include "entry-header.S" + +#ifdef CONFIG_TRACE_IRQFLAGS +#error "CONFIG_TRACE_IRQFLAGS not supported on the current ARMv7M implementation" +#endif + +__invalid_entry: + v7m_exception_entry + adr r0, strerr + mrs r1, ipsr + mov r2, lr + bl printk + mov r0, sp + bl show_regs +1: b 1b +ENDPROC(__invalid_entry) + +strerr: .asciz "\nUnhandled exception: IPSR = %08lx LR = %08lx\n" + + .align 2 +__irq_entry: + v7m_exception_entry + + @ + @ Invoke the IRQ handler + @ + mrs r0, ipsr + ldr r1, =V7M_xPSR_EXCEPTIONNO + and r0, r1 + sub r0, #16 + mov r1, sp + stmdb sp!, {lr} + @ routine called with r0 = irq number, r1 = struct pt_regs * + bl nvic_do_IRQ + + pop {lr} + @ + @ Check for any pending work if returning to user + @ + ldr r1, =BASEADDR_V7M_SCB + ldr r0, [r1, V7M_SCB_ICSR] + tst r0, V7M_SCB_ICSR_RETTOBASE + beq 2f + + get_thread_info tsk + ldr r2, [tsk, #TI_FLAGS] + tst r2, #_TIF_WORK_MASK + beq 2f @ no work pending + mov r0, #V7M_SCB_ICSR_PENDSVSET + str r0, [r1, V7M_SCB_ICSR] @ raise PendSV + +2: + @ registers r0-r3 and r12 are automatically restored on exception + @ return. r4-r7 were not clobbered in v7m_exception_entry so for + @ correctness they don't need to be restored. So only r8-r11 must be + @ restored here. The easiest way to do so is to restore r0-r7, too. + ldmia sp!, {r0-r11} + add sp, #S_FRAME_SIZE-S_IP + cpsie i + bx lr +ENDPROC(__irq_entry) + +__pendsv_entry: + v7m_exception_entry + + ldr r1, =BASEADDR_V7M_SCB + mov r0, #V7M_SCB_ICSR_PENDSVCLR + str r0, [r1, V7M_SCB_ICSR] @ clear PendSV + + @ execute the pending work, including reschedule + get_thread_info tsk + mov why, #0 + b ret_to_user +ENDPROC(__pendsv_entry) + +/* + * Register switch for ARMv7-M processors. + * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info + * previous and next are guaranteed not to be the same. + */ +ENTRY(__switch_to) + .fnstart + .cantunwind + add ip, r1, #TI_CPU_SAVE + stmia ip!, {r4 - r11} @ Store most regs on stack + str sp, [ip], #4 + str lr, [ip], #4 + mov r5, r0 + add r4, r2, #TI_CPU_SAVE + ldr r0, =thread_notify_head + mov r1, #THREAD_NOTIFY_SWITCH + bl atomic_notifier_call_chain + mov ip, r4 + mov r0, r5 + ldmia ip!, {r4 - r11} @ Load all regs saved previously + ldr sp, [ip] + ldr pc, [ip, #4]! + .fnend +ENDPROC(__switch_to) + + .data + .align 8 +/* + * Vector table (64 words => 256 bytes natural alignment) + */ +ENTRY(vector_table) + .long 0 @ 0 - Reset stack pointer + .long __invalid_entry @ 1 - Reset + .long __invalid_entry @ 2 - NMI + .long __invalid_entry @ 3 - HardFault + .long __invalid_entry @ 4 - MemManage + .long __invalid_entry @ 5 - BusFault + .long __invalid_entry @ 6 - UsageFault + .long __invalid_entry @ 7 - Reserved + .long __invalid_entry @ 8 - Reserved + .long __invalid_entry @ 9 - Reserved + .long __invalid_entry @ 10 - Reserved + .long vector_swi @ 11 - SVCall + .long __invalid_entry @ 12 - Debug Monitor + .long __invalid_entry @ 13 - Reserved + .long __pendsv_entry @ 14 - PendSV + .long __invalid_entry @ 15 - SysTick + .rept 64 - 16 + .long __irq_entry @ 16..64 - External Interrupts + .endr diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 6a2e09c..8812ce8 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -19,6 +19,7 @@ #include <asm/asm-offsets.h> #include <asm/cp15.h> #include <asm/thread_info.h> +#include <asm/v7m.h> /* * Kernel startup entry point. @@ -50,10 +51,13 @@ ENTRY(stext) setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode @ and irqs disabled -#ifndef CONFIG_CPU_CP15 - ldr r9, =CONFIG_PROCESSOR_ID -#else +#if defined(CONFIG_CPU_CP15) mrc p15, 0, r9, c0, c0 @ get processor id +#elif defined(CONFIG_CPU_V7M) + ldr r9, =BASEADDR_V7M_SCB + ldr r9, [r9, V7M_SCB_CPUID] +#else + ldr r9, =CONFIG_PROCESSOR_ID #endif bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c index 3653164..4693188 100644 --- a/arch/arm/kernel/psci.c +++ b/arch/arm/kernel/psci.c @@ -158,7 +158,7 @@ static const struct of_device_id psci_of_match[] __initconst = { {}, }; -static int __init psci_init(void) +void __init psci_init(void) { struct device_node *np; const char *method; @@ -166,7 +166,7 @@ static int __init psci_init(void) np = of_find_matching_node(NULL, psci_of_match); if (!np) - return 0; + return; pr_info("probing function IDs from device-tree\n"); @@ -206,6 +206,5 @@ static int __init psci_init(void) out_put_node: of_node_put(np); - return 0; + return; } -early_initcall(psci_init); diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c new file mode 100644 index 0000000..23a1142 --- /dev/null +++ b/arch/arm/kernel/psci_smp.c @@ -0,0 +1,84 @@ +/* + * 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. + * + * Copyright (C) 2012 ARM Limited + * + * Author: Will Deacon <will.deacon@arm.com> + */ + +#include <linux/init.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/smp.h> +#include <linux/of.h> + +#include <asm/psci.h> +#include <asm/smp_plat.h> + +/* + * psci_smp assumes that the following is true about PSCI: + * + * cpu_suspend Suspend the execution on a CPU + * @state we don't currently describe affinity levels, so just pass 0. + * @entry_point the first instruction to be executed on return + * returns 0 success, < 0 on failure + * + * cpu_off Power down a CPU + * @state we don't currently describe affinity levels, so just pass 0. + * no return on successful call + * + * cpu_on Power up a CPU + * @cpuid cpuid of target CPU, as from MPIDR + * @entry_point the first instruction to be executed on return + * returns 0 success, < 0 on failure + * + * migrate Migrate the context to a different CPU + * @cpuid cpuid of target CPU, as from MPIDR + * returns 0 success, < 0 on failure + * + */ + +extern void secondary_startup(void); + +static int __cpuinit psci_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + if (psci_ops.cpu_on) + return psci_ops.cpu_on(cpu_logical_map(cpu), + __pa(secondary_startup)); + return -ENODEV; +} + +#ifdef CONFIG_HOTPLUG_CPU +void __ref psci_cpu_die(unsigned int cpu) +{ + const struct psci_power_state ps = { + .type = PSCI_POWER_STATE_TYPE_POWER_DOWN, + }; + + if (psci_ops.cpu_off) + psci_ops.cpu_off(ps); + + /* We should never return */ + panic("psci: cpu %d failed to shutdown\n", cpu); +} +#else +#define psci_cpu_die NULL +#endif + +bool __init psci_smp_available(void) +{ + /* is cpu_on available at least? */ + return (psci_ops.cpu_on != NULL); +} + +struct smp_operations __initdata psci_smp_ops = { + .smp_boot_secondary = psci_boot_secondary, + .cpu_die = psci_cpu_die, +}; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 1522c7a..a1a2fba 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -37,6 +37,7 @@ #include <asm/cputype.h> #include <asm/elf.h> #include <asm/procinfo.h> +#include <asm/psci.h> #include <asm/sections.h> #include <asm/setup.h> #include <asm/smp_plat.h> @@ -128,7 +129,9 @@ struct stack { u32 und[3]; } ____cacheline_aligned; +#ifndef CONFIG_CPU_V7M static struct stack stacks[NR_CPUS]; +#endif char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); @@ -207,7 +210,7 @@ static const char *proc_arch[] = { "5TEJ", "6TEJ", "7", - "?(11)", + "7M", "?(12)", "?(13)", "?(14)", @@ -216,6 +219,12 @@ static const char *proc_arch[] = { "?(17)", }; +#ifdef CONFIG_CPU_V7M +static int __get_cpu_architecture(void) +{ + return CPU_ARCH_ARMv7M; +} +#else static int __get_cpu_architecture(void) { int cpu_arch; @@ -248,6 +257,7 @@ static int __get_cpu_architecture(void) return cpu_arch; } +#endif int __pure cpu_architecture(void) { @@ -293,7 +303,9 @@ static void __init cacheid_init(void) { unsigned int arch = cpu_architecture(); - if (arch >= CPU_ARCH_ARMv6) { + if (arch == CPU_ARCH_ARMv7M) { + cacheid = 0; + } else if (arch >= CPU_ARCH_ARMv6) { unsigned int cachetype = read_cpuid_cachetype(); if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ @@ -392,6 +404,7 @@ static void __init feat_v6_fixup(void) */ void notrace cpu_init(void) { +#ifndef CONFIG_CPU_V7M unsigned int cpu = smp_processor_id(); struct stack *stk = &stacks[cpu]; @@ -442,6 +455,7 @@ void notrace cpu_init(void) "I" (offsetof(struct stack, und[0])), PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14"); +#endif } int __cpu_logical_map[NR_CPUS]; @@ -796,9 +810,15 @@ void __init setup_arch(char **cmdline_p) unflatten_device_tree(); arm_dt_init_cpu_maps(); + psci_init(); #ifdef CONFIG_SMP if (is_smp()) { - smp_set_ops(mdesc->smp); + if (!mdesc->smp_init || !mdesc->smp_init()) { + if (psci_smp_available()) + smp_set_ops(&psci_smp_ops); + else if (mdesc->smp) + smp_set_ops(mdesc->smp); + } smp_init_cpus(); } #endif diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 18b32e8..486e12a 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -812,6 +812,7 @@ static void __init kuser_get_tls_init(unsigned long vectors) void __init early_trap_init(void *vectors_base) { +#ifndef CONFIG_CPU_V7M unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; @@ -843,4 +844,11 @@ void __init early_trap_init(void *vectors_base) flush_icache_range(vectors, vectors + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); +#else /* ifndef CONFIG_CPU_V7M */ + /* + * on V7-M there is no need to copy the vector table to a dedicated + * memory area. The address is configurable and so a table in the kernel + * image can be used. + */ +#endif } diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 2d00165..01ad4d4 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -22,8 +22,7 @@ config ARCH_CLEP7312 config ARCH_EDB7211 bool "EDB7211" - select ARCH_SELECT_MEMORY_MODEL - select ARCH_SPARSEMEM_ENABLE + select ARCH_HAS_HOLES_MEMORYMODEL help Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 evaluation board. diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile index 992995a..f30ed2b 100644 --- a/arch/arm/mach-clps711x/Makefile +++ b/arch/arm/mach-clps711x/Makefile @@ -4,10 +4,7 @@ # Object file lists. -obj-y := common.o -obj-m := -obj-n := -obj- := +obj-y := common.o devices.o obj-$(CONFIG_ARCH_AUTCPU12) += board-autcpu12.o obj-$(CONFIG_ARCH_CDB89712) += board-cdb89712.o diff --git a/arch/arm/mach-clps711x/board-autcpu12.c b/arch/arm/mach-clps711x/board-autcpu12.c index f385847..5867aeb 100644 --- a/arch/arm/mach-clps711x/board-autcpu12.c +++ b/arch/arm/mach-clps711x/board-autcpu12.c @@ -26,6 +26,8 @@ #include <linux/gpio.h> #include <linux/ioport.h> #include <linux/interrupt.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/plat-ram.h> #include <linux/mtd/partitions.h> #include <linux/mtd/nand-gpio.h> #include <linux/platform_device.h> @@ -40,38 +42,49 @@ #include <asm/page.h> #include <asm/mach/map.h> -#include <mach/autcpu12.h> #include "common.h" +#include "devices.h" -#define AUTCPU12_CS8900_BASE (CS2_PHYS_BASE + 0x300) -#define AUTCPU12_CS8900_IRQ (IRQ_EINT3) +/* NOR flash */ +#define AUTCPU12_FLASH_BASE (CS0_PHYS_BASE) + +/* Board specific hardware definitions */ +#define AUTCPU12_CHAR_LCD_BASE (CS1_PHYS_BASE + 0x00000000) +#define AUTCPU12_CSAUX1_BASE (CS1_PHYS_BASE + 0x04000000) +#define AUTCPU12_CAN_BASE (CS1_PHYS_BASE + 0x08000000) +#define AUTCPU12_TOUCH_BASE (CS1_PHYS_BASE + 0x0a000000) +#define AUTCPU12_IO_BASE (CS1_PHYS_BASE + 0x0c000000) +#define AUTCPU12_LPT_BASE (CS1_PHYS_BASE + 0x0e000000) + +/* NVRAM */ +#define AUTCPU12_NVRAM_BASE (CS1_PHYS_BASE + 0x02000000) +/* SmartMedia flash */ #define AUTCPU12_SMC_BASE (CS1_PHYS_BASE + 0x06000000) #define AUTCPU12_SMC_SEL_BASE (AUTCPU12_SMC_BASE + 0x10) +/* Ethernet */ +#define AUTCPU12_CS8900_BASE (CS2_PHYS_BASE + 0x300) +#define AUTCPU12_CS8900_IRQ (IRQ_EINT3) + +/* NAND flash */ #define AUTCPU12_MMGPIO_BASE (CLPS711X_NR_GPIO) #define AUTCPU12_SMC_NCE (AUTCPU12_MMGPIO_BASE + 0) /* Bit 0 */ #define AUTCPU12_SMC_RDY CLPS711X_GPIO(1, 2) #define AUTCPU12_SMC_ALE CLPS711X_GPIO(1, 3) #define AUTCPU12_SMC_CLE CLPS711X_GPIO(1, 3) +/* LCD contrast digital potentiometer */ +#define AUTCPU12_DPOT_CS CLPS711X_GPIO(4, 0) +#define AUTCPU12_DPOT_CLK CLPS711X_GPIO(4, 1) +#define AUTCPU12_DPOT_UD CLPS711X_GPIO(4, 2) + static struct resource autcpu12_cs8900_resource[] __initdata = { DEFINE_RES_MEM(AUTCPU12_CS8900_BASE, SZ_1K), DEFINE_RES_IRQ(AUTCPU12_CS8900_IRQ), }; -static struct resource autcpu12_nvram_resource[] __initdata = { - DEFINE_RES_MEM_NAMED(AUTCPU12_PHYS_NVRAM, SZ_128K, "SRAM"), -}; - -static struct platform_device autcpu12_nvram_pdev __initdata = { - .name = "autcpu12_nvram", - .id = -1, - .resource = autcpu12_nvram_resource, - .num_resources = ARRAY_SIZE(autcpu12_nvram_resource), -}; - static struct resource autcpu12_nand_resource[] __initdata = { DEFINE_RES_MEM(AUTCPU12_SMC_BASE, SZ_16), }; @@ -147,17 +160,106 @@ static struct platform_device autcpu12_mmgpio_pdev __initdata = { }, }; +static const struct gpio autcpu12_gpios[] __initconst = { + { AUTCPU12_DPOT_CS, GPIOF_OUT_INIT_HIGH, "DPOT CS" }, + { AUTCPU12_DPOT_CLK, GPIOF_OUT_INIT_LOW, "DPOT CLK" }, + { AUTCPU12_DPOT_UD, GPIOF_OUT_INIT_LOW, "DPOT UD" }, +}; + +static struct mtd_partition autcpu12_flash_partitions[] = { + { + .name = "NOR.0", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data autcpu12_flash_pdata = { + .width = 4, + .parts = autcpu12_flash_partitions, + .nr_parts = ARRAY_SIZE(autcpu12_flash_partitions), +}; + +static struct resource autcpu12_flash_resources[] __initdata = { + DEFINE_RES_MEM(AUTCPU12_FLASH_BASE, SZ_8M), +}; + +static struct platform_device autcpu12_flash_pdev __initdata = { + .name = "physmap-flash", + .id = 0, + .resource = autcpu12_flash_resources, + .num_resources = ARRAY_SIZE(autcpu12_flash_resources), + .dev = { + .platform_data = &autcpu12_flash_pdata, + }, +}; + +static struct resource autcpu12_nvram_resource[] __initdata = { + DEFINE_RES_MEM(AUTCPU12_NVRAM_BASE, 0), +}; + +static struct platdata_mtd_ram autcpu12_nvram_pdata = { + .bankwidth = 4, +}; + +static struct platform_device autcpu12_nvram_pdev __initdata = { + .name = "mtd-ram", + .id = 0, + .resource = autcpu12_nvram_resource, + .num_resources = ARRAY_SIZE(autcpu12_nvram_resource), + .dev = { + .platform_data = &autcpu12_nvram_pdata, + }, +}; + +static void __init autcpu12_nvram_init(void) +{ + void __iomem *nvram; + unsigned int save[2]; + resource_size_t nvram_size = SZ_128K; + + /* + * Check for 32K/128K + * Read ofs 0K + * Read ofs 64K + * Write complement to ofs 64K + * Read and check result on ofs 0K + * Restore contents + */ + nvram = ioremap(autcpu12_nvram_resource[0].start, SZ_128K); + if (nvram) { + save[0] = readl(nvram + 0); + save[1] = readl(nvram + SZ_64K); + writel(~save[0], nvram + SZ_64K); + if (readl(nvram + 0) != save[0]) { + writel(save[0], nvram + 0); + nvram_size = SZ_32K; + } else + writel(save[1], nvram + SZ_64K); + iounmap(nvram); + + autcpu12_nvram_resource[0].end = + autcpu12_nvram_resource[0].start + nvram_size - 1; + platform_device_register(&autcpu12_nvram_pdev); + } else + pr_err("Failed to remap NVRAM resource\n"); +} + static void __init autcpu12_init(void) { + clps711x_devices_init(); + platform_device_register(&autcpu12_flash_pdev); platform_device_register_simple("video-clps711x", 0, NULL, 0); platform_device_register_simple("cs89x0", 0, autcpu12_cs8900_resource, ARRAY_SIZE(autcpu12_cs8900_resource)); platform_device_register(&autcpu12_mmgpio_pdev); - platform_device_register(&autcpu12_nvram_pdev); + autcpu12_nvram_init(); } static void __init autcpu12_init_late(void) { + gpio_request_array(autcpu12_gpios, ARRAY_SIZE(autcpu12_gpios)); + if (IS_ENABLED(MTD_NAND_GPIO) && IS_ENABLED(GPIO_GENERIC_PLATFORM)) { /* We are need both drivers to handle NAND */ platform_device_register(&autcpu12_nand_pdev); @@ -169,6 +271,7 @@ MACHINE_START(AUTCPU12, "autronix autcpu12") .atag_offset = 0x20000, .nr_irqs = CLPS711X_NR_IRQS, .map_io = clps711x_map_io, + .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .init_machine = autcpu12_init, diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c index baab7da..a9e38c6 100644 --- a/arch/arm/mach-clps711x/board-cdb89712.c +++ b/arch/arm/mach-clps711x/board-cdb89712.c @@ -39,6 +39,7 @@ #include <asm/mach/map.h> #include "common.h" +#include "devices.h" #define CDB89712_CS8900_BASE (CS2_PHYS_BASE + 0x300) #define CDB89712_CS8900_IRQ (IRQ_EINT3) @@ -127,6 +128,7 @@ static struct platform_device cdb89712_sram_pdev __initdata = { static void __init cdb89712_init(void) { + clps711x_devices_init(); platform_device_register(&cdb89712_flash_pdev); platform_device_register(&cdb89712_bootrom_pdev); platform_device_register(&cdb89712_sram_pdev); @@ -139,6 +141,7 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712") .atag_offset = 0x100, .nr_irqs = CLPS711X_NR_IRQS, .map_io = clps711x_map_io, + .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .init_machine = cdb89712_init, diff --git a/arch/arm/mach-clps711x/board-clep7312.c b/arch/arm/mach-clps711x/board-clep7312.c index 014aa3c..b476424 100644 --- a/arch/arm/mach-clps711x/board-clep7312.c +++ b/arch/arm/mach-clps711x/board-clep7312.c @@ -39,6 +39,7 @@ MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") .nr_irqs = CLPS711X_NR_IRQS, .fixup = fixup_clep7312, .map_io = clps711x_map_io, + .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .handle_irq = clps711x_handle_irq, diff --git a/arch/arm/mach-clps711x/board-edb7211.c b/arch/arm/mach-clps711x/board-edb7211.c index 5f928e9..9dfb990 100644 --- a/arch/arm/mach-clps711x/board-edb7211.c +++ b/arch/arm/mach-clps711x/board-edb7211.c @@ -12,6 +12,7 @@ #include <linux/delay.h> #include <linux/memblock.h> #include <linux/types.h> +#include <linux/i2c-gpio.h> #include <linux/interrupt.h> #include <linux/backlight.h> #include <linux/platform_device.h> @@ -29,6 +30,7 @@ #include <mach/hardware.h> #include "common.h" +#include "devices.h" #define VIDEORAM_SIZE SZ_128K @@ -36,11 +38,24 @@ #define EDB7211_LCDEN CLPS711X_GPIO(3, 2) #define EDB7211_LCDBL CLPS711X_GPIO(3, 3) +#define EDB7211_I2C_SDA CLPS711X_GPIO(3, 4) +#define EDB7211_I2C_SCL CLPS711X_GPIO(3, 5) + #define EDB7211_FLASH0_BASE (CS0_PHYS_BASE) #define EDB7211_FLASH1_BASE (CS1_PHYS_BASE) + #define EDB7211_CS8900_BASE (CS2_PHYS_BASE + 0x300) #define EDB7211_CS8900_IRQ (IRQ_EINT3) +/* The extra 8 lines of the keyboard matrix */ +#define EDB7211_EXTKBD_BASE (CS3_PHYS_BASE) + +static struct i2c_gpio_platform_data edb7211_i2c_pdata __initdata = { + .sda_pin = EDB7211_I2C_SDA, + .scl_pin = EDB7211_I2C_SCL, + .scl_is_output_only = 1, +}; + static struct resource edb7211_cs8900_resource[] __initdata = { DEFINE_RES_MEM(EDB7211_CS8900_BASE, SZ_1K), DEFINE_RES_IRQ(EDB7211_CS8900_IRQ), @@ -94,13 +109,14 @@ static struct plat_lcd_data edb7211_lcd_power_pdata = { static void edb7211_lcd_backlight_set_intensity(int intensity) { - gpio_set_value(EDB7211_LCDBL, intensity); + gpio_set_value(EDB7211_LCDBL, !!intensity); + clps_writel((clps_readl(PMPCON) & 0xf0ff) | (intensity << 8), PMPCON); } static struct generic_bl_info edb7211_lcd_backlight_pdata = { .name = "lcd-backlight.0", .default_intensity = 0x01, - .max_intensity = 0x01, + .max_intensity = 0x0f, .set_bl_intensity = edb7211_lcd_backlight_set_intensity, }; @@ -112,8 +128,8 @@ static struct gpio edb7211_gpios[] __initconst = { static struct map_desc edb7211_io_desc[] __initdata = { { /* Memory-mapped extra keyboard row */ - .virtual = IO_ADDRESS(EP7211_PHYS_EXTKBD), - .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD), + .virtual = IO_ADDRESS(EDB7211_EXTKBD_BASE), + .pfn = __phys_to_pfn(EDB7211_EXTKBD_BASE), .length = SZ_1M, .type = MT_DEVICE, }, @@ -151,6 +167,11 @@ fixup_edb7211(struct tag *tags, char **cmdline, struct meminfo *mi) static void __init edb7211_init(void) { + clps711x_devices_init(); +} + +static void __init edb7211_init_late(void) +{ gpio_request_array(edb7211_gpios, ARRAY_SIZE(edb7211_gpios)); platform_device_register(&edb7211_flash_pdev); @@ -163,6 +184,9 @@ static void __init edb7211_init(void) platform_device_register_simple("video-clps711x", 0, NULL, 0); platform_device_register_simple("cs89x0", 0, edb7211_cs8900_resource, ARRAY_SIZE(edb7211_cs8900_resource)); + platform_device_register_data(&platform_bus, "i2c-gpio", 0, + &edb7211_i2c_pdata, + sizeof(edb7211_i2c_pdata)); } MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") @@ -172,9 +196,11 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") .fixup = fixup_edb7211, .reserve = edb7211_reserve, .map_io = edb7211_map_io, + .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .init_machine = edb7211_init, + .init_late = edb7211_init_late, .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/board-fortunet.c b/arch/arm/mach-clps711x/board-fortunet.c index c5675ef..b1561e3 100644 --- a/arch/arm/mach-clps711x/board-fortunet.c +++ b/arch/arm/mach-clps711x/board-fortunet.c @@ -77,6 +77,7 @@ MACHINE_START(FORTUNET, "ARM-FortuNet") .nr_irqs = CLPS711X_NR_IRQS, .fixup = fortunet_fixup, .map_io = clps711x_map_io, + .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .handle_irq = clps711x_handle_irq, diff --git a/arch/arm/mach-clps711x/board-p720t.c b/arch/arm/mach-clps711x/board-p720t.c index 8d3ee67..dd81b06 100644 --- a/arch/arm/mach-clps711x/board-p720t.c +++ b/arch/arm/mach-clps711x/board-p720t.c @@ -23,10 +23,12 @@ #include <linux/string.h> #include <linux/mm.h> #include <linux/io.h> +#include <linux/gpio.h> #include <linux/slab.h> #include <linux/leds.h> #include <linux/sizes.h> #include <linux/backlight.h> +#include <linux/basic_mmio_gpio.h> #include <linux/platform_device.h> #include <linux/mtd/partitions.h> #include <linux/mtd/nand-gpio.h> @@ -38,11 +40,11 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/syspld.h> #include <video/platform_lcd.h> #include "common.h" +#include "devices.h" #define P720T_USERLED CLPS711X_GPIO(3, 0) #define P720T_NAND_CLE CLPS711X_GPIO(4, 0) @@ -51,6 +53,178 @@ #define P720T_NAND_BASE (CLPS711X_SDRAM1_BASE) +#define P720T_MMGPIO_BASE (CLPS711X_NR_GPIO) + +#define SYSPLD_PHYS_BASE IOMEM(CS1_PHYS_BASE) + +#define PLD_INT (SYSPLD_PHYS_BASE + 0x000000) +#define PLD_INT_MMGPIO_BASE (P720T_MMGPIO_BASE + 0) +#define PLD_INT_PENIRQ (PLD_INT_MMGPIO_BASE + 5) +#define PLD_INT_UCB_IRQ (PLD_INT_MMGPIO_BASE + 1) +#define PLD_INT_KBD_ATN (PLD_INT_MMGPIO_BASE + 0) /* EINT1 */ + +#define PLD_PWR (SYSPLD_PHYS_BASE + 0x000004) +#define PLD_PWR_MMGPIO_BASE (P720T_MMGPIO_BASE + 8) +#define PLD_PWR_EXT (PLD_PWR_MMGPIO_BASE + 5) +#define PLD_PWR_MODE (PLD_PWR_MMGPIO_BASE + 4) /* 1 = PWM, 0 = PFM */ +#define PLD_S4_ON (PLD_PWR_MMGPIO_BASE + 3) /* LCD bias voltage enable */ +#define PLD_S3_ON (PLD_PWR_MMGPIO_BASE + 2) /* LCD backlight enable */ +#define PLD_S2_ON (PLD_PWR_MMGPIO_BASE + 1) /* LCD 3V3 supply enable */ +#define PLD_S1_ON (PLD_PWR_MMGPIO_BASE + 0) /* LCD 3V supply enable */ + +#define PLD_KBD (SYSPLD_PHYS_BASE + 0x000008) +#define PLD_KBD_MMGPIO_BASE (P720T_MMGPIO_BASE + 16) +#define PLD_KBD_WAKE (PLD_KBD_MMGPIO_BASE + 1) +#define PLD_KBD_EN (PLD_KBD_MMGPIO_BASE + 0) + +#define PLD_SPI (SYSPLD_PHYS_BASE + 0x00000c) +#define PLD_SPI_MMGPIO_BASE (P720T_MMGPIO_BASE + 24) +#define PLD_SPI_EN (PLD_SPI_MMGPIO_BASE + 0) + +#define PLD_IO (SYSPLD_PHYS_BASE + 0x000010) +#define PLD_IO_MMGPIO_BASE (P720T_MMGPIO_BASE + 32) +#define PLD_IO_BOOTSEL (PLD_IO_MMGPIO_BASE + 6) /* Boot sel switch */ +#define PLD_IO_USER (PLD_IO_MMGPIO_BASE + 5) /* User defined switch */ +#define PLD_IO_LED3 (PLD_IO_MMGPIO_BASE + 4) +#define PLD_IO_LED2 (PLD_IO_MMGPIO_BASE + 3) +#define PLD_IO_LED1 (PLD_IO_MMGPIO_BASE + 2) +#define PLD_IO_LED0 (PLD_IO_MMGPIO_BASE + 1) +#define PLD_IO_LEDEN (PLD_IO_MMGPIO_BASE + 0) + +#define PLD_IRDA (SYSPLD_PHYS_BASE + 0x000014) +#define PLD_IRDA_MMGPIO_BASE (P720T_MMGPIO_BASE + 40) +#define PLD_IRDA_EN (PLD_IRDA_MMGPIO_BASE + 0) + +#define PLD_COM2 (SYSPLD_PHYS_BASE + 0x000018) +#define PLD_COM2_MMGPIO_BASE (P720T_MMGPIO_BASE + 48) +#define PLD_COM2_EN (PLD_COM2_MMGPIO_BASE + 0) + +#define PLD_COM1 (SYSPLD_PHYS_BASE + 0x00001c) +#define PLD_COM1_MMGPIO_BASE (P720T_MMGPIO_BASE + 56) +#define PLD_COM1_EN (PLD_COM1_MMGPIO_BASE + 0) + +#define PLD_AUD (SYSPLD_PHYS_BASE + 0x000020) +#define PLD_AUD_MMGPIO_BASE (P720T_MMGPIO_BASE + 64) +#define PLD_AUD_DIV1 (PLD_AUD_MMGPIO_BASE + 6) +#define PLD_AUD_DIV0 (PLD_AUD_MMGPIO_BASE + 5) +#define PLD_AUD_CLK_SEL1 (PLD_AUD_MMGPIO_BASE + 4) +#define PLD_AUD_CLK_SEL0 (PLD_AUD_MMGPIO_BASE + 3) +#define PLD_AUD_MIC_PWR (PLD_AUD_MMGPIO_BASE + 2) +#define PLD_AUD_MIC_GAIN (PLD_AUD_MMGPIO_BASE + 1) +#define PLD_AUD_CODEC_EN (PLD_AUD_MMGPIO_BASE + 0) + +#define PLD_CF (SYSPLD_PHYS_BASE + 0x000024) +#define PLD_CF_MMGPIO_BASE (P720T_MMGPIO_BASE + 72) +#define PLD_CF2_SLEEP (PLD_CF_MMGPIO_BASE + 5) +#define PLD_CF1_SLEEP (PLD_CF_MMGPIO_BASE + 4) +#define PLD_CF2_nPDREQ (PLD_CF_MMGPIO_BASE + 3) +#define PLD_CF1_nPDREQ (PLD_CF_MMGPIO_BASE + 2) +#define PLD_CF2_nIRQ (PLD_CF_MMGPIO_BASE + 1) +#define PLD_CF1_nIRQ (PLD_CF_MMGPIO_BASE + 0) + +#define PLD_SDC (SYSPLD_PHYS_BASE + 0x000028) +#define PLD_SDC_MMGPIO_BASE (P720T_MMGPIO_BASE + 80) +#define PLD_SDC_INT_EN (PLD_SDC_MMGPIO_BASE + 2) +#define PLD_SDC_WP (PLD_SDC_MMGPIO_BASE + 1) +#define PLD_SDC_CD (PLD_SDC_MMGPIO_BASE + 0) + +#define PLD_CODEC (SYSPLD_PHYS_BASE + 0x400000) +#define PLD_CODEC_MMGPIO_BASE (P720T_MMGPIO_BASE + 88) +#define PLD_CODEC_IRQ3 (PLD_CODEC_MMGPIO_BASE + 4) +#define PLD_CODEC_IRQ2 (PLD_CODEC_MMGPIO_BASE + 3) +#define PLD_CODEC_IRQ1 (PLD_CODEC_MMGPIO_BASE + 2) +#define PLD_CODEC_EN (PLD_CODEC_MMGPIO_BASE + 0) + +#define PLD_BRITE (SYSPLD_PHYS_BASE + 0x400004) +#define PLD_BRITE_MMGPIO_BASE (P720T_MMGPIO_BASE + 96) +#define PLD_BRITE_UP (PLD_BRITE_MMGPIO_BASE + 1) +#define PLD_BRITE_DN (PLD_BRITE_MMGPIO_BASE + 0) + +#define PLD_LCDEN (SYSPLD_PHYS_BASE + 0x400008) +#define PLD_LCDEN_MMGPIO_BASE (P720T_MMGPIO_BASE + 104) +#define PLD_LCDEN_EN (PLD_LCDEN_MMGPIO_BASE + 0) + +#define PLD_TCH (SYSPLD_PHYS_BASE + 0x400010) +#define PLD_TCH_MMGPIO_BASE (P720T_MMGPIO_BASE + 112) +#define PLD_TCH_PENIRQ (PLD_TCH_MMGPIO_BASE + 1) +#define PLD_TCH_EN (PLD_TCH_MMGPIO_BASE + 0) + +#define PLD_GPIO (SYSPLD_PHYS_BASE + 0x400014) +#define PLD_GPIO_MMGPIO_BASE (P720T_MMGPIO_BASE + 120) +#define PLD_GPIO2 (PLD_GPIO_MMGPIO_BASE + 2) +#define PLD_GPIO1 (PLD_GPIO_MMGPIO_BASE + 1) +#define PLD_GPIO0 (PLD_GPIO_MMGPIO_BASE + 0) + +static struct gpio p720t_gpios[] __initconst = { + { PLD_S1_ON, GPIOF_OUT_INIT_LOW, "PLD_S1_ON" }, + { PLD_S2_ON, GPIOF_OUT_INIT_LOW, "PLD_S2_ON" }, + { PLD_S3_ON, GPIOF_OUT_INIT_LOW, "PLD_S3_ON" }, + { PLD_S4_ON, GPIOF_OUT_INIT_LOW, "PLD_S4_ON" }, + { PLD_KBD_EN, GPIOF_OUT_INIT_LOW, "PLD_KBD_EN" }, + { PLD_SPI_EN, GPIOF_OUT_INIT_LOW, "PLD_SPI_EN" }, + { PLD_IO_USER, GPIOF_OUT_INIT_LOW, "PLD_IO_USER" }, + { PLD_IO_LED0, GPIOF_OUT_INIT_LOW, "PLD_IO_LED0" }, + { PLD_IO_LED1, GPIOF_OUT_INIT_LOW, "PLD_IO_LED1" }, + { PLD_IO_LED2, GPIOF_OUT_INIT_LOW, "PLD_IO_LED2" }, + { PLD_IO_LED3, GPIOF_OUT_INIT_LOW, "PLD_IO_LED3" }, + { PLD_IO_LEDEN, GPIOF_OUT_INIT_LOW, "PLD_IO_LEDEN" }, + { PLD_IRDA_EN, GPIOF_OUT_INIT_LOW, "PLD_IRDA_EN" }, + { PLD_COM1_EN, GPIOF_OUT_INIT_HIGH, "PLD_COM1_EN" }, + { PLD_COM2_EN, GPIOF_OUT_INIT_HIGH, "PLD_COM2_EN" }, + { PLD_CODEC_EN, GPIOF_OUT_INIT_LOW, "PLD_CODEC_EN" }, + { PLD_LCDEN_EN, GPIOF_OUT_INIT_LOW, "PLD_LCDEN_EN" }, + { PLD_TCH_EN, GPIOF_OUT_INIT_LOW, "PLD_TCH_EN" }, + { P720T_USERLED,GPIOF_OUT_INIT_LOW, "USER_LED" }, +}; + +static struct resource p720t_mmgpio_resource[] __initdata = { + DEFINE_RES_MEM_NAMED(0, 4, "dat"), +}; + +static struct bgpio_pdata p720t_mmgpio_pdata = { + .ngpio = 8, +}; + +static struct platform_device p720t_mmgpio __initdata = { + .name = "basic-mmio-gpio", + .id = -1, + .resource = p720t_mmgpio_resource, + .num_resources = ARRAY_SIZE(p720t_mmgpio_resource), + .dev = { + .platform_data = &p720t_mmgpio_pdata, + }, +}; + +static void __init p720t_mmgpio_init(void __iomem *addrbase, int gpiobase) +{ + p720t_mmgpio_resource[0].start = (unsigned long)addrbase; + p720t_mmgpio_pdata.base = gpiobase; + + platform_device_register(&p720t_mmgpio); +} + +static struct { + void __iomem *addrbase; + int gpiobase; +} mmgpios[] __initconst = { + { PLD_INT, PLD_INT_MMGPIO_BASE }, + { PLD_PWR, PLD_PWR_MMGPIO_BASE }, + { PLD_KBD, PLD_KBD_MMGPIO_BASE }, + { PLD_SPI, PLD_SPI_MMGPIO_BASE }, + { PLD_IO, PLD_IO_MMGPIO_BASE }, + { PLD_IRDA, PLD_IRDA_MMGPIO_BASE }, + { PLD_COM2, PLD_COM2_MMGPIO_BASE }, + { PLD_COM1, PLD_COM1_MMGPIO_BASE }, + { PLD_AUD, PLD_AUD_MMGPIO_BASE }, + { PLD_CF, PLD_CF_MMGPIO_BASE }, + { PLD_SDC, PLD_SDC_MMGPIO_BASE }, + { PLD_CODEC, PLD_CODEC_MMGPIO_BASE }, + { PLD_BRITE, PLD_BRITE_MMGPIO_BASE }, + { PLD_LCDEN, PLD_LCDEN_MMGPIO_BASE }, + { PLD_TCH, PLD_TCH_MMGPIO_BASE }, + { PLD_GPIO, PLD_GPIO_MMGPIO_BASE }, +}; + static struct resource p720t_nand_resource[] __initdata = { DEFINE_RES_MEM(P720T_NAND_BASE, SZ_4), }; @@ -92,11 +266,15 @@ static struct platform_device p720t_nand_pdev __initdata = { static void p720t_lcd_power_set(struct plat_lcd_data *pd, unsigned int power) { if (power) { - PLD_LCDEN = PLD_LCDEN_EN; - PLD_PWR |= PLD_S4_ON | PLD_S2_ON | PLD_S1_ON; + gpio_set_value(PLD_LCDEN_EN, 1); + gpio_set_value(PLD_S1_ON, 1); + gpio_set_value(PLD_S2_ON, 1); + gpio_set_value(PLD_S4_ON, 1); } else { - PLD_PWR &= ~(PLD_S4_ON | PLD_S2_ON | PLD_S1_ON); - PLD_LCDEN = 0; + gpio_set_value(PLD_S1_ON, 0); + gpio_set_value(PLD_S2_ON, 0); + gpio_set_value(PLD_S4_ON, 0); + gpio_set_value(PLD_LCDEN_EN, 0); } } @@ -106,10 +284,7 @@ static struct plat_lcd_data p720t_lcd_power_pdata = { static void p720t_lcd_backlight_set_intensity(int intensity) { - if (intensity) - PLD_PWR |= PLD_S3_ON; - else - PLD_PWR = 0; + gpio_set_value(PLD_S3_ON, intensity); } static struct generic_bl_info p720t_lcd_backlight_pdata = { @@ -119,19 +294,6 @@ static struct generic_bl_info p720t_lcd_backlight_pdata = { .set_bl_intensity = p720t_lcd_backlight_set_intensity, }; -/* - * Map the P720T system PLD. It occupies two address spaces: - * 0x10000000 and 0x10400000. We map both regions as one. - */ -static struct map_desc p720t_io_desc[] __initdata = { - { - .virtual = SYSPLD_VIRT_BASE, - .pfn = __phys_to_pfn(SYSPLD_PHYS_BASE), - .length = SZ_8M, - .type = MT_DEVICE, - }, -}; - static void __init fixup_p720t(struct tag *tag, char **cmdline, struct meminfo *mi) { @@ -157,33 +319,6 @@ fixup_p720t(struct tag *tag, char **cmdline, struct meminfo *mi) } } -static void __init p720t_map_io(void) -{ - clps711x_map_io(); - iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc)); -} - -static void __init p720t_init_early(void) -{ - /* - * Power down as much as possible in case we don't - * have the drivers loaded. - */ - PLD_LCDEN = 0; - PLD_PWR &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON); - - PLD_KBD = 0; - PLD_IO = 0; - PLD_IRDA = 0; - PLD_CODEC = 0; - PLD_TCH = 0; - PLD_SPI = 0; - if (!IS_ENABLED(CONFIG_DEBUG_LL)) { - PLD_COM2 = 0; - PLD_COM1 = 0; - } -} - static struct gpio_led p720t_gpio_leds[] = { { .name = "User LED", @@ -199,7 +334,20 @@ static struct gpio_led_platform_data p720t_gpio_led_pdata __initdata = { static void __init p720t_init(void) { + int i; + + clps711x_devices_init(); + + for (i = 0; i < ARRAY_SIZE(mmgpios); i++) + p720t_mmgpio_init(mmgpios[i].addrbase, mmgpios[i].gpiobase); + platform_device_register(&p720t_nand_pdev); +} + +static void __init p720t_init_late(void) +{ + WARN_ON(gpio_request_array(p720t_gpios, ARRAY_SIZE(p720t_gpios))); + platform_device_register_data(&platform_bus, "platform-lcd", 0, &p720t_lcd_power_pdata, sizeof(p720t_lcd_power_pdata)); @@ -207,10 +355,6 @@ static void __init p720t_init(void) &p720t_lcd_backlight_pdata, sizeof(p720t_lcd_backlight_pdata)); platform_device_register_simple("video-clps711x", 0, NULL, 0); -} - -static void __init p720t_init_late(void) -{ platform_device_register_data(&platform_bus, "leds-gpio", 0, &p720t_gpio_led_pdata, sizeof(p720t_gpio_led_pdata)); @@ -221,8 +365,8 @@ MACHINE_START(P720T, "ARM-Prospector720T") .atag_offset = 0x100, .nr_irqs = CLPS711X_NR_IRQS, .fixup = fixup_p720t, - .map_io = p720t_map_io, - .init_early = p720t_init_early, + .map_io = clps711x_map_io, + .init_early = clps711x_init_early, .init_irq = clps711x_init_irq, .init_time = clps711x_timer_init, .init_machine = p720t_init, diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index 20ff50f..f6d1746 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -27,12 +27,14 @@ #include <linux/clk.h> #include <linux/clkdev.h> #include <linux/clockchips.h> +#include <linux/clocksource.h> #include <linux/clk-provider.h> #include <asm/exception.h> #include <asm/mach/irq.h> #include <asm/mach/map.h> #include <asm/mach/time.h> +#include <asm/sched_clock.h> #include <asm/system_misc.h> #include <mach/hardware.h> @@ -213,7 +215,7 @@ void __init clps711x_init_irq(void) } } -inline u32 fls16(u32 x) +static inline u32 fls16(u32 x) { u32 r = 15; @@ -237,27 +239,52 @@ inline u32 fls16(u32 x) asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs) { - u32 irqstat; - void __iomem *base = CLPS711X_VIRT_BASE; - - irqstat = readl_relaxed(base + INTSR1) & readl_relaxed(base + INTMR1); - if (irqstat) { - handle_IRQ(fls16(irqstat), regs); - return; - } + do { + u32 irqstat; + void __iomem *base = CLPS711X_VIRT_BASE; + + irqstat = readw_relaxed(base + INTSR1) & + readw_relaxed(base + INTMR1); + if (irqstat) + handle_IRQ(fls16(irqstat), regs); + + irqstat = readw_relaxed(base + INTSR2) & + readw_relaxed(base + INTMR2); + if (irqstat) { + handle_IRQ(fls16(irqstat) + 16, regs); + continue; + } + + break; + } while (1); +} - irqstat = readl_relaxed(base + INTSR2) & readl_relaxed(base + INTMR2); - if (likely(irqstat)) - handle_IRQ(fls16(irqstat) + 16, regs); +static u32 notrace clps711x_sched_clock_read(void) +{ + return ~readw_relaxed(CLPS711X_VIRT_BASE + TC1D); } static void clps711x_clockevent_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { + disable_irq(IRQ_TC2OI); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + enable_irq(IRQ_TC2OI); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* Not supported */ + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + /* Left event sources disabled, no more interrupts appear */ + break; + } } static struct clock_event_device clockevent_clps711x = { - .name = "CLPS711x Clockevents", + .name = "clps711x-clockevent", .rating = 300, .features = CLOCK_EVT_FEAT_PERIODIC, .set_mode = clps711x_clockevent_set_mode, @@ -271,8 +298,8 @@ static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id) } static struct irqaction clps711x_timer_irq = { - .name = "CLPS711x Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .name = "clps711x-timer", + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = clps711x_timer_interrupt, }; @@ -301,6 +328,7 @@ void __init clps711x_timer_init(void) cpu = ext; bus = cpu; spi = 135400; + pll = 0; } else { cpu = pll; if (cpu >= 36864000) @@ -319,9 +347,9 @@ void __init clps711x_timer_init(void) else timh = 541440; } else - timh = cpu / 144; + timh = DIV_ROUND_CLOSEST(cpu, 144); - timl = timh / 256; + timl = DIV_ROUND_CLOSEST(timh, 256); /* All clocks are fixed */ add_fixed_clk(clk_pll, "pll", pll); @@ -334,13 +362,24 @@ void __init clps711x_timer_init(void) pr_info("CPU frequency set at %i Hz.\n", cpu); + /* Start Timer1 in free running mode (Low frequency) */ + tmp = clps_readl(SYSCON1) & ~(SYSCON1_TC1S | SYSCON1_TC1M); + clps_writel(tmp, SYSCON1); + + setup_sched_clock(clps711x_sched_clock_read, 16, timl); + + clocksource_mmio_init(CLPS711X_VIRT_BASE + TC1D, + "clps711x_clocksource", timl, 300, 16, + clocksource_mmio_readw_down); + + /* Set Timer2 prescaler */ clps_writew(DIV_ROUND_CLOSEST(timh, HZ), TC2D); - tmp = clps_readl(SYSCON1); - tmp |= SYSCON1_TC2S | SYSCON1_TC2M; + /* Start Timer2 in prescale mode (High frequency)*/ + tmp = clps_readl(SYSCON1) | SYSCON1_TC2M | SYSCON1_TC2S; clps_writel(tmp, SYSCON1); - clockevents_config_and_register(&clockevent_clps711x, timh, 1, 0xffff); + clockevents_config_and_register(&clockevent_clps711x, timh, 0, 0); setup_irq(IRQ_TC2OI, &clps711x_timer_irq); } @@ -353,15 +392,11 @@ void clps711x_restart(char mode, const char *cmd) static void clps711x_idle(void) { clps_writel(1, HALT); - __asm__ __volatile__( - "mov r0, r0\n\ - mov r0, r0"); + asm("mov r0, r0"); + asm("mov r0, r0"); } -static int __init clps711x_idle_init(void) +void __init clps711x_init_early(void) { arm_pm_idle = clps711x_idle; - return 0; } - -arch_initcall(clps711x_idle_init); diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h index f84a729..2a22f4c 100644 --- a/arch/arm/mach-clps711x/common.h +++ b/arch/arm/mach-clps711x/common.h @@ -13,3 +13,4 @@ extern void clps711x_init_irq(void); extern void clps711x_timer_init(void); extern void clps711x_handle_irq(struct pt_regs *regs); extern void clps711x_restart(char mode, const char *cmd); +extern void clps711x_init_early(void); diff --git a/arch/arm/mach-clps711x/devices.c b/arch/arm/mach-clps711x/devices.c new file mode 100644 index 0000000..856b81c --- /dev/null +++ b/arch/arm/mach-clps711x/devices.c @@ -0,0 +1,68 @@ +/* + * CLPS711X common devices definitions + * + * Author: Alexander Shiyan <shc_work@mail.ru>, 2013 + * + * 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/platform_device.h> +#include <linux/sizes.h> + +#include <mach/hardware.h> + +static const phys_addr_t clps711x_gpios[][2] __initconst = { + { PADR, PADDR }, + { PBDR, PBDDR }, + { PCDR, PCDDR }, + { PDDR, PDDDR }, + { PEDR, PEDDR }, +}; + +static void __init clps711x_add_gpio(void) +{ + unsigned i; + struct resource gpio_res[2]; + + memset(gpio_res, 0, sizeof(gpio_res)); + + gpio_res[0].flags = IORESOURCE_MEM; + gpio_res[1].flags = IORESOURCE_MEM; + + for (i = 0; i < ARRAY_SIZE(clps711x_gpios); i++) { + gpio_res[0].start = CLPS711X_PHYS_BASE + clps711x_gpios[i][0]; + gpio_res[0].end = gpio_res[0].start; + gpio_res[1].start = CLPS711X_PHYS_BASE + clps711x_gpios[i][1]; + gpio_res[1].end = gpio_res[1].start; + + platform_device_register_simple("clps711x-gpio", i, + gpio_res, ARRAY_SIZE(gpio_res)); + } +} + +const struct resource clps711x_syscon_res[] __initconst = { + /* SYSCON1, SYSFLG1 */ + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON1, SZ_128), + /* SYSCON2, SYSFLG2 */ + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON2, SZ_128), + /* SYSCON3 */ + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON3, SZ_64), +}; + +static void __init clps711x_add_syscon(void) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(clps711x_syscon_res); i++) + platform_device_register_simple("clps711x-syscon", i + 1, + &clps711x_syscon_res[i], 1); +} + +void __init clps711x_devices_init(void) +{ + clps711x_add_gpio(); + clps711x_add_syscon(); +} diff --git a/arch/arm/mach-clps711x/devices.h b/arch/arm/mach-clps711x/devices.h new file mode 100644 index 0000000..a5efc17 --- /dev/null +++ b/arch/arm/mach-clps711x/devices.h @@ -0,0 +1,12 @@ +/* + * CLPS711X common devices definitions + * + * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru> + * + * 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. + */ + +void clps711x_devices_init(void); diff --git a/arch/arm/mach-clps711x/include/mach/autcpu12.h b/arch/arm/mach-clps711x/include/mach/autcpu12.h deleted file mode 100644 index 0452f5f..0000000 --- a/arch/arm/mach-clps711x/include/mach/autcpu12.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * AUTCPU12 specific defines - * - * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de> - * - * 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 - */ -#ifndef __ASM_ARCH_AUTCPU12_H -#define __ASM_ARCH_AUTCPU12_H - -/* - * The flash bank is wired to chip select 0 - */ -#define AUTCPU12_PHYS_FLASH CS0_PHYS_BASE /* physical */ - -/* offset for device specific information structure */ -#define AUTCPU12_LCDINFO_OFFS (0x00010000) - -/* Videomemory in the internal SRAM (CS 6) */ -#define AUTCPU12_PHYS_VIDEO CS6_PHYS_BASE - -/* -* All special IO's are tied to CS1 -*/ -#define AUTCPU12_PHYS_CHAR_LCD CS1_PHYS_BASE +0x00000000 /* physical */ - -#define AUTCPU12_PHYS_NVRAM CS1_PHYS_BASE +0x02000000 /* physical */ - -#define AUTCPU12_PHYS_CSAUX1 CS1_PHYS_BASE +0x04000000 /* physical */ - -#define AUTCPU12_PHYS_CAN CS1_PHYS_BASE +0x08000000 /* physical */ - -#define AUTCPU12_PHYS_TOUCH CS1_PHYS_BASE +0x0A000000 /* physical */ - -#define AUTCPU12_PHYS_IO CS1_PHYS_BASE +0x0C000000 /* physical */ - -#define AUTCPU12_PHYS_LPT CS1_PHYS_BASE +0x0E000000 /* physical */ - -/* -* defines for lcd contrast -*/ -#define AUTCPU12_DPOT_PORT_OFFSET PEDR -#define AUTCPU12_DPOT_CS (1<<0) -#define AUTCPU12_DPOT_CLK (1<<1) -#define AUTCPU12_DPOT_UD (1<<2) - -#endif diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h index 01d1b95..0286f4b 100644 --- a/arch/arm/mach-clps711x/include/mach/clps711x.h +++ b/arch/arm/mach-clps711x/include/mach/clps711x.h @@ -21,6 +21,8 @@ #ifndef __MACH_CLPS711X_H #define __MACH_CLPS711X_H +#include <linux/mfd/syscon/clps711x.h> + #define CLPS711X_PHYS_BASE (0x80000000) #define PADR (0x0000) @@ -96,83 +98,9 @@ #define RANDID2 (0x2708) #define RANDID3 (0x270c) -/* common bits: SYSCON1 / SYSCON2 */ -#define SYSCON_UARTEN (1 << 8) - -#define SYSCON1_KBDSCAN(x) ((x) & 15) -#define SYSCON1_KBDSCANMASK (15) -#define SYSCON1_TC1M (1 << 4) -#define SYSCON1_TC1S (1 << 5) -#define SYSCON1_TC2M (1 << 6) -#define SYSCON1_TC2S (1 << 7) -#define SYSCON1_UART1EN SYSCON_UARTEN -#define SYSCON1_BZTOG (1 << 9) -#define SYSCON1_BZMOD (1 << 10) -#define SYSCON1_DBGEN (1 << 11) -#define SYSCON1_LCDEN (1 << 12) -#define SYSCON1_CDENTX (1 << 13) -#define SYSCON1_CDENRX (1 << 14) -#define SYSCON1_SIREN (1 << 15) -#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16) -#define SYSCON1_ADCKSEL_MASK (3 << 16) -#define SYSCON1_EXCKEN (1 << 18) -#define SYSCON1_WAKEDIS (1 << 19) -#define SYSCON1_IRTXM (1 << 20) - -/* common bits: SYSFLG1 / SYSFLG2 */ -#define SYSFLG_UBUSY (1 << 11) -#define SYSFLG_URXFE (1 << 22) -#define SYSFLG_UTXFF (1 << 23) - -#define SYSFLG1_MCDR (1 << 0) -#define SYSFLG1_DCDET (1 << 1) -#define SYSFLG1_WUDR (1 << 2) -#define SYSFLG1_WUON (1 << 3) -#define SYSFLG1_CTS (1 << 8) -#define SYSFLG1_DSR (1 << 9) -#define SYSFLG1_DCD (1 << 10) -#define SYSFLG1_UBUSY SYSFLG_UBUSY -#define SYSFLG1_NBFLG (1 << 12) -#define SYSFLG1_RSTFLG (1 << 13) -#define SYSFLG1_PFFLG (1 << 14) -#define SYSFLG1_CLDFLG (1 << 15) -#define SYSFLG1_URXFE SYSFLG_URXFE -#define SYSFLG1_UTXFF SYSFLG_UTXFF -#define SYSFLG1_CRXFE (1 << 24) -#define SYSFLG1_CTXFF (1 << 25) -#define SYSFLG1_SSIBUSY (1 << 26) -#define SYSFLG1_ID (1 << 29) -#define SYSFLG1_VERID(x) (((x) >> 30) & 3) -#define SYSFLG1_VERID_MASK (3 << 30) - -#define SYSFLG2_SSRXOF (1 << 0) -#define SYSFLG2_RESVAL (1 << 1) -#define SYSFLG2_RESFRM (1 << 2) -#define SYSFLG2_SS2RXFE (1 << 3) -#define SYSFLG2_SS2TXFF (1 << 4) -#define SYSFLG2_SS2TXUF (1 << 5) -#define SYSFLG2_CKMODE (1 << 6) -#define SYSFLG2_UBUSY SYSFLG_UBUSY -#define SYSFLG2_URXFE SYSFLG_URXFE -#define SYSFLG2_UTXFF SYSFLG_UTXFF - #define LCDCON_GSEN (1 << 30) #define LCDCON_GSMD (1 << 31) -#define SYSCON2_SERSEL (1 << 0) -#define SYSCON2_KBD6 (1 << 1) -#define SYSCON2_DRAMZ (1 << 2) -#define SYSCON2_KBWEN (1 << 3) -#define SYSCON2_SS2TXEN (1 << 4) -#define SYSCON2_PCCARD1 (1 << 5) -#define SYSCON2_PCCARD2 (1 << 6) -#define SYSCON2_SS2RXEN (1 << 7) -#define SYSCON2_UART2EN SYSCON_UARTEN -#define SYSCON2_SS2MAEN (1 << 9) -#define SYSCON2_OSTB (1 << 12) -#define SYSCON2_CLKENSL (1 << 13) -#define SYSCON2_BUZFREQ (1 << 14) - /* common bits: UARTDR1 / UARTDR2 */ #define UARTDR_FRMERR (1 << 8) #define UARTDR_PARERR (1 << 9) @@ -228,18 +156,6 @@ #define DAI64FS_MCLK256EN (1 << 3) #define DAI64FS_LOOPBACK (1 << 5) -#define SYSCON3_ADCCON (1 << 0) -#define SYSCON3_CLKCTL0 (1 << 1) -#define SYSCON3_CLKCTL1 (1 << 2) -#define SYSCON3_DAISEL (1 << 3) -#define SYSCON3_ADCCKNSEN (1 << 4) -#define SYSCON3_VERSN(x) (((x) >> 5) & 7) -#define SYSCON3_VERSN_MASK (7 << 5) -#define SYSCON3_FASTWAKE (1 << 8) -#define SYSCON3_DAIEN (1 << 9) -#define SYSCON3_128FS SYSCON3_DAIEN -#define SYSCON3_ENPD67 (1 << 10) - #define SDCONF_ACTIVE (1 << 10) #define SDCONF_CLKCTL (1 << 9) #define SDCONF_WIDTH_4 (0 << 7) diff --git a/arch/arm/mach-clps711x/include/mach/hardware.h b/arch/arm/mach-clps711x/include/mach/hardware.h index 2f23dd5..c5a8ea6 100644 --- a/arch/arm/mach-clps711x/include/mach/hardware.h +++ b/arch/arm/mach-clps711x/include/mach/hardware.h @@ -70,11 +70,4 @@ #define CLPS711X_SDRAM0_BASE (0xc0000000) #define CLPS711X_SDRAM1_BASE (0xd0000000) -#if defined (CONFIG_ARCH_EDB7211) - -/* The extra 8 lines of the keyboard matrix are wired to chip select 3 */ -#define EP7211_PHYS_EXTKBD CS3_PHYS_BASE - -#endif /* CONFIG_ARCH_EDB7211 */ - #endif diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h deleted file mode 100644 index fc0e028..0000000 --- a/arch/arm/mach-clps711x/include/mach/memory.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/memory.h - * - * Copyright (C) 1999 ARM Limited - * - * 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 - */ -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET UL(0xc0000000) - -/* - * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211 - * uses only one of the two banks (bank #1). However, even within - * bank #1, memory is discontiguous. - * - * The EDB7211 has two 8MB DRAM areas with 8MB of empty space between - * them, so we use 24 for the node max shift to get 16MB node sizes. - */ - -#define SECTION_SIZE_BITS 24 -#define MAX_PHYSMEM_BITS 32 - -#endif - diff --git a/arch/arm/mach-clps711x/include/mach/syspld.h b/arch/arm/mach-clps711x/include/mach/syspld.h deleted file mode 100644 index 9a43315..0000000 --- a/arch/arm/mach-clps711x/include/mach/syspld.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/syspld.h - * - * System Control PLD register definitions. - * - * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * 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 - */ -#ifndef __ASM_ARCH_SYSPLD_H -#define __ASM_ARCH_SYSPLD_H - -#define SYSPLD_PHYS_BASE (0x10000000) -#define SYSPLD_VIRT_BASE IO_ADDRESS(SYSPLD_PHYS_BASE) - -#define SYSPLD_REG(type, off) (*(volatile type *)(SYSPLD_VIRT_BASE + (off))) - -#define PLD_INT SYSPLD_REG(u32, 0x000000) -#define PLD_INT_PENIRQ (1 << 5) -#define PLD_INT_UCB_IRQ (1 << 1) -#define PLD_INT_KBD_ATN (1 << 0) /* EINT1 */ - -#define PLD_PWR SYSPLD_REG(u32, 0x000004) -#define PLD_PWR_EXT (1 << 5) -#define PLD_PWR_MODE (1 << 4) /* 1 = PWM, 0 = PFM */ -#define PLD_S4_ON (1 << 3) /* LCD bias voltage enable */ -#define PLD_S3_ON (1 << 2) /* LCD backlight enable */ -#define PLD_S2_ON (1 << 1) /* LCD 3V3 supply enable */ -#define PLD_S1_ON (1 << 0) /* LCD 3V supply enable */ - -#define PLD_KBD SYSPLD_REG(u32, 0x000008) -#define PLD_KBD_WAKE (1 << 1) -#define PLD_KBD_EN (1 << 0) - -#define PLD_SPI SYSPLD_REG(u32, 0x00000c) -#define PLD_SPI_EN (1 << 0) - -#define PLD_IO SYSPLD_REG(u32, 0x000010) -#define PLD_IO_BOOTSEL (1 << 6) /* boot sel switch */ -#define PLD_IO_USER (1 << 5) /* user defined switch */ -#define PLD_IO_LED3 (1 << 4) -#define PLD_IO_LED2 (1 << 3) -#define PLD_IO_LED1 (1 << 2) -#define PLD_IO_LED0 (1 << 1) -#define PLD_IO_LEDEN (1 << 0) - -#define PLD_IRDA SYSPLD_REG(u32, 0x000014) -#define PLD_IRDA_EN (1 << 0) - -#define PLD_COM2 SYSPLD_REG(u32, 0x000018) -#define PLD_COM2_EN (1 << 0) - -#define PLD_COM1 SYSPLD_REG(u32, 0x00001c) -#define PLD_COM1_EN (1 << 0) - -#define PLD_AUD SYSPLD_REG(u32, 0x000020) -#define PLD_AUD_DIV1 (1 << 6) -#define PLD_AUD_DIV0 (1 << 5) -#define PLD_AUD_CLK_SEL1 (1 << 4) -#define PLD_AUD_CLK_SEL0 (1 << 3) -#define PLD_AUD_MIC_PWR (1 << 2) -#define PLD_AUD_MIC_GAIN (1 << 1) -#define PLD_AUD_CODEC_EN (1 << 0) - -#define PLD_CF SYSPLD_REG(u32, 0x000024) -#define PLD_CF2_SLEEP (1 << 5) -#define PLD_CF1_SLEEP (1 << 4) -#define PLD_CF2_nPDREQ (1 << 3) -#define PLD_CF1_nPDREQ (1 << 2) -#define PLD_CF2_nIRQ (1 << 1) -#define PLD_CF1_nIRQ (1 << 0) - -#define PLD_SDC SYSPLD_REG(u32, 0x000028) -#define PLD_SDC_INT_EN (1 << 2) -#define PLD_SDC_WP (1 << 1) -#define PLD_SDC_CD (1 << 0) - -#define PLD_FPGA SYSPLD_REG(u32, 0x00002c) - -#define PLD_CODEC SYSPLD_REG(u32, 0x400000) -#define PLD_CODEC_IRQ3 (1 << 4) -#define PLD_CODEC_IRQ2 (1 << 3) -#define PLD_CODEC_IRQ1 (1 << 2) -#define PLD_CODEC_EN (1 << 0) - -#define PLD_BRITE SYSPLD_REG(u32, 0x400004) -#define PLD_BRITE_UP (1 << 1) -#define PLD_BRITE_DN (1 << 0) - -#define PLD_LCDEN SYSPLD_REG(u32, 0x400008) -#define PLD_LCDEN_EN (1 << 0) - -#define PLD_ID SYSPLD_REG(u32, 0x40000c) - -#define PLD_TCH SYSPLD_REG(u32, 0x400010) -#define PLD_TCH_PENIRQ (1 << 1) -#define PLD_TCH_EN (1 << 0) - -#define PLD_GPIO SYSPLD_REG(u32, 0x400014) -#define PLD_GPIO2 (1 << 2) -#define PLD_GPIO1 (1 << 1) -#define PLD_GPIO0 (1 << 0) - -#endif diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig index 36469d8..dff7b2f 100644 --- a/arch/arm/mach-dove/Kconfig +++ b/arch/arm/mach-dove/Kconfig @@ -22,8 +22,7 @@ config MACH_CM_A510 config MACH_DOVE_DT bool "Marvell Dove Flattened Device Tree" - select MVEBU_CLK_CORE - select MVEBU_CLK_GATING + select DOVE_CLK select REGULATOR select REGULATOR_FIXED_VOLTAGE select USE_OF diff --git a/arch/arm/mach-dove/board-dt.c b/arch/arm/mach-dove/board-dt.c index 0b14280..f3755ac 100644 --- a/arch/arm/mach-dove/board-dt.c +++ b/arch/arm/mach-dove/board-dt.c @@ -10,7 +10,6 @@ #include <linux/init.h> #include <linux/clk-provider.h> -#include <linux/clk/mvebu.h> #include <linux/of.h> #include <linux/of_platform.h> #include <linux/platform_data/usb-ehci-orion.h> @@ -49,7 +48,7 @@ static void __init dove_legacy_clk_init(void) static void __init dove_of_clk_init(void) { - mvebu_clocks_init(); + of_clk_init(NULL); dove_legacy_clk_init(); } diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index e2b5da0..2a9443d 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -9,7 +9,6 @@ */ #include <linux/clk-provider.h> -#include <linux/clk/mvebu.h> #include <linux/dma-mapping.h> #include <linux/init.h> #include <linux/of.h> diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 7509a89..e610e137 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -8,12 +8,6 @@ config MACH_D2NET_V2 Say 'Y' here if you want your kernel to support the LaCie d2 Network v2 NAS. -config MACH_DB88F6281_BP - bool "Marvell DB-88F6281-BP Development Board" - help - Say 'Y' here if you want your kernel to support the - Marvell DB-88F6281-BP Development Board. - config MACH_DOCKSTAR bool "Seagate FreeAgent DockStar" help @@ -134,13 +128,12 @@ comment "Device tree entries" config ARCH_KIRKWOOD_DT bool "Marvell Kirkwood Flattened Device Tree" + select KIRKWOOD_CLK select POWER_SUPPLY select POWER_RESET select POWER_RESET_GPIO select REGULATOR select REGULATOR_FIXED_VOLTAGE - select MVEBU_CLK_CORE - select MVEBU_CLK_GATING select USE_OF help Say 'Y' here if you want your kernel to support the @@ -153,6 +146,13 @@ config MACH_CLOUDBOX_DT Say 'Y' here if you want your kernel to support the LaCie CloudBox NAS, using Flattened Device Tree. +config MACH_DB88F628X_BP_DT + bool "Marvell DB-88F628x-BP Development Board (Flattened Device Tree)" + help + Say 'Y' here if you want your kernel to support the Marvell + DB-88F6281-BP and DB-88F6282-BP Development Board (Flattened + Device Tree). + config MACH_DLINK_KIRKWOOD_DT bool "D-Link Kirkwood-based NAS (Flattened Device Tree)" select ARCH_KIRKWOOD_DT @@ -272,14 +272,6 @@ config MACH_NETSPACE_V2_DT Say 'Y' here if you want your kernel to support the LaCie Network Space v2 NAS, using Flattened Device Tree. -config MACH_NSA310_DT - bool "ZyXEL NSA-310 (Flattened Device Tree)" - select ARCH_KIRKWOOD_DT - select ARM_ATAG_DTB_COMPAT - help - Say 'Y' here if you want your kernel to support the - ZyXEL NSA-310 board (Flattened Device Tree). - config MACH_OPENBLOCKS_A6_DT bool "Plat'Home OpenBlocks A6 (Flattened Device Tree)" select ARCH_KIRKWOOD_DT diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index e1f3735..2fdc3a7 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -1,7 +1,6 @@ obj-y += common.o irq.o pcie.o mpp.o obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o -obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o @@ -21,6 +20,7 @@ obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o obj-$(CONFIG_MACH_CLOUDBOX_DT) += board-ns2.o +obj-$(CONFIG_MACH_DB88F628X_BP_DT) += board-db88f628x-bp.o obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o obj-$(CONFIG_MACH_DOCKSTAR_DT) += board-dockstar.o obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o @@ -37,7 +37,6 @@ obj-$(CONFIG_MACH_NETSPACE_LITE_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_NETSPACE_MINI_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_NETSPACE_V2_DT) += board-ns2.o -obj-$(CONFIG_MACH_NSA310_DT) += board-nsa310.o obj-$(CONFIG_MACH_OPENBLOCKS_A6_DT) += board-openblocks_a6.o obj-$(CONFIG_MACH_READYNAS_DT) += board-readynas.o obj-$(CONFIG_MACH_TOPKICK_DT) += board-usi_topkick.o diff --git a/arch/arm/mach-kirkwood/board-db88f628x-bp.c b/arch/arm/mach-kirkwood/board-db88f628x-bp.c new file mode 100644 index 0000000..2f574bc --- /dev/null +++ b/arch/arm/mach-kirkwood/board-db88f628x-bp.c @@ -0,0 +1,24 @@ +/* + * Saeed Bishara <saeed@marvell.com> + * + * Marvell DB-88F628{1,2}-BP Development Board Setup + * + * 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/kernel.h> +#include <linux/init.h> +#include <linux/of.h> +#include <linux/mv643xx_eth.h> +#include "common.h" + +static struct mv643xx_eth_platform_data db88f628x_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +void __init db88f628x_init(void) +{ + kirkwood_ge00_init(&db88f628x_ge00_data); +} diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index e9647b8..cee5dc7 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -15,7 +15,6 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/clk-provider.h> -#include <linux/clk/mvebu.h> #include <linux/kexec.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -25,11 +24,6 @@ #include <plat/common.h> #include "common.h" -static struct of_device_id kirkwood_dt_match_table[] __initdata = { - { .compatible = "simple-bus", }, - { } -}; - /* * There are still devices that doesn't know about DT yet. Get clock * gates here and add a clock lookup alias, so that old platform @@ -77,7 +71,7 @@ static void __init kirkwood_legacy_clk_init(void) static void __init kirkwood_of_clk_init(void) { - mvebu_clocks_init(); + of_clk_init(NULL); kirkwood_legacy_clk_init(); } @@ -97,6 +91,8 @@ static void __init kirkwood_dt_init(void) kirkwood_l2_init(); + kirkwood_cpufreq_init(); + /* Setup root of clk tree */ kirkwood_of_clk_init(); @@ -147,6 +143,10 @@ static void __init kirkwood_dt_init(void) of_machine_is_compatible("lacie,netspace_v2")) ns2_init(); + if (of_machine_is_compatible("marvell,db-88f6281-bp") || + of_machine_is_compatible("marvell,db-88f6282-bp")) + db88f628x_init(); + if (of_machine_is_compatible("mpl,cec4")) mplcec4_init(); @@ -159,7 +159,7 @@ static void __init kirkwood_dt_init(void) if (of_machine_is_compatible("usi,topkick")) usi_topkick_init(); - of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char * const kirkwood_dt_board_compat[] = { @@ -181,6 +181,8 @@ static const char * const kirkwood_dt_board_compat[] = { "lacie,netspace_max_v2", "lacie,netspace_mini_v2", "lacie,netspace_v2", + "marvell,db-88f6281-bp", + "marvell,db-88f6282-bp", "mpl,cec4", "netgear,readynas-duo-v2", "plathome,openblocks-a6", diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c index c8ebde4..98b5ad1 100644 --- a/arch/arm/mach-kirkwood/board-iconnect.c +++ b/arch/arm/mach-kirkwood/board-iconnect.c @@ -22,11 +22,3 @@ void __init iconnect_init(void) { kirkwood_ge00_init(&iconnect_ge00_data); } - -static int __init iconnect_pci_init(void) -{ - if (of_machine_is_compatible("iom,iconnect")) - kirkwood_pcie_init(KW_PCIE0); - return 0; -} -subsys_initcall(iconnect_pci_init); diff --git a/arch/arm/mach-kirkwood/board-mplcec4.c b/arch/arm/mach-kirkwood/board-mplcec4.c index 7d6dc66..938712e 100644 --- a/arch/arm/mach-kirkwood/board-mplcec4.c +++ b/arch/arm/mach-kirkwood/board-mplcec4.c @@ -29,7 +29,6 @@ void __init mplcec4_init(void) */ kirkwood_ge00_init(&mplcec4_ge00_data); kirkwood_ge01_init(&mplcec4_ge01_data); - kirkwood_pcie_init(KW_PCIE0); } diff --git a/arch/arm/mach-kirkwood/board-nsa310.c b/arch/arm/mach-kirkwood/board-nsa310.c deleted file mode 100644 index 55ade93..0000000 --- a/arch/arm/mach-kirkwood/board-nsa310.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mach-kirkwood/nsa-310-setup.c - * - * ZyXEL NSA-310 Setup - * - * 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/kernel.h> -#include <linux/init.h> -#include <mach/kirkwood.h> -#include <linux/of.h> -#include "common.h" - -static int __init nsa310_pci_init(void) -{ - if (of_machine_is_compatible("zyxel,nsa310")) - kirkwood_pcie_init(KW_PCIE0); - - return 0; -} - -subsys_initcall(nsa310_pci_init); diff --git a/arch/arm/mach-kirkwood/board-readynas.c b/arch/arm/mach-kirkwood/board-readynas.c index fb42c20..341b82d 100644 --- a/arch/arm/mach-kirkwood/board-readynas.c +++ b/arch/arm/mach-kirkwood/board-readynas.c @@ -24,5 +24,4 @@ static struct mv643xx_eth_platform_data netgear_readynas_ge00_data = { void __init netgear_readynas_init(void) { kirkwood_ge00_init(&netgear_readynas_ge00_data); - kirkwood_pcie_init(KW_PCIE0); } diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f389228..7c72c72 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -598,6 +598,29 @@ void __init kirkwood_audio_init(void) } /***************************************************************************** + * CPU Frequency + ****************************************************************************/ +static struct resource kirkwood_cpufreq_resources[] = { + [0] = { + .start = CPU_CONTROL_PHYS, + .end = CPU_CONTROL_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device kirkwood_cpufreq_device = { + .name = "kirkwood-cpufreq", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources), + .resource = kirkwood_cpufreq_resources, +}; + +void __init kirkwood_cpufreq_init(void) +{ + platform_device_register(&kirkwood_cpufreq_device); +} + +/***************************************************************************** * General ****************************************************************************/ /* @@ -648,30 +671,6 @@ char * __init kirkwood_id(void) void __init kirkwood_setup_wins(void) { - /* - * The PCIe windows will no longer be statically allocated - * here once Kirkwood is migrated to the pci-mvebu driver. - */ - mvebu_mbus_add_window_remap_flags("pcie0.0", - KIRKWOOD_PCIE_IO_PHYS_BASE, - KIRKWOOD_PCIE_IO_SIZE, - KIRKWOOD_PCIE_IO_BUS_BASE, - MVEBU_MBUS_PCI_IO); - mvebu_mbus_add_window_remap_flags("pcie0.0", - KIRKWOOD_PCIE_MEM_PHYS_BASE, - KIRKWOOD_PCIE_MEM_SIZE, - MVEBU_MBUS_NO_REMAP, - MVEBU_MBUS_PCI_MEM); - mvebu_mbus_add_window_remap_flags("pcie1.0", - KIRKWOOD_PCIE1_IO_PHYS_BASE, - KIRKWOOD_PCIE1_IO_SIZE, - KIRKWOOD_PCIE1_IO_BUS_BASE, - MVEBU_MBUS_PCI_IO); - mvebu_mbus_add_window_remap_flags("pcie1.0", - KIRKWOOD_PCIE1_MEM_PHYS_BASE, - KIRKWOOD_PCIE1_MEM_SIZE, - MVEBU_MBUS_NO_REMAP, - MVEBU_MBUS_PCI_MEM); mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE); mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE, diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 21da3b1..e2e19b3 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -51,6 +51,8 @@ void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); void kirkwood_audio_init(void); void kirkwood_cpuidle_init(void); +void kirkwood_cpufreq_init(void); + void kirkwood_restart(char, const char *); void kirkwood_clk_init(void); @@ -119,6 +121,12 @@ void km_kirkwood_init(void); static inline void km_kirkwood_init(void) {}; #endif +#ifdef CONFIG_MACH_DB88F628X_BP_DT +void db88f628x_init(void); +#else +static inline void db88f628x_init(void) {}; +#endif + #ifdef CONFIG_MACH_MPLCEC4_DT void mplcec4_init(void); #else diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c deleted file mode 100644 index 5a369fe..0000000 --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * arch/arm/mach-kirkwood/db88f6281-bp-setup.c - * - * Marvell DB-88F6281-BP Development Board Setup - * - * 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/kernel.h> -#include <linux/init.h> -#include <linux/sizes.h> -#include <linux/platform_device.h> -#include <linux/mtd/partitions.h> -#include <linux/ata_platform.h> -#include <linux/mv643xx_eth.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <mach/kirkwood.h> -#include <linux/platform_data/mmc-mvsdio.h> -#include "common.h" -#include "mpp.h" - -static struct mtd_partition db88f6281_nand_parts[] = { - { - .name = "u-boot", - .offset = 0, - .size = SZ_1M - }, { - .name = "uImage", - .offset = MTDPART_OFS_NXTBLK, - .size = SZ_4M - }, { - .name = "root", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL - }, -}; - -static struct mv643xx_eth_platform_data db88f6281_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -static struct mv_sata_platform_data db88f6281_sata_data = { - .n_ports = 2, -}; - -static struct mvsdio_platform_data db88f6281_mvsdio_data = { - .gpio_write_protect = 37, - .gpio_card_detect = 38, -}; - -static unsigned int db88f6281_mpp_config[] __initdata = { - MPP0_NF_IO2, - MPP1_NF_IO3, - MPP2_NF_IO4, - MPP3_NF_IO5, - MPP4_NF_IO6, - MPP5_NF_IO7, - MPP18_NF_IO0, - MPP19_NF_IO1, - MPP37_GPIO, - MPP38_GPIO, - 0 -}; - -static void __init db88f6281_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_init(); - kirkwood_mpp_conf(db88f6281_mpp_config); - - kirkwood_nand_init(ARRAY_AND_SIZE(db88f6281_nand_parts), 25); - kirkwood_ehci_init(); - kirkwood_ge00_init(&db88f6281_ge00_data); - kirkwood_sata_init(&db88f6281_sata_data); - kirkwood_uart0_init(); - kirkwood_sdio_init(&db88f6281_mvsdio_data); -} - -static int __init db88f6281_pci_init(void) -{ - if (machine_is_db88f6281_bp()) { - u32 dev, rev; - - kirkwood_pcie_id(&dev, &rev); - if (dev == MV88F6282_DEV_ID) - kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0); - else - kirkwood_pcie_init(KW_PCIE0); - } - return 0; -} -subsys_initcall(db88f6281_pci_init); - -MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board") - /* Maintainer: Saeed Bishara <saeed@marvell.com> */ - .atag_offset = 0x100, - .init_machine = db88f6281_init, - .map_io = kirkwood_map_io, - .init_early = kirkwood_init_early, - .init_irq = kirkwood_init_irq, - .init_time = kirkwood_timer_init, - .restart = kirkwood_restart, -MACHINE_END diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 5c82b7d..d4cbe5e 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -17,6 +17,7 @@ #define CPU_CONFIG_ERROR_PROP 0x00000004 #define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104) +#define CPU_CONTROL_PHYS (BRIDGE_PHYS_BASE + 0x0104) #define CPU_RESET 0x00000002 #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) @@ -69,6 +70,7 @@ #define CGC_RUNIT (1 << 7) #define CGC_XOR0 (1 << 8) #define CGC_AUDIO (1 << 9) +#define CGC_POWERSAVE (1 << 11) #define CGC_SATA0 (1 << 14) #define CGC_SATA1 (1 << 15) #define CGC_XOR1 (1 << 16) diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 7f43e6c..ddcb09f 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -12,6 +12,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/clk.h> +#include <linux/mbus.h> #include <video/vga.h> #include <asm/irq.h> #include <asm/mach/pci.h> @@ -253,6 +254,27 @@ static void __init add_pcie_port(int index, void __iomem *base) void __init kirkwood_pcie_init(unsigned int portmask) { + mvebu_mbus_add_window_remap_flags("pcie0.0", + KIRKWOOD_PCIE_IO_PHYS_BASE, + KIRKWOOD_PCIE_IO_SIZE, + KIRKWOOD_PCIE_IO_BUS_BASE, + MVEBU_MBUS_PCI_IO); + mvebu_mbus_add_window_remap_flags("pcie0.0", + KIRKWOOD_PCIE_MEM_PHYS_BASE, + KIRKWOOD_PCIE_MEM_SIZE, + MVEBU_MBUS_NO_REMAP, + MVEBU_MBUS_PCI_MEM); + mvebu_mbus_add_window_remap_flags("pcie1.0", + KIRKWOOD_PCIE1_IO_PHYS_BASE, + KIRKWOOD_PCIE1_IO_SIZE, + KIRKWOOD_PCIE1_IO_BUS_BASE, + MVEBU_MBUS_PCI_IO); + mvebu_mbus_add_window_remap_flags("pcie1.0", + KIRKWOOD_PCIE1_MEM_PHYS_BASE, + KIRKWOOD_PCIE1_MEM_SIZE, + MVEBU_MBUS_NO_REMAP, + MVEBU_MBUS_PCI_MEM); + vga_base = KIRKWOOD_PCIE_MEM_PHYS_BASE; if (portmask & KW_PCIE0) diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 80a8bca..9eb63d7 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -10,12 +10,11 @@ config ARCH_MVEBU select PLAT_ORION select SPARSE_IRQ select CLKDEV_LOOKUP - select MVEBU_CLK_CORE - select MVEBU_CLK_CPU - select MVEBU_CLK_GATING select MVEBU_MBUS select ZONE_DMA if ARM_LPAE select ARCH_REQUIRE_GPIOLIB + select MIGHT_HAVE_PCI + select PCI_QUIRKS if PCI if ARCH_MVEBU @@ -30,6 +29,7 @@ config MACH_ARMADA_370_XP config MACH_ARMADA_370 bool "Marvell Armada 370 boards" + select ARMADA_370_CLK select MACH_ARMADA_370_XP select PINCTRL_ARMADA_370 help @@ -38,6 +38,7 @@ config MACH_ARMADA_370 config MACH_ARMADA_XP bool "Marvell Armada XP boards" + select ARMADA_XP_CLK select MACH_ARMADA_370_XP select PINCTRL_ARMADA_XP help diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index 1c48890..ebbc997 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -14,10 +14,10 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/clk-provider.h> #include <linux/of_platform.h> #include <linux/io.h> #include <linux/time-armada-370-xp.h> -#include <linux/clk/mvebu.h> #include <linux/dma-mapping.h> #include <linux/mbus.h> #include <linux/irqchip.h> @@ -45,7 +45,7 @@ void __init armada_370_xp_map_io(void) void __init armada_370_xp_timer_and_clk_init(void) { - mvebu_clocks_init(); + of_clk_init(NULL); armada_370_xp_timer_init(); } diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 00f890e..72cab3f 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -238,8 +238,8 @@ extern void omap_do_wfi(void); #ifdef CONFIG_SMP /* Needed for secondary core boot */ -extern void omap_secondary_startup(void); -extern void omap_secondary_startup_4460(void); +extern void omap4_secondary_startup(void); +extern void omap4460_secondary_startup(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 0ea09fa..4ea3081 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -49,7 +49,7 @@ END(omap5_secondary_startup) * The primary core will update this flag using a hardware * register AuxCoreBoot0. */ -ENTRY(omap_secondary_startup) +ENTRY(omap4_secondary_startup) hold: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 @@ -64,9 +64,9 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -ENDPROC(omap_secondary_startup) +ENDPROC(omap4_secondary_startup) -ENTRY(omap_secondary_startup_4460) +ENTRY(omap4460_secondary_startup) hold_2: ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 @@ -101,4 +101,4 @@ hold_2: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -ENDPROC(omap_secondary_startup_4460) +ENDPROC(omap4460_secondary_startup) diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index e80327b..f993a41 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -71,10 +71,43 @@ struct omap4_cpu_pm_info { void (*secondary_startup)(void); }; +/** + * struct cpu_pm_ops - CPU pm operations + * @finish_suspend: CPU suspend finisher function pointer + * @resume: CPU resume function pointer + * @scu_prepare: CPU Snoop Control program function pointer + * + * Structure holds functions pointer for CPU low power operations like + * suspend, resume and scu programming. + */ +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); +}; + static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; static void __iomem *sar_base; +static int default_finish_suspend(unsigned long cpu_state) +{ + omap_do_wfi(); + return 0; +} + +static void dummy_cpu_resume(void) +{} + +static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) +{} + +struct cpu_pm_ops omap_pm_ops = { + .finish_suspend = default_finish_suspend, + .resume = dummy_cpu_resume, + .scu_prepare = dummy_scu_prepare, +}; + /* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup. @@ -158,11 +191,12 @@ static void save_l2x0_context(void) { u32 val; void __iomem *l2x0_base = omap4_get_l2cache_base(); - - val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); - __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); - val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); - __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); + if (l2x0_base) { + val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); + __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); + val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); + __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); + } } #else static void save_l2x0_context(void) @@ -225,14 +259,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) cpu_clear_prev_logic_pwrst(cpu); pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); - set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); - scu_pwrst_prepare(cpu, power_state); + set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); + omap_pm_ops.scu_prepare(cpu, power_state); l2x0_pwrst_prepare(cpu, save_state); /* * Call low level function with targeted low power state. */ - cpu_suspend(save_state, omap4_finish_suspend); + if (save_state) + cpu_suspend(save_state, omap_pm_ops.finish_suspend); + else + omap_pm_ops.finish_suspend(save_state); /* * Restore the CPUx power state to ON otherwise CPUx @@ -268,14 +305,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) 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)); - scu_pwrst_prepare(cpu, power_state); + omap_pm_ops.scu_prepare(cpu, power_state); /* * CPU never retuns back if targeted power state is OFF mode. * CPU ONLINE follows normal CPU ONLINE ptah via - * omap_secondary_startup(). + * omap4_secondary_startup(). */ - omap4_finish_suspend(cpu_state); + omap_pm_ops.finish_suspend(cpu_state); pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); return 0; @@ -319,9 +356,9 @@ int __init omap4_mpuss_init(void) 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 = omap_secondary_startup_4460; + pm_info->secondary_startup = omap4460_secondary_startup; else - pm_info->secondary_startup = omap_secondary_startup; + pm_info->secondary_startup = omap4_secondary_startup; pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); if (!pm_info->pwrdm) { @@ -352,6 +389,12 @@ int __init omap4_mpuss_init(void) save_l2x0_context(); + if (cpu_is_omap44xx()) { + omap_pm_ops.finish_suspend = omap4_finish_suspend; + omap_pm_ops.resume = omap4_cpu_resume; + omap_pm_ops.scu_prepare = scu_pwrst_prepare; + } + return 0; } diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 2a551f9..98a1146 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -87,7 +87,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * /* * Update the AuxCoreBoot0 with boot state for secondary core. - * omap_secondary_startup() routine will hold the secondary core till + * omap4_secondary_startup() routine will hold the secondary core till * the AuxCoreBoot1 register is updated with cpu state * A barrier is added to ensure that write buffer is drained */ @@ -200,7 +200,7 @@ static void __init omap4_smp_init_cpus(void) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { - void *startup_addr = omap_secondary_startup; + void *startup_addr = omap4_secondary_startup; void __iomem *base = omap_get_wakeupgen_base(); /* @@ -211,7 +211,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) scu_enable(scu_base); if (cpu_is_omap446x()) { - startup_addr = omap_secondary_startup_4460; + startup_addr = omap4460_secondary_startup; pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; } diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index a251f87..82f06989 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -1,7 +1,7 @@ /* - * OMAP4 Power Management Routines + * OMAP4+ Power Management Routines * - * Copyright (C) 2010-2011 Texas Instruments, Inc. + * Copyright (C) 2010-2013 Texas Instruments, Inc. * Rajendra Nayak <rnayak@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.com> * @@ -135,16 +135,16 @@ static void omap_default_idle(void) } /** - * omap4_pm_init - Init routine for OMAP4 PM + * omap4_init_static_deps - Add OMAP4 static dependencies * - * Initializes all powerdomain and clockdomain target states - * and all PRCM settings. + * Add needed static clockdomain dependencies on OMAP4 devices. + * Return: 0 on success or 'err' on failures */ -int __init omap4_pm_init(void) +static inline int omap4_init_static_deps(void) { - int ret; struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; struct clockdomain *ducati_clkdm, *l3_2_clkdm; + int ret = 0; if (omap_rev() == OMAP4430_REV_ES1_0) { WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); @@ -163,7 +163,7 @@ int __init omap4_pm_init(void) ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains\n"); - goto err2; + return ret; } /* @@ -171,6 +171,10 @@ int __init omap4_pm_init(void) * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as * expected. The hardware recommendation is to enable static * dependencies for these to avoid system lock ups or random crashes. + * The L4 wakeup depedency is added to workaround the OCP sync hardware + * BUG with 32K synctimer which lead to incorrect timer value read + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which + * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); @@ -179,7 +183,7 @@ int __init omap4_pm_init(void) ducati_clkdm = clkdm_lookup("ducati_clkdm"); if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l3_2_clkdm) || (!ducati_clkdm)) - goto err2; + return -EINVAL; ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); @@ -188,9 +192,42 @@ int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); if (ret) { pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); + return -EINVAL; + } + + return ret; +} + +/** + * omap4_pm_init - Init routine for OMAP4+ devices + * + * Initializes all powerdomain and clockdomain target states + * and all PRCM settings. + * Return: Returns the error code returned by called functions. + */ +int __init omap4_pm_init(void) +{ + int ret = 0; + + if (omap_rev() == OMAP4430_REV_ES1_0) { + WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); + return -ENODEV; + } + + pr_info("Power Management for TI OMAP4+ devices.\n"); + + ret = pwrdm_for_each(pwrdms_setup, NULL); + if (ret) { + pr_err("Failed to setup powerdomains.\n"); goto err2; } + if (cpu_is_omap44xx()) { + ret = omap4_init_static_deps(); + if (ret) + goto err2; + } + ret = omap4_mpuss_init(); if (ret) { pr_err("Failed to initialise OMAP4 MPUSS\n"); @@ -206,7 +243,8 @@ int __init omap4_pm_init(void) /* Overwrite the default cpu_do_idle() */ arm_pm_idle = omap_default_idle; - omap4_idle_init(); + if (cpu_is_omap44xx()) + omap4_idle_init(); err2: return ret; diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c index ab1700e..b7e0946 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2412.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2412.c @@ -35,121 +35,95 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { [DMACH_XD0] = { .name = "xdreq0", .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), - .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0), }, [DMACH_XD1] = { .name = "xdreq1", .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), - .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1), }, [DMACH_SDI] = { .name = "sdi", .channels = MAP(S3C2412_DMAREQSEL_SDI), - .channels_rx = MAP(S3C2412_DMAREQSEL_SDI), }, - [DMACH_SPI0] = { - .name = "spi0", + [DMACH_SPI0_RX] = { + .name = "spi0-rx", + .channels = MAP(S3C2412_DMAREQSEL_SPI0RX), + }, + [DMACH_SPI0_TX] = { + .name = "spi0-tx", .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), - .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX), }, - [DMACH_SPI1] = { - .name = "spi1", + [DMACH_SPI1_RX] = { + .name = "spi1-rx", + .channels = MAP(S3C2412_DMAREQSEL_SPI1RX), + }, + [DMACH_SPI1_TX] = { + .name = "spi1-tx", .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), - .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX), }, [DMACH_UART0] = { .name = "uart0", .channels = MAP(S3C2412_DMAREQSEL_UART0_0), - .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0), }, [DMACH_UART1] = { .name = "uart1", .channels = MAP(S3C2412_DMAREQSEL_UART1_0), - .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0), }, [DMACH_UART2] = { .name = "uart2", .channels = MAP(S3C2412_DMAREQSEL_UART2_0), - .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0), }, [DMACH_UART0_SRC2] = { .name = "uart0", .channels = MAP(S3C2412_DMAREQSEL_UART0_1), - .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1), }, [DMACH_UART1_SRC2] = { .name = "uart1", .channels = MAP(S3C2412_DMAREQSEL_UART1_1), - .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1), }, [DMACH_UART2_SRC2] = { .name = "uart2", .channels = MAP(S3C2412_DMAREQSEL_UART2_1), - .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1), }, [DMACH_TIMER] = { .name = "timer", .channels = MAP(S3C2412_DMAREQSEL_TIMER), - .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER), }, [DMACH_I2S_IN] = { .name = "i2s-sdi", .channels = MAP(S3C2412_DMAREQSEL_I2SRX), - .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX), }, [DMACH_I2S_OUT] = { .name = "i2s-sdo", .channels = MAP(S3C2412_DMAREQSEL_I2STX), - .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX), }, [DMACH_USB_EP1] = { .name = "usb-ep1", .channels = MAP(S3C2412_DMAREQSEL_USBEP1), - .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1), }, [DMACH_USB_EP2] = { .name = "usb-ep2", .channels = MAP(S3C2412_DMAREQSEL_USBEP2), - .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2), }, [DMACH_USB_EP3] = { .name = "usb-ep3", .channels = MAP(S3C2412_DMAREQSEL_USBEP3), - .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3), }, [DMACH_USB_EP4] = { .name = "usb-ep4", .channels = MAP(S3C2412_DMAREQSEL_USBEP4), - .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4), }, }; -static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map, - enum dma_data_direction dir) -{ - unsigned long chsel; - - if (dir == DMA_FROM_DEVICE) - chsel = map->channels_rx[0]; - else - chsel = map->channels[0]; - - chsel &= ~DMA_CH_VALID; - chsel |= S3C2412_DMAREQSEL_HW; - - writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL); -} - static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, struct s3c24xx_dma_map *map) { - s3c2412_dma_direction(chan, map, chan->source); + unsigned long chsel = map->channels[0] & (~DMA_CH_VALID); + writel(chsel | S3C2412_DMAREQSEL_HW, + chan->regs + S3C2412_DMA_DMAREQSEL); } static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { .select = s3c2412_dma_select, - .direction = s3c2412_dma_direction, .dcon_mask = 0, .map = s3c2412_dma_mappings, .map_size = ARRAY_SIZE(s3c2412_dma_mappings), diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c index 5fe3539..95b9f75 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2443.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c @@ -128,7 +128,8 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { static void s3c2443_dma_select(struct s3c2410_dma_chan *chan, struct s3c24xx_dma_map *map) { - writel(map->channels[0] | S3C2443_DMAREQSEL_HW, + unsigned long chsel = map->channels[0] & (~DMA_CH_VALID); + writel(chsel | S3C2443_DMAREQSEL_HW, chan->regs + S3C2443_DMA_DMAREQSEL); } diff --git a/arch/arm/mach-s3c24xx/dma.c b/arch/arm/mach-s3c24xx/dma.c index aab6490..4a65cba 100644 --- a/arch/arm/mach-s3c24xx/dma.c +++ b/arch/arm/mach-s3c24xx/dma.c @@ -1159,9 +1159,6 @@ int s3c2410_dma_devconfig(enum dma_ch channel, return -EINVAL; } - if (dma_sel.direction != NULL) - (dma_sel.direction)(chan, chan->map, source); - return 0; } diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 1a517e2..5414402 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -36,7 +36,8 @@ config ARCH_R8A7740 select RENESAS_INTC_IRQPIN config ARCH_R8A7778 - bool "R-Car M1 (R8A77780)" + bool "R-Car M1A (R8A77781)" + select ARCH_WANT_OPTIONAL_GPIOLIB select CPU_V7 select SH_CLK_CPG select ARM_GIC @@ -169,6 +170,8 @@ config MACH_KZM9D config MACH_KZM9G bool "KZM-A9-GT board" depends on ARCH_SH73A0 + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select ARCH_REQUIRE_GPIOLIB select REGULATOR_FIXED_VOLTAGE if REGULATOR select SND_SOC_AK4642 if SND_SIMPLE_CARD diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 45f78ca..297bf5e 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -1026,10 +1026,8 @@ out: /* TouchScreen */ #ifdef CONFIG_AP4EVB_QHD -# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123 # define GPIO_TSC_PORT 123 #else /* WVGA */ -# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40 # define GPIO_TSC_PORT 40 #endif @@ -1037,22 +1035,12 @@ out: #define IRQ7 evt2irq(0x02e0) /* IRQ7A */ static int ts_get_pendown_state(void) { - int val; - - gpio_free(GPIO_TSC_IRQ); - - gpio_request_one(GPIO_TSC_PORT, GPIOF_IN, NULL); - - val = gpio_get_value(GPIO_TSC_PORT); - - gpio_request(GPIO_TSC_IRQ, NULL); - - return !val; + return !gpio_get_value(GPIO_TSC_PORT); } static int ts_init(void) { - gpio_request(GPIO_TSC_IRQ, NULL); + gpio_request_one(GPIO_TSC_PORT, GPIOF_IN, NULL); return 0; } @@ -1086,11 +1074,42 @@ static struct i2c_board_info i2c1_devices[] = { static const struct pinctrl_map ap4evb_pinctrl_map[] = { + /* CEU */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372", + "ceu_clk_0", "ceu"), + /* FSIA (AK4643) */ + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372", + "fsia_sclk_in", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372", + "fsia_data_in", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372", + "fsia_data_out", "fsia"), + /* FSIB (HDMI) */ + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-sh7372", + "fsib_mclk_in", "fsib"), + /* HDMI */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-sh7372", + "hdmi", "hdmi"), + /* KEYSC */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc", "pfc-sh7372", + "keysc_in04_0", "keysc"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc", "pfc-sh7372", + "keysc_out5", "keysc"), +#ifndef CONFIG_AP4EVB_QHD + /* LCDC */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh7372", + "lcd_data18", "lcd"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh7372", + "lcd_sync", "lcd"), +#endif /* MMCIF */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh7372", "mmc0_data8_0", "mmc0"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh7372", "mmc0_ctrl_0", "mmc0"), + /* SCIFA0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-sh7372", + "scifa0_data", "scifa0"), /* SDHI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372", "sdhi0_data4", "sdhi0"), @@ -1105,6 +1124,26 @@ static const struct pinctrl_map ap4evb_pinctrl_map[] = { "sdhi1_data4", "sdhi1"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh7372", "sdhi1_ctrl", "sdhi1"), + /* SMSC911X */ + PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-sh7372", + "bsc_cs5a", "bsc"), + PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-sh7372", + "intc_irq6_0", "intc"), + /* TSC2007 */ +#ifdef CONFIG_AP4EVB_QHD + PIN_MAP_MUX_GROUP_DEFAULT("1-0048", "pfc-sh7372", + "intc_irq28_0", "intc"), +#else /* WVGA */ + PIN_MAP_MUX_GROUP_DEFAULT("1-0048", "pfc-sh7372", + "intc_irq7_0", "intc"), +#endif + /* USBHS1 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a66597_hcd.1", "pfc-sh7372", + "usb1_vbus", "usb1"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a66597_hcd.1", "pfc-sh7372", + "usb1_otg_id_0", "usb1"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a66597_hcd.1", "pfc-sh7372", + "usb1_otg_ctrl_0", "usb1"), }; #define GPIO_PORT9CR IOMEM(0xE6051009) @@ -1137,36 +1176,16 @@ static void __init ap4evb_init(void) ARRAY_SIZE(ap4evb_pinctrl_map)); sh7372_pinmux_init(); - /* enable SCIFA0 */ - gpio_request(GPIO_FN_SCIFA0_TXD, NULL); - gpio_request(GPIO_FN_SCIFA0_RXD, NULL); - - /* enable SMSC911X */ - gpio_request(GPIO_FN_CS5A, NULL); - gpio_request(GPIO_FN_IRQ6_39, NULL); - /* enable Debug switch (S6) */ gpio_request_one(32, GPIOF_IN | GPIOF_EXPORT, NULL); gpio_request_one(33, GPIOF_IN | GPIOF_EXPORT, NULL); gpio_request_one(34, GPIOF_IN | GPIOF_EXPORT, NULL); gpio_request_one(35, GPIOF_IN | GPIOF_EXPORT, NULL); - /* USB enable */ - gpio_request(GPIO_FN_VBUS0_1, NULL); - gpio_request(GPIO_FN_IDIN_1_18, NULL); - gpio_request(GPIO_FN_PWEN_1_115, NULL); - gpio_request(GPIO_FN_OVCN_1_114, NULL); - gpio_request(GPIO_FN_EXTLP_1, NULL); - gpio_request(GPIO_FN_OVCN2_1, NULL); - /* setup USB phy */ __raw_writew(0x8a0a, IOMEM(0xE6058130)); /* USBCR4 */ - /* enable FSI2 port A (ak4643) */ - gpio_request(GPIO_FN_FSIAIBT, NULL); - gpio_request(GPIO_FN_FSIAILR, NULL); - gpio_request(GPIO_FN_FSIAISLD, NULL); - gpio_request(GPIO_FN_FSIAOSLD, NULL); + /* FSI2 port A (ak4643) */ gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */ gpio_request(9, NULL); @@ -1177,8 +1196,7 @@ static void __init ap4evb_init(void) /* card detect pin for MMC slot (CN7) */ gpio_request_one(41, GPIOF_IN, NULL); - /* setup FSI2 port B (HDMI) */ - gpio_request(GPIO_FN_FSIBCK, NULL); + /* FSI2 port B (HDMI) */ __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */ /* set SPU2 clock to 119.6 MHz */ @@ -1208,18 +1226,6 @@ static void __init ap4evb_init(void) * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON. */ - /* enable KEYSC */ - gpio_request(GPIO_FN_KEYOUT0, NULL); - gpio_request(GPIO_FN_KEYOUT1, NULL); - gpio_request(GPIO_FN_KEYOUT2, NULL); - gpio_request(GPIO_FN_KEYOUT3, NULL); - gpio_request(GPIO_FN_KEYOUT4, NULL); - gpio_request(GPIO_FN_KEYIN0_136, NULL); - gpio_request(GPIO_FN_KEYIN1_135, NULL); - gpio_request(GPIO_FN_KEYIN2_134, NULL); - gpio_request(GPIO_FN_KEYIN3_133, NULL); - gpio_request(GPIO_FN_KEYIN4, NULL); - /* enable TouchScreen */ irq_set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW); @@ -1241,28 +1247,6 @@ static void __init ap4evb_init(void) * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF. */ - - gpio_request(GPIO_FN_LCDD17, NULL); - gpio_request(GPIO_FN_LCDD16, NULL); - gpio_request(GPIO_FN_LCDD15, NULL); - gpio_request(GPIO_FN_LCDD14, NULL); - gpio_request(GPIO_FN_LCDD13, NULL); - gpio_request(GPIO_FN_LCDD12, NULL); - gpio_request(GPIO_FN_LCDD11, NULL); - gpio_request(GPIO_FN_LCDD10, NULL); - gpio_request(GPIO_FN_LCDD9, NULL); - gpio_request(GPIO_FN_LCDD8, NULL); - gpio_request(GPIO_FN_LCDD7, NULL); - gpio_request(GPIO_FN_LCDD6, NULL); - gpio_request(GPIO_FN_LCDD5, NULL); - gpio_request(GPIO_FN_LCDD4, NULL); - gpio_request(GPIO_FN_LCDD3, NULL); - gpio_request(GPIO_FN_LCDD2, NULL); - gpio_request(GPIO_FN_LCDD1, NULL); - gpio_request(GPIO_FN_LCDD0, NULL); - gpio_request(GPIO_FN_LCDDISP, NULL); - gpio_request(GPIO_FN_LCDDCK, NULL); - gpio_request_one(189, GPIOF_OUT_INIT_HIGH, NULL); /* backlight */ gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */ @@ -1288,8 +1272,6 @@ static void __init ap4evb_init(void) */ /* MIPI-CSI stuff */ - gpio_request(GPIO_FN_VIO_CKO, NULL); - clk = clk_get(NULL, "vck1_clk"); if (!IS_ERR(clk)) { clk_set_rate(clk, clk_round_rate(clk, 13000000)); @@ -1299,10 +1281,6 @@ static void __init ap4evb_init(void) sh7372_add_standard_devices(); - /* HDMI */ - gpio_request(GPIO_FN_HDMI_HPD, NULL); - gpio_request(GPIO_FN_HDMI_CEC, NULL); - /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */ #define SRCR4 IOMEM(0xe61580bc) srcr4 = __raw_readl(SRCR4); diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index b85b288..44a6215 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -584,7 +584,7 @@ static struct regulator_init_data vcc_sdhi0_init_data = { static struct fixed_voltage_config vcc_sdhi0_info = { .supply_name = "SDHI0 Vcc", .microvolts = 3300000, - .gpio = GPIO_PORT75, + .gpio = 75, .enable_high = 1, .init_data = &vcc_sdhi0_init_data, }; @@ -615,7 +615,7 @@ static struct regulator_init_data vccq_sdhi0_init_data = { }; static struct gpio vccq_sdhi0_gpios[] = { - {GPIO_PORT17, GPIOF_OUT_INIT_LOW, "vccq-sdhi0" }, + {17, GPIOF_OUT_INIT_LOW, "vccq-sdhi0" }, }; static struct gpio_regulator_state vccq_sdhi0_states[] = { @@ -626,7 +626,7 @@ static struct gpio_regulator_state vccq_sdhi0_states[] = { static struct gpio_regulator_config vccq_sdhi0_info = { .supply_name = "vqmmc", - .enable_gpio = GPIO_PORT74, + .enable_gpio = 74, .enable_high = 1, .enabled_at_boot = 0, @@ -664,7 +664,7 @@ static struct regulator_init_data vcc_sdhi1_init_data = { static struct fixed_voltage_config vcc_sdhi1_info = { .supply_name = "SDHI1 Vcc", .microvolts = 3300000, - .gpio = GPIO_PORT16, + .gpio = 16, .enable_high = 1, .init_data = &vcc_sdhi1_init_data, }; @@ -693,7 +693,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = { .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, - .cd_gpio = GPIO_PORT167, + .cd_gpio = 167, }; static struct resource sdhi0_resources[] = { @@ -736,7 +736,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { MMC_CAP_POWER_OFF_CARD, .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, /* Port72 cannot generate IRQs, will be used in polling mode. */ - .cd_gpio = GPIO_PORT72, + .cd_gpio = 72, }; static struct resource sdhi1_resources[] = { @@ -1046,6 +1046,35 @@ static struct platform_device *eva_devices[] __initdata = { }; static const struct pinctrl_map eva_pinctrl_map[] = { + /* CEU0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740", + "ceu0_data_0_7", "ceu0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740", + "ceu0_clk_0", "ceu0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740", + "ceu0_sync", "ceu0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740", + "ceu0_field", "ceu0"), + /* FSIA */ + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740", + "fsia_sclk_in", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740", + "fsia_mclk_out", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740", + "fsia_data_in_1", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740", + "fsia_data_out_0", "fsia"), + /* FSIB */ + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-r8a7740", + "fsib_mclk_in", "fsib"), + /* GETHER */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740", + "gether_mii", "gether"), + PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740", + "gether_int", "gether"), + /* HDMI */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-r8a7740", + "hdmi", "hdmi"), /* LCD0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740", "lcd0_data24_0", "lcd0"), @@ -1058,6 +1087,9 @@ static const struct pinctrl_map eva_pinctrl_map[] = { "mmc0_data8_1", "mmc0"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a7740", "mmc0_ctrl_1", "mmc0"), + /* SCIFA1 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.1", "pfc-r8a7740", + "scifa1_data", "scifa1"), /* SDHI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740", "sdhi0_data4", "sdhi0"), @@ -1065,6 +1097,12 @@ static const struct pinctrl_map eva_pinctrl_map[] = { "sdhi0_ctrl", "sdhi0"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740", "sdhi0_wp", "sdhi0"), + /* ST1232 */ + PIN_MAP_MUX_GROUP_DEFAULT("0-0055", "pfc-r8a7740", + "intc_irq10", "intc"), + /* USBHS */ + PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7740", + "intc_irq7_1", "intc"), }; static void __init eva_clock_init(void) @@ -1119,40 +1157,14 @@ static void __init eva_init(void) r8a7740_pinmux_init(); r8a7740_meram_workaround(); - /* SCIFA1 */ - gpio_request(GPIO_FN_SCIFA1_RXD, NULL); - gpio_request(GPIO_FN_SCIFA1_TXD, NULL); - /* LCDC0 */ - gpio_request(GPIO_FN_LCDC0_SELECT, NULL); - gpio_request_one(61, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */ gpio_request_one(202, GPIOF_OUT_INIT_LOW, NULL); /* LCD0_LED_CONT */ /* Touchscreen */ - gpio_request(GPIO_FN_IRQ10, NULL); /* TP_INT */ + gpio_request_one(166, GPIOF_OUT_INIT_HIGH, NULL); /* TP_RST_B */ /* GETHER */ - gpio_request(GPIO_FN_ET_CRS, NULL); - gpio_request(GPIO_FN_ET_MDC, NULL); - gpio_request(GPIO_FN_ET_MDIO, NULL); - gpio_request(GPIO_FN_ET_TX_ER, NULL); - gpio_request(GPIO_FN_ET_RX_ER, NULL); - gpio_request(GPIO_FN_ET_ERXD0, NULL); - gpio_request(GPIO_FN_ET_ERXD1, NULL); - gpio_request(GPIO_FN_ET_ERXD2, NULL); - gpio_request(GPIO_FN_ET_ERXD3, NULL); - gpio_request(GPIO_FN_ET_TX_CLK, NULL); - gpio_request(GPIO_FN_ET_TX_EN, NULL); - gpio_request(GPIO_FN_ET_ETXD0, NULL); - gpio_request(GPIO_FN_ET_ETXD1, NULL); - gpio_request(GPIO_FN_ET_ETXD2, NULL); - gpio_request(GPIO_FN_ET_ETXD3, NULL); - gpio_request(GPIO_FN_ET_PHY_INT, NULL); - gpio_request(GPIO_FN_ET_COL, NULL); - gpio_request(GPIO_FN_ET_RX_DV, NULL); - gpio_request(GPIO_FN_ET_RX_CLK, NULL); - gpio_request_one(18, GPIOF_OUT_INIT_HIGH, NULL); /* PHY_RST */ /* USB */ @@ -1163,34 +1175,17 @@ static void __init eva_init(void) } else { /* USB Func */ /* - * A1 chip has 2 IRQ7 pin and it was controled by MSEL register. - * OTOH, usbhs interrupt needs its value (HI/LOW) to decide - * USB connection/disconnection (usbhsf_get_vbus()). - * This means we needs to select GPIO_FN_IRQ7_PORT209 first, - * and select GPIO 209 here + * The USBHS interrupt handlers needs to read the IRQ pin value + * (HI/LOW) to diffentiate USB connection and disconnection + * events (usbhsf_get_vbus()). We thus need to select both the + * intc_irq7_1 pin group and GPIO 209 here. */ - gpio_request(GPIO_FN_IRQ7_PORT209, NULL); gpio_request_one(209, GPIOF_IN, NULL); platform_device_register(&usbhsf_device); usb = &usbhsf_device; } - /* CEU0 */ - gpio_request(GPIO_FN_VIO0_D7, NULL); - gpio_request(GPIO_FN_VIO0_D6, NULL); - gpio_request(GPIO_FN_VIO0_D5, NULL); - gpio_request(GPIO_FN_VIO0_D4, NULL); - gpio_request(GPIO_FN_VIO0_D3, NULL); - gpio_request(GPIO_FN_VIO0_D2, NULL); - gpio_request(GPIO_FN_VIO0_D1, NULL); - gpio_request(GPIO_FN_VIO0_D0, NULL); - gpio_request(GPIO_FN_VIO0_CLK, NULL); - gpio_request(GPIO_FN_VIO0_HD, NULL); - gpio_request(GPIO_FN_VIO0_VD, NULL); - gpio_request(GPIO_FN_VIO0_FIELD, NULL); - gpio_request(GPIO_FN_VIO_CKO, NULL); - /* CON1/CON15 Camera */ gpio_request_one(173, GPIOF_OUT_INIT_LOW, NULL); /* STANDBY */ gpio_request_one(172, GPIOF_OUT_INIT_HIGH, NULL); /* RST */ @@ -1198,24 +1193,11 @@ static void __init eva_init(void) gpio_request_one(158, GPIOF_OUT_INIT_LOW, NULL); /* CAM_PON */ /* FSI-WM8978 */ - gpio_request(GPIO_FN_FSIAIBT, NULL); - gpio_request(GPIO_FN_FSIAILR, NULL); - gpio_request(GPIO_FN_FSIAOMC, NULL); - gpio_request(GPIO_FN_FSIAOSLD, NULL); - gpio_request(GPIO_FN_FSIAISLD_PORT5, NULL); - gpio_request(7, NULL); gpio_request(8, NULL); gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */ gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */ - /* FSI-HDMI */ - gpio_request(GPIO_FN_FSIBCK, NULL); - - /* HDMI */ - gpio_request(GPIO_FN_HDMI_HPD, NULL); - gpio_request(GPIO_FN_HDMI_CEC, NULL); - /* * CAUTION * diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index 38e5e50..dac4365 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <linux/pinctrl/machine.h> #include <linux/platform_device.h> #include <linux/smsc911x.h> #include <mach/common.h> @@ -37,6 +38,14 @@ static struct resource smsc911x_resources[] = { DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */ }; +static const struct pinctrl_map bockw_pinctrl_map[] = { + /* SCIF0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778", + "scif0_data_a", "scif0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778", + "scif0_ctrl", "scif0"), +}; + #define IRQ0MR 0x30 static void __init bockw_init(void) { @@ -46,6 +55,10 @@ static void __init bockw_init(void) r8a7778_init_irq_extpin(1); r8a7778_add_standard_devices(); + pinctrl_register_mappings(bockw_pinctrl_map, + ARRAY_SIZE(bockw_pinctrl_map)); + r8a7778_pinmux_init(); + fpga = ioremap_nocache(0x18200000, SZ_1M); if (fpga) { /* diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c index 70d992c..b373e9c 100644 --- a/arch/arm/mach-shmobile/board-bonito.c +++ b/arch/arm/mach-shmobile/board-bonito.c @@ -331,12 +331,6 @@ static struct platform_device smsc_device = { }; /* - * core board devices - */ -static struct platform_device *bonito_core_devices[] __initdata = { -}; - -/* * base board devices */ static struct platform_device *bonito_base_devices[] __initdata = { @@ -375,12 +369,37 @@ static void __init bonito_map_io(void) #define VCCQ1CR IOMEM(0xE6058140) #define VCCQ1LCDCR IOMEM(0xE6058186) +/* + * HACK: The FPGA mappings should be associated with the FPGA device, but we + * don't have one at the moment. Associate them with the PFC device to make + * sure they will be applied. + */ +static const struct pinctrl_map fpga_pinctrl_map[] = { + /* FPGA */ + PIN_MAP_MUX_GROUP_DEFAULT("pfc-r8a7740", "pfc-r8a7740", + "bsc_cs5a_0", "bsc"), + PIN_MAP_MUX_GROUP_DEFAULT("pfc-r8a7740", "pfc-r8a7740", + "bsc_cs5b", "bsc"), + PIN_MAP_MUX_GROUP_DEFAULT("pfc-r8a7740", "pfc-r8a7740", + "bsc_cs6a", "bsc"), + PIN_MAP_MUX_GROUP_DEFAULT("pfc-r8a7740", "pfc-r8a7740", + "intc_irq10", "intc"), +}; + +static const struct pinctrl_map scifa5_pinctrl_map[] = { + /* SCIFA5 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.5", "pfc-r8a7740", + "scifa5_data_2", "scifa5"), +}; + static void __init bonito_init(void) { u16 val; regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + pinctrl_register_mappings(fpga_pinctrl_map, + ARRAY_SIZE(fpga_pinctrl_map)); r8a7740_pinmux_init(); bonito_fpga_init(); @@ -397,9 +416,6 @@ static void __init bonito_init(void) r8a7740_add_standard_devices(); - platform_add_devices(bonito_core_devices, - ARRAY_SIZE(bonito_core_devices)); - /* * base board settings */ @@ -409,14 +425,6 @@ static void __init bonito_init(void) u16 bsw3; u16 bsw4; - /* - * FPGA - */ - gpio_request(GPIO_FN_CS5B, NULL); - gpio_request(GPIO_FN_CS6A, NULL); - gpio_request(GPIO_FN_CS5A_PORT105, NULL); - gpio_request(GPIO_FN_IRQ10, NULL); - val = bonito_fpga_read(BVERR); pr_info("bonito version: cpu %02x, base %02x\n", ((val >> 8) & 0xFF), @@ -432,8 +440,8 @@ static void __init bonito_init(void) if (BIT_OFF(bsw2, 1) && /* S38.3 = ON */ BIT_OFF(bsw3, 9) && /* S39.6 = ON */ BIT_OFF(bsw4, 4)) { /* S43.1 = ON */ - gpio_request(GPIO_FN_SCIFA5_TXD_PORT91, NULL); - gpio_request(GPIO_FN_SCIFA5_RXD_PORT92, NULL); + pinctrl_register_mappings(scifa5_pinctrl_map, + ARRAY_SIZE(scifa5_pinctrl_map)); } /* @@ -443,7 +451,6 @@ static void __init bonito_init(void) BIT_ON(bsw2, 2)) { /* S38.2 = OFF */ pinctrl_register_mappings(lcdc0_pinctrl_map, ARRAY_SIZE(lcdc0_pinctrl_map)); - gpio_request(GPIO_FN_LCDC0_SELECT, NULL); gpio_request_one(61, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */ diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index aefa50d..44055fe 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -79,7 +79,6 @@ static void __init kzm_init(void) sh73a0_pinmux_init(); /* enable SD */ - gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL); gpio_request_one(15, GPIOF_OUT_INIT_HIGH, NULL); /* power */ gpio_request_one(14, GPIOF_OUT_INIT_HIGH, NULL); /* power */ diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index e6b775a..1fdf05c 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -663,13 +663,13 @@ static unsigned long pin_pullup_conf[] = { static const struct pinctrl_map kzm_pinctrl_map[] = { /* FSIA (AK4648) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", + PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", "fsia_mclk_in", "fsia"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", + PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", "fsia_sclk_in", "fsia"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", + PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", "fsia_data_in", "fsia"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", + PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", "fsia_data_out", "fsia"), /* I2C3 */ PIN_MAP_MUX_GROUP_DEFAULT("i2c-sh_mobile.3", "pfc-sh73a0", @@ -788,9 +788,6 @@ static void __init kzm_init(void) /* Touchscreen */ gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */ - /* enable SD */ - gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL); - #ifdef CONFIG_CACHE_L2X0 /* Early BRESP enable, Shared attribute override enable, 64K*8way */ l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index f587187..6114edd 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -21,15 +21,30 @@ #include <linux/interrupt.h> #include <linux/irqchip.h> #include <linux/kernel.h> +#include <linux/pinctrl/machine.h> #include <linux/platform_device.h> #include <mach/common.h> #include <mach/r8a7790.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +static const struct pinctrl_map lager_pinctrl_map[] = { + /* SCIF0 (CN19: DEBUG SERIAL0) */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790", + "scif0_data", "scif0"), + /* SCIF1 (CN20: DEBUG SERIAL1) */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7790", + "scif1_data", "scif1"), +}; + static void __init lager_add_standard_devices(void) { r8a7790_clock_init(); + + pinctrl_register_mappings(lager_pinctrl_map, + ARRAY_SIZE(lager_pinctrl_map)); + r8a7790_pinmux_init(); + r8a7790_add_standard_devices(); } diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index fa3407d..85f51a8 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1309,6 +1309,49 @@ static struct i2c_board_info i2c1_devices[] = { }; static const struct pinctrl_map mackerel_pinctrl_map[] = { + /* ADXL34X */ + PIN_MAP_MUX_GROUP_DEFAULT("1-0053", "pfc-sh7372", + "intc_irq21", "intc"), + /* CEU */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372", + "ceu_data_0_7", "ceu"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372", + "ceu_clk_0", "ceu"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372", + "ceu_sync", "ceu"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372", + "ceu_field", "ceu"), + /* FLCTL */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_flctl.0", "pfc-sh7372", + "flctl_data", "flctl"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_flctl.0", "pfc-sh7372", + "flctl_ce0", "flctl"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_flctl.0", "pfc-sh7372", + "flctl_ctrl", "flctl"), + /* FSIA (AK4643) */ + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372", + "fsia_sclk_in", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372", + "fsia_data_in", "fsia"), + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372", + "fsia_data_out", "fsia"), + /* FSIB (HDMI) */ + PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-sh7372", + "fsib_mclk_in", "fsib"), + /* HDMI */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-sh7372", + "hdmi", "hdmi"), + /* LCDC */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh7372", + "lcd_data24", "lcd"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh7372", + "lcd_sync", "lcd"), + /* SCIFA0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-sh7372", + "scifa0_data", "scifa0"), + /* SCIFA2 (GT-720F GPS module) */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-sh7372", + "scifa2_data", "scifa2"), /* SDHI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372", "sdhi0_data4", "sdhi0"), @@ -1316,6 +1359,8 @@ static const struct pinctrl_map mackerel_pinctrl_map[] = { "sdhi0_ctrl", "sdhi0"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372", "sdhi0_wp", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372", + "intc_irq26_1", "intc"), /* SDHI1 */ #if !IS_ENABLED(CONFIG_MMC_SH_MMCIF) PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh7372", @@ -1334,6 +1379,25 @@ static const struct pinctrl_map mackerel_pinctrl_map[] = { "sdhi2_data4", "sdhi2"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-sh7372", "sdhi2_ctrl", "sdhi2"), + /* SMSC911X */ + PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-sh7372", + "bsc_cs5a", "bsc"), + PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-sh7372", + "intc_irq6_0", "intc"), + /* ST1232 */ + PIN_MAP_MUX_GROUP_DEFAULT("0-0055", "pfc-sh7372", + "intc_irq7_0", "intc"), + /* TCA6416 */ + PIN_MAP_MUX_GROUP_DEFAULT("0-0020", "pfc-sh7372", + "intc_irq9_0", "intc"), + /* USBHS0 */ + PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.0", "pfc-sh7372", + "usb0_vbus", "usb0"), + /* USBHS1 */ + PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372", + "usb1_vbus", "usb1"), + PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372", + "usb1_otg_id_0", "usb1"), }; #define GPIO_PORT9CR IOMEM(0xE6051009) @@ -1377,61 +1441,18 @@ static void __init mackerel_init(void) ARRAY_SIZE(mackerel_pinctrl_map)); sh7372_pinmux_init(); - /* enable SCIFA0 */ - gpio_request(GPIO_FN_SCIFA0_TXD, NULL); - gpio_request(GPIO_FN_SCIFA0_RXD, NULL); - - /* enable SMSC911X */ - gpio_request(GPIO_FN_CS5A, NULL); - gpio_request(GPIO_FN_IRQ6_39, NULL); - - /* LCDC */ - gpio_request(GPIO_FN_LCDD23, NULL); - gpio_request(GPIO_FN_LCDD22, NULL); - gpio_request(GPIO_FN_LCDD21, NULL); - gpio_request(GPIO_FN_LCDD20, NULL); - gpio_request(GPIO_FN_LCDD19, NULL); - gpio_request(GPIO_FN_LCDD18, NULL); - gpio_request(GPIO_FN_LCDD17, NULL); - gpio_request(GPIO_FN_LCDD16, NULL); - gpio_request(GPIO_FN_LCDD15, NULL); - gpio_request(GPIO_FN_LCDD14, NULL); - gpio_request(GPIO_FN_LCDD13, NULL); - gpio_request(GPIO_FN_LCDD12, NULL); - gpio_request(GPIO_FN_LCDD11, NULL); - gpio_request(GPIO_FN_LCDD10, NULL); - gpio_request(GPIO_FN_LCDD9, NULL); - gpio_request(GPIO_FN_LCDD8, NULL); - gpio_request(GPIO_FN_LCDD7, NULL); - gpio_request(GPIO_FN_LCDD6, NULL); - gpio_request(GPIO_FN_LCDD5, NULL); - gpio_request(GPIO_FN_LCDD4, NULL); - gpio_request(GPIO_FN_LCDD3, NULL); - gpio_request(GPIO_FN_LCDD2, NULL); - gpio_request(GPIO_FN_LCDD1, NULL); - gpio_request(GPIO_FN_LCDD0, NULL); - gpio_request(GPIO_FN_LCDDISP, NULL); - gpio_request(GPIO_FN_LCDDCK, NULL); - /* backlight, off by default */ gpio_request_one(31, GPIOF_OUT_INIT_LOW, NULL); gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */ /* USBHS0 */ - gpio_request(GPIO_FN_VBUS0_0, NULL); gpio_request_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */ /* USBHS1 */ - gpio_request(GPIO_FN_VBUS0_1, NULL); gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */ - gpio_request(GPIO_FN_IDIN_1_113, NULL); - /* enable FSI2 port A (ak4643) */ - gpio_request(GPIO_FN_FSIAIBT, NULL); - gpio_request(GPIO_FN_FSIAILR, NULL); - gpio_request(GPIO_FN_FSIAISLD, NULL); - gpio_request(GPIO_FN_FSIAOSLD, NULL); + /* FSI2 port A (ak4643) */ gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */ gpio_request(9, NULL); @@ -1441,8 +1462,7 @@ static void __init mackerel_init(void) intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */ - /* setup FSI2 port B (HDMI) */ - gpio_request(GPIO_FN_FSIBCK, NULL); + /* FSI2 port B (HDMI) */ __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */ /* set SPU2 clock to 119.6 MHz */ @@ -1452,68 +1472,15 @@ static void __init mackerel_init(void) clk_put(clk); } - /* enable Keypad */ - gpio_request(GPIO_FN_IRQ9_42, NULL); + /* Keypad */ irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); - /* enable Touchscreen */ - gpio_request(GPIO_FN_IRQ7_40, NULL); + /* Touchscreen */ irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); - /* enable Accelerometer */ - gpio_request(GPIO_FN_IRQ21, NULL); + /* Accelerometer */ irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); - /* SDHI0 PORT172 card-detect IRQ26 */ - gpio_request(GPIO_FN_IRQ26_172, NULL); - - /* FLCTL */ - gpio_request(GPIO_FN_D0_NAF0, NULL); - gpio_request(GPIO_FN_D1_NAF1, NULL); - gpio_request(GPIO_FN_D2_NAF2, NULL); - gpio_request(GPIO_FN_D3_NAF3, NULL); - gpio_request(GPIO_FN_D4_NAF4, NULL); - gpio_request(GPIO_FN_D5_NAF5, NULL); - gpio_request(GPIO_FN_D6_NAF6, NULL); - gpio_request(GPIO_FN_D7_NAF7, NULL); - gpio_request(GPIO_FN_D8_NAF8, NULL); - gpio_request(GPIO_FN_D9_NAF9, NULL); - gpio_request(GPIO_FN_D10_NAF10, NULL); - gpio_request(GPIO_FN_D11_NAF11, NULL); - gpio_request(GPIO_FN_D12_NAF12, NULL); - gpio_request(GPIO_FN_D13_NAF13, NULL); - gpio_request(GPIO_FN_D14_NAF14, NULL); - gpio_request(GPIO_FN_D15_NAF15, NULL); - gpio_request(GPIO_FN_FCE0, NULL); - gpio_request(GPIO_FN_WE0_FWE, NULL); - gpio_request(GPIO_FN_FRB, NULL); - gpio_request(GPIO_FN_A4_FOE, NULL); - gpio_request(GPIO_FN_A5_FCDE, NULL); - gpio_request(GPIO_FN_RD_FSC, NULL); - - /* enable GPS module (GT-720F) */ - gpio_request(GPIO_FN_SCIFA2_TXD1, NULL); - gpio_request(GPIO_FN_SCIFA2_RXD1, NULL); - - /* CEU */ - gpio_request(GPIO_FN_VIO_CLK, NULL); - gpio_request(GPIO_FN_VIO_VD, NULL); - gpio_request(GPIO_FN_VIO_HD, NULL); - gpio_request(GPIO_FN_VIO_FIELD, NULL); - gpio_request(GPIO_FN_VIO_CKO, NULL); - gpio_request(GPIO_FN_VIO_D7, NULL); - gpio_request(GPIO_FN_VIO_D6, NULL); - gpio_request(GPIO_FN_VIO_D5, NULL); - gpio_request(GPIO_FN_VIO_D4, NULL); - gpio_request(GPIO_FN_VIO_D3, NULL); - gpio_request(GPIO_FN_VIO_D2, NULL); - gpio_request(GPIO_FN_VIO_D1, NULL); - gpio_request(GPIO_FN_VIO_D0, NULL); - - /* HDMI */ - gpio_request(GPIO_FN_HDMI_HPD, NULL); - gpio_request(GPIO_FN_HDMI_CEC, NULL); - /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */ srcr4 = __raw_readl(SRCR4); __raw_writel(srcr4 | (1 << 13), SRCR4); diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index b9594e9..9112fae 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -28,6 +28,7 @@ #include <linux/leds.h> #include <linux/dma-mapping.h> #include <linux/pinctrl/machine.h> +#include <linux/platform_data/gpio-rcar.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/smsc911x.h> @@ -173,15 +174,15 @@ static struct platform_device usb_phy_device = { static struct gpio_led marzen_leds[] = { { .name = "led2", - .gpio = 157, + .gpio = RCAR_GP_PIN(4, 29), .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "led3", - .gpio = 158, + .gpio = RCAR_GP_PIN(4, 30), .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "led4", - .gpio = 159, + .gpio = RCAR_GP_PIN(4, 31), .default_state = LEDS_GPIO_DEFSTATE_ON, }, }; diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index e710c00..f6227bb 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -22,15 +22,43 @@ #include <linux/kernel.h> #include <linux/sh_clk.h> #include <linux/clkdev.h> +#include <mach/clock.h> #include <mach/common.h> #define CPG_BASE 0xe6150000 #define CPG_LEN 0x270 -#define MPCKCR 0xe6150080 #define SMSTPCR2 0xe6150138 #define SMSTPCR5 0xe6150144 +#define FRQCRA 0xE6150000 +#define FRQCRB 0xE6150004 +#define VCLKCR1 0xE6150008 +#define VCLKCR2 0xE615000C +#define VCLKCR3 0xE615001C +#define VCLKCR4 0xE6150014 +#define VCLKCR5 0xE6150034 +#define ZBCKCR 0xE6150010 +#define SD0CKCR 0xE6150074 +#define SD1CKCR 0xE6150078 +#define SD2CKCR 0xE615007C +#define MMC0CKCR 0xE6150240 +#define MMC1CKCR 0xE6150244 +#define FSIACKCR 0xE6150018 +#define FSIBCKCR 0xE6150090 +#define MPCKCR 0xe6150080 +#define SPUVCKCR 0xE6150094 +#define HSICKCR 0xE615026C +#define M4CKCR 0xE6150098 +#define PLLECR 0xE61500D0 +#define PLL1CR 0xE6150028 +#define PLL2CR 0xE615002C +#define PLL2SCR 0xE61501F4 +#define PLL2HCR 0xE61501E4 +#define CKSCR 0xE61500C0 + +#define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base) + static struct clk_mapping cpg_mapping = { .phys = CPG_BASE, .len = CPG_LEN, @@ -51,29 +79,326 @@ static struct clk extal2_clk = { .mapping = &cpg_mapping, }; +static struct sh_clk_ops followparent_clk_ops = { + .recalc = followparent_recalc, +}; + +static struct clk main_clk = { + /* .parent will be set r8a73a4_clock_init */ + .ops = &followparent_clk_ops, +}; + +SH_CLK_RATIO(div2, 1, 2); +SH_CLK_RATIO(div4, 1, 4); + +SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2); +SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2); +SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); +SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); + +/* External FSIACK/FSIBCK clock */ +static struct clk fsiack_clk = { +}; + +static struct clk fsibck_clk = { +}; + +/* + * PLL clocks + */ +static struct clk *pll_parent_main[] = { + [0] = &main_clk, + [1] = &main_div2_clk +}; + +static struct clk *pll_parent_main_extal[8] = { + [0] = &main_div2_clk, + [1] = &extal2_div2_clk, + [3] = &extal2_div4_clk, + [4] = &main_clk, + [5] = &extal2_clk, +}; + +static unsigned long pll_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit)) + mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1); + + return clk->parent->rate * mult; +} + +static int pll_set_parent(struct clk *clk, struct clk *parent) +{ + u32 val; + int i, ret; + + if (!clk->parent_table || !clk->parent_num) + return -EINVAL; + + /* Search the parent */ + for (i = 0; i < clk->parent_num; i++) + if (clk->parent_table[i] == parent) + break; + + if (i == clk->parent_num) + return -ENODEV; + + ret = clk_reparent(clk, parent); + if (ret < 0) + return ret; + + val = ioread32(clk->mapped_reg) & + ~(((1 << clk->src_width) - 1) << clk->src_shift); + + iowrite32(val | i << clk->src_shift, clk->mapped_reg); + + return 0; +} + +static struct sh_clk_ops pll_clk_ops = { + .recalc = pll_recalc, + .set_parent = pll_set_parent, +}; + +#define PLL_CLOCK(name, p, pt, w, s, reg, e) \ + static struct clk name = { \ + .ops = &pll_clk_ops, \ + .flags = CLK_ENABLE_ON_INIT, \ + .parent = p, \ + .parent_table = pt, \ + .parent_num = ARRAY_SIZE(pt), \ + .src_width = w, \ + .src_shift = s, \ + .enable_reg = (void __iomem *)reg, \ + .enable_bit = e, \ + .mapping = &cpg_mapping, \ + } + +PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1); +PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2); +PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4); +PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5); + +SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2); + static struct clk *main_clks[] = { &extalr_clk, &extal1_clk, + &extal1_div2_clk, &extal2_clk, + &extal2_div2_clk, + &extal2_div4_clk, + &main_clk, + &main_div2_clk, + &fsiack_clk, + &fsibck_clk, + &pll1_clk, + &pll1_div2_clk, + &pll2_clk, + &pll2s_clk, + &pll2h_clk, +}; + +/* DIV4 */ +static void div4_kick(struct clk *clk) +{ + unsigned long value; + + /* set KICK bit in FRQCRB to update hardware setting */ + value = ioread32(CPG_MAP(FRQCRB)); + value |= (1 << 31); + iowrite32(value, CPG_MAP(FRQCRB)); +} + +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10}; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = divisors, + .nr_divisors = ARRAY_SIZE(divisors), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, + .kick = div4_kick, +}; + +enum { + DIV4_I, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, + DIV4_ZX, DIV4_ZS, DIV4_HP, + DIV4_NR }; + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 20, 0x0dff, CLK_ENABLE_ON_INIT), + [DIV4_M3] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), + [DIV4_B] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 8, 0x0dff, CLK_ENABLE_ON_INIT), + [DIV4_M1] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 4, 0x1dff, 0), + [DIV4_M2] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 0, 0x1dff, 0), + [DIV4_ZX] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 12, 0x0dff, 0), + [DIV4_ZS] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 8, 0x0dff, 0), + [DIV4_HP] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 4, 0x0dff, 0), }; enum { + DIV6_ZB, + DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2, + DIV6_MMC0, DIV6_MMC1, + DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VCK4, DIV6_VCK5, + DIV6_FSIA, DIV6_FSIB, + DIV6_MP, DIV6_M4, DIV6_HSI, DIV6_SPUV, + DIV6_NR }; + +static struct clk *div6_parents[8] = { + [0] = &pll1_div2_clk, + [1] = &pll2s_clk, + [3] = &extal2_clk, + [4] = &main_div2_clk, + [6] = &extalr_clk, +}; + +static struct clk *fsia_parents[4] = { + [0] = &pll1_div2_clk, + [1] = &pll2s_clk, + [2] = &fsiack_clk, +}; + +static struct clk *fsib_parents[4] = { + [0] = &pll1_div2_clk, + [1] = &pll2s_clk, + [2] = &fsibck_clk, +}; + +static struct clk *mp_parents[4] = { + [0] = &pll1_div2_clk, + [1] = &pll2s_clk, + [2] = &extal2_clk, + [3] = &extal2_clk, +}; + +static struct clk *m4_parents[2] = { + [0] = &pll2s_clk, +}; + +static struct clk *hsi_parents[4] = { + [0] = &pll2h_clk, + [1] = &pll1_div2_clk, + [3] = &pll2s_clk, +}; + +/*** FIXME *** + * SH_CLK_DIV6_EXT() macro doesn't care .mapping + * but, it is necessary on R-Car (= ioremap() base CPG) + * The difference between + * SH_CLK_DIV6_EXT() <--> SH_CLK_MAP_DIV6_EXT() + * is only .mapping + */ +#define SH_CLK_MAP_DIV6_EXT(_reg, _flags, _parents, \ + _num_parents, _src_shift, _src_width) \ +{ \ + .enable_reg = (void __iomem *)_reg, \ + .enable_bit = 0, /* unused */ \ + .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ + .div_mask = SH_CLK_DIV6_MSK, \ + .parent_table = _parents, \ + .parent_num = _num_parents, \ + .src_shift = _src_shift, \ + .src_width = _src_width, \ + .mapping = &cpg_mapping, \ +} + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_ZB] = SH_CLK_MAP_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT, + div6_parents, 2, 7, 1), + [DIV6_SDHI0] = SH_CLK_MAP_DIV6_EXT(SD0CKCR, 0, + div6_parents, 2, 6, 2), + [DIV6_SDHI1] = SH_CLK_MAP_DIV6_EXT(SD1CKCR, 0, + div6_parents, 2, 6, 2), + [DIV6_SDHI2] = SH_CLK_MAP_DIV6_EXT(SD2CKCR, 0, + div6_parents, 2, 6, 2), + [DIV6_MMC0] = SH_CLK_MAP_DIV6_EXT(MMC0CKCR, 0, + div6_parents, 2, 6, 2), + [DIV6_MMC1] = SH_CLK_MAP_DIV6_EXT(MMC1CKCR, 0, + div6_parents, 2, 6, 2), + [DIV6_VCK1] = SH_CLK_MAP_DIV6_EXT(VCLKCR1, 0, /* didn't care bit[6-7] */ + div6_parents, ARRAY_SIZE(div6_parents), 12, 3), + [DIV6_VCK2] = SH_CLK_MAP_DIV6_EXT(VCLKCR2, 0, /* didn't care bit[6-7] */ + div6_parents, ARRAY_SIZE(div6_parents), 12, 3), + [DIV6_VCK3] = SH_CLK_MAP_DIV6_EXT(VCLKCR3, 0, /* didn't care bit[6-7] */ + div6_parents, ARRAY_SIZE(div6_parents), 12, 3), + [DIV6_VCK4] = SH_CLK_MAP_DIV6_EXT(VCLKCR4, 0, /* didn't care bit[6-7] */ + div6_parents, ARRAY_SIZE(div6_parents), 12, 3), + [DIV6_VCK5] = SH_CLK_MAP_DIV6_EXT(VCLKCR5, 0, /* didn't care bit[6-7] */ + div6_parents, ARRAY_SIZE(div6_parents), 12, 3), + [DIV6_FSIA] = SH_CLK_MAP_DIV6_EXT(FSIACKCR, 0, + fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2), + [DIV6_FSIB] = SH_CLK_MAP_DIV6_EXT(FSIBCKCR, 0, + fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2), + [DIV6_MP] = SH_CLK_MAP_DIV6_EXT(MPCKCR, 0, /* it needs bit[9-11] control */ + mp_parents, ARRAY_SIZE(mp_parents), 6, 2), + /* pll2s will be selected always for M4 */ + [DIV6_M4] = SH_CLK_MAP_DIV6_EXT(M4CKCR, 0, /* it needs bit[9] control */ + m4_parents, ARRAY_SIZE(m4_parents), 6, 1), + [DIV6_HSI] = SH_CLK_MAP_DIV6_EXT(HSICKCR, 0, /* it needs bit[9] control */ + hsi_parents, ARRAY_SIZE(hsi_parents), 6, 2), + [DIV6_SPUV] = SH_CLK_MAP_DIV6_EXT(SPUVCKCR, 0, + mp_parents, ARRAY_SIZE(mp_parents), 6, 2), +}; + +/* MSTP */ +enum { MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP522, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { - [MSTP204] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ - [MSTP203] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ - [MSTP206] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ - [MSTP207] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ - [MSTP216] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ - [MSTP217] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 17, 0), /* SCIFB3 */ + [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 6, 0), /* SCIFB0 */ + [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ + [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ + [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ }; static struct clk_lookup lookups[] = { + /* main clock */ + CLKDEV_CON_ID("extal1", &extal1_clk), + CLKDEV_CON_ID("extal1_div2", &extal1_div2_clk), + CLKDEV_CON_ID("extal2", &extal2_clk), + CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), + CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), + CLKDEV_CON_ID("fsiack", &fsiack_clk), + CLKDEV_CON_ID("fsibck", &fsibck_clk), + + /* pll clock */ + CLKDEV_CON_ID("pll1", &pll1_clk), + CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), + CLKDEV_CON_ID("pll2", &pll2_clk), + CLKDEV_CON_ID("pll2s", &pll2s_clk), + CLKDEV_CON_ID("pll2h", &pll2h_clk), + + /* DIV6 */ + CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]), + CLKDEV_CON_ID("sdhi0", &div6_clks[DIV6_SDHI0]), + CLKDEV_CON_ID("sdhi1", &div6_clks[DIV6_SDHI1]), + CLKDEV_CON_ID("sdhi2", &div6_clks[DIV6_SDHI2]), + CLKDEV_CON_ID("mmc0", &div6_clks[DIV6_MMC0]), + CLKDEV_CON_ID("mmc1", &div6_clks[DIV6_MMC1]), + CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("vck4", &div6_clks[DIV6_VCK4]), + CLKDEV_CON_ID("vck5", &div6_clks[DIV6_VCK5]), + CLKDEV_CON_ID("fsia", &div6_clks[DIV6_FSIA]), + CLKDEV_CON_ID("fsib", &div6_clks[DIV6_FSIB]), + CLKDEV_CON_ID("mp", &div6_clks[DIV6_MP]), + CLKDEV_CON_ID("m4", &div6_clks[DIV6_M4]), + CLKDEV_CON_ID("hsi", &div6_clks[DIV6_HSI]), + CLKDEV_CON_ID("spuv", &div6_clks[DIV6_SPUV]), + + /* MSTP */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), @@ -88,22 +413,40 @@ static struct clk_lookup lookups[] = { void __init r8a73a4_clock_init(void) { - void __iomem *cpg_base, *reg; + void __iomem *reg; int k, ret = 0; + u32 ckscr; + + reg = ioremap_nocache(CKSCR, PAGE_SIZE); + BUG_ON(!reg); + ckscr = ioread32(reg); + iounmap(reg); - /* fix MPCLK to EXTAL2 for now. - * this is needed until more detailed clock topology is supported - */ - cpg_base = ioremap_nocache(CPG_BASE, CPG_LEN); - BUG_ON(!cpg_base); - reg = cpg_base + (MPCKCR - CPG_BASE); - iowrite32(ioread32(reg) | 1 << 7 | 0x0c, reg); /* set CKSEL */ - iounmap(cpg_base); + switch ((ckscr >> 28) & 0x3) { + case 0: + main_clk.parent = &extal1_clk; + break; + case 1: + main_clk.parent = &extal1_div2_clk; + break; + case 2: + main_clk.parent = &extal2_clk; + break; + case 3: + main_clk.parent = &extal2_div2_clk; + break; + } for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); + + if (!ret) ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); clkdev_add_table(lookups, ARRAY_SIZE(lookups)); diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index c0d39aa..7fd32d6 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c @@ -266,7 +266,7 @@ static struct clk fsiack_clk = { static struct clk fsibck_clk = { }; -struct clk *main_clks[] = { +static struct clk *main_clks[] = { &extalr_clk, &extal1_clk, &extal2_clk, @@ -317,7 +317,7 @@ enum { DIV4_NR }; -struct clk div4_clks[DIV4_NR] = { +static struct clk div4_clks[DIV4_NR] = { [DIV4_I] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT), [DIV4_ZG] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT), [DIV4_B] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT), @@ -461,7 +461,7 @@ enum { MSTP329, MSTP328, MSTP323, MSTP320, MSTP314, MSTP313, MSTP312, - MSTP309, + MSTP309, MSTP304, MSTP416, MSTP415, MSTP407, MSTP406, @@ -499,6 +499,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */ [MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 9, 0), /* GEther */ + [MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_CP], SMSTPCR3, 4, 0), /* TPU0 */ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */ [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */ @@ -551,6 +552,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_tmu.4", &mstp_clks[MSTP111]), CLKDEV_DEV_ID("sh_tmu.5", &mstp_clks[MSTP111]), CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), + CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), @@ -584,6 +586,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), + CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]), CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), @@ -592,6 +595,8 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]), CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP309]), + CLKDEV_DEV_ID("e9a00000.sh-eth", &mstp_clks[MSTP309]), + CLKDEV_DEV_ID("renesas_tpu_pwm", &mstp_clks[MSTP304]), CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index cd68552..b251e4d 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -23,9 +23,23 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + * MD MD MD MD PLLA PLLB EXTAL clki clkz + * 19 18 12 11 (HMz) (MHz) (MHz) + *---------------------------------------------------------------------------- + * 1 0 0 0 x21 x21 38.00 800 800 + * 1 0 0 1 x24 x24 33.33 800 800 + * 1 0 1 0 x28 x28 28.50 800 800 + * 1 0 1 1 x32 x32 25.00 800 800 + * 1 1 0 1 x24 x21 33.33 800 700 + * 1 1 1 0 x28 x21 28.50 800 600 + * 1 1 1 1 x32 x24 25.00 800 600 + */ + #include <linux/io.h> #include <linux/sh_clk.h> #include <linux/clkdev.h> +#include <mach/clock.h> #include <mach/common.h> #define MSTPCR0 IOMEM(0xffc80030) @@ -37,6 +51,9 @@ #define MSTPCR4 IOMEM(0xffc80050) #define MSTPCR5 IOMEM(0xffc80054) #define MSTPCR6 IOMEM(0xffc80058) +#define MODEMR 0xFFCC0020 + +#define MD(nr) BIT(nr) /* ioremap() through clock mapping mandatory to avoid * collision with ARM coherent DMA virtual memory range. @@ -47,36 +64,71 @@ static struct clk_mapping cpg_mapping = { .len = 0x80, }; -static struct clk clkp = { - .rate = 62500000, /* FIXME: shortcut */ - .flags = CLK_ENABLE_ON_INIT, +static struct clk extal_clk = { + /* .rate will be updated on r8a7778_clock_init() */ .mapping = &cpg_mapping, }; +/* + * clock ratio of these clock will be updated + * on r8a7778_clock_init() + */ +SH_FIXED_RATIO_CLK_SET(plla_clk, extal_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(pllb_clk, extal_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(i_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(s_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(s1_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(s3_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(s4_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(b_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(out_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(p_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(g_clk, plla_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(z_clk, pllb_clk, 1, 1); + static struct clk *main_clks[] = { - &clkp, + &extal_clk, + &plla_clk, + &pllb_clk, + &i_clk, + &s_clk, + &s1_clk, + &s3_clk, + &s4_clk, + &b_clk, + &out_clk, + &p_clk, + &g_clk, + &z_clk, }; enum { + MSTP323, MSTP322, MSTP321, MSTP114, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, MSTP016, MSTP015, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { - [MSTP114] = SH_CLK_MSTP32(&clkp, MSTPCR1, 14, 0), /* Ether */ - [MSTP026] = SH_CLK_MSTP32(&clkp, MSTPCR0, 26, 0), /* SCIF0 */ - [MSTP025] = SH_CLK_MSTP32(&clkp, MSTPCR0, 25, 0), /* SCIF1 */ - [MSTP024] = SH_CLK_MSTP32(&clkp, MSTPCR0, 24, 0), /* SCIF2 */ - [MSTP023] = SH_CLK_MSTP32(&clkp, MSTPCR0, 23, 0), /* SCIF3 */ - [MSTP022] = SH_CLK_MSTP32(&clkp, MSTPCR0, 22, 0), /* SCIF4 */ - [MSTP021] = SH_CLK_MSTP32(&clkp, MSTPCR0, 21, 0), /* SCIF5 */ - [MSTP016] = SH_CLK_MSTP32(&clkp, MSTPCR0, 16, 0), /* TMU0 */ - [MSTP015] = SH_CLK_MSTP32(&clkp, MSTPCR0, 15, 0), /* TMU1 */ + [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */ + [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ + [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ + [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ + [MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */ + [MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */ + [MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */ + [MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */ + [MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */ + [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */ + [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */ + [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */ }; static struct clk_lookup lookups[] = { /* MSTP32 clocks */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ @@ -90,8 +142,86 @@ static struct clk_lookup lookups[] = { void __init r8a7778_clock_init(void) { + void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); + u32 mode; int k, ret = 0; + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) { + case MD(19): + extal_clk.rate = 38000000; + SH_CLK_SET_RATIO(&plla_clk_ratio, 21, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1); + break; + case MD(19) | MD(11): + extal_clk.rate = 33333333; + SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1); + break; + case MD(19) | MD(12): + extal_clk.rate = 28500000; + SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 28, 1); + break; + case MD(19) | MD(12) | MD(11): + extal_clk.rate = 25000000; + SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 32, 1); + break; + case MD(19) | MD(18) | MD(11): + extal_clk.rate = 33333333; + SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1); + break; + case MD(19) | MD(18) | MD(12): + extal_clk.rate = 28500000; + SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1); + break; + case MD(19) | MD(18) | MD(12) | MD(11): + extal_clk.rate = 25000000; + SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1); + SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1); + break; + default: + BUG(); + } + + if (mode & MD(1)) { + SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1); + SH_CLK_SET_RATIO(&s_clk_ratio, 1, 3); + SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6); + SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4); + SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8); + SH_CLK_SET_RATIO(&p_clk_ratio, 1, 12); + SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12); + if (mode & MD(2)) { + SH_CLK_SET_RATIO(&b_clk_ratio, 1, 18); + SH_CLK_SET_RATIO(&out_clk_ratio, 1, 18); + } else { + SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12); + SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12); + } + } else { + SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1); + SH_CLK_SET_RATIO(&s_clk_ratio, 1, 4); + SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8); + SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4); + SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8); + SH_CLK_SET_RATIO(&p_clk_ratio, 1, 16); + SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12); + if (mode & MD(2)) { + SH_CLK_SET_RATIO(&b_clk_ratio, 1, 16); + SH_CLK_SET_RATIO(&out_clk_ratio, 1, 16); + } else { + SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12); + SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12); + } + } + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index 31d5cd4..9daeb8c 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -112,7 +112,7 @@ static struct clk *main_clks[] = { }; enum { MSTP323, MSTP322, MSTP321, MSTP320, - MSTP115, MSTP114, + MSTP116, MSTP115, MSTP114, MSTP103, MSTP101, MSTP100, MSTP030, MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, @@ -125,6 +125,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */ [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ + [MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */ [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */ [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */ [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */ @@ -161,6 +162,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("peripheral_clk", &clkp_clk), /* MSTP32 clocks */ + CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */ CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */ diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index bad9bf2..b393592 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -22,39 +22,174 @@ #include <linux/kernel.h> #include <linux/sh_clk.h> #include <linux/clkdev.h> +#include <mach/clock.h> #include <mach/common.h> +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x 1 x172/2 x208/2 x106 + * 0 0 1 15 x 1 x172/2 x208/2 x88 + * 0 1 0 20 x 1 x130/2 x156/2 x80 + * 0 1 1 20 x 1 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) + * see "p1 / 2" on R8A7790_CLOCK_ROOT() below + */ + +#define MD(nr) (1 << nr) + #define CPG_BASE 0xe6150000 #define CPG_LEN 0x1000 #define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xe615013c #define SMSTPCR7 0xe615014c +#define MODEMR 0xE6160060 +#define SDCKCR 0xE6150074 +#define SD2CKCR 0xE6150078 +#define SD3CKCR 0xE615007C +#define MMC0CKCR 0xE6150240 +#define MMC1CKCR 0xE6150244 +#define SSPCKCR 0xE6150248 +#define SSPRSCKCR 0xE615024C + static struct clk_mapping cpg_mapping = { .phys = CPG_BASE, .len = CPG_LEN, }; -static struct clk p_clk = { - .rate = 65000000, /* shortcut for now */ +static struct clk extal_clk = { + /* .rate will be updated on r8a7790_clock_init() */ .mapping = &cpg_mapping, }; -static struct clk mp_clk = { - .rate = 52000000, /* shortcut for now */ - .mapping = &cpg_mapping, +static struct sh_clk_ops followparent_clk_ops = { + .recalc = followparent_recalc, +}; + +static struct clk main_clk = { + /* .parent will be set r8a73a4_clock_init */ + .ops = &followparent_clk_ops, }; +/* + * clock ratio of these clock will be updated + * on r8a7790_clock_init() + */ +SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(lb_clk, pll1_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1); + +/* fixed ratio clock */ +SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); + +SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3); +SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3); +SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6); +SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); +SH_FIXED_RATIO_CLK_SET(i_clk, pll1_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(b_clk, pll1_clk, 1, 12); +SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); +SH_FIXED_RATIO_CLK_SET(cl_clk, pll1_clk, 1, 48); +SH_FIXED_RATIO_CLK_SET(m2_clk, pll1_clk, 1, 8); +SH_FIXED_RATIO_CLK_SET(imp_clk, pll1_clk, 1, 4); +SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); +SH_FIXED_RATIO_CLK_SET(oscclk_clk, pll1_clk, 1, (12 * 1024)); + +SH_FIXED_RATIO_CLK_SET(zb3_clk, pll3_clk, 1, 4); +SH_FIXED_RATIO_CLK_SET(zb3d2_clk, pll3_clk, 1, 8); +SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8); +SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); + static struct clk *main_clks[] = { + &extal_clk, + &extal_div2_clk, + &main_clk, + &pll1_clk, + &pll1_div2_clk, + &pll3_clk, + &lb_clk, + &qspi_clk, + &zg_clk, + &zx_clk, + &zs_clk, + &hp_clk, + &i_clk, + &b_clk, &p_clk, + &cl_clk, + &m2_clk, + &imp_clk, + &rclk_clk, + &oscclk_clk, + &zb3_clk, + &zb3d2_clk, + &ddr_clk, &mp_clk, + &cp_clk, +}; + +/* SDHI (DIV4) clock */ +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = divisors, + .nr_divisors = ARRAY_SIZE(divisors), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + +enum { + DIV4_SDH, DIV4_SD0, DIV4_SD1, DIV4_NR +}; + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT), + [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT), + [DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1de0, CLK_ENABLE_ON_INIT), +}; + +/* DIV6 clocks */ +enum { + DIV6_SD2, DIV6_SD3, + DIV6_MMC0, DIV6_MMC1, + DIV6_SSP, DIV6_SSPRS, + DIV6_NR +}; + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0), + [DIV6_SD3] = SH_CLK_DIV6(&pll1_div2_clk, SD3CKCR, 0), + [DIV6_MMC0] = SH_CLK_DIV6(&pll1_div2_clk, MMC0CKCR, 0), + [DIV6_MMC1] = SH_CLK_DIV6(&pll1_div2_clk, MMC1CKCR, 0), + [DIV6_SSP] = SH_CLK_DIV6(&pll1_div2_clk, SSPCKCR, 0), + [DIV6_SSPRS] = SH_CLK_DIV6(&pll1_div2_clk, SSPRSCKCR, 0), +}; + +/* MSTP */ +enum { + MSTP721, MSTP720, + MSTP304, + MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, + MSTP_NR }; -enum { MSTP721, MSTP720, - MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ + [MSTP304] = SH_CLK_MSTP32(&cp_clk, SMSTPCR3, 4, 0), /* TPU0 */ [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ @@ -64,6 +199,48 @@ static struct clk mstp_clks[MSTP_NR] = { }; static struct clk_lookup lookups[] = { + + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("extal_div2", &extal_div2_clk), + CLKDEV_CON_ID("main", &main_clk), + CLKDEV_CON_ID("pll1", &pll1_clk), + CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), + CLKDEV_CON_ID("pll3", &pll3_clk), + CLKDEV_CON_ID("zg", &zg_clk), + CLKDEV_CON_ID("zx", &zx_clk), + CLKDEV_CON_ID("zs", &zs_clk), + CLKDEV_CON_ID("hp", &hp_clk), + CLKDEV_CON_ID("i", &i_clk), + CLKDEV_CON_ID("b", &b_clk), + CLKDEV_CON_ID("lb", &lb_clk), + CLKDEV_CON_ID("p", &p_clk), + CLKDEV_CON_ID("cl", &cl_clk), + CLKDEV_CON_ID("m2", &m2_clk), + CLKDEV_CON_ID("imp", &imp_clk), + CLKDEV_CON_ID("rclk", &rclk_clk), + CLKDEV_CON_ID("oscclk", &oscclk_clk), + CLKDEV_CON_ID("zb3", &zb3_clk), + CLKDEV_CON_ID("zb3d2", &zb3d2_clk), + CLKDEV_CON_ID("ddr", &ddr_clk), + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("qspi", &qspi_clk), + CLKDEV_CON_ID("cp", &cp_clk), + + /* DIV4 */ + CLKDEV_CON_ID("sdh", &div4_clks[DIV4_SDH]), + CLKDEV_CON_ID("sd0", &div4_clks[DIV4_SD0]), + CLKDEV_CON_ID("sd1", &div4_clks[DIV4_SD1]), + + /* DIV6 */ + CLKDEV_CON_ID("sd2", &div6_clks[DIV6_SD2]), + CLKDEV_CON_ID("sd3", &div6_clks[DIV6_SD3]), + CLKDEV_CON_ID("mmc0", &div6_clks[DIV6_MMC0]), + CLKDEV_CON_ID("mmc1", &div6_clks[DIV6_MMC1]), + CLKDEV_CON_ID("ssp", &div6_clks[DIV6_SSP]), + CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]), + + /* MSTP */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), @@ -74,14 +251,61 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), }; +#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ + extal_clk.rate = e * 1000 * 1000; \ + main_clk.parent = m; \ + SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \ + if (mode & MD(19)) \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \ + else \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1) + + void __init r8a7790_clock_init(void) { + void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); + u32 mode; int k, ret = 0; + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + switch (mode & (MD(14) | MD(13))) { + case 0: + R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); + break; + case MD(13): + R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); + break; + case MD(14): + R8A7790_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); + break; + case MD(13) | MD(14): + R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); + break; + } + + if (mode & (MD(18))) + SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 36); + else + SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 24); + + if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2)) + SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16); + else + SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20); + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_div6_register(div6_clks, DIV6_NR); + + if (!ret) ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); clkdev_add_table(lookups, ARRAY_SIZE(lookups)); diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 784fbaa..d9fd033 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -228,6 +228,11 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, static struct clk div4_clks[DIV4_NR] = { [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT), + /* + * ZG clock is dividing PLL0 frequency to supply SGX. Make sure not to + * exceed maximum frequencies of 201.5MHz for VDD_DVFS=1.175 and + * 239.2MHz for VDD_DVFS=1.315V. + */ [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT), @@ -252,6 +257,101 @@ static struct clk twd_clk = { .ops = &twd_clk_ops, }; +static struct sh_clk_ops zclk_ops, kicker_ops; +static const struct sh_clk_ops *div4_clk_ops; + +static int zclk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret; + + if (!clk->parent || !__clk_get(clk->parent)) + return -ENODEV; + + if (readl(FRQCRB) & (1 << 31)) + return -EBUSY; + + if (rate == clk_get_rate(clk->parent)) { + /* 1:1 - switch off divider */ + __raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB); + /* nullify the divider to prepare for the next time */ + ret = div4_clk_ops->set_rate(clk, rate / 2); + if (!ret) + ret = frqcr_kick(); + if (ret > 0) + ret = 0; + } else { + /* Enable the divider */ + __raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB); + + ret = frqcr_kick(); + if (ret >= 0) + /* + * set the divider - call the DIV4 method, it will kick + * FRQCRB too + */ + ret = div4_clk_ops->set_rate(clk, rate); + if (ret < 0) + goto esetrate; + } + +esetrate: + __clk_put(clk->parent); + return ret; +} + +static long zclk_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long div_freq = div4_clk_ops->round_rate(clk, rate), + parent_freq = clk_get_rate(clk->parent); + + if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq) + return parent_freq; + + return div_freq; +} + +static unsigned long zclk_recalc(struct clk *clk) +{ + /* + * Must recalculate frequencies in case PLL0 has been changed, even if + * the divisor is unused ATM! + */ + unsigned long div_freq = div4_clk_ops->recalc(clk); + + if (__raw_readl(FRQCRB) & (1 << 28)) + return div_freq; + + return clk_get_rate(clk->parent); +} + +static int kicker_set_rate(struct clk *clk, unsigned long rate) +{ + if (__raw_readl(FRQCRB) & (1 << 31)) + return -EBUSY; + + return div4_clk_ops->set_rate(clk, rate); +} + +static void div4_clk_extend(void) +{ + int i; + + div4_clk_ops = div4_clks[0].ops; + + /* Add a kicker-busy check before changing the rate */ + kicker_ops = *div4_clk_ops; + /* We extend the DIV4 clock with a 1:1 pass-through case */ + zclk_ops = *div4_clk_ops; + + kicker_ops.set_rate = kicker_set_rate; + zclk_ops.set_rate = zclk_set_rate; + zclk_ops.round_rate = zclk_round_rate; + zclk_ops.recalc = zclk_recalc; + + for (i = 0; i < DIV4_NR; i++) + div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops; +} + enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2, DIV6_FSIA, DIV6_FSIB, DIV6_SUB, @@ -450,7 +550,7 @@ static struct clk *late_main_clks[] = { }; enum { MSTP001, - MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, + MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100, MSTP219, MSTP218, MSTP217, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322, @@ -471,6 +571,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */ [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */ + [MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */ [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */ @@ -513,6 +614,9 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("r_clk", &r_clk), CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */ + /* DIV4 clocks */ + CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]), + /* DIV6 clocks */ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), @@ -604,8 +708,11 @@ void __init sh73a0_clock_init(void) for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ret = clk_register(main_clks[k]); - if (!ret) + if (!ret) { ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + if (!ret) + div4_clk_extend(); + } if (!ret) ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); diff --git a/arch/arm/mach-shmobile/include/mach/clock.h b/arch/arm/mach-shmobile/include/mach/clock.h index 76ac612..03e5607 100644 --- a/arch/arm/mach-shmobile/include/mach/clock.h +++ b/arch/arm/mach-shmobile/include/mach/clock.h @@ -24,16 +24,16 @@ struct clk name = { \ } #define SH_FIXED_RATIO_CLK(name, p, r) \ -static SH_FIXED_RATIO_CLKg(name, p, r); +static SH_FIXED_RATIO_CLKg(name, p, r) #define SH_FIXED_RATIO_CLK_SET(name, p, m, d) \ SH_CLK_RATIO(name, m, d); \ - SH_FIXED_RATIO_CLK(name, p, name); + SH_FIXED_RATIO_CLK(name, p, name) #define SH_CLK_SET_RATIO(p, m, d) \ -{ \ +do { \ (p)->mul = m; \ (p)->div = d; \ -} +} while (0) #endif diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index b2074e2..d241bfd 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -16,4 +16,9 @@ #define IRQPIN_BASE 2000 #define irq_pin(nr) ((nr) + IRQPIN_BASE) +/* GPIO IRQ */ +#define _GPIO_IRQ_BASE 2500 +#define GPIO_IRQ_BASE(x) (_GPIO_IRQ_BASE + (32 * x)) +#define GPIO_IRQ(x, y) (_GPIO_IRQ_BASE + (32 * x) + y) + #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h index abdc4d4..9c9a66c 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7740.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h @@ -28,494 +28,6 @@ #define MD_CK1 (1 << 1) #define MD_CK0 (1 << 0) -/* - * Pin Function Controller: - * GPIO_FN_xx - GPIO used to select pin function - * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU - */ -enum { - /* PORT */ - GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4, - GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9, - - GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14, - GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19, - - GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24, - GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29, - - GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34, - GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39, - - GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44, - GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49, - - GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54, - GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59, - - GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64, - GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69, - - GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74, - GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79, - - GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84, - GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89, - - GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94, - GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99, - - GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104, - GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109, - - GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114, - GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119, - - GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124, - GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129, - - GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134, - GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139, - - GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144, - GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149, - - GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154, - GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159, - - GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164, - GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169, - - GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174, - GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179, - - GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184, - GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189, - - GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194, - GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199, - - GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204, - GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209, - - GPIO_PORT210, GPIO_PORT211, - - /* IRQ */ - GPIO_FN_IRQ0_PORT2, GPIO_FN_IRQ0_PORT13, - GPIO_FN_IRQ1, - GPIO_FN_IRQ2_PORT11, GPIO_FN_IRQ2_PORT12, - GPIO_FN_IRQ3_PORT10, GPIO_FN_IRQ3_PORT14, - GPIO_FN_IRQ4_PORT15, GPIO_FN_IRQ4_PORT172, - GPIO_FN_IRQ5_PORT0, GPIO_FN_IRQ5_PORT1, - GPIO_FN_IRQ6_PORT121, GPIO_FN_IRQ6_PORT173, - GPIO_FN_IRQ7_PORT120, GPIO_FN_IRQ7_PORT209, - GPIO_FN_IRQ8, - GPIO_FN_IRQ9_PORT118, GPIO_FN_IRQ9_PORT210, - GPIO_FN_IRQ10, - GPIO_FN_IRQ11, - GPIO_FN_IRQ12_PORT42, GPIO_FN_IRQ12_PORT97, - GPIO_FN_IRQ13_PORT64, GPIO_FN_IRQ13_PORT98, - GPIO_FN_IRQ14_PORT63, GPIO_FN_IRQ14_PORT99, - GPIO_FN_IRQ15_PORT62, GPIO_FN_IRQ15_PORT100, - GPIO_FN_IRQ16_PORT68, GPIO_FN_IRQ16_PORT211, - GPIO_FN_IRQ17, - GPIO_FN_IRQ18, - GPIO_FN_IRQ19, - GPIO_FN_IRQ20, - GPIO_FN_IRQ21, - GPIO_FN_IRQ22, - GPIO_FN_IRQ23, - GPIO_FN_IRQ24, - GPIO_FN_IRQ25, - GPIO_FN_IRQ26_PORT58, GPIO_FN_IRQ26_PORT81, - GPIO_FN_IRQ27_PORT57, GPIO_FN_IRQ27_PORT168, - GPIO_FN_IRQ28_PORT56, GPIO_FN_IRQ28_PORT169, - GPIO_FN_IRQ29_PORT50, GPIO_FN_IRQ29_PORT170, - GPIO_FN_IRQ30_PORT49, GPIO_FN_IRQ30_PORT171, - GPIO_FN_IRQ31_PORT41, GPIO_FN_IRQ31_PORT167, - - /* Function */ - - /* DBGT */ - GPIO_FN_DBGMDT2, GPIO_FN_DBGMDT1, GPIO_FN_DBGMDT0, - GPIO_FN_DBGMD10, GPIO_FN_DBGMD11, GPIO_FN_DBGMD20, - GPIO_FN_DBGMD21, - - /* FSI-A */ - GPIO_FN_FSIAISLD_PORT0, /* FSIAISLD Port 0/5 */ - GPIO_FN_FSIAISLD_PORT5, - GPIO_FN_FSIASPDIF_PORT9, /* FSIASPDIF Port 9/18 */ - GPIO_FN_FSIASPDIF_PORT18, - GPIO_FN_FSIAOSLD1, GPIO_FN_FSIAOSLD2, - GPIO_FN_FSIAOLR, GPIO_FN_FSIAOBT, - GPIO_FN_FSIAOSLD, GPIO_FN_FSIAOMC, - GPIO_FN_FSIACK, GPIO_FN_FSIAILR, - GPIO_FN_FSIAIBT, - - /* FSI-B */ - GPIO_FN_FSIBCK, - - /* FMSI */ - GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */ - GPIO_FN_FMSISLD_PORT6, - GPIO_FN_FMSIILR, GPIO_FN_FMSIIBT, - GPIO_FN_FMSIOLR, GPIO_FN_FMSIOBT, - GPIO_FN_FMSICK, GPIO_FN_FMSOILR, - GPIO_FN_FMSOIBT, GPIO_FN_FMSOOLR, - GPIO_FN_FMSOOBT, GPIO_FN_FMSOSLD, - GPIO_FN_FMSOCK, - - /* SCIFA0 */ - GPIO_FN_SCIFA0_SCK, GPIO_FN_SCIFA0_CTS, - GPIO_FN_SCIFA0_RTS, GPIO_FN_SCIFA0_RXD, - GPIO_FN_SCIFA0_TXD, - - /* SCIFA1 */ - GPIO_FN_SCIFA1_CTS, GPIO_FN_SCIFA1_SCK, - GPIO_FN_SCIFA1_RXD, GPIO_FN_SCIFA1_TXD, - GPIO_FN_SCIFA1_RTS, - - /* SCIFA2 */ - GPIO_FN_SCIFA2_SCK_PORT22, /* SCIFA2_SCK Port 22/199 */ - GPIO_FN_SCIFA2_SCK_PORT199, - GPIO_FN_SCIFA2_RXD, GPIO_FN_SCIFA2_TXD, - GPIO_FN_SCIFA2_CTS, GPIO_FN_SCIFA2_RTS, - - /* SCIFA3 */ - GPIO_FN_SCIFA3_RTS_PORT105, /* MSEL5CR_8_0 */ - GPIO_FN_SCIFA3_SCK_PORT116, - GPIO_FN_SCIFA3_CTS_PORT117, - GPIO_FN_SCIFA3_RXD_PORT174, - GPIO_FN_SCIFA3_TXD_PORT175, - - GPIO_FN_SCIFA3_RTS_PORT161, /* MSEL5CR_8_1 */ - GPIO_FN_SCIFA3_SCK_PORT158, - GPIO_FN_SCIFA3_CTS_PORT162, - GPIO_FN_SCIFA3_RXD_PORT159, - GPIO_FN_SCIFA3_TXD_PORT160, - - /* SCIFA4 */ - GPIO_FN_SCIFA4_RXD_PORT12, /* MSEL5CR[12:11] = 00 */ - GPIO_FN_SCIFA4_TXD_PORT13, - - GPIO_FN_SCIFA4_RXD_PORT204, /* MSEL5CR[12:11] = 01 */ - GPIO_FN_SCIFA4_TXD_PORT203, - - GPIO_FN_SCIFA4_RXD_PORT94, /* MSEL5CR[12:11] = 10 */ - GPIO_FN_SCIFA4_TXD_PORT93, - - GPIO_FN_SCIFA4_SCK_PORT21, /* SCIFA4_SCK Port 21/205 */ - GPIO_FN_SCIFA4_SCK_PORT205, - - /* SCIFA5 */ - GPIO_FN_SCIFA5_TXD_PORT20, /* MSEL5CR[15:14] = 00 */ - GPIO_FN_SCIFA5_RXD_PORT10, - - GPIO_FN_SCIFA5_RXD_PORT207, /* MSEL5CR[15:14] = 01 */ - GPIO_FN_SCIFA5_TXD_PORT208, - - GPIO_FN_SCIFA5_TXD_PORT91, /* MSEL5CR[15:14] = 10 */ - GPIO_FN_SCIFA5_RXD_PORT92, - - GPIO_FN_SCIFA5_SCK_PORT23, /* SCIFA5_SCK Port 23/206 */ - GPIO_FN_SCIFA5_SCK_PORT206, - - /* SCIFA6 */ - GPIO_FN_SCIFA6_SCK, GPIO_FN_SCIFA6_RXD, GPIO_FN_SCIFA6_TXD, - - /* SCIFA7 */ - GPIO_FN_SCIFA7_TXD, GPIO_FN_SCIFA7_RXD, - - /* SCIFAB */ - GPIO_FN_SCIFB_SCK_PORT190, /* MSEL5CR_17_0 */ - GPIO_FN_SCIFB_RXD_PORT191, - GPIO_FN_SCIFB_TXD_PORT192, - GPIO_FN_SCIFB_RTS_PORT186, - GPIO_FN_SCIFB_CTS_PORT187, - - GPIO_FN_SCIFB_SCK_PORT2, /* MSEL5CR_17_1 */ - GPIO_FN_SCIFB_RXD_PORT3, - GPIO_FN_SCIFB_TXD_PORT4, - GPIO_FN_SCIFB_RTS_PORT172, - GPIO_FN_SCIFB_CTS_PORT173, - - /* LCD0 */ - GPIO_FN_LCDC0_SELECT, - - /* LCD1 */ - GPIO_FN_LCDC1_SELECT, - - /* RSPI */ - GPIO_FN_RSPI_SSL0_A, GPIO_FN_RSPI_SSL1_A, - GPIO_FN_RSPI_SSL2_A, GPIO_FN_RSPI_SSL3_A, - GPIO_FN_RSPI_MOSI_A, GPIO_FN_RSPI_MISO_A, - GPIO_FN_RSPI_CK_A, - - /* VIO CKO */ - GPIO_FN_VIO_CKO1, - GPIO_FN_VIO_CKO2, - GPIO_FN_VIO_CKO_1, - GPIO_FN_VIO_CKO, - - /* VIO0 */ - GPIO_FN_VIO0_D0, GPIO_FN_VIO0_D1, GPIO_FN_VIO0_D2, - GPIO_FN_VIO0_D3, GPIO_FN_VIO0_D4, GPIO_FN_VIO0_D5, - GPIO_FN_VIO0_D6, GPIO_FN_VIO0_D7, GPIO_FN_VIO0_D8, - GPIO_FN_VIO0_D9, GPIO_FN_VIO0_D10, GPIO_FN_VIO0_D11, - GPIO_FN_VIO0_D12, GPIO_FN_VIO0_VD, GPIO_FN_VIO0_HD, - GPIO_FN_VIO0_CLK, GPIO_FN_VIO0_FIELD, - - GPIO_FN_VIO0_D13_PORT26, /* MSEL5CR_27_0 */ - GPIO_FN_VIO0_D14_PORT25, - GPIO_FN_VIO0_D15_PORT24, - - GPIO_FN_VIO0_D13_PORT22, /* MSEL5CR_27_1 */ - GPIO_FN_VIO0_D14_PORT95, - GPIO_FN_VIO0_D15_PORT96, - - /* VIO1 */ - GPIO_FN_VIO1_D0, GPIO_FN_VIO1_D1, GPIO_FN_VIO1_D2, - GPIO_FN_VIO1_D3, GPIO_FN_VIO1_D4, GPIO_FN_VIO1_D5, - GPIO_FN_VIO1_D6, GPIO_FN_VIO1_D7, GPIO_FN_VIO1_VD, - GPIO_FN_VIO1_HD, GPIO_FN_VIO1_CLK, GPIO_FN_VIO1_FIELD, - - /* TPU0 */ - GPIO_FN_TPU0TO0, GPIO_FN_TPU0TO1, - GPIO_FN_TPU0TO3, - GPIO_FN_TPU0TO2_PORT66, /* TPU0TO2 Port 66/202 */ - GPIO_FN_TPU0TO2_PORT202, - - /* SSP1 0 */ - GPIO_FN_STP0_IPD0, GPIO_FN_STP0_IPD1, GPIO_FN_STP0_IPD2, - GPIO_FN_STP0_IPD3, GPIO_FN_STP0_IPD4, GPIO_FN_STP0_IPD5, - GPIO_FN_STP0_IPD6, GPIO_FN_STP0_IPD7, GPIO_FN_STP0_IPEN, - GPIO_FN_STP0_IPCLK, GPIO_FN_STP0_IPSYNC, - - /* SSP1 1 */ - GPIO_FN_STP1_IPD1, GPIO_FN_STP1_IPD2, GPIO_FN_STP1_IPD3, - GPIO_FN_STP1_IPD4, GPIO_FN_STP1_IPD5, GPIO_FN_STP1_IPD6, - GPIO_FN_STP1_IPD7, GPIO_FN_STP1_IPCLK, GPIO_FN_STP1_IPSYNC, - - GPIO_FN_STP1_IPD0_PORT186, /* MSEL5CR_23_0 */ - GPIO_FN_STP1_IPEN_PORT187, - - GPIO_FN_STP1_IPD0_PORT194, /* MSEL5CR_23_1 */ - GPIO_FN_STP1_IPEN_PORT193, - - /* SIM */ - GPIO_FN_SIM_RST, GPIO_FN_SIM_CLK, - GPIO_FN_SIM_D_PORT22, /* SIM_D Port 22/199 */ - GPIO_FN_SIM_D_PORT199, - - /* MSIOF2 */ - GPIO_FN_MSIOF2_TXD, GPIO_FN_MSIOF2_RXD, GPIO_FN_MSIOF2_TSCK, - GPIO_FN_MSIOF2_SS2, GPIO_FN_MSIOF2_TSYNC, GPIO_FN_MSIOF2_SS1, - GPIO_FN_MSIOF2_MCK1, GPIO_FN_MSIOF2_MCK0, GPIO_FN_MSIOF2_RSYNC, - GPIO_FN_MSIOF2_RSCK, - - /* KEYSC */ - GPIO_FN_KEYIN4, GPIO_FN_KEYIN5, - GPIO_FN_KEYIN6, GPIO_FN_KEYIN7, - GPIO_FN_KEYOUT0, GPIO_FN_KEYOUT1, GPIO_FN_KEYOUT2, - GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4, GPIO_FN_KEYOUT5, - GPIO_FN_KEYOUT6, GPIO_FN_KEYOUT7, - - GPIO_FN_KEYIN0_PORT43, /* MSEL4CR_18_0 */ - GPIO_FN_KEYIN1_PORT44, - GPIO_FN_KEYIN2_PORT45, - GPIO_FN_KEYIN3_PORT46, - - GPIO_FN_KEYIN0_PORT58, /* MSEL4CR_18_1 */ - GPIO_FN_KEYIN1_PORT57, - GPIO_FN_KEYIN2_PORT56, - GPIO_FN_KEYIN3_PORT55, - - /* VOU */ - GPIO_FN_DV_D0, GPIO_FN_DV_D1, GPIO_FN_DV_D2, GPIO_FN_DV_D3, - GPIO_FN_DV_D4, GPIO_FN_DV_D5, GPIO_FN_DV_D6, GPIO_FN_DV_D7, - GPIO_FN_DV_D8, GPIO_FN_DV_D9, GPIO_FN_DV_D10, GPIO_FN_DV_D11, - GPIO_FN_DV_D12, GPIO_FN_DV_D13, GPIO_FN_DV_D14, GPIO_FN_DV_D15, - GPIO_FN_DV_CLK, - GPIO_FN_DV_VSYNC, - GPIO_FN_DV_HSYNC, - - /* MEMC */ - GPIO_FN_MEMC_AD0, GPIO_FN_MEMC_AD1, GPIO_FN_MEMC_AD2, - GPIO_FN_MEMC_AD3, GPIO_FN_MEMC_AD4, GPIO_FN_MEMC_AD5, - GPIO_FN_MEMC_AD6, GPIO_FN_MEMC_AD7, GPIO_FN_MEMC_AD8, - GPIO_FN_MEMC_AD9, GPIO_FN_MEMC_AD10, GPIO_FN_MEMC_AD11, - GPIO_FN_MEMC_AD12, GPIO_FN_MEMC_AD13, GPIO_FN_MEMC_AD14, - GPIO_FN_MEMC_AD15, GPIO_FN_MEMC_CS0, GPIO_FN_MEMC_INT, - GPIO_FN_MEMC_NWE, GPIO_FN_MEMC_NOE, - - GPIO_FN_MEMC_CS1, /* MSEL4CR_6_0 */ - GPIO_FN_MEMC_ADV, - GPIO_FN_MEMC_WAIT, - GPIO_FN_MEMC_BUSCLK, - - GPIO_FN_MEMC_A1, /* MSEL4CR_6_1 */ - GPIO_FN_MEMC_DREQ0, - GPIO_FN_MEMC_DREQ1, - GPIO_FN_MEMC_A0, - - /* MSIOF0 */ - GPIO_FN_MSIOF0_SS1, GPIO_FN_MSIOF0_SS2, - GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_TXD, - GPIO_FN_MSIOF0_MCK0, GPIO_FN_MSIOF0_MCK1, - GPIO_FN_MSIOF0_RSYNC, GPIO_FN_MSIOF0_RSCK, - GPIO_FN_MSIOF0_TSCK, GPIO_FN_MSIOF0_TSYNC, - - /* MSIOF1 */ - GPIO_FN_MSIOF1_RSCK, GPIO_FN_MSIOF1_RSYNC, - GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1, - - GPIO_FN_MSIOF1_SS2_PORT116, GPIO_FN_MSIOF1_SS1_PORT117, - GPIO_FN_MSIOF1_RXD_PORT118, GPIO_FN_MSIOF1_TXD_PORT119, - GPIO_FN_MSIOF1_TSYNC_PORT120, - GPIO_FN_MSIOF1_TSCK_PORT121, /* MSEL4CR_10_0 */ - - GPIO_FN_MSIOF1_SS1_PORT67, GPIO_FN_MSIOF1_TSCK_PORT72, - GPIO_FN_MSIOF1_TSYNC_PORT73, GPIO_FN_MSIOF1_TXD_PORT74, - GPIO_FN_MSIOF1_RXD_PORT75, - GPIO_FN_MSIOF1_SS2_PORT202, /* MSEL4CR_10_1 */ - - /* GPIO */ - GPIO_FN_GPO0, GPIO_FN_GPI0, - GPIO_FN_GPO1, GPIO_FN_GPI1, - - /* USB0 */ - GPIO_FN_USB0_OCI, GPIO_FN_USB0_PPON, GPIO_FN_VBUS, - - /* USB1 */ - GPIO_FN_USB1_OCI, GPIO_FN_USB1_PPON, - - /* BBIF1 */ - GPIO_FN_BBIF1_RXD, GPIO_FN_BBIF1_TXD, GPIO_FN_BBIF1_TSYNC, - GPIO_FN_BBIF1_TSCK, GPIO_FN_BBIF1_RSCK, GPIO_FN_BBIF1_RSYNC, - GPIO_FN_BBIF1_FLOW, GPIO_FN_BBIF1_RX_FLOW_N, - - /* BBIF2 */ - GPIO_FN_BBIF2_TXD2_PORT5, /* MSEL5CR_0_0 */ - GPIO_FN_BBIF2_RXD2_PORT60, - GPIO_FN_BBIF2_TSYNC2_PORT6, - GPIO_FN_BBIF2_TSCK2_PORT59, - - GPIO_FN_BBIF2_RXD2_PORT90, /* MSEL5CR_0_1 */ - GPIO_FN_BBIF2_TXD2_PORT183, - GPIO_FN_BBIF2_TSCK2_PORT89, - GPIO_FN_BBIF2_TSYNC2_PORT184, - - /* BSC / FLCTL / PCMCIA */ - GPIO_FN_CS0, GPIO_FN_CS2, GPIO_FN_CS4, - GPIO_FN_CS5B, GPIO_FN_CS6A, - GPIO_FN_CS5A_PORT105, /* CS5A PORT 19/105 */ - GPIO_FN_CS5A_PORT19, - GPIO_FN_IOIS16, /* ? */ - - GPIO_FN_A0, GPIO_FN_A1, GPIO_FN_A2, GPIO_FN_A3, - GPIO_FN_A4_FOE, /* share with FLCTL */ - GPIO_FN_A5_FCDE, /* share with FLCTL */ - GPIO_FN_A6, GPIO_FN_A7, GPIO_FN_A8, GPIO_FN_A9, - GPIO_FN_A10, GPIO_FN_A11, GPIO_FN_A12, GPIO_FN_A13, - GPIO_FN_A14, GPIO_FN_A15, GPIO_FN_A16, GPIO_FN_A17, - GPIO_FN_A18, GPIO_FN_A19, GPIO_FN_A20, GPIO_FN_A21, - GPIO_FN_A22, GPIO_FN_A23, GPIO_FN_A24, GPIO_FN_A25, - GPIO_FN_A26, - - GPIO_FN_D0_NAF0, GPIO_FN_D1_NAF1, /* share with FLCTL */ - GPIO_FN_D2_NAF2, GPIO_FN_D3_NAF3, /* share with FLCTL */ - GPIO_FN_D4_NAF4, GPIO_FN_D5_NAF5, /* share with FLCTL */ - GPIO_FN_D6_NAF6, GPIO_FN_D7_NAF7, /* share with FLCTL */ - GPIO_FN_D8_NAF8, GPIO_FN_D9_NAF9, /* share with FLCTL */ - GPIO_FN_D10_NAF10, GPIO_FN_D11_NAF11, /* share with FLCTL */ - GPIO_FN_D12_NAF12, GPIO_FN_D13_NAF13, /* share with FLCTL */ - GPIO_FN_D14_NAF14, GPIO_FN_D15_NAF15, /* share with FLCTL */ - - GPIO_FN_D16, GPIO_FN_D17, GPIO_FN_D18, GPIO_FN_D19, - GPIO_FN_D20, GPIO_FN_D21, GPIO_FN_D22, GPIO_FN_D23, - GPIO_FN_D24, GPIO_FN_D25, GPIO_FN_D26, GPIO_FN_D27, - GPIO_FN_D28, GPIO_FN_D29, GPIO_FN_D30, GPIO_FN_D31, - - GPIO_FN_WE0_FWE, /* share with FLCTL */ - GPIO_FN_WE1, - GPIO_FN_WE2_ICIORD, /* share with PCMCIA */ - GPIO_FN_WE3_ICIOWR, /* share with PCMCIA */ - GPIO_FN_CKO, GPIO_FN_BS, GPIO_FN_RDWR, - GPIO_FN_RD_FSC, /* share with FLCTL */ - GPIO_FN_WAIT_PORT177, /* WAIT Port 90/177 */ - GPIO_FN_WAIT_PORT90, - - GPIO_FN_FCE0, GPIO_FN_FCE1, GPIO_FN_FRB, /* FLCTL */ - - /* IRDA */ - GPIO_FN_IRDA_FIRSEL, GPIO_FN_IRDA_IN, GPIO_FN_IRDA_OUT, - - /* ATAPI */ - GPIO_FN_IDE_D0, GPIO_FN_IDE_D1, GPIO_FN_IDE_D2, - GPIO_FN_IDE_D3, GPIO_FN_IDE_D4, GPIO_FN_IDE_D5, - GPIO_FN_IDE_D6, GPIO_FN_IDE_D7, GPIO_FN_IDE_D8, - GPIO_FN_IDE_D9, GPIO_FN_IDE_D10, GPIO_FN_IDE_D11, - GPIO_FN_IDE_D12, GPIO_FN_IDE_D13, GPIO_FN_IDE_D14, - GPIO_FN_IDE_D15, GPIO_FN_IDE_A0, GPIO_FN_IDE_A1, - GPIO_FN_IDE_A2, GPIO_FN_IDE_CS0, GPIO_FN_IDE_CS1, - GPIO_FN_IDE_IOWR, GPIO_FN_IDE_IORD, GPIO_FN_IDE_IORDY, - GPIO_FN_IDE_INT, GPIO_FN_IDE_RST, GPIO_FN_IDE_DIRECTION, - GPIO_FN_IDE_EXBUF_ENB, GPIO_FN_IDE_IODACK, GPIO_FN_IDE_IODREQ, - - /* RMII */ - GPIO_FN_RMII_CRS_DV, GPIO_FN_RMII_RX_ER, GPIO_FN_RMII_RXD0, - GPIO_FN_RMII_RXD1, GPIO_FN_RMII_TX_EN, GPIO_FN_RMII_TXD0, - GPIO_FN_RMII_MDC, GPIO_FN_RMII_TXD1, GPIO_FN_RMII_MDIO, - GPIO_FN_RMII_REF50CK, /* for RMII */ - GPIO_FN_RMII_REF125CK, /* for GMII */ - - /* GEther */ - GPIO_FN_ET_TX_CLK, GPIO_FN_ET_TX_EN, GPIO_FN_ET_ETXD0, - GPIO_FN_ET_ETXD1, GPIO_FN_ET_ETXD2, GPIO_FN_ET_ETXD3, - GPIO_FN_ET_ETXD4, GPIO_FN_ET_ETXD5, /* for GEther */ - GPIO_FN_ET_ETXD6, GPIO_FN_ET_ETXD7, /* for GEther */ - GPIO_FN_ET_COL, GPIO_FN_ET_TX_ER, - GPIO_FN_ET_RX_CLK, GPIO_FN_ET_RX_DV, - GPIO_FN_ET_ERXD0, GPIO_FN_ET_ERXD1, - GPIO_FN_ET_ERXD2, GPIO_FN_ET_ERXD3, - GPIO_FN_ET_ERXD4, GPIO_FN_ET_ERXD5, /* for GEther */ - GPIO_FN_ET_ERXD6, GPIO_FN_ET_ERXD7, /* for GEther */ - GPIO_FN_ET_RX_ER, GPIO_FN_ET_CRS, - GPIO_FN_ET_MDC, GPIO_FN_ET_MDIO, - GPIO_FN_ET_LINK, GPIO_FN_ET_PHY_INT, - GPIO_FN_ET_WOL, GPIO_FN_ET_GTX_CLK, - - /* DMA0 */ - GPIO_FN_DREQ0, GPIO_FN_DACK0, - - /* DMA1 */ - GPIO_FN_DREQ1, GPIO_FN_DACK1, - - /* SYSC */ - GPIO_FN_RESETOUTS, - GPIO_FN_RESETP_PULLUP, - GPIO_FN_RESETP_PLAIN, - - /* HDMI */ - GPIO_FN_HDMI_HPD, - GPIO_FN_HDMI_CEC, - - /* SDENC */ - GPIO_FN_SDENC_CPG, - GPIO_FN_SDENC_DV_CLKI, - - /* IRREM */ - GPIO_FN_IROUT, - - /* DEBUG */ - GPIO_FN_EDEBGREQ_PULLDOWN, - GPIO_FN_EDEBGREQ_PULLUP, - - GPIO_FN_TRACEAUD_FROM_VIO, - GPIO_FN_TRACEAUD_FROM_LCDC0, - GPIO_FN_TRACEAUD_FROM_MEMC, -}; - /* DMA slave IDs */ enum { SHDMA_SLAVE_INVALID, diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index 951149e..ae65b45 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -18,6 +18,7 @@ #ifndef __ASM_R8A7778_H__ #define __ASM_R8A7778_H__ +#include <linux/mmc/sh_mobile_sdhi.h> #include <linux/sh_eth.h> extern void r8a7778_add_standard_devices(void); @@ -28,5 +29,7 @@ extern void r8a7778_init_irq(void); extern void r8a7778_init_irq_dt(void); extern void r8a7778_clock_init(void); extern void r8a7778_init_irq_extpin(int irlm); +extern void r8a7778_pinmux_init(void); +extern void r8a7778_sdhi_init(int id, struct sh_mobile_sdhi_info *info); #endif /* __ASM_R8A7778_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index fd7cba0..e882717 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -15,397 +15,6 @@ #include <linux/pm_domain.h> #include <mach/pm-rmobile.h> -/* - * Pin Function Controller: - * GPIO_FN_xx - GPIO used to select pin function - * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU - */ -enum { - /* PORT */ - GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4, - GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9, - - GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14, - GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19, - - GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24, - GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29, - - GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34, - GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39, - - GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44, - GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49, - - GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54, - GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59, - - GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64, - GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69, - - GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74, - GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79, - - GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84, - GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89, - - GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94, - GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99, - - GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104, - GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109, - - GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114, - GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119, - - GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124, - GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129, - - GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134, - GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139, - - GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144, - GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149, - - GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154, - GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159, - - GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164, - GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169, - - GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174, - GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179, - - GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184, - GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189, - - GPIO_PORT190, - - /* IRQ */ - GPIO_FN_IRQ0_6, /* PORT 6 */ - GPIO_FN_IRQ0_162, /* PORT 162 */ - GPIO_FN_IRQ1, /* PORT 12 */ - GPIO_FN_IRQ2_4, /* PORT 4 */ - GPIO_FN_IRQ2_5, /* PORT 5 */ - GPIO_FN_IRQ3_8, /* PORT 8 */ - GPIO_FN_IRQ3_16, /* PORT 16 */ - GPIO_FN_IRQ4_17, /* PORT 17 */ - GPIO_FN_IRQ4_163, /* PORT 163 */ - GPIO_FN_IRQ5, /* PORT 18 */ - GPIO_FN_IRQ6_39, /* PORT 39 */ - GPIO_FN_IRQ6_164, /* PORT 164 */ - GPIO_FN_IRQ7_40, /* PORT 40 */ - GPIO_FN_IRQ7_167, /* PORT 167 */ - GPIO_FN_IRQ8_41, /* PORT 41 */ - GPIO_FN_IRQ8_168, /* PORT 168 */ - GPIO_FN_IRQ9_42, /* PORT 42 */ - GPIO_FN_IRQ9_169, /* PORT 169 */ - GPIO_FN_IRQ10, /* PORT 65 */ - GPIO_FN_IRQ11, /* PORT 67 */ - GPIO_FN_IRQ12_80, /* PORT 80 */ - GPIO_FN_IRQ12_137, /* PORT 137 */ - GPIO_FN_IRQ13_81, /* PORT 81 */ - GPIO_FN_IRQ13_145, /* PORT 145 */ - GPIO_FN_IRQ14_82, /* PORT 82 */ - GPIO_FN_IRQ14_146, /* PORT 146 */ - GPIO_FN_IRQ15_83, /* PORT 83 */ - GPIO_FN_IRQ15_147, /* PORT 147 */ - GPIO_FN_IRQ16_84, /* PORT 84 */ - GPIO_FN_IRQ16_170, /* PORT 170 */ - GPIO_FN_IRQ17, /* PORT 85 */ - GPIO_FN_IRQ18, /* PORT 86 */ - GPIO_FN_IRQ19, /* PORT 87 */ - GPIO_FN_IRQ20, /* PORT 92 */ - GPIO_FN_IRQ21, /* PORT 93 */ - GPIO_FN_IRQ22, /* PORT 94 */ - GPIO_FN_IRQ23, /* PORT 95 */ - GPIO_FN_IRQ24, /* PORT 112 */ - GPIO_FN_IRQ25, /* PORT 119 */ - GPIO_FN_IRQ26_121, /* PORT 121 */ - GPIO_FN_IRQ26_172, /* PORT 172 */ - GPIO_FN_IRQ27_122, /* PORT 122 */ - GPIO_FN_IRQ27_180, /* PORT 180 */ - GPIO_FN_IRQ28_123, /* PORT 123 */ - GPIO_FN_IRQ28_181, /* PORT 181 */ - GPIO_FN_IRQ29_129, /* PORT 129 */ - GPIO_FN_IRQ29_182, /* PORT 182 */ - GPIO_FN_IRQ30_130, /* PORT 130 */ - GPIO_FN_IRQ30_183, /* PORT 183 */ - GPIO_FN_IRQ31_138, /* PORT 138 */ - GPIO_FN_IRQ31_184, /* PORT 184 */ - - /* - * MSIOF0 (PORT 36, 37, 38, 39 - * 40, 41, 42, 43, 44, 45) - */ - GPIO_FN_MSIOF0_TSYNC, GPIO_FN_MSIOF0_TSCK, - GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_RSCK, - GPIO_FN_MSIOF0_RSYNC, GPIO_FN_MSIOF0_MCK0, - GPIO_FN_MSIOF0_MCK1, GPIO_FN_MSIOF0_SS1, - GPIO_FN_MSIOF0_SS2, GPIO_FN_MSIOF0_TXD, - - /* - * MSIOF1 (PORT 39, 40, 41, 42, 43, 44 - * 84, 85, 86, 87, 88, 89, 90, 91, 92, 93) - */ - GPIO_FN_MSIOF1_TSCK_39, GPIO_FN_MSIOF1_TSYNC_40, - GPIO_FN_MSIOF1_TSCK_88, GPIO_FN_MSIOF1_TSYNC_89, - GPIO_FN_MSIOF1_TXD_41, GPIO_FN_MSIOF1_RXD_42, - GPIO_FN_MSIOF1_TXD_90, GPIO_FN_MSIOF1_RXD_91, - GPIO_FN_MSIOF1_SS1_43, GPIO_FN_MSIOF1_SS2_44, - GPIO_FN_MSIOF1_SS1_92, GPIO_FN_MSIOF1_SS2_93, - GPIO_FN_MSIOF1_RSCK, GPIO_FN_MSIOF1_RSYNC, - GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1, - - /* - * MSIOF2 (PORT 134, 135, 136, 137, 138, 139 - * 148, 149, 150, 151) - */ - GPIO_FN_MSIOF2_RSCK, GPIO_FN_MSIOF2_RSYNC, - GPIO_FN_MSIOF2_MCK0, GPIO_FN_MSIOF2_MCK1, - GPIO_FN_MSIOF2_SS1, GPIO_FN_MSIOF2_SS2, - GPIO_FN_MSIOF2_TSYNC, GPIO_FN_MSIOF2_TSCK, - GPIO_FN_MSIOF2_RXD, GPIO_FN_MSIOF2_TXD, - - /* MSIOF3 (PORT 76, 77, 78, 79, 80, 81, 82, 83) */ - GPIO_FN_BBIF1_RXD, GPIO_FN_BBIF1_TSYNC, - GPIO_FN_BBIF1_TSCK, GPIO_FN_BBIF1_TXD, - GPIO_FN_BBIF1_RSCK, GPIO_FN_BBIF1_RSYNC, - GPIO_FN_BBIF1_FLOW, GPIO_FN_BB_RX_FLOW_N, - - /* MSIOF4 (PORT 0, 1, 2, 3) */ - GPIO_FN_BBIF2_TSCK1, GPIO_FN_BBIF2_TSYNC1, - GPIO_FN_BBIF2_TXD1, GPIO_FN_BBIF2_RXD, - - /* FSI (PORT 4, 5, 6, 7, 8, 9, 10, 11, 15) */ - GPIO_FN_FSIACK, GPIO_FN_FSIBCK, - GPIO_FN_FSIAILR, GPIO_FN_FSIAIBT, - GPIO_FN_FSIAISLD, GPIO_FN_FSIAOMC, - GPIO_FN_FSIAOLR, GPIO_FN_FSIAOBT, - GPIO_FN_FSIAOSLD, GPIO_FN_FSIASPDIF_11, - GPIO_FN_FSIASPDIF_15, - - /* FMSI (PORT 12, 13, 14, 15, 16, 17, 18, 65) */ - GPIO_FN_FMSOCK, GPIO_FN_FMSOOLR, - GPIO_FN_FMSIOLR, GPIO_FN_FMSOOBT, - GPIO_FN_FMSIOBT, GPIO_FN_FMSOSLD, - GPIO_FN_FMSOILR, GPIO_FN_FMSIILR, - GPIO_FN_FMSOIBT, GPIO_FN_FMSIIBT, - GPIO_FN_FMSISLD, GPIO_FN_FMSICK, - - /* SCIFA0 (PORT 152, 153, 156, 157, 158) */ - GPIO_FN_SCIFA0_TXD, GPIO_FN_SCIFA0_RXD, - GPIO_FN_SCIFA0_SCK, GPIO_FN_SCIFA0_RTS, - GPIO_FN_SCIFA0_CTS, - - /* SCIFA1 (PORT 154, 155, 159, 160, 161) */ - GPIO_FN_SCIFA1_TXD, GPIO_FN_SCIFA1_RXD, - GPIO_FN_SCIFA1_SCK, GPIO_FN_SCIFA1_RTS, - GPIO_FN_SCIFA1_CTS, - - /* SCIFA2 (PORT 94, 95, 96, 97, 98) */ - GPIO_FN_SCIFA2_CTS1, GPIO_FN_SCIFA2_RTS1, - GPIO_FN_SCIFA2_TXD1, GPIO_FN_SCIFA2_RXD1, - GPIO_FN_SCIFA2_SCK1, - - /* SCIFA3 (PORT 43, 44, - 140, 141, 142, 143, 144) */ - GPIO_FN_SCIFA3_CTS_43, GPIO_FN_SCIFA3_CTS_140, - GPIO_FN_SCIFA3_RTS_44, GPIO_FN_SCIFA3_RTS_141, - GPIO_FN_SCIFA3_SCK, GPIO_FN_SCIFA3_TXD, - GPIO_FN_SCIFA3_RXD, - - /* SCIFA4 (PORT 5, 6) */ - GPIO_FN_SCIFA4_RXD, GPIO_FN_SCIFA4_TXD, - - /* SCIFA5 (PORT 8, 12) */ - GPIO_FN_SCIFA5_RXD, GPIO_FN_SCIFA5_TXD, - - /* SCIFB (PORT 162, 163, 164, 165, 166) */ - GPIO_FN_SCIFB_SCK, GPIO_FN_SCIFB_RTS, - GPIO_FN_SCIFB_CTS, GPIO_FN_SCIFB_TXD, - GPIO_FN_SCIFB_RXD, - - /* - * CEU (PORT 16, 17, - * 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - * 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - * 120) - */ - GPIO_FN_VIO_HD, GPIO_FN_VIO_CKO1, GPIO_FN_VIO_CKO2, - GPIO_FN_VIO_VD, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD, - GPIO_FN_VIO_CKO, - GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2, - GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5, - GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8, - GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11, - GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14, - GPIO_FN_VIO_D15, - - /* USB0 (PORT 113, 114, 115, 116, 117, 167) */ - GPIO_FN_IDIN_0, GPIO_FN_EXTLP_0, - GPIO_FN_OVCN2_0, GPIO_FN_PWEN_0, - GPIO_FN_OVCN_0, GPIO_FN_VBUS0_0, - - /* USB1 (PORT 18, 113, 114, 115, 116, 117, 138, 162, 168) */ - GPIO_FN_IDIN_1_18, GPIO_FN_IDIN_1_113, - GPIO_FN_PWEN_1_115, GPIO_FN_PWEN_1_138, - GPIO_FN_OVCN_1_114, GPIO_FN_OVCN_1_162, - GPIO_FN_EXTLP_1, GPIO_FN_OVCN2_1, - GPIO_FN_VBUS0_1, - - /* GPIO (PORT 41, 42, 43, 44) */ - GPIO_FN_GPI0, GPIO_FN_GPI1, GPIO_FN_GPO0, GPIO_FN_GPO1, - - /* - * BSC (PORT 19, - * 20, 21, 22, 25, 26, 27, 28, 29, - * 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - * 40, 41, 42, 43, 44, 45, - * 62, 63, 64, 65, 66, 67, - * 71, 72, 74, 75) - */ - GPIO_FN_BS, GPIO_FN_WE1, - GPIO_FN_CKO, GPIO_FN_WAIT, GPIO_FN_RDWR, - - GPIO_FN_A0, GPIO_FN_A1, GPIO_FN_A2, GPIO_FN_A3, - GPIO_FN_A6, GPIO_FN_A7, GPIO_FN_A8, GPIO_FN_A9, - GPIO_FN_A10, GPIO_FN_A11, GPIO_FN_A12, GPIO_FN_A13, - GPIO_FN_A14, GPIO_FN_A15, GPIO_FN_A16, GPIO_FN_A17, - GPIO_FN_A18, GPIO_FN_A19, GPIO_FN_A20, GPIO_FN_A21, - GPIO_FN_A22, GPIO_FN_A23, GPIO_FN_A24, GPIO_FN_A25, - GPIO_FN_A26, - - GPIO_FN_CS0, GPIO_FN_CS2, GPIO_FN_CS4, - GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_CS6A, - - /* - * BSC/FLCTL (PORT 23, 24, - * 46, 47, 48, 49, - * 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - * 60, 61, 69, 70) - */ - GPIO_FN_RD_FSC, GPIO_FN_WE0_FWE, - GPIO_FN_A4_FOE, GPIO_FN_A5_FCDE, - GPIO_FN_D0_NAF0, GPIO_FN_D1_NAF1, GPIO_FN_D2_NAF2, - GPIO_FN_D3_NAF3, GPIO_FN_D4_NAF4, GPIO_FN_D5_NAF5, - GPIO_FN_D6_NAF6, GPIO_FN_D7_NAF7, GPIO_FN_D8_NAF8, - GPIO_FN_D9_NAF9, GPIO_FN_D10_NAF10, GPIO_FN_D11_NAF11, - GPIO_FN_D12_NAF12, GPIO_FN_D13_NAF13, GPIO_FN_D14_NAF14, - GPIO_FN_D15_NAF15, - - /* SPU2 (PORT 65) */ - GPIO_FN_VINT_I, - - /* FLCTL (PORT 66, 68, 73) */ - GPIO_FN_FCE1, GPIO_FN_FCE0, GPIO_FN_FRB, - - /* HSI (PORT 76, 77, 78, 79, 80, 81, 82, 83) */ - GPIO_FN_GP_RX_FLAG, GPIO_FN_GP_RX_DATA, GPIO_FN_GP_TX_READY, - GPIO_FN_GP_RX_WAKE, GPIO_FN_MP_TX_FLAG, GPIO_FN_MP_TX_DATA, - GPIO_FN_MP_RX_READY, GPIO_FN_MP_TX_WAKE, - - /* - * MFI (PORT 76, 77, 78, 79, - * 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - * 90, 91, 92, 93, 94, 95, 96, 97, 98, 99) - */ - GPIO_FN_MFIv6, /* see MSEL4CR 6 */ - GPIO_FN_MFIv4, /* see MSEL4CR 6 */ - - GPIO_FN_MEMC_CS0, GPIO_FN_MEMC_BUSCLK_MEMC_A0, - GPIO_FN_MEMC_CS1_MEMC_A1, GPIO_FN_MEMC_ADV_MEMC_DREQ0, - GPIO_FN_MEMC_WAIT_MEMC_DREQ1, GPIO_FN_MEMC_NOE, - GPIO_FN_MEMC_NWE, GPIO_FN_MEMC_INT, - - GPIO_FN_MEMC_AD0, GPIO_FN_MEMC_AD1, GPIO_FN_MEMC_AD2, - GPIO_FN_MEMC_AD3, GPIO_FN_MEMC_AD4, GPIO_FN_MEMC_AD5, - GPIO_FN_MEMC_AD6, GPIO_FN_MEMC_AD7, GPIO_FN_MEMC_AD8, - GPIO_FN_MEMC_AD9, GPIO_FN_MEMC_AD10, GPIO_FN_MEMC_AD11, - GPIO_FN_MEMC_AD12, GPIO_FN_MEMC_AD13, GPIO_FN_MEMC_AD14, - GPIO_FN_MEMC_AD15, - - /* SIM (PORT 94, 95, 98) */ - GPIO_FN_SIM_RST, GPIO_FN_SIM_CLK, GPIO_FN_SIM_D, - - /* TPU (PORT 93, 99, 112, 160, 161) */ - GPIO_FN_TPU0TO0, GPIO_FN_TPU0TO1, - GPIO_FN_TPU0TO2_93, GPIO_FN_TPU0TO2_99, - GPIO_FN_TPU0TO3, - - /* I2C2 (PORT 110, 111) */ - GPIO_FN_I2C_SCL2, GPIO_FN_I2C_SDA2, - - /* I2C3(1) (PORT 114, 115) */ - GPIO_FN_I2C_SCL3, GPIO_FN_I2C_SDA3, - - /* I2C3(2) (PORT 137, 145) */ - GPIO_FN_I2C_SCL3S, GPIO_FN_I2C_SDA3S, - - /* I2C4(2) (PORT 116, 117) */ - GPIO_FN_I2C_SCL4, GPIO_FN_I2C_SDA4, - - /* I2C4(2) (PORT 146, 147) */ - GPIO_FN_I2C_SCL4S, GPIO_FN_I2C_SDA4S, - - /* - * KEYSC (PORT 121, 122, 123, 124, 125, 126, 127, 128, 129, - * 130, 131, 132, 133, 134, 135, 136) - */ - GPIO_FN_KEYOUT0, GPIO_FN_KEYIN0_121, GPIO_FN_KEYIN0_136, - GPIO_FN_KEYOUT1, GPIO_FN_KEYIN1_122, GPIO_FN_KEYIN1_135, - GPIO_FN_KEYOUT2, GPIO_FN_KEYIN2_123, GPIO_FN_KEYIN2_134, - GPIO_FN_KEYOUT3, GPIO_FN_KEYIN3_124, GPIO_FN_KEYIN3_133, - GPIO_FN_KEYOUT4, GPIO_FN_KEYIN4, - GPIO_FN_KEYOUT5, GPIO_FN_KEYIN5, - GPIO_FN_KEYOUT6, GPIO_FN_KEYIN6, - GPIO_FN_KEYOUT7, GPIO_FN_KEYIN7, - - /* - * LCDC (PORT 121, 122, 123, 124, 125, 126, 127, 128, 129, - * 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - * 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - * 150, 151) - */ - GPIO_FN_LCDC0_SELECT, /* LCDC 0 */ - GPIO_FN_LCDC1_SELECT, /* LCDC 1 */ - GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDVSYN, - GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_LCDRD, - GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_LCDLCLK, - GPIO_FN_LCDDON, - - GPIO_FN_LCDD0, GPIO_FN_LCDD1, GPIO_FN_LCDD2, GPIO_FN_LCDD3, - GPIO_FN_LCDD4, GPIO_FN_LCDD5, GPIO_FN_LCDD6, GPIO_FN_LCDD7, - GPIO_FN_LCDD8, GPIO_FN_LCDD9, GPIO_FN_LCDD10, GPIO_FN_LCDD11, - GPIO_FN_LCDD12, GPIO_FN_LCDD13, GPIO_FN_LCDD14, GPIO_FN_LCDD15, - GPIO_FN_LCDD16, GPIO_FN_LCDD17, GPIO_FN_LCDD18, GPIO_FN_LCDD19, - GPIO_FN_LCDD20, GPIO_FN_LCDD21, GPIO_FN_LCDD22, GPIO_FN_LCDD23, - - /* IRDA (PORT 139, 140, 141, 142) */ - GPIO_FN_IRDA_OUT, GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL, - GPIO_FN_IROUT_139, GPIO_FN_IROUT_140, - - /* TSIF1 (PORT 156, 157, 158, 159) */ - GPIO_FN_TS0_1SELECT, /* TSIF0 - 1 select */ - GPIO_FN_TS0_2SELECT, /* TSIF0 - 2 select */ - GPIO_FN_TS1_1SELECT, /* TSIF1 - 1 select */ - GPIO_FN_TS1_2SELECT, /* TSIF1 - 2 select */ - - GPIO_FN_TS_SPSYNC1, GPIO_FN_TS_SDAT1, - GPIO_FN_TS_SDEN1, GPIO_FN_TS_SCK1, - - /* TSIF2 (PORT 137, 145, 146, 147) */ - GPIO_FN_TS_SPSYNC2, GPIO_FN_TS_SDAT2, - GPIO_FN_TS_SDEN2, GPIO_FN_TS_SCK2, - - /* HDMI (PORT 169, 170) */ - GPIO_FN_HDMI_HPD, GPIO_FN_HDMI_CEC, - - /* SDENC see MSEL4CR 19 */ - GPIO_FN_SDENC_CPG, - GPIO_FN_SDENC_DV_CLKI, -}; - /* DMA slave IDs */ enum { SHDMA_SLAVE_INVALID, diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 326a4ab..3a6b6fe 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -70,29 +70,15 @@ void __init r8a7740_map_io(void) } /* PFC */ -static struct resource r8a7740_pfc_resources[] = { - [0] = { - .start = 0xe6050000, - .end = 0xe6057fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0xe605800c, - .end = 0xe605802b, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device r8a7740_pfc_device = { - .name = "pfc-r8a7740", - .id = -1, - .resource = r8a7740_pfc_resources, - .num_resources = ARRAY_SIZE(r8a7740_pfc_resources), +static const struct resource pfc_resources[] = { + DEFINE_RES_MEM(0xe6050000, 0x8000), + DEFINE_RES_MEM(0xe605800c, 0x0020), }; void __init r8a7740_pinmux_init(void) { - platform_device_register(&r8a7740_pfc_device); + platform_device_register_simple("pfc-r8a7740", -1, pfc_resources, + ARRAY_SIZE(pfc_resources)); } static struct renesas_intc_irqpin_config irqpin0_platform_data = { diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 30b4a33..1b9b7f2 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -24,6 +24,7 @@ #include <linux/irqchip/arm-gic.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> #include <linux/irqchip.h> @@ -80,12 +81,6 @@ static struct sh_timer_config sh_tmu1_platform_data = { .clocksource_rating = 200, }; -/* Ether */ -static struct resource ether_resources[] = { - DEFINE_RES_MEM(0xfde00000, 0x400), - DEFINE_RES_IRQ(gic_iid(0x89)), -}; - #define r8a7778_register_tmu(idx) \ platform_device_register_resndata( \ &platform_bus, "sh_tmu", idx, \ @@ -94,6 +89,90 @@ static struct resource ether_resources[] = { &sh_tmu##idx##_platform_data, \ sizeof(sh_tmu##idx##_platform_data)) +/* Ether */ +static struct resource ether_resources[] = { + DEFINE_RES_MEM(0xfde00000, 0x400), + DEFINE_RES_IRQ(gic_iid(0x89)), +}; + +void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) +{ + platform_device_register_resndata(&platform_bus, "sh_eth", -1, + ether_resources, + ARRAY_SIZE(ether_resources), + pdata, sizeof(*pdata)); +} + +/* PFC/GPIO */ +static struct resource pfc_resources[] = { + DEFINE_RES_MEM(0xfffc0000, 0x118), +}; + +#define R8A7778_GPIO(idx) \ +static struct resource r8a7778_gpio##idx##_resources[] = { \ + DEFINE_RES_MEM(0xffc40000 + 0x1000 * (idx), 0x30), \ + DEFINE_RES_IRQ(gic_iid(0x87)), \ +}; \ + \ +static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data = { \ + .gpio_base = 32 * (idx), \ + .irq_base = GPIO_IRQ_BASE(idx), \ + .number_of_pins = 32, \ + .pctl_name = "pfc-r8a7778", \ +} + +R8A7778_GPIO(0); +R8A7778_GPIO(1); +R8A7778_GPIO(2); +R8A7778_GPIO(3); +R8A7778_GPIO(4); + +#define r8a7778_register_gpio(idx) \ + platform_device_register_resndata( \ + &platform_bus, "gpio_rcar", idx, \ + r8a7778_gpio##idx##_resources, \ + ARRAY_SIZE(r8a7778_gpio##idx##_resources), \ + &r8a7778_gpio##idx##_platform_data, \ + sizeof(r8a7778_gpio##idx##_platform_data)) + +void __init r8a7778_pinmux_init(void) +{ + platform_device_register_simple( + "pfc-r8a7778", -1, + pfc_resources, + ARRAY_SIZE(pfc_resources)); + + r8a7778_register_gpio(0); + r8a7778_register_gpio(1); + r8a7778_register_gpio(2); + r8a7778_register_gpio(3); + r8a7778_register_gpio(4); +}; + +/* SDHI */ +static struct resource sdhi_resources[] = { + /* SDHI0 */ + DEFINE_RES_MEM(0xFFE4C000, 0x100), + DEFINE_RES_IRQ(gic_iid(0x77)), + /* SDHI1 */ + DEFINE_RES_MEM(0xFFE4D000, 0x100), + DEFINE_RES_IRQ(gic_iid(0x78)), + /* SDHI2 */ + DEFINE_RES_MEM(0xFFE4F000, 0x100), + DEFINE_RES_IRQ(gic_iid(0x76)), +}; + +void __init r8a7778_sdhi_init(int id, + struct sh_mobile_sdhi_info *info) +{ + BUG_ON(id < 0 || id > 2); + + platform_device_register_resndata( + &platform_bus, "sh_mobile_sdhi", id, + sdhi_resources + (2 * id), 2, + info, sizeof(*info)); +} + void __init r8a7778_add_standard_devices(void) { int i; @@ -118,14 +197,6 @@ void __init r8a7778_add_standard_devices(void) r8a7778_register_tmu(1); } -void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) -{ - platform_device_register_resndata(&platform_bus, "sh_eth", -1, - ether_resources, - ARRAY_SIZE(ether_resources), - pdata, sizeof(*pdata)); -} - static struct renesas_intc_irqpin_config irqpin_platform_data = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ .sense_bitfield_width = 2, diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index b0b3948..dbb13f2 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -65,11 +65,7 @@ void __init r8a7779_map_io(void) } static struct resource r8a7779_pfc_resources[] = { - [0] = { - .start = 0xfffc0000, - .end = 0xfffc023b, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0xfffc0000, 0x023c), }; static struct platform_device r8a7779_pfc_device = { @@ -81,15 +77,8 @@ static struct platform_device r8a7779_pfc_device = { #define R8A7779_GPIO(idx, npins) \ static struct resource r8a7779_gpio##idx##_resources[] = { \ - [0] = { \ - .start = 0xffc40000 + 0x1000 * (idx), \ - .end = 0xffc4002b + 0x1000 * (idx), \ - .flags = IORESOURCE_MEM, \ - }, \ - [1] = { \ - .start = gic_iid(0xad + (idx)), \ - .flags = IORESOURCE_IRQ, \ - } \ + DEFINE_RES_MEM(0xffc40000 + (0x1000 * (idx)), 0x002c), \ + DEFINE_RES_IRQ(gic_iid(0xad + (idx))), \ }; \ \ static struct gpio_rcar_config r8a7779_gpio##idx##_platform_data = { \ diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 49de2d5..b461d93 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -23,6 +23,7 @@ #include <linux/kernel.h> #include <linux/of_platform.h> #include <linux/serial_sci.h> +#include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-irqc.h> #include <mach/common.h> #include <mach/irqs.h> @@ -31,13 +32,46 @@ static const struct resource pfc_resources[] = { DEFINE_RES_MEM(0xe6060000, 0x250), - DEFINE_RES_MEM(0xe6050000, 0x5050), }; +#define R8A7790_GPIO(idx) \ +static struct resource r8a7790_gpio##idx##_resources[] = { \ + DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \ + DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ +}; \ + \ +static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data = { \ + .gpio_base = 32 * (idx), \ + .irq_base = 0, \ + .number_of_pins = 32, \ + .pctl_name = "pfc-r8a7790", \ + .has_both_edge_trigger = 1, \ +}; \ + +R8A7790_GPIO(0); +R8A7790_GPIO(1); +R8A7790_GPIO(2); +R8A7790_GPIO(3); +R8A7790_GPIO(4); +R8A7790_GPIO(5); + +#define r8a7790_register_gpio(idx) \ + platform_device_register_resndata(&platform_bus, "gpio_rcar", idx, \ + r8a7790_gpio##idx##_resources, \ + ARRAY_SIZE(r8a7790_gpio##idx##_resources), \ + &r8a7790_gpio##idx##_platform_data, \ + sizeof(r8a7790_gpio##idx##_platform_data)) + void __init r8a7790_pinmux_init(void) { platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, ARRAY_SIZE(pfc_resources)); + r8a7790_register_gpio(0); + r8a7790_register_gpio(1); + r8a7790_register_gpio(2); + r8a7790_register_gpio(3); + r8a7790_register_gpio(4); + r8a7790_register_gpio(5); } #define SCIF_COMMON(scif_type, baseaddr, irq) \ diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 9696f36..96e7ca1 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -288,12 +288,7 @@ static struct sh_timer_config tmu00_platform_data = { }; static struct resource tmu00_resources[] = { - [0] = { - .name = "TMU00", - .start = 0xfff60008, - .end = 0xfff60013, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xfff60008, 0xc, "TMU00"), [1] = { .start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */ .flags = IORESOURCE_IRQ, @@ -318,12 +313,7 @@ static struct sh_timer_config tmu01_platform_data = { }; static struct resource tmu01_resources[] = { - [0] = { - .name = "TMU01", - .start = 0xfff60014, - .end = 0xfff6001f, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xfff60014, 0xc, "TMU00"), [1] = { .start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */ .flags = IORESOURCE_IRQ, @@ -341,12 +331,7 @@ static struct platform_device tmu01_device = { }; static struct resource i2c0_resources[] = { - [0] = { - .name = "IIC0", - .start = 0xe6820000, - .end = 0xe6820425 - 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xe6820000, 0x426, "IIC0"), [1] = { .start = gic_spi(167), .end = gic_spi(170), @@ -355,12 +340,7 @@ static struct resource i2c0_resources[] = { }; static struct resource i2c1_resources[] = { - [0] = { - .name = "IIC1", - .start = 0xe6822000, - .end = 0xe6822425 - 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xe6822000, 0x426, "IIC1"), [1] = { .start = gic_spi(51), .end = gic_spi(54), @@ -369,12 +349,7 @@ static struct resource i2c1_resources[] = { }; static struct resource i2c2_resources[] = { - [0] = { - .name = "IIC2", - .start = 0xe6824000, - .end = 0xe6824425 - 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xe6824000, 0x426, "IIC2"), [1] = { .start = gic_spi(171), .end = gic_spi(174), @@ -383,12 +358,7 @@ static struct resource i2c2_resources[] = { }; static struct resource i2c3_resources[] = { - [0] = { - .name = "IIC3", - .start = 0xe6826000, - .end = 0xe6826425 - 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xe6826000, 0x426, "IIC3"), [1] = { .start = gic_spi(183), .end = gic_spi(186), @@ -397,12 +367,7 @@ static struct resource i2c3_resources[] = { }; static struct resource i2c4_resources[] = { - [0] = { - .name = "IIC4", - .start = 0xe6828000, - .end = 0xe6828425 - 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM_NAMED(0xe6828000, 0x426, "IIC4"), [1] = { .start = gic_spi(187), .end = gic_spi(190), @@ -623,12 +588,7 @@ static struct sh_dmae_pdata sh73a0_dmae_platform_data = { }; static struct resource sh73a0_dmae_resources[] = { - { - /* Registers including DMAOR and channels including DMARSx */ - .start = 0xfe000020, - .end = 0xfe008a00 - 1, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0xfe000020, 0x89e0), { .name = "error_irq", .start = gic_spi(129), @@ -727,18 +687,10 @@ static struct sh_dmae_pdata sh73a0_mpdma_platform_data = { /* Resource order important! */ static struct resource sh73a0_mpdma_resources[] = { - { - /* Channel registers and DMAOR */ - .start = 0xec618020, - .end = 0xec61828f, - .flags = IORESOURCE_MEM, - }, - { - /* DMARSx */ - .start = 0xec619000, - .end = 0xec61900b, - .flags = IORESOURCE_MEM, - }, + /* Channel registers and DMAOR */ + DEFINE_RES_MEM(0xec618020, 0x270), + /* DMARSx */ + DEFINE_RES_MEM(0xec619000, 0xc), { .name = "error_irq", .start = gic_spi(181), @@ -785,12 +737,7 @@ static struct platform_device pmu_device = { /* an IPMMU module for ICB */ static struct resource ipmmu_resources[] = { - [0] = { - .name = "IPMMU", - .start = 0xfe951000, - .end = 0xfe9510ff, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM_NAMED(0xfe951000, 0x100, "IPMMU"), }; static const char * const ipmmu_dev_names[] = { @@ -982,11 +929,17 @@ void __init sh73a0_add_standard_devices(void) ARRAY_SIZE(sh73a0_late_devices)); } +void __init sh73a0_init_delay(void) +{ + shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ +} + /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ void __init __weak sh73a0_register_twd(void) { } void __init sh73a0_earlytimer_init(void) { + sh73a0_init_delay(); sh73a0_clock_init(); shmobile_earlytimer_init(); sh73a0_register_twd(); @@ -1005,17 +958,14 @@ void __init sh73a0_add_early_devices(void) #ifdef CONFIG_USE_OF -void __init sh73a0_init_delay(void) -{ - shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ -} - static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = { {}, }; void __init sh73a0_add_standard_devices_dt(void) { + struct platform_device_info devinfo = { .name = "cpufreq-cpu0", .id = -1, }; + /* clocks are setup late during boot in the case of DT */ sh73a0_clock_init(); @@ -1023,6 +973,9 @@ void __init sh73a0_add_standard_devices_dt(void) ARRAY_SIZE(sh73a0_devices_dt)); of_platform_populate(NULL, of_default_bus_match_table, sh73a0_auxdata_lookup, NULL); + + /* Instantiate cpufreq-cpu0 */ + platform_device_register_full(&devinfo); } static const char *sh73a0_boards_compat_dt[] __initdata = { diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 566e804..07dff6f 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -13,5 +13,6 @@ config ARCH_SOCFPGA select GPIO_PL061 if GPIOLIB select HAVE_ARM_SCU select HAVE_SMP + select MFD_SYSCON select SPARSE_IRQ select USE_OF diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 5907e10..b8bbabe 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -57,4 +57,13 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA config ARCH_VEXPRESS_CA9X4 bool "Versatile Express Cortex-A9x4 tile" +config ARCH_VEXPRESS_DCSCB + bool "Dual Cluster System Control Block (DCSCB) support" + depends on MCPM + select ARM_CCI + help + Support for the Dual Cluster System Configuration Block (DCSCB). + This is needed to provide CPU and cluster power management + on RTSM implementing big.LITTLE. + endmenu diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index 42703e8..48ba89a 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile @@ -6,5 +6,6 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ obj-y := v2m.o obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o +obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index f134cd4..bde4374 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h @@ -6,6 +6,8 @@ void vexpress_dt_smp_map_io(void); +bool vexpress_smp_init_ops(void); + extern struct smp_operations vexpress_smp_ops; extern void vexpress_cpu_die(unsigned int cpu); diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c new file mode 100644 index 0000000..16d57a8 --- /dev/null +++ b/arch/arm/mach-vexpress/dcscb.c @@ -0,0 +1,253 @@ +/* + * arch/arm/mach-vexpress/dcscb.c - Dual Cluster System Configuration Block + * + * Created by: Nicolas Pitre, May 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/spinlock.h> +#include <linux/errno.h> +#include <linux/of_address.h> +#include <linux/vexpress.h> +#include <linux/arm-cci.h> + +#include <asm/mcpm.h> +#include <asm/proc-fns.h> +#include <asm/cacheflush.h> +#include <asm/cputype.h> +#include <asm/cp15.h> + + +#define RST_HOLD0 0x0 +#define RST_HOLD1 0x4 +#define SYS_SWRESET 0x8 +#define RST_STAT0 0xc +#define RST_STAT1 0x10 +#define EAG_CFG_R 0x20 +#define EAG_CFG_W 0x24 +#define KFC_CFG_R 0x28 +#define KFC_CFG_W 0x2c +#define DCS_CFG_R 0x30 + +/* + * We can't use regular spinlocks. In the switcher case, it is possible + * for an outbound CPU to call power_down() while its inbound counterpart + * is already live using the same logical CPU number which trips lockdep + * debugging. + */ +static arch_spinlock_t dcscb_lock = __ARCH_SPIN_LOCK_UNLOCKED; + +static void __iomem *dcscb_base; +static int dcscb_use_count[4][2]; +static int dcscb_allcpus_mask[2]; + +static int dcscb_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned int rst_hold, cpumask = (1 << cpu); + unsigned int all_mask = dcscb_allcpus_mask[cluster]; + + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); + if (cpu >= 4 || cluster >= 2) + return -EINVAL; + + /* + * Since this is called with IRQs enabled, and no arch_spin_lock_irq + * variant exists, we need to disable IRQs manually here. + */ + local_irq_disable(); + arch_spin_lock(&dcscb_lock); + + dcscb_use_count[cpu][cluster]++; + if (dcscb_use_count[cpu][cluster] == 1) { + rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4); + if (rst_hold & (1 << 8)) { + /* remove cluster reset and add individual CPU's reset */ + rst_hold &= ~(1 << 8); + rst_hold |= all_mask; + } + rst_hold &= ~(cpumask | (cpumask << 4)); + writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4); + } else if (dcscb_use_count[cpu][cluster] != 2) { + /* + * The only possible values are: + * 0 = CPU down + * 1 = CPU (still) up + * 2 = CPU requested to be up before it had a chance + * to actually make itself down. + * Any other value is a bug. + */ + BUG(); + } + + arch_spin_unlock(&dcscb_lock); + local_irq_enable(); + + return 0; +} + +static void dcscb_power_down(void) +{ + unsigned int mpidr, cpu, cluster, rst_hold, cpumask, all_mask; + bool last_man = false, skip_wfi = false; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + cpumask = (1 << cpu); + all_mask = dcscb_allcpus_mask[cluster]; + + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); + BUG_ON(cpu >= 4 || cluster >= 2); + + __mcpm_cpu_going_down(cpu, cluster); + + arch_spin_lock(&dcscb_lock); + BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP); + dcscb_use_count[cpu][cluster]--; + if (dcscb_use_count[cpu][cluster] == 0) { + rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4); + rst_hold |= cpumask; + if (((rst_hold | (rst_hold >> 4)) & all_mask) == all_mask) { + rst_hold |= (1 << 8); + last_man = true; + } + writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4); + } else if (dcscb_use_count[cpu][cluster] == 1) { + /* + * A power_up request went ahead of us. + * Even if we do not want to shut this CPU down, + * the caller expects a certain state as if the WFI + * was aborted. So let's continue with cache cleaning. + */ + skip_wfi = true; + } else + BUG(); + + if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) { + arch_spin_unlock(&dcscb_lock); + + /* + * Flush all cache levels for this cluster. + * + * A15/A7 can hit in the cache with SCTLR.C=0, so we don't need + * a preliminary flush here for those CPUs. At least, that's + * the theory -- without the extra flush, Linux explodes on + * RTSM (to be investigated). + */ + flush_cache_all(); + set_cr(get_cr() & ~CR_C); + flush_cache_all(); + + /* + * This is a harmless no-op. On platforms with a real + * outer cache this might either be needed or not, + * depending on where the outer cache sits. + */ + outer_flush_all(); + + /* Disable local coherency by clearing the ACTLR "SMP" bit: */ + set_auxcr(get_auxcr() & ~(1 << 6)); + + /* + * Disable cluster-level coherency by masking + * incoming snoops and DVM messages: + */ + cci_disable_port_by_cpu(mpidr); + + __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN); + } else { + arch_spin_unlock(&dcscb_lock); + + /* + * Flush the local CPU cache. + * + * A15/A7 can hit in the cache with SCTLR.C=0, so we don't need + * a preliminary flush here for those CPUs. At least, that's + * the theory -- without the extra flush, Linux explodes on + * RTSM (to be investigated). + */ + flush_cache_louis(); + set_cr(get_cr() & ~CR_C); + flush_cache_louis(); + + /* Disable local coherency by clearing the ACTLR "SMP" bit: */ + set_auxcr(get_auxcr() & ~(1 << 6)); + } + + __mcpm_cpu_down(cpu, cluster); + + /* Now we are prepared for power-down, do it: */ + dsb(); + if (!skip_wfi) + wfi(); + + /* Not dead at this point? Let our caller cope. */ +} + +static const struct mcpm_platform_ops dcscb_power_ops = { + .power_up = dcscb_power_up, + .power_down = dcscb_power_down, +}; + +static void __init dcscb_usage_count_init(void) +{ + unsigned int mpidr, cpu, cluster; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); + BUG_ON(cpu >= 4 || cluster >= 2); + dcscb_use_count[cpu][cluster] = 1; +} + +extern void dcscb_power_up_setup(unsigned int affinity_level); + +static int __init dcscb_init(void) +{ + struct device_node *node; + unsigned int cfg; + int ret; + + if (!cci_probed()) + return -ENODEV; + + node = of_find_compatible_node(NULL, NULL, "arm,rtsm,dcscb"); + if (!node) + return -ENODEV; + dcscb_base = of_iomap(node, 0); + if (!dcscb_base) + return -EADDRNOTAVAIL; + cfg = readl_relaxed(dcscb_base + DCS_CFG_R); + dcscb_allcpus_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1; + dcscb_allcpus_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1; + dcscb_usage_count_init(); + + ret = mcpm_platform_register(&dcscb_power_ops); + if (!ret) + ret = mcpm_sync_init(dcscb_power_up_setup); + if (ret) { + iounmap(dcscb_base); + return ret; + } + + pr_info("VExpress DCSCB support installed\n"); + + /* + * Future entries into the kernel can now go + * through the cluster entry vectors. + */ + vexpress_flags_set(virt_to_phys(mcpm_entry_point)); + + return 0; +} + +early_initcall(dcscb_init); diff --git a/arch/arm/mach-vexpress/dcscb_setup.S b/arch/arm/mach-vexpress/dcscb_setup.S new file mode 100644 index 0000000..4bb7fbe --- /dev/null +++ b/arch/arm/mach-vexpress/dcscb_setup.S @@ -0,0 +1,38 @@ +/* + * arch/arm/include/asm/dcscb_setup.S + * + * Created by: Dave Martin, 2012-06-22 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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/linkage.h> + + +ENTRY(dcscb_power_up_setup) + + cmp r0, #0 @ check affinity level + beq 2f + +/* + * Enable cluster-level coherency, in preparation for turning on the MMU. + * The ACTLR SMP bit does not need to be set here, because cpu_resume() + * already restores that. + * + * A15/A7 may not require explicit L2 invalidation on reset, dependent + * on hardware integration decisions. + * For now, this code assumes that L2 is either already invalidated, + * or invalidation is not required. + */ + + b cci_enable_port_for_self + +2: @ Implementation-specific local CPU setup operations should go here, + @ if any. In this case, there is nothing to do. + + bx lr + +ENDPROC(dcscb_power_up_setup) diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index dc1ace5..993c9ae 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c @@ -12,9 +12,11 @@ #include <linux/errno.h> #include <linux/smp.h> #include <linux/io.h> +#include <linux/of.h> #include <linux/of_fdt.h> #include <linux/vexpress.h> +#include <asm/mcpm.h> #include <asm/smp_scu.h> #include <asm/mach/map.h> @@ -203,3 +205,21 @@ struct smp_operations __initdata vexpress_smp_ops = { .cpu_die = vexpress_cpu_die, #endif }; + +bool __init vexpress_smp_init_ops(void) +{ +#ifdef CONFIG_MCPM + /* + * The best way to detect a multi-cluster configuration at the moment + * is to look for the presence of a CCI in the system. + * Override the default vexpress_smp_ops if so. + */ + struct device_node *node; + node = of_find_compatible_node(NULL, NULL, "arm,cci-400"); + if (node && of_device_is_available(node)) { + mcpm_smp_set_ops(); + return true; + } +#endif + return false; +} diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 8802030..b0eccf7 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -456,6 +456,7 @@ static const char * const v2m_dt_match[] __initconst = { DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") .dt_compat = v2m_dt_match, .smp = smp_ops(vexpress_smp_ops), + .smp_init = smp_init_ops(vexpress_smp_init_ops), .map_io = v2m_dt_map_io, .init_early = v2m_dt_init_early, .init_irq = irqchip_init, diff --git a/arch/arm/mach-virt/Makefile b/arch/arm/mach-virt/Makefile index 042afc1..7ddbfa6 100644 --- a/arch/arm/mach-virt/Makefile +++ b/arch/arm/mach-virt/Makefile @@ -3,4 +3,3 @@ # obj-y := virt.o -obj-$(CONFIG_SMP) += platsmp.o diff --git a/arch/arm/mach-virt/platsmp.c b/arch/arm/mach-virt/platsmp.c deleted file mode 100644 index f4143f5..0000000 --- a/arch/arm/mach-virt/platsmp.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Dummy Virtual Machine - does what it says on the tin. - * - * Copyright (C) 2012 ARM Ltd - * Author: Will Deacon <will.deacon@arm.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/init.h> -#include <linux/smp.h> -#include <linux/of.h> - -#include <asm/psci.h> -#include <asm/smp_plat.h> - -extern void secondary_startup(void); - -static void __init virt_smp_init_cpus(void) -{ -} - -static void __init virt_smp_prepare_cpus(unsigned int max_cpus) -{ -} - -static int __cpuinit virt_boot_secondary(unsigned int cpu, - struct task_struct *idle) -{ - if (psci_ops.cpu_on) - return psci_ops.cpu_on(cpu_logical_map(cpu), - __pa(secondary_startup)); - return -ENODEV; -} - -struct smp_operations __initdata virt_smp_ops = { - .smp_init_cpus = virt_smp_init_cpus, - .smp_prepare_cpus = virt_smp_prepare_cpus, - .smp_boot_secondary = virt_boot_secondary, -}; diff --git a/arch/arm/mach-virt/virt.c b/arch/arm/mach-virt/virt.c index 061f283..a67d2dd 100644 --- a/arch/arm/mach-virt/virt.c +++ b/arch/arm/mach-virt/virt.c @@ -36,11 +36,8 @@ static const char *virt_dt_match[] = { NULL }; -extern struct smp_operations virt_smp_ops; - DT_MACHINE_START(VIRT, "Dummy Virtual Machine") .init_irq = irqchip_init, .init_machine = virt_init, - .smp = smp_ops(virt_smp_ops), .dt_compat = virt_dt_match, MACHINE_END diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index c70969b..50d008d 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -117,7 +117,7 @@ int __init zynq_slcr_init(void) pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); - xilinx_zynq_clocks_init(zynq_slcr_base); + zynq_clock_init(zynq_slcr_base); of_node_put(np); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 35955b5..9e8101e 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -397,6 +397,15 @@ config CPU_V7 select CPU_PABRT_V7 select CPU_TLB_V7 if MMU +# ARMv7M +config CPU_V7M + bool + select CPU_32v7M + select CPU_ABRT_NOMMU + select CPU_CACHE_NOP + select CPU_PABRT_LEGACY + select CPU_THUMBONLY + config CPU_THUMBONLY bool # There are no CPUs available with MMU that don't implement an ARM ISA: @@ -441,6 +450,9 @@ config CPU_32v6K config CPU_32v7 bool +config CPU_32v7M + bool + # The abort model config CPU_ABRT_NOMMU bool @@ -491,6 +503,9 @@ config CPU_CACHE_V6 config CPU_CACHE_V7 bool +config CPU_CACHE_NOP + bool + config CPU_CACHE_VIVT bool @@ -613,7 +628,11 @@ config ARCH_DMA_ADDR_T_64BIT config ARM_THUMB bool "Support Thumb user binaries" if !CPU_THUMBONLY - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || \ + CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || \ + CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \ + CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || \ + CPU_V7 || CPU_FEROCEON || CPU_V7M default y help Say Y if you want to include kernel support for running user space diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 9e51be9..ee558a0 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o +obj-$(CONFIG_CPU_CACHE_NOP) += cache-nop.o AFLAGS_cache-v6.o :=-Wa,-march=armv6 AFLAGS_cache-v7.o :=-Wa,-march=armv7-a @@ -87,6 +88,7 @@ obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V6K) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o +obj-$(CONFIG_CPU_V7M) += proc-v7m.o AFLAGS_proc-v6.o :=-Wa,-march=armv6 AFLAGS_proc-v7.o :=-Wa,-march=armv7-a diff --git a/arch/arm/mm/cache-nop.S b/arch/arm/mm/cache-nop.S new file mode 100644 index 0000000..8e12ddc --- /dev/null +++ b/arch/arm/mm/cache-nop.S @@ -0,0 +1,50 @@ +/* + * 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/linkage.h> +#include <linux/init.h> + +#include "proc-macros.S" + +ENTRY(nop_flush_icache_all) + mov pc, lr +ENDPROC(nop_flush_icache_all) + + .globl nop_flush_kern_cache_all + .equ nop_flush_kern_cache_all, nop_flush_icache_all + + .globl nop_flush_kern_cache_louis + .equ nop_flush_kern_cache_louis, nop_flush_icache_all + + .globl nop_flush_user_cache_all + .equ nop_flush_user_cache_all, nop_flush_icache_all + + .globl nop_flush_user_cache_range + .equ nop_flush_user_cache_range, nop_flush_icache_all + + .globl nop_coherent_kern_range + .equ nop_coherent_kern_range, nop_flush_icache_all + +ENTRY(nop_coherent_user_range) + mov r0, 0 + mov pc, lr +ENDPROC(nop_coherent_user_range) + + .globl nop_flush_kern_dcache_area + .equ nop_flush_kern_dcache_area, nop_flush_icache_all + + .globl nop_dma_flush_range + .equ nop_dma_flush_range, nop_flush_icache_all + + .globl nop_dma_map_area + .equ nop_dma_map_area, nop_flush_icache_all + + .globl nop_dma_unmap_area + .equ nop_dma_unmap_area, nop_flush_icache_all + + __INITDATA + + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions nop diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index d51225f..dd3a6c6 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -20,12 +20,19 @@ void __init arm_mm_memblock_reserve(void) { +#ifndef CONFIG_CPU_V7M /* * Register the exception vector page. * some architectures which the DRAM is the exception vector to trap, * alloc_page breaks with error, although it is not NULL, but "0." */ memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); +#else /* ifndef CONFIG_CPU_V7M */ + /* + * There is no dedicated vector page on V7-M. So nothing needs to be + * reserved here. + */ +#endif } void __init sanity_check_meminfo(void) diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S new file mode 100644 index 0000000..0c93588 --- /dev/null +++ b/arch/arm/mm/proc-v7m.S @@ -0,0 +1,157 @@ +/* + * linux/arch/arm/mm/proc-v7m.S + * + * Copyright (C) 2008 ARM Ltd. + * Copyright (C) 2001 Deep Blue Solutions Ltd. + * + * 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 is the "shell" of the ARMv7-M processor support. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/v7m.h> +#include "proc-macros.S" + +ENTRY(cpu_v7m_proc_init) + mov pc, lr +ENDPROC(cpu_v7m_proc_init) + +ENTRY(cpu_v7m_proc_fin) + mov pc, lr +ENDPROC(cpu_v7m_proc_fin) + +/* + * cpu_v7m_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * - loc - location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_v7m_reset) + mov pc, r0 +ENDPROC(cpu_v7m_reset) + +/* + * cpu_v7m_do_idle() + * + * Idle the processor (eg, wait for interrupt). + * + * IRQs are already disabled. + */ +ENTRY(cpu_v7m_do_idle) + wfi + mov pc, lr +ENDPROC(cpu_v7m_do_idle) + +ENTRY(cpu_v7m_dcache_clean_area) + mov pc, lr +ENDPROC(cpu_v7m_dcache_clean_area) + +/* + * There is no MMU, so here is nothing to do. + */ +ENTRY(cpu_v7m_switch_mm) + mov pc, lr +ENDPROC(cpu_v7m_switch_mm) + +.globl cpu_v7m_suspend_size +.equ cpu_v7m_suspend_size, 0 + +#ifdef CONFIG_ARM_CPU_SUSPEND +ENTRY(cpu_v7m_do_suspend) + mov pc, lr +ENDPROC(cpu_v7m_do_suspend) + +ENTRY(cpu_v7m_do_resume) + mov pc, lr +ENDPROC(cpu_v7m_do_resume) +#endif + + .section ".text.init", #alloc, #execinstr + +/* + * __v7m_setup + * + * This should be able to cover all ARMv7-M cores. + */ +__v7m_setup: + @ Configure the vector table base address + ldr r0, =BASEADDR_V7M_SCB + ldr r12, =vector_table + str r12, [r0, V7M_SCB_VTOR] + + @ enable UsageFault, BusFault and MemManage fault. + ldr r5, [r0, #V7M_SCB_SHCSR] + orr r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA) + str r5, [r0, #V7M_SCB_SHCSR] + + @ Lower the priority of the SVC and PendSV exceptions + mov r5, #0x80000000 + str r5, [r0, V7M_SCB_SHPR2] @ set SVC priority + mov r5, #0x00800000 + str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority + + @ SVC to run the kernel in this mode + adr r1, BSYM(1f) + ldr r5, [r12, #11 * 4] @ read the SVC vector entry + str r1, [r12, #11 * 4] @ write the temporary SVC vector entry + mov r6, lr @ save LR + mov r7, sp @ save SP + ldr sp, =__v7m_setup_stack_top + cpsie i + svc #0 +1: cpsid i + str r5, [r12, #11 * 4] @ restore the original SVC vector entry + mov lr, r6 @ restore LR + mov sp, r7 @ restore SP + + @ Special-purpose control register + mov r1, #1 + msr control, r1 @ Thread mode has unpriviledged access + + @ Configure the System Control Register to ensure 8-byte stack alignment + @ Note the STKALIGN bit is either RW or RAO. + ldr r12, [r0, V7M_SCB_CCR] @ system control register + orr r12, #V7M_SCB_CCR_STKALIGN + str r12, [r0, V7M_SCB_CCR] + mov pc, lr +ENDPROC(__v7m_setup) + + define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 + + .section ".rodata" + string cpu_arch_name, "armv7m" + string cpu_elf_name "v7m" + string cpu_v7m_name "ARMv7-M" + + .section ".proc.info.init", #alloc, #execinstr + + /* + * Match any ARMv7-M processor core. + */ + .type __v7m_proc_info, #object +__v7m_proc_info: + .long 0x000f0000 @ Required ID value + .long 0x000f0000 @ Mask for ID + .long 0 @ proc_info_list.__cpu_mm_mmu_flags + .long 0 @ proc_info_list.__cpu_io_mmu_flags + b __v7m_setup @ proc_info_list.__cpu_flush + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT + .long cpu_v7m_name + .long v7m_processor_functions @ proc_info_list.proc + .long 0 @ proc_info_list.tlb + .long 0 @ proc_info_list.user + .long nop_cache_fns @ proc_info_list.cache + .size __v7m_proc_info, . - __v7m_proc_info + +__v7m_setup_stack: + .space 4 * 8 @ 8 registers +__v7m_setup_stack_top: diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h index d015763..bd3a6db 100644 --- a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h +++ b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h @@ -28,7 +28,6 @@ struct s3c24xx_dma_map { const char *name; unsigned long channels[S3C_DMA_CHANNELS]; - unsigned long channels_rx[S3C_DMA_CHANNELS]; }; struct s3c24xx_dma_selection { @@ -38,10 +37,6 @@ struct s3c24xx_dma_selection { void (*select)(struct s3c2410_dma_chan *chan, struct s3c24xx_dma_map *map); - - void (*direction)(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map, - enum dma_data_direction dir); }; extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); |