diff options
Diffstat (limited to 'arch/arm/mach-shmobile')
83 files changed, 7292 insertions, 4630 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 3912ce91fee..798073057e5 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -1,6 +1,62 @@ -if ARCH_SHMOBILE +config ARCH_SHMOBILE + bool + +menuconfig ARCH_SHMOBILE_MULTI + bool "Renesas ARM SoCs" if ARCH_MULTI_V7 + depends on MMU + select ARCH_SHMOBILE + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + select ARM_GIC + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE + select NO_IOPORT_MAP + select PINCTRL + select ARCH_REQUIRE_GPIOLIB + +if ARCH_SHMOBILE_MULTI + +#comment "Renesas ARM SoCs System Type" + +config ARCH_EMEV2 + bool "Emma Mobile EV2" + select SYS_SUPPORTS_EM_STI + +config ARCH_R7S72100 + bool "RZ/A1H (R7S72100)" + select SYS_SUPPORTS_SH_MTU2 + +config ARCH_R8A7790 + bool "R-Car H2 (R8A77900)" + select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT + +config ARCH_R8A7791 + bool "R-Car M2 (R8A77910)" + select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT + +comment "Renesas ARM SoCs Board Type" -comment "SH-Mobile System Type" +config MACH_GENMAI + bool "Genmai board" + depends on ARCH_R7S72100 + +config MACH_KOELSCH + bool "Koelsch board" + depends on ARCH_R8A7791 + select MICREL_PHY if SH_ETH + +config MACH_LAGER + bool "Lager board" + depends on ARCH_R8A7790 + select MICREL_PHY if SH_ETH + +comment "Renesas ARM SoCs System Configuration" +endif + +if ARCH_SHMOBILE_LEGACY + +comment "Renesas ARM SoCs System Type" config ARCH_SH7372 bool "SH-Mobile AP4 (SH7372)" @@ -8,6 +64,8 @@ config ARCH_SH7372 select ARM_CPU_SUSPEND if PM || CPU_IDLE select CPU_V7 select SH_CLK_CPG + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_SH73A0 bool "SH-Mobile AG5 (R8A73A00)" @@ -17,15 +75,19 @@ config ARCH_SH73A0 select I2C select SH_CLK_CPG select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_R8A73A4 bool "R-Mobile APE6 (R8A73A40)" 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_OPP + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7740 bool "R-Mobile A1 (R8A77400)" @@ -34,6 +96,8 @@ config ARCH_R8A7740 select CPU_V7 select SH_CLK_CPG select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7778 bool "R-Car M1A (R8A77781)" @@ -41,8 +105,8 @@ config ARCH_R8A7778 select CPU_V7 select SH_CLK_CPG select ARM_GIC - select USB_ARCH_HAS_EHCI - select USB_ARCH_HAS_OHCI + select SYS_SUPPORTS_SH_TMU + select RENESAS_INTC_IRQPIN config ARCH_R8A7779 bool "R-Car H1 (R8A77790)" @@ -50,58 +114,74 @@ config ARCH_R8A7779 select ARM_GIC select CPU_V7 select SH_CLK_CPG - select USB_ARCH_HAS_EHCI - select USB_ARCH_HAS_OHCI select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC select CPU_V7 - select HAVE_ARM_ARCH_TIMER + select MIGHT_HAVE_PCI select SH_CLK_CPG select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE -config ARCH_EMEV2 - bool "Emma Mobile EV2" +config ARCH_R8A7791 + bool "R-Car M2 (R8A77910)" select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC select CPU_V7 + select MIGHT_HAVE_PCI + select SH_CLK_CPG + select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE -comment "SH-Mobile Board Type" +config ARCH_R7S72100 + bool "RZ/A1H (R7S72100)" + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + select SYS_SUPPORTS_SH_MTU2 -config MACH_AG5EVM - bool "AG5EVM board" - depends on ARCH_SH73A0 - select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR - select SH_LCD_MIPI_DSI +comment "Renesas ARM SoCs Board Type" config MACH_APE6EVM bool "APE6EVM board" depends on ARCH_R8A73A4 + select SMSC_PHY if SMSC911X select USE_OF +config MACH_APE6EVM_REFERENCE + bool "APE6EVM board - Reference Device Tree Implementation" + depends on ARCH_R8A73A4 + select SMSC_PHY if SMSC911X + select USE_OF + ---help--- + Use reference implementation of APE6EVM 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_MACKEREL bool "mackerel board" depends on ARCH_SH7372 select ARCH_REQUIRE_GPIOLIB select REGULATOR_FIXED_VOLTAGE if REGULATOR + select SMSC_PHY if SMSC911X select SND_SOC_AK4642 if SND_SIMPLE_CARD select USE_OF -config MACH_KOTA2 - bool "KOTA2 board" - depends on ARCH_SH73A0 - select ARCH_REQUIRE_GPIOLIB - select REGULATOR_FIXED_VOLTAGE if REGULATOR - config MACH_ARMADILLO800EVA bool "Armadillo-800 EVA board" depends on ARCH_R8A7740 select ARCH_REQUIRE_GPIOLIB select REGULATOR_FIXED_VOLTAGE if REGULATOR + select SMSC_PHY if SH_ETH select SND_SOC_WM8978 if SND_SIMPLE_CARD select USE_OF @@ -110,11 +190,12 @@ config MACH_ARMADILLO800EVA_REFERENCE depends on ARCH_R8A7740 select ARCH_REQUIRE_GPIOLIB select REGULATOR_FIXED_VOLTAGE if REGULATOR + select SMSC_PHY if SH_ETH select SND_SOC_WM8978 if SND_SIMPLE_CARD select USE_OF ---help--- - Use reference implementation of Aramdillo800 EVA board support - which makes a greater use of device tree at the expense + Use reference implementation of Armadillo800 EVA board support + which makes greater use of device tree at the expense of not supporting a number of devices. This is intended to aid developers @@ -123,7 +204,27 @@ config MACH_BOCKW bool "BOCK-W platform" depends on ARCH_R8A7778 select ARCH_REQUIRE_GPIOLIB - select RENESAS_INTC_IRQPIN + select REGULATOR_FIXED_VOLTAGE if REGULATOR + select SND_SOC_AK4554 if SND_SIMPLE_CARD + select SND_SOC_AK4642 if SND_SIMPLE_CARD + select USE_OF + +config MACH_BOCKW_REFERENCE + bool "BOCK-W - Reference Device Tree Implementation" + depends on ARCH_R8A7778 + select ARCH_REQUIRE_GPIOLIB + select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USE_OF + ---help--- + Use reference implementation of BockW board support + which makes use of device tree at the expense + of not supporting a number of devices. + + This is intended to aid developers + +config MACH_GENMAI + bool "Genmai board" + depends on ARCH_R7S72100 select USE_OF config MACH_MARZEN @@ -131,6 +232,7 @@ config MACH_MARZEN depends on ARCH_R8A7779 select ARCH_REQUIRE_GPIOLIB select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USE_OF config MACH_MARZEN_REFERENCE bool "MARZEN board - Reference Device Tree Implementation" @@ -149,17 +251,18 @@ config MACH_LAGER bool "Lager board" depends on ARCH_R8A7790 select USE_OF + select MICREL_PHY if SH_ETH + select SND_SOC_AK4642 if SND_SIMPLE_CARD -config MACH_KZM9D - bool "KZM9D board" - depends on ARCH_EMEV2 - select REGULATOR_FIXED_VOLTAGE if REGULATOR +config MACH_KOELSCH + bool "Koelsch board" + depends on ARCH_R8A7791 select USE_OF + select MICREL_PHY if SH_ETH 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 @@ -180,12 +283,21 @@ config MACH_KZM9G_REFERENCE This is intended to aid developers -comment "SH-Mobile System Configuration" +comment "Renesas ARM SoCs System Configuration" config CPU_HAS_INTEVT bool default y +config SH_CLK_CPG + bool + +source "drivers/sh/Kconfig" + +endif + +if ARCH_SHMOBILE + menu "Timer and clock configuration" config SHMOBILE_TIMER_HZ @@ -196,33 +308,10 @@ config SHMOBILE_TIMER_HZ Allows the configuration of the timer frequency. It is customary to have the timer interrupt run at 1000 Hz or 100 Hz, but in the case of low timer frequencies other values may be more suitable. - SH-Mobile systems using a 32768 Hz RCLK for clock events may want - to select a HZ value such as 128 that can evenly divide RCLK. + Renesas ARM SoC systems using a 32768 Hz RCLK for clock events may + want to select a HZ value such as 128 that can evenly divide RCLK. A HZ value that does not divide evenly may cause timer drift. -config SH_TIMER_CMT - bool "CMT timer driver" - default y - help - This enables build of the CMT timer driver. - -config SH_TIMER_TMU - bool "TMU timer driver" - default y - help - This enables build of the TMU timer driver. - -config EM_TIMER_STI - bool "STI timer driver" - default y - help - This enables build of the STI timer driver. - endmenu -config SH_CLK_CPG - bool - -source "drivers/sh/Kconfig" - endif diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 6165a517f58..38d5fe825e9 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -2,52 +2,79 @@ # Makefile for the linux kernel. # +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/mach-shmobile/include + # Common objects -obj-y := timer.o console.o clock.o +obj-y := timer.o console.o # CPU objects -obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o -obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o -obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o clock-r8a73a4.o -obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o clock-r8a7740.o intc-r8a7740.o -obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o clock-r8a7778.o -obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o -obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o clock-r8a7790.o -obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o +obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o intc-sh7372.o +obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o intc-sh73a0.o +obj-$(CONFIG_ARCH_R8A73A4) += setup-r8a73a4.o +obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o +obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o +obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o +obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o +obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o +obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o +obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o + +# Clock objects +obj-y += clock.o +ifndef CONFIG_COMMON_CLK +obj-$(CONFIG_ARCH_SH7372) += clock-sh7372.o +obj-$(CONFIG_ARCH_SH73A0) += clock-sh73a0.o +obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o +obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o +obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o +obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o +obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o +obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o +obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o +endif # SMP objects smp-y := platsmp.o headsmp.o -smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o -smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o -smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o +smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o +smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o +smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o +smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o platsmp-apmu.o +smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o # IRQ objects obj-$(CONFIG_ARCH_SH7372) += entry-intc.o -obj-$(CONFIG_ARCH_R8A7740) += entry-intc.o # PM objects obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o -obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o -obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o -obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o +obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o pm-rmobile.o obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o +obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o pm-rmobile.o +obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o pm-rcar.o +obj-$(CONFIG_ARCH_R8A7790) += pm-r8a7790.o pm-rcar.o # Board objects -obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o +ifdef CONFIG_ARCH_SHMOBILE_MULTI +obj-$(CONFIG_MACH_GENMAI) += board-genmai-reference.o +obj-$(CONFIG_MACH_KOELSCH) += board-koelsch-reference.o +obj-$(CONFIG_MACH_LAGER) += board-lager-reference.o +else obj-$(CONFIG_MACH_APE6EVM) += board-ape6evm.o +obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o -obj-$(CONFIG_MACH_KOTA2) += board-kota2.o obj-$(CONFIG_MACH_BOCKW) += board-bockw.o +obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o +obj-$(CONFIG_MACH_GENMAI) += board-genmai.o obj-$(CONFIG_MACH_MARZEN) += board-marzen.o obj-$(CONFIG_MACH_MARZEN_REFERENCE) += board-marzen-reference.o 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_KOELSCH) += board-koelsch.o obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o +endif # Framework support obj-$(CONFIG_SMP) += $(smp-y) diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot index 84c6868580f..918fccffa1b 100644 --- a/arch/arm/mach-shmobile/Makefile.boot +++ b/arch/arm/mach-shmobile/Makefile.boot @@ -1,12 +1,13 @@ # per-board load address for uImage loadaddr-y := -loadaddr-$(CONFIG_MACH_AG5EVM) += 0x40008000 loadaddr-$(CONFIG_MACH_APE6EVM) += 0x40008000 +loadaddr-$(CONFIG_MACH_APE6EVM_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000 loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000 -loadaddr-$(CONFIG_MACH_KOTA2) += 0x41008000 -loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000 +loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000 +loadaddr-$(CONFIG_MACH_GENMAI) += 0x08008000 +loadaddr-$(CONFIG_MACH_KOELSCH) += 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-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c deleted file mode 100644 index c7540710906..00000000000 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * arch/arm/mach-shmobile/board-ag5evm.c - * - * Copyright (C) 2010 Takashi Yoshii <yoshii.takashi.zj@renesas.com> - * Copyright (C) 2009 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 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/kernel.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/pinctrl/machine.h> -#include <linux/pinctrl/pinconf-generic.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/dma-mapping.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <linux/serial_sci.h> -#include <linux/smsc911x.h> -#include <linux/gpio.h> -#include <linux/videodev2.h> -#include <linux/input.h> -#include <linux/input/sh_keysc.h> -#include <linux/mmc/host.h> -#include <linux/mmc/sh_mmcif.h> -#include <linux/mmc/sh_mobile_sdhi.h> -#include <linux/mfd/tmio.h> -#include <linux/sh_clk.h> -#include <linux/irqchip/arm-gic.h> -#include <video/sh_mobile_lcdc.h> -#include <video/sh_mipi_dsi.h> -#include <sound/sh_fsi.h> -#include <mach/hardware.h> -#include <mach/irqs.h> -#include <mach/sh73a0.h> -#include <mach/common.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/hardware/cache-l2x0.h> -#include <asm/traps.h> - -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - -static struct resource smsc9220_resources[] = { - [0] = { - .start = 0x14000000, - .end = 0x14000000 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct smsc911x_platform_config smsc9220_platdata = { - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, - .phy_interface = PHY_INTERFACE_MODE_MII, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, -}; - -static struct platform_device eth_device = { - .name = "smsc911x", - .id = 0, - .dev = { - .platform_data = &smsc9220_platdata, - }, - .resource = smsc9220_resources, - .num_resources = ARRAY_SIZE(smsc9220_resources), -}; - -static struct sh_keysc_info keysc_platdata = { - .mode = SH_KEYSC_MODE_6, - .scan_timing = 3, - .delay = 100, - .keycodes = { - KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, - KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, - KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, - KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, - KEY_SPACE, KEY_9, KEY_6, KEY_3, KEY_WAKEUP, KEY_RIGHT, \ - KEY_COFFEE, - KEY_0, KEY_8, KEY_5, KEY_2, KEY_DOWN, KEY_ENTER, KEY_UP, - KEY_KPASTERISK, KEY_7, KEY_4, KEY_1, KEY_STOP, KEY_LEFT, \ - KEY_COMPUTER, - }, -}; - -static struct resource keysc_resources[] = { - [0] = { - .name = "KEYSC", - .start = 0xe61b0000, - .end = 0xe61b0098 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(71), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device keysc_device = { - .name = "sh_keysc", - .id = 0, - .num_resources = ARRAY_SIZE(keysc_resources), - .resource = keysc_resources, - .dev = { - .platform_data = &keysc_platdata, - }, -}; - -/* FSI A */ -static struct resource fsi_resources[] = { - [0] = { - .name = "FSI", - .start = 0xEC230000, - .end = 0xEC230400 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(146), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device fsi_device = { - .name = "sh_fsi2", - .id = -1, - .num_resources = ARRAY_SIZE(fsi_resources), - .resource = fsi_resources, -}; - -/* Fixed 1.8V regulator to be used by MMCIF */ -static struct regulator_consumer_supply fixed1v8_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), -}; - -static struct resource sh_mmcif_resources[] = { - [0] = { - .name = "MMCIF", - .start = 0xe6bd0000, - .end = 0xe6bd00ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(141), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = gic_spi(140), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct sh_mmcif_plat_data sh_mmcif_platdata = { - .sup_pclk = 0, - .ocr = MMC_VDD_165_195, - .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, - .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, - .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, -}; - -static struct platform_device mmc_device = { - .name = "sh_mmcif", - .id = 0, - .dev = { - .dma_mask = NULL, - .coherent_dma_mask = 0xffffffff, - .platform_data = &sh_mmcif_platdata, - }, - .num_resources = ARRAY_SIZE(sh_mmcif_resources), - .resource = sh_mmcif_resources, -}; - -/* IrDA */ -static struct resource irda_resources[] = { - [0] = { - .start = 0xE6D00000, - .end = 0xE6D01FD4 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(95), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device irda_device = { - .name = "sh_irda", - .id = 0, - .resource = irda_resources, - .num_resources = ARRAY_SIZE(irda_resources), -}; - -/* MIPI-DSI */ -static struct resource mipidsi0_resources[] = { - [0] = { - .name = "DSI0", - .start = 0xfeab0000, - .end = 0xfeab3fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "DSI0", - .start = 0xfeab4000, - .end = 0xfeab7fff, - .flags = IORESOURCE_MEM, - }, -}; - -static int sh_mipi_set_dot_clock(struct platform_device *pdev, - void __iomem *base, - int enable) -{ - struct clk *pck, *phy; - int ret; - - pck = clk_get(&pdev->dev, "dsip_clk"); - if (IS_ERR(pck)) { - ret = PTR_ERR(pck); - goto sh_mipi_set_dot_clock_pck_err; - } - - phy = clk_get(&pdev->dev, "dsiphy_clk"); - if (IS_ERR(phy)) { - ret = PTR_ERR(phy); - goto sh_mipi_set_dot_clock_phy_err; - } - - if (enable) { - clk_set_rate(pck, clk_round_rate(pck, 24000000)); - clk_set_rate(phy, clk_round_rate(pck, 510000000)); - clk_enable(pck); - clk_enable(phy); - } else { - clk_disable(pck); - clk_disable(phy); - } - - ret = 0; - - clk_put(phy); -sh_mipi_set_dot_clock_phy_err: - clk_put(pck); -sh_mipi_set_dot_clock_pck_err: - return ret; -} - -static struct sh_mipi_dsi_info mipidsi0_info = { - .data_format = MIPI_RGB888, - .channel = LCDC_CHAN_MAINLCD, - .lane = 2, - .vsynw_offset = 20, - .clksrc = 1, - .flags = SH_MIPI_DSI_HSABM | - SH_MIPI_DSI_SYNC_PULSES_MODE | - SH_MIPI_DSI_HSbyteCLK, - .set_dot_clock = sh_mipi_set_dot_clock, -}; - -static struct platform_device mipidsi0_device = { - .name = "sh-mipi-dsi", - .num_resources = ARRAY_SIZE(mipidsi0_resources), - .resource = mipidsi0_resources, - .id = 0, - .dev = { - .platform_data = &mipidsi0_info, - }, -}; - -static unsigned char lcd_backlight_seq[3][2] = { - { 0x04, 0x07 }, - { 0x23, 0x80 }, - { 0x03, 0x01 }, -}; - -static int lcd_backlight_set_brightness(int brightness) -{ - struct i2c_adapter *adap; - struct i2c_msg msg; - unsigned int i; - int ret; - - if (brightness == 0) { - /* Reset the chip */ - gpio_set_value(235, 0); - mdelay(24); - gpio_set_value(235, 1); - return 0; - } - - adap = i2c_get_adapter(1); - if (adap == NULL) - return -ENODEV; - - for (i = 0; i < ARRAY_SIZE(lcd_backlight_seq); i++) { - msg.addr = 0x6d; - msg.buf = &lcd_backlight_seq[i][0]; - msg.len = 2; - msg.flags = 0; - - ret = i2c_transfer(adap, &msg, 1); - if (ret < 0) - break; - } - - i2c_put_adapter(adap); - return ret < 0 ? ret : 0; -} - -/* LCDC0 */ -static const struct fb_videomode lcdc0_modes[] = { - { - .name = "R63302(QHD)", - .xres = 544, - .yres = 961, - .left_margin = 72, - .right_margin = 600, - .hsync_len = 16, - .upper_margin = 8, - .lower_margin = 8, - .vsync_len = 2, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, - }, -}; - -static struct sh_mobile_lcdc_info lcdc0_info = { - .clock_source = LCDC_CLK_PERIPHERAL, - .ch[0] = { - .chan = LCDC_CHAN_MAINLCD, - .interface_type = RGB24, - .clock_divider = 1, - .flags = LCDC_FLAGS_DWPOL, - .fourcc = V4L2_PIX_FMT_RGB565, - .lcd_modes = lcdc0_modes, - .num_modes = ARRAY_SIZE(lcdc0_modes), - .panel_cfg = { - .width = 44, - .height = 79, - }, - .bl_info = { - .name = "sh_mobile_lcdc_bl", - .max_brightness = 1, - .set_brightness = lcd_backlight_set_brightness, - }, - .tx_dev = &mipidsi0_device, - } -}; - -static struct resource lcdc0_resources[] = { - [0] = { - .name = "LCDC0", - .start = 0xfe940000, /* P4-only space */ - .end = 0xfe943fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = intcs_evt2irq(0x580), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device lcdc0_device = { - .name = "sh_mobile_lcdc_fb", - .num_resources = ARRAY_SIZE(lcdc0_resources), - .resource = lcdc0_resources, - .id = 0, - .dev = { - .platform_data = &lcdc0_info, - .coherent_dma_mask = ~0, - }, -}; - -/* Fixed 2.8V regulators to be used by SDHI0 */ -static struct regulator_consumer_supply fixed2v8_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), -}; - -/* SDHI0 */ -static struct sh_mobile_sdhi_info sdhi0_info = { - .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, - .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD, - .tmio_caps = MMC_CAP_SD_HIGHSPEED, - .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, - .cd_gpio = 251, -}; - -static struct resource sdhi0_resources[] = { - [0] = { - .name = "SDHI0", - .start = 0xee100000, - .end = 0xee1000ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT, - .start = gic_spi(83), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .name = SH_MOBILE_SDHI_IRQ_SDCARD, - .start = gic_spi(84), - .flags = IORESOURCE_IRQ, - }, - [3] = { - .name = SH_MOBILE_SDHI_IRQ_SDIO, - .start = gic_spi(85), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sdhi0_device = { - .name = "sh_mobile_sdhi", - .id = 0, - .num_resources = ARRAY_SIZE(sdhi0_resources), - .resource = sdhi0_resources, - .dev = { - .platform_data = &sdhi0_info, - }, -}; - -/* Fixed 3.3V regulator to be used by SDHI1 */ -static struct regulator_consumer_supply cn4_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), -}; - -static struct regulator_init_data cn4_power_init_data = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(cn4_power_consumers), - .consumer_supplies = cn4_power_consumers, -}; - -static struct fixed_voltage_config cn4_power_info = { - .supply_name = "CN4 SD/MMC Vdd", - .microvolts = 3300000, - .gpio = 114, - .enable_high = 1, - .init_data = &cn4_power_init_data, -}; - -static struct platform_device cn4_power = { - .name = "reg-fixed-voltage", - .id = 2, - .dev = { - .platform_data = &cn4_power_info, - }, -}; - -static void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state) -{ - static int power_gpio = -EINVAL; - - if (power_gpio < 0) { - int ret = gpio_request_one(114, GPIOF_OUT_INIT_LOW, - "sdhi1_power"); - if (!ret) - power_gpio = 114; - } - - /* - * If requesting the GPIO above failed, it means, that the regulator got - * probed and grabbed the GPIO, but we don't know, whether the sdhi - * driver already uses the regulator. If it doesn't, we have to toggle - * the GPIO ourselves, even though it is now owned by the fixed - * regulator driver. We have to live with the race in case the driver - * gets unloaded and the GPIO freed between these two steps. - */ - gpio_set_value(114, state); -} - -static struct sh_mobile_sdhi_info sh_sdhi1_info = { - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, - .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, - .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, - .set_pwr = ag5evm_sdhi1_set_pwr, -}; - -static struct resource sdhi1_resources[] = { - [0] = { - .name = "SDHI1", - .start = 0xee120000, - .end = 0xee1200ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT, - .start = gic_spi(87), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .name = SH_MOBILE_SDHI_IRQ_SDCARD, - .start = gic_spi(88), - .flags = IORESOURCE_IRQ, - }, - [3] = { - .name = SH_MOBILE_SDHI_IRQ_SDIO, - .start = gic_spi(89), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sdhi1_device = { - .name = "sh_mobile_sdhi", - .id = 1, - .dev = { - .platform_data = &sh_sdhi1_info, - }, - .num_resources = ARRAY_SIZE(sdhi1_resources), - .resource = sdhi1_resources, -}; - -static struct platform_device *ag5evm_devices[] __initdata = { - &cn4_power, - ð_device, - &keysc_device, - &fsi_device, - &mmc_device, - &irda_device, - &mipidsi0_device, - &lcdc0_device, - &sdhi0_device, - &sdhi1_device, -}; - -static unsigned long pin_pullup_conf[] = { - PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0), -}; - -static const struct pinctrl_map ag5evm_pinctrl_map[] = { - /* FSIA */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", - "fsia_mclk_in", "fsia"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", - "fsia_sclk_in", "fsia"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", - "fsia_data_in", "fsia"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0", - "fsia_data_out", "fsia"), - /* I2C2 & I2C3 */ - PIN_MAP_MUX_GROUP_DEFAULT("i2c-sh_mobile.2", "pfc-sh73a0", - "i2c2_0", "i2c2"), - PIN_MAP_MUX_GROUP_DEFAULT("i2c-sh_mobile.3", "pfc-sh73a0", - "i2c3_0", "i2c3"), - /* IrDA */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_irda.0", "pfc-sh73a0", - "irda_0", "irda"), - /* KEYSC */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_in8", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out04", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out5", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out6_0", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out7_0", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out8_0", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out9_2", "keysc"), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_in8", pin_pullup_conf), - /* MMCIF */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "mmc0_data8_0", "mmc0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "mmc0_ctrl_0", "mmc0"), - PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "PORT279", pin_pullup_conf), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "mmc0_data8_0", pin_pullup_conf), - /* SCIFA2 */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-sh73a0", - "scifa2_data_0", "scifa2"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-sh73a0", - "scifa2_ctrl_0", "scifa2"), - /* SDHI0 (CN15 [SD I/F]) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_data4", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_ctrl", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_wp", "sdhi0"), - /* SDHI1 (CN4 [WLAN I/F]) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "sdhi1_data4", "sdhi1"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "sdhi1_ctrl", "sdhi1"), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "sdhi1_data4", pin_pullup_conf), - PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "PORT263", pin_pullup_conf), -}; - -static void __init ag5evm_init(void) -{ - regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, - ARRAY_SIZE(fixed1v8_power_consumers), 1800000); - regulator_register_always_on(1, "fixed-2.8V", fixed2v8_power_consumers, - ARRAY_SIZE(fixed2v8_power_consumers), 3300000); - regulator_register_fixed(3, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - pinctrl_register_mappings(ag5evm_pinctrl_map, - ARRAY_SIZE(ag5evm_pinctrl_map)); - sh73a0_pinmux_init(); - - /* enable MMCIF */ - gpio_request_one(208, GPIOF_OUT_INIT_HIGH, NULL); /* Reset */ - - /* enable SMSC911X */ - gpio_request_one(144, GPIOF_IN, NULL); /* PINTA2 */ - gpio_request_one(145, GPIOF_OUT_INIT_HIGH, NULL); /* RESET */ - - /* LCD panel */ - gpio_request_one(217, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ - mdelay(1); - gpio_set_value(217, 1); - mdelay(100); - - /* LCD backlight controller */ - gpio_request_one(235, GPIOF_OUT_INIT_LOW, NULL); /* RESET */ - lcd_backlight_set_brightness(0); - -#ifdef CONFIG_CACHE_L2X0 - /* Shared attribute override enable, 64K*8way */ - l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff); -#endif - sh73a0_add_standard_devices(); - platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices)); -} - -MACHINE_START(AG5EVM, "ag5evm") - .smp = smp_ops(sh73a0_smp_ops), - .map_io = sh73a0_map_io, - .init_early = sh73a0_add_early_devices, - .nr_irqs = NR_IRQS_LEGACY, - .init_irq = sh73a0_init_irq, - .init_machine = ag5evm_init, - .init_late = shmobile_init_late, - .init_time = sh73a0_earlytimer_init, -MACHINE_END diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c new file mode 100644 index 00000000000..3276afcf3cc --- /dev/null +++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c @@ -0,0 +1,63 @@ +/* + * APE6EVM board support + * + * 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/gpio.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/pinctrl/machine.h> +#include <linux/platform_device.h> +#include <linux/sh_clk.h> +#include <mach/common.h> +#include <mach/r8a73a4.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +static void __init ape6evm_add_standard_devices(void) +{ + + struct clk *parent; + struct clk *mp; + + r8a73a4_clock_init(); + + /* MP clock parent = extal2 */ + parent = clk_get(NULL, "extal2"); + mp = clk_get(NULL, "mp"); + BUG_ON(IS_ERR(parent) || IS_ERR(mp)); + + clk_set_parent(mp, parent); + clk_put(parent); + clk_put(mp); + + r8a73a4_add_dt_devices(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0); +} + +static const char *ape6evm_boards_compat_dt[] __initdata = { + "renesas,ape6evm-reference", + NULL, +}; + +DT_MACHINE_START(APE6EVM_DT, "ape6evm") + .init_early = r8a73a4_init_early, + .init_machine = ape6evm_add_standard_devices, + .dt_compat = ape6evm_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index 5eb0caa6a7d..fe071a9130b 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -19,9 +19,14 @@ */ #include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.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> @@ -34,6 +39,58 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* LEDS */ +static struct gpio_led ape6evm_leds[] = { + { + .name = "gnss-en", + .gpio = 28, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, { + .name = "nfc-nrst", + .gpio = 126, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, { + .name = "gnss-nrst", + .gpio = 132, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, { + .name = "bt-wakeup", + .gpio = 232, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, { + .name = "strobe", + .gpio = 250, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, { + .name = "bbresetout", + .gpio = 288, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, +}; + +static __initdata struct gpio_led_platform_data ape6evm_leds_pdata = { + .leds = ape6evm_leds, + .num_leds = ARRAY_SIZE(ape6evm_leds), +}; + +/* GPIO KEY */ +#define GPIO_KEY(c, g, d, ...) \ + { .code = c, .gpio = g, .desc = d, .active_low = 1 } + +static struct gpio_keys_button gpio_buttons[] = { + GPIO_KEY(KEY_0, 324, "S16"), + GPIO_KEY(KEY_MENU, 325, "S17"), + GPIO_KEY(KEY_HOME, 326, "S18"), + GPIO_KEY(KEY_BACK, 327, "S19"), + GPIO_KEY(KEY_VOLUMEUP, 328, "S20"), + GPIO_KEY(KEY_VOLUMEDOWN, 329, "S21"), +}; + +static struct gpio_keys_platform_data ape6evm_keys_pdata __initdata = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + /* Dummy supplies, where voltage doesn't matter */ static struct regulator_consumer_supply dummy_supplies[] = { REGULATOR_SUPPLY("vddvario", "smsc911x"), @@ -41,7 +98,7 @@ static struct regulator_consumer_supply dummy_supplies[] = { }; /* SMSC LAN9220 */ -static const struct resource lan9220_res[] = { +static const struct resource lan9220_res[] __initconst = { DEFINE_RES_MEM(0x08000000, 0x1000), { .start = irq_pin(40), /* IRQ40 */ @@ -49,19 +106,119 @@ static const struct resource lan9220_res[] = { }, }; -static const struct smsc911x_platform_config lan9220_data = { +static const struct smsc911x_platform_config lan9220_data __initconst = { .flags = SMSC911X_USE_32BIT, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, }; -static const struct pinctrl_map ape6evm_pinctrl_map[] = { +/* + * MMC0 power supplies: + * Both Vcc and VccQ to eMMC on APE6EVM are supplied by a tps80032 voltage + * regulator. Until support for it is added to this file we simulate the + * Vcc supply by a fixed always-on regulator + */ +static struct regulator_consumer_supply vcc_mmc0_consumers[] = +{ + REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), +}; + +/* + * SDHI0 power supplies: + * Vcc to SDHI0 on APE6EVM is supplied by a GPIO-switchable regulator. VccQ is + * provided by the same tps80032 regulator as both MMC0 voltages - see comment + * above + */ +static struct regulator_consumer_supply vcc_sdhi0_consumers[] = +{ + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), +}; + +static struct regulator_init_data vcc_sdhi0_init_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers), + .consumer_supplies = vcc_sdhi0_consumers, +}; + +static const struct fixed_voltage_config vcc_sdhi0_info __initconst = { + .supply_name = "SDHI0 Vcc", + .microvolts = 3300000, + .gpio = 76, + .enable_high = 1, + .init_data = &vcc_sdhi0_init_data, +}; + +/* + * SDHI1 power supplies: + * Vcc and VccQ to SDHI1 on APE6EVM are both fixed at 3.3V + */ +static struct regulator_consumer_supply vcc_sdhi1_consumers[] = +{ + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), +}; + +/* MMCIF */ +static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .slave_id_tx = SHDMA_SLAVE_MMCIF0_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF0_RX, + .ccs_unsupported = true, +}; + +static const struct resource mmcif0_resources[] __initconst = { + DEFINE_RES_MEM(0xee200000, 0x100), + DEFINE_RES_IRQ(gic_spi(169)), +}; + +/* SDHI0 */ +static const struct sh_mobile_sdhi_info sdhi0_pdata __initconst = { + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, +}; + +static const struct resource sdhi0_resources[] __initconst = { + DEFINE_RES_MEM(0xee100000, 0x100), + DEFINE_RES_IRQ(gic_spi(165)), +}; + +/* SDHI1 */ +static const struct sh_mobile_sdhi_info sdhi1_pdata __initconst = { + .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 const struct resource sdhi1_resources[] __initconst = { + DEFINE_RES_MEM(0xee120000, 0x100), + DEFINE_RES_IRQ(gic_spi(166)), +}; + +static const struct pinctrl_map ape6evm_pinctrl_map[] __initconst = { /* SCIFA0 console */ PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a73a4", "scifa0_data", "scifa0"), /* 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 +251,28 @@ 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, "MMC0 Vcc", vcc_mmc0_consumers, + ARRAY_SIZE(vcc_mmc0_consumers), 2800000); + platform_device_register_resndata(&platform_bus, "sh_mmcif", 0, + mmcif0_resources, ARRAY_SIZE(mmcif0_resources), + &mmcif0_pdata, sizeof(mmcif0_pdata)); + platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2, + &vcc_sdhi0_info, sizeof(vcc_sdhi0_info)); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0, + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_pdata, sizeof(sdhi0_pdata)); + regulator_register_always_on(3, "SDHI1 Vcc", vcc_sdhi1_consumers, + ARRAY_SIZE(vcc_sdhi1_consumers), 3300000); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1, + sdhi1_resources, ARRAY_SIZE(sdhi1_resources), + &sdhi1_pdata, sizeof(sdhi1_pdata)); + platform_device_register_data(&platform_bus, "gpio-keys", -1, + &ape6evm_keys_pdata, + sizeof(ape6evm_keys_pdata)); + platform_device_register_data(&platform_bus, "leds-gpio", -1, + &ape6evm_leds_pdata, + sizeof(ape6evm_leds_pdata)); } static const char *ape6evm_boards_compat_dt[] __initdata = { @@ -102,8 +281,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_irq = irqchip_init, - .init_time = shmobile_timer_init, + .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-armadillo800eva-reference.c b/arch/arm/mach-shmobile/board-armadillo800eva-reference.c index 03b85fec2dd..f660fbb96e0 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva-reference.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva-reference.c @@ -24,7 +24,6 @@ #include <linux/kernel.h> #include <linux/gpio.h> #include <linux/io.h> -#include <linux/pinctrl/machine.h> #include <mach/common.h> #include <mach/r8a7740.h> #include <asm/mach/arch.h> @@ -119,12 +118,6 @@ * usbhsf_power_ctrl() */ -static const struct pinctrl_map eva_pinctrl_map[] = { - /* SCIFA1 */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.1", "pfc-r8a7740", - "scifa1_data", "scifa1"), -}; - static void __init eva_clock_init(void) { struct clk *system = clk_get(NULL, "system_clk"); @@ -165,35 +158,26 @@ clock_error: */ static void __init eva_init(void) { - r8a7740_clock_init(MD_CK0 | MD_CK2); eva_clock_init(); - pinctrl_register_mappings(eva_pinctrl_map, ARRAY_SIZE(eva_pinctrl_map)); - r8a7740_pinmux_init(); - r8a7740_meram_workaround(); - /* - * Touchscreen - * TODO: Move reset GPIO over to .dts when we can reference it - */ - gpio_request_one(166, GPIOF_OUT_INIT_HIGH, NULL); /* TP_RST_B */ - #ifdef CONFIG_CACHE_L2X0 - /* Early BRESP enable, Shared attribute override enable, 32K*8way */ - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff); + /* Shared attribute override enable, 32K*8way */ + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff); #endif r8a7740_add_standard_devices_dt(); + r8a7740_pm_init(); } #define RESCNT2 IOMEM(0xe6188020) -static void eva_restart(char mode, const char *cmd) +static void eva_restart(enum reboot_mode mode, const char *cmd) { /* Do soft power on reset */ - writel((1 << 31), RESCNT2); + writel(1 << 31, RESCNT2); } static const char *eva_boards_compat_dt[] __initdata = { @@ -203,10 +187,9 @@ static const char *eva_boards_compat_dt[] __initdata = { DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva-reference") .map_io = r8a7740_map_io, - .init_early = r8a7740_init_delay, + .init_early = shmobile_init_delay, .init_irq = r8a7740_init_irq_of, .init_machine = eva_init, - .init_time = shmobile_timer_init, .init_late = shmobile_init_late, .dt_compat = eva_boards_compat_dt, .restart = eva_restart, diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index e115f674210..30fcac73a54 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -31,6 +31,8 @@ #include <linux/gpio_keys.h> #include <linux/regulator/driver.h> #include <linux/pinctrl/machine.h> +#include <linux/pwm.h> +#include <linux/pwm_backlight.h> #include <linux/regulator/fixed.h> #include <linux/regulator/gpio-regulator.h> #include <linux/regulator/machine.h> @@ -358,7 +360,6 @@ static struct platform_device usbhsf_device = { static struct sh_eth_plat_data sh_eth_platdata = { .phy = 0x00, /* LAN8710A */ .edmac_endian = EDMAC_LITTLE_ENDIAN, - .register_type = SH_ETH_REG_GIGABIT, .phy_interface = PHY_INTERFACE_MODE_MII, }; @@ -382,12 +383,50 @@ static struct platform_device sh_eth_device = { .id = -1, .dev = { .platform_data = &sh_eth_platdata, + .dma_mask = &sh_eth_device.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), }, .resource = sh_eth_resources, .num_resources = ARRAY_SIZE(sh_eth_resources), }; -/* LCDC */ +/* PWM */ +static struct resource pwm_resources[] = { + [0] = { + .start = 0xe6600000, + .end = 0xe66000ff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device pwm_device = { + .name = "renesas-tpu-pwm", + .id = -1, + .num_resources = ARRAY_SIZE(pwm_resources), + .resource = pwm_resources, +}; + +static struct pwm_lookup pwm_lookup[] = { + PWM_LOOKUP("renesas-tpu-pwm", 2, "pwm-backlight.0", NULL, + 33333, PWM_POLARITY_INVERSED), +}; + +/* LCDC and backlight */ +static struct platform_pwm_backlight_data pwm_backlight_data = { + .lth_brightness = 50, + .max_brightness = 255, + .dft_brightness = 255, + .pwm_period_ns = 33333, /* 30kHz */ + .enable_gpio = 61, +}; + +static struct platform_device pwm_backlight_device = { + .name = "pwm-backlight", + .dev = { + .platform_data = &pwm_backlight_data, + }, +}; + static struct fb_videomode lcdc0_mode = { .name = "AMPIER/AM-800480", .xres = 800, @@ -438,7 +477,7 @@ static struct platform_device lcdc0_device = { .id = 0, .dev = { .platform_data = &lcdc0_info, - .coherent_dma_mask = ~0, + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -535,7 +574,7 @@ static struct platform_device hdmi_lcdc_device = { .id = 1, .dev = { .platform_data = &hdmi_lcdc_info, - .coherent_dma_mask = ~0, + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -569,6 +608,11 @@ static struct regulator_consumer_supply fixed3v3_power_consumers[] = { REGULATOR_SUPPLY("vqmmc", "sh_mmcif"), }; +/* Fixed 3.3V regulator used by LCD backlight */ +static struct regulator_consumer_supply fixed5v0_power_consumers[] = { + REGULATOR_SUPPLY("power", "pwm-backlight.0"), +}; + /* Fixed 3.3V regulator to be used by SDHI0 */ static struct regulator_consumer_supply vcc_sdhi0_consumers[] = { REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), @@ -679,15 +723,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, @@ -788,6 +823,9 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .ccs_unsupported = true, + .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, }; static struct resource sh_mmcif_resources[] = { @@ -919,7 +957,7 @@ static struct resource fsi_resources[] = { [0] = { .name = "FSI", .start = 0xfe1f0000, - .end = 0xfe1f8400 - 1, + .end = 0xfe1f0400 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -944,14 +982,13 @@ static struct asoc_simple_card_info fsi_wm8978_info = { .card = "FSI2A-WM8978", .codec = "wm8978.0-001a", .platform = "sh_fsi2", - .daifmt = SND_SOC_DAIFMT_I2S, + .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { + .fmt = SND_SOC_DAIFMT_IB_NF, .name = "fsia-dai", - .fmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_IB_NF, }, .codec_dai = { .name = "wm8978-hifi", - .fmt = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF, .sysclk = 12288000, }, }; @@ -972,7 +1009,7 @@ static struct asoc_simple_card_info fsi2_hdmi_info = { .platform = "sh_fsi2", .cpu_dai = { .name = "fsib-dai", - .fmt = SND_SOC_DAIFMT_CBM_CFM, + .fmt = SND_SOC_DAIFMT_CBS_CFS, }, .codec_dai = { .name = "sh_mobile_hdmi-hifi", @@ -1030,6 +1067,8 @@ static struct i2c_board_info i2c2_devices[] = { */ static struct platform_device *eva_devices[] __initdata = { &lcdc0_device, + &pwm_device, + &pwm_backlight_device, &gpio_keys_device, &sh_eth_device, &vcc_sdhi0, @@ -1069,9 +1108,9 @@ static const struct pinctrl_map eva_pinctrl_map[] = { 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", + PIN_MAP_MUX_GROUP_DEFAULT("r8a7740-gether", "pfc-r8a7740", "gether_mii", "gether"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740", + PIN_MAP_MUX_GROUP_DEFAULT("r8a7740-gether", "pfc-r8a7740", "gether_int", "gether"), /* HDMI */ PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-r8a7740", @@ -1101,6 +1140,9 @@ static const struct pinctrl_map eva_pinctrl_map[] = { /* ST1232 */ PIN_MAP_MUX_GROUP_DEFAULT("0-0055", "pfc-r8a7740", "intc_irq10", "intc"), + /* TPU0 */ + PIN_MAP_MUX_GROUP_DEFAULT("renesas-tpu-pwm", "pfc-r8a7740", + "tpu0_to2_1", "tpu0"), /* USBHS */ PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7740", "intc_irq7_1", "intc"), @@ -1152,19 +1194,15 @@ static void __init eva_init(void) regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, ARRAY_SIZE(fixed3v3_power_consumers), 3300000); + regulator_register_always_on(3, "fixed-5.0V", fixed5v0_power_consumers, + ARRAY_SIZE(fixed5v0_power_consumers), 5000000); pinctrl_register_mappings(eva_pinctrl_map, ARRAY_SIZE(eva_pinctrl_map)); + pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); r8a7740_pinmux_init(); r8a7740_meram_workaround(); - /* LCDC0 */ - 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_one(166, GPIOF_OUT_INIT_HIGH, NULL); /* TP_RST_B */ - /* GETHER */ gpio_request_one(18, GPIOF_OUT_INIT_HIGH, NULL); /* PHY_RST */ @@ -1225,8 +1263,8 @@ static void __init eva_init(void) #ifdef CONFIG_CACHE_L2X0 - /* Early BRESP enable, Shared attribute override enable, 32K*8way */ - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff); + /* Shared attribute override enable, 32K*8way */ + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff); #endif i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); @@ -1254,11 +1292,6 @@ static void __init eva_earlytimer_init(void) eva_clock_init(); } -static void __init eva_add_early_devices(void) -{ - r8a7740_add_early_devices(); -} - #define RESCNT2 IOMEM(0xe6188020) static void eva_restart(enum reboot_mode mode, const char *cmd) { @@ -1273,8 +1306,8 @@ static const char *eva_boards_compat_dt[] __initdata = { DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva") .map_io = r8a7740_map_io, - .init_early = eva_add_early_devices, - .init_irq = r8a7740_init_irq, + .init_early = r8a7740_add_early_devices, + .init_irq = r8a7740_init_irq_of, .init_machine = eva_init, .init_late = shmobile_init_late, .init_time = eva_earlytimer_init, diff --git a/arch/arm/mach-shmobile/board-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c new file mode 100644 index 00000000000..027373f8de8 --- /dev/null +++ b/arch/arm/mach-shmobile/board-bockw-reference.c @@ -0,0 +1,85 @@ +/* + * Bock-W board support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 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/of_platform.h> +#include <mach/common.h> +#include <mach/r8a7778.h> +#include <asm/mach/arch.h> + +/* + * see board-bock.c for checking detail of dip-switch + */ + +#define FPGA 0x18200000 +#define IRQ0MR 0x30 +#define COMCTLR 0x101c + +#define PFC 0xfffc0000 +#define PUPR4 0x110 +static void __init bockw_init(void) +{ + void __iomem *fpga; + void __iomem *pfc; + + r8a7778_clock_init(); + r8a7778_init_irq_extpin_dt(1); + r8a7778_add_dt_devices(); + + fpga = ioremap_nocache(FPGA, SZ_1M); + if (fpga) { + /* + * CAUTION + * + * IRQ0/1 is cascaded interrupt from FPGA. + * it should be cared in the future + * Now, it is assuming IRQ0 was used only from SMSC. + */ + u16 val = ioread16(fpga + IRQ0MR); + val &= ~(1 << 4); /* enable SMSC911x */ + iowrite16(val, fpga + IRQ0MR); + + iounmap(fpga); + } + + pfc = ioremap_nocache(PFC, 0x200); + if (pfc) { + /* + * FIXME + * + * SDHI CD/WP pin needs pull-up + */ + iowrite32(ioread32(pfc + PUPR4) | (3 << 26), pfc + PUPR4); + iounmap(pfc); + } + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *bockw_boards_compat_dt[] __initdata = { + "renesas,bockw-reference", + NULL, +}; + +DT_MACHINE_START(BOCKW_DT, "bockw") + .init_early = r8a7778_init_delay, + .init_irq = r8a7778_init_irq_dt, + .init_machine = bockw_init, + .dt_compat = bockw_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index d5554646916..f444be2f241 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -1,8 +1,9 @@ /* * Bock-W board support * - * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013-2014 Renesas Solutions Corp. * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * Copyright (C) 2013-2014 Cogent Embedded, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,18 +21,31 @@ #include <linux/mfd/tmio.h> #include <linux/mmc/host.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/mmc/sh_mmcif.h> #include <linux/mtd/partitions.h> #include <linux/pinctrl/machine.h> +#include <linux/platform_data/camera-rcar.h> +#include <linux/platform_data/usb-rcar-phy.h> #include <linux/platform_device.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/smsc911x.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <linux/usb/renesas_usbhs.h> +#include <media/soc_camera.h> #include <mach/common.h> #include <mach/irqs.h> #include <mach/r8a7778.h> #include <asm/mach/arch.h> +#include <sound/rcar_snd.h> +#include <sound/simple_card.h> + +#define FPGA 0x18200000 +#define IRQ0MR 0x30 +#define COMCTLR 0x101c +static void __iomem *fpga; /* * CN9(Upper side) SCIF/RCAN selection @@ -58,38 +72,159 @@ * SW19 (MMC) 1 pin */ +/* + * SSI settings + * + * SW45: 1-4 side (SSI5 out, ROUT/LOUT CN19 Mid) + * SW46: 1101 (SSI6 Recorde) + * SW47: 1110 (SSI5 Playback) + * SW48: 11 (Recorde power) + * SW49: 1 (SSI slave mode) + * SW50: 1111 (SSI7, SSI8) + * SW51: 1111 (SSI3, SSI4) + * SW54: 1pin (ak4554 FPGA control) + * SW55: 1 (CLKB is 24.5760MHz) + * SW60: 1pin (ak4554 FPGA control) + * SW61: 3pin (use X11 clock) + * SW78: 3-6 (ak4642 connects I2C0) + * + * You can use sound as + * + * hw0: CN19: SSI56-AK4643 + * hw1: CN21: SSI3-AK4554(playback) + * hw2: CN21: SSI4-AK4554(capture) + * hw3: CN20: SSI7-AK4554(playback) + * hw4: CN20: SSI8-AK4554(capture) + * + * this command is required when playback on hw0. + * + * # amixer set "LINEOUT Mixer DACL" on + */ + +/* + * USB + * + * USB1 (CN29) can be Host/Function + * + * Host Func + * SW98 1 2 + * SW99 1 3 + */ + /* Dummy supplies, where voltage doesn't matter */ static struct regulator_consumer_supply dummy_supplies[] = { REGULATOR_SUPPLY("vddvario", "smsc911x"), REGULATOR_SUPPLY("vdd33a", "smsc911x"), }; -static struct smsc911x_platform_config smsc911x_data = { +static struct regulator_consumer_supply fixed3v3_power_consumers[] = { + REGULATOR_SUPPLY("vmmc", "sh_mmcif"), + REGULATOR_SUPPLY("vqmmc", "sh_mmcif"), +}; + +static struct smsc911x_platform_config smsc911x_data __initdata = { .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, .flags = SMSC911X_USE_32BIT, .phy_interface = PHY_INTERFACE_MODE_MII, }; -static struct resource smsc911x_resources[] = { +static struct resource smsc911x_resources[] __initdata = { DEFINE_RES_MEM(0x18300000, 0x1000), DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */ }; +#if IS_ENABLED(CONFIG_USB_RENESAS_USBHS_UDC) +/* + * When USB1 is Func + */ +static int usbhsf_get_id(struct platform_device *pdev) +{ + return USBHS_GADGET; +} + +#define SUSPMODE 0x102 +static int usbhsf_power_ctrl(struct platform_device *pdev, + void __iomem *base, int enable) +{ + enable = !!enable; + + r8a7778_usb_phy_power(enable); + + iowrite16(enable << 14, base + SUSPMODE); + + return 0; +} + +static struct resource usbhsf_resources[] __initdata = { + DEFINE_RES_MEM(0xffe60000, 0x110), + DEFINE_RES_IRQ(gic_iid(0x4f)), +}; + +static struct renesas_usbhs_platform_info usbhs_info __initdata = { + .platform_callback = { + .get_id = usbhsf_get_id, + .power_ctrl = usbhsf_power_ctrl, + }, + .driver_param = { + .buswait_bwait = 4, + .d0_tx_id = HPBDMA_SLAVE_USBFUNC_TX, + .d1_rx_id = HPBDMA_SLAVE_USBFUNC_RX, + }, +}; + +#define USB_PHY_SETTING {.port1_func = 1, .ovc_pin[1].active_high = 1,} +#define USB1_DEVICE "renesas_usbhs" +#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() \ + platform_device_register_resndata( \ + &platform_bus, "renesas_usbhs", -1, \ + usbhsf_resources, \ + ARRAY_SIZE(usbhsf_resources), \ + &usbhs_info, sizeof(struct renesas_usbhs_platform_info)) + +#else +/* + * When USB1 is Host + */ +#define USB_PHY_SETTING { } +#define USB1_DEVICE "ehci-platform" +#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() + +#endif + /* USB */ -static struct rcar_phy_platform_data usb_phy_platform_data __initdata; +static struct resource usb_phy_resources[] __initdata = { + DEFINE_RES_MEM(0xffe70800, 0x100), + DEFINE_RES_MEM(0xffe76000, 0x100), +}; + +static struct rcar_phy_platform_data usb_phy_platform_data __initdata = + USB_PHY_SETTING; + /* SDHI */ -static struct sh_mobile_sdhi_info sdhi0_info = { +static struct sh_mobile_sdhi_info sdhi0_info __initdata = { + .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, .tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, }; +static struct resource sdhi0_resources[] __initdata = { + DEFINE_RES_MEM(0xFFE4C000, 0x100), + DEFINE_RES_IRQ(gic_iid(0x77)), +}; + +/* Ether */ +static struct resource ether_resources[] __initdata = { + DEFINE_RES_MEM(0xfde00000, 0x400), + DEFINE_RES_IRQ(gic_iid(0x89)), +}; + static struct sh_eth_plat_data ether_platform_data __initdata = { .phy = 0x01, .edmac_endian = EDMAC_LITTLE_ENDIAN, - .register_type = SH_ETH_REG_FAST_RCAR, .phy_interface = PHY_INTERFACE_MODE_RMII, /* * Although the LINK signal is available on the board, it's connected to @@ -100,11 +235,24 @@ static struct sh_eth_plat_data ether_platform_data __initdata = { .no_ether_link = 1, }; +static struct platform_device_info ether_info __initdata = { + .parent = &platform_bus, + .name = "r8a777x-ether", + .id = -1, + .res = ether_resources, + .num_res = ARRAY_SIZE(ether_resources), + .data = ðer_platform_data, + .size_data = sizeof(ether_platform_data), + .dma_mask = DMA_BIT_MASK(32), +}; + /* I2C */ static struct i2c_board_info i2c0_devices[] = { { I2C_BOARD_INFO("rx8581", 0x51), - }, + }, { + I2C_BOARD_INFO("ak4643", 0x12), + } }; /* HSPI*/ @@ -135,15 +283,283 @@ static struct spi_board_info spi_board_info[] __initdata = { }; /* MMC */ -static struct sh_mmcif_plat_data sh_mmcif_plat = { +static struct resource mmc_resources[] __initdata = { + DEFINE_RES_MEM(0xffe4e000, 0x100), + DEFINE_RES_IRQ(gic_iid(0x5d)), +}; + +static struct sh_mmcif_plat_data sh_mmcif_plat __initdata = { .sup_pclk = 0, - .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_NEEDS_POLL, }; +/* In the default configuration both decoders reside on I2C bus 0 */ +#define BOCKW_CAMERA(idx) \ +static struct i2c_board_info camera##idx##_info = { \ + I2C_BOARD_INFO("ml86v7667", 0x41 + 2 * (idx)), \ +}; \ + \ +static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = { \ + .bus_id = idx, \ + .i2c_adapter_id = 0, \ + .board_info = &camera##idx##_info, \ +} + +BOCKW_CAMERA(0); +BOCKW_CAMERA(1); + +/* VIN */ +static struct rcar_vin_platform_data vin_platform_data __initdata = { + .flags = RCAR_VIN_BT656, +}; + +#define R8A7778_VIN(idx) \ +static struct resource vin##idx##_resources[] __initdata = { \ + DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ + DEFINE_RES_IRQ(gic_iid(0x5a)), \ +}; \ + \ +static struct platform_device_info vin##idx##_info __initdata = { \ + .parent = &platform_bus, \ + .name = "r8a7778-vin", \ + .id = idx, \ + .res = vin##idx##_resources, \ + .num_res = ARRAY_SIZE(vin##idx##_resources), \ + .dma_mask = DMA_BIT_MASK(32), \ + .data = &vin_platform_data, \ + .size_data = sizeof(vin_platform_data), \ +} +R8A7778_VIN(0); +R8A7778_VIN(1); + +/* Sound */ +static struct resource rsnd_resources[] __initdata = { + [RSND_GEN1_SRU] = DEFINE_RES_MEM(0xffd90000, 0x1000), + [RSND_GEN1_SSI] = DEFINE_RES_MEM(0xffd91000, 0x1240), + [RSND_GEN1_ADG] = DEFINE_RES_MEM(0xfffe0000, 0x24), +}; + +static struct rsnd_ssi_platform_info rsnd_ssi[] = { + RSND_SSI_UNUSED, /* SSI 0 */ + RSND_SSI_UNUSED, /* SSI 1 */ + RSND_SSI_UNUSED, /* SSI 2 */ + RSND_SSI(HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE), + RSND_SSI(HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE), +}; + +static struct rsnd_src_platform_info rsnd_src[9] = { + RSND_SRC_UNUSED, /* SRU 0 */ + RSND_SRC_UNUSED, /* SRU 1 */ + RSND_SRC_UNUSED, /* SRU 2 */ + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), +}; + +static struct rsnd_dai_platform_info rsnd_dai[] = { + { + .playback = { .ssi = &rsnd_ssi[5], .src = &rsnd_src[5] }, + .capture = { .ssi = &rsnd_ssi[6], .src = &rsnd_src[6] }, + }, { + .playback = { .ssi = &rsnd_ssi[3], .src = &rsnd_src[3] }, + }, { + .capture = { .ssi = &rsnd_ssi[4], .src = &rsnd_src[4] }, + }, { + .playback = { .ssi = &rsnd_ssi[7], .src = &rsnd_src[7] }, + }, { + .capture = { .ssi = &rsnd_ssi[8], .src = &rsnd_src[8] }, + }, +}; + +enum { + AK4554_34 = 0, + AK4643_56, + AK4554_78, + SOUND_MAX, +}; + +static int rsnd_codec_power(int id, int enable) +{ + static int sound_user[SOUND_MAX] = {0, 0, 0}; + int *usr = NULL; + u32 bit; + + switch (id) { + case 3: + case 4: + usr = sound_user + AK4554_34; + bit = (1 << 10); + break; + case 5: + case 6: + usr = sound_user + AK4643_56; + bit = (1 << 6); + break; + case 7: + case 8: + usr = sound_user + AK4554_78; + bit = (1 << 7); + break; + } + + if (!usr) + return -EIO; + + if (enable) { + if (*usr == 0) { + u32 val = ioread16(fpga + COMCTLR); + val &= ~bit; + iowrite16(val, fpga + COMCTLR); + } + + (*usr)++; + } else { + if (*usr == 0) + return 0; + + (*usr)--; + + if (*usr == 0) { + u32 val = ioread16(fpga + COMCTLR); + val |= bit; + iowrite16(val, fpga + COMCTLR); + } + } + + return 0; +} + +static int rsnd_start(int id) +{ + return rsnd_codec_power(id, 1); +} + +static int rsnd_stop(int id) +{ + return rsnd_codec_power(id, 0); +} + +static struct rcar_snd_info rsnd_info = { + .flags = RSND_GEN1, + .ssi_info = rsnd_ssi, + .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), + .src_info = rsnd_src, + .src_info_nr = ARRAY_SIZE(rsnd_src), + .dai_info = rsnd_dai, + .dai_info_nr = ARRAY_SIZE(rsnd_dai), + .start = rsnd_start, + .stop = rsnd_stop, +}; + +static struct asoc_simple_card_info rsnd_card_info[] = { + /* SSI5, SSI6 */ + { + .name = "AK4643", + .card = "SSI56-AK4643", + .codec = "ak4642-codec.0-0012", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM, + .cpu_dai = { + .name = "rsnd-dai.0", + }, + .codec_dai = { + .name = "ak4642-hifi", + .sysclk = 11289600, + }, + }, + /* SSI3 */ + { + .name = "AK4554", + .card = "SSI3-AK4554(playback)", + .codec = "ak4554-adc-dac.0", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_RIGHT_J, + .cpu_dai = { + .name = "rsnd-dai.1", + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI4 */ + { + .name = "AK4554", + .card = "SSI4-AK4554(capture)", + .codec = "ak4554-adc-dac.0", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_LEFT_J, + .cpu_dai = { + .name = "rsnd-dai.2", + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI7 */ + { + .name = "AK4554", + .card = "SSI7-AK4554(playback)", + .codec = "ak4554-adc-dac.1", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_RIGHT_J, + .cpu_dai = { + .name = "rsnd-dai.3", + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI8 */ + { + .name = "AK4554", + .card = "SSI8-AK4554(capture)", + .codec = "ak4554-adc-dac.1", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_LEFT_J, + .cpu_dai = { + .name = "rsnd-dai.4", + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + } +}; + static const struct pinctrl_map bockw_pinctrl_map[] = { + /* AUDIO */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "audio_clk_a", "audio_clk"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "audio_clk_b", "audio_clk"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi34_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi3_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi4_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi5_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi5_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi6_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi6_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi78_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi7_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi8_data", "ssi"), /* Ether */ PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", "ether_rmii", "ether"), @@ -163,29 +579,54 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { /* USB */ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", "usb0", "usb0"), - PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", + PIN_MAP_MUX_GROUP_DEFAULT(USB1_DEVICE, "pfc-r8a7778", "usb1", "usb1"), /* SDHI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", - "sdhi0", "sdhi0"), + "sdhi0_data4", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", + "sdhi0_ctrl", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", + "sdhi0_cd", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", + "sdhi0_wp", "sdhi0"), + /* VIN0 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778", + "vin0_clk", "vin0"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778", + "vin0_data8", "vin0"), + /* VIN1 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778", + "vin1_clk", "vin1"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778", + "vin1_data8", "vin1"), }; -#define FPGA 0x18200000 -#define IRQ0MR 0x30 #define PFC 0xfffc0000 #define PUPR4 0x110 static void __init bockw_init(void) { void __iomem *base; + struct clk *clk; + struct platform_device *pdev; + int i; r8a7778_clock_init(); r8a7778_init_irq_extpin(1); r8a7778_add_standard_devices(); - r8a7778_add_usb_phy_device(&usb_phy_platform_data); - r8a7778_add_ether_device(ðer_platform_data); - r8a7778_add_i2c_device(0); - r8a7778_add_hspi_device(0); - r8a7778_add_mmc_device(&sh_mmcif_plat); + + platform_device_register_full(ðer_info); + + platform_device_register_full(&vin0_info); + /* VIN1 has a pin conflict with Ether */ + if (!IS_ENABLED(CONFIG_SH_ETH)) + platform_device_register_full(&vin1_info); + platform_device_register_data(&platform_bus, "soc-camera-pdrv", 0, + &iclink0_ml86v7667, + sizeof(iclink0_ml86v7667)); + platform_device_register_data(&platform_bus, "soc-camera-pdrv", 1, + &iclink1_ml86v7667, + sizeof(iclink1_ml86v7667)); i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); @@ -195,9 +636,26 @@ static void __init bockw_init(void) ARRAY_SIZE(bockw_pinctrl_map)); r8a7778_pinmux_init(); + platform_device_register_resndata( + &platform_bus, "sh_mmcif", -1, + mmc_resources, ARRAY_SIZE(mmc_resources), + &sh_mmcif_plat, sizeof(struct sh_mmcif_plat_data)); + + platform_device_register_resndata( + &platform_bus, "rcar_usb_phy", -1, + usb_phy_resources, + ARRAY_SIZE(usb_phy_resources), + &usb_phy_platform_data, + sizeof(struct rcar_phy_platform_data)); + + regulator_register_fixed(0, dummy_supplies, + ARRAY_SIZE(dummy_supplies)); + regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, + ARRAY_SIZE(fixed3v3_power_consumers), 3300000); + /* for SMSC */ - base = ioremap_nocache(FPGA, SZ_1M); - if (base) { + fpga = ioremap_nocache(FPGA, SZ_1M); + if (fpga) { /* * CAUTION * @@ -205,13 +663,9 @@ static void __init bockw_init(void) * it should be cared in the future * Now, it is assuming IRQ0 was used only from SMSC. */ - u16 val = ioread16(base + IRQ0MR); + u16 val = ioread16(fpga + IRQ0MR); val &= ~(1 << 4); /* enable SMSC911x */ - iowrite16(val, base + IRQ0MR); - iounmap(base); - - regulator_register_fixed(0, dummy_supplies, - ARRAY_SIZE(dummy_supplies)); + iowrite16(val, fpga + IRQ0MR); platform_device_register_resndata( &platform_bus, "smsc911x", -1, @@ -230,10 +684,50 @@ static void __init bockw_init(void) iowrite32(ioread32(base + PUPR4) | (3 << 26), base + PUPR4); iounmap(base); - r8a7778_sdhi_init(0, &sdhi0_info); + platform_device_register_resndata( + &platform_bus, "sh_mobile_sdhi", 0, + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); + } + + /* for Audio */ + rsnd_codec_power(5, 1); /* enable ak4642 */ + + platform_device_register_simple( + "ak4554-adc-dac", 0, NULL, 0); + + platform_device_register_simple( + "ak4554-adc-dac", 1, NULL, 0); + + pdev = platform_device_register_resndata( + &platform_bus, "rcar_sound", -1, + rsnd_resources, ARRAY_SIZE(rsnd_resources), + &rsnd_info, sizeof(rsnd_info)); + + clk = clk_get(&pdev->dev, "clk_b"); + clk_set_rate(clk, 24576000); + clk_put(clk); + + for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { + struct platform_device_info cardinfo = { + .parent = &platform_bus, + .name = "asoc-simple-card", + .id = i, + .data = &rsnd_card_info[i], + .size_data = sizeof(struct asoc_simple_card_info), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&cardinfo); } } +static void __init bockw_init_late(void) +{ + r8a7778_init_late(); + ADD_USB_FUNC_DEVICE_IF_POSSIBLE(); +} + static const char *bockw_boards_compat_dt[] __initdata = { "renesas,bockw", NULL, @@ -243,7 +737,6 @@ DT_MACHINE_START(BOCKW_DT, "bockw") .init_early = r8a7778_init_delay, .init_irq = r8a7778_init_irq_dt, .init_machine = bockw_init, - .init_time = shmobile_timer_init, .dt_compat = bockw_boards_compat_dt, - .init_late = r8a7778_init_late, + .init_late = bockw_init_late, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-genmai-reference.c b/arch/arm/mach-shmobile/board-genmai-reference.c new file mode 100644 index 00000000000..2ff6ad6e608 --- /dev/null +++ b/arch/arm/mach-shmobile/board-genmai-reference.c @@ -0,0 +1,53 @@ +/* + * Genmai board support + * + * 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/kernel.h> +#include <linux/of_platform.h> +#include <mach/clock.h> +#include <mach/common.h> +#include <mach/r7s72100.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +/* + * This is a really crude hack to provide clkdev support to platform + * devices until they get moved to DT. + */ +static const struct clk_name clk_names[] = { + { "mtu2", "fck", "sh-mtu2" }, +}; + +static void __init genmai_add_standard_devices(void) +{ + shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), true); + r7s72100_add_dt_devices(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const genmai_boards_compat_dt[] __initconst = { + "renesas,genmai", + NULL, +}; + +DT_MACHINE_START(GENMAI_DT, "genmai") + .init_early = r7s72100_init_early, + .init_machine = genmai_add_standard_devices, + .dt_compat = genmai_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c new file mode 100644 index 00000000000..c94201ee859 --- /dev/null +++ b/arch/arm/mach-shmobile/board-genmai.c @@ -0,0 +1,160 @@ +/* + * Genmai board support + * + * Copyright (C) 2013-2014 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * Copyright (C) 2014 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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/kernel.h> +#include <linux/platform_device.h> +#include <linux/serial_sci.h> +#include <linux/sh_eth.h> +#include <linux/spi/rspi.h> +#include <linux/spi/spi.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r7s72100.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +/* Ether */ +static const struct sh_eth_plat_data ether_pdata __initconst = { + .phy = 0x00, /* PD60610 */ + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .phy_interface = PHY_INTERFACE_MODE_MII, + .no_ether_link = 1 +}; + +static const struct resource ether_resources[] __initconst = { + DEFINE_RES_MEM(0xe8203000, 0x800), + DEFINE_RES_MEM(0xe8204800, 0x200), + DEFINE_RES_IRQ(gic_iid(359)), +}; + +static const struct platform_device_info ether_info __initconst = { + .parent = &platform_bus, + .name = "r7s72100-ether", + .id = -1, + .res = ether_resources, + .num_res = ARRAY_SIZE(ether_resources), + .data = ðer_pdata, + .size_data = sizeof(ether_pdata), + .dma_mask = DMA_BIT_MASK(32), +}; + +/* RSPI */ +#define RSPI_RESOURCE(idx, baseaddr, irq) \ +static const struct resource rspi##idx##_resources[] __initconst = { \ + DEFINE_RES_MEM(baseaddr, 0x24), \ + DEFINE_RES_IRQ_NAMED(irq, "error"), \ + DEFINE_RES_IRQ_NAMED(irq + 1, "rx"), \ + DEFINE_RES_IRQ_NAMED(irq + 2, "tx"), \ +} + +RSPI_RESOURCE(0, 0xe800c800, gic_iid(270)); +RSPI_RESOURCE(1, 0xe800d000, gic_iid(273)); +RSPI_RESOURCE(2, 0xe800d800, gic_iid(276)); +RSPI_RESOURCE(3, 0xe800e000, gic_iid(279)); +RSPI_RESOURCE(4, 0xe800e800, gic_iid(282)); + +static const struct rspi_plat_data rspi_pdata __initconst = { + .num_chipselect = 1, +}; + +#define r7s72100_register_rspi(idx) \ + platform_device_register_resndata(&platform_bus, "rspi-rz", idx, \ + rspi##idx##_resources, \ + ARRAY_SIZE(rspi##idx##_resources), \ + &rspi_pdata, sizeof(rspi_pdata)) + +static const struct spi_board_info spi_info[] __initconst = { + { + .modalias = "wm8978", + .max_speed_hz = 5000000, + .bus_num = 4, + .chip_select = 0, + }, +}; + +/* SCIF */ +#define R7S72100_SCIF(index, baseaddr, irq) \ +static const struct plat_sci_port scif##index##_platform_data = { \ + .type = PORT_SCIF, \ + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \ + SCSCR_REIE, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq + 1), \ + DEFINE_RES_IRQ(irq + 2), \ + DEFINE_RES_IRQ(irq + 3), \ + DEFINE_RES_IRQ(irq), \ +} \ + +R7S72100_SCIF(0, 0xe8007000, gic_iid(221)); +R7S72100_SCIF(1, 0xe8007800, gic_iid(225)); +R7S72100_SCIF(2, 0xe8008000, gic_iid(229)); +R7S72100_SCIF(3, 0xe8008800, gic_iid(233)); +R7S72100_SCIF(4, 0xe8009000, gic_iid(237)); +R7S72100_SCIF(5, 0xe8009800, gic_iid(241)); +R7S72100_SCIF(6, 0xe800a000, gic_iid(245)); +R7S72100_SCIF(7, 0xe800a800, gic_iid(249)); + +#define r7s72100_register_scif(index) \ + platform_device_register_resndata(&platform_bus, "sh-sci", index, \ + scif##index##_resources, \ + ARRAY_SIZE(scif##index##_resources), \ + &scif##index##_platform_data, \ + sizeof(scif##index##_platform_data)) + +static void __init genmai_add_standard_devices(void) +{ + r7s72100_clock_init(); + r7s72100_add_dt_devices(); + + platform_device_register_full(ðer_info); + + r7s72100_register_rspi(0); + r7s72100_register_rspi(1); + r7s72100_register_rspi(2); + r7s72100_register_rspi(3); + r7s72100_register_rspi(4); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + + r7s72100_register_scif(0); + r7s72100_register_scif(1); + r7s72100_register_scif(2); + r7s72100_register_scif(3); + r7s72100_register_scif(4); + r7s72100_register_scif(5); + r7s72100_register_scif(6); + r7s72100_register_scif(7); +} + +static const char * const genmai_boards_compat_dt[] __initconst = { + "renesas,genmai", + NULL, +}; + +DT_MACHINE_START(GENMAI_DT, "genmai") + .init_early = r7s72100_init_early, + .init_machine = genmai_add_standard_devices, + .dt_compat = genmai_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c new file mode 100644 index 00000000000..d322a162b4b --- /dev/null +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -0,0 +1,132 @@ +/* + * Koelsch board support - Reference DT implementation + * + * Copyright (C) 2013 Renesas Electronics Corporation + * 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/dma-mapping.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/platform_data/rcar-du.h> +#include <mach/clock.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/rcar-gen2.h> +#include <mach/r8a7791.h> +#include <asm/mach/arch.h> + +/* DU */ +static struct rcar_du_encoder_data koelsch_du_encoders[] = { + { + .type = RCAR_DU_ENCODER_NONE, + .output = RCAR_DU_OUTPUT_LVDS0, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static struct rcar_du_platform_data koelsch_du_pdata = { + .encoders = koelsch_du_encoders, + .num_encoders = ARRAY_SIZE(koelsch_du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfeb00000, 0x40000), + DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"), + DEFINE_RES_IRQ(gic_spi(256)), + DEFINE_RES_IRQ(gic_spi(268)), +}; + +static void __init koelsch_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7791", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &koelsch_du_pdata, + .size_data = sizeof(koelsch_du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} + +/* + * This is a really crude hack to provide clkdev support to platform + * devices until they get moved to DT. + */ +static const struct clk_name clk_names[] __initconst = { + { "cmt0", "fck", "sh-cmt-48-gen2.0" }, + { "du0", "du.0", "rcar-du-r8a7791" }, + { "du1", "du.1", "rcar-du-r8a7791" }, + { "lvds0", "lvds.0", "rcar-du-r8a7791" }, +}; + +/* + * This is a really crude hack to work around core platform clock issues + */ +static const struct clk_name clk_enables[] __initconst = { + { "ether", NULL, "ee700000.ethernet" }, + { "i2c2", NULL, "e6530000.i2c" }, + { "msiof0", NULL, "e6e20000.spi" }, + { "qspi_mod", NULL, "e6b10000.spi" }, + { "sdhi0", NULL, "ee100000.sd" }, + { "sdhi1", NULL, "ee140000.sd" }, + { "sdhi2", NULL, "ee160000.sd" }, + { "thermal", NULL, "e61f0000.thermal" }, +}; + +static void __init koelsch_add_standard_devices(void) +{ + shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); + shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true); + r8a7791_add_dt_devices(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + + koelsch_add_du_device(); +} + +static const char * const koelsch_boards_compat_dt[] __initconst = { + "renesas,koelsch", + "renesas,koelsch-reference", + NULL, +}; + +DT_MACHINE_START(KOELSCH_DT, "koelsch") + .smp = smp_ops(r8a7791_smp_ops), + .init_early = shmobile_init_delay, + .init_time = rcar_gen2_timer_init, + .init_machine = koelsch_add_standard_devices, + .init_late = shmobile_init_late, + .dt_compat = koelsch_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c new file mode 100644 index 00000000000..c6c68892caa --- /dev/null +++ b/arch/arm/mach-shmobile/board-koelsch.c @@ -0,0 +1,530 @@ +/* + * Koelsch board support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013-2014 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * Copyright (C) 2014 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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/dma-mapping.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/leds.h> +#include <linux/mfd/tmio.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/phy.h> +#include <linux/pinctrl/machine.h> +#include <linux/platform_data/gpio-rcar.h> +#include <linux/platform_data/rcar-du.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/gpio-regulator.h> +#include <linux/regulator/machine.h> +#include <linux/sh_eth.h> +#include <linux/spi/flash.h> +#include <linux/spi/rspi.h> +#include <linux/spi/spi.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r8a7791.h> +#include <mach/rcar-gen2.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +/* DU */ +static struct rcar_du_encoder_data koelsch_du_encoders[] = { + { + .type = RCAR_DU_ENCODER_NONE, + .output = RCAR_DU_OUTPUT_LVDS0, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static const struct rcar_du_platform_data koelsch_du_pdata __initconst = { + .encoders = koelsch_du_encoders, + .num_encoders = ARRAY_SIZE(koelsch_du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfeb00000, 0x40000), + DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"), + DEFINE_RES_IRQ(gic_spi(256)), + DEFINE_RES_IRQ(gic_spi(268)), +}; + +static void __init koelsch_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7791", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &koelsch_du_pdata, + .size_data = sizeof(koelsch_du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} + +/* Ether */ +static const struct sh_eth_plat_data ether_pdata __initconst = { + .phy = 0x1, + .phy_irq = irq_pin(0), + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .phy_interface = PHY_INTERFACE_MODE_RMII, + .ether_link_active_low = 1, +}; + +static const struct resource ether_resources[] __initconst = { + DEFINE_RES_MEM(0xee700000, 0x400), + DEFINE_RES_IRQ(gic_spi(162)), +}; + +static const struct platform_device_info ether_info __initconst = { + .parent = &platform_bus, + .name = "r8a7791-ether", + .id = -1, + .res = ether_resources, + .num_res = ARRAY_SIZE(ether_resources), + .data = ðer_pdata, + .size_data = sizeof(ether_pdata), + .dma_mask = DMA_BIT_MASK(32), +}; + +/* LEDS */ +static struct gpio_led koelsch_leds[] = { + { + .name = "led8", + .gpio = RCAR_GP_PIN(2, 21), + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, { + .name = "led7", + .gpio = RCAR_GP_PIN(2, 20), + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, { + .name = "led6", + .gpio = RCAR_GP_PIN(2, 19), + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, +}; + +static const struct gpio_led_platform_data koelsch_leds_pdata __initconst = { + .leds = koelsch_leds, + .num_leds = ARRAY_SIZE(koelsch_leds), +}; + +/* GPIO KEY */ +#define GPIO_KEY(c, g, d, ...) \ + { .code = c, .gpio = g, .desc = d, .active_low = 1, \ + .wakeup = 1, .debounce_interval = 20 } + +static struct gpio_keys_button gpio_buttons[] = { + GPIO_KEY(KEY_4, RCAR_GP_PIN(5, 3), "SW2-pin4"), + GPIO_KEY(KEY_3, RCAR_GP_PIN(5, 2), "SW2-pin3"), + GPIO_KEY(KEY_2, RCAR_GP_PIN(5, 1), "SW2-pin2"), + GPIO_KEY(KEY_1, RCAR_GP_PIN(5, 0), "SW2-pin1"), + GPIO_KEY(KEY_G, RCAR_GP_PIN(7, 6), "SW36"), + GPIO_KEY(KEY_F, RCAR_GP_PIN(7, 5), "SW35"), + GPIO_KEY(KEY_E, RCAR_GP_PIN(7, 4), "SW34"), + GPIO_KEY(KEY_D, RCAR_GP_PIN(7, 3), "SW33"), + GPIO_KEY(KEY_C, RCAR_GP_PIN(7, 2), "SW32"), + GPIO_KEY(KEY_B, RCAR_GP_PIN(7, 1), "SW31"), + GPIO_KEY(KEY_A, RCAR_GP_PIN(7, 0), "SW30"), +}; + +static const struct gpio_keys_platform_data koelsch_keys_pdata __initconst = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +/* QSPI */ +static const struct resource qspi_resources[] __initconst = { + DEFINE_RES_MEM(0xe6b10000, 0x1000), + DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"), +}; + +static const struct rspi_plat_data qspi_pdata __initconst = { + .num_chipselect = 1, +}; + +/* SPI Flash memory (Spansion S25FL512SAGMFIG11 64 MiB) */ +static struct mtd_partition spi_flash_part[] = { + { + .name = "loader", + .offset = 0x00000000, + .size = 512 * 1024, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "bootenv", + .offset = MTDPART_OFS_APPEND, + .size = 512 * 1024, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "data", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static const struct flash_platform_data spi_flash_data = { + .name = "m25p80", + .parts = spi_flash_part, + .nr_parts = ARRAY_SIZE(spi_flash_part), + .type = "s25fl512s", +}; + +static const struct spi_board_info spi_info[] __initconst = { + { + .modalias = "m25p80", + .platform_data = &spi_flash_data, + .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD, + .max_speed_hz = 30000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/* SATA0 */ +static const struct resource sata0_resources[] __initconst = { + DEFINE_RES_MEM(0xee300000, 0x2000), + DEFINE_RES_IRQ(gic_spi(105)), +}; + +static const struct platform_device_info sata0_info __initconst = { + .parent = &platform_bus, + .name = "sata-r8a7791", + .id = 0, + .res = sata0_resources, + .num_res = ARRAY_SIZE(sata0_resources), + .dma_mask = DMA_BIT_MASK(32), +}; + +/* I2C */ +static const struct resource i2c_resources[] __initconst = { + /* I2C0 */ + DEFINE_RES_MEM(0xE6508000, 0x40), + DEFINE_RES_IRQ(gic_spi(287)), + /* I2C1 */ + DEFINE_RES_MEM(0xE6518000, 0x40), + DEFINE_RES_IRQ(gic_spi(288)), + /* I2C2 */ + DEFINE_RES_MEM(0xE6530000, 0x40), + DEFINE_RES_IRQ(gic_spi(286)), + /* I2C3 */ + DEFINE_RES_MEM(0xE6540000, 0x40), + DEFINE_RES_IRQ(gic_spi(290)), + /* I2C4 */ + DEFINE_RES_MEM(0xE6520000, 0x40), + DEFINE_RES_IRQ(gic_spi(19)), + /* I2C5 */ + DEFINE_RES_MEM(0xE6528000, 0x40), + DEFINE_RES_IRQ(gic_spi(20)), +}; + +static void __init koelsch_add_i2c(unsigned idx) +{ + unsigned res_idx = idx * 2; + + BUG_ON(res_idx >= ARRAY_SIZE(i2c_resources)); + + platform_device_register_simple("i2c-rcar_gen2", idx, + i2c_resources + res_idx, 2); +} + +#define SDHI_REGULATOR(idx, vdd_pin, vccq_pin) \ +static struct regulator_consumer_supply vcc_sdhi##idx##_consumer = \ + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi." #idx); \ + \ +static struct regulator_init_data vcc_sdhi##idx##_init_data = { \ + .constraints = { \ + .valid_ops_mask = REGULATOR_CHANGE_STATUS, \ + }, \ + .consumer_supplies = &vcc_sdhi##idx##_consumer, \ + .num_consumer_supplies = 1, \ +}; \ + \ +static const struct fixed_voltage_config vcc_sdhi##idx##_info __initconst = {\ + .supply_name = "SDHI" #idx "Vcc", \ + .microvolts = 3300000, \ + .gpio = vdd_pin, \ + .enable_high = 1, \ + .init_data = &vcc_sdhi##idx##_init_data, \ +}; \ + \ +static struct regulator_consumer_supply vccq_sdhi##idx##_consumer = \ + REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi." #idx); \ + \ +static struct regulator_init_data vccq_sdhi##idx##_init_data = { \ + .constraints = { \ + .input_uV = 3300000, \ + .min_uV = 1800000, \ + .max_uV = 3300000, \ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \ + REGULATOR_CHANGE_STATUS, \ + }, \ + .consumer_supplies = &vccq_sdhi##idx##_consumer, \ + .num_consumer_supplies = 1, \ +}; \ + \ +static struct gpio vccq_sdhi##idx##_gpio = \ + { vccq_pin, GPIOF_OUT_INIT_HIGH, "vccq-sdhi" #idx }; \ + \ +static struct gpio_regulator_state vccq_sdhi##idx##_states[] = { \ + { .value = 1800000, .gpios = 0 }, \ + { .value = 3300000, .gpios = 1 }, \ +}; \ + \ +static const struct gpio_regulator_config vccq_sdhi##idx##_info __initconst = {\ + .supply_name = "vqmmc", \ + .gpios = &vccq_sdhi##idx##_gpio, \ + .nr_gpios = 1, \ + .states = vccq_sdhi##idx##_states, \ + .nr_states = ARRAY_SIZE(vccq_sdhi##idx##_states), \ + .type = REGULATOR_VOLTAGE, \ + .init_data = &vccq_sdhi##idx##_init_data, \ +}; + +SDHI_REGULATOR(0, RCAR_GP_PIN(7, 17), RCAR_GP_PIN(2, 12)); +SDHI_REGULATOR(1, RCAR_GP_PIN(7, 18), RCAR_GP_PIN(2, 13)); +SDHI_REGULATOR(2, RCAR_GP_PIN(7, 19), RCAR_GP_PIN(2, 26)); + +/* SDHI0 */ +static struct sh_mobile_sdhi_info sdhi0_info __initdata = { + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | + MMC_CAP_POWER_OFF_CARD, + .tmio_caps2 = MMC_CAP2_NO_MULTI_READ, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, +}; + +static struct resource sdhi0_resources[] __initdata = { + DEFINE_RES_MEM(0xee100000, 0x200), + DEFINE_RES_IRQ(gic_spi(165)), +}; + +/* SDHI1 */ +static struct sh_mobile_sdhi_info sdhi1_info __initdata = { + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | + MMC_CAP_POWER_OFF_CARD, + .tmio_caps2 = MMC_CAP2_NO_MULTI_READ, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, +}; + +static struct resource sdhi1_resources[] __initdata = { + DEFINE_RES_MEM(0xee140000, 0x100), + DEFINE_RES_IRQ(gic_spi(167)), +}; + +/* SDHI2 */ +static struct sh_mobile_sdhi_info sdhi2_info __initdata = { + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | + MMC_CAP_POWER_OFF_CARD, + .tmio_caps2 = MMC_CAP2_NO_MULTI_READ, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | + TMIO_MMC_WRPROTECT_DISABLE, +}; + +static struct resource sdhi2_resources[] __initdata = { + DEFINE_RES_MEM(0xee160000, 0x100), + DEFINE_RES_IRQ(gic_spi(168)), +}; + +static const struct pinctrl_map koelsch_pinctrl_map[] = { + /* DU */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791", + "du_rgb666", "du"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791", + "du_sync", "du"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791", + "du_clk_out_0", "du"), + /* Ether */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791", + "eth_link", "eth"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791", + "eth_mdio", "eth"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791", + "eth_rmii", "eth"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791", + "intc_irq0", "intc"), + /* QSPI */ + PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7791", + "qspi_ctrl", "qspi"), + PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7791", + "qspi_data4", "qspi"), + /* SCIF0 (CN19: DEBUG SERIAL0) */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7791", + "scif0_data_d", "scif0"), + /* SCIF1 (CN20: DEBUG SERIAL1) */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7791", + "scif1_data_d", "scif1"), + /* I2C1 */ + PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.1", "pfc-r8a7791", + "i2c1_e", "i2c1"), + /* I2C2 */ + PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.2", "pfc-r8a7791", + "i2c2", "i2c2"), + /* I2C4 */ + PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.4", "pfc-r8a7791", + "i2c4_c", "i2c4"), + /* SDHI0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791", + "sdhi0_data4", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791", + "sdhi0_ctrl", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791", + "sdhi0_cd", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791", + "sdhi0_wp", "sdhi0"), + /* SDHI2 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791", + "sdhi1_data4", "sdhi1"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791", + "sdhi1_ctrl", "sdhi1"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791", + "sdhi1_cd", "sdhi1"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791", + "sdhi1_wp", "sdhi1"), + /* SDHI2 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791", + "sdhi2_data4", "sdhi2"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791", + "sdhi2_ctrl", "sdhi2"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791", + "sdhi2_cd", "sdhi2"), +}; + +static void __init koelsch_add_standard_devices(void) +{ + r8a7791_clock_init(); + pinctrl_register_mappings(koelsch_pinctrl_map, + ARRAY_SIZE(koelsch_pinctrl_map)); + r8a7791_pinmux_init(); + r8a7791_add_standard_devices(); + platform_device_register_full(ðer_info); + platform_device_register_data(&platform_bus, "leds-gpio", -1, + &koelsch_leds_pdata, + sizeof(koelsch_leds_pdata)); + platform_device_register_data(&platform_bus, "gpio-keys", -1, + &koelsch_keys_pdata, + sizeof(koelsch_keys_pdata)); + platform_device_register_resndata(&platform_bus, "qspi", 0, + qspi_resources, + ARRAY_SIZE(qspi_resources), + &qspi_pdata, sizeof(qspi_pdata)); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + + koelsch_add_du_device(); + + platform_device_register_full(&sata0_info); + + koelsch_add_i2c(1); + koelsch_add_i2c(2); + koelsch_add_i2c(4); + koelsch_add_i2c(5); + + platform_device_register_data(&platform_bus, "reg-fixed-voltage", 0, + &vcc_sdhi0_info, sizeof(struct fixed_voltage_config)); + platform_device_register_data(&platform_bus, "reg-fixed-voltage", 1, + &vcc_sdhi1_info, sizeof(struct fixed_voltage_config)); + platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2, + &vcc_sdhi2_info, sizeof(struct fixed_voltage_config)); + platform_device_register_data(&platform_bus, "gpio-regulator", 0, + &vccq_sdhi0_info, sizeof(struct gpio_regulator_config)); + platform_device_register_data(&platform_bus, "gpio-regulator", 1, + &vccq_sdhi1_info, sizeof(struct gpio_regulator_config)); + platform_device_register_data(&platform_bus, "gpio-regulator", 2, + &vccq_sdhi2_info, sizeof(struct gpio_regulator_config)); + + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0, + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); + + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1, + sdhi1_resources, ARRAY_SIZE(sdhi1_resources), + &sdhi1_info, sizeof(struct sh_mobile_sdhi_info)); + + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 2, + sdhi2_resources, ARRAY_SIZE(sdhi2_resources), + &sdhi2_info, sizeof(struct sh_mobile_sdhi_info)); + +} + +/* + * Ether LEDs on the Koelsch board are named LINK and ACTIVE which corresponds + * to non-default 01 setting of the Micrel KSZ8041 PHY control register 1 bits + * 14-15. We have to set them back to 01 from the default 00 value each time + * the PHY is reset. It's also important because the PHY's LED0 signal is + * connected to SoC's ETH_LINK signal and in the PHY's default mode it will + * bounce on and off after each packet, which we apparently want to avoid. + */ +static int koelsch_ksz8041_fixup(struct phy_device *phydev) +{ + u16 phyctrl1 = phy_read(phydev, 0x1e); + + phyctrl1 &= ~0xc000; + phyctrl1 |= 0x4000; + return phy_write(phydev, 0x1e, phyctrl1); +} + +static void __init koelsch_init(void) +{ + koelsch_add_standard_devices(); + + irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW); + + if (IS_ENABLED(CONFIG_PHYLIB)) + phy_register_fixup_for_id("r8a7791-ether-ff:01", + koelsch_ksz8041_fixup); +} + +static const char * const koelsch_boards_compat_dt[] __initconst = { + "renesas,koelsch", + NULL, +}; + +DT_MACHINE_START(KOELSCH_DT, "koelsch") + .smp = smp_ops(r8a7791_smp_ops), + .init_early = shmobile_init_delay, + .init_time = rcar_gen2_timer_init, + .init_machine = koelsch_init, + .init_late = shmobile_init_late, + .dt_compat = koelsch_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c deleted file mode 100644 index ef5ca0ef0cb..00000000000 --- a/arch/arm/mach-shmobile/board-kota2.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * kota2 board support - * - * Copyright (C) 2011 Renesas Solutions Corp. - * Copyright (C) 2011 Magnus Damm - * Copyright (C) 2010 Takashi Yoshii <yoshii.takashi.zj@renesas.com> - * Copyright (C) 2009 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 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/kernel.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/pinctrl/machine.h> -#include <linux/pinctrl/pinconf-generic.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <linux/smsc911x.h> -#include <linux/gpio.h> -#include <linux/input.h> -#include <linux/input/sh_keysc.h> -#include <linux/gpio_keys.h> -#include <linux/leds.h> -#include <linux/irqchip/arm-gic.h> -#include <linux/platform_data/leds-renesas-tpu.h> -#include <linux/mmc/host.h> -#include <linux/mmc/sh_mmcif.h> -#include <linux/mfd/tmio.h> -#include <linux/mmc/sh_mobile_sdhi.h> -#include <mach/hardware.h> -#include <mach/irqs.h> -#include <mach/sh73a0.h> -#include <mach/common.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/hardware/cache-l2x0.h> -#include <asm/traps.h> - -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - -/* SMSC 9220 */ -static struct resource smsc9220_resources[] = { - [0] = { - .start = 0x14000000, /* CS5A */ - .end = 0x140000ff, /* A1->A7 */ - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct smsc911x_platform_config smsc9220_platdata = { - .flags = SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */ - .phy_interface = PHY_INTERFACE_MODE_MII, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, -}; - -static struct platform_device eth_device = { - .name = "smsc911x", - .id = 0, - .dev = { - .platform_data = &smsc9220_platdata, - }, - .resource = smsc9220_resources, - .num_resources = ARRAY_SIZE(smsc9220_resources), -}; - -/* KEYSC */ -static struct sh_keysc_info keysc_platdata = { - .mode = SH_KEYSC_MODE_6, - .scan_timing = 3, - .delay = 100, - .keycodes = { - KEY_NUMERIC_STAR, KEY_NUMERIC_0, KEY_NUMERIC_POUND, - 0, 0, 0, 0, 0, - KEY_NUMERIC_7, KEY_NUMERIC_8, KEY_NUMERIC_9, - 0, KEY_DOWN, 0, 0, 0, - KEY_NUMERIC_4, KEY_NUMERIC_5, KEY_NUMERIC_6, - KEY_LEFT, KEY_ENTER, KEY_RIGHT, 0, 0, - KEY_NUMERIC_1, KEY_NUMERIC_2, KEY_NUMERIC_3, - 0, KEY_UP, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, -}; - -static struct resource keysc_resources[] = { - [0] = { - .name = "KEYSC", - .start = 0xe61b0000, - .end = 0xe61b0098 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(71), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device keysc_device = { - .name = "sh_keysc", - .id = 0, - .num_resources = ARRAY_SIZE(keysc_resources), - .resource = keysc_resources, - .dev = { - .platform_data = &keysc_platdata, - }, -}; - -/* GPIO KEY */ -#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } - -static struct gpio_keys_button gpio_buttons[] = { - GPIO_KEY(KEY_VOLUMEUP, 56, "+"), /* S2: VOL+ [IRQ9] */ - GPIO_KEY(KEY_VOLUMEDOWN, 54, "-"), /* S3: VOL- [IRQ10] */ - GPIO_KEY(KEY_MENU, 27, "Menu"), /* S4: MENU [IRQ30] */ - GPIO_KEY(KEY_HOMEPAGE, 26, "Home"), /* S5: HOME [IRQ31] */ - GPIO_KEY(KEY_BACK, 11, "Back"), /* S6: BACK [IRQ0] */ - GPIO_KEY(KEY_PHONE, 238, "Tel"), /* S7: TEL [IRQ11] */ - GPIO_KEY(KEY_POWER, 239, "C1"), /* S8: CAM [IRQ13] */ - GPIO_KEY(KEY_MAIL, 224, "Mail"), /* S9: MAIL [IRQ3] */ - /* Omitted button "C3?": 223 - S10: CUST [IRQ8] */ - GPIO_KEY(KEY_CAMERA, 164, "C2"), /* S11: CAM_HALF [IRQ25] */ - /* Omitted button "?": 152 - S12: CAM_FULL [No IRQ] */ -}; - -static struct gpio_keys_platform_data gpio_key_info = { - .buttons = gpio_buttons, - .nbuttons = ARRAY_SIZE(gpio_buttons), -}; - -static struct platform_device gpio_keys_device = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &gpio_key_info, - }, -}; - -/* GPIO LED */ -#define GPIO_LED(n, g) { .name = n, .gpio = g } - -static struct gpio_led gpio_leds[] = { - GPIO_LED("G", 20), /* PORT20 [GPO0] -> LED7 -> "G" */ - GPIO_LED("H", 21), /* PORT21 [GPO1] -> LED8 -> "H" */ - GPIO_LED("J", 22), /* PORT22 [GPO2] -> LED9 -> "J" */ -}; - -static struct gpio_led_platform_data gpio_leds_info = { - .leds = gpio_leds, - .num_leds = ARRAY_SIZE(gpio_leds), -}; - -static struct platform_device gpio_leds_device = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &gpio_leds_info, - }, -}; - -/* TPU LED */ -static struct led_renesas_tpu_config led_renesas_tpu12_pdata = { - .name = "V2513", - .pin_gpio_fn = GPIO_FN_TPU1TO2, - .pin_gpio = 153, - .channel_offset = 0x90, - .timer_bit = 2, - .max_brightness = 1000, -}; - -static struct resource tpu12_resources[] = { - [0] = { - .name = "TPU12", - .start = 0xe6610090, - .end = 0xe66100b5, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device leds_tpu12_device = { - .name = "leds-renesas-tpu", - .id = 12, - .dev = { - .platform_data = &led_renesas_tpu12_pdata, - }, - .num_resources = ARRAY_SIZE(tpu12_resources), - .resource = tpu12_resources, -}; - -static struct led_renesas_tpu_config led_renesas_tpu41_pdata = { - .name = "V2514", - .pin_gpio_fn = GPIO_FN_TPU4TO1, - .pin_gpio = 199, - .channel_offset = 0x50, - .timer_bit = 1, - .max_brightness = 1000, -}; - -static struct resource tpu41_resources[] = { - [0] = { - .name = "TPU41", - .start = 0xe6640050, - .end = 0xe6640075, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device leds_tpu41_device = { - .name = "leds-renesas-tpu", - .id = 41, - .dev = { - .platform_data = &led_renesas_tpu41_pdata, - }, - .num_resources = ARRAY_SIZE(tpu41_resources), - .resource = tpu41_resources, -}; - -static struct led_renesas_tpu_config led_renesas_tpu21_pdata = { - .name = "V2515", - .pin_gpio_fn = GPIO_FN_TPU2TO1, - .pin_gpio = 197, - .channel_offset = 0x50, - .timer_bit = 1, - .max_brightness = 1000, -}; - -static struct resource tpu21_resources[] = { - [0] = { - .name = "TPU21", - .start = 0xe6620050, - .end = 0xe6620075, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device leds_tpu21_device = { - .name = "leds-renesas-tpu", - .id = 21, - .dev = { - .platform_data = &led_renesas_tpu21_pdata, - }, - .num_resources = ARRAY_SIZE(tpu21_resources), - .resource = tpu21_resources, -}; - -static struct led_renesas_tpu_config led_renesas_tpu30_pdata = { - .name = "KEYLED", - .pin_gpio_fn = GPIO_FN_TPU3TO0, - .pin_gpio = 163, - .channel_offset = 0x10, - .timer_bit = 0, - .max_brightness = 1000, -}; - -static struct resource tpu30_resources[] = { - [0] = { - .name = "TPU30", - .start = 0xe6630010, - .end = 0xe6630035, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device leds_tpu30_device = { - .name = "leds-renesas-tpu", - .id = 30, - .dev = { - .platform_data = &led_renesas_tpu30_pdata, - }, - .num_resources = ARRAY_SIZE(tpu30_resources), - .resource = tpu30_resources, -}; - -/* Fixed 1.8V regulator to be used by MMCIF */ -static struct regulator_consumer_supply fixed1v8_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), -}; - -/* MMCIF */ -static struct resource mmcif_resources[] = { - [0] = { - .name = "MMCIF", - .start = 0xe6bd0000, - .end = 0xe6bd00ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(140), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = gic_spi(141), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct sh_mmcif_plat_data mmcif_info = { - .ocr = MMC_VDD_165_195, - .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, -}; - -static struct platform_device mmcif_device = { - .name = "sh_mmcif", - .id = 0, - .dev = { - .platform_data = &mmcif_info, - }, - .num_resources = ARRAY_SIZE(mmcif_resources), - .resource = mmcif_resources, -}; - -/* Fixed 3.3V regulator to be used by SDHI0 and SDHI1 */ -static struct regulator_consumer_supply fixed3v3_power_consumers[] = -{ - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), - REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), - REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), -}; - -/* SDHI0 */ -static struct sh_mobile_sdhi_info sdhi0_info = { - .tmio_caps = MMC_CAP_SD_HIGHSPEED, - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, -}; - -static struct resource sdhi0_resources[] = { - [0] = { - .name = "SDHI0", - .start = 0xee100000, - .end = 0xee1000ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(83), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = gic_spi(84), - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = gic_spi(85), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sdhi0_device = { - .name = "sh_mobile_sdhi", - .id = 0, - .num_resources = ARRAY_SIZE(sdhi0_resources), - .resource = sdhi0_resources, - .dev = { - .platform_data = &sdhi0_info, - }, -}; - -/* SDHI1 */ -static struct sh_mobile_sdhi_info sdhi1_info = { - .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, - .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, -}; - -static struct resource sdhi1_resources[] = { - [0] = { - .name = "SDHI1", - .start = 0xee120000, - .end = 0xee1200ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(87), - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = gic_spi(88), - .flags = IORESOURCE_IRQ, - }, - [3] = { - .start = gic_spi(89), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sdhi1_device = { - .name = "sh_mobile_sdhi", - .id = 1, - .num_resources = ARRAY_SIZE(sdhi1_resources), - .resource = sdhi1_resources, - .dev = { - .platform_data = &sdhi1_info, - }, -}; - -static struct platform_device *kota2_devices[] __initdata = { - ð_device, - &keysc_device, - &gpio_keys_device, - &gpio_leds_device, - &leds_tpu12_device, - &leds_tpu41_device, - &leds_tpu21_device, - &leds_tpu30_device, - &mmcif_device, - &sdhi0_device, - &sdhi1_device, -}; - -static unsigned long pin_pullup_conf[] = { - PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0), -}; - -static const struct pinctrl_map kota2_pinctrl_map[] = { - /* KEYSC */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_in8", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out04", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out5", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out6_0", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out7_0", "keysc"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_out8_0", "keysc"), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_keysc.0", "pfc-sh73a0", - "keysc_in8", pin_pullup_conf), - /* MMCIF */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "mmc0_data8_0", "mmc0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "mmc0_ctrl_0", "mmc0"), - PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "PORT279", pin_pullup_conf), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", - "mmc0_data8_0", pin_pullup_conf), - /* SCIFA2 (UART2) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-sh73a0", - "scifa2_data_0", "scifa2"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-sh73a0", - "scifa2_ctrl_0", "scifa2"), - /* SCIFA4 (UART1) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0", - "scifa4_data", "scifa4"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0", - "scifa4_ctrl", "scifa4"), - /* SCIFB (BT) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.8", "pfc-sh73a0", - "scifb_data_0", "scifb"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.8", "pfc-sh73a0", - "scifb_clk_0", "scifb"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.8", "pfc-sh73a0", - "scifb_ctrl_0", "scifb"), - /* SDHI0 (microSD) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_data4", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_ctrl", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_cd", "sdhi0"), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "sdhi0_data4", pin_pullup_conf), - PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "PORT256", pin_pullup_conf), - PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", - "PORT251", pin_pullup_conf), - /* SDHI1 (BCM4330) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "sdhi1_data4", "sdhi1"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "sdhi1_ctrl", "sdhi1"), - PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "sdhi1_data4", pin_pullup_conf), - PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mobile_sdhi.1", "pfc-sh73a0", - "PORT263", pin_pullup_conf), - /* SMSC911X */ - PIN_MAP_MUX_GROUP_DEFAULT("smsc911x.0", "pfc-sh73a0", - "bsc_data_0_7", "bsc"), - PIN_MAP_MUX_GROUP_DEFAULT("smsc911x.0", "pfc-sh73a0", - "bsc_data_8_15", "bsc"), - PIN_MAP_MUX_GROUP_DEFAULT("smsc911x.0", "pfc-sh73a0", - "bsc_cs5_a", "bsc"), - PIN_MAP_MUX_GROUP_DEFAULT("smsc911x.0", "pfc-sh73a0", - "bsc_we0", "bsc"), -}; - -static void __init kota2_init(void) -{ - regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers, - ARRAY_SIZE(fixed1v8_power_consumers), 1800000); - regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, - ARRAY_SIZE(fixed3v3_power_consumers), 3300000); - regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - pinctrl_register_mappings(kota2_pinctrl_map, - ARRAY_SIZE(kota2_pinctrl_map)); - sh73a0_pinmux_init(); - - /* SMSC911X */ - gpio_request_one(144, GPIOF_IN, NULL); /* PINTA2 */ - gpio_request_one(145, GPIOF_OUT_INIT_HIGH, NULL); /* RESET */ - - /* MMCIF */ - gpio_request_one(208, GPIOF_OUT_INIT_HIGH, NULL); /* Reset */ - -#ifdef CONFIG_CACHE_L2X0 - /* Early BRESP enable, Shared attribute override enable, 64K*8way */ - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); -#endif - sh73a0_add_standard_devices(); - platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices)); -} - -MACHINE_START(KOTA2, "kota2") - .smp = smp_ops(sh73a0_smp_ops), - .map_io = sh73a0_map_io, - .init_early = sh73a0_add_early_devices, - .nr_irqs = NR_IRQS_LEGACY, - .init_irq = sh73a0_init_irq, - .init_machine = kota2_init, - .init_late = shmobile_init_late, - .init_time = sh73a0_earlytimer_init, -MACHINE_END diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c deleted file mode 100644 index 4368000e112..00000000000 --- a/arch/arm/mach-shmobile/board-kzm9d.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * kzm9d board support - * - * Copyright (C) 2012 Renesas Solutions Corp. - * Copyright (C) 2012 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/kernel.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <linux/smsc911x.h> -#include <mach/common.h> -#include <mach/emev2.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -/* Dummy supplies, where voltage doesn't matter */ -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x"), - REGULATOR_SUPPLY("vdd33a", "smsc911x"), -}; - -/* Ether */ -static struct resource smsc911x_resources[] = { - [0] = { - .start = 0x20000000, - .end = 0x2000ffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = EMEV2_GPIO_IRQ(1), - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, - }, -}; - -static struct smsc911x_platform_config smsc911x_platdata = { - .flags = SMSC911X_USE_32BIT, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, -}; - -static struct platform_device smsc91x_device = { - .name = "smsc911x", - .id = -1, - .dev = { - .platform_data = &smsc911x_platdata, - }, - .num_resources = ARRAY_SIZE(smsc911x_resources), - .resource = smsc911x_resources, -}; - -static struct platform_device *kzm9d_devices[] __initdata = { - &smsc91x_device, -}; - -void __init kzm9d_add_standard_devices(void) -{ - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - emev2_add_standard_devices(); - - platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices)); -} - -static const char *kzm9d_boards_compat_dt[] __initdata = { - "renesas,kzm9d", - NULL, -}; - -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_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-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index 44055fe8a45..a735a1d80c2 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -21,71 +21,23 @@ */ #include <linux/delay.h> -#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> -#include <linux/pinctrl/pinconf-generic.h> #include <mach/sh73a0.h> #include <mach/common.h> #include <asm/hardware/cache-l2x0.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -static unsigned long pin_pullup_conf[] = { - PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0), -}; - -static const struct pinctrl_map kzm_pinctrl_map[] = { - PIN_MAP_MUX_GROUP_DEFAULT("e6826000.i2c", "pfc-sh73a0", - "i2c3_1", "i2c3"), - /* MMCIF */ - PIN_MAP_MUX_GROUP_DEFAULT("e6bd0000.mmcif", "pfc-sh73a0", - "mmc0_data8_0", "mmc0"), - PIN_MAP_MUX_GROUP_DEFAULT("e6bd0000.mmcif", "pfc-sh73a0", - "mmc0_ctrl_0", "mmc0"), - PIN_MAP_CONFIGS_PIN_DEFAULT("e6bd0000.mmcif", "pfc-sh73a0", - "PORT279", pin_pullup_conf), - PIN_MAP_CONFIGS_GROUP_DEFAULT("e6bd0000.mmcif", "pfc-sh73a0", - "mmc0_data8_0", pin_pullup_conf), - /* SCIFA4 */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0", - "scifa4_data", "scifa4"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0", - "scifa4_ctrl", "scifa4"), - /* SDHI0 */ - PIN_MAP_MUX_GROUP_DEFAULT("ee100000.sdhi", "pfc-sh73a0", - "sdhi0_data4", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("ee100000.sdhi", "pfc-sh73a0", - "sdhi0_ctrl", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("ee100000.sdhi", "pfc-sh73a0", - "sdhi0_cd", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("ee100000.sdhi", "pfc-sh73a0", - "sdhi0_wp", "sdhi0"), - /* SDHI2 */ - PIN_MAP_MUX_GROUP_DEFAULT("ee140000.sdhi", "pfc-sh73a0", - "sdhi2_data4", "sdhi2"), - PIN_MAP_MUX_GROUP_DEFAULT("ee140000.sdhi", "pfc-sh73a0", - "sdhi2_ctrl", "sdhi2"), -}; - static void __init kzm_init(void) { sh73a0_add_standard_devices_dt(); - pinctrl_register_mappings(kzm_pinctrl_map, ARRAY_SIZE(kzm_pinctrl_map)); - sh73a0_pinmux_init(); - - /* enable SD */ - gpio_request_one(15, GPIOF_OUT_INIT_HIGH, NULL); /* power */ - - gpio_request_one(14, GPIOF_OUT_INIT_HIGH, NULL); /* power */ #ifdef CONFIG_CACHE_L2X0 - /* Early BRESP enable, Shared attribute override enable, 64K*8way */ - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); + /* Shared attribute override enable, 64K*8way */ + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff); #endif } @@ -99,8 +51,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, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 1068120d339..f94ec8ca42c 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -54,14 +54,14 @@ /* * external GPIO */ -#define GPIO_PCF8575_BASE (GPIO_NR) -#define GPIO_PCF8575_PORT10 (GPIO_NR + 8) -#define GPIO_PCF8575_PORT11 (GPIO_NR + 9) -#define GPIO_PCF8575_PORT12 (GPIO_NR + 10) -#define GPIO_PCF8575_PORT13 (GPIO_NR + 11) -#define GPIO_PCF8575_PORT14 (GPIO_NR + 12) -#define GPIO_PCF8575_PORT15 (GPIO_NR + 13) -#define GPIO_PCF8575_PORT16 (GPIO_NR + 14) +#define GPIO_PCF8575_BASE (310) +#define GPIO_PCF8575_PORT10 (GPIO_PCF8575_BASE + 8) +#define GPIO_PCF8575_PORT11 (GPIO_PCF8575_BASE + 9) +#define GPIO_PCF8575_PORT12 (GPIO_PCF8575_BASE + 10) +#define GPIO_PCF8575_PORT13 (GPIO_PCF8575_BASE + 11) +#define GPIO_PCF8575_PORT14 (GPIO_PCF8575_BASE + 12) +#define GPIO_PCF8575_PORT15 (GPIO_PCF8575_BASE + 13) +#define GPIO_PCF8575_PORT16 (GPIO_PCF8575_BASE + 14) /* Dummy supplies, where voltage doesn't matter */ static struct regulator_consumer_supply dummy_supplies[] = { @@ -334,7 +334,7 @@ static struct platform_device lcdc_device = { .resource = lcdc_resources, .dev = { .platform_data = &lcdc_info, - .coherent_dma_mask = ~0, + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -366,6 +366,7 @@ static struct resource sh_mmcif_resources[] = { static struct sh_mmcif_plat_data sh_mmcif_platdata = { .ocr = MMC_VDD_165_195, .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .ccs_unsupported = true, .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, }; @@ -588,14 +589,12 @@ static struct asoc_simple_card_info fsi2_ak4648_info = { .card = "FSI2A-AK4648", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi2", - .daifmt = SND_SOC_DAIFMT_LEFT_J, + .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { .name = "fsia-dai", - .fmt = SND_SOC_DAIFMT_CBS_CFS, }, .codec_dai = { .name = "ak4642-hifi", - .fmt = SND_SOC_DAIFMT_CBM_CFM, .sysclk = 11289600, }, }; @@ -877,8 +876,8 @@ static void __init kzm_init(void) gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */ #ifdef CONFIG_CACHE_L2X0 - /* Early BRESP enable, Shared attribute override enable, 64K*8way */ - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); + /* Shared attribute override enable, 64K*8way */ + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff); #endif i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c new file mode 100644 index 00000000000..749832e3f33 --- /dev/null +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -0,0 +1,137 @@ +/* + * Lager board support - Reference DT implementation + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Simon Horman + * + * 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/dma-mapping.h> +#include <linux/init.h> +#include <linux/of_platform.h> +#include <linux/platform_data/rcar-du.h> +#include <mach/clock.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/rcar-gen2.h> +#include <mach/r8a7790.h> +#include <asm/mach/arch.h> + +/* DU */ +static struct rcar_du_encoder_data lager_du_encoders[] = { + { + .type = RCAR_DU_ENCODER_VGA, + .output = RCAR_DU_OUTPUT_DPAD0, + }, { + .type = RCAR_DU_ENCODER_NONE, + .output = RCAR_DU_OUTPUT_LVDS1, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static struct rcar_du_platform_data lager_du_pdata = { + .encoders = lager_du_encoders, + .num_encoders = ARRAY_SIZE(lager_du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfeb00000, 0x70000), + DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"), + DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"), + DEFINE_RES_IRQ(gic_spi(256)), + DEFINE_RES_IRQ(gic_spi(268)), + DEFINE_RES_IRQ(gic_spi(269)), +}; + +static void __init lager_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7790", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &lager_du_pdata, + .size_data = sizeof(lager_du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} + +/* + * This is a really crude hack to provide clkdev support to platform + * devices until they get moved to DT. + */ +static const struct clk_name clk_names[] __initconst = { + { "cmt0", "fck", "sh-cmt-48-gen2.0" }, + { "du0", "du.0", "rcar-du-r8a7790" }, + { "du1", "du.1", "rcar-du-r8a7790" }, + { "du2", "du.2", "rcar-du-r8a7790" }, + { "lvds0", "lvds.0", "rcar-du-r8a7790" }, + { "lvds1", "lvds.1", "rcar-du-r8a7790" }, +}; + +/* + * This is a really crude hack to work around core platform clock issues + */ +static const struct clk_name clk_enables[] __initconst = { + { "ether", NULL, "ee700000.ethernet" }, + { "msiof1", NULL, "e6e10000.spi" }, + { "mmcif1", NULL, "ee220000.mmc" }, + { "qspi_mod", NULL, "e6b10000.spi" }, + { "sdhi0", NULL, "ee100000.sd" }, + { "sdhi2", NULL, "ee140000.sd" }, + { "thermal", NULL, "e61f0000.thermal" }, +}; + +static void __init lager_add_standard_devices(void) +{ + shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); + shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true); + r8a7790_add_dt_devices(); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + + lager_add_du_device(); +} + +static const char *lager_boards_compat_dt[] __initdata = { + "renesas,lager", + "renesas,lager-reference", + NULL, +}; + +DT_MACHINE_START(LAGER_DT, "lager") + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, + .init_machine = lager_add_standard_devices, + .init_late = shmobile_init_late, + .dt_compat = lager_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index d73e21d3ea8..f8b1e05463c 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -1,8 +1,9 @@ /* * Lager board support * - * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013-2014 Renesas Solutions Corp. * Copyright (C) 2013 Magnus Damm + * Copyright (C) 2014 Cogent Embedded, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,18 +21,124 @@ #include <linux/gpio.h> #include <linux/gpio_keys.h> +#include <linux/i2c.h> #include <linux/input.h> #include <linux/interrupt.h> -#include <linux/irqchip.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/leds.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_data/camera-rcar.h> #include <linux/platform_data/gpio-rcar.h> +#include <linux/platform_data/rcar-du.h> +#include <linux/platform_data/usb-rcar-gen2-phy.h> #include <linux/platform_device.h> +#include <linux/phy.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/gpio-regulator.h> +#include <linux/regulator/machine.h> +#include <linux/sh_eth.h> +#include <linux/usb/phy.h> +#include <linux/usb/renesas_usbhs.h> #include <mach/common.h> +#include <mach/irqs.h> #include <mach/r8a7790.h> +#include <media/soc_camera.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/mtd.h> +#include <linux/spi/flash.h> +#include <linux/spi/rspi.h> +#include <linux/spi/spi.h> +#include <sound/rcar_snd.h> +#include <sound/simple_card.h> + +/* + * SSI-AK4643 + * + * SW1: 1: AK4643 + * 2: CN22 + * 3: ADV7511 + * + * this command is required when playback. + * + * # amixer set "LINEOUT Mixer DACL" on + */ + +/* + * SDHI0 (CN8) + * + * JP3: pin1 + * SW20: pin1 + + * GP5_24: 1: VDD 3.3V (defult) + * 0: VDD 0.0V + * GP5_29: 1: VccQ 3.3V (defult) + * 0: VccQ 1.8V + * + */ + +/* DU */ +static struct rcar_du_encoder_data lager_du_encoders[] = { + { + .type = RCAR_DU_ENCODER_VGA, + .output = RCAR_DU_OUTPUT_DPAD0, + }, { + .type = RCAR_DU_ENCODER_NONE, + .output = RCAR_DU_OUTPUT_LVDS1, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static const struct rcar_du_platform_data lager_du_pdata __initconst = { + .encoders = lager_du_encoders, + .num_encoders = ARRAY_SIZE(lager_du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfeb00000, 0x70000), + DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"), + DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"), + DEFINE_RES_IRQ(gic_spi(256)), + DEFINE_RES_IRQ(gic_spi(268)), + DEFINE_RES_IRQ(gic_spi(269)), +}; + +static void __init lager_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7790", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &lager_du_pdata, + .size_data = sizeof(lager_du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} /* LEDS */ static struct gpio_led lager_leds[] = { @@ -50,38 +157,637 @@ static struct gpio_led lager_leds[] = { }, }; -static __initdata struct gpio_led_platform_data lager_leds_pdata = { +static const struct gpio_led_platform_data lager_leds_pdata __initconst = { .leds = lager_leds, .num_leds = ARRAY_SIZE(lager_leds), }; /* GPIO KEY */ #define GPIO_KEY(c, g, d, ...) \ - { .code = c, .gpio = g, .desc = d, .active_low = 1 } + { .code = c, .gpio = g, .desc = d, .active_low = 1, \ + .wakeup = 1, .debounce_interval = 20 } -static __initdata struct gpio_keys_button gpio_buttons[] = { +static struct gpio_keys_button gpio_buttons[] = { GPIO_KEY(KEY_4, RCAR_GP_PIN(1, 28), "SW2-pin4"), GPIO_KEY(KEY_3, RCAR_GP_PIN(1, 26), "SW2-pin3"), GPIO_KEY(KEY_2, RCAR_GP_PIN(1, 24), "SW2-pin2"), GPIO_KEY(KEY_1, RCAR_GP_PIN(1, 14), "SW2-pin1"), }; -static __initdata struct gpio_keys_platform_data lager_keys_pdata = { +static const struct gpio_keys_platform_data lager_keys_pdata __initconst = { .buttons = gpio_buttons, .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"), +}; + +/* + * SDHI regulator macro + * + ** FIXME** + * Lager board vqmmc is provided via DA9063 PMIC chip, + * and we should use ${LINK}/drivers/mfd/da9063-* driver for it. + * but, it doesn't have regulator support at this point. + * It uses gpio-regulator for vqmmc as quick-hack. + */ +#define SDHI_REGULATOR(idx, vdd_pin, vccq_pin) \ +static struct regulator_consumer_supply vcc_sdhi##idx##_consumer = \ + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi." #idx); \ + \ +static struct regulator_init_data vcc_sdhi##idx##_init_data = { \ + .constraints = { \ + .valid_ops_mask = REGULATOR_CHANGE_STATUS, \ + }, \ + .consumer_supplies = &vcc_sdhi##idx##_consumer, \ + .num_consumer_supplies = 1, \ +}; \ + \ +static const struct fixed_voltage_config vcc_sdhi##idx##_info __initconst = {\ + .supply_name = "SDHI" #idx "Vcc", \ + .microvolts = 3300000, \ + .gpio = vdd_pin, \ + .enable_high = 1, \ + .init_data = &vcc_sdhi##idx##_init_data, \ +}; \ + \ +static struct regulator_consumer_supply vccq_sdhi##idx##_consumer = \ + REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi." #idx); \ + \ +static struct regulator_init_data vccq_sdhi##idx##_init_data = { \ + .constraints = { \ + .input_uV = 3300000, \ + .min_uV = 1800000, \ + .max_uV = 3300000, \ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \ + REGULATOR_CHANGE_STATUS, \ + }, \ + .consumer_supplies = &vccq_sdhi##idx##_consumer, \ + .num_consumer_supplies = 1, \ +}; \ + \ +static struct gpio vccq_sdhi##idx##_gpio = \ + { vccq_pin, GPIOF_OUT_INIT_HIGH, "vccq-sdhi" #idx }; \ + \ +static struct gpio_regulator_state vccq_sdhi##idx##_states[] = { \ + { .value = 1800000, .gpios = 0 }, \ + { .value = 3300000, .gpios = 1 }, \ +}; \ + \ +static const struct gpio_regulator_config vccq_sdhi##idx##_info __initconst = {\ + .supply_name = "vqmmc", \ + .gpios = &vccq_sdhi##idx##_gpio, \ + .nr_gpios = 1, \ + .states = vccq_sdhi##idx##_states, \ + .nr_states = ARRAY_SIZE(vccq_sdhi##idx##_states), \ + .type = REGULATOR_VOLTAGE, \ + .init_data = &vccq_sdhi##idx##_init_data, \ +}; + +SDHI_REGULATOR(0, RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 29)); +SDHI_REGULATOR(2, RCAR_GP_PIN(5, 25), RCAR_GP_PIN(5, 30)); + +/* MMCIF */ +static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .clk_ctrl2_present = true, + .ccs_unsupported = true, +}; + +static const struct resource mmcif1_resources[] __initconst = { + DEFINE_RES_MEM(0xee220000, 0x80), + DEFINE_RES_IRQ(gic_spi(170)), +}; + +/* Ether */ +static const struct sh_eth_plat_data ether_pdata __initconst = { + .phy = 0x1, + .phy_irq = irq_pin(0), + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .phy_interface = PHY_INTERFACE_MODE_RMII, + .ether_link_active_low = 1, +}; + +static const struct resource ether_resources[] __initconst = { + DEFINE_RES_MEM(0xee700000, 0x400), + DEFINE_RES_IRQ(gic_spi(162)), +}; + +static const struct platform_device_info ether_info __initconst = { + .parent = &platform_bus, + .name = "r8a7790-ether", + .id = -1, + .res = ether_resources, + .num_res = ARRAY_SIZE(ether_resources), + .data = ðer_pdata, + .size_data = sizeof(ether_pdata), + .dma_mask = DMA_BIT_MASK(32), +}; + +/* SPI Flash memory (Spansion S25FL512SAGMFIG11 64Mb) */ +static struct mtd_partition spi_flash_part[] = { + /* Reserved for user loader program, read-only */ + { + .name = "loader", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, + }, + /* Reserved for user program, read-only */ + { + .name = "user", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + .mask_flags = MTD_WRITEABLE, + }, + /* All else is writable (e.g. JFFS2) */ + { + .name = "flash", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static const struct flash_platform_data spi_flash_data = { + .name = "m25p80", + .parts = spi_flash_part, + .nr_parts = ARRAY_SIZE(spi_flash_part), + .type = "s25fl512s", +}; + +static const struct rspi_plat_data qspi_pdata __initconst = { + .num_chipselect = 1, +}; + +static const struct spi_board_info spi_info[] __initconst = { + { + .modalias = "m25p80", + .platform_data = &spi_flash_data, + .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD, + .max_speed_hz = 30000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/* QSPI resource */ +static const struct resource qspi_resources[] __initconst = { + DEFINE_RES_MEM(0xe6b10000, 0x1000), + DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"), +}; + +/* VIN */ +static const struct resource vin_resources[] __initconst = { + /* VIN0 */ + DEFINE_RES_MEM(0xe6ef0000, 0x1000), + DEFINE_RES_IRQ(gic_spi(188)), + /* VIN1 */ + DEFINE_RES_MEM(0xe6ef1000, 0x1000), + DEFINE_RES_IRQ(gic_spi(189)), +}; + +static void __init lager_add_vin_device(unsigned idx, + struct rcar_vin_platform_data *pdata) +{ + struct platform_device_info vin_info = { + .parent = &platform_bus, + .name = "r8a7790-vin", + .id = idx, + .res = &vin_resources[idx * 2], + .num_res = 2, + .dma_mask = DMA_BIT_MASK(32), + .data = pdata, + .size_data = sizeof(*pdata), + }; + + BUG_ON(idx > 1); + + platform_device_register_full(&vin_info); +} + +#define LAGER_CAMERA(idx, name, addr, pdata, flag) \ +static struct i2c_board_info i2c_cam##idx##_device = { \ + I2C_BOARD_INFO(name, addr), \ +}; \ + \ +static struct rcar_vin_platform_data vin##idx##_pdata = { \ + .flags = flag, \ +}; \ + \ +static struct soc_camera_link cam##idx##_link = { \ + .bus_id = idx, \ + .board_info = &i2c_cam##idx##_device, \ + .i2c_adapter_id = 2, \ + .module_name = name, \ + .priv = pdata, \ +} + +/* Camera 0 is not currently supported due to adv7612 support missing */ +LAGER_CAMERA(1, "adv7180", 0x20, NULL, RCAR_VIN_BT656); + +static void __init lager_add_camera1_device(void) +{ + platform_device_register_data(&platform_bus, "soc-camera-pdrv", 1, + &cam1_link, sizeof(cam1_link)); + lager_add_vin_device(1, &vin1_pdata); +} + +/* SATA1 */ +static const struct resource sata1_resources[] __initconst = { + DEFINE_RES_MEM(0xee500000, 0x2000), + DEFINE_RES_IRQ(gic_spi(106)), +}; + +static const struct platform_device_info sata1_info __initconst = { + .parent = &platform_bus, + .name = "sata-r8a7790", + .id = 1, + .res = sata1_resources, + .num_res = ARRAY_SIZE(sata1_resources), + .dma_mask = DMA_BIT_MASK(32), +}; + +/* USBHS */ +static const struct resource usbhs_resources[] __initconst = { + DEFINE_RES_MEM(0xe6590000, 0x100), + DEFINE_RES_IRQ(gic_spi(107)), +}; + +struct usbhs_private { + struct renesas_usbhs_platform_info info; + struct usb_phy *phy; +}; + +#define usbhs_get_priv(pdev) \ + container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info) + +static int usbhs_power_ctrl(struct platform_device *pdev, + void __iomem *base, int enable) +{ + struct usbhs_private *priv = usbhs_get_priv(pdev); + + if (!priv->phy) + return -ENODEV; + + if (enable) { + int retval = usb_phy_init(priv->phy); + + if (!retval) + retval = usb_phy_set_suspend(priv->phy, 0); + return retval; + } + + usb_phy_set_suspend(priv->phy, 1); + usb_phy_shutdown(priv->phy); + return 0; +} + +static int usbhs_hardware_init(struct platform_device *pdev) +{ + struct usbhs_private *priv = usbhs_get_priv(pdev); + struct usb_phy *phy; + int ret; + + /* USB0 Function - use PWEN as GPIO input to detect DIP Switch SW5 + * setting to avoid VBUS short circuit due to wrong cable. + * PWEN should be pulled up high if USB Function is selected by SW5 + */ + gpio_request_one(RCAR_GP_PIN(5, 18), GPIOF_IN, NULL); /* USB0_PWEN */ + if (!gpio_get_value(RCAR_GP_PIN(5, 18))) { + pr_warn("Error: USB Function not selected - check SW5 + SW6\n"); + ret = -ENOTSUPP; + goto error; + } + + phy = usb_get_phy_dev(&pdev->dev, 0); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + goto error; + } + + priv->phy = phy; + return 0; + error: + gpio_free(RCAR_GP_PIN(5, 18)); + return ret; +} + +static int usbhs_hardware_exit(struct platform_device *pdev) +{ + struct usbhs_private *priv = usbhs_get_priv(pdev); + + if (!priv->phy) + return 0; + + usb_put_phy(priv->phy); + priv->phy = NULL; + + gpio_free(RCAR_GP_PIN(5, 18)); + return 0; +} + +static int usbhs_get_id(struct platform_device *pdev) +{ + return USBHS_GADGET; +} + +static u32 lager_usbhs_pipe_type[] = { + USB_ENDPOINT_XFER_CONTROL, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, +}; + +static struct usbhs_private usbhs_priv __initdata = { + .info = { + .platform_callback = { + .power_ctrl = usbhs_power_ctrl, + .hardware_init = usbhs_hardware_init, + .hardware_exit = usbhs_hardware_exit, + .get_id = usbhs_get_id, + }, + .driver_param = { + .buswait_bwait = 4, + .pipe_type = lager_usbhs_pipe_type, + .pipe_size = ARRAY_SIZE(lager_usbhs_pipe_type), + }, + } +}; + +static void __init lager_register_usbhs(void) +{ + usb_bind_phy("renesas_usbhs", 0, "usb_phy_rcar_gen2"); + platform_device_register_resndata(&platform_bus, + "renesas_usbhs", -1, + usbhs_resources, + ARRAY_SIZE(usbhs_resources), + &usbhs_priv.info, + sizeof(usbhs_priv.info)); +} + +/* USBHS PHY */ +static const struct rcar_gen2_phy_platform_data usbhs_phy_pdata __initconst = { + .chan0_pci = 0, /* Channel 0 is USBHS */ + .chan2_pci = 1, /* Channel 2 is PCI USB */ +}; + +static const struct resource usbhs_phy_resources[] __initconst = { + DEFINE_RES_MEM(0xe6590100, 0x100), +}; + +/* I2C */ +static struct i2c_board_info i2c2_devices[] = { + { + I2C_BOARD_INFO("ak4643", 0x12), + } +}; + +/* Sound */ +static struct resource rsnd_resources[] __initdata = { + [RSND_GEN2_SCU] = DEFINE_RES_MEM(0xec500000, 0x1000), + [RSND_GEN2_ADG] = DEFINE_RES_MEM(0xec5a0000, 0x100), + [RSND_GEN2_SSIU] = DEFINE_RES_MEM(0xec540000, 0x1000), + [RSND_GEN2_SSI] = DEFINE_RES_MEM(0xec541000, 0x1280), +}; + +static struct rsnd_ssi_platform_info rsnd_ssi[] = { + RSND_SSI(0, gic_spi(370), 0), + RSND_SSI(0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE), +}; + +static struct rsnd_src_platform_info rsnd_src[2] = { + /* no member at this point */ +}; + +static struct rsnd_dai_platform_info rsnd_dai = { + .playback = { .ssi = &rsnd_ssi[0], }, + .capture = { .ssi = &rsnd_ssi[1], }, +}; + +static struct rcar_snd_info rsnd_info = { + .flags = RSND_GEN2, + .ssi_info = rsnd_ssi, + .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), + .src_info = rsnd_src, + .src_info_nr = ARRAY_SIZE(rsnd_src), + .dai_info = &rsnd_dai, + .dai_info_nr = 1, +}; + +static struct asoc_simple_card_info rsnd_card_info = { + .name = "AK4643", + .card = "SSI01-AK4643", + .codec = "ak4642-codec.2-0012", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM, + .cpu_dai = { + .name = "rcar_sound", + }, + .codec_dai = { + .name = "ak4642-hifi", + .sysclk = 11289600, + }, +}; + +static void __init lager_add_rsnd_device(void) +{ + struct platform_device_info cardinfo = { + .parent = &platform_bus, + .name = "asoc-simple-card", + .id = -1, + .data = &rsnd_card_info, + .size_data = sizeof(struct asoc_simple_card_info), + .dma_mask = DMA_BIT_MASK(32), + }; + + i2c_register_board_info(2, i2c2_devices, + ARRAY_SIZE(i2c2_devices)); + + platform_device_register_resndata( + &platform_bus, "rcar_sound", -1, + rsnd_resources, ARRAY_SIZE(rsnd_resources), + &rsnd_info, sizeof(rsnd_info)); + + platform_device_register_full(&cardinfo); +} + +/* SDHI0 */ +static struct sh_mobile_sdhi_info sdhi0_info __initdata = { + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | + MMC_CAP_POWER_OFF_CARD, + .tmio_caps2 = MMC_CAP2_NO_MULTI_READ, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | + TMIO_MMC_WRPROTECT_DISABLE, +}; + +static struct resource sdhi0_resources[] __initdata = { + DEFINE_RES_MEM(0xee100000, 0x200), + DEFINE_RES_IRQ(gic_spi(165)), +}; + +/* SDHI2 */ +static struct sh_mobile_sdhi_info sdhi2_info __initdata = { + .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | + MMC_CAP_POWER_OFF_CARD, + .tmio_caps2 = MMC_CAP2_NO_MULTI_READ, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | + TMIO_MMC_WRPROTECT_DISABLE, +}; + +static struct resource sdhi2_resources[] __initdata = { + DEFINE_RES_MEM(0xee140000, 0x100), + DEFINE_RES_IRQ(gic_spi(167)), +}; + +/* Internal PCI1 */ +static const struct resource pci1_resources[] __initconst = { + DEFINE_RES_MEM(0xee0b0000, 0x10000), /* CFG */ + DEFINE_RES_MEM(0xee0a0000, 0x10000), /* MEM */ + DEFINE_RES_IRQ(gic_spi(112)), +}; + +static const struct platform_device_info pci1_info __initconst = { + .parent = &platform_bus, + .name = "pci-rcar-gen2", + .id = 1, + .res = pci1_resources, + .num_res = ARRAY_SIZE(pci1_resources), + .dma_mask = DMA_BIT_MASK(32), +}; + +static void __init lager_add_usb1_device(void) +{ + platform_device_register_full(&pci1_info); +} + +/* Internal PCI2 */ +static const struct resource pci2_resources[] __initconst = { + DEFINE_RES_MEM(0xee0d0000, 0x10000), /* CFG */ + DEFINE_RES_MEM(0xee0c0000, 0x10000), /* MEM */ + DEFINE_RES_IRQ(gic_spi(113)), +}; + +static const struct platform_device_info pci2_info __initconst = { + .parent = &platform_bus, + .name = "pci-rcar-gen2", + .id = 2, + .res = pci2_resources, + .num_res = ARRAY_SIZE(pci2_resources), + .dma_mask = DMA_BIT_MASK(32), +}; + +static void __init lager_add_usb2_device(void) +{ + platform_device_register_full(&pci2_info); +} + static const struct pinctrl_map lager_pinctrl_map[] = { + /* DU (CN10: ARGB0, CN13: LVDS) */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", + "du_rgb666", "du"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", + "du_sync_1", "du"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", + "du_clk_out_0", "du"), + /* I2C2 */ + PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar.2", "pfc-r8a7790", + "i2c2", "i2c2"), + /* QSPI */ + PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790", + "qspi_ctrl", "qspi"), + PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790", + "qspi_data4", "qspi"), /* 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"), + /* SDHI0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790", + "sdhi0_data4", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790", + "sdhi0_ctrl", "sdhi0"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790", + "sdhi0_cd", "sdhi0"), + /* SDHI2 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790", + "sdhi2_data4", "sdhi2"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790", + "sdhi2_ctrl", "sdhi2"), + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790", + "sdhi2_cd", "sdhi2"), + /* SSI (CN17: sound) */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790", + "ssi0129_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790", + "ssi0_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790", + "ssi1_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790", + "audio_clk_a", "audio_clk"), + /* 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"), + /* Ether */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790", + "eth_link", "eth"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790", + "eth_mdio", "eth"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790", + "eth_rmii", "eth"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790", + "intc_irq0", "intc"), + /* VIN0 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790", + "vin0_data24", "vin0"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790", + "vin0_sync", "vin0"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790", + "vin0_field", "vin0"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790", + "vin0_clkenb", "vin0"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790", + "vin0_clk", "vin0"), + /* VIN1 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790", + "vin1_data8", "vin1"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790", + "vin1_clk", "vin1"), + /* USB0 */ + PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7790", + "usb0_ovc_vbus", "usb0"), + /* USB1 */ + PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.1", "pfc-r8a7790", + "usb1", "usb1"), + /* USB2 */ + PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.2", "pfc-r8a7790", + "usb2", "usb2"), }; static void __init lager_add_standard_devices(void) { + int fixed_regulator_idx = 0; + int gpio_regulator_idx = 0; + r8a7790_clock_init(); pinctrl_register_mappings(lager_pinctrl_map, @@ -95,16 +801,94 @@ 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(fixed_regulator_idx++, + "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)); + + platform_device_register_full(ðer_info); + + lager_add_du_device(); + + platform_device_register_resndata(&platform_bus, "qspi", 0, + qspi_resources, + ARRAY_SIZE(qspi_resources), + &qspi_pdata, sizeof(qspi_pdata)); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + + platform_device_register_data(&platform_bus, "reg-fixed-voltage", fixed_regulator_idx++, + &vcc_sdhi0_info, sizeof(struct fixed_voltage_config)); + platform_device_register_data(&platform_bus, "reg-fixed-voltage", fixed_regulator_idx++, + &vcc_sdhi2_info, sizeof(struct fixed_voltage_config)); + + platform_device_register_data(&platform_bus, "gpio-regulator", gpio_regulator_idx++, + &vccq_sdhi0_info, sizeof(struct gpio_regulator_config)); + platform_device_register_data(&platform_bus, "gpio-regulator", gpio_regulator_idx++, + &vccq_sdhi2_info, sizeof(struct gpio_regulator_config)); + + lager_add_camera1_device(); + + platform_device_register_full(&sata1_info); + + platform_device_register_resndata(&platform_bus, "usb_phy_rcar_gen2", + -1, usbhs_phy_resources, + ARRAY_SIZE(usbhs_phy_resources), + &usbhs_phy_pdata, + sizeof(usbhs_phy_pdata)); + lager_register_usbhs(); + lager_add_usb1_device(); + lager_add_usb2_device(); + + lager_add_rsnd_device(); + + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0, + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 2, + sdhi2_resources, ARRAY_SIZE(sdhi2_resources), + &sdhi2_info, sizeof(struct sh_mobile_sdhi_info)); +} + +/* + * Ether LEDs on the Lager board are named LINK and ACTIVE which corresponds + * to non-default 01 setting of the Micrel KSZ8041 PHY control register 1 bits + * 14-15. We have to set them back to 01 from the default 00 value each time + * the PHY is reset. It's also important because the PHY's LED0 signal is + * connected to SoC's ETH_LINK signal and in the PHY's default mode it will + * bounce on and off after each packet, which we apparently want to avoid. + */ +static int lager_ksz8041_fixup(struct phy_device *phydev) +{ + u16 phyctrl1 = phy_read(phydev, 0x1e); + + phyctrl1 &= ~0xc000; + phyctrl1 |= 0x4000; + return phy_write(phydev, 0x1e, phyctrl1); +} + +static void __init lager_init(void) +{ + lager_add_standard_devices(); + + irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW); + + if (IS_ENABLED(CONFIG_PHYLIB)) + phy_register_fixup_for_id("r8a7790-ether-ff:01", + lager_ksz8041_fixup); } -static const char *lager_boards_compat_dt[] __initdata = { +static const char * const lager_boards_compat_dt[] __initconst = { "renesas,lager", NULL, }; DT_MACHINE_START(LAGER_DT, "lager") - .init_irq = irqchip_init, - .init_time = r8a7790_timer_init, - .init_machine = lager_add_standard_devices, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, + .init_machine = lager_init, + .init_late = shmobile_init_late, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 85f51a849a5..0ff4d8e45cf 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -41,6 +41,8 @@ #include <linux/mtd/physmap.h> #include <linux/mtd/sh_flctl.h> #include <linux/pinctrl/machine.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/platform_data/gpio_backlight.h> #include <linux/pm_clock.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> @@ -49,7 +51,6 @@ #include <linux/tca6416_keypad.h> #include <linux/usb/renesas_usbhs.h> #include <linux/dma-mapping.h> - #include <video/sh_mobile_hdmi.h> #include <video/sh_mobile_lcdc.h> #include <media/sh_mobile_ceu.h> @@ -346,7 +347,7 @@ static struct platform_device meram_device = { }, }; -/* LCDC */ +/* LCDC and backlight */ static struct fb_videomode mackerel_lcdc_modes[] = { { .name = "WVGA Panel", @@ -362,13 +363,6 @@ static struct fb_videomode mackerel_lcdc_modes[] = { }, }; -static int mackerel_set_brightness(int brightness) -{ - gpio_set_value(31, brightness); - - return 0; -} - static const struct sh_mobile_meram_cfg lcd_meram_cfg = { .icb[0] = { .meram_size = 0x40, @@ -393,11 +387,6 @@ static struct sh_mobile_lcdc_info lcdc_info = { .width = 152, .height = 91, }, - .bl_info = { - .name = "sh_mobile_lcdc_bl", - .max_brightness = 1, - .set_brightness = mackerel_set_brightness, - }, .meram_cfg = &lcd_meram_cfg, } }; @@ -421,7 +410,21 @@ static struct platform_device lcdc_device = { .resource = lcdc_resources, .dev = { .platform_data = &lcdc_info, - .coherent_dma_mask = ~0, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct gpio_backlight_platform_data gpio_backlight_data = { + .fbdev = &lcdc_device.dev, + .gpio = 31, + .def_value = 1, + .name = "backlight", +}; + +static struct platform_device gpio_backlight_device = { + .name = "gpio-backlight", + .dev = { + .platform_data = &gpio_backlight_data, }, }; @@ -497,7 +500,7 @@ static struct platform_device hdmi_lcdc_device = { .id = 1, .dev = { .platform_data = &hdmi_lcdc_info, - .coherent_dma_mask = ~0, + .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -506,9 +509,9 @@ static struct asoc_simple_card_info fsi2_hdmi_info = { .card = "FSI2B-HDMI", .codec = "sh-mobile-hdmi", .platform = "sh_fsi2", + .daifmt = SND_SOC_DAIFMT_CBS_CFS, .cpu_dai = { .name = "fsib-dai", - .fmt = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF, }, .codec_dai = { .name = "sh_mobile_hdmi-hifi", @@ -546,9 +549,9 @@ static void __init hdmi_init_pm_clock(void) clk_get_rate(&sh7372_pllc2_clk)); rate = clk_round_rate(&sh7372_pllc2_clk, 594000000); - if (rate < 0) { + if (rate <= 0) { pr_err("Cannot get suitable rate: %ld\n", rate); - ret = rate; + ret = -EINVAL; goto out; } @@ -902,14 +905,12 @@ static struct asoc_simple_card_info fsi2_ak4643_info = { .card = "FSI2A-AK4643", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi2", - .daifmt = SND_SOC_DAIFMT_LEFT_J, + .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { .name = "fsia-dai", - .fmt = SND_SOC_DAIFMT_CBS_CFS, }, .codec_dai = { .name = "ak4642-hifi", - .fmt = SND_SOC_DAIFMT_CBM_CFM, .sysclk = 11289600, }, }; @@ -1231,6 +1232,7 @@ static struct platform_device *mackerel_devices[] __initdata = { &nor_flash_device, &smc911x_device, &lcdc_device, + &gpio_backlight_device, &usbhs0_device, &usbhs1_device, &leds_device, @@ -1308,6 +1310,10 @@ static struct i2c_board_info i2c1_devices[] = { }, }; +static unsigned long pin_pulldown_conf[] = { + PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0), +}; + static const struct pinctrl_map mackerel_pinctrl_map[] = { /* ADXL34X */ PIN_MAP_MUX_GROUP_DEFAULT("1-0053", "pfc-sh7372", @@ -1393,17 +1399,19 @@ static const struct pinctrl_map mackerel_pinctrl_map[] = { /* USBHS0 */ PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.0", "pfc-sh7372", "usb0_vbus", "usb0"), + PIN_MAP_CONFIGS_GROUP_DEFAULT("renesas_usbhs.0", "pfc-sh7372", + "usb0_vbus", pin_pulldown_conf), /* USBHS1 */ PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372", "usb1_vbus", "usb1"), + PIN_MAP_CONFIGS_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372", + "usb1_vbus", pin_pulldown_conf), PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372", "usb1_otg_id_0", "usb1"), }; #define GPIO_PORT9CR IOMEM(0xE6051009) #define GPIO_PORT10CR IOMEM(0xE605100A) -#define GPIO_PORT167CR IOMEM(0xE60520A7) -#define GPIO_PORT168CR IOMEM(0xE60520A8) #define SRCR4 IOMEM(0xe61580bc) #define USCCR1 IOMEM(0xE6058144) static void __init mackerel_init(void) @@ -1441,17 +1449,8 @@ static void __init mackerel_init(void) ARRAY_SIZE(mackerel_pinctrl_map)); sh7372_pinmux_init(); - /* 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_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */ - - /* USBHS1 */ - gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */ - /* FSI2 port A (ak4643) */ gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */ diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c index 480d882e42c..2773936bf7d 100644 --- a/arch/arm/mach-shmobile/board-marzen-reference.c +++ b/arch/arm/mach-shmobile/board-marzen-reference.c @@ -19,43 +19,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <linux/pinctrl/machine.h> #include <mach/r8a7779.h> #include <mach/common.h> #include <mach/irqs.h> #include <asm/irq.h> #include <asm/mach/arch.h> -static const struct pinctrl_map marzen_pinctrl_map[] = { - /* SCIF2 (CN18: DEBUG0) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-r8a7779", - "scif2_data_c", "scif2"), - /* SCIF4 (CN19: DEBUG1) */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-r8a7779", - "scif4_data", "scif4"), - /* SDHI0 */ - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779", - "sdhi0_data4", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779", - "sdhi0_ctrl", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779", - "sdhi0_cd", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779", - "sdhi0_wp", "sdhi0"), - /* SMSC */ - PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779", - "intc_irq1_b", "intc"), - PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779", - "lbsc_ex_cs0", "lbsc"), -}; - static void __init marzen_init(void) { - pinctrl_register_mappings(marzen_pinctrl_map, - ARRAY_SIZE(marzen_pinctrl_map)); - r8a7779_pinmux_init(); - r8a7779_add_standard_devices_dt(); + r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */ } static const char *marzen_boards_compat_dt[] __initdata = { @@ -70,6 +43,5 @@ DT_MACHINE_START(MARZEN, "marzen") .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = marzen_init, - .init_time = shmobile_timer_init, .dt_compat = marzen_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index a7d1010505b..d832a4477b4 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -1,8 +1,9 @@ /* * marzen board support * - * Copyright (C) 2011 Renesas Solutions Corp. + * Copyright (C) 2011, 2013 Renesas Solutions Corp. * Copyright (C) 2011 Magnus Damm + * Copyright (C) 2013 Cogent Embedded, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +29,10 @@ #include <linux/leds.h> #include <linux/dma-mapping.h> #include <linux/pinctrl/machine.h> +#include <linux/platform_data/camera-rcar.h> #include <linux/platform_data/gpio-rcar.h> +#include <linux/platform_data/rcar-du.h> +#include <linux/platform_data/usb-rcar-phy.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/smsc911x.h> @@ -37,7 +41,7 @@ #include <linux/mmc/host.h> #include <linux/mmc/sh_mobile_sdhi.h> #include <linux/mfd/tmio.h> -#include <mach/hardware.h> +#include <media/soc_camera.h> #include <mach/r8a7779.h> #include <mach/common.h> #include <mach/irqs.h> @@ -57,7 +61,26 @@ static struct regulator_consumer_supply dummy_supplies[] = { REGULATOR_SUPPLY("vdd33a", "smsc911x"), }; -static struct rcar_phy_platform_data usb_phy_platform_data __initdata; +/* USB PHY */ +static struct resource usb_phy_resources[] = { + [0] = { + .start = 0xffe70800, + .end = 0xffe70900 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct rcar_phy_platform_data usb_phy_platform_data; + +static struct platform_device usb_phy = { + .name = "rcar_usb_phy", + .id = -1, + .dev = { + .platform_data = &usb_phy_platform_data, + }, + .resource = usb_phy_resources, + .num_resources = ARRAY_SIZE(usb_phy_resources), +}; /* SMSC LAN89218 */ static struct resource smsc911x_resources[] = { @@ -103,6 +126,8 @@ static struct resource sdhi0_resources[] = { }; static struct sh_mobile_sdhi_info sdhi0_platform_data = { + .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, .tmio_caps = MMC_CAP_SD_HIGHSPEED, }; @@ -148,6 +173,63 @@ static struct platform_device hspi_device = { .num_resources = ARRAY_SIZE(hspi_resources), }; +/* + * DU + * + * The panel only specifies the [hv]display and [hv]total values. The position + * and width of the sync pulses don't matter, they're copied from VESA timings. + */ +static struct rcar_du_encoder_data du_encoders[] = { + { + .type = RCAR_DU_ENCODER_VGA, + .output = RCAR_DU_OUTPUT_DPAD0, + }, { + .type = RCAR_DU_ENCODER_LVDS, + .output = RCAR_DU_OUTPUT_DPAD1, + .connector.lvds.panel = { + .width_mm = 210, + .height_mm = 158, + .mode = { + .clock = 65000, + .hdisplay = 1024, + .hsync_start = 1048, + .hsync_end = 1184, + .htotal = 1344, + .vdisplay = 768, + .vsync_start = 771, + .vsync_end = 777, + .vtotal = 806, + .flags = 0, + }, + }, + }, +}; + +static const struct rcar_du_platform_data du_pdata __initconst = { + .encoders = du_encoders, + .num_encoders = ARRAY_SIZE(du_encoders), +}; + +static const struct resource du_resources[] __initconst = { + DEFINE_RES_MEM(0xfff80000, 0x40000), + DEFINE_RES_IRQ(gic_iid(0x3f)), +}; + +static void __init marzen_add_du_device(void) +{ + struct platform_device_info info = { + .name = "rcar-du-r8a7779", + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), + .data = &du_pdata, + .size_data = sizeof(du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + + platform_device_register_full(&info); +} + /* LEDS */ static struct gpio_led marzen_leds[] = { { @@ -178,15 +260,77 @@ static struct platform_device leds_device = { }, }; +/* VIN */ +static struct rcar_vin_platform_data vin_platform_data __initdata = { + .flags = RCAR_VIN_BT656, +}; + +#define MARZEN_VIN(idx) \ +static struct resource vin##idx##_resources[] __initdata = { \ + DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ + DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \ +}; \ + \ +static struct platform_device_info vin##idx##_info __initdata = { \ + .parent = &platform_bus, \ + .name = "r8a7779-vin", \ + .id = idx, \ + .res = vin##idx##_resources, \ + .num_res = ARRAY_SIZE(vin##idx##_resources), \ + .dma_mask = DMA_BIT_MASK(32), \ + .data = &vin_platform_data, \ + .size_data = sizeof(vin_platform_data), \ +} +MARZEN_VIN(1); +MARZEN_VIN(3); + +#define MARZEN_CAMERA(idx) \ +static struct i2c_board_info camera##idx##_info = { \ + I2C_BOARD_INFO("adv7180", 0x20 + (idx)), \ +}; \ + \ +static struct soc_camera_link iclink##idx##_adv7180 = { \ + .bus_id = 1 + 2 * (idx), \ + .i2c_adapter_id = 0, \ + .board_info = &camera##idx##_info, \ +}; \ + \ +static struct platform_device camera##idx##_device = { \ + .name = "soc-camera-pdrv", \ + .id = idx, \ + .dev = { \ + .platform_data = &iclink##idx##_adv7180, \ + }, \ +}; + +MARZEN_CAMERA(0); +MARZEN_CAMERA(1); + static struct platform_device *marzen_devices[] __initdata = { ð_device, &sdhi0_device, &thermal_device, &hspi_device, &leds_device, + &usb_phy, + &camera0_device, + &camera1_device, }; static const struct pinctrl_map marzen_pinctrl_map[] = { + /* DU (CN10: ARGB0, CN13: LVDS) */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du0_rgb888", "du0"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du0_sync_1", "du0"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du0_clk_out_0", "du0"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du1_rgb666", "du1"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du1_sync_1", "du1"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", + "du1_clk_out", "du1"), /* HSPI0 */ PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779", "hspi0", "hspi0"), @@ -203,8 +347,6 @@ static const struct pinctrl_map marzen_pinctrl_map[] = { "sdhi0_ctrl", "sdhi0"), PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779", "sdhi0_cd", "sdhi0"), - PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779", - "sdhi0_wp", "sdhi0"), /* SMSC */ PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779", "intc_irq1_b", "intc"), @@ -219,6 +361,16 @@ static const struct pinctrl_map marzen_pinctrl_map[] = { /* USB2 */ PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.1", "pfc-r8a7779", "usb2", "usb2"), + /* VIN1 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779", + "vin1_clk", "vin1"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779", + "vin1_data8", "vin1"), + /* VIN3 */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779", + "vin3_clk", "vin3"), + PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779", + "vin3_data8", "vin3"), }; static void __init marzen_init(void) @@ -234,17 +386,24 @@ static void __init marzen_init(void) r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */ r8a7779_add_standard_devices(); - r8a7779_add_usb_phy_device(&usb_phy_platform_data); + platform_device_register_full(&vin1_info); + platform_device_register_full(&vin3_info); platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); + marzen_add_du_device(); } -MACHINE_START(MARZEN, "marzen") +static const char *marzen_boards_compat_dt[] __initdata = { + "renesas,marzen", + NULL, +}; + +DT_MACHINE_START(MARZEN, "marzen") .smp = smp_ops(r8a7779_smp_ops), .map_io = r8a7779_map_io, .init_early = r8a7779_add_early_devices, - .nr_irqs = NR_IRQS_LEGACY, - .init_irq = r8a7779_init_irq, + .init_irq = r8a7779_init_irq_dt, .init_machine = marzen_init, .init_late = r8a7779_init_late, + .dt_compat = marzen_boards_compat_dt, .init_time = r8a7779_earlytimer_init, MACHINE_END diff --git a/arch/arm/mach-shmobile/clock-emev2.c b/arch/arm/mach-shmobile/clock-emev2.c deleted file mode 100644 index 4710f1847bb..00000000000 --- a/arch/arm/mach-shmobile/clock-emev2.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Emma Mobile EV2 clock framework support - * - * Copyright (C) 2012 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/kernel.h> -#include <linux/io.h> -#include <linux/sh_clk.h> -#include <linux/clkdev.h> -#include <mach/common.h> - -#define EMEV2_SMU_BASE 0xe0110000 - -/* EMEV2 SMU registers */ -#define USIAU0_RSTCTRL 0x094 -#define USIBU1_RSTCTRL 0x0ac -#define USIBU2_RSTCTRL 0x0b0 -#define USIBU3_RSTCTRL 0x0b4 -#define STI_RSTCTRL 0x124 -#define USIAU0GCLKCTRL 0x4a0 -#define USIBU1GCLKCTRL 0x4b8 -#define USIBU2GCLKCTRL 0x4bc -#define USIBU3GCLKCTRL 0x04c0 -#define STIGCLKCTRL 0x528 -#define USIAU0SCLKDIV 0x61c -#define USIB2SCLKDIV 0x65c -#define USIB3SCLKDIV 0x660 -#define STI_CLKSEL 0x688 -#define SMU_GENERAL_REG0 0x7c0 - -/* not pretty, but hey */ -static void __iomem *smu_base; - -static void emev2_smu_write(unsigned long value, int offs) -{ - BUG_ON(!smu_base || (offs >= PAGE_SIZE)); - 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, -}; - -/* Fixed 32 KHz root clock from C32K pin */ -static struct clk c32k_clk = { - .rate = 32768, - .mapping = &smu_mapping, -}; - -/* PLL3 multiplies C32K with 7000 */ -static unsigned long pll3_recalc(struct clk *clk) -{ - return clk->parent->rate * 7000; -} - -static struct sh_clk_ops pll3_clk_ops = { - .recalc = pll3_recalc, -}; - -static struct clk pll3_clk = { - .ops = &pll3_clk_ops, - .parent = &c32k_clk, -}; - -static struct clk *main_clks[] = { - &c32k_clk, - &pll3_clk, -}; - -enum { SCLKDIV_USIAU0, SCLKDIV_USIBU2, SCLKDIV_USIBU1, SCLKDIV_USIBU3, - SCLKDIV_NR }; - -#define SCLKDIV(_reg, _shift) \ -{ \ - .parent = &pll3_clk, \ - .enable_reg = IOMEM(EMEV2_SMU_BASE + (_reg)), \ - .enable_bit = _shift, \ -} - -static struct clk sclkdiv_clks[SCLKDIV_NR] = { - [SCLKDIV_USIAU0] = SCLKDIV(USIAU0SCLKDIV, 0), - [SCLKDIV_USIBU2] = SCLKDIV(USIB2SCLKDIV, 16), - [SCLKDIV_USIBU1] = SCLKDIV(USIB2SCLKDIV, 0), - [SCLKDIV_USIBU3] = SCLKDIV(USIB3SCLKDIV, 0), -}; - -enum { GCLK_USIAU0_SCLK, GCLK_USIBU1_SCLK, GCLK_USIBU2_SCLK, GCLK_USIBU3_SCLK, - GCLK_STI_SCLK, - GCLK_NR }; - -#define GCLK_SCLK(_parent, _reg) \ -{ \ - .parent = _parent, \ - .enable_reg = IOMEM(EMEV2_SMU_BASE + (_reg)), \ - .enable_bit = 1, /* SCLK_GCC */ \ -} - -static struct clk gclk_clks[GCLK_NR] = { - [GCLK_USIAU0_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIAU0], - USIAU0GCLKCTRL), - [GCLK_USIBU1_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU1], - USIBU1GCLKCTRL), - [GCLK_USIBU2_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU2], - USIBU2GCLKCTRL), - [GCLK_USIBU3_SCLK] = GCLK_SCLK(&sclkdiv_clks[SCLKDIV_USIBU3], - USIBU3GCLKCTRL), - [GCLK_STI_SCLK] = GCLK_SCLK(&c32k_clk, STIGCLKCTRL), -}; - -static int emev2_gclk_enable(struct clk *clk) -{ - iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), - clk->mapped_reg); - return 0; -} - -static void emev2_gclk_disable(struct clk *clk) -{ - iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), - clk->mapped_reg); -} - -static struct sh_clk_ops emev2_gclk_clk_ops = { - .enable = emev2_gclk_enable, - .disable = emev2_gclk_disable, - .recalc = followparent_recalc, -}; - -static int __init emev2_gclk_register(struct clk *clks, int nr) -{ - struct clk *clkp; - int ret = 0; - int k; - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - clkp->ops = &emev2_gclk_clk_ops; - ret |= clk_register(clkp); - } - - return ret; -} - -static unsigned long emev2_sclkdiv_recalc(struct clk *clk) -{ - unsigned int sclk_div; - - sclk_div = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0xff; - - return clk->parent->rate / (sclk_div + 1); -} - -static struct sh_clk_ops emev2_sclkdiv_clk_ops = { - .recalc = emev2_sclkdiv_recalc, -}; - -static int __init emev2_sclkdiv_register(struct clk *clks, int nr) -{ - struct clk *clkp; - int ret = 0; - int k; - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - clkp->ops = &emev2_sclkdiv_clk_ops; - ret |= clk_register(clkp); - } - - return ret; -} - -static struct clk_lookup lookups[] = { - CLKDEV_DEV_ID("serial8250-em.0", &gclk_clks[GCLK_USIAU0_SCLK]), - CLKDEV_DEV_ID("e1020000.uart", &gclk_clks[GCLK_USIAU0_SCLK]), - CLKDEV_DEV_ID("serial8250-em.1", &gclk_clks[GCLK_USIBU1_SCLK]), - CLKDEV_DEV_ID("e1030000.uart", &gclk_clks[GCLK_USIBU1_SCLK]), - CLKDEV_DEV_ID("serial8250-em.2", &gclk_clks[GCLK_USIBU2_SCLK]), - CLKDEV_DEV_ID("e1040000.uart", &gclk_clks[GCLK_USIBU2_SCLK]), - CLKDEV_DEV_ID("serial8250-em.3", &gclk_clks[GCLK_USIBU3_SCLK]), - CLKDEV_DEV_ID("e1050000.uart", &gclk_clks[GCLK_USIBU3_SCLK]), - CLKDEV_DEV_ID("em_sti.0", &gclk_clks[GCLK_STI_SCLK]), - CLKDEV_DEV_ID("e0180000.sti", &gclk_clks[GCLK_STI_SCLK]), -}; - -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 */ - emev2_smu_write(0, STI_CLKSEL); - emev2_smu_write(1, STI_RSTCTRL); - - /* deassert reset for UART0->UART3 */ - emev2_smu_write(2, USIAU0_RSTCTRL); - emev2_smu_write(2, USIBU1_RSTCTRL); - emev2_smu_write(2, USIBU2_RSTCTRL); - emev2_smu_write(2, USIBU3_RSTCTRL); - - for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) - ret = clk_register(main_clks[k]); - - if (!ret) - ret = emev2_sclkdiv_register(sclkdiv_clks, SCLKDIV_NR); - - if (!ret) - ret = emev2_gclk_register(gclk_clks, GCLK_NR); - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - if (!ret) - shmobile_clk_init(); - else - panic("failed to setup emev2 clocks\n"); -} diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c new file mode 100644 index 00000000000..df187484de5 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r7s72100.c @@ -0,0 +1,230 @@ +/* + * r7a72100 clock framework support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2012 Phil Edworthy + * Copyright (C) 2011 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. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <linux/clkdev.h> +#include <mach/common.h> +#include <mach/r7s72100.h> + +/* Frequency Control Registers */ +#define FRQCR 0xfcfe0010 +#define FRQCR2 0xfcfe0014 +/* Standby Control Registers */ +#define STBCR3 0xfcfe0420 +#define STBCR4 0xfcfe0424 +#define STBCR7 0xfcfe0430 +#define STBCR9 0xfcfe0438 +#define STBCR10 0xfcfe043c + +#define PLL_RATE 30 + +static struct clk_mapping cpg_mapping = { + .phys = 0xfcfe0000, + .len = 0x1000, +}; + +/* Fixed 32 KHz root clock for RTC */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * Default rate for the root input clock, reset this with clk_set_rate() + * from the platform code. + */ +static struct clk extal_clk = { + .rate = 13330000, + .mapping = &cpg_mapping, +}; + +static unsigned long pll_recalc(struct clk *clk) +{ + return clk->parent->rate * PLL_RATE; +} + +static struct sh_clk_ops pll_clk_ops = { + .recalc = pll_recalc, +}; + +static struct clk pll_clk = { + .ops = &pll_clk_ops, + .parent = &extal_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long bus_recalc(struct clk *clk) +{ + return clk->parent->rate / 3; +} + +static struct sh_clk_ops bus_clk_ops = { + .recalc = bus_recalc, +}; + +static struct clk bus_clk = { + .ops = &bus_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral0_recalc(struct clk *clk) +{ + return clk->parent->rate / 12; +} + +static struct sh_clk_ops peripheral0_clk_ops = { + .recalc = peripheral0_recalc, +}; + +static struct clk peripheral0_clk = { + .ops = &peripheral0_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral1_recalc(struct clk *clk) +{ + return clk->parent->rate / 6; +} + +static struct sh_clk_ops peripheral1_clk_ops = { + .recalc = peripheral1_recalc, +}; + +static struct clk peripheral1_clk = { + .ops = &peripheral1_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +struct clk *main_clks[] = { + &r_clk, + &extal_clk, + &pll_clk, + &bus_clk, + &peripheral0_clk, + &peripheral1_clk, +}; + +static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */ +static int multipliers[] = { 1, 2, 1, 1 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = div2, + .nr_divisors = ARRAY_SIZE(div2), + .multipliers = multipliers, + .nr_multipliers = ARRAY_SIZE(multipliers), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + +enum { DIV4_I, + DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) + +/* The mask field specifies the div2 entries that are valid */ +struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT + | CLK_ENABLE_ON_INIT), +}; + +enum { + MSTP107, MSTP106, MSTP105, MSTP104, MSTP103, + MSTP97, MSTP96, MSTP95, MSTP94, + MSTP74, + MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, + MSTP33, MSTP_NR +}; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP107] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 7, 0), /* RSPI0 */ + [MSTP106] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 6, 0), /* RSPI1 */ + [MSTP105] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 5, 0), /* RSPI2 */ + [MSTP104] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 4, 0), /* RSPI3 */ + [MSTP103] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 3, 0), /* RSPI4 */ + [MSTP97] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 7, 0), /* RIIC0 */ + [MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */ + [MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */ + [MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */ + [MSTP74] = SH_CLK_MSTP8(&peripheral1_clk, STBCR7, 4, 0), /* Ether */ + [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ + [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ + [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ + [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */ + [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */ + [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */ + [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */ + [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */ + [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */ +}; + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + + /* MSTP clocks */ + CLKDEV_DEV_ID("rspi-rz.0", &mstp_clks[MSTP107]), + CLKDEV_DEV_ID("rspi-rz.1", &mstp_clks[MSTP106]), + CLKDEV_DEV_ID("rspi-rz.2", &mstp_clks[MSTP105]), + CLKDEV_DEV_ID("rspi-rz.3", &mstp_clks[MSTP104]), + CLKDEV_DEV_ID("rspi-rz.4", &mstp_clks[MSTP103]), + CLKDEV_DEV_ID("r7s72100-ether", &mstp_clks[MSTP74]), + + /* ICK */ + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), + CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP33]), +}; + +void __init r7s72100_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + if (!ret) + shmobile_clk_init(); + else + panic("failed to setup rza1 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 5f7fe628b8a..b5bc22c6a85 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}; @@ -348,9 +504,11 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { - MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, - MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, - MSTP522, + MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, + MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, + MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, + MSTP411, MSTP410, MSTP409, + MSTP522, MSTP515, MSTP_NR }; @@ -361,12 +519,23 @@ 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 */ + [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */ + [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 +555,9 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("pll2s", &pll2s_clk), CLKDEV_CON_ID("pll2h", &pll2h_clk), + /* CPU clock */ + CLKDEV_DEV_ID("cpu0", &z_clk), + /* DIV6 */ CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]), CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]), @@ -407,17 +579,29 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), + CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]), 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("ee220000.mmc", &mstp_clks[MSTP305]), CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), - CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]), + CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]), CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), - CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), + CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), - CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), + CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), - CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), + CLKDEV_DEV_ID("ee200000.mmc", &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_ICK_ID("fck", "sh-cmt-48-gen2.1", &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 +613,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-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index de10fd78bf2..50931e3c97c 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c @@ -548,15 +548,9 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), - CLKDEV_DEV_ID("sh_tmu.3", &mstp_clks[MSTP111]), - 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]), - CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP125]), CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), @@ -583,25 +577,29 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), CLKDEV_DEV_ID("e6cc0000.sci", &mstp_clks[MSTP230]), - CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), + CLKDEV_DEV_ID("fe1f0000.sound", &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]), + CLKDEV_DEV_ID("e6850000.sd", &mstp_clks[MSTP314]), CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), - CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), + CLKDEV_DEV_ID("e6860000.sd", &mstp_clks[MSTP313]), CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]), - CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), + CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), CLKDEV_DEV_ID("r8a7740-gether", &mstp_clks[MSTP309]), - CLKDEV_DEV_ID("e9a00000.sh-eth", &mstp_clks[MSTP309]), - CLKDEV_DEV_ID("renesas_tpu_pwm", &mstp_clks[MSTP304]), + CLKDEV_DEV_ID("e9a00000.ethernet", &mstp_clks[MSTP309]), + CLKDEV_DEV_ID("renesas-tpu-pwm", &mstp_clks[MSTP304]), + CLKDEV_DEV_ID("e6600000.pwm", &mstp_clks[MSTP304]), CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), - CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), + CLKDEV_DEV_ID("e6870000.sd", &mstp_clks[MSTP415]), /* ICK */ + CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP111]), + CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), + CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]), CLKDEV_ICK_ID("func", "renesas_usbhs", &mstp_clks[MSTP407]), CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]), diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index a0e9eb72e46..13f8f3ab884 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -69,6 +69,15 @@ static struct clk extal_clk = { .mapping = &cpg_mapping, }; +static struct clk audio_clk_a = { +}; + +static struct clk audio_clk_b = { +}; + +static struct clk audio_clk_c = { +}; + /* * clock ratio of these clock will be updated * on r8a7778_clock_init() @@ -100,25 +109,49 @@ static struct clk *main_clks[] = { &p_clk, &g_clk, &z_clk, + &audio_clk_a, + &audio_clk_b, + &audio_clk_c, }; enum { + MSTP531, MSTP530, + MSTP529, MSTP528, MSTP527, MSTP526, MSTP525, MSTP524, MSTP523, MSTP331, MSTP323, MSTP322, MSTP321, + MSTP311, MSTP310, + MSTP309, MSTP308, MSTP307, MSTP114, + MSTP110, MSTP109, MSTP100, MSTP030, MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, - MSTP016, MSTP015, - MSTP007, + MSTP016, MSTP015, MSTP012, MSTP011, MSTP010, + MSTP009, MSTP008, MSTP007, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { + [MSTP531] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 31, 0), /* SCU0 */ + [MSTP530] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 30, 0), /* SCU1 */ + [MSTP529] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 29, 0), /* SCU2 */ + [MSTP528] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 28, 0), /* SCU3 */ + [MSTP527] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 27, 0), /* SCU4 */ + [MSTP526] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 26, 0), /* SCU5 */ + [MSTP525] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 25, 0), /* SCU6 */ + [MSTP524] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 24, 0), /* SCU7 */ + [MSTP523] = SH_CLK_MSTP32(&p_clk, MSTPCR5, 23, 0), /* SCU8 */ [MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */ [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 */ + [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */ + [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */ + [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 9, 0), /* SSI6 */ + [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 8, 0), /* SSI7 */ + [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 7, 0), /* SSI8 */ [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ + [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */ + [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */ [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */ [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */ [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */ @@ -132,7 +165,12 @@ static struct clk mstp_clks[MSTP_NR] = { [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 */ - [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */ + [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */ + [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */ + [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */ + [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */ + [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */ + [MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0, 7, 0), /* HSPI */ }; static struct clk_lookup lookups[] = { @@ -142,27 +180,65 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */ + CLKDEV_DEV_ID("ffe4e000.mmc", &mstp_clks[MSTP331]), /* MMC */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */ + CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ + CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ + CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP321]), /* SDHI2 */ CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ + CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */ + CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ + CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ + CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ + CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ + CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */ CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */ + CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */ - CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */ - CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP015]), /* TMU01 */ CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */ + CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */ + CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */ CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */ + CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */ + CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */ + + CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a), + CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), + CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), + CLKDEV_ICK_ID("clk_i", "rcar_sound", &s1_clk), + CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]), + CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]), + CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]), + CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]), + CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]), + CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), + CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), + CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), + CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]), + CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]), + CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]), + CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]), + CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]), + CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]), + CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]), + CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]), + CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]), + CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), + CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]), }; void __init r8a7778_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index 10340f5becb..a13298bd37a 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -47,17 +47,10 @@ #define MD(nr) BIT(nr) -#define FRQMR IOMEM(0xffc80014) #define MSTPCR0 IOMEM(0xffc80030) #define MSTPCR1 IOMEM(0xffc80034) #define MSTPCR3 IOMEM(0xffc8003c) #define MSTPSR1 IOMEM(0xffc80044) -#define MSTPSR4 IOMEM(0xffc80048) -#define MSTPSR6 IOMEM(0xffc8004c) -#define MSTPCR4 IOMEM(0xffc80050) -#define MSTPCR5 IOMEM(0xffc80054) -#define MSTPCR6 IOMEM(0xffc80058) -#define MSTPCR7 IOMEM(0xffc80040) #define MODEMR 0xffcc0020 @@ -112,7 +105,9 @@ static struct clk *main_clks[] = { }; enum { MSTP323, MSTP322, MSTP321, MSTP320, + MSTP120, MSTP116, MSTP115, MSTP114, + MSTP110, MSTP109, MSTP108, MSTP103, MSTP101, MSTP100, MSTP030, MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, @@ -125,12 +120,16 @@ 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 */ - [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */ - [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */ + [MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */ + [MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */ + [MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */ + [MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */ + [MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */ + [MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 9, MSTPSR1, 0), /* VIN1 */ + [MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 8, MSTPSR1, 0), /* VIN2 */ + [MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 3, MSTPSR1, 0), /* DU */ + [MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 1, MSTPSR1, 0), /* USB2 */ + [MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 0, MSTPSR1, 0), /* USB0/1 */ [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */ [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */ [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */ @@ -162,21 +161,27 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("peripheral_clk", &clkp_clk), /* MSTP32 clocks */ + CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */ 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("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ + CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */ + CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ + CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */ CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */ CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */ CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ - CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */ - CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */ - CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP016]), /* TMU02 */ + CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), /* TMU0 */ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ + CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ + CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ + CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */ CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */ + CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */ @@ -184,13 +189,20 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */ CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */ + CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */ + CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */ CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */ + CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */ + CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ + CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ + CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */ CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ - CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */ + CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */ + CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */ }; void __init r8a7779_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 5d71313df52..296a057109e 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,27 @@ * 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 SMSTPCR8 0xe6150990 +#define SMSTPCR9 0xe6150994 +#define SMSTPCR10 0xe6150998 + +#define MSTPSR1 IOMEM(0xe6150038) +#define MSTPSR2 IOMEM(0xe6150040) +#define MSTPSR3 IOMEM(0xe6150048) +#define MSTPSR5 IOMEM(0xe615003c) +#define MSTPSR7 IOMEM(0xe61501c4) +#define MSTPSR8 IOMEM(0xe61509a0) +#define MSTPSR9 IOMEM(0xe61509a4) +#define MSTPSR10 IOMEM(0xe61509a8) -#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 @@ -75,10 +87,19 @@ static struct sh_clk_ops followparent_clk_ops = { }; static struct clk main_clk = { - /* .parent will be set r8a73a4_clock_init */ + /* .parent will be set r8a7790_clock_init */ .ops = &followparent_clk_ops, }; +static struct clk audio_clk_a = { +}; + +static struct clk audio_clk_b = { +}; + +static struct clk audio_clk_c = { +}; + /* * clock ratio of these clock will be updated * on r8a7790_clock_init() @@ -112,6 +133,9 @@ 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[] = { + &audio_clk_a, + &audio_clk_b, + &audio_clk_c, &extal_clk, &extal_div2_clk, &main_clk, @@ -180,31 +204,91 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { - MSTP721, MSTP720, + MSTP1017, /* parent of SCU */ + + MSTP1031, MSTP1030, + MSTP1029, MSTP1028, MSTP1027, MSTP1026, MSTP1025, MSTP1024, MSTP1023, MSTP1022, + MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010, + MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005, + MSTP931, MSTP930, MSTP929, MSTP928, + MSTP917, + MSTP815, MSTP814, + MSTP813, + MSTP811, MSTP810, MSTP809, MSTP808, + MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, MSTP717, MSTP716, + MSTP704, MSTP703, + MSTP522, + MSTP502, MSTP501, 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 */ - [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 */ - [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SD2], SMSTPCR3, 12, 0), /* SDHI2 */ - [MSTP311] = SH_CLK_MSTP32(&div6_clks[DIV6_SD3], SMSTPCR3, 11, 0), /* SDHI3 */ - [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, 0), /* MMC1 */ - [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 */ - [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 */ + [MSTP1031] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 31, MSTPSR10, 0), /* SCU0 */ + [MSTP1030] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 30, MSTPSR10, 0), /* SCU1 */ + [MSTP1029] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 29, MSTPSR10, 0), /* SCU2 */ + [MSTP1028] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 28, MSTPSR10, 0), /* SCU3 */ + [MSTP1027] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 27, MSTPSR10, 0), /* SCU4 */ + [MSTP1026] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 26, MSTPSR10, 0), /* SCU5 */ + [MSTP1025] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 25, MSTPSR10, 0), /* SCU6 */ + [MSTP1024] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 24, MSTPSR10, 0), /* SCU7 */ + [MSTP1023] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 23, MSTPSR10, 0), /* SCU8 */ + [MSTP1022] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 22, MSTPSR10, 0), /* SCU9 */ + [MSTP1017] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 17, MSTPSR10, 0), /* SCU */ + [MSTP1015] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 15, MSTPSR10, 0), /* SSI0 */ + [MSTP1014] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 14, MSTPSR10, 0), /* SSI1 */ + [MSTP1013] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 13, MSTPSR10, 0), /* SSI2 */ + [MSTP1012] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 12, MSTPSR10, 0), /* SSI3 */ + [MSTP1011] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 11, MSTPSR10, 0), /* SSI4 */ + [MSTP1010] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 10, MSTPSR10, 0), /* SSI5 */ + [MSTP1009] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 9, MSTPSR10, 0), /* SSI6 */ + [MSTP1008] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 8, MSTPSR10, 0), /* SSI7 */ + [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */ + [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */ + [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */ + [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ + [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ + [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ + [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ + [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ + [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ + [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ + [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */ + [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */ + [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */ + [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */ + [MSTP808] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 8, MSTPSR8, 0), /* VIN3 */ + [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */ + [MSTP725] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 25, MSTPSR7, 0), /* LVDS1 */ + [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */ + [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */ + [MSTP722] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 22, MSTPSR7, 0), /* DU2 */ + [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */ + [MSTP717] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 17, MSTPSR7, 0), /* HSCIF0 */ + [MSTP716] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 16, MSTPSR7, 0), /* HSCIF1 */ + [MSTP704] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 4, MSTPSR7, 0), /* HSUSB */ + [MSTP703] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 3, MSTPSR7, 0), /* EHCI */ + [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */ + [MSTP502] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 2, MSTPSR5, 0), /* Audio-DMAC low */ + [MSTP501] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 1, MSTPSR5, 0), /* Audio-DMAC hi */ + [MSTP315] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, MSTPSR3, 0), /* MMC0 */ + [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */ + [MSTP313] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD1], SMSTPCR3, 13, MSTPSR3, 0), /* SDHI1 */ + [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI2 */ + [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD3], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI3 */ + [MSTP305] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, MSTPSR3, 0), /* MMC1 */ + [MSTP304] = SH_CLK_MSTP32_STS(&cp_clk, SMSTPCR3, 4, MSTPSR3, 0), /* TPU0 */ + [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */ + [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */ + [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */ + [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */ + [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */ + [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */ + [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */ }; static struct clk_lookup lookups[] = { @@ -244,6 +328,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]), /* MSTP */ + CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP1005]), 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]), @@ -254,18 +339,65 @@ 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("ee200000.mmcif", &mstp_clks[MSTP315]), + CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]), + CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]), + CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]), + CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]), + CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]), + CLKDEV_DEV_ID("r8a7790-vin.0", &mstp_clks[MSTP811]), + CLKDEV_DEV_ID("r8a7790-vin.1", &mstp_clks[MSTP810]), + CLKDEV_DEV_ID("r8a7790-vin.2", &mstp_clks[MSTP809]), + CLKDEV_DEV_ID("r8a7790-vin.3", &mstp_clks[MSTP808]), + CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP502]), + CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP501]), CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), - CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), - CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), - CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]), CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), - CLKDEV_DEV_ID("ee160000.sdhi", &mstp_clks[MSTP311]), 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("qspi.0", &mstp_clks[MSTP917]), + CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]), + CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]), + CLKDEV_DEV_ID("pci-rcar-gen2.1", &mstp_clks[MSTP703]), + CLKDEV_DEV_ID("pci-rcar-gen2.2", &mstp_clks[MSTP703]), + CLKDEV_DEV_ID("sata-r8a7790.0", &mstp_clks[MSTP815]), + CLKDEV_DEV_ID("sata-r8a7790.1", &mstp_clks[MSTP814]), + + /* ICK */ + CLKDEV_ICK_ID("fck", "sh-cmt-48-gen2.0", &mstp_clks[MSTP124]), + CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]), + CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]), + CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]), + CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]), + CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]), + CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]), + CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a), + CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), + CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), + CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk), + CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP1031]), + CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP1030]), + CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP1029]), + CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP1028]), + CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP1027]), + CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP1026]), + CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP1025]), + CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP1024]), + CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP1023]), + CLKDEV_ICK_ID("src.9", "rcar_sound", &mstp_clks[MSTP1022]), + CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]), + CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]), + CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]), + CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP1012]), + CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP1011]), + CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP1010]), + CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP1009]), + CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP1008]), + CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP1007]), + CLKDEV_ICK_ID("ssi.9", "rcar_sound", &mstp_clks[MSTP1006]), + }; #define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ @@ -280,14 +412,9 @@ static struct clk_lookup lookups[] = { void __init r8a7790_clock_init(void) { - void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); - u32 mode; + u32 mode = rcar_gen2_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); @@ -296,10 +423,10 @@ void __init r8a7790_clock_init(void) 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); + R8A7790_CLOCK_ROOT(26 / 2, &extal_div2_clk, 200, 240, 122, 102); break; case MD(13) | MD(14): - R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); + R8A7790_CLOCK_ROOT(30 / 2, &extal_div2_clk, 172, 208, 106, 88); break; } diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c new file mode 100644 index 00000000000..e2fdfcc1443 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -0,0 +1,342 @@ +/* + * r8a7791 clock framework support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * 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/io.h> +#include <linux/kernel.h> +#include <linux/sh_clk.h> +#include <linux/clkdev.h> +#include <mach/clock.h> +#include <mach/common.h> +#include <mach/rcar-gen2.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 R8A7791_CLOCK_ROOT() below + */ + +#define CPG_BASE 0xe6150000 +#define CPG_LEN 0x1000 + +#define SMSTPCR0 0xE6150130 +#define SMSTPCR1 0xE6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xE615013C +#define SMSTPCR5 0xE6150144 +#define SMSTPCR7 0xe615014c +#define SMSTPCR8 0xE6150990 +#define SMSTPCR9 0xE6150994 +#define SMSTPCR10 0xE6150998 +#define SMSTPCR11 0xE615099C + +#define MSTPSR1 IOMEM(0xe6150038) +#define MSTPSR2 IOMEM(0xe6150040) +#define MSTPSR3 IOMEM(0xe6150048) +#define MSTPSR5 IOMEM(0xe615003c) +#define MSTPSR7 IOMEM(0xe61501c4) +#define MSTPSR8 IOMEM(0xe61509a0) +#define MSTPSR9 IOMEM(0xe61509a4) +#define MSTPSR11 IOMEM(0xe61509ac) + +#define SDCKCR 0xE6150074 +#define SD1CKCR 0xE6150078 +#define SD2CKCR 0xE615026c +#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 extal_clk = { + /* .rate will be updated on r8a7791_clock_init() */ + .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 r8a7791_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(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(hp_clk, pll1_clk, 1, 12); +SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); +SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); +SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); +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); + +static struct clk *main_clks[] = { + &extal_clk, + &extal_div2_clk, + &main_clk, + &pll1_clk, + &pll1_div2_clk, + &pll3_clk, + &hp_clk, + &p_clk, + &qspi_clk, + &rclk_clk, + &mp_clk, + &cp_clk, + &zg_clk, + &zx_clk, + &zs_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_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), +}; + +/* DIV6 clocks */ +enum { + DIV6_SD1, DIV6_SD2, + DIV6_NR +}; + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_SD1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0), + [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0), +}; + +/* MSTP */ +enum { + MSTP1108, MSTP1107, MSTP1106, + MSTP931, MSTP930, MSTP929, MSTP928, MSTP927, MSTP925, + MSTP917, + MSTP815, MSTP814, + MSTP813, + MSTP811, MSTP810, MSTP809, + MSTP726, MSTP724, MSTP723, MSTP721, MSTP720, + MSTP719, MSTP718, MSTP715, MSTP714, + MSTP522, + MSTP314, MSTP312, MSTP311, + MSTP216, MSTP207, MSTP206, + MSTP204, MSTP203, MSTP202, + MSTP124, + MSTP_NR +}; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */ + [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */ + [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */ + [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ + [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ + [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ + [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ + [MSTP927] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */ + [MSTP925] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */ + [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ + [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ + [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ + [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */ + [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */ + [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */ + [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */ + [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */ + [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */ + [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */ + [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */ + [MSTP719] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 19, MSTPSR7, 0), /* SCIF2 */ + [MSTP718] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 18, MSTPSR7, 0), /* SCIF3 */ + [MSTP715] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 15, MSTPSR7, 0), /* SCIF4 */ + [MSTP714] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 14, MSTPSR7, 0), /* SCIF5 */ + [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */ + [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */ + [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD1], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI1 */ + [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI2 */ + [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */ + [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */ + [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */ + [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */ + [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */ + [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */ + [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */ +}; + +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("zs", &zs_clk), + CLKDEV_CON_ID("hp", &hp_clk), + CLKDEV_CON_ID("p", &p_clk), + CLKDEV_CON_ID("qspi", &qspi_clk), + CLKDEV_CON_ID("rclk", &rclk_clk), + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("cp", &cp_clk), + CLKDEV_CON_ID("peripheral_clk", &hp_clk), + + /* MSTP */ + CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]), + CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]), + CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]), + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */ + CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */ + CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ + CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ + CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ + CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1106]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1107]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1108]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP312]), + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), + CLKDEV_ICK_ID("fck", "sh-cmt-48-gen2.0", &mstp_clks[MSTP124]), + CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]), + CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), + CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]), + CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]), + CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]), + CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]), + CLKDEV_DEV_ID("i2c-rcar_gen2.4", &mstp_clks[MSTP927]), + CLKDEV_DEV_ID("i2c-rcar_gen2.5", &mstp_clks[MSTP925]), + CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */ + CLKDEV_DEV_ID("r8a7791-vin.0", &mstp_clks[MSTP811]), + CLKDEV_DEV_ID("r8a7791-vin.1", &mstp_clks[MSTP810]), + CLKDEV_DEV_ID("r8a7791-vin.2", &mstp_clks[MSTP809]), + CLKDEV_DEV_ID("sata-r8a7791.0", &mstp_clks[MSTP815]), + CLKDEV_DEV_ID("sata-r8a7791.1", &mstp_clks[MSTP814]), +}; + +#define R8A7791_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 r8a7791_clock_init(void) +{ + u32 mode = rcar_gen2_read_mode_pins(); + int k, ret = 0; + + switch (mode & (MD(14) | MD(13))) { + case 0: + R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); + break; + case MD(13): + R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); + break; + case MD(14): + R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); + break; + case MD(13) | MD(14): + R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); + break; + } + + 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)); + + if (!ret) + shmobile_clk_init(); + else + goto epanic; + + return; + +epanic: + panic("failed to setup r8a7791 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 5390c6bbbc0..d16d9ca7f79 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -504,10 +504,6 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]), - CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), - CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), - CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), - CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ @@ -519,8 +515,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */ CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ - CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ - CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ @@ -569,17 +563,23 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */ - CLKDEV_DEV_ID("sh_cmt.4", &mstp_clks[MSTP405]), /* CMT4 */ - CLKDEV_DEV_ID("sh_cmt.3", &mstp_clks[MSTP404]), /* CMT3 */ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ - CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */ + /* ICK */ + CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), + CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), CLKDEV_ICK_ID("hdmi", "sh_mobile_lcdc_fb.1", &div6_reparent_clks[DIV6_HDMI]), CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), + CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */ CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), + CLKDEV_ICK_ID("fck", "sh-cmt-32-fast.4", &mstp_clks[MSTP405]), /* CMT4 */ + CLKDEV_ICK_ID("fck", "sh-cmt-32-fast.3", &mstp_clks[MSTP404]), /* CMT3 */ + CLKDEV_ICK_ID("fck", "sh-cmt-32-fast.2", &mstp_clks[MSTP400]), /* CMT2 */ CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]), CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]), CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk), diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index d9fd0336b91..0d9cd1fe021 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -555,7 +555,7 @@ enum { MSTP001, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, MSTP311, - MSTP303, MSTP302, MSTP301, MSTP300, + MSTP304, MSTP303, MSTP302, MSTP301, MSTP300, MSTP411, MSTP410, MSTP403, MSTP_NR }; @@ -593,6 +593,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */ + [MSTP304] = MSTP(&main_div2_clk, SMSTPCR3, 4, 0), /* TPU0 */ [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */ [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */ [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */ @@ -615,7 +616,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */ /* DIV4 clocks */ - CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]), + CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]), /* DIV6 clocks */ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), @@ -624,12 +625,6 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]), CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]), CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]), - CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), - CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), - CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), - CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), - CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk), - CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk), /* MSTP32 clocks */ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ @@ -638,8 +633,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */ CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */ - CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ - CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */ CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */ @@ -655,29 +648,40 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ - CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */ + CLKDEV_DEV_ID("ec230000.sound", &mstp_clks[MSTP328]), /* FSI */ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */ CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ - CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ - CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ - CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */ + CLKDEV_DEV_ID("e6bd0000.mmc", &mstp_clks[MSTP312]), /* MMCIF0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ - CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */ - CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ - CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ - CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ - CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */ + CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP311]), /* SDHI2 */ + CLKDEV_DEV_ID("renesas-tpu-pwm.0", &mstp_clks[MSTP304]), /* TPU0 */ + CLKDEV_DEV_ID("renesas-tpu-pwm.1", &mstp_clks[MSTP303]), /* TPU1 */ + CLKDEV_DEV_ID("renesas-tpu-pwm.2", &mstp_clks[MSTP302]), /* TPU2 */ + CLKDEV_DEV_ID("renesas-tpu-pwm.3", &mstp_clks[MSTP301]), /* TPU3 */ + CLKDEV_DEV_ID("renesas-tpu-pwm.4", &mstp_clks[MSTP300]), /* TPU4 */ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ + + /* ICK */ + CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), + CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), + CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), + CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk), + CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk), + CLKDEV_ICK_ID("fck", "sh-cmt-48.1", &mstp_clks[MSTP329]), /* CMT1 */ + CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP125]), /* TMU0 */ }; void __init sh73a0_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c index ad7df629d99..e7232a0373b 100644 --- a/arch/arm/mach-shmobile/clock.c +++ b/arch/arm/mach-shmobile/clock.c @@ -21,6 +21,32 @@ */ #include <linux/kernel.h> #include <linux/init.h> + +#ifdef CONFIG_COMMON_CLK +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <mach/clock.h> + +void __init shmobile_clk_workaround(const struct clk_name *clks, + int nr_clks, bool enable) +{ + const struct clk_name *clkn; + struct clk *clk; + unsigned int i; + + for (i = 0; i < nr_clks; ++i) { + clkn = clks + i; + clk = clk_get(NULL, clkn->clk); + if (!IS_ERR(clk)) { + clk_register_clkdev(clk, clkn->con_id, clkn->dev_id); + if (enable) + clk_prepare_enable(clk); + clk_put(clk); + } + } +} + +#else /* CONFIG_COMMON_CLK */ #include <linux/sh_clk.h> #include <linux/export.h> #include <mach/clock.h> @@ -58,3 +84,5 @@ void __clk_put(struct clk *clk) { } EXPORT_SYMBOL(__clk_put); + +#endif /* CONFIG_COMMON_CLK */ diff --git a/arch/arm/mach-shmobile/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S index bfd920083a3..f45dde701d7 100644 --- a/arch/arm/mach-shmobile/headsmp-scu.S +++ b/arch/arm/mach-shmobile/headsmp-scu.S @@ -37,13 +37,15 @@ ENTRY(shmobile_boot_scu) lsl r1, r1, #3 @ we will shift by cpu_id * 8 bits ldr r2, [r0, #8] @ SCU Power Status Register mov r3, #3 - bic r2, r2, r3, lsl r1 @ Clear bits of our CPU (Run Mode) + lsl r3, r3, r1 + bic r2, r2, r3 @ Clear bits of our CPU (Run Mode) str r2, [r0, #8] @ write back b shmobile_invalidate_start ENDPROC(shmobile_boot_scu) .text + .align 2 .globl shmobile_scu_base shmobile_scu_base: .space 4 diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index a9d21249898..e5be5c88644 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -24,15 +24,71 @@ ENDPROC(shmobile_invalidate_start) * This will be mapped at address 0 by SBAR register. * We need _long_ jump to the physical address. */ + .arm .align 12 ENTRY(shmobile_boot_vector) ldr r0, 2f - ldr pc, 1f + ldr r1, 1f + bx r1 + ENDPROC(shmobile_boot_vector) + .align 2 .globl shmobile_boot_fn shmobile_boot_fn: 1: .space 4 .globl shmobile_boot_arg shmobile_boot_arg: 2: .space 4 + .globl shmobile_boot_size +shmobile_boot_size: + .long . - shmobile_boot_vector + +/* + * Per-CPU SMP boot function/argument selection code based on MPIDR + */ + +ENTRY(shmobile_smp_boot) + @ r0 = MPIDR_HWID_BITMASK + mrc p15, 0, r1, c0, c0, 5 @ r1 = MPIDR + and r0, r1, r0 @ r0 = cpu_logical_map() value + mov r1, #0 @ r1 = CPU index + adr r5, 1f @ array of per-cpu mpidr values + adr r6, 2f @ array of per-cpu functions + adr r7, 3f @ array of per-cpu arguments + +shmobile_smp_boot_find_mpidr: + ldr r8, [r5, r1, lsl #2] + cmp r8, r0 + bne shmobile_smp_boot_next + + ldr r9, [r6, r1, lsl #2] + cmp r9, #0 + bne shmobile_smp_boot_found + +shmobile_smp_boot_next: + add r1, r1, #1 + cmp r1, #CONFIG_NR_CPUS + blo shmobile_smp_boot_find_mpidr + + b shmobile_smp_sleep + +shmobile_smp_boot_found: + ldr r0, [r7, r1, lsl #2] + mov pc, r9 +ENDPROC(shmobile_smp_boot) + +ENTRY(shmobile_smp_sleep) + wfi + b shmobile_smp_boot +ENDPROC(shmobile_smp_sleep) + + .globl shmobile_smp_mpidr +shmobile_smp_mpidr: +1: .space CONFIG_NR_CPUS * 4 + .globl shmobile_smp_fn +shmobile_smp_fn: +2: .space CONFIG_NR_CPUS * 4 + .globl shmobile_smp_arg +shmobile_smp_arg: +3: .space CONFIG_NR_CPUS * 4 diff --git a/arch/arm/mach-shmobile/include/mach/clock.h b/arch/arm/mach-shmobile/include/mach/clock.h index 03e56074928..31b6417463e 100644 --- a/arch/arm/mach-shmobile/include/mach/clock.h +++ b/arch/arm/mach-shmobile/include/mach/clock.h @@ -1,6 +1,22 @@ #ifndef CLOCK_H #define CLOCK_H +#ifdef CONFIG_COMMON_CLK +/* temporary clock configuration helper for platform devices */ + +struct clk_name { + const char *clk; + const char *con_id; + const char *dev_id; +}; + +void shmobile_clk_workaround(const struct clk_name *clks, int nr_clks, + bool enable); + +#else /* CONFIG_COMMON_CLK */ +/* legacy clock implementation */ + +struct clk; unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk); extern struct sh_clk_ops shmobile_fixed_ratio_clk_ops; @@ -36,4 +52,5 @@ do { \ (p)->div = d; \ } while (0) +#endif /* CONFIG_COMMON_CLK */ #endif diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index e818f029d8e..f7a360edcc3 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -2,15 +2,30 @@ #define __ARCH_MACH_COMMON_H extern void shmobile_earlytimer_init(void); -extern void shmobile_timer_init(void); extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, unsigned int mult, unsigned int div); +extern void shmobile_init_delay(void); struct twd_local_timer; extern void shmobile_setup_console(void); extern void shmobile_boot_vector(void); extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_arg; +extern unsigned long shmobile_boot_size; +extern void shmobile_smp_boot(void); +extern void shmobile_smp_sleep(void); +extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, + unsigned long arg); +extern int shmobile_smp_cpu_disable(unsigned int cpu); +extern void shmobile_invalidate_start(void); extern void shmobile_boot_scu(void); +extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); +extern void shmobile_smp_scu_cpu_die(unsigned int cpu); +extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); +extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); +extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, + struct task_struct *idle); +extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); +extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); struct clk; extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); @@ -31,7 +46,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; } #endif extern void __iomem *shmobile_scu_base; -extern void shmobile_smp_init_cpus(unsigned int ncores); static inline void __init shmobile_init_late(void) { 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 40a8c178f10..00000000000 --- 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 deleted file mode 100644 index ac3751705ca..00000000000 --- a/arch/arm/mach-shmobile/include/mach/emev2.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ASM_EMEV2_H__ -#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_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)) - -extern struct smp_operations emev2_smp_ops; - -#endif /* __ASM_EMEV2_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/hardware.h b/arch/arm/mach-shmobile/include/mach/hardware.h deleted file mode 100644 index 99264a5ce5e..00000000000 --- a/arch/arm/mach-shmobile/include/mach/hardware.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __ASM_MACH_HARDWARE_H -#define __ASM_MACH_HARDWARE_H - -#endif /* __ASM_MACH_HARDWARE_H */ diff --git a/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt b/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt new file mode 100644 index 00000000000..9531f46a822 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/head-kzm9g.txt @@ -0,0 +1,410 @@ +LIST "KZM9G low-level initialization routine." +LIST "Adapted from u-boot KZM9G support code." + +LIST "Copyright (C) 2013 Ulrich Hecht" + +LIST "This program is free software; you can redistribute it and/or modify" +LIST "it under the terms of the GNU General Public License version 2 as" +LIST "published by the Free Software Foundation." + +LIST "This program is distributed in the hope that it will be useful," +LIST "but WITHOUT ANY WARRANTY; without even the implied warranty of" +LIST "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" +LIST "GNU General Public License for more details." + + +LIST "Register definitions:" + +LIST "Secure control register" +#define LIFEC_SEC_SRC (0xE6110008) + +LIST "RWDT" +#define RWDT_BASE (0xE6020000) +#define RWTCSRA0 (RWDT_BASE + 0x04) + +LIST "HPB Semaphore Control Registers" +#define HPBSCR_BASE (0xE6000000) +#define HPBCTRL6 (HPBSCR_BASE + 0x1030) + +#define SBSC1_BASE (0xFE400000) +#define SDCR0A (SBSC1_BASE + 0x0008) +#define SDCR1A (SBSC1_BASE + 0x000C) +#define SDPCRA (SBSC1_BASE + 0x0010) +#define SDCR0SA (SBSC1_BASE + 0x0018) +#define SDCR1SA (SBSC1_BASE + 0x001C) +#define RTCSRA (SBSC1_BASE + 0x0020) +#define RTCORA (SBSC1_BASE + 0x0028) +#define RTCORHA (SBSC1_BASE + 0x002C) +#define SDWCRC0A (SBSC1_BASE + 0x0040) +#define SDWCRC1A (SBSC1_BASE + 0x0044) +#define SDWCR00A (SBSC1_BASE + 0x0048) +#define SDWCR01A (SBSC1_BASE + 0x004C) +#define SDWCR10A (SBSC1_BASE + 0x0050) +#define SDWCR11A (SBSC1_BASE + 0x0054) +#define SDWCR2A (SBSC1_BASE + 0x0060) +#define SDWCRC2A (SBSC1_BASE + 0x0064) +#define ZQCCRA (SBSC1_BASE + 0x0068) +#define SDMRACR0A (SBSC1_BASE + 0x0084) +#define SDMRTMPCRA (SBSC1_BASE + 0x008C) +#define SDMRTMPMSKA (SBSC1_BASE + 0x0094) +#define SDGENCNTA (SBSC1_BASE + 0x009C) +#define SDDRVCR0A (SBSC1_BASE + 0x00B4) +#define DLLCNT0A (SBSC1_BASE + 0x0354) + +#define SDMRA1 (0xFE500000) +#define SDMRA2 (0xFE5C0000) +#define SDMRA3 (0xFE504000) + +#define SBSC2_BASE (0xFB400000) +#define SDCR0B (SBSC2_BASE + 0x0008) +#define SDCR1B (SBSC2_BASE + 0x000C) +#define SDPCRB (SBSC2_BASE + 0x0010) +#define SDCR0SB (SBSC2_BASE + 0x0018) +#define SDCR1SB (SBSC2_BASE + 0x001C) +#define RTCSRB (SBSC2_BASE + 0x0020) +#define RTCORB (SBSC2_BASE + 0x0028) +#define RTCORHB (SBSC2_BASE + 0x002C) +#define SDWCRC0B (SBSC2_BASE + 0x0040) +#define SDWCRC1B (SBSC2_BASE + 0x0044) +#define SDWCR00B (SBSC2_BASE + 0x0048) +#define SDWCR01B (SBSC2_BASE + 0x004C) +#define SDWCR10B (SBSC2_BASE + 0x0050) +#define SDWCR11B (SBSC2_BASE + 0x0054) +#define SDPDCR0B (SBSC2_BASE + 0x0058) +#define SDWCR2B (SBSC2_BASE + 0x0060) +#define SDWCRC2B (SBSC2_BASE + 0x0064) +#define ZQCCRB (SBSC2_BASE + 0x0068) +#define SDMRACR0B (SBSC2_BASE + 0x0084) +#define SDMRTMPCRB (SBSC2_BASE + 0x008C) +#define SDMRTMPMSKB (SBSC2_BASE + 0x0094) +#define SDGENCNTB (SBSC2_BASE + 0x009C) +#define DPHYCNT0B (SBSC2_BASE + 0x00A0) +#define DPHYCNT1B (SBSC2_BASE + 0x00A4) +#define DPHYCNT2B (SBSC2_BASE + 0x00A8) +#define SDDRVCR0B (SBSC2_BASE + 0x00B4) +#define DLLCNT0B (SBSC2_BASE + 0x0354) + +#define SDMRB1 (0xFB500000) +#define SDMRB2 (0xFB5C0000) +#define SDMRB3 (0xFB504000) + +#define CPG_BASE (0xE6150000) +#define FRQCRA (CPG_BASE + 0x0000) +#define FRQCRB (CPG_BASE + 0x0004) +#define FRQCRD (CPG_BASE + 0x00E4) +#define VCLKCR1 (CPG_BASE + 0x0008) +#define VCLKCR2 (CPG_BASE + 0x000C) +#define VCLKCR3 (CPG_BASE + 0x001C) +#define ZBCKCR (CPG_BASE + 0x0010) +#define FLCKCR (CPG_BASE + 0x0014) +#define SD0CKCR (CPG_BASE + 0x0074) +#define SD1CKCR (CPG_BASE + 0x0078) +#define SD2CKCR (CPG_BASE + 0x007C) +#define FSIACKCR (CPG_BASE + 0x0018) +#define SUBCKCR (CPG_BASE + 0x0080) +#define SPUACKCR (CPG_BASE + 0x0084) +#define SPUVCKCR (CPG_BASE + 0x0094) +#define MSUCKCR (CPG_BASE + 0x0088) +#define HSICKCR (CPG_BASE + 0x008C) +#define FSIBCKCR (CPG_BASE + 0x0090) +#define MFCK1CR (CPG_BASE + 0x0098) +#define MFCK2CR (CPG_BASE + 0x009C) +#define DSITCKCR (CPG_BASE + 0x0060) +#define DSI0PCKCR (CPG_BASE + 0x0064) +#define DSI1PCKCR (CPG_BASE + 0x0068) +#define DSI0PHYCR (CPG_BASE + 0x006C) +#define DVFSCR3 (CPG_BASE + 0x0174) +#define DVFSCR4 (CPG_BASE + 0x0178) +#define DVFSCR5 (CPG_BASE + 0x017C) +#define MPMODE (CPG_BASE + 0x00CC) + +#define PLLECR (CPG_BASE + 0x00D0) +#define PLL0CR (CPG_BASE + 0x00D8) +#define PLL1CR (CPG_BASE + 0x0028) +#define PLL2CR (CPG_BASE + 0x002C) +#define PLL3CR (CPG_BASE + 0x00DC) +#define PLL0STPCR (CPG_BASE + 0x00F0) +#define PLL1STPCR (CPG_BASE + 0x00C8) +#define PLL2STPCR (CPG_BASE + 0x00F8) +#define PLL3STPCR (CPG_BASE + 0x00FC) +#define RMSTPCR0 (CPG_BASE + 0x0110) +#define RMSTPCR1 (CPG_BASE + 0x0114) +#define RMSTPCR2 (CPG_BASE + 0x0118) +#define RMSTPCR3 (CPG_BASE + 0x011C) +#define RMSTPCR4 (CPG_BASE + 0x0120) +#define RMSTPCR5 (CPG_BASE + 0x0124) +#define SMSTPCR0 (CPG_BASE + 0x0130) +#define SMSTPCR2 (CPG_BASE + 0x0138) +#define SMSTPCR3 (CPG_BASE + 0x013C) +#define CPGXXCR4 (CPG_BASE + 0x0150) +#define SRCR0 (CPG_BASE + 0x80A0) +#define SRCR2 (CPG_BASE + 0x80B0) +#define SRCR3 (CPG_BASE + 0x80A8) +#define VREFCR (CPG_BASE + 0x00EC) +#define PCLKCR (CPG_BASE + 0x1020) + +#define PORT32CR (0xE6051020) +#define PORT33CR (0xE6051021) +#define PORT34CR (0xE6051022) +#define PORT35CR (0xE6051023) + +LIST "DRAM initialization code:" + +EW RWTCSRA0, 0xA507 + +ED_AND LIFEC_SEC_SRC, 0xFFFF7FFF + +ED_AND SMSTPCR3,0xFFFF7FFF +ED_AND SRCR3, 0xFFFF7FFF +ED_AND SMSTPCR2,0xFFFBFFFF +ED_AND SRCR2, 0xFFFBFFFF +ED PLLECR, 0x00000000 + +WAIT_MASK PLLECR, 0x00000F00, 0x00000000 +WAIT_MASK FRQCRB, 0x80000000, 0x00000000 + +ED PLL0CR, 0x2D000000 +ED PLL1CR, 0x17100000 +ED FRQCRB, 0x96235880 +WAIT_MASK FRQCRB, 0x80000000, 0x00000000 + +ED FLCKCR, 0x0000000B +ED_AND SMSTPCR0, 0xFFFFFFFD + +ED_AND SRCR0, 0xFFFFFFFD +ED 0xE6001628, 0x514 +ED 0xE6001648, 0x514 +ED 0xE6001658, 0x514 +ED 0xE6001678, 0x514 + +ED DVFSCR4, 0x00092000 +ED DVFSCR5, 0x000000DC +ED PLLECR, 0x00000000 +WAIT_MASK PLLECR, 0x00000F00, 0x00000000 + +ED FRQCRA, 0x0012453C +ED FRQCRB, 0x80431350 +WAIT_MASK FRQCRB, 0x80000000, 0x00000000 +ED FRQCRD, 0x00000B0B +WAIT_MASK FRQCRD, 0x80000000, 0x00000000 + +ED PCLKCR, 0x00000003 +ED VCLKCR1, 0x0000012F +ED VCLKCR2, 0x00000119 +ED VCLKCR3, 0x00000119 +ED ZBCKCR, 0x00000002 +ED FLCKCR, 0x00000005 +ED SD0CKCR, 0x00000080 +ED SD1CKCR, 0x00000080 +ED SD2CKCR, 0x00000080 +ED FSIACKCR, 0x0000003F +ED FSIBCKCR, 0x0000003F +ED SUBCKCR, 0x00000080 +ED SPUACKCR, 0x0000000B +ED SPUVCKCR, 0x0000000B +ED MSUCKCR, 0x0000013F +ED HSICKCR, 0x00000080 +ED MFCK1CR, 0x0000003F +ED MFCK2CR, 0x0000003F +ED DSITCKCR, 0x00000107 +ED DSI0PCKCR, 0x00000313 +ED DSI1PCKCR, 0x0000130D +ED DSI0PHYCR, 0x2A800E0E +ED PLL0CR, 0x1E000000 +ED PLL0CR, 0x2D000000 +ED PLL1CR, 0x17100000 +ED PLL2CR, 0x27000080 +ED PLL3CR, 0x1D000000 +ED PLL0STPCR, 0x00080000 +ED PLL1STPCR, 0x000120C0 +ED PLL2STPCR, 0x00012000 +ED PLL3STPCR, 0x00000030 +ED PLLECR, 0x0000000B +WAIT_MASK PLLECR, 0x00000B00, 0x00000B00 + +ED DVFSCR3, 0x000120F0 +ED MPMODE, 0x00000020 +ED VREFCR, 0x0000028A +ED RMSTPCR0, 0xE4628087 +ED RMSTPCR1, 0xFFFFFFFF +ED RMSTPCR2, 0x53FFFFFF +ED RMSTPCR3, 0xFFFFFFFF +ED RMSTPCR4, 0x00800D3D +ED RMSTPCR5, 0xFFFFF3FF +ED SMSTPCR2, 0x00000000 +ED SRCR2, 0x00040000 +ED_AND PLLECR, 0xFFFFFFF7 +WAIT_MASK PLLECR, 0x00000800, 0x00000000 + +LIST "set SBSC operational" +ED HPBCTRL6, 0x00000001 +WAIT_MASK HPBCTRL6, 0x00000001, 0x00000001 + +LIST "set SBSC operating frequency" +ED FRQCRD, 0x00001414 +WAIT_MASK FRQCRD, 0x80000000, 0x00000000 +ED PLL3CR, 0x1D000000 +ED_OR PLLECR, 0x00000008 +WAIT_MASK PLLECR, 0x00000800, 0x00000800 + +LIST "enable DLL oscillation in DDRPHY" +ED_OR DLLCNT0A, 0x00000002 + +LIST "wait >= 100 ns" +ED SDGENCNTA, 0x00000005 +WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 + +LIST "target LPDDR2 device settings" +ED SDCR0A, 0xACC90159 +ED SDCR1A, 0x00010059 +ED SDWCRC0A, 0x50874114 +ED SDWCRC1A, 0x33199B37 +ED SDWCRC2A, 0x008F2313 +ED SDWCR00A, 0x31020707 +ED SDWCR01A, 0x0017040A +ED SDWCR10A, 0x31020707 +ED SDWCR11A, 0x0017040A + +ED SDDRVCR0A, 0x055557ff + +ED SDWCR2A, 0x30000000 + +LIST "drive CKE high" +ED_OR SDPCRA, 0x00000080 +WAIT_MASK SDPCRA, 0x00000080, 0x00000080 + +LIST "wait >= 200 us" +ED SDGENCNTA, 0x00002710 +WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 + +LIST "issue reset command to LPDDR2 device" +ED SDMRACR0A, 0x0000003F +ED SDMRA1, 0x00000000 + +LIST "wait >= 10 (or 1) us (docs inconsistent)" +ED SDGENCNTA, 0x000001F4 +WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 + +LIST "MRW ZS initialization calibration command" +ED SDMRACR0A, 0x0000FF0A +ED SDMRA3, 0x00000000 + +LIST "wait >= 1 us" +ED SDGENCNTA, 0x00000032 +WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 + +LIST "specify operating mode in LPDDR2" +ED SDMRACR0A, 0x00002201 +ED SDMRA1, 0x00000000 +ED SDMRACR0A, 0x00000402 +ED SDMRA1, 0x00000000 +ED SDMRACR0A, 0x00000203 +ED SDMRA1, 0x00000000 + +LIST "initialize DDR interface" +ED SDMRA2, 0x00000000 + +LIST "temperature sensor control" +ED SDMRTMPCRA, 0x88800004 +ED SDMRTMPMSKA,0x00000004 + +LIST "auto-refreshing control" +ED RTCORA, 0xA55A0032 +ED RTCORHA, 0xA55A000C +ED RTCSRA, 0xA55A2048 + +ED_OR SDCR0A, 0x00000800 +ED_OR SDCR1A, 0x00000400 + +LIST "auto ZQ calibration control" +ED ZQCCRA, 0xFFF20000 + +ED_OR DLLCNT0B, 0x00000002 +ED SDGENCNTB, 0x00000005 +WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 + +ED SDCR0B, 0xACC90159 +ED SDCR1B, 0x00010059 +ED SDWCRC0B, 0x50874114 +ED SDWCRC1B, 0x33199B37 +ED SDWCRC2B, 0x008F2313 +ED SDWCR00B, 0x31020707 +ED SDWCR01B, 0x0017040A +ED SDWCR10B, 0x31020707 +ED SDWCR11B, 0x0017040A +ED SDDRVCR0B, 0x055557ff +ED SDWCR2B, 0x30000000 +ED_OR SDPCRB, 0x00000080 +WAIT_MASK SDPCRB, 0x00000080, 0x00000080 + +ED SDGENCNTB, 0x00002710 +WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 +ED SDMRACR0B, 0x0000003F + +LIST "upstream u-boot writes to SDMRA1A for both SBSC 1 and 2, which does" +LIST "not seem to make a lot of sense..." +ED SDMRB1, 0x00000000 + +ED SDGENCNTB, 0x000001F4 +WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 + +ED SDMRACR0B, 0x0000FF0A +ED SDMRB3, 0x00000000 +ED SDGENCNTB, 0x00000032 +WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 + +ED SDMRACR0B, 0x00002201 +ED SDMRB1, 0x00000000 +ED SDMRACR0B, 0x00000402 +ED SDMRB1, 0x00000000 +ED SDMRACR0B, 0x00000203 +ED SDMRB1, 0x00000000 +ED SDMRB2, 0x00000000 +ED SDMRTMPCRB, 0x88800004 +ED SDMRTMPMSKB, 0x00000004 +ED RTCORB, 0xA55A0032 +ED RTCORHB, 0xA55A000C +ED RTCSRB, 0xA55A2048 +ED_OR SDCR0B, 0x00000800 +ED_OR SDCR1B, 0x00000400 +ED ZQCCRB, 0xFFF20000 +ED_OR SDPDCR0B, 0x00030000 +ED DPHYCNT1B, 0xA5390000 +ED DPHYCNT0B, 0x00001200 +ED DPHYCNT1B, 0x07CE0000 +ED DPHYCNT0B, 0x00001247 +WAIT_MASK DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000 + +ED_AND SDPDCR0B, 0xFFFCFFFF + +ED FRQCRD, 0x00000B0B +WAIT_MASK FRQCRD, 0x80000000, 0x00000000 + +ED CPGXXCR4, 0xfffffffc + +LIST "Setup SCIF4 / workaround" +EB PORT32CR, 0x12 +EB PORT33CR, 0x22 +EB PORT34CR, 0x12 +EB PORT35CR, 0x22 + +EW 0xE6C80000, 0 +EB 0xE6C80004, 0x19 +EW 0xE6C80008, 0x0030 +EW 0xE6C80018, 0 +EW 0xE6C80030, 0x0014 + +LIST "Magic to avoid hangs and corruption on DRAM writes." + +LIST "It has been observed that the system would most often hang while" +LIST "decompressing the kernel, and if it didn't it would always write" +LIST "a corrupt image to DRAM." +LIST "This problem does not occur in u-boot, and the reason is that" +LIST "u-boot performs an additional cache invalidation after setting up" +LIST "the DRAM controller. Such an invalidation should not be necessary at" +LIST "this point, and attempts at removing parts of the routine to arrive" +LIST "at the minimal snippet of code necessary to avoid the DRAM stability" +LIST "problem yielded the following:" + +MRC p15, 0, r0, c1, c0, 0 +MCR p15, 0, r0, c1, c0, 0 diff --git a/arch/arm/mach-shmobile/include/mach/pm-rcar.h b/arch/arm/mach-shmobile/include/mach/pm-rcar.h new file mode 100644 index 00000000000..ef3a1ef628f --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/pm-rcar.h @@ -0,0 +1,15 @@ +#ifndef PM_RCAR_H +#define PM_RCAR_H + +struct rcar_sysc_ch { + unsigned long chan_offs; + unsigned int chan_bit; + unsigned int isr_bit; +}; + +int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch); +int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch); +bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch); +void __iomem *rcar_sysc_init(phys_addr_t base); + +#endif /* PM_RCAR_H */ diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h new file mode 100644 index 00000000000..5f34b20ecd4 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h @@ -0,0 +1,8 @@ +#ifndef __ASM_R7S72100_H__ +#define __ASM_R7S72100_H__ + +void r7s72100_add_dt_devices(void); +void r7s72100_clock_init(void); +void r7s72100_init_early(void); + +#endif /* __ASM_R7S72100_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h index f043103e32c..ce8bdd1d8a8 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h +++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h @@ -1,8 +1,19 @@ #ifndef __ASM_R8A73A4_H__ #define __ASM_R8A73A4_H__ +/* DMA slave IDs */ +enum { + SHDMA_SLAVE_INVALID, + SHDMA_SLAVE_MMCIF0_TX, + SHDMA_SLAVE_MMCIF0_RX, + SHDMA_SLAVE_MMCIF1_TX, + SHDMA_SLAVE_MMCIF1_RX, +}; + void r8a73a4_add_standard_devices(void); +void r8a73a4_add_dt_devices(void); void r8a73a4_clock_init(void); void r8a73a4_pinmux_init(void); +void r8a73a4_init_early(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 b34d19b5ca5..5e3c9ec0630 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7740.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h @@ -42,11 +42,11 @@ 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); -extern void r8a7740_init_delay(void); -extern void r8a7740_init_irq(void); extern void r8a7740_init_irq_of(void); extern void r8a7740_map_io(void); extern void r8a7740_add_early_devices(void); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index 851d027a2f0..f4076a50e97 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2013 Renesas Solutions Corp. * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * Copyright (C) 2013 Cogent Embedded, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,26 +19,65 @@ #ifndef __ASM_R8A7778_H__ #define __ASM_R8A7778_H__ -#include <linux/mmc/sh_mmcif.h> -#include <linux/mmc/sh_mobile_sdhi.h> #include <linux/sh_eth.h> -#include <linux/platform_data/usb-rcar-phy.h> + +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, + HPBDMA_SLAVE_SSI0_TX, + HPBDMA_SLAVE_SSI0_RX, + HPBDMA_SLAVE_SSI1_TX, + HPBDMA_SLAVE_SSI1_RX, + HPBDMA_SLAVE_SSI2_TX, + HPBDMA_SLAVE_SSI2_RX, + HPBDMA_SLAVE_SSI3_TX, + HPBDMA_SLAVE_SSI3_RX, + HPBDMA_SLAVE_SSI4_TX, + HPBDMA_SLAVE_SSI4_RX, + HPBDMA_SLAVE_SSI5_TX, + HPBDMA_SLAVE_SSI5_RX, + HPBDMA_SLAVE_SSI6_TX, + HPBDMA_SLAVE_SSI6_RX, + HPBDMA_SLAVE_SSI7_TX, + HPBDMA_SLAVE_SSI7_RX, + HPBDMA_SLAVE_SSI8_TX, + HPBDMA_SLAVE_SSI8_RX, + HPBDMA_SLAVE_HPBIF0_TX, + HPBDMA_SLAVE_HPBIF0_RX, + HPBDMA_SLAVE_HPBIF1_TX, + HPBDMA_SLAVE_HPBIF1_RX, + HPBDMA_SLAVE_HPBIF2_TX, + HPBDMA_SLAVE_HPBIF2_RX, + HPBDMA_SLAVE_HPBIF3_TX, + HPBDMA_SLAVE_HPBIF3_RX, + HPBDMA_SLAVE_HPBIF4_TX, + HPBDMA_SLAVE_HPBIF4_RX, + HPBDMA_SLAVE_HPBIF5_TX, + HPBDMA_SLAVE_HPBIF5_RX, + HPBDMA_SLAVE_HPBIF6_TX, + HPBDMA_SLAVE_HPBIF6_RX, + HPBDMA_SLAVE_HPBIF7_TX, + HPBDMA_SLAVE_HPBIF7_RX, + HPBDMA_SLAVE_HPBIF8_TX, + HPBDMA_SLAVE_HPBIF8_RX, + HPBDMA_SLAVE_USBFUNC_TX, + HPBDMA_SLAVE_USBFUNC_RX, +}; extern void r8a7778_add_standard_devices(void); extern void r8a7778_add_standard_devices_dt(void); -extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); -extern void r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata); -extern void r8a7778_add_i2c_device(int id); -extern void r8a7778_add_hspi_device(int id); -extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info); +extern void r8a7778_add_dt_devices(void); 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); +extern void r8a7778_init_irq_extpin_dt(int irlm); extern void r8a7778_pinmux_init(void); -extern void r8a7778_sdhi_init(int id, struct sh_mobile_sdhi_info *info); + +extern int r8a7778_usb_phy_power(bool enable); #endif /* __ASM_R8A7778_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index fc47073c7ba..88eeceaf108 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -3,45 +3,39 @@ #include <linux/sh_clk.h> #include <linux/pm_domain.h> -#include <linux/sh_eth.h> -#include <linux/platform_data/usb-rcar-phy.h> +#include <mach/pm-rcar.h> -struct platform_device; - -struct r8a7779_pm_ch { - unsigned long chan_offs; - unsigned int chan_bit; - unsigned int isr_bit; +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, }; struct r8a7779_pm_domain { struct generic_pm_domain genpd; - struct r8a7779_pm_ch ch; + struct rcar_sysc_ch ch; }; -static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d) +static inline struct rcar_sysc_ch *to_r8a7779_ch(struct generic_pm_domain *d) { return &container_of(d, struct r8a7779_pm_domain, genpd)->ch; } extern void r8a7779_init_delay(void); -extern void r8a7779_init_irq(void); extern void r8a7779_init_irq_extpin(int irlm); +extern void r8a7779_init_irq_extpin_dt(int irlm); extern void r8a7779_init_irq_dt(void); extern void r8a7779_map_io(void); extern void r8a7779_earlytimer_init(void); extern void r8a7779_add_early_devices(void); extern void r8a7779_add_standard_devices(void); extern void r8a7779_add_standard_devices_dt(void); -extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata); -extern void r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata); extern void r8a7779_init_late(void); extern void r8a7779_clock_init(void); extern void r8a7779_pinmux_init(void); extern void r8a7779_pm_init(void); extern void r8a7779_register_twd(void); -extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch); -extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch); #ifdef CONFIG_PM extern void __init r8a7779_init_pm_domains(void); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 2e919e61fa0..0b95babe84b 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h @@ -1,9 +1,39 @@ #ifndef __ASM_R8A7790_H__ #define __ASM_R8A7790_H__ +#include <mach/rcar-gen2.h> + +/* DMA slave IDs */ +enum { + RCAR_DMA_SLAVE_INVALID, + AUDIO_DMAC_SLAVE_SSI0_TX, + AUDIO_DMAC_SLAVE_SSI0_RX, + AUDIO_DMAC_SLAVE_SSI1_TX, + AUDIO_DMAC_SLAVE_SSI1_RX, + AUDIO_DMAC_SLAVE_SSI2_TX, + AUDIO_DMAC_SLAVE_SSI2_RX, + AUDIO_DMAC_SLAVE_SSI3_TX, + AUDIO_DMAC_SLAVE_SSI3_RX, + AUDIO_DMAC_SLAVE_SSI4_TX, + AUDIO_DMAC_SLAVE_SSI4_RX, + AUDIO_DMAC_SLAVE_SSI5_TX, + AUDIO_DMAC_SLAVE_SSI5_RX, + AUDIO_DMAC_SLAVE_SSI6_TX, + AUDIO_DMAC_SLAVE_SSI6_RX, + AUDIO_DMAC_SLAVE_SSI7_TX, + AUDIO_DMAC_SLAVE_SSI7_RX, + AUDIO_DMAC_SLAVE_SSI8_TX, + AUDIO_DMAC_SLAVE_SSI8_RX, + AUDIO_DMAC_SLAVE_SSI9_TX, + AUDIO_DMAC_SLAVE_SSI9_RX, +}; + void r8a7790_add_standard_devices(void); +void r8a7790_add_dt_devices(void); void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); -void r8a7790_timer_init(void); +void r8a7790_pm_init(void); +void r8a7790_init_early(void); +extern struct smp_operations r8a7790_smp_ops; #endif /* __ASM_R8A7790_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h new file mode 100644 index 00000000000..664274cc4b6 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -0,0 +1,10 @@ +#ifndef __ASM_R8A7791_H__ +#define __ASM_R8A7791_H__ + +void r8a7791_add_standard_devices(void); +void r8a7791_add_dt_devices(void); +void r8a7791_clock_init(void); +void r8a7791_pinmux_init(void); +extern struct smp_operations r8a7791_smp_ops; + +#endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/rcar-gen2.h b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h new file mode 100644 index 00000000000..43f606eb2d8 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h @@ -0,0 +1,8 @@ +#ifndef __ASM_RCAR_GEN2_H__ +#define __ASM_RCAR_GEN2_H__ + +void rcar_gen2_timer_init(void); +#define MD(nr) BIT(nr) +u32 rcar_gen2_read_mode_pins(void); + +#endif /* __ASM_RCAR_GEN2_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h index eb7a4320d48..359b582dc27 100644 --- a/arch/arm/mach-shmobile/include/mach/sh73a0.h +++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h @@ -1,379 +1,6 @@ #ifndef __ASM_SH73A0_H__ #define __ASM_SH73A0_H__ -/* Pin Function Controller: - * GPIO_FN_xx - GPIO used to select pin function and MSEL switch - * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU - */ -enum { - /* Hardware manual Table 25-1 (GPIO) */ - 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_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_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, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214, - GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219, - - GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224, - GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229, - - GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234, - GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239, - - GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244, - GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249, - - GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254, - GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259, - - GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264, - GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269, - - GPIO_PORT270, GPIO_PORT271, GPIO_PORT272, GPIO_PORT273, GPIO_PORT274, - GPIO_PORT275, GPIO_PORT276, GPIO_PORT277, GPIO_PORT278, GPIO_PORT279, - - GPIO_PORT280, GPIO_PORT281, GPIO_PORT282, - - GPIO_PORT288, GPIO_PORT289, - - GPIO_PORT290, GPIO_PORT291, GPIO_PORT292, GPIO_PORT293, GPIO_PORT294, - GPIO_PORT295, GPIO_PORT296, GPIO_PORT297, GPIO_PORT298, GPIO_PORT299, - - GPIO_PORT300, GPIO_PORT301, GPIO_PORT302, GPIO_PORT303, GPIO_PORT304, - GPIO_PORT305, GPIO_PORT306, GPIO_PORT307, GPIO_PORT308, GPIO_PORT309, - - /* Table 25-1 (Function 0-7) */ - GPIO_FN_GPI0 = 310, - GPIO_FN_GPI1, - GPIO_FN_GPI2, - GPIO_FN_GPI3, - GPIO_FN_GPI4, - GPIO_FN_GPI5, - GPIO_FN_GPI6, - GPIO_FN_GPI7, - GPIO_FN_GPO7, GPIO_FN_MFG0_OUT2, - GPIO_FN_GPO6, GPIO_FN_MFG1_OUT2, - GPIO_FN_GPO5, - GPIO_FN_PORT16_VIO_CKOR, - GPIO_FN_PORT19_VIO_CKO2, - GPIO_FN_GPO0, - GPIO_FN_GPO1, - GPIO_FN_GPO2, GPIO_FN_STATUS0, - GPIO_FN_GPO3, GPIO_FN_STATUS1, - GPIO_FN_GPO4, GPIO_FN_STATUS2, - GPIO_FN_VINT, - GPIO_FN_TCKON, - GPIO_FN_XDVFS1, - GPIO_FN_MFG0_OUT1, GPIO_FN_PORT27_IROUT, - GPIO_FN_XDVFS2, - GPIO_FN_PORT28_TPU1TO1, - GPIO_FN_SIM_RST, GPIO_FN_PORT29_TPU1TO1, - GPIO_FN_SIM_CLK, GPIO_FN_PORT30_VIO_CKOR, - GPIO_FN_SIM_D, GPIO_FN_PORT31_IROUT, - GPIO_FN_XWUP, - GPIO_FN_VACK, - GPIO_FN_XTAL1L, - GPIO_FN_PORT49_IROUT, - GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, - - GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, - GPIO_FN_BBIF2_TXD2, - GPIO_FN_TPU3TO3, - GPIO_FN_TPU3TO2, - GPIO_FN_TPU0TO0, - GPIO_FN_A0, GPIO_FN_BS_, - GPIO_FN_A12, GPIO_FN_TPU4TO2, - GPIO_FN_A13, GPIO_FN_TPU0TO1, - GPIO_FN_A14, - GPIO_FN_A15, - GPIO_FN_A16, GPIO_FN_MSIOF0_SS1, - GPIO_FN_A17, GPIO_FN_MSIOF0_TSYNC, - GPIO_FN_A18, GPIO_FN_MSIOF0_TSCK, - GPIO_FN_A19, GPIO_FN_MSIOF0_TXD, - GPIO_FN_A20, GPIO_FN_MSIOF0_RSCK, - GPIO_FN_A21, GPIO_FN_MSIOF0_RSYNC, - GPIO_FN_A22, GPIO_FN_MSIOF0_MCK0, - GPIO_FN_A23, GPIO_FN_MSIOF0_MCK1, - GPIO_FN_A24, GPIO_FN_MSIOF0_RXD, - GPIO_FN_A25, GPIO_FN_MSIOF0_SS2, - GPIO_FN_A26, - GPIO_FN_FCE1_, - GPIO_FN_DACK0, - GPIO_FN_FCE0_, - GPIO_FN_WAIT_, GPIO_FN_DREQ0, - GPIO_FN_FRB, - GPIO_FN_CKO, - GPIO_FN_NBRSTOUT_, - GPIO_FN_NBRST_, - GPIO_FN_BBIF2_TXD, - GPIO_FN_BBIF2_RXD, - GPIO_FN_BBIF2_SYNC, - GPIO_FN_BBIF2_SCK, - GPIO_FN_MFG3_IN2, - GPIO_FN_MFG3_IN1, - GPIO_FN_BBIF1_SS2, GPIO_FN_MFG3_OUT1, - GPIO_FN_HSI_RX_DATA, GPIO_FN_BBIF1_RXD, - GPIO_FN_HSI_TX_WAKE, GPIO_FN_BBIF1_TSCK, - GPIO_FN_HSI_TX_DATA, GPIO_FN_BBIF1_TSYNC, - GPIO_FN_HSI_TX_READY, GPIO_FN_BBIF1_TXD, - GPIO_FN_HSI_RX_READY, GPIO_FN_BBIF1_RSCK, - GPIO_FN_HSI_RX_WAKE, GPIO_FN_BBIF1_RSYNC, - GPIO_FN_HSI_RX_FLAG, GPIO_FN_BBIF1_SS1, GPIO_FN_BBIF1_FLOW, - GPIO_FN_HSI_TX_FLAG, - GPIO_FN_VIO_VD, GPIO_FN_VIO2_VD, - - GPIO_FN_VIO_HD, - GPIO_FN_VIO2_HD, - GPIO_FN_VIO_D0, GPIO_FN_PORT130_MSIOF2_RXD, - GPIO_FN_VIO_D1, GPIO_FN_PORT131_MSIOF2_SS1, - GPIO_FN_VIO_D2, GPIO_FN_PORT132_MSIOF2_SS2, - GPIO_FN_VIO_D3, GPIO_FN_MSIOF2_TSYNC, - GPIO_FN_VIO_D4, GPIO_FN_MSIOF2_TXD, - GPIO_FN_VIO_D5, GPIO_FN_MSIOF2_TSCK, - GPIO_FN_VIO_D6, - GPIO_FN_VIO_D7, - GPIO_FN_VIO_D8, GPIO_FN_VIO2_D0, - GPIO_FN_VIO_D9, GPIO_FN_VIO2_D1, - GPIO_FN_VIO_D10, GPIO_FN_TPU0TO2, GPIO_FN_VIO2_D2, - GPIO_FN_VIO_D11, GPIO_FN_TPU0TO3, GPIO_FN_VIO2_D3, - GPIO_FN_VIO_D12, GPIO_FN_VIO2_D4, - GPIO_FN_VIO_D13, - GPIO_FN_VIO2_D5, - GPIO_FN_VIO_D14, GPIO_FN_VIO2_D6, - GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, - GPIO_FN_VIO2_D7, - GPIO_FN_VIO_CLK, - GPIO_FN_VIO2_CLK, - GPIO_FN_VIO_FIELD, GPIO_FN_VIO2_FIELD, - GPIO_FN_VIO_CKO, - GPIO_FN_A27, GPIO_FN_MFG0_IN1, - GPIO_FN_MFG0_IN2, - GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK, - GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC, - GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1, - GPIO_FN_MSIOF2_MCK0, - GPIO_FN_MSIOF2_MCK1, - GPIO_FN_PORT156_MSIOF2_SS2, - GPIO_FN_PORT157_MSIOF2_RXD, - GPIO_FN_DINT_, GPIO_FN_TS_SCK3, - GPIO_FN_NMI, - GPIO_FN_TPU3TO0, - GPIO_FN_BBIF2_TSYNC1, - GPIO_FN_BBIF2_TSCK1, - GPIO_FN_BBIF2_TXD1, - GPIO_FN_MFG2_OUT2, - GPIO_FN_TPU2TO1, - GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2, - GPIO_FN_D16, - GPIO_FN_D17, - GPIO_FN_D18, - GPIO_FN_D19, - GPIO_FN_D20, - GPIO_FN_D21, - GPIO_FN_D22, - GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_D23, - GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_D24, - GPIO_FN_D25, - GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26, - GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27, - GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28, - GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29, - GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30, - GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31, - GPIO_FN_DACK2, - GPIO_FN_MSIOF0L_TSYNC, GPIO_FN_VIO2_FIELD3, - GPIO_FN_DACK3, - GPIO_FN_PORT218_VIO_CKOR, - GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK, GPIO_FN_VIO2_CLK3, \ - GPIO_FN_DREQ1, - GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD, GPIO_FN_VIO2_HD3, \ - GPIO_FN_DACK1, GPIO_FN_OVCN, - GPIO_FN_MSIOF0L_TXD, GPIO_FN_VIO2_VD3, - - GPIO_FN_OVCN2, - GPIO_FN_EXTLP, GPIO_FN_PORT226_VIO_CKO2, - GPIO_FN_IDIN, - GPIO_FN_MFG1_IN1, - GPIO_FN_MSIOF1_TXD, - GPIO_FN_MSIOF1_TSYNC, - GPIO_FN_MSIOF1_TSCK, - GPIO_FN_MSIOF1_RXD, - GPIO_FN_MSIOF1_RSCK, GPIO_FN_VIO2_CLK2, - GPIO_FN_MSIOF1_RSYNC, GPIO_FN_MFG1_IN2, GPIO_FN_VIO2_VD2, \ - GPIO_FN_MSIOF1_MCK0, - GPIO_FN_MSIOF1_MCK1, - GPIO_FN_MSIOF1_SS1, GPIO_FN_VIO2_FIELD2, - GPIO_FN_MSIOF1_SS2, GPIO_FN_VIO2_HD2, - GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1, \ - GPIO_FN_TPU4TO0, - GPIO_FN_MFG4_IN2, - GPIO_FN_PORT243_VIO_CKO2, - GPIO_FN_MFG2_IN1, - GPIO_FN_MSIOF2R_RXD, - GPIO_FN_MFG2_IN2, - GPIO_FN_MSIOF2R_TXD, - GPIO_FN_MFG1_OUT1, - GPIO_FN_TPU1TO0, - GPIO_FN_MFG3_OUT2, - GPIO_FN_TPU3TO1, - GPIO_FN_MFG2_OUT1, - GPIO_FN_TPU2TO0, - GPIO_FN_MSIOF2R_TSCK, - GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, \ - GPIO_FN_MSIOF2R_TSYNC, - GPIO_FN_SDHICLK0, - GPIO_FN_SDHICD0, - GPIO_FN_SDHID0_0, - GPIO_FN_SDHID0_1, - GPIO_FN_SDHID0_2, - GPIO_FN_SDHID0_3, - GPIO_FN_SDHICMD0, - GPIO_FN_SDHIWP0, - GPIO_FN_SDHICLK1, - GPIO_FN_SDHID1_0, GPIO_FN_TS_SPSYNC2, - GPIO_FN_SDHID1_1, GPIO_FN_TS_SDAT2, - GPIO_FN_SDHID1_2, GPIO_FN_TS_SDEN2, - GPIO_FN_SDHID1_3, GPIO_FN_TS_SCK2, - GPIO_FN_SDHICMD1, - GPIO_FN_SDHICLK2, - GPIO_FN_SDHID2_0, GPIO_FN_TS_SPSYNC4, - GPIO_FN_SDHID2_1, GPIO_FN_TS_SDAT4, - GPIO_FN_SDHID2_2, GPIO_FN_TS_SDEN4, - GPIO_FN_SDHID2_3, GPIO_FN_TS_SCK4, - GPIO_FN_SDHICMD2, - GPIO_FN_MMCCLK0, - GPIO_FN_MMCD0_0, - GPIO_FN_MMCD0_1, - GPIO_FN_MMCD0_2, - GPIO_FN_MMCD0_3, - GPIO_FN_MMCD0_4, GPIO_FN_TS_SPSYNC5, - GPIO_FN_MMCD0_5, GPIO_FN_TS_SDAT5, - GPIO_FN_MMCD0_6, GPIO_FN_TS_SDEN5, - GPIO_FN_MMCD0_7, GPIO_FN_TS_SCK5, - GPIO_FN_MMCCMD0, - GPIO_FN_RESETOUTS_, GPIO_FN_EXTAL2OUT, - GPIO_FN_MCP_WAIT__MCP_FRB, - GPIO_FN_MCP_CKO, GPIO_FN_MMCCLK1, - GPIO_FN_MCP_D15_MCP_NAF15, - GPIO_FN_MCP_D14_MCP_NAF14, - GPIO_FN_MCP_D13_MCP_NAF13, - GPIO_FN_MCP_D12_MCP_NAF12, - GPIO_FN_MCP_D11_MCP_NAF11, - GPIO_FN_MCP_D10_MCP_NAF10, - GPIO_FN_MCP_D9_MCP_NAF9, - GPIO_FN_MCP_D8_MCP_NAF8, GPIO_FN_MMCCMD1, - GPIO_FN_MCP_D7_MCP_NAF7, GPIO_FN_MMCD1_7, - - GPIO_FN_MCP_D6_MCP_NAF6, GPIO_FN_MMCD1_6, - GPIO_FN_MCP_D5_MCP_NAF5, GPIO_FN_MMCD1_5, - GPIO_FN_MCP_D4_MCP_NAF4, GPIO_FN_MMCD1_4, - GPIO_FN_MCP_D3_MCP_NAF3, GPIO_FN_MMCD1_3, - GPIO_FN_MCP_D2_MCP_NAF2, GPIO_FN_MMCD1_2, - GPIO_FN_MCP_D1_MCP_NAF1, GPIO_FN_MMCD1_1, - GPIO_FN_MCP_D0_MCP_NAF0, GPIO_FN_MMCD1_0, - GPIO_FN_MCP_NBRSTOUT_, - GPIO_FN_MCP_WE0__MCP_FWE, GPIO_FN_MCP_RDWR_MCP_FWE, - - /* MSEL2 special case */ - GPIO_FN_TSIF2_TS_XX1, - GPIO_FN_TSIF2_TS_XX2, - GPIO_FN_TSIF2_TS_XX3, - GPIO_FN_TSIF2_TS_XX4, - GPIO_FN_TSIF2_TS_XX5, - GPIO_FN_TSIF1_TS_XX1, - GPIO_FN_TSIF1_TS_XX2, - GPIO_FN_TSIF1_TS_XX3, - GPIO_FN_TSIF1_TS_XX4, - GPIO_FN_TSIF1_TS_XX5, - GPIO_FN_TSIF0_TS_XX1, - GPIO_FN_TSIF0_TS_XX2, - GPIO_FN_TSIF0_TS_XX3, - GPIO_FN_TSIF0_TS_XX4, - GPIO_FN_TSIF0_TS_XX5, - GPIO_FN_MST1_TS_XX1, - GPIO_FN_MST1_TS_XX2, - GPIO_FN_MST1_TS_XX3, - GPIO_FN_MST1_TS_XX4, - GPIO_FN_MST1_TS_XX5, - GPIO_FN_MST0_TS_XX1, - GPIO_FN_MST0_TS_XX2, - GPIO_FN_MST0_TS_XX3, - GPIO_FN_MST0_TS_XX4, - GPIO_FN_MST0_TS_XX5, - - /* MSEL3 special cases */ - GPIO_FN_SDHI0_VCCQ_MC0_ON, - GPIO_FN_SDHI0_VCCQ_MC0_OFF, - GPIO_FN_DEBUG_MON_VIO, - GPIO_FN_DEBUG_MON_LCDD, - GPIO_FN_LCDC_LCDC0, - GPIO_FN_LCDC_LCDC1, - - /* MSEL4 special cases */ - GPIO_FN_IRQ9_MEM_INT, - GPIO_FN_IRQ9_MCP_INT, - GPIO_FN_A11, - GPIO_FN_TPU4TO3, - GPIO_FN_RESETA_N_PU_ON, - GPIO_FN_RESETA_N_PU_OFF, - GPIO_FN_EDBGREQ_PD, - GPIO_FN_EDBGREQ_PU, - - /* end of GPIO */ - GPIO_NR, -}; - /* DMA slave IDs */ enum { SHDMA_SLAVE_INVALID, diff --git a/arch/arm/mach-shmobile/include/mach/timex.h b/arch/arm/mach-shmobile/include/mach/timex.h deleted file mode 100644 index ae0d8d825c2..00000000000 --- a/arch/arm/mach-shmobile/include/mach/timex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_MACH_TIMEX_H -#define __ASM_MACH_TIMEX_H - -#define CLOCK_TICK_RATE 1193180 /* unused i8253 PIT value */ - -#endif /* __ASM_MACH_TIMEX_H */ diff --git a/arch/arm/mach-shmobile/include/mach/zboot.h b/arch/arm/mach-shmobile/include/mach/zboot.h index f2d8744c1f1..727cc78ac8e 100644 --- a/arch/arm/mach-shmobile/include/mach/zboot.h +++ b/arch/arm/mach-shmobile/include/mach/zboot.h @@ -1,7 +1,6 @@ #ifndef ZBOOT_H #define ZBOOT_H -#include <asm/mach-types.h> #include <mach/zboot_macros.h> /************************************************** @@ -11,9 +10,11 @@ **************************************************/ #ifdef CONFIG_MACH_MACKEREL -#define MACH_TYPE MACH_TYPE_MACKEREL #define MEMORY_START 0x40000000 #include "mach/head-mackerel.txt" +#elif defined(CONFIG_MACH_KZM9G) || defined(CONFIG_MACH_KZM9G_REFERENCE) +#define MEMORY_START 0x43000000 +#include "mach/head-kzm9g.txt" #else #error "unsupported board." #endif diff --git a/arch/arm/mach-shmobile/include/mach/zboot_macros.h b/arch/arm/mach-shmobile/include/mach/zboot_macros.h index aa6111fbc98..14fd3d538e9 100644 --- a/arch/arm/mach-shmobile/include/mach/zboot_macros.h +++ b/arch/arm/mach-shmobile/include/mach/zboot_macros.h @@ -62,4 +62,47 @@ 2 : .endm +/* loop until a given value has been read (with mask) */ +.macro WAIT_MASK, addr, data, cmp + LDR r0, 2f + LDR r1, 3f + LDR r2, 4f +1: + LDR r3, [r0, #0] + AND r3, r1, r3 + CMP r2, r3 + BNE 1b + B 5f +2: .long \addr +3: .long \data +4: .long \cmp +5: +.endm + +/* read 32-bit value from addr, "or" an immediate and write back */ +.macro ED_OR, addr, data + LDR r4, 1f + LDR r5, 2f + LDR r6, [r4] + ORR r5, r6, r5 + STR r5, [r4] + B 3f +1: .long \addr +2: .long \data +3: +.endm + +/* read 32-bit value from addr, "and" an immediate and write back */ +.macro ED_AND, addr, data + LDR r4, 1f + LDR r5, 2f + LDR r6, [r4] + AND r5, r6, r5 + STR r5, [r4] + B 3f +1: .long \addr +2: .long \data +3: +.endm + #endif /* __ZBOOT_MACRO_H */ diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c deleted file mode 100644 index 8871f7717dc..00000000000 --- a/arch/arm/mach-shmobile/intc-r8a7740.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * R8A7740 processor support - * - * Copyright (C) 2011 Renesas Solutions Corp. - * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 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/io.h> -#include <linux/irqchip.h> -#include <linux/irqchip/arm-gic.h> - -static void __init r8a7740_init_irq_common(void) -{ - void __iomem *intc_prio_base = ioremap_nocache(0xe6900010, 0x10); - void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10); - void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4); - - /* route signals to GIC */ - iowrite32(0x0, pfc_inta_ctrl); - - /* - * To mask the shared interrupt to SPI 149 we must ensure to set - * PRIO *and* MASK. Else we run into IRQ floods when registering - * the intc_irqpin devices - */ - iowrite32(0x0, intc_prio_base + 0x0); - iowrite32(0x0, intc_prio_base + 0x4); - iowrite32(0x0, intc_prio_base + 0x8); - iowrite32(0x0, intc_prio_base + 0xc); - iowrite8(0xff, intc_msk_base + 0x0); - iowrite8(0xff, intc_msk_base + 0x4); - iowrite8(0xff, intc_msk_base + 0x8); - iowrite8(0xff, intc_msk_base + 0xc); - - iounmap(intc_prio_base); - iounmap(intc_msk_base); - iounmap(pfc_inta_ctrl); -} - -void __init r8a7740_init_irq_of(void) -{ - irqchip_init(); - r8a7740_init_irq_common(); -} - -void __init r8a7740_init_irq(void) -{ - void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000); - void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000); - - /* initialize the Generic Interrupt Controller PL390 r0p0 */ - gic_init(0, 29, gic_dist_base, gic_cpu_base); - r8a7740_init_irq_common(); -} diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c deleted file mode 100644 index b86dc890872..00000000000 --- a/arch/arm/mach-shmobile/intc-r8a7779.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * r8a7779 processor support - INTC hardware block - * - * Copyright (C) 2011 Renesas Solutions Corp. - * Copyright (C) 2011 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/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/irqchip/arm-gic.h> -#include <linux/platform_data/irq-renesas-intc-irqpin.h> -#include <linux/irqchip.h> -#include <mach/common.h> -#include <mach/intc.h> -#include <mach/irqs.h> -#include <mach/r8a7779.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#define INT2SMSKCR0 IOMEM(0xfe7822a0) -#define INT2SMSKCR1 IOMEM(0xfe7822a4) -#define INT2SMSKCR2 IOMEM(0xfe7822a8) -#define INT2SMSKCR3 IOMEM(0xfe7822ac) -#define INT2SMSKCR4 IOMEM(0xfe7822b0) - -#define INT2NTSR0 IOMEM(0xfe700060) -#define INT2NTSR1 IOMEM(0xfe700064) - -static struct renesas_intc_irqpin_config irqpin0_platform_data = { - .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ - .sense_bitfield_width = 2, -}; - -static struct resource irqpin0_resources[] = { - DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */ - DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */ - DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */ - DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */ - DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */ - DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */ - DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */ - DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */ - DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ -}; - -static struct platform_device irqpin0_device = { - .name = "renesas_intc_irqpin", - .id = 0, - .resource = irqpin0_resources, - .num_resources = ARRAY_SIZE(irqpin0_resources), - .dev = { - .platform_data = &irqpin0_platform_data, - }, -}; - -void __init r8a7779_init_irq_extpin(int irlm) -{ - void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); - unsigned long tmp; - - if (icr0) { - tmp = ioread32(icr0); - if (irlm) - tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */ - else - tmp &= ~(1 << 23); /* IRL mode - not supported */ - tmp |= (1 << 21); /* LVLMODE = 1 */ - iowrite32(tmp, icr0); - iounmap(icr0); - - if (irlm) - platform_device_register(&irqpin0_device); - } else - pr_warn("r8a7779: unable to setup external irq pin mode\n"); -} - -static int r8a7779_set_wake(struct irq_data *data, unsigned int on) -{ - return 0; /* always allow wakeup */ -} - -static void __init r8a7779_init_irq_common(void) -{ - gic_arch_extn.irq_set_wake = r8a7779_set_wake; - - /* route all interrupts to ARM */ - __raw_writel(0xffffffff, INT2NTSR0); - __raw_writel(0x3fffffff, INT2NTSR1); - - /* unmask all known interrupts in INTCS2 */ - __raw_writel(0xfffffff0, INT2SMSKCR0); - __raw_writel(0xfff7ffff, INT2SMSKCR1); - __raw_writel(0xfffbffdf, INT2SMSKCR2); - __raw_writel(0xbffffffc, INT2SMSKCR3); - __raw_writel(0x003fee3f, INT2SMSKCR4); -} - -void __init r8a7779_init_irq(void) -{ - void __iomem *gic_dist_base = IOMEM(0xf0001000); - void __iomem *gic_cpu_base = IOMEM(0xf0000100); - - /* use GIC to handle interrupts */ - gic_init(0, 29, gic_dist_base, gic_cpu_base); - - r8a7779_init_irq_common(); -} - -#ifdef CONFIG_OF -void __init r8a7779_init_irq_dt(void) -{ - irqchip_init(); - r8a7779_init_irq_common(); -} -#endif diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c new file mode 100644 index 00000000000..8cb641c00fd --- /dev/null +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -0,0 +1,194 @@ +/* + * SMP support for SoCs with APMU + * + * 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 version 2 as + * published by the Free Software Foundation. + */ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/of_address.h> +#include <linux/smp.h> +#include <asm/cacheflush.h> +#include <asm/cp15.h> +#include <asm/smp_plat.h> +#include <mach/common.h> + +static struct { + void __iomem *iomem; + int bit; +} apmu_cpus[CONFIG_NR_CPUS]; + +#define WUPCR_OFFS 0x10 +#define PSTR_OFFS 0x40 +#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n))) + +static int apmu_power_on(void __iomem *p, int bit) +{ + /* request power on */ + writel_relaxed(BIT(bit), p + WUPCR_OFFS); + + /* wait for APMU to finish */ + while (readl_relaxed(p + WUPCR_OFFS) != 0) + ; + + return 0; +} + +static int apmu_power_off(void __iomem *p, int bit) +{ + /* request Core Standby for next WFI */ + writel_relaxed(3, p + CPUNCR_OFFS(bit)); + return 0; +} + +static int apmu_power_off_poll(void __iomem *p, int bit) +{ + int k; + + for (k = 0; k < 1000; k++) { + if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3) + return 1; + + mdelay(1); + } + + return 0; +} + +static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)) +{ + void __iomem *p = apmu_cpus[cpu].iomem; + + return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL; +} + +static void apmu_init_cpu(struct resource *res, int cpu, int bit) +{ + if (apmu_cpus[cpu].iomem) + return; + + apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); + apmu_cpus[cpu].bit = bit; + + pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res); +} + +static struct { + struct resource iomem; + int cpus[4]; +} apmu_config[] = { + { + .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), + .cpus = { 0, 1, 2, 3 }, + }, + { + .iomem = DEFINE_RES_MEM(0xe6151000, 0x88), + .cpus = { 0x100, 0x101, 0x102, 0x103 }, + } +}; + +static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) +{ + u32 id; + int k; + int bit, index; + bool is_allowed; + + for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { + /* only enable the cluster that includes the boot CPU */ + is_allowed = false; + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + if (id == cpu_logical_map(0)) + is_allowed = true; + } + } + if (!is_allowed) + continue; + + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + index = get_logical_index(id); + if (index >= 0) + fn(&apmu_config[k].iomem, index, bit); + } + } + } +} + +void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) +{ + /* install boot code shared by all CPUs */ + shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); + shmobile_boot_arg = MPIDR_HWID_BITMASK; + + /* perform per-cpu setup */ + apmu_parse_cfg(apmu_init_cpu); +} + +int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + /* For this particular CPU register boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0); + + return apmu_wrap(cpu, apmu_power_on); +} + +#ifdef CONFIG_HOTPLUG_CPU +/* nicked from arch/arm/mach-exynos/hotplug.c */ +static inline void cpu_enter_lowpower_a15(void) +{ + unsigned int v; + + asm volatile( + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "Ir" (CR_C) + : "cc"); + + flush_cache_louis(); + + asm volatile( + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); + dsb(); +} + +void shmobile_smp_apmu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + /* Select next sleep mode using the APMU */ + apmu_wrap(cpu, apmu_power_off); + + /* Do ARM specific CPU shutdown */ + cpu_enter_lowpower_a15(); + + /* jump to shared mach-shmobile sleep / reset code */ + shmobile_smp_sleep(); +} + +int shmobile_smp_apmu_cpu_kill(unsigned int cpu) +{ + return apmu_wrap(cpu, apmu_power_off_poll); +} +#endif diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c new file mode 100644 index 00000000000..673ad6e8086 --- /dev/null +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -0,0 +1,97 @@ +/* + * SMP support for SoCs with SCU covered by mach-shmobile + * + * 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 version 2 as + * published by the Free Software Foundation. + */ +#include <linux/cpu.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/smp.h> +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include <asm/smp_scu.h> +#include <mach/common.h> + +static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action) { + case CPU_UP_PREPARE: + /* For this particular CPU register SCU SMP boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), + (unsigned long)shmobile_scu_base); + break; + }; + + return NOTIFY_OK; +} + +static struct notifier_block shmobile_smp_scu_notifier = { + .notifier_call = shmobile_smp_scu_notifier_call, +}; + +void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) +{ + /* install boot code shared by all CPUs */ + shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); + shmobile_boot_arg = MPIDR_HWID_BITMASK; + + /* enable SCU and cache coherency on booting CPU */ + scu_enable(shmobile_scu_base); + scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); + + /* Use CPU notifier for reset vector control */ + register_cpu_notifier(&shmobile_smp_scu_notifier); +} + +#ifdef CONFIG_HOTPLUG_CPU +void shmobile_smp_scu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + dsb(); + flush_cache_all(); + + /* disable cache coherency */ + scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF); + + /* jump to shared mach-shmobile sleep / reset code */ + shmobile_smp_sleep(); +} + +static int shmobile_smp_scu_psr_core_disabled(int cpu) +{ + unsigned long mask = SCU_PM_POWEROFF << (cpu * 8); + + if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask) + return 1; + + return 0; +} + +int shmobile_smp_scu_cpu_kill(unsigned int cpu) +{ + int k; + + /* this function is running on another CPU than the offline target, + * here we need wait for shutdown code in platform_cpu_die() to + * finish before asking SoC-specific code to power off the CPU core. + */ + for (k = 0; k < 1000; k++) { + if (shmobile_smp_scu_psr_core_disabled(cpu)) + return 1; + + mdelay(1); + } + + return 0; +} +#endif diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index 1f958d7b0ba..9ebc246b8d7 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -11,18 +11,28 @@ * published by the Free Software Foundation. */ #include <linux/init.h> -#include <linux/smp.h> +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include <mach/common.h> -void __init shmobile_smp_init_cpus(unsigned int ncores) +extern unsigned long shmobile_smp_fn[]; +extern unsigned long shmobile_smp_arg[]; +extern unsigned long shmobile_smp_mpidr[]; + +void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg) { - unsigned int i; + shmobile_smp_fn[cpu] = 0; + flush_cache_all(); - if (ncores > nr_cpu_ids) { - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", - ncores, nr_cpu_ids); - ncores = nr_cpu_ids; - } + shmobile_smp_mpidr[cpu] = cpu_logical_map(cpu); + shmobile_smp_fn[cpu] = fn; + shmobile_smp_arg[cpu] = arg; + flush_cache_all(); +} - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); +#ifdef CONFIG_HOTPLUG_CPU +int shmobile_smp_cpu_disable(unsigned int cpu) +{ + return 0; /* Hotplug of any CPU is supported */ } +#endif diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index d50a8e9b94a..d6fe189b2df 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -20,132 +20,22 @@ #include <linux/console.h> #include <asm/io.h> #include <mach/common.h> +#include <mach/pm-rcar.h> #include <mach/r8a7779.h> -static void __iomem *r8a7779_sysc_base; - /* SYSC */ -#define SYSCSR 0x00 -#define SYSCISR 0x04 -#define SYSCISCR 0x08 #define SYSCIER 0x0c #define SYSCIMR 0x10 -#define PWRSR0 0x40 -#define PWRSR1 0x80 -#define PWRSR2 0xc0 -#define PWRSR3 0x100 -#define PWRSR4 0x140 - -#define PWRSR_OFFS 0x00 -#define PWROFFCR_OFFS 0x04 -#define PWRONCR_OFFS 0x0c -#define PWRER_OFFS 0x14 - -#define SYSCSR_RETRIES 100 -#define SYSCSR_DELAY_US 1 - -#define SYSCISR_RETRIES 1000 -#define SYSCISR_DELAY_US 1 #if defined(CONFIG_PM) || defined(CONFIG_SMP) -static DEFINE_SPINLOCK(r8a7779_sysc_lock); /* SMP CPUs + I/O devices */ - -static int r8a7779_sysc_pwr_on_off(struct r8a7779_pm_ch *r8a7779_ch, - int sr_bit, int reg_offs) -{ - int k; - - for (k = 0; k < SYSCSR_RETRIES; k++) { - if (ioread32(r8a7779_sysc_base + SYSCSR) & (1 << sr_bit)) - break; - udelay(SYSCSR_DELAY_US); - } - - if (k == SYSCSR_RETRIES) - return -EAGAIN; - - iowrite32(1 << r8a7779_ch->chan_bit, - r8a7779_sysc_base + r8a7779_ch->chan_offs + reg_offs); - - return 0; -} - -static int r8a7779_sysc_pwr_off(struct r8a7779_pm_ch *r8a7779_ch) -{ - return r8a7779_sysc_pwr_on_off(r8a7779_ch, 0, PWROFFCR_OFFS); -} - -static int r8a7779_sysc_pwr_on(struct r8a7779_pm_ch *r8a7779_ch) -{ - return r8a7779_sysc_pwr_on_off(r8a7779_ch, 1, PWRONCR_OFFS); -} - -static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch, - int (*on_off_fn)(struct r8a7779_pm_ch *)) -{ - unsigned int isr_mask = 1 << r8a7779_ch->isr_bit; - unsigned int chan_mask = 1 << r8a7779_ch->chan_bit; - unsigned int status; - unsigned long flags; - int ret = 0; - int k; - - spin_lock_irqsave(&r8a7779_sysc_lock, flags); - - iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR); - - do { - ret = on_off_fn(r8a7779_ch); - if (ret) - goto out; - - status = ioread32(r8a7779_sysc_base + - r8a7779_ch->chan_offs + PWRER_OFFS); - } while (status & chan_mask); - - for (k = 0; k < SYSCISR_RETRIES; k++) { - if (ioread32(r8a7779_sysc_base + SYSCISR) & isr_mask) - break; - udelay(SYSCISR_DELAY_US); - } - - if (k == SYSCISR_RETRIES) - ret = -EIO; - - iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR); - - out: - spin_unlock_irqrestore(&r8a7779_sysc_lock, flags); - - pr_debug("r8a7779 power domain %d: %02x %02x %02x %02x %02x -> %d\n", - r8a7779_ch->isr_bit, ioread32(r8a7779_sysc_base + PWRSR0), - ioread32(r8a7779_sysc_base + PWRSR1), - ioread32(r8a7779_sysc_base + PWRSR2), - ioread32(r8a7779_sysc_base + PWRSR3), - ioread32(r8a7779_sysc_base + PWRSR4), ret); - return ret; -} - -int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch) -{ - return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off); -} - -int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch) -{ - return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on); -} - static void __init r8a7779_sysc_init(void) { - r8a7779_sysc_base = ioremap_nocache(0xffd85000, PAGE_SIZE); - if (!r8a7779_sysc_base) - panic("unable to ioremap r8a7779 SYSC hardware block\n"); + void __iomem *base = rcar_sysc_init(0xffd85000); /* enable all interrupt sources, but do not use interrupt handler */ - iowrite32(0x0131000e, r8a7779_sysc_base + SYSCIER); - iowrite32(0, r8a7779_sysc_base + SYSCIMR); + iowrite32(0x0131000e, base + SYSCIER); + iowrite32(0, base + SYSCIMR); } #else /* CONFIG_PM || CONFIG_SMP */ @@ -158,24 +48,17 @@ static inline void r8a7779_sysc_init(void) {} static int pd_power_down(struct generic_pm_domain *genpd) { - return r8a7779_sysc_power_down(to_r8a7779_ch(genpd)); + return rcar_sysc_power_down(to_r8a7779_ch(genpd)); } static int pd_power_up(struct generic_pm_domain *genpd) { - return r8a7779_sysc_power_up(to_r8a7779_ch(genpd)); + return rcar_sysc_power_up(to_r8a7779_ch(genpd)); } static bool pd_is_off(struct generic_pm_domain *genpd) { - struct r8a7779_pm_ch *r8a7779_ch = to_r8a7779_ch(genpd); - unsigned int st; - - st = ioread32(r8a7779_sysc_base + r8a7779_ch->chan_offs + PWRSR_OFFS); - if (st & (1 << r8a7779_ch->chan_bit)) - return true; - - return false; + return rcar_sysc_power_is_off(to_r8a7779_ch(genpd)); } static bool pd_active_wakeup(struct device *dev) diff --git a/arch/arm/mach-shmobile/pm-r8a7790.c b/arch/arm/mach-shmobile/pm-r8a7790.c new file mode 100644 index 00000000000..fc82839e2c2 --- /dev/null +++ b/arch/arm/mach-shmobile/pm-r8a7790.c @@ -0,0 +1,45 @@ +/* + * r8a7790 Power management support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2011 Renesas Solutions Corp. + * Copyright (C) 2011 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/kernel.h> +#include <asm/io.h> +#include <mach/pm-rcar.h> +#include <mach/r8a7790.h> + +/* SYSC */ +#define SYSCIER 0x0c +#define SYSCIMR 0x10 + +#if defined(CONFIG_SMP) + +static void __init r8a7790_sysc_init(void) +{ + void __iomem *base = rcar_sysc_init(0xe6180000); + + /* enable all interrupt sources, but do not use interrupt handler */ + iowrite32(0x0131000e, base + SYSCIER); + iowrite32(0, base + SYSCIMR); +} + +#else /* CONFIG_SMP */ + +static inline void r8a7790_sysc_init(void) {} + +#endif /* CONFIG_SMP */ + +void __init r8a7790_pm_init(void) +{ + static int once; + + if (!once++) + r8a7790_sysc_init(); +} diff --git a/arch/arm/mach-shmobile/pm-rcar.c b/arch/arm/mach-shmobile/pm-rcar.c new file mode 100644 index 00000000000..1f465a12d1b --- /dev/null +++ b/arch/arm/mach-shmobile/pm-rcar.c @@ -0,0 +1,141 @@ +/* + * R-Car SYSC Power management support + * + * Copyright (C) 2014 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/mm.h> +#include <linux/spinlock.h> +#include <asm/io.h> +#include <mach/pm-rcar.h> + +/* SYSC */ +#define SYSCSR 0x00 +#define SYSCISR 0x04 +#define SYSCISCR 0x08 + +#define PWRSR_OFFS 0x00 +#define PWROFFCR_OFFS 0x04 +#define PWRONCR_OFFS 0x0c +#define PWRER_OFFS 0x14 + +#define SYSCSR_RETRIES 100 +#define SYSCSR_DELAY_US 1 + +#define SYSCISR_RETRIES 1000 +#define SYSCISR_DELAY_US 1 + +#if defined(CONFIG_PM) || defined(CONFIG_SMP) + +static void __iomem *rcar_sysc_base; +static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */ + +static int rcar_sysc_pwr_on_off(struct rcar_sysc_ch *sysc_ch, + int sr_bit, int reg_offs) +{ + int k; + + for (k = 0; k < SYSCSR_RETRIES; k++) { + if (ioread32(rcar_sysc_base + SYSCSR) & (1 << sr_bit)) + break; + udelay(SYSCSR_DELAY_US); + } + + if (k == SYSCSR_RETRIES) + return -EAGAIN; + + iowrite32(1 << sysc_ch->chan_bit, + rcar_sysc_base + sysc_ch->chan_offs + reg_offs); + + return 0; +} + +static int rcar_sysc_pwr_off(struct rcar_sysc_ch *sysc_ch) +{ + return rcar_sysc_pwr_on_off(sysc_ch, 0, PWROFFCR_OFFS); +} + +static int rcar_sysc_pwr_on(struct rcar_sysc_ch *sysc_ch) +{ + return rcar_sysc_pwr_on_off(sysc_ch, 1, PWRONCR_OFFS); +} + +static int rcar_sysc_update(struct rcar_sysc_ch *sysc_ch, + int (*on_off_fn)(struct rcar_sysc_ch *)) +{ + unsigned int isr_mask = 1 << sysc_ch->isr_bit; + unsigned int chan_mask = 1 << sysc_ch->chan_bit; + unsigned int status; + unsigned long flags; + int ret = 0; + int k; + + spin_lock_irqsave(&rcar_sysc_lock, flags); + + iowrite32(isr_mask, rcar_sysc_base + SYSCISCR); + + do { + ret = on_off_fn(sysc_ch); + if (ret) + goto out; + + status = ioread32(rcar_sysc_base + + sysc_ch->chan_offs + PWRER_OFFS); + } while (status & chan_mask); + + for (k = 0; k < SYSCISR_RETRIES; k++) { + if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask) + break; + udelay(SYSCISR_DELAY_US); + } + + if (k == SYSCISR_RETRIES) + ret = -EIO; + + iowrite32(isr_mask, rcar_sysc_base + SYSCISCR); + + out: + spin_unlock_irqrestore(&rcar_sysc_lock, flags); + + pr_debug("sysc power domain %d: %08x -> %d\n", + sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret); + return ret; +} + +int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch) +{ + return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_off); +} + +int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch) +{ + return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_on); +} + +bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch) +{ + unsigned int st; + + st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS); + if (st & (1 << sysc_ch->chan_bit)) + return true; + + return false; +} + +void __iomem *rcar_sysc_init(phys_addr_t base) +{ + rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE); + if (!rcar_sysc_base) + panic("unable to ioremap R-Car SYSC hardware block\n"); + + return rcar_sysc_base; +} + +#endif /* CONFIG_PM || CONFIG_SMP */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 1fc05d9453d..f710235aff2 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -99,39 +99,7 @@ static int rmobile_pd_power_up(struct generic_pm_domain *genpd) static bool rmobile_pd_active_wakeup(struct device *dev) { - bool (*active_wakeup)(struct device *dev); - - active_wakeup = dev_gpd_data(dev)->ops.active_wakeup; - return active_wakeup ? active_wakeup(dev) : true; -} - -static int rmobile_pd_stop_dev(struct device *dev) -{ - int (*stop)(struct device *dev); - - stop = dev_gpd_data(dev)->ops.stop; - if (stop) { - int ret = stop(dev); - if (ret) - return ret; - } - return pm_clk_suspend(dev); -} - -static int rmobile_pd_start_dev(struct device *dev) -{ - int (*start)(struct device *dev); - int ret; - - ret = pm_clk_resume(dev); - if (ret) - return ret; - - start = dev_gpd_data(dev)->ops.start; - if (start) - ret = start(dev); - - return ret; + return true; } static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) @@ -140,8 +108,8 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) struct dev_power_governor *gov = rmobile_pd->gov; pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); - genpd->dev_ops.stop = rmobile_pd_stop_dev; - genpd->dev_ops.start = rmobile_pd_start_dev; + genpd->dev_ops.stop = pm_clk_suspend; + genpd->dev_ops.start = pm_clk_resume; genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; genpd->dev_irq_safe = true; genpd->power_off = rmobile_pd_power_down; diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 1ccddd22811..d953ff6e78a 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -16,36 +16,17 @@ * 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/clk-provider.h> #include <linux/kernel.h> #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> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/io.h> -#include <linux/irqchip/arm-gic.h> -#include <mach/hardware.h> #include <mach/common.h> -#include <mach/emev2.h> -#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <asm/mach/time.h> 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, @@ -56,407 +37,34 @@ static struct map_desc emev2_io_desc[] __initdata = { #endif }; -void __init emev2_map_io(void) +static void __init emev2_map_io(void) { iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc)); } -/* 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, -}; - -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, -}; - -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, -}; - -static struct resource uart3_resources[] = { - [0] = { - .start = 0xe1050000, - .end = 0xe1050037, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 43, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device uart3_device = { - .name = "serial8250-em", - .id = 3, - .num_resources = ARRAY_SIZE(uart3_resources), - .resource = uart3_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), -}; - - -/* GIO */ -static struct gpio_em_config gio0_config = { - .gpio_base = 0, - .irq_base = EMEV2_GPIO_IRQ(0), - .number_of_pins = 32, -}; - -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, - }, -}; - -static struct gpio_em_config gio1_config = { - .gpio_base = 32, - .irq_base = EMEV2_GPIO_IRQ(32), - .number_of_pins = 32, -}; - -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, - }, -}; - -static struct gpio_em_config gio2_config = { - .gpio_base = 64, - .irq_base = EMEV2_GPIO_IRQ(64), - .number_of_pins = 32, -}; - -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, - }, -}; - -static struct gpio_em_config gio3_config = { - .gpio_base = 96, - .irq_base = EMEV2_GPIO_IRQ(96), - .number_of_pins = 32, -}; - -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, - }, -}; - -static struct gpio_em_config gio4_config = { - .gpio_base = 128, - .irq_base = EMEV2_GPIO_IRQ(128), - .number_of_pins = 31, -}; - -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, - }, -}; - -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, - }, -}; - -static struct resource pmu_resources[] = { - [0] = { - .start = 152, - .end = 152, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = 153, - .end = 153, - .flags = IORESOURCE_IRQ, - }, -}; - -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, -}; - -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)); -} - static 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); + of_clk_init(NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static const char *emev2_boards_compat_dt[] __initdata = { +static const char *emev2_boards_compat_dt[] __initconst = { "renesas,emev2", NULL, }; +extern struct smp_operations emev2_smp_ops; + 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, + .init_late = shmobile_init_late, .dt_compat = emev2_boards_compat_dt, MACHINE_END - -#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c new file mode 100644 index 00000000000..412e179429c --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -0,0 +1,61 @@ +/* + * r7s72100 processor support + * + * 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/irq.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/sh_timer.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r7s72100.h> +#include <asm/mach/arch.h> + +static struct resource mtu2_resources[] __initdata = { + DEFINE_RES_MEM(0xfcff0000, 0x400), + DEFINE_RES_IRQ_NAMED(gic_iid(139), "tgi0a"), +}; + +#define r7s72100_register_mtu2() \ + platform_device_register_resndata(&platform_bus, "sh-mtu2", \ + -1, mtu2_resources, \ + ARRAY_SIZE(mtu2_resources), \ + NULL, 0) + +void __init r7s72100_add_dt_devices(void) +{ + r7s72100_register_mtu2(); +} + +void __init r7s72100_init_early(void) +{ + shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ +} + +#ifdef CONFIG_USE_OF +static const char *r7s72100_boards_compat_dt[] __initdata = { + "renesas,r7s72100", + NULL, +}; + +DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") + .init_early = r7s72100_init_early, + .dt_compat = r7s72100_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 7f45c2edbca..9333770cfac 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -18,12 +18,14 @@ * 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_dma.h> +#include <linux/sh_timer.h> #include <mach/common.h> +#include <mach/dma-register.h> #include <mach/irqs.h> #include <mach/r8a73a4.h> #include <asm/mach/arch.h> @@ -38,41 +40,39 @@ void __init r8a73a4_pinmux_init(void) ARRAY_SIZE(pfc_resources)); } -#define SCIF_COMMON(scif_type, baseaddr, irq) \ +#define R8A73A4_SCIF(scif_type, _scscr, index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ .type = scif_type, \ - .mapbase = baseaddr, \ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ - .scbrr_algo_id = SCBRR_ALGO_4, \ - .irqs = SCIx_IRQ_MUXED(irq) - -#define SCIFA_DATA(index, baseaddr, irq) \ -[index] = { \ - SCIF_COMMON(PORT_SCIFA, baseaddr, irq), \ - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE0, \ + .scscr = _scscr, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ } -#define SCIFB_DATA(index, baseaddr, irq) \ -[index] = { \ - SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \ - .scscr = SCSCR_RE | SCSCR_TE, \ -} +#define R8A73A4_SCIFA(index, baseaddr, irq) \ + R8A73A4_SCIF(PORT_SCIFA, SCSCR_RE | SCSCR_TE | SCSCR_CKE0, \ + index, baseaddr, irq) -enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFB3 }; +#define R8A73A4_SCIFB(index, baseaddr, irq) \ + R8A73A4_SCIF(PORT_SCIFB, SCSCR_RE | SCSCR_TE, \ + index, baseaddr, irq) -static const struct plat_sci_port scif[] = { - SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ - SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ - SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ - SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */ - SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */ - SCIFB_DATA(SCIFB3, 0xe6cf0000, gic_spi(151)), /* SCIFB3 */ -}; +R8A73A4_SCIFA(0, 0xe6c40000, gic_spi(144)); /* SCIFA0 */ +R8A73A4_SCIFA(1, 0xe6c50000, gic_spi(145)); /* SCIFA1 */ +R8A73A4_SCIFB(2, 0xe6c20000, gic_spi(148)); /* SCIFB0 */ +R8A73A4_SCIFB(3, 0xe6c30000, gic_spi(149)); /* SCIFB1 */ +R8A73A4_SCIFB(4, 0xe6ce0000, gic_spi(150)); /* SCIFB2 */ +R8A73A4_SCIFB(5, 0xe6cf0000, gic_spi(151)); /* SCIFB3 */ -static inline void r8a73a4_register_scif(int idx) -{ - platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], - sizeof(struct plat_sci_port)); -} +#define r8a73a4_register_scif(index) \ + platform_device_register_resndata(&platform_bus, "sh-sci", index, \ + scif##index##_resources, \ + ARRAY_SIZE(scif##index##_resources), \ + &scif##index##_platform_data, \ + sizeof(scif##index##_platform_data)) static const struct renesas_irqc_config irqc0_data = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ31 */ @@ -169,34 +169,146 @@ static const struct resource thermal0_resources[] = { thermal0_resources, \ ARRAY_SIZE(thermal0_resources)) +static struct sh_timer_config cmt1_platform_data = { + .channels_mask = 0xff, +}; + +static struct resource cmt1_resources[] = { + DEFINE_RES_MEM(0xe6130000, 0x1004), + DEFINE_RES_IRQ(gic_spi(120)), +}; + +#define r8a7790_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + +void __init r8a73a4_add_dt_devices(void) +{ + r8a73a4_register_scif(0); + r8a73a4_register_scif(1); + r8a73a4_register_scif(2); + r8a73a4_register_scif(3); + r8a73a4_register_scif(4); + r8a73a4_register_scif(5); + r8a7790_register_cmt(1); +} + +/* DMA */ +static const struct sh_dmae_slave_config dma_slaves[] = { + { + .slave_id = SHDMA_SLAVE_MMCIF0_TX, + .addr = 0xee200034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xd1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF0_RX, + .addr = 0xee200034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xd2, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_TX, + .addr = 0xee220034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xe1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_RX, + .addr = 0xee220034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xe2, + }, +}; + +#define DMAE_CHANNEL(a, b) \ + { \ + .offset = (a) - 0x20, \ + .dmars = (a) - 0x20 + 0x40, \ + .chclr_bit = (b), \ + .chclr_offset = 0x80 - 0x20, \ + } + +static const struct sh_dmae_channel dma_channels[] = { + DMAE_CHANNEL(0x8000, 0), + DMAE_CHANNEL(0x8080, 1), + DMAE_CHANNEL(0x8100, 2), + DMAE_CHANNEL(0x8180, 3), + DMAE_CHANNEL(0x8200, 4), + DMAE_CHANNEL(0x8280, 5), + DMAE_CHANNEL(0x8300, 6), + DMAE_CHANNEL(0x8380, 7), + DMAE_CHANNEL(0x8400, 8), + DMAE_CHANNEL(0x8480, 9), + DMAE_CHANNEL(0x8500, 10), + DMAE_CHANNEL(0x8580, 11), + DMAE_CHANNEL(0x8600, 12), + DMAE_CHANNEL(0x8680, 13), + DMAE_CHANNEL(0x8700, 14), + DMAE_CHANNEL(0x8780, 15), + DMAE_CHANNEL(0x8800, 16), + DMAE_CHANNEL(0x8880, 17), + DMAE_CHANNEL(0x8900, 18), + DMAE_CHANNEL(0x8980, 19), +}; + +static const struct sh_dmae_pdata dma_pdata = { + .slave = dma_slaves, + .slave_num = ARRAY_SIZE(dma_slaves), + .channel = dma_channels, + .channel_num = ARRAY_SIZE(dma_channels), + .ts_low_shift = TS_LOW_SHIFT, + .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, + .ts_high_shift = TS_HI_SHIFT, + .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, + .ts_shift = dma_ts_shift, + .ts_shift_num = ARRAY_SIZE(dma_ts_shift), + .dmaor_init = DMAOR_DME, + .chclr_present = 1, + .chclr_bitwise = 1, +}; + +static struct resource dma_resources[] = { + DEFINE_RES_MEM(0xe6700020, 0x89e0), + DEFINE_RES_IRQ(gic_spi(220)), + { + /* IRQ for channels 0-19 */ + .start = gic_spi(200), + .end = gic_spi(219), + .flags = IORESOURCE_IRQ, + }, +}; + +#define r8a73a4_register_dmac() \ + platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0, \ + dma_resources, ARRAY_SIZE(dma_resources), \ + &dma_pdata, sizeof(dma_pdata)) + void __init r8a73a4_add_standard_devices(void) { - r8a73a4_register_scif(SCIFA0); - r8a73a4_register_scif(SCIFA1); - r8a73a4_register_scif(SCIFB0); - r8a73a4_register_scif(SCIFB1); - r8a73a4_register_scif(SCIFB2); - r8a73a4_register_scif(SCIFB3); + r8a73a4_add_dt_devices(); r8a73a4_register_irqc(0); r8a73a4_register_irqc(1); r8a73a4_register_thermal(); + r8a73a4_register_dmac(); } -#ifdef CONFIG_USE_OF -void __init r8a73a4_add_standard_devices_dt(void) +void __init r8a73a4_init_early(void) { - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */ +#endif } +#ifdef CONFIG_USE_OF + static const char *r8a73a4_boards_compat_dt[] __initdata = { "renesas,r8a73a4", NULL, }; DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") - .init_irq = irqchip_init, - .init_machine = r8a73a4_add_standard_devices_dt, - .init_time = shmobile_timer_init, + .init_early = r8a73a4_init_early, .dt_compat = r8a73a4_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 00c5a707238..35dec233301 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -22,6 +22,8 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/irqchip.h> +#include <linux/irqchip/arm-gic.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> #include <linux/of_platform.h> @@ -201,289 +203,79 @@ static struct platform_device irqpin3_device = { }, }; -/* SCIFA0 */ -static struct plat_sci_port scif0_platform_data = { - .mapbase = 0xe6c40000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(100)), -}; - -static struct platform_device scif0_device = { - .name = "sh-sci", - .id = 0, - .dev = { - .platform_data = &scif0_platform_data, - }, -}; - -/* SCIFA1 */ -static struct plat_sci_port scif1_platform_data = { - .mapbase = 0xe6c50000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(101)), -}; - -static struct platform_device scif1_device = { - .name = "sh-sci", - .id = 1, - .dev = { - .platform_data = &scif1_platform_data, - }, -}; - -/* SCIFA2 */ -static struct plat_sci_port scif2_platform_data = { - .mapbase = 0xe6c60000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(102)), -}; - -static struct platform_device scif2_device = { - .name = "sh-sci", - .id = 2, - .dev = { - .platform_data = &scif2_platform_data, - }, -}; - -/* SCIFA3 */ -static struct plat_sci_port scif3_platform_data = { - .mapbase = 0xe6c70000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(103)), -}; - -static struct platform_device scif3_device = { - .name = "sh-sci", - .id = 3, - .dev = { - .platform_data = &scif3_platform_data, - }, -}; - -/* SCIFA4 */ -static struct plat_sci_port scif4_platform_data = { - .mapbase = 0xe6c80000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(104)), -}; - -static struct platform_device scif4_device = { - .name = "sh-sci", - .id = 4, - .dev = { - .platform_data = &scif4_platform_data, - }, -}; - -/* SCIFA5 */ -static struct plat_sci_port scif5_platform_data = { - .mapbase = 0xe6cb0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(105)), -}; - -static struct platform_device scif5_device = { - .name = "sh-sci", - .id = 5, - .dev = { - .platform_data = &scif5_platform_data, - }, -}; - -/* SCIFA6 */ -static struct plat_sci_port scif6_platform_data = { - .mapbase = 0xe6cc0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(106)), -}; - -static struct platform_device scif6_device = { - .name = "sh-sci", - .id = 6, - .dev = { - .platform_data = &scif6_platform_data, - }, -}; - -/* SCIFA7 */ -static struct plat_sci_port scif7_platform_data = { - .mapbase = 0xe6cd0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = SCIx_IRQ_MUXED(gic_spi(107)), -}; - -static struct platform_device scif7_device = { - .name = "sh-sci", - .id = 7, - .dev = { - .platform_data = &scif7_platform_data, - }, -}; - -/* SCIFB */ -static struct plat_sci_port scifb_platform_data = { - .mapbase = 0xe6c30000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFB, - .irqs = SCIx_IRQ_MUXED(gic_spi(108)), -}; +/* SCIF */ +#define R8A7740_SCIF(scif_type, index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ + .type = scif_type, \ + .flags = UPF_BOOT_AUTOCONF, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ +}; \ + \ +static struct platform_device scif##index##_device = { \ + .name = "sh-sci", \ + .id = index, \ + .resource = scif##index##_resources, \ + .num_resources = ARRAY_SIZE(scif##index##_resources), \ + .dev = { \ + .platform_data = &scif##index##_platform_data, \ + }, \ +} -static struct platform_device scifb_device = { - .name = "sh-sci", - .id = 8, - .dev = { - .platform_data = &scifb_platform_data, - }, -}; +R8A7740_SCIF(PORT_SCIFA, 0, 0xe6c40000, gic_spi(100)); +R8A7740_SCIF(PORT_SCIFA, 1, 0xe6c50000, gic_spi(101)); +R8A7740_SCIF(PORT_SCIFA, 2, 0xe6c60000, gic_spi(102)); +R8A7740_SCIF(PORT_SCIFA, 3, 0xe6c70000, gic_spi(103)); +R8A7740_SCIF(PORT_SCIFA, 4, 0xe6c80000, gic_spi(104)); +R8A7740_SCIF(PORT_SCIFA, 5, 0xe6cb0000, gic_spi(105)); +R8A7740_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(106)); +R8A7740_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(107)); +R8A7740_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(108)); /* CMT */ -static struct sh_timer_config cmt10_platform_data = { - .name = "CMT10", - .channel_offset = 0x10, - .timer_bit = 0, - .clockevent_rating = 125, - .clocksource_rating = 125, +static struct sh_timer_config cmt1_platform_data = { + .channels_mask = 0x3f, }; -static struct resource cmt10_resources[] = { - [0] = { - .name = "CMT10", - .start = 0xe6138010, - .end = 0xe613801b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(58), - .flags = IORESOURCE_IRQ, - }, +static struct resource cmt1_resources[] = { + DEFINE_RES_MEM(0xe6138000, 0x170), + DEFINE_RES_IRQ(gic_spi(58)), }; -static struct platform_device cmt10_device = { - .name = "sh_cmt", - .id = 10, +static struct platform_device cmt1_device = { + .name = "sh-cmt-48", + .id = 1, .dev = { - .platform_data = &cmt10_platform_data, + .platform_data = &cmt1_platform_data, }, - .resource = cmt10_resources, - .num_resources = ARRAY_SIZE(cmt10_resources), + .resource = cmt1_resources, + .num_resources = ARRAY_SIZE(cmt1_resources), }; /* TMU */ -static struct sh_timer_config tmu00_platform_data = { - .name = "TMU00", - .channel_offset = 0x4, - .timer_bit = 0, - .clockevent_rating = 200, +static struct sh_timer_config tmu0_platform_data = { + .channels_mask = 7, }; -static struct resource tmu00_resources[] = { - [0] = { - .name = "TMU00", - .start = 0xfff80008, - .end = 0xfff80014 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(198), - .flags = IORESOURCE_IRQ, - }, +static struct resource tmu0_resources[] = { + DEFINE_RES_MEM(0xfff80000, 0x2c), + DEFINE_RES_IRQ(gic_spi(198)), + DEFINE_RES_IRQ(gic_spi(199)), + DEFINE_RES_IRQ(gic_spi(200)), }; -static struct platform_device tmu00_device = { - .name = "sh_tmu", +static struct platform_device tmu0_device = { + .name = "sh-tmu", .id = 0, .dev = { - .platform_data = &tmu00_platform_data, - }, - .resource = tmu00_resources, - .num_resources = ARRAY_SIZE(tmu00_resources), -}; - -static struct sh_timer_config tmu01_platform_data = { - .name = "TMU01", - .channel_offset = 0x10, - .timer_bit = 1, - .clocksource_rating = 200, -}; - -static struct resource tmu01_resources[] = { - [0] = { - .name = "TMU01", - .start = 0xfff80014, - .end = 0xfff80020 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(199), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device tmu01_device = { - .name = "sh_tmu", - .id = 1, - .dev = { - .platform_data = &tmu01_platform_data, + .platform_data = &tmu0_platform_data, }, - .resource = tmu01_resources, - .num_resources = ARRAY_SIZE(tmu01_resources), -}; - -static struct sh_timer_config tmu02_platform_data = { - .name = "TMU02", - .channel_offset = 0x1C, - .timer_bit = 2, - .clocksource_rating = 200, -}; - -static struct resource tmu02_resources[] = { - [0] = { - .name = "TMU02", - .start = 0xfff80020, - .end = 0xfff8002C - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(200), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device tmu02_device = { - .name = "sh_tmu", - .id = 2, - .dev = { - .platform_data = &tmu02_platform_data, - }, - .resource = tmu02_resources, - .num_resources = ARRAY_SIZE(tmu02_resources), + .resource = tmu0_resources, + .num_resources = ARRAY_SIZE(tmu0_resources), }; /* IPMMUI (an IPMMU module for ICB/LMB) */ @@ -526,8 +318,8 @@ static struct platform_device *r8a7740_devices_dt[] __initdata = { &scif5_device, &scif6_device, &scif7_device, - &scifb_device, - &cmt10_device, + &scif8_device, + &cmt1_device, }; static struct platform_device *r8a7740_early_devices[] __initdata = { @@ -535,9 +327,7 @@ static struct platform_device *r8a7740_early_devices[] __initdata = { &irqpin1_device, &irqpin2_device, &irqpin3_device, - &tmu00_device, - &tmu01_device, - &tmu02_device, + &tmu0_device, &ipmmu_device, }; @@ -588,6 +378,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, }, }; @@ -882,7 +682,7 @@ static struct platform_device *r8a7740_late_devices[] __initdata = { * "Media RAM (MERAM)" on r8a7740 documentation */ #define MEBUFCNTR 0xFE950098 -void r8a7740_meram_workaround(void) +void __init r8a7740_meram_workaround(void) { void __iomem *reg; @@ -969,7 +769,7 @@ void __init r8a7740_add_standard_devices(void) rmobile_add_device_to_domain("A3SP", &scif5_device); rmobile_add_device_to_domain("A3SP", &scif6_device); rmobile_add_device_to_domain("A3SP", &scif7_device); - rmobile_add_device_to_domain("A3SP", &scifb_device); + rmobile_add_device_to_domain("A3SP", &scif8_device); rmobile_add_device_to_domain("A3SP", &i2c1_device); } @@ -986,22 +786,42 @@ 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_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) +void __init r8a7740_init_irq_of(void) { - shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ -}; + void __iomem *intc_prio_base = ioremap_nocache(0xe6900010, 0x10); + void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10); + void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4); + + irqchip_init(); + + /* route signals to GIC */ + iowrite32(0x0, pfc_inta_ctrl); + + /* + * To mask the shared interrupt to SPI 149 we must ensure to set + * PRIO *and* MASK. Else we run into IRQ floods when registering + * the intc_irqpin devices + */ + iowrite32(0x0, intc_prio_base + 0x0); + iowrite32(0x0, intc_prio_base + 0x4); + iowrite32(0x0, intc_prio_base + 0x8); + iowrite32(0x0, intc_prio_base + 0xc); + iowrite8(0xff, intc_msk_base + 0x0); + iowrite8(0xff, intc_msk_base + 0x4); + iowrite8(0xff, intc_msk_base + 0x8); + iowrite8(0xff, intc_msk_base + 0xc); + + iounmap(intc_prio_base); + iounmap(intc_msk_base); + iounmap(pfc_inta_ctrl); +} static void __init r8a7740_generic_init(void) { @@ -1016,10 +836,10 @@ static const char *r8a7740_boards_compat_dt[] __initdata = { DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)") .map_io = r8a7740_map_io, - .init_early = r8a7740_init_delay, + .init_early = shmobile_init_delay, .init_irq = r8a7740_init_irq_of, .init_machine = r8a7740_generic_init, - .init_time = shmobile_timer_init, + .init_late = shmobile_init_late, .dt_compat = r8a7740_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 80c20392ad7..d311ef903b3 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/dma-rcar-hpbdma.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> @@ -43,95 +44,92 @@ #include <asm/hardware/cache-l2x0.h> /* SCIF */ -#define SCIF_INFO(baseaddr, irq) \ -{ \ - .mapbase = baseaddr, \ +#define R8A7778_SCIF(index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ - .scbrr_algo_id = SCBRR_ALGO_2, \ .type = PORT_SCIF, \ - .irqs = SCIx_IRQ_MUXED(irq), \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ } -static struct plat_sci_port scif_platform_data[] = { - SCIF_INFO(0xffe40000, gic_iid(0x66)), - SCIF_INFO(0xffe41000, gic_iid(0x67)), - SCIF_INFO(0xffe42000, gic_iid(0x68)), - SCIF_INFO(0xffe43000, gic_iid(0x69)), - SCIF_INFO(0xffe44000, gic_iid(0x6a)), - SCIF_INFO(0xffe45000, gic_iid(0x6b)), -}; +R8A7778_SCIF(0, 0xffe40000, gic_iid(0x66)); +R8A7778_SCIF(1, 0xffe41000, gic_iid(0x67)); +R8A7778_SCIF(2, 0xffe42000, gic_iid(0x68)); +R8A7778_SCIF(3, 0xffe43000, gic_iid(0x69)); +R8A7778_SCIF(4, 0xffe44000, gic_iid(0x6a)); +R8A7778_SCIF(5, 0xffe45000, gic_iid(0x6b)); -/* TMU */ -static struct resource sh_tmu0_resources[] = { - DEFINE_RES_MEM(0xffd80008, 12), - DEFINE_RES_IRQ(gic_iid(0x40)), -}; +#define r8a7778_register_scif(index) \ + platform_device_register_resndata(&platform_bus, "sh-sci", index, \ + scif##index##_resources, \ + ARRAY_SIZE(scif##index##_resources), \ + &scif##index##_platform_data, \ + sizeof(scif##index##_platform_data)) +/* TMU */ static struct sh_timer_config sh_tmu0_platform_data = { - .name = "TMU00", - .channel_offset = 0x4, - .timer_bit = 0, - .clockevent_rating = 200, + .channels_mask = 7, }; -static struct resource sh_tmu1_resources[] = { - DEFINE_RES_MEM(0xffd80014, 12), +static struct resource sh_tmu0_resources[] = { + DEFINE_RES_MEM(0xffd80000, 0x30), + DEFINE_RES_IRQ(gic_iid(0x40)), DEFINE_RES_IRQ(gic_iid(0x41)), -}; - -static struct sh_timer_config sh_tmu1_platform_data = { - .name = "TMU01", - .channel_offset = 0x10, - .timer_bit = 1, - .clocksource_rating = 200, + DEFINE_RES_IRQ(gic_iid(0x42)), }; #define r8a7778_register_tmu(idx) \ platform_device_register_resndata( \ - &platform_bus, "sh_tmu", idx, \ + &platform_bus, "sh-tmu", idx, \ sh_tmu##idx##_resources, \ ARRAY_SIZE(sh_tmu##idx##_resources), \ &sh_tmu##idx##_platform_data, \ sizeof(sh_tmu##idx##_platform_data)) -/* USB PHY */ -static struct resource usb_phy_resources[] __initdata = { - DEFINE_RES_MEM(0xffe70800, 0x100), - DEFINE_RES_MEM(0xffe76000, 0x100), -}; - -void __init r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata) +int r8a7778_usb_phy_power(bool enable) { - platform_device_register_resndata(&platform_bus, "rcar_usb_phy", -1, - usb_phy_resources, - ARRAY_SIZE(usb_phy_resources), - pdata, sizeof(*pdata)); + static struct usb_phy *phy = NULL; + int ret = 0; + + if (!phy) + phy = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(phy)) { + pr_err("kernel doesn't have usb phy driver\n"); + return PTR_ERR(phy); + } + + if (enable) + ret = usb_phy_init(phy); + else + usb_phy_shutdown(phy); + + return ret; } /* USB */ -static struct usb_phy *phy; - static int usb_power_on(struct platform_device *pdev) { - if (IS_ERR(phy)) - return PTR_ERR(phy); + int ret = r8a7778_usb_phy_power(true); + + if (ret) + return ret; pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - usb_phy_init(phy); - return 0; } static void usb_power_off(struct platform_device *pdev) { - if (IS_ERR(phy)) + if (r8a7778_usb_phy_power(false)) return; - usb_phy_shutdown(phy); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); } @@ -188,32 +186,18 @@ static struct platform_device_info hci##_info __initdata = { \ USB_PLATFORM_INFO(ehci); USB_PLATFORM_INFO(ohci); -/* 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, "r8a777x-ether", -1, - ether_resources, - ARRAY_SIZE(ether_resources), - pdata, sizeof(*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, \ @@ -248,30 +232,6 @@ void __init r8a7778_pinmux_init(void) 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)); -} - /* I2C */ static struct resource i2c_resources[] __initdata = { /* I2C0 */ @@ -288,7 +248,7 @@ static struct resource i2c_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x6d)), }; -void __init r8a7778_add_i2c_device(int id) +static void __init r8a7778_register_i2c(int id) { BUG_ON(id < 0 || id > 3); @@ -310,7 +270,7 @@ static struct resource hspi_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x75)), }; -void __init r8a7778_add_hspi_device(int id) +static void __init r8a7778_register_hspi(int id) { BUG_ON(id < 0 || id > 2); @@ -319,58 +279,256 @@ void __init r8a7778_add_hspi_device(int id) hspi_resources + (2 * id), 2); } -/* MMC */ -static struct resource mmc_resources[] __initdata = { - DEFINE_RES_MEM(0xffe4e000, 0x100), - DEFINE_RES_IRQ(gic_iid(0x5d)), -}; - -void __init r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info) +void __init r8a7778_add_dt_devices(void) { - platform_device_register_resndata( - &platform_bus, "sh_mmcif", -1, - mmc_resources, ARRAY_SIZE(mmc_resources), - info, sizeof(*info)); -} - -void __init r8a7778_add_standard_devices(void) -{ - int i; - #ifdef CONFIG_CACHE_L2X0 void __iomem *base = ioremap_nocache(0xf0100000, 0x1000); if (base) { /* - * Early BRESP enable, Shared attribute override enable, 64K*16way + * Shared attribute override enable, 64K*16way * don't call iounmap(base) */ - l2x0_init(base, 0x40470000, 0x82000fff); + l2x0_init(base, 0x00400000, 0xc20f0fff); } #endif - for (i = 0; i < ARRAY_SIZE(scif_platform_data); i++) - platform_device_register_data(&platform_bus, "sh-sci", i, - &scif_platform_data[i], - sizeof(struct plat_sci_port)); - + r8a7778_register_scif(0); + r8a7778_register_scif(1); + r8a7778_register_scif(2); + r8a7778_register_scif(3); + r8a7778_register_scif(4); + r8a7778_register_scif(5); r8a7778_register_tmu(0); - r8a7778_register_tmu(1); } -void __init r8a7778_init_late(void) +/* HPB-DMA */ + +/* Asynchronous mode register (ASYNCMDR) bits */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ + +#define HPBDMA_SSI(_id) \ +{ \ + .id = HPBDMA_SLAVE_SSI## _id ##_TX, \ + .addr = 0xffd91008 + (_id * 0x40), \ + .dcr = HPB_DMAE_DCR_CT | \ + HPB_DMAE_DCR_DIP | \ + HPB_DMAE_DCR_SPDS_32BIT | \ + HPB_DMAE_DCR_DMDL | \ + HPB_DMAE_DCR_DPDS_32BIT, \ + .port = _id + (_id << 8), \ + .dma_ch = (28 + _id), \ +}, { \ + .id = HPBDMA_SLAVE_SSI## _id ##_RX, \ + .addr = 0xffd9100c + (_id * 0x40), \ + .dcr = HPB_DMAE_DCR_CT | \ + HPB_DMAE_DCR_DIP | \ + HPB_DMAE_DCR_SMDL | \ + HPB_DMAE_DCR_SPDS_32BIT | \ + HPB_DMAE_DCR_DPDS_32BIT, \ + .port = _id + (_id << 8), \ + .dma_ch = (28 + _id), \ +} + +#define HPBDMA_HPBIF(_id) \ +{ \ + .id = HPBDMA_SLAVE_HPBIF## _id ##_TX, \ + .addr = 0xffda0000 + (_id * 0x1000), \ + .dcr = HPB_DMAE_DCR_CT | \ + HPB_DMAE_DCR_DIP | \ + HPB_DMAE_DCR_SPDS_32BIT | \ + HPB_DMAE_DCR_DMDL | \ + HPB_DMAE_DCR_DPDS_32BIT, \ + .port = 0x1111, \ + .dma_ch = (28 + _id), \ +}, { \ + .id = HPBDMA_SLAVE_HPBIF## _id ##_RX, \ + .addr = 0xffda0000 + (_id * 0x1000), \ + .dcr = HPB_DMAE_DCR_CT | \ + HPB_DMAE_DCR_DIP | \ + HPB_DMAE_DCR_SMDL | \ + HPB_DMAE_DCR_SPDS_32BIT | \ + HPB_DMAE_DCR_DPDS_32BIT, \ + .port = 0x1111, \ + .dma_ch = (28 + _id), \ +} + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, { + .id = HPBDMA_SLAVE_USBFUNC_TX, /* for D0 */ + .addr = 0xffe60018, + .dcr = HPB_DMAE_DCR_SPDS_32BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_32BIT, + .port = 0x0000, + .dma_ch = 14, + }, { + .id = HPBDMA_SLAVE_USBFUNC_RX, /* for D1 */ + .addr = 0xffe6001c, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_32BIT | + HPB_DMAE_DCR_DPDS_32BIT, + .port = 0x0101, + .dma_ch = 15, + }, + + HPBDMA_SSI(0), + HPBDMA_SSI(1), + HPBDMA_SSI(2), + HPBDMA_SSI(3), + HPBDMA_SSI(4), + HPBDMA_SSI(5), + HPBDMA_SSI(6), + HPBDMA_SSI(7), + HPBDMA_SSI(8), + + HPBDMA_HPBIF(0), + HPBDMA_HPBIF(1), + HPBDMA_HPBIF(2), + HPBDMA_HPBIF(3), + HPBDMA_HPBIF(4), + HPBDMA_HPBIF(5), + HPBDMA_HPBIF(6), + HPBDMA_HPBIF(7), + HPBDMA_HPBIF(8), +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_TX), /* ch. 14 */ + HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_RX), /* ch. 15 */ + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_TX), /* ch. 28 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_RX), /* ch. 28 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_TX), /* ch. 28 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_RX), /* ch. 28 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_TX), /* ch. 29 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_RX), /* ch. 29 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_TX), /* ch. 29 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_RX), /* ch. 29 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_TX), /* ch. 30 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_RX), /* ch. 30 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_TX), /* ch. 30 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_RX), /* ch. 30 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_TX), /* ch. 31 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_RX), /* ch. 31 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_TX), /* ch. 31 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_RX), /* ch. 31 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_TX), /* ch. 32 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_RX), /* ch. 32 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_TX), /* ch. 32 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_RX), /* ch. 32 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_TX), /* ch. 33 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_RX), /* ch. 33 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_TX), /* ch. 33 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_RX), /* ch. 33 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_TX), /* ch. 34 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_RX), /* ch. 34 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_TX), /* ch. 34 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_RX), /* ch. 34 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_TX), /* ch. 35 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_RX), /* ch. 35 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_TX), /* ch. 35 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_RX), /* ch. 35 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_TX), /* ch. 36 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_RX), /* ch. 36 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_TX), /* ch. 36 */ + HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_RX), /* ch. 36 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 39, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7778_register_hpb_dmae(void) { - phy = usb_get_phy(USB_PHY_TYPE_USB2); + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + +void __init r8a7778_add_standard_devices(void) +{ + r8a7778_add_dt_devices(); + r8a7778_register_i2c(0); + r8a7778_register_i2c(1); + r8a7778_register_i2c(2); + r8a7778_register_i2c(3); + r8a7778_register_hspi(0); + r8a7778_register_hspi(1); + r8a7778_register_hspi(2); + + r8a7778_register_hpb_dmae(); +} +void __init r8a7778_init_late(void) +{ platform_device_register_full(&ehci_info); 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 */ @@ -382,7 +540,7 @@ static struct resource irqpin_resources[] = { DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */ }; -void __init r8a7778_init_irq_extpin(int irlm) +void __init r8a7778_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); unsigned long tmp; @@ -400,7 +558,11 @@ void __init r8a7778_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7778_init_irq_extpin(int irlm) +{ + r8a7778_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, @@ -408,17 +570,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 +600,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,8 +608,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, MACHINE_END diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 398687761f5..aba4ed652d5 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -22,14 +22,17 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/irqchip.h> +#include <linux/irqchip/arm-gic.h> #include <linux/of_platform.h> +#include <linux/platform_data/dma-rcar-hpbdma.h> #include <linux/platform_data/gpio-rcar.h> +#include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/io.h> #include <linux/serial_sci.h> -#include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <linux/dma-mapping.h> #include <linux/usb/otg.h> @@ -37,7 +40,6 @@ #include <linux/usb/ehci_pdriver.h> #include <linux/usb/ohci_pdriver.h> #include <linux/pm_runtime.h> -#include <mach/hardware.h> #include <mach/irqs.h> #include <mach/r8a7779.h> #include <mach/common.h> @@ -69,6 +71,64 @@ void __init r8a7779_map_io(void) iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); } +/* IRQ */ +#define INT2SMSKCR0 IOMEM(0xfe7822a0) +#define INT2SMSKCR1 IOMEM(0xfe7822a4) +#define INT2SMSKCR2 IOMEM(0xfe7822a8) +#define INT2SMSKCR3 IOMEM(0xfe7822ac) +#define INT2SMSKCR4 IOMEM(0xfe7822b0) + +#define INT2NTSR0 IOMEM(0xfe700060) +#define INT2NTSR1 IOMEM(0xfe700064) + +static struct renesas_intc_irqpin_config irqpin0_platform_data __initdata = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ + .sense_bitfield_width = 2, +}; + +static struct resource irqpin0_resources[] __initdata = { + DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */ + DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */ + DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */ + DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */ + DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */ + DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ +}; + +void __init r8a7779_init_irq_extpin_dt(int irlm) +{ + void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); + u32 tmp; + + if (!icr0) { + pr_warn("r8a7779: unable to setup external irq pin mode\n"); + return; + } + + tmp = ioread32(icr0); + if (irlm) + tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */ + else + tmp &= ~(1 << 23); /* IRL mode - not supported */ + tmp |= (1 << 21); /* LVLMODE = 1 */ + iowrite32(tmp, icr0); + iounmap(icr0); +} + +void __init r8a7779_init_irq_extpin(int irlm) +{ + r8a7779_init_irq_extpin_dt(irlm); + if (irlm) + platform_device_register_resndata( + &platform_bus, "renesas_intc_irqpin", -1, + irqpin0_resources, ARRAY_SIZE(irqpin0_resources), + &irqpin0_platform_data, sizeof(irqpin0_platform_data)); +} + +/* PFC/GPIO */ static struct resource r8a7779_pfc_resources[] = { DEFINE_RES_MEM(0xfffc0000, 0x023c), }; @@ -128,167 +188,56 @@ void __init r8a7779_pinmux_init(void) ARRAY_SIZE(r8a7779_pinctrl_devices)); } -static struct plat_sci_port scif0_platform_data = { - .mapbase = 0xffe40000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, - .scbrr_algo_id = SCBRR_ALGO_2, - .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_iid(0x78)), -}; - -static struct platform_device scif0_device = { - .name = "sh-sci", - .id = 0, - .dev = { - .platform_data = &scif0_platform_data, - }, -}; - -static struct plat_sci_port scif1_platform_data = { - .mapbase = 0xffe41000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, - .scbrr_algo_id = SCBRR_ALGO_2, - .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_iid(0x79)), -}; - -static struct platform_device scif1_device = { - .name = "sh-sci", - .id = 1, - .dev = { - .platform_data = &scif1_platform_data, - }, -}; - -static struct plat_sci_port scif2_platform_data = { - .mapbase = 0xffe42000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, - .scbrr_algo_id = SCBRR_ALGO_2, - .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_iid(0x7a)), -}; - -static struct platform_device scif2_device = { - .name = "sh-sci", - .id = 2, - .dev = { - .platform_data = &scif2_platform_data, - }, -}; - -static struct plat_sci_port scif3_platform_data = { - .mapbase = 0xffe43000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, - .scbrr_algo_id = SCBRR_ALGO_2, - .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_iid(0x7b)), -}; - -static struct platform_device scif3_device = { - .name = "sh-sci", - .id = 3, - .dev = { - .platform_data = &scif3_platform_data, - }, -}; - -static struct plat_sci_port scif4_platform_data = { - .mapbase = 0xffe44000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, - .scbrr_algo_id = SCBRR_ALGO_2, - .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_iid(0x7c)), -}; - -static struct platform_device scif4_device = { - .name = "sh-sci", - .id = 4, - .dev = { - .platform_data = &scif4_platform_data, - }, -}; +/* SCIF */ +#define R8A7779_SCIF(index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ + .type = PORT_SCIF, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ +}; \ + \ +static struct platform_device scif##index##_device = { \ + .name = "sh-sci", \ + .id = index, \ + .resource = scif##index##_resources, \ + .num_resources = ARRAY_SIZE(scif##index##_resources), \ + .dev = { \ + .platform_data = &scif##index##_platform_data, \ + }, \ +} -static struct plat_sci_port scif5_platform_data = { - .mapbase = 0xffe45000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, - .scbrr_algo_id = SCBRR_ALGO_2, - .type = PORT_SCIF, - .irqs = SCIx_IRQ_MUXED(gic_iid(0x7d)), -}; - -static struct platform_device scif5_device = { - .name = "sh-sci", - .id = 5, - .dev = { - .platform_data = &scif5_platform_data, - }, -}; +R8A7779_SCIF(0, 0xffe40000, gic_iid(0x78)); +R8A7779_SCIF(1, 0xffe41000, gic_iid(0x79)); +R8A7779_SCIF(2, 0xffe42000, gic_iid(0x7a)); +R8A7779_SCIF(3, 0xffe43000, gic_iid(0x7b)); +R8A7779_SCIF(4, 0xffe44000, gic_iid(0x7c)); +R8A7779_SCIF(5, 0xffe45000, gic_iid(0x7d)); /* TMU */ -static struct sh_timer_config tmu00_platform_data = { - .name = "TMU00", - .channel_offset = 0x4, - .timer_bit = 0, - .clockevent_rating = 200, +static struct sh_timer_config tmu0_platform_data = { + .channels_mask = 7, }; -static struct resource tmu00_resources[] = { - [0] = { - .name = "TMU00", - .start = 0xffd80008, - .end = 0xffd80013, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_iid(0x40), - .flags = IORESOURCE_IRQ, - }, +static struct resource tmu0_resources[] = { + DEFINE_RES_MEM(0xffd80000, 0x30), + DEFINE_RES_IRQ(gic_iid(0x40)), + DEFINE_RES_IRQ(gic_iid(0x41)), + DEFINE_RES_IRQ(gic_iid(0x42)), }; -static struct platform_device tmu00_device = { - .name = "sh_tmu", +static struct platform_device tmu0_device = { + .name = "sh-tmu", .id = 0, .dev = { - .platform_data = &tmu00_platform_data, - }, - .resource = tmu00_resources, - .num_resources = ARRAY_SIZE(tmu00_resources), -}; - -static struct sh_timer_config tmu01_platform_data = { - .name = "TMU01", - .channel_offset = 0x10, - .timer_bit = 1, - .clocksource_rating = 200, -}; - -static struct resource tmu01_resources[] = { - [0] = { - .name = "TMU01", - .start = 0xffd80014, - .end = 0xffd8001f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_iid(0x41), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device tmu01_device = { - .name = "sh_tmu", - .id = 1, - .dev = { - .platform_data = &tmu01_platform_data, + .platform_data = &tmu0_platform_data, }, - .resource = tmu01_resources, - .num_resources = ARRAY_SIZE(tmu01_resources), + .resource = tmu0_resources, + .num_resources = ARRAY_SIZE(tmu0_resources), }; /* I2C */ @@ -388,15 +337,6 @@ static struct platform_device sata_device = { }, }; -/* USB PHY */ -static struct resource usb_phy_resources[] __initdata = { - [0] = { - .start = 0xffe70800, - .end = 0xffe70900 - 1, - .flags = IORESOURCE_MEM, - }, -}; - /* USB */ static struct usb_phy *phy; @@ -547,17 +487,157 @@ static struct platform_device ohci1_device = { .resource = ohci1_resources, }; -/* Ether */ -static struct resource ether_resources[] = { +/* HPB-DMA */ + +/* Asynchronous mode register bits */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { { - .start = 0xfde00000, - .end = 0xfde003ff, - .flags = IORESOURCE_MEM, + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, }, { - .start = gic_iid(0xb4), - .flags = IORESOURCE_IRQ, - }, -}; + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 44, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7779_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} static struct platform_device *r8a7779_devices_dt[] __initdata = { &scif0_device, @@ -566,8 +646,7 @@ static struct platform_device *r8a7779_devices_dt[] __initdata = { &scif3_device, &scif4_device, &scif5_device, - &tmu00_device, - &tmu01_device, + &tmu0_device, }; static struct platform_device *r8a7779_standard_devices[] __initdata = { @@ -581,8 +660,8 @@ static struct platform_device *r8a7779_standard_devices[] __initdata = { void __init r8a7779_add_standard_devices(void) { #ifdef CONFIG_CACHE_L2X0 - /* Early BRESP enable, Shared attribute override enable, 64K*16way */ - l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff); + /* Shared attribute override enable, 64K*16way */ + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff); #endif r8a7779_pm_init(); @@ -592,22 +671,7 @@ void __init r8a7779_add_standard_devices(void) ARRAY_SIZE(r8a7779_devices_dt)); platform_add_devices(r8a7779_standard_devices, ARRAY_SIZE(r8a7779_standard_devices)); -} - -void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) -{ - platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1, - ether_resources, - ARRAY_SIZE(ether_resources), - pdata, sizeof(*pdata)); -} - -void __init r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata) -{ - platform_device_register_resndata(&platform_bus, "rcar_usb_phy", -1, - usb_phy_resources, - ARRAY_SIZE(usb_phy_resources), - pdata, sizeof(*pdata)); + r8a7779_register_hpb_dmae(); } /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ @@ -616,8 +680,8 @@ void __init __weak r8a7779_register_twd(void) { } void __init r8a7779_earlytimer_init(void) { r8a7779_clock_init(); - shmobile_earlytimer_init(); r8a7779_register_twd(); + shmobile_earlytimer_init(); } void __init r8a7779_add_early_devices(void) @@ -660,15 +724,34 @@ void __init r8a7779_init_late(void) } #ifdef CONFIG_USE_OF +static int r8a7779_set_wake(struct irq_data *data, unsigned int on) +{ + return 0; /* always allow wakeup */ +} + +void __init r8a7779_init_irq_dt(void) +{ + gic_arch_extn.irq_set_wake = r8a7779_set_wake; + + irqchip_init(); + + /* route all interrupts to ARM */ + __raw_writel(0xffffffff, INT2NTSR0); + __raw_writel(0x3fffffff, INT2NTSR1); + + /* unmask all known interrupts in INTCS2 */ + __raw_writel(0xfffffff0, INT2SMSKCR0); + __raw_writel(0xfff7ffff, INT2SMSKCR1); + __raw_writel(0xfffbffdf, INT2SMSKCR2); + __raw_writel(0xbffffffc, INT2SMSKCR3); + __raw_writel(0x003fee3f, INT2SMSKCR4); +} + 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 +759,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 = { @@ -691,7 +773,6 @@ DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = r8a7779_add_standard_devices_dt, - .init_time = shmobile_timer_init, .init_late = r8a7779_init_late, .dt_compat = r8a7779_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 28f94752b8f..6bd08b127fa 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -19,28 +19,121 @@ */ #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_dma.h> +#include <linux/sh_timer.h> #include <mach/common.h> +#include <mach/dma-register.h> #include <mach/irqs.h> #include <mach/r8a7790.h> #include <asm/mach/arch.h> -static struct resource pfc_resources[] __initdata = { +/* Audio-DMAC */ +#define AUDIO_DMAC_SLAVE(_id, _addr, t, r) \ +{ \ + .slave_id = AUDIO_DMAC_SLAVE_## _id ##_TX, \ + .addr = _addr + 0x8, \ + .chcr = CHCR_TX(XMIT_SZ_32BIT), \ + .mid_rid = t, \ +}, { \ + .slave_id = AUDIO_DMAC_SLAVE_## _id ##_RX, \ + .addr = _addr + 0xc, \ + .chcr = CHCR_RX(XMIT_SZ_32BIT), \ + .mid_rid = r, \ +} + +static const struct sh_dmae_slave_config r8a7790_audio_dmac_slaves[] = { + AUDIO_DMAC_SLAVE(SSI0, 0xec241000, 0x01, 0x02), + AUDIO_DMAC_SLAVE(SSI1, 0xec241040, 0x03, 0x04), + AUDIO_DMAC_SLAVE(SSI2, 0xec241080, 0x05, 0x06), + AUDIO_DMAC_SLAVE(SSI3, 0xec2410c0, 0x07, 0x08), + AUDIO_DMAC_SLAVE(SSI4, 0xec241100, 0x09, 0x0a), + AUDIO_DMAC_SLAVE(SSI5, 0xec241140, 0x0b, 0x0c), + AUDIO_DMAC_SLAVE(SSI6, 0xec241180, 0x0d, 0x0e), + AUDIO_DMAC_SLAVE(SSI7, 0xec2411c0, 0x0f, 0x10), + AUDIO_DMAC_SLAVE(SSI8, 0xec241200, 0x11, 0x12), + AUDIO_DMAC_SLAVE(SSI9, 0xec241240, 0x13, 0x14), +}; + +#define DMAE_CHANNEL(a, b) \ +{ \ + .offset = (a) - 0x20, \ + .dmars = (a) - 0x20 + 0x40, \ + .chclr_bit = (b), \ + .chclr_offset = 0x80 - 0x20, \ +} + +static const struct sh_dmae_channel r8a7790_audio_dmac_channels[] = { + DMAE_CHANNEL(0x8000, 0), + DMAE_CHANNEL(0x8080, 1), + DMAE_CHANNEL(0x8100, 2), + DMAE_CHANNEL(0x8180, 3), + DMAE_CHANNEL(0x8200, 4), + DMAE_CHANNEL(0x8280, 5), + DMAE_CHANNEL(0x8300, 6), + DMAE_CHANNEL(0x8380, 7), + DMAE_CHANNEL(0x8400, 8), + DMAE_CHANNEL(0x8480, 9), + DMAE_CHANNEL(0x8500, 10), + DMAE_CHANNEL(0x8580, 11), + DMAE_CHANNEL(0x8600, 12), +}; + +static struct sh_dmae_pdata r8a7790_audio_dmac_platform_data = { + .slave = r8a7790_audio_dmac_slaves, + .slave_num = ARRAY_SIZE(r8a7790_audio_dmac_slaves), + .channel = r8a7790_audio_dmac_channels, + .channel_num = ARRAY_SIZE(r8a7790_audio_dmac_channels), + .ts_low_shift = TS_LOW_SHIFT, + .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, + .ts_high_shift = TS_HI_SHIFT, + .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, + .ts_shift = dma_ts_shift, + .ts_shift_num = ARRAY_SIZE(dma_ts_shift), + .dmaor_init = DMAOR_DME, + .chclr_present = 1, + .chclr_bitwise = 1, +}; + +static struct resource r8a7790_audio_dmac_resources[] = { + /* Channel registers and DMAOR for low */ + DEFINE_RES_MEM(0xec700020, 0x8663 - 0x20), + DEFINE_RES_IRQ(gic_spi(346)), + DEFINE_RES_NAMED(gic_spi(320), 13, NULL, IORESOURCE_IRQ), + + /* Channel registers and DMAOR for hi */ + DEFINE_RES_MEM(0xec720020, 0x8663 - 0x20), /* hi */ + DEFINE_RES_IRQ(gic_spi(347)), + DEFINE_RES_NAMED(gic_spi(333), 13, NULL, IORESOURCE_IRQ), +}; + +#define r8a7790_register_audio_dmac(id) \ + platform_device_register_resndata( \ + &platform_bus, "sh-dma-engine", id, \ + &r8a7790_audio_dmac_resources[id * 3], 3, \ + &r8a7790_audio_dmac_platform_data, \ + sizeof(r8a7790_audio_dmac_platform_data)) + +static const struct resource pfc_resources[] __initconst = { DEFINE_RES_MEM(0xe6060000, 0x250), }; +#define r8a7790_register_pfc() \ + platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, \ + ARRAY_SIZE(pfc_resources)) + #define R8A7790_GPIO(idx) \ -static struct resource r8a7790_gpio##idx##_resources[] __initdata = { \ +static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \ DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \ DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ }; \ \ -static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = { \ +static const struct gpio_rcar_config \ +r8a7790_gpio##idx##_platform_data __initconst = { \ .gpio_base = 32 * (idx), \ .irq_base = 0, \ .number_of_pins = 32, \ @@ -62,10 +155,30 @@ R8A7790_GPIO(5); &r8a7790_gpio##idx##_platform_data, \ sizeof(r8a7790_gpio##idx##_platform_data)) +static struct resource i2c_resources[] __initdata = { + /* I2C0 */ + DEFINE_RES_MEM(0xE6508000, 0x40), + DEFINE_RES_IRQ(gic_spi(287)), + /* I2C1 */ + DEFINE_RES_MEM(0xE6518000, 0x40), + DEFINE_RES_IRQ(gic_spi(288)), + /* I2C2 */ + DEFINE_RES_MEM(0xE6530000, 0x40), + DEFINE_RES_IRQ(gic_spi(286)), + /* I2C3 */ + DEFINE_RES_MEM(0xE6540000, 0x40), + DEFINE_RES_IRQ(gic_spi(290)), + +}; + +#define r8a7790_register_i2c(idx) \ + platform_device_register_simple( \ + "i2c-rcar_gen2", idx, \ + i2c_resources + (2 * idx), 2); \ + void __init r8a7790_pinmux_init(void) { - platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, - ARRAY_SIZE(pfc_resources)); + r8a7790_register_pfc(); r8a7790_register_gpio(0); r8a7790_register_gpio(1); r8a7790_register_gpio(2); @@ -74,67 +187,57 @@ void __init r8a7790_pinmux_init(void) r8a7790_register_gpio(5); } -#define SCIF_COMMON(scif_type, baseaddr, irq) \ - .type = scif_type, \ - .mapbase = baseaddr, \ - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ - .irqs = SCIx_IRQ_MUXED(irq) - -#define SCIFA_DATA(index, baseaddr, irq) \ -[index] = { \ - SCIF_COMMON(PORT_SCIFA, baseaddr, irq), \ - .scbrr_algo_id = SCBRR_ALGO_4, \ - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE0, \ +#define __R8A7790_SCIF(scif_type, _scscr, index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ + .type = scif_type, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scscr = _scscr, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ } -#define SCIFB_DATA(index, baseaddr, irq) \ -[index] = { \ - SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \ - .scbrr_algo_id = SCBRR_ALGO_4, \ - .scscr = SCSCR_RE | SCSCR_TE, \ -} +#define R8A7790_SCIF(index, baseaddr, irq) \ + __R8A7790_SCIF(PORT_SCIF, SCSCR_RE | SCSCR_TE, \ + index, baseaddr, irq) -#define SCIF_DATA(index, baseaddr, irq) \ -[index] = { \ - SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ - .scbrr_algo_id = SCBRR_ALGO_2, \ - .scscr = SCSCR_RE | SCSCR_TE, \ -} +#define R8A7790_SCIFA(index, baseaddr, irq) \ + __R8A7790_SCIF(PORT_SCIFA, SCSCR_RE | SCSCR_TE | SCSCR_CKE0, \ + index, baseaddr, irq) -#define HSCIF_DATA(index, baseaddr, irq) \ -[index] = { \ - SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ - .scbrr_algo_id = SCBRR_ALGO_6, \ - .scscr = SCSCR_RE | SCSCR_TE, \ -} +#define R8A7790_SCIFB(index, baseaddr, irq) \ + __R8A7790_SCIF(PORT_SCIFB, SCSCR_RE | SCSCR_TE, \ + index, baseaddr, irq) -enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, - HSCIF0, HSCIF1 }; - -static struct plat_sci_port scif[] __initdata = { - SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ - SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ - SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ - SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */ - SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */ - SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ - SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ - SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ - HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */ - HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */ -}; +#define R8A7790_HSCIF(index, baseaddr, irq) \ + __R8A7790_SCIF(PORT_HSCIF, SCSCR_RE | SCSCR_TE, \ + index, baseaddr, irq) -static inline void r8a7790_register_scif(int idx) -{ - platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], - sizeof(struct plat_sci_port)); -} +R8A7790_SCIFA(0, 0xe6c40000, gic_spi(144)); /* SCIFA0 */ +R8A7790_SCIFA(1, 0xe6c50000, gic_spi(145)); /* SCIFA1 */ +R8A7790_SCIFB(2, 0xe6c20000, gic_spi(148)); /* SCIFB0 */ +R8A7790_SCIFB(3, 0xe6c30000, gic_spi(149)); /* SCIFB1 */ +R8A7790_SCIFB(4, 0xe6ce0000, gic_spi(150)); /* SCIFB2 */ +R8A7790_SCIFA(5, 0xe6c60000, gic_spi(151)); /* SCIFA2 */ +R8A7790_SCIF(6, 0xe6e60000, gic_spi(152)); /* SCIF0 */ +R8A7790_SCIF(7, 0xe6e68000, gic_spi(153)); /* SCIF1 */ +R8A7790_HSCIF(8, 0xe62c0000, gic_spi(154)); /* HSCIF0 */ +R8A7790_HSCIF(9, 0xe62c8000, gic_spi(155)); /* HSCIF1 */ -static struct renesas_irqc_config irqc0_data __initdata = { +#define r8a7790_register_scif(index) \ + platform_device_register_resndata(&platform_bus, "sh-sci", index, \ + scif##index##_resources, \ + ARRAY_SIZE(scif##index##_resources), \ + &scif##index##_platform_data, \ + sizeof(scif##index##_platform_data)) + +static const struct renesas_irqc_config irqc0_data __initconst = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ }; -static struct resource irqc0_resources[] __initdata = { +static const struct resource irqc0_resources[] __initconst = { DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ @@ -149,48 +252,79 @@ static struct resource irqc0_resources[] __initdata = { &irqc##idx##_data, \ sizeof(struct renesas_irqc_config)) +static const struct resource thermal_resources[] __initconst = { + 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 cmt0_platform_data = { + .channels_mask = 0x60, +}; + +static struct resource cmt0_resources[] = { + DEFINE_RES_MEM(0xffca0000, 0x1004), + DEFINE_RES_IRQ(gic_spi(142)), +}; + +#define r8a7790_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + +void __init r8a7790_add_dt_devices(void) +{ + r8a7790_register_cmt(0); +} + void __init r8a7790_add_standard_devices(void) { - r8a7790_register_scif(SCIFA0); - r8a7790_register_scif(SCIFA1); - r8a7790_register_scif(SCIFB0); - r8a7790_register_scif(SCIFB1); - r8a7790_register_scif(SCIFB2); - r8a7790_register_scif(SCIFA2); - r8a7790_register_scif(SCIF0); - r8a7790_register_scif(SCIF1); - r8a7790_register_scif(HSCIF0); - r8a7790_register_scif(HSCIF1); + r8a7790_register_scif(0); + r8a7790_register_scif(1); + r8a7790_register_scif(2); + r8a7790_register_scif(3); + r8a7790_register_scif(4); + r8a7790_register_scif(5); + r8a7790_register_scif(6); + r8a7790_register_scif(7); + r8a7790_register_scif(8); + r8a7790_register_scif(9); + r8a7790_add_dt_devices(); r8a7790_register_irqc(0); + r8a7790_register_thermal(); + r8a7790_register_i2c(0); + r8a7790_register_i2c(1); + r8a7790_register_i2c(2); + r8a7790_register_i2c(3); + r8a7790_register_audio_dmac(0); + r8a7790_register_audio_dmac(1); } -void __init r8a7790_timer_init(void) +void __init r8a7790_init_early(void) { - void __iomem *cntcr; - - /* make sure arch timer is started by setting bit 0 of CNTCT */ - cntcr = ioremap(0xe6080000, PAGE_SIZE); - iowrite32(1, cntcr); - iounmap(cntcr); - - shmobile_timer_init(); +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ +#endif } #ifdef CONFIG_USE_OF -void __init r8a7790_add_standard_devices_dt(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -} -static const char *r8a7790_boards_compat_dt[] __initdata = { +static const char * const r8a7790_boards_compat_dt[] __initconst = { "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_time = r8a7790_timer_init, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c new file mode 100644 index 00000000000..04a96ddb322 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -0,0 +1,222 @@ +/* + * r8a7791 processor support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * 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/irq.h> +#include <linux/kernel.h> +#include <linux/of_platform.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/r8a7791.h> +#include <mach/rcar-gen2.h> +#include <asm/mach/arch.h> + +static const struct resource pfc_resources[] __initconst = { + DEFINE_RES_MEM(0xe6060000, 0x250), +}; + +#define r8a7791_register_pfc() \ + platform_device_register_simple("pfc-r8a7791", -1, pfc_resources, \ + ARRAY_SIZE(pfc_resources)) + +#define R8A7791_GPIO(idx, base, nr) \ +static const struct resource r8a7791_gpio##idx##_resources[] __initconst = { \ + DEFINE_RES_MEM((base), 0x50), \ + DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ +}; \ + \ +static const struct gpio_rcar_config \ +r8a7791_gpio##idx##_platform_data __initconst = { \ + .gpio_base = 32 * (idx), \ + .irq_base = 0, \ + .number_of_pins = (nr), \ + .pctl_name = "pfc-r8a7791", \ + .has_both_edge_trigger = 1, \ +}; \ + +R8A7791_GPIO(0, 0xe6050000, 32); +R8A7791_GPIO(1, 0xe6051000, 32); +R8A7791_GPIO(2, 0xe6052000, 32); +R8A7791_GPIO(3, 0xe6053000, 32); +R8A7791_GPIO(4, 0xe6054000, 32); +R8A7791_GPIO(5, 0xe6055000, 32); +R8A7791_GPIO(6, 0xe6055400, 32); +R8A7791_GPIO(7, 0xe6055800, 26); + +#define r8a7791_register_gpio(idx) \ + platform_device_register_resndata(&platform_bus, "gpio_rcar", idx, \ + r8a7791_gpio##idx##_resources, \ + ARRAY_SIZE(r8a7791_gpio##idx##_resources), \ + &r8a7791_gpio##idx##_platform_data, \ + sizeof(r8a7791_gpio##idx##_platform_data)) + +void __init r8a7791_pinmux_init(void) +{ + r8a7791_register_pfc(); + r8a7791_register_gpio(0); + r8a7791_register_gpio(1); + r8a7791_register_gpio(2); + r8a7791_register_gpio(3); + r8a7791_register_gpio(4); + r8a7791_register_gpio(5); + r8a7791_register_gpio(6); + r8a7791_register_gpio(7); +} + +#define __R8A7791_SCIF(scif_type, index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ + .type = scif_type, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ +} + +#define R8A7791_SCIF(index, baseaddr, irq) \ + __R8A7791_SCIF(PORT_SCIF, index, baseaddr, irq) + +#define R8A7791_SCIFA(index, baseaddr, irq) \ + __R8A7791_SCIF(PORT_SCIFA, index, baseaddr, irq) + +#define R8A7791_SCIFB(index, baseaddr, irq) \ + __R8A7791_SCIF(PORT_SCIFB, index, baseaddr, irq) + +R8A7791_SCIFA(0, 0xe6c40000, gic_spi(144)); /* SCIFA0 */ +R8A7791_SCIFA(1, 0xe6c50000, gic_spi(145)); /* SCIFA1 */ +R8A7791_SCIFB(2, 0xe6c20000, gic_spi(148)); /* SCIFB0 */ +R8A7791_SCIFB(3, 0xe6c30000, gic_spi(149)); /* SCIFB1 */ +R8A7791_SCIFB(4, 0xe6ce0000, gic_spi(150)); /* SCIFB2 */ +R8A7791_SCIFA(5, 0xe6c60000, gic_spi(151)); /* SCIFA2 */ +R8A7791_SCIF(6, 0xe6e60000, gic_spi(152)); /* SCIF0 */ +R8A7791_SCIF(7, 0xe6e68000, gic_spi(153)); /* SCIF1 */ +R8A7791_SCIF(8, 0xe6e58000, gic_spi(22)); /* SCIF2 */ +R8A7791_SCIF(9, 0xe6ea8000, gic_spi(23)); /* SCIF3 */ +R8A7791_SCIF(10, 0xe6ee0000, gic_spi(24)); /* SCIF4 */ +R8A7791_SCIF(11, 0xe6ee8000, gic_spi(25)); /* SCIF5 */ +R8A7791_SCIFA(12, 0xe6c70000, gic_spi(29)); /* SCIFA3 */ +R8A7791_SCIFA(13, 0xe6c78000, gic_spi(30)); /* SCIFA4 */ +R8A7791_SCIFA(14, 0xe6c80000, gic_spi(31)); /* SCIFA5 */ + +#define r8a7791_register_scif(index) \ + platform_device_register_resndata(&platform_bus, "sh-sci", index, \ + scif##index##_resources, \ + ARRAY_SIZE(scif##index##_resources), \ + &scif##index##_platform_data, \ + sizeof(scif##index##_platform_data)) + +static struct sh_timer_config cmt0_platform_data = { + .channels_mask = 0x60, +}; + +static struct resource cmt0_resources[] = { + DEFINE_RES_MEM(0xffca0000, 0x1004), + DEFINE_RES_IRQ(gic_spi(142)), +}; + +#define r8a7791_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + +static struct renesas_irqc_config irqc0_data = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */ +}; + +static struct resource irqc0_resources[] = { + DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ + DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */ + DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */ + DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */ + DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */ + DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */ + DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */ + DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */ +}; + +#define r8a7791_register_irqc(idx) \ + platform_device_register_resndata(&platform_bus, "renesas_irqc", \ + idx, irqc##idx##_resources, \ + ARRAY_SIZE(irqc##idx##_resources), \ + &irqc##idx##_data, \ + sizeof(struct renesas_irqc_config)) + +static const struct resource thermal_resources[] __initconst = { + DEFINE_RES_MEM(0xe61f0000, 0x14), + DEFINE_RES_MEM(0xe61f0100, 0x38), + DEFINE_RES_IRQ(gic_spi(69)), +}; + +#define r8a7791_register_thermal() \ + platform_device_register_simple("rcar_thermal", -1, \ + thermal_resources, \ + ARRAY_SIZE(thermal_resources)) + +void __init r8a7791_add_dt_devices(void) +{ + r8a7791_register_cmt(0); +} + +void __init r8a7791_add_standard_devices(void) +{ + r8a7791_register_scif(0); + r8a7791_register_scif(1); + r8a7791_register_scif(2); + r8a7791_register_scif(3); + r8a7791_register_scif(4); + r8a7791_register_scif(5); + r8a7791_register_scif(6); + r8a7791_register_scif(7); + r8a7791_register_scif(8); + r8a7791_register_scif(9); + r8a7791_register_scif(10); + r8a7791_register_scif(11); + r8a7791_register_scif(12); + r8a7791_register_scif(13); + r8a7791_register_scif(14); + r8a7791_add_dt_devices(); + r8a7791_register_irqc(0); + r8a7791_register_thermal(); +} + +#ifdef CONFIG_USE_OF +static const char *r8a7791_boards_compat_dt[] __initdata = { + "renesas,r8a7791", + NULL, +}; + +DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .smp = smp_ops(r8a7791_smp_ops), + .init_early = shmobile_init_delay, + .init_time = rcar_gen2_timer_init, + .dt_compat = r8a7791_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c new file mode 100644 index 00000000000..542c5a47173 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -0,0 +1,112 @@ +/* + * R-Car Generation 2 support + * + * 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/clk/shmobile.h> +#include <linux/clocksource.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <mach/common.h> +#include <mach/rcar-gen2.h> +#include <asm/mach/arch.h> + +#define MODEMR 0xe6160060 + +u32 rcar_gen2_read_mode_pins(void) +{ + static u32 mode; + static bool mode_valid; + + if (!mode_valid) { + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + mode_valid = true; + } + + return mode; +} + +#define CNTCR 0 +#define CNTFID0 0x20 + +void __init rcar_gen2_timer_init(void) +{ +#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK) + u32 mode = rcar_gen2_read_mode_pins(); +#endif +#ifdef CONFIG_ARM_ARCH_TIMER + 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; + } + + /* The arch timer frequency equals EXTAL / 2 */ + freq = extal_mhz * (1000000 / 2); + + /* Remap "armgcnt address map" space */ + base = ioremap(0xe6080000, PAGE_SIZE); + + /* + * Update the timer if it is either not running, or is not at the + * right frequency. The timer is only configurable in secure mode + * so this avoids an abort if the loader started the timer and + * entered the kernel in non-secure mode. + */ + + if ((ioread32(base + CNTCR) & 1) == 0 || + ioread32(base + CNTFID0) != freq) { + /* 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 */ + +#ifdef CONFIG_COMMON_CLK + rcar_gen2_clocks_init(mode); +#endif + clocksource_of_init(); +} diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 5502d624aca..2a8b9f2a2f5 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -35,7 +35,6 @@ #include <linux/dma-mapping.h> #include <linux/platform_data/sh_ipmmu.h> #include <mach/dma-register.h> -#include <mach/hardware.h> #include <mach/irqs.h> #include <mach/sh7372.h> #include <mach/common.h> @@ -87,163 +86,49 @@ void __init sh7372_pinmux_init(void) platform_device_register(&sh7372_pfc_device); } -/* SCIFA0 */ -static struct plat_sci_port scif0_platform_data = { - .mapbase = 0xe6c40000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { evt2irq(0x0c00), evt2irq(0x0c00), - evt2irq(0x0c00), evt2irq(0x0c00) }, -}; - -static struct platform_device scif0_device = { - .name = "sh-sci", - .id = 0, - .dev = { - .platform_data = &scif0_platform_data, - }, -}; - -/* SCIFA1 */ -static struct plat_sci_port scif1_platform_data = { - .mapbase = 0xe6c50000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { evt2irq(0x0c20), evt2irq(0x0c20), - evt2irq(0x0c20), evt2irq(0x0c20) }, -}; - -static struct platform_device scif1_device = { - .name = "sh-sci", - .id = 1, - .dev = { - .platform_data = &scif1_platform_data, - }, -}; - -/* SCIFA2 */ -static struct plat_sci_port scif2_platform_data = { - .mapbase = 0xe6c60000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { evt2irq(0x0c40), evt2irq(0x0c40), - evt2irq(0x0c40), evt2irq(0x0c40) }, -}; - -static struct platform_device scif2_device = { - .name = "sh-sci", - .id = 2, - .dev = { - .platform_data = &scif2_platform_data, - }, -}; - -/* SCIFA3 */ -static struct plat_sci_port scif3_platform_data = { - .mapbase = 0xe6c70000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { evt2irq(0x0c60), evt2irq(0x0c60), - evt2irq(0x0c60), evt2irq(0x0c60) }, -}; - -static struct platform_device scif3_device = { - .name = "sh-sci", - .id = 3, - .dev = { - .platform_data = &scif3_platform_data, - }, -}; - -/* SCIFA4 */ -static struct plat_sci_port scif4_platform_data = { - .mapbase = 0xe6c80000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { evt2irq(0x0d20), evt2irq(0x0d20), - evt2irq(0x0d20), evt2irq(0x0d20) }, -}; - -static struct platform_device scif4_device = { - .name = "sh-sci", - .id = 4, - .dev = { - .platform_data = &scif4_platform_data, - }, -}; - -/* SCIFA5 */ -static struct plat_sci_port scif5_platform_data = { - .mapbase = 0xe6cb0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { evt2irq(0x0d40), evt2irq(0x0d40), - evt2irq(0x0d40), evt2irq(0x0d40) }, -}; - -static struct platform_device scif5_device = { - .name = "sh-sci", - .id = 5, - .dev = { - .platform_data = &scif5_platform_data, - }, -}; +/* SCIF */ +#define SH7372_SCIF(scif_type, index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ + .type = scif_type, \ + .flags = UPF_BOOT_AUTOCONF, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ +}; \ + \ +static struct platform_device scif##index##_device = { \ + .name = "sh-sci", \ + .id = index, \ + .resource = scif##index##_resources, \ + .num_resources = ARRAY_SIZE(scif##index##_resources), \ + .dev = { \ + .platform_data = &scif##index##_platform_data, \ + }, \ +} -/* SCIFB */ -static struct plat_sci_port scif6_platform_data = { - .mapbase = 0xe6c30000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFB, - .irqs = { evt2irq(0x0d60), evt2irq(0x0d60), - evt2irq(0x0d60), evt2irq(0x0d60) }, -}; - -static struct platform_device scif6_device = { - .name = "sh-sci", - .id = 6, - .dev = { - .platform_data = &scif6_platform_data, - }, -}; +SH7372_SCIF(PORT_SCIFA, 0, 0xe6c40000, evt2irq(0x0c00)); +SH7372_SCIF(PORT_SCIFA, 1, 0xe6c50000, evt2irq(0x0c20)); +SH7372_SCIF(PORT_SCIFA, 2, 0xe6c60000, evt2irq(0x0c40)); +SH7372_SCIF(PORT_SCIFA, 3, 0xe6c70000, evt2irq(0x0c60)); +SH7372_SCIF(PORT_SCIFA, 4, 0xe6c80000, evt2irq(0x0d20)); +SH7372_SCIF(PORT_SCIFA, 5, 0xe6cb0000, evt2irq(0x0d40)); +SH7372_SCIF(PORT_SCIFB, 6, 0xe6c30000, evt2irq(0x0d60)); /* CMT */ static struct sh_timer_config cmt2_platform_data = { - .name = "CMT2", - .channel_offset = 0x40, - .timer_bit = 5, - .clockevent_rating = 125, - .clocksource_rating = 125, + .channels_mask = 0x20, }; static struct resource cmt2_resources[] = { - [0] = { - .name = "CMT2", - .start = 0xe6130040, - .end = 0xe613004b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = evt2irq(0x0b80), /* CMT2 */ - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_MEM(0xe6130000, 0x50), + DEFINE_RES_IRQ(evt2irq(0x0b80)), }; static struct platform_device cmt2_device = { - .name = "sh_cmt", + .name = "sh-cmt-32-fast", .id = 2, .dev = { .platform_data = &cmt2_platform_data, @@ -253,64 +138,25 @@ static struct platform_device cmt2_device = { }; /* TMU */ -static struct sh_timer_config tmu00_platform_data = { - .name = "TMU00", - .channel_offset = 0x4, - .timer_bit = 0, - .clockevent_rating = 200, +static struct sh_timer_config tmu0_platform_data = { + .channels_mask = 7, }; -static struct resource tmu00_resources[] = { - [0] = { - .name = "TMU00", - .start = 0xfff60008, - .end = 0xfff60013, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */ - .flags = IORESOURCE_IRQ, - }, +static struct resource tmu0_resources[] = { + DEFINE_RES_MEM(0xfff60000, 0x2c), + DEFINE_RES_IRQ(intcs_evt2irq(0xe80)), + DEFINE_RES_IRQ(intcs_evt2irq(0xea0)), + DEFINE_RES_IRQ(intcs_evt2irq(0xec0)), }; -static struct platform_device tmu00_device = { - .name = "sh_tmu", +static struct platform_device tmu0_device = { + .name = "sh-tmu", .id = 0, .dev = { - .platform_data = &tmu00_platform_data, + .platform_data = &tmu0_platform_data, }, - .resource = tmu00_resources, - .num_resources = ARRAY_SIZE(tmu00_resources), -}; - -static struct sh_timer_config tmu01_platform_data = { - .name = "TMU01", - .channel_offset = 0x10, - .timer_bit = 1, - .clocksource_rating = 200, -}; - -static struct resource tmu01_resources[] = { - [0] = { - .name = "TMU01", - .start = 0xfff60014, - .end = 0xfff6001f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device tmu01_device = { - .name = "sh_tmu", - .id = 1, - .dev = { - .platform_data = &tmu01_platform_data, - }, - .resource = tmu01_resources, - .num_resources = ARRAY_SIZE(tmu01_resources), + .resource = tmu0_resources, + .num_resources = ARRAY_SIZE(tmu0_resources), }; /* I2C */ @@ -1055,8 +901,7 @@ static struct platform_device *sh7372_early_devices[] __initdata = { &scif5_device, &scif6_device, &cmt2_device, - &tmu00_device, - &tmu01_device, + &tmu0_device, &ipmmu_device, }; @@ -1103,8 +948,7 @@ void __init sh7372_add_standard_devices(void) { "A4R", &veu2_device, }, { "A4R", &veu3_device, }, { "A4R", &jpu_device, }, - { "A4R", &tmu00_device, }, - { "A4R", &tmu01_device, }, + { "A4R", &tmu0_device, }, }; sh7372_init_pm_domains(); @@ -1140,17 +984,9 @@ void __init sh7372_add_early_devices_dt(void) { shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */ - early_platform_add_devices(sh7372_early_devices, - ARRAY_SIZE(sh7372_early_devices)); - - /* setup early console here as well */ - shmobile_setup_console(); + sh7372_add_early_devices(); } -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 +995,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 96e7ca1e4e1..ad00724a226 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> @@ -35,7 +34,6 @@ #include <linux/platform_data/sh_ipmmu.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <mach/dma-register.h> -#include <mach/hardware.h> #include <mach/irqs.h> #include <mach/sh73a0.h> #include <mach/common.h> @@ -61,277 +59,94 @@ 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 = { - .mapbase = 0xe6c40000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(72), gic_spi(72), - gic_spi(72), gic_spi(72) }, -}; - -static struct platform_device scif0_device = { - .name = "sh-sci", - .id = 0, - .dev = { - .platform_data = &scif0_platform_data, - }, -}; - -static struct plat_sci_port scif1_platform_data = { - .mapbase = 0xe6c50000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(73), gic_spi(73), - gic_spi(73), gic_spi(73) }, -}; - -static struct platform_device scif1_device = { - .name = "sh-sci", - .id = 1, - .dev = { - .platform_data = &scif1_platform_data, - }, -}; - -static struct plat_sci_port scif2_platform_data = { - .mapbase = 0xe6c60000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(74), gic_spi(74), - gic_spi(74), gic_spi(74) }, -}; - -static struct platform_device scif2_device = { - .name = "sh-sci", - .id = 2, - .dev = { - .platform_data = &scif2_platform_data, - }, -}; - -static struct plat_sci_port scif3_platform_data = { - .mapbase = 0xe6c70000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(75), gic_spi(75), - gic_spi(75), gic_spi(75) }, -}; - -static struct platform_device scif3_device = { - .name = "sh-sci", - .id = 3, - .dev = { - .platform_data = &scif3_platform_data, - }, -}; - -static struct plat_sci_port scif4_platform_data = { - .mapbase = 0xe6c80000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(78), gic_spi(78), - gic_spi(78), gic_spi(78) }, -}; - -static struct platform_device scif4_device = { - .name = "sh-sci", - .id = 4, - .dev = { - .platform_data = &scif4_platform_data, - }, -}; - -static struct plat_sci_port scif5_platform_data = { - .mapbase = 0xe6cb0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(79), gic_spi(79), - gic_spi(79), gic_spi(79) }, -}; - -static struct platform_device scif5_device = { - .name = "sh-sci", - .id = 5, - .dev = { - .platform_data = &scif5_platform_data, - }, -}; - -static struct plat_sci_port scif6_platform_data = { - .mapbase = 0xe6cc0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(156), gic_spi(156), - gic_spi(156), gic_spi(156) }, -}; - -static struct platform_device scif6_device = { - .name = "sh-sci", - .id = 6, - .dev = { - .platform_data = &scif6_platform_data, - }, -}; - -static struct plat_sci_port scif7_platform_data = { - .mapbase = 0xe6cd0000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFA, - .irqs = { gic_spi(143), gic_spi(143), - gic_spi(143), gic_spi(143) }, -}; - -static struct platform_device scif7_device = { - .name = "sh-sci", - .id = 7, - .dev = { - .platform_data = &scif7_platform_data, - }, -}; - -static struct plat_sci_port scif8_platform_data = { - .mapbase = 0xe6c30000, - .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE, - .scbrr_algo_id = SCBRR_ALGO_4, - .type = PORT_SCIFB, - .irqs = { gic_spi(80), gic_spi(80), - gic_spi(80), gic_spi(80) }, -}; +/* SCIF */ +#define SH73A0_SCIF(scif_type, index, baseaddr, irq) \ +static struct plat_sci_port scif##index##_platform_data = { \ + .type = scif_type, \ + .flags = UPF_BOOT_AUTOCONF, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +}; \ + \ +static struct resource scif##index##_resources[] = { \ + DEFINE_RES_MEM(baseaddr, 0x100), \ + DEFINE_RES_IRQ(irq), \ +}; \ + \ +static struct platform_device scif##index##_device = { \ + .name = "sh-sci", \ + .id = index, \ + .resource = scif##index##_resources, \ + .num_resources = ARRAY_SIZE(scif##index##_resources), \ + .dev = { \ + .platform_data = &scif##index##_platform_data, \ + }, \ +} -static struct platform_device scif8_device = { - .name = "sh-sci", - .id = 8, - .dev = { - .platform_data = &scif8_platform_data, - }, -}; +SH73A0_SCIF(PORT_SCIFA, 0, 0xe6c40000, gic_spi(72)); +SH73A0_SCIF(PORT_SCIFA, 1, 0xe6c50000, gic_spi(73)); +SH73A0_SCIF(PORT_SCIFA, 2, 0xe6c60000, gic_spi(74)); +SH73A0_SCIF(PORT_SCIFA, 3, 0xe6c70000, gic_spi(75)); +SH73A0_SCIF(PORT_SCIFA, 4, 0xe6c80000, gic_spi(78)); +SH73A0_SCIF(PORT_SCIFA, 5, 0xe6cb0000, gic_spi(79)); +SH73A0_SCIF(PORT_SCIFA, 6, 0xe6cc0000, gic_spi(156)); +SH73A0_SCIF(PORT_SCIFA, 7, 0xe6cd0000, gic_spi(143)); +SH73A0_SCIF(PORT_SCIFB, 8, 0xe6c30000, gic_spi(80)); -static struct sh_timer_config cmt10_platform_data = { - .name = "CMT10", - .channel_offset = 0x10, - .timer_bit = 0, - .clockevent_rating = 80, - .clocksource_rating = 125, +static struct sh_timer_config cmt1_platform_data = { + .channels_mask = 0x3f, }; -static struct resource cmt10_resources[] = { - [0] = { - .name = "CMT10", - .start = 0xe6138010, - .end = 0xe613801b, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = gic_spi(65), - .flags = IORESOURCE_IRQ, - }, +static struct resource cmt1_resources[] = { + DEFINE_RES_MEM(0xe6138000, 0x200), + DEFINE_RES_IRQ(gic_spi(65)), }; -static struct platform_device cmt10_device = { - .name = "sh_cmt", - .id = 10, +static struct platform_device cmt1_device = { + .name = "sh-cmt-48", + .id = 1, .dev = { - .platform_data = &cmt10_platform_data, + .platform_data = &cmt1_platform_data, }, - .resource = cmt10_resources, - .num_resources = ARRAY_SIZE(cmt10_resources), + .resource = cmt1_resources, + .num_resources = ARRAY_SIZE(cmt1_resources), }; /* TMU */ -static struct sh_timer_config tmu00_platform_data = { - .name = "TMU00", - .channel_offset = 0x4, - .timer_bit = 0, - .clockevent_rating = 200, +static struct sh_timer_config tmu0_platform_data = { + .channels_mask = 7, }; -static struct resource tmu00_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xfff60008, 0xc, "TMU00"), - [1] = { - .start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */ - .flags = IORESOURCE_IRQ, - }, +static struct resource tmu0_resources[] = { + DEFINE_RES_MEM(0xfff60000, 0x2c), + DEFINE_RES_IRQ(intcs_evt2irq(0xe80)), + DEFINE_RES_IRQ(intcs_evt2irq(0xea0)), + DEFINE_RES_IRQ(intcs_evt2irq(0xec0)), }; -static struct platform_device tmu00_device = { - .name = "sh_tmu", +static struct platform_device tmu0_device = { + .name = "sh-tmu", .id = 0, .dev = { - .platform_data = &tmu00_platform_data, - }, - .resource = tmu00_resources, - .num_resources = ARRAY_SIZE(tmu00_resources), -}; - -static struct sh_timer_config tmu01_platform_data = { - .name = "TMU01", - .channel_offset = 0x10, - .timer_bit = 1, - .clocksource_rating = 200, -}; - -static struct resource tmu01_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xfff60014, 0xc, "TMU00"), - [1] = { - .start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device tmu01_device = { - .name = "sh_tmu", - .id = 1, - .dev = { - .platform_data = &tmu01_platform_data, + .platform_data = &tmu0_platform_data, }, - .resource = tmu01_resources, - .num_resources = ARRAY_SIZE(tmu01_resources), + .resource = tmu0_resources, + .num_resources = ARRAY_SIZE(tmu0_resources), }; static struct resource i2c0_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xe6820000, 0x426, "IIC0"), + [0] = DEFINE_RES_MEM(0xe6820000, 0x426), [1] = { .start = gic_spi(167), .end = gic_spi(170), @@ -340,7 +155,7 @@ static struct resource i2c0_resources[] = { }; static struct resource i2c1_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xe6822000, 0x426, "IIC1"), + [0] = DEFINE_RES_MEM(0xe6822000, 0x426), [1] = { .start = gic_spi(51), .end = gic_spi(54), @@ -349,7 +164,7 @@ static struct resource i2c1_resources[] = { }; static struct resource i2c2_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xe6824000, 0x426, "IIC2"), + [0] = DEFINE_RES_MEM(0xe6824000, 0x426), [1] = { .start = gic_spi(171), .end = gic_spi(174), @@ -358,7 +173,7 @@ static struct resource i2c2_resources[] = { }; static struct resource i2c3_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xe6826000, 0x426, "IIC3"), + [0] = DEFINE_RES_MEM(0xe6826000, 0x426), [1] = { .start = gic_spi(183), .end = gic_spi(186), @@ -367,7 +182,7 @@ static struct resource i2c3_resources[] = { }; static struct resource i2c4_resources[] = { - [0] = DEFINE_RES_MEM_NAMED(0xe6828000, 0x426, "IIC4"), + [0] = DEFINE_RES_MEM(0xe6828000, 0x426), [1] = { .start = gic_spi(187), .end = gic_spi(190), @@ -737,7 +552,7 @@ static struct platform_device pmu_device = { /* an IPMMU module for ICB */ static struct resource ipmmu_resources[] = { - DEFINE_RES_MEM_NAMED(0xfe951000, 0x100, "IPMMU"), + DEFINE_RES_MEM(0xfe951000, 0x100), }; static const char * const ipmmu_dev_names[] = { @@ -890,12 +705,11 @@ static struct platform_device *sh73a0_devices_dt[] __initdata = { &scif6_device, &scif7_device, &scif8_device, - &cmt10_device, + &cmt1_device, }; static struct platform_device *sh73a0_early_devices[] __initdata = { - &tmu00_device, - &tmu01_device, + &tmu0_device, &ipmmu_device, }; @@ -958,10 +772,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 +781,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 +797,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/sh-gpio.h b/arch/arm/mach-shmobile/sh-gpio.h index e834763ac2a..2c4141413db 100644 --- a/arch/arm/mach-shmobile/sh-gpio.h +++ b/arch/arm/mach-shmobile/sh-gpio.h @@ -26,23 +26,4 @@ static inline void __init gpio_direction_none(void __iomem * addr) __raw_writeb(0x00, addr); } -static inline void __init gpio_request_pullup(void __iomem * addr) -{ - u8 data = __raw_readb(addr); - - data &= 0x0F; - data |= 0xC0; - __raw_writeb(data, addr); -} - -static inline void __init gpio_request_pulldown(void __iomem * addr) -{ - u8 data = __raw_readb(addr); - - data &= 0x0F; - data |= 0xA0; - - __raw_writeb(data, addr); -} - #endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-shmobile/sleep-sh7372.S b/arch/arm/mach-shmobile/sleep-sh7372.S index 53f4840e494..9782862899e 100644 --- a/arch/arm/mach-shmobile/sleep-sh7372.S +++ b/arch/arm/mach-shmobile/sleep-sh7372.S @@ -41,6 +41,7 @@ sh7372_resume_core_standby_sysc: ldr pc, 1f + .align 2 .globl sh7372_cpu_resume sh7372_cpu_resume: 1: .space 4 @@ -96,6 +97,7 @@ sh7372_do_idle_sysc: 1: b 1b + .align 2 kernel_flush: .word v7_flush_dcache_all #endif diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 22a05a869d2..2dfd748da7f 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -24,11 +24,12 @@ #include <linux/io.h> #include <linux/delay.h> #include <mach/common.h> -#include <mach/emev2.h> #include <asm/smp_plat.h> #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,32 +39,21 @@ static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) { - scu_enable(shmobile_scu_base); + void __iomem *smu; - /* Tell ROM loader about our vector (in headsmp-scu.S, headsmp.S) */ - emev2_set_boot_vector(__pa(shmobile_boot_vector)); - shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); - shmobile_boot_arg = (unsigned long)shmobile_scu_base; + /* Tell ROM loader about our vector (in headsmp.S) */ + smu = ioremap(EMEV2_SMU_BASE, PAGE_SIZE); + if (smu) { + iowrite32(__pa(shmobile_boot_vector), smu + SMU_GENERAL_REG0); + iounmap(smu); + } - /* enable cache coherency on booting CPU */ - 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 */ + /* setup EMEV2 specific SCU bits */ 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); + shmobile_smp_scu_prepare_cpus(max_cpus); } 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, }; diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 9bdf810f2a8..e7a3201473d 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -24,6 +24,7 @@ #include <linux/io.h> #include <linux/delay.h> #include <mach/common.h> +#include <mach/pm-rcar.h> #include <mach/r8a7779.h> #include <asm/cacheflush.h> #include <asm/smp_plat.h> @@ -33,25 +34,25 @@ #define AVECR IOMEM(0xfe700040) #define R8A7779_SCU_BASE 0xf0000000 -static struct r8a7779_pm_ch r8a7779_ch_cpu1 = { +static struct rcar_sysc_ch r8a7779_ch_cpu1 = { .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */ .chan_bit = 1, /* ARM1 */ .isr_bit = 1, /* ARM1 */ }; -static struct r8a7779_pm_ch r8a7779_ch_cpu2 = { +static struct rcar_sysc_ch r8a7779_ch_cpu2 = { .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */ .chan_bit = 2, /* ARM2 */ .isr_bit = 2, /* ARM2 */ }; -static struct r8a7779_pm_ch r8a7779_ch_cpu3 = { +static struct rcar_sysc_ch r8a7779_ch_cpu3 = { .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */ .chan_bit = 3, /* ARM3 */ .isr_bit = 3, /* ARM3 */ }; -static struct r8a7779_pm_ch *r8a7779_ch_cpu[4] = { +static struct rcar_sysc_ch *r8a7779_ch_cpu[4] = { [1] = &r8a7779_ch_cpu1, [2] = &r8a7779_ch_cpu2, [3] = &r8a7779_ch_cpu3, @@ -67,7 +68,7 @@ void __init r8a7779_register_twd(void) static int r8a7779_platform_cpu_kill(unsigned int cpu) { - struct r8a7779_pm_ch *ch = NULL; + struct rcar_sysc_ch *ch = NULL; int ret = -EIO; cpu = cpu_logical_map(cpu); @@ -76,38 +77,38 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu) ch = r8a7779_ch_cpu[cpu]; if (ch) - ret = r8a7779_sysc_power_down(ch); + ret = rcar_sysc_power_down(ch); return ret ? ret : 1; } static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) { - struct r8a7779_pm_ch *ch = NULL; - int ret = -EIO; + struct rcar_sysc_ch *ch = NULL; + unsigned int lcpu = cpu_logical_map(cpu); + int ret; - cpu = cpu_logical_map(cpu); - - if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) - ch = r8a7779_ch_cpu[cpu]; + if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu)) + ch = r8a7779_ch_cpu[lcpu]; if (ch) - ret = r8a7779_sysc_power_up(ch); + ret = rcar_sysc_power_up(ch); + else + ret = -EIO; return ret; } static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) { - scu_enable(shmobile_scu_base); - /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ __raw_writel(__pa(shmobile_boot_vector), AVECR); shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); shmobile_boot_arg = (unsigned long)shmobile_scu_base; - /* enable cache coherency on booting CPU */ - scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); + /* setup r8a7779 specific SCU bits */ + shmobile_scu_base = IOMEM(R8A7779_SCU_BASE); + shmobile_smp_scu_prepare_cpus(max_cpus); r8a7779_pm_init(); @@ -117,56 +118,15 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) r8a7779_platform_cpu_kill(3); } -static void __init r8a7779_smp_init_cpus(void) -{ - /* setup r8a7779 specific SCU base */ - shmobile_scu_base = IOMEM(R8A7779_SCU_BASE); - - shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base)); -} - #ifdef CONFIG_HOTPLUG_CPU -static int r8a7779_scu_psr_core_disabled(int cpu) -{ - unsigned long mask = 3 << (cpu * 8); - - if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask) - return 1; - - return 0; -} - static int r8a7779_cpu_kill(unsigned int cpu) { - int k; - - /* this function is running on another CPU than the offline target, - * here we need wait for shutdown code in platform_cpu_die() to - * finish before asking SoC-specific code to power off the CPU core. - */ - for (k = 0; k < 1000; k++) { - if (r8a7779_scu_psr_core_disabled(cpu)) - return r8a7779_platform_cpu_kill(cpu); - - mdelay(1); - } + if (shmobile_smp_scu_cpu_kill(cpu)) + return r8a7779_platform_cpu_kill(cpu); return 0; } -static void r8a7779_cpu_die(unsigned int cpu) -{ - dsb(); - flush_cache_all(); - - /* disable cache coherency */ - scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF); - - /* Endless loop until power off from r8a7779_cpu_kill() */ - while (1) - cpu_do_idle(); -} - static int r8a7779_cpu_disable(unsigned int cpu) { /* only CPU1->3 have power domains, do not allow hotplug of CPU0 */ @@ -175,12 +135,11 @@ static int r8a7779_cpu_disable(unsigned int cpu) #endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations r8a7779_smp_ops __initdata = { - .smp_init_cpus = r8a7779_smp_init_cpus, .smp_prepare_cpus = r8a7779_smp_prepare_cpus, .smp_boot_secondary = r8a7779_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = r8a7779_cpu_kill, - .cpu_die = r8a7779_cpu_die, .cpu_disable = r8a7779_cpu_disable, + .cpu_die = shmobile_smp_scu_cpu_die, + .cpu_kill = r8a7779_cpu_kill, #endif }; diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c new file mode 100644 index 00000000000..591052799e8 --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7790.c @@ -0,0 +1,84 @@ +/* + * SMP support for r8a7790 + * + * Copyright (C) 2012-2013 Renesas Solutions Corp. + * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 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. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <asm/smp_plat.h> +#include <mach/common.h> +#include <mach/pm-rcar.h> +#include <mach/r8a7790.h> + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA7BAR 0x0030 +#define CA15RESCNT 0x0040 +#define CA7RESCNT 0x0044 +#define MERAM 0xe8080000 + +static struct rcar_sysc_ch r8a7790_ca15_scu = { + .chan_offs = 0x180, /* PWRSR5 .. PWRER5 */ + .isr_bit = 12, /* CA15-SCU */ +}; + +static struct rcar_sysc_ch r8a7790_ca7_scu = { + .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ + .isr_bit = 21, /* CA7-SCU */ +}; + +static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* MERAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(MERAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (MERAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar, p + CA7BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA7BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000, + p + CA7RESCNT); + iounmap(p); + + /* turn on power to SCU */ + r8a7790_pm_init(); + rcar_sysc_power_up(&r8a7790_ca15_scu); + rcar_sysc_power_up(&r8a7790_ca7_scu); +} + +struct smp_operations r8a7790_smp_ops __initdata = { + .smp_prepare_cpus = r8a7790_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c new file mode 100644 index 00000000000..ec979529f30 --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7791.c @@ -0,0 +1,75 @@ +/* + * SMP support for r8a7791 + * + * 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. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <asm/smp_plat.h> +#include <mach/common.h> +#include <mach/r8a7791.h> +#include <mach/rcar-gen2.h> + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA15RESCNT 0x0040 +#define RAM 0xe6300000 + +static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* RAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(RAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (RAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + iounmap(p); +} + +static int r8a7791_smp_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + /* Error out when hardware debug mode is enabled */ + if (rcar_gen2_read_mode_pins() & BIT(21)) { + pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu); + return -ENOTSUPP; + } + + return shmobile_smp_apmu_boot_secondary(cpu, idle); +} + +struct smp_operations r8a7791_smp_ops __initdata = { + .smp_prepare_cpus = r8a7791_smp_prepare_cpus, + .smp_boot_secondary = r8a7791_smp_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index d5fc3ed4e31..13ba36a6831 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -20,14 +20,11 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/smp.h> -#include <linux/spinlock.h> #include <linux/io.h> #include <linux/delay.h> #include <mach/common.h> -#include <asm/cacheflush.h> -#include <asm/smp_plat.h> #include <mach/sh73a0.h> -#include <asm/smp_scu.h> +#include <asm/smp_plat.h> #include <asm/smp_twd.h> #define WUPCR IOMEM(0xe6151010) @@ -36,8 +33,6 @@ #define SBAR IOMEM(0xe6180020) #define APARMBAREA IOMEM(0xe6f10020) -#define PSTR_SHUTDOWN_MODE 3 - #define SH73A0_SCU_BASE 0xf0000000 #ifdef CONFIG_HAVE_ARM_TWD @@ -50,82 +45,33 @@ void __init sh73a0_register_twd(void) static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) { - cpu = cpu_logical_map(cpu); + unsigned int lcpu = cpu_logical_map(cpu); - if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) - __raw_writel(1 << cpu, WUPCR); /* wake up */ + if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3) + __raw_writel(1 << lcpu, WUPCR); /* wake up */ else - __raw_writel(1 << cpu, SRESCR); /* reset */ + __raw_writel(1 << lcpu, SRESCR); /* reset */ return 0; } static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) { - scu_enable(shmobile_scu_base); - - /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ + /* Map the reset vector (in headsmp.S) */ __raw_writel(0, APARMBAREA); /* 4k */ __raw_writel(__pa(shmobile_boot_vector), SBAR); - shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); - shmobile_boot_arg = (unsigned long)shmobile_scu_base; - - /* enable cache coherency on booting CPU */ - scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); -} -static void __init sh73a0_smp_init_cpus(void) -{ - /* setup sh73a0 specific SCU base */ + /* setup sh73a0 specific SCU bits */ shmobile_scu_base = IOMEM(SH73A0_SCU_BASE); - - shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base)); -} - -#ifdef CONFIG_HOTPLUG_CPU -static int sh73a0_cpu_kill(unsigned int cpu) -{ - - int k; - u32 pstr; - - /* - * wait until the power status register confirms the shutdown of the - * offline target - */ - for (k = 0; k < 1000; k++) { - pstr = (__raw_readl(PSTR) >> (4 * cpu)) & 3; - if (pstr == PSTR_SHUTDOWN_MODE) - return 1; - - mdelay(1); - } - - return 0; -} - -static void sh73a0_cpu_die(unsigned int cpu) -{ - /* Set power off mode. This takes the CPU out of the MP cluster */ - scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF); - - /* Enter shutdown mode */ - cpu_do_idle(); -} - -static int sh73a0_cpu_disable(unsigned int cpu) -{ - return 0; /* CPU0 and CPU1 supported */ + shmobile_smp_scu_prepare_cpus(max_cpus); } -#endif /* CONFIG_HOTPLUG_CPU */ struct smp_operations sh73a0_smp_ops __initdata = { - .smp_init_cpus = sh73a0_smp_init_cpus, .smp_prepare_cpus = sh73a0_smp_prepare_cpus, .smp_boot_secondary = sh73a0_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = sh73a0_cpu_kill, - .cpu_die = sh73a0_cpu_die, - .cpu_disable = sh73a0_cpu_disable, + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_scu_cpu_die, + .cpu_kill = shmobile_smp_scu_cpu_kill, #endif }; diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index f321dbeb237..68bc0b82226 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -21,6 +21,24 @@ #include <linux/platform_device.h> #include <linux/clocksource.h> #include <linux/delay.h> +#include <linux/of_address.h> + +void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, + unsigned int mult, unsigned int div) +{ + /* calculate a worst-case loops-per-jiffy value + * based on maximum cpu core hz setting and the + * __delay() implementation in arch/arm/lib/delay.S + * + * this will result in a longer delay than expected + * when the cpu core runs on lower frequencies. + */ + + unsigned int value = HZ * div / mult; + + if (!preset_lpj) + preset_lpj = max_cpu_core_hz / value; +} void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, unsigned int mult, unsigned int div) @@ -39,6 +57,33 @@ void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, preset_lpj = max_cpu_core_mhz * value; } +void __init shmobile_init_delay(void) +{ + struct device_node *np, *parent; + u32 max_freq, freq; + + max_freq = 0; + + parent = of_find_node_by_path("/cpus"); + if (parent) { + for_each_child_of_node(parent, np) { + if (!of_property_read_u32(np, "clock-frequency", &freq)) + max_freq = max(max_freq, freq); + } + of_node_put(parent); + } + + if (max_freq) { + if (of_find_compatible_node(NULL, NULL, "arm,cortex-a8")) + shmobile_setup_delay_hz(max_freq, 1, 3); + else if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9")) + shmobile_setup_delay_hz(max_freq, 1, 3); + else if (of_find_compatible_node(NULL, NULL, "arm,cortex-a15")) + if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) + shmobile_setup_delay_hz(max_freq, 2, 4); + } +} + static void __init shmobile_late_time_init(void) { /* @@ -59,7 +104,3 @@ void __init shmobile_earlytimer_init(void) late_time_init = shmobile_late_time_init; } -void __init shmobile_timer_init(void) -{ - clocksource_of_init(); -} |
