diff options
author | Olof Johansson <olof@lixom.net> | 2013-08-14 07:54:46 (GMT) |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-08-14 07:54:46 (GMT) |
commit | 74f19946976edabe6432ac0005346b0611e2f8c1 (patch) | |
tree | 9c39cba7d0dd32f67f67f82f19e385d8bd34afed | |
parent | 13b837999f5cff1b0f40842704a18a2357dc22b2 (diff) | |
parent | f79d68da510bf1b95beff4d556b78d06801f11dc (diff) | |
download | linux-fsl-qoriq-74f19946976edabe6432ac0005346b0611e2f8c1.tar.xz |
Merge tag 'renesas-boards-for-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/boards
From Simon Horman:
Renesas ARM-based SoC board updates for v3.12
* ape6evm: Add SDHI and MMCIF support
* lager: Add MMCIF support
* armadillo800eva: Add DMA support for MMCIF
* tag 'renesas-boards-for-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: (54 commits)
ARM: shmobile: ape6evm: add SDHI interfaces
ARM: shmobile: ape6evm: add MMCIF support
ARM: shmobile: select the fixed regulator driver on BockW
ARM: shmobile: lager: add MMCIF support
ARM: shmobile: armadillo800eva: add DMA support to MMCIF
ARM: shmobile: Setup r8a7790 arch timer based on MD pins
ARM: shmobile: Introduce r8a7790_read_mode_pins()
ARM: shmobile: r8a7740: add MMCIF DMA definitions
ARM: shmobile: Disconnect EMEV2 SMP code from clocks
ARM: shmobile: Make r8a73a4 Arch timer optional
ARM: shmobile: Add r8a73a4 CMT10 clock event
ARM: shmobile: Make r8a7790 Arch timer optional
ARM: shmobile: Add r8a7790 CMT00 clock event
ARM: shmobile: Sort r8a7790 MSTP entries
ARM: shmobile: r8a73a4: add clocks for I2C controllers
ARM: shmobile: r8a73a4: add Z2 clock support
ARM: shmobile: r8a73a4: safeguard against wrong clk_set_rate() uses
ARM: shmobile: r8a73a4: implement CPU clock scaling for CPUFreq
ARM: shmobile: r8a73a4: wait for completion when kicking the clock
ARM: shmobile: r8a7790: add thermal driver support
...
Signed-off-by: Olof Johansson <olof@lixom.net>
34 files changed, 964 insertions, 501 deletions
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 641b3c9..af19e38 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -183,6 +183,7 @@ dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \ ccu9540.dtb dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ + emev2-kzm9d-reference.dtb \ r8a7740-armadillo800eva.dtb \ r8a7778-bockw.dtb \ r8a7740-armadillo800eva-reference.dtb \ diff --git a/arch/arm/boot/dts/emev2-kzm9d-reference.dts b/arch/arm/boot/dts/emev2-kzm9d-reference.dts new file mode 100644 index 0000000..bed676b --- /dev/null +++ b/arch/arm/boot/dts/emev2-kzm9d-reference.dts @@ -0,0 +1,57 @@ +/* + * Device Tree Source for the KZM9D board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * 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/ "emev2.dtsi" + +/ { + model = "EMEV2 KZM9D Board"; + compatible = "renesas,kzm9d-reference", "renesas,emev2"; + + memory { + device_type = "memory"; + reg = <0x40000000 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"; + }; + + reg_1p8v: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + reg_3p3v: regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + lan9220@20000000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x20000000 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gpio0>; + interrupts = <1 1>; /* active high */ + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vddvario-supply = <®_1p8v>; + vdd33a-supply = <®_3p3v>; + }; +}; diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts index b9b3241..dda13bc 100644 --- a/arch/arm/boot/dts/emev2-kzm9d.dts +++ b/arch/arm/boot/dts/emev2-kzm9d.dts @@ -21,6 +21,6 @@ }; chosen { - bootargs = "console=tty0 console=ttyS1,115200n81 earlyprintk=serial8250-em.1,115200n81 mem=128M@0x40000000 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"; + bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"; }; }; diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index c8a8c08..99ad2b2 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -14,6 +14,14 @@ compatible = "renesas,emev2"; interrupt-parent = <&gic>; + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -67,4 +75,55 @@ reg = <0xe1050000 0x38>; interrupts = <0 11 0>; }; + + gpio0: gpio@e0050000 { + compatible = "renesas,em-gio"; + reg = <0xe0050000 0x2c>, <0xe0050040 0x20>; + interrupts = <0 67 0>, <0 68 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gpio1: gpio@e0050080 { + compatible = "renesas,em-gio"; + reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>; + interrupts = <0 69 0>, <0 70 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gpio2: gpio@e0050100 { + compatible = "renesas,em-gio"; + reg = <0xe0050100 0x2c>, <0xe0050140 0x20>; + interrupts = <0 71 0>, <0 72 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gpio3: gpio@e0050180 { + compatible = "renesas,em-gio"; + reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>; + interrupts = <0 73 0>, <0 74 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gpio4: gpio@e0050200 { + compatible = "renesas,em-gio"; + reg = <0xe0050200 0x2c>, <0xe0050240 0x20>; + interrupts = <0 75 0>, <0 76 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <31>; + interrupt-controller; + #interrupt-cells = <2>; + }; }; diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts index f603c69..e657a9d 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -50,3 +50,25 @@ }; }; }; + +&i2c5 { + vdd_dvfs: max8973@1b { + compatible = "maxim,max8973"; + reg = <0x1b>; + + regulator-min-microvolt = <935000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&cpu0 { + cpu0-supply = <&vdd_dvfs>; + operating-points = < + /* kHz uV */ + 1950000 1115000 + 1462500 995000 + >; + voltage-tolerance = <1>; /* 1% */ +}; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index 4ff2019..6ce699b 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -85,4 +85,130 @@ interrupt-parent = <&gic>; interrupts = <0 69 4>; }; + + i2c0: i2c@e6500000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6500000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 174 0x4>; + }; + + i2c1: i2c@e6510000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6510000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 175 0x4>; + }; + + i2c2: i2c@e6520000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6520000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 176 0x4>; + }; + + i2c3: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6530000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 177 0x4>; + }; + + i2c4: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6540000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 178 0x4>; + }; + + i2c5: i2c@e60b0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe60b0000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 179 0x4>; + }; + + i2c6: i2c@e6550000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6550000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 184 0x4>; + }; + + i2c7: i2c@e6560000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6560000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 185 0x4>; + }; + + i2c8: i2c@e6570000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,rmobile-iic"; + reg = <0 0xe6570000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 173 0x4>; + }; + + mmcif0: mmcif@ee200000 { + compatible = "renesas,sh-mmcif"; + reg = <0 0xee200000 0 0x80>; + interrupt-parent = <&gic>; + interrupts = <0 169 0x4>; + reg-io-width = <4>; + status = "disabled"; + }; + + mmcif1: mmcif@ee220000 { + compatible = "renesas,sh-mmcif"; + reg = <0 0xee220000 0 0x80>; + interrupt-parent = <&gic>; + interrupts = <0 170 0x4>; + reg-io-width = <4>; + status = "disabled"; + }; + + sdhi0: sdhi@ee100000 { + compatible = "renesas,r8a73a4-sdhi"; + reg = <0 0xee100000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 165 4>; + cap-sd-highspeed; + status = "disabled"; + }; + + sdhi1: sdhi@ee120000 { + compatible = "renesas,r8a73a4-sdhi"; + reg = <0 0xee120000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 166 4>; + cap-sd-highspeed; + status = "disabled"; + }; + + sdhi2: sdhi@ee140000 { + compatible = "renesas,r8a73a4-sdhi"; + reg = <0 0xee140000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 167 4>; + cap-sd-highspeed; + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 339d9b1..9cd8820 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -54,4 +54,58 @@ interrupt-parent = <&gic>; interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>; }; + + mmcif0: mmcif@ee200000 { + compatible = "renesas,sh-mmcif"; + reg = <0 0xee200000 0 0x80>; + interrupt-parent = <&gic>; + interrupts = <0 169 0x4>; + reg-io-width = <4>; + status = "disabled"; + }; + + mmcif1: mmcif@ee220000 { + compatible = "renesas,sh-mmcif"; + reg = <0 0xee220000 0 0x80>; + interrupt-parent = <&gic>; + interrupts = <0 170 0x4>; + reg-io-width = <4>; + status = "disabled"; + }; + + sdhi0: sdhi@ee100000 { + compatible = "renesas,r8a7790-sdhi"; + reg = <0 0xee100000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 165 4>; + cap-sd-highspeed; + status = "disabled"; + }; + + sdhi1: sdhi@ee120000 { + compatible = "renesas,r8a7790-sdhi"; + reg = <0 0xee120000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 166 4>; + cap-sd-highspeed; + status = "disabled"; + }; + + sdhi2: sdhi@ee140000 { + compatible = "renesas,r8a7790-sdhi"; + reg = <0 0xee140000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 167 4>; + cap-sd-highspeed; + status = "disabled"; + }; + + sdhi3: sdhi@ee160000 { + compatible = "renesas,r8a7790-sdhi"; + reg = <0 0xee160000 0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 168 4>; + cap-sd-highspeed; + status = "disabled"; + }; }; diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 3912ce9..f76fca6 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -23,9 +23,10 @@ config ARCH_R8A73A4 select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC select CPU_V7 - select HAVE_ARM_ARCH_TIMER select SH_CLK_CPG select RENESAS_IRQC + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP config ARCH_R8A7740 bool "R-Mobile A1 (R8A77400)" @@ -59,7 +60,6 @@ config ARCH_R8A7790 select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC select CPU_V7 - select HAVE_ARM_ARCH_TIMER select SH_CLK_CPG select RENESAS_IRQC @@ -124,6 +124,7 @@ config MACH_BOCKW depends on ARCH_R8A7778 select ARCH_REQUIRE_GPIOLIB select RENESAS_INTC_IRQPIN + select REGULATOR_FIXED_VOLTAGE if REGULATOR select USE_OF config MACH_MARZEN @@ -156,6 +157,18 @@ config MACH_KZM9D select REGULATOR_FIXED_VOLTAGE if REGULATOR select USE_OF +config MACH_KZM9D_REFERENCE + bool "KZM9D board - Reference Device Tree Implementation" + depends on ARCH_EMEV2 + select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USE_OF + ---help--- + Use reference implementation of KZM9D board support + which makes a greater use of device tree at the expense + of not supporting a number of devices. + + This is intended to aid developers + config MACH_KZM9G bool "KZM-A9-GT board" depends on ARCH_SH73A0 diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 6165a51..e8d0a2c 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_MACH_LAGER) += board-lager.o obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += board-armadillo800eva-reference.o obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o +obj-$(CONFIG_MACH_KZM9D_REFERENCE) += board-kzm9d-reference.o obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot index 84c6868..7785c52 100644 --- a/arch/arm/mach-shmobile/Makefile.boot +++ b/arch/arm/mach-shmobile/Makefile.boot @@ -7,6 +7,7 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000 loadaddr-$(CONFIG_MACH_KOTA2) += 0x41008000 loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000 +loadaddr-$(CONFIG_MACH_KZM9D_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000 loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000 loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000 diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index 5eb0caa..ccf8b04 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -20,8 +20,11 @@ #include <linux/gpio.h> #include <linux/interrupt.h> -#include <linux/irqchip.h> #include <linux/kernel.h> +#include <linux/mfd/tmio.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mmcif.h> +#include <linux/mmc/sh_mobile_sdhi.h> #include <linux/pinctrl/machine.h> #include <linux/platform_device.h> #include <linux/regulator/fixed.h> @@ -55,6 +58,53 @@ static const struct smsc911x_platform_config lan9220_data = { .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, }; +/* + * On APE6EVM power is supplied to MMCIF by a tps80032 regulator. For now we + * model a VDD supply to MMCIF, using a fixed 3.3V regulator. Also use the + * static power supply for SDHI0 and SDHI1, whereas SDHI0's VccQ is also + * supplied by the same tps80032 regulator and thus can also be adjusted + * dynamically. + */ +static struct regulator_consumer_supply fixed3v3_power_consumers[] = +{ + REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), +}; + +/* MMCIF */ +static struct sh_mmcif_plat_data mmcif0_pdata = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, +}; + +static struct resource mmcif0_resources[] = { + DEFINE_RES_MEM_NAMED(0xee200000, 0x100, "MMCIF0"), + DEFINE_RES_IRQ(gic_spi(169)), +}; + +/* SDHI0 */ +static struct sh_mobile_sdhi_info sdhi0_pdata = { + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, +}; + +static struct resource sdhi0_resources[] = { + DEFINE_RES_MEM_NAMED(0xee100000, 0x100, "SDHI0"), + DEFINE_RES_IRQ(gic_spi(165)), +}; + +/* SDHI1 */ +static struct sh_mobile_sdhi_info sdhi1_pdata = { + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | + MMC_CAP_NEEDS_POLL, +}; + +static struct resource sdhi1_resources[] = { + DEFINE_RES_MEM_NAMED(0xee120000, 0x100, "SDHI1"), + DEFINE_RES_IRQ(gic_spi(166)), +}; + static const struct pinctrl_map ape6evm_pinctrl_map[] = { /* SCIFA0 console */ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a73a4", @@ -62,6 +112,23 @@ static const struct pinctrl_map ape6evm_pinctrl_map[] = { /* SMSC */ PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a73a4", "irqc_irq40", "irqc"), + /* MMCIF0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a73a4", + "mmc0_data8", "mmc0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a73a4", + "mmc0_ctrl", "mmc0"), + /* SDHI0: uSD: no WP */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4", + "sdhi0_data4", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4", + "sdhi0_ctrl", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4", + "sdhi0_cd", "sdhi0"), + /* SDHI1 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a73a4", + "sdhi1_data4", "sdhi1"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a73a4", + "sdhi1_ctrl", "sdhi1"), }; static void __init ape6evm_add_standard_devices(void) @@ -94,6 +161,17 @@ static void __init ape6evm_add_standard_devices(void) platform_device_register_resndata(&platform_bus, "smsc911x", -1, lan9220_res, ARRAY_SIZE(lan9220_res), &lan9220_data, sizeof(lan9220_data)); + regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, + ARRAY_SIZE(fixed3v3_power_consumers), 3300000); + platform_device_register_resndata(&platform_bus, "sh_mmcif", 0, + mmcif0_resources, ARRAY_SIZE(mmcif0_resources), + &mmcif0_pdata, sizeof(mmcif0_pdata)); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0, + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_pdata, sizeof(sdhi0_pdata)); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1, + sdhi1_resources, ARRAY_SIZE(sdhi1_resources), + &sdhi1_pdata, sizeof(sdhi1_pdata)); } static const char *ape6evm_boards_compat_dt[] __initdata = { @@ -102,7 +180,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_irq = irqchip_init, + .init_early = r8a73a4_init_delay, .init_time = shmobile_timer_init, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 9457c76..2412fca 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -724,15 +724,6 @@ static struct platform_device vcc_sdhi1 = { }; /* SDHI0 */ -/* - * FIXME - * - * It use polling mode here, since - * CD (= Card Detect) pin is not connected to SDHI0_CD. - * We can use IRQ31 as card detect irq, - * but it needs chattering removal operation - */ -#define IRQ31 irq_pin(31) static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, @@ -833,6 +824,8 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, }; static struct resource sh_mmcif_resources[] = { diff --git a/arch/arm/mach-shmobile/board-kzm9d-reference.c b/arch/arm/mach-shmobile/board-kzm9d-reference.c new file mode 100644 index 0000000..a7b28b2 --- /dev/null +++ b/arch/arm/mach-shmobile/board-kzm9d-reference.c @@ -0,0 +1,46 @@ +/* + * kzm9d board support - Reference DT implementation + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/init.h> +#include <linux/of_platform.h> +#include <mach/emev2.h> +#include <mach/common.h> +#include <asm/mach/arch.h> + +static void __init kzm9d_add_standard_devices(void) +{ + emev2_clock_init(); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *kzm9d_boards_compat_dt[] __initdata = { + "renesas,kzm9d-reference", + NULL, +}; + +DT_MACHINE_START(KZM9D_DT, "kzm9d") + .smp = smp_ops(emev2_smp_ops), + .map_io = emev2_map_io, + .init_early = emev2_init_delay, + .init_machine = kzm9d_add_standard_devices, + .init_late = shmobile_init_late, + .dt_compat = kzm9d_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c index 4368000..30c2cc6 100644 --- a/arch/arm/mach-shmobile/board-kzm9d.c +++ b/arch/arm/mach-shmobile/board-kzm9d.c @@ -85,9 +85,7 @@ static const char *kzm9d_boards_compat_dt[] __initdata = { DT_MACHINE_START(KZM9D_DT, "kzm9d") .smp = smp_ops(emev2_smp_ops), .map_io = emev2_map_io, - .init_early = emev2_add_early_devices, - .nr_irqs = NR_IRQS_LEGACY, - .init_irq = emev2_init_irq, + .init_early = emev2_init_delay, .init_machine = kzm9d_add_standard_devices, .init_late = shmobile_init_late, .dt_compat = kzm9d_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index 44055fe..41092bb 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -24,7 +24,6 @@ #include <linux/gpio.h> #include <linux/io.h> #include <linux/irq.h> -#include <linux/irqchip.h> #include <linux/input.h> #include <linux/of_platform.h> #include <linux/pinctrl/machine.h> @@ -99,7 +98,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g-reference") .map_io = sh73a0_map_io, .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_irq = irqchip_init, .init_machine = kzm_init, .init_time = shmobile_timer_init, .dt_compat = kzm9g_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index d73e21d..3c67b2a 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -22,13 +22,17 @@ #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/interrupt.h> -#include <linux/irqchip.h> #include <linux/kernel.h> #include <linux/leds.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mmcif.h> #include <linux/pinctrl/machine.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_device.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> #include <mach/common.h> +#include <mach/irqs.h> #include <mach/r8a7790.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -71,6 +75,22 @@ static __initdata struct gpio_keys_platform_data lager_keys_pdata = { .nbuttons = ARRAY_SIZE(gpio_buttons), }; +/* Fixed 3.3V regulator to be used by MMCIF */ +static struct regulator_consumer_supply fixed3v3_power_consumers[] = +{ + REGULATOR_SUPPLY("vmmc", "sh_mmcif.1"), +}; + +/* MMCIF */ +static struct sh_mmcif_plat_data mmcif1_pdata = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, +}; + +static struct resource mmcif1_resources[] = { + DEFINE_RES_MEM_NAMED(0xee220000, 0x80, "MMCIF1"), + DEFINE_RES_IRQ(gic_spi(170)), +}; + static const struct pinctrl_map lager_pinctrl_map[] = { /* SCIF0 (CN19: DEBUG SERIAL0) */ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790", @@ -78,6 +98,11 @@ static const struct pinctrl_map lager_pinctrl_map[] = { /* SCIF1 (CN20: DEBUG SERIAL1) */ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7790", "scif1_data", "scif1"), + /* MMCIF1 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790", + "mmc1_data8", "mmc1"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790", + "mmc1_ctrl", "mmc1"), }; static void __init lager_add_standard_devices(void) @@ -95,6 +120,11 @@ static void __init lager_add_standard_devices(void) platform_device_register_data(&platform_bus, "gpio-keys", -1, &lager_keys_pdata, sizeof(lager_keys_pdata)); + regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, + ARRAY_SIZE(fixed3v3_power_consumers), 3300000); + platform_device_register_resndata(&platform_bus, "sh_mmcif", 1, + mmcif1_resources, ARRAY_SIZE(mmcif1_resources), + &mmcif1_pdata, sizeof(mmcif1_pdata)); } static const char *lager_boards_compat_dt[] __initdata = { @@ -103,7 +133,7 @@ static const char *lager_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(LAGER_DT, "lager") - .init_irq = irqchip_init, + .init_early = r8a7790_init_delay, .init_time = r8a7790_timer_init, .init_machine = lager_add_standard_devices, .dt_compat = lager_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c index 4710f18..5ac13ba 100644 --- a/arch/arm/mach-shmobile/clock-emev2.c +++ b/arch/arm/mach-shmobile/clock-emev2.c @@ -40,7 +40,6 @@ #define USIB2SCLKDIV 0x65c #define USIB3SCLKDIV 0x660 #define STI_CLKSEL 0x688 -#define SMU_GENERAL_REG0 0x7c0 /* not pretty, but hey */ static void __iomem *smu_base; @@ -51,11 +50,6 @@ static void emev2_smu_write(unsigned long value, int offs) iowrite32(value, smu_base + offs); } -void emev2_set_boot_vector(unsigned long value) -{ - emev2_smu_write(value, SMU_GENERAL_REG0); -} - static struct clk_mapping smu_mapping = { .phys = EMEV2_SMU_BASE, .len = PAGE_SIZE, @@ -205,23 +199,11 @@ static struct clk_lookup lookups[] = { void __init emev2_clock_init(void) { int k, ret = 0; - static int is_setup; - - /* yuck, this is ugly as hell, but the non-smp case of clocks - * code is now designed to rely on ioremap() instead of static - * entity maps. in the case of smp we need access to the SMU - * register earlier than ioremap() is actually working without - * any static maps. to enable SMP in ugly but with dynamic - * mappings we have to call emev2_clock_init() from different - * places depending on UP and SMP... - */ - if (is_setup++) - return; smu_base = ioremap(EMEV2_SMU_BASE, PAGE_SIZE); BUG_ON(!smu_base); - /* setup STI timer to run on 37.768 kHz and deassert reset */ + /* setup STI timer to run on 32.768 kHz and deassert reset */ emev2_smu_write(0, STI_CLKSEL); emev2_smu_write(1, STI_RSTCTRL); diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 5f7fe62..8ea5ef6 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -30,10 +30,12 @@ #define SMSTPCR2 0xe6150138 #define SMSTPCR3 0xe615013c +#define SMSTPCR4 0xe6150140 #define SMSTPCR5 0xe6150144 #define FRQCRA 0xE6150000 #define FRQCRB 0xE6150004 +#define FRQCRC 0xE61500E0 #define VCLKCR1 0xE6150008 #define VCLKCR2 0xE615000C #define VCLKCR3 0xE615001C @@ -52,6 +54,7 @@ #define HSICKCR 0xE615026C #define M4CKCR 0xE6150098 #define PLLECR 0xE61500D0 +#define PLL0CR 0xE61500D8 #define PLL1CR 0xE6150028 #define PLL2CR 0xE615002C #define PLL2SCR 0xE61501F4 @@ -177,6 +180,7 @@ static struct sh_clk_ops pll_clk_ops = { .mapping = &cpg_mapping, \ } +PLL_CLOCK(pll0_clk, &main_clk, pll_parent_main, 1, 20, PLL0CR, 0); 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); @@ -184,6 +188,157 @@ 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 atomic_t frqcr_lock; + +/* Several clocks need to access FRQCRB, have to lock */ +static bool frqcr_kick_check(struct clk *clk) +{ + return !(ioread32(CPG_MAP(FRQCRB)) & BIT(31)); +} + +static int frqcr_kick_do(struct clk *clk) +{ + int i; + + /* set KICK bit in FRQCRB to update hardware setting, check success */ + iowrite32(ioread32(CPG_MAP(FRQCRB)) | BIT(31), CPG_MAP(FRQCRB)); + for (i = 1000; i; i--) + if (ioread32(CPG_MAP(FRQCRB)) & BIT(31)) + cpu_relax(); + else + return 0; + + return -ETIMEDOUT; +} + +static int zclk_set_rate(struct clk *clk, unsigned long rate) +{ + void __iomem *frqcrc; + int ret; + unsigned long step, p_rate; + u32 val; + + if (!clk->parent || !__clk_get(clk->parent)) + return -ENODEV; + + if (!atomic_inc_and_test(&frqcr_lock) || !frqcr_kick_check(clk)) { + ret = -EBUSY; + goto done; + } + + /* + * Users are supposed to first call clk_set_rate() only with + * clk_round_rate() results. So, we don't fix wrong rates here, but + * guard against them anyway + */ + + p_rate = clk_get_rate(clk->parent); + if (rate == p_rate) { + val = 0; + } else { + step = DIV_ROUND_CLOSEST(p_rate, 32); + + if (rate > p_rate || rate < step) { + ret = -EINVAL; + goto done; + } + + val = 32 - rate / step; + } + + frqcrc = clk->mapped_reg + (FRQCRC - (u32)clk->enable_reg); + + iowrite32((ioread32(frqcrc) & ~(clk->div_mask << clk->enable_bit)) | + (val << clk->enable_bit), frqcrc); + + ret = frqcr_kick_do(clk); + +done: + atomic_dec(&frqcr_lock); + __clk_put(clk->parent); + return ret; +} + +static long zclk_round_rate(struct clk *clk, unsigned long rate) +{ + /* + * theoretical rate = parent rate * multiplier / 32, + * where 1 <= multiplier <= 32. Therefore we should do + * multiplier = rate * 32 / parent rate + * rounded rate = parent rate * multiplier / 32. + * However, multiplication before division won't fit in 32 bits, so + * we sacrifice some precision by first dividing and then multiplying. + * To find the nearest divisor we calculate both and pick up the best + * one. This avoids 64-bit arithmetics. + */ + unsigned long step, mul_min, mul_max, rate_min, rate_max; + + rate_max = clk_get_rate(clk->parent); + + /* output freq <= parent */ + if (rate >= rate_max) + return rate_max; + + step = DIV_ROUND_CLOSEST(rate_max, 32); + /* output freq >= parent / 32 */ + if (step >= rate) + return step; + + mul_min = rate / step; + mul_max = DIV_ROUND_UP(rate, step); + rate_min = step * mul_min; + if (mul_max == mul_min) + return rate_min; + + rate_max = step * mul_max; + + if (rate_max - rate < rate - rate_min) + return rate_max; + + return rate_min; +} + +static unsigned long zclk_recalc(struct clk *clk) +{ + void __iomem *frqcrc = FRQCRC - (u32)clk->enable_reg + clk->mapped_reg; + unsigned int max = clk->div_mask + 1; + unsigned long val = ((ioread32(frqcrc) >> clk->enable_bit) & + clk->div_mask); + + return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), max) * + (max - val); +} + +static struct sh_clk_ops zclk_ops = { + .recalc = zclk_recalc, + .set_rate = zclk_set_rate, + .round_rate = zclk_round_rate, +}; + +static struct clk z_clk = { + .parent = &pll0_clk, + .div_mask = 0x1f, + .enable_bit = 8, + /* We'll need to access FRQCRB and FRQCRC */ + .enable_reg = (void __iomem *)FRQCRB, + .ops = &zclk_ops, +}; + +/* + * It seems only 1/2 divider is usable in manual mode. 1/2 / 2/3 + * switching is only available in auto-DVFS mode + */ +SH_FIXED_RATIO_CLK(pll0_div2_clk, pll0_clk, div2); + +static struct clk z2_clk = { + .parent = &pll0_div2_clk, + .div_mask = 0x1f, + .enable_bit = 0, + /* We'll need to access FRQCRB and FRQCRC */ + .enable_reg = (void __iomem *)FRQCRB, + .ops = &zclk_ops, +}; + static struct clk *main_clks[] = { &extalr_clk, &extal1_clk, @@ -195,22 +350,23 @@ static struct clk *main_clks[] = { &main_div2_clk, &fsiack_clk, &fsibck_clk, + &pll0_clk, &pll1_clk, &pll1_div2_clk, &pll2_clk, &pll2s_clk, &pll2h_clk, + &z_clk, + &pll0_div2_clk, + &z2_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)); + if (!WARN(!atomic_inc_and_test(&frqcr_lock), "FRQCR* lock broken!\n")) + frqcr_kick_do(clk); + atomic_dec(&frqcr_lock); } static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10}; @@ -349,8 +505,10 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, - MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, - MSTP522, + MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, + MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, + MSTP411, MSTP410, MSTP409, + MSTP522, MSTP515, MSTP_NR }; @@ -361,12 +519,22 @@ static struct clk mstp_clks[MSTP_NR] = { [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 */ + [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */ [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ [MSTP313] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI1],SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP314] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI0],SMSTPCR3, 14, 0), /* SDHI0 */ [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0],SMSTPCR3, 15, 0), /* MMCIF0 */ + [MSTP316] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 16, 0), /* IIC6 */ + [MSTP317] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 17, 0), /* IIC7 */ + [MSTP318] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* IIC0 */ + [MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */ + [MSTP329] = SH_CLK_MSTP32(&extalr_clk, SMSTPCR3, 29, 0), /* CMT10 */ + [MSTP409] = SH_CLK_MSTP32(&main_div2_clk, SMSTPCR4, 9, 0), /* IIC5 */ + [MSTP410] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */ + [MSTP411] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */ [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ + [MSTP515] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR5, 15, 0), /* IIC8 */ }; static struct clk_lookup lookups[] = { @@ -386,6 +554,9 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("pll2s", &pll2s_clk), CLKDEV_CON_ID("pll2h", &pll2h_clk), + /* CPU clock */ + CLKDEV_DEV_ID("cpufreq-cpu0", &z_clk), + /* DIV6 */ CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]), CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]), @@ -408,6 +579,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), + CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]), CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), @@ -418,6 +590,15 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), + CLKDEV_DEV_ID("e6550000.i2c", &mstp_clks[MSTP316]), + CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]), + CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]), + CLKDEV_DEV_ID("e6510000.i2c", &mstp_clks[MSTP323]), + CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), + CLKDEV_DEV_ID("e60b0000.i2c", &mstp_clks[MSTP409]), + CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP410]), + CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP411]), + CLKDEV_DEV_ID("e6570000.i2c", &mstp_clks[MSTP515]), /* for DT */ CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), @@ -429,6 +610,8 @@ void __init r8a73a4_clock_init(void) int k, ret = 0; u32 ckscr; + atomic_set(&frqcr_lock, -1); + reg = ioremap_nocache(CKSCR, PAGE_SIZE); BUG_ON(!reg); ckscr = ioread32(reg); diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 5d71313..50d96f9 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -24,6 +24,7 @@ #include <linux/clkdev.h> #include <mach/clock.h> #include <mach/common.h> +#include <mach/r8a7790.h> /* * MD EXTAL PLL0 PLL1 PLL3 @@ -42,16 +43,15 @@ * see "p1 / 2" on R8A7790_CLOCK_ROOT() below */ -#define MD(nr) (1 << nr) - #define CPG_BASE 0xe6150000 #define CPG_LEN 0x1000 +#define SMSTPCR1 0xe6150134 #define SMSTPCR2 0xe6150138 #define SMSTPCR3 0xe615013c +#define SMSTPCR5 0xe6150144 #define SMSTPCR7 0xe615014c -#define MODEMR 0xE6160060 #define SDCKCR 0xE6150074 #define SD2CKCR 0xE6150078 #define SD3CKCR 0xE615007C @@ -182,14 +182,19 @@ static struct clk div6_clks[DIV6_NR] = { enum { MSTP721, MSTP720, MSTP717, MSTP716, + MSTP522, MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, + MSTP124, 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 */ + [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ + [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */ + [MSTP522] = SH_CLK_MSTP32(&extal_clk, SMSTPCR5, 22, 0), /* Thermal */ [MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */ [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */ @@ -203,8 +208,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ - [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ - [MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */ + [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ }; static struct clk_lookup lookups[] = { @@ -254,6 +258,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), + CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), @@ -266,6 +271,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]), CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]), CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), + CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), }; #define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ @@ -280,14 +286,9 @@ static struct clk_lookup lookups[] = { void __init r8a7790_clock_init(void) { - void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); - u32 mode; + u32 mode = r8a7790_read_mode_pins(); 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); diff --git a/arch/arm/mach-shmobile/include/mach/dma.h b/arch/arm/mach-shmobile/include/mach/dma.h deleted file mode 100644 index 40a8c17..0000000 --- a/arch/arm/mach-shmobile/include/mach/dma.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h index ac37517..c2eb756 100644 --- a/arch/arm/mach-shmobile/include/mach/emev2.h +++ b/arch/arm/mach-shmobile/include/mach/emev2.h @@ -2,11 +2,9 @@ #define __ASM_EMEV2_H__ extern void emev2_map_io(void); -extern void emev2_init_irq(void); -extern void emev2_add_early_devices(void); +extern void emev2_init_delay(void); extern void emev2_add_standard_devices(void); extern void emev2_clock_init(void); -extern void emev2_set_boot_vector(unsigned long value); #define EMEV2_GPIO_BASE 200 #define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n)) diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h index f043103..144a85e 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h +++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h @@ -4,5 +4,6 @@ void r8a73a4_add_standard_devices(void); void r8a73a4_clock_init(void); void r8a73a4_pinmux_init(void); +void r8a73a4_init_delay(void); #endif /* __ASM_R8A73A4_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h index b34d19b..56f3750 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7740.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h @@ -42,6 +42,8 @@ enum { SHDMA_SLAVE_FSIB_TX, SHDMA_SLAVE_USBHS_TX, SHDMA_SLAVE_USBHS_RX, + SHDMA_SLAVE_MMCIF_TX, + SHDMA_SLAVE_MMCIF_RX, }; extern void r8a7740_meram_workaround(void); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index 851d027..9b561bf 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -33,7 +33,6 @@ extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info); extern void r8a7778_init_late(void); extern void r8a7778_init_delay(void); -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); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 2e919e6..7aaef40 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h @@ -4,6 +4,10 @@ void r8a7790_add_standard_devices(void); void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); +void r8a7790_init_delay(void); void r8a7790_timer_init(void); +#define MD(nr) BIT(nr) +u32 r8a7790_read_mode_pins(void); + #endif /* __ASM_R8A7790_H__ */ diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 1ccddd2..19980be 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -20,7 +20,6 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/irqchip.h> #include <linux/platform_device.h> #include <linux/platform_data/gpio-em.h> #include <linux/of_platform.h> @@ -39,13 +38,6 @@ static struct map_desc emev2_io_desc[] __initdata = { #ifdef CONFIG_SMP - /* 128K entity map for 0xe0100000 (SMU) */ - { - .virtual = 0xe0100000, - .pfn = __phys_to_pfn(0xe0100000), - .length = SZ_128K, - .type = MT_DEVICE - }, /* 2M mapping for SCU + L2 controller */ { .virtual = 0xf0000000, @@ -63,102 +55,40 @@ void __init emev2_map_io(void) /* UART */ static struct resource uart0_resources[] = { - [0] = { - .start = 0xe1020000, - .end = 0xe1020037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 40, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart0_device = { - .name = "serial8250-em", - .id = 0, - .num_resources = ARRAY_SIZE(uart0_resources), - .resource = uart0_resources, + DEFINE_RES_MEM(0xe1020000, 0x38), + DEFINE_RES_IRQ(40), }; static struct resource uart1_resources[] = { - [0] = { - .start = 0xe1030000, - .end = 0xe1030037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 41, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart1_device = { - .name = "serial8250-em", - .id = 1, - .num_resources = ARRAY_SIZE(uart1_resources), - .resource = uart1_resources, + DEFINE_RES_MEM(0xe1030000, 0x38), + DEFINE_RES_IRQ(41), }; static struct resource uart2_resources[] = { - [0] = { - .start = 0xe1040000, - .end = 0xe1040037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 42, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart2_device = { - .name = "serial8250-em", - .id = 2, - .num_resources = ARRAY_SIZE(uart2_resources), - .resource = uart2_resources, + DEFINE_RES_MEM(0xe1040000, 0x38), + DEFINE_RES_IRQ(42), }; static struct resource uart3_resources[] = { - [0] = { - .start = 0xe1050000, - .end = 0xe1050037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 43, - .flags = IORESOURCE_IRQ, - } + DEFINE_RES_MEM(0xe1050000, 0x38), + DEFINE_RES_IRQ(43), }; -static struct platform_device uart3_device = { - .name = "serial8250-em", - .id = 3, - .num_resources = ARRAY_SIZE(uart3_resources), - .resource = uart3_resources, -}; +#define emev2_register_uart(idx) \ + platform_device_register_simple("serial8250-em", idx, \ + uart##idx##_resources, \ + ARRAY_SIZE(uart##idx##_resources)) /* STI */ static struct resource sti_resources[] = { - [0] = { - .name = "STI", - .start = 0xe0180000, - .end = 0xe0180053, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 157, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sti_device = { - .name = "em_sti", - .id = 0, - .resource = sti_resources, - .num_resources = ARRAY_SIZE(sti_resources), + DEFINE_RES_MEM(0xe0180000, 0x54), + DEFINE_RES_IRQ(157), }; +#define emev2_register_sti() \ + platform_device_register_simple("em_sti", 0, \ + sti_resources, \ + ARRAY_SIZE(sti_resources)) /* GIO */ static struct gpio_em_config gio0_config = { @@ -168,36 +98,10 @@ static struct gpio_em_config gio0_config = { }; static struct resource gio0_resources[] = { - [0] = { - .name = "GIO_000", - .start = 0xe0050000, - .end = 0xe005002b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_000", - .start = 0xe0050040, - .end = 0xe005005f, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 99, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 100, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio0_device = { - .name = "em_gio", - .id = 0, - .resource = gio0_resources, - .num_resources = ARRAY_SIZE(gio0_resources), - .dev = { - .platform_data = &gio0_config, - }, + DEFINE_RES_MEM(0xe0050000, 0x2c), + DEFINE_RES_MEM(0xe0050040, 0x20), + DEFINE_RES_IRQ(99), + DEFINE_RES_IRQ(100), }; static struct gpio_em_config gio1_config = { @@ -207,36 +111,10 @@ static struct gpio_em_config gio1_config = { }; static struct resource gio1_resources[] = { - [0] = { - .name = "GIO_032", - .start = 0xe0050080, - .end = 0xe00500ab, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_032", - .start = 0xe00500c0, - .end = 0xe00500df, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 101, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 102, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio1_device = { - .name = "em_gio", - .id = 1, - .resource = gio1_resources, - .num_resources = ARRAY_SIZE(gio1_resources), - .dev = { - .platform_data = &gio1_config, - }, + DEFINE_RES_MEM(0xe0050080, 0x2c), + DEFINE_RES_MEM(0xe00500c0, 0x20), + DEFINE_RES_IRQ(101), + DEFINE_RES_IRQ(102), }; static struct gpio_em_config gio2_config = { @@ -246,36 +124,10 @@ static struct gpio_em_config gio2_config = { }; static struct resource gio2_resources[] = { - [0] = { - .name = "GIO_064", - .start = 0xe0050100, - .end = 0xe005012b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_064", - .start = 0xe0050140, - .end = 0xe005015f, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 103, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 104, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio2_device = { - .name = "em_gio", - .id = 2, - .resource = gio2_resources, - .num_resources = ARRAY_SIZE(gio2_resources), - .dev = { - .platform_data = &gio2_config, - }, + DEFINE_RES_MEM(0xe0050100, 0x2c), + DEFINE_RES_MEM(0xe0050140, 0x20), + DEFINE_RES_IRQ(103), + DEFINE_RES_IRQ(104), }; static struct gpio_em_config gio3_config = { @@ -285,36 +137,10 @@ static struct gpio_em_config gio3_config = { }; static struct resource gio3_resources[] = { - [0] = { - .name = "GIO_096", - .start = 0xe0050180, - .end = 0xe00501ab, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_096", - .start = 0xe00501c0, - .end = 0xe00501df, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 105, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 106, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device gio3_device = { - .name = "em_gio", - .id = 3, - .resource = gio3_resources, - .num_resources = ARRAY_SIZE(gio3_resources), - .dev = { - .platform_data = &gio3_config, - }, + DEFINE_RES_MEM(0xe0050180, 0x2c), + DEFINE_RES_MEM(0xe00501c0, 0x20), + DEFINE_RES_IRQ(105), + DEFINE_RES_IRQ(106), }; static struct gpio_em_config gio4_config = { @@ -324,126 +150,52 @@ static struct gpio_em_config gio4_config = { }; static struct resource gio4_resources[] = { - [0] = { - .name = "GIO_128", - .start = 0xe0050200, - .end = 0xe005022b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "GIO_128", - .start = 0xe0050240, - .end = 0xe005025f, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 107, - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = 108, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_MEM(0xe0050200, 0x2c), + DEFINE_RES_MEM(0xe0050240, 0x20), + DEFINE_RES_IRQ(107), + DEFINE_RES_IRQ(108), }; -static struct platform_device gio4_device = { - .name = "em_gio", - .id = 4, - .resource = gio4_resources, - .num_resources = ARRAY_SIZE(gio4_resources), - .dev = { - .platform_data = &gio4_config, - }, -}; +#define emev2_register_gio(idx) \ + platform_device_register_resndata(&platform_bus, "em_gio", \ + idx, gio##idx##_resources, \ + ARRAY_SIZE(gio##idx##_resources), \ + &gio##idx##_config, \ + sizeof(struct gpio_em_config)) static struct resource pmu_resources[] = { - [0] = { - .start = 152, - .end = 152, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = 153, - .end = 153, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(152), + DEFINE_RES_IRQ(153), }; -static struct platform_device pmu_device = { - .name = "arm-pmu", - .id = -1, - .num_resources = ARRAY_SIZE(pmu_resources), - .resource = pmu_resources, -}; - -static struct platform_device *emev2_early_devices[] __initdata = { - &uart0_device, - &uart1_device, - &uart2_device, - &uart3_device, -}; - -static struct platform_device *emev2_late_devices[] __initdata = { - &sti_device, - &gio0_device, - &gio1_device, - &gio2_device, - &gio3_device, - &gio4_device, - &pmu_device, -}; +#define emev2_register_pmu() \ + platform_device_register_simple("arm-pmu", -1, \ + pmu_resources, \ + ARRAY_SIZE(pmu_resources)) void __init emev2_add_standard_devices(void) { emev2_clock_init(); - platform_add_devices(emev2_early_devices, - ARRAY_SIZE(emev2_early_devices)); - - platform_add_devices(emev2_late_devices, - ARRAY_SIZE(emev2_late_devices)); + emev2_register_uart(0); + emev2_register_uart(1); + emev2_register_uart(2); + emev2_register_uart(3); + emev2_register_sti(); + emev2_register_gio(0); + emev2_register_gio(1); + emev2_register_gio(2); + emev2_register_gio(3); + emev2_register_gio(4); + emev2_register_pmu(); } -static void __init emev2_init_delay(void) +void __init emev2_init_delay(void) { shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */ } -void __init emev2_add_early_devices(void) -{ - emev2_init_delay(); - - early_platform_add_devices(emev2_early_devices, - ARRAY_SIZE(emev2_early_devices)); - - /* setup early console here as well */ - shmobile_setup_console(); -} - -void __init emev2_init_irq(void) -{ - void __iomem *gic_dist_base; - void __iomem *gic_cpu_base; - - /* Static mappings, never released */ - gic_dist_base = ioremap(0xe0028000, PAGE_SIZE); - gic_cpu_base = ioremap(0xe0020000, PAGE_SIZE); - BUG_ON(!gic_dist_base || !gic_cpu_base); - - /* Use GIC to handle interrupts */ - gic_init(0, 29, gic_dist_base, gic_cpu_base); -} - #ifdef CONFIG_USE_OF -static const struct of_dev_auxdata emev2_auxdata_lookup[] __initconst = { - { } -}; - -static void __init emev2_add_standard_devices_dt(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - emev2_auxdata_lookup, NULL); -} static const char *emev2_boards_compat_dt[] __initdata = { "renesas,emev2", @@ -452,10 +204,8 @@ static const char *emev2_boards_compat_dt[] __initdata = { DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") .smp = smp_ops(emev2_smp_ops), + .map_io = emev2_map_io, .init_early = emev2_init_delay, - .nr_irqs = NR_IRQS_LEGACY, - .init_irq = irqchip_init, - .init_machine = emev2_add_standard_devices_dt, .dt_compat = emev2_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 7f45c2e..d533bd2 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -18,11 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <linux/irq.h> -#include <linux/irqchip.h> #include <linux/kernel.h> #include <linux/of_platform.h> #include <linux/platform_data/irq-renesas-irqc.h> #include <linux/serial_sci.h> +#include <linux/sh_timer.h> #include <mach/common.h> #include <mach/irqs.h> #include <mach/r8a73a4.h> @@ -169,6 +169,25 @@ static const struct resource thermal0_resources[] = { thermal0_resources, \ ARRAY_SIZE(thermal0_resources)) +static struct sh_timer_config cmt10_platform_data = { + .name = "CMT10", + .timer_bit = 0, + .clockevent_rating = 80, +}; + +static struct resource cmt10_resources[] = { + DEFINE_RES_MEM(0xe6130010, 0x0c), + DEFINE_RES_MEM(0xe6130000, 0x04), + DEFINE_RES_IRQ(gic_spi(120)), /* CMT1_0 */ +}; + +#define r8a7790_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh_cmt", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + void __init r8a73a4_add_standard_devices(void) { r8a73a4_register_scif(SCIFA0); @@ -180,11 +199,20 @@ void __init r8a73a4_add_standard_devices(void) r8a73a4_register_irqc(0); r8a73a4_register_irqc(1); r8a73a4_register_thermal(); + r8a7790_register_cmt(10); +} + +void __init r8a73a4_init_delay(void) +{ +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */ +#endif } #ifdef CONFIG_USE_OF void __init r8a73a4_add_standard_devices_dt(void) { + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -194,7 +222,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") - .init_irq = irqchip_init, + .init_early = r8a73a4_init_delay, .init_machine = r8a73a4_add_standard_devices_dt, .init_time = shmobile_timer_init, .dt_compat = r8a73a4_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 00c5a70..84c5bb6 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -588,6 +588,16 @@ static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = { .addr = 0xfe1f0064, .chcr = CHCR_TX(XMIT_SZ_32BIT), .mid_rid = 0xb5, + }, { + .slave_id = SHDMA_SLAVE_MMCIF_TX, + .addr = 0xe6bd0034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xd1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF_RX, + .addr = 0xe6bd0034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xd2, }, }; @@ -986,16 +996,22 @@ void __init r8a7740_add_early_devices(void) #ifdef CONFIG_USE_OF -static const struct of_dev_auxdata r8a7740_auxdata_lookup[] __initconst = { - { } -}; +void __init r8a7740_add_early_devices_dt(void) +{ + shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ + + early_platform_add_devices(r8a7740_early_devices, + ARRAY_SIZE(r8a7740_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); +} void __init r8a7740_add_standard_devices_dt(void) { platform_add_devices(r8a7740_devices_dt, ARRAY_SIZE(r8a7740_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, - r8a7740_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } void __init r8a7740_init_delay(void) diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 80c2039..a3a2e37 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -53,7 +53,7 @@ .irqs = SCIx_IRQ_MUXED(irq), \ } -static struct plat_sci_port scif_platform_data[] = { +static struct plat_sci_port scif_platform_data[] __initdata = { SCIF_INFO(0xffe40000, gic_iid(0x66)), SCIF_INFO(0xffe41000, gic_iid(0x67)), SCIF_INFO(0xffe42000, gic_iid(0x68)), @@ -63,24 +63,24 @@ static struct plat_sci_port scif_platform_data[] = { }; /* TMU */ -static struct resource sh_tmu0_resources[] = { +static struct resource sh_tmu0_resources[] __initdata = { DEFINE_RES_MEM(0xffd80008, 12), DEFINE_RES_IRQ(gic_iid(0x40)), }; -static struct sh_timer_config sh_tmu0_platform_data = { +static struct sh_timer_config sh_tmu0_platform_data __initdata = { .name = "TMU00", .channel_offset = 0x4, .timer_bit = 0, .clockevent_rating = 200, }; -static struct resource sh_tmu1_resources[] = { +static struct resource sh_tmu1_resources[] __initdata = { DEFINE_RES_MEM(0xffd80014, 12), DEFINE_RES_IRQ(gic_iid(0x41)), }; -static struct sh_timer_config sh_tmu1_platform_data = { +static struct sh_timer_config sh_tmu1_platform_data __initdata = { .name = "TMU01", .channel_offset = 0x10, .timer_bit = 1, @@ -189,7 +189,7 @@ USB_PLATFORM_INFO(ehci); USB_PLATFORM_INFO(ohci); /* Ether */ -static struct resource ether_resources[] = { +static struct resource ether_resources[] __initdata = { DEFINE_RES_MEM(0xfde00000, 0x400), DEFINE_RES_IRQ(gic_iid(0x89)), }; @@ -203,17 +203,17 @@ void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) } /* PFC/GPIO */ -static struct resource pfc_resources[] = { +static struct resource pfc_resources[] __initdata = { DEFINE_RES_MEM(0xfffc0000, 0x118), }; #define R8A7778_GPIO(idx) \ -static struct resource r8a7778_gpio##idx##_resources[] = { \ +static struct resource r8a7778_gpio##idx##_resources[] __initdata = { \ DEFINE_RES_MEM(0xffc40000 + 0x1000 * (idx), 0x30), \ DEFINE_RES_IRQ(gic_iid(0x87)), \ }; \ \ -static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data = { \ +static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data __initdata = { \ .gpio_base = 32 * (idx), \ .irq_base = GPIO_IRQ_BASE(idx), \ .number_of_pins = 32, \ @@ -249,7 +249,7 @@ void __init r8a7778_pinmux_init(void) }; /* SDHI */ -static struct resource sdhi_resources[] = { +static struct resource sdhi_resources[] __initdata = { /* SDHI0 */ DEFINE_RES_MEM(0xFFE4C000, 0x100), DEFINE_RES_IRQ(gic_iid(0x77)), @@ -365,12 +365,12 @@ void __init r8a7778_init_late(void) platform_device_register_full(&ohci_info); } -static struct renesas_intc_irqpin_config irqpin_platform_data = { +static struct renesas_intc_irqpin_config irqpin_platform_data __initdata = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ .sense_bitfield_width = 2, }; -static struct resource irqpin_resources[] = { +static struct resource irqpin_resources[] __initdata = { DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */ DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */ DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */ @@ -408,17 +408,25 @@ void __init r8a7778_init_irq_extpin(int irlm) &irqpin_platform_data, sizeof(irqpin_platform_data)); } +void __init r8a7778_init_delay(void) +{ + shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ +} + +#ifdef CONFIG_USE_OF #define INT2SMSKCR0 0x82288 /* 0xfe782288 */ #define INT2SMSKCR1 0x8228c /* 0xfe78228c */ #define INT2NTSR0 0x00018 /* 0xfe700018 */ #define INT2NTSR1 0x0002c /* 0xfe70002c */ -static void __init r8a7778_init_irq_common(void) +void __init r8a7778_init_irq_dt(void) { void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000); BUG_ON(!base); + irqchip_init(); + /* route all interrupts to ARM */ __raw_writel(0x73ffffff, base + INT2NTSR0); __raw_writel(0xffffffff, base + INT2NTSR1); @@ -430,43 +438,6 @@ static void __init r8a7778_init_irq_common(void) iounmap(base); } -void __init r8a7778_init_irq(void) -{ - void __iomem *gic_dist_base; - void __iomem *gic_cpu_base; - - gic_dist_base = ioremap_nocache(0xfe438000, PAGE_SIZE); - gic_cpu_base = ioremap_nocache(0xfe430000, PAGE_SIZE); - BUG_ON(!gic_dist_base || !gic_cpu_base); - - /* use GIC to handle interrupts */ - gic_init(0, 29, gic_dist_base, gic_cpu_base); - - r8a7778_init_irq_common(); -} - -void __init r8a7778_init_delay(void) -{ - shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ -} - -#ifdef CONFIG_USE_OF -void __init r8a7778_init_irq_dt(void) -{ - irqchip_init(); - r8a7778_init_irq_common(); -} - -static const struct of_dev_auxdata r8a7778_auxdata_lookup[] __initconst = { - {}, -}; - -void __init r8a7778_add_standard_devices_dt(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - r8a7778_auxdata_lookup, NULL); -} - static const char *r8a7778_compat_dt[] __initdata = { "renesas,r8a7778", NULL, @@ -475,7 +446,6 @@ static const char *r8a7778_compat_dt[] __initdata = { DT_MACHINE_START(R8A7778_DT, "Generic R8A7778 (Flattened Device Tree)") .init_early = r8a7778_init_delay, .init_irq = r8a7778_init_irq_dt, - .init_machine = r8a7778_add_standard_devices_dt, .init_time = shmobile_timer_init, .dt_compat = r8a7778_compat_dt, .init_late = r8a7778_init_late, diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 3986877..66d3826 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -665,10 +665,6 @@ void __init r8a7779_init_delay(void) shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */ } -static const struct of_dev_auxdata r8a7779_auxdata_lookup[] __initconst = { - {}, -}; - void __init r8a7779_add_standard_devices_dt(void) { /* clocks are setup late during boot in the case of DT */ @@ -676,8 +672,7 @@ void __init r8a7779_add_standard_devices_dt(void) platform_add_devices(r8a7779_devices_dt, ARRAY_SIZE(r8a7779_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, - r8a7779_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char *r8a7779_compat_dt[] __initdata = { diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 28f9475..4c96dad 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -19,12 +19,12 @@ */ #include <linux/irq.h> -#include <linux/irqchip.h> #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 <linux/serial_sci.h> +#include <linux/sh_timer.h> #include <mach/common.h> #include <mach/irqs.h> #include <mach/r8a7790.h> @@ -149,6 +149,36 @@ static struct resource irqc0_resources[] __initdata = { &irqc##idx##_data, \ sizeof(struct renesas_irqc_config)) +static struct resource thermal_resources[] __initdata = { + DEFINE_RES_MEM(0xe61f0000, 0x14), + DEFINE_RES_MEM(0xe61f0100, 0x38), + DEFINE_RES_IRQ(gic_spi(69)), +}; + +#define r8a7790_register_thermal() \ + platform_device_register_simple("rcar_thermal", -1, \ + thermal_resources, \ + ARRAY_SIZE(thermal_resources)) + +static struct sh_timer_config cmt00_platform_data = { + .name = "CMT00", + .timer_bit = 0, + .clockevent_rating = 80, +}; + +static struct resource cmt00_resources[] = { + DEFINE_RES_MEM(0xffca0510, 0x0c), + DEFINE_RES_MEM(0xffca0500, 0x04), + DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ +}; + +#define r8a7790_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh_cmt", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + void __init r8a7790_add_standard_devices(void) { r8a7790_register_scif(SCIFA0); @@ -162,34 +192,91 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_scif(HSCIF0); r8a7790_register_scif(HSCIF1); r8a7790_register_irqc(0); + r8a7790_register_thermal(); + r8a7790_register_cmt(00); } +#define MODEMR 0xe6160060 + +u32 __init r8a7790_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +#define CNTCR 0 +#define CNTFID0 0x20 + void __init r8a7790_timer_init(void) { - void __iomem *cntcr; +#ifdef CONFIG_ARM_ARCH_TIMER + u32 mode = r8a7790_read_mode_pins(); + void __iomem *base; + int extal_mhz = 0; + u32 freq; + + /* At Linux boot time the r8a7790 arch timer comes up + * with the counter disabled. Moreover, it may also report + * a potentially incorrect fixed 13 MHz frequency. To be + * correct these registers need to be updated to use the + * frequency EXTAL / 2 which can be determined by the MD pins. + */ + + switch (mode & (MD(14) | MD(13))) { + case 0: + extal_mhz = 15; + break; + case MD(13): + extal_mhz = 20; + break; + case MD(14): + extal_mhz = 26; + break; + case MD(13) | MD(14): + extal_mhz = 30; + break; + } - /* make sure arch timer is started by setting bit 0 of CNTCT */ - cntcr = ioremap(0xe6080000, PAGE_SIZE); - iowrite32(1, cntcr); - iounmap(cntcr); + /* The arch timer frequency equals EXTAL / 2 */ + freq = extal_mhz * (1000000 / 2); + + /* Remap "armgcnt address map" space */ + base = ioremap(0xe6080000, PAGE_SIZE); + + /* Update registers with correct frequency */ + iowrite32(freq, base + CNTFID0); + asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); + + /* make sure arch timer is started by setting bit 0 of CNTCR */ + iowrite32(1, base + CNTCR); + iounmap(base); +#endif /* CONFIG_ARM_ARCH_TIMER */ shmobile_timer_init(); } -#ifdef CONFIG_USE_OF -void __init r8a7790_add_standard_devices_dt(void) +void __init r8a7790_init_delay(void) { - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ +#endif } +#ifdef CONFIG_USE_OF + static const char *r8a7790_boards_compat_dt[] __initdata = { "renesas,r8a7790", NULL, }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") - .init_irq = irqchip_init, - .init_machine = r8a7790_add_standard_devices_dt, + .init_early = r8a7790_init_delay, .init_time = r8a7790_timer_init, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 5502d62..13e6fdb 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1147,10 +1147,6 @@ void __init sh7372_add_early_devices_dt(void) shmobile_setup_console(); } -static const struct of_dev_auxdata sh7372_auxdata_lookup[] __initconst = { - { } -}; - void __init sh7372_add_standard_devices_dt(void) { /* clocks are setup late during boot in the case of DT */ @@ -1159,8 +1155,7 @@ void __init sh7372_add_standard_devices_dt(void) platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); - of_platform_populate(NULL, of_default_bus_match_table, - sh7372_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char *sh7372_boards_compat_dt[] __initdata = { diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 96e7ca1..516c239 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -22,7 +22,6 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/irqchip.h> #include <linux/platform_device.h> #include <linux/of_platform.h> #include <linux/delay.h> @@ -61,29 +60,16 @@ void __init sh73a0_map_io(void) iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); } -static struct resource sh73a0_pfc_resources[] = { - [0] = { - .start = 0xe6050000, - .end = 0xe6057fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0xe605801c, - .end = 0xe6058027, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device sh73a0_pfc_device = { - .name = "pfc-sh73a0", - .id = -1, - .resource = sh73a0_pfc_resources, - .num_resources = ARRAY_SIZE(sh73a0_pfc_resources), +/* PFC */ +static struct resource pfc_resources[] __initdata = { + DEFINE_RES_MEM(0xe6050000, 0x8000), + DEFINE_RES_MEM(0xe605801c, 0x000c), }; void __init sh73a0_pinmux_init(void) { - platform_device_register(&sh73a0_pfc_device); + platform_device_register_simple("pfc-sh73a0", -1, pfc_resources, + ARRAY_SIZE(pfc_resources)); } static struct plat_sci_port scif0_platform_data = { @@ -958,10 +944,6 @@ void __init sh73a0_add_early_devices(void) #ifdef CONFIG_USE_OF -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, }; @@ -971,8 +953,7 @@ void __init sh73a0_add_standard_devices_dt(void) platform_add_devices(sh73a0_devices_dt, ARRAY_SIZE(sh73a0_devices_dt)); - of_platform_populate(NULL, of_default_bus_match_table, - sh73a0_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); /* Instantiate cpufreq-cpu0 */ platform_device_register_full(&devinfo); @@ -988,7 +969,6 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") .map_io = sh73a0_map_io, .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, - .init_irq = irqchip_init, .init_machine = sh73a0_add_standard_devices_dt, .dt_compat = sh73a0_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 22a05a8..78e84c5 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -29,6 +29,8 @@ #include <asm/smp_scu.h> #define EMEV2_SCU_BASE 0x1e000000 +#define EMEV2_SMU_BASE 0xe0110000 +#define SMU_GENERAL_REG0 0x7c0 static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) { @@ -38,10 +40,18 @@ static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) { + void __iomem *smu; + + /* setup EMEV2 specific SCU base, enable */ + shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); scu_enable(shmobile_scu_base); /* Tell ROM loader about our vector (in headsmp-scu.S, headsmp.S) */ - emev2_set_boot_vector(__pa(shmobile_boot_vector)); + smu = ioremap(EMEV2_SMU_BASE, PAGE_SIZE); + if (smu) { + iowrite32(__pa(shmobile_boot_vector), smu + SMU_GENERAL_REG0); + iounmap(smu); + } shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); shmobile_boot_arg = (unsigned long)shmobile_scu_base; @@ -49,21 +59,7 @@ static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); } -static void __init emev2_smp_init_cpus(void) -{ - unsigned int ncores; - - /* setup EMEV2 specific SCU base */ - shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); - emev2_clock_init(); /* need ioremapped SMU */ - - ncores = shmobile_scu_base ? scu_get_core_count(shmobile_scu_base) : 1; - - shmobile_smp_init_cpus(ncores); -} - struct smp_operations emev2_smp_ops __initdata = { - .smp_init_cpus = emev2_smp_init_cpus, .smp_prepare_cpus = emev2_smp_prepare_cpus, .smp_boot_secondary = emev2_boot_secondary, }; |