summaryrefslogtreecommitdiffstats
path: root/arch/sh/boards
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:49:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:49:45 +0000
commit2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch)
tree848558de17fb3008cdf4d861b01ac7781903ce39 /arch/sh/boards
parentInitial commit. (diff)
downloadlinux-2c3c1048746a4622d8c89a29670120dc8fab93c4.tar.xz
linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.zip
Adding upstream version 6.1.76.upstream/6.1.76
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--arch/sh/boards/Kconfig400
-rw-r--r--arch/sh/boards/Makefile20
-rw-r--r--arch/sh/boards/board-apsh4a3a.c182
-rw-r--r--arch/sh/boards/board-apsh4ad0a.c132
-rw-r--r--arch/sh/boards/board-edosk7705.c79
-rw-r--r--arch/sh/boards/board-edosk7760.c178
-rw-r--r--arch/sh/boards/board-espt.c105
-rw-r--r--arch/sh/boards/board-magicpanelr2.c390
-rw-r--r--arch/sh/boards/board-polaris.c156
-rw-r--r--arch/sh/boards/board-secureedge5410.c75
-rw-r--r--arch/sh/boards/board-sh2007.c146
-rw-r--r--arch/sh/boards/board-sh7757lcr.c604
-rw-r--r--arch/sh/boards/board-sh7785lcr.c384
-rw-r--r--arch/sh/boards/board-shmin.c35
-rw-r--r--arch/sh/boards/board-titan.c21
-rw-r--r--arch/sh/boards/board-urquell.c218
-rw-r--r--arch/sh/boards/mach-ap325rxa/Makefile3
-rw-r--r--arch/sh/boards/mach-ap325rxa/sdram.S66
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c573
-rw-r--r--arch/sh/boards/mach-dreamcast/Makefile7
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c155
-rw-r--r--arch/sh/boards/mach-dreamcast/rtc.c96
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c39
-rw-r--r--arch/sh/boards/mach-ecovec24/Makefile10
-rw-r--r--arch/sh/boards/mach-ecovec24/sdram.S108
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c1519
-rw-r--r--arch/sh/boards/mach-highlander/Kconfig26
-rw-r--r--arch/sh/boards/mach-highlander/Makefile12
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7780mp.c71
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7780rp.c64
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7785rp.c83
-rw-r--r--arch/sh/boards/mach-highlander/pinmux-r7785rp.c17
-rw-r--r--arch/sh/boards/mach-highlander/psw.c119
-rw-r--r--arch/sh/boards/mach-highlander/setup.c416
-rw-r--r--arch/sh/boards/mach-hp6xx/Makefile8
-rw-r--r--arch/sh/boards/mach-hp6xx/hp6xx_apm.c109
-rw-r--r--arch/sh/boards/mach-hp6xx/pm.c156
-rw-r--r--arch/sh/boards/mach-hp6xx/pm_wakeup.S39
-rw-r--r--arch/sh/boards/mach-hp6xx/setup.c172
-rw-r--r--arch/sh/boards/mach-kfr2r09/Makefile5
-rw-r--r--arch/sh/boards/mach-kfr2r09/lcd_wqvga.c275
-rw-r--r--arch/sh/boards/mach-kfr2r09/sdram.S77
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c649
-rw-r--r--arch/sh/boards/mach-landisk/Makefile6
-rw-r--r--arch/sh/boards/mach-landisk/gio.c164
-rw-r--r--arch/sh/boards/mach-landisk/irq.c63
-rw-r--r--arch/sh/boards/mach-landisk/psw.c140
-rw-r--r--arch/sh/boards/mach-landisk/setup.c102
-rw-r--r--arch/sh/boards/mach-lboxre2/Makefile6
-rw-r--r--arch/sh/boards/mach-lboxre2/irq.c27
-rw-r--r--arch/sh/boards/mach-lboxre2/setup.c79
-rw-r--r--arch/sh/boards/mach-microdev/Makefile6
-rw-r--r--arch/sh/boards/mach-microdev/fdc37c93xapm.c157
-rw-r--r--arch/sh/boards/mach-microdev/io.c123
-rw-r--r--arch/sh/boards/mach-microdev/irq.c150
-rw-r--r--arch/sh/boards/mach-microdev/setup.c197
-rw-r--r--arch/sh/boards/mach-migor/Kconfig16
-rw-r--r--arch/sh/boards/mach-migor/Makefile3
-rw-r--r--arch/sh/boards/mach-migor/lcd_qvga.c163
-rw-r--r--arch/sh/boards/mach-migor/sdram.S66
-rw-r--r--arch/sh/boards/mach-migor/setup.c649
-rw-r--r--arch/sh/boards/mach-r2d/Kconfig24
-rw-r--r--arch/sh/boards/mach-r2d/Makefile6
-rw-r--r--arch/sh/boards/mach-r2d/irq.c156
-rw-r--r--arch/sh/boards/mach-r2d/setup.c305
-rw-r--r--arch/sh/boards/mach-rsk/Kconfig29
-rw-r--r--arch/sh/boards/mach-rsk/Makefile5
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7203.c137
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7264.c55
-rw-r--r--arch/sh/boards/mach-rsk/devices-rsk7269.c57
-rw-r--r--arch/sh/boards/mach-rsk/setup.c84
-rw-r--r--arch/sh/boards/mach-sdk7780/Kconfig17
-rw-r--r--arch/sh/boards/mach-sdk7780/Makefile6
-rw-r--r--arch/sh/boards/mach-sdk7780/irq.c43
-rw-r--r--arch/sh/boards/mach-sdk7780/setup.c96
-rw-r--r--arch/sh/boards/mach-sdk7786/Makefile5
-rw-r--r--arch/sh/boards/mach-sdk7786/fpga.c69
-rw-r--r--arch/sh/boards/mach-sdk7786/gpio.c46
-rw-r--r--arch/sh/boards/mach-sdk7786/irq.c45
-rw-r--r--arch/sh/boards/mach-sdk7786/nmi.c80
-rw-r--r--arch/sh/boards/mach-sdk7786/setup.c266
-rw-r--r--arch/sh/boards/mach-sdk7786/sram.c69
-rw-r--r--arch/sh/boards/mach-se/7206/Makefile6
-rw-r--r--arch/sh/boards/mach-se/7206/irq.c151
-rw-r--r--arch/sh/boards/mach-se/7206/setup.c96
-rw-r--r--arch/sh/boards/mach-se/7343/Makefile6
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c123
-rw-r--r--arch/sh/boards/mach-se/7343/setup.c182
-rw-r--r--arch/sh/boards/mach-se/770x/Makefile6
-rw-r--r--arch/sh/boards/mach-se/770x/irq.c109
-rw-r--r--arch/sh/boards/mach-se/770x/setup.c205
-rw-r--r--arch/sh/boards/mach-se/7721/Makefile2
-rw-r--r--arch/sh/boards/mach-se/7721/irq.c42
-rw-r--r--arch/sh/boards/mach-se/7721/setup.c92
-rw-r--r--arch/sh/boards/mach-se/7722/Makefile11
-rw-r--r--arch/sh/boards/mach-se/7722/irq.c116
-rw-r--r--arch/sh/boards/mach-se/7722/setup.c190
-rw-r--r--arch/sh/boards/mach-se/7724/Makefile11
-rw-r--r--arch/sh/boards/mach-se/7724/irq.c143
-rw-r--r--arch/sh/boards/mach-se/7724/sdram.S128
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c984
-rw-r--r--arch/sh/boards/mach-se/7751/Makefile6
-rw-r--r--arch/sh/boards/mach-se/7751/irq.c51
-rw-r--r--arch/sh/boards/mach-se/7751/setup.c60
-rw-r--r--arch/sh/boards/mach-se/7780/Makefile11
-rw-r--r--arch/sh/boards/mach-se/7780/irq.c65
-rw-r--r--arch/sh/boards/mach-se/7780/setup.c111
-rw-r--r--arch/sh/boards/mach-se/Makefile11
-rw-r--r--arch/sh/boards/mach-se/board-se7619.c27
-rw-r--r--arch/sh/boards/mach-sh03/Makefile7
-rw-r--r--arch/sh/boards/mach-sh03/rtc.c143
-rw-r--r--arch/sh/boards/mach-sh03/setup.c97
-rw-r--r--arch/sh/boards/mach-sh7763rdp/Makefile2
-rw-r--r--arch/sh/boards/mach-sh7763rdp/irq.c42
-rw-r--r--arch/sh/boards/mach-sh7763rdp/setup.c213
-rw-r--r--arch/sh/boards/mach-x3proto/Makefile4
-rw-r--r--arch/sh/boards/mach-x3proto/gpio.c136
-rw-r--r--arch/sh/boards/mach-x3proto/ilsel.c156
-rw-r--r--arch/sh/boards/mach-x3proto/setup.c270
-rw-r--r--arch/sh/boards/of-generic.c172
120 files changed, 15903 insertions, 0 deletions
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
new file mode 100644
index 000000000..83bcb6d2d
--- /dev/null
+++ b/arch/sh/boards/Kconfig
@@ -0,0 +1,400 @@
+# SPDX-License-Identifier: GPL-2.0
+menu "Board support"
+
+config SOLUTION_ENGINE
+ bool
+
+config SH_ALPHA_BOARD
+ bool
+
+config SH_CUSTOM_CLK
+ def_bool y
+ depends on !SH_DEVICE_TREE
+ select HAVE_LEGACY_CLK
+
+config SH_DEVICE_TREE
+ bool
+ select OF
+ select OF_EARLY_FLATTREE
+ select TIMER_OF
+ select COMMON_CLK
+ select GENERIC_CALIBRATE_DELAY
+
+config SH_JCORE_SOC
+ bool "J-Core SoC"
+ select SH_DEVICE_TREE
+ select CLKSRC_JCORE_PIT
+ select JCORE_AIC
+ depends on CPU_J2
+ help
+ Select this option to include drivers core components of the
+ J-Core SoC, including interrupt controllers and timers.
+
+config SH_SOLUTION_ENGINE
+ bool "SolutionEngine"
+ select SOLUTION_ENGINE
+ select CPU_HAS_IPR_IRQ
+ depends on CPU_SUBTYPE_SH7705 || CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7710 || \
+ CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7750S || \
+ CPU_SUBTYPE_SH7750R
+ help
+ Select SolutionEngine if configuring for a Hitachi SH7705, SH7709,
+ SH7710, SH7712, SH7750, SH7750S or SH7750R evaluation board.
+
+config SH_7206_SOLUTION_ENGINE
+ bool "SolutionEngine7206"
+ select SOLUTION_ENGINE
+ depends on CPU_SUBTYPE_SH7206
+ help
+ Select 7206 SolutionEngine if configuring for a Hitachi SH7206
+ evaluation board.
+
+config SH_7619_SOLUTION_ENGINE
+ bool "SolutionEngine7619"
+ select SOLUTION_ENGINE
+ depends on CPU_SUBTYPE_SH7619
+ help
+ Select 7619 SolutionEngine if configuring for a Hitachi SH7619
+ evaluation board.
+
+config SH_7721_SOLUTION_ENGINE
+ bool "SolutionEngine7721"
+ select SOLUTION_ENGINE
+ depends on CPU_SUBTYPE_SH7721
+ help
+ Select 7721 SolutionEngine if configuring for a Hitachi SH7721
+ evaluation board.
+
+config SH_7722_SOLUTION_ENGINE
+ bool "SolutionEngine7722"
+ select SOLUTION_ENGINE
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ depends on CPU_SUBTYPE_SH7722
+ help
+ Select 7722 SolutionEngine if configuring for a Hitachi SH772
+ evaluation board.
+
+config SH_7724_SOLUTION_ENGINE
+ bool "SolutionEngine7724"
+ select SOLUTION_ENGINE
+ depends on CPU_SUBTYPE_SH7724
+ select GPIOLIB
+ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Select 7724 SolutionEngine if configuring for a Hitachi SH7724
+ evaluation board.
+
+config SH_7751_SOLUTION_ENGINE
+ bool "SolutionEngine7751"
+ select SOLUTION_ENGINE
+ select CPU_HAS_IPR_IRQ
+ depends on CPU_SUBTYPE_SH7751
+ help
+ Select 7751 SolutionEngine if configuring for a Hitachi SH7751
+ evaluation board.
+
+config SH_7780_SOLUTION_ENGINE
+ bool "SolutionEngine7780"
+ select SOLUTION_ENGINE
+ select HAVE_PCI
+ depends on CPU_SUBTYPE_SH7780
+ help
+ Select 7780 SolutionEngine if configuring for a Renesas SH7780
+ evaluation board.
+
+config SH_7343_SOLUTION_ENGINE
+ bool "SolutionEngine7343"
+ select SOLUTION_ENGINE
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ depends on CPU_SUBTYPE_SH7343
+ help
+ Select 7343 SolutionEngine if configuring for a Hitachi
+ SH7343 (SH-Mobile 3AS) evaluation board.
+
+config SH_HP6XX
+ bool "HP6XX"
+ select SYS_SUPPORTS_APM_EMULATION
+ select HD6446X_SERIES
+ depends on CPU_SUBTYPE_SH7709
+ help
+ Select HP6XX if configuring for a HP jornada HP6xx.
+ More information (hardware only) at
+ <http://www.hp.com/jornada/>.
+
+config SH_DREAMCAST
+ bool "Dreamcast"
+ select HAVE_PCI
+ depends on CPU_SUBTYPE_SH7091
+ help
+ Select Dreamcast if configuring for a SEGA Dreamcast.
+ More information at <http://www.linux-sh.org>
+
+config SH_SH03
+ bool "Interface CTP/PCI-SH03"
+ depends on CPU_SUBTYPE_SH7751
+ select CPU_HAS_IPR_IRQ
+ select HAVE_PCI
+ help
+ CTP/PCI-SH03 is a CPU module computer that is produced
+ by Interface Corporation.
+ More information at <http://www.interface.co.jp>
+
+config SH_SECUREEDGE5410
+ bool "SecureEdge5410"
+ depends on CPU_SUBTYPE_SH7751R
+ select CPU_HAS_IPR_IRQ
+ select HAVE_PCI
+ help
+ Select SecureEdge5410 if configuring for a SnapGear SH board.
+ This includes both the OEM SecureEdge products as well as the
+ SME product line.
+
+config SH_RTS7751R2D
+ bool "RTS7751R2D"
+ depends on CPU_SUBTYPE_SH7751R
+ select HAVE_PCI
+ select IO_TRAPPED if MMU
+ help
+ Select RTS7751R2D if configuring for a Renesas Technology
+ Sales SH-Graphics board.
+
+config SH_RSK
+ bool "Renesas Starter Kit"
+ depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 || \
+ CPU_SUBTYPE_SH7264 || CPU_SUBTYPE_SH7269
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Select this option if configuring for any of the RSK+ MCU
+ evaluation platforms.
+
+config SH_SDK7780
+ bool "SDK7780R3"
+ depends on CPU_SUBTYPE_SH7780
+ select HAVE_PCI
+ help
+ Select SDK7780 if configuring for a Renesas SH7780 SDK7780R3
+ evaluation board.
+
+config SH_SDK7786
+ bool "SDK7786"
+ depends on CPU_SUBTYPE_SH7786
+ select HAVE_PCI
+ select NO_IOPORT_MAP if !PCI
+ select HAVE_SRAM_POOL
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Select SDK7786 if configuring for a Renesas Technology Europe
+ SH7786-65nm board.
+
+config SH_HIGHLANDER
+ bool "Highlander"
+ depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+ select HAVE_PCI
+ select IO_TRAPPED if MMU
+
+config SH_SH7757LCR
+ bool "SH7757LCR"
+ depends on CPU_SUBTYPE_SH7757
+ select GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+
+config SH_SH7785LCR
+ bool "SH7785LCR"
+ depends on CPU_SUBTYPE_SH7785
+ select HAVE_PCI
+
+config SH_SH7785LCR_29BIT_PHYSMAPS
+ bool "SH7785LCR 29bit physmaps"
+ depends on SH_SH7785LCR && 29BIT
+ default y
+ help
+ This board has 2 physical memory maps. It can be changed with
+ DIP switch(S2-5). If you set the DIP switch for S2-5 = ON,
+ you can access all on-board device in 29bit address mode.
+
+config SH_SH7785LCR_PT
+ bool "SH7785LCR prototype board on 32-bit MMU mode"
+ depends on SH_SH7785LCR && 32BIT
+ default n
+ help
+ If you use prototype board, this option is enabled.
+
+config SH_URQUELL
+ bool "Urquell"
+ depends on CPU_SUBTYPE_SH7786
+ select GPIOLIB
+ select HAVE_PCI
+ select NO_IOPORT_MAP if !PCI
+
+config SH_MIGOR
+ bool "Migo-R"
+ depends on CPU_SUBTYPE_SH7722
+ select GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Select Migo-R if configuring for the SH7722 Migo-R platform
+ by Renesas System Solutions Asia Pte. Ltd.
+
+config SH_AP325RXA
+ bool "AP-325RXA"
+ depends on CPU_SUBTYPE_SH7723
+ select GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Renesas "AP-325RXA" support.
+ Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
+
+config SH_KFR2R09
+ bool "KFR2R09"
+ depends on CPU_SUBTYPE_SH7724
+ select GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ "Kit For R2R for 2009" support.
+
+config SH_ECOVEC
+ bool "EcoVec"
+ depends on CPU_SUBTYPE_SH7724
+ select GPIOLIB
+ select SND_SOC_DA7210 if SND_SIMPLE_CARD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Renesas "R0P7724LC0011/21RL (EcoVec)" support.
+
+config SH_SH7763RDP
+ bool "SH7763RDP"
+ depends on CPU_SUBTYPE_SH7763
+ help
+ Select SH7763RDP if configuring for a Renesas SH7763
+ evaluation board.
+
+config SH_ESPT
+ bool "ESPT"
+ depends on CPU_SUBTYPE_SH7763
+ help
+ Select ESPT if configuring for a Renesas SH7763
+ with gigabit ether evaluation board.
+
+config SH_EDOSK7705
+ bool "EDOSK7705"
+ depends on CPU_SUBTYPE_SH7705
+
+config SH_EDOSK7760
+ bool "EDOSK7760"
+ depends on CPU_SUBTYPE_SH7760
+ help
+ Select if configuring for a Renesas EDOSK7760
+ evaluation board.
+
+config SH_SH4202_MICRODEV
+ bool "SH4-202 MicroDev"
+ depends on CPU_SUBTYPE_SH4_202
+ help
+ Select SH4-202 MicroDev if configuring for a SuperH MicroDev board
+ with an SH4-202 CPU.
+
+config SH_LANDISK
+ bool "LANDISK"
+ depends on CPU_SUBTYPE_SH7751R
+ select HAVE_PCI
+ help
+ I-O DATA DEVICE, INC. "LANDISK Series" support.
+
+config SH_TITAN
+ bool "TITAN"
+ depends on CPU_SUBTYPE_SH7751R
+ select CPU_HAS_IPR_IRQ
+ select HAVE_PCI
+ help
+ Select Titan if you are configuring for a Nimble Microsystems
+ NetEngine NP51R.
+
+config SH_SHMIN
+ bool "SHMIN"
+ depends on CPU_SUBTYPE_SH7706
+ select CPU_HAS_IPR_IRQ
+ help
+ Select SHMIN if configuring for the SHMIN board.
+
+config SH_LBOX_RE2
+ bool "L-BOX RE2"
+ depends on CPU_SUBTYPE_SH7751R
+ select HAVE_PCI
+ help
+ Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2.
+
+config SH_X3PROTO
+ bool "SH-X3 Prototype board"
+ depends on CPU_SUBTYPE_SHX3
+ select NO_IOPORT_MAP if !PCI
+ select IRQ_DOMAIN
+
+config SH_MAGIC_PANEL_R2
+ bool "Magic Panel R2"
+ depends on CPU_SUBTYPE_SH7720
+ select GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ help
+ Select Magic Panel R2 if configuring for Magic Panel R2.
+
+config SH_POLARIS
+ bool "SMSC Polaris"
+ select CPU_HAS_IPR_IRQ
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ depends on CPU_SUBTYPE_SH7709
+ help
+ Select if configuring for an SMSC Polaris development board
+
+config SH_SH2007
+ bool "SH-2007 board"
+ select NO_IOPORT_MAP
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ depends on CPU_SUBTYPE_SH7780
+ help
+ SH-2007 is a single-board computer based around SH7780 chip
+ intended for embedded applications.
+ It has an Ethernet interface (SMC9118), direct connected
+ Compact Flash socket, two serial ports and PC-104 bus.
+ More information at <http://sh2000.sh-linux.org>.
+
+config SH_APSH4A3A
+ bool "AP-SH4A-3A"
+ select SH_ALPHA_BOARD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ depends on CPU_SUBTYPE_SH7785
+ help
+ Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A.
+
+config SH_APSH4AD0A
+ bool "AP-SH4AD-0A"
+ select SH_ALPHA_BOARD
+ select HAVE_PCI
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ depends on CPU_SUBTYPE_SH7786
+ help
+ Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A.
+
+source "arch/sh/boards/mach-r2d/Kconfig"
+source "arch/sh/boards/mach-highlander/Kconfig"
+source "arch/sh/boards/mach-sdk7780/Kconfig"
+source "arch/sh/boards/mach-migor/Kconfig"
+source "arch/sh/boards/mach-rsk/Kconfig"
+
+if SH_MAGIC_PANEL_R2
+
+menu "Magic Panel R2 options"
+
+config SH_MAGIC_PANEL_R2_VERSION
+ int "Magic Panel R2 Version"
+ default "3"
+ help
+ Set the version of the Magic Panel R2
+
+endmenu
+
+endif
+
+endmenu
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
new file mode 100644
index 000000000..4002a22a7
--- /dev/null
+++ b/arch/sh/boards/Makefile
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Specific board support, not covered by a mach group.
+#
+obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
+obj-$(CONFIG_SH_SECUREEDGE5410) += board-secureedge5410.o
+obj-$(CONFIG_SH_SH2007) += board-sh2007.o
+obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
+obj-$(CONFIG_SH_URQUELL) += board-urquell.o
+obj-$(CONFIG_SH_SHMIN) += board-shmin.o
+obj-$(CONFIG_SH_EDOSK7705) += board-edosk7705.o
+obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
+obj-$(CONFIG_SH_ESPT) += board-espt.o
+obj-$(CONFIG_SH_POLARIS) += board-polaris.o
+obj-$(CONFIG_SH_TITAN) += board-titan.o
+obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o
+obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o
+obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o
+
+obj-$(CONFIG_SH_DEVICE_TREE) += of-generic.o
diff --git a/arch/sh/boards/board-apsh4a3a.c b/arch/sh/boards/board-apsh4a3a.c
new file mode 100644
index 000000000..abf19a947
--- /dev/null
+++ b/arch/sh/boards/board-apsh4a3a.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ALPHAPROJECT AP-SH4A-3A Support.
+ *
+ * Copyright (C) 2010 ALPHAPROJECT Co.,Ltd.
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ * Copyright (C) 2009 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/physmap.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <asm/machvec.h>
+#include <linux/sizes.h>
+#include <asm/clock.h>
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 4,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x01000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* 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 smsc911x_resources[] = {
+ [0] = {
+ .name = "smsc911x-memory",
+ .start = 0xA4000000,
+ .end = 0xA4000000 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smsc911x-irq",
+ .start = evt2irq(0x200),
+ .end = evt2irq(0x200),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_16BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct platform_device *apsh4a3a_devices[] __initdata = {
+ &nor_flash_device,
+ &smsc911x_device,
+};
+
+static int __init apsh4a3a_devices_setup(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ return platform_add_devices(apsh4a3a_devices,
+ ARRAY_SIZE(apsh4a3a_devices));
+}
+device_initcall(apsh4a3a_devices_setup);
+
+static int apsh4a3a_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = clk_get(NULL, "extal");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333000);
+ clk_put(clk);
+
+ return ret;
+}
+
+/* Initialize the board */
+static void __init apsh4a3a_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "Alpha Project AP-SH4A-3A support:\n");
+}
+
+static void __init apsh4a3a_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ7654);
+}
+
+/* Return the board specific boot mode pin configuration */
+static int apsh4a3a_mode_pins(void)
+{
+ int value = 0;
+
+ /* These are the factory default settings of SW1 and SW2.
+ * If you change these dip switches then you will need to
+ * adjust the values below as well.
+ */
+ value &= ~MODE_PIN0; /* Clock Mode 16 */
+ value &= ~MODE_PIN1;
+ value &= ~MODE_PIN2;
+ value &= ~MODE_PIN3;
+ value |= MODE_PIN4;
+ value &= ~MODE_PIN5; /* 16-bit Area0 bus width */
+ value |= MODE_PIN6; /* Area 0 SRAM interface */
+ value |= MODE_PIN7;
+ value |= MODE_PIN8; /* Little Endian */
+ value |= MODE_PIN9; /* Master Mode */
+ value |= MODE_PIN10; /* Crystal resonator */
+ value |= MODE_PIN11; /* Display Unit */
+ value |= MODE_PIN12;
+ value &= ~MODE_PIN13; /* 29-bit address mode */
+ value |= MODE_PIN14; /* No PLL step-up */
+
+ return value;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_apsh4a3a __initmv = {
+ .mv_name = "AP-SH4A-3A",
+ .mv_setup = apsh4a3a_setup,
+ .mv_clk_init = apsh4a3a_clk_init,
+ .mv_init_irq = apsh4a3a_init_irq,
+ .mv_mode_pins = apsh4a3a_mode_pins,
+};
diff --git a/arch/sh/boards/board-apsh4ad0a.c b/arch/sh/boards/board-apsh4ad0a.c
new file mode 100644
index 000000000..fa031a16c
--- /dev/null
+++ b/arch/sh/boards/board-apsh4ad0a.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ALPHAPROJECT AP-SH4AD-0A Support.
+ *
+ * Copyright (C) 2010 ALPHAPROJECT Co.,Ltd.
+ * Copyright (C) 2010 Matt Fleming
+ * Copyright (C) 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <asm/machvec.h>
+#include <linux/sizes.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 smsc911x_resources[] = {
+ [0] = {
+ .name = "smsc911x-memory",
+ .start = 0xA4000000,
+ .end = 0xA4000000 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smsc911x-irq",
+ .start = evt2irq(0x200),
+ .end = evt2irq(0x200),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_16BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct platform_device *apsh4ad0a_devices[] __initdata = {
+ &smsc911x_device,
+};
+
+static int __init apsh4ad0a_devices_setup(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ return platform_add_devices(apsh4ad0a_devices,
+ ARRAY_SIZE(apsh4ad0a_devices));
+}
+device_initcall(apsh4ad0a_devices_setup);
+
+static int apsh4ad0a_mode_pins(void)
+{
+ int value = 0;
+
+ /* These are the factory default settings of SW1 and SW2.
+ * If you change these dip switches then you will need to
+ * adjust the values below as well.
+ */
+ value |= MODE_PIN0; /* Clock Mode 3 */
+ value |= MODE_PIN1;
+ value &= ~MODE_PIN2;
+ value &= ~MODE_PIN3;
+ value &= ~MODE_PIN4; /* 16-bit Area0 bus width */
+ value |= MODE_PIN5;
+ value |= MODE_PIN6;
+ value |= MODE_PIN7; /* Normal mode */
+ value |= MODE_PIN8; /* Little Endian */
+ value |= MODE_PIN9; /* Crystal resonator */
+ value &= ~MODE_PIN10; /* 29-bit address mode */
+ value &= ~MODE_PIN11; /* PCI-E Root port */
+ value &= ~MODE_PIN12; /* 4 lane + 1 lane */
+ value |= MODE_PIN13; /* AUD Enable */
+ value &= ~MODE_PIN14; /* Normal Operation */
+
+ return value;
+}
+
+static int apsh4ad0a_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = clk_get(NULL, "extal");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333000);
+ clk_put(clk);
+
+ return ret;
+}
+
+/* Initialize the board */
+static void __init apsh4ad0a_setup(char **cmdline_p)
+{
+ pr_info("Alpha Project AP-SH4AD-0A support:\n");
+}
+
+static void __init apsh4ad0a_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ3210);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_apsh4ad0a __initmv = {
+ .mv_name = "AP-SH4AD-0A",
+ .mv_setup = apsh4ad0a_setup,
+ .mv_mode_pins = apsh4ad0a_mode_pins,
+ .mv_clk_init = apsh4ad0a_clk_init,
+ .mv_init_irq = apsh4ad0a_init_irq,
+};
diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c
new file mode 100644
index 000000000..0de7d603d
--- /dev/null
+++ b/arch/sh/boards/board-edosk7705.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/renesas/edosk7705/setup.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for edosk7705 development
+ * board by S. Dunn, 2003.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smc91x.h>
+#include <linux/sh_intc.h>
+#include <asm/machvec.h>
+#include <linux/sizes.h>
+
+#define SMC_IOBASE 0xA2000000
+#define SMC_IO_OFFSET 0x300
+#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET)
+
+#define ETHERNET_IRQ evt2irq(0x320)
+
+static void __init sh_edosk7705_init_irq(void)
+{
+ make_imask_irq(ETHERNET_IRQ);
+}
+
+/* eth initialization functions */
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static struct resource smc91x_res[] = {
+ [0] = {
+ .start = SMC_IOADDR,
+ .end = SMC_IOADDR + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ETHERNET_IRQ,
+ .end = ETHERNET_IRQ,
+ .flags = IORESOURCE_IRQ ,
+ }
+};
+
+static struct platform_device smc91x_dev = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_res),
+ .resource = smc91x_res,
+
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+/* platform init code */
+static struct platform_device *edosk7705_devices[] __initdata = {
+ &smc91x_dev,
+};
+
+static int __init init_edosk7705_devices(void)
+{
+ return platform_add_devices(edosk7705_devices,
+ ARRAY_SIZE(edosk7705_devices));
+}
+device_initcall(init_edosk7705_devices);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_edosk7705 __initmv = {
+ .mv_name = "EDOSK7705",
+ .mv_init_irq = sh_edosk7705_init_irq,
+};
diff --git a/arch/sh/boards/board-edosk7760.c b/arch/sh/boards/board-edosk7760.c
new file mode 100644
index 000000000..7569d85c5
--- /dev/null
+++ b/arch/sh/boards/board-edosk7760.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Renesas Europe EDOSK7760 Board Support
+ *
+ * Copyright (C) 2008 SPES Societa' Progettazione Elettronica e Software Ltd.
+ * Author: Luca Santini <luca.santini@spesonline.com>
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <linux/interrupt.h>
+#include <linux/sh_intc.h>
+#include <linux/i2c.h>
+#include <linux/mtd/physmap.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/delay.h>
+#include <asm/i2c-sh7760.h>
+#include <linux/sizes.h>
+
+/* Bus state controller registers for CS4 area */
+#define BSC_CS4BCR 0xA4FD0010
+#define BSC_CS4WCR 0xA4FD0030
+
+#define SMC_IOBASE 0xA2000000
+#define SMC_IO_OFFSET 0x300
+#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET)
+
+/* NOR flash */
+static struct mtd_partition edosk7760_nor_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ }, {
+ .name = "fs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (26 << 20),
+ }, {
+ .name = "other",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data edosk7760_nor_flash_data = {
+ .width = 4,
+ .parts = edosk7760_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(edosk7760_nor_flash_partitions),
+};
+
+static struct resource edosk7760_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x00000000 + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device edosk7760_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = edosk7760_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(edosk7760_nor_flash_resources),
+ .dev = {
+ .platform_data = &edosk7760_nor_flash_data,
+ },
+};
+
+/* i2c initialization functions */
+static struct sh7760_i2c_platdata i2c_pd = {
+ .speed_khz = 400,
+};
+
+static struct resource sh7760_i2c1_res[] = {
+ {
+ .start = SH7760_I2C1_MMIO,
+ .end = SH7760_I2C1_MMIOEND,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = evt2irq(0x9e0),
+ .end = evt2irq(0x9e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh7760_i2c1_dev = {
+ .dev = {
+ .platform_data = &i2c_pd,
+ },
+
+ .name = SH7760_I2C_DEVNAME,
+ .id = 1,
+ .resource = sh7760_i2c1_res,
+ .num_resources = ARRAY_SIZE(sh7760_i2c1_res),
+};
+
+static struct resource sh7760_i2c0_res[] = {
+ {
+ .start = SH7760_I2C0_MMIO,
+ .end = SH7760_I2C0_MMIOEND,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x9c0),
+ .end = evt2irq(0x9c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh7760_i2c0_dev = {
+ .dev = {
+ .platform_data = &i2c_pd,
+ },
+ .name = SH7760_I2C_DEVNAME,
+ .id = 0,
+ .resource = sh7760_i2c0_res,
+ .num_resources = ARRAY_SIZE(sh7760_i2c0_res),
+};
+
+/* eth initialization functions */
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static struct resource smc91x_res[] = {
+ [0] = {
+ .start = SMC_IOADDR,
+ .end = SMC_IOADDR + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x2a0),
+ .end = evt2irq(0x2a0),
+ .flags = IORESOURCE_IRQ ,
+ }
+};
+
+static struct platform_device smc91x_dev = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_res),
+ .resource = smc91x_res,
+
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+/* platform init code */
+static struct platform_device *edosk7760_devices[] __initdata = {
+ &smc91x_dev,
+ &edosk7760_nor_flash_device,
+ &sh7760_i2c0_dev,
+ &sh7760_i2c1_dev,
+};
+
+static int __init init_edosk7760_devices(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+
+ return platform_add_devices(edosk7760_devices,
+ ARRAY_SIZE(edosk7760_devices));
+}
+device_initcall(init_edosk7760_devices);
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_edosk7760 __initmv = {
+ .mv_name = "EDOSK7760",
+};
diff --git a/arch/sh/boards/board-espt.c b/arch/sh/boards/board-espt.c
new file mode 100644
index 000000000..6e784b5cf
--- /dev/null
+++ b/arch/sh/boards/board-espt.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Data Technology Inc. ESPT-GIGA board support
+ *
+ * Copyright (C) 2008, 2009 Renesas Solutions Corp.
+ * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <linux/sh_eth.h>
+#include <linux/sh_intc.h>
+#include <asm/machvec.h>
+#include <linux/sizes.h>
+
+/* NOR Flash */
+static struct mtd_partition espt_nor_flash_partitions[] = {
+ {
+ .name = "U-Boot",
+ .offset = 0,
+ .size = (2 * SZ_128K),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "Linux-Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (20 * SZ_128K),
+ }, {
+ .name = "Root Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data espt_nor_flash_data = {
+ .width = 2,
+ .parts = espt_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(espt_nor_flash_partitions),
+};
+
+static struct resource espt_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0,
+ .end = SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device espt_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = espt_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(espt_nor_flash_resources),
+ .dev = {
+ .platform_data = &espt_nor_flash_data,
+ },
+};
+
+/* SH-Ether */
+static struct resource sh_eth_resources[] = {
+ {
+ .start = 0xFEE00800, /* use eth1 */
+ .end = 0xFEE00F7C - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0xFEE01800, /* TSU */
+ .end = 0xFEE01FFF,
+ .flags = IORESOURCE_MEM,
+ }, {
+
+ .start = evt2irq(0x920), /* irq number */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7763_eth_pdata = {
+ .phy = 0,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device espt_eth_device = {
+ .name = "sh7763-gether",
+ .resource = sh_eth_resources,
+ .num_resources = ARRAY_SIZE(sh_eth_resources),
+ .dev = {
+ .platform_data = &sh7763_eth_pdata,
+ },
+};
+
+static struct platform_device *espt_devices[] __initdata = {
+ &espt_nor_flash_device,
+ &espt_eth_device,
+};
+
+static int __init espt_devices_setup(void)
+{
+ return platform_add_devices(espt_devices,
+ ARRAY_SIZE(espt_devices));
+}
+device_initcall(espt_devices_setup);
+
+static struct sh_machine_vector mv_espt __initmv = {
+ .mv_name = "ESPT-GIGA",
+};
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
new file mode 100644
index 000000000..56bd386ff
--- /dev/null
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/magicpanel/setup.c
+ *
+ * Copyright (C) 2007 Markus Brunner, Mark Jonas
+ *
+ * Magic Panel Release 2 board setup
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/map.h>
+#include <linux/sh_intc.h>
+#include <mach/magicpanelr2.h>
+#include <asm/heartbeat.h>
+#include <cpu/sh7720.h>
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
+#define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL)
+
+/* Wait until reset finished. Timeout is 100ms. */
+static int __init ethernet_reset_finished(void)
+{
+ int i;
+
+ if (LAN9115_READY)
+ return 1;
+
+ for (i = 0; i < 10; ++i) {
+ mdelay(10);
+ if (LAN9115_READY)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void __init reset_ethernet(void)
+{
+ /* PMDR: LAN_RESET=on */
+ CLRBITS_OUTB(0x10, PORT_PMDR);
+
+ udelay(200);
+
+ /* PMDR: LAN_RESET=off */
+ SETBITS_OUTB(0x10, PORT_PMDR);
+}
+
+static void __init setup_chip_select(void)
+{
+ /* CS2: LAN (0x08000000 - 0x0bffffff) */
+ /* no idle cycles, normal space, 8 bit data bus */
+ __raw_writel(0x36db0400, CS2BCR);
+ /* (SW:1.5 WR:3 HW:1.5), ext. wait */
+ __raw_writel(0x000003c0, CS2WCR);
+
+ /* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */
+ /* no idle cycles, normal space, 8 bit data bus */
+ __raw_writel(0x00000200, CS4BCR);
+ /* (SW:1.5 WR:3 HW:1.5), ext. wait */
+ __raw_writel(0x00100981, CS4WCR);
+
+ /* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */
+ /* no idle cycles, normal space, 8 bit data bus */
+ __raw_writel(0x00000200, CS5ABCR);
+ /* (SW:1.5 WR:3 HW:1.5), ext. wait */
+ __raw_writel(0x00100981, CS5AWCR);
+
+ /* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */
+ /* no idle cycles, normal space, 8 bit data bus */
+ __raw_writel(0x00000200, CS5BBCR);
+ /* (SW:1.5 WR:3 HW:1.5), ext. wait */
+ __raw_writel(0x00100981, CS5BWCR);
+
+ /* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */
+ /* no idle cycles, normal space, 8 bit data bus */
+ __raw_writel(0x00000200, CS6ABCR);
+ /* (SW:1.5 WR:3 HW:1.5), no ext. wait */
+ __raw_writel(0x001009C1, CS6AWCR);
+}
+
+static void __init setup_port_multiplexing(void)
+{
+ /* A7 GPO(LED8); A6 GPO(LED7); A5 GPO(LED6); A4 GPO(LED5);
+ * A3 GPO(LED4); A2 GPO(LED3); A1 GPO(LED2); A0 GPO(LED1);
+ */
+ __raw_writew(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */
+
+ /* B7 GPO(RST4); B6 GPO(RST3); B5 GPO(RST2); B4 GPO(RST1);
+ * B3 GPO(PB3); B2 GPO(PB2); B1 GPO(PB1); B0 GPO(PB0);
+ */
+ __raw_writew(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */
+
+ /* C7 GPO(PC7); C6 GPO(PC6); C5 GPO(PC5); C4 GPO(PC4);
+ * C3 LCD_DATA3; C2 LCD_DATA2; C1 LCD_DATA1; C0 LCD_DATA0;
+ */
+ __raw_writew(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */
+
+ /* D7 GPO(PD7); D6 GPO(PD6); D5 GPO(PD5); D4 GPO(PD4);
+ * D3 GPO(PD3); D2 GPO(PD2); D1 GPO(PD1); D0 GPO(PD0);
+ */
+ __raw_writew(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */
+
+ /* E7 (x); E6 GPI(nu); E5 GPI(nu); E4 LCD_M_DISP;
+ * E3 LCD_CL1; E2 LCD_CL2; E1 LCD_DON; E0 LCD_FLM;
+ */
+ __raw_writew(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */
+
+ /* F7 (x); F6 DA1(VLCD); F5 DA0(nc); F4 AN3;
+ * F3 AN2(MID_AD); F2 AN1(EARTH_AD); F1 AN0(TEMP); F0 GPI+(nc);
+ */
+ __raw_writew(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */
+
+ /* G7 (x); G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2);
+ * G3 GPI(KEY1); G2 GPO(LED11); G1 GPO(LED10); G0 GPO(LED9);
+ */
+ __raw_writew(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */
+
+ /* H7 (x); H6 /RAS(BRAS); H5 /CAS(BCAS); H4 CKE(BCKE);
+ * H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR; H0 USB1_PWR;
+ */
+ __raw_writew(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */
+
+ /* J7 (x); J6 AUDCK; J5 ASEBRKAK; J4 AUDATA3;
+ * J3 AUDATA2; J2 AUDATA1; J1 AUDATA0; J0 AUDSYNC;
+ */
+ __raw_writew(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */
+
+ /* K7 (x); K6 (x); K5 (x); K4 (x);
+ * K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY)
+ */
+ __raw_writew(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */
+
+ /* L7 TRST; L6 TMS; L5 TDO; L4 TDI;
+ * L3 TCK; L2 (x); L1 (x); L0 (x);
+ */
+ __raw_writew(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */
+
+ /* M7 GPO(CURRENT_SINK); M6 GPO(PWR_SWITCH); M5 GPO(LAN_SPEED);
+ * M4 GPO(LAN_RESET); M3 GPO(BUZZER); M2 GPO(LCD_BL);
+ * M1 CS5B(CAN3_CS); M0 GPI+(nc);
+ */
+ __raw_writew(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */
+
+ /* CURRENT_SINK=off, PWR_SWITCH=off, LAN_SPEED=100MBit,
+ * LAN_RESET=off, BUZZER=off, LCD_BL=off
+ */
+#if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2
+ __raw_writeb(0x30, PORT_PMDR);
+#elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3
+ __raw_writeb(0xF0, PORT_PMDR);
+#else
+#error Unknown revision of PLATFORM_MP_R2
+#endif
+
+ /* P7 (x); P6 (x); P5 (x);
+ * P4 GPO(nu); P3 IRQ3(LAN_IRQ); P2 IRQ2(CAN3_IRQ);
+ * P1 IRQ1(CAN2_IRQ); P0 IRQ0(CAN1_IRQ)
+ */
+ __raw_writew(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */
+ __raw_writeb(0x10, PORT_PPDR);
+
+ /* R7 A25; R6 A24; R5 A23; R4 A22;
+ * R3 A21; R2 A20; R1 A19; R0 A0;
+ */
+ gpio_request(GPIO_FN_A25, NULL);
+ gpio_request(GPIO_FN_A24, NULL);
+ gpio_request(GPIO_FN_A23, NULL);
+ gpio_request(GPIO_FN_A22, NULL);
+ gpio_request(GPIO_FN_A21, NULL);
+ gpio_request(GPIO_FN_A20, NULL);
+ gpio_request(GPIO_FN_A19, NULL);
+ gpio_request(GPIO_FN_A0, NULL);
+
+ /* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2);
+ * S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK;
+ */
+ __raw_writew(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */
+
+ /* T7 (x); T6 (x); T5 (x); T4 COM1_CTS;
+ * T3 COM1_RTS; T2 COM1_TXD; T1 COM1_RXD; T0 GPO(WDOG)
+ */
+ __raw_writew(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */
+
+ /* U7 (x); U6 (x); U5 (x); U4 GPI+(/AC_FAULT);
+ * U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD; U0 TOUCH_SCK;
+ */
+ __raw_writew(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */
+
+ /* V7 (x); V6 (x); V5 (x); V4 GPO(MID2);
+ * V3 GPO(MID1); V2 CARD_TxD; V1 CARD_RxD; V0 GPI+(/BAT_FAULT);
+ */
+ __raw_writew(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */
+}
+
+static void __init mpr2_setup(char **cmdline_p)
+{
+ /* set Pin Select Register A:
+ * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2,
+ * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND
+ */
+ __raw_writew(0xAABC, PORT_PSELA);
+ /* set Pin Select Register B:
+ * /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC,
+ * LCD_VEPWC, IIC_SDA, IIC_SCL, Reserved
+ */
+ __raw_writew(0x3C00, PORT_PSELB);
+ /* set Pin Select Register C:
+ * SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved
+ */
+ __raw_writew(0x0000, PORT_PSELC);
+ /* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK,
+ * Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved
+ */
+ __raw_writew(0x0000, PORT_PSELD);
+ /* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */
+ __raw_writew(0x0101, PORT_UTRCTL);
+ /* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */
+ __raw_writew(0xA5C0, PORT_UCLKCR_W);
+
+ setup_chip_select();
+
+ setup_port_multiplexing();
+
+ reset_ethernet();
+
+ printk(KERN_INFO "Magic Panel Release 2 A.%i\n",
+ CONFIG_SH_MAGIC_PANEL_R2_VERSION);
+
+ if (ethernet_reset_finished() == 0)
+ printk(KERN_WARNING "Ethernet not ready\n");
+}
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = 0xa8000000,
+ .end = 0xabffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x660),
+ .end = evt2irq(0x660),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct heartbeat_data heartbeat_data = {
+ .flags = HEARTBEAT_INVERTED,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct mtd_partition mpr2_partitions[] = {
+ /* Reserved for bootloader, read-only */
+ {
+ .name = "Bootloader",
+ .offset = 0x00000000UL,
+ .size = MPR2_MTD_BOOTLOADER_SIZE,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ /* Reserved for kernel image */
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MPR2_MTD_KERNEL_SIZE,
+ },
+ /* Rest is used for Flash FS */
+ {
+ .name = "Flash_FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data flash_data = {
+ .parts = mpr2_partitions,
+ .nr_parts = ARRAY_SIZE(mpr2_partitions),
+ .width = 2,
+};
+
+static struct resource flash_resource = {
+ .start = 0x00000000,
+ .end = 0x2000000UL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
+/*
+ * Add all resources to the platform_device
+ */
+
+static struct platform_device *mpr2_devices[] __initdata = {
+ &heartbeat_device,
+ &smsc911x_device,
+ &flash_device,
+};
+
+
+static int __init mpr2_devices_setup(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices));
+}
+device_initcall(mpr2_devices_setup);
+
+/*
+ * Initialize IRQ setting
+ */
+static void __init init_mpr2_IRQ(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-5 */
+
+ irq_set_irq_type(evt2irq(0x600), IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */
+ irq_set_irq_type(evt2irq(0x620), IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */
+ irq_set_irq_type(evt2irq(0x640), IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */
+ irq_set_irq_type(evt2irq(0x660), IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */
+ irq_set_irq_type(evt2irq(0x680), IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */
+ irq_set_irq_type(evt2irq(0x6a0), IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */
+
+ intc_set_priority(evt2irq(0x600), 13); /* IRQ0 CAN1 */
+ intc_set_priority(evt2irq(0x620), 13); /* IRQ0 CAN2 */
+ intc_set_priority(evt2irq(0x640), 13); /* IRQ0 CAN3 */
+ intc_set_priority(evt2irq(0x660), 6); /* IRQ3 SMSC9115 */
+}
+
+/*
+ * The Machine Vector
+ */
+
+static struct sh_machine_vector mv_mpr2 __initmv = {
+ .mv_name = "mpr2",
+ .mv_setup = mpr2_setup,
+ .mv_init_irq = init_mpr2_IRQ,
+};
diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c
new file mode 100644
index 000000000..3de7bac01
--- /dev/null
+++ b/arch/sh/boards/board-polaris.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * June 2006 Steve Glendinning <steve.glendinning@shawell.net>
+ *
+ * Polaris-specific resource declaration
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+#include <cpu/gpio.h>
+#include <mach-se/mach/se.h>
+
+#define BCR2 (0xFFFFFF62)
+#define WCR2 (0xFFFFFF66)
+#define AREA5_WAIT_CTRL (0x1C00)
+#define WAIT_STATES_10 (0x7)
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .name = "smsc911x-memory",
+ .start = PA_EXT5,
+ .end = PA_EXT5 + 0x1fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smsc911x-irq",
+ .start = IRQ0_IRQ,
+ .end = IRQ0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+};
+
+static struct resource heartbeat_resource = {
+ .start = PORT_PCDR,
+ .end = PORT_PCDR,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+static struct platform_device *polaris_devices[] __initdata = {
+ &smsc911x_device,
+ &heartbeat_device,
+};
+
+static int __init polaris_initialise(void)
+{
+ u16 wcr, bcr_mask;
+
+ printk(KERN_INFO "Configuring Polaris external bus\n");
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ /* Configure area 5 with 2 wait states */
+ wcr = __raw_readw(WCR2);
+ wcr &= (~AREA5_WAIT_CTRL);
+ wcr |= (WAIT_STATES_10 << 10);
+ __raw_writew(wcr, WCR2);
+
+ /* Configure area 5 for 32-bit access */
+ bcr_mask = __raw_readw(BCR2);
+ bcr_mask |= 1 << 10;
+ __raw_writew(bcr_mask, BCR2);
+
+ return platform_add_devices(polaris_devices,
+ ARRAY_SIZE(polaris_devices));
+}
+arch_initcall(polaris_initialise);
+
+static struct ipr_data ipr_irq_table[] = {
+ /* External IRQs */
+ { IRQ0_IRQ, 0, 0, 1, }, /* IRQ0 */
+ { IRQ1_IRQ, 0, 4, 1, }, /* IRQ1 */
+};
+
+static unsigned long ipr_offsets[] = {
+ INTC_IPRC
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+ .chip = {
+ .name = "sh7709-ext",
+ },
+};
+
+static void __init init_polaris_irq(void)
+{
+ /* Disable all interrupts */
+ __raw_writew(0, BCR_ILCRA);
+ __raw_writew(0, BCR_ILCRB);
+ __raw_writew(0, BCR_ILCRC);
+ __raw_writew(0, BCR_ILCRD);
+ __raw_writew(0, BCR_ILCRE);
+ __raw_writew(0, BCR_ILCRF);
+ __raw_writew(0, BCR_ILCRG);
+
+ register_ipr_controller(&ipr_irq_desc);
+}
+
+static struct sh_machine_vector mv_polaris __initmv = {
+ .mv_name = "Polaris",
+ .mv_init_irq = init_polaris_irq,
+};
diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c
new file mode 100644
index 000000000..603a82325
--- /dev/null
+++ b/arch/sh/boards/board-secureedge5410.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
+ * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
+ *
+ * Based on files with the following comments:
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <asm/machvec.h>
+#include <mach/secureedge5410.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <cpu/timer.h>
+
+unsigned short secureedge5410_ioport;
+
+/*
+ * EraseConfig handling functions
+ */
+static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
+{
+ printk("SnapGear: erase switch interrupt!\n");
+
+ return IRQ_HANDLED;
+}
+
+static int __init eraseconfig_init(void)
+{
+ unsigned int irq = evt2irq(0x240);
+
+ printk("SnapGear: EraseConfig init\n");
+
+ /* Setup "EraseConfig" switch on external IRQ 0 */
+ if (request_irq(irq, eraseconfig_interrupt, 0, "Erase Config", NULL))
+ printk("SnapGear: failed to register IRQ%d for Reset witch\n",
+ irq);
+ else
+ printk("SnapGear: registered EraseConfig switch on IRQ%d\n",
+ irq);
+ return 0;
+}
+device_initcall(eraseconfig_init);
+
+/*
+ * Initialize IRQ setting
+ *
+ * IRL0 = erase switch
+ * IRL1 = eth0
+ * IRL2 = eth1
+ * IRL3 = crypto
+ */
+static void __init init_snapgear_IRQ(void)
+{
+ printk("Setup SnapGear IRQ/IPR ...\n");
+ /* enable individual interrupt mode for externals */
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_snapgear __initmv = {
+ .mv_name = "SnapGear SecureEdge5410",
+ .mv_init_irq = init_snapgear_IRQ,
+};
diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c
new file mode 100644
index 000000000..6ea85e480
--- /dev/null
+++ b/arch/sh/boards/board-sh2007.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SH-2007 board support.
+ *
+ * Copyright (C) 2003, 2004 SUGIOKA Toshinobu
+ * Copyright (C) 2010 Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/io.h>
+#include <asm/machvec.h>
+#include <mach/sh2007.h>
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+ REGULATOR_SUPPLY("vddvario", "smsc911x.1"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.1"),
+};
+
+struct smsc911x_platform_config smc911x_info = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct resource smsc9118_0_resources[] = {
+ [0] = {
+ .start = SMC0_BASE,
+ .end = SMC0_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x240),
+ .end = evt2irq(0x240),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource smsc9118_1_resources[] = {
+ [0] = {
+ .start = SMC1_BASE,
+ .end = SMC1_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x280),
+ .end = evt2irq(0x280),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device smsc9118_0_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smsc9118_0_resources),
+ .resource = smsc9118_0_resources,
+ .dev = {
+ .platform_data = &smc911x_info,
+ },
+};
+
+static struct platform_device smsc9118_1_device = {
+ .name = "smsc911x",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(smsc9118_1_resources),
+ .resource = smsc9118_1_resources,
+ .dev = {
+ .platform_data = &smc911x_info,
+ },
+};
+
+static struct resource cf_resources[] = {
+ [0] = {
+ .start = CF_BASE + CF_OFFSET,
+ .end = CF_BASE + CF_OFFSET + 0x0f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CF_BASE + CF_OFFSET + 0x206,
+ .end = CF_BASE + CF_OFFSET + 0x20f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = evt2irq(0x2c0),
+ .end = evt2irq(0x2c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_device = {
+ .name = "pata_platform",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cf_resources),
+ .resource = cf_resources,
+};
+
+static struct platform_device *sh2007_devices[] __initdata = {
+ &smsc9118_0_device,
+ &smsc9118_1_device,
+ &cf_device,
+};
+
+static int __init sh2007_io_init(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices));
+ return 0;
+}
+subsys_initcall(sh2007_io_init);
+
+static void __init sh2007_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+/*
+ * Initialize the board
+ */
+static void __init sh2007_setup(char **cmdline_p)
+{
+ pr_info("SH-2007 Setup...");
+
+ /* setup wait control registers for area 5 */
+ __raw_writel(CS5BCR_D, CS5BCR);
+ __raw_writel(CS5WCR_D, CS5WCR);
+ __raw_writel(CS5PCR_D, CS5PCR);
+
+ pr_cont(" done.\n");
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_sh2007 __initmv = {
+ .mv_setup = sh2007_setup,
+ .mv_name = "sh2007",
+ .mv_init_irq = sh2007_init_irq,
+};
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
new file mode 100644
index 000000000..f39c8196e
--- /dev/null
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -0,0 +1,604 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas R0P7757LC0012RL Support.
+ *
+ * Copyright (C) 2009 - 2010 Renesas Solutions Corp.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/io.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_data/sh_mmcif.h>
+#include <linux/sh_eth.h>
+#include <linux/sh_intc.h>
+#include <linux/usb/renesas_usbhs.h>
+#include <cpu/sh7757.h>
+#include <asm/heartbeat.h>
+
+static struct resource heartbeat_resource = {
+ .start = 0xffec005c, /* PUDR */
+ .end = 0xffec005c,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+ .flags = HEARTBEAT_INVERTED,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* Fast Ethernet */
+#define GBECONT 0xffc10100
+#define GBECONT_RMII1 BIT(17)
+#define GBECONT_RMII0 BIT(16)
+static void sh7757_eth_set_mdio_gate(void *addr)
+{
+ if (((unsigned long)addr & 0x00000fff) < 0x0800)
+ writel(readl(GBECONT) | GBECONT_RMII0, GBECONT);
+ else
+ writel(readl(GBECONT) | GBECONT_RMII1, GBECONT);
+}
+
+static struct resource sh_eth0_resources[] = {
+ {
+ .start = 0xfef00000,
+ .end = 0xfef001ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0xc80),
+ .end = evt2irq(0xc80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth0_pdata = {
+ .phy = 1,
+ .set_mdio_gate = sh7757_eth_set_mdio_gate,
+};
+
+static struct platform_device sh7757_eth0_device = {
+ .name = "sh7757-ether",
+ .resource = sh_eth0_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sh_eth0_resources),
+ .dev = {
+ .platform_data = &sh7757_eth0_pdata,
+ },
+};
+
+static struct resource sh_eth1_resources[] = {
+ {
+ .start = 0xfef00800,
+ .end = 0xfef009ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0xc80),
+ .end = evt2irq(0xc80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth1_pdata = {
+ .phy = 1,
+ .set_mdio_gate = sh7757_eth_set_mdio_gate,
+};
+
+static struct platform_device sh7757_eth1_device = {
+ .name = "sh7757-ether",
+ .resource = sh_eth1_resources,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sh_eth1_resources),
+ .dev = {
+ .platform_data = &sh7757_eth1_pdata,
+ },
+};
+
+static void sh7757_eth_giga_set_mdio_gate(void *addr)
+{
+ if (((unsigned long)addr & 0x00000fff) < 0x0800) {
+ gpio_set_value(GPIO_PTT4, 1);
+ writel(readl(GBECONT) & ~GBECONT_RMII0, GBECONT);
+ } else {
+ gpio_set_value(GPIO_PTT4, 0);
+ writel(readl(GBECONT) & ~GBECONT_RMII1, GBECONT);
+ }
+}
+
+static struct resource sh_eth_giga0_resources[] = {
+ {
+ .start = 0xfee00000,
+ .end = 0xfee007ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* TSU */
+ .start = 0xfee01800,
+ .end = 0xfee01fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x2960),
+ .end = evt2irq(0x2960),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth_giga0_pdata = {
+ .phy = 18,
+ .set_mdio_gate = sh7757_eth_giga_set_mdio_gate,
+ .phy_interface = PHY_INTERFACE_MODE_RGMII_ID,
+};
+
+static struct platform_device sh7757_eth_giga0_device = {
+ .name = "sh7757-gether",
+ .resource = sh_eth_giga0_resources,
+ .id = 2,
+ .num_resources = ARRAY_SIZE(sh_eth_giga0_resources),
+ .dev = {
+ .platform_data = &sh7757_eth_giga0_pdata,
+ },
+};
+
+static struct resource sh_eth_giga1_resources[] = {
+ {
+ .start = 0xfee00800,
+ .end = 0xfee00fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* TSU */
+ .start = 0xfee01800,
+ .end = 0xfee01fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x2980),
+ .end = evt2irq(0x2980),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth_giga1_pdata = {
+ .phy = 19,
+ .set_mdio_gate = sh7757_eth_giga_set_mdio_gate,
+ .phy_interface = PHY_INTERFACE_MODE_RGMII_ID,
+};
+
+static struct platform_device sh7757_eth_giga1_device = {
+ .name = "sh7757-gether",
+ .resource = sh_eth_giga1_resources,
+ .id = 3,
+ .num_resources = ARRAY_SIZE(sh_eth_giga1_resources),
+ .dev = {
+ .platform_data = &sh7757_eth_giga1_pdata,
+ },
+};
+
+/* Fixed 3.3V regulator to be used by SDHI0, MMCIF */
+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_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
+/* SH_MMCIF */
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .start = 0xffcb0000,
+ .end = 0xffcb00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1c60),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = evt2irq(0x1c80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+ .sup_pclk = 0x0f,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NONREMOVABLE,
+ .ocr = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
+};
+
+static struct platform_device sh_mmcif_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .platform_data = &sh_mmcif_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+/* SDHI0 */
+static struct tmio_mmc_data sdhi_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI_RX,
+ .capabilities = MMC_CAP_SD_HIGHSPEED,
+};
+
+static struct resource sdhi_resources[] = {
+ [0] = {
+ .start = 0xffe50000,
+ .end = 0xffe500ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x480),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi_resources),
+ .resource = sdhi_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &sdhi_info,
+ },
+};
+
+static int usbhs0_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static struct renesas_usbhs_platform_info usb0_data = {
+ .platform_callback = {
+ .get_id = usbhs0_get_id,
+ },
+ .driver_param = {
+ .buswait_bwait = 5,
+ }
+};
+
+static struct resource usb0_resources[] = {
+ [0] = {
+ .start = 0xfe450000,
+ .end = 0xfe4501ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x840),
+ .end = evt2irq(0x840),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb0_device = {
+ .name = "renesas_usbhs",
+ .id = 0,
+ .dev = {
+ .platform_data = &usb0_data,
+ },
+ .num_resources = ARRAY_SIZE(usb0_resources),
+ .resource = usb0_resources,
+};
+
+static struct platform_device *sh7757lcr_devices[] __initdata = {
+ &heartbeat_device,
+ &sh7757_eth0_device,
+ &sh7757_eth1_device,
+ &sh7757_eth_giga0_device,
+ &sh7757_eth_giga1_device,
+ &sh_mmcif_device,
+ &sdhi_device,
+ &usb0_device,
+};
+
+static struct flash_platform_data spi_flash_data = {
+ .name = "m25p80",
+ .type = "m25px64",
+};
+
+static struct spi_board_info spi_board_info[] = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 25000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &spi_flash_data,
+ },
+};
+
+static int __init sh7757lcr_devices_setup(void)
+{
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+ /* RGMII (PTA) */
+ gpio_request(GPIO_FN_ET0_MDC, NULL);
+ gpio_request(GPIO_FN_ET0_MDIO, NULL);
+ gpio_request(GPIO_FN_ET1_MDC, NULL);
+ gpio_request(GPIO_FN_ET1_MDIO, NULL);
+
+ /* ONFI (PTB, PTZ) */
+ gpio_request(GPIO_FN_ON_NRE, NULL);
+ gpio_request(GPIO_FN_ON_NWE, NULL);
+ gpio_request(GPIO_FN_ON_NWP, NULL);
+ gpio_request(GPIO_FN_ON_NCE0, NULL);
+ gpio_request(GPIO_FN_ON_R_B0, NULL);
+ gpio_request(GPIO_FN_ON_ALE, NULL);
+ gpio_request(GPIO_FN_ON_CLE, NULL);
+
+ gpio_request(GPIO_FN_ON_DQ7, NULL);
+ gpio_request(GPIO_FN_ON_DQ6, NULL);
+ gpio_request(GPIO_FN_ON_DQ5, NULL);
+ gpio_request(GPIO_FN_ON_DQ4, NULL);
+ gpio_request(GPIO_FN_ON_DQ3, NULL);
+ gpio_request(GPIO_FN_ON_DQ2, NULL);
+ gpio_request(GPIO_FN_ON_DQ1, NULL);
+ gpio_request(GPIO_FN_ON_DQ0, NULL);
+
+ /* IRQ8 to 0 (PTB, PTC) */
+ gpio_request(GPIO_FN_IRQ8, NULL);
+ gpio_request(GPIO_FN_IRQ7, NULL);
+ gpio_request(GPIO_FN_IRQ6, NULL);
+ gpio_request(GPIO_FN_IRQ5, NULL);
+ gpio_request(GPIO_FN_IRQ4, NULL);
+ gpio_request(GPIO_FN_IRQ3, NULL);
+ gpio_request(GPIO_FN_IRQ2, NULL);
+ gpio_request(GPIO_FN_IRQ1, NULL);
+ gpio_request(GPIO_FN_IRQ0, NULL);
+
+ /* SPI0 (PTD) */
+ gpio_request(GPIO_FN_SP0_MOSI, NULL);
+ gpio_request(GPIO_FN_SP0_MISO, NULL);
+ gpio_request(GPIO_FN_SP0_SCK, NULL);
+ gpio_request(GPIO_FN_SP0_SCK_FB, NULL);
+ gpio_request(GPIO_FN_SP0_SS0, NULL);
+ gpio_request(GPIO_FN_SP0_SS1, NULL);
+ gpio_request(GPIO_FN_SP0_SS2, NULL);
+ gpio_request(GPIO_FN_SP0_SS3, NULL);
+
+ /* RMII 0/1 (PTE, PTF) */
+ gpio_request(GPIO_FN_RMII0_CRS_DV, NULL);
+ gpio_request(GPIO_FN_RMII0_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII0_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII0_TXEN, NULL);
+ gpio_request(GPIO_FN_RMII0_REFCLK, NULL);
+ gpio_request(GPIO_FN_RMII0_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII0_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII0_RX_ER, NULL);
+ gpio_request(GPIO_FN_RMII1_CRS_DV, NULL);
+ gpio_request(GPIO_FN_RMII1_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII1_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII1_TXEN, NULL);
+ gpio_request(GPIO_FN_RMII1_REFCLK, NULL);
+ gpio_request(GPIO_FN_RMII1_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII1_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII1_RX_ER, NULL);
+
+ /* eMMC (PTG) */
+ gpio_request(GPIO_FN_MMCCLK, NULL);
+ gpio_request(GPIO_FN_MMCCMD, NULL);
+ gpio_request(GPIO_FN_MMCDAT7, NULL);
+ gpio_request(GPIO_FN_MMCDAT6, NULL);
+ gpio_request(GPIO_FN_MMCDAT5, NULL);
+ gpio_request(GPIO_FN_MMCDAT4, NULL);
+ gpio_request(GPIO_FN_MMCDAT3, NULL);
+ gpio_request(GPIO_FN_MMCDAT2, NULL);
+ gpio_request(GPIO_FN_MMCDAT1, NULL);
+ gpio_request(GPIO_FN_MMCDAT0, NULL);
+
+ /* LPC (PTG, PTH, PTQ, PTU) */
+ gpio_request(GPIO_FN_SERIRQ, NULL);
+ gpio_request(GPIO_FN_LPCPD, NULL);
+ gpio_request(GPIO_FN_LDRQ, NULL);
+ gpio_request(GPIO_FN_WP, NULL);
+ gpio_request(GPIO_FN_FMS0, NULL);
+ gpio_request(GPIO_FN_LAD3, NULL);
+ gpio_request(GPIO_FN_LAD2, NULL);
+ gpio_request(GPIO_FN_LAD1, NULL);
+ gpio_request(GPIO_FN_LAD0, NULL);
+ gpio_request(GPIO_FN_LFRAME, NULL);
+ gpio_request(GPIO_FN_LRESET, NULL);
+ gpio_request(GPIO_FN_LCLK, NULL);
+ gpio_request(GPIO_FN_LGPIO7, NULL);
+ gpio_request(GPIO_FN_LGPIO6, NULL);
+ gpio_request(GPIO_FN_LGPIO5, NULL);
+ gpio_request(GPIO_FN_LGPIO4, NULL);
+
+ /* SPI1 (PTH) */
+ gpio_request(GPIO_FN_SP1_MOSI, NULL);
+ gpio_request(GPIO_FN_SP1_MISO, NULL);
+ gpio_request(GPIO_FN_SP1_SCK, NULL);
+ gpio_request(GPIO_FN_SP1_SCK_FB, NULL);
+ gpio_request(GPIO_FN_SP1_SS0, NULL);
+ gpio_request(GPIO_FN_SP1_SS1, NULL);
+
+ /* SDHI (PTI) */
+ gpio_request(GPIO_FN_SD_WP, NULL);
+ gpio_request(GPIO_FN_SD_CD, NULL);
+ gpio_request(GPIO_FN_SD_CLK, NULL);
+ gpio_request(GPIO_FN_SD_CMD, NULL);
+ gpio_request(GPIO_FN_SD_D3, NULL);
+ gpio_request(GPIO_FN_SD_D2, NULL);
+ gpio_request(GPIO_FN_SD_D1, NULL);
+ gpio_request(GPIO_FN_SD_D0, NULL);
+
+ /* SCIF3/4 (PTJ, PTW) */
+ gpio_request(GPIO_FN_RTS3, NULL);
+ gpio_request(GPIO_FN_CTS3, NULL);
+ gpio_request(GPIO_FN_TXD3, NULL);
+ gpio_request(GPIO_FN_RXD3, NULL);
+ gpio_request(GPIO_FN_RTS4, NULL);
+ gpio_request(GPIO_FN_RXD4, NULL);
+ gpio_request(GPIO_FN_TXD4, NULL);
+ gpio_request(GPIO_FN_CTS4, NULL);
+
+ /* SERMUX (PTK, PTL, PTO, PTV) */
+ gpio_request(GPIO_FN_COM2_TXD, NULL);
+ gpio_request(GPIO_FN_COM2_RXD, NULL);
+ gpio_request(GPIO_FN_COM2_RTS, NULL);
+ gpio_request(GPIO_FN_COM2_CTS, NULL);
+ gpio_request(GPIO_FN_COM2_DTR, NULL);
+ gpio_request(GPIO_FN_COM2_DSR, NULL);
+ gpio_request(GPIO_FN_COM2_DCD, NULL);
+ gpio_request(GPIO_FN_COM2_RI, NULL);
+ gpio_request(GPIO_FN_RAC_RXD, NULL);
+ gpio_request(GPIO_FN_RAC_RTS, NULL);
+ gpio_request(GPIO_FN_RAC_CTS, NULL);
+ gpio_request(GPIO_FN_RAC_DTR, NULL);
+ gpio_request(GPIO_FN_RAC_DSR, NULL);
+ gpio_request(GPIO_FN_RAC_DCD, NULL);
+ gpio_request(GPIO_FN_RAC_TXD, NULL);
+ gpio_request(GPIO_FN_COM1_TXD, NULL);
+ gpio_request(GPIO_FN_COM1_RXD, NULL);
+ gpio_request(GPIO_FN_COM1_RTS, NULL);
+ gpio_request(GPIO_FN_COM1_CTS, NULL);
+
+ writeb(0x10, 0xfe470000); /* SMR0: SerMux mode 0 */
+
+ /* IIC (PTM, PTR, PTS) */
+ gpio_request(GPIO_FN_SDA7, NULL);
+ gpio_request(GPIO_FN_SCL7, NULL);
+ gpio_request(GPIO_FN_SDA6, NULL);
+ gpio_request(GPIO_FN_SCL6, NULL);
+ gpio_request(GPIO_FN_SDA5, NULL);
+ gpio_request(GPIO_FN_SCL5, NULL);
+ gpio_request(GPIO_FN_SDA4, NULL);
+ gpio_request(GPIO_FN_SCL4, NULL);
+ gpio_request(GPIO_FN_SDA3, NULL);
+ gpio_request(GPIO_FN_SCL3, NULL);
+ gpio_request(GPIO_FN_SDA2, NULL);
+ gpio_request(GPIO_FN_SCL2, NULL);
+ gpio_request(GPIO_FN_SDA1, NULL);
+ gpio_request(GPIO_FN_SCL1, NULL);
+ gpio_request(GPIO_FN_SDA0, NULL);
+ gpio_request(GPIO_FN_SCL0, NULL);
+
+ /* USB (PTN) */
+ gpio_request(GPIO_FN_VBUS_EN, NULL);
+ gpio_request(GPIO_FN_VBUS_OC, NULL);
+
+ /* SGPIO1/0 (PTN, PTO) */
+ gpio_request(GPIO_FN_SGPIO1_CLK, NULL);
+ gpio_request(GPIO_FN_SGPIO1_LOAD, NULL);
+ gpio_request(GPIO_FN_SGPIO1_DI, NULL);
+ gpio_request(GPIO_FN_SGPIO1_DO, NULL);
+ gpio_request(GPIO_FN_SGPIO0_CLK, NULL);
+ gpio_request(GPIO_FN_SGPIO0_LOAD, NULL);
+ gpio_request(GPIO_FN_SGPIO0_DI, NULL);
+ gpio_request(GPIO_FN_SGPIO0_DO, NULL);
+
+ /* WDT (PTN) */
+ gpio_request(GPIO_FN_SUB_CLKIN, NULL);
+
+ /* System (PTT) */
+ gpio_request(GPIO_FN_STATUS1, NULL);
+ gpio_request(GPIO_FN_STATUS0, NULL);
+
+ /* PWMX (PTT) */
+ gpio_request(GPIO_FN_PWMX1, NULL);
+ gpio_request(GPIO_FN_PWMX0, NULL);
+
+ /* R-SPI (PTV) */
+ gpio_request(GPIO_FN_R_SPI_MOSI, NULL);
+ gpio_request(GPIO_FN_R_SPI_MISO, NULL);
+ gpio_request(GPIO_FN_R_SPI_RSPCK, NULL);
+ gpio_request(GPIO_FN_R_SPI_SSL0, NULL);
+ gpio_request(GPIO_FN_R_SPI_SSL1, NULL);
+
+ /* EVC (PTV, PTW) */
+ gpio_request(GPIO_FN_EVENT7, NULL);
+ gpio_request(GPIO_FN_EVENT6, NULL);
+ gpio_request(GPIO_FN_EVENT5, NULL);
+ gpio_request(GPIO_FN_EVENT4, NULL);
+ gpio_request(GPIO_FN_EVENT3, NULL);
+ gpio_request(GPIO_FN_EVENT2, NULL);
+ gpio_request(GPIO_FN_EVENT1, NULL);
+ gpio_request(GPIO_FN_EVENT0, NULL);
+
+ /* LED for heartbeat */
+ gpio_request(GPIO_PTU3, NULL);
+ gpio_direction_output(GPIO_PTU3, 1);
+ gpio_request(GPIO_PTU2, NULL);
+ gpio_direction_output(GPIO_PTU2, 1);
+ gpio_request(GPIO_PTU1, NULL);
+ gpio_direction_output(GPIO_PTU1, 1);
+ gpio_request(GPIO_PTU0, NULL);
+ gpio_direction_output(GPIO_PTU0, 1);
+
+ /* control for MDIO of Gigabit Ethernet */
+ gpio_request(GPIO_PTT4, NULL);
+ gpio_direction_output(GPIO_PTT4, 1);
+
+ /* control for eMMC */
+ gpio_request(GPIO_PTT7, NULL); /* eMMC_RST# */
+ gpio_direction_output(GPIO_PTT7, 0);
+ gpio_request(GPIO_PTT6, NULL); /* eMMC_INDEX# */
+ gpio_direction_output(GPIO_PTT6, 0);
+ gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */
+ gpio_direction_output(GPIO_PTT5, 1);
+
+ /* register SPI device information */
+ spi_register_board_info(spi_board_info,
+ ARRAY_SIZE(spi_board_info));
+
+ /* General platform */
+ return platform_add_devices(sh7757lcr_devices,
+ ARRAY_SIZE(sh7757lcr_devices));
+}
+arch_initcall(sh7757lcr_devices_setup);
+
+/* Initialize IRQ setting */
+void __init init_sh7757lcr_IRQ(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ7654);
+ plat_irq_setup_pins(IRQ_MODE_IRQ3210);
+}
+
+/* Initialize the board */
+static void __init sh7757lcr_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "Renesas R0P7757LC0012RL support.\n");
+}
+
+static int sh7757lcr_mode_pins(void)
+{
+ int value = 0;
+
+ /* These are the factory default settings of S3 (Low active).
+ * If you change these dip switches then you will need to
+ * adjust the values below as well.
+ */
+ value |= MODE_PIN0; /* Clock Mode: 1 */
+
+ return value;
+}
+
+/* The Machine Vector */
+static struct sh_machine_vector mv_sh7757lcr __initmv = {
+ .mv_name = "SH7757LCR",
+ .mv_setup = sh7757lcr_setup,
+ .mv_init_irq = init_sh7757lcr_IRQ,
+ .mv_mode_pins = sh7757lcr_mode_pins,
+};
+
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
new file mode 100644
index 000000000..77dad1e51
--- /dev/null
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Technology Corp. R0P7785LC0011RL Support.
+ *
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ * Copyright (C) 2009 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sm501.h>
+#include <linux/sm501-regs.h>
+#include <linux/fb.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/platform_data/i2c-pca-platform.h>
+#include <linux/i2c-algo-pca.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/sh_intc.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/gpio/machine.h>
+#include <mach/sh7785lcr.h>
+#include <cpu/sh7785.h>
+#include <asm/heartbeat.h>
+#include <asm/clock.h>
+#include <asm/bl_bit.h>
+
+/*
+ * NOTE: This board has 2 physical memory maps.
+ * Please look at include/asm-sh/sh7785lcr.h or hardware manual.
+ */
+static struct resource heartbeat_resource = {
+ .start = PLD_LEDCR,
+ .end = PLD_LEDCR,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 4,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = NOR_FLASH_ADDR,
+ .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+static struct r8a66597_platdata r8a66597_data = {
+ .xtal = R8A66597_PLATDATA_XTAL_12MHZ,
+ .vif = 1,
+};
+
+static struct resource r8a66597_usb_host_resources[] = {
+ [0] = {
+ .start = R8A66597_ADDR,
+ .end = R8A66597_ADDR + R8A66597_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x240),
+ .end = evt2irq(0x240),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device r8a66597_usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &r8a66597_data,
+ },
+ .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources),
+ .resource = r8a66597_usb_host_resources,
+};
+
+static struct resource sm501_resources[] = {
+ [0] = {
+ .start = SM107_MEM_ADDR,
+ .end = SM107_MEM_ADDR + SM107_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SM107_REG_ADDR,
+ .end = SM107_REG_ADDR + SM107_REG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = evt2irq(0x340),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct fb_videomode sm501_default_mode_crt = {
+ .pixclock = 35714, /* 28MHz */
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 105,
+ .right_margin = 16,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .hsync_len = 39,
+ .vsync_len = 2,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct fb_videomode sm501_default_mode_pnl = {
+ .pixclock = 40000, /* 25MHz */
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 2,
+ .right_margin = 16,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .hsync_len = 39,
+ .vsync_len = 2,
+ .sync = 0,
+};
+
+static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = {
+ .def_bpp = 16,
+ .def_mode = &sm501_default_mode_pnl,
+ .flags = SM501FB_FLAG_USE_INIT_MODE |
+ SM501FB_FLAG_USE_HWCURSOR |
+ SM501FB_FLAG_USE_HWACCEL |
+ SM501FB_FLAG_DISABLE_AT_EXIT |
+ SM501FB_FLAG_PANEL_NO_VBIASEN,
+};
+
+static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = {
+ .def_bpp = 16,
+ .def_mode = &sm501_default_mode_crt,
+ .flags = SM501FB_FLAG_USE_INIT_MODE |
+ SM501FB_FLAG_USE_HWCURSOR |
+ SM501FB_FLAG_USE_HWACCEL |
+ SM501FB_FLAG_DISABLE_AT_EXIT,
+};
+
+static struct sm501_platdata_fb sm501_fb_pdata = {
+ .fb_route = SM501_FB_OWN,
+ .fb_crt = &sm501_pdata_fbsub_crt,
+ .fb_pnl = &sm501_pdata_fbsub_pnl,
+};
+
+static struct sm501_initdata sm501_initdata = {
+ .gpio_high = {
+ .set = 0x00001fe0,
+ .mask = 0x0,
+ },
+ .devices = 0,
+ .mclk = 84 * 1000000,
+ .m1xclk = 112 * 1000000,
+};
+
+static struct sm501_platdata sm501_platform_data = {
+ .init = &sm501_initdata,
+ .fb = &sm501_fb_pdata,
+};
+
+static struct platform_device sm501_device = {
+ .name = "sm501",
+ .id = -1,
+ .dev = {
+ .platform_data = &sm501_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(sm501_resources),
+ .resource = sm501_resources,
+};
+
+static struct resource i2c_proto_resources[] = {
+ [0] = {
+ .start = PCA9564_PROTO_32BIT_ADDR,
+ .end = PCA9564_PROTO_32BIT_ADDR + PCA9564_SIZE - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+ },
+ [1] = {
+ .start = evt2irq(0x380),
+ .end = evt2irq(0x380),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c_resources[] = {
+ [0] = {
+ .start = PCA9564_ADDR,
+ .end = PCA9564_ADDR + PCA9564_SIZE - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+ },
+ [1] = {
+ .start = evt2irq(0x380),
+ .end = evt2irq(0x380),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct gpiod_lookup_table i2c_gpio_table = {
+ .dev_id = "i2c.0",
+ .table = {
+ GPIO_LOOKUP("pfc-sh7757", 0, "reset-gpios", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct i2c_pca9564_pf_platform_data i2c_platform_data = {
+ .i2c_clock_speed = I2C_PCA_CON_330kHz,
+ .timeout = HZ,
+};
+
+static struct platform_device i2c_device = {
+ .name = "i2c-pca-platform",
+ .id = -1,
+ .dev = {
+ .platform_data = &i2c_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(i2c_resources),
+ .resource = i2c_resources,
+};
+
+static struct platform_device *sh7785lcr_devices[] __initdata = {
+ &heartbeat_device,
+ &nor_flash_device,
+ &r8a66597_usb_host_device,
+ &sm501_device,
+ &i2c_device,
+};
+
+static struct i2c_board_info __initdata sh7785lcr_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ },
+};
+
+static int __init sh7785lcr_devices_setup(void)
+{
+ i2c_register_board_info(0, sh7785lcr_i2c_devices,
+ ARRAY_SIZE(sh7785lcr_i2c_devices));
+
+ if (mach_is_sh7785lcr_pt()) {
+ i2c_device.resource = i2c_proto_resources;
+ i2c_device.num_resources = ARRAY_SIZE(i2c_proto_resources);
+ }
+
+ gpiod_add_lookup_table(&i2c_gpio_table);
+ return platform_add_devices(sh7785lcr_devices,
+ ARRAY_SIZE(sh7785lcr_devices));
+}
+device_initcall(sh7785lcr_devices_setup);
+
+/* Initialize IRQ setting */
+void __init init_sh7785lcr_IRQ(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ7654);
+ plat_irq_setup_pins(IRQ_MODE_IRQ3210);
+}
+
+static int sh7785lcr_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = clk_get(NULL, "extal");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333333);
+ clk_put(clk);
+
+ return ret;
+}
+
+static void sh7785lcr_power_off(void)
+{
+ unsigned char *p;
+
+ p = ioremap(PLD_POFCR, PLD_POFCR + 1);
+ if (!p) {
+ printk(KERN_ERR "%s: ioremap error.\n", __func__);
+ return;
+ }
+ *p = 0x01;
+ iounmap(p);
+ set_bl_bit();
+ while (1)
+ cpu_relax();
+}
+
+/* Initialize the board */
+static void __init sh7785lcr_setup(char **cmdline_p)
+{
+ void __iomem *sm501_reg;
+
+ printk(KERN_INFO "Renesas Technology Corp. R0P7785LC0011RL support.\n");
+
+ pm_power_off = sh7785lcr_power_off;
+
+ /* sm501 DRAM configuration */
+ sm501_reg = ioremap(SM107_REG_ADDR, SM501_DRAM_CONTROL);
+ if (!sm501_reg) {
+ printk(KERN_ERR "%s: ioremap error.\n", __func__);
+ return;
+ }
+
+ writel(0x000307c2, sm501_reg + SM501_DRAM_CONTROL);
+ iounmap(sm501_reg);
+}
+
+/* Return the board specific boot mode pin configuration */
+static int sh7785lcr_mode_pins(void)
+{
+ int value = 0;
+
+ /* These are the factory default settings of S1 and S2.
+ * If you change these dip switches then you will need to
+ * adjust the values below as well.
+ */
+ value |= MODE_PIN4; /* Clock Mode 16 */
+ value |= MODE_PIN5; /* 32-bit Area0 bus width */
+ value |= MODE_PIN6; /* 32-bit Area0 bus width */
+ value |= MODE_PIN7; /* Area 0 SRAM interface [fixed] */
+ value |= MODE_PIN8; /* Little Endian */
+ value |= MODE_PIN9; /* Master Mode */
+ value |= MODE_PIN14; /* No PLL step-up */
+
+ return value;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_sh7785lcr __initmv = {
+ .mv_name = "SH7785LCR",
+ .mv_setup = sh7785lcr_setup,
+ .mv_clk_init = sh7785lcr_clk_init,
+ .mv_init_irq = init_sh7785lcr_IRQ,
+ .mv_mode_pins = sh7785lcr_mode_pins,
+};
+
diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c
new file mode 100644
index 000000000..83296c0b7
--- /dev/null
+++ b/arch/sh/boards/board-shmin.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/shmin/setup.c
+ *
+ * Copyright (C) 2006 Takashi YOSHII
+ *
+ * SHMIN Support.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/machvec.h>
+#include <mach/shmin.h>
+#include <asm/clock.h>
+#include <asm/io.h>
+
+#define PFC_PHCR 0xa400010eUL
+#define INTC_ICR1 0xa4000010UL
+
+static void __init init_shmin_irq(void)
+{
+ __raw_writew(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
+ __raw_writew(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active.
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+static void __init shmin_setup(char **cmdline_p)
+{
+ __set_io_port_base(SHMIN_IO_BASE);
+}
+
+static struct sh_machine_vector mv_shmin __initmv = {
+ .mv_name = "SHMIN",
+ .mv_setup = shmin_setup,
+ .mv_init_irq = init_shmin_irq,
+};
diff --git a/arch/sh/boards/board-titan.c b/arch/sh/boards/board-titan.c
new file mode 100644
index 000000000..074a848d8
--- /dev/null
+++ b/arch/sh/boards/board-titan.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/titan/setup.c - Setup for Titan
+ *
+ * Copyright (C) 2006 Jamie Lenehan
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <mach/titan.h>
+#include <asm/io.h>
+
+static void __init init_titan_irq(void)
+{
+ /* enable individual interrupt mode for externals */
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+static struct sh_machine_vector mv_titan __initmv = {
+ .mv_name = "Titan",
+ .mv_init_irq = init_titan_irq,
+};
diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c
new file mode 100644
index 000000000..dad2b3b40
--- /dev/null
+++ b/arch/sh/boards/board-urquell.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Technology Corp. SH7786 Urquell Support.
+ *
+ * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ * Copyright (C) 2009, 2010 Paul Mundt
+ *
+ * Based on board-sh7785lcr.c
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/smc91x.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/sh_intc.h>
+#include <mach/urquell.h>
+#include <cpu/sh7786.h>
+#include <asm/heartbeat.h>
+#include <linux/sizes.h>
+#include <asm/smp-ops.h>
+
+/*
+ * bit 1234 5678
+ *----------------------------
+ * SW1 0101 0010 -> Pck 33MHz version
+ * (1101 0010) Pck 66MHz version
+ * SW2 0x1x xxxx -> little endian
+ * 29bit mode
+ * SW47 0001 1000 -> CS0 : on-board flash
+ * CS1 : SRAM, registers, LAN, PCMCIA
+ * 38400 bps for SCIF1
+ *
+ * Address
+ * 0x00000000 - 0x04000000 (CS0) Nor Flash
+ * 0x04000000 - 0x04200000 (CS1) SRAM
+ * 0x05000000 - 0x05800000 (CS1) on board register
+ * 0x05800000 - 0x06000000 (CS1) LAN91C111
+ * 0x06000000 - 0x06400000 (CS1) PCMCIA
+ * 0x08000000 - 0x10000000 (CS2-CS3) DDR3
+ * 0x10000000 - 0x14000000 (CS4) PCIe
+ * 0x14000000 - 0x14800000 (CS5) Core0 LRAM/URAM
+ * 0x14800000 - 0x15000000 (CS5) Core1 LRAM/URAM
+ * 0x18000000 - 0x1C000000 (CS6) ATA/NAND-Flash
+ * 0x1C000000 - (CS7) SH7786 Control register
+ */
+
+/* HeartBeat */
+static struct resource heartbeat_resource = {
+ .start = BOARDREG(SLEDR),
+ .end = BOARDREG(SLEDR),
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* LAN91C111 */
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "SMC91C111" ,
+ .start = 0x05800300,
+ .end = 0x0580030f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x360),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+/* Nor Flash */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = NOR_FLASH_ADDR,
+ .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+static struct platform_device *urquell_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+ &nor_flash_device,
+};
+
+static int __init urquell_devices_setup(void)
+{
+ /* USB */
+ gpio_request(GPIO_FN_USB_OVC0, NULL);
+ gpio_request(GPIO_FN_USB_PENC0, NULL);
+
+ /* enable LAN */
+ __raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001,
+ UBOARDREG(IRL2MSKR));
+
+ return platform_add_devices(urquell_devices,
+ ARRAY_SIZE(urquell_devices));
+}
+device_initcall(urquell_devices_setup);
+
+static void urquell_power_off(void)
+{
+ __raw_writew(0xa5a5, UBOARDREG(SRSTR));
+}
+
+static void __init urquell_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
+}
+
+static int urquell_mode_pins(void)
+{
+ return __raw_readw(UBOARDREG(MDSWMR));
+}
+
+static int urquell_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ /*
+ * Only handle the EXTAL case, anyone interfacing a crystal
+ * resonator will need to provide their own input clock.
+ */
+ if (test_mode_pin(MODE_PIN9))
+ return -EINVAL;
+
+ clk = clk_get(NULL, "extal");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333333);
+ clk_put(clk);
+
+ return ret;
+}
+
+/* Initialize the board */
+static void __init urquell_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n");
+
+ pm_power_off = urquell_power_off;
+
+ register_smp_ops(&shx3_smp_ops);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_urquell __initmv = {
+ .mv_name = "Urquell",
+ .mv_setup = urquell_setup,
+ .mv_init_irq = urquell_init_irq,
+ .mv_mode_pins = urquell_mode_pins,
+ .mv_clk_init = urquell_clk_init,
+};
diff --git a/arch/sh/boards/mach-ap325rxa/Makefile b/arch/sh/boards/mach-ap325rxa/Makefile
new file mode 100644
index 000000000..dba5d0c20
--- /dev/null
+++ b/arch/sh/boards/mach-ap325rxa/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := setup.o sdram.o
+
diff --git a/arch/sh/boards/mach-ap325rxa/sdram.S b/arch/sh/boards/mach-ap325rxa/sdram.S
new file mode 100644
index 000000000..541c82cc3
--- /dev/null
+++ b/arch/sh/boards/mach-ap325rxa/sdram.S
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * AP325RXA sdram self/auto-refresh setup code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+ .balign 4
+ENTRY(ap325rxa_sdram_enter_start)
+
+ /* SBSC: disable power down and put in self-refresh mode */
+ mov.l 1f, r4
+ mov.l 2f, r1
+ mov.l @r4, r2
+ or r1, r2
+ mov.l 3f, r3
+ and r3, r2
+ mov.l r2, @r4
+
+ rts
+ nop
+
+ .balign 4
+1: .long 0xfe400008 /* SDCR0 */
+2: .long 0x00000400
+3: .long 0xffff7fff
+ENTRY(ap325rxa_sdram_enter_end)
+
+ .balign 4
+ENTRY(ap325rxa_sdram_leave_start)
+
+ /* SBSC: set auto-refresh mode */
+ mov.l 1f, r4
+ mov.l @r4, r0
+ mov.l 4f, r1
+ and r1, r0
+ mov.l r0, @r4
+ mov.l 6f, r4
+ mov.l 8f, r0
+ mov.l @r4, r1
+ mov #-1, r4
+ add r4, r1
+ or r1, r0
+ mov.l 7f, r1
+ mov.l r0, @r1
+
+ rts
+ nop
+
+ .balign 4
+1: .long 0xfe400008 /* SDCR0 */
+4: .long 0xfffffbff
+6: .long 0xfe40001c /* RTCOR */
+7: .long 0xfe400018 /* RTCNT */
+8: .long 0xa55a0000
+ENTRY(ap325rxa_sdram_leave_end)
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
new file mode 100644
index 000000000..d8f8dca4d
--- /dev/null
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -0,0 +1,573 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas - AP-325RXA
+ * (Compatible with Algo System ., LTD. - AP-320A)
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Author : Yusuke Goda <goda.yuske@renesas.com>
+ */
+
+#include <asm/clock.h>
+#include <asm/io.h>
+#include <asm/suspend.h>
+
+#include <cpu/sh7723.h>
+
+#include <linux/dma-map-ops.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/memblock.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/sh_intc.h>
+#include <linux/smsc911x.h>
+#include <linux/videodev2.h>
+
+#include <media/drv-intf/renesas-ceu.h>
+#include <media/i2c/ov772x.h>
+
+#include <video/sh_mobile_lcdc.h>
+
+#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
+static phys_addr_t ceu_dma_membase;
+
+/* 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_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct resource smsc9118_resources[] = {
+ [0] = {
+ .start = 0xb6080000,
+ .end = 0xb60fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x660),
+ .end = evt2irq(0x660),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device smsc9118_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc9118_resources),
+ .resource = smsc9118_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+/*
+ * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
+ * If this area erased, this board can not boot.
+ */
+static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (1 * 1024 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (2 * 1024 * 1024),
+ }, {
+ .name = "free-area0",
+ .offset = MTDPART_OFS_APPEND,
+ .size = ((7 * 1024 * 1024) + (512 * 1024)),
+ }, {
+ .name = "CPLD-Data",
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ .size = (1024 * 128 * 2),
+ }, {
+ .name = "free-area1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data ap325rxa_nor_flash_data = {
+ .width = 2,
+ .parts = ap325rxa_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(ap325rxa_nor_flash_partitions),
+};
+
+static struct resource ap325rxa_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x00ffffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device ap325rxa_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = ap325rxa_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(ap325rxa_nor_flash_resources),
+ .dev = {
+ .platform_data = &ap325rxa_nor_flash_data,
+ },
+};
+
+static struct mtd_partition nand_partition_info[] = {
+ {
+ .name = "nand_data",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct resource nand_flash_resources[] = {
+ [0] = {
+ .start = 0xa4530000,
+ .end = 0xa45300ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+ .parts = nand_partition_info,
+ .nr_parts = ARRAY_SIZE(nand_partition_info),
+ .flcmncr_val = FCKSEL_E | TYPESEL_SET | NANWF_E,
+ .has_hwecc = 1,
+};
+
+static struct platform_device nand_flash_device = {
+ .name = "sh_flctl",
+ .resource = nand_flash_resources,
+ .num_resources = ARRAY_SIZE(nand_flash_resources),
+ .dev = {
+ .platform_data = &nand_flash_data,
+ },
+};
+
+#define FPGA_LCDREG 0xB4100180
+#define FPGA_BKLREG 0xB4100212
+#define FPGA_LCDREG_VAL 0x0018
+#define PORT_MSELCRB 0xA4050182
+#define PORT_HIZCRC 0xA405015C
+#define PORT_DRVCRA 0xA405018A
+#define PORT_DRVCRB 0xA405018C
+
+static int ap320_wvga_set_brightness(int brightness)
+{
+ if (brightness) {
+ gpio_set_value(GPIO_PTS3, 0);
+ __raw_writew(0x100, FPGA_BKLREG);
+ } else {
+ __raw_writew(0, FPGA_BKLREG);
+ gpio_set_value(GPIO_PTS3, 1);
+ }
+
+ return 0;
+}
+
+static void ap320_wvga_power_on(void)
+{
+ msleep(100);
+
+ /* ASD AP-320/325 LCD ON */
+ __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
+}
+
+static void ap320_wvga_power_off(void)
+{
+ /* ASD AP-320/325 LCD OFF */
+ __raw_writew(0, FPGA_LCDREG);
+}
+
+static const struct fb_videomode ap325rxa_lcdc_modes[] = {
+ {
+ .name = "LB070WV1",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 32,
+ .right_margin = 160,
+ .hsync_len = 8,
+ .upper_margin = 63,
+ .lower_margin = 80,
+ .vsync_len = 1,
+ .sync = 0, /* hsync and vsync are active low */
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .clock_source = LCDC_CLK_EXTERNAL,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = RGB18,
+ .clock_divider = 1,
+ .lcd_modes = ap325rxa_lcdc_modes,
+ .num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
+ .panel_cfg = {
+ .width = 152, /* 7.0 inch */
+ .height = 91,
+ .display_on = ap320_wvga_power_on,
+ .display_off = ap320_wvga_power_off,
+ },
+ .bl_info = {
+ .name = "sh_mobile_lcdc_bl",
+ .max_brightness = 1,
+ .set_brightness = ap320_wvga_set_brightness,
+ },
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe942fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ },
+};
+
+/* Powerdown/reset gpios for CEU image sensors */
+static struct gpiod_lookup_table ov7725_gpios = {
+ .dev_id = "0-0021",
+ .table = {
+ GPIO_LOOKUP("sh7723_pfc", GPIO_PTZ5, "reset", GPIO_ACTIVE_LOW),
+ },
+};
+
+static struct ceu_platform_data ceu0_pdata = {
+ .num_subdevs = 1,
+ .subdevs = {
+ { /* [0] = ov7725 */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 0,
+ .i2c_address = 0x21,
+ },
+ },
+};
+
+static struct resource ceu_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ap325rxa_ceu_device = {
+ .name = "renesas-ceu",
+ .id = 0, /* "ceu.0" clock */
+ .num_resources = ARRAY_SIZE(ceu_resources),
+ .resource = ceu_resources,
+ .dev = {
+ .platform_data = &ceu0_pdata,
+ },
+};
+
+/* Fixed 3.3V regulators to be used by SDHI0, 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"),
+};
+
+static struct resource sdhi0_cn3_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0x04ce0000,
+ .end = 0x04ce00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xe80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sdhi0_cn3_data = {
+ .capabilities = MMC_CAP_SDIO_IRQ,
+};
+
+static struct platform_device sdhi0_cn3_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 0, /* "sdhi0" clock */
+ .num_resources = ARRAY_SIZE(sdhi0_cn3_resources),
+ .resource = sdhi0_cn3_resources,
+ .dev = {
+ .platform_data = &sdhi0_cn3_data,
+ },
+};
+
+static struct resource sdhi1_cn7_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0x04cf0000,
+ .end = 0x04cf00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x4e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sdhi1_cn7_data = {
+ .capabilities = MMC_CAP_SDIO_IRQ,
+};
+
+static struct platform_device sdhi1_cn7_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 1, /* "sdhi1" clock */
+ .num_resources = ARRAY_SIZE(sdhi1_cn7_resources),
+ .resource = sdhi1_cn7_resources,
+ .dev = {
+ .platform_data = &sdhi1_cn7_data,
+ },
+};
+
+static struct ov772x_camera_info ov7725_info = {
+ .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+ .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
+};
+
+static struct i2c_board_info ap325rxa_i2c_devices[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+ {
+ I2C_BOARD_INFO("ov772x", 0x21),
+ .platform_data = &ov7725_info,
+ },
+};
+
+static struct platform_device *ap325rxa_devices[] __initdata = {
+ &smsc9118_device,
+ &ap325rxa_nor_flash_device,
+ &lcdc_device,
+ &nand_flash_device,
+ &sdhi0_cn3_device,
+ &sdhi1_cn7_device,
+};
+
+extern char ap325rxa_sdram_enter_start;
+extern char ap325rxa_sdram_enter_end;
+extern char ap325rxa_sdram_leave_start;
+extern char ap325rxa_sdram_leave_end;
+
+static int __init ap325rxa_devices_setup(void)
+{
+ /* register board specific self-refresh code */
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+ &ap325rxa_sdram_enter_start,
+ &ap325rxa_sdram_enter_end,
+ &ap325rxa_sdram_leave_start,
+ &ap325rxa_sdram_leave_end);
+
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+ regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ /* LD3 and LD4 LEDs */
+ gpio_request(GPIO_PTX5, NULL); /* RUN */
+ gpio_direction_output(GPIO_PTX5, 1);
+ gpio_export(GPIO_PTX5, 0);
+
+ gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
+ gpio_direction_output(GPIO_PTX4, 0);
+ gpio_export(GPIO_PTX4, 0);
+
+ /* SW1 input */
+ gpio_request(GPIO_PTF7, NULL); /* MODE */
+ gpio_direction_input(GPIO_PTF7);
+ gpio_export(GPIO_PTF7, 0);
+
+ /* LCDC */
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+ gpio_request(GPIO_FN_LCDVEPWC, NULL);
+ gpio_request(GPIO_FN_LCDVCPWC, NULL);
+ gpio_request(GPIO_FN_LCDVSYN, NULL);
+ gpio_request(GPIO_FN_LCDHSYN, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDON, NULL);
+
+ /* LCD backlight */
+ gpio_request(GPIO_PTS3, NULL);
+ gpio_direction_output(GPIO_PTS3, 1);
+
+ /* CEU */
+ gpio_request(GPIO_FN_VIO_CLK2, NULL);
+ gpio_request(GPIO_FN_VIO_VD2, NULL);
+ gpio_request(GPIO_FN_VIO_HD2, NULL);
+ gpio_request(GPIO_FN_VIO_FLD, NULL);
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+ gpio_request(GPIO_FN_VIO_D15, NULL);
+ gpio_request(GPIO_FN_VIO_D14, NULL);
+ gpio_request(GPIO_FN_VIO_D13, NULL);
+ gpio_request(GPIO_FN_VIO_D12, NULL);
+ gpio_request(GPIO_FN_VIO_D11, NULL);
+ gpio_request(GPIO_FN_VIO_D10, NULL);
+ gpio_request(GPIO_FN_VIO_D9, NULL);
+ gpio_request(GPIO_FN_VIO_D8, NULL);
+
+ gpio_request(GPIO_PTZ7, NULL);
+ gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
+ gpio_request(GPIO_PTZ6, NULL);
+ gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
+ gpio_request(GPIO_PTZ5, NULL);
+ gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
+ gpio_request(GPIO_PTZ4, NULL);
+ gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
+
+ __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
+
+ /* FLCTL */
+ gpio_request(GPIO_FN_FCE, NULL);
+ gpio_request(GPIO_FN_NAF7, NULL);
+ gpio_request(GPIO_FN_NAF6, NULL);
+ gpio_request(GPIO_FN_NAF5, NULL);
+ gpio_request(GPIO_FN_NAF4, NULL);
+ gpio_request(GPIO_FN_NAF3, NULL);
+ gpio_request(GPIO_FN_NAF2, NULL);
+ gpio_request(GPIO_FN_NAF1, NULL);
+ gpio_request(GPIO_FN_NAF0, NULL);
+ gpio_request(GPIO_FN_FCDE, NULL);
+ gpio_request(GPIO_FN_FOE, NULL);
+ gpio_request(GPIO_FN_FSC, NULL);
+ gpio_request(GPIO_FN_FWE, NULL);
+ gpio_request(GPIO_FN_FRB, NULL);
+
+ __raw_writew(0, PORT_HIZCRC);
+ __raw_writew(0xFFFF, PORT_DRVCRA);
+ __raw_writew(0xFFFF, PORT_DRVCRB);
+
+ /* SDHI0 - CN3 - SD CARD */
+ gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
+ gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
+
+ /* SDHI1 - CN7 - MICRO SD CARD */
+ gpio_request(GPIO_FN_SDHI1CD, NULL);
+ gpio_request(GPIO_FN_SDHI1D3, NULL);
+ gpio_request(GPIO_FN_SDHI1D2, NULL);
+ gpio_request(GPIO_FN_SDHI1D1, NULL);
+ gpio_request(GPIO_FN_SDHI1D0, NULL);
+ gpio_request(GPIO_FN_SDHI1CMD, NULL);
+ gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
+ /* Add a clock alias for ov7725 xclk source. */
+ clk_add_alias(NULL, "0-0021", "video_clk", NULL);
+
+ /* Register RSTB gpio for ov7725 camera sensor. */
+ gpiod_add_lookup_table(&ov7725_gpios);
+
+ i2c_register_board_info(0, ap325rxa_i2c_devices,
+ ARRAY_SIZE(ap325rxa_i2c_devices));
+
+ /* Initialize CEU platform device separately to map memory first */
+ device_initialize(&ap325rxa_ceu_device.dev);
+ dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
+ ceu_dma_membase, ceu_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+
+ platform_device_add(&ap325rxa_ceu_device);
+
+ return platform_add_devices(ap325rxa_devices,
+ ARRAY_SIZE(ap325rxa_devices));
+}
+arch_initcall(ap325rxa_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int ap325rxa_mode_pins(void)
+{
+ /* MD0=0, MD1=0, MD2=0: Clock Mode 0
+ * MD3=0: 16-bit Area0 Bus Width
+ * MD5=1: Little Endian
+ * TSTMD=1, MD8=1: Test Mode Disabled
+ */
+ return MODE_PIN5 | MODE_PIN8;
+}
+
+/* Reserve a portion of memory for CEU buffers */
+static void __init ap325rxa_mv_mem_reserve(void)
+{
+ phys_addr_t phys;
+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+
+ ceu_dma_membase = phys;
+}
+
+static struct sh_machine_vector mv_ap325rxa __initmv = {
+ .mv_name = "AP-325RXA",
+ .mv_mode_pins = ap325rxa_mode_pins,
+ .mv_mem_reserve = ap325rxa_mv_mem_reserve,
+};
diff --git a/arch/sh/boards/mach-dreamcast/Makefile b/arch/sh/boards/mach-dreamcast/Makefile
new file mode 100644
index 000000000..37b245220
--- /dev/null
+++ b/arch/sh/boards/mach-dreamcast/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Sega Dreamcast specific parts of the kernel
+#
+
+obj-y := setup.o irq.o
+obj-$(CONFIG_RTC_DRV_GENERIC) += rtc.o
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
new file mode 100644
index 000000000..0eec82fb8
--- /dev/null
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/dreamcast/irq.c
+ *
+ * Holly IRQ support for the Sega Dreamcast.
+ *
+ * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
+ *
+ * This file is part of the LinuxDC project (www.linuxdc.org)
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <mach/sysasic.h>
+
+/*
+ * Dreamcast System ASIC Hardware Events -
+ *
+ * The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
+ * hardware events from system peripherals and triggering an SH7750 IRQ.
+ * Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
+ * set in the Event Mask Registers (EMRs). When a hardware event is
+ * triggered, its corresponding bit in the Event Status Registers (ESRs)
+ * is set, and that bit should be rewritten to the ESR to acknowledge that
+ * event.
+ *
+ * There are three 32-bit ESRs located at 0xa05f6900 - 0xa05f6908. Event
+ * types can be found in arch/sh/include/mach-dreamcast/mach/sysasic.h.
+ * There are three groups of EMRs that parallel the ESRs. Each EMR group
+ * corresponds to an IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13,
+ * 0xa05f6920 - 0xa05f6928 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938
+ * triggers IRQ 9.
+ *
+ * In the kernel, these events are mapped to virtual IRQs so that drivers can
+ * respond to them as they would a normal interrupt. In order to keep this
+ * mapping simple, the events are mapped as:
+ *
+ * 6900/6910 - Events 0-31, IRQ 13
+ * 6904/6924 - Events 32-63, IRQ 11
+ * 6908/6938 - Events 64-95, IRQ 9
+ *
+ */
+
+#define ESR_BASE 0x005f6900 /* Base event status register */
+#define EMR_BASE 0x005f6910 /* Base event mask register */
+
+/*
+ * Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
+ * 1 = 0x6920, 2 = 0x6930; also determine the event offset.
+ */
+#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
+
+/* Return the hardware event's bit position within the EMR/ESR */
+#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
+
+/*
+ * For each of these *_irq routines, the IRQ passed in is the virtual IRQ
+ * (logically mapped to the corresponding bit for the hardware event).
+ */
+
+/* Disable the hardware event by masking its bit in its EMR */
+static inline void disable_systemasic_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+ __u32 mask;
+
+ mask = inl(emr);
+ mask &= ~(1 << EVENT_BIT(irq));
+ outl(mask, emr);
+}
+
+/* Enable the hardware event by setting its bit in its EMR */
+static inline void enable_systemasic_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+ __u32 mask;
+
+ mask = inl(emr);
+ mask |= (1 << EVENT_BIT(irq));
+ outl(mask, emr);
+}
+
+/* Acknowledge a hardware event by writing its bit back to its ESR */
+static void mask_ack_systemasic_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
+ disable_systemasic_irq(data);
+ outl((1 << EVENT_BIT(irq)), esr);
+}
+
+struct irq_chip systemasic_int = {
+ .name = "System ASIC",
+ .irq_mask = disable_systemasic_irq,
+ .irq_mask_ack = mask_ack_systemasic_irq,
+ .irq_unmask = enable_systemasic_irq,
+};
+
+/*
+ * Map the hardware event indicated by the processor IRQ to a virtual IRQ.
+ */
+int systemasic_irq_demux(int irq)
+{
+ __u32 emr, esr, status, level;
+ __u32 j, bit;
+
+ switch (irq) {
+ case 13 + 16:
+ level = 0;
+ break;
+ case 11 + 16:
+ level = 1;
+ break;
+ case 9 + 16:
+ level = 2;
+ break;
+ default:
+ return irq;
+ }
+ emr = EMR_BASE + (level << 4) + (level << 2);
+ esr = ESR_BASE + (level << 2);
+
+ /* Mask the ESR to filter any spurious, unwanted interrupts */
+ status = inl(esr);
+ status &= inl(emr);
+
+ /* Now scan and find the first set bit as the event to map */
+ for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
+ if (status & bit) {
+ irq = HW_EVENT_IRQ_BASE + j + (level << 5);
+ return irq;
+ }
+ }
+
+ /* Not reached */
+ return irq;
+}
+
+void systemasic_irq_init(void)
+{
+ int irq_base, i;
+
+ irq_base = irq_alloc_descs(HW_EVENT_IRQ_BASE, HW_EVENT_IRQ_BASE,
+ HW_EVENT_IRQ_MAX - HW_EVENT_IRQ_BASE, -1);
+ if (IS_ERR_VALUE(irq_base)) {
+ pr_err("%s: failed hooking irqs\n", __func__);
+ return;
+ }
+
+ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
+ irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq);
+}
diff --git a/arch/sh/boards/mach-dreamcast/rtc.c b/arch/sh/boards/mach-dreamcast/rtc.c
new file mode 100644
index 000000000..7873cd27e
--- /dev/null
+++ b/arch/sh/boards/mach-dreamcast/rtc.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/dreamcast/rtc.c
+ *
+ * Dreamcast AICA RTC routines.
+ *
+ * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
+ * Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
+ */
+
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
+ seconds) to get the standard Unix Epoch when getting the time, and add
+ 20 years when setting the time. */
+#define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
+
+/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
+ registers.*/
+#define AICA_RTC_SECS_H 0xa0710000
+#define AICA_RTC_SECS_L 0xa0710004
+
+/**
+ * aica_rtc_gettimeofday - Get the time from the AICA RTC
+ * @dev: the RTC device (ignored)
+ * @tm: pointer to resulting RTC time structure
+ *
+ * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
+ */
+static int aica_rtc_gettimeofday(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long val1, val2;
+ time64_t t;
+
+ do {
+ val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
+
+ val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
+ } while (val1 != val2);
+
+ /* normalize to 1970..2106 time range */
+ t = (u32)(val1 - TWENTY_YEARS);
+
+ rtc_time64_to_tm(t, tm);
+
+ return 0;
+}
+
+/**
+ * aica_rtc_settimeofday - Set the AICA RTC to the current time
+ * @dev: the RTC device (ignored)
+ * @tm: pointer to new RTC time structure
+ *
+ * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
+ */
+static int aica_rtc_settimeofday(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long val1, val2;
+ time64_t secs = rtc_tm_to_time64(tm);
+ u32 adj = secs + TWENTY_YEARS;
+
+ do {
+ __raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
+ __raw_writel((adj & 0xffff), AICA_RTC_SECS_L);
+
+ val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
+
+ val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+ (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
+ } while (val1 != val2);
+
+ return 0;
+}
+
+static const struct rtc_class_ops rtc_generic_ops = {
+ .read_time = aica_rtc_gettimeofday,
+ .set_time = aica_rtc_settimeofday,
+};
+
+static int __init aica_time_init(void)
+{
+ struct platform_device *pdev;
+
+ pdev = platform_device_register_data(NULL, "rtc-generic", -1,
+ &rtc_generic_ops,
+ sizeof(rtc_generic_ops));
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+arch_initcall(aica_time_init);
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
new file mode 100644
index 000000000..2d966c1c2
--- /dev/null
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/dreamcast/setup.c
+ *
+ * Hardware support for the Sega Dreamcast.
+ *
+ * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@linuxdc.org>
+ * Copyright (c) 2002, 2003, 2004 Paul Mundt <lethal@linux-sh.org>
+ *
+ * This file is part of the LinuxDC project (www.linuxdc.org)
+ *
+ * This file originally bore the message (with enclosed-$):
+ * Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
+ * SEGA Dreamcast support
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/rtc.h>
+#include <asm/machvec.h>
+#include <mach/sysasic.h>
+
+static void __init dreamcast_setup(char **cmdline_p)
+{
+}
+
+static struct sh_machine_vector mv_dreamcast __initmv = {
+ .mv_name = "Sega Dreamcast",
+ .mv_setup = dreamcast_setup,
+ .mv_irq_demux = systemasic_irq_demux,
+ .mv_init_irq = systemasic_irq_init,
+};
diff --git a/arch/sh/boards/mach-ecovec24/Makefile b/arch/sh/boards/mach-ecovec24/Makefile
new file mode 100644
index 000000000..d78d4904d
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the R0P7724LC0011/21RL (EcoVec)
+#
+# 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.
+#
+
+obj-y := setup.o sdram.o
diff --git a/arch/sh/boards/mach-ecovec24/sdram.S b/arch/sh/boards/mach-ecovec24/sdram.S
new file mode 100644
index 000000000..d2f269169
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/sdram.S
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Ecovec24 sdram self/auto-refresh setup code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+ .balign 4
+ENTRY(ecovec24_sdram_enter_start)
+
+ /* DBSC: put memory in self-refresh mode */
+
+ ED 0xFD000010, 0x00000000 /* DBEN */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ENTRY(ecovec24_sdram_enter_end)
+
+ .balign 4
+ENTRY(ecovec24_sdram_leave_start)
+
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_RSTANDBY, r0
+ bf resume_rstandby
+
+ /* DBSC: put memory in auto-refresh mode */
+
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ WAIT 1
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+resume_rstandby:
+
+ /* DBSC: re-initialize and put in auto-refresh */
+
+ ED 0xFD000108, 0x00000181 /* DBPDCNT0 */
+ ED 0xFD000020, 0x015B0002 /* DBCONF */
+ ED 0xFD000030, 0x03071502 /* DBTR0 */
+ ED 0xFD000034, 0x02020102 /* DBTR1 */
+ ED 0xFD000038, 0x01090405 /* DBTR2 */
+ ED 0xFD00003C, 0x00000002 /* DBTR3 */
+ ED 0xFD000008, 0x00000005 /* DBKIND */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000018, 0x00000001 /* DBCKECNT */
+
+ mov #100,r0
+WAIT_400NS:
+ dt r0
+ bf WAIT_400NS
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */
+ ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */
+ ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */
+ ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */
+
+ mov #100,r0
+WAIT_400NS_2:
+ dt r0
+ bf WAIT_400NS_2
+
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000044, 0x0000050f /* DBRFPDN1 */
+ ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */
+
+ mov.l DUMMY,r0
+ mov.l @r0, r1 /* force single dummy read */
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000108, 0x00000080 /* DBPDCNT0 */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ .balign 4
+DUMMY: .long 0xac400000
+
+ENTRY(ecovec24_sdram_leave_end)
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
new file mode 100644
index 000000000..7ec03d4a4
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -0,0 +1,1519 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ */
+#include <asm/clock.h>
+#include <asm/heartbeat.h>
+#include <asm/suspend.h>
+#include <cpu/sh7724.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/interrupt.h>
+#include <linux/memblock.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_data/sh_mmcif.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/platform_data/gpio_backlight.h>
+#include <linux/platform_data/tsc2007.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/sh_eth.h>
+#include <linux/sh_intc.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/spi/sh_msiof.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/usb/renesas_usbhs.h>
+#include <linux/videodev2.h>
+#include <linux/dma-map-ops.h>
+
+#include <media/drv-intf/renesas-ceu.h>
+#include <media/i2c/mt9t112.h>
+#include <media/i2c/tw9910.h>
+
+#include <sound/sh_fsi.h>
+#include <sound/simple_card.h>
+
+#include <video/sh_mobile_lcdc.h>
+
+/*
+ * Address Interface BusWidth
+ *-----------------------------------------
+ * 0x0000_0000 uboot 16bit
+ * 0x0004_0000 Linux romImage 16bit
+ * 0x0014_0000 MTD for Linux 16bit
+ * 0x0400_0000 Internal I/O 16/32bit
+ * 0x0800_0000 DRAM 32bit
+ * 0x1800_0000 MFI 16bit
+ */
+
+/* SWITCH
+ *------------------------------
+ * DS2[1] = FlashROM write protect ON : write protect
+ * OFF : No write protect
+ * DS2[2] = RMII / TS, SCIF ON : RMII
+ * OFF : TS, SCIF3
+ * DS2[3] = Camera / Video ON : Camera
+ * OFF : NTSC/PAL (IN)
+ * DS2[5] = NTSC_OUT Clock ON : On board OSC
+ * OFF : SH7724 DV_CLK
+ * DS2[6-7] = MMC / SD ON-OFF : SD
+ * OFF-ON : MMC
+ */
+
+/*
+ * FSI - DA7210
+ *
+ * it needs amixer settings for playing
+ *
+ * amixer set 'HeadPhone' 80
+ * amixer set 'Out Mixer Left DAC Left' on
+ * amixer set 'Out Mixer Right DAC Right' on
+ */
+
+#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
+static phys_addr_t ceu0_dma_membase;
+static phys_addr_t ceu1_dma_membase;
+
+/* Heartbeat */
+static unsigned char led_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+ .nr_bits = 4,
+ .bit_pos = led_pos,
+};
+
+static struct resource heartbeat_resource = {
+ .start = 0xA405012C, /* PTG */
+ .end = 0xA405012E - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "boot loader",
+ .offset = 0,
+ .size = (5 * 1024 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "free-area",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = nor_flash_resources,
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+};
+
+/* SH Eth */
+#define SH_ETH_ADDR (0xA4600000)
+static struct resource sh_eth_resources[] = {
+ [0] = {
+ .start = SH_ETH_ADDR,
+ .end = SH_ETH_ADDR + 0x1FC,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xd60),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct sh_eth_plat_data sh_eth_plat = {
+ .phy = 0x1f, /* SMSC LAN8700 */
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .ether_link_active_low = 1
+};
+
+static struct platform_device sh_eth_device = {
+ .name = "sh7724-ether",
+ .id = 0,
+ .dev = {
+ .platform_data = &sh_eth_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_eth_resources),
+ .resource = sh_eth_resources,
+};
+
+/* USB0 host */
+static void usb0_port_power(int port, int power)
+{
+ gpio_set_value(GPIO_PTB4, power);
+}
+
+static struct r8a66597_platdata usb0_host_data = {
+ .on_chip = 1,
+ .port_power = usb0_port_power,
+};
+
+static struct resource usb0_host_resources[] = {
+ [0] = {
+ .start = 0xa4d80000,
+ .end = 0xa4d80124 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa20),
+ .end = evt2irq(0xa20),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device usb0_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb0_host_data,
+ },
+ .num_resources = ARRAY_SIZE(usb0_host_resources),
+ .resource = usb0_host_resources,
+};
+
+/* USB1 host/function */
+static void usb1_port_power(int port, int power)
+{
+ gpio_set_value(GPIO_PTB5, power);
+}
+
+static struct r8a66597_platdata usb1_common_data = {
+ .on_chip = 1,
+ .port_power = usb1_port_power,
+};
+
+static struct resource usb1_common_resources[] = {
+ [0] = {
+ .start = 0xa4d90000,
+ .end = 0xa4d90124 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa40),
+ .end = evt2irq(0xa40),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device usb1_common_device = {
+ /* .name will be added in arch_setup */
+ .id = 1,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb1_common_data,
+ },
+ .num_resources = ARRAY_SIZE(usb1_common_resources),
+ .resource = usb1_common_resources,
+};
+
+/*
+ * USBHS
+ */
+static int usbhs_get_id(struct platform_device *pdev)
+{
+ return gpio_get_value(GPIO_PTB3);
+}
+
+static int usbhs_phy_reset(struct platform_device *pdev)
+{
+ /* enable vbus if HOST */
+ if (!gpio_get_value(GPIO_PTB3))
+ gpio_set_value(GPIO_PTB5, 1);
+
+ return 0;
+}
+
+static struct renesas_usbhs_platform_info usbhs_info = {
+ .platform_callback = {
+ .get_id = usbhs_get_id,
+ .phy_reset = usbhs_phy_reset,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ .detection_delay = 5,
+ .d0_tx_id = SHDMA_SLAVE_USB1D0_TX,
+ .d0_rx_id = SHDMA_SLAVE_USB1D0_RX,
+ .d1_tx_id = SHDMA_SLAVE_USB1D1_TX,
+ .d1_rx_id = SHDMA_SLAVE_USB1D1_RX,
+ },
+};
+
+static struct resource usbhs_resources[] = {
+ [0] = {
+ .start = 0xa4d90000,
+ .end = 0xa4d90124 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa40),
+ .end = evt2irq(0xa40),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhs_device = {
+ .name = "renesas_usbhs",
+ .id = 1,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usbhs_info,
+ },
+ .num_resources = ARRAY_SIZE(usbhs_resources),
+ .resource = usbhs_resources,
+};
+
+/* LCDC and backlight */
+static const struct fb_videomode ecovec_lcd_modes[] = {
+ {
+ .name = "Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0, /* hsync and vsync are active low */
+ },
+};
+
+static const struct fb_videomode ecovec_dvi_modes[] = {
+ {
+ .name = "DVI",
+ .xres = 1280,
+ .yres = 720,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0, /* hsync and vsync are active low */
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .ch[0] = {
+ .interface_type = RGB18,
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .panel_cfg = { /* 7.0 inch */
+ .width = 152,
+ .height = 91,
+ },
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000,
+ .end = 0xfe942fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xf40),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ },
+};
+
+static struct gpiod_lookup_table gpio_backlight_lookup = {
+ .dev_id = "gpio-backlight.0",
+ .table = {
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTR1, NULL, GPIO_ACTIVE_HIGH),
+ { }
+ },
+};
+
+static struct property_entry gpio_backlight_props[] = {
+ PROPERTY_ENTRY_BOOL("default-on"),
+ { }
+};
+
+static struct gpio_backlight_platform_data gpio_backlight_data = {
+ .fbdev = &lcdc_device.dev,
+};
+
+static const struct platform_device_info gpio_backlight_device_info = {
+ .name = "gpio-backlight",
+ .data = &gpio_backlight_data,
+ .size_data = sizeof(gpio_backlight_data),
+ .properties = gpio_backlight_props,
+};
+
+static struct platform_device *gpio_backlight_device;
+
+/* CEU0 */
+static struct ceu_platform_data ceu0_pdata = {
+ .num_subdevs = 2,
+ .subdevs = {
+ { /* [0] = mt9t112 */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 0,
+ .i2c_address = 0x3c,
+ },
+ { /* [1] = tw9910 */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 0,
+ .i2c_address = 0x45,
+ },
+ },
+};
+
+static struct resource ceu0_resources[] = {
+ [0] = {
+ .name = "CEU0",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ceu0_device = {
+ .name = "renesas-ceu",
+ .id = 0, /* ceu.0 */
+ .num_resources = ARRAY_SIZE(ceu0_resources),
+ .resource = ceu0_resources,
+ .dev = {
+ .platform_data = &ceu0_pdata,
+ },
+};
+
+/* CEU1 */
+static struct ceu_platform_data ceu1_pdata = {
+ .num_subdevs = 1,
+ .subdevs = {
+ { /* [0] = mt9t112 */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 1,
+ .i2c_address = 0x3c,
+ },
+ },
+};
+
+static struct resource ceu1_resources[] = {
+ [0] = {
+ .name = "CEU1",
+ .start = 0xfe914000,
+ .end = 0xfe91409f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x9e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ceu1_device = {
+ .name = "renesas-ceu",
+ .id = 1, /* ceu.1 */
+ .num_resources = ARRAY_SIZE(ceu1_resources),
+ .resource = ceu1_resources,
+ .dev = {
+ .platform_data = &ceu1_pdata,
+ },
+};
+
+/* Power up/down GPIOs for camera devices and video decoder */
+static struct gpiod_lookup_table tw9910_gpios = {
+ .dev_id = "0-0045",
+ .table = {
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTU2, "pdn", GPIO_ACTIVE_HIGH),
+ },
+};
+
+static struct gpiod_lookup_table mt9t112_0_gpios = {
+ .dev_id = "0-003c",
+ .table = {
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTA3, "standby",
+ GPIO_ACTIVE_HIGH),
+ },
+};
+
+static struct gpiod_lookup_table mt9t112_1_gpios = {
+ .dev_id = "1-003c",
+ .table = {
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTA4, "standby",
+ GPIO_ACTIVE_HIGH),
+ },
+};
+
+/* I2C device */
+static struct tw9910_video_info tw9910_info = {
+ .buswidth = 8,
+ .mpout = TW9910_MPO_FIELD,
+};
+
+static struct mt9t112_platform_data mt9t112_0_pdata = {
+ .flags = MT9T112_FLAG_PCLK_RISING_EDGE,
+ .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */
+};
+
+static struct mt9t112_platform_data mt9t112_1_pdata = {
+ .flags = MT9T112_FLAG_PCLK_RISING_EDGE,
+ .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */
+};
+
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("da7210", 0x1a),
+ },
+ {
+ I2C_BOARD_INFO("tw9910", 0x45),
+ .platform_data = &tw9910_info,
+ },
+ {
+ /* 1st camera */
+ I2C_BOARD_INFO("mt9t112", 0x3c),
+ .platform_data = &mt9t112_0_pdata,
+ },
+};
+
+static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ },
+ {
+ I2C_BOARD_INFO("lis3lv02d", 0x1c),
+ .irq = evt2irq(0x620),
+ },
+ {
+ /* 2nd camera */
+ I2C_BOARD_INFO("mt9t112", 0x3c),
+ .platform_data = &mt9t112_1_pdata,
+ },
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_1,
+ .scan_timing = 3,
+ .delay = 50,
+ .kycr2_delay = 100,
+ .keycodes = { KEY_1, 0, 0, 0, 0,
+ KEY_2, 0, 0, 0, 0,
+ KEY_3, 0, 0, 0, 0,
+ KEY_4, 0, 0, 0, 0,
+ KEY_5, 0, 0, 0, 0,
+ KEY_6, 0, 0, 0, 0, },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0x044b0000,
+ .end = 0x044b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xbe0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* keysc0 clock */
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+/* TouchScreen */
+#define IRQ0 evt2irq(0x600)
+
+static int ts_get_pendown_state(struct device *dev)
+{
+ int val = 0;
+ gpio_free(GPIO_FN_INTC_IRQ0);
+ gpio_request(GPIO_PTZ0, NULL);
+ gpio_direction_input(GPIO_PTZ0);
+
+ val = gpio_get_value(GPIO_PTZ0);
+
+ gpio_free(GPIO_PTZ0);
+ gpio_request(GPIO_FN_INTC_IRQ0, NULL);
+
+ return val ? 0 : 1;
+}
+
+static int ts_init(void)
+{
+ gpio_request(GPIO_FN_INTC_IRQ0, NULL);
+ return 0;
+}
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = ts_get_pendown_state,
+ .init_platform_hw = ts_init,
+};
+
+static struct i2c_board_info ts_i2c_clients = {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = IRQ0,
+};
+
+static struct regulator_consumer_supply cn12_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+};
+
+static struct regulator_init_data cn12_power_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cn12_power_consumers),
+ .consumer_supplies = cn12_power_consumers,
+};
+
+static struct fixed_voltage_config cn12_power_info = {
+ .supply_name = "CN12 SD/MMC Vdd",
+ .microvolts = 3300000,
+ .init_data = &cn12_power_init_data,
+};
+
+static struct platform_device cn12_power = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &cn12_power_info,
+ },
+};
+
+static struct gpiod_lookup_table cn12_power_gpiod_table = {
+ .dev_id = "reg-fixed-voltage.0",
+ .table = {
+ /* Offset 7 on port B */
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTB7,
+ NULL, GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+/* SDHI0 */
+static struct regulator_consumer_supply sdhi0_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_init_data sdhi0_power_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdhi0_power_consumers),
+ .consumer_supplies = sdhi0_power_consumers,
+};
+
+static struct fixed_voltage_config sdhi0_power_info = {
+ .supply_name = "CN11 SD/MMC Vdd",
+ .microvolts = 3300000,
+ .init_data = &sdhi0_power_init_data,
+};
+
+static struct platform_device sdhi0_power = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi0_power_info,
+ },
+};
+
+static struct gpiod_lookup_table sdhi0_power_gpiod_table = {
+ .dev_id = "reg-fixed-voltage.1",
+ .table = {
+ /* Offset 6 on port B */
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTB6,
+ NULL, GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table sdhi0_gpio_table = {
+ .dev_id = "sh_mobile_sdhi.0",
+ .table = {
+ /* Card detect */
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTY7, "cd", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct tmio_mmc_data sdhi0_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX,
+ .capabilities = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
+ MMC_CAP_NEEDS_POLL,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0x04ce0000,
+ .end = 0x04ce00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xe80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+/* SDHI1 */
+static struct tmio_mmc_data sdhi1_info = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI1_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI1_RX,
+ .capabilities = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
+ MMC_CAP_NEEDS_POLL,
+};
+
+static struct gpiod_lookup_table sdhi1_gpio_table = {
+ .dev_id = "sh_mobile_sdhi.1",
+ .table = {
+ /* Card detect */
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTW7, "cd", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0x04cf0000,
+ .end = 0x04cf00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x4e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+};
+#endif /* CONFIG_MMC_SH_MMCIF */
+
+#else
+
+/* MMC SPI */
+static void mmc_spi_setpower(struct device *dev, unsigned int maskval)
+{
+ gpio_set_value(GPIO_PTB6, maskval ? 1 : 0);
+}
+
+static struct mmc_spi_platform_data mmc_spi_info = {
+ .caps = MMC_CAP_NEEDS_POLL,
+ .caps2 = MMC_CAP2_RO_ACTIVE_HIGH,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */
+ .setpower = mmc_spi_setpower,
+};
+
+static struct gpiod_lookup_table mmc_spi_gpio_table = {
+ .dev_id = "mmc_spi.0", /* device "mmc_spi" @ CS0 */
+ .table = {
+ /* Card detect */
+ GPIO_LOOKUP_IDX("sh7724_pfc", GPIO_PTY7, NULL, 0,
+ GPIO_ACTIVE_LOW),
+ /* Write protect */
+ GPIO_LOOKUP_IDX("sh7724_pfc", GPIO_PTY6, NULL, 1,
+ GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static struct spi_board_info spi_bus[] = {
+ {
+ .modalias = "mmc_spi",
+ .platform_data = &mmc_spi_info,
+ .max_speed_hz = 5000000,
+ .mode = SPI_MODE_0,
+ },
+};
+
+/* MSIOF0 */
+static struct sh_msiof_spi_info msiof0_data = {
+ .num_chipselect = 1,
+};
+
+static struct resource msiof0_resources[] = {
+ [0] = {
+ .name = "MSIOF0",
+ .start = 0xa4c40000,
+ .end = 0xa4c40063,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xc80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device msiof0_device = {
+ .name = "spi_sh_msiof",
+ .id = 0, /* MSIOF0 */
+ .dev = {
+ .platform_data = &msiof0_data,
+ },
+ .num_resources = ARRAY_SIZE(msiof0_resources),
+ .resource = msiof0_resources,
+};
+
+static struct gpiod_lookup_table msiof_gpio_table = {
+ .dev_id = "spi_sh_msiof.0",
+ .table = {
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTM4, "cs", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+#endif
+
+/* FSI */
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xFE3C0000,
+ .end = 0xFE3C021d,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xf80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+};
+
+static struct asoc_simple_card_info fsi_da7210_info = {
+ .name = "DA7210",
+ .card = "FSIB-DA7210",
+ .codec = "da7210.0-001a",
+ .platform = "sh_fsi.0",
+ .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBP_CFP,
+ .cpu_dai = {
+ .name = "fsib-dai",
+ },
+ .codec_dai = {
+ .name = "da7210-hifi",
+ },
+};
+
+static struct platform_device fsi_da7210_device = {
+ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi_da7210_info,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &fsi_da7210_device.dev.coherent_dma_mask,
+ },
+};
+
+
+/* IrDA */
+static struct resource irda_resources[] = {
+ [0] = {
+ .name = "IrDA",
+ .start = 0xA45D0000,
+ .end = 0xA45D0049,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x480),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_sir",
+ .num_resources = ARRAY_SIZE(irda_resources),
+ .resource = irda_resources,
+};
+
+#include <media/i2c/ak881x.h>
+#include <media/drv-intf/sh_vou.h>
+
+static struct ak881x_pdata ak881x_pdata = {
+ .flags = AK881X_IF_MODE_SLAVE,
+};
+
+static struct i2c_board_info ak8813 = {
+ I2C_BOARD_INFO("ak8813", 0x20),
+ .platform_data = &ak881x_pdata,
+};
+
+static struct sh_vou_pdata sh_vou_pdata = {
+ .bus_fmt = SH_VOU_BUS_8BIT,
+ .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
+ .board_info = &ak8813,
+ .i2c_adap = 0,
+};
+
+static struct resource sh_vou_resources[] = {
+ [0] = {
+ .start = 0xfe960000,
+ .end = 0xfe962043,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x8e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device vou_device = {
+ .name = "sh-vou",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sh_vou_resources),
+ .resource = sh_vou_resources,
+ .dev = {
+ .platform_data = &sh_vou_pdata,
+ },
+};
+
+#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
+/* SH_MMCIF */
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "SH_MMCIF",
+ .start = 0xA4CA0000,
+ .end = 0xA4CA00FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* MMC2I */
+ .start = evt2irq(0x5a0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* MMC3I */
+ .start = evt2irq(0x5c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+ .sup_pclk = 0, /* SH7724: Max Pclk/2 */
+ .caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NEEDS_POLL,
+ .ocr = MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+static struct platform_device sh_mmcif_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .platform_data = &sh_mmcif_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+#endif
+
+static struct platform_device *ecovec_ceu_devices[] __initdata = {
+ &ceu0_device,
+ &ceu1_device,
+};
+
+static struct platform_device *ecovec_devices[] __initdata = {
+ &heartbeat_device,
+ &nor_flash_device,
+ &sh_eth_device,
+ &usb0_host_device,
+ &usb1_common_device,
+ &usbhs_device,
+ &lcdc_device,
+ &keysc_device,
+ &cn12_power,
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+ &sdhi0_power,
+ &sdhi0_device,
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ &sdhi1_device,
+#endif
+#else
+ &msiof0_device,
+#endif
+ &fsi_device,
+ &fsi_da7210_device,
+ &irda_device,
+ &vou_device,
+#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ &sh_mmcif_device,
+#endif
+};
+
+#ifdef CONFIG_I2C
+#define EEPROM_ADDR 0x50
+static u8 mac_read(struct i2c_adapter *a, u8 command)
+{
+ struct i2c_msg msg[2];
+ u8 buf;
+ int ret;
+
+ msg[0].addr = EEPROM_ADDR;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = &command;
+
+ msg[1].addr = EEPROM_ADDR;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 1;
+ msg[1].buf = &buf;
+
+ ret = i2c_transfer(a, msg, 2);
+ if (ret < 0) {
+ printk(KERN_ERR "error %d\n", ret);
+ buf = 0xff;
+ }
+
+ return buf;
+}
+
+static void __init sh_eth_init(struct sh_eth_plat_data *pd)
+{
+ struct i2c_adapter *a = i2c_get_adapter(1);
+ int i;
+
+ if (!a) {
+ pr_err("can not get I2C 1\n");
+ return;
+ }
+
+ /* read MAC address from EEPROM */
+ for (i = 0; i < sizeof(pd->mac_addr); i++) {
+ pd->mac_addr[i] = mac_read(a, 0x10 + i);
+ msleep(10);
+ }
+
+ i2c_put_adapter(a);
+}
+#else
+static void __init sh_eth_init(struct sh_eth_plat_data *pd)
+{
+ pr_err("unable to read sh_eth MAC address\n");
+}
+#endif
+
+#define PORT_HIZA 0xA4050158
+#define IODRIVEA 0xA405018A
+
+extern char ecovec24_sdram_enter_start;
+extern char ecovec24_sdram_enter_end;
+extern char ecovec24_sdram_leave_start;
+extern char ecovec24_sdram_leave_end;
+
+static int __init arch_setup(void)
+{
+ struct clk *clk;
+ bool cn12_enabled = false;
+
+ /* register board specific self-refresh code */
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+ SUSP_SH_RSTANDBY,
+ &ecovec24_sdram_enter_start,
+ &ecovec24_sdram_enter_end,
+ &ecovec24_sdram_leave_start,
+ &ecovec24_sdram_leave_end);
+
+ /* enable STATUS0, STATUS2 and PDSTATUS */
+ gpio_request(GPIO_FN_STATUS0, NULL);
+ gpio_request(GPIO_FN_STATUS2, NULL);
+ gpio_request(GPIO_FN_PDSTATUS, NULL);
+
+ /* enable SCIFA0 */
+ gpio_request(GPIO_FN_SCIF0_TXD, NULL);
+ gpio_request(GPIO_FN_SCIF0_RXD, NULL);
+
+ /* enable debug LED */
+ gpio_request(GPIO_PTG0, NULL);
+ gpio_request(GPIO_PTG1, NULL);
+ gpio_request(GPIO_PTG2, NULL);
+ gpio_request(GPIO_PTG3, NULL);
+ gpio_direction_output(GPIO_PTG0, 0);
+ gpio_direction_output(GPIO_PTG1, 0);
+ gpio_direction_output(GPIO_PTG2, 0);
+ gpio_direction_output(GPIO_PTG3, 0);
+ __raw_writew((__raw_readw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
+
+ /* enable SH-Eth */
+ gpio_request(GPIO_PTA1, NULL);
+ gpio_direction_output(GPIO_PTA1, 1);
+ mdelay(20);
+
+ gpio_request(GPIO_FN_RMII_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
+ gpio_request(GPIO_FN_RMII_TX_EN, NULL);
+ gpio_request(GPIO_FN_RMII_RX_ER, NULL);
+ gpio_request(GPIO_FN_RMII_CRS_DV, NULL);
+ gpio_request(GPIO_FN_MDIO, NULL);
+ gpio_request(GPIO_FN_MDC, NULL);
+ gpio_request(GPIO_FN_LNKSTA, NULL);
+
+ /* enable USB */
+ __raw_writew(0x0000, 0xA4D80000);
+ __raw_writew(0x0000, 0xA4D90000);
+ gpio_request(GPIO_PTB3, NULL);
+ gpio_request(GPIO_PTB4, NULL);
+ gpio_request(GPIO_PTB5, NULL);
+ gpio_direction_input(GPIO_PTB3);
+ gpio_direction_output(GPIO_PTB4, 0);
+ gpio_direction_output(GPIO_PTB5, 0);
+ __raw_writew(0x0600, 0xa40501d4);
+ __raw_writew(0x0600, 0xa4050192);
+
+ if (gpio_get_value(GPIO_PTB3)) {
+ printk(KERN_INFO "USB1 function is selected\n");
+ usb1_common_device.name = "r8a66597_udc";
+ } else {
+ printk(KERN_INFO "USB1 host is selected\n");
+ usb1_common_device.name = "r8a66597_hcd";
+ }
+
+ /* enable LCDC */
+ gpio_request(GPIO_FN_LCDD23, NULL);
+ gpio_request(GPIO_FN_LCDD22, NULL);
+ gpio_request(GPIO_FN_LCDD21, NULL);
+ gpio_request(GPIO_FN_LCDD20, NULL);
+ gpio_request(GPIO_FN_LCDD19, NULL);
+ gpio_request(GPIO_FN_LCDD18, NULL);
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDHSYN, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+ gpio_request(GPIO_FN_LCDVSYN, NULL);
+ gpio_request(GPIO_FN_LCDDON, NULL);
+ gpio_request(GPIO_FN_LCDLCLK, NULL);
+ __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+
+ gpio_request(GPIO_PTE6, NULL);
+ gpio_request(GPIO_PTU1, NULL);
+ gpio_request(GPIO_PTA2, NULL);
+ gpio_direction_input(GPIO_PTE6);
+ gpio_direction_output(GPIO_PTU1, 0);
+ gpio_direction_output(GPIO_PTA2, 0);
+
+ /* I/O buffer drive ability is high */
+ __raw_writew((__raw_readw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA);
+
+ if (gpio_get_value(GPIO_PTE6)) {
+ /* DVI */
+ lcdc_info.clock_source = LCDC_CLK_EXTERNAL;
+ lcdc_info.ch[0].clock_divider = 1;
+ lcdc_info.ch[0].lcd_modes = ecovec_dvi_modes;
+ lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_dvi_modes);
+
+ /* No backlight */
+ gpio_backlight_data.fbdev = NULL;
+
+ gpio_set_value(GPIO_PTA2, 1);
+ gpio_set_value(GPIO_PTU1, 1);
+ } else {
+ /* Panel */
+ lcdc_info.clock_source = LCDC_CLK_PERIPHERAL;
+ lcdc_info.ch[0].clock_divider = 2;
+ lcdc_info.ch[0].lcd_modes = ecovec_lcd_modes;
+ lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_lcd_modes);
+
+ /* FIXME
+ *
+ * LCDDON control is needed for Panel,
+ * but current sh_mobile_lcdc driver doesn't control it.
+ * It is temporary correspondence
+ */
+ gpio_request(GPIO_PTF4, NULL);
+ gpio_direction_output(GPIO_PTF4, 1);
+
+ /* enable TouchScreen */
+ i2c_register_board_info(0, &ts_i2c_clients, 1);
+ irq_set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
+ }
+
+ /* enable CEU0 */
+ gpio_request(GPIO_FN_VIO0_D15, NULL);
+ gpio_request(GPIO_FN_VIO0_D14, NULL);
+ gpio_request(GPIO_FN_VIO0_D13, NULL);
+ gpio_request(GPIO_FN_VIO0_D12, NULL);
+ gpio_request(GPIO_FN_VIO0_D11, NULL);
+ gpio_request(GPIO_FN_VIO0_D10, NULL);
+ gpio_request(GPIO_FN_VIO0_D9, NULL);
+ gpio_request(GPIO_FN_VIO0_D8, NULL);
+ gpio_request(GPIO_FN_VIO0_D7, NULL);
+ gpio_request(GPIO_FN_VIO0_D6, NULL);
+ gpio_request(GPIO_FN_VIO0_D5, NULL);
+ gpio_request(GPIO_FN_VIO0_D4, NULL);
+ gpio_request(GPIO_FN_VIO0_D3, NULL);
+ gpio_request(GPIO_FN_VIO0_D2, NULL);
+ gpio_request(GPIO_FN_VIO0_D1, NULL);
+ gpio_request(GPIO_FN_VIO0_D0, NULL);
+ gpio_request(GPIO_FN_VIO0_VD, NULL);
+ gpio_request(GPIO_FN_VIO0_CLK, NULL);
+ gpio_request(GPIO_FN_VIO0_FLD, NULL);
+ gpio_request(GPIO_FN_VIO0_HD, NULL);
+
+ /* enable CEU1 */
+ gpio_request(GPIO_FN_VIO1_D7, NULL);
+ gpio_request(GPIO_FN_VIO1_D6, NULL);
+ gpio_request(GPIO_FN_VIO1_D5, NULL);
+ gpio_request(GPIO_FN_VIO1_D4, NULL);
+ gpio_request(GPIO_FN_VIO1_D3, NULL);
+ gpio_request(GPIO_FN_VIO1_D2, NULL);
+ gpio_request(GPIO_FN_VIO1_D1, NULL);
+ gpio_request(GPIO_FN_VIO1_D0, NULL);
+ gpio_request(GPIO_FN_VIO1_FLD, NULL);
+ gpio_request(GPIO_FN_VIO1_HD, NULL);
+ gpio_request(GPIO_FN_VIO1_VD, NULL);
+ gpio_request(GPIO_FN_VIO1_CLK, NULL);
+
+ /* enable KEYSC */
+ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+ gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYIN0, NULL);
+
+ /* enable user debug switch */
+ gpio_request(GPIO_PTR0, NULL);
+ gpio_request(GPIO_PTR4, NULL);
+ gpio_request(GPIO_PTR5, NULL);
+ gpio_request(GPIO_PTR6, NULL);
+ gpio_direction_input(GPIO_PTR0);
+ gpio_direction_input(GPIO_PTR4);
+ gpio_direction_input(GPIO_PTR5);
+ gpio_direction_input(GPIO_PTR6);
+
+ /* SD-card slot CN11 */
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+ /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
+ gpio_request(GPIO_FN_SDHI0WP, NULL);
+ gpio_request(GPIO_FN_SDHI0CMD, NULL);
+ gpio_request(GPIO_FN_SDHI0CLK, NULL);
+ gpio_request(GPIO_FN_SDHI0D3, NULL);
+ gpio_request(GPIO_FN_SDHI0D2, NULL);
+ gpio_request(GPIO_FN_SDHI0D1, NULL);
+ gpio_request(GPIO_FN_SDHI0D0, NULL);
+#else
+ /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */
+ gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
+ gpio_request(GPIO_FN_MSIOF0_RXD, NULL);
+ gpio_request(GPIO_FN_MSIOF0_TSCK, NULL);
+ gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */
+ gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */
+
+ gpiod_add_lookup_table(&mmc_spi_gpio_table);
+ gpiod_add_lookup_table(&msiof_gpio_table);
+ spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
+#endif
+
+ /* MMC/SD-card slot CN12 */
+#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */
+ gpio_request(GPIO_FN_MMC_D7, NULL);
+ gpio_request(GPIO_FN_MMC_D6, NULL);
+ gpio_request(GPIO_FN_MMC_D5, NULL);
+ gpio_request(GPIO_FN_MMC_D4, NULL);
+ gpio_request(GPIO_FN_MMC_D3, NULL);
+ gpio_request(GPIO_FN_MMC_D2, NULL);
+ gpio_request(GPIO_FN_MMC_D1, NULL);
+ gpio_request(GPIO_FN_MMC_D0, NULL);
+ gpio_request(GPIO_FN_MMC_CLK, NULL);
+ gpio_request(GPIO_FN_MMC_CMD, NULL);
+
+ cn12_enabled = true;
+#elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+ /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */
+ gpio_request(GPIO_FN_SDHI1WP, NULL);
+ gpio_request(GPIO_FN_SDHI1CMD, NULL);
+ gpio_request(GPIO_FN_SDHI1CLK, NULL);
+ gpio_request(GPIO_FN_SDHI1D3, NULL);
+ gpio_request(GPIO_FN_SDHI1D2, NULL);
+ gpio_request(GPIO_FN_SDHI1D1, NULL);
+ gpio_request(GPIO_FN_SDHI1D0, NULL);
+
+ cn12_enabled = true;
+#endif
+
+ if (cn12_enabled)
+ /* I/O buffer drive ability is high for CN12 */
+ __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000,
+ IODRIVEA);
+
+ /* enable FSI */
+ gpio_request(GPIO_FN_FSIMCKB, NULL);
+ gpio_request(GPIO_FN_FSIIBSD, NULL);
+ gpio_request(GPIO_FN_FSIOBSD, NULL);
+ gpio_request(GPIO_FN_FSIIBBCK, NULL);
+ gpio_request(GPIO_FN_FSIIBLRCK, NULL);
+ gpio_request(GPIO_FN_FSIOBBCK, NULL);
+ gpio_request(GPIO_FN_FSIOBLRCK, NULL);
+ gpio_request(GPIO_FN_CLKAUDIOBO, NULL);
+
+ /* set SPU2 clock to 83.4 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 83333333));
+ clk_put(clk);
+ }
+
+ /* change parent of FSI B */
+ clk = clk_get(NULL, "fsib_clk");
+ if (!IS_ERR(clk)) {
+ /* 48kHz dummy clock was used to make sure 1/1 divide */
+ clk_set_rate(&sh7724_fsimckb_clk, 48000);
+ clk_set_parent(clk, &sh7724_fsimckb_clk);
+ clk_set_rate(clk, 48000);
+ clk_put(clk);
+ }
+
+ gpio_request(GPIO_PTU0, NULL);
+ gpio_direction_output(GPIO_PTU0, 0);
+ mdelay(20);
+
+ /* enable motion sensor */
+ gpio_request(GPIO_FN_INTC_IRQ1, NULL);
+ gpio_direction_input(GPIO_FN_INTC_IRQ1);
+
+ /* set VPU clock to 166 MHz */
+ clk = clk_get(NULL, "vpu_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 166000000));
+ clk_put(clk);
+ }
+
+ /* enable IrDA */
+ gpio_request(GPIO_FN_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_IRDA_IN, NULL);
+ gpio_request(GPIO_PTU5, NULL);
+ gpio_direction_output(GPIO_PTU5, 0);
+
+ /* Register gpio lookup tables for cameras and video decoder */
+ gpiod_add_lookup_table(&tw9910_gpios);
+ gpiod_add_lookup_table(&mt9t112_0_gpios);
+ gpiod_add_lookup_table(&mt9t112_1_gpios);
+
+ /* enable I2C device */
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+
+ i2c_register_board_info(1, i2c1_devices,
+ ARRAY_SIZE(i2c1_devices));
+
+#if defined(CONFIG_VIDEO_SH_VOU) || defined(CONFIG_VIDEO_SH_VOU_MODULE)
+ /* VOU */
+ gpio_request(GPIO_FN_DV_D15, NULL);
+ gpio_request(GPIO_FN_DV_D14, NULL);
+ gpio_request(GPIO_FN_DV_D13, NULL);
+ gpio_request(GPIO_FN_DV_D12, NULL);
+ gpio_request(GPIO_FN_DV_D11, NULL);
+ gpio_request(GPIO_FN_DV_D10, NULL);
+ gpio_request(GPIO_FN_DV_D9, NULL);
+ gpio_request(GPIO_FN_DV_D8, NULL);
+ gpio_request(GPIO_FN_DV_CLKI, NULL);
+ gpio_request(GPIO_FN_DV_CLK, NULL);
+ gpio_request(GPIO_FN_DV_VSYNC, NULL);
+ gpio_request(GPIO_FN_DV_HSYNC, NULL);
+
+ /* AK8813 power / reset sequence */
+ gpio_request(GPIO_PTG4, NULL);
+ gpio_request(GPIO_PTU3, NULL);
+ /* Reset */
+ gpio_direction_output(GPIO_PTG4, 0);
+ /* Power down */
+ gpio_direction_output(GPIO_PTU3, 1);
+
+ udelay(10);
+
+ /* Power up, reset */
+ gpio_set_value(GPIO_PTU3, 0);
+
+ udelay(10);
+
+ /* Remove reset */
+ gpio_set_value(GPIO_PTG4, 1);
+#endif
+
+ /* Initialize CEU platform devices separately to map memory first */
+ device_initialize(&ecovec_ceu_devices[0]->dev);
+ dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev,
+ ceu0_dma_membase, ceu0_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+ platform_device_add(ecovec_ceu_devices[0]);
+
+ device_initialize(&ecovec_ceu_devices[1]->dev);
+ dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev,
+ ceu1_dma_membase, ceu1_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+ platform_device_add(ecovec_ceu_devices[1]);
+
+ gpiod_add_lookup_table(&cn12_power_gpiod_table);
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+ gpiod_add_lookup_table(&sdhi0_power_gpiod_table);
+ gpiod_add_lookup_table(&sdhi0_gpio_table);
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ gpiod_add_lookup_table(&sdhi1_gpio_table);
+#endif
+#endif
+
+ gpiod_add_lookup_table(&gpio_backlight_lookup);
+ gpio_backlight_device = platform_device_register_full(
+ &gpio_backlight_device_info);
+ if (IS_ERR(gpio_backlight_device))
+ return PTR_ERR(gpio_backlight_device);
+
+ return platform_add_devices(ecovec_devices,
+ ARRAY_SIZE(ecovec_devices));
+}
+arch_initcall(arch_setup);
+
+static int __init devices_setup(void)
+{
+ sh_eth_init(&sh_eth_plat);
+ return 0;
+}
+device_initcall(devices_setup);
+
+/* Reserve a portion of memory for CEU 0 and CEU 1 buffers */
+static void __init ecovec_mv_mem_reserve(void)
+{
+ phys_addr_t phys;
+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU0 memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+ ceu0_dma_membase = phys;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU1 memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+ ceu1_dma_membase = phys;
+}
+
+static struct sh_machine_vector mv_ecovec __initmv = {
+ .mv_name = "R0P7724 (EcoVec)",
+ .mv_mem_reserve = ecovec_mv_mem_reserve,
+};
diff --git a/arch/sh/boards/mach-highlander/Kconfig b/arch/sh/boards/mach-highlander/Kconfig
new file mode 100644
index 000000000..b0abd03ca
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0
+if SH_HIGHLANDER
+
+choice
+ prompt "Highlander options"
+ default SH_R7780MP
+
+config SH_R7780RP
+ bool "R7780RP-1 board support"
+ depends on CPU_SUBTYPE_SH7780
+
+config SH_R7780MP
+ bool "R7780MP board support"
+ depends on CPU_SUBTYPE_SH7780
+ help
+ Selecting this option will enable support for the mass-production
+ version of the R7780RP. If in doubt, say Y.
+
+config SH_R7785RP
+ bool "R7785RP board support"
+ depends on CPU_SUBTYPE_SH7785
+ select GPIOLIB
+
+endchoice
+
+endif
diff --git a/arch/sh/boards/mach-highlander/Makefile b/arch/sh/boards/mach-highlander/Makefile
new file mode 100644
index 000000000..880ed6813
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Highlander specific parts of the kernel
+#
+obj-y := setup.o
+obj-$(CONFIG_SH_R7780RP) += irq-r7780rp.o
+obj-$(CONFIG_SH_R7780MP) += irq-r7780mp.o
+obj-$(CONFIG_SH_R7785RP) += irq-r7785rp.o pinmux-r7785rp.o
+
+ifneq ($(CONFIG_SH_R7785RP),y)
+obj-$(CONFIG_PUSH_SWITCH) += psw.o
+endif
diff --git a/arch/sh/boards/mach-highlander/irq-r7780mp.c b/arch/sh/boards/mach-highlander/irq-r7780mp.c
new file mode 100644
index 000000000..f46637377
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/irq-r7780mp.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Solutions Highlander R7780MP Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2007 Magnus Damm
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/highlander.h>
+
+enum {
+ UNUSED = 0,
+
+ /* board specific interrupt sources */
+ CF, /* Compact Flash */
+ TP, /* Touch panel */
+ SCIF1, /* FPGA SCIF1 */
+ SCIF0, /* FPGA SCIF0 */
+ SMBUS, /* SMBUS */
+ RTC, /* RTC Alarm */
+ AX88796, /* Ethernet controller */
+ PSW, /* Push Switch */
+
+ /* external bus connector */
+ EXT1, EXT2, EXT4, EXT5, EXT6,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_IRQ(CF, IRQ_CF),
+ INTC_IRQ(TP, IRQ_TP),
+ INTC_IRQ(SCIF1, IRQ_SCIF1),
+ INTC_IRQ(SCIF0, IRQ_SCIF0),
+ INTC_IRQ(SMBUS, IRQ_SMBUS),
+ INTC_IRQ(RTC, IRQ_RTC),
+ INTC_IRQ(AX88796, IRQ_AX88796),
+ INTC_IRQ(PSW, IRQ_PSW),
+
+ INTC_IRQ(EXT1, IRQ_EXT1), INTC_IRQ(EXT2, IRQ_EXT2),
+ INTC_IRQ(EXT4, IRQ_EXT4), INTC_IRQ(EXT5, IRQ_EXT5),
+ INTC_IRQ(EXT6, IRQ_EXT6),
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { 0xa4000000, 0, 16, /* IRLMSK */
+ { SCIF0, SCIF1, RTC, 0, CF, 0, TP, SMBUS,
+ 0, EXT6, EXT5, EXT4, EXT2, EXT1, PSW, AX88796 } },
+};
+
+static unsigned char irl2irq[HL_NR_IRL] __initdata = {
+ 0, IRQ_CF, IRQ_TP, IRQ_SCIF1,
+ IRQ_SCIF0, IRQ_SMBUS, IRQ_RTC, IRQ_EXT6,
+ IRQ_EXT5, IRQ_EXT4, IRQ_EXT2, IRQ_EXT1,
+ 0, IRQ_AX88796, IRQ_PSW,
+};
+
+static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors,
+ NULL, mask_registers, NULL, NULL);
+
+unsigned char * __init highlander_plat_irq_setup(void)
+{
+ if ((__raw_readw(0xa4000700) & 0xf000) == 0x2000) {
+ printk(KERN_INFO "Using r7780mp interrupt controller.\n");
+ register_intc_controller(&intc_desc);
+ return irl2irq;
+ }
+
+ return NULL;
+}
diff --git a/arch/sh/boards/mach-highlander/irq-r7780rp.c b/arch/sh/boards/mach-highlander/irq-r7780rp.c
new file mode 100644
index 000000000..c61177e87
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/irq-r7780rp.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Solutions Highlander R7780RP-1 Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2008 Magnus Damm
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/highlander.h>
+
+enum {
+ UNUSED = 0,
+
+ /* board specific interrupt sources */
+
+ AX88796, /* Ethernet controller */
+ PSW, /* Push Switch */
+ CF, /* Compact Flash */
+
+ PCI_A,
+ PCI_B,
+ PCI_C,
+ PCI_D,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_IRQ(PCI_A, 65), /* dirty: overwrite cpu vectors for pci */
+ INTC_IRQ(PCI_B, 66),
+ INTC_IRQ(PCI_C, 67),
+ INTC_IRQ(PCI_D, 68),
+ INTC_IRQ(CF, IRQ_CF),
+ INTC_IRQ(PSW, IRQ_PSW),
+ INTC_IRQ(AX88796, IRQ_AX88796),
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { 0xa5000000, 0, 16, /* IRLMSK */
+ { PCI_A, PCI_B, PCI_C, PCI_D, CF, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, PSW, AX88796 } },
+};
+
+static unsigned char irl2irq[HL_NR_IRL] __initdata = {
+ 65, 66, 67, 68,
+ IRQ_CF, 0, 0, 0,
+ 0, 0, 0, 0,
+ IRQ_AX88796, IRQ_PSW
+};
+
+static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors,
+ NULL, mask_registers, NULL, NULL);
+
+unsigned char * __init highlander_plat_irq_setup(void)
+{
+ if (__raw_readw(0xa5000600)) {
+ printk(KERN_INFO "Using r7780rp interrupt controller.\n");
+ register_intc_controller(&intc_desc);
+ return irl2irq;
+ }
+
+ return NULL;
+}
diff --git a/arch/sh/boards/mach-highlander/irq-r7785rp.c b/arch/sh/boards/mach-highlander/irq-r7785rp.c
new file mode 100644
index 000000000..0ebebbed0
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/irq-r7785rp.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Solutions Highlander R7785RP Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 - 2008 Paul Mundt
+ * Copyright (C) 2007 Magnus Damm
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/highlander.h>
+
+enum {
+ UNUSED = 0,
+
+ /* FPGA specific interrupt sources */
+ CF, /* Compact Flash */
+ SMBUS, /* SMBUS */
+ TP, /* Touch panel */
+ RTC, /* RTC Alarm */
+ TH_ALERT, /* Temperature sensor */
+ AX88796, /* Ethernet controller */
+
+ /* external bus connector */
+ EXT0, EXT1, EXT2, EXT3, EXT4, EXT5, EXT6, EXT7,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_IRQ(CF, IRQ_CF),
+ INTC_IRQ(SMBUS, IRQ_SMBUS),
+ INTC_IRQ(TP, IRQ_TP),
+ INTC_IRQ(RTC, IRQ_RTC),
+ INTC_IRQ(TH_ALERT, IRQ_TH_ALERT),
+
+ INTC_IRQ(EXT0, IRQ_EXT0), INTC_IRQ(EXT1, IRQ_EXT1),
+ INTC_IRQ(EXT2, IRQ_EXT2), INTC_IRQ(EXT3, IRQ_EXT3),
+
+ INTC_IRQ(EXT4, IRQ_EXT4), INTC_IRQ(EXT5, IRQ_EXT5),
+ INTC_IRQ(EXT6, IRQ_EXT6), INTC_IRQ(EXT7, IRQ_EXT7),
+
+ INTC_IRQ(AX88796, IRQ_AX88796),
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { 0xa4000010, 0, 16, /* IRLMCR1 */
+ { 0, 0, 0, 0, CF, AX88796, SMBUS, TP,
+ RTC, 0, TH_ALERT, 0, 0, 0, 0, 0 } },
+ { 0xa4000012, 0, 16, /* IRLMCR2 */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ EXT7, EXT6, EXT5, EXT4, EXT3, EXT2, EXT1, EXT0 } },
+};
+
+static unsigned char irl2irq[HL_NR_IRL] __initdata = {
+ 0, IRQ_CF, IRQ_EXT4, IRQ_EXT5,
+ IRQ_EXT6, IRQ_EXT7, IRQ_SMBUS, IRQ_TP,
+ IRQ_RTC, IRQ_TH_ALERT, IRQ_AX88796, IRQ_EXT0,
+ IRQ_EXT1, IRQ_EXT2, IRQ_EXT3,
+};
+
+static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors,
+ NULL, mask_registers, NULL, NULL);
+
+unsigned char * __init highlander_plat_irq_setup(void)
+{
+ if ((__raw_readw(0xa4000158) & 0xf000) != 0x1000)
+ return NULL;
+
+ printk(KERN_INFO "Using r7785rp interrupt controller.\n");
+
+ __raw_writew(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */
+
+ /* Setup the FPGA IRL */
+ __raw_writew(0x0000, PA_IRLPRA); /* FPGA IRLA */
+ __raw_writew(0xe598, PA_IRLPRB); /* FPGA IRLB */
+ __raw_writew(0x7060, PA_IRLPRC); /* FPGA IRLC */
+ __raw_writew(0x0000, PA_IRLPRD); /* FPGA IRLD */
+ __raw_writew(0x4321, PA_IRLPRE); /* FPGA IRLE */
+ __raw_writew(0xdcba, PA_IRLPRF); /* FPGA IRLF */
+
+ register_intc_controller(&intc_desc);
+ return irl2irq;
+}
diff --git a/arch/sh/boards/mach-highlander/pinmux-r7785rp.c b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c
new file mode 100644
index 000000000..703179faf
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2008 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <cpu/sh7785.h>
+
+void __init highlander_plat_pinmux_setup(void)
+{
+ /* SCIF0 */
+ gpio_request(GPIO_FN_SCIF0_CTS, NULL);
+ gpio_request(GPIO_FN_SCIF0_RTS, NULL);
+ gpio_request(GPIO_FN_SCIF0_SCK, NULL);
+ gpio_request(GPIO_FN_SCIF0_RXD, NULL);
+ gpio_request(GPIO_FN_SCIF0_TXD, NULL);
+}
diff --git a/arch/sh/boards/mach-highlander/psw.c b/arch/sh/boards/mach-highlander/psw.c
new file mode 100644
index 000000000..d445c54f7
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/psw.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/renesas/r7780rp/psw.c
+ *
+ * push switch support for RDBRP-1/RDBREVRP-1 debug boards.
+ *
+ * Copyright (C) 2006 Paul Mundt
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <mach/highlander.h>
+#include <asm/push-switch.h>
+
+static irqreturn_t psw_irq_handler(int irq, void *arg)
+{
+ struct platform_device *pdev = arg;
+ struct push_switch *psw = platform_get_drvdata(pdev);
+ struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
+ unsigned int l, mask;
+ int ret = 0;
+
+ l = __raw_readw(PA_DBSW);
+
+ /* Nothing to do if there's no state change */
+ if (psw->state) {
+ ret = 1;
+ goto out;
+ }
+
+ mask = l & 0x70;
+ /* Figure out who raised it */
+ if (mask & (1 << psw_info->bit)) {
+ psw->state = !!(mask & (1 << psw_info->bit));
+ if (psw->state) /* debounce */
+ mod_timer(&psw->debounce, jiffies + 50);
+
+ ret = 1;
+ }
+
+out:
+ /* Clear the switch IRQs */
+ l |= (0x7 << 12);
+ __raw_writew(l, PA_DBSW);
+
+ return IRQ_RETVAL(ret);
+}
+
+static struct resource psw_resources[] = {
+ [0] = {
+ .start = IRQ_PSW,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct push_switch_platform_info s2_platform_data = {
+ .name = "s2",
+ .bit = 6,
+ .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct platform_device s2_switch_device = {
+ .name = "push-switch",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(psw_resources),
+ .resource = psw_resources,
+ .dev = {
+ .platform_data = &s2_platform_data,
+ },
+};
+
+static struct push_switch_platform_info s3_platform_data = {
+ .name = "s3",
+ .bit = 5,
+ .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct platform_device s3_switch_device = {
+ .name = "push-switch",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(psw_resources),
+ .resource = psw_resources,
+ .dev = {
+ .platform_data = &s3_platform_data,
+ },
+};
+
+static struct push_switch_platform_info s4_platform_data = {
+ .name = "s4",
+ .bit = 4,
+ .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct platform_device s4_switch_device = {
+ .name = "push-switch",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(psw_resources),
+ .resource = psw_resources,
+ .dev = {
+ .platform_data = &s4_platform_data,
+ },
+};
+
+static struct platform_device *psw_devices[] = {
+ &s2_switch_device, &s3_switch_device, &s4_switch_device,
+};
+
+static int __init psw_init(void)
+{
+ return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
+}
+module_init(psw_init);
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
new file mode 100644
index 000000000..01565660a
--- /dev/null
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/renesas/r7780rp/setup.c
+ *
+ * Renesas Solutions Highlander Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2005 - 2008 Paul Mundt
+ *
+ * This contains support for the R7780RP-1, R7780MP, and R7785RP
+ * Highlander modules.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/types.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
+#include <linux/clkdev.h>
+#include <net/ax88796.h>
+#include <asm/machvec.h>
+#include <mach/highlander.h>
+#include <asm/clock.h>
+#include <asm/heartbeat.h>
+#include <asm/io.h>
+#include <asm/io_trapped.h>
+
+static struct r8a66597_platdata r8a66597_data = {
+ .xtal = R8A66597_PLATDATA_XTAL_12MHZ,
+ .vif = 1,
+};
+
+static struct resource r8a66597_usb_host_resources[] = {
+ [0] = {
+ .start = 0xA4200000,
+ .end = 0xA42000FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EXT1, /* irq number */
+ .end = IRQ_EXT1,
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device r8a66597_usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &r8a66597_data,
+ },
+ .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources),
+ .resource = r8a66597_usb_host_resources,
+};
+
+static struct m66592_platdata usbf_platdata = {
+ .xtal = M66592_PLATDATA_XTAL_24MHZ,
+ .vif = 1,
+};
+
+static struct resource m66592_usb_peripheral_resources[] = {
+ [0] = {
+ .name = "m66592_udc",
+ .start = 0xb0000000,
+ .end = 0xb00000FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "m66592_udc",
+ .start = IRQ_EXT4, /* irq number */
+ .end = IRQ_EXT4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m66592_usb_peripheral_device = {
+ .name = "m66592_udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usbf_platdata,
+ },
+ .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
+ .resource = m66592_usb_peripheral_resources,
+};
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_AREA5_IO + 0x1000,
+ .end = PA_AREA5_IO + 0x1000 + 0x08 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PA_AREA5_IO + 0x80c,
+ .end = PA_AREA5_IO + 0x80c + 0x16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_CF,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct pata_platform_info pata_info = {
+ .ioport_shift = 1,
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+ .dev = {
+ .platform_data = &pata_info,
+ },
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_OBLED,
+ .end = PA_OBLED,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+#ifndef CONFIG_SH_R7785RP
+static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+};
+#endif
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+
+ /* R7785RP has a slightly more sensible FPGA.. */
+#ifndef CONFIG_SH_R7785RP
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+#endif
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct ax_plat_data ax88796_platdata = {
+ .flags = AXFLG_HAS_93CX6,
+ .wordlength = 2,
+ .dcr_val = 0x1,
+ .rcr_val = 0x40,
+};
+
+static struct resource ax88796_resources[] = {
+ {
+#ifdef CONFIG_SH_R7780RP
+ .start = 0xa5800400,
+ .end = 0xa5800400 + (0x20 * 0x2) - 1,
+#else
+ .start = 0xa4100400,
+ .end = 0xa4100400 + (0x20 * 0x2) - 1,
+#endif
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_AX88796,
+ .end = IRQ_AX88796,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ax88796_device = {
+ .name = "ax88796",
+ .id = 0,
+
+ .dev = {
+ .platform_data = &ax88796_platdata,
+ },
+
+ .num_resources = ARRAY_SIZE(ax88796_resources),
+ .resource = ax88796_resources,
+};
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 4,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+/* This config is flash board for mass production. */
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = PA_NORFLASH_ADDR,
+ .end = PA_NORFLASH_ADDR + PA_NORFLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+static struct resource smbus_resources[] = {
+ [0] = {
+ .start = PA_SMCR,
+ .end = PA_SMCR + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SMBUS,
+ .end = IRQ_SMBUS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smbus_device = {
+ .name = "i2c-highlander",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smbus_resources),
+ .resource = smbus_resources,
+};
+
+static struct i2c_board_info __initdata highlander_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ },
+};
+
+static struct platform_device *r7780rp_devices[] __initdata = {
+ &r8a66597_usb_host_device,
+ &m66592_usb_peripheral_device,
+ &heartbeat_device,
+ &smbus_device,
+ &nor_flash_device,
+#ifndef CONFIG_SH_R7780RP
+ &ax88796_device,
+#endif
+};
+
+/*
+ * The CF is connected using a 16-bit bus where 8-bit operations are
+ * unsupported. The linux ata driver is however using 8-bit operations, so
+ * insert a trapped io filter to convert 8-bit operations into 16-bit.
+ */
+static struct trapped_io cf_trapped_io = {
+ .resource = cf_ide_resources,
+ .num_resources = 2,
+ .minimum_bus_width = 16,
+};
+
+static int __init r7780rp_devices_setup(void)
+{
+ int ret = 0;
+
+#ifndef CONFIG_SH_R7780RP
+ if (register_trapped_io(&cf_trapped_io) == 0)
+ ret |= platform_device_register(&cf_ide_device);
+#endif
+
+ ret |= platform_add_devices(r7780rp_devices,
+ ARRAY_SIZE(r7780rp_devices));
+
+ ret |= i2c_register_board_info(0, highlander_i2c_devices,
+ ARRAY_SIZE(highlander_i2c_devices));
+
+ return ret;
+}
+device_initcall(r7780rp_devices_setup);
+
+/*
+ * Platform specific clocks
+ */
+static int ivdr_clk_enable(struct clk *clk)
+{
+ __raw_writew(__raw_readw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
+ return 0;
+}
+
+static void ivdr_clk_disable(struct clk *clk)
+{
+ __raw_writew(__raw_readw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
+}
+
+static struct sh_clk_ops ivdr_clk_ops = {
+ .enable = ivdr_clk_enable,
+ .disable = ivdr_clk_disable,
+};
+
+static struct clk ivdr_clk = {
+ .ops = &ivdr_clk_ops,
+};
+
+static struct clk *r7780rp_clocks[] = {
+ &ivdr_clk,
+};
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("ivdr_clk", &ivdr_clk),
+};
+
+static void r7780rp_power_off(void)
+{
+ if (mach_is_r7780mp() || mach_is_r7785rp())
+ __raw_writew(0x0001, PA_POFF);
+}
+
+/*
+ * Initialize the board
+ */
+static void __init highlander_setup(char **cmdline_p)
+{
+ u16 ver = __raw_readw(PA_VERREG);
+ int i;
+
+ printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
+ mach_is_r7780rp() ? "R7780RP-1" :
+ mach_is_r7780mp() ? "R7780MP" :
+ "R7785RP");
+
+ printk(KERN_INFO "Board version: %d (revision %d), "
+ "FPGA version: %d (revision %d)\n",
+ (ver >> 12) & 0xf, (ver >> 8) & 0xf,
+ (ver >> 4) & 0xf, ver & 0xf);
+
+ highlander_plat_pinmux_setup();
+
+ /*
+ * Enable the important clocks right away..
+ */
+ for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) {
+ struct clk *clk = r7780rp_clocks[i];
+
+ clk_register(clk);
+ clk_enable(clk);
+ }
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ __raw_writew(0x0000, PA_OBLED); /* Clear LED. */
+
+ if (mach_is_r7780rp())
+ __raw_writew(0x0001, PA_SDPOW); /* SD Power ON */
+
+ __raw_writew(__raw_readw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */
+
+ pm_power_off = r7780rp_power_off;
+}
+
+static unsigned char irl2irq[HL_NR_IRL];
+
+static int highlander_irq_demux(int irq)
+{
+ if (irq >= HL_NR_IRL + 16 || irq < 16 || !irl2irq[irq - 16])
+ return irq;
+
+ return irl2irq[irq - 16];
+}
+
+static void __init highlander_init_irq(void)
+{
+ unsigned char *ucp = highlander_plat_irq_setup();
+
+ if (ucp) {
+ plat_irq_setup_pins(IRQ_MODE_IRL3210);
+ memcpy(irl2irq, ucp, HL_NR_IRL);
+ }
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_highlander __initmv = {
+ .mv_name = "Highlander",
+ .mv_setup = highlander_setup,
+ .mv_init_irq = highlander_init_irq,
+ .mv_irq_demux = highlander_irq_demux,
+};
diff --git a/arch/sh/boards/mach-hp6xx/Makefile b/arch/sh/boards/mach-hp6xx/Makefile
new file mode 100644
index 000000000..4b0fe29e5
--- /dev/null
+++ b/arch/sh/boards/mach-hp6xx/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the HP6xx specific parts of the kernel
+#
+
+obj-y := setup.o
+obj-$(CONFIG_PM) += pm.o pm_wakeup.o
+obj-$(CONFIG_APM_EMULATION) += hp6xx_apm.o
diff --git a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
new file mode 100644
index 000000000..e5c4c7d34
--- /dev/null
+++ b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * bios-less APM driver for hp680
+ *
+ * Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com>
+ * Copyright 2008 (c) Kristoffer Ericson <kristoffer.ericson@gmail.com>
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/apm-emulation.h>
+#include <linux/io.h>
+#include <asm/adc.h>
+#include <mach/hp6xx.h>
+
+/* percentage values */
+#define APM_CRITICAL 10
+#define APM_LOW 30
+
+/* resonably sane values */
+#define HP680_BATTERY_MAX 898
+#define HP680_BATTERY_MIN 486
+#define HP680_BATTERY_AC_ON 1023
+
+#define MODNAME "hp6x0_apm"
+
+#define PGDR 0xa400012c
+
+static void hp6x0_apm_get_power_status(struct apm_power_info *info)
+{
+ int battery, backup, charging, percentage;
+ u8 pgdr;
+
+ battery = adc_single(ADC_CHANNEL_BATTERY);
+ backup = adc_single(ADC_CHANNEL_BACKUP);
+ charging = adc_single(ADC_CHANNEL_CHARGE);
+
+ percentage = 100 * (battery - HP680_BATTERY_MIN) /
+ (HP680_BATTERY_MAX - HP680_BATTERY_MIN);
+
+ /* % of full battery */
+ info->battery_life = percentage;
+
+ /* We want our estimates in minutes */
+ info->units = 0;
+
+ /* Extremely(!!) rough estimate, we will replace this with a datalist later on */
+ info->time = (2 * battery);
+
+ info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ?
+ APM_AC_ONLINE : APM_AC_OFFLINE;
+
+ pgdr = __raw_readb(PGDR);
+ if (pgdr & PGDR_MAIN_BATTERY_OUT) {
+ info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
+ info->battery_flag = 0x80;
+ } else if (charging < 8) {
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ info->battery_flag = 0x08;
+ info->ac_line_status = 0x01;
+ } else if (percentage <= APM_CRITICAL) {
+ info->battery_status = APM_BATTERY_STATUS_CRITICAL;
+ info->battery_flag = 0x04;
+ } else if (percentage <= APM_LOW) {
+ info->battery_status = APM_BATTERY_STATUS_LOW;
+ info->battery_flag = 0x02;
+ } else {
+ info->battery_status = APM_BATTERY_STATUS_HIGH;
+ info->battery_flag = 0x01;
+ }
+}
+
+static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev)
+{
+ if (!APM_DISABLED)
+ apm_queue_event(APM_USER_SUSPEND);
+
+ return IRQ_HANDLED;
+}
+
+static int __init hp6x0_apm_init(void)
+{
+ int ret;
+
+ ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt,
+ 0, MODNAME, NULL);
+ if (unlikely(ret < 0)) {
+ printk(KERN_ERR MODNAME ": IRQ %d request failed\n",
+ HP680_BTN_IRQ);
+ return ret;
+ }
+
+ apm_get_power_status = hp6x0_apm_get_power_status;
+
+ return ret;
+}
+
+static void __exit hp6x0_apm_exit(void)
+{
+ free_irq(HP680_BTN_IRQ, 0);
+}
+
+module_init(hp6x0_apm_init);
+module_exit(hp6x0_apm_exit);
+
+MODULE_AUTHOR("Adriy Skulysh");
+MODULE_DESCRIPTION("hp6xx Advanced Power Management");
+MODULE_LICENSE("GPL");
diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c
new file mode 100644
index 000000000..fe505ec16
--- /dev/null
+++ b/arch/sh/boards/mach-hp6xx/pm.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * hp6x0 Power Management Routines
+ *
+ * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
+ */
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/gfp.h>
+#include <asm/io.h>
+#include <asm/hd64461.h>
+#include <asm/bl_bit.h>
+#include <mach/hp6xx.h>
+#include <cpu/dac.h>
+#include <asm/freq.h>
+#include <asm/watchdog.h>
+
+#define INTR_OFFSET 0x600
+
+#define STBCR 0xffffff82
+#define STBCR2 0xffffff88
+
+#define STBCR_STBY 0x80
+#define STBCR_MSTP2 0x04
+
+#define MCR 0xffffff68
+#define RTCNT 0xffffff70
+
+#define MCR_RMODE 2
+#define MCR_RFSH 4
+
+extern u8 wakeup_start;
+extern u8 wakeup_end;
+
+static void pm_enter(void)
+{
+ u8 stbcr, csr;
+ u16 frqcr, mcr;
+ u32 vbr_new, vbr_old;
+
+ set_bl_bit();
+
+ /* set wdt */
+ csr = sh_wdt_read_csr();
+ csr &= ~WTCSR_TME;
+ csr |= WTCSR_CKS_4096;
+ sh_wdt_write_csr(csr);
+ csr = sh_wdt_read_csr();
+ sh_wdt_write_cnt(0);
+
+ /* disable PLL1 */
+ frqcr = __raw_readw(FRQCR);
+ frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
+ __raw_writew(frqcr, FRQCR);
+
+ /* enable standby */
+ stbcr = __raw_readb(STBCR);
+ __raw_writeb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
+
+ /* set self-refresh */
+ mcr = __raw_readw(MCR);
+ __raw_writew(mcr & ~MCR_RFSH, MCR);
+
+ /* set interrupt handler */
+ asm volatile("stc vbr, %0" : "=r" (vbr_old));
+ vbr_new = get_zeroed_page(GFP_ATOMIC);
+ udelay(50);
+ memcpy((void*)(vbr_new + INTR_OFFSET),
+ &wakeup_start, &wakeup_end - &wakeup_start);
+ asm volatile("ldc %0, vbr" : : "r" (vbr_new));
+
+ __raw_writew(0, RTCNT);
+ __raw_writew(mcr | MCR_RFSH | MCR_RMODE, MCR);
+
+ cpu_sleep();
+
+ asm volatile("ldc %0, vbr" : : "r" (vbr_old));
+
+ free_page(vbr_new);
+
+ /* enable PLL1 */
+ frqcr = __raw_readw(FRQCR);
+ frqcr |= FRQCR_PSTBY;
+ __raw_writew(frqcr, FRQCR);
+ udelay(50);
+ frqcr |= FRQCR_PLLEN;
+ __raw_writew(frqcr, FRQCR);
+
+ __raw_writeb(stbcr, STBCR);
+
+ clear_bl_bit();
+}
+
+static int hp6x0_pm_enter(suspend_state_t state)
+{
+ u8 stbcr, stbcr2;
+#ifdef CONFIG_HD64461_ENABLER
+ u8 scr;
+ u16 hd64461_stbcr;
+#endif
+
+#ifdef CONFIG_HD64461_ENABLER
+ outb(0, HD64461_PCC1CSCIER);
+
+ scr = inb(HD64461_PCC1SCR);
+ scr |= HD64461_PCCSCR_VCC1;
+ outb(scr, HD64461_PCC1SCR);
+
+ hd64461_stbcr = inw(HD64461_STBCR);
+ hd64461_stbcr |= HD64461_STBCR_SPC1ST;
+ outw(hd64461_stbcr, HD64461_STBCR);
+#endif
+
+ __raw_writeb(0x1f, DACR);
+
+ stbcr = __raw_readb(STBCR);
+ __raw_writeb(0x01, STBCR);
+
+ stbcr2 = __raw_readb(STBCR2);
+ __raw_writeb(0x7f , STBCR2);
+
+ outw(0xf07f, HD64461_SCPUCR);
+
+ pm_enter();
+
+ outw(0, HD64461_SCPUCR);
+ __raw_writeb(stbcr, STBCR);
+ __raw_writeb(stbcr2, STBCR2);
+
+#ifdef CONFIG_HD64461_ENABLER
+ hd64461_stbcr = inw(HD64461_STBCR);
+ hd64461_stbcr &= ~HD64461_STBCR_SPC1ST;
+ outw(hd64461_stbcr, HD64461_STBCR);
+
+ outb(0x4c, HD64461_PCC1CSCIER);
+ outb(0x00, HD64461_PCC1CSCR);
+#endif
+
+ return 0;
+}
+
+static const struct platform_suspend_ops hp6x0_pm_ops = {
+ .enter = hp6x0_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init hp6x0_pm_init(void)
+{
+ suspend_set_ops(&hp6x0_pm_ops);
+ return 0;
+}
+
+late_initcall(hp6x0_pm_init);
diff --git a/arch/sh/boards/mach-hp6xx/pm_wakeup.S b/arch/sh/boards/mach-hp6xx/pm_wakeup.S
new file mode 100644
index 000000000..0fd43301f
--- /dev/null
+++ b/arch/sh/boards/mach-hp6xx/pm_wakeup.S
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
+ */
+
+#include <linux/linkage.h>
+#include <cpu/mmu_context.h>
+
+/*
+ * Kernel mode register usage:
+ * k0 scratch
+ * k1 scratch
+ * For more details, please have a look at entry.S
+ */
+
+#define k0 r0
+#define k1 r1
+
+ENTRY(wakeup_start)
+! clear STBY bit
+ mov #-126, k1
+ and #127, k0
+ mov.b k0, @k1
+! enable refresh
+ mov.l 5f, k1
+ mov.w 6f, k0
+ mov.w k0, @k1
+! jump to handler
+ mov.l 4f, k1
+ jmp @k1
+ nop
+
+ .align 2
+4: .long handle_interrupt
+5: .long 0xffffff68
+6: .word 0x0524
+
+ENTRY(wakeup_end)
+ nop
diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c
new file mode 100644
index 000000000..2ceead68d
--- /dev/null
+++ b/arch/sh/boards/mach-hp6xx/setup.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/hp6xx/setup.c
+ *
+ * Copyright (C) 2002 Andriy Skulysh
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer_e1@hotmail.com>
+ *
+ * Setup code for HP620/HP660/HP680/HP690 (internal peripherials only)
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/sh_intc.h>
+#include <sound/sh_dac_audio.h>
+#include <asm/hd64461.h>
+#include <asm/io.h>
+#include <mach/hp6xx.h>
+#include <cpu/dac.h>
+
+#define SCPCR 0xa4000116
+#define SCPDR 0xa4000136
+
+/* CF Slot */
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x15000000 + 0x1f0,
+ .end = 0x15000000 + 0x1f0 + 0x08 - 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x15000000 + 0x1fe,
+ .end = 0x15000000 + 0x1fe + 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = evt2irq(0xba0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device jornadakbd_device = {
+ .name = "jornada680_kbd",
+ .id = -1,
+};
+
+static void dac_audio_start(struct dac_audio_pdata *pdata)
+{
+ u16 v;
+ u8 v8;
+
+ /* HP Jornada 680/690 speaker on */
+ v = inw(HD64461_GPADR);
+ v &= ~HD64461_GPADR_SPEAKER;
+ outw(v, HD64461_GPADR);
+
+ /* HP Palmtop 620lx/660lx speaker on */
+ v8 = inb(PKDR);
+ v8 &= ~PKDR_SPEAKER;
+ outb(v8, PKDR);
+
+ sh_dac_enable(pdata->channel);
+}
+
+static void dac_audio_stop(struct dac_audio_pdata *pdata)
+{
+ u16 v;
+ u8 v8;
+
+ /* HP Jornada 680/690 speaker off */
+ v = inw(HD64461_GPADR);
+ v |= HD64461_GPADR_SPEAKER;
+ outw(v, HD64461_GPADR);
+
+ /* HP Palmtop 620lx/660lx speaker off */
+ v8 = inb(PKDR);
+ v8 |= PKDR_SPEAKER;
+ outb(v8, PKDR);
+
+ sh_dac_output(0, pdata->channel);
+ sh_dac_disable(pdata->channel);
+}
+
+static struct dac_audio_pdata dac_audio_platform_data = {
+ .buffer_size = 64000,
+ .channel = 1,
+ .start = dac_audio_start,
+ .stop = dac_audio_stop,
+};
+
+static struct platform_device dac_audio_device = {
+ .name = "dac_audio",
+ .id = -1,
+ .dev = {
+ .platform_data = &dac_audio_platform_data,
+ }
+
+};
+
+static struct platform_device *hp6xx_devices[] __initdata = {
+ &cf_ide_device,
+ &jornadakbd_device,
+ &dac_audio_device,
+};
+
+static void __init hp6xx_init_irq(void)
+{
+ /* Gets touchscreen and powerbutton IRQ working */
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+static int __init hp6xx_devices_setup(void)
+{
+ return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices));
+}
+
+static void __init hp6xx_setup(char **cmdline_p)
+{
+ u8 v8;
+ u16 v;
+
+ v = inw(HD64461_STBCR);
+ v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
+ HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
+ HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST |
+ HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST|
+ HD64461_STBCR_SAFECKE_IST;
+#ifndef CONFIG_HD64461_ENABLER
+ v |= HD64461_STBCR_SPC1ST;
+#endif
+ outw(v, HD64461_STBCR);
+ v = inw(HD64461_GPADR);
+ v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
+ outw(v, HD64461_GPADR);
+
+ outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR);
+
+#ifndef CONFIG_HD64461_ENABLER
+ outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR);
+#endif
+
+ sh_dac_output(0, DAC_SPEAKER_VOLUME);
+ sh_dac_disable(DAC_SPEAKER_VOLUME);
+ v8 = __raw_readb(DACR);
+ v8 &= ~DACR_DAE;
+ __raw_writeb(v8,DACR);
+
+ v8 = __raw_readb(SCPDR);
+ v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y;
+ v8 &= ~SCPDR_TS_SCAN_ENABLE;
+ __raw_writeb(v8, SCPDR);
+
+ v = __raw_readw(SCPCR);
+ v &= ~SCPCR_TS_MASK;
+ v |= SCPCR_TS_ENABLE;
+ __raw_writew(v, SCPCR);
+}
+device_initcall(hp6xx_devices_setup);
+
+static struct sh_machine_vector mv_hp6xx __initmv = {
+ .mv_name = "hp6xx",
+ .mv_setup = hp6xx_setup,
+ /* Enable IRQ0 -> IRQ3 in IRQ_MODE */
+ .mv_init_irq = hp6xx_init_irq,
+};
diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile
new file mode 100644
index 000000000..4a4a35ad7
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := setup.o sdram.o
+ifneq ($(CONFIG_FB_SH_MOBILE_LCDC),)
+obj-y += lcd_wqvga.o
+endif
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
new file mode 100644
index 000000000..f6bbac106
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KFR2R09 LCD panel support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * Register settings based on the out-of-tree t33fb.c driver
+ * Copyright (C) 2008 Lineo Solutions, Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <video/sh_mobile_lcdc.h>
+#include <mach/kfr2r09.h>
+#include <cpu/sh7724.h>
+
+/* The on-board LCD module is a Hitachi TX07D34VM0AAA. This module is made
+ * up of a 240x400 LCD hooked up to a R61517 driver IC. The driver IC is
+ * communicating with the main port of the LCDC using an 18-bit SYS interface.
+ *
+ * The device code for this LCD module is 0x01221517.
+ */
+
+static const unsigned char data_frame_if[] = {
+ 0x02, /* WEMODE: 1=cont, 0=one-shot */
+ 0x00, 0x00,
+ 0x00, /* EPF, DFM */
+ 0x02, /* RIM[1] : 1 (18bpp) */
+};
+
+static const unsigned char data_panel[] = {
+ 0x0b,
+ 0x63, /* 400 lines */
+ 0x04, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00,
+};
+
+static const unsigned char data_timing[] = {
+ 0x00, 0x00, 0x13, 0x08, 0x08,
+};
+
+static const unsigned char data_timing_src[] = {
+ 0x11, 0x01, 0x00, 0x01,
+};
+
+static const unsigned char data_gamma[] = {
+ 0x01, 0x02, 0x08, 0x23, 0x03, 0x0c, 0x00, 0x06, 0x00, 0x00,
+ 0x01, 0x00, 0x0c, 0x23, 0x03, 0x08, 0x02, 0x06, 0x00, 0x00,
+};
+
+static const unsigned char data_power[] = {
+ 0x07, 0xc5, 0xdc, 0x02, 0x33, 0x0a,
+};
+
+static unsigned long read_reg(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ return so->read_data(sohandle);
+}
+
+static void write_reg(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so,
+ int i, unsigned long v)
+{
+ if (i)
+ so->write_data(sohandle, v); /* PTH4/LCDRS High [param, 17:0] */
+ else
+ so->write_index(sohandle, v); /* PTH4/LCDRS Low [cmd, 7:0] */
+}
+
+static void write_data(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so,
+ unsigned char const *data, int no_data)
+{
+ int i;
+
+ for (i = 0; i < no_data; i++)
+ write_reg(sohandle, so, 1, data[i]);
+}
+
+static unsigned long read_device_code(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ unsigned long device_code;
+
+ /* access protect OFF */
+ write_reg(sohandle, so, 0, 0xb0);
+ write_reg(sohandle, so, 1, 0x00);
+
+ /* deep standby OFF */
+ write_reg(sohandle, so, 0, 0xb1);
+ write_reg(sohandle, so, 1, 0x00);
+
+ /* device code command */
+ write_reg(sohandle, so, 0, 0xbf);
+ mdelay(50);
+
+ /* dummy read */
+ read_reg(sohandle, so);
+
+ /* read device code */
+ device_code = ((read_reg(sohandle, so) & 0xff) << 24);
+ device_code |= ((read_reg(sohandle, so) & 0xff) << 16);
+ device_code |= ((read_reg(sohandle, so) & 0xff) << 8);
+ device_code |= (read_reg(sohandle, so) & 0xff);
+
+ return device_code;
+}
+
+static void write_memory_start(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ write_reg(sohandle, so, 0, 0x2c);
+}
+
+static void clear_memory(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ int i;
+
+ /* write start */
+ write_memory_start(sohandle, so);
+
+ /* paint it black */
+ for (i = 0; i < (240 * 400); i++)
+ write_reg(sohandle, so, 1, 0x00);
+}
+
+static void display_on(void *sohandle,
+ struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ /* access protect off */
+ write_reg(sohandle, so, 0, 0xb0);
+ write_reg(sohandle, so, 1, 0x00);
+
+ /* exit deep standby mode */
+ write_reg(sohandle, so, 0, 0xb1);
+ write_reg(sohandle, so, 1, 0x00);
+
+ /* frame memory I/F */
+ write_reg(sohandle, so, 0, 0xb3);
+ write_data(sohandle, so, data_frame_if, ARRAY_SIZE(data_frame_if));
+
+ /* display mode and frame memory write mode */
+ write_reg(sohandle, so, 0, 0xb4);
+ write_reg(sohandle, so, 1, 0x00); /* DBI, internal clock */
+
+ /* panel */
+ write_reg(sohandle, so, 0, 0xc0);
+ write_data(sohandle, so, data_panel, ARRAY_SIZE(data_panel));
+
+ /* timing (normal) */
+ write_reg(sohandle, so, 0, 0xc1);
+ write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+ /* timing (partial) */
+ write_reg(sohandle, so, 0, 0xc2);
+ write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+ /* timing (idle) */
+ write_reg(sohandle, so, 0, 0xc3);
+ write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+ /* timing (source/VCOM/gate driving) */
+ write_reg(sohandle, so, 0, 0xc4);
+ write_data(sohandle, so, data_timing_src, ARRAY_SIZE(data_timing_src));
+
+ /* gamma (red) */
+ write_reg(sohandle, so, 0, 0xc8);
+ write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+ /* gamma (green) */
+ write_reg(sohandle, so, 0, 0xc9);
+ write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+ /* gamma (blue) */
+ write_reg(sohandle, so, 0, 0xca);
+ write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+ /* power (common) */
+ write_reg(sohandle, so, 0, 0xd0);
+ write_data(sohandle, so, data_power, ARRAY_SIZE(data_power));
+
+ /* VCOM */
+ write_reg(sohandle, so, 0, 0xd1);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0x0f);
+ write_reg(sohandle, so, 1, 0x02);
+
+ /* power (normal) */
+ write_reg(sohandle, so, 0, 0xd2);
+ write_reg(sohandle, so, 1, 0x63);
+ write_reg(sohandle, so, 1, 0x24);
+
+ /* power (partial) */
+ write_reg(sohandle, so, 0, 0xd3);
+ write_reg(sohandle, so, 1, 0x63);
+ write_reg(sohandle, so, 1, 0x24);
+
+ /* power (idle) */
+ write_reg(sohandle, so, 0, 0xd4);
+ write_reg(sohandle, so, 1, 0x63);
+ write_reg(sohandle, so, 1, 0x24);
+
+ write_reg(sohandle, so, 0, 0xd8);
+ write_reg(sohandle, so, 1, 0x77);
+ write_reg(sohandle, so, 1, 0x77);
+
+ /* TE signal */
+ write_reg(sohandle, so, 0, 0x35);
+ write_reg(sohandle, so, 1, 0x00);
+
+ /* TE signal line */
+ write_reg(sohandle, so, 0, 0x44);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0x00);
+
+ /* column address */
+ write_reg(sohandle, so, 0, 0x2a);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0xef);
+
+ /* page address */
+ write_reg(sohandle, so, 0, 0x2b);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0x00);
+ write_reg(sohandle, so, 1, 0x01);
+ write_reg(sohandle, so, 1, 0x8f);
+
+ /* exit sleep mode */
+ write_reg(sohandle, so, 0, 0x11);
+
+ mdelay(120);
+
+ /* clear vram */
+ clear_memory(sohandle, so);
+
+ /* display ON */
+ write_reg(sohandle, so, 0, 0x29);
+ mdelay(1);
+
+ write_memory_start(sohandle, so);
+}
+
+int kfr2r09_lcd_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ /* power on */
+ gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */
+ gpio_set_value(GPIO_PTE4, 0); /* LCD_RST/ -> L */
+ gpio_set_value(GPIO_PTF4, 1); /* PROTECT/ -> H */
+ udelay(1100);
+ gpio_set_value(GPIO_PTE4, 1); /* LCD_RST/ -> H */
+ udelay(10);
+ gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */
+ mdelay(20);
+
+ if (read_device_code(sohandle, so) != 0x01221517)
+ return -ENODEV;
+
+ pr_info("KFR2R09 WQVGA LCD Module detected.\n");
+
+ display_on(sohandle, so);
+ return 0;
+}
+
+void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ write_memory_start(sohandle, so);
+}
diff --git a/arch/sh/boards/mach-kfr2r09/sdram.S b/arch/sh/boards/mach-kfr2r09/sdram.S
new file mode 100644
index 000000000..f1b8985cb
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/sdram.S
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * KFR2R09 sdram self/auto-refresh setup code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+ .balign 4
+ENTRY(kfr2r09_sdram_enter_start)
+
+ /* DBSC: put memory in self-refresh mode */
+
+ ED 0xFD000010, 0x00000000 /* DBEN */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ENTRY(kfr2r09_sdram_enter_end)
+
+ .balign 4
+ENTRY(kfr2r09_sdram_leave_start)
+
+ /* DBSC: put memory in auto-refresh mode */
+
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_RSTANDBY, r0
+ bf resume_rstandby
+
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ WAIT 1
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+resume_rstandby:
+
+ /* DBSC: re-initialize and put in auto-refresh */
+
+ ED 0xFD000108, 0x40000301 /* DBPDCNT0 */
+ ED 0xFD000020, 0x011B0002 /* DBCONF */
+ ED 0xFD000030, 0x03060E02 /* DBTR0 */
+ ED 0xFD000034, 0x01020102 /* DBTR1 */
+ ED 0xFD000038, 0x01090406 /* DBTR2 */
+ ED 0xFD000008, 0x00000004 /* DBKIND */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000018, 0x00000001 /* DBCKECNT */
+ WAIT 1
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000044, 0x000004AF /* DBRFPDN1 */
+ ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000108, 0x40000300 /* DBPDCNT0 */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ENTRY(kfr2r09_sdram_leave_end)
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
new file mode 100644
index 000000000..c6d556dfb
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -0,0 +1,649 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KFR2R09 board support code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ */
+
+#include <asm/clock.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <asm/suspend.h>
+
+#include <cpu/sh7724.h>
+
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/interrupt.h>
+#include <linux/memblock.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_data/lv5207lp.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/sh_intc.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/videodev2.h>
+#include <linux/dma-map-ops.h>
+
+#include <mach/kfr2r09.h>
+
+#include <media/drv-intf/renesas-ceu.h>
+#include <media/i2c/rj54n1cb0c.h>
+
+#include <video/sh_mobile_lcdc.h>
+
+#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
+static phys_addr_t ceu_dma_membase;
+
+/* set VIO_CKO clock to 25MHz */
+#define CEU_MCLK_FREQ 25000000
+#define DRVCRB 0xA405018C
+
+static struct mtd_partition kfr2r09_nor_flash_partitions[] =
+{
+ {
+ .name = "boot",
+ .offset = 0,
+ .size = (4 * 1024 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ },
+ {
+ .name = "other",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data kfr2r09_nor_flash_data = {
+ .width = 2,
+ .parts = kfr2r09_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(kfr2r09_nor_flash_partitions),
+};
+
+static struct resource kfr2r09_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device kfr2r09_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = kfr2r09_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(kfr2r09_nor_flash_resources),
+ .dev = {
+ .platform_data = &kfr2r09_nor_flash_data,
+ },
+};
+
+static struct resource kfr2r09_nand_flash_resources[] = {
+ [0] = {
+ .name = "NAND Flash",
+ .start = 0x10000000,
+ .end = 0x1001ffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device kfr2r09_nand_flash_device = {
+ .name = "onenand-flash",
+ .resource = kfr2r09_nand_flash_resources,
+ .num_resources = ARRAY_SIZE(kfr2r09_nand_flash_resources),
+};
+
+static struct sh_keysc_info kfr2r09_sh_keysc_info = {
+ .mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */
+ .scan_timing = 3,
+ .delay = 10,
+ .keycodes = {
+ KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER,
+ KEY_1, KEY_2, KEY_3, 0, KEY_UP,
+ KEY_4, KEY_5, KEY_6, 0, KEY_LEFT,
+ KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT,
+ KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN,
+ 0, 0, 0, 0, 0
+ },
+};
+
+static struct resource kfr2r09_sh_keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0x044b0000,
+ .end = 0x044b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xbe0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kfr2r09_sh_keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* "keysc0" clock */
+ .num_resources = ARRAY_SIZE(kfr2r09_sh_keysc_resources),
+ .resource = kfr2r09_sh_keysc_resources,
+ .dev = {
+ .platform_data = &kfr2r09_sh_keysc_info,
+ },
+};
+
+static const struct fb_videomode kfr2r09_lcdc_modes[] = {
+ {
+ .name = "TX07D34VM0AAA",
+ .xres = 240,
+ .yres = 400,
+ .left_margin = 0,
+ .right_margin = 16,
+ .hsync_len = 8,
+ .upper_margin = 0,
+ .lower_margin = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+};
+
+static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = SYS18,
+ .clock_divider = 6,
+ .flags = LCDC_FLAGS_DWPOL,
+ .lcd_modes = kfr2r09_lcdc_modes,
+ .num_modes = ARRAY_SIZE(kfr2r09_lcdc_modes),
+ .panel_cfg = {
+ .width = 35,
+ .height = 58,
+ .setup_sys = kfr2r09_lcd_setup,
+ .start_transfer = kfr2r09_lcd_start,
+ },
+ .sys_bus_cfg = {
+ .ldmt2r = 0x07010904,
+ .ldmt3r = 0x14012914,
+ /* set 1s delay to encourage fsync() */
+ .deferred_io_msec = 1000,
+ },
+ }
+};
+
+static struct resource kfr2r09_sh_lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe942fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xf40),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kfr2r09_sh_lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(kfr2r09_sh_lcdc_resources),
+ .resource = kfr2r09_sh_lcdc_resources,
+ .dev = {
+ .platform_data = &kfr2r09_sh_lcdc_info,
+ },
+};
+
+static struct lv5207lp_platform_data kfr2r09_backlight_data = {
+ .fbdev = &kfr2r09_sh_lcdc_device.dev,
+ .def_value = 13,
+ .max_value = 13,
+};
+
+static struct i2c_board_info kfr2r09_backlight_board_info = {
+ I2C_BOARD_INFO("lv5207lp", 0x75),
+ .platform_data = &kfr2r09_backlight_data,
+};
+
+static struct r8a66597_platdata kfr2r09_usb0_gadget_data = {
+ .on_chip = 1,
+};
+
+static struct resource kfr2r09_usb0_gadget_resources[] = {
+ [0] = {
+ .start = 0x04d80000,
+ .end = 0x04d80123,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa20),
+ .end = evt2irq(0xa20),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device kfr2r09_usb0_gadget_device = {
+ .name = "r8a66597_udc",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &kfr2r09_usb0_gadget_data,
+ },
+ .num_resources = ARRAY_SIZE(kfr2r09_usb0_gadget_resources),
+ .resource = kfr2r09_usb0_gadget_resources,
+};
+
+static struct ceu_platform_data ceu_pdata = {
+ .num_subdevs = 1,
+ .subdevs = {
+ { /* [0] = rj54n1cb0c */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 1,
+ .i2c_address = 0x50,
+ },
+ },
+};
+
+static struct resource kfr2r09_ceu_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x880),
+ .end = evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kfr2r09_ceu_device = {
+ .name = "renesas-ceu",
+ .id = 0, /* "ceu0" clock */
+ .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources),
+ .resource = kfr2r09_ceu_resources,
+ .dev = {
+ .platform_data = &ceu_pdata,
+ },
+};
+
+static struct rj54n1_pdata rj54n1_priv = {
+ .mclk_freq = CEU_MCLK_FREQ,
+ .ioctl_high = false,
+};
+
+static struct i2c_board_info kfr2r09_i2c_camera = {
+ I2C_BOARD_INFO("rj54n1cb0c", 0x50),
+ .platform_data = &rj54n1_priv,
+};
+
+static struct gpiod_lookup_table rj54n1_gpios = {
+ .dev_id = "1-0050",
+ .table = {
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTB4, "poweron",
+ GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sh7724_pfc", GPIO_PTB7, "enable",
+ GPIO_ACTIVE_HIGH),
+ },
+};
+
+/* Fixed 3.3V regulator to be used by SDHI0 */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct resource kfr2r09_sh_sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0x04ce0000,
+ .end = 0x04ce00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xe80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sh7724_sdhi0_data = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX,
+ .capabilities = MMC_CAP_SDIO_IRQ,
+ .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT,
+};
+
+static struct platform_device kfr2r09_sh_sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources),
+ .resource = kfr2r09_sh_sdhi0_resources,
+ .dev = {
+ .platform_data = &sh7724_sdhi0_data,
+ },
+};
+
+static struct platform_device *kfr2r09_devices[] __initdata = {
+ &kfr2r09_nor_flash_device,
+ &kfr2r09_nand_flash_device,
+ &kfr2r09_sh_keysc_device,
+ &kfr2r09_sh_lcdc_device,
+ &kfr2r09_sh_sdhi0_device,
+};
+
+#define BSC_CS0BCR 0xfec10004
+#define BSC_CS0WCR 0xfec10024
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS4WCR 0xfec10030
+#define PORT_MSELCRB 0xa4050182
+
+#ifdef CONFIG_I2C
+static int kfr2r09_usb0_gadget_i2c_setup(void)
+{
+ struct i2c_adapter *a;
+ struct i2c_msg msg;
+ unsigned char buf[2];
+ int ret;
+
+ a = i2c_get_adapter(0);
+ if (!a)
+ return -ENODEV;
+
+ /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
+ buf[0] = 0x13;
+ msg.addr = 0x09;
+ msg.buf = buf;
+ msg.len = 1;
+ msg.flags = 0;
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret != 1)
+ return -ENODEV;
+
+ buf[0] = 0;
+ msg.addr = 0x09;
+ msg.buf = buf;
+ msg.len = 1;
+ msg.flags = I2C_M_RD;
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret != 1)
+ return -ENODEV;
+
+ buf[1] = buf[0] | (1 << 1);
+ buf[0] = 0x13;
+ msg.addr = 0x09;
+ msg.buf = buf;
+ msg.len = 2;
+ msg.flags = 0;
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret != 1)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int kfr2r09_serial_i2c_setup(void)
+{
+ struct i2c_adapter *a;
+ struct i2c_msg msg;
+ unsigned char buf[2];
+ int ret;
+
+ a = i2c_get_adapter(0);
+ if (!a)
+ return -ENODEV;
+
+ /* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */
+ buf[0] = 0x13;
+ msg.addr = 0x09;
+ msg.buf = buf;
+ msg.len = 1;
+ msg.flags = 0;
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret != 1)
+ return -ENODEV;
+
+ buf[0] = 0;
+ msg.addr = 0x09;
+ msg.buf = buf;
+ msg.len = 1;
+ msg.flags = I2C_M_RD;
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret != 1)
+ return -ENODEV;
+
+ buf[1] = buf[0] | (1 << 6);
+ buf[0] = 0x13;
+ msg.addr = 0x09;
+ msg.buf = buf;
+ msg.len = 2;
+ msg.flags = 0;
+ ret = i2c_transfer(a, &msg, 1);
+ if (ret != 1)
+ return -ENODEV;
+
+ return 0;
+}
+#else
+static int kfr2r09_usb0_gadget_i2c_setup(void)
+{
+ return -ENODEV;
+}
+
+static int kfr2r09_serial_i2c_setup(void)
+{
+ return -ENODEV;
+}
+#endif
+
+static int kfr2r09_usb0_gadget_setup(void)
+{
+ int plugged_in;
+
+ gpio_request(GPIO_PTN4, NULL); /* USB_DET */
+ gpio_direction_input(GPIO_PTN4);
+ plugged_in = gpio_get_value(GPIO_PTN4);
+ if (!plugged_in)
+ return -ENODEV; /* no cable plugged in */
+
+ if (kfr2r09_usb0_gadget_i2c_setup() != 0)
+ return -ENODEV; /* unable to configure using i2c */
+
+ __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+ gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */
+ gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */
+ gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */
+ msleep(20); /* wait 20ms to let the clock settle */
+ clk_enable(clk_get(NULL, "usb0"));
+ __raw_writew(0x0600, 0xa40501d4);
+
+ return 0;
+}
+
+extern char kfr2r09_sdram_enter_start;
+extern char kfr2r09_sdram_enter_end;
+extern char kfr2r09_sdram_leave_start;
+extern char kfr2r09_sdram_leave_end;
+
+static int __init kfr2r09_devices_setup(void)
+{
+ struct clk *camera_clk;
+
+ /* register board specific self-refresh code */
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+ SUSP_SH_RSTANDBY,
+ &kfr2r09_sdram_enter_start,
+ &kfr2r09_sdram_enter_end,
+ &kfr2r09_sdram_leave_start,
+ &kfr2r09_sdram_leave_end);
+
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+ /* enable SCIF1 serial port for YC401 console support */
+ gpio_request(GPIO_FN_SCIF1_RXD, NULL);
+ gpio_request(GPIO_FN_SCIF1_TXD, NULL);
+ kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */
+ gpio_request(GPIO_PTG3, NULL); /* HPON_ON */
+ gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */
+
+ /* setup NOR flash at CS0 */
+ __raw_writel(0x36db0400, BSC_CS0BCR);
+ __raw_writel(0x00000500, BSC_CS0WCR);
+
+ /* setup NAND flash at CS4 */
+ __raw_writel(0x36db0400, BSC_CS4BCR);
+ __raw_writel(0x00000500, BSC_CS4WCR);
+
+ /* setup KEYSC pins */
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+ gpio_request(GPIO_FN_KEYIN0, NULL);
+ gpio_request(GPIO_FN_KEYIN1, NULL);
+ gpio_request(GPIO_FN_KEYIN2, NULL);
+ gpio_request(GPIO_FN_KEYIN3, NULL);
+ gpio_request(GPIO_FN_KEYIN4, NULL);
+ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+
+ /* setup LCDC pins for SYS panel */
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */
+ gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */
+ gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */
+ gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */
+ gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */
+ gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */
+ gpio_direction_output(GPIO_PTE4, 1);
+ gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */
+ gpio_direction_output(GPIO_PTF4, 1);
+ gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */
+ gpio_direction_output(GPIO_PTU0, 1);
+
+ /* setup USB function */
+ if (kfr2r09_usb0_gadget_setup() == 0)
+ platform_device_register(&kfr2r09_usb0_gadget_device);
+
+ /* CEU */
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+ gpio_request(GPIO_FN_VIO0_CLK, NULL);
+ gpio_request(GPIO_FN_VIO0_VD, NULL);
+ gpio_request(GPIO_FN_VIO0_HD, NULL);
+ gpio_request(GPIO_FN_VIO0_FLD, NULL);
+ gpio_request(GPIO_FN_VIO0_D7, NULL);
+ gpio_request(GPIO_FN_VIO0_D6, NULL);
+ gpio_request(GPIO_FN_VIO0_D5, NULL);
+ gpio_request(GPIO_FN_VIO0_D4, NULL);
+ gpio_request(GPIO_FN_VIO0_D3, NULL);
+ gpio_request(GPIO_FN_VIO0_D2, NULL);
+ gpio_request(GPIO_FN_VIO0_D1, NULL);
+ gpio_request(GPIO_FN_VIO0_D0, NULL);
+
+ /* SDHI0 connected to yc304 */
+ gpio_request(GPIO_FN_SDHI0CD, NULL);
+ gpio_request(GPIO_FN_SDHI0D3, NULL);
+ gpio_request(GPIO_FN_SDHI0D2, NULL);
+ gpio_request(GPIO_FN_SDHI0D1, NULL);
+ gpio_request(GPIO_FN_SDHI0D0, NULL);
+ gpio_request(GPIO_FN_SDHI0CMD, NULL);
+ gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
+ i2c_register_board_info(0, &kfr2r09_backlight_board_info, 1);
+
+ /* Set camera clock frequency and register and alias for rj54n1. */
+ camera_clk = clk_get(NULL, "video_clk");
+ if (!IS_ERR(camera_clk)) {
+ clk_set_rate(camera_clk,
+ clk_round_rate(camera_clk, CEU_MCLK_FREQ));
+ clk_put(camera_clk);
+ }
+ clk_add_alias(NULL, "1-0050", "video_clk", NULL);
+
+ /* set DRVCRB
+ *
+ * use 1.8 V for VccQ_VIO
+ * use 2.85V for VccQ_SR
+ */
+ __raw_writew((__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB);
+
+ gpiod_add_lookup_table(&rj54n1_gpios);
+
+ i2c_register_board_info(1, &kfr2r09_i2c_camera, 1);
+
+ /* Initialize CEU platform device separately to map memory first */
+ device_initialize(&kfr2r09_ceu_device.dev);
+ dma_declare_coherent_memory(&kfr2r09_ceu_device.dev,
+ ceu_dma_membase, ceu_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+
+ platform_device_add(&kfr2r09_ceu_device);
+
+ return platform_add_devices(kfr2r09_devices,
+ ARRAY_SIZE(kfr2r09_devices));
+}
+device_initcall(kfr2r09_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int kfr2r09_mode_pins(void)
+{
+ /* MD0=1, MD1=1, MD2=0: Clock Mode 3
+ * MD3=0: 16-bit Area0 Bus Width
+ * MD5=1: Little Endian
+ * MD8=1: Test Mode Disabled
+ */
+ return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8;
+}
+
+/* Reserve a portion of memory for CEU buffers */
+static void __init kfr2r09_mv_mem_reserve(void)
+{
+ phys_addr_t phys;
+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+
+ ceu_dma_membase = phys;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_kfr2r09 __initmv = {
+ .mv_name = "kfr2r09",
+ .mv_mode_pins = kfr2r09_mode_pins,
+ .mv_mem_reserve = kfr2r09_mv_mem_reserve,
+};
diff --git a/arch/sh/boards/mach-landisk/Makefile b/arch/sh/boards/mach-landisk/Makefile
new file mode 100644
index 000000000..6cba041ff
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
+#
+
+obj-y := setup.o irq.o psw.o gio.o
diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c
new file mode 100644
index 000000000..ff2200fec
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/gio.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/landisk/gio.c - driver for landisk
+ *
+ * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
+ * LANDISK and USL-5P Button, LED and GIO driver drive function.
+ *
+ * Copylight (C) 2006 kogiidena
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd. *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <mach-landisk/mach/gio.h>
+#include <mach-landisk/mach/iodata_landisk.h>
+
+#define DEVCOUNT 4
+#define GIO_MINOR 2 /* GIO minor no. */
+
+static dev_t dev;
+static struct cdev *cdev_p;
+static int openCnt;
+
+static int gio_open(struct inode *inode, struct file *filp)
+{
+ int minor = iminor(inode);
+ int ret = -ENOENT;
+
+ preempt_disable();
+ if (minor < DEVCOUNT) {
+ if (openCnt > 0) {
+ ret = -EALREADY;
+ } else {
+ openCnt++;
+ ret = 0;
+ }
+ }
+ preempt_enable();
+ return ret;
+}
+
+static int gio_close(struct inode *inode, struct file *filp)
+{
+ int minor = iminor(inode);
+
+ if (minor < DEVCOUNT) {
+ openCnt--;
+ }
+ return 0;
+}
+
+static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ unsigned int data;
+ static unsigned int addr = 0;
+
+ if (cmd & 0x01) { /* write */
+ if (copy_from_user(&data, (int *)arg, sizeof(int))) {
+ return -EFAULT;
+ }
+ }
+
+ switch (cmd) {
+ case GIODRV_IOCSGIOSETADDR: /* address set */
+ addr = data;
+ break;
+
+ case GIODRV_IOCSGIODATA1: /* write byte */
+ __raw_writeb((unsigned char)(0x0ff & data), addr);
+ break;
+
+ case GIODRV_IOCSGIODATA2: /* write word */
+ if (addr & 0x01) {
+ return -EFAULT;
+ }
+ __raw_writew((unsigned short int)(0x0ffff & data), addr);
+ break;
+
+ case GIODRV_IOCSGIODATA4: /* write long */
+ if (addr & 0x03) {
+ return -EFAULT;
+ }
+ __raw_writel(data, addr);
+ break;
+
+ case GIODRV_IOCGGIODATA1: /* read byte */
+ data = __raw_readb(addr);
+ break;
+
+ case GIODRV_IOCGGIODATA2: /* read word */
+ if (addr & 0x01) {
+ return -EFAULT;
+ }
+ data = __raw_readw(addr);
+ break;
+
+ case GIODRV_IOCGGIODATA4: /* read long */
+ if (addr & 0x03) {
+ return -EFAULT;
+ }
+ data = __raw_readl(addr);
+ break;
+ default:
+ return -EFAULT;
+ break;
+ }
+
+ if ((cmd & 0x01) == 0) { /* read */
+ if (copy_to_user((int *)arg, &data, sizeof(int))) {
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+static const struct file_operations gio_fops = {
+ .owner = THIS_MODULE,
+ .open = gio_open, /* open */
+ .release = gio_close, /* release */
+ .unlocked_ioctl = gio_ioctl,
+ .llseek = noop_llseek,
+};
+
+static int __init gio_init(void)
+{
+ int error;
+
+ printk(KERN_INFO "gio: driver initialized\n");
+
+ openCnt = 0;
+
+ if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) {
+ printk(KERN_ERR
+ "gio: Couldn't alloc_chrdev_region, error=%d\n",
+ error);
+ return 1;
+ }
+
+ cdev_p = cdev_alloc();
+ cdev_p->ops = &gio_fops;
+ error = cdev_add(cdev_p, dev, DEVCOUNT);
+ if (error) {
+ printk(KERN_ERR
+ "gio: Couldn't cdev_add, error=%d\n", error);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void __exit gio_exit(void)
+{
+ cdev_del(cdev_p);
+ unregister_chrdev_region(dev, DEVCOUNT);
+}
+
+module_init(gio_init);
+module_exit(gio_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c
new file mode 100644
index 000000000..0b672b80c
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/irq.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/mach-landisk/irq.c
+ *
+ * I-O DATA Device, Inc. LANDISK Support
+ *
+ * Copyright (C) 2005-2007 kogiidena
+ * Copyright (C) 2011 Nobuhiro Iwamatsu
+ *
+ * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
+ * Based largely on io_se.c.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <mach-landisk/mach/iodata_landisk.h>
+
+enum {
+ UNUSED = 0,
+
+ PCI_INTA, /* PCI int A */
+ PCI_INTB, /* PCI int B */
+ PCI_INTC, /* PCI int C */
+ PCI_INTD, /* PCI int D */
+ ATA, /* ATA */
+ FATA, /* CF */
+ POWER, /* Power switch */
+ BUTTON, /* Button switch */
+};
+
+/* Vectors for LANDISK */
+static struct intc_vect vectors_landisk[] __initdata = {
+ INTC_IRQ(PCI_INTA, IRQ_PCIINTA),
+ INTC_IRQ(PCI_INTB, IRQ_PCIINTB),
+ INTC_IRQ(PCI_INTC, IRQ_PCIINTC),
+ INTC_IRQ(PCI_INTD, IRQ_PCIINTD),
+ INTC_IRQ(ATA, IRQ_ATA),
+ INTC_IRQ(FATA, IRQ_FATA),
+ INTC_IRQ(POWER, IRQ_POWER),
+ INTC_IRQ(BUTTON, IRQ_BUTTON),
+};
+
+/* IRLMSK mask register layout for LANDISK */
+static struct intc_mask_reg mask_registers_landisk[] __initdata = {
+ { PA_IMASK, 0, 8, /* IRLMSK */
+ { BUTTON, POWER, FATA, ATA,
+ PCI_INTD, PCI_INTC, PCI_INTB, PCI_INTA,
+ }
+ },
+};
+
+static DECLARE_INTC_DESC(intc_desc_landisk, "landisk", vectors_landisk, NULL,
+ mask_registers_landisk, NULL, NULL);
+/*
+ * Initialize IRQ setting
+ */
+void __init init_landisk_IRQ(void)
+{
+ register_intc_controller(&intc_desc_landisk);
+ __raw_writeb(0x00, PA_PWRINT_CLR);
+}
diff --git a/arch/sh/boards/mach-landisk/psw.c b/arch/sh/boards/mach-landisk/psw.c
new file mode 100644
index 000000000..e171d9af4
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/psw.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/landisk/psw.c
+ *
+ * push switch support for LANDISK and USL-5P
+ *
+ * Copyright (C) 2006-2007 Paul Mundt
+ * Copyright (C) 2007 kogiidena
+ */
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <mach-landisk/mach/iodata_landisk.h>
+#include <asm/push-switch.h>
+
+static irqreturn_t psw_irq_handler(int irq, void *arg)
+{
+ struct platform_device *pdev = arg;
+ struct push_switch *psw = platform_get_drvdata(pdev);
+ struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
+ unsigned int sw_value;
+ int ret = 0;
+
+ sw_value = (0x0ff & (~__raw_readb(PA_STATUS)));
+
+ /* Nothing to do if there's no state change */
+ if (psw->state) {
+ ret = 1;
+ goto out;
+ }
+
+ /* Figure out who raised it */
+ if (sw_value & (1 << psw_info->bit)) {
+ psw->state = 1;
+ mod_timer(&psw->debounce, jiffies + 50);
+ ret = 1;
+ }
+
+out:
+ /* Clear the switch IRQs */
+ __raw_writeb(0x00, PA_PWRINT_CLR);
+
+ return IRQ_RETVAL(ret);
+}
+
+static struct resource psw_power_resources[] = {
+ [0] = {
+ .start = IRQ_POWER,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource psw_usl5p_resources[] = {
+ [0] = {
+ .start = IRQ_BUTTON,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct push_switch_platform_info psw_power_platform_data = {
+ .name = "psw_power",
+ .bit = 4,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw1_platform_data = {
+ .name = "psw1",
+ .bit = 0,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw2_platform_data = {
+ .name = "psw2",
+ .bit = 2,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw3_platform_data = {
+ .name = "psw3",
+ .bit = 1,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct platform_device psw_power_switch_device = {
+ .name = "push-switch",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(psw_power_resources),
+ .resource = psw_power_resources,
+ .dev = {
+ .platform_data = &psw_power_platform_data,
+ },
+};
+
+static struct platform_device psw1_switch_device = {
+ .name = "push-switch",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw1_platform_data,
+ },
+};
+
+static struct platform_device psw2_switch_device = {
+ .name = "push-switch",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw2_platform_data,
+ },
+};
+
+static struct platform_device psw3_switch_device = {
+ .name = "push-switch",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw3_platform_data,
+ },
+};
+
+static struct platform_device *psw_devices[] = {
+ &psw_power_switch_device,
+ &psw1_switch_device,
+ &psw2_switch_device,
+ &psw3_switch_device,
+};
+
+static int __init psw_init(void)
+{
+ return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
+}
+device_initcall(psw_init);
diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c
new file mode 100644
index 000000000..2c44b94f8
--- /dev/null
+++ b/arch/sh/boards/mach-landisk/setup.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/landisk/setup.c
+ *
+ * I-O DATA Device, Inc. LANDISK Support.
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ * Copyright (C) 2002 Paul Mundt
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2005-2007 kogiidena
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/pm.h>
+#include <linux/mm.h>
+#include <asm/machvec.h>
+#include <mach-landisk/mach/iodata_landisk.h>
+#include <asm/io.h>
+
+static void landisk_power_off(void)
+{
+ __raw_writeb(0x01, PA_SHUTDOWN);
+}
+
+static struct resource cf_ide_resources[3];
+
+static struct pata_platform_info pata_info = {
+ .ioport_shift = 1,
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+ .dev = {
+ .platform_data = &pata_info,
+ },
+};
+
+static struct platform_device rtc_device = {
+ .name = "rs5c313",
+ .id = -1,
+};
+
+static struct platform_device *landisk_devices[] __initdata = {
+ &cf_ide_device,
+ &rtc_device,
+};
+
+static int __init landisk_devices_setup(void)
+{
+ pgprot_t prot;
+ unsigned long paddrbase;
+ void *cf_ide_base;
+
+ /* open I/O area window */
+ paddrbase = virt_to_phys((void *)PA_AREA5_IO);
+ prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
+ cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot));
+ if (!cf_ide_base) {
+ printk("allocate_cf_area : can't open CF I/O window!\n");
+ return -ENOMEM;
+ }
+
+ /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
+ cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40;
+ cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f;
+ cf_ide_resources[0].flags = IORESOURCE_IO;
+ cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c;
+ cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03;
+ cf_ide_resources[1].flags = IORESOURCE_IO;
+ cf_ide_resources[2].start = IRQ_FATA;
+ cf_ide_resources[2].flags = IORESOURCE_IRQ;
+
+ return platform_add_devices(landisk_devices,
+ ARRAY_SIZE(landisk_devices));
+}
+
+device_initcall(landisk_devices_setup);
+
+static void __init landisk_setup(char **cmdline_p)
+{
+ /* I/O port identity mapping */
+ __set_io_port_base(0);
+
+ /* LED ON */
+ __raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED);
+
+ printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
+ pm_power_off = landisk_power_off;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_landisk __initmv = {
+ .mv_name = "LANDISK",
+ .mv_setup = landisk_setup,
+ .mv_init_irq = init_landisk_IRQ,
+};
diff --git a/arch/sh/boards/mach-lboxre2/Makefile b/arch/sh/boards/mach-lboxre2/Makefile
new file mode 100644
index 000000000..0fbd08229
--- /dev/null
+++ b/arch/sh/boards/mach-lboxre2/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the L-BOX RE2 specific parts of the kernel
+# Copyright (c) 2007 Nobuhiro Iwamatsu
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-lboxre2/irq.c b/arch/sh/boards/mach-lboxre2/irq.c
new file mode 100644
index 000000000..a250e3b90
--- /dev/null
+++ b/arch/sh/boards/mach-lboxre2/irq.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/lboxre2/irq.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 Support.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <mach/lboxre2.h>
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_lboxre2_IRQ(void)
+{
+ make_imask_irq(IRQ_CF1);
+ make_imask_irq(IRQ_CF0);
+ make_imask_irq(IRQ_INTD);
+ make_imask_irq(IRQ_ETH1);
+ make_imask_irq(IRQ_ETH0);
+ make_imask_irq(IRQ_INTA);
+}
diff --git a/arch/sh/boards/mach-lboxre2/setup.c b/arch/sh/boards/mach-lboxre2/setup.c
new file mode 100644
index 000000000..20d01b430
--- /dev/null
+++ b/arch/sh/boards/mach-lboxre2/setup.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/lbox/setup.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 Support
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <asm/machvec.h>
+#include <asm/addrspace.h>
+#include <mach/lboxre2.h>
+#include <asm/io.h>
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x1f0,
+ .end = 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = 0x1f0 + 0x206,
+ .end = 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = IRQ_CF0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *lboxre2_devices[] __initdata = {
+ &cf_ide_device,
+};
+
+static int __init lboxre2_devices_setup(void)
+{
+ u32 cf0_io_base; /* Boot CF base address */
+ pgprot_t prot;
+ unsigned long paddrbase, psize;
+
+ /* open I/O area window */
+ paddrbase = virt_to_phys((void*)PA_AREA5_IO);
+ psize = PAGE_SIZE;
+ prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
+ cf0_io_base = (u32)ioremap_prot(paddrbase, psize, pgprot_val(prot));
+ if (!cf0_io_base) {
+ printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ );
+ return -ENOMEM;
+ }
+
+ cf_ide_resources[0].start += cf0_io_base ;
+ cf_ide_resources[0].end += cf0_io_base ;
+ cf_ide_resources[1].start += cf0_io_base ;
+ cf_ide_resources[1].end += cf0_io_base ;
+
+ return platform_add_devices(lboxre2_devices,
+ ARRAY_SIZE(lboxre2_devices));
+
+}
+device_initcall(lboxre2_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_lboxre2 __initmv = {
+ .mv_name = "L-BOX RE2",
+ .mv_init_irq = init_lboxre2_IRQ,
+};
diff --git a/arch/sh/boards/mach-microdev/Makefile b/arch/sh/boards/mach-microdev/Makefile
new file mode 100644
index 000000000..05c5698dc
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the SuperH MicroDev specific parts of the kernel
+#
+
+obj-y := setup.o irq.o io.o fdc37c93xapm.o
diff --git a/arch/sh/boards/mach-microdev/fdc37c93xapm.c b/arch/sh/boards/mach-microdev/fdc37c93xapm.c
new file mode 100644
index 000000000..2a04f72dd
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/fdc37c93xapm.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Setup for the SMSC FDC37C93xAPM
+ *
+ * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
+ * Copyright (C) 2003, 2004 SuperH, Inc.
+ * Copyright (C) 2004, 2005 Paul Mundt
+ *
+ * SuperH SH4-202 MicroDev board support.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <mach/microdev.h>
+
+#define SMSC_CONFIG_PORT_ADDR (0x3F0)
+#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR
+#define SMSC_DATA_PORT_ADDR (SMSC_INDEX_PORT_ADDR + 1)
+
+#define SMSC_ENTER_CONFIG_KEY 0x55
+#define SMSC_EXIT_CONFIG_KEY 0xaa
+
+#define SMCS_LOGICAL_DEV_INDEX 0x07 /* Logical Device Number */
+#define SMSC_DEVICE_ID_INDEX 0x20 /* Device ID */
+#define SMSC_DEVICE_REV_INDEX 0x21 /* Device Revision */
+#define SMSC_ACTIVATE_INDEX 0x30 /* Activate */
+#define SMSC_PRIMARY_BASE_INDEX 0x60 /* Primary Base Address */
+#define SMSC_SECONDARY_BASE_INDEX 0x62 /* Secondary Base Address */
+#define SMSC_PRIMARY_INT_INDEX 0x70 /* Primary Interrupt Select */
+#define SMSC_SECONDARY_INT_INDEX 0x72 /* Secondary Interrupt Select */
+#define SMSC_HDCS0_INDEX 0xf0 /* HDCS0 Address Decoder */
+#define SMSC_HDCS1_INDEX 0xf1 /* HDCS1 Address Decoder */
+
+#define SMSC_IDE1_DEVICE 1 /* IDE #1 logical device */
+#define SMSC_IDE2_DEVICE 2 /* IDE #2 logical device */
+#define SMSC_PARALLEL_DEVICE 3 /* Parallel Port logical device */
+#define SMSC_SERIAL1_DEVICE 4 /* Serial #1 logical device */
+#define SMSC_SERIAL2_DEVICE 5 /* Serial #2 logical device */
+#define SMSC_KEYBOARD_DEVICE 7 /* Keyboard logical device */
+#define SMSC_CONFIG_REGISTERS 8 /* Configuration Registers (Aux I/O) */
+
+#define SMSC_READ_INDEXED(index) ({ \
+ outb((index), SMSC_INDEX_PORT_ADDR); \
+ inb(SMSC_DATA_PORT_ADDR); })
+#define SMSC_WRITE_INDEXED(val, index) ({ \
+ outb((index), SMSC_INDEX_PORT_ADDR); \
+ outb((val), SMSC_DATA_PORT_ADDR); })
+
+#define IDE1_PRIMARY_BASE 0x01f0 /* Task File Registe base for IDE #1 */
+#define IDE1_SECONDARY_BASE 0x03f6 /* Miscellaneous AT registers for IDE #1 */
+#define IDE2_PRIMARY_BASE 0x0170 /* Task File Registe base for IDE #2 */
+#define IDE2_SECONDARY_BASE 0x0376 /* Miscellaneous AT registers for IDE #2 */
+
+#define SERIAL1_PRIMARY_BASE 0x03f8
+#define SERIAL2_PRIMARY_BASE 0x02f8
+
+#define MSB(x) ( (x) >> 8 )
+#define LSB(x) ( (x) & 0xff )
+
+ /* General-Purpose base address on CPU-board FPGA */
+#define MICRODEV_FPGA_GP_BASE 0xa6100000ul
+
+static int __init smsc_superio_setup(void)
+{
+
+ unsigned char devid, devrev;
+
+ /* Initially the chip is in run state */
+ /* Put it into configuration state */
+ outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+
+ /* Read device ID info */
+ devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
+ devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
+
+ if ((devid == 0x30) && (devrev == 0x01))
+ printk("SMSC FDC37C93xAPM SuperIO device detected\n");
+ else
+ return -ENODEV;
+
+ /* Select the keyboard device */
+ SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+ /* enable it */
+ SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+ /* enable the interrupts */
+ SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
+ SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
+
+ /* Select the Serial #1 device */
+ SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+ /* enable it */
+ SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+ /* program with port addresses */
+ SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+ SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+ SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
+ /* enable the interrupts */
+ SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
+
+ /* Select the Serial #2 device */
+ SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+ /* enable it */
+ SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+ /* program with port addresses */
+ SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+ SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+ SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
+ /* enable the interrupts */
+ SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
+
+ /* Select the IDE#1 device */
+ SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+ /* enable it */
+ SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+ /* program with port addresses */
+ SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+ SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+ SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
+ SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
+ SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
+ SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
+ /* select the interrupt */
+ SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
+
+ /* Select the IDE#2 device */
+ SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
+ /* enable it */
+ SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
+ /* program with port addresses */
+ SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
+ SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
+ SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
+ SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
+ /* select the interrupt */
+ SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
+
+ /* Select the configuration registers */
+ SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
+ /* enable the appropriate GPIO pins for IDE functionality:
+ * bit[0] In/Out 1==input; 0==output
+ * bit[1] Polarity 1==invert; 0==no invert
+ * bit[2] Int Enb #1 1==Enable Combined IRQ #1; 0==disable
+ * bit[3:4] Function Select 00==original; 01==Alternate Function #1
+ */
+ SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
+ SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
+ SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
+ SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
+ SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
+
+ /* Exit the configuration state */
+ outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
+
+ return 0;
+}
+device_initcall(smsc_superio_setup);
diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c
new file mode 100644
index 000000000..a76c12721
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/io.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/superh/microdev/io.c
+ *
+ * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
+ * Copyright (C) 2003, 2004 SuperH, Inc.
+ * Copyright (C) 2004 Paul Mundt
+ *
+ * SuperH SH4-202 MicroDev board support.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+#include <mach/microdev.h>
+
+ /*
+ * we need to have a 'safe' address to re-direct all I/O requests
+ * that we do not explicitly wish to handle. This safe address
+ * must have the following properies:
+ *
+ * * writes are ignored (no exception)
+ * * reads are benign (no side-effects)
+ * * accesses of width 1, 2 and 4-bytes are all valid.
+ *
+ * The Processor Version Register (PVR) has these properties.
+ */
+#define PVR 0xff000030 /* Processor Version Register */
+
+
+#define IO_IDE2_BASE 0x170ul /* I/O base for SMSC FDC37C93xAPM IDE #2 */
+#define IO_IDE1_BASE 0x1f0ul /* I/O base for SMSC FDC37C93xAPM IDE #1 */
+#define IO_ISP1161_BASE 0x290ul /* I/O port for Philips ISP1161x USB chip */
+#define IO_SERIAL2_BASE 0x2f8ul /* I/O base for SMSC FDC37C93xAPM Serial #2 */
+#define IO_LAN91C111_BASE 0x300ul /* I/O base for SMSC LAN91C111 Ethernet chip */
+#define IO_IDE2_MISC 0x376ul /* I/O misc for SMSC FDC37C93xAPM IDE #2 */
+#define IO_SUPERIO_BASE 0x3f0ul /* I/O base for SMSC FDC37C93xAPM SuperIO chip */
+#define IO_IDE1_MISC 0x3f6ul /* I/O misc for SMSC FDC37C93xAPM IDE #1 */
+#define IO_SERIAL1_BASE 0x3f8ul /* I/O base for SMSC FDC37C93xAPM Serial #1 */
+
+#define IO_ISP1161_EXTENT 0x04ul /* I/O extent for Philips ISP1161x USB chip */
+#define IO_LAN91C111_EXTENT 0x10ul /* I/O extent for SMSC LAN91C111 Ethernet chip */
+#define IO_SUPERIO_EXTENT 0x02ul /* I/O extent for SMSC FDC37C93xAPM SuperIO chip */
+#define IO_IDE_EXTENT 0x08ul /* I/O extent for IDE Task Register set */
+#define IO_SERIAL_EXTENT 0x10ul
+
+#define IO_LAN91C111_PHYS 0xa7500000ul /* Physical address of SMSC LAN91C111 Ethernet chip */
+#define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */
+#define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */
+
+/*
+ * map I/O ports to memory-mapped addresses
+ */
+void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len)
+{
+ unsigned long result;
+
+ if ((offset >= IO_LAN91C111_BASE) &&
+ (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
+ /*
+ * SMSC LAN91C111 Ethernet chip
+ */
+ result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE;
+ } else if ((offset >= IO_SUPERIO_BASE) &&
+ (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) {
+ /*
+ * SMSC FDC37C93xAPM SuperIO chip
+ *
+ * Configuration Registers
+ */
+ result = IO_SUPERIO_PHYS + (offset << 1);
+ } else if (((offset >= IO_IDE1_BASE) &&
+ (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) ||
+ (offset == IO_IDE1_MISC)) {
+ /*
+ * SMSC FDC37C93xAPM SuperIO chip
+ *
+ * IDE #1
+ */
+ result = IO_SUPERIO_PHYS + (offset << 1);
+ } else if (((offset >= IO_IDE2_BASE) &&
+ (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) ||
+ (offset == IO_IDE2_MISC)) {
+ /*
+ * SMSC FDC37C93xAPM SuperIO chip
+ *
+ * IDE #2
+ */
+ result = IO_SUPERIO_PHYS + (offset << 1);
+ } else if ((offset >= IO_SERIAL1_BASE) &&
+ (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) {
+ /*
+ * SMSC FDC37C93xAPM SuperIO chip
+ *
+ * Serial #1
+ */
+ result = IO_SUPERIO_PHYS + (offset << 1);
+ } else if ((offset >= IO_SERIAL2_BASE) &&
+ (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) {
+ /*
+ * SMSC FDC37C93xAPM SuperIO chip
+ *
+ * Serial #2
+ */
+ result = IO_SUPERIO_PHYS + (offset << 1);
+ } else if ((offset >= IO_ISP1161_BASE) &&
+ (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) {
+ /*
+ * Philips USB ISP1161x chip
+ */
+ result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE;
+ } else {
+ /*
+ * safe default.
+ */
+ printk("Warning: unexpected port in %s( offset = 0x%lx )\n",
+ __func__, offset);
+ result = PVR;
+ }
+
+ return (void __iomem *)result;
+}
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
new file mode 100644
index 000000000..dc27492c8
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/superh/microdev/irq.c
+ *
+ * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
+ *
+ * SuperH SH4-202 MicroDev board support.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <mach/microdev.h>
+
+#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */
+
+static const struct {
+ unsigned char fpgaIrq;
+ unsigned char mapped;
+ const char *name;
+} fpgaIrqTable[NUM_EXTERNAL_IRQS] = {
+ { 0, 0, "unused" }, /* IRQ #0 IRL=15 0x200 */
+ { MICRODEV_FPGA_IRQ_KEYBOARD, 1, "keyboard" }, /* IRQ #1 IRL=14 0x220 */
+ { MICRODEV_FPGA_IRQ_SERIAL1, 1, "Serial #1"}, /* IRQ #2 IRL=13 0x240 */
+ { MICRODEV_FPGA_IRQ_ETHERNET, 1, "Ethernet" }, /* IRQ #3 IRL=12 0x260 */
+ { MICRODEV_FPGA_IRQ_SERIAL2, 0, "Serial #2"}, /* IRQ #4 IRL=11 0x280 */
+ { 0, 0, "unused" }, /* IRQ #5 IRL=10 0x2a0 */
+ { 0, 0, "unused" }, /* IRQ #6 IRL=9 0x2c0 */
+ { MICRODEV_FPGA_IRQ_USB_HC, 1, "USB" }, /* IRQ #7 IRL=8 0x2e0 */
+ { MICRODEV_IRQ_PCI_INTA, 1, "PCI INTA" }, /* IRQ #8 IRL=7 0x300 */
+ { MICRODEV_IRQ_PCI_INTB, 1, "PCI INTB" }, /* IRQ #9 IRL=6 0x320 */
+ { MICRODEV_IRQ_PCI_INTC, 1, "PCI INTC" }, /* IRQ #10 IRL=5 0x340 */
+ { MICRODEV_IRQ_PCI_INTD, 1, "PCI INTD" }, /* IRQ #11 IRL=4 0x360 */
+ { MICRODEV_FPGA_IRQ_MOUSE, 1, "mouse" }, /* IRQ #12 IRL=3 0x380 */
+ { MICRODEV_FPGA_IRQ_IDE2, 1, "IDE #2" }, /* IRQ #13 IRL=2 0x3a0 */
+ { MICRODEV_FPGA_IRQ_IDE1, 1, "IDE #1" }, /* IRQ #14 IRL=1 0x3c0 */
+ { 0, 0, "unused" }, /* IRQ #15 IRL=0 0x3e0 */
+};
+
+#if (MICRODEV_LINUX_IRQ_KEYBOARD != 1)
+# error Inconsistancy in defining the IRQ# for Keyboard!
+#endif
+
+#if (MICRODEV_LINUX_IRQ_ETHERNET != 3)
+# error Inconsistancy in defining the IRQ# for Ethernet!
+#endif
+
+#if (MICRODEV_LINUX_IRQ_USB_HC != 7)
+# error Inconsistancy in defining the IRQ# for USB!
+#endif
+
+#if (MICRODEV_LINUX_IRQ_MOUSE != 12)
+# error Inconsistancy in defining the IRQ# for PS/2 Mouse!
+#endif
+
+#if (MICRODEV_LINUX_IRQ_IDE2 != 13)
+# error Inconsistancy in defining the IRQ# for secondary IDE!
+#endif
+
+#if (MICRODEV_LINUX_IRQ_IDE1 != 14)
+# error Inconsistancy in defining the IRQ# for primary IDE!
+#endif
+
+static void disable_microdev_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ unsigned int fpgaIrq;
+
+ if (irq >= NUM_EXTERNAL_IRQS)
+ return;
+ if (!fpgaIrqTable[irq].mapped)
+ return;
+
+ fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
+
+ /* disable interrupts on the FPGA INTC register */
+ __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
+}
+
+static void enable_microdev_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ unsigned long priorityReg, priorities, pri;
+ unsigned int fpgaIrq;
+
+ if (unlikely(irq >= NUM_EXTERNAL_IRQS))
+ return;
+ if (unlikely(!fpgaIrqTable[irq].mapped))
+ return;
+
+ pri = 15 - irq;
+
+ fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
+ priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
+
+ /* set priority for the interrupt */
+ priorities = __raw_readl(priorityReg);
+ priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
+ priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
+ __raw_writel(priorities, priorityReg);
+
+ /* enable interrupts on the FPGA INTC register */
+ __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
+}
+
+static struct irq_chip microdev_irq_type = {
+ .name = "MicroDev-IRQ",
+ .irq_unmask = enable_microdev_irq,
+ .irq_mask = disable_microdev_irq,
+};
+
+/* This function sets the desired irq handler to be a MicroDev type */
+static void __init make_microdev_irq(unsigned int irq)
+{
+ disable_irq_nosync(irq);
+ irq_set_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
+ disable_microdev_irq(irq_get_irq_data(irq));
+}
+
+extern void __init init_microdev_irq(void)
+{
+ int i;
+
+ /* disable interrupts on the FPGA INTC register */
+ __raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG);
+
+ for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
+ make_microdev_irq(i);
+}
+
+extern void microdev_print_fpga_intc_status(void)
+{
+ volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG;
+ volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG;
+ volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0);
+ volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8);
+ volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16);
+ volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24);
+ volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG;
+ volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG;
+
+ printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n");
+ printk("FPGA_INTENB = 0x%08x\n", *intenb);
+ printk("FPGA_INTDSB = 0x%08x\n", *intdsb);
+ printk("FPGA_INTSRC = 0x%08x\n", *intsrc);
+ printk("FPGA_INTREQ = 0x%08x\n", *intreq);
+ printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
+ printk("-------------------------------------------------------------------------------\n");
+}
diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c
new file mode 100644
index 000000000..f4a777fe2
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/setup.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/superh/microdev/setup.c
+ *
+ * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
+ * Copyright (C) 2003, 2004 SuperH, Inc.
+ * Copyright (C) 2004, 2005 Paul Mundt
+ *
+ * SuperH SH4-202 MicroDev board support.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <video/s1d13xxxfb.h>
+#include <mach/microdev.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <linux/sizes.h>
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = 0x300,
+ .end = 0x300 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MICRODEV_LINUX_IRQ_ETHERNET,
+ .end = MICRODEV_LINUX_IRQ_ETHERNET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct s1d13xxxfb_regval s1d13806_initregs[] = {
+ { S1DREG_MISC, 0x00 },
+ { S1DREG_COM_DISP_MODE, 0x00 },
+ { S1DREG_GPIO_CNF0, 0x00 },
+ { S1DREG_GPIO_CNF1, 0x00 },
+ { S1DREG_GPIO_CTL0, 0x00 },
+ { S1DREG_GPIO_CTL1, 0x00 },
+ { S1DREG_CLK_CNF, 0x02 },
+ { S1DREG_LCD_CLK_CNF, 0x01 },
+ { S1DREG_CRT_CLK_CNF, 0x03 },
+ { S1DREG_MPLUG_CLK_CNF, 0x03 },
+ { S1DREG_CPU2MEM_WST_SEL, 0x02 },
+ { S1DREG_SDRAM_REF_RATE, 0x03 },
+ { S1DREG_SDRAM_TC0, 0x00 },
+ { S1DREG_SDRAM_TC1, 0x01 },
+ { S1DREG_MEM_CNF, 0x80 },
+ { S1DREG_PANEL_TYPE, 0x25 },
+ { S1DREG_MOD_RATE, 0x00 },
+ { S1DREG_LCD_DISP_HWIDTH, 0x63 },
+ { S1DREG_LCD_NDISP_HPER, 0x1e },
+ { S1DREG_TFT_FPLINE_START, 0x06 },
+ { S1DREG_TFT_FPLINE_PWIDTH, 0x03 },
+ { S1DREG_LCD_DISP_VHEIGHT0, 0x57 },
+ { S1DREG_LCD_DISP_VHEIGHT1, 0x02 },
+ { S1DREG_LCD_NDISP_VPER, 0x00 },
+ { S1DREG_TFT_FPFRAME_START, 0x0a },
+ { S1DREG_TFT_FPFRAME_PWIDTH, 0x81 },
+ { S1DREG_LCD_DISP_MODE, 0x03 },
+ { S1DREG_LCD_MISC, 0x00 },
+ { S1DREG_LCD_DISP_START0, 0x00 },
+ { S1DREG_LCD_DISP_START1, 0x00 },
+ { S1DREG_LCD_DISP_START2, 0x00 },
+ { S1DREG_LCD_MEM_OFF0, 0x90 },
+ { S1DREG_LCD_MEM_OFF1, 0x01 },
+ { S1DREG_LCD_PIX_PAN, 0x00 },
+ { S1DREG_LCD_DISP_FIFO_HTC, 0x00 },
+ { S1DREG_LCD_DISP_FIFO_LTC, 0x00 },
+ { S1DREG_CRT_DISP_HWIDTH, 0x63 },
+ { S1DREG_CRT_NDISP_HPER, 0x1f },
+ { S1DREG_CRT_HRTC_START, 0x04 },
+ { S1DREG_CRT_HRTC_PWIDTH, 0x8f },
+ { S1DREG_CRT_DISP_VHEIGHT0, 0x57 },
+ { S1DREG_CRT_DISP_VHEIGHT1, 0x02 },
+ { S1DREG_CRT_NDISP_VPER, 0x1b },
+ { S1DREG_CRT_VRTC_START, 0x00 },
+ { S1DREG_CRT_VRTC_PWIDTH, 0x83 },
+ { S1DREG_TV_OUT_CTL, 0x10 },
+ { S1DREG_CRT_DISP_MODE, 0x05 },
+ { S1DREG_CRT_DISP_START0, 0x00 },
+ { S1DREG_CRT_DISP_START1, 0x00 },
+ { S1DREG_CRT_DISP_START2, 0x00 },
+ { S1DREG_CRT_MEM_OFF0, 0x20 },
+ { S1DREG_CRT_MEM_OFF1, 0x03 },
+ { S1DREG_CRT_PIX_PAN, 0x00 },
+ { S1DREG_CRT_DISP_FIFO_HTC, 0x00 },
+ { S1DREG_CRT_DISP_FIFO_LTC, 0x00 },
+ { S1DREG_LCD_CUR_CTL, 0x00 },
+ { S1DREG_LCD_CUR_START, 0x01 },
+ { S1DREG_LCD_CUR_XPOS0, 0x00 },
+ { S1DREG_LCD_CUR_XPOS1, 0x00 },
+ { S1DREG_LCD_CUR_YPOS0, 0x00 },
+ { S1DREG_LCD_CUR_YPOS1, 0x00 },
+ { S1DREG_LCD_CUR_BCTL0, 0x00 },
+ { S1DREG_LCD_CUR_GCTL0, 0x00 },
+ { S1DREG_LCD_CUR_RCTL0, 0x00 },
+ { S1DREG_LCD_CUR_BCTL1, 0x1f },
+ { S1DREG_LCD_CUR_GCTL1, 0x3f },
+ { S1DREG_LCD_CUR_RCTL1, 0x1f },
+ { S1DREG_LCD_CUR_FIFO_HTC, 0x00 },
+ { S1DREG_CRT_CUR_CTL, 0x00 },
+ { S1DREG_CRT_CUR_START, 0x01 },
+ { S1DREG_CRT_CUR_XPOS0, 0x00 },
+ { S1DREG_CRT_CUR_XPOS1, 0x00 },
+ { S1DREG_CRT_CUR_YPOS0, 0x00 },
+ { S1DREG_CRT_CUR_YPOS1, 0x00 },
+ { S1DREG_CRT_CUR_BCTL0, 0x00 },
+ { S1DREG_CRT_CUR_GCTL0, 0x00 },
+ { S1DREG_CRT_CUR_RCTL0, 0x00 },
+ { S1DREG_CRT_CUR_BCTL1, 0x1f },
+ { S1DREG_CRT_CUR_GCTL1, 0x3f },
+ { S1DREG_CRT_CUR_RCTL1, 0x1f },
+ { S1DREG_CRT_CUR_FIFO_HTC, 0x00 },
+ { S1DREG_BBLT_CTL0, 0x00 },
+ { S1DREG_BBLT_CTL1, 0x00 },
+ { S1DREG_BBLT_CC_EXP, 0x00 },
+ { S1DREG_BBLT_OP, 0x00 },
+ { S1DREG_BBLT_SRC_START0, 0x00 },
+ { S1DREG_BBLT_SRC_START1, 0x00 },
+ { S1DREG_BBLT_SRC_START2, 0x00 },
+ { S1DREG_BBLT_DST_START0, 0x00 },
+ { S1DREG_BBLT_DST_START1, 0x00 },
+ { S1DREG_BBLT_DST_START2, 0x00 },
+ { S1DREG_BBLT_MEM_OFF0, 0x00 },
+ { S1DREG_BBLT_MEM_OFF1, 0x00 },
+ { S1DREG_BBLT_WIDTH0, 0x00 },
+ { S1DREG_BBLT_WIDTH1, 0x00 },
+ { S1DREG_BBLT_HEIGHT0, 0x00 },
+ { S1DREG_BBLT_HEIGHT1, 0x00 },
+ { S1DREG_BBLT_BGC0, 0x00 },
+ { S1DREG_BBLT_BGC1, 0x00 },
+ { S1DREG_BBLT_FGC0, 0x00 },
+ { S1DREG_BBLT_FGC1, 0x00 },
+ { S1DREG_LKUP_MODE, 0x00 },
+ { S1DREG_LKUP_ADDR, 0x00 },
+ { S1DREG_PS_CNF, 0x10 },
+ { S1DREG_PS_STATUS, 0x00 },
+ { S1DREG_CPU2MEM_WDOGT, 0x00 },
+ { S1DREG_COM_DISP_MODE, 0x02 },
+};
+
+static struct s1d13xxxfb_pdata s1d13806_platform_data = {
+ .initregs = s1d13806_initregs,
+ .initregssize = ARRAY_SIZE(s1d13806_initregs),
+};
+
+static struct resource s1d13806_resources[] = {
+ [0] = {
+ .start = 0x07200000,
+ .end = 0x07200000 + SZ_2M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x07000000,
+ .end = 0x07000000 + SZ_2M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device s1d13806_device = {
+ .name = "s1d13806fb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s1d13806_resources),
+ .resource = s1d13806_resources,
+
+ .dev = {
+ .platform_data = &s1d13806_platform_data,
+ },
+};
+
+static struct platform_device *microdev_devices[] __initdata = {
+ &smc91x_device,
+ &s1d13806_device,
+};
+
+static int __init microdev_devices_setup(void)
+{
+ return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
+}
+device_initcall(microdev_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_sh4202_microdev __initmv = {
+ .mv_name = "SH4-202 MicroDev",
+ .mv_ioport_map = microdev_ioport_map,
+ .mv_init_irq = init_microdev_irq,
+};
diff --git a/arch/sh/boards/mach-migor/Kconfig b/arch/sh/boards/mach-migor/Kconfig
new file mode 100644
index 000000000..fb64a10e2
--- /dev/null
+++ b/arch/sh/boards/mach-migor/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+if SH_MIGOR
+
+choice
+ prompt "Migo-R LCD Panel Board Selection"
+ default SH_MIGOR_QVGA
+
+config SH_MIGOR_QVGA
+ bool "QVGA (320x240)"
+
+config SH_MIGOR_RTA_WVGA
+ bool "RTA WVGA (800x480)"
+
+endchoice
+
+endif
diff --git a/arch/sh/boards/mach-migor/Makefile b/arch/sh/boards/mach-migor/Makefile
new file mode 100644
index 000000000..c223d759f
--- /dev/null
+++ b/arch/sh/boards/mach-migor/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := setup.o sdram.o
+obj-$(CONFIG_SH_MIGOR_QVGA) += lcd_qvga.o
diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c
new file mode 100644
index 000000000..4ebf13051
--- /dev/null
+++ b/arch/sh/boards/mach-migor/lcd_qvga.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for SuperH MigoR Quarter VGA LCD Panel
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Based on lcd_powertip.c from Kenati Technologies Pvt Ltd.
+ * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>,
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <video/sh_mobile_lcdc.h>
+#include <cpu/sh7722.h>
+#include <mach/migor.h>
+
+/* LCD Module is a PH240320T according to board schematics. This module
+ * is made up of a 240x320 LCD hooked up to a R61505U (or HX8347-A01?)
+ * Driver IC. This IC is connected to the SH7722 built-in LCDC using a
+ * SYS-80 interface configured in 16 bit mode.
+ *
+ * Index 0: "Device Code Read" returns 0x1505.
+ */
+
+static void reset_lcd_module(void)
+{
+ gpio_set_value(GPIO_PTH2, 0);
+ mdelay(2);
+ gpio_set_value(GPIO_PTH2, 1);
+ mdelay(1);
+}
+
+/* DB0-DB7 are connected to D1-D8, and DB8-DB15 to D10-D17 */
+
+static unsigned long adjust_reg18(unsigned short data)
+{
+ unsigned long tmp1, tmp2;
+
+ tmp1 = (data<<1 | 0x00000001) & 0x000001FF;
+ tmp2 = (data<<2 | 0x00000200) & 0x0003FE00;
+ return tmp1 | tmp2;
+}
+
+static void write_reg(void *sys_ops_handle,
+ struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
+ unsigned short reg, unsigned short data)
+{
+ sys_ops->write_index(sys_ops_handle, adjust_reg18(reg << 8 | data));
+}
+
+static void write_reg16(void *sys_ops_handle,
+ struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
+ unsigned short reg, unsigned short data)
+{
+ sys_ops->write_index(sys_ops_handle, adjust_reg18(reg));
+ sys_ops->write_data(sys_ops_handle, adjust_reg18(data));
+}
+
+static unsigned long read_reg16(void *sys_ops_handle,
+ struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
+ unsigned short reg)
+{
+ unsigned long data;
+
+ sys_ops->write_index(sys_ops_handle, adjust_reg18(reg));
+ data = sys_ops->read_data(sys_ops_handle);
+ return ((data >> 1) & 0xff) | ((data >> 2) & 0xff00);
+}
+
+static void migor_lcd_qvga_seq(void *sys_ops_handle,
+ struct sh_mobile_lcdc_sys_bus_ops *sys_ops,
+ unsigned short const *data, int no_data)
+{
+ int i;
+
+ for (i = 0; i < no_data; i += 2)
+ write_reg16(sys_ops_handle, sys_ops, data[i], data[i + 1]);
+}
+
+static const unsigned short sync_data[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const unsigned short magic0_data[] = {
+ 0x0060, 0x2700, 0x0008, 0x0808, 0x0090, 0x001A, 0x0007, 0x0001,
+ 0x0017, 0x0001, 0x0019, 0x0000, 0x0010, 0x17B0, 0x0011, 0x0116,
+ 0x0012, 0x0198, 0x0013, 0x1400, 0x0029, 0x000C, 0x0012, 0x01B8,
+};
+
+static const unsigned short magic1_data[] = {
+ 0x0030, 0x0307, 0x0031, 0x0303, 0x0032, 0x0603, 0x0033, 0x0202,
+ 0x0034, 0x0202, 0x0035, 0x0202, 0x0036, 0x1F1F, 0x0037, 0x0303,
+ 0x0038, 0x0303, 0x0039, 0x0603, 0x003A, 0x0202, 0x003B, 0x0102,
+ 0x003C, 0x0204, 0x003D, 0x0000, 0x0001, 0x0100, 0x0002, 0x0300,
+ 0x0003, 0x5028, 0x0020, 0x00ef, 0x0021, 0x0000, 0x0004, 0x0000,
+ 0x0009, 0x0000, 0x000A, 0x0008, 0x000C, 0x0000, 0x000D, 0x0000,
+ 0x0015, 0x8000,
+};
+
+static const unsigned short magic2_data[] = {
+ 0x0061, 0x0001, 0x0092, 0x0100, 0x0093, 0x0001, 0x0007, 0x0021,
+};
+
+static const unsigned short magic3_data[] = {
+ 0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061,
+};
+
+int migor_lcd_qvga_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+ unsigned long xres = 320;
+ unsigned long yres = 240;
+ int k;
+
+ reset_lcd_module();
+ migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
+
+ if (read_reg16(sohandle, so, 0) != 0x1505)
+ return -ENODEV;
+
+ pr_info("Migo-R QVGA LCD Module detected.\n");
+
+ migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data));
+ write_reg16(sohandle, so, 0x00A4, 0x0001);
+ mdelay(10);
+
+ migor_lcd_qvga_seq(sohandle, so, magic0_data, ARRAY_SIZE(magic0_data));
+ mdelay(100);
+
+ migor_lcd_qvga_seq(sohandle, so, magic1_data, ARRAY_SIZE(magic1_data));
+ write_reg16(sohandle, so, 0x0050, 0xef - (yres - 1));
+ write_reg16(sohandle, so, 0x0051, 0x00ef);
+ write_reg16(sohandle, so, 0x0052, 0x0000);
+ write_reg16(sohandle, so, 0x0053, xres - 1);
+
+ migor_lcd_qvga_seq(sohandle, so, magic2_data, ARRAY_SIZE(magic2_data));
+ mdelay(10);
+
+ migor_lcd_qvga_seq(sohandle, so, magic3_data, ARRAY_SIZE(magic3_data));
+ mdelay(40);
+
+ /* clear GRAM to avoid displaying garbage */
+
+ write_reg16(sohandle, so, 0x0020, 0x0000); /* horiz addr */
+ write_reg16(sohandle, so, 0x0021, 0x0000); /* vert addr */
+
+ for (k = 0; k < (xres * 256); k++) /* yes, 256 words per line */
+ write_reg16(sohandle, so, 0x0022, 0x0000);
+
+ write_reg16(sohandle, so, 0x0020, 0x0000); /* reset horiz addr */
+ write_reg16(sohandle, so, 0x0021, 0x0000); /* reset vert addr */
+ write_reg16(sohandle, so, 0x0007, 0x0173);
+ mdelay(40);
+
+ /* enable display */
+ write_reg(sohandle, so, 0x00, 0x22);
+ mdelay(100);
+ return 0;
+}
diff --git a/arch/sh/boards/mach-migor/sdram.S b/arch/sh/boards/mach-migor/sdram.S
new file mode 100644
index 000000000..3a6bee127
--- /dev/null
+++ b/arch/sh/boards/mach-migor/sdram.S
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Migo-R sdram self/auto-refresh setup code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+ .balign 4
+ENTRY(migor_sdram_enter_start)
+
+ /* SBSC: disable power down and put in self-refresh mode */
+ mov.l 1f, r4
+ mov.l 2f, r1
+ mov.l @r4, r2
+ or r1, r2
+ mov.l 3f, r3
+ and r3, r2
+ mov.l r2, @r4
+
+ rts
+ nop
+
+ .balign 4
+1: .long 0xfe400008 /* SDCR0 */
+2: .long 0x00000400
+3: .long 0xffff7fff
+ENTRY(migor_sdram_enter_end)
+
+ .balign 4
+ENTRY(migor_sdram_leave_start)
+
+ /* SBSC: set auto-refresh mode */
+ mov.l 1f, r4
+ mov.l @r4, r0
+ mov.l 4f, r1
+ and r1, r0
+ mov.l r0, @r4
+ mov.l 6f, r4
+ mov.l 8f, r0
+ mov.l @r4, r1
+ mov #-1, r4
+ add r4, r1
+ or r1, r0
+ mov.l 7f, r1
+ mov.l r0, @r1
+
+ rts
+ nop
+
+ .balign 4
+1: .long 0xfe400008 /* SDCR0 */
+4: .long 0xfffffbff
+6: .long 0xfe40001c /* RTCOR */
+7: .long 0xfe400018 /* RTCNT */
+8: .long 0xa55a0000
+ENTRY(migor_sdram_leave_end)
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
new file mode 100644
index 000000000..773ee767d
--- /dev/null
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -0,0 +1,649 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas System Solutions Asia Pte. Ltd - Migo-R
+ *
+ * Copyright (C) 2008 Magnus Damm
+ */
+#include <linux/clkdev.h>
+#include <linux/dma-map-ops.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/memblock.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mtd/platnand.h>
+#include <linux/i2c.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smc91x.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/videodev2.h>
+#include <linux/sh_intc.h>
+#include <video/sh_mobile_lcdc.h>
+#include <media/drv-intf/renesas-ceu.h>
+#include <media/i2c/ov772x.h>
+#include <media/i2c/tw9910.h>
+#include <asm/clock.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/suspend.h>
+#include <mach/migor.h>
+#include <cpu/sh7722.h>
+
+/* Address IRQ Size Bus Description
+ * 0x00000000 64MB 16 NOR Flash (SP29PL256N)
+ * 0x0c000000 64MB 64 SDRAM (2xK4M563233G)
+ * 0x10000000 IRQ0 16 Ethernet (SMC91C111)
+ * 0x14000000 IRQ4 16 USB 2.0 Host Controller (M66596)
+ * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A)
+ */
+
+#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
+static phys_addr_t ceu_dma_membase;
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "SMC91C111" ,
+ .start = 0x10000300,
+ .end = 0x1000030f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x600), /* IRQ0 */
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+static struct sh_keysc_info sh_keysc_info = {
+ .mode = SH_KEYSC_MODE_2, /* KEYOUT0->4, KEYIN1->5 */
+ .scan_timing = 3,
+ .delay = 5,
+ .keycodes = {
+ 0, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER,
+ 0, KEY_F, KEY_C, KEY_D, KEY_H, KEY_1,
+ 0, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
+ 0, KEY_7, KEY_8, KEY_9, KEY_S, KEY_0,
+ 0, KEY_P, KEY_STOP, KEY_REWIND, KEY_PLAY, KEY_FASTFORWARD,
+ },
+};
+
+static struct resource sh_keysc_resources[] = {
+ [0] = {
+ .start = 0x044b0000,
+ .end = 0x044b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xbe0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* "keysc0" clock */
+ .num_resources = ARRAY_SIZE(sh_keysc_resources),
+ .resource = sh_keysc_resources,
+ .dev = {
+ .platform_data = &sh_keysc_info,
+ },
+};
+
+static struct mtd_partition migor_nor_flash_partitions[] =
+{
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (1 * 1024 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (15 * 1024 * 1024),
+ },
+ {
+ .name = "other",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data migor_nor_flash_data = {
+ .width = 2,
+ .parts = migor_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(migor_nor_flash_partitions),
+};
+
+static struct resource migor_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device migor_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = migor_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(migor_nor_flash_resources),
+ .dev = {
+ .platform_data = &migor_nor_flash_data,
+ },
+};
+
+static struct mtd_partition migor_nand_flash_partitions[] = {
+ {
+ .name = "nanddata1",
+ .offset = 0x0,
+ .size = 512 * 1024 * 1024,
+ },
+ {
+ .name = "nanddata2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024 * 1024,
+ },
+};
+
+static void migor_nand_flash_cmd_ctl(struct nand_chip *chip, int cmd,
+ unsigned int ctrl)
+{
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, chip->legacy.IO_ADDR_W + 0x00400000);
+ else if (ctrl & NAND_ALE)
+ writeb(cmd, chip->legacy.IO_ADDR_W + 0x00800000);
+ else
+ writeb(cmd, chip->legacy.IO_ADDR_W);
+}
+
+static int migor_nand_flash_ready(struct nand_chip *chip)
+{
+ return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
+}
+
+static struct platform_nand_data migor_nand_flash_data = {
+ .chip = {
+ .nr_chips = 1,
+ .partitions = migor_nand_flash_partitions,
+ .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions),
+ .chip_delay = 20,
+ },
+ .ctrl = {
+ .dev_ready = migor_nand_flash_ready,
+ .cmd_ctrl = migor_nand_flash_cmd_ctl,
+ },
+};
+
+static struct resource migor_nand_flash_resources[] = {
+ [0] = {
+ .name = "NAND Flash",
+ .start = 0x18000000,
+ .end = 0x18ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device migor_nand_flash_device = {
+ .name = "gen_nand",
+ .resource = migor_nand_flash_resources,
+ .num_resources = ARRAY_SIZE(migor_nand_flash_resources),
+ .dev = {
+ .platform_data = &migor_nand_flash_data,
+ }
+};
+
+static const struct fb_videomode migor_lcd_modes[] = {
+ {
+#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
+ .name = "LB070WV1",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 64,
+ .right_margin = 16,
+ .hsync_len = 120,
+ .sync = 0,
+#elif defined(CONFIG_SH_MIGOR_QVGA)
+ .name = "PH240320T",
+ .xres = 320,
+ .yres = 240,
+ .left_margin = 0,
+ .right_margin = 16,
+ .hsync_len = 8,
+ .sync = FB_SYNC_HOR_HIGH_ACT,
+#endif
+ .upper_margin = 1,
+ .lower_margin = 17,
+ .vsync_len = 2,
+ },
+};
+
+static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
+#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = RGB16,
+ .clock_divider = 2,
+ .lcd_modes = migor_lcd_modes,
+ .num_modes = ARRAY_SIZE(migor_lcd_modes),
+ .panel_cfg = { /* 7.0 inch */
+ .width = 152,
+ .height = 91,
+ },
+ }
+#elif defined(CONFIG_SH_MIGOR_QVGA)
+ .clock_source = LCDC_CLK_PERIPHERAL,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = SYS16A,
+ .clock_divider = 10,
+ .lcd_modes = migor_lcd_modes,
+ .num_modes = ARRAY_SIZE(migor_lcd_modes),
+ .panel_cfg = {
+ .width = 49, /* 2.4 inch */
+ .height = 37,
+ .setup_sys = migor_lcd_qvga_setup,
+ },
+ .sys_bus_cfg = {
+ .ldmt2r = 0x06000a09,
+ .ldmt3r = 0x180e3418,
+ /* set 1s delay to encourage fsync() */
+ .deferred_io_msec = 1000,
+ },
+ }
+#endif
+};
+
+static struct resource migor_lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe942fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device migor_lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(migor_lcdc_resources),
+ .resource = migor_lcdc_resources,
+ .dev = {
+ .platform_data = &sh_mobile_lcdc_info,
+ },
+};
+
+static struct ceu_platform_data ceu_pdata = {
+ .num_subdevs = 2,
+ .subdevs = {
+ { /* [0] = ov772x */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 0,
+ .i2c_address = 0x21,
+ },
+ { /* [1] = tw9910 */
+ .flags = 0,
+ .bus_width = 8,
+ .bus_shift = 0,
+ .i2c_adapter_id = 0,
+ .i2c_address = 0x45,
+ },
+ },
+};
+
+static struct resource migor_ceu_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device migor_ceu_device = {
+ .name = "renesas-ceu",
+ .id = 0, /* ceu.0 */
+ .num_resources = ARRAY_SIZE(migor_ceu_resources),
+ .resource = migor_ceu_resources,
+ .dev = {
+ .platform_data = &ceu_pdata,
+ },
+};
+
+/* Powerdown/reset gpios for CEU image sensors */
+static struct gpiod_lookup_table ov7725_gpios = {
+ .dev_id = "0-0021",
+ .table = {
+ GPIO_LOOKUP("sh7722_pfc", GPIO_PTT0, "powerdown",
+ GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sh7722_pfc", GPIO_PTT3, "reset", GPIO_ACTIVE_LOW),
+ },
+};
+
+static struct gpiod_lookup_table tw9910_gpios = {
+ .dev_id = "0-0045",
+ .table = {
+ GPIO_LOOKUP("sh7722_pfc", GPIO_PTT2, "pdn", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("sh7722_pfc", GPIO_PTT3, "rstb", GPIO_ACTIVE_LOW),
+ },
+};
+
+/* Fixed 3.3V regulator to be used by SDHI0 */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct resource sdhi_cn9_resources[] = {
+ [0] = {
+ .name = "SDHI",
+ .start = 0x04ce0000,
+ .end = 0x04ce00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xe80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sh7724_sdhi_data = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX,
+ .capabilities = MMC_CAP_SDIO_IRQ,
+};
+
+static struct platform_device sdhi_cn9_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi_cn9_resources),
+ .resource = sdhi_cn9_resources,
+ .dev = {
+ .platform_data = &sh7724_sdhi_data,
+ },
+};
+
+static struct ov772x_camera_info ov7725_info = {
+ .flags = 0,
+};
+
+static struct tw9910_video_info tw9910_info = {
+ .buswidth = 8,
+ .mpout = TW9910_MPO_FIELD,
+};
+
+static struct i2c_board_info migor_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rs5c372b", 0x32),
+ },
+ {
+ I2C_BOARD_INFO("migor_ts", 0x51),
+ .irq = evt2irq(0x6c0), /* IRQ6 */
+ },
+ {
+ I2C_BOARD_INFO("wm8978", 0x1a),
+ },
+ {
+ I2C_BOARD_INFO("ov772x", 0x21),
+ .platform_data = &ov7725_info,
+ },
+ {
+ I2C_BOARD_INFO("tw9910", 0x45),
+ .platform_data = &tw9910_info,
+ },
+};
+
+static struct platform_device *migor_devices[] __initdata = {
+ &smc91x_eth_device,
+ &sh_keysc_device,
+ &migor_lcdc_device,
+ &migor_nor_flash_device,
+ &migor_nand_flash_device,
+ &sdhi_cn9_device,
+};
+
+extern char migor_sdram_enter_start;
+extern char migor_sdram_enter_end;
+extern char migor_sdram_leave_start;
+extern char migor_sdram_leave_end;
+
+static int __init migor_devices_setup(void)
+{
+ struct clk *video_clk;
+
+ /* register board specific self-refresh code */
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
+ &migor_sdram_enter_start,
+ &migor_sdram_enter_end,
+ &migor_sdram_leave_start,
+ &migor_sdram_leave_end);
+
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+ /* Let D11 LED show STATUS0 */
+ gpio_request(GPIO_FN_STATUS0, NULL);
+
+ /* Lit D12 LED show PDSTATUS */
+ gpio_request(GPIO_FN_PDSTATUS, NULL);
+
+ /* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */
+ gpio_request(GPIO_FN_IRQ0, NULL);
+ __raw_writel(0x00003400, BSC_CS4BCR);
+ __raw_writel(0x00110080, BSC_CS4WCR);
+
+ /* KEYSC */
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+ gpio_request(GPIO_FN_KEYIN1, NULL);
+ gpio_request(GPIO_FN_KEYIN2, NULL);
+ gpio_request(GPIO_FN_KEYIN3, NULL);
+ gpio_request(GPIO_FN_KEYIN4, NULL);
+ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+
+ /* NAND Flash */
+ gpio_request(GPIO_FN_CS6A_CE2B, NULL);
+ __raw_writel((__raw_readl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
+ gpio_request(GPIO_PTA1, NULL);
+ gpio_direction_input(GPIO_PTA1);
+
+ /* SDHI */
+ gpio_request(GPIO_FN_SDHICD, NULL);
+ gpio_request(GPIO_FN_SDHIWP, NULL);
+ gpio_request(GPIO_FN_SDHID3, NULL);
+ gpio_request(GPIO_FN_SDHID2, NULL);
+ gpio_request(GPIO_FN_SDHID1, NULL);
+ gpio_request(GPIO_FN_SDHID0, NULL);
+ gpio_request(GPIO_FN_SDHICMD, NULL);
+ gpio_request(GPIO_FN_SDHICLK, NULL);
+
+ /* Touch Panel */
+ gpio_request(GPIO_FN_IRQ6, NULL);
+
+ /* LCD Panel */
+#ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDRS, NULL);
+ gpio_request(GPIO_FN_LCDCS, NULL);
+ gpio_request(GPIO_FN_LCDRD, NULL);
+ gpio_request(GPIO_FN_LCDWR, NULL);
+ gpio_request(GPIO_PTH2, NULL); /* LCD_DON */
+ gpio_direction_output(GPIO_PTH2, 1);
+#endif
+#ifdef CONFIG_SH_MIGOR_RTA_WVGA /* LCDC - WVGA - Enable RGB Interface signals */
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDLCLK, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+ gpio_request(GPIO_FN_LCDVEPWC, NULL);
+ gpio_request(GPIO_FN_LCDVCPWC, NULL);
+ gpio_request(GPIO_FN_LCDVSYN, NULL);
+ gpio_request(GPIO_FN_LCDHSYN, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDON, NULL);
+#endif
+
+ /* CEU */
+ gpio_request(GPIO_FN_VIO_CLK2, NULL);
+ gpio_request(GPIO_FN_VIO_VD2, NULL);
+ gpio_request(GPIO_FN_VIO_HD2, NULL);
+ gpio_request(GPIO_FN_VIO_FLD, NULL);
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+ gpio_request(GPIO_FN_VIO_D15, NULL);
+ gpio_request(GPIO_FN_VIO_D14, NULL);
+ gpio_request(GPIO_FN_VIO_D13, NULL);
+ gpio_request(GPIO_FN_VIO_D12, NULL);
+ gpio_request(GPIO_FN_VIO_D11, NULL);
+ gpio_request(GPIO_FN_VIO_D10, NULL);
+ gpio_request(GPIO_FN_VIO_D9, NULL);
+ gpio_request(GPIO_FN_VIO_D8, NULL);
+
+ __raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
+
+ /* SIU: Port B */
+ gpio_request(GPIO_FN_SIUBOLR, NULL);
+ gpio_request(GPIO_FN_SIUBOBT, NULL);
+ gpio_request(GPIO_FN_SIUBISLD, NULL);
+ gpio_request(GPIO_FN_SIUBOSLD, NULL);
+ gpio_request(GPIO_FN_SIUMCKB, NULL);
+
+ /*
+ * The original driver sets SIUB OLR/OBT, ILR/IBT, and SIUA OLR/OBT to
+ * output. Need only SIUB, set to output for master mode (table 34.2)
+ */
+ __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA);
+
+ /*
+ * Use 10 MHz VIO_CKO instead of 24 MHz to work around signal quality
+ * issues on Panel Board V2.1.
+ */
+ video_clk = clk_get(NULL, "video_clk");
+ if (!IS_ERR(video_clk)) {
+ clk_set_rate(video_clk, clk_round_rate(video_clk, 10000000));
+ clk_put(video_clk);
+ }
+
+ /* Add a clock alias for ov7725 xclk source. */
+ clk_add_alias(NULL, "0-0021", "video_clk", NULL);
+
+ /* Register GPIOs for video sources. */
+ gpiod_add_lookup_table(&ov7725_gpios);
+ gpiod_add_lookup_table(&tw9910_gpios);
+
+ i2c_register_board_info(0, migor_i2c_devices,
+ ARRAY_SIZE(migor_i2c_devices));
+
+ /* Initialize CEU platform device separately to map memory first */
+ device_initialize(&migor_ceu_device.dev);
+ dma_declare_coherent_memory(&migor_ceu_device.dev,
+ ceu_dma_membase, ceu_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+
+ platform_device_add(&migor_ceu_device);
+
+ return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
+}
+arch_initcall(migor_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int migor_mode_pins(void)
+{
+ /* MD0=1, MD1=1, MD2=0: Clock Mode 3
+ * MD3=0: 16-bit Area0 Bus Width
+ * MD5=1: Little Endian
+ * TSTMD=1, MD8=0: Test Mode Disabled
+ */
+ return MODE_PIN0 | MODE_PIN1 | MODE_PIN5;
+}
+
+/* Reserve a portion of memory for CEU buffers */
+static void __init migor_mv_mem_reserve(void)
+{
+ phys_addr_t phys;
+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+
+ ceu_dma_membase = phys;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_migor __initmv = {
+ .mv_name = "Migo-R",
+ .mv_mode_pins = migor_mode_pins,
+ .mv_mem_reserve = migor_mv_mem_reserve,
+};
diff --git a/arch/sh/boards/mach-r2d/Kconfig b/arch/sh/boards/mach-r2d/Kconfig
new file mode 100644
index 000000000..21770e668
--- /dev/null
+++ b/arch/sh/boards/mach-r2d/Kconfig
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0
+if SH_RTS7751R2D
+
+menu "RTS7751R2D Board Revision"
+
+config RTS7751R2D_PLUS
+ bool "R2D-PLUS"
+ help
+ Selecting this option will configure the kernel for R2D-PLUS.
+
+ R2D-PLUS is the smaller of the two R2D board versions, equipped
+ with a single PCI slot.
+
+config RTS7751R2D_1
+ bool "R2D-1"
+ help
+ Selecting this option will configure the kernel for R2D-1.
+
+ R2D-1 is the larger of the two R2D board versions, equipped
+ with two PCI slots.
+endmenu
+
+endif
+
diff --git a/arch/sh/boards/mach-r2d/Makefile b/arch/sh/boards/mach-r2d/Makefile
new file mode 100644
index 000000000..7e7ac5e05
--- /dev/null
+++ b/arch/sh/boards/mach-r2d/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the RTS7751R2D specific parts of the kernel
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c
new file mode 100644
index 000000000..d0a54a9ad
--- /dev/null
+++ b/arch/sh/boards/mach-r2d/irq.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/renesas/rts7751r2d/irq.c
+ *
+ * Copyright (C) 2007 Magnus Damm
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Renesas Technology Sales RTS7751R2D Support, R2D-PLUS and R2D-1.
+ *
+ * Modified for RTS7751R2D by
+ * Atom Create Engineering Co., Ltd. 2002.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <mach/r2d.h>
+
+#define R2D_NR_IRL 13
+
+enum {
+ UNUSED = 0,
+
+ /* board specific interrupt sources (R2D-1 and R2D-PLUS) */
+ EXT, /* EXT_INT0-3 */
+ RTC_T, RTC_A, /* Real Time Clock */
+ AX88796, /* Ethernet controller (R2D-1 board) */
+ KEY, /* Key input (R2D-PLUS board) */
+ SDCARD, /* SD Card */
+ CF_CD, CF_IDE, /* CF Card Detect + CF IDE */
+ SM501, /* SM501 aka Voyager */
+ PCI_INTD_RTL8139, /* Ethernet controller */
+ PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */
+ PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */
+ PCI_INTB_SLOT, /* PCI Slot 3.3v (R2D-1 board) */
+ PCI_INTA_SLOT, /* PCI Slot 3.3v */
+ TP, /* Touch Panel */
+};
+
+#ifdef CONFIG_RTS7751R2D_1
+
+/* Vectors for R2D-1 */
+static struct intc_vect vectors_r2d_1[] __initdata = {
+ INTC_IRQ(EXT, IRQ_EXT),
+ INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A),
+ INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD),
+ INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */
+ INTC_IRQ(SM501, IRQ_VOYAGER),
+ INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD),
+ INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC),
+ INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB),
+ INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA),
+ INTC_IRQ(TP, IRQ_TP),
+};
+
+/* IRLMSK mask register layout for R2D-1 */
+static struct intc_mask_reg mask_registers_r2d_1[] __initdata = {
+ { 0xa4000000, 0, 16, /* IRLMSK */
+ { TP, PCI_INTA_SLOT, PCI_INTB_SLOT,
+ PCI_INTC_PCI1520, PCI_INTD_RTL8139,
+ SM501, CF_IDE, CF_CD, SDCARD, AX88796,
+ RTC_A, RTC_T, 0, 0, 0, EXT } },
+};
+
+/* IRLn to IRQ table for R2D-1 */
+static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = {
+ IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC,
+ IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T,
+ IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT,
+ IRQ_TP,
+};
+
+static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1,
+ NULL, mask_registers_r2d_1, NULL, NULL);
+
+#endif /* CONFIG_RTS7751R2D_1 */
+
+#ifdef CONFIG_RTS7751R2D_PLUS
+
+/* Vectors for R2D-PLUS */
+static struct intc_vect vectors_r2d_plus[] __initdata = {
+ INTC_IRQ(EXT, IRQ_EXT),
+ INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A),
+ INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD),
+ INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE),
+ INTC_IRQ(SM501, IRQ_VOYAGER),
+ INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD),
+ INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC),
+ INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB),
+ INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA),
+ INTC_IRQ(TP, IRQ_TP),
+};
+
+/* IRLMSK mask register layout for R2D-PLUS */
+static struct intc_mask_reg mask_registers_r2d_plus[] __initdata = {
+ { 0xa4000000, 0, 16, /* IRLMSK */
+ { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139,
+ PCI_INTC_PCI1520, PCI_INTD_RTL8139,
+ SM501, CF_IDE, CF_CD, SDCARD, KEY,
+ RTC_A, RTC_T, 0, 0, 0, EXT } },
+};
+
+/* IRLn to IRQ table for R2D-PLUS */
+static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = {
+ IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC,
+ IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T,
+ IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT,
+ IRQ_TP,
+};
+
+static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus,
+ NULL, mask_registers_r2d_plus, NULL, NULL);
+
+#endif /* CONFIG_RTS7751R2D_PLUS */
+
+static unsigned char irl2irq[R2D_NR_IRL];
+
+int rts7751r2d_irq_demux(int irq)
+{
+ if (irq >= R2D_NR_IRL + 16 || irq < 16 || !irl2irq[irq - 16])
+ return irq;
+
+ return irl2irq[irq - 16];
+}
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_rts7751r2d_IRQ(void)
+{
+ struct intc_desc *d;
+
+ switch (__raw_readw(PA_VERREG) & 0xf0) {
+#ifdef CONFIG_RTS7751R2D_PLUS
+ case 0x10:
+ printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n");
+ d = &intc_desc_r2d_plus;
+ memcpy(irl2irq, irl2irq_r2d_plus, R2D_NR_IRL);
+ break;
+#endif
+#ifdef CONFIG_RTS7751R2D_1
+ case 0x00: /* according to manual */
+ case 0x30: /* in reality */
+ printk(KERN_INFO "Using R2D-1 interrupt controller.\n");
+ d = &intc_desc_r2d_1;
+ memcpy(irl2irq, irl2irq_r2d_1, R2D_NR_IRL);
+ break;
+#endif
+ default:
+ printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n",
+ __raw_readw(PA_VERREG));
+ return;
+ }
+
+ register_intc_controller(d);
+}
diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c
new file mode 100644
index 000000000..3bc52f651
--- /dev/null
+++ b/arch/sh/boards/mach-r2d/setup.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Technology Sales RTS7751R2D Support.
+ *
+ * Copyright (C) 2002 - 2006 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2004 - 2007 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/ata_platform.h>
+#include <linux/sm501.h>
+#include <linux/sm501-regs.h>
+#include <linux/pm.h>
+#include <linux/fb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <asm/machvec.h>
+#include <mach/r2d.h>
+#include <asm/io.h>
+#include <asm/io_trapped.h>
+#include <asm/spi.h>
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_AREA5_IO + 0x1000,
+ .end = PA_AREA5_IO + 0x1000 + 0x10 - 0x2,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PA_AREA5_IO + 0x80c,
+ .end = PA_AREA5_IO + 0x80c,
+ .flags = IORESOURCE_MEM,
+ },
+#ifndef CONFIG_RTS7751R2D_1 /* For R2D-1 polling is preferred */
+ [2] = {
+ .start = IRQ_CF_IDE,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+static struct pata_platform_info pata_info = {
+ .ioport_shift = 1,
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+ .dev = {
+ .platform_data = &pata_info,
+ },
+};
+
+static struct spi_board_info spi_bus[] = {
+ {
+ .modalias = "rtc-r9701",
+ .max_speed_hz = 1000000,
+ .mode = SPI_MODE_3,
+ },
+};
+
+static void r2d_chip_select(struct sh_spi_info *spi, int cs, int state)
+{
+ BUG_ON(cs != 0); /* Single Epson RTC-9701JE attached on CS0 */
+ __raw_writew(state == BITBANG_CS_ACTIVE, PA_RTCCE);
+}
+
+static struct sh_spi_info spi_info = {
+ .num_chipselect = 1,
+ .chip_select = r2d_chip_select,
+};
+
+static struct resource spi_sh_sci_resources[] = {
+ {
+ .start = 0xffe00000,
+ .end = 0xffe0001f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spi_sh_sci_device = {
+ .name = "spi_sh_sci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(spi_sh_sci_resources),
+ .resource = spi_sh_sci_resources,
+ .dev = {
+ .platform_data = &spi_info,
+ },
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_OUTPORT,
+ .end = PA_OUTPORT,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct resource sm501_resources[] = {
+ [0] = {
+ .start = 0x10000000,
+ .end = 0x13e00000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x13e00000,
+ .end = 0x13ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_VOYAGER,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct fb_videomode sm501_default_mode = {
+ .pixclock = 35714,
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 105,
+ .right_margin = 50,
+ .upper_margin = 35,
+ .lower_margin = 0,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = {
+ .def_bpp = 16,
+ .def_mode = &sm501_default_mode,
+ .flags = SM501FB_FLAG_USE_INIT_MODE |
+ SM501FB_FLAG_USE_HWCURSOR |
+ SM501FB_FLAG_USE_HWACCEL |
+ SM501FB_FLAG_DISABLE_AT_EXIT,
+};
+
+static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = {
+ .flags = (SM501FB_FLAG_USE_INIT_MODE |
+ SM501FB_FLAG_USE_HWCURSOR |
+ SM501FB_FLAG_USE_HWACCEL |
+ SM501FB_FLAG_DISABLE_AT_EXIT),
+
+};
+
+static struct sm501_platdata_fb sm501_fb_pdata = {
+ .fb_route = SM501_FB_OWN,
+ .fb_crt = &sm501_pdata_fbsub_crt,
+ .fb_pnl = &sm501_pdata_fbsub_pnl,
+ .flags = SM501_FBPD_SWAP_FB_ENDIAN,
+};
+
+static struct sm501_initdata sm501_initdata = {
+ .devices = SM501_USE_USB_HOST | SM501_USE_UART0,
+};
+
+static struct sm501_platdata sm501_platform_data = {
+ .init = &sm501_initdata,
+ .fb = &sm501_fb_pdata,
+};
+
+static struct platform_device sm501_device = {
+ .name = "sm501",
+ .id = -1,
+ .dev = {
+ .platform_data = &sm501_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(sm501_resources),
+ .resource = sm501_resources,
+};
+
+static struct mtd_partition r2d_partitions[] = {
+ {
+ .name = "U-Boot",
+ .offset = 0x00000000,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Environment",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 0x001c0000,
+ }, {
+ .name = "Flash_FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data flash_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(r2d_partitions),
+ .parts = r2d_partitions,
+};
+
+static struct resource flash_resource = {
+ .start = 0x00000000,
+ .end = 0x02000000,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
+static struct platform_device *rts7751r2d_devices[] __initdata = {
+ &sm501_device,
+ &heartbeat_device,
+ &spi_sh_sci_device,
+};
+
+/*
+ * The CF is connected with a 16-bit bus where 8-bit operations are
+ * unsupported. The linux ata driver is however using 8-bit operations, so
+ * insert a trapped io filter to convert 8-bit operations into 16-bit.
+ */
+static struct trapped_io cf_trapped_io = {
+ .resource = cf_ide_resources,
+ .num_resources = 2,
+ .minimum_bus_width = 16,
+};
+
+static int __init rts7751r2d_devices_setup(void)
+{
+ if (register_trapped_io(&cf_trapped_io) == 0)
+ platform_device_register(&cf_ide_device);
+
+ if (mach_is_r2d_plus())
+ platform_device_register(&flash_device);
+
+ spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
+
+ return platform_add_devices(rts7751r2d_devices,
+ ARRAY_SIZE(rts7751r2d_devices));
+}
+device_initcall(rts7751r2d_devices_setup);
+
+static void rts7751r2d_power_off(void)
+{
+ __raw_writew(0x0001, PA_POWOFF);
+}
+
+/*
+ * Initialize the board
+ */
+static void __init rts7751r2d_setup(char **cmdline_p)
+{
+ void __iomem *sm501_reg;
+ u16 ver = __raw_readw(PA_VERREG);
+
+ printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
+
+ printk(KERN_INFO "FPGA version:%d (revision:%d)\n",
+ (ver >> 4) & 0xf, ver & 0xf);
+
+ __raw_writew(0x0000, PA_OUTPORT);
+ pm_power_off = rts7751r2d_power_off;
+
+ /* sm501 dram configuration:
+ * ColSizeX = 11 - External Memory Column Size: 256 words.
+ * APX = 1 - External Memory Active to Pre-Charge Delay: 7 clocks.
+ * RstX = 1 - External Memory Reset: Normal.
+ * Rfsh = 1 - Local Memory Refresh to Command Delay: 12 clocks.
+ * BwC = 1 - Local Memory Block Write Cycle Time: 2 clocks.
+ * BwP = 1 - Local Memory Block Write to Pre-Charge Delay: 1 clock.
+ * AP = 1 - Internal Memory Active to Pre-Charge Delay: 7 clocks.
+ * Rst = 1 - Internal Memory Reset: Normal.
+ * RA = 1 - Internal Memory Remain in Active State: Do not remain.
+ */
+
+ sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL;
+ writel(readl(sm501_reg) | 0x00f107c0, sm501_reg);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_rts7751r2d __initmv = {
+ .mv_name = "RTS7751R2D",
+ .mv_setup = rts7751r2d_setup,
+ .mv_init_irq = init_rts7751r2d_IRQ,
+ .mv_irq_demux = rts7751r2d_irq_demux,
+};
diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig
new file mode 100644
index 000000000..f0299bc44
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/Kconfig
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+if SH_RSK
+
+choice
+ prompt "RSK+ options"
+ default SH_RSK7203
+
+config SH_RSK7201
+ bool "RSK7201"
+ depends on CPU_SUBTYPE_SH7201
+
+config SH_RSK7203
+ bool "RSK7203"
+ select GPIOLIB
+ depends on CPU_SUBTYPE_SH7203
+
+config SH_RSK7264
+ bool "RSK2+SH7264"
+ select GPIOLIB
+ depends on CPU_SUBTYPE_SH7264
+
+config SH_RSK7269
+ bool "RSK2+SH7269"
+ select GPIOLIB
+ depends on CPU_SUBTYPE_SH7269
+
+endchoice
+
+endif
diff --git a/arch/sh/boards/mach-rsk/Makefile b/arch/sh/boards/mach-rsk/Makefile
new file mode 100644
index 000000000..43cca39a9
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := setup.o
+obj-$(CONFIG_SH_RSK7203) += devices-rsk7203.o
+obj-$(CONFIG_SH_RSK7264) += devices-rsk7264.o
+obj-$(CONFIG_SH_RSK7269) += devices-rsk7269.o
diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c
new file mode 100644
index 000000000..e6b05d458
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Technology Europe RSK+ 7203 Support.
+ *
+ * Copyright (C) 2008 - 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <cpu/sh7203.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SWAP_FIFO,
+};
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = 0x24000000,
+ .end = 0x240000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 64,
+ .end = 64,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct gpio_led rsk7203_gpio_leds[] = {
+ {
+ .name = "green",
+ .gpio = GPIO_PE10,
+ .active_low = 1,
+ }, {
+ .name = "orange",
+ .default_trigger = "nand-disk",
+ .gpio = GPIO_PE12,
+ .active_low = 1,
+ }, {
+ .name = "red:timer",
+ .default_trigger = "timer",
+ .gpio = GPIO_PC14,
+ .active_low = 1,
+ }, {
+ .name = "red:heartbeat",
+ .default_trigger = "heartbeat",
+ .gpio = GPIO_PE11,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data rsk7203_gpio_leds_info = {
+ .leds = rsk7203_gpio_leds,
+ .num_leds = ARRAY_SIZE(rsk7203_gpio_leds),
+};
+
+static struct platform_device led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &rsk7203_gpio_leds_info,
+ },
+};
+
+static struct gpio_keys_button rsk7203_gpio_keys_table[] = {
+ {
+ .code = BTN_0,
+ .gpio = GPIO_PB0,
+ .active_low = 1,
+ .desc = "SW1",
+ }, {
+ .code = BTN_1,
+ .gpio = GPIO_PB1,
+ .active_low = 1,
+ .desc = "SW2",
+ }, {
+ .code = BTN_2,
+ .gpio = GPIO_PB2,
+ .active_low = 1,
+ .desc = "SW3",
+ },
+};
+
+static struct gpio_keys_platform_data rsk7203_gpio_keys_info = {
+ .buttons = rsk7203_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(rsk7203_gpio_keys_table),
+ .poll_interval = 50, /* default to 50ms */
+};
+
+static struct platform_device keys_device = {
+ .name = "gpio-keys-polled",
+ .dev = {
+ .platform_data = &rsk7203_gpio_keys_info,
+ },
+};
+
+static struct platform_device *rsk7203_devices[] __initdata = {
+ &smsc911x_device,
+ &led_device,
+ &keys_device,
+};
+
+static int __init rsk7203_devices_setup(void)
+{
+ /* Select pins for SCIF0 */
+ gpio_request(GPIO_FN_TXD0, NULL);
+ gpio_request(GPIO_FN_RXD0, NULL);
+
+ /* Setup LAN9118: CS1 in 16-bit Big Endian Mode, IRQ0 at Port B */
+ __raw_writel(0x36db0400, 0xfffc0008); /* CS1BCR */
+ gpio_request(GPIO_FN_IRQ0_PB, NULL);
+
+ return platform_add_devices(rsk7203_devices,
+ ARRAY_SIZE(rsk7203_devices));
+}
+device_initcall(rsk7203_devices_setup);
diff --git a/arch/sh/boards/mach-rsk/devices-rsk7264.c b/arch/sh/boards/mach-rsk/devices-rsk7264.c
new file mode 100644
index 000000000..eaf700a20
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/devices-rsk7264.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RSK+SH7264 Support.
+ *
+ * Copyright (C) 2012 Renesas Electronics Europe
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/smsc911x.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_SWAP_FIFO,
+};
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = 0x28000000,
+ .end = 0x280000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 65,
+ .end = 65,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct platform_device *rsk7264_devices[] __initdata = {
+ &smsc911x_device,
+};
+
+static int __init rsk7264_devices_setup(void)
+{
+ return platform_add_devices(rsk7264_devices,
+ ARRAY_SIZE(rsk7264_devices));
+}
+device_initcall(rsk7264_devices_setup);
diff --git a/arch/sh/boards/mach-rsk/devices-rsk7269.c b/arch/sh/boards/mach-rsk/devices-rsk7269.c
new file mode 100644
index 000000000..4b1e386b5
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/devices-rsk7269.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RSK+SH7269 Support
+ *
+ * Copyright (C) 2012 Renesas Electronics Europe Ltd
+ * Copyright (C) 2012 Phil Edworthy
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_SWAP_FIFO,
+};
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .start = 0x24000000,
+ .end = 0x240000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 85,
+ .end = 85,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct platform_device *rsk7269_devices[] __initdata = {
+ &smsc911x_device,
+};
+
+static int __init rsk7269_devices_setup(void)
+{
+ return platform_add_devices(rsk7269_devices,
+ ARRAY_SIZE(rsk7269_devices));
+}
+device_initcall(rsk7269_devices_setup);
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c
new file mode 100644
index 000000000..9370c4fdc
--- /dev/null
+++ b/arch/sh/boards/mach-rsk/setup.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Technology Europe RSK+ Support.
+ *
+ * Copyright (C) 2008 Paul Mundt
+ * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk>
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/map.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <asm/machvec.h>
+#include <asm/io.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 mtd_partition rsk_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0x00000000,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 0x001c0000,
+ }, {
+ .name = "Flash_FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data flash_data = {
+ .parts = rsk_partitions,
+ .nr_parts = ARRAY_SIZE(rsk_partitions),
+ .width = 2,
+};
+
+static struct resource flash_resource = {
+ .start = 0x20000000,
+ .end = 0x20400000,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
+static struct platform_device *rsk_devices[] __initdata = {
+ &flash_device,
+};
+
+static int __init rsk_devices_setup(void)
+{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ return platform_add_devices(rsk_devices,
+ ARRAY_SIZE(rsk_devices));
+}
+device_initcall(rsk_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_rsk __initmv = {
+ .mv_name = "RSK+",
+};
diff --git a/arch/sh/boards/mach-sdk7780/Kconfig b/arch/sh/boards/mach-sdk7780/Kconfig
new file mode 100644
index 000000000..d4392efd2
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7780/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+if SH_SDK7780
+
+choice
+ prompt "SDK7780 options"
+ default SH_SDK7780_BASE
+
+config SH_SDK7780_BASE
+ bool "SDK7780 with base-board support"
+ depends on CPU_SUBTYPE_SH7780
+ help
+ Selecting this option will enable support for the expansion
+ baseboard devices. If in doubt, say Y.
+
+endchoice
+
+endif
diff --git a/arch/sh/boards/mach-sdk7780/Makefile b/arch/sh/boards/mach-sdk7780/Makefile
new file mode 100644
index 000000000..37e857f9a
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7780/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the SDK7780 specific parts of the kernel
+#
+obj-y := setup.o irq.o
+
diff --git a/arch/sh/boards/mach-sdk7780/irq.c b/arch/sh/boards/mach-sdk7780/irq.c
new file mode 100644
index 000000000..fa392f3dc
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7780/irq.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/renesas/sdk7780/irq.c
+ *
+ * Renesas Technology Europe SDK7780 Support.
+ *
+ * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk>
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/sdk7780.h>
+
+enum {
+ UNUSED = 0,
+ /* board specific interrupt sources */
+ SMC91C111, /* Ethernet controller */
+};
+
+static struct intc_vect fpga_vectors[] __initdata = {
+ INTC_IRQ(SMC91C111, IRQ_ETHERNET),
+};
+
+static struct intc_mask_reg fpga_mask_registers[] __initdata = {
+ { 0, FPGA_IRQ0MR, 16,
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, SMC91C111, 0, 0, 0, 0 } },
+};
+
+static DECLARE_INTC_DESC(fpga_intc_desc, "sdk7780-irq", fpga_vectors,
+ NULL, fpga_mask_registers, NULL, NULL);
+
+void __init init_sdk7780_IRQ(void)
+{
+ printk(KERN_INFO "Using SDK7780 interrupt controller.\n");
+
+ __raw_writew(0xFFFF, FPGA_IRQ0MR);
+ /* Setup IRL 0-3 */
+ __raw_writew(0x0003, FPGA_IMSR);
+ plat_irq_setup_pins(IRQ_MODE_IRL3210);
+
+ register_intc_controller(&fpga_intc_desc);
+}
diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c
new file mode 100644
index 000000000..482761b78
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7780/setup.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/renesas/sdk7780/setup.c
+ *
+ * Renesas Solutions SH7780 SDK Support
+ * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk>
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <asm/machvec.h>
+#include <mach/sdk7780.h>
+#include <asm/heartbeat.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+#define GPIO_PECR 0xFFEA0008
+
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* SMC91x */
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ETHERNET,
+ .end = IRQ_ETHERNET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct platform_device *sdk7780_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+};
+
+static int __init sdk7780_devices_setup(void)
+{
+ return platform_add_devices(sdk7780_devices,
+ ARRAY_SIZE(sdk7780_devices));
+}
+device_initcall(sdk7780_devices_setup);
+
+static void __init sdk7780_setup(char **cmdline_p)
+{
+ u16 ver = __raw_readw(FPGA_FPVERR);
+ u16 dateStamp = __raw_readw(FPGA_FPDATER);
+
+ printk(KERN_INFO "Renesas Technology Europe SDK7780 support.\n");
+ printk(KERN_INFO "Board version: %d (revision %d), "
+ "FPGA version: %d (revision %d), datestamp : %d\n",
+ (ver >> 12) & 0xf, (ver >> 8) & 0xf,
+ (ver >> 4) & 0xf, ver & 0xf,
+ dateStamp);
+
+ /* Setup pin mux'ing for PCIC */
+ __raw_writew(0x0000, GPIO_PECR);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_se7780 __initmv = {
+ .mv_name = "Renesas SDK7780-R3" ,
+ .mv_setup = sdk7780_setup,
+ .mv_init_irq = init_sdk7780_IRQ,
+};
+
diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile
new file mode 100644
index 000000000..731a87c69
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := fpga.o irq.o nmi.o setup.o
+
+obj-$(CONFIG_GPIOLIB) += gpio.o
+obj-$(CONFIG_HAVE_SRAM_POOL) += sram.o
diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c
new file mode 100644
index 000000000..a37e1e88c
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/fpga.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SDK7786 FPGA Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bcd.h>
+#include <mach/fpga.h>
+#include <linux/sizes.h>
+
+#define FPGA_REGS_OFFSET 0x03fff800
+#define FPGA_REGS_SIZE 0x490
+
+/*
+ * The FPGA can be mapped in any of the generally available areas,
+ * so we attempt to scan for it using the fixed SRSTR read magic.
+ *
+ * Once the FPGA is located, the rest of the mapping data for the other
+ * components can be determined dynamically from its section mapping
+ * registers.
+ */
+static void __iomem *sdk7786_fpga_probe(void)
+{
+ unsigned long area;
+ void __iomem *base;
+
+ /*
+ * Iterate over all of the areas where the FPGA could be mapped.
+ * The possible range is anywhere from area 0 through 6, area 7
+ * is reserved.
+ */
+ for (area = PA_AREA0; area < PA_AREA7; area += SZ_64M) {
+ base = ioremap(area + FPGA_REGS_OFFSET, FPGA_REGS_SIZE);
+ if (!base) {
+ /* Failed to remap this area, move along. */
+ continue;
+ }
+
+ if (ioread16(base + SRSTR) == SRSTR_MAGIC)
+ return base; /* Found it! */
+
+ iounmap(base);
+ }
+
+ return NULL;
+}
+
+void __iomem *sdk7786_fpga_base;
+
+void __init sdk7786_fpga_init(void)
+{
+ u16 version, date;
+
+ sdk7786_fpga_base = sdk7786_fpga_probe();
+ if (unlikely(!sdk7786_fpga_base)) {
+ panic("FPGA detection failed.\n");
+ return;
+ }
+
+ version = fpga_read_reg(FPGAVR);
+ date = fpga_read_reg(FPGADR);
+
+ pr_info("\tFPGA version:\t%d.%d (built on %d/%d/%d)\n",
+ bcd2bin(version >> 8) & 0xf, bcd2bin(version & 0xf),
+ ((date >> 12) & 0xf) + 2000,
+ (date >> 8) & 0xf, bcd2bin(date & 0xff));
+}
diff --git a/arch/sh/boards/mach-sdk7786/gpio.c b/arch/sh/boards/mach-sdk7786/gpio.c
new file mode 100644
index 000000000..c4587d101
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/gpio.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SDK7786 FPGA USRGPIR Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/gpio/driver.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <mach/fpga.h>
+
+#define NR_FPGA_GPIOS 8
+
+static const char *usrgpir_gpio_names[NR_FPGA_GPIOS] = {
+ "in0", "in1", "in2", "in3", "in4", "in5", "in6", "in7",
+};
+
+static int usrgpir_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ /* always in */
+ return 0;
+}
+
+static int usrgpir_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+ return !!(fpga_read_reg(USRGPIR) & (1 << gpio));
+}
+
+static struct gpio_chip usrgpir_gpio_chip = {
+ .label = "sdk7786-fpga",
+ .names = usrgpir_gpio_names,
+ .direction_input = usrgpir_gpio_direction_input,
+ .get = usrgpir_gpio_get,
+ .base = -1, /* don't care */
+ .ngpio = NR_FPGA_GPIOS,
+};
+
+static int __init usrgpir_gpio_setup(void)
+{
+ return gpiochip_add_data(&usrgpir_gpio_chip, NULL);
+}
+device_initcall(usrgpir_gpio_setup);
diff --git a/arch/sh/boards/mach-sdk7786/irq.c b/arch/sh/boards/mach-sdk7786/irq.c
new file mode 100644
index 000000000..340c306ea
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/irq.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SDK7786 FPGA IRQ Controller Support.
+ *
+ * Copyright (C) 2010 Matt Fleming
+ * Copyright (C) 2010 Paul Mundt
+ */
+#include <linux/irq.h>
+#include <mach/fpga.h>
+#include <mach/irq.h>
+
+enum {
+ ATA_IRQ_BIT = 1,
+ SPI_BUSY_BIT = 2,
+ LIRQ5_BIT = 3,
+ LIRQ6_BIT = 4,
+ LIRQ7_BIT = 5,
+ LIRQ8_BIT = 6,
+ KEY_IRQ_BIT = 7,
+ PEN_IRQ_BIT = 8,
+ ETH_IRQ_BIT = 9,
+ RTC_ALARM_BIT = 10,
+ CRYSTAL_FAIL_BIT = 12,
+ ETH_PME_BIT = 14,
+};
+
+void __init sdk7786_init_irq(void)
+{
+ unsigned int tmp;
+
+ /* Enable priority encoding for all IRLs */
+ fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR);
+
+ /* Clear FPGA interrupt status registers */
+ fpga_write_reg(0x0000, INTASR);
+ fpga_write_reg(0x0000, INTBSR);
+
+ /* Unmask FPGA interrupts */
+ tmp = fpga_read_reg(INTAMR);
+ tmp &= ~(1 << ETH_IRQ_BIT);
+ fpga_write_reg(tmp, INTAMR);
+
+ plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK);
+ plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
+}
diff --git a/arch/sh/boards/mach-sdk7786/nmi.c b/arch/sh/boards/mach-sdk7786/nmi.c
new file mode 100644
index 000000000..afba49679
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/nmi.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SDK7786 FPGA NMI Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <mach/fpga.h>
+
+enum {
+ NMI_MODE_MANUAL,
+ NMI_MODE_AUX,
+ NMI_MODE_MASKED,
+ NMI_MODE_ANY,
+ NMI_MODE_UNKNOWN,
+};
+
+/*
+ * Default to the manual NMI switch.
+ */
+static unsigned int __initdata nmi_mode = NMI_MODE_ANY;
+
+static int __init nmi_mode_setup(char *str)
+{
+ if (!str)
+ return 0;
+
+ if (strcmp(str, "manual") == 0)
+ nmi_mode = NMI_MODE_MANUAL;
+ else if (strcmp(str, "aux") == 0)
+ nmi_mode = NMI_MODE_AUX;
+ else if (strcmp(str, "masked") == 0)
+ nmi_mode = NMI_MODE_MASKED;
+ else if (strcmp(str, "any") == 0)
+ nmi_mode = NMI_MODE_ANY;
+ else {
+ nmi_mode = NMI_MODE_UNKNOWN;
+ pr_warn("Unknown NMI mode %s\n", str);
+ }
+
+ printk("Set NMI mode to %d\n", nmi_mode);
+ return 0;
+}
+early_param("nmi_mode", nmi_mode_setup);
+
+void __init sdk7786_nmi_init(void)
+{
+ unsigned int source, mask, tmp;
+
+ switch (nmi_mode) {
+ case NMI_MODE_MANUAL:
+ source = NMISR_MAN_NMI;
+ mask = NMIMR_MAN_NMIM;
+ break;
+ case NMI_MODE_AUX:
+ source = NMISR_AUX_NMI;
+ mask = NMIMR_AUX_NMIM;
+ break;
+ case NMI_MODE_ANY:
+ source = NMISR_MAN_NMI | NMISR_AUX_NMI;
+ mask = NMIMR_MAN_NMIM | NMIMR_AUX_NMIM;
+ break;
+ case NMI_MODE_MASKED:
+ case NMI_MODE_UNKNOWN:
+ default:
+ source = mask = 0;
+ break;
+ }
+
+ /* Set the NMI source */
+ tmp = fpga_read_reg(NMISR);
+ tmp &= ~NMISR_MASK;
+ tmp |= source;
+ fpga_write_reg(tmp, NMISR);
+
+ /* And the IRQ masking */
+ fpga_write_reg(NMIMR_MASK ^ mask, NMIMR);
+}
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c
new file mode 100644
index 000000000..d183026db
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/setup.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas Technology Europe SDK7786 Support.
+ *
+ * Copyright (C) 2010 Matt Fleming
+ * Copyright (C) 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <mach/fpga.h>
+#include <mach/irq.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+#include <linux/sizes.h>
+#include <asm/clock.h>
+#include <asm/reboot.h>
+#include <asm/smp-ops.h>
+
+static struct resource heartbeat_resource = {
+ .start = 0x07fff8b0,
+ .end = 0x07fff8b0 + sizeof(u16) - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* 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 smsc911x_resources[] = {
+ [0] = {
+ .name = "smsc911x-memory",
+ .start = 0x07ffff00,
+ .end = 0x07ffff00 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smsc911x-irq",
+ .start = evt2irq(0x2c0),
+ .end = evt2irq(0x2c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static struct resource smbus_fpga_resource = {
+ .start = 0x07fff9e0,
+ .end = 0x07fff9e0 + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device smbus_fpga_device = {
+ .name = "i2c-sdk7786",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &smbus_fpga_resource,
+};
+
+static struct resource smbus_pcie_resource = {
+ .start = 0x07fffc30,
+ .end = 0x07fffc30 + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device smbus_pcie_device = {
+ .name = "i2c-sdk7786",
+ .id = 1,
+ .num_resources = 1,
+ .resource = &smbus_pcie_resource,
+};
+
+static struct i2c_board_info __initdata sdk7786_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("max6900", 0x68),
+ },
+};
+
+static struct platform_device *sh7786_devices[] __initdata = {
+ &heartbeat_device,
+ &smsc911x_device,
+ &smbus_fpga_device,
+ &smbus_pcie_device,
+};
+
+static int sdk7786_i2c_setup(void)
+{
+ unsigned int tmp;
+
+ /*
+ * Hand over I2C control to the FPGA.
+ */
+ tmp = fpga_read_reg(SBCR);
+ tmp &= ~SCBR_I2CCEN;
+ tmp |= SCBR_I2CMEN;
+ fpga_write_reg(tmp, SBCR);
+
+ return i2c_register_board_info(0, sdk7786_i2c_devices,
+ ARRAY_SIZE(sdk7786_i2c_devices));
+}
+
+static int __init sdk7786_devices_setup(void)
+{
+ int ret;
+
+ ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices));
+ if (unlikely(ret != 0))
+ return ret;
+
+ return sdk7786_i2c_setup();
+}
+device_initcall(sdk7786_devices_setup);
+
+static int sdk7786_mode_pins(void)
+{
+ return fpga_read_reg(MODSWR);
+}
+
+/*
+ * FPGA-driven PCIe clocks
+ *
+ * Historically these include the oscillator, clock B (slots 2/3/4) and
+ * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove
+ * everything under a single PCIe clocks enable bit that happens to map
+ * to the same bit position as the oscillator bit for earlier FPGA
+ * versions.
+ *
+ * Given that the legacy clocks have the side-effect of shutting the CPU
+ * off through the FPGA along with the PCI slots, we simply leave them in
+ * their initial state and don't bother registering them with the clock
+ * framework.
+ */
+static int sdk7786_pcie_clk_enable(struct clk *clk)
+{
+ fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR);
+ return 0;
+}
+
+static void sdk7786_pcie_clk_disable(struct clk *clk)
+{
+ fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
+}
+
+static struct sh_clk_ops sdk7786_pcie_clk_ops = {
+ .enable = sdk7786_pcie_clk_enable,
+ .disable = sdk7786_pcie_clk_disable,
+};
+
+static struct clk sdk7786_pcie_clk = {
+ .ops = &sdk7786_pcie_clk_ops,
+};
+
+static struct clk_lookup sdk7786_pcie_cl = {
+ .con_id = "pcie_plat_clk",
+ .clk = &sdk7786_pcie_clk,
+};
+
+static int sdk7786_clk_init(void)
+{
+ struct clk *clk;
+ int ret;
+
+ /*
+ * Only handle the EXTAL case, anyone interfacing a crystal
+ * resonator will need to provide their own input clock.
+ */
+ if (test_mode_pin(MODE_PIN9))
+ return -EINVAL;
+
+ clk = clk_get(NULL, "extal");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ ret = clk_set_rate(clk, 33333333);
+ clk_put(clk);
+
+ /*
+ * Setup the FPGA clocks.
+ */
+ ret = clk_register(&sdk7786_pcie_clk);
+ if (unlikely(ret)) {
+ pr_err("FPGA clock registration failed\n");
+ return ret;
+ }
+
+ clkdev_add(&sdk7786_pcie_cl);
+
+ return 0;
+}
+
+static void sdk7786_restart(char *cmd)
+{
+ fpga_write_reg(0xa5a5, SRSTR);
+}
+
+static void sdk7786_power_off(void)
+{
+ fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR);
+
+ /*
+ * It can take up to 20us for the R8C to do its job, back off and
+ * wait a bit until we've been shut off. Even though newer FPGA
+ * versions don't set the ACK bit, the latency issue remains.
+ */
+ while ((fpga_read_reg(PWRCR) & PWRCR_PDWNACK) == 0)
+ cpu_sleep();
+}
+
+/* Initialize the board */
+static void __init sdk7786_setup(char **cmdline_p)
+{
+ pr_info("Renesas Technology Europe SDK7786 support:\n");
+
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+ sdk7786_fpga_init();
+ sdk7786_nmi_init();
+
+ pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
+
+ machine_ops.restart = sdk7786_restart;
+ pm_power_off = sdk7786_power_off;
+
+ register_smp_ops(&shx3_smp_ops);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_sdk7786 __initmv = {
+ .mv_name = "SDK7786",
+ .mv_setup = sdk7786_setup,
+ .mv_mode_pins = sdk7786_mode_pins,
+ .mv_clk_init = sdk7786_clk_init,
+ .mv_init_irq = sdk7786_init_irq,
+};
diff --git a/arch/sh/boards/mach-sdk7786/sram.c b/arch/sh/boards/mach-sdk7786/sram.c
new file mode 100644
index 000000000..7c6ca976f
--- /dev/null
+++ b/arch/sh/boards/mach-sdk7786/sram.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SDK7786 FPGA SRAM Support.
+ *
+ * Copyright (C) 2010 Paul Mundt
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <mach/fpga.h>
+#include <asm/sram.h>
+#include <linux/sizes.h>
+
+static int __init fpga_sram_init(void)
+{
+ unsigned long phys;
+ unsigned int area;
+ void __iomem *vaddr;
+ int ret;
+ u16 data;
+
+ /* Enable FPGA SRAM */
+ data = fpga_read_reg(LCLASR);
+ data |= LCLASR_FRAMEN;
+ fpga_write_reg(data, LCLASR);
+
+ /*
+ * FPGA_SEL determines the area mapping
+ */
+ area = (data & LCLASR_FPGA_SEL_MASK) >> LCLASR_FPGA_SEL_SHIFT;
+ if (unlikely(area == LCLASR_AREA_MASK)) {
+ pr_err("FPGA memory unmapped.\n");
+ return -ENXIO;
+ }
+
+ /*
+ * The memory itself occupies a 2KiB range at the top of the area
+ * immediately below the system registers.
+ */
+ phys = (area << 26) + SZ_64M - SZ_4K;
+
+ /*
+ * The FPGA SRAM resides in translatable physical space, so set
+ * up a mapping prior to inserting it in to the pool.
+ */
+ vaddr = ioremap(phys, SZ_2K);
+ if (unlikely(!vaddr)) {
+ pr_err("Failed remapping FPGA memory.\n");
+ return -ENXIO;
+ }
+
+ pr_info("Adding %dKiB of FPGA memory at 0x%08lx-0x%08lx "
+ "(area %d) to pool.\n",
+ SZ_2K >> 10, phys, phys + SZ_2K - 1, area);
+
+ ret = gen_pool_add(sram_pool, (unsigned long)vaddr, SZ_2K, -1);
+ if (unlikely(ret < 0)) {
+ pr_err("Failed adding memory\n");
+ iounmap(vaddr);
+ return ret;
+ }
+
+ return 0;
+}
+postcore_initcall(fpga_sram_init);
diff --git a/arch/sh/boards/mach-se/7206/Makefile b/arch/sh/boards/mach-se/7206/Makefile
new file mode 100644
index 000000000..b40b30853
--- /dev/null
+++ b/arch/sh/boards/mach-se/7206/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the 7206 SolutionEngine specific parts of the kernel
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
new file mode 100644
index 000000000..2b1537082
--- /dev/null
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7206/irq.c
+ *
+ * Copyright (C) 2005,2006 Yoshinori Sato
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <mach-se/mach/se7206.h>
+
+#define INTSTS0 0x31800000
+#define INTSTS1 0x31800002
+#define INTMSK0 0x31800004
+#define INTMSK1 0x31800006
+#define INTSEL 0x31800008
+
+#define IRQ0_IRQ 64
+#define IRQ1_IRQ 65
+#define IRQ3_IRQ 67
+
+#define INTC_IPR01 0xfffe0818
+#define INTC_ICR1 0xfffe0802
+
+static void disable_se7206_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ unsigned short val;
+ unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
+ unsigned short msk0,msk1;
+
+ /* Set the priority in IPR to 0 */
+ val = __raw_readw(INTC_IPR01);
+ val &= mask;
+ __raw_writew(val, INTC_IPR01);
+ /* FPGA mask set */
+ msk0 = __raw_readw(INTMSK0);
+ msk1 = __raw_readw(INTMSK1);
+
+ switch (irq) {
+ case IRQ0_IRQ:
+ msk0 |= 0x0010;
+ break;
+ case IRQ1_IRQ:
+ msk0 |= 0x000f;
+ break;
+ case IRQ3_IRQ:
+ msk0 |= 0x0f00;
+ msk1 |= 0x00ff;
+ break;
+ }
+ __raw_writew(msk0, INTMSK0);
+ __raw_writew(msk1, INTMSK1);
+}
+
+static void enable_se7206_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ unsigned short val;
+ unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
+ unsigned short msk0,msk1;
+
+ /* Set priority in IPR back to original value */
+ val = __raw_readw(INTC_IPR01);
+ val |= value;
+ __raw_writew(val, INTC_IPR01);
+
+ /* FPGA mask reset */
+ msk0 = __raw_readw(INTMSK0);
+ msk1 = __raw_readw(INTMSK1);
+
+ switch (irq) {
+ case IRQ0_IRQ:
+ msk0 &= ~0x0010;
+ break;
+ case IRQ1_IRQ:
+ msk0 &= ~0x000f;
+ break;
+ case IRQ3_IRQ:
+ msk0 &= ~0x0f00;
+ msk1 &= ~0x00ff;
+ break;
+ }
+ __raw_writew(msk0, INTMSK0);
+ __raw_writew(msk1, INTMSK1);
+}
+
+static void eoi_se7206_irq(struct irq_data *data)
+{
+ unsigned short sts0,sts1;
+ unsigned int irq = data->irq;
+
+ if (!irqd_irq_disabled(data) && !irqd_irq_inprogress(data))
+ enable_se7206_irq(data);
+ /* FPGA isr clear */
+ sts0 = __raw_readw(INTSTS0);
+ sts1 = __raw_readw(INTSTS1);
+
+ switch (irq) {
+ case IRQ0_IRQ:
+ sts0 &= ~0x0010;
+ break;
+ case IRQ1_IRQ:
+ sts0 &= ~0x000f;
+ break;
+ case IRQ3_IRQ:
+ sts0 &= ~0x0f00;
+ sts1 &= ~0x00ff;
+ break;
+ }
+ __raw_writew(sts0, INTSTS0);
+ __raw_writew(sts1, INTSTS1);
+}
+
+static struct irq_chip se7206_irq_chip __read_mostly = {
+ .name = "SE7206-FPGA",
+ .irq_mask = disable_se7206_irq,
+ .irq_unmask = enable_se7206_irq,
+ .irq_eoi = eoi_se7206_irq,
+};
+
+static void make_se7206_irq(unsigned int irq)
+{
+ disable_irq_nosync(irq);
+ irq_set_chip_and_handler_name(irq, &se7206_irq_chip,
+ handle_level_irq, "level");
+ disable_se7206_irq(irq_get_irq_data(irq));
+}
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7206_IRQ(void)
+{
+ make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
+ make_se7206_irq(IRQ1_IRQ); /* ATA */
+ make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
+
+ __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */
+
+ /* FPGA System register setup*/
+ __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
+ __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */
+
+ /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
+ __raw_writew(0x0001,INTSEL);
+}
diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c
new file mode 100644
index 000000000..dc55d3a69
--- /dev/null
+++ b/arch/sh/boards/mach-se/7206/setup.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * linux/arch/sh/boards/se/7206/setup.c
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ * Copyright (C) 2007 - 2008 Paul Mundt
+ *
+ * Hitachi 7206 SolutionEngine Support.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <mach-se/mach/se7206.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = PA_SMSC + 0x300,
+ .end = PA_SMSC + 0x300 + 0x020 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 64,
+ .end = 64,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+};
+
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+static struct platform_device *se7206_devices[] __initdata = {
+ &smc91x_device,
+ &heartbeat_device,
+};
+
+static int __init se7206_devices_setup(void)
+{
+ return platform_add_devices(se7206_devices, ARRAY_SIZE(se7206_devices));
+}
+device_initcall(se7206_devices_setup);
+
+static int se7206_mode_pins(void)
+{
+ return MODE_PIN1 | MODE_PIN2;
+}
+
+/*
+ * The Machine Vector
+ */
+
+static struct sh_machine_vector mv_se __initmv = {
+ .mv_name = "SolutionEngine",
+ .mv_init_irq = init_se7206_IRQ,
+ .mv_mode_pins = se7206_mode_pins,
+};
diff --git a/arch/sh/boards/mach-se/7343/Makefile b/arch/sh/boards/mach-se/7343/Makefile
new file mode 100644
index 000000000..e05866109
--- /dev/null
+++ b/arch/sh/boards/mach-se/7343/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the 7343 SolutionEngine specific parts of the kernel
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
new file mode 100644
index 000000000..f9f3b14f7
--- /dev/null
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hitachi UL SolutionEngine 7343 FPGA IRQ Support.
+ *
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ * Copyright (C) 2012 Paul Mundt
+ *
+ * Based on linux/arch/sh/boards/se/7343/irq.c
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ */
+#define DRV_NAME "SE7343-FPGA"
+#define pr_fmt(fmt) DRV_NAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <mach-se/mach/se7343.h>
+
+#define PA_CPLD_BASE_ADDR 0x11400000
+#define PA_CPLD_ST_REG 0x08 /* CPLD Interrupt status register */
+#define PA_CPLD_IMSK_REG 0x0a /* CPLD Interrupt mask register */
+
+static void __iomem *se7343_irq_regs;
+struct irq_domain *se7343_irq_domain;
+
+static void se7343_irq_demux(struct irq_desc *desc)
+{
+ struct irq_data *data = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+ unsigned long mask;
+ int bit;
+
+ chip->irq_mask_ack(data);
+
+ mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG);
+
+ for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR)
+ generic_handle_domain_irq(se7343_irq_domain, bit);
+
+ chip->irq_unmask(data);
+}
+
+static void __init se7343_domain_init(void)
+{
+ int i;
+
+ se7343_irq_domain = irq_domain_add_linear(NULL, SE7343_FPGA_IRQ_NR,
+ &irq_domain_simple_ops, NULL);
+ if (unlikely(!se7343_irq_domain)) {
+ printk("Failed to get IRQ domain\n");
+ return;
+ }
+
+ for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
+ int irq = irq_create_mapping(se7343_irq_domain, i);
+
+ if (unlikely(irq == 0)) {
+ printk("Failed to allocate IRQ %d\n", i);
+ return;
+ }
+ }
+}
+
+static void __init se7343_gc_init(void)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+ unsigned int irq_base;
+
+ irq_base = irq_linear_revmap(se7343_irq_domain, 0);
+
+ gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7343_irq_regs,
+ handle_level_irq);
+ if (unlikely(!gc))
+ return;
+
+ ct = gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_set_bit;
+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+
+ ct->regs.mask = PA_CPLD_IMSK_REG;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(SE7343_FPGA_IRQ_NR),
+ IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+
+ irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW);
+}
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_7343se_IRQ(void)
+{
+ se7343_irq_regs = ioremap(PA_CPLD_BASE_ADDR, SZ_16);
+ if (unlikely(!se7343_irq_regs)) {
+ pr_err("Failed to remap CPLD\n");
+ return;
+ }
+
+ /*
+ * All FPGA IRQs disabled by default
+ */
+ iowrite16(0, se7343_irq_regs + PA_CPLD_IMSK_REG);
+
+ __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */
+
+ se7343_domain_init();
+ se7343_gc_init();
+}
diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c
new file mode 100644
index 000000000..fe0e55060
--- /dev/null
+++ b/arch/sh/boards/mach-se/7343/setup.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/usb/isp116x.h>
+#include <linux/delay.h>
+#include <linux/irqdomain.h>
+#include <asm/machvec.h>
+#include <mach-se/mach/se7343.h>
+#include <asm/heartbeat.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 128 * 1024,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 31 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x01ffffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+#define ST16C2550C_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP)
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ [0] = {
+ .iotype = UPIO_MEM,
+ .mapbase = 0x16000000,
+ .regshift = 1,
+ .flags = ST16C2550C_FLAGS,
+ .uartclk = 7372800,
+ },
+ [1] = {
+ .iotype = UPIO_MEM,
+ .mapbase = 0x17000000,
+ .regshift = 1,
+ .flags = ST16C2550C_FLAGS,
+ .uartclk = 7372800,
+ },
+ { },
+};
+
+static struct platform_device uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static void isp116x_delay(struct device *dev, int delay)
+{
+ ndelay(delay);
+}
+
+static struct resource usb_resources[] = {
+ [0] = {
+ .start = 0x11800000,
+ .end = 0x11800001,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x11800002,
+ .end = 0x11800003,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ /* Filled in later */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct isp116x_platform_data usb_platform_data = {
+ .sel15Kres = 1,
+ .oc_enable = 1,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_enable = 0,
+ .delay = isp116x_delay,
+};
+
+static struct platform_device usb_device = {
+ .name = "isp116x-hcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(usb_resources),
+ .resource = usb_resources,
+ .dev = {
+ .platform_data = &usb_platform_data,
+ },
+
+};
+
+static struct platform_device *sh7343se_platform_devices[] __initdata = {
+ &heartbeat_device,
+ &nor_flash_device,
+ &uart_device,
+ &usb_device,
+};
+
+static int __init sh7343se_devices_setup(void)
+{
+ /* Wire-up dynamic vectors */
+ serial_platform_data[0].irq = irq_find_mapping(se7343_irq_domain,
+ SE7343_FPGA_IRQ_UARTA);
+ serial_platform_data[1].irq = irq_find_mapping(se7343_irq_domain,
+ SE7343_FPGA_IRQ_UARTB);
+ usb_resources[2].start = usb_resources[2].end =
+ irq_find_mapping(se7343_irq_domain, SE7343_FPGA_IRQ_USB);
+
+ return platform_add_devices(sh7343se_platform_devices,
+ ARRAY_SIZE(sh7343se_platform_devices));
+}
+device_initcall(sh7343se_devices_setup);
+
+/*
+ * Initialize the board
+ */
+static void __init sh7343se_setup(char **cmdline_p)
+{
+ __raw_writew(0xf900, FPGA_OUT); /* FPGA */
+
+ __raw_writew(0x0002, PORT_PECR); /* PORT E 1 = IRQ5 */
+ __raw_writew(0x0020, PORT_PSELD);
+
+ printk(KERN_INFO "MS7343CP01 Setup...done\n");
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_7343se __initmv = {
+ .mv_name = "SolutionEngine 7343",
+ .mv_setup = sh7343se_setup,
+ .mv_init_irq = init_7343se_IRQ,
+};
diff --git a/arch/sh/boards/mach-se/770x/Makefile b/arch/sh/boards/mach-se/770x/Makefile
new file mode 100644
index 000000000..900d93cfb
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the 770x SolutionEngine specific parts of the kernel
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/770x/irq.c b/arch/sh/boards/mach-se/770x/irq.c
new file mode 100644
index 000000000..66e2c8aa0
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/irq.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/770x/irq.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ * Copyright (C) 2006 Nobuhiro Iwamatsu
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <mach-se/mach/se.h>
+
+static struct ipr_data ipr_irq_table[] = {
+ /*
+ * Super I/O (Just mimic PC):
+ * 1: keyboard
+ * 3: serial 0
+ * 4: serial 1
+ * 5: printer
+ * 6: floppy
+ * 8: rtc
+ * 12: mouse
+ * 14: ide0
+ */
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+ /* This is default value */
+ { 13, 0, 8, 0x0f-13, },
+ { 5 , 0, 4, 0x0f- 5, },
+ { 10, 1, 0, 0x0f-10, },
+ { 7 , 2, 4, 0x0f- 7, },
+ { 3 , 2, 0, 0x0f- 3, },
+ { 1 , 3, 12, 0x0f- 1, },
+ { 12, 3, 4, 0x0f-12, }, /* LAN */
+ { 2 , 4, 8, 0x0f- 2, }, /* PCIRQ2 */
+ { 6 , 4, 4, 0x0f- 6, }, /* PCIRQ1 */
+ { 14, 4, 0, 0x0f-14, }, /* PCIRQ0 */
+ { 0 , 5, 12, 0x0f , },
+ { 4 , 5, 4, 0x0f- 4, },
+ { 8 , 6, 12, 0x0f- 8, },
+ { 9 , 6, 8, 0x0f- 9, },
+ { 11, 6, 4, 0x0f-11, },
+#else
+ { 14, 0, 8, 0x0f-14, },
+ { 12, 0, 4, 0x0f-12, },
+ { 8, 1, 4, 0x0f- 8, },
+ { 6, 2, 12, 0x0f- 6, },
+ { 5, 2, 8, 0x0f- 5, },
+ { 4, 2, 4, 0x0f- 4, },
+ { 3, 2, 0, 0x0f- 3, },
+ { 1, 3, 12, 0x0f- 1, },
+#if defined(CONFIG_STNIC)
+ /* ST NIC */
+ { 10, 3, 4, 0x0f-10, }, /* LAN */
+#endif
+ /* MRSHPC IRQs setting */
+ { 0, 4, 12, 0x0f- 0, }, /* PCIRQ3 */
+ { 11, 4, 8, 0x0f-11, }, /* PCIRQ2 */
+ { 9, 4, 4, 0x0f- 9, }, /* PCIRQ1 */
+ { 7, 4, 0, 0x0f- 7, }, /* PCIRQ0 */
+ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+ /* NOTE: #2 and #13 are not used on PC */
+ { 13, 6, 4, 0x0f-13, }, /* SLOTIRQ2 */
+ { 2, 6, 0, 0x0f- 2, }, /* SLOTIRQ1 */
+#endif
+};
+
+static unsigned long ipr_offsets[] = {
+ BCR_ILCRA,
+ BCR_ILCRB,
+ BCR_ILCRC,
+ BCR_ILCRD,
+ BCR_ILCRE,
+ BCR_ILCRF,
+ BCR_ILCRG,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+ .chip = {
+ .name = "IPR-se770x",
+ },
+};
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se_IRQ(void)
+{
+ /* Disable all interrupts */
+ __raw_writew(0, BCR_ILCRA);
+ __raw_writew(0, BCR_ILCRB);
+ __raw_writew(0, BCR_ILCRC);
+ __raw_writew(0, BCR_ILCRD);
+ __raw_writew(0, BCR_ILCRE);
+ __raw_writew(0, BCR_ILCRF);
+ __raw_writew(0, BCR_ILCRG);
+
+ register_ipr_controller(&ipr_irq_desc);
+}
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c
new file mode 100644
index 000000000..412326d59
--- /dev/null
+++ b/arch/sh/boards/mach-se/770x/setup.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/770x/setup.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sh_eth.h>
+#include <mach-se/mach/se.h>
+#include <mach-se/mach/mrshpc.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/smc37c93x.h>
+#include <asm/heartbeat.h>
+
+/*
+ * Configure the Super I/O chip
+ */
+static void __init smsc_config(int index, int data)
+{
+ outb_p(index, INDEX_PORT);
+ outb_p(data, DATA_PORT);
+}
+
+/* XXX: Another candidate for a more generic cchip machine vector */
+static void __init smsc_setup(char **cmdline_p)
+{
+ outb_p(CONFIG_ENTER, CONFIG_PORT);
+ outb_p(CONFIG_ENTER, CONFIG_PORT);
+
+ /* FDC */
+ smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
+
+ /* AUXIO (GPIO): to use IDE1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
+ smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
+ smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
+
+ /* COM1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x03);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+ /* COM2 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x02);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
+
+ /* RTC */
+ smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
+
+ /* XXX: PARPORT, KBD, and MOUSE will come here... */
+ outb_p(CONFIG_EXIT, CONFIG_PORT);
+}
+
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 + 0x206 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_CFCARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+};
+
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7712)
+/* SH771X Ethernet driver */
+static struct sh_eth_plat_data sh_eth_plat = {
+ .phy = PHY_ID,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource sh_eth0_resources[] = {
+ [0] = {
+ .start = SH_ETH0_BASE,
+ .end = SH_ETH0_BASE + 0x1B8 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SH_TSU_BASE,
+ .end = SH_TSU_BASE + 0x200 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = SH_ETH0_IRQ,
+ .end = SH_ETH0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_eth0_device = {
+ .name = "sh771x-ether",
+ .id = 0,
+ .dev = {
+ .platform_data = &sh_eth_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_eth0_resources),
+ .resource = sh_eth0_resources,
+};
+
+static struct resource sh_eth1_resources[] = {
+ [0] = {
+ .start = SH_ETH1_BASE,
+ .end = SH_ETH1_BASE + 0x1B8 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SH_TSU_BASE,
+ .end = SH_TSU_BASE + 0x200 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = SH_ETH1_IRQ,
+ .end = SH_ETH1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_eth1_device = {
+ .name = "sh771x-ether",
+ .id = 1,
+ .dev = {
+ .platform_data = &sh_eth_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_eth1_resources),
+ .resource = sh_eth1_resources,
+};
+#endif
+
+static struct platform_device *se_devices[] __initdata = {
+ &heartbeat_device,
+ &cf_ide_device,
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
+ defined(CONFIG_CPU_SUBTYPE_SH7712)
+ &sh_eth0_device,
+ &sh_eth1_device,
+#endif
+};
+
+static int __init se_devices_setup(void)
+{
+ mrshpc_setup_windows();
+ return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
+}
+device_initcall(se_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_se __initmv = {
+ .mv_name = "SolutionEngine",
+ .mv_setup = smsc_setup,
+ .mv_init_irq = init_se_IRQ,
+};
diff --git a/arch/sh/boards/mach-se/7721/Makefile b/arch/sh/boards/mach-se/7721/Makefile
new file mode 100644
index 000000000..09436f10d
--- /dev/null
+++ b/arch/sh/boards/mach-se/7721/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7721/irq.c b/arch/sh/boards/mach-se/7721/irq.c
new file mode 100644
index 000000000..e6ef2a265
--- /dev/null
+++ b/arch/sh/boards/mach-se/7721/irq.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7721/irq.c
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <mach-se/mach/se7721.h>
+
+enum {
+ UNUSED = 0,
+
+ /* board specific interrupt sources */
+ MRSHPC,
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_IRQ(MRSHPC, MRSHPC_IRQ0),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { FPGA_ILSR6, 0, 8, 4, /* IRLMSK */
+ { 0, MRSHPC } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "SE7721", vectors,
+ NULL, NULL, prio_registers, NULL);
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7721_IRQ(void)
+{
+ /* PPCR */
+ __raw_writew(__raw_readw(0xa4050118) & ~0x00ff, 0xa4050118);
+
+ register_intc_controller(&intc_desc);
+ intc_set_priority(MRSHPC_IRQ0, 0xf - MRSHPC_IRQ0);
+}
diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c
new file mode 100644
index 000000000..3af724dc4
--- /dev/null
+++ b/arch/sh/boards/mach-se/7721/setup.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7721/setup.c
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ *
+ * Hitachi UL SolutionEngine 7721 Support.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <mach-se/mach/se7721.h>
+#include <mach-se/mach/mrshpc.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/heartbeat.h>
+
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+};
+
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = MRSHPC_IRQ0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *se7721_devices[] __initdata = {
+ &cf_ide_device,
+ &heartbeat_device
+};
+
+static int __init se7721_devices_setup(void)
+{
+ mrshpc_setup_windows();
+ return platform_add_devices(se7721_devices, ARRAY_SIZE(se7721_devices));
+}
+device_initcall(se7721_devices_setup);
+
+static void __init se7721_setup(char **cmdline_p)
+{
+ /* for USB */
+ __raw_writew(0x0000, 0xA405010C); /* PGCR */
+ __raw_writew(0x0000, 0xA405010E); /* PHCR */
+ __raw_writew(0x00AA, 0xA4050118); /* PPCR */
+ __raw_writew(0x0000, 0xA4050124); /* PSELA */
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_se7721 __initmv = {
+ .mv_name = "Solution Engine 7721",
+ .mv_setup = se7721_setup,
+ .mv_init_irq = init_se7721_IRQ,
+};
diff --git a/arch/sh/boards/mach-se/7722/Makefile b/arch/sh/boards/mach-se/7722/Makefile
new file mode 100644
index 000000000..a5e89c0c6
--- /dev/null
+++ b/arch/sh/boards/mach-se/7722/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the HITACHI UL SolutionEngine 7722 specific parts of the kernel
+#
+# 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.
+#
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
new file mode 100644
index 000000000..efa96edd4
--- /dev/null
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hitachi UL SolutionEngine 7722 FPGA IRQ Support.
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ * Copyright (C) 2012 Paul Mundt
+ */
+#define DRV_NAME "SE7722-FPGA"
+#define pr_fmt(fmt) DRV_NAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/sizes.h>
+#include <mach-se/mach/se7722.h>
+
+#define IRQ01_BASE_ADDR 0x11800000
+#define IRQ01_MODE_REG 0
+#define IRQ01_STS_REG 4
+#define IRQ01_MASK_REG 8
+
+static void __iomem *se7722_irq_regs;
+struct irq_domain *se7722_irq_domain;
+
+static void se7722_irq_demux(struct irq_desc *desc)
+{
+ struct irq_data *data = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+ unsigned long mask;
+ int bit;
+
+ chip->irq_mask_ack(data);
+
+ mask = ioread16(se7722_irq_regs + IRQ01_STS_REG);
+
+ for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR)
+ generic_handle_domain_irq(se7722_irq_domain, bit);
+
+ chip->irq_unmask(data);
+}
+
+static void __init se7722_domain_init(void)
+{
+ int i;
+
+ se7722_irq_domain = irq_domain_add_linear(NULL, SE7722_FPGA_IRQ_NR,
+ &irq_domain_simple_ops, NULL);
+ if (unlikely(!se7722_irq_domain)) {
+ printk("Failed to get IRQ domain\n");
+ return;
+ }
+
+ for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) {
+ int irq = irq_create_mapping(se7722_irq_domain, i);
+
+ if (unlikely(irq == 0)) {
+ printk("Failed to allocate IRQ %d\n", i);
+ return;
+ }
+ }
+}
+
+static void __init se7722_gc_init(void)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+ unsigned int irq_base;
+
+ irq_base = irq_linear_revmap(se7722_irq_domain, 0);
+
+ gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs,
+ handle_level_irq);
+ if (unlikely(!gc))
+ return;
+
+ ct = gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_set_bit;
+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+
+ ct->regs.mask = IRQ01_MASK_REG;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(SE7722_FPGA_IRQ_NR),
+ IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+
+ irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux);
+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux);
+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
+}
+
+/*
+ * Initialize FPGA IRQs
+ */
+void __init init_se7722_IRQ(void)
+{
+ se7722_irq_regs = ioremap(IRQ01_BASE_ADDR, SZ_16);
+ if (unlikely(!se7722_irq_regs)) {
+ printk("Failed to remap IRQ01 regs\n");
+ return;
+ }
+
+ /*
+ * All FPGA IRQs disabled by default
+ */
+ iowrite16(0, se7722_irq_regs + IRQ01_MASK_REG);
+
+ __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */
+
+ se7722_domain_init();
+ se7722_gc_init();
+}
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
new file mode 100644
index 000000000..2cd4a2e84
--- /dev/null
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7722/setup.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ * Copyright (C) 2012 Paul Mundt
+ *
+ * Hitachi UL SolutionEngine 7722 Support.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/irqdomain.h>
+#include <linux/smc91x.h>
+#include <linux/sh_intc.h>
+#include <mach-se/mach/se7722.h>
+#include <mach-se/mach/mrshpc.h>
+#include <asm/machvec.h>
+#include <asm/clock.h>
+#include <asm/io.h>
+#include <asm/heartbeat.h>
+#include <cpu/sh7722.h>
+
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* SMC91x */
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT,
+};
+
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* Filled in later */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ /* Filled in later */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct sh_keysc_info sh_keysc_info = {
+ .mode = SH_KEYSC_MODE_1, /* KEYOUT0->5, KEYIN0->4 */
+ .scan_timing = 3,
+ .delay = 5,
+ .keycodes = { /* SW1 -> SW30 */
+ 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_WAKEUP, KEY_COFFEE, /* life */
+ },
+};
+
+static struct resource sh_keysc_resources[] = {
+ [0] = {
+ .start = 0x044b0000,
+ .end = 0x044b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xbe0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh_keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* "keysc0" clock */
+ .num_resources = ARRAY_SIZE(sh_keysc_resources),
+ .resource = sh_keysc_resources,
+ .dev = {
+ .platform_data = &sh_keysc_info,
+ },
+};
+
+static struct platform_device *se7722_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+ &cf_ide_device,
+ &sh_keysc_device,
+};
+
+static int __init se7722_devices_setup(void)
+{
+ mrshpc_setup_windows();
+
+ /* Wire-up dynamic vectors */
+ cf_ide_resources[2].start = cf_ide_resources[2].end =
+ irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_MRSHPC0);
+
+ smc91x_eth_resources[1].start = smc91x_eth_resources[1].end =
+ irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_SMC);
+
+ return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices));
+}
+device_initcall(se7722_devices_setup);
+
+static void __init se7722_setup(char **cmdline_p)
+{
+ __raw_writew(0x010D, FPGA_OUT); /* FPGA */
+
+ __raw_writew(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */
+ __raw_writew(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */
+
+ /* LCDC I/O */
+ __raw_writew(0x0020, PORT_PSELD);
+
+ /* SIOF1*/
+ __raw_writew(0x0003, PORT_PSELB);
+ __raw_writew(0xe000, PORT_PSELC);
+ __raw_writew(0x0000, PORT_PKCR);
+
+ /* LCDC */
+ __raw_writew(0x4020, PORT_PHCR);
+ __raw_writew(0x0000, PORT_PLCR);
+ __raw_writew(0x0000, PORT_PMCR);
+ __raw_writew(0x0002, PORT_PRCR);
+ __raw_writew(0x0000, PORT_PXCR); /* LCDC,CS6A */
+
+ /* KEYSC */
+ __raw_writew(0x0A10, PORT_PSELA); /* BS,SHHID2 */
+ __raw_writew(0x0000, PORT_PYCR);
+ __raw_writew(0x0000, PORT_PZCR);
+ __raw_writew(__raw_readw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
+ __raw_writew(__raw_readw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_se7722 __initmv = {
+ .mv_name = "Solution Engine 7722" ,
+ .mv_setup = se7722_setup ,
+ .mv_init_irq = init_se7722_IRQ,
+};
diff --git a/arch/sh/boards/mach-se/7724/Makefile b/arch/sh/boards/mach-se/7724/Makefile
new file mode 100644
index 000000000..6c6112b24
--- /dev/null
+++ b/arch/sh/boards/mach-se/7724/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the HITACHI UL SolutionEngine 7724 specific parts of the kernel
+#
+# 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.
+#
+#
+
+obj-y := setup.o irq.o sdram.o
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
new file mode 100644
index 000000000..14ce30247
--- /dev/null
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7724/irq.c
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on linux/arch/sh/boards/se/7722/irq.c
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7724 Support.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/export.h>
+#include <linux/topology.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <mach-se/mach/se7724.h>
+
+struct fpga_irq {
+ unsigned long sraddr;
+ unsigned long mraddr;
+ unsigned short mask;
+ unsigned int base;
+};
+
+static unsigned int fpga2irq(unsigned int irq)
+{
+ if (irq >= IRQ0_BASE &&
+ irq <= IRQ0_END)
+ return IRQ0_IRQ;
+ else if (irq >= IRQ1_BASE &&
+ irq <= IRQ1_END)
+ return IRQ1_IRQ;
+ else
+ return IRQ2_IRQ;
+}
+
+static struct fpga_irq get_fpga_irq(unsigned int irq)
+{
+ struct fpga_irq set;
+
+ switch (irq) {
+ case IRQ0_IRQ:
+ set.sraddr = IRQ0_SR;
+ set.mraddr = IRQ0_MR;
+ set.mask = IRQ0_MASK;
+ set.base = IRQ0_BASE;
+ break;
+ case IRQ1_IRQ:
+ set.sraddr = IRQ1_SR;
+ set.mraddr = IRQ1_MR;
+ set.mask = IRQ1_MASK;
+ set.base = IRQ1_BASE;
+ break;
+ default:
+ set.sraddr = IRQ2_SR;
+ set.mraddr = IRQ2_MR;
+ set.mask = IRQ2_MASK;
+ set.base = IRQ2_BASE;
+ break;
+ }
+
+ return set;
+}
+
+static void disable_se7724_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
+ unsigned int bit = irq - set.base;
+ __raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
+}
+
+static void enable_se7724_irq(struct irq_data *data)
+{
+ unsigned int irq = data->irq;
+ struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
+ unsigned int bit = irq - set.base;
+ __raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
+}
+
+static struct irq_chip se7724_irq_chip __read_mostly = {
+ .name = "SE7724-FPGA",
+ .irq_mask = disable_se7724_irq,
+ .irq_unmask = enable_se7724_irq,
+};
+
+static void se7724_irq_demux(struct irq_desc *desc)
+{
+ unsigned int irq = irq_desc_get_irq(desc);
+ struct fpga_irq set = get_fpga_irq(irq);
+ unsigned short intv = __raw_readw(set.sraddr);
+ unsigned int ext_irq = set.base;
+
+ intv &= set.mask;
+
+ for (; intv; intv >>= 1, ext_irq++) {
+ if (!(intv & 1))
+ continue;
+
+ generic_handle_irq(ext_irq);
+ }
+}
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7724_IRQ(void)
+{
+ int irq_base, i;
+
+ __raw_writew(0xffff, IRQ0_MR); /* mask all */
+ __raw_writew(0xffff, IRQ1_MR); /* mask all */
+ __raw_writew(0xffff, IRQ2_MR); /* mask all */
+ __raw_writew(0x0000, IRQ0_SR); /* clear irq */
+ __raw_writew(0x0000, IRQ1_SR); /* clear irq */
+ __raw_writew(0x0000, IRQ2_SR); /* clear irq */
+ __raw_writew(0x002a, IRQ_MODE); /* set irq type */
+
+ irq_base = irq_alloc_descs(SE7724_FPGA_IRQ_BASE, SE7724_FPGA_IRQ_BASE,
+ SE7724_FPGA_IRQ_NR, numa_node_id());
+ if (IS_ERR_VALUE(irq_base)) {
+ pr_err("%s: failed hooking irqs for FPGA\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < SE7724_FPGA_IRQ_NR; i++)
+ irq_set_chip_and_handler_name(irq_base + i, &se7724_irq_chip,
+ handle_level_irq, "level");
+
+ irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux);
+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_chained_handler(IRQ1_IRQ, se7724_irq_demux);
+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_chained_handler(IRQ2_IRQ, se7724_irq_demux);
+ irq_set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW);
+}
diff --git a/arch/sh/boards/mach-se/7724/sdram.S b/arch/sh/boards/mach-se/7724/sdram.S
new file mode 100644
index 000000000..61c1fe78d
--- /dev/null
+++ b/arch/sh/boards/mach-se/7724/sdram.S
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * MS7724SE sdram self/auto-refresh setup code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+#include <asm/romimage-macros.h>
+
+/* code to enter and leave self-refresh. must be self-contained.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+ .balign 4
+ENTRY(ms7724se_sdram_enter_start)
+
+ /* DBSC: put memory in self-refresh mode */
+
+ ED 0xFD000010, 0x00000000 /* DBEN */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ENTRY(ms7724se_sdram_enter_end)
+
+ .balign 4
+ENTRY(ms7724se_sdram_leave_start)
+
+ /* DBSC: put memory in auto-refresh mode */
+
+ mov.l @(SH_SLEEP_MODE, r5), r0
+ tst #SUSP_SH_RSTANDBY, r0
+ bf resume_rstandby
+
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ WAIT 1
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+resume_rstandby:
+
+ /* CPG: setup clocks before restarting external memory */
+
+ ED 0xA4150024, 0x00004000 /* PLLCR */
+
+ mov.l FRQCRA,r0
+ mov.l @r0,r3
+ mov.l KICK,r1
+ or r1, r3
+ mov.l r3, @r0
+
+ mov.l LSTATS,r0
+ mov #1,r1
+WAIT_LSTATS:
+ mov.l @r0,r3
+ tst r1,r3
+ bf WAIT_LSTATS
+
+ /* DBSC: re-initialize and put in auto-refresh */
+
+ ED 0xFD000108, 0x00000181 /* DBPDCNT0 */
+ ED 0xFD000020, 0x015B0002 /* DBCONF */
+ ED 0xFD000030, 0x03071502 /* DBTR0 */
+ ED 0xFD000034, 0x02020102 /* DBTR1 */
+ ED 0xFD000038, 0x01090405 /* DBTR2 */
+ ED 0xFD00003C, 0x00000002 /* DBTR3 */
+ ED 0xFD000008, 0x00000005 /* DBKIND */
+ ED 0xFD000040, 0x00000001 /* DBRFPDN0 */
+ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */
+ ED 0xFD000018, 0x00000001 /* DBCKECNT */
+
+ mov #100,r0
+WAIT_400NS:
+ dt r0
+ bf WAIT_400NS
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */
+ ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */
+ ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */
+ ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */
+ ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */
+
+ mov #100,r0
+WAIT_400NS_2:
+ dt r0
+ bf WAIT_400NS_2
+
+ ED 0xFD000010, 0x00000001 /* DBEN */
+ ED 0xFD000044, 0x0000050f /* DBRFPDN1 */
+ ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */
+
+ mov.l DUMMY,r0
+ mov.l @r0, r1 /* force single dummy read */
+
+ ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */
+ ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */
+ ED 0xFD000108, 0x00000080 /* DBPDCNT0 */
+ ED 0xFD000040, 0x00010000 /* DBRFPDN0 */
+
+ rts
+ nop
+
+ .balign 4
+DUMMY: .long 0xac400000
+FRQCRA: .long 0xa4150000
+KICK: .long 0x80000000
+LSTATS: .long 0xa4150060
+
+ENTRY(ms7724se_sdram_leave_end)
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
new file mode 100644
index 000000000..6495f9354
--- /dev/null
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -0,0 +1,984 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7724/setup.c
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ */
+#include <asm/clock.h>
+#include <asm/heartbeat.h>
+#include <asm/io.h>
+#include <asm/suspend.h>
+
+#include <cpu/sh7724.h>
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/interrupt.h>
+#include <linux/memblock.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/sh_eth.h>
+#include <linux/sh_intc.h>
+#include <linux/smc91x.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/videodev2.h>
+#include <linux/dma-map-ops.h>
+
+#include <mach-se/mach/se7724.h>
+#include <media/drv-intf/renesas-ceu.h>
+
+#include <sound/sh_fsi.h>
+#include <sound/simple_card.h>
+
+#include <video/sh_mobile_lcdc.h>
+
+#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
+static phys_addr_t ceu0_dma_membase;
+static phys_addr_t ceu1_dma_membase;
+
+/*
+ * SWx 1234 5678
+ * ------------------------------------
+ * SW31 : 1001 1100 : default
+ * SW32 : 0111 1111 : use on board flash
+ *
+ * SW41 : abxx xxxx -> a = 0 : Analog monitor
+ * 1 : Digital monitor
+ * b = 0 : VGA
+ * 1 : 720p
+ */
+
+/*
+ * about 720p
+ *
+ * When you use 1280 x 720 lcdc output,
+ * you should change OSC6 lcdc clock from 25.175MHz to 74.25MHz,
+ * and change SW41 to use 720p
+ */
+
+/*
+ * about sound
+ *
+ * This setup.c supports FSI slave mode.
+ * Please change J20, J21, J22 pin to 1-2 connection.
+ */
+
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* LAN91C111 */
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "SMC91C111" ,
+ .start = 0x1a300300,
+ .end = 0x1a30030f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ0_SMC,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (1 * 1024 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (2 * 1024 * 1024),
+ }, {
+ .name = "free-area",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x01ffffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = nor_flash_resources,
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+};
+
+/* LCDC */
+static const struct fb_videomode lcdc_720p_modes[] = {
+ {
+ .name = "LB070WV1",
+ .sync = 0, /* hsync and vsync are active low */
+ .xres = 1280,
+ .yres = 720,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ },
+};
+
+static const struct fb_videomode lcdc_vga_modes[] = {
+ {
+ .name = "LB070WV1",
+ .sync = 0, /* hsync and vsync are active low */
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 105,
+ .right_margin = 50,
+ .hsync_len = 96,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .vsync_len = 2,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .clock_source = LCDC_CLK_EXTERNAL,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .clock_divider = 1,
+ .panel_cfg = { /* 7.0 inch */
+ .width = 152,
+ .height = 91,
+ },
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000,
+ .end = 0xfe942fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xf40),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ },
+};
+
+/* CEU0 */
+static struct ceu_platform_data ceu0_pdata = {
+ .num_subdevs = 0,
+};
+
+static struct resource ceu0_resources[] = {
+ [0] = {
+ .name = "CEU0",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ceu0_device = {
+ .name = "renesas-ceu",
+ .id = 0, /* "ceu.0" clock */
+ .num_resources = ARRAY_SIZE(ceu0_resources),
+ .resource = ceu0_resources,
+ .dev = {
+ .platform_data = &ceu0_pdata,
+ },
+};
+
+/* CEU1 */
+static struct ceu_platform_data ceu1_pdata = {
+ .num_subdevs = 0,
+};
+
+static struct resource ceu1_resources[] = {
+ [0] = {
+ .name = "CEU1",
+ .start = 0xfe914000,
+ .end = 0xfe91409f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x9e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ceu1_device = {
+ .name = "renesas-ceu",
+ .id = 1, /* "ceu.1" clock */
+ .num_resources = ARRAY_SIZE(ceu1_resources),
+ .resource = ceu1_resources,
+ .dev = {
+ .platform_data = &ceu1_pdata,
+ },
+};
+
+/* FSI */
+/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xFE3C0000,
+ .end = 0xFE3C021d,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xf80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+};
+
+static struct asoc_simple_card_info fsi_ak4642_info = {
+ .name = "AK4642",
+ .card = "FSIA-AK4642",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+ .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBP_CFP,
+ .cpu_dai = {
+ .name = "fsia-dai",
+ },
+ .codec_dai = {
+ .name = "ak4642-hifi",
+ .sysclk = 11289600,
+ },
+};
+
+static struct platform_device fsi_ak4642_device = {
+ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi_ak4642_info,
+ },
+};
+
+/* KEYSC in SoC (Needs SW33-2 set to ON) */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_1,
+ .scan_timing = 3,
+ .delay = 50,
+ .keycodes = {
+ KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
+ KEY_6, KEY_7, KEY_8, KEY_9, KEY_A,
+ KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
+ KEY_G, KEY_H, KEY_I, KEY_K, KEY_L,
+ KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q,
+ KEY_R, KEY_S, KEY_T, KEY_U, KEY_V,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0x044b0000,
+ .end = 0x044b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xbe0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* "keysc0" clock */
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+/* SH Eth */
+static struct resource sh_eth_resources[] = {
+ [0] = {
+ .start = SH_ETH_ADDR,
+ .end = SH_ETH_ADDR + 0x1FC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xd60),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct sh_eth_plat_data sh_eth_plat = {
+ .phy = 0x1f, /* SMSC LAN8187 */
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device sh_eth_device = {
+ .name = "sh7724-ether",
+ .id = 0,
+ .dev = {
+ .platform_data = &sh_eth_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_eth_resources),
+ .resource = sh_eth_resources,
+};
+
+static struct r8a66597_platdata sh7724_usb0_host_data = {
+ .on_chip = 1,
+};
+
+static struct resource sh7724_usb0_host_resources[] = {
+ [0] = {
+ .start = 0xa4d80000,
+ .end = 0xa4d80124 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa20),
+ .end = evt2irq(0xa20),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device sh7724_usb0_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh7724_usb0_host_data,
+ },
+ .num_resources = ARRAY_SIZE(sh7724_usb0_host_resources),
+ .resource = sh7724_usb0_host_resources,
+};
+
+static struct r8a66597_platdata sh7724_usb1_gadget_data = {
+ .on_chip = 1,
+};
+
+static struct resource sh7724_usb1_gadget_resources[] = {
+ [0] = {
+ .start = 0xa4d90000,
+ .end = 0xa4d90123,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa40),
+ .end = evt2irq(0xa40),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device sh7724_usb1_gadget_device = {
+ .name = "r8a66597_udc",
+ .id = 1, /* USB1 */
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh7724_usb1_gadget_data,
+ },
+ .num_resources = ARRAY_SIZE(sh7724_usb1_gadget_resources),
+ .resource = sh7724_usb1_gadget_resources,
+};
+
+/* Fixed 3.3V regulator to be used by SDHI0, 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"),
+};
+
+static struct resource sdhi0_cn7_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0x04ce0000,
+ .end = 0x04ce00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xe80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sh7724_sdhi0_data = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI0_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI0_RX,
+ .capabilities = MMC_CAP_SDIO_IRQ,
+};
+
+static struct platform_device sdhi0_cn7_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sdhi0_cn7_resources),
+ .resource = sdhi0_cn7_resources,
+ .dev = {
+ .platform_data = &sh7724_sdhi0_data,
+ },
+};
+
+static struct resource sdhi1_cn8_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0x04cf0000,
+ .end = 0x04cf00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x4e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct tmio_mmc_data sh7724_sdhi1_data = {
+ .chan_priv_tx = (void *)SHDMA_SLAVE_SDHI1_TX,
+ .chan_priv_rx = (void *)SHDMA_SLAVE_SDHI1_RX,
+ .capabilities = MMC_CAP_SDIO_IRQ,
+};
+
+static struct platform_device sdhi1_cn8_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sdhi1_cn8_resources),
+ .resource = sdhi1_cn8_resources,
+ .dev = {
+ .platform_data = &sh7724_sdhi1_data,
+ },
+};
+
+/* IrDA */
+static struct resource irda_resources[] = {
+ [0] = {
+ .name = "IrDA",
+ .start = 0xA45D0000,
+ .end = 0xA45D0049,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x480),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_sir",
+ .num_resources = ARRAY_SIZE(irda_resources),
+ .resource = irda_resources,
+};
+
+#include <media/i2c/ak881x.h>
+#include <media/drv-intf/sh_vou.h>
+
+static struct ak881x_pdata ak881x_pdata = {
+ .flags = AK881X_IF_MODE_SLAVE,
+};
+
+static struct i2c_board_info ak8813 = {
+ /* With open J18 jumper address is 0x21 */
+ I2C_BOARD_INFO("ak8813", 0x20),
+ .platform_data = &ak881x_pdata,
+};
+
+static struct sh_vou_pdata sh_vou_pdata = {
+ .bus_fmt = SH_VOU_BUS_8BIT,
+ .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW,
+ .board_info = &ak8813,
+ .i2c_adap = 0,
+};
+
+static struct resource sh_vou_resources[] = {
+ [0] = {
+ .start = 0xfe960000,
+ .end = 0xfe962043,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x8e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device vou_device = {
+ .name = "sh-vou",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sh_vou_resources),
+ .resource = sh_vou_resources,
+ .dev = {
+ .platform_data = &sh_vou_pdata,
+ },
+};
+
+static struct platform_device *ms7724se_ceu_devices[] __initdata = {
+ &ceu0_device,
+ &ceu1_device,
+};
+
+static struct platform_device *ms7724se_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+ &lcdc_device,
+ &nor_flash_device,
+ &keysc_device,
+ &sh_eth_device,
+ &sh7724_usb0_host_device,
+ &sh7724_usb1_gadget_device,
+ &fsi_device,
+ &fsi_ak4642_device,
+ &sdhi0_cn7_device,
+ &sdhi1_cn8_device,
+ &irda_device,
+ &vou_device,
+};
+
+/* I2C device */
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4642", 0x12),
+ },
+};
+
+#define EEPROM_OP 0xBA206000
+#define EEPROM_ADR 0xBA206004
+#define EEPROM_DATA 0xBA20600C
+#define EEPROM_STAT 0xBA206010
+#define EEPROM_STRT 0xBA206014
+
+static int __init sh_eth_is_eeprom_ready(void)
+{
+ int t = 10000;
+
+ while (t--) {
+ if (!__raw_readw(EEPROM_STAT))
+ return 1;
+ udelay(1);
+ }
+
+ printk(KERN_ERR "ms7724se can not access to eeprom\n");
+ return 0;
+}
+
+static void __init sh_eth_init(void)
+{
+ int i;
+ u16 mac;
+
+ /* check EEPROM status */
+ if (!sh_eth_is_eeprom_ready())
+ return;
+
+ /* read MAC addr from EEPROM */
+ for (i = 0 ; i < 3 ; i++) {
+ __raw_writew(0x0, EEPROM_OP); /* read */
+ __raw_writew(i*2, EEPROM_ADR);
+ __raw_writew(0x1, EEPROM_STRT);
+ if (!sh_eth_is_eeprom_ready())
+ return;
+
+ mac = __raw_readw(EEPROM_DATA);
+ sh_eth_plat.mac_addr[i << 1] = mac & 0xff;
+ sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8;
+ }
+}
+
+#define SW4140 0xBA201000
+#define FPGA_OUT 0xBA200400
+#define PORT_HIZA 0xA4050158
+#define PORT_MSELCRB 0xA4050182
+
+#define SW41_A 0x0100
+#define SW41_B 0x0200
+#define SW41_C 0x0400
+#define SW41_D 0x0800
+#define SW41_E 0x1000
+#define SW41_F 0x2000
+#define SW41_G 0x4000
+#define SW41_H 0x8000
+
+extern char ms7724se_sdram_enter_start;
+extern char ms7724se_sdram_enter_end;
+extern char ms7724se_sdram_leave_start;
+extern char ms7724se_sdram_leave_end;
+
+static int __init arch_setup(void)
+{
+ /* enable I2C device */
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+ return 0;
+}
+arch_initcall(arch_setup);
+
+static int __init devices_setup(void)
+{
+ u16 sw = __raw_readw(SW4140); /* select camera, monitor */
+ struct clk *clk;
+ u16 fpga_out;
+
+ /* register board specific self-refresh code */
+ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF |
+ SUSP_SH_RSTANDBY,
+ &ms7724se_sdram_enter_start,
+ &ms7724se_sdram_enter_end,
+ &ms7724se_sdram_leave_start,
+ &ms7724se_sdram_leave_end);
+
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+ /* Reset Release */
+ fpga_out = __raw_readw(FPGA_OUT);
+ /* bit4: NTSC_PDN, bit5: NTSC_RESET */
+ fpga_out &= ~((1 << 1) | /* LAN */
+ (1 << 4) | /* AK8813 PDN */
+ (1 << 5) | /* AK8813 RESET */
+ (1 << 6) | /* VIDEO DAC */
+ (1 << 7) | /* AK4643 */
+ (1 << 8) | /* IrDA */
+ (1 << 12) | /* USB0 */
+ (1 << 14)); /* RMII */
+ __raw_writew(fpga_out | (1 << 4), FPGA_OUT);
+
+ udelay(10);
+
+ /* AK8813 RESET */
+ __raw_writew(fpga_out | (1 << 5), FPGA_OUT);
+
+ udelay(10);
+
+ __raw_writew(fpga_out, FPGA_OUT);
+
+ /* turn on USB clocks, use external clock */
+ __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+
+ /* Let LED9 show STATUS2 */
+ gpio_request(GPIO_FN_STATUS2, NULL);
+
+ /* Lit LED10 show STATUS0 */
+ gpio_request(GPIO_FN_STATUS0, NULL);
+
+ /* Lit LED11 show PDSTATUS */
+ gpio_request(GPIO_FN_PDSTATUS, NULL);
+
+ /* enable USB0 port */
+ __raw_writew(0x0600, 0xa40501d4);
+
+ /* enable USB1 port */
+ __raw_writew(0x0600, 0xa4050192);
+
+ /* enable IRQ 0,1,2 */
+ gpio_request(GPIO_FN_INTC_IRQ0, NULL);
+ gpio_request(GPIO_FN_INTC_IRQ1, NULL);
+ gpio_request(GPIO_FN_INTC_IRQ2, NULL);
+
+ /* enable SCIFA3 */
+ gpio_request(GPIO_FN_SCIF3_I_SCK, NULL);
+ gpio_request(GPIO_FN_SCIF3_I_RXD, NULL);
+ gpio_request(GPIO_FN_SCIF3_I_TXD, NULL);
+ gpio_request(GPIO_FN_SCIF3_I_CTS, NULL);
+ gpio_request(GPIO_FN_SCIF3_I_RTS, NULL);
+
+ /* enable LCDC */
+ gpio_request(GPIO_FN_LCDD23, NULL);
+ gpio_request(GPIO_FN_LCDD22, NULL);
+ gpio_request(GPIO_FN_LCDD21, NULL);
+ gpio_request(GPIO_FN_LCDD20, NULL);
+ gpio_request(GPIO_FN_LCDD19, NULL);
+ gpio_request(GPIO_FN_LCDD18, NULL);
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDHSYN, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+ gpio_request(GPIO_FN_LCDVSYN, NULL);
+ gpio_request(GPIO_FN_LCDDON, NULL);
+ gpio_request(GPIO_FN_LCDVEPWC, NULL);
+ gpio_request(GPIO_FN_LCDVCPWC, NULL);
+ gpio_request(GPIO_FN_LCDRD, NULL);
+ gpio_request(GPIO_FN_LCDLCLK, NULL);
+ __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+
+ /* enable CEU0 */
+ gpio_request(GPIO_FN_VIO0_D15, NULL);
+ gpio_request(GPIO_FN_VIO0_D14, NULL);
+ gpio_request(GPIO_FN_VIO0_D13, NULL);
+ gpio_request(GPIO_FN_VIO0_D12, NULL);
+ gpio_request(GPIO_FN_VIO0_D11, NULL);
+ gpio_request(GPIO_FN_VIO0_D10, NULL);
+ gpio_request(GPIO_FN_VIO0_D9, NULL);
+ gpio_request(GPIO_FN_VIO0_D8, NULL);
+ gpio_request(GPIO_FN_VIO0_D7, NULL);
+ gpio_request(GPIO_FN_VIO0_D6, NULL);
+ gpio_request(GPIO_FN_VIO0_D5, NULL);
+ gpio_request(GPIO_FN_VIO0_D4, NULL);
+ gpio_request(GPIO_FN_VIO0_D3, NULL);
+ gpio_request(GPIO_FN_VIO0_D2, NULL);
+ gpio_request(GPIO_FN_VIO0_D1, NULL);
+ gpio_request(GPIO_FN_VIO0_D0, NULL);
+ gpio_request(GPIO_FN_VIO0_VD, NULL);
+ gpio_request(GPIO_FN_VIO0_CLK, NULL);
+ gpio_request(GPIO_FN_VIO0_FLD, NULL);
+ gpio_request(GPIO_FN_VIO0_HD, NULL);
+
+ /* enable CEU1 */
+ gpio_request(GPIO_FN_VIO1_D7, NULL);
+ gpio_request(GPIO_FN_VIO1_D6, NULL);
+ gpio_request(GPIO_FN_VIO1_D5, NULL);
+ gpio_request(GPIO_FN_VIO1_D4, NULL);
+ gpio_request(GPIO_FN_VIO1_D3, NULL);
+ gpio_request(GPIO_FN_VIO1_D2, NULL);
+ gpio_request(GPIO_FN_VIO1_D1, NULL);
+ gpio_request(GPIO_FN_VIO1_D0, NULL);
+ gpio_request(GPIO_FN_VIO1_FLD, NULL);
+ gpio_request(GPIO_FN_VIO1_HD, NULL);
+ gpio_request(GPIO_FN_VIO1_VD, NULL);
+ gpio_request(GPIO_FN_VIO1_CLK, NULL);
+
+ /* KEYSC */
+ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+ gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+ gpio_request(GPIO_FN_KEYIN4, NULL);
+ gpio_request(GPIO_FN_KEYIN3, NULL);
+ gpio_request(GPIO_FN_KEYIN2, NULL);
+ gpio_request(GPIO_FN_KEYIN1, NULL);
+ gpio_request(GPIO_FN_KEYIN0, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+
+ /* enable FSI */
+ gpio_request(GPIO_FN_FSIMCKA, NULL);
+ gpio_request(GPIO_FN_FSIIASD, NULL);
+ gpio_request(GPIO_FN_FSIOASD, NULL);
+ gpio_request(GPIO_FN_FSIIABCK, NULL);
+ gpio_request(GPIO_FN_FSIIALRCK, NULL);
+ gpio_request(GPIO_FN_FSIOABCK, NULL);
+ gpio_request(GPIO_FN_FSIOALRCK, NULL);
+ gpio_request(GPIO_FN_CLKAUDIOAO, NULL);
+
+ /* set SPU2 clock to 83.4 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 83333333));
+ clk_put(clk);
+ }
+
+ /* change parent of FSI A */
+ clk = clk_get(NULL, "fsia_clk");
+ if (!IS_ERR(clk)) {
+ /* 48kHz dummy clock was used to make sure 1/1 divide */
+ clk_set_rate(&sh7724_fsimcka_clk, 48000);
+ clk_set_parent(clk, &sh7724_fsimcka_clk);
+ clk_set_rate(clk, 48000);
+ clk_put(clk);
+ }
+
+ /* SDHI0 connected to cn7 */
+ gpio_request(GPIO_FN_SDHI0CD, NULL);
+ gpio_request(GPIO_FN_SDHI0WP, NULL);
+ gpio_request(GPIO_FN_SDHI0D3, NULL);
+ gpio_request(GPIO_FN_SDHI0D2, NULL);
+ gpio_request(GPIO_FN_SDHI0D1, NULL);
+ gpio_request(GPIO_FN_SDHI0D0, NULL);
+ gpio_request(GPIO_FN_SDHI0CMD, NULL);
+ gpio_request(GPIO_FN_SDHI0CLK, NULL);
+
+ /* SDHI1 connected to cn8 */
+ gpio_request(GPIO_FN_SDHI1CD, NULL);
+ gpio_request(GPIO_FN_SDHI1WP, NULL);
+ gpio_request(GPIO_FN_SDHI1D3, NULL);
+ gpio_request(GPIO_FN_SDHI1D2, NULL);
+ gpio_request(GPIO_FN_SDHI1D1, NULL);
+ gpio_request(GPIO_FN_SDHI1D0, NULL);
+ gpio_request(GPIO_FN_SDHI1CMD, NULL);
+ gpio_request(GPIO_FN_SDHI1CLK, NULL);
+
+ /* enable IrDA */
+ gpio_request(GPIO_FN_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_IRDA_IN, NULL);
+
+ /*
+ * enable SH-Eth
+ *
+ * please remove J33 pin from your board !!
+ *
+ * ms7724 board should not use GPIO_FN_LNKSTA pin
+ * So, This time PTX5 is set to input pin
+ */
+ gpio_request(GPIO_FN_RMII_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
+ gpio_request(GPIO_FN_RMII_TX_EN, NULL);
+ gpio_request(GPIO_FN_RMII_RX_ER, NULL);
+ gpio_request(GPIO_FN_RMII_CRS_DV, NULL);
+ gpio_request(GPIO_FN_MDIO, NULL);
+ gpio_request(GPIO_FN_MDC, NULL);
+ gpio_request(GPIO_PTX5, NULL);
+ gpio_direction_input(GPIO_PTX5);
+ sh_eth_init();
+
+ if (sw & SW41_B) {
+ /* 720p */
+ lcdc_info.ch[0].lcd_modes = lcdc_720p_modes;
+ lcdc_info.ch[0].num_modes = ARRAY_SIZE(lcdc_720p_modes);
+ } else {
+ /* VGA */
+ lcdc_info.ch[0].lcd_modes = lcdc_vga_modes;
+ lcdc_info.ch[0].num_modes = ARRAY_SIZE(lcdc_vga_modes);
+ }
+
+ if (sw & SW41_A) {
+ /* Digital monitor */
+ lcdc_info.ch[0].interface_type = RGB18;
+ lcdc_info.ch[0].flags = 0;
+ } else {
+ /* Analog monitor */
+ lcdc_info.ch[0].interface_type = RGB24;
+ lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
+ }
+
+ /* VOU */
+ gpio_request(GPIO_FN_DV_D15, NULL);
+ gpio_request(GPIO_FN_DV_D14, NULL);
+ gpio_request(GPIO_FN_DV_D13, NULL);
+ gpio_request(GPIO_FN_DV_D12, NULL);
+ gpio_request(GPIO_FN_DV_D11, NULL);
+ gpio_request(GPIO_FN_DV_D10, NULL);
+ gpio_request(GPIO_FN_DV_D9, NULL);
+ gpio_request(GPIO_FN_DV_D8, NULL);
+ gpio_request(GPIO_FN_DV_CLKI, NULL);
+ gpio_request(GPIO_FN_DV_CLK, NULL);
+ gpio_request(GPIO_FN_DV_VSYNC, NULL);
+ gpio_request(GPIO_FN_DV_HSYNC, NULL);
+
+ /* Initialize CEU platform devices separately to map memory first */
+ device_initialize(&ms7724se_ceu_devices[0]->dev);
+ dma_declare_coherent_memory(&ms7724se_ceu_devices[0]->dev,
+ ceu0_dma_membase, ceu0_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+ platform_device_add(ms7724se_ceu_devices[0]);
+
+ device_initialize(&ms7724se_ceu_devices[1]->dev);
+ dma_declare_coherent_memory(&ms7724se_ceu_devices[1]->dev,
+ ceu1_dma_membase, ceu1_dma_membase,
+ CEU_BUFFER_MEMORY_SIZE);
+ platform_device_add(ms7724se_ceu_devices[1]);
+
+ return platform_add_devices(ms7724se_devices,
+ ARRAY_SIZE(ms7724se_devices));
+}
+device_initcall(devices_setup);
+
+/* Reserve a portion of memory for CEU 0 and CEU 1 buffers */
+static void __init ms7724se_mv_mem_reserve(void)
+{
+ phys_addr_t phys;
+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU0 memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+ ceu0_dma_membase = phys;
+
+ phys = memblock_phys_alloc(size, PAGE_SIZE);
+ if (!phys)
+ panic("Failed to allocate CEU1 memory\n");
+
+ memblock_phys_free(phys, size);
+ memblock_remove(phys, size);
+ ceu1_dma_membase = phys;
+}
+
+static struct sh_machine_vector mv_ms7724se __initmv = {
+ .mv_name = "ms7724se",
+ .mv_init_irq = init_se7724_IRQ,
+ .mv_mem_reserve = ms7724se_mv_mem_reserve,
+};
diff --git a/arch/sh/boards/mach-se/7751/Makefile b/arch/sh/boards/mach-se/7751/Makefile
new file mode 100644
index 000000000..2406d3e35
--- /dev/null
+++ b/arch/sh/boards/mach-se/7751/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the 7751 SolutionEngine specific parts of the kernel
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7751/irq.c b/arch/sh/boards/mach-se/7751/irq.c
new file mode 100644
index 000000000..dcefe58d8
--- /dev/null
+++ b/arch/sh/boards/mach-se/7751/irq.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7751/irq.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <mach-se/mach/se7751.h>
+
+static struct ipr_data ipr_irq_table[] = {
+ { 13, 3, 3, 2 },
+ /* Add additional entries here as drivers are added and tested. */
+};
+
+static unsigned long ipr_offsets[] = {
+ BCR_ILCRA,
+ BCR_ILCRB,
+ BCR_ILCRC,
+ BCR_ILCRD,
+ BCR_ILCRE,
+ BCR_ILCRF,
+ BCR_ILCRG,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-se7751",
+ },
+};
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_7751se_IRQ(void)
+{
+ register_ipr_controller(&ipr_irq_desc);
+}
diff --git a/arch/sh/boards/mach-se/7751/setup.c b/arch/sh/boards/mach-se/7751/setup.c
new file mode 100644
index 000000000..4c4806055
--- /dev/null
+++ b/arch/sh/boards/mach-se/7751/setup.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7751/setup.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/machvec.h>
+#include <mach-se/mach/se7751.h>
+#include <asm/io.h>
+#include <asm/heartbeat.h>
+
+static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct platform_device *se7751_devices[] __initdata = {
+ &heartbeat_device,
+};
+
+static int __init se7751_devices_setup(void)
+{
+ return platform_add_devices(se7751_devices, ARRAY_SIZE(se7751_devices));
+}
+device_initcall(se7751_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_7751se __initmv = {
+ .mv_name = "7751 SolutionEngine",
+ .mv_init_irq = init_7751se_IRQ,
+};
diff --git a/arch/sh/boards/mach-se/7780/Makefile b/arch/sh/boards/mach-se/7780/Makefile
new file mode 100644
index 000000000..1f6669ab1
--- /dev/null
+++ b/arch/sh/boards/mach-se/7780/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the HITACHI UL SolutionEngine 7780 specific parts of the kernel
+#
+# 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.
+#
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7780/irq.c b/arch/sh/boards/mach-se/7780/irq.c
new file mode 100644
index 000000000..d427dfd71
--- /dev/null
+++ b/arch/sh/boards/mach-se/7780/irq.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7780/irq.c
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <mach-se/mach/se7780.h>
+
+#define INTC_BASE 0xffd00000
+#define INTC_ICR1 (INTC_BASE+0x1c)
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7780_IRQ(void)
+{
+ /* enable all interrupt at FPGA */
+ __raw_writew(0, FPGA_INTMSK1);
+ /* mask SM501 interrupt */
+ __raw_writew((__raw_readw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
+ /* enable all interrupt at FPGA */
+ __raw_writew(0, FPGA_INTMSK2);
+
+ /* set FPGA INTSEL register */
+ /* FPGA + 0x06 */
+ __raw_writew( ((IRQPIN_SM501 << IRQPOS_SM501) |
+ (IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1);
+
+ /* FPGA + 0x08 */
+ __raw_writew(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) |
+ (IRQPIN_EXTINT3 << IRQPOS_EXTINT3) |
+ (IRQPIN_EXTINT2 << IRQPOS_EXTINT2) |
+ (IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2);
+
+ /* FPGA + 0x0A */
+ __raw_writew((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
+
+ plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */
+
+ /* ICR1: detect low level(for 2ndcut) */
+ __raw_writel(0xAAAA0000, INTC_ICR1);
+
+ /*
+ * FPGA PCISEL register initialize
+ *
+ * CPU || SLOT1 | SLOT2 | S-ATA | USB
+ * -------------------------------------
+ * INTA || INTA | INTD | -- | INTB
+ * -------------------------------------
+ * INTB || INTB | INTA | -- | INTC
+ * -------------------------------------
+ * INTC || INTC | INTB | INTA | --
+ * -------------------------------------
+ * INTD || INTD | INTC | -- | INTA
+ * -------------------------------------
+ */
+ __raw_writew(0x0013, FPGA_PCI_INTSEL1);
+ __raw_writew(0xE402, FPGA_PCI_INTSEL2);
+}
diff --git a/arch/sh/boards/mach-se/7780/setup.c b/arch/sh/boards/mach-se/7780/setup.c
new file mode 100644
index 000000000..309f26813
--- /dev/null
+++ b/arch/sh/boards/mach-se/7780/setup.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/se/7780/setup.c
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/machvec.h>
+#include <mach-se/mach/se7780.h>
+#include <asm/io.h>
+#include <asm/heartbeat.h>
+
+/* Heartbeat */
+static struct resource heartbeat_resource = {
+ .start = PA_LED,
+ .end = PA_LED,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* SMC91x */
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SMC_IRQ,
+ .end = SMC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct platform_device *se7780_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+};
+
+static int __init se7780_devices_setup(void)
+{
+ return platform_add_devices(se7780_devices,
+ ARRAY_SIZE(se7780_devices));
+}
+device_initcall(se7780_devices_setup);
+
+#define GPIO_PHCR 0xFFEA000E
+#define GPIO_PMSELR 0xFFEA0080
+#define GPIO_PECR 0xFFEA0008
+
+static void __init se7780_setup(char **cmdline_p)
+{
+ /* "SH-Linux" on LED Display */
+ __raw_writew( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) );
+ __raw_writew( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) );
+ __raw_writew( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) );
+ __raw_writew( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) );
+ __raw_writew( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) );
+ __raw_writew( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) );
+ __raw_writew( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) );
+ __raw_writew( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) );
+
+ printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n");
+
+ /*
+ * PCI REQ/GNT setting
+ * REQ0/GNT0 -> USB
+ * REQ1/GNT1 -> PC Card
+ * REQ2/GNT2 -> Serial ATA
+ * REQ3/GNT3 -> PCI slot
+ */
+ __raw_writew(0x0213, FPGA_REQSEL);
+
+ /* GPIO setting */
+ __raw_writew(0x0000, GPIO_PECR);
+ __raw_writew(__raw_readw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
+ __raw_writew(0x0c00, GPIO_PMSELR);
+
+ /* iVDR Power ON */
+ __raw_writew(0x0001, FPGA_IVDRPW);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_se7780 __initmv = {
+ .mv_name = "Solution Engine 7780" ,
+ .mv_setup = se7780_setup ,
+ .mv_init_irq = init_se7780_IRQ,
+};
diff --git a/arch/sh/boards/mach-se/Makefile b/arch/sh/boards/mach-se/Makefile
new file mode 100644
index 000000000..8f69fc147
--- /dev/null
+++ b/arch/sh/boards/mach-se/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_SH_7619_SOLUTION_ENGINE) += board-se7619.o
+
+obj-$(CONFIG_SH_SOLUTION_ENGINE) += 770x/
+obj-$(CONFIG_SH_7206_SOLUTION_ENGINE) += 7206/
+obj-$(CONFIG_SH_7722_SOLUTION_ENGINE) += 7722/
+obj-$(CONFIG_SH_7751_SOLUTION_ENGINE) += 7751/
+obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += 7780/
+obj-$(CONFIG_SH_7343_SOLUTION_ENGINE) += 7343/
+obj-$(CONFIG_SH_7721_SOLUTION_ENGINE) += 7721/
+obj-$(CONFIG_SH_7724_SOLUTION_ENGINE) += 7724/
diff --git a/arch/sh/boards/mach-se/board-se7619.c b/arch/sh/boards/mach-se/board-se7619.c
new file mode 100644
index 000000000..4431da64a
--- /dev/null
+++ b/arch/sh/boards/mach-se/board-se7619.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/se/7619/setup.c
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ *
+ * Hitachi SH7619 SolutionEngine Support.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+static int se7619_mode_pins(void)
+{
+ return MODE_PIN2 | MODE_PIN0;
+}
+
+/*
+ * The Machine Vector
+ */
+
+static struct sh_machine_vector mv_se __initmv = {
+ .mv_name = "SolutionEngine",
+ .mv_mode_pins = se7619_mode_pins,
+};
diff --git a/arch/sh/boards/mach-sh03/Makefile b/arch/sh/boards/mach-sh03/Makefile
new file mode 100644
index 000000000..f89c25c6a
--- /dev/null
+++ b/arch/sh/boards/mach-sh03/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Interface (CTP/PCI-SH03) specific parts of the kernel
+#
+
+obj-y := setup.o
+obj-$(CONFIG_RTC_DRV_GENERIC) += rtc.o
diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c
new file mode 100644
index 000000000..7fb474844
--- /dev/null
+++ b/arch/sh/boards/mach-sh03/rtc.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/sh03/rtc.c -- CTP/PCI-SH03 on-chip RTC support
+ *
+ * Copyright (C) 2004 Saito.K & Jeanne(ksaito@interface.co.jp)
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/bcd.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#define RTC_BASE 0xb0000000
+#define RTC_SEC1 (RTC_BASE + 0)
+#define RTC_SEC10 (RTC_BASE + 1)
+#define RTC_MIN1 (RTC_BASE + 2)
+#define RTC_MIN10 (RTC_BASE + 3)
+#define RTC_HOU1 (RTC_BASE + 4)
+#define RTC_HOU10 (RTC_BASE + 5)
+#define RTC_WEE1 (RTC_BASE + 6)
+#define RTC_DAY1 (RTC_BASE + 7)
+#define RTC_DAY10 (RTC_BASE + 8)
+#define RTC_MON1 (RTC_BASE + 9)
+#define RTC_MON10 (RTC_BASE + 10)
+#define RTC_YEA1 (RTC_BASE + 11)
+#define RTC_YEA10 (RTC_BASE + 12)
+#define RTC_YEA100 (RTC_BASE + 13)
+#define RTC_YEA1000 (RTC_BASE + 14)
+#define RTC_CTL (RTC_BASE + 15)
+#define RTC_BUSY 1
+#define RTC_STOP 2
+
+static DEFINE_SPINLOCK(sh03_rtc_lock);
+
+static int sh03_rtc_gettimeofday(struct device *dev, struct rtc_time *tm)
+{
+ unsigned int year, mon, day, hour, min, sec;
+
+ spin_lock(&sh03_rtc_lock);
+ again:
+ do {
+ sec = (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10;
+ min = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10;
+ hour = (__raw_readb(RTC_HOU1) & 0xf) + (__raw_readb(RTC_HOU10) & 0xf) * 10;
+ day = (__raw_readb(RTC_DAY1) & 0xf) + (__raw_readb(RTC_DAY10) & 0xf) * 10;
+ mon = (__raw_readb(RTC_MON1) & 0xf) + (__raw_readb(RTC_MON10) & 0xf) * 10;
+ year = (__raw_readb(RTC_YEA1) & 0xf) + (__raw_readb(RTC_YEA10) & 0xf) * 10
+ + (__raw_readb(RTC_YEA100 ) & 0xf) * 100
+ + (__raw_readb(RTC_YEA1000) & 0xf) * 1000;
+ } while (sec != (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10);
+ if (year == 0 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
+ hour > 23 || min > 59 || sec > 59) {
+ printk(KERN_ERR
+ "SH-03 RTC: invalid value, resetting to 1 Jan 2000\n");
+ printk("year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n",
+ year, mon, day, hour, min, sec);
+
+ __raw_writeb(0, RTC_SEC1); __raw_writeb(0, RTC_SEC10);
+ __raw_writeb(0, RTC_MIN1); __raw_writeb(0, RTC_MIN10);
+ __raw_writeb(0, RTC_HOU1); __raw_writeb(0, RTC_HOU10);
+ __raw_writeb(6, RTC_WEE1);
+ __raw_writeb(1, RTC_DAY1); __raw_writeb(0, RTC_DAY10);
+ __raw_writeb(1, RTC_MON1); __raw_writeb(0, RTC_MON10);
+ __raw_writeb(0, RTC_YEA1); __raw_writeb(0, RTC_YEA10);
+ __raw_writeb(0, RTC_YEA100);
+ __raw_writeb(2, RTC_YEA1000);
+ __raw_writeb(0, RTC_CTL);
+ goto again;
+ }
+
+ spin_unlock(&sh03_rtc_lock);
+
+ tm->tm_sec = sec;
+ tm->tm_min = min;
+ tm->tm_hour = hour;
+ tm->tm_mday = day;
+ tm->tm_mon = mon;
+ tm->tm_year = year - 1900;
+
+ return 0;
+}
+
+static int set_rtc_mmss(struct rtc_time *tm)
+{
+ int retval = 0;
+ int real_seconds, real_minutes, cmos_minutes;
+ int i;
+
+ /* gets recalled with irq locally disabled */
+ spin_lock(&sh03_rtc_lock);
+ for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
+ if (!(__raw_readb(RTC_CTL) & RTC_BUSY))
+ break;
+ cmos_minutes = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10;
+ real_seconds = tm->tm_sec;
+ real_minutes = tm->tm_min;
+ if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+ real_minutes %= 60;
+
+ if (abs(real_minutes - cmos_minutes) < 30) {
+ __raw_writeb(real_seconds % 10, RTC_SEC1);
+ __raw_writeb(real_seconds / 10, RTC_SEC10);
+ __raw_writeb(real_minutes % 10, RTC_MIN1);
+ __raw_writeb(real_minutes / 10, RTC_MIN10);
+ } else {
+ printk_once(KERN_NOTICE
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);
+ retval = -EINVAL;
+ }
+ spin_unlock(&sh03_rtc_lock);
+
+ return retval;
+}
+
+int sh03_rtc_settimeofday(struct device *dev, struct rtc_time *tm)
+{
+ return set_rtc_mmss(tm);
+}
+
+static const struct rtc_class_ops rtc_generic_ops = {
+ .read_time = sh03_rtc_gettimeofday,
+ .set_time = sh03_rtc_settimeofday,
+};
+
+static int __init sh03_time_init(void)
+{
+ struct platform_device *pdev;
+
+ pdev = platform_device_register_data(NULL, "rtc-generic", -1,
+ &rtc_generic_ops,
+ sizeof(rtc_generic_ops));
+
+ return PTR_ERR_OR_ZERO(pdev);
+}
+arch_initcall(sh03_time_init);
diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c
new file mode 100644
index 000000000..3901b6031
--- /dev/null
+++ b/arch/sh/boards/mach-sh03/setup.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/sh03/setup.c
+ *
+ * Copyright (C) 2004 Interface Co.,Ltd. Saito.K
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <asm/io.h>
+#include <asm/rtc.h>
+#include <mach-sh03/mach/io.h>
+#include <mach-sh03/mach/sh03.h>
+#include <asm/addrspace.h>
+
+static void __init init_sh03_IRQ(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x1f0,
+ .end = 0x1f0 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = 0x1f0 + 0x206,
+ .end = 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = IRL2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = 0xa0800000,
+ .end = 0xa0800000,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct platform_device *sh03_devices[] __initdata = {
+ &heartbeat_device,
+ &cf_ide_device,
+};
+
+static int __init sh03_devices_setup(void)
+{
+ pgprot_t prot;
+ unsigned long paddrbase;
+ void *cf_ide_base;
+
+ /* open I/O area window */
+ paddrbase = virt_to_phys((void *)PA_AREA5_IO);
+ prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
+ cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot));
+ if (!cf_ide_base) {
+ printk("allocate_cf_area : can't open CF I/O window!\n");
+ return -ENOMEM;
+ }
+
+ /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
+ cf_ide_resources[0].start += (unsigned long)cf_ide_base;
+ cf_ide_resources[0].end += (unsigned long)cf_ide_base;
+ cf_ide_resources[1].start += (unsigned long)cf_ide_base;
+ cf_ide_resources[1].end += (unsigned long)cf_ide_base;
+
+ return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices));
+}
+device_initcall(sh03_devices_setup);
+
+static struct sh_machine_vector mv_sh03 __initmv = {
+ .mv_name = "Interface (CTP/PCI-SH03)",
+ .mv_init_irq = init_sh03_IRQ,
+};
diff --git a/arch/sh/boards/mach-sh7763rdp/Makefile b/arch/sh/boards/mach-sh7763rdp/Makefile
new file mode 100644
index 000000000..d63413104
--- /dev/null
+++ b/arch/sh/boards/mach-sh7763rdp/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/mach-sh7763rdp/irq.c b/arch/sh/boards/mach-sh7763rdp/irq.c
new file mode 100644
index 000000000..efd382b7d
--- /dev/null
+++ b/arch/sh/boards/mach-sh7763rdp/irq.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/renesas/sh7763rdp/irq.c
+ *
+ * Renesas Solutions SH7763RDP Support.
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Copyright (C) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <mach/sh7763rdp.h>
+
+#define INTC_BASE (0xFFD00000)
+#define INTC_INT2PRI7 (INTC_BASE+0x4001C)
+#define INTC_INT2MSKCR (INTC_BASE+0x4003C)
+#define INTC_INT2MSKCR1 (INTC_BASE+0x400D4)
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_sh7763rdp_IRQ(void)
+{
+ /* GPIO enabled */
+ __raw_writel(1 << 25, INTC_INT2MSKCR);
+
+ /* enable GPIO interrupts */
+ __raw_writel((__raw_readl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000,
+ INTC_INT2PRI7);
+
+ /* USBH enabled */
+ __raw_writel(1 << 17, INTC_INT2MSKCR1);
+
+ /* GETHER enabled */
+ __raw_writel(1 << 16, INTC_INT2MSKCR1);
+
+ /* DMAC enabled */
+ __raw_writel(1 << 8, INTC_INT2MSKCR);
+}
diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c
new file mode 100644
index 000000000..97e715e4e
--- /dev/null
+++ b/arch/sh/boards/mach-sh7763rdp/setup.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/sh/boards/renesas/sh7763rdp/setup.c
+ *
+ * Renesas Solutions sh7763rdp board
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Copyright (C) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/mtd/physmap.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/sh_eth.h>
+#include <linux/sh_intc.h>
+#include <mach/sh7763rdp.h>
+#include <asm/sh7760fb.h>
+
+/* NOR Flash */
+static struct mtd_partition sh7763rdp_nor_flash_partitions[] = {
+ {
+ .name = "U-Boot",
+ .offset = 0,
+ .size = (2 * 128 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "Linux-Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (20 * 128 * 1024),
+ }, {
+ .name = "Root Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data sh7763rdp_nor_flash_data = {
+ .width = 2,
+ .parts = sh7763rdp_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(sh7763rdp_nor_flash_partitions),
+};
+
+static struct resource sh7763rdp_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0,
+ .end = (64 * 1024 * 1024),
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sh7763rdp_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = sh7763rdp_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(sh7763rdp_nor_flash_resources),
+ .dev = {
+ .platform_data = &sh7763rdp_nor_flash_data,
+ },
+};
+
+/*
+ * SH-Ether
+ *
+ * SH Ether of SH7763 has multi IRQ handling.
+ * (0x920,0x940,0x960 -> 0x920)
+ */
+static struct resource sh_eth_resources[] = {
+ {
+ .start = 0xFEE00800, /* use eth1 */
+ .end = 0xFEE00F7C - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0xFEE01800, /* TSU */
+ .end = 0xFEE01FFF,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x920), /* irq number */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7763_eth_pdata = {
+ .phy = 1,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device sh7763rdp_eth_device = {
+ .name = "sh7763-gether",
+ .resource = sh_eth_resources,
+ .num_resources = ARRAY_SIZE(sh_eth_resources),
+ .dev = {
+ .platform_data = &sh7763_eth_pdata,
+ },
+};
+
+/* SH7763 LCDC */
+static struct resource sh7763rdp_fb_resources[] = {
+ {
+ .start = 0xFFE80000,
+ .end = 0xFFE80442 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct fb_videomode sh7763fb_videomode = {
+ .refresh = 60,
+ .name = "VGA Monitor",
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 10000,
+ .left_margin = 80,
+ .right_margin = 24,
+ .upper_margin = 30,
+ .lower_margin = 1,
+ .hsync_len = 96,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = FBINFO_FLAG_DEFAULT,
+};
+
+static struct sh7760fb_platdata sh7763fb_def_pdata = {
+ .def_mode = &sh7763fb_videomode,
+ .ldmtr = (LDMTR_TFT_COLOR_16|LDMTR_MCNT),
+ .lddfr = LDDFR_16BPP_RGB565,
+ .ldpmmr = 0x0000,
+ .ldpspr = 0xFFFF,
+ .ldaclnr = 0x0001,
+ .ldickr = 0x1102,
+ .rotate = 0,
+ .novsync = 0,
+ .blank = NULL,
+};
+
+static struct platform_device sh7763rdp_fb_device = {
+ .name = "sh7760-lcdc",
+ .resource = sh7763rdp_fb_resources,
+ .num_resources = ARRAY_SIZE(sh7763rdp_fb_resources),
+ .dev = {
+ .platform_data = &sh7763fb_def_pdata,
+ },
+};
+
+static struct platform_device *sh7763rdp_devices[] __initdata = {
+ &sh7763rdp_nor_flash_device,
+ &sh7763rdp_eth_device,
+ &sh7763rdp_fb_device,
+};
+
+static int __init sh7763rdp_devices_setup(void)
+{
+ return platform_add_devices(sh7763rdp_devices,
+ ARRAY_SIZE(sh7763rdp_devices));
+}
+device_initcall(sh7763rdp_devices_setup);
+
+static void __init sh7763rdp_setup(char **cmdline_p)
+{
+ /* Board version check */
+ if (__raw_readw(CPLD_BOARD_ID_ERV_REG) == 0xECB1)
+ printk(KERN_INFO "RTE Standard Configuration\n");
+ else
+ printk(KERN_INFO "RTA Standard Configuration\n");
+
+ /* USB pin select bits (clear bit 5-2 to 0) */
+ __raw_writew((__raw_readw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2);
+ /* USBH setup port I controls to other (clear bits 4-9 to 0) */
+ __raw_writew(__raw_readw(PORT_PICR) & 0xFC0F, PORT_PICR);
+
+ /* Select USB Host controller */
+ __raw_writew(0x00, USB_USBHSC);
+
+ /* For LCD */
+ /* set PTJ7-1, bits 15-2 of PJCR to 0 */
+ __raw_writew(__raw_readw(PORT_PJCR) & 0x0003, PORT_PJCR);
+ /* set PTI5, bits 11-10 of PICR to 0 */
+ __raw_writew(__raw_readw(PORT_PICR) & 0xF3FF, PORT_PICR);
+ __raw_writew(0, PORT_PKCR);
+ __raw_writew(0, PORT_PLCR);
+ /* set PSEL2 bits 14-8, 5-4, of PSEL2 to 0 */
+ __raw_writew((__raw_readw(PORT_PSEL2) & 0x00C0), PORT_PSEL2);
+ /* set PSEL3 bits 14-12, 6-4, 2-0 of PSEL3 to 0 */
+ __raw_writew((__raw_readw(PORT_PSEL3) & 0x0700), PORT_PSEL3);
+
+ /* For HAC */
+ /* bit3-0 0100:HAC & SSI1 enable */
+ __raw_writew((__raw_readw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1);
+ /* bit14 1:SSI_HAC_CLK enable */
+ __raw_writew(__raw_readw(PORT_PSEL4) | 0x4000, PORT_PSEL4);
+
+ /* SH-Ether */
+ __raw_writew((__raw_readw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1);
+ __raw_writew(0x0, PORT_PFCR);
+ __raw_writew(0x0, PORT_PFCR);
+ __raw_writew(0x0, PORT_PFCR);
+
+ /* MMC */
+ /*selects SCIF and MMC other functions */
+ __raw_writew(0x0001, PORT_PSEL0);
+ /* MMC clock operates */
+ __raw_writel(__raw_readl(MSTPCR1) & ~0x8, MSTPCR1);
+ __raw_writew(__raw_readw(PORT_PACR) & ~0x3000, PORT_PACR);
+ __raw_writew(__raw_readw(PORT_PCCR) & ~0xCFC3, PORT_PCCR);
+}
+
+static struct sh_machine_vector mv_sh7763rdp __initmv = {
+ .mv_name = "sh7763drp",
+ .mv_setup = sh7763rdp_setup,
+ .mv_init_irq = init_sh7763rdp_IRQ,
+};
diff --git a/arch/sh/boards/mach-x3proto/Makefile b/arch/sh/boards/mach-x3proto/Makefile
new file mode 100644
index 000000000..6caefa114
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += setup.o ilsel.o
+
+obj-$(CONFIG_GPIOLIB) += gpio.o
diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c
new file mode 100644
index 000000000..f82d3a6a8
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/gpio.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/mach-x3proto/gpio.c
+ *
+ * Renesas SH-X3 Prototype Baseboard GPIO Support.
+ *
+ * Copyright (C) 2010 - 2012 Paul Mundt
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/gpio/driver.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <mach/ilsel.h>
+#include <mach/hardware.h>
+
+#define KEYCTLR 0xb81c0000
+#define KEYOUTR 0xb81c0002
+#define KEYDETR 0xb81c0004
+
+static DEFINE_SPINLOCK(x3proto_gpio_lock);
+static struct irq_domain *x3proto_irq_domain;
+
+static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ unsigned long flags;
+ unsigned int data;
+
+ spin_lock_irqsave(&x3proto_gpio_lock, flags);
+ data = __raw_readw(KEYCTLR);
+ data |= (1 << gpio);
+ __raw_writew(data, KEYCTLR);
+ spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
+
+ return 0;
+}
+
+static int x3proto_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+ return !!(__raw_readw(KEYDETR) & (1 << gpio));
+}
+
+static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+ int virq;
+
+ if (gpio < chip->ngpio)
+ virq = irq_create_mapping(x3proto_irq_domain, gpio);
+ else
+ virq = -ENXIO;
+
+ return virq;
+}
+
+static void x3proto_gpio_irq_handler(struct irq_desc *desc)
+{
+ struct irq_data *data = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+ unsigned long mask;
+ int pin;
+
+ chip->irq_mask_ack(data);
+
+ mask = __raw_readw(KEYDETR);
+ for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS)
+ generic_handle_domain_irq(x3proto_irq_domain, pin);
+
+ chip->irq_unmask(data);
+}
+
+struct gpio_chip x3proto_gpio_chip = {
+ .label = "x3proto-gpio",
+ .direction_input = x3proto_gpio_direction_input,
+ .get = x3proto_gpio_get,
+ .to_irq = x3proto_gpio_to_irq,
+ .base = -1,
+ .ngpio = NR_BASEBOARD_GPIOS,
+};
+
+static int x3proto_gpio_irq_map(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler_name(virq, &dummy_irq_chip, handle_simple_irq,
+ "gpio");
+
+ return 0;
+}
+
+static struct irq_domain_ops x3proto_gpio_irq_ops = {
+ .map = x3proto_gpio_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+int __init x3proto_gpio_setup(void)
+{
+ int ilsel, ret;
+
+ ilsel = ilsel_enable(ILSEL_KEY);
+ if (unlikely(ilsel < 0))
+ return ilsel;
+
+ ret = gpiochip_add_data(&x3proto_gpio_chip, NULL);
+ if (unlikely(ret))
+ goto err_gpio;
+
+ x3proto_irq_domain = irq_domain_add_linear(NULL, NR_BASEBOARD_GPIOS,
+ &x3proto_gpio_irq_ops, NULL);
+ if (unlikely(!x3proto_irq_domain))
+ goto err_irq;
+
+ pr_info("registering '%s' support, handling GPIOs %u -> %u, "
+ "bound to IRQ %u\n",
+ x3proto_gpio_chip.label, x3proto_gpio_chip.base,
+ x3proto_gpio_chip.base + x3proto_gpio_chip.ngpio,
+ ilsel);
+
+ irq_set_chained_handler(ilsel, x3proto_gpio_irq_handler);
+ irq_set_irq_wake(ilsel, 1);
+
+ return 0;
+
+err_irq:
+ gpiochip_remove(&x3proto_gpio_chip);
+ ret = 0;
+err_gpio:
+ synchronize_irq(ilsel);
+
+ ilsel_disable(ILSEL_KEY);
+
+ return ret;
+}
diff --git a/arch/sh/boards/mach-x3proto/ilsel.c b/arch/sh/boards/mach-x3proto/ilsel.c
new file mode 100644
index 000000000..f0d5eb415
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/ilsel.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/mach-x3proto/ilsel.c
+ *
+ * Helper routines for SH-X3 proto board ILSEL.
+ *
+ * Copyright (C) 2007 - 2010 Paul Mundt
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/bitmap.h>
+#include <linux/io.h>
+#include <mach/ilsel.h>
+
+/*
+ * ILSEL is split across:
+ *
+ * ILSEL0 - 0xb8100004 [ Levels 1 - 4 ]
+ * ILSEL1 - 0xb8100006 [ Levels 5 - 8 ]
+ * ILSEL2 - 0xb8100008 [ Levels 9 - 12 ]
+ * ILSEL3 - 0xb810000a [ Levels 13 - 15 ]
+ *
+ * With each level being relative to an ilsel_source_t.
+ */
+#define ILSEL_BASE 0xb8100004
+#define ILSEL_LEVELS 15
+
+/*
+ * ILSEL level map, in descending order from the highest level down.
+ *
+ * Supported levels are 1 - 15 spread across ILSEL0 - ILSEL4, mapping
+ * directly to IRLs. As the IRQs are numbered in reverse order relative
+ * to the interrupt level, the level map is carefully managed to ensure a
+ * 1:1 mapping between the bit position and the IRQ number.
+ *
+ * This careful constructions allows ilsel_enable*() to be referenced
+ * directly for hooking up an ILSEL set and getting back an IRQ which can
+ * subsequently be used for internal accounting in the (optional) disable
+ * path.
+ */
+static unsigned long ilsel_level_map;
+
+static inline unsigned int ilsel_offset(unsigned int bit)
+{
+ return ILSEL_LEVELS - bit - 1;
+}
+
+static inline unsigned long mk_ilsel_addr(unsigned int bit)
+{
+ return ILSEL_BASE + ((ilsel_offset(bit) >> 1) & ~0x1);
+}
+
+static inline unsigned int mk_ilsel_shift(unsigned int bit)
+{
+ return (ilsel_offset(bit) & 0x3) << 2;
+}
+
+static void __ilsel_enable(ilsel_source_t set, unsigned int bit)
+{
+ unsigned int tmp, shift;
+ unsigned long addr;
+
+ pr_notice("enabling ILSEL set %d\n", set);
+
+ addr = mk_ilsel_addr(bit);
+ shift = mk_ilsel_shift(bit);
+
+ pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n",
+ __func__, bit, addr, shift, set);
+
+ tmp = __raw_readw(addr);
+ tmp &= ~(0xf << shift);
+ tmp |= set << shift;
+ __raw_writew(tmp, addr);
+}
+
+/**
+ * ilsel_enable - Enable an ILSEL set.
+ * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h).
+ *
+ * Enables a given non-aliased ILSEL source (<= ILSEL_KEY) at the highest
+ * available interrupt level. Callers should take care to order callsites
+ * noting descending interrupt levels. Aliasing FPGA and external board
+ * IRQs need to use ilsel_enable_fixed().
+ *
+ * The return value is an IRQ number that can later be taken down with
+ * ilsel_disable().
+ */
+int ilsel_enable(ilsel_source_t set)
+{
+ unsigned int bit;
+
+ if (unlikely(set > ILSEL_KEY)) {
+ pr_err("Aliased sources must use ilsel_enable_fixed()\n");
+ return -EINVAL;
+ }
+
+ do {
+ bit = find_first_zero_bit(&ilsel_level_map, ILSEL_LEVELS);
+ } while (test_and_set_bit(bit, &ilsel_level_map));
+
+ __ilsel_enable(set, bit);
+
+ return bit;
+}
+EXPORT_SYMBOL_GPL(ilsel_enable);
+
+/**
+ * ilsel_enable_fixed - Enable an ILSEL set at a fixed interrupt level
+ * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h).
+ * @level: Interrupt level (1 - 15)
+ *
+ * Enables a given ILSEL source at a fixed interrupt level. Necessary
+ * both for level reservation as well as for aliased sources that only
+ * exist on special ILSEL#s.
+ *
+ * Returns an IRQ number (as ilsel_enable()).
+ */
+int ilsel_enable_fixed(ilsel_source_t set, unsigned int level)
+{
+ unsigned int bit = ilsel_offset(level - 1);
+
+ if (test_and_set_bit(bit, &ilsel_level_map))
+ return -EBUSY;
+
+ __ilsel_enable(set, bit);
+
+ return bit;
+}
+EXPORT_SYMBOL_GPL(ilsel_enable_fixed);
+
+/**
+ * ilsel_disable - Disable an ILSEL set
+ * @irq: Bit position for ILSEL set value (retval from enable routines)
+ *
+ * Disable a previously enabled ILSEL set.
+ */
+void ilsel_disable(unsigned int irq)
+{
+ unsigned long addr;
+ unsigned int tmp;
+
+ pr_notice("disabling ILSEL set %d\n", irq);
+
+ addr = mk_ilsel_addr(irq);
+
+ tmp = __raw_readw(addr);
+ tmp &= ~(0xf << mk_ilsel_shift(irq));
+ __raw_writew(tmp, addr);
+
+ clear_bit(irq, &ilsel_level_map);
+}
+EXPORT_SYMBOL_GPL(ilsel_disable);
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
new file mode 100644
index 000000000..95b85f2e1
--- /dev/null
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * arch/sh/boards/mach-x3proto/setup.c
+ *
+ * Renesas SH-X3 Prototype Board Support.
+ *
+ * Copyright (C) 2007 - 2010 Paul Mundt
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/smc91x.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <mach/ilsel.h>
+#include <mach/hardware.h>
+#include <asm/smp-ops.h>
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = 0xb8140020,
+ .end = 0xb8140020,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = 0x18000300,
+ .end = 0x18000300 + 0x10 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* Filled in by ilsel */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .resource = smc91x_resources,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+static struct r8a66597_platdata r8a66597_data = {
+ .xtal = R8A66597_PLATDATA_XTAL_12MHZ,
+ .vif = 1,
+};
+
+static struct resource r8a66597_usb_host_resources[] = {
+ [0] = {
+ .start = 0x18040000,
+ .end = 0x18080000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* Filled in by ilsel */
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device r8a66597_usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &r8a66597_data,
+ },
+ .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources),
+ .resource = r8a66597_usb_host_resources,
+};
+
+static struct m66592_platdata usbf_platdata = {
+ .xtal = M66592_PLATDATA_XTAL_24MHZ,
+ .vif = 1,
+};
+
+static struct resource m66592_usb_peripheral_resources[] = {
+ [0] = {
+ .name = "m66592_udc",
+ .start = 0x18080000,
+ .end = 0x180c0000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "m66592_udc",
+ /* Filled in by ilsel */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m66592_usb_peripheral_device = {
+ .name = "m66592_udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usbf_platdata,
+ },
+ .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources),
+ .resource = m66592_usb_peripheral_resources,
+};
+
+static struct gpio_keys_button baseboard_buttons[NR_BASEBOARD_GPIOS] = {
+ {
+ .desc = "key44",
+ .code = KEY_POWER,
+ .active_low = 1,
+ .wakeup = 1,
+ }, {
+ .desc = "key43",
+ .code = KEY_SUSPEND,
+ .active_low = 1,
+ .wakeup = 1,
+ }, {
+ .desc = "key42",
+ .code = KEY_KATAKANAHIRAGANA,
+ .active_low = 1,
+ }, {
+ .desc = "key41",
+ .code = KEY_SWITCHVIDEOMODE,
+ .active_low = 1,
+ }, {
+ .desc = "key34",
+ .code = KEY_F12,
+ .active_low = 1,
+ }, {
+ .desc = "key33",
+ .code = KEY_F11,
+ .active_low = 1,
+ }, {
+ .desc = "key32",
+ .code = KEY_F10,
+ .active_low = 1,
+ }, {
+ .desc = "key31",
+ .code = KEY_F9,
+ .active_low = 1,
+ }, {
+ .desc = "key24",
+ .code = KEY_F8,
+ .active_low = 1,
+ }, {
+ .desc = "key23",
+ .code = KEY_F7,
+ .active_low = 1,
+ }, {
+ .desc = "key22",
+ .code = KEY_F6,
+ .active_low = 1,
+ }, {
+ .desc = "key21",
+ .code = KEY_F5,
+ .active_low = 1,
+ }, {
+ .desc = "key14",
+ .code = KEY_F4,
+ .active_low = 1,
+ }, {
+ .desc = "key13",
+ .code = KEY_F3,
+ .active_low = 1,
+ }, {
+ .desc = "key12",
+ .code = KEY_F2,
+ .active_low = 1,
+ }, {
+ .desc = "key11",
+ .code = KEY_F1,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data baseboard_buttons_data = {
+ .buttons = baseboard_buttons,
+ .nbuttons = ARRAY_SIZE(baseboard_buttons),
+};
+
+static struct platform_device baseboard_buttons_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &baseboard_buttons_data,
+ },
+};
+
+static struct platform_device *x3proto_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_device,
+ &r8a66597_usb_host_device,
+ &m66592_usb_peripheral_device,
+ &baseboard_buttons_device,
+};
+
+static void __init x3proto_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRL3210);
+
+ /* Set ICR0.LVLMODE */
+ __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
+}
+
+static int __init x3proto_devices_setup(void)
+{
+ int ret, i;
+
+ /*
+ * IRLs are only needed for ILSEL mappings, so flip over the INTC
+ * pins at a later point to enable the GPIOs to settle.
+ */
+ x3proto_init_irq();
+
+ /*
+ * Now that ILSELs are available, set up the baseboard GPIOs.
+ */
+ ret = x3proto_gpio_setup();
+ if (unlikely(ret))
+ return ret;
+
+ /*
+ * Propagate dynamic GPIOs for the baseboard button device.
+ */
+ for (i = 0; i < ARRAY_SIZE(baseboard_buttons); i++)
+ baseboard_buttons[i].gpio = x3proto_gpio_chip.base + i;
+
+ r8a66597_usb_host_resources[1].start =
+ r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I);
+
+ m66592_usb_peripheral_resources[1].start =
+ m66592_usb_peripheral_resources[1].end = ilsel_enable(ILSEL_USBP_I);
+
+ smc91x_resources[1].start =
+ smc91x_resources[1].end = ilsel_enable(ILSEL_LAN);
+
+ return platform_add_devices(x3proto_devices,
+ ARRAY_SIZE(x3proto_devices));
+}
+device_initcall(x3proto_devices_setup);
+
+static void __init x3proto_setup(char **cmdline_p)
+{
+ register_smp_ops(&shx3_smp_ops);
+}
+
+static struct sh_machine_vector mv_x3proto __initmv = {
+ .mv_name = "x3proto",
+ .mv_setup = x3proto_setup,
+};
diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
new file mode 100644
index 000000000..f7f3e618e
--- /dev/null
+++ b/arch/sh/boards/of-generic.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SH generic board support, using device tree
+ *
+ * Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
+ */
+
+#include <linux/of.h>
+#include <linux/of_clk.h>
+#include <linux/of_fdt.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+
+#ifdef CONFIG_SMP
+
+static void dummy_smp_setup(void)
+{
+}
+
+static void dummy_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point)
+{
+}
+
+static unsigned int dummy_smp_processor_id(void)
+{
+ return 0;
+}
+
+static void dummy_send_ipi(unsigned int cpu, unsigned int message)
+{
+}
+
+static struct plat_smp_ops dummy_smp_ops = {
+ .smp_setup = dummy_smp_setup,
+ .prepare_cpus = dummy_prepare_cpus,
+ .start_cpu = dummy_start_cpu,
+ .smp_processor_id = dummy_smp_processor_id,
+ .send_ipi = dummy_send_ipi,
+ .cpu_die = native_cpu_die,
+ .cpu_disable = native_cpu_disable,
+ .play_dead = native_play_dead,
+};
+
+extern const struct of_cpu_method __cpu_method_of_table[];
+const struct of_cpu_method __cpu_method_of_table_sentinel
+ __section("__cpu_method_of_table_end");
+
+static void sh_of_smp_probe(void)
+{
+ struct device_node *np;
+ const char *method = NULL;
+ const struct of_cpu_method *m = __cpu_method_of_table;
+
+ pr_info("SH generic board support: scanning for cpus\n");
+
+ init_cpu_possible(cpumask_of(0));
+
+ for_each_of_cpu_node(np) {
+ u64 id = of_get_cpu_hwid(np, 0);
+
+ if (id < NR_CPUS) {
+ if (!method)
+ of_property_read_string(np, "enable-method", &method);
+ set_cpu_possible(id, true);
+ set_cpu_present(id, true);
+ __cpu_number_map[id] = id;
+ __cpu_logical_map[id] = id;
+ }
+ }
+ if (!method) {
+ np = of_find_node_by_name(NULL, "cpus");
+ of_property_read_string(np, "enable-method", &method);
+ of_node_put(np);
+ }
+
+ pr_info("CPU enable method: %s\n", method);
+ if (method)
+ for (; m->method; m++)
+ if (!strcmp(m->method, method)) {
+ register_smp_ops(m->ops);
+ return;
+ }
+
+ register_smp_ops(&dummy_smp_ops);
+}
+
+#else
+
+static void sh_of_smp_probe(void)
+{
+}
+
+#endif
+
+static void noop(void)
+{
+}
+
+static int noopi(void)
+{
+ return 0;
+}
+
+static void __init sh_of_mem_reserve(void)
+{
+ early_init_fdt_reserve_self();
+ early_init_fdt_scan_reserved_mem();
+}
+
+static void __init sh_of_setup(char **cmdline_p)
+{
+ struct device_node *root;
+
+ sh_mv.mv_name = "Unknown SH model";
+ root = of_find_node_by_path("/");
+ if (root) {
+ of_property_read_string(root, "model", &sh_mv.mv_name);
+ of_node_put(root);
+ }
+
+ sh_of_smp_probe();
+}
+
+static int sh_of_irq_demux(int irq)
+{
+ /* FIXME: eventually this should not be used at all;
+ * the interrupt controller should set_handle_irq(). */
+ return irq;
+}
+
+static void __init sh_of_init_irq(void)
+{
+ pr_info("SH generic board support: scanning for interrupt controllers\n");
+ irqchip_init();
+}
+
+static int __init sh_of_clk_init(void)
+{
+#ifdef CONFIG_COMMON_CLK
+ /* Disabled pending move to COMMON_CLK framework. */
+ pr_info("SH generic board support: scanning for clk providers\n");
+ of_clk_init(NULL);
+#endif
+ return 0;
+}
+
+static struct sh_machine_vector __initmv sh_of_generic_mv = {
+ .mv_setup = sh_of_setup,
+ .mv_name = "devicetree", /* replaced by DT root's model */
+ .mv_irq_demux = sh_of_irq_demux,
+ .mv_init_irq = sh_of_init_irq,
+ .mv_clk_init = sh_of_clk_init,
+ .mv_mode_pins = noopi,
+ .mv_mem_init = noop,
+ .mv_mem_reserve = sh_of_mem_reserve,
+};
+
+struct sh_clk_ops;
+
+void __init __weak arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
+{
+}
+
+void __init __weak plat_irq_setup(void)
+{
+}