Merge branch 'rmobile-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6

* 'rmobile-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (67 commits)
  ARM: mach-shmobile: update for SMP changes.
  ARM: mach-shmobile: update for GIC changes.
  ARM: mach-shmobile: Fix up clkdev fallout for SH73A0.
  dma: shdma: don't register the global die notifier multiple times
  ARM: mach-shmobile: Rely on run-time IRQ handlers
  ARM: mach-shmobile: Run-time IRQ handler for GIC
  ARM: mach-shmobile: Run-time IRQ handler for INTCA
  ARM: mach-shmobile: Enable CONFIG_MULTI_IRQ_HANDLER
  ARM: mach-shmobile: Use shared GIC entry macros
  ARM: mach-shmobile: mackerel: Add zboot support
  ARM: mach-shmobile: mackerel: Add HDMI sound support
  ARM: mach-shmobile: mackerel: add HDMI video support
  ARM: mach-shmobile: ap4evb: fixup clk_put timing of fsib_clk
  ARM: mach-shmobile: sh73a0: fix div4 table
  ARM: mach-shmobile: ap4/mackerel: modify wrong comment out of USB
  ARM: mach-shmobile: Mackerel VGA camera support
  mmc: sh_mmcif: make DMA support by the driver unconditional
  ARM: mach-shmobile: Add eMMC support through MMCIF on AG5EVM
  ARM: mach-shmobile: Use pullups for AG5EVM KEYSC pins
  ARM: mach-shmobile: sh73a0 GPIO pullup improvement
  ...
This commit is contained in:
Linus Torvalds 2011-01-07 14:50:14 -08:00
commit d074b104ce
40 changed files with 6907 additions and 223 deletions

View File

@ -105,3 +105,4 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Uwe Kleine-König <ukl@pengutronix.de> Uwe Kleine-König <ukl@pengutronix.de>
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Valdis Kletnieks <Valdis.Kletnieks@vt.edu> Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Takashi YOSHII <takashi.yoshii.zj@renesas.com>

View File

@ -632,9 +632,15 @@ config ARCH_MSM
(clock and power control, etc). (clock and power control, etc).
config ARCH_SHMOBILE config ARCH_SHMOBILE
bool "Renesas SH-Mobile" bool "Renesas SH-Mobile / R-Mobile"
select HAVE_CLK
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select NO_IOPORT
select SPARSE_IRQ
select MULTI_IRQ_HANDLER
help help
Support for Renesas's SH-Mobile ARM platforms Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
config ARCH_RPC config ARCH_RPC
bool "RiscPC" bool "RiscPC"
@ -1252,7 +1258,7 @@ config SMP
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
ARCH_MSM_SCORPIONMP ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
select USE_GENERIC_SMP_HELPERS select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
help help

View File

@ -0,0 +1,83 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_SHMOBILE=y
CONFIG_ARCH_SH73A0=y
CONFIG_MACH_AG5EVM=y
CONFIG_MEMORY_SIZE=0x10000000
CONFIG_CPU_BPREDICT_DISABLE=y
CONFIG_ARM_ERRATA_430973=y
CONFIG_ARM_ERRATA_458693=y
CONFIG_NO_HZ=y
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
CONFIG_HIGHMEM=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=tty0 console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel"
CONFIG_CMDLINE_FORCE=y
CONFIG_KEXEC=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM=y
# CONFIG_SUSPEND is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_BLK_DEV is not set
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_SMSC911X=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_WLAN is not set
CONFIG_INPUT_SPARSEKMAP=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=9
CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_SH_MOBILE=y
# CONFIG_HWMON is not set
# CONFIG_MFD_SUPPORT is not set
CONFIG_FB=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_FTRACE is not set

View File

@ -0,0 +1,138 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_NET_NS is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_SHMOBILE=y
CONFIG_ARCH_SH7372=y
CONFIG_MACH_MACKEREL=y
CONFIG_MEMORY_SIZE=0x10000000
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
CONFIG_FORCE_MAX_ZONEORDER=15
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp memchunk.vpu=64m memchunk.veu0=8m memchunk.spu0=2m mem=240m"
CONFIG_KEXEC=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM=y
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_ARM_INTEGRATOR=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_SMSC911X=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_WLAN is not set
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=8
CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
# CONFIG_MFD_SUPPORT is not set
CONFIG_FB=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT2_FS_XIP=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_852=y
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_UTF8=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_ARM_UNWIND is not set
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ANSI_CPRNG=y

View File

@ -5,26 +5,27 @@ comment "SH-Mobile System Type"
config ARCH_SH7367 config ARCH_SH7367
bool "SH-Mobile G3 (SH7367)" bool "SH-Mobile G3 (SH7367)"
select CPU_V6 select CPU_V6
select HAVE_CLK
select CLKDEV_LOOKUP
select SH_CLK_CPG select SH_CLK_CPG
select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH7377 config ARCH_SH7377
bool "SH-Mobile G4 (SH7377)" bool "SH-Mobile G4 (SH7377)"
select CPU_V7 select CPU_V7
select HAVE_CLK
select CLKDEV_LOOKUP
select SH_CLK_CPG select SH_CLK_CPG
select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH7372 config ARCH_SH7372
bool "SH-Mobile AP4 (SH7372)" bool "SH-Mobile AP4 (SH7372)"
select CPU_V7 select CPU_V7
select HAVE_CLK
select CLKDEV_LOOKUP
select SH_CLK_CPG select SH_CLK_CPG
select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH73A0
bool "SH-Mobile AG5 (R8A73A00)"
select CPU_V7
select SH_CLK_CPG
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
comment "SH-Mobile Board Type" comment "SH-Mobile Board Type"
@ -57,6 +58,15 @@ config AP4EVB_WVGA
endchoice endchoice
config MACH_AG5EVM
bool "AG5EVM board"
depends on ARCH_SH73A0
config MACH_MACKEREL
bool "mackerel board"
depends on ARCH_SH7372
select ARCH_REQUIRE_GPIOLIB
comment "SH-Mobile System Configuration" comment "SH-Mobile System Configuration"
menu "Memory configuration" menu "Memory configuration"
@ -64,8 +74,8 @@ menu "Memory configuration"
config MEMORY_START config MEMORY_START
hex "Physical memory start address" hex "Physical memory start address"
default "0x50000000" if MACH_G3EVM default "0x50000000" if MACH_G3EVM
default "0x40000000" if MACH_G4EVM default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
default "0x40000000" if MACH_AP4EVB MACH_MACKEREL
default "0x00000000" default "0x00000000"
---help--- ---help---
Tweak this only when porting to a new machine which does not Tweak this only when porting to a new machine which does not
@ -76,7 +86,8 @@ config MEMORY_SIZE
hex "Physical memory size" hex "Physical memory size"
default "0x08000000" if MACH_G3EVM default "0x08000000" if MACH_G3EVM
default "0x08000000" if MACH_G4EVM default "0x08000000" if MACH_G4EVM
default "0x10000000" if MACH_AP4EVB default "0x20000000" if MACH_AG5EVM
default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
default "0x04000000" default "0x04000000"
help help
This sets the default memory size assumed by your kernel. It can This sets the default memory size assumed by your kernel. It can

View File

@ -9,14 +9,34 @@ obj-y := timer.o console.o clock.o pm_runtime.o
obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
# SMP objects
smp-y := platsmp.o headsmp.o
smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
# Pinmux setup # Pinmux setup
pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o pfc-y :=
pfc-$(CONFIG_ARCH_SH7377) := pfc-sh7377.o pfc-$(CONFIG_ARCH_SH7367) += pfc-sh7367.o
pfc-$(CONFIG_ARCH_SH7372) := pfc-sh7372.o pfc-$(CONFIG_ARCH_SH7377) += pfc-sh7377.o
obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y) pfc-$(CONFIG_ARCH_SH7372) += pfc-sh7372.o
pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o
# IRQ objects
obj-$(CONFIG_ARCH_SH7367) += entry-intc.o
obj-$(CONFIG_ARCH_SH7377) += entry-intc.o
obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o
# Board objects # Board objects
obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
# Framework support
obj-$(CONFIG_SMP) += $(smp-y)
obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y)

View File

@ -0,0 +1,315 @@
/*
* arch/arm/mach-shmobile/board-ag5evm.c
*
* Copyright (C) 2010 Takashi Yoshii <yoshii.takashi.zj@renesas.com>
* Copyright (C) 2009 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/serial_sci.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
#include <sound/sh_fsi.h>
#include <mach/hardware.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/traps.h>
static struct resource smsc9220_resources[] = {
[0] = {
.start = 0x14000000,
.end = 0x14000000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(33), /* PINT1 */
.flags = IORESOURCE_IRQ,
},
};
static struct smsc911x_platform_config smsc9220_platdata = {
.flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
.phy_interface = PHY_INTERFACE_MODE_MII,
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
};
static struct platform_device eth_device = {
.name = "smsc911x",
.id = 0,
.dev = {
.platform_data = &smsc9220_platdata,
},
.resource = smsc9220_resources,
.num_resources = ARRAY_SIZE(smsc9220_resources),
};
static struct sh_keysc_info keysc_platdata = {
.mode = SH_KEYSC_MODE_6,
.scan_timing = 3,
.delay = 100,
.keycodes = {
KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
KEY_SPACE, KEY_9, KEY_6, KEY_3, KEY_WAKEUP, KEY_RIGHT, \
KEY_COFFEE,
KEY_0, KEY_8, KEY_5, KEY_2, KEY_DOWN, KEY_ENTER, KEY_UP,
KEY_KPASTERISK, KEY_7, KEY_4, KEY_1, KEY_STOP, KEY_LEFT, \
KEY_COMPUTER,
},
};
static struct resource keysc_resources[] = {
[0] = {
.name = "KEYSC",
.start = 0xe61b0000,
.end = 0xe61b0098 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(71),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device keysc_device = {
.name = "sh_keysc",
.id = 0,
.num_resources = ARRAY_SIZE(keysc_resources),
.resource = keysc_resources,
.dev = {
.platform_data = &keysc_platdata,
},
};
/* FSI A */
static struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_OUT_SLAVE_MODE |
SH_FSI_IN_SLAVE_MODE |
SH_FSI_OFMT(I2S) |
SH_FSI_IFMT(I2S),
};
static struct resource fsi_resources[] = {
[0] = {
.name = "FSI",
.start = 0xEC230000,
.end = 0xEC230400 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(146),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device fsi_device = {
.name = "sh_fsi2",
.id = -1,
.num_resources = ARRAY_SIZE(fsi_resources),
.resource = fsi_resources,
.dev = {
.platform_data = &fsi_info,
},
};
static struct resource sh_mmcif_resources[] = {
[0] = {
.name = "MMCIF",
.start = 0xe6bd0000,
.end = 0xe6bd00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(141),
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = gic_spi(140),
.flags = IORESOURCE_IRQ,
},
};
static struct sh_mmcif_plat_data sh_mmcif_platdata = {
.sup_pclk = 0,
.ocr = MMC_VDD_165_195,
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
};
static struct platform_device mmc_device = {
.name = "sh_mmcif",
.id = 0,
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
.platform_data = &sh_mmcif_platdata,
},
.num_resources = ARRAY_SIZE(sh_mmcif_resources),
.resource = sh_mmcif_resources,
};
static struct platform_device *ag5evm_devices[] __initdata = {
&eth_device,
&keysc_device,
&fsi_device,
&mmc_device,
};
static struct map_desc ag5evm_io_desc[] __initdata = {
/* create a 1:1 entity map for 0xe6xxxxxx
* used by CPGA, INTC and PFC.
*/
{
.virtual = 0xe6000000,
.pfn = __phys_to_pfn(0xe6000000),
.length = 256 << 20,
.type = MT_DEVICE_NONSHARED
},
};
static void __init ag5evm_map_io(void)
{
iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
/* setup early devices and console here as well */
sh73a0_add_early_devices();
shmobile_setup_console();
}
#define PINTC_ADDR 0xe6900000
#define PINTER0A (PINTC_ADDR + 0xa0)
#define PINTCR0A (PINTC_ADDR + 0xb0)
void __init ag5evm_init_irq(void)
{
sh73a0_init_irq();
/* setup PINT: enable PINTA2 as active low */
__raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A);
__raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
}
static void __init ag5evm_init(void)
{
sh73a0_pinmux_init();
/* enable SCIFA2 */
gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
/* enable KEYSC */
gpio_request(GPIO_FN_KEYIN0_PU, NULL);
gpio_request(GPIO_FN_KEYIN1_PU, NULL);
gpio_request(GPIO_FN_KEYIN2_PU, NULL);
gpio_request(GPIO_FN_KEYIN3_PU, NULL);
gpio_request(GPIO_FN_KEYIN4_PU, NULL);
gpio_request(GPIO_FN_KEYIN5_PU, NULL);
gpio_request(GPIO_FN_KEYIN6_PU, NULL);
gpio_request(GPIO_FN_KEYIN7_PU, NULL);
gpio_request(GPIO_FN_KEYOUT0, NULL);
gpio_request(GPIO_FN_KEYOUT1, NULL);
gpio_request(GPIO_FN_KEYOUT2, NULL);
gpio_request(GPIO_FN_KEYOUT3, NULL);
gpio_request(GPIO_FN_KEYOUT4, NULL);
gpio_request(GPIO_FN_KEYOUT5, NULL);
gpio_request(GPIO_FN_PORT59_KEYOUT6, NULL);
gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
gpio_request(GPIO_FN_KEYOUT8, NULL);
gpio_request(GPIO_FN_PORT149_KEYOUT9, NULL);
/* enable I2C channel 2 and 3 */
gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL);
gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL);
gpio_request(GPIO_FN_PORT248_I2C_SCL3, NULL);
gpio_request(GPIO_FN_PORT249_I2C_SDA3, NULL);
/* enable MMCIF */
gpio_request(GPIO_FN_MMCCLK0, NULL);
gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
gpio_request(GPIO_FN_MMCD0_0, NULL);
gpio_request(GPIO_FN_MMCD0_1, NULL);
gpio_request(GPIO_FN_MMCD0_2, NULL);
gpio_request(GPIO_FN_MMCD0_3, NULL);
gpio_request(GPIO_FN_MMCD0_4, NULL);
gpio_request(GPIO_FN_MMCD0_5, NULL);
gpio_request(GPIO_FN_MMCD0_6, NULL);
gpio_request(GPIO_FN_MMCD0_7, NULL);
gpio_request(GPIO_PORT208, NULL); /* Reset */
gpio_direction_output(GPIO_PORT208, 1);
/* enable SMSC911X */
gpio_request(GPIO_PORT144, NULL); /* PINTA2 */
gpio_direction_input(GPIO_PORT144);
gpio_request(GPIO_PORT145, NULL); /* RESET */
gpio_direction_output(GPIO_PORT145, 1);
/* FSI A */
gpio_request(GPIO_FN_FSIACK, NULL);
gpio_request(GPIO_FN_FSIAILR, NULL);
gpio_request(GPIO_FN_FSIAIBT, NULL);
gpio_request(GPIO_FN_FSIAISLD, NULL);
gpio_request(GPIO_FN_FSIAOSLD, NULL);
#ifdef CONFIG_CACHE_L2X0
/* Shared attribute override enable, 64K*8way */
l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
#endif
sh73a0_add_standard_devices();
platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
}
static void __init ag5evm_timer_init(void)
{
sh73a0_clock_init();
shmobile_timer.init();
return;
}
struct sys_timer ag5evm_timer = {
.init = ag5evm_timer_init,
};
MACHINE_START(AG5EVM, "ag5evm")
.map_io = ag5evm_map_io,
.init_irq = ag5evm_init_irq,
.handle_irq = shmobile_handle_irq_gic,
.init_machine = ag5evm_init,
.timer = &ag5evm_timer,
MACHINE_END

View File

@ -273,6 +273,15 @@ static struct resource sh_mmcif_resources[] = {
}, },
}; };
static struct sh_mmcif_dma sh_mmcif_dma = {
.chan_priv_rx = {
.slave_id = SHDMA_SLAVE_MMCIF_RX,
},
.chan_priv_tx = {
.slave_id = SHDMA_SLAVE_MMCIF_TX,
},
};
static struct sh_mmcif_plat_data sh_mmcif_plat = { static struct sh_mmcif_plat_data sh_mmcif_plat = {
.sup_pclk = 0, .sup_pclk = 0,
.ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@ -280,6 +289,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
MMC_CAP_8_BIT_DATA | MMC_CAP_8_BIT_DATA |
MMC_CAP_NEEDS_POLL, MMC_CAP_NEEDS_POLL,
.get_cd = slot_cn7_get_cd, .get_cd = slot_cn7_get_cd,
.dma = &sh_mmcif_dma,
}; };
static struct platform_device sh_mmcif_device = { static struct platform_device sh_mmcif_device = {
@ -633,9 +643,8 @@ static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
return -EIO; return -EIO;
ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable); ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
clk_put(fsib_clk);
if (ret < 0) if (ret < 0)
return ret; goto fsi_set_rate_end;
/* FSI DIV setting */ /* FSI DIV setting */
ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable); ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
@ -643,10 +652,14 @@ static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
/* disable FSI B */ /* disable FSI B */
if (enable) if (enable)
__fsi_set_round_rate(fsib_clk, fsib_rate, 0); __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
return ret; goto fsi_set_rate_end;
} }
return ackmd_bpfmd; ret = ackmd_bpfmd;
fsi_set_rate_end:
clk_put(fsib_clk);
return ret;
} }
static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
@ -1174,7 +1187,7 @@ static void __init ap4evb_init(void)
gpio_request(GPIO_FN_OVCN2_1, NULL); gpio_request(GPIO_FN_OVCN2_1, NULL);
/* setup USB phy */ /* setup USB phy */
__raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
/* enable FSI2 port A (ak4643) */ /* enable FSI2 port A (ak4643) */
gpio_request(GPIO_FN_FSIAIBT, NULL); gpio_request(GPIO_FN_FSIAIBT, NULL);
@ -1348,6 +1361,7 @@ static struct sys_timer ap4evb_timer = {
MACHINE_START(AP4EVB, "ap4evb") MACHINE_START(AP4EVB, "ap4evb")
.map_io = ap4evb_map_io, .map_io = ap4evb_map_io,
.init_irq = sh7372_init_irq, .init_irq = sh7372_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = ap4evb_init, .init_machine = ap4evb_init,
.timer = &ap4evb_timer, .timer = &ap4evb_timer,
MACHINE_END MACHINE_END

View File

@ -367,6 +367,7 @@ static struct sys_timer g3evm_timer = {
MACHINE_START(G3EVM, "g3evm") MACHINE_START(G3EVM, "g3evm")
.map_io = g3evm_map_io, .map_io = g3evm_map_io,
.init_irq = sh7367_init_irq, .init_irq = sh7367_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = g3evm_init, .init_machine = g3evm_init,
.timer = &g3evm_timer, .timer = &g3evm_timer,
MACHINE_END MACHINE_END

View File

@ -394,6 +394,7 @@ static struct sys_timer g4evm_timer = {
MACHINE_START(G4EVM, "g4evm") MACHINE_START(G4EVM, "g4evm")
.map_io = g4evm_map_io, .map_io = g4evm_map_io,
.init_irq = sh7377_init_irq, .init_irq = sh7377_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = g4evm_init, .init_machine = g4evm_init,
.timer = &g4evm_timer, .timer = &g4evm_timer,
MACHINE_END MACHINE_END

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,356 @@
/*
* sh73a0 clock framework support
*
* Copyright (C) 2010 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
#include <linux/clkdev.h>
#include <mach/common.h>
#define FRQCRA 0xe6150000
#define FRQCRB 0xe6150004
#define FRQCRD 0xe61500e4
#define VCLKCR1 0xe6150008
#define VCLKCR2 0xe615000C
#define VCLKCR3 0xe615001C
#define ZBCKCR 0xe6150010
#define FLCKCR 0xe6150014
#define SD0CKCR 0xe6150074
#define SD1CKCR 0xe6150078
#define SD2CKCR 0xe615007C
#define FSIACKCR 0xe6150018
#define FSIBCKCR 0xe6150090
#define SUBCKCR 0xe6150080
#define SPUACKCR 0xe6150084
#define SPUVCKCR 0xe6150094
#define MSUCKCR 0xe6150088
#define HSICKCR 0xe615008C
#define MFCK1CR 0xe6150098
#define MFCK2CR 0xe615009C
#define DSITCKCR 0xe6150060
#define DSI0PCKCR 0xe6150064
#define DSI1PCKCR 0xe6150068
#define DSI0PHYCR 0xe615006C
#define DSI1PHYCR 0xe6150070
#define PLLECR 0xe61500d0
#define PLL0CR 0xe61500d8
#define PLL1CR 0xe6150028
#define PLL2CR 0xe615002c
#define PLL3CR 0xe61500dc
#define SMSTPCR0 0xe6150130
#define SMSTPCR1 0xe6150134
#define SMSTPCR2 0xe6150138
#define SMSTPCR3 0xe615013c
#define SMSTPCR4 0xe6150140
#define SMSTPCR5 0xe6150144
#define CKSCR 0xe61500c0
/* Fixed 32 KHz root clock from EXTALR pin */
static struct clk r_clk = {
.rate = 32768,
};
/*
* 26MHz default rate for the EXTAL1 root input clock.
* If needed, reset this with clk_set_rate() from the platform code.
*/
struct clk sh73a0_extal1_clk = {
.rate = 26000000,
};
/*
* 48MHz default rate for the EXTAL2 root input clock.
* If needed, reset this with clk_set_rate() from the platform code.
*/
struct clk sh73a0_extal2_clk = {
.rate = 48000000,
};
/* A fixed divide-by-2 block */
static unsigned long div2_recalc(struct clk *clk)
{
return clk->parent->rate / 2;
}
static struct clk_ops div2_clk_ops = {
.recalc = div2_recalc,
};
/* Divide extal1 by two */
static struct clk extal1_div2_clk = {
.ops = &div2_clk_ops,
.parent = &sh73a0_extal1_clk,
};
/* Divide extal2 by two */
static struct clk extal2_div2_clk = {
.ops = &div2_clk_ops,
.parent = &sh73a0_extal2_clk,
};
static struct clk_ops main_clk_ops = {
.recalc = followparent_recalc,
};
/* Main clock */
static struct clk main_clk = {
.ops = &main_clk_ops,
};
/* PLL0, PLL1, PLL2, PLL3 */
static unsigned long pll_recalc(struct clk *clk)
{
unsigned long mult = 1;
if (__raw_readl(PLLECR) & (1 << clk->enable_bit))
mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
return clk->parent->rate * mult;
}
static struct clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll0_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
.parent = &main_clk,
.enable_reg = (void __iomem *)PLL0CR,
.enable_bit = 0,
};
static struct clk pll1_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
.parent = &main_clk,
.enable_reg = (void __iomem *)PLL1CR,
.enable_bit = 1,
};
static struct clk pll2_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
.parent = &main_clk,
.enable_reg = (void __iomem *)PLL2CR,
.enable_bit = 2,
};
static struct clk pll3_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
.parent = &main_clk,
.enable_reg = (void __iomem *)PLL3CR,
.enable_bit = 3,
};
/* Divide PLL1 by two */
static struct clk pll1_div2_clk = {
.ops = &div2_clk_ops,
.parent = &pll1_clk,
};
static struct clk *main_clks[] = {
&r_clk,
&sh73a0_extal1_clk,
&sh73a0_extal2_clk,
&extal1_div2_clk,
&extal2_div2_clk,
&main_clk,
&pll0_clk,
&pll1_clk,
&pll2_clk,
&pll3_clk,
&pll1_div2_clk,
};
static void div4_kick(struct clk *clk)
{
unsigned long value;
/* set KICK bit in FRQCRB to update hardware setting */
value = __raw_readl(FRQCRB);
value |= (1 << 31);
__raw_writel(value, FRQCRB);
}
static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
24, 0, 36, 48, 7 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
.kick = div4_kick,
};
enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
static struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
[DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
[DIV4_M3] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
[DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
[DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
[DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
[DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
[DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
[DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
[DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
};
enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
DIV6_HSI, DIV6_MFG1, DIV6_MFG2,
DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
DIV6_NR };
static struct clk div6_clks[DIV6_NR] = {
[DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
[DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
[DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
[DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
[DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
[DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
[DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
[DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
[DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
[DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
[DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
[DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
[DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
[DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
[DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
[DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
[DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
[DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
[DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
[DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
};
enum { MSTP001,
MSTP125, MSTP116,
MSTP219,
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
MSTP331, MSTP329, MSTP323, MSTP312,
MSTP411, MSTP410, MSTP403,
MSTP_NR };
#define MSTP(_parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
static struct clk mstp_clks[MSTP_NR] = {
[MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
[MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
[MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
[MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
[MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("r_clk", &r_clk),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
};
void __init sh73a0_clock_init(void)
{
int k, ret = 0;
/* detect main clock parent */
switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
case 0:
main_clk.parent = &sh73a0_extal1_clk;
break;
case 1:
main_clk.parent = &extal1_div2_clk;
break;
case 2:
main_clk.parent = &sh73a0_extal2_clk;
break;
case 3:
main_clk.parent = &extal2_div2_clk;
break;
}
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
ret = clk_register(main_clks[k]);
if (!ret)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
clk_init();
else
panic("failed to setup sh73a0 clocks\n");
}

View File

@ -0,0 +1,18 @@
/*
* ARM Interrupt demux handler using GIC
*
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2011 Paul Mundt
* Copyright (C) 2010 - 2011 Renesas Solutions Corp.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <asm/assembler.h>
#include <asm/entry-macro-multi.S>
#include <asm/hardware/gic.h>
#include <asm/hardware/entry-macro-gic.S>
arch_irq_handler shmobile_handle_irq_gic

View File

@ -0,0 +1,57 @@
/*
* ARM Interrupt demux handler using INTC
*
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2008 Renesas Solutions Corp.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <asm/entry-macro-multi.S>
#define INTCA_BASE 0xe6980000
#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
#define INTLVLB_OFFS 0x00000034 /* previous priority level */
.macro get_irqnr_preamble, base, tmp
ldr \base, =INTCA_BASE
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* The single INTFLGA read access below results in the following:
*
* 1. INTLVLB is updated with old priority value from INTLVLA
* 2. Highest priority interrupt is accepted
* 3. INTLVLA is updated to contain priority of accepted interrupt
* 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
*/
ldr \irqnr, [\base, #INTFLGA_OFFS]
/* Restore INTLVLA with the value saved in INTLVLB.
* This is required to support interrupt priorities properly.
*/
ldrb \tmp, [\base, #INTLVLB_OFFS]
strb \tmp, [\base, #INTLVLA_OFFS]
/* Handle invalid vector number case */
cmp \irqnr, #0
beq 1000f
/* Convert vector to irq number, same as the evt2irq() macro */
lsr \irqnr, \irqnr, #0x5
subs \irqnr, \irqnr, #16
1000:
.endm
.macro test_for_ipi, irqnr, irqstat, base, tmp
.endm
.macro test_for_ltirq, irqnr, irqstat, base, tmp
.endm
arch_irq_handler shmobile_handle_irq_intc

View File

@ -0,0 +1,27 @@
/*
* SMP support for R-Mobile / SH-Mobile
*
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2010 Takashi Yoshii
*
* Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/memory.h>
__INIT
/*
* Reset vector for secondary CPUs.
* This will be mapped at address 0 by SBAR register.
* We need _long_ jump to the physical address.
*/
.align 12
ENTRY(shmobile_secondary_vector)
ldr pc, 1f
1: .long secondary_startup - PAGE_OFFSET + PHYS_OFFSET

View File

@ -0,0 +1,41 @@
/*
* SMP support for R-Mobile / SH-Mobile
*
* Copyright (C) 2010 Magnus Damm
*
* Based on realview, Copyright (C) 2002 ARM Ltd, All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
int platform_cpu_kill(unsigned int cpu)
{
return 1;
}
void platform_cpu_die(unsigned int cpu)
{
while (1) {
/*
* here's the WFI
*/
asm(".word 0xe320f003\n"
:
:
: "memory", "cc");
}
}
int platform_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
* e.g. clock tick interrupts)
*/
return cpu == 0 ? -EPERM : 0;
}

View File

@ -3,8 +3,11 @@
extern struct sys_timer shmobile_timer; extern struct sys_timer shmobile_timer;
extern void shmobile_setup_console(void); extern void shmobile_setup_console(void);
extern void shmobile_secondary_vector(void);
struct clk; struct clk;
extern int clk_init(void); extern int clk_init(void);
extern void shmobile_handle_irq_intc(struct pt_regs *);
extern void shmobile_handle_irq_gic(struct pt_regs *);
extern void sh7367_init_irq(void); extern void sh7367_init_irq(void);
extern void sh7367_add_early_devices(void); extern void sh7367_add_early_devices(void);
@ -30,4 +33,17 @@ extern void sh7372_pinmux_init(void);
extern struct clk sh7372_extal1_clk; extern struct clk sh7372_extal1_clk;
extern struct clk sh7372_extal2_clk; extern struct clk sh7372_extal2_clk;
extern void sh73a0_init_irq(void);
extern void sh73a0_add_early_devices(void);
extern void sh73a0_add_standard_devices(void);
extern void sh73a0_clock_init(void);
extern void sh73a0_pinmux_init(void);
extern struct clk sh73a0_extal1_clk;
extern struct clk sh73a0_extal2_clk;
extern unsigned int sh73a0_get_core_count(void);
extern void sh73a0_secondary_init(unsigned int cpu);
extern int sh73a0_boot_secondary(unsigned int cpu);
extern void sh73a0_smp_prepare_cpus(void);
#endif /* __ARCH_MACH_COMMON_H */ #endif /* __ARCH_MACH_COMMON_H */

View File

@ -1,6 +1,5 @@
/* /*
* Copyright (C) 2010 Magnus Damm * Copyright (C) 2010 Paul Mundt
* Copyright (C) 2008 Renesas Solutions Corp.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -15,47 +14,21 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <mach/irqs.h>
#define INTCA_BASE 0xe6980000
#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
#define INTLVLB_OFFS 0x00000034 /* previous priority level */
.macro disable_fiq .macro disable_fiq
.endm .endm
.macro get_irqnr_preamble, base, tmp .macro get_irqnr_preamble, base, tmp
ldr \base, =INTCA_BASE .endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
.endm
.macro test_for_ipi, irqnr, irqstat, base, tmp
.endm
.macro test_for_ltirq, irqnr, irqstat, base, tmp
.endm .endm
.macro arch_ret_to_user, tmp1, tmp2 .macro arch_ret_to_user, tmp1, tmp2
.endm .endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* The single INTFLGA read access below results in the following:
*
* 1. INTLVLB is updated with old priority value from INTLVLA
* 2. Highest priority interrupt is accepted
* 3. INTLVLA is updated to contain priority of accepted interrupt
* 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
*/
ldr \irqnr, [\base, #INTFLGA_OFFS]
/* Restore INTLVLA with the value saved in INTLVLB.
* This is required to support interrupt priorities properly.
*/
ldrb \tmp, [\base, #INTLVLB_OFFS]
strb \tmp, [\base, #INTLVLA_OFFS]
/* Handle invalid vector number case */
cmp \irqnr, #0
beq 1000f
/* Convert vector to irq number, same as the evt2irq() macro */
lsr \irqnr, \irqnr, #0x5
subs \irqnr, \irqnr, #16
1000:
.endm

View File

@ -1,7 +1,4 @@
#ifndef __ASM_MACH_HARDWARE_H #ifndef __ASM_MACH_HARDWARE_H
#define __ASM_MACH_HARDWARE_H #define __ASM_MACH_HARDWARE_H
/* INTFLGA register - used by low level interrupt code in entry-macro.S */
#define INTFLGA 0xe6980018
#endif /* __ASM_MACH_HARDWARE_H */ #endif /* __ASM_MACH_HARDWARE_H */

View File

@ -0,0 +1,87 @@
LIST "partner-jet-setup.txt"
LIST "(C) Copyright 2010 Renesas Solutions Corp"
LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
LIST "RWT Setting"
EW 0xE6020004, 0xA500
EW 0xE6030004, 0xA500
DD 0x01001000, 0x01001000
LIST "GPIO Setting"
EB 0xE6051013, 0xA2
LIST "CPG"
ED 0xE6150080, 0x00000180
ED 0xE61500C0, 0x00000002
WAIT 1, 0xFE40009C
LIST "FRQCR"
ED 0xE6150000, 0x2D1305C3
ED 0xE61500E0, 0x9E40358E
ED 0xE6150004, 0x80331050
WAIT 1, 0xFE40009C
ED 0xE61500E4, 0x00002000
WAIT 1, 0xFE40009C
LIST "PLL"
ED 0xE6150028, 0x00004000
WAIT 1, 0xFE40009C
ED 0xE615002C, 0x93000040
WAIT 1, 0xFE40009C
LIST "BSC"
ED 0xFEC10000, 0x00E0001B
LIST "SBSC1"
ED 0xFE400354, 0x01AD8000
ED 0xFE400354, 0x01AD8001
WAIT 5, 0xFE40009C
ED 0xFE400008, 0xBCC90151
ED 0xFE400040, 0x41774113
ED 0xFE400044, 0x2712E229
ED 0xFE400048, 0x20C18505
ED 0xFE40004C, 0x00110209
ED 0xFE400010, 0x00000087
WAIT 10, 0xFE40009C
ED 0xFE400084, 0x0000003F
EB 0xFE500000, 0x00
WAIT 5, 0xFE40009C
ED 0xFE400084, 0x0000FF0A
EB 0xFE500000, 0x00
WAIT 1, 0xFE40009C
ED 0xFE400084, 0x00002201
EB 0xFE500000, 0x00
ED 0xFE400084, 0x00000302
EB 0xFE500000, 0x00
EB 0xFE5C0000, 0x00
ED 0xFE400008, 0xBCC90159
ED 0xFE40008C, 0x88800004
ED 0xFE400094, 0x00000004
ED 0xFE400028, 0xA55A0032
ED 0xFE40002C, 0xA55A000C
ED 0xFE400020, 0xA55A2048
ED 0xFE400008, 0xBCC90959
LIST "Change CPGA setting"
ED 0xE61500E0, 0x9E40352E
ED 0xE6150004, 0x80331050
WAIT 1, 0xFE40009C
ED 0xE6150354, 0x00000002

View File

@ -1,7 +1,10 @@
#ifndef __ASM_MACH_IRQS_H #ifndef __ASM_MACH_IRQS_H
#define __ASM_MACH_IRQS_H #define __ASM_MACH_IRQS_H
#define NR_IRQS 512 #define NR_IRQS 1024
/* GIC */
#define gic_spi(nr) ((nr) + 32)
/* INTCA */ /* INTCA */
#define evt2irq(evt) (((evt) >> 5) - 16) #define evt2irq(evt) (((evt) >> 5) - 16)

View File

@ -455,6 +455,8 @@ enum {
SHDMA_SLAVE_SDHI1_TX, SHDMA_SLAVE_SDHI1_TX,
SHDMA_SLAVE_SDHI2_RX, SHDMA_SLAVE_SDHI2_RX,
SHDMA_SLAVE_SDHI2_TX, SHDMA_SLAVE_SDHI2_TX,
SHDMA_SLAVE_MMCIF_RX,
SHDMA_SLAVE_MMCIF_TX,
}; };
extern struct clk sh7372_extal1_clk; extern struct clk sh7372_extal1_clk;

View File

@ -0,0 +1,467 @@
#ifndef __ASM_SH73A0_H__
#define __ASM_SH73A0_H__
/* Pin Function Controller:
* GPIO_FN_xx - GPIO used to select pin function and MSEL switch
* GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
*/
enum {
/* Hardware manual Table 25-1 (GPIO) */
GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118,
GPIO_PORT128, GPIO_PORT129,
GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
GPIO_PORT270, GPIO_PORT271, GPIO_PORT272, GPIO_PORT273, GPIO_PORT274,
GPIO_PORT275, GPIO_PORT276, GPIO_PORT277, GPIO_PORT278, GPIO_PORT279,
GPIO_PORT280, GPIO_PORT281, GPIO_PORT282,
GPIO_PORT288, GPIO_PORT289,
GPIO_PORT290, GPIO_PORT291, GPIO_PORT292, GPIO_PORT293, GPIO_PORT294,
GPIO_PORT295, GPIO_PORT296, GPIO_PORT297, GPIO_PORT298, GPIO_PORT299,
GPIO_PORT300, GPIO_PORT301, GPIO_PORT302, GPIO_PORT303, GPIO_PORT304,
GPIO_PORT305, GPIO_PORT306, GPIO_PORT307, GPIO_PORT308, GPIO_PORT309,
/* Table 25-1 (Function 0-7) */
GPIO_FN_VBUS_0,
GPIO_FN_GPI0,
GPIO_FN_GPI1,
GPIO_FN_GPI2,
GPIO_FN_GPI3,
GPIO_FN_GPI4,
GPIO_FN_GPI5,
GPIO_FN_GPI6,
GPIO_FN_GPI7,
GPIO_FN_SCIFA7_RXD,
GPIO_FN_SCIFA7_CTS_,
GPIO_FN_GPO7, GPIO_FN_MFG0_OUT2,
GPIO_FN_GPO6, GPIO_FN_MFG1_OUT2,
GPIO_FN_GPO5, GPIO_FN_SCIFA0_SCK, GPIO_FN_FSICOSLDT3, \
GPIO_FN_PORT16_VIO_CKOR,
GPIO_FN_SCIFA0_TXD,
GPIO_FN_SCIFA7_TXD,
GPIO_FN_SCIFA7_RTS_, GPIO_FN_PORT19_VIO_CKO2,
GPIO_FN_GPO0,
GPIO_FN_GPO1,
GPIO_FN_GPO2, GPIO_FN_STATUS0,
GPIO_FN_GPO3, GPIO_FN_STATUS1,
GPIO_FN_GPO4, GPIO_FN_STATUS2,
GPIO_FN_VINT,
GPIO_FN_TCKON,
GPIO_FN_XDVFS1, GPIO_FN_PORT27_I2C_SCL2, GPIO_FN_PORT27_I2C_SCL3, \
GPIO_FN_MFG0_OUT1, GPIO_FN_PORT27_IROUT,
GPIO_FN_XDVFS2, GPIO_FN_PORT28_I2C_SDA2, GPIO_FN_PORT28_I2C_SDA3, \
GPIO_FN_PORT28_TPU1TO1,
GPIO_FN_SIM_RST, GPIO_FN_PORT29_TPU1TO1,
GPIO_FN_SIM_CLK, GPIO_FN_PORT30_VIO_CKOR,
GPIO_FN_SIM_D, GPIO_FN_PORT31_IROUT,
GPIO_FN_SCIFA4_TXD,
GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
GPIO_FN_SCIFA4_RTS_,
GPIO_FN_SCIFA4_CTS_,
GPIO_FN_FSIBOBT, GPIO_FN_FSIBIBT,
GPIO_FN_FSIBOLR, GPIO_FN_FSIBILR,
GPIO_FN_FSIBOSLD,
GPIO_FN_FSIBISLD,
GPIO_FN_VACK,
GPIO_FN_XTAL1L,
GPIO_FN_SCIFA0_RTS_, GPIO_FN_FSICOSLDT2,
GPIO_FN_SCIFA0_RXD,
GPIO_FN_SCIFA0_CTS_, GPIO_FN_FSICOSLDT1,
GPIO_FN_FSICOBT, GPIO_FN_FSICIBT, GPIO_FN_FSIDOBT, GPIO_FN_FSIDIBT,
GPIO_FN_FSICOLR, GPIO_FN_FSICILR, GPIO_FN_FSIDOLR, GPIO_FN_FSIDILR,
GPIO_FN_FSICOSLD, GPIO_FN_PORT47_FSICSPDIF,
GPIO_FN_FSICISLD, GPIO_FN_FSIDISLD,
GPIO_FN_FSIACK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT, \
GPIO_FN_FSIAOMC,
GPIO_FN_FSIAOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_FSIAILR,
GPIO_FN_FSIAOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_FSIAIBT,
GPIO_FN_FSIAOSLD, GPIO_FN_BBIF2_TXD2,
GPIO_FN_FSIASPDIF, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3, \
GPIO_FN_FSIBSPDIF, GPIO_FN_PORT53_FSICSPDIF,
GPIO_FN_FSIBCK, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2, \
GPIO_FN_FSIBOMC, GPIO_FN_FSICCK, GPIO_FN_FSICOMC,
GPIO_FN_FSIAISLD, GPIO_FN_TPU0TO0,
GPIO_FN_A0, GPIO_FN_BS_,
GPIO_FN_A12, GPIO_FN_PORT58_KEYOUT7, GPIO_FN_TPU4TO2,
GPIO_FN_A13, GPIO_FN_PORT59_KEYOUT6, GPIO_FN_TPU0TO1,
GPIO_FN_A14, GPIO_FN_KEYOUT5,
GPIO_FN_A15, GPIO_FN_KEYOUT4,
GPIO_FN_A16, GPIO_FN_KEYOUT3, GPIO_FN_MSIOF0_SS1,
GPIO_FN_A17, GPIO_FN_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
GPIO_FN_A18, GPIO_FN_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
GPIO_FN_A19, GPIO_FN_KEYOUT0, GPIO_FN_MSIOF0_TXD,
GPIO_FN_A20, GPIO_FN_KEYIN0, GPIO_FN_MSIOF0_RSCK,
GPIO_FN_A21, GPIO_FN_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
GPIO_FN_A22, GPIO_FN_KEYIN2, GPIO_FN_MSIOF0_MCK0,
GPIO_FN_A23, GPIO_FN_KEYIN3, GPIO_FN_MSIOF0_MCK1,
GPIO_FN_A24, GPIO_FN_KEYIN4, GPIO_FN_MSIOF0_RXD,
GPIO_FN_A25, GPIO_FN_KEYIN5, GPIO_FN_MSIOF0_SS2,
GPIO_FN_A26, GPIO_FN_KEYIN6,
GPIO_FN_KEYIN7,
GPIO_FN_D0_NAF0,
GPIO_FN_D1_NAF1,
GPIO_FN_D2_NAF2,
GPIO_FN_D3_NAF3,
GPIO_FN_D4_NAF4,
GPIO_FN_D5_NAF5,
GPIO_FN_D6_NAF6,
GPIO_FN_D7_NAF7,
GPIO_FN_D8_NAF8,
GPIO_FN_D9_NAF9,
GPIO_FN_D10_NAF10,
GPIO_FN_D11_NAF11,
GPIO_FN_D12_NAF12,
GPIO_FN_D13_NAF13,
GPIO_FN_D14_NAF14,
GPIO_FN_D15_NAF15,
GPIO_FN_CS4_,
GPIO_FN_CS5A_, GPIO_FN_PORT91_RDWR,
GPIO_FN_CS5B_, GPIO_FN_FCE1_,
GPIO_FN_CS6B_, GPIO_FN_DACK0,
GPIO_FN_FCE0_, GPIO_FN_CS6A_,
GPIO_FN_WAIT_, GPIO_FN_DREQ0,
GPIO_FN_RD__FSC,
GPIO_FN_WE0__FWE, GPIO_FN_RDWR_FWE,
GPIO_FN_WE1_,
GPIO_FN_FRB,
GPIO_FN_CKO,
GPIO_FN_NBRSTOUT_,
GPIO_FN_NBRST_,
GPIO_FN_BBIF2_TXD,
GPIO_FN_BBIF2_RXD,
GPIO_FN_BBIF2_SYNC,
GPIO_FN_BBIF2_SCK,
GPIO_FN_SCIFA3_CTS_, GPIO_FN_MFG3_IN2,
GPIO_FN_SCIFA3_RXD, GPIO_FN_MFG3_IN1,
GPIO_FN_BBIF1_SS2, GPIO_FN_SCIFA3_RTS_, GPIO_FN_MFG3_OUT1,
GPIO_FN_SCIFA3_TXD,
GPIO_FN_HSI_RX_DATA, GPIO_FN_BBIF1_RXD,
GPIO_FN_HSI_TX_WAKE, GPIO_FN_BBIF1_TSCK,
GPIO_FN_HSI_TX_DATA, GPIO_FN_BBIF1_TSYNC,
GPIO_FN_HSI_TX_READY, GPIO_FN_BBIF1_TXD,
GPIO_FN_HSI_RX_READY, GPIO_FN_BBIF1_RSCK, GPIO_FN_PORT115_I2C_SCL2, \
GPIO_FN_PORT115_I2C_SCL3,
GPIO_FN_HSI_RX_WAKE, GPIO_FN_BBIF1_RSYNC, GPIO_FN_PORT116_I2C_SDA2, \
GPIO_FN_PORT116_I2C_SDA3,
GPIO_FN_HSI_RX_FLAG, GPIO_FN_BBIF1_SS1, GPIO_FN_BBIF1_FLOW,
GPIO_FN_HSI_TX_FLAG,
GPIO_FN_VIO_VD, GPIO_FN_PORT128_LCD2VSYN, GPIO_FN_VIO2_VD, \
GPIO_FN_LCD2D0,
GPIO_FN_VIO_HD, GPIO_FN_PORT129_LCD2HSYN, GPIO_FN_PORT129_LCD2CS_, \
GPIO_FN_VIO2_HD, GPIO_FN_LCD2D1,
GPIO_FN_VIO_D0, GPIO_FN_PORT130_MSIOF2_RXD, GPIO_FN_LCD2D10,
GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT6, GPIO_FN_PORT131_MSIOF2_SS1, \
GPIO_FN_PORT131_KEYOUT11, GPIO_FN_LCD2D11,
GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT7, GPIO_FN_PORT132_MSIOF2_SS2, \
GPIO_FN_PORT132_KEYOUT10, GPIO_FN_LCD2D12,
GPIO_FN_VIO_D3, GPIO_FN_MSIOF2_TSYNC, GPIO_FN_LCD2D13,
GPIO_FN_VIO_D4, GPIO_FN_MSIOF2_TXD, GPIO_FN_LCD2D14,
GPIO_FN_VIO_D5, GPIO_FN_MSIOF2_TSCK, GPIO_FN_LCD2D15,
GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYOUT8, GPIO_FN_LCD2D16,
GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYOUT9, GPIO_FN_LCD2D17,
GPIO_FN_VIO_D8, GPIO_FN_PORT138_KEYOUT8, GPIO_FN_VIO2_D0, \
GPIO_FN_LCD2D6,
GPIO_FN_VIO_D9, GPIO_FN_PORT139_KEYOUT9, GPIO_FN_VIO2_D1, \
GPIO_FN_LCD2D7,
GPIO_FN_VIO_D10, GPIO_FN_TPU0TO2, GPIO_FN_VIO2_D2, GPIO_FN_LCD2D8,
GPIO_FN_VIO_D11, GPIO_FN_TPU0TO3, GPIO_FN_VIO2_D3, GPIO_FN_LCD2D9,
GPIO_FN_VIO_D12, GPIO_FN_PORT142_KEYOUT10, GPIO_FN_VIO2_D4, \
GPIO_FN_LCD2D2,
GPIO_FN_VIO_D13, GPIO_FN_PORT143_KEYOUT11, GPIO_FN_PORT143_KEYOUT6, \
GPIO_FN_VIO2_D5, GPIO_FN_LCD2D3,
GPIO_FN_VIO_D14, GPIO_FN_PORT144_KEYOUT7, GPIO_FN_VIO2_D6, \
GPIO_FN_LCD2D4,
GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_LCD2DISP, \
GPIO_FN_PORT145_LCD2RS, GPIO_FN_VIO2_D7, GPIO_FN_LCD2D5,
GPIO_FN_VIO_CLK, GPIO_FN_LCD2DCK, GPIO_FN_PORT146_LCD2WR_, \
GPIO_FN_VIO2_CLK, GPIO_FN_LCD2D18,
GPIO_FN_VIO_FIELD, GPIO_FN_LCD2RD_, GPIO_FN_VIO2_FIELD, GPIO_FN_LCD2D19,
GPIO_FN_VIO_CKO,
GPIO_FN_A27, GPIO_FN_PORT149_RDWR, GPIO_FN_MFG0_IN1, \
GPIO_FN_PORT149_KEYOUT9,
GPIO_FN_MFG0_IN2,
GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK,
GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC,
GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1,
GPIO_FN_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
GPIO_FN_SCIFA2_RTS1_, GPIO_FN_PORT156_MSIOF2_SS2,
GPIO_FN_SCIFA2_CTS1_, GPIO_FN_PORT157_MSIOF2_RXD,
GPIO_FN_DINT_, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
GPIO_FN_PORT159_SCIFB_SCK, GPIO_FN_PORT159_SCIFA5_SCK, GPIO_FN_NMI,
GPIO_FN_PORT160_SCIFB_TXD, GPIO_FN_PORT160_SCIFA5_TXD,
GPIO_FN_PORT161_SCIFB_CTS_, GPIO_FN_PORT161_SCIFA5_CTS_,
GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD,
GPIO_FN_PORT163_SCIFB_RTS_, GPIO_FN_PORT163_SCIFA5_RTS_, \
GPIO_FN_TPU3TO0,
GPIO_FN_LCDD0,
GPIO_FN_LCDD1, GPIO_FN_PORT193_SCIFA5_CTS_, GPIO_FN_BBIF2_TSYNC1,
GPIO_FN_LCDD2, GPIO_FN_PORT194_SCIFA5_RTS_, GPIO_FN_BBIF2_TSCK1,
GPIO_FN_LCDD3, GPIO_FN_PORT195_SCIFA5_RXD, GPIO_FN_BBIF2_TXD1,
GPIO_FN_LCDD4, GPIO_FN_PORT196_SCIFA5_TXD,
GPIO_FN_LCDD5, GPIO_FN_PORT197_SCIFA5_SCK, GPIO_FN_MFG2_OUT2, \
GPIO_FN_TPU2TO1,
GPIO_FN_LCDD6,
GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2,
GPIO_FN_LCDD8, GPIO_FN_D16,
GPIO_FN_LCDD9, GPIO_FN_D17,
GPIO_FN_LCDD10, GPIO_FN_D18,
GPIO_FN_LCDD11, GPIO_FN_D19,
GPIO_FN_LCDD12, GPIO_FN_D20,
GPIO_FN_LCDD13, GPIO_FN_D21,
GPIO_FN_LCDD14, GPIO_FN_D22,
GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_D23,
GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_D24,
GPIO_FN_LCDD17, GPIO_FN_D25,
GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26,
GPIO_FN_LCDD19, GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27,
GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28,
GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29,
GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30,
GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31,
GPIO_FN_LCDDCK, GPIO_FN_LCDWR_,
GPIO_FN_LCDRD_, GPIO_FN_DACK2, GPIO_FN_PORT217_LCD2RS, \
GPIO_FN_MSIOF0L_TSYNC, GPIO_FN_VIO2_FIELD3, GPIO_FN_PORT217_LCD2DISP,
GPIO_FN_LCDHSYN, GPIO_FN_LCDCS_, GPIO_FN_LCDCS2_, GPIO_FN_DACK3, \
GPIO_FN_PORT218_VIO_CKOR,
GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_PORT219_LCD2WR_, \
GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK, GPIO_FN_VIO2_CLK3, \
GPIO_FN_LCD2DCK_2,
GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2,
GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PORT221_LCD2CS_, \
GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD, GPIO_FN_VIO2_HD3, \
GPIO_FN_PORT221_LCD2HSYN,
GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN, \
GPIO_FN_MSIOF0L_TXD, GPIO_FN_VIO2_VD3, GPIO_FN_PORT222_LCD2VSYN,
GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, GPIO_FN_PORT226_VIO_CKO2,
GPIO_FN_SCIFA1_RTS_, GPIO_FN_IDIN,
GPIO_FN_SCIFA1_RXD,
GPIO_FN_SCIFA1_CTS_, GPIO_FN_MFG1_IN1,
GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA2_TXD2,
GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2_,
GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2,
GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2,
GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2_, GPIO_FN_VIO2_CLK2, \
GPIO_FN_LCD2D20,
GPIO_FN_MSIOF1_RSYNC, GPIO_FN_MFG1_IN2, GPIO_FN_VIO2_VD2, \
GPIO_FN_LCD2D21,
GPIO_FN_MSIOF1_MCK0, GPIO_FN_PORT236_I2C_SDA2,
GPIO_FN_MSIOF1_MCK1, GPIO_FN_PORT237_I2C_SCL2,
GPIO_FN_MSIOF1_SS1, GPIO_FN_VIO2_FIELD2, GPIO_FN_LCD2D22,
GPIO_FN_MSIOF1_SS2, GPIO_FN_VIO2_HD2, GPIO_FN_LCD2D23,
GPIO_FN_SCIFA6_TXD,
GPIO_FN_PORT241_IRDA_OUT, GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1, \
GPIO_FN_TPU4TO0,
GPIO_FN_PORT242_IRDA_IN, GPIO_FN_MFG4_IN2,
GPIO_FN_PORT243_IRDA_FIRSEL, GPIO_FN_PORT243_VIO_CKO2,
GPIO_FN_PORT244_SCIFA5_CTS_, GPIO_FN_MFG2_IN1, \
GPIO_FN_PORT244_SCIFB_CTS_, GPIO_FN_MSIOF2R_RXD,
GPIO_FN_PORT245_SCIFA5_RTS_, GPIO_FN_MFG2_IN2, \
GPIO_FN_PORT245_SCIFB_RTS_, GPIO_FN_MSIOF2R_TXD,
GPIO_FN_PORT246_SCIFA5_RXD, GPIO_FN_MFG1_OUT1, \
GPIO_FN_PORT246_SCIFB_RXD, GPIO_FN_TPU1TO0,
GPIO_FN_PORT247_SCIFA5_TXD, GPIO_FN_MFG3_OUT2, \
GPIO_FN_PORT247_SCIFB_TXD, GPIO_FN_TPU3TO1,
GPIO_FN_PORT248_SCIFA5_SCK, GPIO_FN_MFG2_OUT1, \
GPIO_FN_PORT248_SCIFB_SCK, GPIO_FN_TPU2TO0, \
GPIO_FN_PORT248_I2C_SCL3, GPIO_FN_MSIOF2R_TSCK,
GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, \
GPIO_FN_PORT249_I2C_SDA3, GPIO_FN_MSIOF2R_TSYNC,
GPIO_FN_SDHICLK0,
GPIO_FN_SDHICD0,
GPIO_FN_SDHID0_0,
GPIO_FN_SDHID0_1,
GPIO_FN_SDHID0_2,
GPIO_FN_SDHID0_3,
GPIO_FN_SDHICMD0,
GPIO_FN_SDHIWP0,
GPIO_FN_SDHICLK1,
GPIO_FN_SDHID1_0, GPIO_FN_TS_SPSYNC2,
GPIO_FN_SDHID1_1, GPIO_FN_TS_SDAT2,
GPIO_FN_SDHID1_2, GPIO_FN_TS_SDEN2,
GPIO_FN_SDHID1_3, GPIO_FN_TS_SCK2,
GPIO_FN_SDHICMD1,
GPIO_FN_SDHICLK2,
GPIO_FN_SDHID2_0, GPIO_FN_TS_SPSYNC4,
GPIO_FN_SDHID2_1, GPIO_FN_TS_SDAT4,
GPIO_FN_SDHID2_2, GPIO_FN_TS_SDEN4,
GPIO_FN_SDHID2_3, GPIO_FN_TS_SCK4,
GPIO_FN_SDHICMD2,
GPIO_FN_MMCCLK0,
GPIO_FN_MMCD0_0,
GPIO_FN_MMCD0_1,
GPIO_FN_MMCD0_2,
GPIO_FN_MMCD0_3,
GPIO_FN_MMCD0_4, GPIO_FN_TS_SPSYNC5,
GPIO_FN_MMCD0_5, GPIO_FN_TS_SDAT5,
GPIO_FN_MMCD0_6, GPIO_FN_TS_SDEN5,
GPIO_FN_MMCD0_7, GPIO_FN_TS_SCK5,
GPIO_FN_MMCCMD0,
GPIO_FN_RESETOUTS_, GPIO_FN_EXTAL2OUT,
GPIO_FN_MCP_WAIT__MCP_FRB,
GPIO_FN_MCP_CKO, GPIO_FN_MMCCLK1,
GPIO_FN_MCP_D15_MCP_NAF15,
GPIO_FN_MCP_D14_MCP_NAF14,
GPIO_FN_MCP_D13_MCP_NAF13,
GPIO_FN_MCP_D12_MCP_NAF12,
GPIO_FN_MCP_D11_MCP_NAF11,
GPIO_FN_MCP_D10_MCP_NAF10,
GPIO_FN_MCP_D9_MCP_NAF9,
GPIO_FN_MCP_D8_MCP_NAF8, GPIO_FN_MMCCMD1,
GPIO_FN_MCP_D7_MCP_NAF7, GPIO_FN_MMCD1_7,
GPIO_FN_MCP_D6_MCP_NAF6, GPIO_FN_MMCD1_6,
GPIO_FN_MCP_D5_MCP_NAF5, GPIO_FN_MMCD1_5,
GPIO_FN_MCP_D4_MCP_NAF4, GPIO_FN_MMCD1_4,
GPIO_FN_MCP_D3_MCP_NAF3, GPIO_FN_MMCD1_3,
GPIO_FN_MCP_D2_MCP_NAF2, GPIO_FN_MMCD1_2,
GPIO_FN_MCP_D1_MCP_NAF1, GPIO_FN_MMCD1_1,
GPIO_FN_MCP_D0_MCP_NAF0, GPIO_FN_MMCD1_0,
GPIO_FN_MCP_NBRSTOUT_,
GPIO_FN_MCP_WE0__MCP_FWE, GPIO_FN_MCP_RDWR_MCP_FWE,
/* MSEL2 special case */
GPIO_FN_TSIF2_TS_XX1,
GPIO_FN_TSIF2_TS_XX2,
GPIO_FN_TSIF2_TS_XX3,
GPIO_FN_TSIF2_TS_XX4,
GPIO_FN_TSIF2_TS_XX5,
GPIO_FN_TSIF1_TS_XX1,
GPIO_FN_TSIF1_TS_XX2,
GPIO_FN_TSIF1_TS_XX3,
GPIO_FN_TSIF1_TS_XX4,
GPIO_FN_TSIF1_TS_XX5,
GPIO_FN_TSIF0_TS_XX1,
GPIO_FN_TSIF0_TS_XX2,
GPIO_FN_TSIF0_TS_XX3,
GPIO_FN_TSIF0_TS_XX4,
GPIO_FN_TSIF0_TS_XX5,
GPIO_FN_MST1_TS_XX1,
GPIO_FN_MST1_TS_XX2,
GPIO_FN_MST1_TS_XX3,
GPIO_FN_MST1_TS_XX4,
GPIO_FN_MST1_TS_XX5,
GPIO_FN_MST0_TS_XX1,
GPIO_FN_MST0_TS_XX2,
GPIO_FN_MST0_TS_XX3,
GPIO_FN_MST0_TS_XX4,
GPIO_FN_MST0_TS_XX5,
/* MSEL3 special cases */
GPIO_FN_SDHI0_VCCQ_MC0_ON,
GPIO_FN_SDHI0_VCCQ_MC0_OFF,
GPIO_FN_DEBUG_MON_VIO,
GPIO_FN_DEBUG_MON_LCDD,
GPIO_FN_LCDC_LCDC0,
GPIO_FN_LCDC_LCDC1,
/* MSEL4 special cases */
GPIO_FN_IRQ9_MEM_INT,
GPIO_FN_IRQ9_MCP_INT,
GPIO_FN_A11,
GPIO_FN_KEYOUT8,
GPIO_FN_TPU4TO3,
GPIO_FN_RESETA_N_PU_ON,
GPIO_FN_RESETA_N_PU_OFF,
GPIO_FN_EDBGREQ_PD,
GPIO_FN_EDBGREQ_PU,
/* Functions with pull-ups */
GPIO_FN_KEYIN0_PU,
GPIO_FN_KEYIN1_PU,
GPIO_FN_KEYIN2_PU,
GPIO_FN_KEYIN3_PU,
GPIO_FN_KEYIN4_PU,
GPIO_FN_KEYIN5_PU,
GPIO_FN_KEYIN6_PU,
GPIO_FN_KEYIN7_PU,
GPIO_FN_SDHID1_0_PU,
GPIO_FN_SDHID1_1_PU,
GPIO_FN_SDHID1_2_PU,
GPIO_FN_SDHID1_3_PU,
GPIO_FN_SDHICMD1_PU,
GPIO_FN_MMCCMD0_PU,
GPIO_FN_MMCCMD1_PU,
GPIO_FN_FSIACK_PU,
GPIO_FN_FSIAILR_PU,
GPIO_FN_FSIAIBT_PU,
GPIO_FN_FSIAISLD_PU,
};
#endif /* __ASM_SH73A0_H__ */

View File

@ -0,0 +1,16 @@
#ifndef __MACH_SMP_H
#define __MACH_SMP_H
#include <asm/hardware/gic.h>
/*
* We use IRQ1 as the IPI
*/
static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
#if defined(CONFIG_ARM_GIC)
gic_raise_softirq(mask, ipi);
#endif
}
#endif

View File

@ -13,6 +13,9 @@
#ifdef CONFIG_MACH_AP4EVB #ifdef CONFIG_MACH_AP4EVB
#define MACH_TYPE MACH_TYPE_AP4EVB #define MACH_TYPE MACH_TYPE_AP4EVB
#include "mach/head-ap4evb.txt" #include "mach/head-ap4evb.txt"
#elif CONFIG_MACH_MACKEREL
#define MACH_TYPE MACH_TYPE_MACKEREL
#include "mach/head-mackerel.txt"
#else #else
#error "unsupported board." #error "unsupported board."
#endif #endif

View File

@ -0,0 +1,267 @@
/*
* sh73a0 processor support - INTC hardware block
*
* Copyright (C) 2010 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/sh_intc.h>
#include <asm/hardware/gic.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
enum {
UNUSED = 0,
/* interrupt sources INTCS */
PINTCS_PINT1, PINTCS_PINT2,
RTDMAC_0_DEI0, RTDMAC_0_DEI1, RTDMAC_0_DEI2, RTDMAC_0_DEI3,
CEU, MFI, BBIF2, VPU, TSIF1, _3DG_SGX543, _2DDMAC_2DDM0,
RTDMAC_1_DEI4, RTDMAC_1_DEI5, RTDMAC_1_DADERR,
KEYSC_KEY, VINT, MSIOF,
TMU0_TUNI00, TMU0_TUNI01, TMU0_TUNI02,
CMT0, TSIF0, CMT2, LMB, MSUG, MSU_MSU, MSU_MSU2,
CTI, RWDT0, ICB, PEP, ASA, JPU_JPEG, LCDC, LCRC,
RTDMAC_2_DEI6, RTDMAC_2_DEI7, RTDMAC_2_DEI8, RTDMAC_2_DEI9,
RTDMAC_3_DEI10, RTDMAC_3_DEI11,
FRC, GCU, LCDC1, CSIRX,
DSITX0_DSITX00, DSITX0_DSITX01,
SPU2_SPU0, SPU2_SPU1, FSI,
TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
TSIF2, CMT4, MFIS2, CPORTS2R, TSG, DMASCH1, SCUW,
VIO60, VIO61, CEU21, CSI21, DSITX1_DSITX10, DSITX1_DSITX11,
DISP, DSRV, EMUX2_EMUX20I, EMUX2_EMUX21I,
MSTIF0_MST00I, MSTIF0_MST01I, MSTIF1_MST10I, MSTIF1_MST11I,
SPUV,
/* interrupt groups INTCS */
RTDMAC_0, RTDMAC_1, RTDMAC_2, RTDMAC_3,
DSITX0, SPU2, TMU1, MSU,
};
static struct intc_vect intcs_vectors[] = {
INTCS_VECT(PINTCS_PINT1, 0x0600), INTCS_VECT(PINTCS_PINT2, 0x0620),
INTCS_VECT(RTDMAC_0_DEI0, 0x0800), INTCS_VECT(RTDMAC_0_DEI1, 0x0820),
INTCS_VECT(RTDMAC_0_DEI2, 0x0840), INTCS_VECT(RTDMAC_0_DEI3, 0x0860),
INTCS_VECT(CEU, 0x0880), INTCS_VECT(MFI, 0x0900),
INTCS_VECT(BBIF2, 0x0960), INTCS_VECT(VPU, 0x0980),
INTCS_VECT(TSIF1, 0x09a0), INTCS_VECT(_3DG_SGX543, 0x09e0),
INTCS_VECT(_2DDMAC_2DDM0, 0x0a00),
INTCS_VECT(RTDMAC_1_DEI4, 0x0b80), INTCS_VECT(RTDMAC_1_DEI5, 0x0ba0),
INTCS_VECT(RTDMAC_1_DADERR, 0x0bc0),
INTCS_VECT(KEYSC_KEY, 0x0be0), INTCS_VECT(VINT, 0x0c80),
INTCS_VECT(MSIOF, 0x0d20),
INTCS_VECT(TMU0_TUNI00, 0x0e80), INTCS_VECT(TMU0_TUNI01, 0x0ea0),
INTCS_VECT(TMU0_TUNI02, 0x0ec0),
INTCS_VECT(CMT0, 0x0f00), INTCS_VECT(TSIF0, 0x0f20),
INTCS_VECT(CMT2, 0x0f40), INTCS_VECT(LMB, 0x0f60),
INTCS_VECT(MSUG, 0x0f80),
INTCS_VECT(MSU_MSU, 0x0fa0), INTCS_VECT(MSU_MSU2, 0x0fc0),
INTCS_VECT(CTI, 0x0400), INTCS_VECT(RWDT0, 0x0440),
INTCS_VECT(ICB, 0x0480), INTCS_VECT(PEP, 0x04a0),
INTCS_VECT(ASA, 0x04c0), INTCS_VECT(JPU_JPEG, 0x0560),
INTCS_VECT(LCDC, 0x0580), INTCS_VECT(LCRC, 0x05a0),
INTCS_VECT(RTDMAC_2_DEI6, 0x1300), INTCS_VECT(RTDMAC_2_DEI7, 0x1320),
INTCS_VECT(RTDMAC_2_DEI8, 0x1340), INTCS_VECT(RTDMAC_2_DEI9, 0x1360),
INTCS_VECT(RTDMAC_3_DEI10, 0x1380), INTCS_VECT(RTDMAC_3_DEI11, 0x13a0),
INTCS_VECT(FRC, 0x1700), INTCS_VECT(GCU, 0x1760),
INTCS_VECT(LCDC1, 0x1780), INTCS_VECT(CSIRX, 0x17a0),
INTCS_VECT(DSITX0_DSITX00, 0x17c0), INTCS_VECT(DSITX0_DSITX01, 0x17e0),
INTCS_VECT(SPU2_SPU0, 0x1800), INTCS_VECT(SPU2_SPU1, 0x1820),
INTCS_VECT(FSI, 0x1840),
INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
INTCS_VECT(TMU1_TUNI12, 0x1940),
INTCS_VECT(TSIF2, 0x1960), INTCS_VECT(CMT4, 0x1980),
INTCS_VECT(MFIS2, 0x1a00), INTCS_VECT(CPORTS2R, 0x1a20),
INTCS_VECT(TSG, 0x1ae0), INTCS_VECT(DMASCH1, 0x1b00),
INTCS_VECT(SCUW, 0x1b40),
INTCS_VECT(VIO60, 0x1b60), INTCS_VECT(VIO61, 0x1b80),
INTCS_VECT(CEU21, 0x1ba0), INTCS_VECT(CSI21, 0x1be0),
INTCS_VECT(DSITX1_DSITX10, 0x1c00), INTCS_VECT(DSITX1_DSITX11, 0x1c20),
INTCS_VECT(DISP, 0x1c40), INTCS_VECT(DSRV, 0x1c60),
INTCS_VECT(EMUX2_EMUX20I, 0x1c80), INTCS_VECT(EMUX2_EMUX21I, 0x1ca0),
INTCS_VECT(MSTIF0_MST00I, 0x1cc0), INTCS_VECT(MSTIF0_MST01I, 0x1ce0),
INTCS_VECT(MSTIF1_MST10I, 0x1d00), INTCS_VECT(MSTIF1_MST11I, 0x1d20),
INTCS_VECT(SPUV, 0x2300),
};
static struct intc_group intcs_groups[] __initdata = {
INTC_GROUP(RTDMAC_0, RTDMAC_0_DEI0, RTDMAC_0_DEI1,
RTDMAC_0_DEI2, RTDMAC_0_DEI3),
INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI4, RTDMAC_1_DEI5, RTDMAC_1_DADERR),
INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI6, RTDMAC_2_DEI7,
RTDMAC_2_DEI8, RTDMAC_2_DEI9),
INTC_GROUP(RTDMAC_3, RTDMAC_3_DEI10, RTDMAC_3_DEI11),
INTC_GROUP(TMU1, TMU1_TUNI12, TMU1_TUNI11, TMU1_TUNI10),
INTC_GROUP(DSITX0, DSITX0_DSITX00, DSITX0_DSITX01),
INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
INTC_GROUP(MSU, MSU_MSU, MSU_MSU2),
};
static struct intc_mask_reg intcs_mask_registers[] = {
{ 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
{ 0, 0, 0, CEU,
0, 0, 0, 0 } },
{ 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
{ 0, 0, 0, VPU,
BBIF2, 0, 0, MFI } },
{ 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
{ 0, 0, 0, _2DDMAC_2DDM0,
0, ASA, PEP, ICB } },
{ 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
{ 0, 0, 0, CTI,
JPU_JPEG, 0, LCRC, LCDC } },
{ 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
{ KEYSC_KEY, RTDMAC_1_DADERR, RTDMAC_1_DEI5, RTDMAC_1_DEI4,
RTDMAC_0_DEI3, RTDMAC_0_DEI2, RTDMAC_0_DEI1, RTDMAC_0_DEI0 } },
{ 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
{ 0, 0, MSIOF, 0,
_3DG_SGX543, 0, 0, 0 } },
{ 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
{ 0, TMU0_TUNI02, TMU0_TUNI01, TMU0_TUNI00,
0, 0, 0, 0 } },
{ 0xffd201a0, 0xffd201e0, 8, /* IMR8SA / IMCR8SA */
{ 0, 0, 0, 0,
0, MSU_MSU, MSU_MSU2, MSUG } },
{ 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
{ 0, RWDT0, CMT2, CMT0,
0, 0, 0, 0 } },
{ 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
{ 0, 0, 0, 0,
0, TSIF1, LMB, TSIF0 } },
{ 0xffd201b0, 0xffd201f0, 8, /* IMR12SA / IMCR12SA */
{ 0, 0, 0, 0,
0, 0, PINTCS_PINT2, PINTCS_PINT1 } },
{ 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */
{ RTDMAC_2_DEI6, RTDMAC_2_DEI7, RTDMAC_2_DEI8, RTDMAC_2_DEI9,
RTDMAC_3_DEI10, RTDMAC_3_DEI11, 0, 0 } },
{ 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */
{ FRC, 0, 0, GCU,
LCDC1, CSIRX, DSITX0_DSITX00, DSITX0_DSITX01 } },
{ 0xffd50194, 0xffd501d4, 8, /* IMR5SA3 / IMCR5SA3 */
{ SPU2_SPU0, SPU2_SPU1, FSI, 0,
0, 0, 0, 0 } },
{ 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */
{ TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, 0,
TSIF2, CMT4, 0, 0 } },
{ 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
{ MFIS2, CPORTS2R, 0, 0,
0, 0, 0, TSG } },
{ 0xffd501a0, 0xffd501e0, 8, /* IMR8SA3 / IMCR8SA3 */
{ DMASCH1, 0, SCUW, VIO60,
VIO61, CEU21, 0, CSI21 } },
{ 0xffd501a4, 0xffd501e4, 8, /* IMR9SA3 / IMCR9SA3 */
{ DSITX1_DSITX10, DSITX1_DSITX11, DISP, DSRV,
EMUX2_EMUX20I, EMUX2_EMUX21I, MSTIF0_MST00I, MSTIF0_MST01I } },
{ 0xffd501a8, 0xffd501e8, 8, /* IMR10SA3 / IMCR10SA3 */
{ MSTIF0_MST00I, MSTIF0_MST01I, 0, 0,
0, 0, 0, 0 } },
{ 0xffd60180, 0xffd601c0, 8, /* IMR0SA4 / IMCR0SA4 */
{ SPUV, 0, 0, 0,
0, 0, 0, 0 } },
};
/* Priority is needed for INTCA to receive the INTCS interrupt */
static struct intc_prio_reg intcs_prio_registers[] = {
{ 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC_2DDM0, ICB } },
{ 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } },
{ 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
{ 0xffd2000c, 0, 16, 4, /* IPRDS */ { PINTCS_PINT1, PINTCS_PINT2,
0, 0 } },
{ 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_0, CEU, MFI, VPU } },
{ 0xffd20014, 0, 16, 4, /* IPRFS */ { KEYSC_KEY, RTDMAC_1,
CMT2, CMT0 } },
{ 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU0_TUNI00, TMU0_TUNI01,
TMU0_TUNI02, TSIF1 } },
{ 0xffd2001c, 0, 16, 4, /* IPRHS */ { VINT, 0, 0, 0 } },
{ 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, 0 } },
{ 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX543, MSUG, MSU } },
{ 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, ASA, LMB, PEP } },
{ 0xffd20030, 0, 16, 4, /* IPRMS */ { 0, 0, 0, RWDT0 } },
{ 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC_2, 0, 0, 0 } },
{ 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC_3, 0, 0, 0 } },
{ 0xffd50020, 0, 16, 4, /* IPRIS3 */ { FRC, 0, 0, 0 } },
{ 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX0, 0 } },
{ 0xffd50028, 0, 16, 4, /* IPRKS3 */ { SPU2, 0, FSI, 0 } },
{ 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, TSIF2 } },
{ 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, 0, 0, 0 } },
{ 0xffd50038, 0, 16, 4, /* IPROS3 */ { MFIS2, CPORTS2R, 0, 0 } },
{ 0xffd50040, 0, 16, 4, /* IPRQS3 */ { DMASCH1, 0, SCUW, VIO60 } },
{ 0xffd50044, 0, 16, 4, /* IPRRS3 */ { VIO61, CEU21, 0, CSI21 } },
{ 0xffd50048, 0, 16, 4, /* IPRSS3 */ { DSITX1_DSITX10, DSITX1_DSITX11,
DISP, DSRV } },
{ 0xffd5004c, 0, 16, 4, /* IPRTS3 */ { EMUX2_EMUX20I, EMUX2_EMUX21I,
MSTIF0_MST00I, MSTIF0_MST01I } },
{ 0xffd50050, 0, 16, 4, /* IPRUS3 */ { MSTIF1_MST10I, MSTIF1_MST11I,
0, 0 } },
{ 0xffd60000, 0, 16, 4, /* IPRAS4 */ { SPUV, 0, 0, 0 } },
};
static struct resource intcs_resources[] __initdata = {
[0] = {
.start = 0xffd20000,
.end = 0xffd201ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0xffd50000,
.end = 0xffd501ff,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = 0xffd60000,
.end = 0xffd601ff,
.flags = IORESOURCE_MEM,
}
};
static struct intc_desc intcs_desc __initdata = {
.name = "sh73a0-intcs",
.resource = intcs_resources,
.num_resources = ARRAY_SIZE(intcs_resources),
.hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
intcs_prio_registers, NULL, NULL),
};
static struct irqaction sh73a0_intcs_cascade;
static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
{
unsigned int evtcodeas = ioread32((void __iomem *)dev_id);
generic_handle_irq(intcs_evt2irq(evtcodeas));
return IRQ_HANDLED;
}
void __init sh73a0_init_irq(void)
{
void __iomem *gic_base = __io(0xf0001000);
void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
gic_init(0, 29, gic_base, gic_base);
register_intc_controller(&intcs_desc);
/* demux using INTEVTSA */
sh73a0_intcs_cascade.name = "INTCS cascade";
sh73a0_intcs_cascade.handler = sh73a0_intcs_demux;
sh73a0_intcs_cascade.dev_id = intevtsa;
setup_irq(gic_spi(50), &sh73a0_intcs_cascade);
}

View File

@ -0,0 +1,25 @@
/*
* SMP support for R-Mobile / SH-Mobile - local timer portion
*
* Copyright (C) 2010 Magnus Damm
*
* Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/clockchips.h>
#include <asm/smp_twd.h>
#include <asm/localtimer.h>
/*
* Setup the local clock events for a CPU.
*/
void __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = 29;
twd_timer_setup(evt);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
/*
* SMP support for R-Mobile / SH-Mobile
*
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2011 Paul Mundt
*
* Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <asm/localtimer.h>
#include <asm/mach-types.h>
#include <mach/common.h>
static unsigned int __init shmobile_smp_get_core_count(void)
{
if (machine_is_ag5evm())
return sh73a0_get_core_count();
return 1;
}
static void __init shmobile_smp_prepare_cpus(void)
{
if (machine_is_ag5evm())
sh73a0_smp_prepare_cpus();
}
void __cpuinit platform_secondary_init(unsigned int cpu)
{
trace_hardirqs_off();
if (machine_is_ag5evm())
sh73a0_secondary_init(cpu);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
if (machine_is_ag5evm())
return sh73a0_boot_secondary(cpu);
return -ENOSYS;
}
void __init smp_init_cpus(void)
{
unsigned int ncores = shmobile_smp_get_core_count();
unsigned int i;
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
}
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
int i;
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
shmobile_smp_prepare_cpus();
}

View File

@ -416,6 +416,16 @@ static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
.addr = 0xe6870030, .addr = 0xe6870030,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xce, .mid_rid = 0xce,
}, {
.slave_id = SHDMA_SLAVE_MMCIF_TX,
.addr = 0xe6bd0034,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xd1,
}, {
.slave_id = SHDMA_SLAVE_MMCIF_RX,
.addr = 0xe6bd0034,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xd2,
}, },
}; };

View File

@ -0,0 +1,412 @@
/*
* sh73a0 processor support
*
* Copyright (C) 2010 Takashi Yoshii
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2008 Yoshihiro Shimoda
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
#include <linux/sh_intc.h>
#include <linux/sh_timer.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xe6c40000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(72), gic_spi(72),
gic_spi(72), gic_spi(72) },
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.mapbase = 0xe6c50000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(73), gic_spi(73),
gic_spi(73), gic_spi(73) },
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xe6c60000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(74), gic_spi(74),
gic_spi(74), gic_spi(74) },
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.mapbase = 0xe6c70000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(75), gic_spi(75),
gic_spi(75), gic_spi(75) },
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct plat_sci_port scif4_platform_data = {
.mapbase = 0xe6c80000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(78), gic_spi(78),
gic_spi(78), gic_spi(78) },
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.dev = {
.platform_data = &scif4_platform_data,
},
};
static struct plat_sci_port scif5_platform_data = {
.mapbase = 0xe6cb0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(79), gic_spi(79),
gic_spi(79), gic_spi(79) },
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.dev = {
.platform_data = &scif5_platform_data,
},
};
static struct plat_sci_port scif6_platform_data = {
.mapbase = 0xe6cc0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(156), gic_spi(156),
gic_spi(156), gic_spi(156) },
};
static struct platform_device scif6_device = {
.name = "sh-sci",
.id = 6,
.dev = {
.platform_data = &scif6_platform_data,
},
};
static struct plat_sci_port scif7_platform_data = {
.mapbase = 0xe6cd0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { gic_spi(143), gic_spi(143),
gic_spi(143), gic_spi(143) },
};
static struct platform_device scif7_device = {
.name = "sh-sci",
.id = 7,
.dev = {
.platform_data = &scif7_platform_data,
},
};
static struct plat_sci_port scif8_platform_data = {
.mapbase = 0xe6c30000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFB,
.irqs = { gic_spi(80), gic_spi(80),
gic_spi(80), gic_spi(80) },
};
static struct platform_device scif8_device = {
.name = "sh-sci",
.id = 8,
.dev = {
.platform_data = &scif8_platform_data,
},
};
static struct sh_timer_config cmt10_platform_data = {
.name = "CMT10",
.channel_offset = 0x10,
.timer_bit = 0,
.clockevent_rating = 125,
.clocksource_rating = 125,
};
static struct resource cmt10_resources[] = {
[0] = {
.name = "CMT10",
.start = 0xe6138010,
.end = 0xe613801b,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(65),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device cmt10_device = {
.name = "sh_cmt",
.id = 10,
.dev = {
.platform_data = &cmt10_platform_data,
},
.resource = cmt10_resources,
.num_resources = ARRAY_SIZE(cmt10_resources),
};
/* TMU */
static struct sh_timer_config tmu00_platform_data = {
.name = "TMU00",
.channel_offset = 0x4,
.timer_bit = 0,
.clockevent_rating = 200,
};
static struct resource tmu00_resources[] = {
[0] = {
.name = "TMU00",
.start = 0xfff60008,
.end = 0xfff60013,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device tmu00_device = {
.name = "sh_tmu",
.id = 0,
.dev = {
.platform_data = &tmu00_platform_data,
},
.resource = tmu00_resources,
.num_resources = ARRAY_SIZE(tmu00_resources),
};
static struct sh_timer_config tmu01_platform_data = {
.name = "TMU01",
.channel_offset = 0x10,
.timer_bit = 1,
.clocksource_rating = 200,
};
static struct resource tmu01_resources[] = {
[0] = {
.name = "TMU01",
.start = 0xfff60014,
.end = 0xfff6001f,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device tmu01_device = {
.name = "sh_tmu",
.id = 1,
.dev = {
.platform_data = &tmu01_platform_data,
},
.resource = tmu01_resources,
.num_resources = ARRAY_SIZE(tmu01_resources),
};
static struct resource i2c0_resources[] = {
[0] = {
.name = "IIC0",
.start = 0xe6820000,
.end = 0xe6820425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(167),
.end = gic_spi(170),
.flags = IORESOURCE_IRQ,
},
};
static struct resource i2c1_resources[] = {
[0] = {
.name = "IIC1",
.start = 0xe6822000,
.end = 0xe6822425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(51),
.end = gic_spi(54),
.flags = IORESOURCE_IRQ,
},
};
static struct resource i2c2_resources[] = {
[0] = {
.name = "IIC2",
.start = 0xe6824000,
.end = 0xe6824425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(171),
.end = gic_spi(174),
.flags = IORESOURCE_IRQ,
},
};
static struct resource i2c3_resources[] = {
[0] = {
.name = "IIC3",
.start = 0xe6826000,
.end = 0xe6826425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(183),
.end = gic_spi(186),
.flags = IORESOURCE_IRQ,
},
};
static struct resource i2c4_resources[] = {
[0] = {
.name = "IIC4",
.start = 0xe6828000,
.end = 0xe6828425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(187),
.end = gic_spi(190),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device i2c0_device = {
.name = "i2c-sh_mobile",
.id = 0,
.resource = i2c0_resources,
.num_resources = ARRAY_SIZE(i2c0_resources),
};
static struct platform_device i2c1_device = {
.name = "i2c-sh_mobile",
.id = 1,
.resource = i2c1_resources,
.num_resources = ARRAY_SIZE(i2c1_resources),
};
static struct platform_device i2c2_device = {
.name = "i2c-sh_mobile",
.id = 2,
.resource = i2c2_resources,
.num_resources = ARRAY_SIZE(i2c2_resources),
};
static struct platform_device i2c3_device = {
.name = "i2c-sh_mobile",
.id = 3,
.resource = i2c3_resources,
.num_resources = ARRAY_SIZE(i2c3_resources),
};
static struct platform_device i2c4_device = {
.name = "i2c-sh_mobile",
.id = 4,
.resource = i2c4_resources,
.num_resources = ARRAY_SIZE(i2c4_resources),
};
static struct platform_device *sh73a0_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&scif6_device,
&scif7_device,
&scif8_device,
&cmt10_device,
&tmu00_device,
&tmu01_device,
};
static struct platform_device *sh73a0_late_devices[] __initdata = {
&i2c0_device,
&i2c1_device,
&i2c2_device,
&i2c3_device,
&i2c4_device,
};
void __init sh73a0_add_standard_devices(void)
{
platform_add_devices(sh73a0_early_devices,
ARRAY_SIZE(sh73a0_early_devices));
platform_add_devices(sh73a0_late_devices,
ARRAY_SIZE(sh73a0_late_devices));
}
void __init sh73a0_add_early_devices(void)
{
early_platform_add_devices(sh73a0_early_devices,
ARRAY_SIZE(sh73a0_early_devices));
}

View File

@ -0,0 +1,97 @@
/*
* SMP support for R-Mobile / SH-Mobile - sh73a0 portion
*
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2010 Takashi Yoshii
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <mach/common.h>
#include <asm/smp_scu.h>
#include <asm/smp_twd.h>
#include <asm/hardware/gic.h>
#define WUPCR 0xe6151010
#define SRESCR 0xe6151018
#define PSTR 0xe6151040
#define SBAR 0xe6180020
#define APARMBAREA 0xe6f10020
static void __iomem *scu_base_addr(void)
{
return (void __iomem *)0xf0000000;
}
static DEFINE_SPINLOCK(scu_lock);
static unsigned long tmp;
static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
{
void __iomem *scu_base = scu_base_addr();
spin_lock(&scu_lock);
tmp = __raw_readl(scu_base + 8);
tmp &= ~clr;
tmp |= set;
spin_unlock(&scu_lock);
/* disable cache coherency after releasing the lock */
__raw_writel(tmp, scu_base + 8);
}
unsigned int __init sh73a0_get_core_count(void)
{
void __iomem *scu_base = scu_base_addr();
return scu_get_core_count(scu_base);
}
void __cpuinit sh73a0_secondary_init(unsigned int cpu)
{
gic_secondary_init(0);
}
int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
{
/* enable cache coherency */
modify_scu_cpu_psr(0, 3 << (cpu * 8));
if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
__raw_writel(1 << cpu, __io(WUPCR)); /* wake up */
else
__raw_writel(1 << cpu, __io(SRESCR)); /* reset */
return 0;
}
void __init sh73a0_smp_prepare_cpus(void)
{
#ifdef CONFIG_HAVE_ARM_TWD
twd_base = (void __iomem *)0xf0000600;
#endif
scu_enable(scu_base_addr());
/* Map the reset vector (in headsmp.S) */
__raw_writel(0, __io(APARMBAREA)); /* 4k */
__raw_writel(__pa(shmobile_secondary_vector), __io(SBAR));
/* enable cache coherency on CPU0 */
modify_scu_cpu_psr(0, 3 << (0 * 8));
}

View File

@ -813,7 +813,7 @@ config CACHE_L2X0
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \ REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
ARCH_NOMADIK || ARCH_OMAP4 || ARCH_S5PV310 || ARCH_TEGRA || \ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_S5PV310 || ARCH_TEGRA || \
ARCH_U8500 || ARCH_VEXPRESS_CA9X4 ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE
default y default y
select OUTER_CACHE select OUTER_CACHE
select OUTER_CACHE_SYNC select OUTER_CACHE_SYNC

View File

@ -4,7 +4,7 @@
#else /* __ASSEMBLY__ */ #else /* __ASSEMBLY__ */
extern inline void mmcif_update_progress(int nr) static inline void mmcif_update_progress(int nr)
{ {
} }

View File

@ -35,7 +35,7 @@
#define HIZCRA 0xa4050158 #define HIZCRA 0xa4050158
#define PGDR 0xa405012c #define PGDR 0xa405012c
extern inline void mmcif_update_progress(int nr) static inline void mmcif_update_progress(int nr)
{ {
/* disable Hi-Z for LED pins */ /* disable Hi-Z for LED pins */
__raw_writew(__raw_readw(HIZCRA) & ~(1 << 1), HIZCRA); __raw_writew(__raw_readw(HIZCRA) & ~(1 << 1), HIZCRA);

View File

@ -23,7 +23,7 @@
#else /* __ASSEMBLY__ */ #else /* __ASSEMBLY__ */
extern inline void mmcif_update_progress(int nr) static inline void mmcif_update_progress(int nr)
{ {
} }

View File

@ -1110,11 +1110,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
list_add_tail_rcu(&shdev->node, &sh_dmae_devices); list_add_tail_rcu(&shdev->node, &sh_dmae_devices);
spin_unlock_irqrestore(&sh_dmae_lock, flags); spin_unlock_irqrestore(&sh_dmae_lock, flags);
/* Wire up NMI handling before bringing the controller online */
err = register_die_notifier(&sh_dmae_nmi_notifier);
if (err)
goto notifier_err;
/* reset dma controller */ /* reset dma controller */
err = sh_dmae_rst(shdev); err = sh_dmae_rst(shdev);
if (err) if (err)
@ -1218,8 +1213,6 @@ eirqres:
eirq_err: eirq_err:
#endif #endif
rst_err: rst_err:
unregister_die_notifier(&sh_dmae_nmi_notifier);
notifier_err:
spin_lock_irqsave(&sh_dmae_lock, flags); spin_lock_irqsave(&sh_dmae_lock, flags);
list_del_rcu(&shdev->node); list_del_rcu(&shdev->node);
spin_unlock_irqrestore(&sh_dmae_lock, flags); spin_unlock_irqrestore(&sh_dmae_lock, flags);
@ -1252,8 +1245,6 @@ static int __exit sh_dmae_remove(struct platform_device *pdev)
if (errirq > 0) if (errirq > 0)
free_irq(errirq, shdev); free_irq(errirq, shdev);
unregister_die_notifier(&sh_dmae_nmi_notifier);
spin_lock_irqsave(&sh_dmae_lock, flags); spin_lock_irqsave(&sh_dmae_lock, flags);
list_del_rcu(&shdev->node); list_del_rcu(&shdev->node);
spin_unlock_irqrestore(&sh_dmae_lock, flags); spin_unlock_irqrestore(&sh_dmae_lock, flags);
@ -1296,6 +1287,11 @@ static struct platform_driver sh_dmae_driver = {
static int __init sh_dmae_init(void) static int __init sh_dmae_init(void)
{ {
/* Wire up NMI handling */
int err = register_die_notifier(&sh_dmae_nmi_notifier);
if (err)
return err;
return platform_driver_probe(&sh_dmae_driver, sh_dmae_probe); return platform_driver_probe(&sh_dmae_driver, sh_dmae_probe);
} }
module_init(sh_dmae_init); module_init(sh_dmae_init);
@ -1303,6 +1299,8 @@ module_init(sh_dmae_init);
static void __exit sh_dmae_exit(void) static void __exit sh_dmae_exit(void)
{ {
platform_driver_unregister(&sh_dmae_driver); platform_driver_unregister(&sh_dmae_driver);
unregister_die_notifier(&sh_dmae_nmi_notifier);
} }
module_exit(sh_dmae_exit); module_exit(sh_dmae_exit);

View File

@ -16,16 +16,19 @@
* *
*/ */
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/mmc/host.h> #include <linux/dmaengine.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mmc/core.h> #include <linux/mmc/core.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h> #include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h> #include <linux/mmc/sdio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/mmc/sh_mmcif.h> #include <linux/mmc/sh_mmcif.h>
#include <linux/pagemap.h>
#include <linux/platform_device.h>
#define DRIVER_NAME "sh_mmcif" #define DRIVER_NAME "sh_mmcif"
#define DRIVER_VERSION "2010-04-28" #define DRIVER_VERSION "2010-04-28"
@ -62,25 +65,6 @@
/* CE_BLOCK_SET */ /* CE_BLOCK_SET */
#define BLOCK_SIZE_MASK 0x0000ffff #define BLOCK_SIZE_MASK 0x0000ffff
/* CE_CLK_CTRL */
#define CLK_ENABLE (1 << 24) /* 1: output mmc clock */
#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
#define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
#define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */
#define SRBSYTO_29 ((1 << 11) | (1 << 10) | \
(1 << 9) | (1 << 8)) /* resp busy timeout */
#define SRWDTO_29 ((1 << 7) | (1 << 6) | \
(1 << 5) | (1 << 4)) /* read/write timeout */
#define SCCSTO_29 ((1 << 3) | (1 << 2) | \
(1 << 1) | (1 << 0)) /* ccs timeout */
/* CE_BUF_ACC */
#define BUF_ACC_DMAWEN (1 << 25)
#define BUF_ACC_DMAREN (1 << 24)
#define BUF_ACC_BUSW_32 (0 << 17)
#define BUF_ACC_BUSW_16 (1 << 17)
#define BUF_ACC_ATYP (1 << 16)
/* CE_INT */ /* CE_INT */
#define INT_CCSDE (1 << 29) #define INT_CCSDE (1 << 29)
#define INT_CMD12DRE (1 << 26) #define INT_CMD12DRE (1 << 26)
@ -165,10 +149,6 @@
STS2_AC12BSYTO | STS2_RSPBSYTO | \ STS2_AC12BSYTO | STS2_RSPBSYTO | \
STS2_AC12RSPTO | STS2_RSPTO) STS2_AC12RSPTO | STS2_RSPTO)
/* CE_VERSION */
#define SOFT_RST_ON (1 << 31)
#define SOFT_RST_OFF (0 << 31)
#define CLKDEV_EMMC_DATA 52000000 /* 52MHz */ #define CLKDEV_EMMC_DATA 52000000 /* 52MHz */
#define CLKDEV_MMC_DATA 20000000 /* 20MHz */ #define CLKDEV_MMC_DATA 20000000 /* 20MHz */
#define CLKDEV_INIT 400000 /* 400 KHz */ #define CLKDEV_INIT 400000 /* 400 KHz */
@ -176,18 +156,21 @@
struct sh_mmcif_host { struct sh_mmcif_host {
struct mmc_host *mmc; struct mmc_host *mmc;
struct mmc_data *data; struct mmc_data *data;
struct mmc_command *cmd;
struct platform_device *pd; struct platform_device *pd;
struct clk *hclk; struct clk *hclk;
unsigned int clk; unsigned int clk;
int bus_width; int bus_width;
u16 wait_int; bool sd_error;
u16 sd_error;
long timeout; long timeout;
void __iomem *addr; void __iomem *addr;
wait_queue_head_t intr_wait; struct completion intr_wait;
};
/* DMA support */
struct dma_chan *chan_rx;
struct dma_chan *chan_tx;
struct completion dma_complete;
unsigned int dma_sglen;
};
static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, static inline void sh_mmcif_bitset(struct sh_mmcif_host *host,
unsigned int reg, u32 val) unsigned int reg, u32 val)
@ -201,6 +184,188 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
writel(~val & readl(host->addr + reg), host->addr + reg); writel(~val & readl(host->addr + reg), host->addr + reg);
} }
static void mmcif_dma_complete(void *arg)
{
struct sh_mmcif_host *host = arg;
dev_dbg(&host->pd->dev, "Command completed\n");
if (WARN(!host->data, "%s: NULL data in DMA completion!\n",
dev_name(&host->pd->dev)))
return;
if (host->data->flags & MMC_DATA_READ)
dma_unmap_sg(&host->pd->dev, host->data->sg, host->dma_sglen,
DMA_FROM_DEVICE);
else
dma_unmap_sg(&host->pd->dev, host->data->sg, host->dma_sglen,
DMA_TO_DEVICE);
complete(&host->dma_complete);
}
static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
{
struct scatterlist *sg = host->data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_rx;
dma_cookie_t cookie = -EINVAL;
int ret;
ret = dma_map_sg(&host->pd->dev, sg, host->data->sg_len, DMA_FROM_DEVICE);
if (ret > 0) {
host->dma_sglen = ret;
desc = chan->device->device_prep_slave_sg(chan, sg, ret,
DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}
if (desc) {
desc->callback = mmcif_dma_complete;
desc->callback_param = host;
cookie = desc->tx_submit(desc);
if (cookie < 0) {
desc = NULL;
ret = cookie;
} else {
sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN);
chan->device->device_issue_pending(chan);
}
}
dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
__func__, host->data->sg_len, ret, cookie);
if (!desc) {
/* DMA failed, fall back to PIO */
if (ret >= 0)
ret = -EIO;
host->chan_rx = NULL;
host->dma_sglen = 0;
dma_release_channel(chan);
/* Free the Tx channel too */
chan = host->chan_tx;
if (chan) {
host->chan_tx = NULL;
dma_release_channel(chan);
}
dev_warn(&host->pd->dev,
"DMA failed: %d, falling back to PIO\n", ret);
sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
}
dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
desc, cookie, host->data->sg_len);
}
static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
{
struct scatterlist *sg = host->data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_tx;
dma_cookie_t cookie = -EINVAL;
int ret;
ret = dma_map_sg(&host->pd->dev, sg, host->data->sg_len, DMA_TO_DEVICE);
if (ret > 0) {
host->dma_sglen = ret;
desc = chan->device->device_prep_slave_sg(chan, sg, ret,
DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}
if (desc) {
desc->callback = mmcif_dma_complete;
desc->callback_param = host;
cookie = desc->tx_submit(desc);
if (cookie < 0) {
desc = NULL;
ret = cookie;
} else {
sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAWEN);
chan->device->device_issue_pending(chan);
}
}
dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
__func__, host->data->sg_len, ret, cookie);
if (!desc) {
/* DMA failed, fall back to PIO */
if (ret >= 0)
ret = -EIO;
host->chan_tx = NULL;
host->dma_sglen = 0;
dma_release_channel(chan);
/* Free the Rx channel too */
chan = host->chan_rx;
if (chan) {
host->chan_rx = NULL;
dma_release_channel(chan);
}
dev_warn(&host->pd->dev,
"DMA failed: %d, falling back to PIO\n", ret);
sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
}
dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d\n", __func__,
desc, cookie);
}
static bool sh_mmcif_filter(struct dma_chan *chan, void *arg)
{
dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
chan->private = arg;
return true;
}
static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
struct sh_mmcif_plat_data *pdata)
{
host->dma_sglen = 0;
/* We can only either use DMA for both Tx and Rx or not use it at all */
if (pdata->dma) {
dma_cap_mask_t mask;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
host->chan_tx = dma_request_channel(mask, sh_mmcif_filter,
&pdata->dma->chan_priv_tx);
dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
host->chan_tx);
if (!host->chan_tx)
return;
host->chan_rx = dma_request_channel(mask, sh_mmcif_filter,
&pdata->dma->chan_priv_rx);
dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
host->chan_rx);
if (!host->chan_rx) {
dma_release_channel(host->chan_tx);
host->chan_tx = NULL;
return;
}
init_completion(&host->dma_complete);
}
}
static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
{
sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
/* Descriptors are freed automatically */
if (host->chan_tx) {
struct dma_chan *chan = host->chan_tx;
host->chan_tx = NULL;
dma_release_channel(chan);
}
if (host->chan_rx) {
struct dma_chan *chan = host->chan_rx;
host->chan_rx = NULL;
dma_release_channel(chan);
}
host->dma_sglen = 0;
}
static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
{ {
@ -239,13 +404,12 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
u32 state1, state2; u32 state1, state2;
int ret, timeout = 10000000; int ret, timeout = 10000000;
host->sd_error = 0; host->sd_error = false;
host->wait_int = 0;
state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1); state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1);
state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2); state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2);
pr_debug("%s: ERR HOST_STS1 = %08x\n", DRIVER_NAME, state1); dev_dbg(&host->pd->dev, "ERR HOST_STS1 = %08x\n", state1);
pr_debug("%s: ERR HOST_STS2 = %08x\n", DRIVER_NAME, state2); dev_dbg(&host->pd->dev, "ERR HOST_STS2 = %08x\n", state2);
if (state1 & STS1_CMDSEQ) { if (state1 & STS1_CMDSEQ) {
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
@ -253,8 +417,8 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
while (1) { while (1) {
timeout--; timeout--;
if (timeout < 0) { if (timeout < 0) {
pr_err(DRIVER_NAME": Forceed end of " \ dev_err(&host->pd->dev,
"command sequence timeout err\n"); "Forceed end of command sequence timeout err\n");
return -EIO; return -EIO;
} }
if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
@ -263,18 +427,18 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
mdelay(1); mdelay(1);
} }
sh_mmcif_sync_reset(host); sh_mmcif_sync_reset(host);
pr_debug(DRIVER_NAME": Forced end of command sequence\n"); dev_dbg(&host->pd->dev, "Forced end of command sequence\n");
return -EIO; return -EIO;
} }
if (state2 & STS2_CRC_ERR) { if (state2 & STS2_CRC_ERR) {
pr_debug(DRIVER_NAME": Happened CRC error\n"); dev_dbg(&host->pd->dev, ": Happened CRC error\n");
ret = -EIO; ret = -EIO;
} else if (state2 & STS2_TIMEOUT_ERR) { } else if (state2 & STS2_TIMEOUT_ERR) {
pr_debug(DRIVER_NAME": Happened Timeout error\n"); dev_dbg(&host->pd->dev, ": Happened Timeout error\n");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} else { } else {
pr_debug(DRIVER_NAME": Happened End/Index error\n"); dev_dbg(&host->pd->dev, ": Happened End/Index error\n");
ret = -EIO; ret = -EIO;
} }
return ret; return ret;
@ -287,17 +451,13 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host,
long time; long time;
u32 blocksize, i, *p = sg_virt(data->sg); u32 blocksize, i, *p = sg_virt(data->sg);
host->wait_int = 0;
/* buf read enable */ /* buf read enable */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout); if (time <= 0 || host->sd_error)
if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
return sh_mmcif_error_manage(host); return sh_mmcif_error_manage(host);
host->wait_int = 0;
blocksize = (BLOCK_SIZE_MASK & blocksize = (BLOCK_SIZE_MASK &
sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
for (i = 0; i < blocksize / 4; i++) for (i = 0; i < blocksize / 4; i++)
@ -305,13 +465,11 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host,
/* buffer read end */ /* buffer read end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout); if (time <= 0 || host->sd_error)
if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
return sh_mmcif_error_manage(host); return sh_mmcif_error_manage(host);
host->wait_int = 0;
return 0; return 0;
} }
@ -326,19 +484,15 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
MMCIF_CE_BLOCK_SET); MMCIF_CE_BLOCK_SET);
for (j = 0; j < data->sg_len; j++) { for (j = 0; j < data->sg_len; j++) {
p = sg_virt(data->sg); p = sg_virt(data->sg);
host->wait_int = 0;
for (sec = 0; sec < data->sg->length / blocksize; sec++) { for (sec = 0; sec < data->sg->length / blocksize; sec++) {
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
/* buf read enable */ /* buf read enable */
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout);
if (host->wait_int != 1 && if (time <= 0 || host->sd_error)
(time == 0 || host->sd_error != 0))
return sh_mmcif_error_manage(host); return sh_mmcif_error_manage(host);
host->wait_int = 0;
for (i = 0; i < blocksize / 4; i++) for (i = 0; i < blocksize / 4; i++)
*p++ = sh_mmcif_readl(host->addr, *p++ = sh_mmcif_readl(host->addr,
MMCIF_CE_DATA); MMCIF_CE_DATA);
@ -356,17 +510,14 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host,
long time; long time;
u32 blocksize, i, *p = sg_virt(data->sg); u32 blocksize, i, *p = sg_virt(data->sg);
host->wait_int = 0;
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
/* buf write enable */ /* buf write enable */
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout); if (time <= 0 || host->sd_error)
if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
return sh_mmcif_error_manage(host); return sh_mmcif_error_manage(host);
host->wait_int = 0;
blocksize = (BLOCK_SIZE_MASK & blocksize = (BLOCK_SIZE_MASK &
sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
for (i = 0; i < blocksize / 4; i++) for (i = 0; i < blocksize / 4; i++)
@ -375,13 +526,11 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host,
/* buffer write end */ /* buffer write end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout); if (time <= 0 || host->sd_error)
if (host->wait_int != 1 && (time == 0 || host->sd_error != 0))
return sh_mmcif_error_manage(host); return sh_mmcif_error_manage(host);
host->wait_int = 0;
return 0; return 0;
} }
@ -397,19 +546,15 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
for (j = 0; j < data->sg_len; j++) { for (j = 0; j < data->sg_len; j++) {
p = sg_virt(data->sg); p = sg_virt(data->sg);
host->wait_int = 0;
for (sec = 0; sec < data->sg->length / blocksize; sec++) { for (sec = 0; sec < data->sg->length / blocksize; sec++) {
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
/* buf write enable*/ /* buf write enable*/
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout);
if (host->wait_int != 1 && if (time <= 0 || host->sd_error)
(time == 0 || host->sd_error != 0))
return sh_mmcif_error_manage(host); return sh_mmcif_error_manage(host);
host->wait_int = 0;
for (i = 0; i < blocksize / 4; i++) for (i = 0; i < blocksize / 4; i++)
sh_mmcif_writel(host->addr, sh_mmcif_writel(host->addr,
MMCIF_CE_DATA, *p++); MMCIF_CE_DATA, *p++);
@ -457,7 +602,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
tmp |= CMD_SET_RTYP_17B; tmp |= CMD_SET_RTYP_17B;
break; break;
default: default:
pr_err(DRIVER_NAME": Not support type response.\n"); dev_err(&host->pd->dev, "Unsupported response type.\n");
break; break;
} }
switch (opc) { switch (opc) {
@ -485,7 +630,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
tmp |= CMD_SET_DATW_8; tmp |= CMD_SET_DATW_8;
break; break;
default: default:
pr_err(DRIVER_NAME": Not support bus width.\n"); dev_err(&host->pd->dev, "Unsupported bus width.\n");
break; break;
} }
} }
@ -513,10 +658,10 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
return opc = ((opc << 24) | tmp); return opc = ((opc << 24) | tmp);
} }
static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host, static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
struct mmc_request *mrq, u32 opc) struct mmc_request *mrq, u32 opc)
{ {
u32 ret; int ret;
switch (opc) { switch (opc) {
case MMC_READ_MULTIPLE_BLOCK: case MMC_READ_MULTIPLE_BLOCK:
@ -533,7 +678,7 @@ static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host,
ret = sh_mmcif_single_read(host, mrq); ret = sh_mmcif_single_read(host, mrq);
break; break;
default: default:
pr_err(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc); dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
@ -547,8 +692,6 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
int ret = 0, mask = 0; int ret = 0, mask = 0;
u32 opc = cmd->opcode; u32 opc = cmd->opcode;
host->cmd = cmd;
switch (opc) { switch (opc) {
/* respons busy check */ /* respons busy check */
case MMC_SWITCH: case MMC_SWITCH:
@ -579,13 +722,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
/* set arg */ /* set arg */
sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
host->wait_int = 0;
/* set cmd */ /* set cmd */
sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->sd_error == 1, host->timeout); host->timeout);
if (host->wait_int != 1 && time == 0) { if (time <= 0) {
cmd->error = sh_mmcif_error_manage(host); cmd->error = sh_mmcif_error_manage(host);
return; return;
} }
@ -597,26 +739,34 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
cmd->error = -ETIMEDOUT; cmd->error = -ETIMEDOUT;
break; break;
default: default:
pr_debug("%s: Cmd(d'%d) err\n", dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n",
DRIVER_NAME, cmd->opcode); cmd->opcode);
cmd->error = sh_mmcif_error_manage(host); cmd->error = sh_mmcif_error_manage(host);
break; break;
} }
host->sd_error = 0; host->sd_error = false;
host->wait_int = 0;
return; return;
} }
if (!(cmd->flags & MMC_RSP_PRESENT)) { if (!(cmd->flags & MMC_RSP_PRESENT)) {
cmd->error = ret; cmd->error = 0;
host->wait_int = 0;
return; return;
} }
if (host->wait_int == 1) { sh_mmcif_get_response(host, cmd);
sh_mmcif_get_response(host, cmd);
host->wait_int = 0;
}
if (host->data) { if (host->data) {
ret = sh_mmcif_data_trans(host, mrq, cmd->opcode); if (!host->dma_sglen) {
ret = sh_mmcif_data_trans(host, mrq, cmd->opcode);
} else {
long time =
wait_for_completion_interruptible_timeout(&host->dma_complete,
host->timeout);
if (!time)
ret = -ETIMEDOUT;
else if (time < 0)
ret = time;
sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
host->dma_sglen = 0;
}
if (ret < 0) if (ret < 0)
mrq->data->bytes_xfered = 0; mrq->data->bytes_xfered = 0;
else else
@ -636,20 +786,18 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
else { else {
pr_err(DRIVER_NAME": not support stop cmd\n"); dev_err(&host->pd->dev, "unsupported stop cmd\n");
cmd->error = sh_mmcif_error_manage(host); cmd->error = sh_mmcif_error_manage(host);
return; return;
} }
time = wait_event_interruptible_timeout(host->intr_wait, time = wait_for_completion_interruptible_timeout(&host->intr_wait,
host->wait_int == 1 || host->timeout);
host->sd_error == 1, host->timeout); if (time <= 0 || host->sd_error) {
if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) {
cmd->error = sh_mmcif_error_manage(host); cmd->error = sh_mmcif_error_manage(host);
return; return;
} }
sh_mmcif_get_cmd12response(host, cmd); sh_mmcif_get_cmd12response(host, cmd);
host->wait_int = 0;
cmd->error = 0; cmd->error = 0;
} }
@ -676,6 +824,15 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
break; break;
} }
host->data = mrq->data; host->data = mrq->data;
if (mrq->data) {
if (mrq->data->flags & MMC_DATA_READ) {
if (host->chan_rx)
sh_mmcif_start_dma_rx(host);
} else {
if (host->chan_tx)
sh_mmcif_start_dma_tx(host);
}
}
sh_mmcif_start_cmd(host, mrq, mrq->cmd); sh_mmcif_start_cmd(host, mrq, mrq->cmd);
host->data = NULL; host->data = NULL;
@ -735,7 +892,7 @@ static void sh_mmcif_detect(struct mmc_host *mmc)
static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
{ {
struct sh_mmcif_host *host = dev_id; struct sh_mmcif_host *host = dev_id;
u32 state = 0; u32 state;
int err = 0; int err = 0;
state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
@ -774,17 +931,19 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
err = 1; err = 1;
} else { } else {
pr_debug("%s: Not support int\n", DRIVER_NAME); dev_dbg(&host->pd->dev, "Not support int\n");
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
err = 1; err = 1;
} }
if (err) { if (err) {
host->sd_error = 1; host->sd_error = true;
pr_debug("%s: int err state = %08x\n", DRIVER_NAME, state); dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
} }
host->wait_int = 1; if (state & ~(INT_CMD12RBE | INT_CMD12CRE))
wake_up(&host->intr_wait); complete(&host->intr_wait);
else
dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -793,8 +952,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
{ {
int ret = 0, irq[2]; int ret = 0, irq[2];
struct mmc_host *mmc; struct mmc_host *mmc;
struct sh_mmcif_host *host = NULL; struct sh_mmcif_host *host;
struct sh_mmcif_plat_data *pd = NULL; struct sh_mmcif_plat_data *pd;
struct resource *res; struct resource *res;
void __iomem *reg; void __iomem *reg;
char clk_name[8]; char clk_name[8];
@ -802,7 +961,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
irq[0] = platform_get_irq(pdev, 0); irq[0] = platform_get_irq(pdev, 0);
irq[1] = platform_get_irq(pdev, 1); irq[1] = platform_get_irq(pdev, 1);
if (irq[0] < 0 || irq[1] < 0) { if (irq[0] < 0 || irq[1] < 0) {
pr_err(DRIVER_NAME": Get irq error\n"); dev_err(&pdev->dev, "Get irq error\n");
return -ENXIO; return -ENXIO;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -815,7 +974,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "ioremap error.\n"); dev_err(&pdev->dev, "ioremap error.\n");
return -ENOMEM; return -ENOMEM;
} }
pd = (struct sh_mmcif_plat_data *)(pdev->dev.platform_data); pd = pdev->dev.platform_data;
if (!pd) { if (!pd) {
dev_err(&pdev->dev, "sh_mmcif plat data error.\n"); dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
ret = -ENXIO; ret = -ENXIO;
@ -842,7 +1001,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
host->clk = clk_get_rate(host->hclk); host->clk = clk_get_rate(host->hclk);
host->pd = pdev; host->pd = pdev;
init_waitqueue_head(&host->intr_wait); init_completion(&host->intr_wait);
mmc->ops = &sh_mmcif_ops; mmc->ops = &sh_mmcif_ops;
mmc->f_max = host->clk; mmc->f_max = host->clk;
@ -858,33 +1017,37 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
mmc->caps = MMC_CAP_MMC_HIGHSPEED; mmc->caps = MMC_CAP_MMC_HIGHSPEED;
if (pd->caps) if (pd->caps)
mmc->caps |= pd->caps; mmc->caps |= pd->caps;
mmc->max_segs = 128; mmc->max_segs = 32;
mmc->max_blk_size = 512; mmc->max_blk_size = 512;
mmc->max_blk_count = 65535; mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
mmc->max_seg_size = mmc->max_req_size; mmc->max_seg_size = mmc->max_req_size;
sh_mmcif_sync_reset(host); sh_mmcif_sync_reset(host);
platform_set_drvdata(pdev, host); platform_set_drvdata(pdev, host);
/* See if we also get DMA */
sh_mmcif_request_dma(host, pd);
mmc_add_host(mmc); mmc_add_host(mmc);
ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host); ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host);
if (ret) { if (ret) {
pr_err(DRIVER_NAME": request_irq error (sh_mmc:error)\n"); dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
goto clean_up2; goto clean_up2;
} }
ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host); ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host);
if (ret) { if (ret) {
free_irq(irq[0], host); free_irq(irq[0], host);
pr_err(DRIVER_NAME": request_irq error (sh_mmc:int)\n"); dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
goto clean_up2; goto clean_up2;
} }
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
sh_mmcif_detect(host->mmc); sh_mmcif_detect(host->mmc);
pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION); dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME, dev_dbg(&pdev->dev, "chip ver H'%04x\n",
sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
return ret; return ret;
@ -903,20 +1066,22 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
struct sh_mmcif_host *host = platform_get_drvdata(pdev); struct sh_mmcif_host *host = platform_get_drvdata(pdev);
int irq[2]; int irq[2];
mmc_remove_host(host->mmc);
sh_mmcif_release_dma(host);
if (host->addr)
iounmap(host->addr);
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
irq[0] = platform_get_irq(pdev, 0); irq[0] = platform_get_irq(pdev, 0);
irq[1] = platform_get_irq(pdev, 1); irq[1] = platform_get_irq(pdev, 1);
if (host->addr)
iounmap(host->addr);
platform_set_drvdata(pdev, NULL);
mmc_remove_host(host->mmc);
free_irq(irq[0], host); free_irq(irq[0], host);
free_irq(irq[1], host); free_irq(irq[1], host);
platform_set_drvdata(pdev, NULL);
clk_disable(host->hclk); clk_disable(host->hclk);
mmc_free_host(host->mmc); mmc_free_host(host->mmc);
@ -947,5 +1112,5 @@ module_exit(sh_mmcif_exit);
MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS(DRIVER_NAME); MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_AUTHOR("Yusuke Goda <yusuke.goda.sx@renesas.com>"); MODULE_AUTHOR("Yusuke Goda <yusuke.goda.sx@renesas.com>");

View File

@ -31,6 +31,7 @@
# define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0
#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \ defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)
@ -244,6 +245,7 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \ defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)
@ -280,6 +282,7 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \ defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)
@ -378,6 +381,7 @@
} }
#if defined(CONFIG_CPU_SH3) || \ #if defined(CONFIG_CPU_SH3) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \ defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)
@ -391,6 +395,7 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) defined(CONFIG_ARCH_SH7377)
#define SCIF_FNS(name, scif_offset, scif_size) \ #define SCIF_FNS(name, scif_offset, scif_size) \
@ -433,6 +438,7 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) defined(CONFIG_ARCH_SH7377)
@ -632,6 +638,7 @@ static inline int sci_rxd_in(struct uart_port *port)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH73A0) || \
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \ defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)

View File

@ -14,8 +14,9 @@
#ifndef __SH_MMCIF_H__ #ifndef __SH_MMCIF_H__
#define __SH_MMCIF_H__ #define __SH_MMCIF_H__
#include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/sh_dma.h>
/* /*
* MMCIF : CE_CLK_CTRL [19:16] * MMCIF : CE_CLK_CTRL [19:16]
@ -31,13 +32,19 @@
* 1111 : Peripheral clock (sup_pclk set '1') * 1111 : Peripheral clock (sup_pclk set '1')
*/ */
struct sh_mmcif_dma {
struct sh_dmae_slave chan_priv_tx;
struct sh_dmae_slave chan_priv_rx;
};
struct sh_mmcif_plat_data { struct sh_mmcif_plat_data {
void (*set_pwr)(struct platform_device *pdev, int state); void (*set_pwr)(struct platform_device *pdev, int state);
void (*down_pwr)(struct platform_device *pdev); void (*down_pwr)(struct platform_device *pdev);
int (*get_cd)(struct platform_device *pdef); int (*get_cd)(struct platform_device *pdef);
u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ struct sh_mmcif_dma *dma;
unsigned long caps; u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */
u32 ocr; unsigned long caps;
u32 ocr;
}; };
#define MMCIF_CE_CMD_SET 0x00000000 #define MMCIF_CE_CMD_SET 0x00000000
@ -59,6 +66,32 @@ struct sh_mmcif_plat_data {
#define MMCIF_CE_HOST_STS2 0x0000004C #define MMCIF_CE_HOST_STS2 0x0000004C
#define MMCIF_CE_VERSION 0x0000007C #define MMCIF_CE_VERSION 0x0000007C
/* CE_BUF_ACC */
#define BUF_ACC_DMAWEN (1 << 25)
#define BUF_ACC_DMAREN (1 << 24)
#define BUF_ACC_BUSW_32 (0 << 17)
#define BUF_ACC_BUSW_16 (1 << 17)
#define BUF_ACC_ATYP (1 << 16)
/* CE_CLK_CTRL */
#define CLK_ENABLE (1 << 24) /* 1: output mmc clock */
#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
#define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
#define CLKDIV_4 (1<<16) /* mmc clock frequency.
* n: bus clock/(2^(n+1)) */
#define CLKDIV_256 (7<<16) /* mmc clock frequency. (see above) */
#define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */
#define SRBSYTO_29 ((1 << 11) | (1 << 10) | \
(1 << 9) | (1 << 8)) /* resp busy timeout */
#define SRWDTO_29 ((1 << 7) | (1 << 6) | \
(1 << 5) | (1 << 4)) /* read/write timeout */
#define SCCSTO_29 ((1 << 3) | (1 << 2) | \
(1 << 1) | (1 << 0)) /* ccs timeout */
/* CE_VERSION */
#define SOFT_RST_ON (1 << 31)
#define SOFT_RST_OFF 0
static inline u32 sh_mmcif_readl(void __iomem *addr, int reg) static inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
{ {
return readl(addr + reg); return readl(addr + reg);
@ -145,21 +178,20 @@ static inline int sh_mmcif_boot_do_read(void __iomem *base,
static inline void sh_mmcif_boot_init(void __iomem *base) static inline void sh_mmcif_boot_init(void __iomem *base)
{ {
unsigned long tmp;
/* reset */ /* reset */
tmp = sh_mmcif_readl(base, MMCIF_CE_VERSION); sh_mmcif_writel(base, MMCIF_CE_VERSION, SOFT_RST_ON);
sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp | 0x80000000); sh_mmcif_writel(base, MMCIF_CE_VERSION, SOFT_RST_OFF);
sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp & ~0x80000000);
/* byte swap */ /* byte swap */
sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, 0x00010000); sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP);
/* Set block size in MMCIF hardware */ /* Set block size in MMCIF hardware */
sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS); sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS);
/* Enable the clock, set it to Bus clock/256 (about 325Khz)*/ /* Enable the clock, set it to Bus clock/256 (about 325Khz). */
sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01072fff); sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL,
CLK_ENABLE | CLKDIV_256 | SRSPTO_256 |
SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
/* CMD0 */ /* CMD0 */
sh_mmcif_boot_cmd(base, 0x00000040, 0); sh_mmcif_boot_cmd(base, 0x00000040, 0);
@ -184,7 +216,9 @@ static inline void sh_mmcif_boot_slurp(void __iomem *base,
unsigned long tmp; unsigned long tmp;
/* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */ /* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */
sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01012fff); sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL,
CLK_ENABLE | CLKDIV_4 | SRSPTO_256 |
SRBSYTO_29 | SRWDTO_29 | SCCSTO_29);
/* CMD9 - Get CSD */ /* CMD9 - Get CSD */
sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000); sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000);