diff options
author | Anton Arapov <anton@redhat.com> | 2012-04-16 10:05:28 +0200 |
---|---|---|
committer | Anton Arapov <anton@redhat.com> | 2012-04-16 10:05:28 +0200 |
commit | b4b6116a13633898cf868f2f103c96a90c4c20f8 (patch) | |
tree | 93d1b7e2cfcdf473d8d4ff3ad141fa864f8491f6 /arch/sh | |
parent | edd4be777c953e5faafc80d091d3084b4343f5d3 (diff) | |
download | kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.gz kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.xz kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.zip |
fedora kernel: d9aad82f3319f3cfd1aebc01234254ef0c37ad84v3.3.2-1
Signed-off-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'arch/sh')
791 files changed, 122918 insertions, 0 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig new file mode 100644 index 00000000000..713fb58ca50 --- /dev/null +++ b/arch/sh/Kconfig @@ -0,0 +1,908 @@ +config SUPERH + def_bool y + select EXPERT + select CLKDEV_LOOKUP + select HAVE_IDE if HAS_IOPORT + select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_NODE_MAP + select HAVE_OPROFILE + select HAVE_GENERIC_DMA_COHERENT + select HAVE_ARCH_TRACEHOOK + select HAVE_DMA_API_DEBUG + select HAVE_DMA_ATTRS + select HAVE_IRQ_WORK + select HAVE_PERF_EVENTS + select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) + select PERF_USE_VMALLOC + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_LZMA + select HAVE_KERNEL_XZ + select HAVE_KERNEL_LZO + select HAVE_SYSCALL_TRACEPOINTS + select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_GENERIC_HARDIRQS + select HAVE_SPARSE_IRQ + select IRQ_FORCED_THREADING + select RTC_LIB + select GENERIC_ATOMIC64 + select GENERIC_IRQ_SHOW + help + The SuperH is a RISC processor targeted for use in embedded systems + and consumer electronics; it was also used in the Sega Dreamcast + gaming console. The SuperH port has a home page at + <http://www.linux-sh.org/>. + +config SUPERH32 + def_bool ARCH = "sh" + select HAVE_KPROBES + select HAVE_KRETPROBES + select HAVE_IOREMAP_PROT if MMU && !X2TLB + select HAVE_FUNCTION_TRACER + select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_DYNAMIC_FTRACE + select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE + select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_ARCH_KGDB + select HAVE_HW_BREAKPOINT + select HAVE_MIXED_BREAKPOINTS_REGS + select PERF_EVENTS + select ARCH_HIBERNATION_POSSIBLE if MMU + select SPARSE_IRQ + +config SUPERH64 + def_bool ARCH = "sh64" + +config ARCH_DEFCONFIG + string + default "arch/sh/configs/shx3_defconfig" if SUPERH32 + default "arch/sh/configs/cayman_defconfig" if SUPERH64 + +config RWSEM_GENERIC_SPINLOCK + def_bool y + +config RWSEM_XCHGADD_ALGORITHM + bool + +config GENERIC_BUG + def_bool y + depends on BUG && SUPERH32 + +config GENERIC_CSUM + def_bool y + depends on SUPERH64 + +config GENERIC_HWEIGHT + def_bool y + +config IRQ_PER_CPU + def_bool y + +config GENERIC_GPIO + def_bool n + +config GENERIC_CALIBRATE_DELAY + bool + +config GENERIC_CLOCKEVENTS + def_bool y + +config GENERIC_CLOCKEVENTS_BROADCAST + bool + +config GENERIC_CMOS_UPDATE + def_bool y + depends on SH_SH03 || SH_DREAMCAST + +config GENERIC_LOCKBREAK + def_bool y + depends on SMP && PREEMPT + +config ARCH_SUSPEND_POSSIBLE + def_bool n + +config ARCH_HIBERNATION_POSSIBLE + def_bool n + +config SYS_SUPPORTS_APM_EMULATION + bool + select ARCH_SUSPEND_POSSIBLE + +config SYS_SUPPORTS_HUGETLBFS + bool + +config SYS_SUPPORTS_SMP + bool + +config SYS_SUPPORTS_NUMA + bool + +config SYS_SUPPORTS_PCI + bool + +config SYS_SUPPORTS_CMT + bool + +config SYS_SUPPORTS_MTU2 + bool + +config SYS_SUPPORTS_TMU + bool + +config STACKTRACE_SUPPORT + def_bool y + +config LOCKDEP_SUPPORT + def_bool y + +config HAVE_LATENCYTOP_SUPPORT + def_bool y + +config ARCH_HAS_ILOG2_U32 + def_bool n + +config ARCH_HAS_ILOG2_U64 + def_bool n + +config ARCH_NO_VIRT_TO_BUS + def_bool y + +config ARCH_HAS_DEFAULT_IDLE + def_bool y + +config ARCH_HAS_CPU_IDLE_WAIT + def_bool y + +config NO_IOPORT + def_bool !PCI + depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN + +config IO_TRAPPED + bool + +config DMA_COHERENT + bool + +config DMA_NONCOHERENT + def_bool !DMA_COHERENT + +config NEED_DMA_MAP_STATE + def_bool DMA_NONCOHERENT + +config NEED_SG_DMA_LENGTH + def_bool y + +source "init/Kconfig" + +source "kernel/Kconfig.freezer" + +menu "System type" + +# +# Processor families +# +config CPU_SH2 + bool + +config CPU_SH2A + bool + select CPU_SH2 + select UNCACHED_MAPPING + +config CPU_SH3 + bool + select CPU_HAS_INTEVT + select CPU_HAS_SR_RB + select SYS_SUPPORTS_TMU + +config CPU_SH4 + bool + select CPU_HAS_INTEVT + select CPU_HAS_SR_RB + select CPU_HAS_FPU if !CPU_SH4AL_DSP + select SYS_SUPPORTS_TMU + select SYS_SUPPORTS_HUGETLBFS if MMU + +config CPU_SH4A + bool + select CPU_SH4 + +config CPU_SH4AL_DSP + bool + select CPU_SH4A + select CPU_HAS_DSP + +config CPU_SH5 + bool + select CPU_HAS_FPU + select SYS_SUPPORTS_TMU + select SYS_SUPPORTS_HUGETLBFS if MMU + +config CPU_SHX2 + bool + +config CPU_SHX3 + bool + select DMA_COHERENT + select SYS_SUPPORTS_SMP + select SYS_SUPPORTS_NUMA + +config ARCH_SHMOBILE + bool + select ARCH_SUSPEND_POSSIBLE + select PM + select PM_RUNTIME + +config CPU_HAS_PMU + depends on CPU_SH4 || CPU_SH4A + default y + bool + +if SUPERH32 + +choice + prompt "Processor sub-type selection" + +# +# Processor subtypes +# + +# SH-2 Processor Support + +config CPU_SUBTYPE_SH7619 + bool "Support SH7619 processor" + select CPU_SH2 + select SYS_SUPPORTS_CMT + +# SH-2A Processor Support + +config CPU_SUBTYPE_SH7201 + bool "Support SH7201 processor" + select CPU_SH2A + select CPU_HAS_FPU + select SYS_SUPPORTS_MTU2 + +config CPU_SUBTYPE_SH7203 + bool "Support SH7203 processor" + select CPU_SH2A + select CPU_HAS_FPU + select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_MTU2 + select ARCH_WANT_OPTIONAL_GPIOLIB + +config CPU_SUBTYPE_SH7206 + bool "Support SH7206 processor" + select CPU_SH2A + select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_MTU2 + +config CPU_SUBTYPE_SH7263 + bool "Support SH7263 processor" + select CPU_SH2A + select CPU_HAS_FPU + select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_MTU2 + +config CPU_SUBTYPE_MXG + bool "Support MX-G processor" + select CPU_SH2A + select SYS_SUPPORTS_MTU2 + help + Select MX-G if running on an R8A03022BG part. + +# SH-3 Processor Support + +config CPU_SUBTYPE_SH7705 + bool "Support SH7705 processor" + select CPU_SH3 + +config CPU_SUBTYPE_SH7706 + bool "Support SH7706 processor" + select CPU_SH3 + help + Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU. + +config CPU_SUBTYPE_SH7707 + bool "Support SH7707 processor" + select CPU_SH3 + help + Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU. + +config CPU_SUBTYPE_SH7708 + bool "Support SH7708 processor" + select CPU_SH3 + help + Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or + if you have a 100 Mhz SH-3 HD6417708R CPU. + +config CPU_SUBTYPE_SH7709 + bool "Support SH7709 processor" + select CPU_SH3 + help + Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. + +config CPU_SUBTYPE_SH7710 + bool "Support SH7710 processor" + select CPU_SH3 + select CPU_HAS_DSP + help + Select SH7710 if you have a SH3-DSP SH7710 CPU. + +config CPU_SUBTYPE_SH7712 + bool "Support SH7712 processor" + select CPU_SH3 + select CPU_HAS_DSP + help + Select SH7712 if you have a SH3-DSP SH7712 CPU. + +config CPU_SUBTYPE_SH7720 + bool "Support SH7720 processor" + select CPU_SH3 + select CPU_HAS_DSP + select SYS_SUPPORTS_CMT + select ARCH_WANT_OPTIONAL_GPIOLIB + select USB_ARCH_HAS_OHCI + select USB_OHCI_SH if USB_OHCI_HCD + help + Select SH7720 if you have a SH3-DSP SH7720 CPU. + +config CPU_SUBTYPE_SH7721 + bool "Support SH7721 processor" + select CPU_SH3 + select CPU_HAS_DSP + select SYS_SUPPORTS_CMT + select USB_ARCH_HAS_OHCI + select USB_OHCI_SH if USB_OHCI_HCD + help + Select SH7721 if you have a SH3-DSP SH7721 CPU. + +# SH-4 Processor Support + +config CPU_SUBTYPE_SH7750 + bool "Support SH7750 processor" + select CPU_SH4 + help + Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. + +config CPU_SUBTYPE_SH7091 + bool "Support SH7091 processor" + select CPU_SH4 + help + Select SH7091 if you have an SH-4 based Sega device (such as + the Dreamcast, Naomi, and Naomi 2). + +config CPU_SUBTYPE_SH7750R + bool "Support SH7750R processor" + select CPU_SH4 + +config CPU_SUBTYPE_SH7750S + bool "Support SH7750S processor" + select CPU_SH4 + +config CPU_SUBTYPE_SH7751 + bool "Support SH7751 processor" + select CPU_SH4 + help + Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, + or if you have a HD6417751R CPU. + +config CPU_SUBTYPE_SH7751R + bool "Support SH7751R processor" + select CPU_SH4 + +config CPU_SUBTYPE_SH7760 + bool "Support SH7760 processor" + select CPU_SH4 + +config CPU_SUBTYPE_SH4_202 + bool "Support SH4-202 processor" + select CPU_SH4 + +# SH-4A Processor Support + +config CPU_SUBTYPE_SH7723 + bool "Support SH7723 processor" + select CPU_SH4A + select CPU_SHX2 + select ARCH_SHMOBILE + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_CMT + select ARCH_WANT_OPTIONAL_GPIOLIB + help + Select SH7723 if you have an SH-MobileR2 CPU. + +config CPU_SUBTYPE_SH7724 + bool "Support SH7724 processor" + select CPU_SH4A + select CPU_SHX2 + select ARCH_SHMOBILE + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_CMT + select ARCH_WANT_OPTIONAL_GPIOLIB + help + Select SH7724 if you have an SH-MobileR2R CPU. + +config CPU_SUBTYPE_SH7757 + bool "Support SH7757 processor" + select CPU_SH4A + select CPU_SHX2 + select ARCH_WANT_OPTIONAL_GPIOLIB + select USB_ARCH_HAS_OHCI + select USB_ARCH_HAS_EHCI + help + Select SH7757 if you have a SH4A SH7757 CPU. + +config CPU_SUBTYPE_SH7763 + bool "Support SH7763 processor" + select CPU_SH4A + select USB_ARCH_HAS_OHCI + select USB_OHCI_SH if USB_OHCI_HCD + help + Select SH7763 if you have a SH4A SH7763(R5S77631) CPU. + +config CPU_SUBTYPE_SH7770 + bool "Support SH7770 processor" + select CPU_SH4A + +config CPU_SUBTYPE_SH7780 + bool "Support SH7780 processor" + select CPU_SH4A + +config CPU_SUBTYPE_SH7785 + bool "Support SH7785 processor" + select CPU_SH4A + select CPU_SHX2 + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA + select ARCH_WANT_OPTIONAL_GPIOLIB + +config CPU_SUBTYPE_SH7786 + bool "Support SH7786 processor" + select CPU_SH4A + select CPU_SHX3 + select CPU_HAS_PTEAEX + select GENERIC_CLOCKEVENTS_BROADCAST if SMP + select ARCH_WANT_OPTIONAL_GPIOLIB + select USB_ARCH_HAS_OHCI + select USB_OHCI_SH if USB_OHCI_HCD + select USB_ARCH_HAS_EHCI + select USB_EHCI_SH if USB_EHCI_HCD + +config CPU_SUBTYPE_SHX3 + bool "Support SH-X3 processor" + select CPU_SH4A + select CPU_SHX3 + select GENERIC_CLOCKEVENTS_BROADCAST if SMP + select ARCH_REQUIRE_GPIOLIB + +# SH4AL-DSP Processor Support + +config CPU_SUBTYPE_SH7343 + bool "Support SH7343 processor" + select CPU_SH4AL_DSP + select ARCH_SHMOBILE + select SYS_SUPPORTS_CMT + +config CPU_SUBTYPE_SH7722 + bool "Support SH7722 processor" + select CPU_SH4AL_DSP + select CPU_SHX2 + select ARCH_SHMOBILE + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA + select SYS_SUPPORTS_CMT + select ARCH_WANT_OPTIONAL_GPIOLIB + +config CPU_SUBTYPE_SH7366 + bool "Support SH7366 processor" + select CPU_SH4AL_DSP + select CPU_SHX2 + select ARCH_SHMOBILE + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_NUMA + select SYS_SUPPORTS_CMT + +endchoice + +endif + +if SUPERH64 + +choice + prompt "Processor sub-type selection" + +# SH-5 Processor Support + +config CPU_SUBTYPE_SH5_101 + bool "Support SH5-101 processor" + select CPU_SH5 + +config CPU_SUBTYPE_SH5_103 + bool "Support SH5-103 processor" + select CPU_SH5 + +endchoice + +endif + +source "arch/sh/mm/Kconfig" + +source "arch/sh/Kconfig.cpu" + +source "arch/sh/boards/Kconfig" + +menu "Timer and clock configuration" + +config SH_TIMER_TMU + bool "TMU timer driver" + depends on SYS_SUPPORTS_TMU + default y + help + This enables the build of the TMU timer driver. + +config SH_TIMER_CMT + bool "CMT timer driver" + depends on SYS_SUPPORTS_CMT + default y + help + This enables build of the CMT timer driver. + +config SH_TIMER_MTU2 + bool "MTU2 timer driver" + depends on SYS_SUPPORTS_MTU2 + default y + help + This enables build of the MTU2 timer driver. + +config SH_PCLK_FREQ + int "Peripheral clock frequency (in Hz)" + depends on SH_CLK_CPG_LEGACY + default "31250000" if CPU_SUBTYPE_SH7619 + default "33333333" if CPU_SUBTYPE_SH7770 || \ + CPU_SUBTYPE_SH7760 || \ + CPU_SUBTYPE_SH7705 || \ + CPU_SUBTYPE_SH7203 || \ + CPU_SUBTYPE_SH7206 || \ + CPU_SUBTYPE_SH7263 || \ + CPU_SUBTYPE_MXG + default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R + default "66000000" if CPU_SUBTYPE_SH4_202 + default "50000000" + help + This option is used to specify the peripheral clock frequency. + This is necessary for determining the reference clock value on + platforms lacking an RTC. + +config SH_CLK_CPG + def_bool y + +config SH_CLK_CPG_LEGACY + depends on SH_CLK_CPG + def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \ + !CPU_SHX3 && !CPU_SUBTYPE_SH7757 + +source "kernel/time/Kconfig" + +endmenu + +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +config SH_CPU_FREQ + tristate "SuperH CPU Frequency driver" + depends on CPU_FREQ + select CPU_FREQ_TABLE + help + This adds the cpufreq driver for SuperH. Any CPU that supports + clock rate rounding through the clock framework can use this + driver. While it will make the kernel slightly larger, this is + harmless for CPUs that don't support rate rounding. The driver + will also generate a notice in the boot log before disabling + itself if the CPU in question is not capable of rate rounding. + + For details, take a look at <file:Documentation/cpu-freq>. + + If unsure, say N. + +endmenu + +source "arch/sh/drivers/Kconfig" + +endmenu + +menu "Kernel features" + +source kernel/Kconfig.hz + +config KEXEC + bool "kexec system call (EXPERIMENTAL)" + depends on SUPERH32 && EXPERIMENTAL && MMU + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is independent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + +config CRASH_DUMP + bool "kernel crash dumps (EXPERIMENTAL)" + depends on SUPERH32 && EXPERIMENTAL && BROKEN_ON_SMP + help + Generate crash dump after being started by kexec. + This should be normally only set in special crash dump kernels + which are loaded in the main kernel with kexec-tools into + a specially reserved region and then later executed after + a crash by kdump/kexec. The crash dump kernel must be compiled + to a memory address not used by the main kernel using + PHYSICAL_START. + + For more details see Documentation/kdump/kdump.txt + +config KEXEC_JUMP + bool "kexec jump (EXPERIMENTAL)" + depends on SUPERH32 && KEXEC && HIBERNATION && EXPERIMENTAL + help + Jump between original kernel and kexeced kernel and invoke + code via KEXEC + +config PHYSICAL_START + hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP) + default MEMORY_START + ---help--- + This gives the physical address where the kernel is loaded + and is ordinarily the same as MEMORY_START. + + Different values are primarily used in the case of kexec on panic + where the fail safe kernel needs to run at a different address + than the panic-ed kernel. + +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via prctl, it cannot be disabled and the task is only + allowed to execute a few safe syscalls defined by each seccomp + mode. + + If unsure, say N. + +config SMP + bool "Symmetric multi-processing support" + depends on SYS_SUPPORTS_SMP + select USE_GENERIC_SMP_HELPERS + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + People using multiprocessor machines who say Y here should also say + Y to "Enhanced Real Time Clock Support", below. + + See also <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO + available at <http://www.tldp.org/docs.html#howto>. + + If you don't know what to do here, say N. + +config NR_CPUS + int "Maximum number of CPUs (2-32)" + range 2 32 + depends on SMP + default "4" if CPU_SUBTYPE_SHX3 + default "2" + help + This allows you to specify the maximum number of CPUs which this + kernel will support. The maximum supported value is 32 and the + minimum value which makes sense is 2. + + This is purely to save memory - each supported CPU adds + approximately eight kilobytes to the kernel image. + +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" + depends on SMP && HOTPLUG && EXPERIMENTAL + help + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + +source "kernel/Kconfig.preempt" + +config GUSA + def_bool y + depends on !SMP && SUPERH32 + help + This enables support for gUSA (general UserSpace Atomicity). + This is the default implementation for both UP and non-ll/sc + CPUs, and is used by the libc, amongst others. + + For additional information, design information can be found + in <http://lc.linux.or.jp/lc2002/papers/niibe0919p.pdf>. + + This should only be disabled for special cases where alternate + atomicity implementations exist. + +config GUSA_RB + bool "Implement atomic operations by roll-back (gRB) (EXPERIMENTAL)" + depends on GUSA && CPU_SH3 || (CPU_SH4 && !CPU_SH4A) + help + Enabling this option will allow the kernel to implement some + atomic operations using a software implementation of load-locked/ + store-conditional (LLSC). On machines which do not have hardware + LLSC, this should be more efficient than the other alternative of + disabling interrupts around the atomic sequence. + +config HW_PERF_EVENTS + bool "Enable hardware performance counter support for perf events" + depends on PERF_EVENTS && CPU_HAS_PMU + default y + help + Enable hardware performance counter support for perf events. If + disabled, perf events will use software events only. + +source "drivers/sh/Kconfig" + +endmenu + +menu "Boot options" + +config ZERO_PAGE_OFFSET + hex + default "0x00010000" if PAGE_SIZE_64KB || SH_RTS7751R2D || \ + SH_7751_SOLUTION_ENGINE + default "0x00004000" if PAGE_SIZE_16KB || SH_SH03 + default "0x00002000" if PAGE_SIZE_8KB + default "0x00001000" + help + This sets the default offset of zero page. + +config BOOT_LINK_OFFSET + hex + default "0x00210000" if SH_SHMIN + default "0x00400000" if SH_CAYMAN + default "0x00810000" if SH_7780_SOLUTION_ENGINE + default "0x009e0000" if SH_TITAN + default "0x01800000" if SH_SDK7780 + default "0x02000000" if SH_EDOSK7760 + default "0x00800000" + help + This option allows you to set the link address offset of the zImage. + This can be useful if you are on a board which has a small amount of + memory. + +config ENTRY_OFFSET + hex + default "0x00001000" if PAGE_SIZE_4KB + default "0x00002000" if PAGE_SIZE_8KB + default "0x00004000" if PAGE_SIZE_16KB + default "0x00010000" if PAGE_SIZE_64KB + default "0x00000000" + +config ROMIMAGE_MMCIF + bool "Include MMCIF loader in romImage (EXPERIMENTAL)" + depends on CPU_SUBTYPE_SH7724 && EXPERIMENTAL + help + Say Y here to include experimental MMCIF loading code in + romImage. With this enabled it is possible to write the romImage + kernel image to an MMC card and boot the kernel straight from + the reset vector. At reset the processor Mask ROM will load the + first part of the romImage which in turn loads the rest the kernel + image to RAM using the MMCIF hardware block. + +choice + prompt "Kernel command line" + optional + default CMDLINE_OVERWRITE + help + Setting this option allows the kernel command line arguments + to be set. + +config CMDLINE_OVERWRITE + bool "Overwrite bootloader kernel arguments" + help + Given string will overwrite any arguments passed in by + a bootloader. + +config CMDLINE_EXTEND + bool "Extend bootloader kernel arguments" + help + Given string will be concatenated with arguments passed in + by a bootloader. + +endchoice + +config CMDLINE + string "Kernel command line arguments string" + depends on CMDLINE_OVERWRITE || CMDLINE_EXTEND + default "console=ttySC1,115200" + +endmenu + +menu "Bus options" + +config SUPERHYWAY + tristate "SuperHyway Bus support" + depends on CPU_SUBTYPE_SH4_202 + +config MAPLE + bool "Maple Bus support" + depends on SH_DREAMCAST + help + The Maple Bus is SEGA's serial communication bus for peripherals + on the Dreamcast. Without this bus support you won't be able to + get your Dreamcast keyboard etc to work, so most users + probably want to say 'Y' here, unless you are only using the + Dreamcast with a serial line terminal or a remote network + connection. + +config PCI + bool "PCI support" + depends on SYS_SUPPORTS_PCI + select PCI_DOMAINS + select GENERIC_PCI_IOMAP + select NO_GENERIC_PCI_IOPORT_MAP + help + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside + your box. If you have PCI, say Y, otherwise N. + +config PCI_DOMAINS + bool + +source "drivers/pci/pcie/Kconfig" + +source "drivers/pci/Kconfig" + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + +endmenu + +menu "Executable file formats" + +source "fs/Kconfig.binfmt" + +endmenu + +menu "Power management options (EXPERIMENTAL)" +depends on EXPERIMENTAL + +source "kernel/power/Kconfig" + +source "drivers/cpuidle/Kconfig" + +endmenu + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +source "arch/sh/Kconfig.debug" + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu new file mode 100644 index 00000000000..ddf096c7d8b --- /dev/null +++ b/arch/sh/Kconfig.cpu @@ -0,0 +1,109 @@ +menu "Processor features" + +choice + prompt "Endianess selection" + default CPU_LITTLE_ENDIAN + help + Some SuperH machines can be configured for either little or big + endian byte order. These modes require different kernels. + +config CPU_LITTLE_ENDIAN + bool "Little Endian" + +config CPU_BIG_ENDIAN + bool "Big Endian" + depends on !CPU_SH5 + +endchoice + +config SH_FPU + def_bool y + prompt "FPU support" + depends on CPU_HAS_FPU + help + Selecting this option will enable support for SH processors that + have FPU units (ie, SH77xx). + + This option must be set in order to enable the FPU. + +config SH64_FPU_DENORM_FLUSH + bool "Flush floating point denorms to zero" + depends on SH_FPU && SUPERH64 + +config SH_FPU_EMU + def_bool n + prompt "FPU emulation support" + depends on !SH_FPU && EXPERIMENTAL + help + Selecting this option will enable support for software FPU emulation. + Most SH-3 users will want to say Y here, whereas most SH-4 users will + want to say N. + +config SH_DSP + def_bool y + prompt "DSP support" + depends on CPU_HAS_DSP + help + Selecting this option will enable support for SH processors that + have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP). + + This option must be set in order to enable the DSP. + +config SH_ADC + def_bool y + prompt "ADC support" + depends on CPU_SH3 + help + Selecting this option will allow the Linux kernel to use SH3 on-chip + ADC module. + + If unsure, say N. + +config SH_STORE_QUEUES + bool "Support for Store Queues" + depends on CPU_SH4 + help + Selecting this option will enable an in-kernel API for manipulating + the store queues integrated in the SH-4 processors. + +config SPECULATIVE_EXECUTION + bool "Speculative subroutine return" + depends on EXPERIMENTAL + depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7786 + help + This enables support for a speculative instruction fetch for + subroutine return. There are various pitfalls associated with + this, as outlined in the SH7780 hardware manual. + + If unsure, say N. + +config SH64_ID2815_WORKAROUND + bool "Include workaround for SH5-101 cut2 silicon defect ID2815" + depends on CPU_SUBTYPE_SH5_101 + +config CPU_HAS_INTEVT + bool + +config CPU_HAS_IPR_IRQ + bool + +config CPU_HAS_SR_RB + bool + help + This will enable the use of SR.RB register bank usage. Processors + that are lacking this bit must have another method in place for + accomplishing what is taken care of by the banked registers. + + See <file:Documentation/sh/register-banks.txt> for further + information on SR.RB and register banking in the kernel in general. + +config CPU_HAS_PTEAEX + bool + +config CPU_HAS_DSP + bool + +config CPU_HAS_FPU + bool + +endmenu diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug new file mode 100644 index 00000000000..c1d5a820b1a --- /dev/null +++ b/arch/sh/Kconfig.debug @@ -0,0 +1,90 @@ +menu "Kernel hacking" + +config TRACE_IRQFLAGS_SUPPORT + def_bool y + +source "lib/Kconfig.debug" + +config SH_STANDARD_BIOS + bool "Use LinuxSH standard BIOS" + depends on SUPERH32 + help + Say Y here if your target has the gdb-sh-stub + package from www.m17n.org (or any conforming standard LinuxSH BIOS) + in FLASH or EPROM. The kernel will use standard BIOS calls during + boot for various housekeeping tasks (including calls to read and + write characters to a system console, get a MAC address from an + on-board Ethernet interface, and shut down the hardware). Note this + does not work with machines with an existing operating system in + mask ROM and no flash (WindowsCE machines fall in this category). + If unsure, say N. + +config STACK_DEBUG + bool "Check for stack overflows" + depends on DEBUG_KERNEL && SUPERH32 + help + This option will cause messages to be printed if free stack space + drops below a certain limit. Saying Y here will add overhead to + every function call and will therefore incur a major + performance hit. Most users should say N. + +config 4KSTACKS + bool "Use 4Kb for kernel stacks instead of 8Kb" + depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB + help + If you say Y here the kernel will use a 4Kb stacksize for the + kernel stack attached to each process/thread. This facilitates + running more threads on a system and also reduces the pressure + on the VM subsystem for higher order allocations. This option + will also use IRQ stacks to compensate for the reduced stackspace. + +config IRQSTACKS + bool "Use separate kernel stacks when processing interrupts" + depends on DEBUG_KERNEL && SUPERH32 && BROKEN + help + If you say Y here the kernel will use separate kernel stacks + for handling hard and soft interrupts. This can help avoid + overflowing the process kernel stacks. + +config DUMP_CODE + bool "Show disassembly of nearby code in register dumps" + depends on DEBUG_KERNEL && SUPERH32 + default y if DEBUG_BUGVERBOSE + default n + help + This prints out a code trace of the instructions leading up to + the faulting instruction as a debugging aid. As this does grow + the kernel in size a bit, most users will want to say N here. + + Those looking for more verbose debugging output should say Y. + +config DWARF_UNWINDER + bool "Enable the DWARF unwinder for stacktraces" + select FRAME_POINTER + default n + help + Enabling this option will make stacktraces more accurate, at + the cost of an increase in overall kernel size. + +config SH_NO_BSS_INIT + bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)" + depends on DEBUG_KERNEL + default n + help + If running in painfully slow environments, such as an RTL + simulation or from remote memory via SHdebug, where the memory + can already be guaranteed to ber zeroed on boot, say Y. + + For all other cases, say N. If this option seems perplexing, or + you aren't sure, say N. + +config SH64_SR_WATCH + bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" + depends on SUPERH64 + +config MCOUNT + def_bool y + depends on SUPERH32 + depends on STACK_DEBUG || FUNCTION_TRACER + +endmenu diff --git a/arch/sh/Makefile b/arch/sh/Makefile new file mode 100644 index 00000000000..3fc0f413777 --- /dev/null +++ b/arch/sh/Makefile @@ -0,0 +1,237 @@ +# +# arch/sh/Makefile +# +# Copyright (C) 1999 Kaz Kojima +# Copyright (C) 2002 - 2008 Paul Mundt +# Copyright (C) 2002 M. R. Brown +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +isa-y := any +isa-$(CONFIG_SH_DSP) := sh +isa-$(CONFIG_CPU_SH2) := sh2 +isa-$(CONFIG_CPU_SH2A) := sh2a +isa-$(CONFIG_CPU_SH3) := sh3 +isa-$(CONFIG_CPU_SH4) := sh4 +isa-$(CONFIG_CPU_SH4A) := sh4a +isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al +isa-$(CONFIG_CPU_SH5) := shmedia + +ifeq ($(CONFIG_SUPERH32),y) +isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp +isa-y := $(isa-y)-up +endif + +cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) +cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ + $(call cc-option,-m2a-nofpu,) +cflags-$(CONFIG_CPU_SH3) := $(call cc-option,-m3,) +cflags-$(CONFIG_CPU_SH4) := $(call cc-option,-m4,) \ + $(call cc-option,-mno-implicit-fp,-m4-nofpu) +cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a,) \ + $(call cc-option,-m4a-nofpu,) +cflags-$(CONFIG_CPU_SH4AL_DSP) += $(call cc-option,-m4al,) +cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,) + +ifeq ($(cflags-y),) +# +# In the case where we are stuck with a compiler that has been uselessly +# restricted to a particular ISA, a favourite default of newer GCCs when +# extensive multilib targets are not provided, ensure we get the best fit +# regarding FP generation. This is intentionally stupid (albeit many +# orders of magnitude less than GCC's default behaviour), as anything +# with a large number of multilib targets better have been built +# correctly for the target in mind. +# +cflags-y += $(shell $(CC) $(KBUILD_CFLAGS) -print-multi-lib | \ + grep nofpu | sed q | sed -e 's/^/-/;s/;.*$$//') +# At this point, anything goes. +isaflags-y := $(call as-option,-Wa$(comma)-isa=any,) +else +# +# -Wa,-isa= tuning implies -Wa,-dsp for the versions of binutils that +# support it, while -Wa,-dsp by itself limits the range of usable opcodes +# on certain CPU subtypes. Try the ISA variant first, and if that fails, +# fall back on -Wa,-dsp for the old binutils versions. Even without DSP +# opcodes, we always want the best ISA tuning the version of binutils +# will provide. +# +isaflags-y := $(call as-option,-Wa$(comma)-isa=$(isa-y),) + +isaflags-$(CONFIG_SH_DSP) := \ + $(call as-option,-Wa$(comma)-isa=$(isa-y),-Wa$(comma)-dsp) +endif + +cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb +cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml + +cflags-y += $(call cc-option,-mno-fdpic) +cflags-y += $(isaflags-y) -ffreestanding + +OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment \ + -R .stab -R .stabstr -S + +# Give the various platforms the opportunity to set default image types +defaultimage-$(CONFIG_SUPERH32) := zImage +defaultimage-$(CONFIG_SH_SH7785LCR) := uImage +defaultimage-$(CONFIG_SH_RSK) := uImage +defaultimage-$(CONFIG_SH_URQUELL) := uImage +defaultimage-$(CONFIG_SH_MIGOR) := uImage +defaultimage-$(CONFIG_SH_AP325RXA) := uImage +defaultimage-$(CONFIG_SH_SH7757LCR) := uImage +defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE) := uImage +defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux +defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux + +# Set some sensible Kbuild defaults +KBUILD_IMAGE := $(defaultimage-y) + +# +# Choosing incompatible machines durings configuration will result in +# error messages during linking. +# +ifdef CONFIG_SUPERH32 +UTS_MACHINE := sh +BITS := 32 +LDFLAGS_vmlinux += -e _stext +KBUILD_DEFCONFIG := shx3_defconfig +else +UTS_MACHINE := sh64 +BITS := 64 +LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \ + --defsym phys_stext_shmedia=phys_stext+1 \ + -e phys_stext_shmedia +KBUILD_DEFCONFIG := cayman_defconfig +endif + +ifneq ($(SUBARCH),$(ARCH)) + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := $(call cc-cross-prefix, $(UTS_MACHINE)-linux- $(UTS_MACHINE)-linux-gnu- $(UTS_MACHINE)-unknown-linux-gnu-) + endif +endif + +ifdef CONFIG_CPU_LITTLE_ENDIAN +ld-bfd := elf32-$(UTS_MACHINE)-linux +LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' --oformat $(ld-bfd) +LDFLAGS += -EL +else +ld-bfd := elf32-$(UTS_MACHINE)big-linux +LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4' --oformat $(ld-bfd) +LDFLAGS += -EB +endif + +export ld-bfd BITS + +head-y := arch/sh/kernel/init_task.o arch/sh/kernel/head_$(BITS).o + +core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/ +core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ + +# Mach groups +machdir-$(CONFIG_SOLUTION_ENGINE) += mach-se +machdir-$(CONFIG_SH_HP6XX) += mach-hp6xx +machdir-$(CONFIG_SH_DREAMCAST) += mach-dreamcast +machdir-$(CONFIG_SH_SH03) += mach-sh03 +machdir-$(CONFIG_SH_RTS7751R2D) += mach-r2d +machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander +machdir-$(CONFIG_SH_MIGOR) += mach-migor +machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa +machdir-$(CONFIG_SH_KFR2R09) += mach-kfr2r09 +machdir-$(CONFIG_SH_ECOVEC) += mach-ecovec24 +machdir-$(CONFIG_SH_SDK7780) += mach-sdk7780 +machdir-$(CONFIG_SH_SDK7786) += mach-sdk7786 +machdir-$(CONFIG_SH_X3PROTO) += mach-x3proto +machdir-$(CONFIG_SH_SH7763RDP) += mach-sh7763rdp +machdir-$(CONFIG_SH_SH4202_MICRODEV) += mach-microdev +machdir-$(CONFIG_SH_LANDISK) += mach-landisk +machdir-$(CONFIG_SH_LBOX_RE2) += mach-lboxre2 +machdir-$(CONFIG_SH_CAYMAN) += mach-cayman +machdir-$(CONFIG_SH_RSK) += mach-rsk + +ifneq ($(machdir-y),) +core-y += $(addprefix arch/sh/boards/, \ + $(filter-out ., $(patsubst %,%/,$(machdir-y)))) +endif + +# Common machine type headers. Not part of the arch/sh/boards/ hierarchy. +machdir-y += mach-common + +# Companion chips +core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/ + +# +# CPU header paths +# +# These are ordered by optimization level. A CPU family that is a subset +# of another (ie, SH-2A / SH-2), is picked up first, with increasing +# levels of genericness if nothing more suitable is situated in the +# hierarchy. +# +# As an example, in order of preference, SH-2A > SH-2 > common definitions. +# +cpuincdir-$(CONFIG_CPU_SH2A) += cpu-sh2a +cpuincdir-$(CONFIG_CPU_SH2) += cpu-sh2 +cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3 +cpuincdir-$(CONFIG_CPU_SH4A) += cpu-sh4a +cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4 +cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5 +cpuincdir-y += cpu-common # Must be last + +drivers-y += arch/sh/drivers/ +drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/ + +boot := arch/sh/boot + +cflags-y += $(foreach d, $(cpuincdir-y), -Iarch/sh/include/$(d)) \ + $(foreach d, $(machdir-y), -Iarch/sh/include/$(d)) + +KBUILD_CFLAGS += -pipe $(cflags-y) +KBUILD_CPPFLAGS += $(cflags-y) +KBUILD_AFLAGS += $(cflags-y) + +ifeq ($(CONFIG_MCOUNT),y) + KBUILD_CFLAGS += -pg +endif + +ifeq ($(CONFIG_DWARF_UNWINDER),y) + KBUILD_CFLAGS += -fasynchronous-unwind-tables +endif + +libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) +libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) + +BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \ + uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \ + romImage +PHONY += $(BOOT_TARGETS) + +all: $(KBUILD_IMAGE) + +$(BOOT_TARGETS): vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + +compressed: zImage + +archprepare: + $(Q)$(MAKE) $(build)=arch/sh/tools include/generated/machtypes.h + +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + $(Q)$(MAKE) $(clean)=arch/sh/kernel/vsyscall + +define archhelp + @echo ' zImage - Compressed kernel image' + @echo ' romImage - Compressed ROM image, if supported' + @echo ' vmlinux.srec - Create an ELF S-record' + @echo ' vmlinux.bin - Create an uncompressed binary image' + @echo '* uImage - Alias to bootable U-Boot image' + @echo ' uImage.srec - Create an S-record for U-Boot' + @echo ' uImage.bin - Kernel-only image for U-Boot (bin)' + @echo '* uImage.gz - Kernel-only image for U-Boot (gzip)' + @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)' + @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)' + @echo ' uImage.xz - Kernel-only image for U-Boot (xz)' + @echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)' +endef diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig new file mode 100644 index 00000000000..d893411022d --- /dev/null +++ b/arch/sh/boards/Kconfig @@ -0,0 +1,361 @@ +menu "Board support" + +config SOLUTION_ENGINE + bool + +config SH_ALPHA_BOARD + bool + +config SH_SOLUTION_ENGINE + bool "SolutionEngine" + select SOLUTION_ENGINE + select CPU_HAS_IPR_IRQ + depends on CPU_SUBTYPE_SH7705 || CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7710 || \ + CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7750S || \ + CPU_SUBTYPE_SH7750R + help + Select SolutionEngine if configuring for a Hitachi SH7705, SH7709, + SH7710, SH7712, SH7750, SH7750S or SH7750R evaluation board. + +config SH_7206_SOLUTION_ENGINE + bool "SolutionEngine7206" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7206 + help + Select 7206 SolutionEngine if configuring for a Hitachi SH7206 + evaluation board. + +config SH_7619_SOLUTION_ENGINE + bool "SolutionEngine7619" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7619 + help + Select 7619 SolutionEngine if configuring for a Hitachi SH7619 + evaluation board. + +config SH_7721_SOLUTION_ENGINE + bool "SolutionEngine7721" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7721 + help + Select 7721 SolutionEngine if configuring for a Hitachi SH7721 + evaluation board. + +config SH_7722_SOLUTION_ENGINE + bool "SolutionEngine7722" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7722 + help + Select 7722 SolutionEngine if configuring for a Hitachi SH772 + evaluation board. + +config SH_7724_SOLUTION_ENGINE + bool "SolutionEngine7724" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7724 + select ARCH_REQUIRE_GPIOLIB + help + Select 7724 SolutionEngine if configuring for a Hitachi SH7724 + evaluation board. + +config SH_7751_SOLUTION_ENGINE + bool "SolutionEngine7751" + select SOLUTION_ENGINE + select CPU_HAS_IPR_IRQ + depends on CPU_SUBTYPE_SH7751 + help + Select 7751 SolutionEngine if configuring for a Hitachi SH7751 + evaluation board. + +config SH_7780_SOLUTION_ENGINE + bool "SolutionEngine7780" + select SOLUTION_ENGINE + select SYS_SUPPORTS_PCI + depends on CPU_SUBTYPE_SH7780 + help + Select 7780 SolutionEngine if configuring for a Renesas SH7780 + evaluation board. + +config SH_7343_SOLUTION_ENGINE + bool "SolutionEngine7343" + select SOLUTION_ENGINE + depends on CPU_SUBTYPE_SH7343 + help + Select 7343 SolutionEngine if configuring for a Hitachi + SH7343 (SH-Mobile 3AS) evaluation board. + +config SH_HP6XX + bool "HP6XX" + select SYS_SUPPORTS_APM_EMULATION + select HD6446X_SERIES + depends on CPU_SUBTYPE_SH7709 + help + Select HP6XX if configuring for a HP jornada HP6xx. + More information (hardware only) at + <http://www.hp.com/jornada/>. + +config SH_DREAMCAST + bool "Dreamcast" + select SYS_SUPPORTS_PCI + depends on CPU_SUBTYPE_SH7091 + help + Select Dreamcast if configuring for a SEGA Dreamcast. + More information at <http://www.linux-sh.org> + +config SH_SH03 + bool "Interface CTP/PCI-SH03" + depends on CPU_SUBTYPE_SH7751 + select CPU_HAS_IPR_IRQ + select SYS_SUPPORTS_PCI + help + CTP/PCI-SH03 is a CPU module computer that is produced + by Interface Corporation. + More information at <http://www.interface.co.jp> + +config SH_SECUREEDGE5410 + bool "SecureEdge5410" + depends on CPU_SUBTYPE_SH7751R + select CPU_HAS_IPR_IRQ + select SYS_SUPPORTS_PCI + help + Select SecureEdge5410 if configuring for a SnapGear SH board. + This includes both the OEM SecureEdge products as well as the + SME product line. + +config SH_RTS7751R2D + bool "RTS7751R2D" + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI + select IO_TRAPPED if MMU + help + Select RTS7751R2D if configuring for a Renesas Technology + Sales SH-Graphics board. + +config SH_RSK + bool "Renesas Starter Kit" + depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 + help + Select this option if configuring for any of the RSK+ MCU + evaluation platforms. + +config SH_SDK7780 + bool "SDK7780R3" + depends on CPU_SUBTYPE_SH7780 + select SYS_SUPPORTS_PCI + help + Select SDK7780 if configuring for a Renesas SH7780 SDK7780R3 + evaluation board. + +config SH_SDK7786 + bool "SDK7786" + depends on CPU_SUBTYPE_SH7786 + select SYS_SUPPORTS_PCI + select NO_IOPORT if !PCI + select ARCH_WANT_OPTIONAL_GPIOLIB + select HAVE_SRAM_POOL + help + Select SDK7786 if configuring for a Renesas Technology Europe + SH7786-65nm board. + +config SH_HIGHLANDER + bool "Highlander" + depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 + select SYS_SUPPORTS_PCI + select IO_TRAPPED if MMU + +config SH_SH7757LCR + bool "SH7757LCR" + depends on CPU_SUBTYPE_SH7757 + select ARCH_REQUIRE_GPIOLIB + +config SH_SH7785LCR + bool "SH7785LCR" + depends on CPU_SUBTYPE_SH7785 + select SYS_SUPPORTS_PCI + +config SH_SH7785LCR_29BIT_PHYSMAPS + bool "SH7785LCR 29bit physmaps" + depends on SH_SH7785LCR && 29BIT + default y + help + This board has 2 physical memory maps. It can be changed with + DIP switch(S2-5). If you set the DIP switch for S2-5 = ON, + you can access all on-board device in 29bit address mode. + +config SH_SH7785LCR_PT + bool "SH7785LCR prototype board on 32-bit MMU mode" + depends on SH_SH7785LCR && 32BIT + default n + help + If you use prototype board, this option is enabled. + +config SH_URQUELL + bool "Urquell" + depends on CPU_SUBTYPE_SH7786 + select ARCH_REQUIRE_GPIOLIB + select SYS_SUPPORTS_PCI + select NO_IOPORT if !PCI + +config SH_MIGOR + bool "Migo-R" + depends on CPU_SUBTYPE_SH7722 + select ARCH_REQUIRE_GPIOLIB + help + Select Migo-R if configuring for the SH7722 Migo-R platform + by Renesas System Solutions Asia Pte. Ltd. + +config SH_AP325RXA + bool "AP-325RXA" + depends on CPU_SUBTYPE_SH7723 + select ARCH_REQUIRE_GPIOLIB + help + Renesas "AP-325RXA" support. + Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" + +config SH_KFR2R09 + bool "KFR2R09" + depends on CPU_SUBTYPE_SH7724 + select ARCH_REQUIRE_GPIOLIB + help + "Kit For R2R for 2009" support. + +config SH_ECOVEC + bool "EcoVec" + depends on CPU_SUBTYPE_SH7724 + select ARCH_REQUIRE_GPIOLIB + help + Renesas "R0P7724LC0011/21RL (EcoVec)" support. + +config SH_SH7763RDP + bool "SH7763RDP" + depends on CPU_SUBTYPE_SH7763 + help + Select SH7763RDP if configuring for a Renesas SH7763 + evaluation board. + +config SH_ESPT + bool "ESPT" + depends on CPU_SUBTYPE_SH7763 + help + Select ESPT if configuring for a Renesas SH7763 + with gigabit ether evaluation board. + +config SH_EDOSK7705 + bool "EDOSK7705" + depends on CPU_SUBTYPE_SH7705 + +config SH_EDOSK7760 + bool "EDOSK7760" + depends on CPU_SUBTYPE_SH7760 + help + Select if configuring for a Renesas EDOSK7760 + evaluation board. + +config SH_SH4202_MICRODEV + bool "SH4-202 MicroDev" + depends on CPU_SUBTYPE_SH4_202 + help + Select SH4-202 MicroDev if configuring for a SuperH MicroDev board + with an SH4-202 CPU. + +config SH_LANDISK + bool "LANDISK" + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI + help + I-O DATA DEVICE, INC. "LANDISK Series" support. + +config SH_TITAN + bool "TITAN" + depends on CPU_SUBTYPE_SH7751R + select CPU_HAS_IPR_IRQ + select SYS_SUPPORTS_PCI + help + Select Titan if you are configuring for a Nimble Microsystems + NetEngine NP51R. + +config SH_SHMIN + bool "SHMIN" + depends on CPU_SUBTYPE_SH7706 + select CPU_HAS_IPR_IRQ + help + Select SHMIN if configuring for the SHMIN board. + +config SH_LBOX_RE2 + bool "L-BOX RE2" + depends on CPU_SUBTYPE_SH7751R + select SYS_SUPPORTS_PCI + help + Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2. + +config SH_X3PROTO + bool "SH-X3 Prototype board" + depends on CPU_SUBTYPE_SHX3 + select NO_IOPORT if !PCI + +config SH_MAGIC_PANEL_R2 + bool "Magic Panel R2" + depends on CPU_SUBTYPE_SH7720 + select ARCH_REQUIRE_GPIOLIB + help + Select Magic Panel R2 if configuring for Magic Panel R2. + +config SH_CAYMAN + bool "Hitachi Cayman" + depends on CPU_SUBTYPE_SH5_101 || CPU_SUBTYPE_SH5_103 + select SYS_SUPPORTS_PCI + +config SH_POLARIS + bool "SMSC Polaris" + select CPU_HAS_IPR_IRQ + depends on CPU_SUBTYPE_SH7709 + help + Select if configuring for an SMSC Polaris development board + +config SH_SH2007 + bool "SH-2007 board" + select NO_IOPORT + depends on CPU_SUBTYPE_SH7780 + help + SH-2007 is a single-board computer based around SH7780 chip + intended for embedded applications. + It has an Ethernet interface (SMC9118), direct connected + Compact Flash socket, two serial ports and PC-104 bus. + More information at <http://sh2000.sh-linux.org>. + +config SH_APSH4A3A + bool "AP-SH4A-3A" + select SH_ALPHA_BOARD + depends on CPU_SUBTYPE_SH7785 + help + Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. + +config SH_APSH4AD0A + bool "AP-SH4AD-0A" + select SH_ALPHA_BOARD + select SYS_SUPPORTS_PCI + depends on CPU_SUBTYPE_SH7786 + help + Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. + +endmenu + +source "arch/sh/boards/mach-r2d/Kconfig" +source "arch/sh/boards/mach-highlander/Kconfig" +source "arch/sh/boards/mach-sdk7780/Kconfig" +source "arch/sh/boards/mach-migor/Kconfig" +source "arch/sh/boards/mach-rsk/Kconfig" + +if SH_MAGIC_PANEL_R2 + +menu "Magic Panel R2 options" + +config SH_MAGIC_PANEL_R2_VERSION + int SH_MAGIC_PANEL_R2_VERSION + default "3" + help + Set the version of the Magic Panel R2 + +endmenu + +endif diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile new file mode 100644 index 00000000000..975a0f64ff2 --- /dev/null +++ b/arch/sh/boards/Makefile @@ -0,0 +1,17 @@ +# +# Specific board support, not covered by a mach group. +# +obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o +obj-$(CONFIG_SH_SECUREEDGE5410) += board-secureedge5410.o +obj-$(CONFIG_SH_SH2007) += board-sh2007.o +obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o +obj-$(CONFIG_SH_URQUELL) += board-urquell.o +obj-$(CONFIG_SH_SHMIN) += board-shmin.o +obj-$(CONFIG_SH_EDOSK7705) += board-edosk7705.o +obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o +obj-$(CONFIG_SH_ESPT) += board-espt.o +obj-$(CONFIG_SH_POLARIS) += board-polaris.o +obj-$(CONFIG_SH_TITAN) += board-titan.o +obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o +obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o +obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o diff --git a/arch/sh/boards/board-apsh4a3a.c b/arch/sh/boards/board-apsh4a3a.c new file mode 100644 index 00000000000..2823619c600 --- /dev/null +++ b/arch/sh/boards/board-apsh4a3a.c @@ -0,0 +1,175 @@ +/* + * ALPHAPROJECT AP-SH4A-3A Support. + * + * Copyright (C) 2010 ALPHAPROJECT Co.,Ltd. + * Copyright (C) 2008 Yoshihiro Shimoda + * Copyright (C) 2009 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/mtd/physmap.h> +#include <linux/smsc911x.h> +#include <linux/irq.h> +#include <linux/clk.h> +#include <asm/machvec.h> +#include <asm/sizes.h> +#include <asm/clock.h> + +static struct mtd_partition nor_flash_partitions[] = { + { + .name = "loader", + .offset = 0x00000000, + .size = 512 * 1024, + }, + { + .name = "bootenv", + .offset = MTDPART_OFS_APPEND, + .size = 512 * 1024, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 4 * 1024 * 1024, + }, + { + .name = "data", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data nor_flash_data = { + .width = 4, + .parts = nor_flash_partitions, + .nr_parts = ARRAY_SIZE(nor_flash_partitions), +}; + +static struct resource nor_flash_resources[] = { + [0] = { + .start = 0x00000000, + .end = 0x01000000 - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device nor_flash_device = { + .name = "physmap-flash", + .dev = { + .platform_data = &nor_flash_data, + }, + .num_resources = ARRAY_SIZE(nor_flash_resources), + .resource = nor_flash_resources, +}; + +static struct resource smsc911x_resources[] = { + [0] = { + .name = "smsc911x-memory", + .start = 0xA4000000, + .end = 0xA4000000 + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "smsc911x-irq", + .start = evt2irq(0x200), + .end = evt2irq(0x200), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_16BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static struct platform_device *apsh4a3a_devices[] __initdata = { + &nor_flash_device, + &smsc911x_device, +}; + +static int __init apsh4a3a_devices_setup(void) +{ + return platform_add_devices(apsh4a3a_devices, + ARRAY_SIZE(apsh4a3a_devices)); +} +device_initcall(apsh4a3a_devices_setup); + +static int apsh4a3a_clk_init(void) +{ + struct clk *clk; + int ret; + + clk = clk_get(NULL, "extal"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + ret = clk_set_rate(clk, 33333000); + clk_put(clk); + + return ret; +} + +/* Initialize the board */ +static void __init apsh4a3a_setup(char **cmdline_p) +{ + printk(KERN_INFO "Alpha Project AP-SH4A-3A support:\n"); +} + +static void __init apsh4a3a_init_irq(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ7654); +} + +/* Return the board specific boot mode pin configuration */ +static int apsh4a3a_mode_pins(void) +{ + int value = 0; + + /* These are the factory default settings of SW1 and SW2. + * If you change these dip switches then you will need to + * adjust the values below as well. + */ + value &= ~MODE_PIN0; /* Clock Mode 16 */ + value &= ~MODE_PIN1; + value &= ~MODE_PIN2; + value &= ~MODE_PIN3; + value |= MODE_PIN4; + value &= ~MODE_PIN5; /* 16-bit Area0 bus width */ + value |= MODE_PIN6; /* Area 0 SRAM interface */ + value |= MODE_PIN7; + value |= MODE_PIN8; /* Little Endian */ + value |= MODE_PIN9; /* Master Mode */ + value |= MODE_PIN10; /* Crystal resonator */ + value |= MODE_PIN11; /* Display Unit */ + value |= MODE_PIN12; + value &= ~MODE_PIN13; /* 29-bit address mode */ + value |= MODE_PIN14; /* No PLL step-up */ + + return value; +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_apsh4a3a __initmv = { + .mv_name = "AP-SH4A-3A", + .mv_setup = apsh4a3a_setup, + .mv_clk_init = apsh4a3a_clk_init, + .mv_init_irq = apsh4a3a_init_irq, + .mv_mode_pins = apsh4a3a_mode_pins, +}; diff --git a/arch/sh/boards/board-apsh4ad0a.c b/arch/sh/boards/board-apsh4ad0a.c new file mode 100644 index 00000000000..b4d6292a924 --- /dev/null +++ b/arch/sh/boards/board-apsh4ad0a.c @@ -0,0 +1,125 @@ +/* + * ALPHAPROJECT AP-SH4AD-0A Support. + * + * Copyright (C) 2010 ALPHAPROJECT Co.,Ltd. + * Copyright (C) 2010 Matt Fleming + * Copyright (C) 2010 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/smsc911x.h> +#include <linux/irq.h> +#include <linux/clk.h> +#include <asm/machvec.h> +#include <asm/sizes.h> + +static struct resource smsc911x_resources[] = { + [0] = { + .name = "smsc911x-memory", + .start = 0xA4000000, + .end = 0xA4000000 + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "smsc911x-irq", + .start = evt2irq(0x200), + .end = evt2irq(0x200), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_16BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static struct platform_device *apsh4ad0a_devices[] __initdata = { + &smsc911x_device, +}; + +static int __init apsh4ad0a_devices_setup(void) +{ + return platform_add_devices(apsh4ad0a_devices, + ARRAY_SIZE(apsh4ad0a_devices)); +} +device_initcall(apsh4ad0a_devices_setup); + +static int apsh4ad0a_mode_pins(void) +{ + int value = 0; + + /* These are the factory default settings of SW1 and SW2. + * If you change these dip switches then you will need to + * adjust the values below as well. + */ + value |= MODE_PIN0; /* Clock Mode 3 */ + value |= MODE_PIN1; + value &= ~MODE_PIN2; + value &= ~MODE_PIN3; + value &= ~MODE_PIN4; /* 16-bit Area0 bus width */ + value |= MODE_PIN5; + value |= MODE_PIN6; + value |= MODE_PIN7; /* Normal mode */ + value |= MODE_PIN8; /* Little Endian */ + value |= MODE_PIN9; /* Crystal resonator */ + value &= ~MODE_PIN10; /* 29-bit address mode */ + value &= ~MODE_PIN11; /* PCI-E Root port */ + value &= ~MODE_PIN12; /* 4 lane + 1 lane */ + value |= MODE_PIN13; /* AUD Enable */ + value &= ~MODE_PIN14; /* Normal Operation */ + + return value; +} + +static int apsh4ad0a_clk_init(void) +{ + struct clk *clk; + int ret; + + clk = clk_get(NULL, "extal"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + ret = clk_set_rate(clk, 33333000); + clk_put(clk); + + return ret; +} + +/* Initialize the board */ +static void __init apsh4ad0a_setup(char **cmdline_p) +{ + pr_info("Alpha Project AP-SH4AD-0A support:\n"); +} + +static void __init apsh4ad0a_init_irq(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ3210); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_apsh4ad0a __initmv = { + .mv_name = "AP-SH4AD-0A", + .mv_setup = apsh4ad0a_setup, + .mv_mode_pins = apsh4ad0a_mode_pins, + .mv_clk_init = apsh4ad0a_clk_init, + .mv_init_irq = apsh4ad0a_init_irq, +}; diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c new file mode 100644 index 00000000000..541d8a28103 --- /dev/null +++ b/arch/sh/boards/board-edosk7705.c @@ -0,0 +1,78 @@ +/* + * arch/sh/boards/renesas/edosk7705/setup.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SolutionEngine Support. + * + * Modified for edosk7705 development + * board by S. Dunn, 2003. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/smc91x.h> +#include <asm/machvec.h> +#include <asm/sizes.h> + +#define SMC_IOBASE 0xA2000000 +#define SMC_IO_OFFSET 0x300 +#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET) + +#define ETHERNET_IRQ 0x09 + +static void __init sh_edosk7705_init_irq(void) +{ + make_imask_irq(ETHERNET_IRQ); +} + +/* eth initialization functions */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL, +}; + +static struct resource smc91x_res[] = { + [0] = { + .start = SMC_IOADDR, + .end = SMC_IOADDR + SZ_32 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ETHERNET_IRQ, + .end = ETHERNET_IRQ, + .flags = IORESOURCE_IRQ , + } +}; + +static struct platform_device smc91x_dev = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_res), + .resource = smc91x_res, + + .dev = { + .platform_data = &smc91x_info, + }, +}; + +/* platform init code */ +static struct platform_device *edosk7705_devices[] __initdata = { + &smc91x_dev, +}; + +static int __init init_edosk7705_devices(void) +{ + return platform_add_devices(edosk7705_devices, + ARRAY_SIZE(edosk7705_devices)); +} +device_initcall(init_edosk7705_devices); + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_edosk7705 __initmv = { + .mv_name = "EDOSK7705", + .mv_nr_irqs = 80, + .mv_init_irq = sh_edosk7705_init_irq, +}; diff --git a/arch/sh/boards/board-edosk7760.c b/arch/sh/boards/board-edosk7760.c new file mode 100644 index 00000000000..e9656a2cc4c --- /dev/null +++ b/arch/sh/boards/board-edosk7760.c @@ -0,0 +1,193 @@ +/* + * Renesas Europe EDOSK7760 Board Support + * + * Copyright (C) 2008 SPES Societa' Progettazione Elettronica e Software Ltd. + * Author: Luca Santini <luca.santini@spesonline.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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/smc91x.h> +#include <linux/interrupt.h> +#include <linux/i2c.h> +#include <linux/mtd/physmap.h> +#include <asm/machvec.h> +#include <asm/io.h> +#include <asm/addrspace.h> +#include <asm/delay.h> +#include <asm/i2c-sh7760.h> +#include <asm/sizes.h> + +/* Bus state controller registers for CS4 area */ +#define BSC_CS4BCR 0xA4FD0010 +#define BSC_CS4WCR 0xA4FD0030 + +#define SMC_IOBASE 0xA2000000 +#define SMC_IO_OFFSET 0x300 +#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET) + +#define ETHERNET_IRQ 5 + +/* NOR flash */ +static struct mtd_partition edosk7760_nor_flash_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = SZ_256K, + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + }, { + .name = "fs", + .offset = MTDPART_OFS_APPEND, + .size = (26 << 20), + }, { + .name = "other", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data edosk7760_nor_flash_data = { + .width = 4, + .parts = edosk7760_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(edosk7760_nor_flash_partitions), +}; + +static struct resource edosk7760_nor_flash_resources[] = { + [0] = { + .name = "NOR Flash", + .start = 0x00000000, + .end = 0x00000000 + SZ_32M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device edosk7760_nor_flash_device = { + .name = "physmap-flash", + .resource = edosk7760_nor_flash_resources, + .num_resources = ARRAY_SIZE(edosk7760_nor_flash_resources), + .dev = { + .platform_data = &edosk7760_nor_flash_data, + }, +}; + +/* i2c initialization functions */ +static struct sh7760_i2c_platdata i2c_pd = { + .speed_khz = 400, +}; + +static struct resource sh7760_i2c1_res[] = { + { + .start = SH7760_I2C1_MMIO, + .end = SH7760_I2C1_MMIOEND, + .flags = IORESOURCE_MEM, + },{ + .start = SH7760_I2C1_IRQ, + .end = SH7760_I2C1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sh7760_i2c1_dev = { + .dev = { + .platform_data = &i2c_pd, + }, + + .name = SH7760_I2C_DEVNAME, + .id = 1, + .resource = sh7760_i2c1_res, + .num_resources = ARRAY_SIZE(sh7760_i2c1_res), +}; + +static struct resource sh7760_i2c0_res[] = { + { + .start = SH7760_I2C0_MMIO, + .end = SH7760_I2C0_MMIOEND, + .flags = IORESOURCE_MEM, + }, { + .start = SH7760_I2C0_IRQ, + .end = SH7760_I2C0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sh7760_i2c0_dev = { + .dev = { + .platform_data = &i2c_pd, + }, + .name = SH7760_I2C_DEVNAME, + .id = 0, + .resource = sh7760_i2c0_res, + .num_resources = ARRAY_SIZE(sh7760_i2c0_res), +}; + +/* eth initialization functions */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL, +}; + +static struct resource smc91x_res[] = { + [0] = { + .start = SMC_IOADDR, + .end = SMC_IOADDR + SZ_32 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ETHERNET_IRQ, + .end = ETHERNET_IRQ, + .flags = IORESOURCE_IRQ , + } +}; + +static struct platform_device smc91x_dev = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_res), + .resource = smc91x_res, + + .dev = { + .platform_data = &smc91x_info, + }, +}; + +/* platform init code */ +static struct platform_device *edosk7760_devices[] __initdata = { + &smc91x_dev, + &edosk7760_nor_flash_device, + &sh7760_i2c0_dev, + &sh7760_i2c1_dev, +}; + +static int __init init_edosk7760_devices(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ); + + return platform_add_devices(edosk7760_devices, + ARRAY_SIZE(edosk7760_devices)); +} +device_initcall(init_edosk7760_devices); + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_edosk7760 __initmv = { + .mv_name = "EDOSK7760", + .mv_nr_irqs = 128, +}; diff --git a/arch/sh/boards/board-espt.c b/arch/sh/boards/board-espt.c new file mode 100644 index 00000000000..b3ae9d38cbc --- /dev/null +++ b/arch/sh/boards/board-espt.c @@ -0,0 +1,109 @@ +/* + * Data Technology Inc. ESPT-GIGA board suport + * + * Copyright (C) 2008, 2009 Renesas Solutions Corp. + * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/mtd/physmap.h> +#include <linux/io.h> +#include <linux/sh_eth.h> +#include <asm/machvec.h> +#include <asm/sizes.h> + +/* NOR Flash */ +static struct mtd_partition espt_nor_flash_partitions[] = { + { + .name = "U-Boot", + .offset = 0, + .size = (2 * SZ_128K), + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, { + .name = "Linux-Kernel", + .offset = MTDPART_OFS_APPEND, + .size = (20 * SZ_128K), + }, { + .name = "Root Filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data espt_nor_flash_data = { + .width = 2, + .parts = espt_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(espt_nor_flash_partitions), +}; + +static struct resource espt_nor_flash_resources[] = { + [0] = { + .name = "NOR Flash", + .start = 0, + .end = SZ_8M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device espt_nor_flash_device = { + .name = "physmap-flash", + .resource = espt_nor_flash_resources, + .num_resources = ARRAY_SIZE(espt_nor_flash_resources), + .dev = { + .platform_data = &espt_nor_flash_data, + }, +}; + +/* SH-Ether */ +static struct resource sh_eth_resources[] = { + { + .start = 0xFEE00800, /* use eth1 */ + .end = 0xFEE00F7C - 1, + .flags = IORESOURCE_MEM, + }, { + .start = 0xFEE01800, /* TSU */ + .end = 0xFEE01FFF, + .flags = IORESOURCE_MEM, + }, { + + .start = 57, /* irq number */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_eth_plat_data sh7763_eth_pdata = { + .phy = 0, + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .register_type = SH_ETH_REG_GIGABIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device espt_eth_device = { + .name = "sh-eth", + .resource = sh_eth_resources, + .num_resources = ARRAY_SIZE(sh_eth_resources), + .dev = { + .platform_data = &sh7763_eth_pdata, + }, +}; + +static struct platform_device *espt_devices[] __initdata = { + &espt_nor_flash_device, + &espt_eth_device, +}; + +static int __init espt_devices_setup(void) +{ + return platform_add_devices(espt_devices, + ARRAY_SIZE(espt_devices)); +} +device_initcall(espt_devices_setup); + +static struct sh_machine_vector mv_espt __initmv = { + .mv_name = "ESPT-GIGA", +}; diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c new file mode 100644 index 00000000000..b2ca1d9948f --- /dev/null +++ b/arch/sh/boards/board-magicpanelr2.c @@ -0,0 +1,382 @@ +/* + * linux/arch/sh/boards/magicpanel/setup.c + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Magic Panel Release 2 board setup + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/smsc911x.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/map.h> +#include <mach/magicpanelr2.h> +#include <asm/heartbeat.h> +#include <cpu/sh7720.h> + +#define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) + +/* Wait until reset finished. Timeout is 100ms. */ +static int __init ethernet_reset_finished(void) +{ + int i; + + if (LAN9115_READY) + return 1; + + for (i = 0; i < 10; ++i) { + mdelay(10); + if (LAN9115_READY) + return 1; + } + + return 0; +} + +static void __init reset_ethernet(void) +{ + /* PMDR: LAN_RESET=on */ + CLRBITS_OUTB(0x10, PORT_PMDR); + + udelay(200); + + /* PMDR: LAN_RESET=off */ + SETBITS_OUTB(0x10, PORT_PMDR); +} + +static void __init setup_chip_select(void) +{ + /* CS2: LAN (0x08000000 - 0x0bffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + __raw_writel(0x36db0400, CS2BCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + __raw_writel(0x000003c0, CS2WCR); + + /* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + __raw_writel(0x00000200, CS4BCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + __raw_writel(0x00100981, CS4WCR); + + /* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + __raw_writel(0x00000200, CS5ABCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + __raw_writel(0x00100981, CS5AWCR); + + /* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + __raw_writel(0x00000200, CS5BBCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + __raw_writel(0x00100981, CS5BWCR); + + /* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + __raw_writel(0x00000200, CS6ABCR); + /* (SW:1.5 WR:3 HW:1.5), no ext. wait */ + __raw_writel(0x001009C1, CS6AWCR); +} + +static void __init setup_port_multiplexing(void) +{ + /* A7 GPO(LED8); A6 GPO(LED7); A5 GPO(LED6); A4 GPO(LED5); + * A3 GPO(LED4); A2 GPO(LED3); A1 GPO(LED2); A0 GPO(LED1); + */ + __raw_writew(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */ + + /* B7 GPO(RST4); B6 GPO(RST3); B5 GPO(RST2); B4 GPO(RST1); + * B3 GPO(PB3); B2 GPO(PB2); B1 GPO(PB1); B0 GPO(PB0); + */ + __raw_writew(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */ + + /* C7 GPO(PC7); C6 GPO(PC6); C5 GPO(PC5); C4 GPO(PC4); + * C3 LCD_DATA3; C2 LCD_DATA2; C1 LCD_DATA1; C0 LCD_DATA0; + */ + __raw_writew(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */ + + /* D7 GPO(PD7); D6 GPO(PD6); D5 GPO(PD5); D4 GPO(PD4); + * D3 GPO(PD3); D2 GPO(PD2); D1 GPO(PD1); D0 GPO(PD0); + */ + __raw_writew(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */ + + /* E7 (x); E6 GPI(nu); E5 GPI(nu); E4 LCD_M_DISP; + * E3 LCD_CL1; E2 LCD_CL2; E1 LCD_DON; E0 LCD_FLM; + */ + __raw_writew(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */ + + /* F7 (x); F6 DA1(VLCD); F5 DA0(nc); F4 AN3; + * F3 AN2(MID_AD); F2 AN1(EARTH_AD); F1 AN0(TEMP); F0 GPI+(nc); + */ + __raw_writew(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */ + + /* G7 (x); G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2); + * G3 GPI(KEY1); G2 GPO(LED11); G1 GPO(LED10); G0 GPO(LED9); + */ + __raw_writew(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */ + + /* H7 (x); H6 /RAS(BRAS); H5 /CAS(BCAS); H4 CKE(BCKE); + * H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR; H0 USB1_PWR; + */ + __raw_writew(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */ + + /* J7 (x); J6 AUDCK; J5 ASEBRKAK; J4 AUDATA3; + * J3 AUDATA2; J2 AUDATA1; J1 AUDATA0; J0 AUDSYNC; + */ + __raw_writew(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */ + + /* K7 (x); K6 (x); K5 (x); K4 (x); + * K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY) + */ + __raw_writew(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */ + + /* L7 TRST; L6 TMS; L5 TDO; L4 TDI; + * L3 TCK; L2 (x); L1 (x); L0 (x); + */ + __raw_writew(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */ + + /* M7 GPO(CURRENT_SINK); M6 GPO(PWR_SWITCH); M5 GPO(LAN_SPEED); + * M4 GPO(LAN_RESET); M3 GPO(BUZZER); M2 GPO(LCD_BL); + * M1 CS5B(CAN3_CS); M0 GPI+(nc); + */ + __raw_writew(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */ + + /* CURRENT_SINK=off, PWR_SWITCH=off, LAN_SPEED=100MBit, + * LAN_RESET=off, BUZZER=off, LCD_BL=off + */ +#if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2 + __raw_writeb(0x30, PORT_PMDR); +#elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3 + __raw_writeb(0xF0, PORT_PMDR); +#else +#error Unknown revision of PLATFORM_MP_R2 +#endif + + /* P7 (x); P6 (x); P5 (x); + * P4 GPO(nu); P3 IRQ3(LAN_IRQ); P2 IRQ2(CAN3_IRQ); + * P1 IRQ1(CAN2_IRQ); P0 IRQ0(CAN1_IRQ) + */ + __raw_writew(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */ + __raw_writeb(0x10, PORT_PPDR); + + /* R7 A25; R6 A24; R5 A23; R4 A22; + * R3 A21; R2 A20; R1 A19; R0 A0; + */ + gpio_request(GPIO_FN_A25, NULL); + gpio_request(GPIO_FN_A24, NULL); + gpio_request(GPIO_FN_A23, NULL); + gpio_request(GPIO_FN_A22, NULL); + gpio_request(GPIO_FN_A21, NULL); + gpio_request(GPIO_FN_A20, NULL); + gpio_request(GPIO_FN_A19, NULL); + gpio_request(GPIO_FN_A0, NULL); + + /* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2); + * S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK; + */ + __raw_writew(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */ + + /* T7 (x); T6 (x); T5 (x); T4 COM1_CTS; + * T3 COM1_RTS; T2 COM1_TXD; T1 COM1_RXD; T0 GPO(WDOG) + */ + __raw_writew(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */ + + /* U7 (x); U6 (x); U5 (x); U4 GPI+(/AC_FAULT); + * U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD; U0 TOUCH_SCK; + */ + __raw_writew(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */ + + /* V7 (x); V6 (x); V5 (x); V4 GPO(MID2); + * V3 GPO(MID1); V2 CARD_TxD; V1 CARD_RxD; V0 GPI+(/BAT_FAULT); + */ + __raw_writew(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */ +} + +static void __init mpr2_setup(char **cmdline_p) +{ + /* set Pin Select Register A: + * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, + * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND + */ + __raw_writew(0xAABC, PORT_PSELA); + /* set Pin Select Register B: + * /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC, + * LCD_VEPWC, IIC_SDA, IIC_SCL, Reserved + */ + __raw_writew(0x3C00, PORT_PSELB); + /* set Pin Select Register C: + * SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved + */ + __raw_writew(0x0000, PORT_PSELC); + /* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK, + * Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved + */ + __raw_writew(0x0000, PORT_PSELD); + /* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */ + __raw_writew(0x0101, PORT_UTRCTL); + /* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */ + __raw_writew(0xA5C0, PORT_UCLKCR_W); + + setup_chip_select(); + + setup_port_multiplexing(); + + reset_ethernet(); + + printk(KERN_INFO "Magic Panel Release 2 A.%i\n", + CONFIG_SH_MAGIC_PANEL_R2_VERSION); + + if (ethernet_reset_finished() == 0) + printk(KERN_WARNING "Ethernet not ready\n"); +} + +static struct resource smsc911x_resources[] = { + [0] = { + .start = 0xa8000000, + .end = 0xabffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 35, + .end = 35, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM, + }, +}; + +static struct heartbeat_data heartbeat_data = { + .flags = HEARTBEAT_INVERTED, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = &heartbeat_data, + }, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +static struct mtd_partition mpr2_partitions[] = { + /* Reserved for bootloader, read-only */ + { + .name = "Bootloader", + .offset = 0x00000000UL, + .size = MPR2_MTD_BOOTLOADER_SIZE, + .mask_flags = MTD_WRITEABLE, + }, + /* Reserved for kernel image */ + { + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = MPR2_MTD_KERNEL_SIZE, + }, + /* Rest is used for Flash FS */ + { + .name = "Flash_FS", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data flash_data = { + .parts = mpr2_partitions, + .nr_parts = ARRAY_SIZE(mpr2_partitions), + .width = 2, +}; + +static struct resource flash_resource = { + .start = 0x00000000, + .end = 0x2000000UL, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = &flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &flash_data, + }, +}; + +/* + * Add all resources to the platform_device + */ + +static struct platform_device *mpr2_devices[] __initdata = { + &heartbeat_device, + &smsc911x_device, + &flash_device, +}; + + +static int __init mpr2_devices_setup(void) +{ + return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); +} +device_initcall(mpr2_devices_setup); + +/* + * Initialize IRQ setting + */ +static void __init init_mpr2_IRQ(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-5 */ + + irq_set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */ + irq_set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */ + irq_set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */ + irq_set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */ + irq_set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */ + irq_set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */ + + intc_set_priority(32, 13); /* IRQ0 CAN1 */ + intc_set_priority(33, 13); /* IRQ0 CAN2 */ + intc_set_priority(34, 13); /* IRQ0 CAN3 */ + intc_set_priority(35, 6); /* IRQ3 SMSC9115 */ +} + +/* + * The Machine Vector + */ + +static struct sh_machine_vector mv_mpr2 __initmv = { + .mv_name = "mpr2", + .mv_setup = mpr2_setup, + .mv_init_irq = init_mpr2_IRQ, +}; diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c new file mode 100644 index 00000000000..594866356c2 --- /dev/null +++ b/arch/sh/boards/board-polaris.c @@ -0,0 +1,146 @@ +/* + * June 2006 steve.glendinning@smsc.com + * + * Polaris-specific resource declaration + * + */ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/smsc911x.h> +#include <linux/io.h> +#include <asm/irq.h> +#include <asm/machvec.h> +#include <asm/heartbeat.h> +#include <cpu/gpio.h> +#include <mach-se/mach/se.h> + +#define BCR2 (0xFFFFFF62) +#define WCR2 (0xFFFFFF66) +#define AREA5_WAIT_CTRL (0x1C00) +#define WAIT_STATES_10 (0x7) + +static struct resource smsc911x_resources[] = { + [0] = { + .name = "smsc911x-memory", + .start = PA_EXT5, + .end = PA_EXT5 + 0x1fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "smsc911x-irq", + .start = IRQ0_IRQ, + .end = IRQ0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 }; + +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; + +static struct resource heartbeat_resource = { + .start = PORT_PCDR, + .end = PORT_PCDR, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = &heartbeat_data, + }, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +static struct platform_device *polaris_devices[] __initdata = { + &smsc911x_device, + &heartbeat_device, +}; + +static int __init polaris_initialise(void) +{ + u16 wcr, bcr_mask; + + printk(KERN_INFO "Configuring Polaris external bus\n"); + + /* Configure area 5 with 2 wait states */ + wcr = __raw_readw(WCR2); + wcr &= (~AREA5_WAIT_CTRL); + wcr |= (WAIT_STATES_10 << 10); + __raw_writew(wcr, WCR2); + + /* Configure area 5 for 32-bit access */ + bcr_mask = __raw_readw(BCR2); + bcr_mask |= 1 << 10; + __raw_writew(bcr_mask, BCR2); + + return platform_add_devices(polaris_devices, + ARRAY_SIZE(polaris_devices)); +} +arch_initcall(polaris_initialise); + +static struct ipr_data ipr_irq_table[] = { + /* External IRQs */ + { IRQ0_IRQ, 0, 0, 1, }, /* IRQ0 */ + { IRQ1_IRQ, 0, 4, 1, }, /* IRQ1 */ +}; + +static unsigned long ipr_offsets[] = { + INTC_IPRC +}; + +static struct ipr_desc ipr_irq_desc = { + .ipr_offsets = ipr_offsets, + .nr_offsets = ARRAY_SIZE(ipr_offsets), + + .ipr_data = ipr_irq_table, + .nr_irqs = ARRAY_SIZE(ipr_irq_table), + .chip = { + .name = "sh7709-ext", + }, +}; + +static void __init init_polaris_irq(void) +{ + /* Disable all interrupts */ + __raw_writew(0, BCR_ILCRA); + __raw_writew(0, BCR_ILCRB); + __raw_writew(0, BCR_ILCRC); + __raw_writew(0, BCR_ILCRD); + __raw_writew(0, BCR_ILCRE); + __raw_writew(0, BCR_ILCRF); + __raw_writew(0, BCR_ILCRG); + + register_ipr_controller(&ipr_irq_desc); +} + +static struct sh_machine_vector mv_polaris __initmv = { + .mv_name = "Polaris", + .mv_nr_irqs = 61, + .mv_init_irq = init_polaris_irq, +}; diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c new file mode 100644 index 00000000000..03820c3c93d --- /dev/null +++ b/arch/sh/boards/board-secureedge5410.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2002 David McCullough <davidm@snapgear.com> + * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> + * + * Based on files with the following comments: + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Modified for 7751 Solution Engine by + * Ian da Silva and Jeremy Siegel, 2001. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <asm/machvec.h> +#include <mach/secureedge5410.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <cpu/timer.h> + +unsigned short secureedge5410_ioport; + +/* + * EraseConfig handling functions + */ +static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) +{ + printk("SnapGear: erase switch interrupt!\n"); + + return IRQ_HANDLED; +} + +static int __init eraseconfig_init(void) +{ + unsigned int irq = evt2irq(0x240); + + printk("SnapGear: EraseConfig init\n"); + + /* Setup "EraseConfig" switch on external IRQ 0 */ + if (request_irq(irq, eraseconfig_interrupt, 0, "Erase Config", NULL)) + printk("SnapGear: failed to register IRQ%d for Reset witch\n", + irq); + else + printk("SnapGear: registered EraseConfig switch on IRQ%d\n", + irq); + return 0; +} +module_init(eraseconfig_init); + +/* + * Initialize IRQ setting + * + * IRL0 = erase switch + * IRL1 = eth0 + * IRL2 = eth1 + * IRL3 = crypto + */ +static void __init init_snapgear_IRQ(void) +{ + printk("Setup SnapGear IRQ/IPR ...\n"); + /* enable individual interrupt mode for externals */ + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_snapgear __initmv = { + .mv_name = "SnapGear SecureEdge5410", + .mv_nr_irqs = 72, + .mv_init_irq = init_snapgear_IRQ, +}; diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c new file mode 100644 index 00000000000..b90b78f6a82 --- /dev/null +++ b/arch/sh/boards/board-sh2007.c @@ -0,0 +1,133 @@ +/* + * SH-2007 board support. + * + * Copyright (C) 2003, 2004 SUGIOKA Toshinobu + * Copyright (C) 2010 Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/smsc911x.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/io.h> +#include <asm/machvec.h> +#include <mach/sh2007.h> + +struct smsc911x_platform_config smc911x_info = { + .flags = SMSC911X_USE_32BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, +}; + +static struct resource smsc9118_0_resources[] = { + [0] = { + .start = SMC0_BASE, + .end = SMC0_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x240), + .end = evt2irq(0x240), + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource smsc9118_1_resources[] = { + [0] = { + .start = SMC1_BASE, + .end = SMC1_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x280), + .end = evt2irq(0x280), + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device smsc9118_0_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(smsc9118_0_resources), + .resource = smsc9118_0_resources, + .dev = { + .platform_data = &smc911x_info, + }, +}; + +static struct platform_device smsc9118_1_device = { + .name = "smsc911x", + .id = 1, + .num_resources = ARRAY_SIZE(smsc9118_1_resources), + .resource = smsc9118_1_resources, + .dev = { + .platform_data = &smc911x_info, + }, +}; + +static struct resource cf_resources[] = { + [0] = { + .start = CF_BASE + CF_OFFSET, + .end = CF_BASE + CF_OFFSET + 0x0f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CF_BASE + CF_OFFSET + 0x206, + .end = CF_BASE + CF_OFFSET + 0x20f, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = evt2irq(0x2c0), + .end = evt2irq(0x2c0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_device = { + .name = "pata_platform", + .id = 0, + .num_resources = ARRAY_SIZE(cf_resources), + .resource = cf_resources, +}; + +static struct platform_device *sh2007_devices[] __initdata = { + &smsc9118_0_device, + &smsc9118_1_device, + &cf_device, +}; + +static int __init sh2007_io_init(void) +{ + platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices)); + return 0; +} +subsys_initcall(sh2007_io_init); + +static void __init sh2007_init_irq(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + +/* + * Initialize the board + */ +static void __init sh2007_setup(char **cmdline_p) +{ + printk(KERN_INFO "SH-2007 Setup..."); + + /* setup wait control registers for area 5 */ + __raw_writel(CS5BCR_D, CS5BCR); + __raw_writel(CS5WCR_D, CS5WCR); + __raw_writel(CS5PCR_D, CS5PCR); + + printk(KERN_INFO " done.\n"); +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_sh2007 __initmv = { + .mv_setup = sh2007_setup, + .mv_name = "sh2007", + .mv_init_irq = sh2007_init_irq, +}; diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c new file mode 100644 index 00000000000..24b1ee410da --- /dev/null +++ b/arch/sh/boards/board-sh7757lcr.c @@ -0,0 +1,600 @@ +/* + * Renesas R0P7757LC0012RL Support. + * + * Copyright (C) 2009 - 2010 Renesas Solutions Corp. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/irq.h> +#include <linux/spi/spi.h> +#include <linux/spi/flash.h> +#include <linux/io.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mmcif.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/sh_eth.h> +#include <linux/usb/renesas_usbhs.h> +#include <cpu/sh7757.h> +#include <asm/heartbeat.h> + +static struct resource heartbeat_resource = { + .start = 0xffec005c, /* PUDR */ + .end = 0xffec005c, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, +}; + +static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 }; + +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), + .flags = HEARTBEAT_INVERTED, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = &heartbeat_data, + }, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +/* Fast Ethernet */ +#define GBECONT 0xffc10100 +#define GBECONT_RMII1 BIT(17) +#define GBECONT_RMII0 BIT(16) +static void sh7757_eth_set_mdio_gate(void *addr) +{ + if (((unsigned long)addr & 0x00000fff) < 0x0800) + writel(readl(GBECONT) | GBECONT_RMII0, GBECONT); + else + writel(readl(GBECONT) | GBECONT_RMII1, GBECONT); +} + +static struct resource sh_eth0_resources[] = { + { + .start = 0xfef00000, + .end = 0xfef001ff, + .flags = IORESOURCE_MEM, + }, { + .start = 84, + .end = 84, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_eth_plat_data sh7757_eth0_pdata = { + .phy = 1, + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .register_type = SH_ETH_REG_FAST_SH4, + .set_mdio_gate = sh7757_eth_set_mdio_gate, +}; + +static struct platform_device sh7757_eth0_device = { + .name = "sh-eth", + .resource = sh_eth0_resources, + .id = 0, + .num_resources = ARRAY_SIZE(sh_eth0_resources), + .dev = { + .platform_data = &sh7757_eth0_pdata, + }, +}; + +static struct resource sh_eth1_resources[] = { + { + .start = 0xfef00800, + .end = 0xfef009ff, + .flags = IORESOURCE_MEM, + }, { + .start = 84, + .end = 84, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_eth_plat_data sh7757_eth1_pdata = { + .phy = 1, + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .register_type = SH_ETH_REG_FAST_SH4, + .set_mdio_gate = sh7757_eth_set_mdio_gate, +}; + +static struct platform_device sh7757_eth1_device = { + .name = "sh-eth", + .resource = sh_eth1_resources, + .id = 1, + .num_resources = ARRAY_SIZE(sh_eth1_resources), + .dev = { + .platform_data = &sh7757_eth1_pdata, + }, +}; + +static void sh7757_eth_giga_set_mdio_gate(void *addr) +{ + if (((unsigned long)addr & 0x00000fff) < 0x0800) { + gpio_set_value(GPIO_PTT4, 1); + writel(readl(GBECONT) & ~GBECONT_RMII0, GBECONT); + } else { + gpio_set_value(GPIO_PTT4, 0); + writel(readl(GBECONT) & ~GBECONT_RMII1, GBECONT); + } +} + +static struct resource sh_eth_giga0_resources[] = { + { + .start = 0xfee00000, + .end = 0xfee007ff, + .flags = IORESOURCE_MEM, + }, { + /* TSU */ + .start = 0xfee01800, + .end = 0xfee01fff, + .flags = IORESOURCE_MEM, + }, { + .start = 315, + .end = 315, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_eth_plat_data sh7757_eth_giga0_pdata = { + .phy = 18, + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .register_type = SH_ETH_REG_GIGABIT, + .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, + .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, +}; + +static struct platform_device sh7757_eth_giga0_device = { + .name = "sh-eth", + .resource = sh_eth_giga0_resources, + .id = 2, + .num_resources = ARRAY_SIZE(sh_eth_giga0_resources), + .dev = { + .platform_data = &sh7757_eth_giga0_pdata, + }, +}; + +static struct resource sh_eth_giga1_resources[] = { + { + .start = 0xfee00800, + .end = 0xfee00fff, + .flags = IORESOURCE_MEM, + }, { + /* TSU */ + .start = 0xfee01800, + .end = 0xfee01fff, + .flags = IORESOURCE_MEM, + }, { + .start = 316, + .end = 316, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_eth_plat_data sh7757_eth_giga1_pdata = { + .phy = 19, + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .register_type = SH_ETH_REG_GIGABIT, + .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, + .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, +}; + +static struct platform_device sh7757_eth_giga1_device = { + .name = "sh-eth", + .resource = sh_eth_giga1_resources, + .id = 3, + .num_resources = ARRAY_SIZE(sh_eth_giga1_resources), + .dev = { + .platform_data = &sh7757_eth_giga1_pdata, + }, +}; + +/* SH_MMCIF */ +static struct resource sh_mmcif_resources[] = { + [0] = { + .start = 0xffcb0000, + .end = 0xffcb00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 211, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 212, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_mmcif_plat_data sh_mmcif_plat = { + .sup_pclk = 0x0f, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | + MMC_CAP_NONREMOVABLE, + .ocr = MMC_VDD_32_33 | MMC_VDD_33_34, + .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, +}; + +static struct platform_device sh_mmcif_device = { + .name = "sh_mmcif", + .id = 0, + .dev = { + .platform_data = &sh_mmcif_plat, + }, + .num_resources = ARRAY_SIZE(sh_mmcif_resources), + .resource = sh_mmcif_resources, +}; + +/* SDHI0 */ +static struct sh_mobile_sdhi_info sdhi_info = { + .dma_slave_tx = SHDMA_SLAVE_SDHI_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI_RX, + .tmio_caps = MMC_CAP_SD_HIGHSPEED, +}; + +static struct resource sdhi_resources[] = { + [0] = { + .start = 0xffe50000, + .end = 0xffe501ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi_resources), + .resource = sdhi_resources, + .id = 0, + .dev = { + .platform_data = &sdhi_info, + }, +}; + +static int usbhs0_get_id(struct platform_device *pdev) +{ + return USBHS_GADGET; +} + +static struct renesas_usbhs_platform_info usb0_data = { + .platform_callback = { + .get_id = usbhs0_get_id, + }, + .driver_param = { + .buswait_bwait = 5, + } +}; + +static struct resource usb0_resources[] = { + [0] = { + .start = 0xfe450000, + .end = 0xfe4501ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 50, + .end = 50, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb0_device = { + .name = "renesas_usbhs", + .id = 0, + .dev = { + .platform_data = &usb0_data, + }, + .num_resources = ARRAY_SIZE(usb0_resources), + .resource = usb0_resources, +}; + +static struct platform_device *sh7757lcr_devices[] __initdata = { + &heartbeat_device, + &sh7757_eth0_device, + &sh7757_eth1_device, + &sh7757_eth_giga0_device, + &sh7757_eth_giga1_device, + &sh_mmcif_device, + &sdhi_device, + &usb0_device, +}; + +static struct flash_platform_data spi_flash_data = { + .name = "m25p80", + .type = "m25px64", +}; + +static struct spi_board_info spi_board_info[] = { + { + .modalias = "m25p80", + .max_speed_hz = 25000000, + .bus_num = 0, + .chip_select = 1, + .platform_data = &spi_flash_data, + }, +}; + +static int __init sh7757lcr_devices_setup(void) +{ + /* RGMII (PTA) */ + gpio_request(GPIO_FN_ET0_MDC, NULL); + gpio_request(GPIO_FN_ET0_MDIO, NULL); + gpio_request(GPIO_FN_ET1_MDC, NULL); + gpio_request(GPIO_FN_ET1_MDIO, NULL); + + /* ONFI (PTB, PTZ) */ + gpio_request(GPIO_FN_ON_NRE, NULL); + gpio_request(GPIO_FN_ON_NWE, NULL); + gpio_request(GPIO_FN_ON_NWP, NULL); + gpio_request(GPIO_FN_ON_NCE0, NULL); + gpio_request(GPIO_FN_ON_R_B0, NULL); + gpio_request(GPIO_FN_ON_ALE, NULL); + gpio_request(GPIO_FN_ON_CLE, NULL); + + gpio_request(GPIO_FN_ON_DQ7, NULL); + gpio_request(GPIO_FN_ON_DQ6, NULL); + gpio_request(GPIO_FN_ON_DQ5, NULL); + gpio_request(GPIO_FN_ON_DQ4, NULL); + gpio_request(GPIO_FN_ON_DQ3, NULL); + gpio_request(GPIO_FN_ON_DQ2, NULL); + gpio_request(GPIO_FN_ON_DQ1, NULL); + gpio_request(GPIO_FN_ON_DQ0, NULL); + + /* IRQ8 to 0 (PTB, PTC) */ + gpio_request(GPIO_FN_IRQ8, NULL); + gpio_request(GPIO_FN_IRQ7, NULL); + gpio_request(GPIO_FN_IRQ6, NULL); + gpio_request(GPIO_FN_IRQ5, NULL); + gpio_request(GPIO_FN_IRQ4, NULL); + gpio_request(GPIO_FN_IRQ3, NULL); + gpio_request(GPIO_FN_IRQ2, NULL); + gpio_request(GPIO_FN_IRQ1, NULL); + gpio_request(GPIO_FN_IRQ0, NULL); + + /* SPI0 (PTD) */ + gpio_request(GPIO_FN_SP0_MOSI, NULL); + gpio_request(GPIO_FN_SP0_MISO, NULL); + gpio_request(GPIO_FN_SP0_SCK, NULL); + gpio_request(GPIO_FN_SP0_SCK_FB, NULL); + gpio_request(GPIO_FN_SP0_SS0, NULL); + gpio_request(GPIO_FN_SP0_SS1, NULL); + gpio_request(GPIO_FN_SP0_SS2, NULL); + gpio_request(GPIO_FN_SP0_SS3, NULL); + + /* RMII 0/1 (PTE, PTF) */ + gpio_request(GPIO_FN_RMII0_CRS_DV, NULL); + gpio_request(GPIO_FN_RMII0_TXD1, NULL); + gpio_request(GPIO_FN_RMII0_TXD0, NULL); + gpio_request(GPIO_FN_RMII0_TXEN, NULL); + gpio_request(GPIO_FN_RMII0_REFCLK, NULL); + gpio_request(GPIO_FN_RMII0_RXD1, NULL); + gpio_request(GPIO_FN_RMII0_RXD0, NULL); + gpio_request(GPIO_FN_RMII0_RX_ER, NULL); + gpio_request(GPIO_FN_RMII1_CRS_DV, NULL); + gpio_request(GPIO_FN_RMII1_TXD1, NULL); + gpio_request(GPIO_FN_RMII1_TXD0, NULL); + gpio_request(GPIO_FN_RMII1_TXEN, NULL); + gpio_request(GPIO_FN_RMII1_REFCLK, NULL); + gpio_request(GPIO_FN_RMII1_RXD1, NULL); + gpio_request(GPIO_FN_RMII1_RXD0, NULL); + gpio_request(GPIO_FN_RMII1_RX_ER, NULL); + + /* eMMC (PTG) */ + gpio_request(GPIO_FN_MMCCLK, NULL); + gpio_request(GPIO_FN_MMCCMD, NULL); + gpio_request(GPIO_FN_MMCDAT7, NULL); + gpio_request(GPIO_FN_MMCDAT6, NULL); + gpio_request(GPIO_FN_MMCDAT5, NULL); + gpio_request(GPIO_FN_MMCDAT4, NULL); + gpio_request(GPIO_FN_MMCDAT3, NULL); + gpio_request(GPIO_FN_MMCDAT2, NULL); + gpio_request(GPIO_FN_MMCDAT1, NULL); + gpio_request(GPIO_FN_MMCDAT0, NULL); + + /* LPC (PTG, PTH, PTQ, PTU) */ + gpio_request(GPIO_FN_SERIRQ, NULL); + gpio_request(GPIO_FN_LPCPD, NULL); + gpio_request(GPIO_FN_LDRQ, NULL); + gpio_request(GPIO_FN_WP, NULL); + gpio_request(GPIO_FN_FMS0, NULL); + gpio_request(GPIO_FN_LAD3, NULL); + gpio_request(GPIO_FN_LAD2, NULL); + gpio_request(GPIO_FN_LAD1, NULL); + gpio_request(GPIO_FN_LAD0, NULL); + gpio_request(GPIO_FN_LFRAME, NULL); + gpio_request(GPIO_FN_LRESET, NULL); + gpio_request(GPIO_FN_LCLK, NULL); + gpio_request(GPIO_FN_LGPIO7, NULL); + gpio_request(GPIO_FN_LGPIO6, NULL); + gpio_request(GPIO_FN_LGPIO5, NULL); + gpio_request(GPIO_FN_LGPIO4, NULL); + + /* SPI1 (PTH) */ + gpio_request(GPIO_FN_SP1_MOSI, NULL); + gpio_request(GPIO_FN_SP1_MISO, NULL); + gpio_request(GPIO_FN_SP1_SCK, NULL); + gpio_request(GPIO_FN_SP1_SCK_FB, NULL); + gpio_request(GPIO_FN_SP1_SS0, NULL); + gpio_request(GPIO_FN_SP1_SS1, NULL); + + /* SDHI (PTI) */ + gpio_request(GPIO_FN_SD_WP, NULL); + gpio_request(GPIO_FN_SD_CD, NULL); + gpio_request(GPIO_FN_SD_CLK, NULL); + gpio_request(GPIO_FN_SD_CMD, NULL); + gpio_request(GPIO_FN_SD_D3, NULL); + gpio_request(GPIO_FN_SD_D2, NULL); + gpio_request(GPIO_FN_SD_D1, NULL); + gpio_request(GPIO_FN_SD_D0, NULL); + + /* SCIF3/4 (PTJ, PTW) */ + gpio_request(GPIO_FN_RTS3, NULL); + gpio_request(GPIO_FN_CTS3, NULL); + gpio_request(GPIO_FN_TXD3, NULL); + gpio_request(GPIO_FN_RXD3, NULL); + gpio_request(GPIO_FN_RTS4, NULL); + gpio_request(GPIO_FN_RXD4, NULL); + gpio_request(GPIO_FN_TXD4, NULL); + gpio_request(GPIO_FN_CTS4, NULL); + + /* SERMUX (PTK, PTL, PTO, PTV) */ + gpio_request(GPIO_FN_COM2_TXD, NULL); + gpio_request(GPIO_FN_COM2_RXD, NULL); + gpio_request(GPIO_FN_COM2_RTS, NULL); + gpio_request(GPIO_FN_COM2_CTS, NULL); + gpio_request(GPIO_FN_COM2_DTR, NULL); + gpio_request(GPIO_FN_COM2_DSR, NULL); + gpio_request(GPIO_FN_COM2_DCD, NULL); + gpio_request(GPIO_FN_COM2_RI, NULL); + gpio_request(GPIO_FN_RAC_RXD, NULL); + gpio_request(GPIO_FN_RAC_RTS, NULL); + gpio_request(GPIO_FN_RAC_CTS, NULL); + gpio_request(GPIO_FN_RAC_DTR, NULL); + gpio_request(GPIO_FN_RAC_DSR, NULL); + gpio_request(GPIO_FN_RAC_DCD, NULL); + gpio_request(GPIO_FN_RAC_TXD, NULL); + gpio_request(GPIO_FN_COM1_TXD, NULL); + gpio_request(GPIO_FN_COM1_RXD, NULL); + gpio_request(GPIO_FN_COM1_RTS, NULL); + gpio_request(GPIO_FN_COM1_CTS, NULL); + + writeb(0x10, 0xfe470000); /* SMR0: SerMux mode 0 */ + + /* IIC (PTM, PTR, PTS) */ + gpio_request(GPIO_FN_SDA7, NULL); + gpio_request(GPIO_FN_SCL7, NULL); + gpio_request(GPIO_FN_SDA6, NULL); + gpio_request(GPIO_FN_SCL6, NULL); + gpio_request(GPIO_FN_SDA5, NULL); + gpio_request(GPIO_FN_SCL5, NULL); + gpio_request(GPIO_FN_SDA4, NULL); + gpio_request(GPIO_FN_SCL4, NULL); + gpio_request(GPIO_FN_SDA3, NULL); + gpio_request(GPIO_FN_SCL3, NULL); + gpio_request(GPIO_FN_SDA2, NULL); + gpio_request(GPIO_FN_SCL2, NULL); + gpio_request(GPIO_FN_SDA1, NULL); + gpio_request(GPIO_FN_SCL1, NULL); + gpio_request(GPIO_FN_SDA0, NULL); + gpio_request(GPIO_FN_SCL0, NULL); + + /* USB (PTN) */ + gpio_request(GPIO_FN_VBUS_EN, NULL); + gpio_request(GPIO_FN_VBUS_OC, NULL); + + /* SGPIO1/0 (PTN, PTO) */ + gpio_request(GPIO_FN_SGPIO1_CLK, NULL); + gpio_request(GPIO_FN_SGPIO1_LOAD, NULL); + gpio_request(GPIO_FN_SGPIO1_DI, NULL); + gpio_request(GPIO_FN_SGPIO1_DO, NULL); + gpio_request(GPIO_FN_SGPIO0_CLK, NULL); + gpio_request(GPIO_FN_SGPIO0_LOAD, NULL); + gpio_request(GPIO_FN_SGPIO0_DI, NULL); + gpio_request(GPIO_FN_SGPIO0_DO, NULL); + + /* WDT (PTN) */ + gpio_request(GPIO_FN_SUB_CLKIN, NULL); + + /* System (PTT) */ + gpio_request(GPIO_FN_STATUS1, NULL); + gpio_request(GPIO_FN_STATUS0, NULL); + + /* PWMX (PTT) */ + gpio_request(GPIO_FN_PWMX1, NULL); + gpio_request(GPIO_FN_PWMX0, NULL); + + /* R-SPI (PTV) */ + gpio_request(GPIO_FN_R_SPI_MOSI, NULL); + gpio_request(GPIO_FN_R_SPI_MISO, NULL); + gpio_request(GPIO_FN_R_SPI_RSPCK, NULL); + gpio_request(GPIO_FN_R_SPI_SSL0, NULL); + gpio_request(GPIO_FN_R_SPI_SSL1, NULL); + + /* EVC (PTV, PTW) */ + gpio_request(GPIO_FN_EVENT7, NULL); + gpio_request(GPIO_FN_EVENT6, NULL); + gpio_request(GPIO_FN_EVENT5, NULL); + gpio_request(GPIO_FN_EVENT4, NULL); + gpio_request(GPIO_FN_EVENT3, NULL); + gpio_request(GPIO_FN_EVENT2, NULL); + gpio_request(GPIO_FN_EVENT1, NULL); + gpio_request(GPIO_FN_EVENT0, NULL); + + /* LED for heartbeat */ + gpio_request(GPIO_PTU3, NULL); + gpio_direction_output(GPIO_PTU3, 1); + gpio_request(GPIO_PTU2, NULL); + gpio_direction_output(GPIO_PTU2, 1); + gpio_request(GPIO_PTU1, NULL); + gpio_direction_output(GPIO_PTU1, 1); + gpio_request(GPIO_PTU0, NULL); + gpio_direction_output(GPIO_PTU0, 1); + + /* control for MDIO of Gigabit Ethernet */ + gpio_request(GPIO_PTT4, NULL); + gpio_direction_output(GPIO_PTT4, 1); + + /* control for eMMC */ + gpio_request(GPIO_PTT7, NULL); /* eMMC_RST# */ + gpio_direction_output(GPIO_PTT7, 0); + gpio_request(GPIO_PTT6, NULL); /* eMMC_INDEX# */ + gpio_direction_output(GPIO_PTT6, 0); + gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */ + gpio_direction_output(GPIO_PTT5, 1); + + /* register SPI device information */ + spi_register_board_info(spi_board_info, + ARRAY_SIZE(spi_board_info)); + + /* General platform */ + return platform_add_devices(sh7757lcr_devices, + ARRAY_SIZE(sh7757lcr_devices)); +} +arch_initcall(sh7757lcr_devices_setup); + +/* Initialize IRQ setting */ +void __init init_sh7757lcr_IRQ(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ7654); + plat_irq_setup_pins(IRQ_MODE_IRQ3210); +} + +/* Initialize the board */ +static void __init sh7757lcr_setup(char **cmdline_p) +{ + printk(KERN_INFO "Renesas R0P7757LC0012RL support.\n"); +} + +static int sh7757lcr_mode_pins(void) +{ + int value = 0; + + /* These are the factory default settings of S3 (Low active). + * If you change these dip switches then you will need to + * adjust the values below as well. + */ + value |= MODE_PIN0; /* Clock Mode: 1 */ + + return value; +} + +/* The Machine Vector */ +static struct sh_machine_vector mv_sh7757lcr __initmv = { + .mv_name = "SH7757LCR", + .mv_setup = sh7757lcr_setup, + .mv_init_irq = init_sh7757lcr_IRQ, + .mv_mode_pins = sh7757lcr_mode_pins, +}; + diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c new file mode 100644 index 00000000000..d879848f3cd --- /dev/null +++ b/arch/sh/boards/board-sh7785lcr.c @@ -0,0 +1,376 @@ +/* + * Renesas Technology Corp. R0P7785LC0011RL Support. + * + * Copyright (C) 2008 Yoshihiro Shimoda + * Copyright (C) 2009 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/sm501.h> +#include <linux/sm501-regs.h> +#include <linux/fb.h> +#include <linux/mtd/physmap.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/i2c.h> +#include <linux/i2c-pca-platform.h> +#include <linux/i2c-algo-pca.h> +#include <linux/usb/r8a66597.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/errno.h> +#include <mach/sh7785lcr.h> +#include <cpu/sh7785.h> +#include <asm/heartbeat.h> +#include <asm/clock.h> + +/* + * NOTE: This board has 2 physical memory maps. + * Please look at include/asm-sh/sh7785lcr.h or hardware manual. + */ +static struct resource heartbeat_resource = { + .start = PLD_LEDCR, + .end = PLD_LEDCR, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +static struct mtd_partition nor_flash_partitions[] = { + { + .name = "loader", + .offset = 0x00000000, + .size = 512 * 1024, + }, + { + .name = "bootenv", + .offset = MTDPART_OFS_APPEND, + .size = 512 * 1024, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 4 * 1024 * 1024, + }, + { + .name = "data", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data nor_flash_data = { + .width = 4, + .parts = nor_flash_partitions, + .nr_parts = ARRAY_SIZE(nor_flash_partitions), +}; + +static struct resource nor_flash_resources[] = { + [0] = { + .start = NOR_FLASH_ADDR, + .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device nor_flash_device = { + .name = "physmap-flash", + .dev = { + .platform_data = &nor_flash_data, + }, + .num_resources = ARRAY_SIZE(nor_flash_resources), + .resource = nor_flash_resources, +}; + +static struct r8a66597_platdata r8a66597_data = { + .xtal = R8A66597_PLATDATA_XTAL_12MHZ, + .vif = 1, +}; + +static struct resource r8a66597_usb_host_resources[] = { + [0] = { + .start = R8A66597_ADDR, + .end = R8A66597_ADDR + R8A66597_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 2, + .end = 2, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, +}; + +static struct platform_device r8a66597_usb_host_device = { + .name = "r8a66597_hcd", + .id = -1, + .dev = { + .dma_mask = NULL, + .coherent_dma_mask = 0xffffffff, + .platform_data = &r8a66597_data, + }, + .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), + .resource = r8a66597_usb_host_resources, +}; + +static struct resource sm501_resources[] = { + [0] = { + .start = SM107_MEM_ADDR, + .end = SM107_MEM_ADDR + SM107_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SM107_REG_ADDR, + .end = SM107_REG_ADDR + SM107_REG_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 10, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fb_videomode sm501_default_mode_crt = { + .pixclock = 35714, /* 28MHz */ + .xres = 640, + .yres = 480, + .left_margin = 105, + .right_margin = 16, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 39, + .vsync_len = 2, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}; + +static struct fb_videomode sm501_default_mode_pnl = { + .pixclock = 40000, /* 25MHz */ + .xres = 640, + .yres = 480, + .left_margin = 2, + .right_margin = 16, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 39, + .vsync_len = 2, + .sync = 0, +}; + +static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = { + .def_bpp = 16, + .def_mode = &sm501_default_mode_pnl, + .flags = SM501FB_FLAG_USE_INIT_MODE | + SM501FB_FLAG_USE_HWCURSOR | + SM501FB_FLAG_USE_HWACCEL | + SM501FB_FLAG_DISABLE_AT_EXIT | + SM501FB_FLAG_PANEL_NO_VBIASEN, +}; + +static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = { + .def_bpp = 16, + .def_mode = &sm501_default_mode_crt, + .flags = SM501FB_FLAG_USE_INIT_MODE | + SM501FB_FLAG_USE_HWCURSOR | + SM501FB_FLAG_USE_HWACCEL | + SM501FB_FLAG_DISABLE_AT_EXIT, +}; + +static struct sm501_platdata_fb sm501_fb_pdata = { + .fb_route = SM501_FB_OWN, + .fb_crt = &sm501_pdata_fbsub_crt, + .fb_pnl = &sm501_pdata_fbsub_pnl, +}; + +static struct sm501_initdata sm501_initdata = { + .gpio_high = { + .set = 0x00001fe0, + .mask = 0x0, + }, + .devices = 0, + .mclk = 84 * 1000000, + .m1xclk = 112 * 1000000, +}; + +static struct sm501_platdata sm501_platform_data = { + .init = &sm501_initdata, + .fb = &sm501_fb_pdata, +}; + +static struct platform_device sm501_device = { + .name = "sm501", + .id = -1, + .dev = { + .platform_data = &sm501_platform_data, + }, + .num_resources = ARRAY_SIZE(sm501_resources), + .resource = sm501_resources, +}; + +static struct resource i2c_proto_resources[] = { + [0] = { + .start = PCA9564_PROTO_32BIT_ADDR, + .end = PCA9564_PROTO_32BIT_ADDR + PCA9564_SIZE - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, + }, + [1] = { + .start = 12, + .end = 12, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource i2c_resources[] = { + [0] = { + .start = PCA9564_ADDR, + .end = PCA9564_ADDR + PCA9564_SIZE - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, + }, + [1] = { + .start = 12, + .end = 12, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct i2c_pca9564_pf_platform_data i2c_platform_data = { + .gpio = 0, + .i2c_clock_speed = I2C_PCA_CON_330kHz, + .timeout = HZ, +}; + +static struct platform_device i2c_device = { + .name = "i2c-pca-platform", + .id = -1, + .dev = { + .platform_data = &i2c_platform_data, + }, + .num_resources = ARRAY_SIZE(i2c_resources), + .resource = i2c_resources, +}; + +static struct platform_device *sh7785lcr_devices[] __initdata = { + &heartbeat_device, + &nor_flash_device, + &r8a66597_usb_host_device, + &sm501_device, + &i2c_device, +}; + +static struct i2c_board_info __initdata sh7785lcr_i2c_devices[] = { + { + I2C_BOARD_INFO("r2025sd", 0x32), + }, +}; + +static int __init sh7785lcr_devices_setup(void) +{ + i2c_register_board_info(0, sh7785lcr_i2c_devices, + ARRAY_SIZE(sh7785lcr_i2c_devices)); + + if (mach_is_sh7785lcr_pt()) { + i2c_device.resource = i2c_proto_resources; + i2c_device.num_resources = ARRAY_SIZE(i2c_proto_resources); + } + + return platform_add_devices(sh7785lcr_devices, + ARRAY_SIZE(sh7785lcr_devices)); +} +device_initcall(sh7785lcr_devices_setup); + +/* Initialize IRQ setting */ +void __init init_sh7785lcr_IRQ(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ7654); + plat_irq_setup_pins(IRQ_MODE_IRQ3210); +} + +static int sh7785lcr_clk_init(void) +{ + struct clk *clk; + int ret; + + clk = clk_get(NULL, "extal"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + ret = clk_set_rate(clk, 33333333); + clk_put(clk); + + return ret; +} + +static void sh7785lcr_power_off(void) +{ + unsigned char *p; + + p = ioremap(PLD_POFCR, PLD_POFCR + 1); + if (!p) { + printk(KERN_ERR "%s: ioremap error.\n", __func__); + return; + } + *p = 0x01; + iounmap(p); + set_bl_bit(); + while (1) + cpu_relax(); +} + +/* Initialize the board */ +static void __init sh7785lcr_setup(char **cmdline_p) +{ + void __iomem *sm501_reg; + + printk(KERN_INFO "Renesas Technology Corp. R0P7785LC0011RL support.\n"); + + pm_power_off = sh7785lcr_power_off; + + /* sm501 DRAM configuration */ + sm501_reg = ioremap_nocache(SM107_REG_ADDR, SM501_DRAM_CONTROL); + if (!sm501_reg) { + printk(KERN_ERR "%s: ioremap error.\n", __func__); + return; + } + + writel(0x000307c2, sm501_reg + SM501_DRAM_CONTROL); + iounmap(sm501_reg); +} + +/* Return the board specific boot mode pin configuration */ +static int sh7785lcr_mode_pins(void) +{ + int value = 0; + + /* These are the factory default settings of S1 and S2. + * If you change these dip switches then you will need to + * adjust the values below as well. + */ + value |= MODE_PIN4; /* Clock Mode 16 */ + value |= MODE_PIN5; /* 32-bit Area0 bus width */ + value |= MODE_PIN6; /* 32-bit Area0 bus width */ + value |= MODE_PIN7; /* Area 0 SRAM interface [fixed] */ + value |= MODE_PIN8; /* Little Endian */ + value |= MODE_PIN9; /* Master Mode */ + value |= MODE_PIN14; /* No PLL step-up */ + + return value; +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_sh7785lcr __initmv = { + .mv_name = "SH7785LCR", + .mv_setup = sh7785lcr_setup, + .mv_clk_init = sh7785lcr_clk_init, + .mv_init_irq = init_sh7785lcr_IRQ, + .mv_mode_pins = sh7785lcr_mode_pins, +}; + diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c new file mode 100644 index 00000000000..325bed53b87 --- /dev/null +++ b/arch/sh/boards/board-shmin.c @@ -0,0 +1,34 @@ +/* + * arch/sh/boards/shmin/setup.c + * + * Copyright (C) 2006 Takashi YOSHII + * + * SHMIN Support. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/machvec.h> +#include <mach/shmin.h> +#include <asm/clock.h> +#include <asm/io.h> + +#define PFC_PHCR 0xa400010eUL +#define INTC_ICR1 0xa4000010UL + +static void __init init_shmin_irq(void) +{ + __raw_writew(0x2a00, PFC_PHCR); // IRQ0-3=IRQ + __raw_writew(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + +static void __init shmin_setup(char **cmdline_p) +{ + __set_io_port_base(SHMIN_IO_BASE); +} + +static struct sh_machine_vector mv_shmin __initmv = { + .mv_name = "SHMIN", + .mv_setup = shmin_setup, + .mv_init_irq = init_shmin_irq, +}; diff --git a/arch/sh/boards/board-titan.c b/arch/sh/boards/board-titan.c new file mode 100644 index 00000000000..94c36c7bc0b --- /dev/null +++ b/arch/sh/boards/board-titan.c @@ -0,0 +1,24 @@ +/* + * arch/sh/boards/titan/setup.c - Setup for Titan + * + * Copyright (C) 2006 Jamie Lenehan + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <mach/titan.h> +#include <asm/io.h> + +static void __init init_titan_irq(void) +{ + /* enable individual interrupt mode for externals */ + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + +static struct sh_machine_vector mv_titan __initmv = { + .mv_name = "Titan", + .mv_init_irq = init_titan_irq, +}; diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c new file mode 100644 index 00000000000..24e3316c5c1 --- /dev/null +++ b/arch/sh/boards/board-urquell.c @@ -0,0 +1,220 @@ +/* + * Renesas Technology Corp. SH7786 Urquell Support. + * + * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> + * Copyright (C) 2009, 2010 Paul Mundt + * + * Based on board-sh7785lcr.c + * Copyright (C) 2008 Yoshihiro Shimoda + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/smc91x.h> +#include <linux/mtd/physmap.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/irq.h> +#include <linux/clk.h> +#include <mach/urquell.h> +#include <cpu/sh7786.h> +#include <asm/heartbeat.h> +#include <asm/sizes.h> +#include <asm/smp-ops.h> + +/* + * bit 1234 5678 + *---------------------------- + * SW1 0101 0010 -> Pck 33MHz version + * (1101 0010) Pck 66MHz version + * SW2 0x1x xxxx -> little endian + * 29bit mode + * SW47 0001 1000 -> CS0 : on-board flash + * CS1 : SRAM, registers, LAN, PCMCIA + * 38400 bps for SCIF1 + * + * Address + * 0x00000000 - 0x04000000 (CS0) Nor Flash + * 0x04000000 - 0x04200000 (CS1) SRAM + * 0x05000000 - 0x05800000 (CS1) on board register + * 0x05800000 - 0x06000000 (CS1) LAN91C111 + * 0x06000000 - 0x06400000 (CS1) PCMCIA + * 0x08000000 - 0x10000000 (CS2-CS3) DDR3 + * 0x10000000 - 0x14000000 (CS4) PCIe + * 0x14000000 - 0x14800000 (CS5) Core0 LRAM/URAM + * 0x14800000 - 0x15000000 (CS5) Core1 LRAM/URAM + * 0x18000000 - 0x1C000000 (CS6) ATA/NAND-Flash + * 0x1C000000 - (CS7) SH7786 Control register + */ + +/* HeartBeat */ +static struct resource heartbeat_resource = { + .start = BOARDREG(SLEDR), + .end = BOARDREG(SLEDR), + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +/* LAN91C111 */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, +}; + +static struct resource smc91x_eth_resources[] = { + [0] = { + .name = "SMC91C111" , + .start = 0x05800300, + .end = 0x0580030f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 11, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_eth_device = { + .name = "smc91x", + .num_resources = ARRAY_SIZE(smc91x_eth_resources), + .resource = smc91x_eth_resources, + .dev = { + .platform_data = &smc91x_info, + }, +}; + +/* Nor Flash */ +static struct mtd_partition nor_flash_partitions[] = { + { + .name = "loader", + .offset = 0x00000000, + .size = SZ_512K, + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, + { + .name = "bootenv", + .offset = MTDPART_OFS_APPEND, + .size = SZ_512K, + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_4M, + }, + { + .name = "data", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data nor_flash_data = { + .width = 2, + .parts = nor_flash_partitions, + .nr_parts = ARRAY_SIZE(nor_flash_partitions), +}; + +static struct resource nor_flash_resources[] = { + [0] = { + .start = NOR_FLASH_ADDR, + .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device nor_flash_device = { + .name = "physmap-flash", + .dev = { + .platform_data = &nor_flash_data, + }, + .num_resources = ARRAY_SIZE(nor_flash_resources), + .resource = nor_flash_resources, +}; + +static struct platform_device *urquell_devices[] __initdata = { + &heartbeat_device, + &smc91x_eth_device, + &nor_flash_device, +}; + +static int __init urquell_devices_setup(void) +{ + /* USB */ + gpio_request(GPIO_FN_USB_OVC0, NULL); + gpio_request(GPIO_FN_USB_PENC0, NULL); + + /* enable LAN */ + __raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001, + UBOARDREG(IRL2MSKR)); + + return platform_add_devices(urquell_devices, + ARRAY_SIZE(urquell_devices)); +} +device_initcall(urquell_devices_setup); + +static void urquell_power_off(void) +{ + __raw_writew(0xa5a5, UBOARDREG(SRSTR)); +} + +static void __init urquell_init_irq(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); +} + +static int urquell_mode_pins(void) +{ + return __raw_readw(UBOARDREG(MDSWMR)); +} + +static int urquell_clk_init(void) +{ + struct clk *clk; + int ret; + + /* + * Only handle the EXTAL case, anyone interfacing a crystal + * resonator will need to provide their own input clock. + */ + if (test_mode_pin(MODE_PIN9)) + return -EINVAL; + + clk = clk_get(NULL, "extal"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + ret = clk_set_rate(clk, 33333333); + clk_put(clk); + + return ret; +} + +/* Initialize the board */ +static void __init urquell_setup(char **cmdline_p) +{ + printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n"); + + pm_power_off = urquell_power_off; + + register_smp_ops(&shx3_smp_ops); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_urquell __initmv = { + .mv_name = "Urquell", + .mv_setup = urquell_setup, + .mv_init_irq = urquell_init_irq, + .mv_mode_pins = urquell_mode_pins, + .mv_clk_init = urquell_clk_init, +}; diff --git a/arch/sh/boards/mach-ap325rxa/Makefile b/arch/sh/boards/mach-ap325rxa/Makefile new file mode 100644 index 00000000000..4cf1774d261 --- /dev/null +++ b/arch/sh/boards/mach-ap325rxa/Makefile @@ -0,0 +1,2 @@ +obj-y := setup.o sdram.o + diff --git a/arch/sh/boards/mach-ap325rxa/sdram.S b/arch/sh/boards/mach-ap325rxa/sdram.S new file mode 100644 index 00000000000..db24fbed4fc --- /dev/null +++ b/arch/sh/boards/mach-ap325rxa/sdram.S @@ -0,0 +1,69 @@ +/* + * AP325RXA sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(ap325rxa_sdram_enter_start) + + /* SBSC: disable power down and put in self-refresh mode */ + mov.l 1f, r4 + mov.l 2f, r1 + mov.l @r4, r2 + or r1, r2 + mov.l 3f, r3 + and r3, r2 + mov.l r2, @r4 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +2: .long 0x00000400 +3: .long 0xffff7fff +ENTRY(ap325rxa_sdram_enter_end) + + .balign 4 +ENTRY(ap325rxa_sdram_leave_start) + + /* SBSC: set auto-refresh mode */ + mov.l 1f, r4 + mov.l @r4, r0 + mov.l 4f, r1 + and r1, r0 + mov.l r0, @r4 + mov.l 6f, r4 + mov.l 8f, r0 + mov.l @r4, r1 + mov #-1, r4 + add r4, r1 + or r1, r0 + mov.l 7f, r1 + mov.l r0, @r1 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +4: .long 0xfffffbff +6: .long 0xfe40001c /* RTCOR */ +7: .long 0xfe400018 /* RTCNT */ +8: .long 0xa55a0000 +ENTRY(ap325rxa_sdram_leave_end) diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c new file mode 100644 index 00000000000..ebd0f818a25 --- /dev/null +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -0,0 +1,681 @@ +/* + * Renesas - AP-325RXA + * (Compatible with Algo System ., LTD. - AP-320A) + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Author : Yusuke Goda <goda.yuske@renesas.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/sh_flctl.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/smsc911x.h> +#include <linux/gpio.h> +#include <linux/videodev2.h> +#include <media/ov772x.h> +#include <media/soc_camera.h> +#include <media/soc_camera_platform.h> +#include <media/sh_mobile_ceu.h> +#include <video/sh_mobile_lcdc.h> +#include <asm/io.h> +#include <asm/clock.h> +#include <asm/suspend.h> +#include <cpu/sh7723.h> + +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT, +}; + +static struct resource smsc9118_resources[] = { + [0] = { + .start = 0xb6080000, + .end = 0xb60fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 35, + .end = 35, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device smsc9118_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc9118_resources), + .resource = smsc9118_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +/* + * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF). + * If this area erased, this board can not boot. + */ +static struct mtd_partition ap325rxa_nor_flash_partitions[] = { + { + .name = "uboot", + .offset = 0, + .size = (1 * 1024 * 1024), + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = (2 * 1024 * 1024), + }, { + .name = "free-area0", + .offset = MTDPART_OFS_APPEND, + .size = ((7 * 1024 * 1024) + (512 * 1024)), + }, { + .name = "CPLD-Data", + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, /* Read-only */ + .size = (1024 * 128 * 2), + }, { + .name = "free-area1", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data ap325rxa_nor_flash_data = { + .width = 2, + .parts = ap325rxa_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(ap325rxa_nor_flash_partitions), +}; + +static struct resource ap325rxa_nor_flash_resources[] = { + [0] = { + .name = "NOR Flash", + .start = 0x00000000, + .end = 0x00ffffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device ap325rxa_nor_flash_device = { + .name = "physmap-flash", + .resource = ap325rxa_nor_flash_resources, + .num_resources = ARRAY_SIZE(ap325rxa_nor_flash_resources), + .dev = { + .platform_data = &ap325rxa_nor_flash_data, + }, +}; + +static struct mtd_partition nand_partition_info[] = { + { + .name = "nand_data", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct resource nand_flash_resources[] = { + [0] = { + .start = 0xa4530000, + .end = 0xa45300ff, + .flags = IORESOURCE_MEM, + } +}; + +static struct sh_flctl_platform_data nand_flash_data = { + .parts = nand_partition_info, + .nr_parts = ARRAY_SIZE(nand_partition_info), + .flcmncr_val = FCKSEL_E | TYPESEL_SET | NANWF_E, + .has_hwecc = 1, +}; + +static struct platform_device nand_flash_device = { + .name = "sh_flctl", + .resource = nand_flash_resources, + .num_resources = ARRAY_SIZE(nand_flash_resources), + .dev = { + .platform_data = &nand_flash_data, + }, +}; + +#define FPGA_LCDREG 0xB4100180 +#define FPGA_BKLREG 0xB4100212 +#define FPGA_LCDREG_VAL 0x0018 +#define PORT_MSELCRB 0xA4050182 +#define PORT_HIZCRC 0xA405015C +#define PORT_DRVCRA 0xA405018A +#define PORT_DRVCRB 0xA405018C + +static int ap320_wvga_set_brightness(void *board_data, int brightness) +{ + if (brightness) { + gpio_set_value(GPIO_PTS3, 0); + __raw_writew(0x100, FPGA_BKLREG); + } else { + __raw_writew(0, FPGA_BKLREG); + gpio_set_value(GPIO_PTS3, 1); + } + + return 0; +} + +static int ap320_wvga_get_brightness(void *board_data) +{ + return gpio_get_value(GPIO_PTS3); +} + +static void ap320_wvga_power_on(void *board_data, struct fb_info *info) +{ + msleep(100); + + /* ASD AP-320/325 LCD ON */ + __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG); +} + +static void ap320_wvga_power_off(void *board_data) +{ + /* ASD AP-320/325 LCD OFF */ + __raw_writew(0, FPGA_LCDREG); +} + +static const struct fb_videomode ap325rxa_lcdc_modes[] = { + { + .name = "LB070WV1", + .xres = 800, + .yres = 480, + .left_margin = 32, + .right_margin = 160, + .hsync_len = 8, + .upper_margin = 63, + .lower_margin = 80, + .vsync_len = 1, + .sync = 0, /* hsync and vsync are active low */ + }, +}; + +static struct sh_mobile_lcdc_info lcdc_info = { + .clock_source = LCDC_CLK_EXTERNAL, + .ch[0] = { + .chan = LCDC_CHAN_MAINLCD, + .fourcc = V4L2_PIX_FMT_RGB565, + .interface_type = RGB18, + .clock_divider = 1, + .lcd_cfg = ap325rxa_lcdc_modes, + .num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes), + .lcd_size_cfg = { /* 7.0 inch */ + .width = 152, + .height = 91, + }, + .board_cfg = { + .display_on = ap320_wvga_power_on, + .display_off = ap320_wvga_power_off, + .set_brightness = ap320_wvga_set_brightness, + .get_brightness = ap320_wvga_get_brightness, + }, + .bl_info = { + .name = "sh_mobile_lcdc_bl", + .max_brightness = 1, + }, + } +}; + +static struct resource lcdc_resources[] = { + [0] = { + .name = "LCDC", + .start = 0xfe940000, /* P4-only space */ + .end = 0xfe942fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 28, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device lcdc_device = { + .name = "sh_mobile_lcdc_fb", + .num_resources = ARRAY_SIZE(lcdc_resources), + .resource = lcdc_resources, + .dev = { + .platform_data = &lcdc_info, + }, +}; + +static void camera_power(int val) +{ + gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */ + mdelay(10); +} + +#ifdef CONFIG_I2C +/* support for the old ncm03j camera */ +static unsigned char camera_ncm03j_magic[] = +{ + 0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8, + 0x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36, + 0x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F, + 0x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55, + 0x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12, + 0x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0, + 0x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F, + 0x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A, + 0x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A, + 0xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A, + 0x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56, + 0xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37, + 0xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A, + 0xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56, + 0x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC, + 0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F, +}; + +static int camera_probe(void) +{ + struct i2c_adapter *a = i2c_get_adapter(0); + struct i2c_msg msg; + int ret; + + if (!a) + return -ENODEV; + + camera_power(1); + msg.addr = 0x6e; + msg.buf = camera_ncm03j_magic; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + camera_power(0); + + return ret; +} + +static int camera_set_capture(struct soc_camera_platform_info *info, + int enable) +{ + struct i2c_adapter *a = i2c_get_adapter(0); + struct i2c_msg msg; + int ret = 0; + int i; + + camera_power(0); + if (!enable) + return 0; /* no disable for now */ + + camera_power(1); + for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) { + u_int8_t buf[8]; + + msg.addr = 0x6e; + msg.buf = buf; + msg.len = 2; + msg.flags = 0; + + buf[0] = camera_ncm03j_magic[i]; + buf[1] = camera_ncm03j_magic[i + 1]; + + ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1); + } + + return ret; +} + +static int ap325rxa_camera_add(struct soc_camera_device *icd); +static void ap325rxa_camera_del(struct soc_camera_device *icd); + +static struct soc_camera_platform_info camera_info = { + .format_name = "UYVY", + .format_depth = 16, + .format = { + .code = V4L2_MBUS_FMT_UYVY8_2X8, + .colorspace = V4L2_COLORSPACE_SMPTE170M, + .field = V4L2_FIELD_NONE, + .width = 640, + .height = 480, + }, + .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | + V4L2_MBUS_DATA_ACTIVE_HIGH, + .mbus_type = V4L2_MBUS_PARALLEL, + .set_capture = camera_set_capture, +}; + +static struct soc_camera_link camera_link = { + .bus_id = 0, + .add_device = ap325rxa_camera_add, + .del_device = ap325rxa_camera_del, + .module_name = "soc_camera_platform", + .priv = &camera_info, +}; + +static struct platform_device *camera_device; + +static void ap325rxa_camera_release(struct device *dev) +{ + soc_camera_platform_release(&camera_device); +} + +static int ap325rxa_camera_add(struct soc_camera_device *icd) +{ + int ret = soc_camera_platform_add(icd, &camera_device, &camera_link, + ap325rxa_camera_release, 0); + if (ret < 0) + return ret; + + ret = camera_probe(); + if (ret < 0) + soc_camera_platform_del(icd, camera_device, &camera_link); + + return ret; +} + +static void ap325rxa_camera_del(struct soc_camera_device *icd) +{ + soc_camera_platform_del(icd, camera_device, &camera_link); +} +#endif /* CONFIG_I2C */ + +static int ov7725_power(struct device *dev, int mode) +{ + camera_power(0); + if (mode) + camera_power(1); + + return 0; +} + +static struct sh_mobile_ceu_info sh_mobile_ceu_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, +}; + +static struct resource ceu_resources[] = { + [0] = { + .name = "CEU", + .start = 0xfe910000, + .end = 0xfe91009f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 52, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device ceu_device = { + .name = "sh_mobile_ceu", + .id = 0, /* "ceu0" clock */ + .num_resources = ARRAY_SIZE(ceu_resources), + .resource = ceu_resources, + .dev = { + .platform_data = &sh_mobile_ceu_info, + }, +}; + +static struct resource sdhi0_cn3_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 100, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_mobile_sdhi_info sdhi0_cn3_data = { + .tmio_caps = MMC_CAP_SDIO_IRQ, +}; + +static struct platform_device sdhi0_cn3_device = { + .name = "sh_mobile_sdhi", + .id = 0, /* "sdhi0" clock */ + .num_resources = ARRAY_SIZE(sdhi0_cn3_resources), + .resource = sdhi0_cn3_resources, + .dev = { + .platform_data = &sdhi0_cn3_data, + }, +}; + +static struct resource sdhi1_cn7_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0x04cf0000, + .end = 0x04cf00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 23, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_mobile_sdhi_info sdhi1_cn7_data = { + .tmio_caps = MMC_CAP_SDIO_IRQ, +}; + +static struct platform_device sdhi1_cn7_device = { + .name = "sh_mobile_sdhi", + .id = 1, /* "sdhi1" clock */ + .num_resources = ARRAY_SIZE(sdhi1_cn7_resources), + .resource = sdhi1_cn7_resources, + .dev = { + .platform_data = &sdhi1_cn7_data, + }, +}; + +static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = { + { + I2C_BOARD_INFO("pcf8563", 0x51), + }, +}; + +static struct i2c_board_info ap325rxa_i2c_camera[] = { + { + I2C_BOARD_INFO("ov772x", 0x21), + }, +}; + +static struct ov772x_camera_info ov7725_info = { + .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, + .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), +}; + +static struct soc_camera_link ov7725_link = { + .bus_id = 0, + .power = ov7725_power, + .board_info = &ap325rxa_i2c_camera[0], + .i2c_adapter_id = 0, + .priv = &ov7725_info, +}; + +static struct platform_device ap325rxa_camera[] = { + { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &ov7725_link, + }, + }, { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &camera_link, + }, + }, +}; + +static struct platform_device *ap325rxa_devices[] __initdata = { + &smsc9118_device, + &ap325rxa_nor_flash_device, + &lcdc_device, + &ceu_device, + &nand_flash_device, + &sdhi0_cn3_device, + &sdhi1_cn7_device, + &ap325rxa_camera[0], + &ap325rxa_camera[1], +}; + +extern char ap325rxa_sdram_enter_start; +extern char ap325rxa_sdram_enter_end; +extern char ap325rxa_sdram_leave_start; +extern char ap325rxa_sdram_leave_end; + +static int __init ap325rxa_devices_setup(void) +{ + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + &ap325rxa_sdram_enter_start, + &ap325rxa_sdram_enter_end, + &ap325rxa_sdram_leave_start, + &ap325rxa_sdram_leave_end); + + /* LD3 and LD4 LEDs */ + gpio_request(GPIO_PTX5, NULL); /* RUN */ + gpio_direction_output(GPIO_PTX5, 1); + gpio_export(GPIO_PTX5, 0); + + gpio_request(GPIO_PTX4, NULL); /* INDICATOR */ + gpio_direction_output(GPIO_PTX4, 0); + gpio_export(GPIO_PTX4, 0); + + /* SW1 input */ + gpio_request(GPIO_PTF7, NULL); /* MODE */ + gpio_direction_input(GPIO_PTF7); + gpio_export(GPIO_PTF7, 0); + + /* LCDC */ + gpio_request(GPIO_FN_LCDD15, NULL); + gpio_request(GPIO_FN_LCDD14, NULL); + gpio_request(GPIO_FN_LCDD13, NULL); + gpio_request(GPIO_FN_LCDD12, NULL); + gpio_request(GPIO_FN_LCDD11, NULL); + gpio_request(GPIO_FN_LCDD10, NULL); + gpio_request(GPIO_FN_LCDD9, NULL); + gpio_request(GPIO_FN_LCDD8, NULL); + gpio_request(GPIO_FN_LCDD7, NULL); + gpio_request(GPIO_FN_LCDD6, NULL); + gpio_request(GPIO_FN_LCDD5, NULL); + gpio_request(GPIO_FN_LCDD4, NULL); + gpio_request(GPIO_FN_LCDD3, NULL); + gpio_request(GPIO_FN_LCDD2, NULL); + gpio_request(GPIO_FN_LCDD1, NULL); + gpio_request(GPIO_FN_LCDD0, NULL); + gpio_request(GPIO_FN_LCDLCLK_PTR, NULL); + gpio_request(GPIO_FN_LCDDCK, NULL); + gpio_request(GPIO_FN_LCDVEPWC, NULL); + gpio_request(GPIO_FN_LCDVCPWC, NULL); + gpio_request(GPIO_FN_LCDVSYN, NULL); + gpio_request(GPIO_FN_LCDHSYN, NULL); + gpio_request(GPIO_FN_LCDDISP, NULL); + gpio_request(GPIO_FN_LCDDON, NULL); + + /* LCD backlight */ + gpio_request(GPIO_PTS3, NULL); + gpio_direction_output(GPIO_PTS3, 1); + + /* CEU */ + gpio_request(GPIO_FN_VIO_CLK2, NULL); + gpio_request(GPIO_FN_VIO_VD2, NULL); + gpio_request(GPIO_FN_VIO_HD2, NULL); + gpio_request(GPIO_FN_VIO_FLD, NULL); + gpio_request(GPIO_FN_VIO_CKO, NULL); + gpio_request(GPIO_FN_VIO_D15, NULL); + gpio_request(GPIO_FN_VIO_D14, NULL); + gpio_request(GPIO_FN_VIO_D13, NULL); + gpio_request(GPIO_FN_VIO_D12, NULL); + gpio_request(GPIO_FN_VIO_D11, NULL); + gpio_request(GPIO_FN_VIO_D10, NULL); + gpio_request(GPIO_FN_VIO_D9, NULL); + gpio_request(GPIO_FN_VIO_D8, NULL); + + gpio_request(GPIO_PTZ7, NULL); + gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */ + gpio_request(GPIO_PTZ6, NULL); + gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */ + gpio_request(GPIO_PTZ5, NULL); + gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */ + gpio_request(GPIO_PTZ4, NULL); + gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ + + __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB); + + /* FLCTL */ + gpio_request(GPIO_FN_FCE, NULL); + gpio_request(GPIO_FN_NAF7, NULL); + gpio_request(GPIO_FN_NAF6, NULL); + gpio_request(GPIO_FN_NAF5, NULL); + gpio_request(GPIO_FN_NAF4, NULL); + gpio_request(GPIO_FN_NAF3, NULL); + gpio_request(GPIO_FN_NAF2, NULL); + gpio_request(GPIO_FN_NAF1, NULL); + gpio_request(GPIO_FN_NAF0, NULL); + gpio_request(GPIO_FN_FCDE, NULL); + gpio_request(GPIO_FN_FOE, NULL); + gpio_request(GPIO_FN_FSC, NULL); + gpio_request(GPIO_FN_FWE, NULL); + gpio_request(GPIO_FN_FRB, NULL); + + __raw_writew(0, PORT_HIZCRC); + __raw_writew(0xFFFF, PORT_DRVCRA); + __raw_writew(0xFFFF, PORT_DRVCRB); + + platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20); + + /* SDHI0 - CN3 - SD CARD */ + gpio_request(GPIO_FN_SDHI0CD_PTD, NULL); + gpio_request(GPIO_FN_SDHI0WP_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D3_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D2_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D1_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D0_PTD, NULL); + gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL); + gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL); + + /* SDHI1 - CN7 - MICRO SD CARD */ + gpio_request(GPIO_FN_SDHI1CD, NULL); + gpio_request(GPIO_FN_SDHI1D3, NULL); + gpio_request(GPIO_FN_SDHI1D2, NULL); + gpio_request(GPIO_FN_SDHI1D1, NULL); + gpio_request(GPIO_FN_SDHI1D0, NULL); + gpio_request(GPIO_FN_SDHI1CMD, NULL); + gpio_request(GPIO_FN_SDHI1CLK, NULL); + + i2c_register_board_info(0, ap325rxa_i2c_devices, + ARRAY_SIZE(ap325rxa_i2c_devices)); + + return platform_add_devices(ap325rxa_devices, + ARRAY_SIZE(ap325rxa_devices)); +} +arch_initcall(ap325rxa_devices_setup); + +/* Return the board specific boot mode pin configuration */ +static int ap325rxa_mode_pins(void) +{ + /* MD0=0, MD1=0, MD2=0: Clock Mode 0 + * MD3=0: 16-bit Area0 Bus Width + * MD5=1: Little Endian + * TSTMD=1, MD8=1: Test Mode Disabled + */ + return MODE_PIN5 | MODE_PIN8; +} + +static struct sh_machine_vector mv_ap325rxa __initmv = { + .mv_name = "AP-325RXA", + .mv_mode_pins = ap325rxa_mode_pins, +}; diff --git a/arch/sh/boards/mach-cayman/Makefile b/arch/sh/boards/mach-cayman/Makefile new file mode 100644 index 00000000000..00fa3eaecb1 --- /dev/null +++ b/arch/sh/boards/mach-cayman/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the Hitachi Cayman specific parts of the kernel +# +obj-y := setup.o irq.o panic.o diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c new file mode 100644 index 00000000000..724e8b7271f --- /dev/null +++ b/arch/sh/boards/mach-cayman/irq.c @@ -0,0 +1,157 @@ +/* + * arch/sh/mach-cayman/irq.c - SH-5 Cayman Interrupt Support + * + * This file handles the board specific parts of the Cayman interrupt system + * + * Copyright (C) 2002 Stuart Menefy + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/signal.h> +#include <cpu/irq.h> +#include <asm/page.h> + +/* Setup for the SMSC FDC37C935 / LAN91C100FD */ +#define SMSC_IRQ IRQ_IRL1 + +/* Setup for PCI Bus 2, which transmits interrupts via the EPLD */ +#define PCI2_IRQ IRQ_IRL3 + +unsigned long epld_virt; + +#define EPLD_BASE 0x04002000 +#define EPLD_STATUS_BASE (epld_virt + 0x10) +#define EPLD_MASK_BASE (epld_virt + 0x20) + +/* Note the SMSC SuperIO chip and SMSC LAN chip interrupts are all muxed onto + the same SH-5 interrupt */ + +static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id) +{ + printk(KERN_INFO "CAYMAN: spurious SMSC interrupt\n"); + return IRQ_NONE; +} + +static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id) +{ + printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq); + return IRQ_NONE; +} + +static struct irqaction cayman_action_smsc = { + .name = "Cayman SMSC Mux", + .handler = cayman_interrupt_smsc, +}; + +static struct irqaction cayman_action_pci2 = { + .name = "Cayman PCI2 Mux", + .handler = cayman_interrupt_pci2, +}; + +static void enable_cayman_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + unsigned long flags; + unsigned long mask; + unsigned int reg; + unsigned char bit; + + irq -= START_EXT_IRQS; + reg = EPLD_MASK_BASE + ((irq / 8) << 2); + bit = 1<<(irq % 8); + local_irq_save(flags); + mask = __raw_readl(reg); + mask |= bit; + __raw_writel(mask, reg); + local_irq_restore(flags); +} + +static void disable_cayman_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + unsigned long flags; + unsigned long mask; + unsigned int reg; + unsigned char bit; + + irq -= START_EXT_IRQS; + reg = EPLD_MASK_BASE + ((irq / 8) << 2); + bit = 1<<(irq % 8); + local_irq_save(flags); + mask = __raw_readl(reg); + mask &= ~bit; + __raw_writel(mask, reg); + local_irq_restore(flags); +} + +struct irq_chip cayman_irq_type = { + .name = "Cayman-IRQ", + .irq_unmask = enable_cayman_irq, + .irq_mask = disable_cayman_irq, +}; + +int cayman_irq_demux(int evt) +{ + int irq = intc_evt_to_irq[evt]; + + if (irq == SMSC_IRQ) { + unsigned long status; + int i; + + status = __raw_readl(EPLD_STATUS_BASE) & + __raw_readl(EPLD_MASK_BASE) & 0xff; + if (status == 0) { + irq = -1; + } else { + for (i=0; i<8; i++) { + if (status & (1<<i)) + break; + } + irq = START_EXT_IRQS + i; + } + } + + if (irq == PCI2_IRQ) { + unsigned long status; + int i; + + status = __raw_readl(EPLD_STATUS_BASE + 3 * sizeof(u32)) & + __raw_readl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff; + if (status == 0) { + irq = -1; + } else { + for (i=0; i<8; i++) { + if (status & (1<<i)) + break; + } + irq = START_EXT_IRQS + (3 * 8) + i; + } + } + + return irq; +} + +void init_cayman_irq(void) +{ + int i; + + epld_virt = (unsigned long)ioremap_nocache(EPLD_BASE, 1024); + if (!epld_virt) { + printk(KERN_ERR "Cayman IRQ: Unable to remap EPLD\n"); + return; + } + + for (i = 0; i < NR_EXT_IRQS; i++) { + irq_set_chip_and_handler(START_EXT_IRQS + i, + &cayman_irq_type, handle_level_irq); + } + + /* Setup the SMSC interrupt */ + setup_irq(SMSC_IRQ, &cayman_action_smsc); + setup_irq(PCI2_IRQ, &cayman_action_pci2); +} diff --git a/arch/sh/boards/mach-cayman/panic.c b/arch/sh/boards/mach-cayman/panic.c new file mode 100644 index 00000000000..d1e67306d07 --- /dev/null +++ b/arch/sh/boards/mach-cayman/panic.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2003 Richard Curnow, SuperH UK Limited + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <cpu/registers.h> + +/* THIS IS A PHYSICAL ADDRESS */ +#define HDSP2534_ADDR (0x04002100) + +static void poor_mans_delay(void) +{ + int i; + + for (i = 0; i < 2500000; i++) + cpu_relax(); +} + +static void show_value(unsigned long x) +{ + int i; + unsigned nibble; + for (i = 0; i < 8; i++) { + nibble = ((x >> (i * 4)) & 0xf); + + __raw_writeb(nibble + ((nibble > 9) ? 55 : 48), + HDSP2534_ADDR + 0xe0 + ((7 - i) << 2)); + } +} + +void +panic_handler(unsigned long panicPC, unsigned long panicSSR, + unsigned long panicEXPEVT) +{ + while (1) { + /* This piece of code displays the PC on the LED display */ + show_value(panicPC); + poor_mans_delay(); + show_value(panicSSR); + poor_mans_delay(); + show_value(panicEXPEVT); + poor_mans_delay(); + } +} diff --git a/arch/sh/boards/mach-cayman/setup.c b/arch/sh/boards/mach-cayman/setup.c new file mode 100644 index 00000000000..e89e8e122a2 --- /dev/null +++ b/arch/sh/boards/mach-cayman/setup.c @@ -0,0 +1,187 @@ +/* + * arch/sh/mach-cayman/setup.c + * + * SH5 Cayman support + * + * Copyright (C) 2002 David J. Mckay & Benedict Gaster + * Copyright (C) 2003 - 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <cpu/irq.h> + +/* + * Platform Dependent Interrupt Priorities. + */ + +/* Using defaults defined in irq.h */ +#define RES NO_PRIORITY /* Disabled */ +#define IR0 IRL0_PRIORITY /* IRLs */ +#define IR1 IRL1_PRIORITY +#define IR2 IRL2_PRIORITY +#define IR3 IRL3_PRIORITY +#define PCA INTA_PRIORITY /* PCI Ints */ +#define PCB INTB_PRIORITY +#define PCC INTC_PRIORITY +#define PCD INTD_PRIORITY +#define SER TOP_PRIORITY +#define ERR TOP_PRIORITY +#define PW0 TOP_PRIORITY +#define PW1 TOP_PRIORITY +#define PW2 TOP_PRIORITY +#define PW3 TOP_PRIORITY +#define DM0 NO_PRIORITY /* DMA Ints */ +#define DM1 NO_PRIORITY +#define DM2 NO_PRIORITY +#define DM3 NO_PRIORITY +#define DAE NO_PRIORITY +#define TU0 TIMER_PRIORITY /* TMU Ints */ +#define TU1 NO_PRIORITY +#define TU2 NO_PRIORITY +#define TI2 NO_PRIORITY +#define ATI NO_PRIORITY /* RTC Ints */ +#define PRI NO_PRIORITY +#define CUI RTC_PRIORITY +#define ERI SCIF_PRIORITY /* SCIF Ints */ +#define RXI SCIF_PRIORITY +#define BRI SCIF_PRIORITY +#define TXI SCIF_PRIORITY +#define ITI TOP_PRIORITY /* WDT Ints */ + +/* Setup for the SMSC FDC37C935 */ +#define SMSC_SUPERIO_BASE 0x04000000 +#define SMSC_CONFIG_PORT_ADDR 0x3f0 +#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR +#define SMSC_DATA_PORT_ADDR 0x3f1 + +#define SMSC_ENTER_CONFIG_KEY 0x55 +#define SMSC_EXIT_CONFIG_KEY 0xaa + +#define SMCS_LOGICAL_DEV_INDEX 0x07 +#define SMSC_DEVICE_ID_INDEX 0x20 +#define SMSC_DEVICE_REV_INDEX 0x21 +#define SMSC_ACTIVATE_INDEX 0x30 +#define SMSC_PRIMARY_BASE_INDEX 0x60 +#define SMSC_SECONDARY_BASE_INDEX 0x62 +#define SMSC_PRIMARY_INT_INDEX 0x70 +#define SMSC_SECONDARY_INT_INDEX 0x72 + +#define SMSC_IDE1_DEVICE 1 +#define SMSC_KEYBOARD_DEVICE 7 +#define SMSC_CONFIG_REGISTERS 8 + +#define SMSC_SUPERIO_READ_INDEXED(index) ({ \ + outb((index), SMSC_INDEX_PORT_ADDR); \ + inb(SMSC_DATA_PORT_ADDR); }) +#define SMSC_SUPERIO_WRITE_INDEXED(val, index) ({ \ + outb((index), SMSC_INDEX_PORT_ADDR); \ + outb((val), SMSC_DATA_PORT_ADDR); }) + +#define IDE1_PRIMARY_BASE 0x01f0 +#define IDE1_SECONDARY_BASE 0x03f6 + +unsigned long smsc_superio_virt; + +int platform_int_priority[NR_INTC_IRQS] = { + IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ 0- 7 */ + RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ 8-15 */ + PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */ + TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */ + RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */ + RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */ + RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */ +}; + +static int __init smsc_superio_setup(void) +{ + unsigned char devid, devrev; + + smsc_superio_virt = (unsigned long)ioremap_nocache(SMSC_SUPERIO_BASE, 1024); + if (!smsc_superio_virt) { + panic("Unable to remap SMSC SuperIO\n"); + } + + /* Initially the chip is in run state */ + /* Put it into configuration state */ + outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + + /* Read device ID info */ + devid = SMSC_SUPERIO_READ_INDEXED(SMSC_DEVICE_ID_INDEX); + devrev = SMSC_SUPERIO_READ_INDEXED(SMSC_DEVICE_REV_INDEX); + printk("SMSC SuperIO devid %02x rev %02x\n", devid, devrev); + + /* Select the keyboard device */ + SMSC_SUPERIO_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX); + + /* enable it */ + SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + + /* Select the interrupts */ + /* On a PC keyboard is IRQ1, mouse is IRQ12 */ + SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_PRIMARY_INT_INDEX); + SMSC_SUPERIO_WRITE_INDEXED(12, SMSC_SECONDARY_INT_INDEX); + +#ifdef CONFIG_IDE + /* + * Only IDE1 exists on the Cayman + */ + + /* Power it on */ + SMSC_SUPERIO_WRITE_INDEXED(1 << SMSC_IDE1_DEVICE, 0x22); + + SMSC_SUPERIO_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX); + SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + + SMSC_SUPERIO_WRITE_INDEXED(IDE1_PRIMARY_BASE >> 8, + SMSC_PRIMARY_BASE_INDEX + 0); + SMSC_SUPERIO_WRITE_INDEXED(IDE1_PRIMARY_BASE & 0xff, + SMSC_PRIMARY_BASE_INDEX + 1); + + SMSC_SUPERIO_WRITE_INDEXED(IDE1_SECONDARY_BASE >> 8, + SMSC_SECONDARY_BASE_INDEX + 0); + SMSC_SUPERIO_WRITE_INDEXED(IDE1_SECONDARY_BASE & 0xff, + SMSC_SECONDARY_BASE_INDEX + 1); + + SMSC_SUPERIO_WRITE_INDEXED(14, SMSC_PRIMARY_INT_INDEX); + + SMSC_SUPERIO_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, + SMCS_LOGICAL_DEV_INDEX); + + SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */ + SMSC_SUPERIO_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */ + SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */ + SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ +#endif + + /* Exit the configuration state */ + outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + + return 0; +} +device_initcall(smsc_superio_setup); + +static void __iomem *cayman_ioport_map(unsigned long port, unsigned int len) +{ + if (port < 0x400) { + extern unsigned long smsc_superio_virt; + return (void __iomem *)((port << 2) | smsc_superio_virt); + } + + return (void __iomem *)port; +} + +extern void init_cayman_irq(void); + +static struct sh_machine_vector mv_cayman __initmv = { + .mv_name = "Hitachi Cayman", + .mv_nr_irqs = 64, + .mv_ioport_map = cayman_ioport_map, + .mv_init_irq = init_cayman_irq, +}; diff --git a/arch/sh/boards/mach-dreamcast/Makefile b/arch/sh/boards/mach-dreamcast/Makefile new file mode 100644 index 00000000000..7b97546c7e5 --- /dev/null +++ b/arch/sh/boards/mach-dreamcast/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Sega Dreamcast specific parts of the kernel +# + +obj-y := setup.o irq.o rtc.o + diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c new file mode 100644 index 00000000000..f63d323f411 --- /dev/null +++ b/arch/sh/boards/mach-dreamcast/irq.c @@ -0,0 +1,166 @@ +/* + * arch/sh/boards/dreamcast/irq.c + * + * Holly IRQ support for the Sega Dreamcast. + * + * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org> + * + * This file is part of the LinuxDC project (www.linuxdc.org) + * Released under the terms of the GNU GPL v2.0 + */ + +#include <linux/irq.h> +#include <linux/io.h> +#include <asm/irq.h> +#include <mach/sysasic.h> + +/* + * Dreamcast System ASIC Hardware Events - + * + * The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving + * hardware events from system peripherals and triggering an SH7750 IRQ. + * Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are + * set in the Event Mask Registers (EMRs). When a hardware event is + * triggered, its corresponding bit in the Event Status Registers (ESRs) + * is set, and that bit should be rewritten to the ESR to acknowledge that + * event. + * + * There are three 32-bit ESRs located at 0xa05f6900 - 0xa05f6908. Event + * types can be found in arch/sh/include/mach-dreamcast/mach/sysasic.h. + * There are three groups of EMRs that parallel the ESRs. Each EMR group + * corresponds to an IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, + * 0xa05f6920 - 0xa05f6928 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 + * triggers IRQ 9. + * + * In the kernel, these events are mapped to virtual IRQs so that drivers can + * respond to them as they would a normal interrupt. In order to keep this + * mapping simple, the events are mapped as: + * + * 6900/6910 - Events 0-31, IRQ 13 + * 6904/6924 - Events 32-63, IRQ 11 + * 6908/6938 - Events 64-95, IRQ 9 + * + */ + +#define ESR_BASE 0x005f6900 /* Base event status register */ +#define EMR_BASE 0x005f6910 /* Base event mask register */ + +/* + * Helps us determine the EMR group that this event belongs to: 0 = 0x6910, + * 1 = 0x6920, 2 = 0x6930; also determine the event offset. + */ +#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32) + +/* Return the hardware event's bit position within the EMR/ESR */ +#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31) + +/* + * For each of these *_irq routines, the IRQ passed in is the virtual IRQ + * (logically mapped to the corresponding bit for the hardware event). + */ + +/* Disable the hardware event by masking its bit in its EMR */ +static inline void disable_systemasic_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); + __u32 mask; + + mask = inl(emr); + mask &= ~(1 << EVENT_BIT(irq)); + outl(mask, emr); +} + +/* Enable the hardware event by setting its bit in its EMR */ +static inline void enable_systemasic_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); + __u32 mask; + + mask = inl(emr); + mask |= (1 << EVENT_BIT(irq)); + outl(mask, emr); +} + +/* Acknowledge a hardware event by writing its bit back to its ESR */ +static void mask_ack_systemasic_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + __u32 esr = ESR_BASE + (LEVEL(irq) << 2); + disable_systemasic_irq(data); + outl((1 << EVENT_BIT(irq)), esr); +} + +struct irq_chip systemasic_int = { + .name = "System ASIC", + .irq_mask = disable_systemasic_irq, + .irq_mask_ack = mask_ack_systemasic_irq, + .irq_unmask = enable_systemasic_irq, +}; + +/* + * Map the hardware event indicated by the processor IRQ to a virtual IRQ. + */ +int systemasic_irq_demux(int irq) +{ + __u32 emr, esr, status, level; + __u32 j, bit; + + switch (irq) { + case 13: + level = 0; + break; + case 11: + level = 1; + break; + case 9: + level = 2; + break; + default: + return irq; + } + emr = EMR_BASE + (level << 4) + (level << 2); + esr = ESR_BASE + (level << 2); + + /* Mask the ESR to filter any spurious, unwanted interrupts */ + status = inl(esr); + status &= inl(emr); + + /* Now scan and find the first set bit as the event to map */ + for (bit = 1, j = 0; j < 32; bit <<= 1, j++) { + if (status & bit) { + irq = HW_EVENT_IRQ_BASE + j + (level << 5); + return irq; + } + } + + /* Not reached */ + return irq; +} + +void systemasic_irq_init(void) +{ + int i, nid = cpu_to_node(boot_cpu_data); + + /* Assign all virtual IRQs to the System ASIC int. handler */ + for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) { + unsigned int irq; + + irq = create_irq_nr(i, nid); + if (unlikely(irq == 0)) { + pr_err("%s: failed hooking irq %d for systemasic\n", + __func__, i); + return; + } + + if (unlikely(irq != i)) { + pr_err("%s: got irq %d but wanted %d, bailing.\n", + __func__, irq, i); + destroy_irq(irq); + return; + } + + irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq); + } +} diff --git a/arch/sh/boards/mach-dreamcast/rtc.c b/arch/sh/boards/mach-dreamcast/rtc.c new file mode 100644 index 00000000000..061d65714fc --- /dev/null +++ b/arch/sh/boards/mach-dreamcast/rtc.c @@ -0,0 +1,81 @@ +/* + * arch/sh/boards/dreamcast/rtc.c + * + * Dreamcast AICA RTC routines. + * + * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org> + * Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org> + * + * Released under the terms of the GNU GPL v2.0. + * + */ + +#include <linux/time.h> +#include <asm/rtc.h> +#include <asm/io.h> + +/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in + seconds) to get the standard Unix Epoch when getting the time, and add + 20 years when setting the time. */ +#define TWENTY_YEARS ((20 * 365LU + 5) * 86400) + +/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit + registers.*/ +#define AICA_RTC_SECS_H 0xa0710000 +#define AICA_RTC_SECS_L 0xa0710004 + +/** + * aica_rtc_gettimeofday - Get the time from the AICA RTC + * @ts: pointer to resulting timespec + * + * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. + */ +static void aica_rtc_gettimeofday(struct timespec *ts) +{ + unsigned long val1, val2; + + do { + val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); + + val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); + } while (val1 != val2); + + ts->tv_sec = val1 - TWENTY_YEARS; + + /* Can't get nanoseconds with just a seconds counter. */ + ts->tv_nsec = 0; +} + +/** + * aica_rtc_settimeofday - Set the AICA RTC to the current time + * @secs: contains the time_t to set + * + * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. + */ +static int aica_rtc_settimeofday(const time_t secs) +{ + unsigned long val1, val2; + unsigned long adj = secs + TWENTY_YEARS; + + do { + __raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H); + __raw_writel((adj & 0xffff), AICA_RTC_SECS_L); + + val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); + + val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); + } while (val1 != val2); + + return 0; +} + +void aica_time_init(void) +{ + rtc_sh_get_time = aica_rtc_gettimeofday; + rtc_sh_set_time = aica_rtc_settimeofday; +} + diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c new file mode 100644 index 00000000000..ad1a4db72e0 --- /dev/null +++ b/arch/sh/boards/mach-dreamcast/setup.c @@ -0,0 +1,41 @@ +/* + * arch/sh/boards/dreamcast/setup.c + * + * Hardware support for the Sega Dreamcast. + * + * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@linuxdc.org> + * Copyright (c) 2002, 2003, 2004 Paul Mundt <lethal@linux-sh.org> + * + * This file is part of the LinuxDC project (www.linuxdc.org) + * + * Released under the terms of the GNU GPL v2.0. + * + * This file originally bore the message (with enclosed-$): + * Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp + * SEGA Dreamcast support + */ + +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/device.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/rtc.h> +#include <asm/machvec.h> +#include <mach/sysasic.h> + +static void __init dreamcast_setup(char **cmdline_p) +{ + board_time_init = aica_time_init; +} + +static struct sh_machine_vector mv_dreamcast __initmv = { + .mv_name = "Sega Dreamcast", + .mv_setup = dreamcast_setup, + .mv_irq_demux = systemasic_irq_demux, + .mv_init_irq = systemasic_irq_init, +}; diff --git a/arch/sh/boards/mach-ecovec24/Makefile b/arch/sh/boards/mach-ecovec24/Makefile new file mode 100644 index 00000000000..e69bc82208f --- /dev/null +++ b/arch/sh/boards/mach-ecovec24/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the R0P7724LC0011/21RL (EcoVec) +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# + +obj-y := setup.o sdram.o
\ No newline at end of file diff --git a/arch/sh/boards/mach-ecovec24/sdram.S b/arch/sh/boards/mach-ecovec24/sdram.S new file mode 100644 index 00000000000..3963c6f23d5 --- /dev/null +++ b/arch/sh/boards/mach-ecovec24/sdram.S @@ -0,0 +1,111 @@ +/* + * Ecovec24 sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(ecovec24_sdram_enter_start) + + /* DBSC: put memory in self-refresh mode */ + + ED 0xFD000010, 0x00000000 /* DBEN */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + + rts + nop + +ENTRY(ecovec24_sdram_enter_end) + + .balign 4 +ENTRY(ecovec24_sdram_leave_start) + + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_RSTANDBY, r0 + bf resume_rstandby + + /* DBSC: put memory in auto-refresh mode */ + + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + WAIT 1 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +resume_rstandby: + + /* DBSC: re-initialize and put in auto-refresh */ + + ED 0xFD000108, 0x00000181 /* DBPDCNT0 */ + ED 0xFD000020, 0x015B0002 /* DBCONF */ + ED 0xFD000030, 0x03071502 /* DBTR0 */ + ED 0xFD000034, 0x02020102 /* DBTR1 */ + ED 0xFD000038, 0x01090405 /* DBTR2 */ + ED 0xFD00003C, 0x00000002 /* DBTR3 */ + ED 0xFD000008, 0x00000005 /* DBKIND */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000018, 0x00000001 /* DBCKECNT */ + + mov #100,r0 +WAIT_400NS: + dt r0 + bf WAIT_400NS + + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */ + ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */ + ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */ + ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */ + ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */ + ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */ + + mov #100,r0 +WAIT_400NS_2: + dt r0 + bf WAIT_400NS_2 + + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000044, 0x0000050f /* DBRFPDN1 */ + ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */ + + mov.l DUMMY,r0 + mov.l @r0, r1 /* force single dummy read */ + + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000108, 0x00000080 /* DBPDCNT0 */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + + .balign 4 +DUMMY: .long 0xac400000 + +ENTRY(ecovec24_sdram_leave_end) diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c new file mode 100644 index 00000000000..cde7c0085ce --- /dev/null +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -0,0 +1,1382 @@ +/* + * Copyright (C) 2009 Renesas Solutions Corp. + * + * Kuninori Morimoto <morimoto.kuninori@renesas.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mmcif.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/mtd/physmap.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/usb/r8a66597.h> +#include <linux/usb/renesas_usbhs.h> +#include <linux/i2c.h> +#include <linux/i2c/tsc2007.h> +#include <linux/spi/spi.h> +#include <linux/spi/sh_msiof.h> +#include <linux/spi/mmc_spi.h> +#include <linux/input.h> +#include <linux/input/sh_keysc.h> +#include <linux/sh_eth.h> +#include <linux/videodev2.h> +#include <video/sh_mobile_lcdc.h> +#include <sound/sh_fsi.h> +#include <media/sh_mobile_ceu.h> +#include <media/soc_camera.h> +#include <media/tw9910.h> +#include <media/mt9t112.h> +#include <asm/heartbeat.h> +#include <asm/clock.h> +#include <asm/suspend.h> +#include <cpu/sh7724.h> + +/* + * Address Interface BusWidth + *----------------------------------------- + * 0x0000_0000 uboot 16bit + * 0x0004_0000 Linux romImage 16bit + * 0x0014_0000 MTD for Linux 16bit + * 0x0400_0000 Internal I/O 16/32bit + * 0x0800_0000 DRAM 32bit + * 0x1800_0000 MFI 16bit + */ + +/* SWITCH + *------------------------------ + * DS2[1] = FlashROM write protect ON : write protect + * OFF : No write protect + * DS2[2] = RMII / TS, SCIF ON : RMII + * OFF : TS, SCIF3 + * DS2[3] = Camera / Video ON : Camera + * OFF : NTSC/PAL (IN) + * DS2[5] = NTSC_OUT Clock ON : On board OSC + * OFF : SH7724 DV_CLK + * DS2[6-7] = MMC / SD ON-OFF : SD + * OFF-ON : MMC + */ + +/* Heartbeat */ +static unsigned char led_pos[] = { 0, 1, 2, 3 }; + +static struct heartbeat_data heartbeat_data = { + .nr_bits = 4, + .bit_pos = led_pos, +}; + +static struct resource heartbeat_resource = { + .start = 0xA405012C, /* PTG */ + .end = 0xA405012E - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = &heartbeat_data, + }, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +/* MTD */ +static struct mtd_partition nor_flash_partitions[] = { + { + .name = "boot loader", + .offset = 0, + .size = (5 * 1024 * 1024), + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "free-area", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data nor_flash_data = { + .width = 2, + .parts = nor_flash_partitions, + .nr_parts = ARRAY_SIZE(nor_flash_partitions), +}; + +static struct resource nor_flash_resources[] = { + [0] = { + .name = "NOR Flash", + .start = 0x00000000, + .end = 0x03ffffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device nor_flash_device = { + .name = "physmap-flash", + .resource = nor_flash_resources, + .num_resources = ARRAY_SIZE(nor_flash_resources), + .dev = { + .platform_data = &nor_flash_data, + }, +}; + +/* SH Eth */ +#define SH_ETH_ADDR (0xA4600000) +static struct resource sh_eth_resources[] = { + [0] = { + .start = SH_ETH_ADDR, + .end = SH_ETH_ADDR + 0x1FC, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 91, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct sh_eth_plat_data sh_eth_plat = { + .phy = 0x1f, /* SMSC LAN8700 */ + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .register_type = SH_ETH_REG_FAST_SH4, + .phy_interface = PHY_INTERFACE_MODE_MII, + .ether_link_active_low = 1 +}; + +static struct platform_device sh_eth_device = { + .name = "sh-eth", + .id = 0, + .dev = { + .platform_data = &sh_eth_plat, + }, + .num_resources = ARRAY_SIZE(sh_eth_resources), + .resource = sh_eth_resources, +}; + +/* USB0 host */ +static void usb0_port_power(int port, int power) +{ + gpio_set_value(GPIO_PTB4, power); +} + +static struct r8a66597_platdata usb0_host_data = { + .on_chip = 1, + .port_power = usb0_port_power, +}; + +static struct resource usb0_host_resources[] = { + [0] = { + .start = 0xa4d80000, + .end = 0xa4d80124 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 65, + .end = 65, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, +}; + +static struct platform_device usb0_host_device = { + .name = "r8a66597_hcd", + .id = 0, + .dev = { + .dma_mask = NULL, /* not use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &usb0_host_data, + }, + .num_resources = ARRAY_SIZE(usb0_host_resources), + .resource = usb0_host_resources, +}; + +/* USB1 host/function */ +static void usb1_port_power(int port, int power) +{ + gpio_set_value(GPIO_PTB5, power); +} + +static struct r8a66597_platdata usb1_common_data = { + .on_chip = 1, + .port_power = usb1_port_power, +}; + +static struct resource usb1_common_resources[] = { + [0] = { + .start = 0xa4d90000, + .end = 0xa4d90124 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 66, + .end = 66, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, +}; + +static struct platform_device usb1_common_device = { + /* .name will be added in arch_setup */ + .id = 1, + .dev = { + .dma_mask = NULL, /* not use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &usb1_common_data, + }, + .num_resources = ARRAY_SIZE(usb1_common_resources), + .resource = usb1_common_resources, +}; + +/* + * USBHS + */ +static int usbhs_get_id(struct platform_device *pdev) +{ + return gpio_get_value(GPIO_PTB3); +} + +static struct renesas_usbhs_platform_info usbhs_info = { + .platform_callback = { + .get_id = usbhs_get_id, + }, + .driver_param = { + .buswait_bwait = 4, + .detection_delay = 5, + .d0_tx_id = SHDMA_SLAVE_USB1D0_TX, + .d0_rx_id = SHDMA_SLAVE_USB1D0_RX, + .d1_tx_id = SHDMA_SLAVE_USB1D1_TX, + .d1_rx_id = SHDMA_SLAVE_USB1D1_RX, + }, +}; + +static struct resource usbhs_resources[] = { + [0] = { + .start = 0xa4d90000, + .end = 0xa4d90124 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 66, + .end = 66, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usbhs_device = { + .name = "renesas_usbhs", + .id = 1, + .dev = { + .dma_mask = NULL, /* not use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbhs_info, + }, + .num_resources = ARRAY_SIZE(usbhs_resources), + .resource = usbhs_resources, +}; + +/* LCDC */ +static const struct fb_videomode ecovec_lcd_modes[] = { + { + .name = "Panel", + .xres = 800, + .yres = 480, + .left_margin = 220, + .right_margin = 110, + .hsync_len = 70, + .upper_margin = 20, + .lower_margin = 5, + .vsync_len = 5, + .sync = 0, /* hsync and vsync are active low */ + }, +}; + +static const struct fb_videomode ecovec_dvi_modes[] = { + { + .name = "DVI", + .xres = 1280, + .yres = 720, + .left_margin = 220, + .right_margin = 110, + .hsync_len = 40, + .upper_margin = 20, + .lower_margin = 5, + .vsync_len = 5, + .sync = 0, /* hsync and vsync are active low */ + }, +}; + +static int ecovec24_set_brightness(void *board_data, int brightness) +{ + gpio_set_value(GPIO_PTR1, brightness); + + return 0; +} + +static int ecovec24_get_brightness(void *board_data) +{ + return gpio_get_value(GPIO_PTR1); +} + +static struct sh_mobile_lcdc_info lcdc_info = { + .ch[0] = { + .interface_type = RGB18, + .chan = LCDC_CHAN_MAINLCD, + .fourcc = V4L2_PIX_FMT_RGB565, + .lcd_size_cfg = { /* 7.0 inch */ + .width = 152, + .height = 91, + }, + .board_cfg = { + .set_brightness = ecovec24_set_brightness, + .get_brightness = ecovec24_get_brightness, + }, + .bl_info = { + .name = "sh_mobile_lcdc_bl", + .max_brightness = 1, + }, + } +}; + +static struct resource lcdc_resources[] = { + [0] = { + .name = "LCDC", + .start = 0xfe940000, + .end = 0xfe942fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 106, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device lcdc_device = { + .name = "sh_mobile_lcdc_fb", + .num_resources = ARRAY_SIZE(lcdc_resources), + .resource = lcdc_resources, + .dev = { + .platform_data = &lcdc_info, + }, +}; + +/* CEU0 */ +static struct sh_mobile_ceu_info sh_mobile_ceu0_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, +}; + +static struct resource ceu0_resources[] = { + [0] = { + .name = "CEU0", + .start = 0xfe910000, + .end = 0xfe91009f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 52, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device ceu0_device = { + .name = "sh_mobile_ceu", + .id = 0, /* "ceu0" clock */ + .num_resources = ARRAY_SIZE(ceu0_resources), + .resource = ceu0_resources, + .dev = { + .platform_data = &sh_mobile_ceu0_info, + }, +}; + +/* CEU1 */ +static struct sh_mobile_ceu_info sh_mobile_ceu1_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, +}; + +static struct resource ceu1_resources[] = { + [0] = { + .name = "CEU1", + .start = 0xfe914000, + .end = 0xfe91409f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 63, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device ceu1_device = { + .name = "sh_mobile_ceu", + .id = 1, /* "ceu1" clock */ + .num_resources = ARRAY_SIZE(ceu1_resources), + .resource = ceu1_resources, + .dev = { + .platform_data = &sh_mobile_ceu1_info, + }, +}; + +/* I2C device */ +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("da7210", 0x1a), + }, +}; + +static struct i2c_board_info i2c1_devices[] = { + { + I2C_BOARD_INFO("r2025sd", 0x32), + }, + { + I2C_BOARD_INFO("lis3lv02d", 0x1c), + .irq = 33, + } +}; + +/* KEYSC */ +static struct sh_keysc_info keysc_info = { + .mode = SH_KEYSC_MODE_1, + .scan_timing = 3, + .delay = 50, + .kycr2_delay = 100, + .keycodes = { KEY_1, 0, 0, 0, 0, + KEY_2, 0, 0, 0, 0, + KEY_3, 0, 0, 0, 0, + KEY_4, 0, 0, 0, 0, + KEY_5, 0, 0, 0, 0, + KEY_6, 0, 0, 0, 0, }, +}; + +static struct resource keysc_resources[] = { + [0] = { + .name = "KEYSC", + .start = 0x044b0000, + .end = 0x044b000f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 79, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device keysc_device = { + .name = "sh_keysc", + .id = 0, /* keysc0 clock */ + .num_resources = ARRAY_SIZE(keysc_resources), + .resource = keysc_resources, + .dev = { + .platform_data = &keysc_info, + }, +}; + +/* TouchScreen */ +#define IRQ0 32 +static int ts_get_pendown_state(void) +{ + int val = 0; + gpio_free(GPIO_FN_INTC_IRQ0); + gpio_request(GPIO_PTZ0, NULL); + gpio_direction_input(GPIO_PTZ0); + + val = gpio_get_value(GPIO_PTZ0); + + gpio_free(GPIO_PTZ0); + gpio_request(GPIO_FN_INTC_IRQ0, NULL); + + return val ? 0 : 1; +} + +static int ts_init(void) +{ + gpio_request(GPIO_FN_INTC_IRQ0, NULL); + return 0; +} + +static struct tsc2007_platform_data tsc2007_info = { + .model = 2007, + .x_plate_ohms = 180, + .get_pendown_state = ts_get_pendown_state, + .init_platform_hw = ts_init, +}; + +static struct i2c_board_info ts_i2c_clients = { + I2C_BOARD_INFO("tsc2007", 0x48), + .type = "tsc2007", + .platform_data = &tsc2007_info, + .irq = IRQ0, +}; + +#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) +/* SDHI0 */ +static void sdhi0_set_pwr(struct platform_device *pdev, int state) +{ + gpio_set_value(GPIO_PTB6, state); +} + +static struct sh_mobile_sdhi_info sdhi0_info = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .set_pwr = sdhi0_set_pwr, + .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, +}; + +static struct resource sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 100, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi0_resources), + .resource = sdhi0_resources, + .id = 0, + .dev = { + .platform_data = &sdhi0_info, + }, +}; + +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) +/* SDHI1 */ +static void sdhi1_set_pwr(struct platform_device *pdev, int state) +{ + gpio_set_value(GPIO_PTB7, state); +} + +static struct sh_mobile_sdhi_info sdhi1_info = { + .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, + .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, + .set_pwr = sdhi1_set_pwr, +}; + +static struct resource sdhi1_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0x04cf0000, + .end = 0x04cf00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 23, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi1_resources), + .resource = sdhi1_resources, + .id = 1, + .dev = { + .platform_data = &sdhi1_info, + }, +}; +#endif /* CONFIG_MMC_SH_MMCIF */ + +#else + +/* MMC SPI */ +static int mmc_spi_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO_PTY6); +} + +static int mmc_spi_get_cd(struct device *dev) +{ + return !gpio_get_value(GPIO_PTY7); +} + +static void mmc_spi_setpower(struct device *dev, unsigned int maskval) +{ + gpio_set_value(GPIO_PTB6, maskval ? 1 : 0); +} + +static struct mmc_spi_platform_data mmc_spi_info = { + .get_ro = mmc_spi_get_ro, + .get_cd = mmc_spi_get_cd, + .caps = MMC_CAP_NEEDS_POLL, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */ + .setpower = mmc_spi_setpower, +}; + +static struct spi_board_info spi_bus[] = { + { + .modalias = "mmc_spi", + .platform_data = &mmc_spi_info, + .max_speed_hz = 5000000, + .mode = SPI_MODE_0, + .controller_data = (void *) GPIO_PTM4, + }, +}; + +/* MSIOF0 */ +static struct sh_msiof_spi_info msiof0_data = { + .num_chipselect = 1, +}; + +static struct resource msiof0_resources[] = { + [0] = { + .name = "MSIOF0", + .start = 0xa4c40000, + .end = 0xa4c40063, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 84, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device msiof0_device = { + .name = "spi_sh_msiof", + .id = 0, /* MSIOF0 */ + .dev = { + .platform_data = &msiof0_data, + }, + .num_resources = ARRAY_SIZE(msiof0_resources), + .resource = msiof0_resources, +}; + +#endif + +/* I2C Video/Camera */ +static struct i2c_board_info i2c_camera[] = { + { + I2C_BOARD_INFO("tw9910", 0x45), + }, + { + /* 1st camera */ + I2C_BOARD_INFO("mt9t112", 0x3c), + }, + { + /* 2nd camera */ + I2C_BOARD_INFO("mt9t112", 0x3c), + }, +}; + +/* tw9910 */ +static int tw9910_power(struct device *dev, int mode) +{ + int val = mode ? 0 : 1; + + gpio_set_value(GPIO_PTU2, val); + if (mode) + mdelay(100); + + return 0; +} + +static struct tw9910_video_info tw9910_info = { + .buswidth = SOCAM_DATAWIDTH_8, + .mpout = TW9910_MPO_FIELD, +}; + +static struct soc_camera_link tw9910_link = { + .i2c_adapter_id = 0, + .bus_id = 1, + .power = tw9910_power, + .board_info = &i2c_camera[0], + .priv = &tw9910_info, +}; + +/* mt9t112 */ +static int mt9t112_power1(struct device *dev, int mode) +{ + gpio_set_value(GPIO_PTA3, mode); + if (mode) + mdelay(100); + + return 0; +} + +static struct mt9t112_camera_info mt9t112_info1 = { + .flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8, + .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ +}; + +static struct soc_camera_link mt9t112_link1 = { + .i2c_adapter_id = 0, + .power = mt9t112_power1, + .bus_id = 0, + .board_info = &i2c_camera[1], + .priv = &mt9t112_info1, +}; + +static int mt9t112_power2(struct device *dev, int mode) +{ + gpio_set_value(GPIO_PTA4, mode); + if (mode) + mdelay(100); + + return 0; +} + +static struct mt9t112_camera_info mt9t112_info2 = { + .flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8, + .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ +}; + +static struct soc_camera_link mt9t112_link2 = { + .i2c_adapter_id = 1, + .power = mt9t112_power2, + .bus_id = 1, + .board_info = &i2c_camera[2], + .priv = &mt9t112_info2, +}; + +static struct platform_device camera_devices[] = { + { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &tw9910_link, + }, + }, + { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &mt9t112_link1, + }, + }, + { + .name = "soc-camera-pdrv", + .id = 2, + .dev = { + .platform_data = &mt9t112_link2, + }, + }, +}; + +/* FSI */ +static struct sh_fsi_platform_info fsi_info = { + .portb_flags = SH_FSI_BRS_INV, +}; + +static struct resource fsi_resources[] = { + [0] = { + .name = "FSI", + .start = 0xFE3C0000, + .end = 0xFE3C021d, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 108, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device fsi_device = { + .name = "sh_fsi", + .id = 0, + .num_resources = ARRAY_SIZE(fsi_resources), + .resource = fsi_resources, + .dev = { + .platform_data = &fsi_info, + }, +}; + +/* IrDA */ +static struct resource irda_resources[] = { + [0] = { + .name = "IrDA", + .start = 0xA45D0000, + .end = 0xA45D0049, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device irda_device = { + .name = "sh_sir", + .num_resources = ARRAY_SIZE(irda_resources), + .resource = irda_resources, +}; + +#include <media/ak881x.h> +#include <media/sh_vou.h> + +static struct ak881x_pdata ak881x_pdata = { + .flags = AK881X_IF_MODE_SLAVE, +}; + +static struct i2c_board_info ak8813 = { + I2C_BOARD_INFO("ak8813", 0x20), + .platform_data = &ak881x_pdata, +}; + +static struct sh_vou_pdata sh_vou_pdata = { + .bus_fmt = SH_VOU_BUS_8BIT, + .flags = SH_VOU_HSYNC_LOW | SH_VOU_VSYNC_LOW, + .board_info = &ak8813, + .i2c_adap = 0, +}; + +static struct resource sh_vou_resources[] = { + [0] = { + .start = 0xfe960000, + .end = 0xfe962043, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 55, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device vou_device = { + .name = "sh-vou", + .id = -1, + .num_resources = ARRAY_SIZE(sh_vou_resources), + .resource = sh_vou_resources, + .dev = { + .platform_data = &sh_vou_pdata, + }, +}; + +#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) +/* SH_MMCIF */ +static void mmcif_set_pwr(struct platform_device *pdev, int state) +{ + gpio_set_value(GPIO_PTB7, state); +} + +static void mmcif_down_pwr(struct platform_device *pdev) +{ + gpio_set_value(GPIO_PTB7, 0); +} + +static struct resource sh_mmcif_resources[] = { + [0] = { + .name = "SH_MMCIF", + .start = 0xA4CA0000, + .end = 0xA4CA00FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* MMC2I */ + .start = 29, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* MMC3I */ + .start = 30, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_mmcif_plat_data sh_mmcif_plat = { + .set_pwr = mmcif_set_pwr, + .down_pwr = mmcif_down_pwr, + .sup_pclk = 0, /* SH7724: Max Pclk/2 */ + .caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_8_BIT_DATA | + MMC_CAP_NEEDS_POLL, + .ocr = MMC_VDD_32_33 | MMC_VDD_33_34, +}; + +static struct platform_device sh_mmcif_device = { + .name = "sh_mmcif", + .id = 0, + .dev = { + .platform_data = &sh_mmcif_plat, + }, + .num_resources = ARRAY_SIZE(sh_mmcif_resources), + .resource = sh_mmcif_resources, +}; +#endif + +static struct platform_device *ecovec_devices[] __initdata = { + &heartbeat_device, + &nor_flash_device, + &sh_eth_device, + &usb0_host_device, + &usb1_common_device, + &usbhs_device, + &lcdc_device, + &ceu0_device, + &ceu1_device, + &keysc_device, +#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) + &sdhi0_device, +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) + &sdhi1_device, +#endif +#else + &msiof0_device, +#endif + &camera_devices[0], + &camera_devices[1], + &camera_devices[2], + &fsi_device, + &irda_device, + &vou_device, +#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) + &sh_mmcif_device, +#endif +}; + +#ifdef CONFIG_I2C +#define EEPROM_ADDR 0x50 +static u8 mac_read(struct i2c_adapter *a, u8 command) +{ + struct i2c_msg msg[2]; + u8 buf; + int ret; + + msg[0].addr = EEPROM_ADDR; + msg[0].flags = 0; + msg[0].len = 1; + msg[0].buf = &command; + + msg[1].addr = EEPROM_ADDR; + msg[1].flags = I2C_M_RD; + msg[1].len = 1; + msg[1].buf = &buf; + + ret = i2c_transfer(a, msg, 2); + if (ret < 0) { + printk(KERN_ERR "error %d\n", ret); + buf = 0xff; + } + + return buf; +} + +static void __init sh_eth_init(struct sh_eth_plat_data *pd) +{ + struct i2c_adapter *a = i2c_get_adapter(1); + int i; + + if (!a) { + pr_err("can not get I2C 1\n"); + return; + } + + /* read MAC address from EEPROM */ + for (i = 0; i < sizeof(pd->mac_addr); i++) { + pd->mac_addr[i] = mac_read(a, 0x10 + i); + msleep(10); + } + + i2c_put_adapter(a); +} +#else +static void __init sh_eth_init(struct sh_eth_plat_data *pd) +{ + pr_err("unable to read sh_eth MAC address\n"); +} +#endif + +#define PORT_HIZA 0xA4050158 +#define IODRIVEA 0xA405018A + +extern char ecovec24_sdram_enter_start; +extern char ecovec24_sdram_enter_end; +extern char ecovec24_sdram_leave_start; +extern char ecovec24_sdram_leave_end; + +static int __init arch_setup(void) +{ + struct clk *clk; + + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | + SUSP_SH_RSTANDBY, + &ecovec24_sdram_enter_start, + &ecovec24_sdram_enter_end, + &ecovec24_sdram_leave_start, + &ecovec24_sdram_leave_end); + + /* enable STATUS0, STATUS2 and PDSTATUS */ + gpio_request(GPIO_FN_STATUS0, NULL); + gpio_request(GPIO_FN_STATUS2, NULL); + gpio_request(GPIO_FN_PDSTATUS, NULL); + + /* enable SCIFA0 */ + gpio_request(GPIO_FN_SCIF0_TXD, NULL); + gpio_request(GPIO_FN_SCIF0_RXD, NULL); + + /* enable debug LED */ + gpio_request(GPIO_PTG0, NULL); + gpio_request(GPIO_PTG1, NULL); + gpio_request(GPIO_PTG2, NULL); + gpio_request(GPIO_PTG3, NULL); + gpio_direction_output(GPIO_PTG0, 0); + gpio_direction_output(GPIO_PTG1, 0); + gpio_direction_output(GPIO_PTG2, 0); + gpio_direction_output(GPIO_PTG3, 0); + __raw_writew((__raw_readw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA); + + /* enable SH-Eth */ + gpio_request(GPIO_PTA1, NULL); + gpio_direction_output(GPIO_PTA1, 1); + mdelay(20); + + gpio_request(GPIO_FN_RMII_RXD0, NULL); + gpio_request(GPIO_FN_RMII_RXD1, NULL); + gpio_request(GPIO_FN_RMII_TXD0, NULL); + gpio_request(GPIO_FN_RMII_TXD1, NULL); + gpio_request(GPIO_FN_RMII_REF_CLK, NULL); + gpio_request(GPIO_FN_RMII_TX_EN, NULL); + gpio_request(GPIO_FN_RMII_RX_ER, NULL); + gpio_request(GPIO_FN_RMII_CRS_DV, NULL); + gpio_request(GPIO_FN_MDIO, NULL); + gpio_request(GPIO_FN_MDC, NULL); + gpio_request(GPIO_FN_LNKSTA, NULL); + + /* enable USB */ + __raw_writew(0x0000, 0xA4D80000); + __raw_writew(0x0000, 0xA4D90000); + gpio_request(GPIO_PTB3, NULL); + gpio_request(GPIO_PTB4, NULL); + gpio_request(GPIO_PTB5, NULL); + gpio_direction_input(GPIO_PTB3); + gpio_direction_output(GPIO_PTB4, 0); + gpio_direction_output(GPIO_PTB5, 0); + __raw_writew(0x0600, 0xa40501d4); + __raw_writew(0x0600, 0xa4050192); + + if (gpio_get_value(GPIO_PTB3)) { + printk(KERN_INFO "USB1 function is selected\n"); + usb1_common_device.name = "r8a66597_udc"; + } else { + printk(KERN_INFO "USB1 host is selected\n"); + usb1_common_device.name = "r8a66597_hcd"; + } + + /* enable LCDC */ + gpio_request(GPIO_FN_LCDD23, NULL); + gpio_request(GPIO_FN_LCDD22, NULL); + gpio_request(GPIO_FN_LCDD21, NULL); + gpio_request(GPIO_FN_LCDD20, NULL); + gpio_request(GPIO_FN_LCDD19, NULL); + gpio_request(GPIO_FN_LCDD18, NULL); + gpio_request(GPIO_FN_LCDD17, NULL); + gpio_request(GPIO_FN_LCDD16, NULL); + gpio_request(GPIO_FN_LCDD15, NULL); + gpio_request(GPIO_FN_LCDD14, NULL); + gpio_request(GPIO_FN_LCDD13, NULL); + gpio_request(GPIO_FN_LCDD12, NULL); + gpio_request(GPIO_FN_LCDD11, NULL); + gpio_request(GPIO_FN_LCDD10, NULL); + gpio_request(GPIO_FN_LCDD9, NULL); + gpio_request(GPIO_FN_LCDD8, NULL); + gpio_request(GPIO_FN_LCDD7, NULL); + gpio_request(GPIO_FN_LCDD6, NULL); + gpio_request(GPIO_FN_LCDD5, NULL); + gpio_request(GPIO_FN_LCDD4, NULL); + gpio_request(GPIO_FN_LCDD3, NULL); + gpio_request(GPIO_FN_LCDD2, NULL); + gpio_request(GPIO_FN_LCDD1, NULL); + gpio_request(GPIO_FN_LCDD0, NULL); + gpio_request(GPIO_FN_LCDDISP, NULL); + gpio_request(GPIO_FN_LCDHSYN, NULL); + gpio_request(GPIO_FN_LCDDCK, NULL); + gpio_request(GPIO_FN_LCDVSYN, NULL); + gpio_request(GPIO_FN_LCDDON, NULL); + gpio_request(GPIO_FN_LCDLCLK, NULL); + __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA); + + gpio_request(GPIO_PTE6, NULL); + gpio_request(GPIO_PTU1, NULL); + gpio_request(GPIO_PTR1, NULL); + gpio_request(GPIO_PTA2, NULL); + gpio_direction_input(GPIO_PTE6); + gpio_direction_output(GPIO_PTU1, 0); + gpio_direction_output(GPIO_PTR1, 0); + gpio_direction_output(GPIO_PTA2, 0); + + /* I/O buffer drive ability is high */ + __raw_writew((__raw_readw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA); + + if (gpio_get_value(GPIO_PTE6)) { + /* DVI */ + lcdc_info.clock_source = LCDC_CLK_EXTERNAL; + lcdc_info.ch[0].clock_divider = 1; + lcdc_info.ch[0].lcd_cfg = ecovec_dvi_modes; + lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_dvi_modes); + + gpio_set_value(GPIO_PTA2, 1); + gpio_set_value(GPIO_PTU1, 1); + } else { + /* Panel */ + lcdc_info.clock_source = LCDC_CLK_PERIPHERAL; + lcdc_info.ch[0].clock_divider = 2; + lcdc_info.ch[0].lcd_cfg = ecovec_lcd_modes; + lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_lcd_modes); + + gpio_set_value(GPIO_PTR1, 1); + + /* FIXME + * + * LCDDON control is needed for Panel, + * but current sh_mobile_lcdc driver doesn't control it. + * It is temporary correspondence + */ + gpio_request(GPIO_PTF4, NULL); + gpio_direction_output(GPIO_PTF4, 1); + + /* enable TouchScreen */ + i2c_register_board_info(0, &ts_i2c_clients, 1); + irq_set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW); + } + + /* enable CEU0 */ + gpio_request(GPIO_FN_VIO0_D15, NULL); + gpio_request(GPIO_FN_VIO0_D14, NULL); + gpio_request(GPIO_FN_VIO0_D13, NULL); + gpio_request(GPIO_FN_VIO0_D12, NULL); + gpio_request(GPIO_FN_VIO0_D11, NULL); + gpio_request(GPIO_FN_VIO0_D10, NULL); + gpio_request(GPIO_FN_VIO0_D9, NULL); + gpio_request(GPIO_FN_VIO0_D8, NULL); + gpio_request(GPIO_FN_VIO0_D7, NULL); + gpio_request(GPIO_FN_VIO0_D6, NULL); + gpio_request(GPIO_FN_VIO0_D5, NULL); + gpio_request(GPIO_FN_VIO0_D4, NULL); + gpio_request(GPIO_FN_VIO0_D3, NULL); + gpio_request(GPIO_FN_VIO0_D2, NULL); + gpio_request(GPIO_FN_VIO0_D1, NULL); + gpio_request(GPIO_FN_VIO0_D0, NULL); + gpio_request(GPIO_FN_VIO0_VD, NULL); + gpio_request(GPIO_FN_VIO0_CLK, NULL); + gpio_request(GPIO_FN_VIO0_FLD, NULL); + gpio_request(GPIO_FN_VIO0_HD, NULL); + platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20); + + /* enable CEU1 */ + gpio_request(GPIO_FN_VIO1_D7, NULL); + gpio_request(GPIO_FN_VIO1_D6, NULL); + gpio_request(GPIO_FN_VIO1_D5, NULL); + gpio_request(GPIO_FN_VIO1_D4, NULL); + gpio_request(GPIO_FN_VIO1_D3, NULL); + gpio_request(GPIO_FN_VIO1_D2, NULL); + gpio_request(GPIO_FN_VIO1_D1, NULL); + gpio_request(GPIO_FN_VIO1_D0, NULL); + gpio_request(GPIO_FN_VIO1_FLD, NULL); + gpio_request(GPIO_FN_VIO1_HD, NULL); + gpio_request(GPIO_FN_VIO1_VD, NULL); + gpio_request(GPIO_FN_VIO1_CLK, NULL); + platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20); + + /* enable KEYSC */ + gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); + gpio_request(GPIO_FN_KEYOUT4_IN6, NULL); + gpio_request(GPIO_FN_KEYOUT3, NULL); + gpio_request(GPIO_FN_KEYOUT2, NULL); + gpio_request(GPIO_FN_KEYOUT1, NULL); + gpio_request(GPIO_FN_KEYOUT0, NULL); + gpio_request(GPIO_FN_KEYIN0, NULL); + + /* enable user debug switch */ + gpio_request(GPIO_PTR0, NULL); + gpio_request(GPIO_PTR4, NULL); + gpio_request(GPIO_PTR5, NULL); + gpio_request(GPIO_PTR6, NULL); + gpio_direction_input(GPIO_PTR0); + gpio_direction_input(GPIO_PTR4); + gpio_direction_input(GPIO_PTR5); + gpio_direction_input(GPIO_PTR6); + +#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) + /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ + gpio_request(GPIO_FN_SDHI0CD, NULL); + gpio_request(GPIO_FN_SDHI0WP, NULL); + gpio_request(GPIO_FN_SDHI0CMD, NULL); + gpio_request(GPIO_FN_SDHI0CLK, NULL); + gpio_request(GPIO_FN_SDHI0D3, NULL); + gpio_request(GPIO_FN_SDHI0D2, NULL); + gpio_request(GPIO_FN_SDHI0D1, NULL); + gpio_request(GPIO_FN_SDHI0D0, NULL); + gpio_request(GPIO_PTB6, NULL); + gpio_direction_output(GPIO_PTB6, 0); + +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) + /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ + gpio_request(GPIO_FN_SDHI1CD, NULL); + gpio_request(GPIO_FN_SDHI1WP, NULL); + gpio_request(GPIO_FN_SDHI1CMD, NULL); + gpio_request(GPIO_FN_SDHI1CLK, NULL); + gpio_request(GPIO_FN_SDHI1D3, NULL); + gpio_request(GPIO_FN_SDHI1D2, NULL); + gpio_request(GPIO_FN_SDHI1D1, NULL); + gpio_request(GPIO_FN_SDHI1D0, NULL); + gpio_request(GPIO_PTB7, NULL); + gpio_direction_output(GPIO_PTB7, 0); + + /* I/O buffer drive ability is high for SDHI1 */ + __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); +#endif /* CONFIG_MMC_SH_MMCIF */ +#else + /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ + gpio_request(GPIO_FN_MSIOF0_TXD, NULL); + gpio_request(GPIO_FN_MSIOF0_RXD, NULL); + gpio_request(GPIO_FN_MSIOF0_TSCK, NULL); + gpio_request(GPIO_PTM4, NULL); /* software CS control of TSYNC pin */ + gpio_direction_output(GPIO_PTM4, 1); /* active low CS */ + gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */ + gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */ + gpio_request(GPIO_PTY6, NULL); /* write protect */ + gpio_direction_input(GPIO_PTY6); + gpio_request(GPIO_PTY7, NULL); /* card detect */ + gpio_direction_input(GPIO_PTY7); + + spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); +#endif + + /* enable Video */ + gpio_request(GPIO_PTU2, NULL); + gpio_direction_output(GPIO_PTU2, 1); + + /* enable Camera */ + gpio_request(GPIO_PTA3, NULL); + gpio_request(GPIO_PTA4, NULL); + gpio_direction_output(GPIO_PTA3, 0); + gpio_direction_output(GPIO_PTA4, 0); + + /* enable FSI */ + gpio_request(GPIO_FN_FSIMCKB, NULL); + gpio_request(GPIO_FN_FSIIBSD, NULL); + gpio_request(GPIO_FN_FSIOBSD, NULL); + gpio_request(GPIO_FN_FSIIBBCK, NULL); + gpio_request(GPIO_FN_FSIIBLRCK, NULL); + gpio_request(GPIO_FN_FSIOBBCK, NULL); + gpio_request(GPIO_FN_FSIOBLRCK, NULL); + gpio_request(GPIO_FN_CLKAUDIOBO, NULL); + + /* set SPU2 clock to 83.4 MHz */ + clk = clk_get(NULL, "spu_clk"); + if (!IS_ERR(clk)) { + clk_set_rate(clk, clk_round_rate(clk, 83333333)); + clk_put(clk); + } + + /* change parent of FSI B */ + clk = clk_get(NULL, "fsib_clk"); + if (!IS_ERR(clk)) { + /* 48kHz dummy clock was used to make sure 1/1 divide */ + clk_set_rate(&sh7724_fsimckb_clk, 48000); + clk_set_parent(clk, &sh7724_fsimckb_clk); + clk_set_rate(clk, 48000); + clk_put(clk); + } + + gpio_request(GPIO_PTU0, NULL); + gpio_direction_output(GPIO_PTU0, 0); + mdelay(20); + + /* enable motion sensor */ + gpio_request(GPIO_FN_INTC_IRQ1, NULL); + gpio_direction_input(GPIO_FN_INTC_IRQ1); + + /* set VPU clock to 166 MHz */ + clk = clk_get(NULL, "vpu_clk"); + if (!IS_ERR(clk)) { + clk_set_rate(clk, clk_round_rate(clk, 166000000)); + clk_put(clk); + } + + /* enable IrDA */ + gpio_request(GPIO_FN_IRDA_OUT, NULL); + gpio_request(GPIO_FN_IRDA_IN, NULL); + gpio_request(GPIO_PTU5, NULL); + gpio_direction_output(GPIO_PTU5, 0); + +#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) + /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */ + gpio_request(GPIO_FN_MMC_D7, NULL); + gpio_request(GPIO_FN_MMC_D6, NULL); + gpio_request(GPIO_FN_MMC_D5, NULL); + gpio_request(GPIO_FN_MMC_D4, NULL); + gpio_request(GPIO_FN_MMC_D3, NULL); + gpio_request(GPIO_FN_MMC_D2, NULL); + gpio_request(GPIO_FN_MMC_D1, NULL); + gpio_request(GPIO_FN_MMC_D0, NULL); + gpio_request(GPIO_FN_MMC_CLK, NULL); + gpio_request(GPIO_FN_MMC_CMD, NULL); + gpio_request(GPIO_PTB7, NULL); + gpio_direction_output(GPIO_PTB7, 0); + + /* I/O buffer drive ability is high for MMCIF */ + __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); +#endif + + /* enable I2C device */ + i2c_register_board_info(0, i2c0_devices, + ARRAY_SIZE(i2c0_devices)); + + i2c_register_board_info(1, i2c1_devices, + ARRAY_SIZE(i2c1_devices)); + +#if defined(CONFIG_VIDEO_SH_VOU) || defined(CONFIG_VIDEO_SH_VOU_MODULE) + /* VOU */ + gpio_request(GPIO_FN_DV_D15, NULL); + gpio_request(GPIO_FN_DV_D14, NULL); + gpio_request(GPIO_FN_DV_D13, NULL); + gpio_request(GPIO_FN_DV_D12, NULL); + gpio_request(GPIO_FN_DV_D11, NULL); + gpio_request(GPIO_FN_DV_D10, NULL); + gpio_request(GPIO_FN_DV_D9, NULL); + gpio_request(GPIO_FN_DV_D8, NULL); + gpio_request(GPIO_FN_DV_CLKI, NULL); + gpio_request(GPIO_FN_DV_CLK, NULL); + gpio_request(GPIO_FN_DV_VSYNC, NULL); + gpio_request(GPIO_FN_DV_HSYNC, NULL); + + /* AK8813 power / reset sequence */ + gpio_request(GPIO_PTG4, NULL); + gpio_request(GPIO_PTU3, NULL); + /* Reset */ + gpio_direction_output(GPIO_PTG4, 0); + /* Power down */ + gpio_direction_output(GPIO_PTU3, 1); + + udelay(10); + + /* Power up, reset */ + gpio_set_value(GPIO_PTU3, 0); + + udelay(10); + + /* Remove reset */ + gpio_set_value(GPIO_PTG4, 1); +#endif + + return platform_add_devices(ecovec_devices, + ARRAY_SIZE(ecovec_devices)); +} +arch_initcall(arch_setup); + +static int __init devices_setup(void) +{ + sh_eth_init(&sh_eth_plat); + return 0; +} +device_initcall(devices_setup); + +static struct sh_machine_vector mv_ecovec __initmv = { + .mv_name = "R0P7724 (EcoVec)", +}; diff --git a/arch/sh/boards/mach-highlander/Kconfig b/arch/sh/boards/mach-highlander/Kconfig new file mode 100644 index 00000000000..def49cc0a7b --- /dev/null +++ b/arch/sh/boards/mach-highlander/Kconfig @@ -0,0 +1,25 @@ +if SH_HIGHLANDER + +choice + prompt "Highlander options" + default SH_R7780MP + +config SH_R7780RP + bool "R7780RP-1 board support" + depends on CPU_SUBTYPE_SH7780 + +config SH_R7780MP + bool "R7780MP board support" + depends on CPU_SUBTYPE_SH7780 + help + Selecting this option will enable support for the mass-production + version of the R7780RP. If in doubt, say Y. + +config SH_R7785RP + bool "R7785RP board support" + depends on CPU_SUBTYPE_SH7785 + select ARCH_REQUIRE_GPIOLIB + +endchoice + +endif diff --git a/arch/sh/boards/mach-highlander/Makefile b/arch/sh/boards/mach-highlander/Makefile new file mode 100644 index 00000000000..d93aaf88013 --- /dev/null +++ b/arch/sh/boards/mach-highlander/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the Highlander specific parts of the kernel +# +obj-y := setup.o +obj-$(CONFIG_SH_R7780RP) += irq-r7780rp.o +obj-$(CONFIG_SH_R7780MP) += irq-r7780mp.o +obj-$(CONFIG_SH_R7785RP) += irq-r7785rp.o pinmux-r7785rp.o + +ifneq ($(CONFIG_SH_R7785RP),y) +obj-$(CONFIG_PUSH_SWITCH) += psw.o +endif diff --git a/arch/sh/boards/mach-highlander/irq-r7780mp.c b/arch/sh/boards/mach-highlander/irq-r7780mp.c new file mode 100644 index 00000000000..9893fd3a135 --- /dev/null +++ b/arch/sh/boards/mach-highlander/irq-r7780mp.c @@ -0,0 +1,74 @@ +/* + * Renesas Solutions Highlander R7780MP Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/highlander.h> + +enum { + UNUSED = 0, + + /* board specific interrupt sources */ + CF, /* Compact Flash */ + TP, /* Touch panel */ + SCIF1, /* FPGA SCIF1 */ + SCIF0, /* FPGA SCIF0 */ + SMBUS, /* SMBUS */ + RTC, /* RTC Alarm */ + AX88796, /* Ethernet controller */ + PSW, /* Push Switch */ + + /* external bus connector */ + EXT1, EXT2, EXT4, EXT5, EXT6, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(TP, IRQ_TP), + INTC_IRQ(SCIF1, IRQ_SCIF1), + INTC_IRQ(SCIF0, IRQ_SCIF0), + INTC_IRQ(SMBUS, IRQ_SMBUS), + INTC_IRQ(RTC, IRQ_RTC), + INTC_IRQ(AX88796, IRQ_AX88796), + INTC_IRQ(PSW, IRQ_PSW), + + INTC_IRQ(EXT1, IRQ_EXT1), INTC_IRQ(EXT2, IRQ_EXT2), + INTC_IRQ(EXT4, IRQ_EXT4), INTC_IRQ(EXT5, IRQ_EXT5), + INTC_IRQ(EXT6, IRQ_EXT6), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { SCIF0, SCIF1, RTC, 0, CF, 0, TP, SMBUS, + 0, EXT6, EXT5, EXT4, EXT2, EXT1, PSW, AX88796 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 0, IRQ_CF, IRQ_TP, IRQ_SCIF1, + IRQ_SCIF0, IRQ_SMBUS, IRQ_RTC, IRQ_EXT6, + IRQ_EXT5, IRQ_EXT4, IRQ_EXT2, IRQ_EXT1, + 0, IRQ_AX88796, IRQ_PSW, +}; + +static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors, + NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_plat_irq_setup(void) +{ + if ((__raw_readw(0xa4000700) & 0xf000) == 0x2000) { + printk(KERN_INFO "Using r7780mp interrupt controller.\n"); + register_intc_controller(&intc_desc); + return irl2irq; + } + + return NULL; +} diff --git a/arch/sh/boards/mach-highlander/irq-r7780rp.c b/arch/sh/boards/mach-highlander/irq-r7780rp.c new file mode 100644 index 00000000000..0805b215145 --- /dev/null +++ b/arch/sh/boards/mach-highlander/irq-r7780rp.c @@ -0,0 +1,67 @@ +/* + * Renesas Solutions Highlander R7780RP-1 Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/highlander.h> + +enum { + UNUSED = 0, + + /* board specific interrupt sources */ + + AX88796, /* Ethernet controller */ + PSW, /* Push Switch */ + CF, /* Compact Flash */ + + PCI_A, + PCI_B, + PCI_C, + PCI_D, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(PCI_A, 65), /* dirty: overwrite cpu vectors for pci */ + INTC_IRQ(PCI_B, 66), + INTC_IRQ(PCI_C, 67), + INTC_IRQ(PCI_D, 68), + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(PSW, IRQ_PSW), + INTC_IRQ(AX88796, IRQ_AX88796), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa5000000, 0, 16, /* IRLMSK */ + { PCI_A, PCI_B, PCI_C, PCI_D, CF, 0, 0, 0, + 0, 0, 0, 0, 0, 0, PSW, AX88796 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 65, 66, 67, 68, + IRQ_CF, 0, 0, 0, + 0, 0, 0, 0, + IRQ_AX88796, IRQ_PSW +}; + +static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors, + NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_plat_irq_setup(void) +{ + if (__raw_readw(0xa5000600)) { + printk(KERN_INFO "Using r7780rp interrupt controller.\n"); + register_intc_controller(&intc_desc); + return irl2irq; + } + + return NULL; +} diff --git a/arch/sh/boards/mach-highlander/irq-r7785rp.c b/arch/sh/boards/mach-highlander/irq-r7785rp.c new file mode 100644 index 00000000000..558b2486277 --- /dev/null +++ b/arch/sh/boards/mach-highlander/irq-r7785rp.c @@ -0,0 +1,86 @@ +/* + * Renesas Solutions Highlander R7785RP Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 - 2008 Paul Mundt + * Copyright (C) 2007 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/highlander.h> + +enum { + UNUSED = 0, + + /* FPGA specific interrupt sources */ + CF, /* Compact Flash */ + SMBUS, /* SMBUS */ + TP, /* Touch panel */ + RTC, /* RTC Alarm */ + TH_ALERT, /* Temperature sensor */ + AX88796, /* Ethernet controller */ + + /* external bus connector */ + EXT0, EXT1, EXT2, EXT3, EXT4, EXT5, EXT6, EXT7, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(SMBUS, IRQ_SMBUS), + INTC_IRQ(TP, IRQ_TP), + INTC_IRQ(RTC, IRQ_RTC), + INTC_IRQ(TH_ALERT, IRQ_TH_ALERT), + + INTC_IRQ(EXT0, IRQ_EXT0), INTC_IRQ(EXT1, IRQ_EXT1), + INTC_IRQ(EXT2, IRQ_EXT2), INTC_IRQ(EXT3, IRQ_EXT3), + + INTC_IRQ(EXT4, IRQ_EXT4), INTC_IRQ(EXT5, IRQ_EXT5), + INTC_IRQ(EXT6, IRQ_EXT6), INTC_IRQ(EXT7, IRQ_EXT7), + + INTC_IRQ(AX88796, IRQ_AX88796), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4000010, 0, 16, /* IRLMCR1 */ + { 0, 0, 0, 0, CF, AX88796, SMBUS, TP, + RTC, 0, TH_ALERT, 0, 0, 0, 0, 0 } }, + { 0xa4000012, 0, 16, /* IRLMCR2 */ + { 0, 0, 0, 0, 0, 0, 0, 0, + EXT7, EXT6, EXT5, EXT4, EXT3, EXT2, EXT1, EXT0 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 0, IRQ_CF, IRQ_EXT4, IRQ_EXT5, + IRQ_EXT6, IRQ_EXT7, IRQ_SMBUS, IRQ_TP, + IRQ_RTC, IRQ_TH_ALERT, IRQ_AX88796, IRQ_EXT0, + IRQ_EXT1, IRQ_EXT2, IRQ_EXT3, +}; + +static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors, + NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_plat_irq_setup(void) +{ + if ((__raw_readw(0xa4000158) & 0xf000) != 0x1000) + return NULL; + + printk(KERN_INFO "Using r7785rp interrupt controller.\n"); + + __raw_writew(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ + + /* Setup the FPGA IRL */ + __raw_writew(0x0000, PA_IRLPRA); /* FPGA IRLA */ + __raw_writew(0xe598, PA_IRLPRB); /* FPGA IRLB */ + __raw_writew(0x7060, PA_IRLPRC); /* FPGA IRLC */ + __raw_writew(0x0000, PA_IRLPRD); /* FPGA IRLD */ + __raw_writew(0x4321, PA_IRLPRE); /* FPGA IRLE */ + __raw_writew(0xdcba, PA_IRLPRF); /* FPGA IRLF */ + + register_intc_controller(&intc_desc); + return irl2irq; +} diff --git a/arch/sh/boards/mach-highlander/pinmux-r7785rp.c b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c new file mode 100644 index 00000000000..c77a2bea8f2 --- /dev/null +++ b/arch/sh/boards/mach-highlander/pinmux-r7785rp.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2008 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/gpio.h> +#include <cpu/sh7785.h> + +void __init highlander_plat_pinmux_setup(void) +{ + /* SCIF0 */ + gpio_request(GPIO_FN_SCIF0_CTS, NULL); + gpio_request(GPIO_FN_SCIF0_RTS, NULL); + gpio_request(GPIO_FN_SCIF0_SCK, NULL); + gpio_request(GPIO_FN_SCIF0_RXD, NULL); + gpio_request(GPIO_FN_SCIF0_TXD, NULL); +} diff --git a/arch/sh/boards/mach-highlander/psw.c b/arch/sh/boards/mach-highlander/psw.c new file mode 100644 index 00000000000..522786318d3 --- /dev/null +++ b/arch/sh/boards/mach-highlander/psw.c @@ -0,0 +1,122 @@ +/* + * arch/sh/boards/renesas/r7780rp/psw.c + * + * push switch support for RDBRP-1/RDBREVRP-1 debug boards. + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/io.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <mach/highlander.h> +#include <asm/push-switch.h> + +static irqreturn_t psw_irq_handler(int irq, void *arg) +{ + struct platform_device *pdev = arg; + struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch_platform_info *psw_info = pdev->dev.platform_data; + unsigned int l, mask; + int ret = 0; + + l = __raw_readw(PA_DBSW); + + /* Nothing to do if there's no state change */ + if (psw->state) { + ret = 1; + goto out; + } + + mask = l & 0x70; + /* Figure out who raised it */ + if (mask & (1 << psw_info->bit)) { + psw->state = !!(mask & (1 << psw_info->bit)); + if (psw->state) /* debounce */ + mod_timer(&psw->debounce, jiffies + 50); + + ret = 1; + } + +out: + /* Clear the switch IRQs */ + l |= (0x7 << 12); + __raw_writew(l, PA_DBSW); + + return IRQ_RETVAL(ret); +} + +static struct resource psw_resources[] = { + [0] = { + .start = IRQ_PSW, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct push_switch_platform_info s2_platform_data = { + .name = "s2", + .bit = 6, + .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device s2_switch_device = { + .name = "push-switch", + .id = 0, + .num_resources = ARRAY_SIZE(psw_resources), + .resource = psw_resources, + .dev = { + .platform_data = &s2_platform_data, + }, +}; + +static struct push_switch_platform_info s3_platform_data = { + .name = "s3", + .bit = 5, + .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device s3_switch_device = { + .name = "push-switch", + .id = 1, + .num_resources = ARRAY_SIZE(psw_resources), + .resource = psw_resources, + .dev = { + .platform_data = &s3_platform_data, + }, +}; + +static struct push_switch_platform_info s4_platform_data = { + .name = "s4", + .bit = 4, + .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device s4_switch_device = { + .name = "push-switch", + .id = 2, + .num_resources = ARRAY_SIZE(psw_resources), + .resource = psw_resources, + .dev = { + .platform_data = &s4_platform_data, + }, +}; + +static struct platform_device *psw_devices[] = { + &s2_switch_device, &s3_switch_device, &s4_switch_device, +}; + +static int __init psw_init(void) +{ + return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); +} +module_init(psw_init); diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c new file mode 100644 index 00000000000..74b8db1b74a --- /dev/null +++ b/arch/sh/boards/mach-highlander/setup.c @@ -0,0 +1,419 @@ +/* + * arch/sh/boards/renesas/r7780rp/setup.c + * + * Renesas Solutions Highlander Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2005 - 2008 Paul Mundt + * + * This contains support for the R7780RP-1, R7780MP, and R7785RP + * Highlander modules. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/types.h> +#include <linux/mtd/physmap.h> +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/usb/r8a66597.h> +#include <linux/usb/m66592.h> +#include <linux/clkdev.h> +#include <net/ax88796.h> +#include <asm/machvec.h> +#include <mach/highlander.h> +#include <asm/clock.h> +#include <asm/heartbeat.h> +#include <asm/io.h> +#include <asm/io_trapped.h> + +static struct r8a66597_platdata r8a66597_data = { + .xtal = R8A66597_PLATDATA_XTAL_12MHZ, + .vif = 1, +}; + +static struct resource r8a66597_usb_host_resources[] = { + [0] = { + .start = 0xA4200000, + .end = 0xA42000FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_EXT1, /* irq number */ + .end = IRQ_EXT1, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, +}; + +static struct platform_device r8a66597_usb_host_device = { + .name = "r8a66597_hcd", + .id = -1, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &r8a66597_data, + }, + .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), + .resource = r8a66597_usb_host_resources, +}; + +static struct m66592_platdata usbf_platdata = { + .xtal = M66592_PLATDATA_XTAL_24MHZ, + .vif = 1, +}; + +static struct resource m66592_usb_peripheral_resources[] = { + [0] = { + .name = "m66592_udc", + .start = 0xb0000000, + .end = 0xb00000FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "m66592_udc", + .start = IRQ_EXT4, /* irq number */ + .end = IRQ_EXT4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m66592_usb_peripheral_device = { + .name = "m66592_udc", + .id = -1, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbf_platdata, + }, + .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), + .resource = m66592_usb_peripheral_resources, +}; + +static struct resource cf_ide_resources[] = { + [0] = { + .start = PA_AREA5_IO + 0x1000, + .end = PA_AREA5_IO + 0x1000 + 0x08 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PA_AREA5_IO + 0x80c, + .end = PA_AREA5_IO + 0x80c + 0x16 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_CF, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct pata_platform_info pata_info = { + .ioport_shift = 1, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, + .dev = { + .platform_data = &pata_info, + }, +}; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_OBLED, + .end = PA_OBLED, + .flags = IORESOURCE_MEM, + }, +}; + +#ifndef CONFIG_SH_R7785RP +static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; + +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; +#endif + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + + /* R7785RP has a slightly more sensible FPGA.. */ +#ifndef CONFIG_SH_R7785RP + .dev = { + .platform_data = &heartbeat_data, + }, +#endif + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +static struct ax_plat_data ax88796_platdata = { + .flags = AXFLG_HAS_93CX6, + .wordlength = 2, + .dcr_val = 0x1, + .rcr_val = 0x40, +}; + +static struct resource ax88796_resources[] = { + { +#ifdef CONFIG_SH_R7780RP + .start = 0xa5800400, + .end = 0xa5800400 + (0x20 * 0x2) - 1, +#else + .start = 0xa4100400, + .end = 0xa4100400 + (0x20 * 0x2) - 1, +#endif + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_AX88796, + .end = IRQ_AX88796, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ax88796_device = { + .name = "ax88796", + .id = 0, + + .dev = { + .platform_data = &ax88796_platdata, + }, + + .num_resources = ARRAY_SIZE(ax88796_resources), + .resource = ax88796_resources, +}; + +static struct mtd_partition nor_flash_partitions[] = { + { + .name = "loader", + .offset = 0x00000000, + .size = 512 * 1024, + }, + { + .name = "bootenv", + .offset = MTDPART_OFS_APPEND, + .size = 512 * 1024, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 4 * 1024 * 1024, + }, + { + .name = "data", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data nor_flash_data = { + .width = 4, + .parts = nor_flash_partitions, + .nr_parts = ARRAY_SIZE(nor_flash_partitions), +}; + +/* This config is flash board for mass production. */ +static struct resource nor_flash_resources[] = { + [0] = { + .start = PA_NORFLASH_ADDR, + .end = PA_NORFLASH_ADDR + PA_NORFLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device nor_flash_device = { + .name = "physmap-flash", + .dev = { + .platform_data = &nor_flash_data, + }, + .num_resources = ARRAY_SIZE(nor_flash_resources), + .resource = nor_flash_resources, +}; + +static struct resource smbus_resources[] = { + [0] = { + .start = PA_SMCR, + .end = PA_SMCR + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SMBUS, + .end = IRQ_SMBUS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smbus_device = { + .name = "i2c-highlander", + .id = 0, + .num_resources = ARRAY_SIZE(smbus_resources), + .resource = smbus_resources, +}; + +static struct i2c_board_info __initdata highlander_i2c_devices[] = { + { + I2C_BOARD_INFO("r2025sd", 0x32), + }, +}; + +static struct platform_device *r7780rp_devices[] __initdata = { + &r8a66597_usb_host_device, + &m66592_usb_peripheral_device, + &heartbeat_device, + &smbus_device, + &nor_flash_device, +#ifndef CONFIG_SH_R7780RP + &ax88796_device, +#endif +}; + +/* + * The CF is connected using a 16-bit bus where 8-bit operations are + * unsupported. The linux ata driver is however using 8-bit operations, so + * insert a trapped io filter to convert 8-bit operations into 16-bit. + */ +static struct trapped_io cf_trapped_io = { + .resource = cf_ide_resources, + .num_resources = 2, + .minimum_bus_width = 16, +}; + +static int __init r7780rp_devices_setup(void) +{ + int ret = 0; + +#ifndef CONFIG_SH_R7780RP + if (register_trapped_io(&cf_trapped_io) == 0) + ret |= platform_device_register(&cf_ide_device); +#endif + + ret |= platform_add_devices(r7780rp_devices, + ARRAY_SIZE(r7780rp_devices)); + + ret |= i2c_register_board_info(0, highlander_i2c_devices, + ARRAY_SIZE(highlander_i2c_devices)); + + return ret; +} +device_initcall(r7780rp_devices_setup); + +/* + * Platform specific clocks + */ +static int ivdr_clk_enable(struct clk *clk) +{ + __raw_writew(__raw_readw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL); + return 0; +} + +static void ivdr_clk_disable(struct clk *clk) +{ + __raw_writew(__raw_readw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL); +} + +static struct clk_ops ivdr_clk_ops = { + .enable = ivdr_clk_enable, + .disable = ivdr_clk_disable, +}; + +static struct clk ivdr_clk = { + .ops = &ivdr_clk_ops, +}; + +static struct clk *r7780rp_clocks[] = { + &ivdr_clk, +}; + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("ivdr_clk", &ivdr_clk), +}; + +static void r7780rp_power_off(void) +{ + if (mach_is_r7780mp() || mach_is_r7785rp()) + __raw_writew(0x0001, PA_POFF); +} + +/* + * Initialize the board + */ +static void __init highlander_setup(char **cmdline_p) +{ + u16 ver = __raw_readw(PA_VERREG); + int i; + + printk(KERN_INFO "Renesas Solutions Highlander %s support.\n", + mach_is_r7780rp() ? "R7780RP-1" : + mach_is_r7780mp() ? "R7780MP" : + "R7785RP"); + + printk(KERN_INFO "Board version: %d (revision %d), " + "FPGA version: %d (revision %d)\n", + (ver >> 12) & 0xf, (ver >> 8) & 0xf, + (ver >> 4) & 0xf, ver & 0xf); + + highlander_plat_pinmux_setup(); + + /* + * Enable the important clocks right away.. + */ + for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) { + struct clk *clk = r7780rp_clocks[i]; + + clk_register(clk); + clk_enable(clk); + } + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + __raw_writew(0x0000, PA_OBLED); /* Clear LED. */ + + if (mach_is_r7780rp()) + __raw_writew(0x0001, PA_SDPOW); /* SD Power ON */ + + __raw_writew(__raw_readw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */ + + pm_power_off = r7780rp_power_off; +} + +static unsigned char irl2irq[HL_NR_IRL]; + +static int highlander_irq_demux(int irq) +{ + if (irq >= HL_NR_IRL || irq < 0 || !irl2irq[irq]) + return irq; + + return irl2irq[irq]; +} + +static void __init highlander_init_irq(void) +{ + unsigned char *ucp = highlander_plat_irq_setup(); + + if (ucp) { + plat_irq_setup_pins(IRQ_MODE_IRL3210); + memcpy(irl2irq, ucp, HL_NR_IRL); + } +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_highlander __initmv = { + .mv_name = "Highlander", + .mv_setup = highlander_setup, + .mv_init_irq = highlander_init_irq, + .mv_irq_demux = highlander_irq_demux, +}; diff --git a/arch/sh/boards/mach-hp6xx/Makefile b/arch/sh/boards/mach-hp6xx/Makefile new file mode 100644 index 00000000000..b3124278247 --- /dev/null +++ b/arch/sh/boards/mach-hp6xx/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the HP6xx specific parts of the kernel +# + +obj-y := setup.o +obj-$(CONFIG_PM) += pm.o pm_wakeup.o +obj-$(CONFIG_APM_EMULATION) += hp6xx_apm.o diff --git a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c new file mode 100644 index 00000000000..865d8d6e823 --- /dev/null +++ b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c @@ -0,0 +1,111 @@ +/* + * bios-less APM driver for hp680 + * + * Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com> + * Copyright 2008 (c) Kristoffer Ericson <kristoffer.ericson@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/apm-emulation.h> +#include <linux/io.h> +#include <asm/adc.h> +#include <mach/hp6xx.h> + +/* percentage values */ +#define APM_CRITICAL 10 +#define APM_LOW 30 + +/* resonably sane values */ +#define HP680_BATTERY_MAX 898 +#define HP680_BATTERY_MIN 486 +#define HP680_BATTERY_AC_ON 1023 + +#define MODNAME "hp6x0_apm" + +#define PGDR 0xa400012c + +static void hp6x0_apm_get_power_status(struct apm_power_info *info) +{ + int battery, backup, charging, percentage; + u8 pgdr; + + battery = adc_single(ADC_CHANNEL_BATTERY); + backup = adc_single(ADC_CHANNEL_BACKUP); + charging = adc_single(ADC_CHANNEL_CHARGE); + + percentage = 100 * (battery - HP680_BATTERY_MIN) / + (HP680_BATTERY_MAX - HP680_BATTERY_MIN); + + /* % of full battery */ + info->battery_life = percentage; + + /* We want our estimates in minutes */ + info->units = 0; + + /* Extremely(!!) rough estimate, we will replace this with a datalist later on */ + info->time = (2 * battery); + + info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ? + APM_AC_ONLINE : APM_AC_OFFLINE; + + pgdr = __raw_readb(PGDR); + if (pgdr & PGDR_MAIN_BATTERY_OUT) { + info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + info->battery_flag = 0x80; + } else if (charging < 8) { + info->battery_status = APM_BATTERY_STATUS_CHARGING; + info->battery_flag = 0x08; + info->ac_line_status = 0x01; + } else if (percentage <= APM_CRITICAL) { + info->battery_status = APM_BATTERY_STATUS_CRITICAL; + info->battery_flag = 0x04; + } else if (percentage <= APM_LOW) { + info->battery_status = APM_BATTERY_STATUS_LOW; + info->battery_flag = 0x02; + } else { + info->battery_status = APM_BATTERY_STATUS_HIGH; + info->battery_flag = 0x01; + } +} + +static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev) +{ + if (!APM_DISABLED) + apm_queue_event(APM_USER_SUSPEND); + + return IRQ_HANDLED; +} + +static int __init hp6x0_apm_init(void) +{ + int ret; + + ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt, + 0, MODNAME, NULL); + if (unlikely(ret < 0)) { + printk(KERN_ERR MODNAME ": IRQ %d request failed\n", + HP680_BTN_IRQ); + return ret; + } + + apm_get_power_status = hp6x0_apm_get_power_status; + + return ret; +} + +static void __exit hp6x0_apm_exit(void) +{ + free_irq(HP680_BTN_IRQ, 0); +} + +module_init(hp6x0_apm_init); +module_exit(hp6x0_apm_exit); + +MODULE_AUTHOR("Adriy Skulysh"); +MODULE_DESCRIPTION("hp6xx Advanced Power Management"); +MODULE_LICENSE("GPL"); diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c new file mode 100644 index 00000000000..adc9b4bba82 --- /dev/null +++ b/arch/sh/boards/mach-hp6xx/pm.c @@ -0,0 +1,157 @@ +/* + * hp6x0 Power Management Routines + * + * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ +#include <linux/init.h> +#include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/delay.h> +#include <linux/gfp.h> +#include <asm/io.h> +#include <asm/hd64461.h> +#include <mach/hp6xx.h> +#include <cpu/dac.h> +#include <asm/freq.h> +#include <asm/watchdog.h> + +#define INTR_OFFSET 0x600 + +#define STBCR 0xffffff82 +#define STBCR2 0xffffff88 + +#define STBCR_STBY 0x80 +#define STBCR_MSTP2 0x04 + +#define MCR 0xffffff68 +#define RTCNT 0xffffff70 + +#define MCR_RMODE 2 +#define MCR_RFSH 4 + +extern u8 wakeup_start; +extern u8 wakeup_end; + +static void pm_enter(void) +{ + u8 stbcr, csr; + u16 frqcr, mcr; + u32 vbr_new, vbr_old; + + set_bl_bit(); + + /* set wdt */ + csr = sh_wdt_read_csr(); + csr &= ~WTCSR_TME; + csr |= WTCSR_CKS_4096; + sh_wdt_write_csr(csr); + csr = sh_wdt_read_csr(); + sh_wdt_write_cnt(0); + + /* disable PLL1 */ + frqcr = __raw_readw(FRQCR); + frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY); + __raw_writew(frqcr, FRQCR); + + /* enable standby */ + stbcr = __raw_readb(STBCR); + __raw_writeb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR); + + /* set self-refresh */ + mcr = __raw_readw(MCR); + __raw_writew(mcr & ~MCR_RFSH, MCR); + + /* set interrupt handler */ + asm volatile("stc vbr, %0" : "=r" (vbr_old)); + vbr_new = get_zeroed_page(GFP_ATOMIC); + udelay(50); + memcpy((void*)(vbr_new + INTR_OFFSET), + &wakeup_start, &wakeup_end - &wakeup_start); + asm volatile("ldc %0, vbr" : : "r" (vbr_new)); + + __raw_writew(0, RTCNT); + __raw_writew(mcr | MCR_RFSH | MCR_RMODE, MCR); + + cpu_sleep(); + + asm volatile("ldc %0, vbr" : : "r" (vbr_old)); + + free_page(vbr_new); + + /* enable PLL1 */ + frqcr = __raw_readw(FRQCR); + frqcr |= FRQCR_PSTBY; + __raw_writew(frqcr, FRQCR); + udelay(50); + frqcr |= FRQCR_PLLEN; + __raw_writew(frqcr, FRQCR); + + __raw_writeb(stbcr, STBCR); + + clear_bl_bit(); +} + +static int hp6x0_pm_enter(suspend_state_t state) +{ + u8 stbcr, stbcr2; +#ifdef CONFIG_HD64461_ENABLER + u8 scr; + u16 hd64461_stbcr; +#endif + +#ifdef CONFIG_HD64461_ENABLER + outb(0, HD64461_PCC1CSCIER); + + scr = inb(HD64461_PCC1SCR); + scr |= HD64461_PCCSCR_VCC1; + outb(scr, HD64461_PCC1SCR); + + hd64461_stbcr = inw(HD64461_STBCR); + hd64461_stbcr |= HD64461_STBCR_SPC1ST; + outw(hd64461_stbcr, HD64461_STBCR); +#endif + + __raw_writeb(0x1f, DACR); + + stbcr = __raw_readb(STBCR); + __raw_writeb(0x01, STBCR); + + stbcr2 = __raw_readb(STBCR2); + __raw_writeb(0x7f , STBCR2); + + outw(0xf07f, HD64461_SCPUCR); + + pm_enter(); + + outw(0, HD64461_SCPUCR); + __raw_writeb(stbcr, STBCR); + __raw_writeb(stbcr2, STBCR2); + +#ifdef CONFIG_HD64461_ENABLER + hd64461_stbcr = inw(HD64461_STBCR); + hd64461_stbcr &= ~HD64461_STBCR_SPC1ST; + outw(hd64461_stbcr, HD64461_STBCR); + + outb(0x4c, HD64461_PCC1CSCIER); + outb(0x00, HD64461_PCC1CSCR); +#endif + + return 0; +} + +static const struct platform_suspend_ops hp6x0_pm_ops = { + .enter = hp6x0_pm_enter, + .valid = suspend_valid_only_mem, +}; + +static int __init hp6x0_pm_init(void) +{ + suspend_set_ops(&hp6x0_pm_ops); + return 0; +} + +late_initcall(hp6x0_pm_init); diff --git a/arch/sh/boards/mach-hp6xx/pm_wakeup.S b/arch/sh/boards/mach-hp6xx/pm_wakeup.S new file mode 100644 index 00000000000..4f18d44e054 --- /dev/null +++ b/arch/sh/boards/mach-hp6xx/pm_wakeup.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include <linux/linkage.h> +#include <cpu/mmu_context.h> + +/* + * Kernel mode register usage: + * k0 scratch + * k1 scratch + * For more details, please have a look at entry.S + */ + +#define k0 r0 +#define k1 r1 + +ENTRY(wakeup_start) +! clear STBY bit + mov #-126, k1 + and #127, k0 + mov.b k0, @k1 +! enable refresh + mov.l 5f, k1 + mov.w 6f, k0 + mov.w k0, @k1 +! jump to handler + mov.l 4f, k1 + jmp @k1 + nop + + .align 2 +4: .long handle_interrupt +5: .long 0xffffff68 +6: .word 0x0524 + +ENTRY(wakeup_end) + nop diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c new file mode 100644 index 00000000000..8c9add5f4cf --- /dev/null +++ b/arch/sh/boards/mach-hp6xx/setup.c @@ -0,0 +1,175 @@ +/* + * linux/arch/sh/boards/hp6xx/setup.c + * + * Copyright (C) 2002 Andriy Skulysh + * Copyright (C) 2007 Kristoffer Ericson <Kristoffer_e1@hotmail.com> + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Setup code for HP620/HP660/HP680/HP690 (internal peripherials only) + */ +#include <linux/types.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <sound/sh_dac_audio.h> +#include <asm/hd64461.h> +#include <asm/io.h> +#include <mach/hp6xx.h> +#include <cpu/dac.h> + +#define SCPCR 0xa4000116 +#define SCPDR 0xa4000136 + +/* CF Slot */ +static struct resource cf_ide_resources[] = { + [0] = { + .start = 0x15000000 + 0x1f0, + .end = 0x15000000 + 0x1f0 + 0x08 - 0x01, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x15000000 + 0x1fe, + .end = 0x15000000 + 0x1fe + 0x01, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 77, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + +static struct platform_device jornadakbd_device = { + .name = "jornada680_kbd", + .id = -1, +}; + +static void dac_audio_start(struct dac_audio_pdata *pdata) +{ + u16 v; + u8 v8; + + /* HP Jornada 680/690 speaker on */ + v = inw(HD64461_GPADR); + v &= ~HD64461_GPADR_SPEAKER; + outw(v, HD64461_GPADR); + + /* HP Palmtop 620lx/660lx speaker on */ + v8 = inb(PKDR); + v8 &= ~PKDR_SPEAKER; + outb(v8, PKDR); + + sh_dac_enable(pdata->channel); +} + +static void dac_audio_stop(struct dac_audio_pdata *pdata) +{ + u16 v; + u8 v8; + + /* HP Jornada 680/690 speaker off */ + v = inw(HD64461_GPADR); + v |= HD64461_GPADR_SPEAKER; + outw(v, HD64461_GPADR); + + /* HP Palmtop 620lx/660lx speaker off */ + v8 = inb(PKDR); + v8 |= PKDR_SPEAKER; + outb(v8, PKDR); + + sh_dac_output(0, pdata->channel); + sh_dac_disable(pdata->channel); +} + +static struct dac_audio_pdata dac_audio_platform_data = { + .buffer_size = 64000, + .channel = 1, + .start = dac_audio_start, + .stop = dac_audio_stop, +}; + +static struct platform_device dac_audio_device = { + .name = "dac_audio", + .id = -1, + .dev = { + .platform_data = &dac_audio_platform_data, + } + +}; + +static struct platform_device *hp6xx_devices[] __initdata = { + &cf_ide_device, + &jornadakbd_device, + &dac_audio_device, +}; + +static void __init hp6xx_init_irq(void) +{ + /* Gets touchscreen and powerbutton IRQ working */ + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + +static int __init hp6xx_devices_setup(void) +{ + return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices)); +} + +static void __init hp6xx_setup(char **cmdline_p) +{ + u8 v8; + u16 v; + + v = inw(HD64461_STBCR); + v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | + HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | + HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | + HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST| + HD64461_STBCR_SAFECKE_IST; +#ifndef CONFIG_HD64461_ENABLER + v |= HD64461_STBCR_SPC1ST; +#endif + outw(v, HD64461_STBCR); + v = inw(HD64461_GPADR); + v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; + outw(v, HD64461_GPADR); + + outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR); + +#ifndef CONFIG_HD64461_ENABLER + outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR); +#endif + + sh_dac_output(0, DAC_SPEAKER_VOLUME); + sh_dac_disable(DAC_SPEAKER_VOLUME); + v8 = __raw_readb(DACR); + v8 &= ~DACR_DAE; + __raw_writeb(v8,DACR); + + v8 = __raw_readb(SCPDR); + v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y; + v8 &= ~SCPDR_TS_SCAN_ENABLE; + __raw_writeb(v8, SCPDR); + + v = __raw_readw(SCPCR); + v &= ~SCPCR_TS_MASK; + v |= SCPCR_TS_ENABLE; + __raw_writew(v, SCPCR); +} +device_initcall(hp6xx_devices_setup); + +static struct sh_machine_vector mv_hp6xx __initmv = { + .mv_name = "hp6xx", + .mv_setup = hp6xx_setup, + /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ + .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, + /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ + .mv_init_irq = hp6xx_init_irq, +}; diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile new file mode 100644 index 00000000000..60dd63f4a42 --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/Makefile @@ -0,0 +1,4 @@ +obj-y := setup.o sdram.o +ifneq ($(CONFIG_FB_SH_MOBILE_LCDC),) +obj-y += lcd_wqvga.o +endif diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c new file mode 100644 index 00000000000..25e145fb708 --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c @@ -0,0 +1,338 @@ +/* + * KFR2R09 LCD panel support + * + * Copyright (C) 2009 Magnus Damm + * + * Register settings based on the out-of-tree t33fb.c driver + * Copyright (C) 2008 Lineo Solutions, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <video/sh_mobile_lcdc.h> +#include <mach/kfr2r09.h> +#include <cpu/sh7724.h> + +/* The on-board LCD module is a Hitachi TX07D34VM0AAA. This module is made + * up of a 240x400 LCD hooked up to a R61517 driver IC. The driver IC is + * communicating with the main port of the LCDC using an 18-bit SYS interface. + * + * The device code for this LCD module is 0x01221517. + */ + +static const unsigned char data_frame_if[] = { + 0x02, /* WEMODE: 1=cont, 0=one-shot */ + 0x00, 0x00, + 0x00, /* EPF, DFM */ + 0x02, /* RIM[1] : 1 (18bpp) */ +}; + +static const unsigned char data_panel[] = { + 0x0b, + 0x63, /* 400 lines */ + 0x04, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, +}; + +static const unsigned char data_timing[] = { + 0x00, 0x00, 0x13, 0x08, 0x08, +}; + +static const unsigned char data_timing_src[] = { + 0x11, 0x01, 0x00, 0x01, +}; + +static const unsigned char data_gamma[] = { + 0x01, 0x02, 0x08, 0x23, 0x03, 0x0c, 0x00, 0x06, 0x00, 0x00, + 0x01, 0x00, 0x0c, 0x23, 0x03, 0x08, 0x02, 0x06, 0x00, 0x00, +}; + +static const unsigned char data_power[] = { + 0x07, 0xc5, 0xdc, 0x02, 0x33, 0x0a, +}; + +static unsigned long read_reg(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + return so->read_data(sohandle); +} + +static void write_reg(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so, + int i, unsigned long v) +{ + if (i) + so->write_data(sohandle, v); /* PTH4/LCDRS High [param, 17:0] */ + else + so->write_index(sohandle, v); /* PTH4/LCDRS Low [cmd, 7:0] */ +} + +static void write_data(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so, + unsigned char const *data, int no_data) +{ + int i; + + for (i = 0; i < no_data; i++) + write_reg(sohandle, so, 1, data[i]); +} + +static unsigned long read_device_code(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + unsigned long device_code; + + /* access protect OFF */ + write_reg(sohandle, so, 0, 0xb0); + write_reg(sohandle, so, 1, 0x00); + + /* deep standby OFF */ + write_reg(sohandle, so, 0, 0xb1); + write_reg(sohandle, so, 1, 0x00); + + /* device code command */ + write_reg(sohandle, so, 0, 0xbf); + mdelay(50); + + /* dummy read */ + read_reg(sohandle, so); + + /* read device code */ + device_code = ((read_reg(sohandle, so) & 0xff) << 24); + device_code |= ((read_reg(sohandle, so) & 0xff) << 16); + device_code |= ((read_reg(sohandle, so) & 0xff) << 8); + device_code |= (read_reg(sohandle, so) & 0xff); + + return device_code; +} + +static void write_memory_start(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + write_reg(sohandle, so, 0, 0x2c); +} + +static void clear_memory(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + int i; + + /* write start */ + write_memory_start(sohandle, so); + + /* paint it black */ + for (i = 0; i < (240 * 400); i++) + write_reg(sohandle, so, 1, 0x00); +} + +static void display_on(void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + /* access protect off */ + write_reg(sohandle, so, 0, 0xb0); + write_reg(sohandle, so, 1, 0x00); + + /* exit deep standby mode */ + write_reg(sohandle, so, 0, 0xb1); + write_reg(sohandle, so, 1, 0x00); + + /* frame memory I/F */ + write_reg(sohandle, so, 0, 0xb3); + write_data(sohandle, so, data_frame_if, ARRAY_SIZE(data_frame_if)); + + /* display mode and frame memory write mode */ + write_reg(sohandle, so, 0, 0xb4); + write_reg(sohandle, so, 1, 0x00); /* DBI, internal clock */ + + /* panel */ + write_reg(sohandle, so, 0, 0xc0); + write_data(sohandle, so, data_panel, ARRAY_SIZE(data_panel)); + + /* timing (normal) */ + write_reg(sohandle, so, 0, 0xc1); + write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing)); + + /* timing (partial) */ + write_reg(sohandle, so, 0, 0xc2); + write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing)); + + /* timing (idle) */ + write_reg(sohandle, so, 0, 0xc3); + write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing)); + + /* timing (source/VCOM/gate driving) */ + write_reg(sohandle, so, 0, 0xc4); + write_data(sohandle, so, data_timing_src, ARRAY_SIZE(data_timing_src)); + + /* gamma (red) */ + write_reg(sohandle, so, 0, 0xc8); + write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma)); + + /* gamma (green) */ + write_reg(sohandle, so, 0, 0xc9); + write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma)); + + /* gamma (blue) */ + write_reg(sohandle, so, 0, 0xca); + write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma)); + + /* power (common) */ + write_reg(sohandle, so, 0, 0xd0); + write_data(sohandle, so, data_power, ARRAY_SIZE(data_power)); + + /* VCOM */ + write_reg(sohandle, so, 0, 0xd1); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0x0f); + write_reg(sohandle, so, 1, 0x02); + + /* power (normal) */ + write_reg(sohandle, so, 0, 0xd2); + write_reg(sohandle, so, 1, 0x63); + write_reg(sohandle, so, 1, 0x24); + + /* power (partial) */ + write_reg(sohandle, so, 0, 0xd3); + write_reg(sohandle, so, 1, 0x63); + write_reg(sohandle, so, 1, 0x24); + + /* power (idle) */ + write_reg(sohandle, so, 0, 0xd4); + write_reg(sohandle, so, 1, 0x63); + write_reg(sohandle, so, 1, 0x24); + + write_reg(sohandle, so, 0, 0xd8); + write_reg(sohandle, so, 1, 0x77); + write_reg(sohandle, so, 1, 0x77); + + /* TE signal */ + write_reg(sohandle, so, 0, 0x35); + write_reg(sohandle, so, 1, 0x00); + + /* TE signal line */ + write_reg(sohandle, so, 0, 0x44); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0x00); + + /* column address */ + write_reg(sohandle, so, 0, 0x2a); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0xef); + + /* page address */ + write_reg(sohandle, so, 0, 0x2b); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0x00); + write_reg(sohandle, so, 1, 0x01); + write_reg(sohandle, so, 1, 0x8f); + + /* exit sleep mode */ + write_reg(sohandle, so, 0, 0x11); + + mdelay(120); + + /* clear vram */ + clear_memory(sohandle, so); + + /* display ON */ + write_reg(sohandle, so, 0, 0x29); + mdelay(1); + + write_memory_start(sohandle, so); +} + +int kfr2r09_lcd_setup(void *board_data, void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + /* power on */ + gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */ + gpio_set_value(GPIO_PTE4, 0); /* LCD_RST/ -> L */ + gpio_set_value(GPIO_PTF4, 1); /* PROTECT/ -> H */ + udelay(1100); + gpio_set_value(GPIO_PTE4, 1); /* LCD_RST/ -> H */ + udelay(10); + gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */ + mdelay(20); + + if (read_device_code(sohandle, so) != 0x01221517) + return -ENODEV; + + pr_info("KFR2R09 WQVGA LCD Module detected.\n"); + + display_on(sohandle, so); + return 0; +} + +void kfr2r09_lcd_start(void *board_data, void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + write_memory_start(sohandle, so); +} + +#define CTRL_CKSW 0x10 +#define CTRL_C10 0x20 +#define CTRL_CPSW 0x80 +#define MAIN_MLED4 0x40 +#define MAIN_MSW 0x80 + +static int kfr2r09_lcd_backlight(int on) +{ + struct i2c_adapter *a; + struct i2c_msg msg; + unsigned char buf[2]; + int ret; + + a = i2c_get_adapter(0); + if (!a) + return -ENODEV; + + buf[0] = 0x00; + if (on) + buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW; + else + buf[1] = 0; + + msg.addr = 0x75; + msg.buf = buf; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[0] = 0x01; + if (on) + buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c; + else + buf[1] = 0; + + msg.addr = 0x75; + msg.buf = buf; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + return 0; +} + +void kfr2r09_lcd_on(void *board_data, struct fb_info *info) +{ + kfr2r09_lcd_backlight(1); +} + +void kfr2r09_lcd_off(void *board_data) +{ + kfr2r09_lcd_backlight(0); +} diff --git a/arch/sh/boards/mach-kfr2r09/sdram.S b/arch/sh/boards/mach-kfr2r09/sdram.S new file mode 100644 index 00000000000..0c9f55bec2f --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/sdram.S @@ -0,0 +1,80 @@ +/* + * KFR2R09 sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(kfr2r09_sdram_enter_start) + + /* DBSC: put memory in self-refresh mode */ + + ED 0xFD000010, 0x00000000 /* DBEN */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + + rts + nop + +ENTRY(kfr2r09_sdram_enter_end) + + .balign 4 +ENTRY(kfr2r09_sdram_leave_start) + + /* DBSC: put memory in auto-refresh mode */ + + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_RSTANDBY, r0 + bf resume_rstandby + + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + WAIT 1 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +resume_rstandby: + + /* DBSC: re-initialize and put in auto-refresh */ + + ED 0xFD000108, 0x40000301 /* DBPDCNT0 */ + ED 0xFD000020, 0x011B0002 /* DBCONF */ + ED 0xFD000030, 0x03060E02 /* DBTR0 */ + ED 0xFD000034, 0x01020102 /* DBTR1 */ + ED 0xFD000038, 0x01090406 /* DBTR2 */ + ED 0xFD000008, 0x00000004 /* DBKIND */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000018, 0x00000001 /* DBCKECNT */ + WAIT 1 + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000044, 0x000004AF /* DBRFPDN1 */ + ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000108, 0x40000300 /* DBPDCNT0 */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +ENTRY(kfr2r09_sdram_leave_end) diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c new file mode 100644 index 00000000000..5b382e1afae --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -0,0 +1,638 @@ +/* + * KFR2R09 board support code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/mfd/tmio.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/onenand.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <linux/input/sh_keysc.h> +#include <linux/i2c.h> +#include <linux/usb/r8a66597.h> +#include <linux/videodev2.h> +#include <media/rj54n1cb0c.h> +#include <media/soc_camera.h> +#include <media/sh_mobile_ceu.h> +#include <video/sh_mobile_lcdc.h> +#include <asm/suspend.h> +#include <asm/clock.h> +#include <asm/machvec.h> +#include <asm/io.h> +#include <cpu/sh7724.h> +#include <mach/kfr2r09.h> + +static struct mtd_partition kfr2r09_nor_flash_partitions[] = +{ + { + .name = "boot", + .offset = 0, + .size = (4 * 1024 * 1024), + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, + { + .name = "other", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data kfr2r09_nor_flash_data = { + .width = 2, + .parts = kfr2r09_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(kfr2r09_nor_flash_partitions), +}; + +static struct resource kfr2r09_nor_flash_resources[] = { + [0] = { + .name = "NOR Flash", + .start = 0x00000000, + .end = 0x03ffffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device kfr2r09_nor_flash_device = { + .name = "physmap-flash", + .resource = kfr2r09_nor_flash_resources, + .num_resources = ARRAY_SIZE(kfr2r09_nor_flash_resources), + .dev = { + .platform_data = &kfr2r09_nor_flash_data, + }, +}; + +static struct resource kfr2r09_nand_flash_resources[] = { + [0] = { + .name = "NAND Flash", + .start = 0x10000000, + .end = 0x1001ffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device kfr2r09_nand_flash_device = { + .name = "onenand-flash", + .resource = kfr2r09_nand_flash_resources, + .num_resources = ARRAY_SIZE(kfr2r09_nand_flash_resources), +}; + +static struct sh_keysc_info kfr2r09_sh_keysc_info = { + .mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */ + .scan_timing = 3, + .delay = 10, + .keycodes = { + KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER, + KEY_1, KEY_2, KEY_3, 0, KEY_UP, + KEY_4, KEY_5, KEY_6, 0, KEY_LEFT, + KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT, + KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN, + 0, 0, 0, 0, 0 + }, +}; + +static struct resource kfr2r09_sh_keysc_resources[] = { + [0] = { + .name = "KEYSC", + .start = 0x044b0000, + .end = 0x044b000f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 79, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kfr2r09_sh_keysc_device = { + .name = "sh_keysc", + .id = 0, /* "keysc0" clock */ + .num_resources = ARRAY_SIZE(kfr2r09_sh_keysc_resources), + .resource = kfr2r09_sh_keysc_resources, + .dev = { + .platform_data = &kfr2r09_sh_keysc_info, + }, +}; + +static const struct fb_videomode kfr2r09_lcdc_modes[] = { + { + .name = "TX07D34VM0AAA", + .xres = 240, + .yres = 400, + .left_margin = 0, + .right_margin = 16, + .hsync_len = 8, + .upper_margin = 0, + .lower_margin = 1, + .vsync_len = 1, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + }, +}; + +static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { + .clock_source = LCDC_CLK_BUS, + .ch[0] = { + .chan = LCDC_CHAN_MAINLCD, + .fourcc = V4L2_PIX_FMT_RGB565, + .interface_type = SYS18, + .clock_divider = 6, + .flags = LCDC_FLAGS_DWPOL, + .lcd_cfg = kfr2r09_lcdc_modes, + .num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes), + .lcd_size_cfg = { + .width = 35, + .height = 58, + }, + .board_cfg = { + .setup_sys = kfr2r09_lcd_setup, + .start_transfer = kfr2r09_lcd_start, + .display_on = kfr2r09_lcd_on, + .display_off = kfr2r09_lcd_off, + }, + .sys_bus_cfg = { + .ldmt2r = 0x07010904, + .ldmt3r = 0x14012914, + /* set 1s delay to encourage fsync() */ + .deferred_io_msec = 1000, + }, + } +}; + +static struct resource kfr2r09_sh_lcdc_resources[] = { + [0] = { + .name = "LCDC", + .start = 0xfe940000, /* P4-only space */ + .end = 0xfe942fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 106, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kfr2r09_sh_lcdc_device = { + .name = "sh_mobile_lcdc_fb", + .num_resources = ARRAY_SIZE(kfr2r09_sh_lcdc_resources), + .resource = kfr2r09_sh_lcdc_resources, + .dev = { + .platform_data = &kfr2r09_sh_lcdc_info, + }, +}; + +static struct r8a66597_platdata kfr2r09_usb0_gadget_data = { + .on_chip = 1, +}; + +static struct resource kfr2r09_usb0_gadget_resources[] = { + [0] = { + .start = 0x04d80000, + .end = 0x04d80123, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 65, + .end = 65, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, +}; + +static struct platform_device kfr2r09_usb0_gadget_device = { + .name = "r8a66597_udc", + .id = 0, + .dev = { + .dma_mask = NULL, /* not use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &kfr2r09_usb0_gadget_data, + }, + .num_resources = ARRAY_SIZE(kfr2r09_usb0_gadget_resources), + .resource = kfr2r09_usb0_gadget_resources, +}; + +static struct sh_mobile_ceu_info sh_mobile_ceu_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, +}; + +static struct resource kfr2r09_ceu_resources[] = { + [0] = { + .name = "CEU", + .start = 0xfe910000, + .end = 0xfe91009f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 52, + .end = 52, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device kfr2r09_ceu_device = { + .name = "sh_mobile_ceu", + .id = 0, /* "ceu0" clock */ + .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources), + .resource = kfr2r09_ceu_resources, + .dev = { + .platform_data = &sh_mobile_ceu_info, + }, +}; + +static struct i2c_board_info kfr2r09_i2c_camera = { + I2C_BOARD_INFO("rj54n1cb0c", 0x50), +}; + +static struct clk *camera_clk; + +/* set VIO_CKO clock to 25MHz */ +#define CEU_MCLK_FREQ 25000000 + +#define DRVCRB 0xA405018C +static int camera_power(struct device *dev, int mode) +{ + int ret; + + if (mode) { + long rate; + + camera_clk = clk_get(NULL, "video_clk"); + if (IS_ERR(camera_clk)) + return PTR_ERR(camera_clk); + + rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ); + ret = clk_set_rate(camera_clk, rate); + if (ret < 0) + goto eclkrate; + + /* set DRVCRB + * + * use 1.8 V for VccQ_VIO + * use 2.85V for VccQ_SR + */ + __raw_writew((__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); + + /* reset clear */ + ret = gpio_request(GPIO_PTB4, NULL); + if (ret < 0) + goto eptb4; + ret = gpio_request(GPIO_PTB7, NULL); + if (ret < 0) + goto eptb7; + + ret = gpio_direction_output(GPIO_PTB4, 1); + if (!ret) + ret = gpio_direction_output(GPIO_PTB7, 1); + if (ret < 0) + goto egpioout; + msleep(1); + + ret = clk_enable(camera_clk); /* start VIO_CKO */ + if (ret < 0) + goto eclkon; + + return 0; + } + + ret = 0; + + clk_disable(camera_clk); +eclkon: + gpio_set_value(GPIO_PTB7, 0); +egpioout: + gpio_set_value(GPIO_PTB4, 0); + gpio_free(GPIO_PTB7); +eptb7: + gpio_free(GPIO_PTB4); +eptb4: +eclkrate: + clk_put(camera_clk); + return ret; +} + +static struct rj54n1_pdata rj54n1_priv = { + .mclk_freq = CEU_MCLK_FREQ, + .ioctl_high = false, +}; + +static struct soc_camera_link rj54n1_link = { + .power = camera_power, + .board_info = &kfr2r09_i2c_camera, + .i2c_adapter_id = 1, + .priv = &rj54n1_priv, +}; + +static struct platform_device kfr2r09_camera = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &rj54n1_link, + }, +}; + +static struct resource kfr2r09_sh_sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 100, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, + .tmio_caps = MMC_CAP_SDIO_IRQ, +}; + +static struct platform_device kfr2r09_sh_sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources), + .resource = kfr2r09_sh_sdhi0_resources, + .dev = { + .platform_data = &sh7724_sdhi0_data, + }, +}; + +static struct platform_device *kfr2r09_devices[] __initdata = { + &kfr2r09_nor_flash_device, + &kfr2r09_nand_flash_device, + &kfr2r09_sh_keysc_device, + &kfr2r09_sh_lcdc_device, + &kfr2r09_ceu_device, + &kfr2r09_camera, + &kfr2r09_sh_sdhi0_device, +}; + +#define BSC_CS0BCR 0xfec10004 +#define BSC_CS0WCR 0xfec10024 +#define BSC_CS4BCR 0xfec10010 +#define BSC_CS4WCR 0xfec10030 +#define PORT_MSELCRB 0xa4050182 + +#ifdef CONFIG_I2C +static int kfr2r09_usb0_gadget_i2c_setup(void) +{ + struct i2c_adapter *a; + struct i2c_msg msg; + unsigned char buf[2]; + int ret; + + a = i2c_get_adapter(0); + if (!a) + return -ENODEV; + + /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */ + buf[0] = 0x13; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 1; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[0] = 0; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 1; + msg.flags = I2C_M_RD; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[1] = buf[0] | (1 << 1); + buf[0] = 0x13; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + return 0; +} + +static int kfr2r09_serial_i2c_setup(void) +{ + struct i2c_adapter *a; + struct i2c_msg msg; + unsigned char buf[2]; + int ret; + + a = i2c_get_adapter(0); + if (!a) + return -ENODEV; + + /* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */ + buf[0] = 0x13; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 1; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[0] = 0; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 1; + msg.flags = I2C_M_RD; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[1] = buf[0] | (1 << 6); + buf[0] = 0x13; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + return 0; +} +#else +static int kfr2r09_usb0_gadget_i2c_setup(void) +{ + return -ENODEV; +} + +static int kfr2r09_serial_i2c_setup(void) +{ + return -ENODEV; +} +#endif + +static int kfr2r09_usb0_gadget_setup(void) +{ + int plugged_in; + + gpio_request(GPIO_PTN4, NULL); /* USB_DET */ + gpio_direction_input(GPIO_PTN4); + plugged_in = gpio_get_value(GPIO_PTN4); + if (!plugged_in) + return -ENODEV; /* no cable plugged in */ + + if (kfr2r09_usb0_gadget_i2c_setup() != 0) + return -ENODEV; /* unable to configure using i2c */ + + __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); + gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */ + gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */ + gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */ + msleep(20); /* wait 20ms to let the clock settle */ + clk_enable(clk_get(NULL, "usb0")); + __raw_writew(0x0600, 0xa40501d4); + + return 0; +} + +extern char kfr2r09_sdram_enter_start; +extern char kfr2r09_sdram_enter_end; +extern char kfr2r09_sdram_leave_start; +extern char kfr2r09_sdram_leave_end; + +static int __init kfr2r09_devices_setup(void) +{ + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | + SUSP_SH_RSTANDBY, + &kfr2r09_sdram_enter_start, + &kfr2r09_sdram_enter_end, + &kfr2r09_sdram_leave_start, + &kfr2r09_sdram_leave_end); + + /* enable SCIF1 serial port for YC401 console support */ + gpio_request(GPIO_FN_SCIF1_RXD, NULL); + gpio_request(GPIO_FN_SCIF1_TXD, NULL); + kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */ + gpio_request(GPIO_PTG3, NULL); /* HPON_ON */ + gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */ + + /* setup NOR flash at CS0 */ + __raw_writel(0x36db0400, BSC_CS0BCR); + __raw_writel(0x00000500, BSC_CS0WCR); + + /* setup NAND flash at CS4 */ + __raw_writel(0x36db0400, BSC_CS4BCR); + __raw_writel(0x00000500, BSC_CS4WCR); + + /* setup KEYSC pins */ + gpio_request(GPIO_FN_KEYOUT0, NULL); + gpio_request(GPIO_FN_KEYOUT1, NULL); + gpio_request(GPIO_FN_KEYOUT2, NULL); + gpio_request(GPIO_FN_KEYOUT3, NULL); + gpio_request(GPIO_FN_KEYOUT4_IN6, NULL); + gpio_request(GPIO_FN_KEYIN0, NULL); + gpio_request(GPIO_FN_KEYIN1, NULL); + gpio_request(GPIO_FN_KEYIN2, NULL); + gpio_request(GPIO_FN_KEYIN3, NULL); + gpio_request(GPIO_FN_KEYIN4, NULL); + gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); + + /* setup LCDC pins for SYS panel */ + gpio_request(GPIO_FN_LCDD17, NULL); + gpio_request(GPIO_FN_LCDD16, NULL); + gpio_request(GPIO_FN_LCDD15, NULL); + gpio_request(GPIO_FN_LCDD14, NULL); + gpio_request(GPIO_FN_LCDD13, NULL); + gpio_request(GPIO_FN_LCDD12, NULL); + gpio_request(GPIO_FN_LCDD11, NULL); + gpio_request(GPIO_FN_LCDD10, NULL); + gpio_request(GPIO_FN_LCDD9, NULL); + gpio_request(GPIO_FN_LCDD8, NULL); + gpio_request(GPIO_FN_LCDD7, NULL); + gpio_request(GPIO_FN_LCDD6, NULL); + gpio_request(GPIO_FN_LCDD5, NULL); + gpio_request(GPIO_FN_LCDD4, NULL); + gpio_request(GPIO_FN_LCDD3, NULL); + gpio_request(GPIO_FN_LCDD2, NULL); + gpio_request(GPIO_FN_LCDD1, NULL); + gpio_request(GPIO_FN_LCDD0, NULL); + gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */ + gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */ + gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */ + gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */ + gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */ + gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */ + gpio_direction_output(GPIO_PTE4, 1); + gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */ + gpio_direction_output(GPIO_PTF4, 1); + gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */ + gpio_direction_output(GPIO_PTU0, 1); + + /* setup USB function */ + if (kfr2r09_usb0_gadget_setup() == 0) + platform_device_register(&kfr2r09_usb0_gadget_device); + + /* CEU */ + gpio_request(GPIO_FN_VIO_CKO, NULL); + gpio_request(GPIO_FN_VIO0_CLK, NULL); + gpio_request(GPIO_FN_VIO0_VD, NULL); + gpio_request(GPIO_FN_VIO0_HD, NULL); + gpio_request(GPIO_FN_VIO0_FLD, NULL); + gpio_request(GPIO_FN_VIO0_D7, NULL); + gpio_request(GPIO_FN_VIO0_D6, NULL); + gpio_request(GPIO_FN_VIO0_D5, NULL); + gpio_request(GPIO_FN_VIO0_D4, NULL); + gpio_request(GPIO_FN_VIO0_D3, NULL); + gpio_request(GPIO_FN_VIO0_D2, NULL); + gpio_request(GPIO_FN_VIO0_D1, NULL); + gpio_request(GPIO_FN_VIO0_D0, NULL); + + platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20); + + /* SDHI0 connected to yc304 */ + gpio_request(GPIO_FN_SDHI0CD, NULL); + gpio_request(GPIO_FN_SDHI0D3, NULL); + gpio_request(GPIO_FN_SDHI0D2, NULL); + gpio_request(GPIO_FN_SDHI0D1, NULL); + gpio_request(GPIO_FN_SDHI0D0, NULL); + gpio_request(GPIO_FN_SDHI0CMD, NULL); + gpio_request(GPIO_FN_SDHI0CLK, NULL); + + return platform_add_devices(kfr2r09_devices, + ARRAY_SIZE(kfr2r09_devices)); +} +device_initcall(kfr2r09_devices_setup); + +/* Return the board specific boot mode pin configuration */ +static int kfr2r09_mode_pins(void) +{ + /* MD0=1, MD1=1, MD2=0: Clock Mode 3 + * MD3=0: 16-bit Area0 Bus Width + * MD5=1: Little Endian + * MD8=1: Test Mode Disabled + */ + return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8; +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_kfr2r09 __initmv = { + .mv_name = "kfr2r09", + .mv_mode_pins = kfr2r09_mode_pins, +}; diff --git a/arch/sh/boards/mach-landisk/Makefile b/arch/sh/boards/mach-landisk/Makefile new file mode 100644 index 00000000000..a696b4277fa --- /dev/null +++ b/arch/sh/boards/mach-landisk/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for I-O DATA DEVICE, INC. "LANDISK Series" +# + +obj-y := setup.o irq.o psw.o gio.o diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c new file mode 100644 index 00000000000..8132dff078f --- /dev/null +++ b/arch/sh/boards/mach-landisk/gio.c @@ -0,0 +1,170 @@ +/* + * arch/sh/boards/landisk/gio.c - driver for landisk + * + * This driver will also support the I-O DATA Device, Inc. LANDISK Board. + * LANDISK and USL-5P Button, LED and GIO driver drive function. + * + * Copylight (C) 2006 kogiidena + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kdev_t.h> +#include <linux/cdev.h> +#include <linux/fs.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <mach-landisk/mach/gio.h> +#include <mach-landisk/mach/iodata_landisk.h> + +#define DEVCOUNT 4 +#define GIO_MINOR 2 /* GIO minor no. */ + +static dev_t dev; +static struct cdev *cdev_p; +static int openCnt; + +static int gio_open(struct inode *inode, struct file *filp) +{ + int minor; + int ret = -ENOENT; + + preempt_disable(); + minor = MINOR(inode->i_rdev); + if (minor < DEVCOUNT) { + if (openCnt > 0) { + ret = -EALREADY; + } else { + openCnt++; + ret = 0; + } + } + preempt_enable(); + return ret; +} + +static int gio_close(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor < DEVCOUNT) { + openCnt--; + } + return 0; +} + +static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + unsigned int data; + static unsigned int addr = 0; + + if (cmd & 0x01) { /* write */ + if (copy_from_user(&data, (int *)arg, sizeof(int))) { + return -EFAULT; + } + } + + switch (cmd) { + case GIODRV_IOCSGIOSETADDR: /* address set */ + addr = data; + break; + + case GIODRV_IOCSGIODATA1: /* write byte */ + __raw_writeb((unsigned char)(0x0ff & data), addr); + break; + + case GIODRV_IOCSGIODATA2: /* write word */ + if (addr & 0x01) { + return -EFAULT; + } + __raw_writew((unsigned short int)(0x0ffff & data), addr); + break; + + case GIODRV_IOCSGIODATA4: /* write long */ + if (addr & 0x03) { + return -EFAULT; + } + __raw_writel(data, addr); + break; + + case GIODRV_IOCGGIODATA1: /* read byte */ + data = __raw_readb(addr); + break; + + case GIODRV_IOCGGIODATA2: /* read word */ + if (addr & 0x01) { + return -EFAULT; + } + data = __raw_readw(addr); + break; + + case GIODRV_IOCGGIODATA4: /* read long */ + if (addr & 0x03) { + return -EFAULT; + } + data = __raw_readl(addr); + break; + default: + return -EFAULT; + break; + } + + if ((cmd & 0x01) == 0) { /* read */ + if (copy_to_user((int *)arg, &data, sizeof(int))) { + return -EFAULT; + } + } + return 0; +} + +static const struct file_operations gio_fops = { + .owner = THIS_MODULE, + .open = gio_open, /* open */ + .release = gio_close, /* release */ + .unlocked_ioctl = gio_ioctl, + .llseek = noop_llseek, +}; + +static int __init gio_init(void) +{ + int error; + + printk(KERN_INFO "gio: driver initialized\n"); + + openCnt = 0; + + if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) { + printk(KERN_ERR + "gio: Couldn't alloc_chrdev_region, error=%d\n", + error); + return 1; + } + + cdev_p = cdev_alloc(); + cdev_p->ops = &gio_fops; + error = cdev_add(cdev_p, dev, DEVCOUNT); + if (error) { + printk(KERN_ERR + "gio: Couldn't cdev_add, error=%d\n", error); + return 1; + } + + return 0; +} + +static void __exit gio_exit(void) +{ + cdev_del(cdev_p); + unregister_chrdev_region(dev, DEVCOUNT); +} + +module_init(gio_init); +module_exit(gio_exit); + +MODULE_LICENSE("GPL"); diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c new file mode 100644 index 00000000000..c00ace38db3 --- /dev/null +++ b/arch/sh/boards/mach-landisk/irq.c @@ -0,0 +1,66 @@ +/* + * arch/sh/boards/mach-landisk/irq.c + * + * I-O DATA Device, Inc. LANDISK Support + * + * Copyright (C) 2005-2007 kogiidena + * Copyright (C) 2011 Nobuhiro Iwamatsu + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <mach-landisk/mach/iodata_landisk.h> + +enum { + UNUSED = 0, + + PCI_INTA, /* PCI int A */ + PCI_INTB, /* PCI int B */ + PCI_INTC, /* PCI int C */ + PCI_INTD, /* PCI int D */ + ATA, /* ATA */ + FATA, /* CF */ + POWER, /* Power swtich */ + BUTTON, /* Button swtich */ +}; + +/* Vectors for LANDISK */ +static struct intc_vect vectors_landisk[] __initdata = { + INTC_IRQ(PCI_INTA, IRQ_PCIINTA), + INTC_IRQ(PCI_INTB, IRQ_PCIINTB), + INTC_IRQ(PCI_INTC, IRQ_PCIINTC), + INTC_IRQ(PCI_INTD, IRQ_PCIINTD), + INTC_IRQ(ATA, IRQ_ATA), + INTC_IRQ(FATA, IRQ_FATA), + INTC_IRQ(POWER, IRQ_POWER), + INTC_IRQ(BUTTON, IRQ_BUTTON), +}; + +/* IRLMSK mask register layout for LANDISK */ +static struct intc_mask_reg mask_registers_landisk[] __initdata = { + { PA_IMASK, 0, 8, /* IRLMSK */ + { BUTTON, POWER, FATA, ATA, + PCI_INTD, PCI_INTC, PCI_INTB, PCI_INTA, + } + }, +}; + +static DECLARE_INTC_DESC(intc_desc_landisk, "landisk", vectors_landisk, NULL, + mask_registers_landisk, NULL, NULL); +/* + * Initialize IRQ setting + */ +void __init init_landisk_IRQ(void) +{ + register_intc_controller(&intc_desc_landisk); + __raw_writeb(0x00, PA_PWRINT_CLR); +} diff --git a/arch/sh/boards/mach-landisk/psw.c b/arch/sh/boards/mach-landisk/psw.c new file mode 100644 index 00000000000..bef83522f95 --- /dev/null +++ b/arch/sh/boards/mach-landisk/psw.c @@ -0,0 +1,143 @@ +/* + * arch/sh/boards/landisk/psw.c + * + * push switch support for LANDISK and USL-5P + * + * Copyright (C) 2006-2007 Paul Mundt + * Copyright (C) 2007 kogiidena + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/io.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <mach-landisk/mach/iodata_landisk.h> +#include <asm/push-switch.h> + +static irqreturn_t psw_irq_handler(int irq, void *arg) +{ + struct platform_device *pdev = arg; + struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch_platform_info *psw_info = pdev->dev.platform_data; + unsigned int sw_value; + int ret = 0; + + sw_value = (0x0ff & (~__raw_readb(PA_STATUS))); + + /* Nothing to do if there's no state change */ + if (psw->state) { + ret = 1; + goto out; + } + + /* Figure out who raised it */ + if (sw_value & (1 << psw_info->bit)) { + psw->state = 1; + mod_timer(&psw->debounce, jiffies + 50); + ret = 1; + } + +out: + /* Clear the switch IRQs */ + __raw_writeb(0x00, PA_PWRINT_CLR); + + return IRQ_RETVAL(ret); +} + +static struct resource psw_power_resources[] = { + [0] = { + .start = IRQ_POWER, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource psw_usl5p_resources[] = { + [0] = { + .start = IRQ_BUTTON, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct push_switch_platform_info psw_power_platform_data = { + .name = "psw_power", + .bit = 4, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw1_platform_data = { + .name = "psw1", + .bit = 0, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw2_platform_data = { + .name = "psw2", + .bit = 2, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw3_platform_data = { + .name = "psw3", + .bit = 1, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device psw_power_switch_device = { + .name = "push-switch", + .id = 0, + .num_resources = ARRAY_SIZE(psw_power_resources), + .resource = psw_power_resources, + .dev = { + .platform_data = &psw_power_platform_data, + }, +}; + +static struct platform_device psw1_switch_device = { + .name = "push-switch", + .id = 1, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw1_platform_data, + }, +}; + +static struct platform_device psw2_switch_device = { + .name = "push-switch", + .id = 2, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw2_platform_data, + }, +}; + +static struct platform_device psw3_switch_device = { + .name = "push-switch", + .id = 3, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw3_platform_data, + }, +}; + +static struct platform_device *psw_devices[] = { + &psw_power_switch_device, + &psw1_switch_device, + &psw2_switch_device, + &psw3_switch_device, +}; + +static int __init psw_init(void) +{ + return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); +} +module_init(psw_init); diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c new file mode 100644 index 00000000000..f1147caebac --- /dev/null +++ b/arch/sh/boards/mach-landisk/setup.c @@ -0,0 +1,102 @@ +/* + * arch/sh/boards/landisk/setup.c + * + * I-O DATA Device, Inc. LANDISK Support. + * + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2002 Paul Mundt + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2005-2007 kogiidena + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/pm.h> +#include <linux/mm.h> +#include <asm/machvec.h> +#include <mach-landisk/mach/iodata_landisk.h> +#include <asm/io.h> + +static void landisk_power_off(void) +{ + __raw_writeb(0x01, PA_SHUTDOWN); +} + +static struct resource cf_ide_resources[3]; + +static struct pata_platform_info pata_info = { + .ioport_shift = 1, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, + .dev = { + .platform_data = &pata_info, + }, +}; + +static struct platform_device rtc_device = { + .name = "rs5c313", + .id = -1, +}; + +static struct platform_device *landisk_devices[] __initdata = { + &cf_ide_device, + &rtc_device, +}; + +static int __init landisk_devices_setup(void) +{ + pgprot_t prot; + unsigned long paddrbase; + void *cf_ide_base; + + /* open I/O area window */ + paddrbase = virt_to_phys((void *)PA_AREA5_IO); + prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); + cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot)); + if (!cf_ide_base) { + printk("allocate_cf_area : can't open CF I/O window!\n"); + return -ENOMEM; + } + + /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */ + cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40; + cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f; + cf_ide_resources[0].flags = IORESOURCE_IO; + cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c; + cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03; + cf_ide_resources[1].flags = IORESOURCE_IO; + cf_ide_resources[2].start = IRQ_FATA; + cf_ide_resources[2].flags = IORESOURCE_IRQ; + + return platform_add_devices(landisk_devices, + ARRAY_SIZE(landisk_devices)); +} + +device_initcall(landisk_devices_setup); + +static void __init landisk_setup(char **cmdline_p) +{ + /* LED ON */ + __raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED); + + printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); + pm_power_off = landisk_power_off; +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_landisk __initmv = { + .mv_name = "LANDISK", + .mv_setup = landisk_setup, + .mv_init_irq = init_landisk_IRQ, +}; diff --git a/arch/sh/boards/mach-lboxre2/Makefile b/arch/sh/boards/mach-lboxre2/Makefile new file mode 100644 index 00000000000..e9ed140c06f --- /dev/null +++ b/arch/sh/boards/mach-lboxre2/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the L-BOX RE2 specific parts of the kernel +# Copyright (c) 2007 Nobuhiro Iwamatsu + +obj-y := setup.o irq.o diff --git a/arch/sh/boards/mach-lboxre2/irq.c b/arch/sh/boards/mach-lboxre2/irq.c new file mode 100644 index 00000000000..8aa171ab833 --- /dev/null +++ b/arch/sh/boards/mach-lboxre2/irq.c @@ -0,0 +1,31 @@ +/* + * linux/arch/sh/boards/lboxre2/irq.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * NTT COMWARE L-BOX RE2 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <mach/lboxre2.h> + +/* + * Initialize IRQ setting + */ +void __init init_lboxre2_IRQ(void) +{ + make_imask_irq(IRQ_CF1); + make_imask_irq(IRQ_CF0); + make_imask_irq(IRQ_INTD); + make_imask_irq(IRQ_ETH1); + make_imask_irq(IRQ_ETH0); + make_imask_irq(IRQ_INTA); +} diff --git a/arch/sh/boards/mach-lboxre2/setup.c b/arch/sh/boards/mach-lboxre2/setup.c new file mode 100644 index 00000000000..79b4e0d77b7 --- /dev/null +++ b/arch/sh/boards/mach-lboxre2/setup.c @@ -0,0 +1,84 @@ +/* + * linux/arch/sh/boards/lbox/setup.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * + * NTT COMWARE L-BOX RE2 Support + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <asm/machvec.h> +#include <asm/addrspace.h> +#include <mach/lboxre2.h> +#include <asm/io.h> + +static struct resource cf_ide_resources[] = { + [0] = { + .start = 0x1f0, + .end = 0x1f0 + 8 , + .flags = IORESOURCE_IO, + }, + [1] = { + .start = 0x1f0 + 0x206, + .end = 0x1f0 +8 + 0x206 + 8, + .flags = IORESOURCE_IO, + }, + [2] = { + .start = IRQ_CF0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + +static struct platform_device *lboxre2_devices[] __initdata = { + &cf_ide_device, +}; + +static int __init lboxre2_devices_setup(void) +{ + u32 cf0_io_base; /* Boot CF base address */ + pgprot_t prot; + unsigned long paddrbase, psize; + + /* open I/O area window */ + paddrbase = virt_to_phys((void*)PA_AREA5_IO); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); + cf0_io_base = (u32)ioremap_prot(paddrbase, psize, pgprot_val(prot)); + if (!cf0_io_base) { + printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ ); + return -ENOMEM; + } + + cf_ide_resources[0].start += cf0_io_base ; + cf_ide_resources[0].end += cf0_io_base ; + cf_ide_resources[1].start += cf0_io_base ; + cf_ide_resources[1].end += cf0_io_base ; + + return platform_add_devices(lboxre2_devices, + ARRAY_SIZE(lboxre2_devices)); + +} +device_initcall(lboxre2_devices_setup); + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_lboxre2 __initmv = { + .mv_name = "L-BOX RE2", + .mv_nr_irqs = 72, + .mv_init_irq = init_lboxre2_IRQ, +}; diff --git a/arch/sh/boards/mach-microdev/Makefile b/arch/sh/boards/mach-microdev/Makefile new file mode 100644 index 00000000000..4e3588e8806 --- /dev/null +++ b/arch/sh/boards/mach-microdev/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the SuperH MicroDev specific parts of the kernel +# + +obj-y := setup.o irq.o io.o fdc37c93xapm.o diff --git a/arch/sh/boards/mach-microdev/fdc37c93xapm.c b/arch/sh/boards/mach-microdev/fdc37c93xapm.c new file mode 100644 index 00000000000..458a7cf5fb4 --- /dev/null +++ b/arch/sh/boards/mach-microdev/fdc37c93xapm.c @@ -0,0 +1,160 @@ +/* + * + * Setup for the SMSC FDC37C93xAPM + * + * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) + * Copyright (C) 2003, 2004 SuperH, Inc. + * Copyright (C) 2004, 2005 Paul Mundt + * + * SuperH SH4-202 MicroDev board support. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/err.h> +#include <mach/microdev.h> + +#define SMSC_CONFIG_PORT_ADDR (0x3F0) +#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR +#define SMSC_DATA_PORT_ADDR (SMSC_INDEX_PORT_ADDR + 1) + +#define SMSC_ENTER_CONFIG_KEY 0x55 +#define SMSC_EXIT_CONFIG_KEY 0xaa + +#define SMCS_LOGICAL_DEV_INDEX 0x07 /* Logical Device Number */ +#define SMSC_DEVICE_ID_INDEX 0x20 /* Device ID */ +#define SMSC_DEVICE_REV_INDEX 0x21 /* Device Revision */ +#define SMSC_ACTIVATE_INDEX 0x30 /* Activate */ +#define SMSC_PRIMARY_BASE_INDEX 0x60 /* Primary Base Address */ +#define SMSC_SECONDARY_BASE_INDEX 0x62 /* Secondary Base Address */ +#define SMSC_PRIMARY_INT_INDEX 0x70 /* Primary Interrupt Select */ +#define SMSC_SECONDARY_INT_INDEX 0x72 /* Secondary Interrupt Select */ +#define SMSC_HDCS0_INDEX 0xf0 /* HDCS0 Address Decoder */ +#define SMSC_HDCS1_INDEX 0xf1 /* HDCS1 Address Decoder */ + +#define SMSC_IDE1_DEVICE 1 /* IDE #1 logical device */ +#define SMSC_IDE2_DEVICE 2 /* IDE #2 logical device */ +#define SMSC_PARALLEL_DEVICE 3 /* Parallel Port logical device */ +#define SMSC_SERIAL1_DEVICE 4 /* Serial #1 logical device */ +#define SMSC_SERIAL2_DEVICE 5 /* Serial #2 logical device */ +#define SMSC_KEYBOARD_DEVICE 7 /* Keyboard logical device */ +#define SMSC_CONFIG_REGISTERS 8 /* Configuration Registers (Aux I/O) */ + +#define SMSC_READ_INDEXED(index) ({ \ + outb((index), SMSC_INDEX_PORT_ADDR); \ + inb(SMSC_DATA_PORT_ADDR); }) +#define SMSC_WRITE_INDEXED(val, index) ({ \ + outb((index), SMSC_INDEX_PORT_ADDR); \ + outb((val), SMSC_DATA_PORT_ADDR); }) + +#define IDE1_PRIMARY_BASE 0x01f0 /* Task File Registe base for IDE #1 */ +#define IDE1_SECONDARY_BASE 0x03f6 /* Miscellaneous AT registers for IDE #1 */ +#define IDE2_PRIMARY_BASE 0x0170 /* Task File Registe base for IDE #2 */ +#define IDE2_SECONDARY_BASE 0x0376 /* Miscellaneous AT registers for IDE #2 */ + +#define SERIAL1_PRIMARY_BASE 0x03f8 +#define SERIAL2_PRIMARY_BASE 0x02f8 + +#define MSB(x) ( (x) >> 8 ) +#define LSB(x) ( (x) & 0xff ) + + /* General-Purpose base address on CPU-board FPGA */ +#define MICRODEV_FPGA_GP_BASE 0xa6100000ul + +static int __init smsc_superio_setup(void) +{ + + unsigned char devid, devrev; + + /* Initially the chip is in run state */ + /* Put it into configuration state */ + outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + + /* Read device ID info */ + devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX); + devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX); + + if ((devid == 0x30) && (devrev == 0x01)) + printk("SMSC FDC37C93xAPM SuperIO device detected\n"); + else + return -ENODEV; + + /* Select the keyboard device */ + SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX); + /* enable it */ + SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + /* enable the interrupts */ + SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX); + SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX); + + /* Select the Serial #1 device */ + SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX); + /* enable it */ + SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + /* program with port addresses */ + SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0); + SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1); + SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX); + /* enable the interrupts */ + SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX); + + /* Select the Serial #2 device */ + SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX); + /* enable it */ + SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + /* program with port addresses */ + SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0); + SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1); + SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX); + /* enable the interrupts */ + SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX); + + /* Select the IDE#1 device */ + SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX); + /* enable it */ + SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + /* program with port addresses */ + SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0); + SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1); + SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0); + SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1); + SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX); + SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX); + /* select the interrupt */ + SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX); + + /* Select the IDE#2 device */ + SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX); + /* enable it */ + SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX); + /* program with port addresses */ + SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0); + SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1); + SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0); + SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1); + /* select the interrupt */ + SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX); + + /* Select the configuration registers */ + SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX); + /* enable the appropriate GPIO pins for IDE functionality: + * bit[0] In/Out 1==input; 0==output + * bit[1] Polarity 1==invert; 0==no invert + * bit[2] Int Enb #1 1==Enable Combined IRQ #1; 0==disable + * bit[3:4] Function Select 00==original; 01==Alternate Function #1 + */ + SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */ + SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */ + SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */ + SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ + SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */ + + /* Exit the configuration state */ + outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); + + return 0; +} +device_initcall(smsc_superio_setup); diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c new file mode 100644 index 00000000000..acdafb0c640 --- /dev/null +++ b/arch/sh/boards/mach-microdev/io.c @@ -0,0 +1,125 @@ +/* + * linux/arch/sh/boards/superh/microdev/io.c + * + * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) + * Copyright (C) 2003, 2004 SuperH, Inc. + * Copyright (C) 2004 Paul Mundt + * + * SuperH SH4-202 MicroDev board support. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ + +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/wait.h> +#include <asm/io.h> +#include <mach/microdev.h> + + /* + * we need to have a 'safe' address to re-direct all I/O requests + * that we do not explicitly wish to handle. This safe address + * must have the following properies: + * + * * writes are ignored (no exception) + * * reads are benign (no side-effects) + * * accesses of width 1, 2 and 4-bytes are all valid. + * + * The Processor Version Register (PVR) has these properties. + */ +#define PVR 0xff000030 /* Processor Version Register */ + + +#define IO_IDE2_BASE 0x170ul /* I/O base for SMSC FDC37C93xAPM IDE #2 */ +#define IO_IDE1_BASE 0x1f0ul /* I/O base for SMSC FDC37C93xAPM IDE #1 */ +#define IO_ISP1161_BASE 0x290ul /* I/O port for Philips ISP1161x USB chip */ +#define IO_SERIAL2_BASE 0x2f8ul /* I/O base for SMSC FDC37C93xAPM Serial #2 */ +#define IO_LAN91C111_BASE 0x300ul /* I/O base for SMSC LAN91C111 Ethernet chip */ +#define IO_IDE2_MISC 0x376ul /* I/O misc for SMSC FDC37C93xAPM IDE #2 */ +#define IO_SUPERIO_BASE 0x3f0ul /* I/O base for SMSC FDC37C93xAPM SuperIO chip */ +#define IO_IDE1_MISC 0x3f6ul /* I/O misc for SMSC FDC37C93xAPM IDE #1 */ +#define IO_SERIAL1_BASE 0x3f8ul /* I/O base for SMSC FDC37C93xAPM Serial #1 */ + +#define IO_ISP1161_EXTENT 0x04ul /* I/O extent for Philips ISP1161x USB chip */ +#define IO_LAN91C111_EXTENT 0x10ul /* I/O extent for SMSC LAN91C111 Ethernet chip */ +#define IO_SUPERIO_EXTENT 0x02ul /* I/O extent for SMSC FDC37C93xAPM SuperIO chip */ +#define IO_IDE_EXTENT 0x08ul /* I/O extent for IDE Task Register set */ +#define IO_SERIAL_EXTENT 0x10ul + +#define IO_LAN91C111_PHYS 0xa7500000ul /* Physical address of SMSC LAN91C111 Ethernet chip */ +#define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */ +#define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */ + +/* + * map I/O ports to memory-mapped addresses + */ +void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) +{ + unsigned long result; + + if ((offset >= IO_LAN91C111_BASE) && + (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { + /* + * SMSC LAN91C111 Ethernet chip + */ + result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE; + } else if ((offset >= IO_SUPERIO_BASE) && + (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * Configuration Registers + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if (((offset >= IO_IDE1_BASE) && + (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || + (offset == IO_IDE1_MISC)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * IDE #1 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if (((offset >= IO_IDE2_BASE) && + (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) || + (offset == IO_IDE2_MISC)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * IDE #2 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if ((offset >= IO_SERIAL1_BASE) && + (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * Serial #1 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if ((offset >= IO_SERIAL2_BASE) && + (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * Serial #2 + */ + result = IO_SUPERIO_PHYS + (offset << 1); + } else if ((offset >= IO_ISP1161_BASE) && + (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) { + /* + * Philips USB ISP1161x chip + */ + result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE; + } else { + /* + * safe default. + */ + printk("Warning: unexpected port in %s( offset = 0x%lx )\n", + __func__, offset); + result = PVR; + } + + return (void __iomem *)result; +} diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c new file mode 100644 index 00000000000..4fb00369f0e --- /dev/null +++ b/arch/sh/boards/mach-microdev/irq.c @@ -0,0 +1,153 @@ +/* + * arch/sh/boards/superh/microdev/irq.c + * + * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) + * + * SuperH SH4-202 MicroDev board support. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <asm/system.h> +#include <asm/io.h> +#include <mach/microdev.h> + +#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ + +static const struct { + unsigned char fpgaIrq; + unsigned char mapped; + const char *name; +} fpgaIrqTable[NUM_EXTERNAL_IRQS] = { + { 0, 0, "unused" }, /* IRQ #0 IRL=15 0x200 */ + { MICRODEV_FPGA_IRQ_KEYBOARD, 1, "keyboard" }, /* IRQ #1 IRL=14 0x220 */ + { MICRODEV_FPGA_IRQ_SERIAL1, 1, "Serial #1"}, /* IRQ #2 IRL=13 0x240 */ + { MICRODEV_FPGA_IRQ_ETHERNET, 1, "Ethernet" }, /* IRQ #3 IRL=12 0x260 */ + { MICRODEV_FPGA_IRQ_SERIAL2, 0, "Serial #2"}, /* IRQ #4 IRL=11 0x280 */ + { 0, 0, "unused" }, /* IRQ #5 IRL=10 0x2a0 */ + { 0, 0, "unused" }, /* IRQ #6 IRL=9 0x2c0 */ + { MICRODEV_FPGA_IRQ_USB_HC, 1, "USB" }, /* IRQ #7 IRL=8 0x2e0 */ + { MICRODEV_IRQ_PCI_INTA, 1, "PCI INTA" }, /* IRQ #8 IRL=7 0x300 */ + { MICRODEV_IRQ_PCI_INTB, 1, "PCI INTB" }, /* IRQ #9 IRL=6 0x320 */ + { MICRODEV_IRQ_PCI_INTC, 1, "PCI INTC" }, /* IRQ #10 IRL=5 0x340 */ + { MICRODEV_IRQ_PCI_INTD, 1, "PCI INTD" }, /* IRQ #11 IRL=4 0x360 */ + { MICRODEV_FPGA_IRQ_MOUSE, 1, "mouse" }, /* IRQ #12 IRL=3 0x380 */ + { MICRODEV_FPGA_IRQ_IDE2, 1, "IDE #2" }, /* IRQ #13 IRL=2 0x3a0 */ + { MICRODEV_FPGA_IRQ_IDE1, 1, "IDE #1" }, /* IRQ #14 IRL=1 0x3c0 */ + { 0, 0, "unused" }, /* IRQ #15 IRL=0 0x3e0 */ +}; + +#if (MICRODEV_LINUX_IRQ_KEYBOARD != 1) +# error Inconsistancy in defining the IRQ# for Keyboard! +#endif + +#if (MICRODEV_LINUX_IRQ_ETHERNET != 3) +# error Inconsistancy in defining the IRQ# for Ethernet! +#endif + +#if (MICRODEV_LINUX_IRQ_USB_HC != 7) +# error Inconsistancy in defining the IRQ# for USB! +#endif + +#if (MICRODEV_LINUX_IRQ_MOUSE != 12) +# error Inconsistancy in defining the IRQ# for PS/2 Mouse! +#endif + +#if (MICRODEV_LINUX_IRQ_IDE2 != 13) +# error Inconsistancy in defining the IRQ# for secondary IDE! +#endif + +#if (MICRODEV_LINUX_IRQ_IDE1 != 14) +# error Inconsistancy in defining the IRQ# for primary IDE! +#endif + +static void disable_microdev_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + unsigned int fpgaIrq; + + if (irq >= NUM_EXTERNAL_IRQS) + return; + if (!fpgaIrqTable[irq].mapped) + return; + + fpgaIrq = fpgaIrqTable[irq].fpgaIrq; + + /* disable interrupts on the FPGA INTC register */ + __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); +} + +static void enable_microdev_irq(struct irq_data *data) +{ + unsigned int irq = data->irq; + unsigned long priorityReg, priorities, pri; + unsigned int fpgaIrq; + + if (unlikely(irq >= NUM_EXTERNAL_IRQS)) + return; + if (unlikely(!fpgaIrqTable[irq].mapped)) + return; + + pri = 15 - irq; + + fpgaIrq = fpgaIrqTable[irq].fpgaIrq; + priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); + + /* set priority for the interrupt */ + priorities = __raw_readl(priorityReg); + priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); + priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); + __raw_writel(priorities, priorityReg); + + /* enable interrupts on the FPGA INTC register */ + __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); +} + +static struct irq_chip microdev_irq_type = { + .name = "MicroDev-IRQ", + .irq_unmask = enable_microdev_irq, + .irq_mask = disable_microdev_irq, +}; + +/* This function sets the desired irq handler to be a MicroDev type */ +static void __init make_microdev_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_set_chip_and_handler(irq, µdev_irq_type, handle_level_irq); + disable_microdev_irq(irq_get_irq_data(irq)); +} + +extern void __init init_microdev_irq(void) +{ + int i; + + /* disable interrupts on the FPGA INTC register */ + __raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG); + + for (i = 0; i < NUM_EXTERNAL_IRQS; i++) + make_microdev_irq(i); +} + +extern void microdev_print_fpga_intc_status(void) +{ + volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG; + volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG; + volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0); + volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8); + volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16); + volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24); + volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG; + volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG; + + printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n"); + printk("FPGA_INTENB = 0x%08x\n", *intenb); + printk("FPGA_INTDSB = 0x%08x\n", *intdsb); + printk("FPGA_INTSRC = 0x%08x\n", *intsrc); + printk("FPGA_INTREQ = 0x%08x\n", *intreq); + printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria); + printk("-------------------------------------------------------------------------------\n"); +} diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c new file mode 100644 index 00000000000..d8a747291e0 --- /dev/null +++ b/arch/sh/boards/mach-microdev/setup.c @@ -0,0 +1,200 @@ +/* + * arch/sh/boards/superh/microdev/setup.c + * + * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) + * Copyright (C) 2003, 2004 SuperH, Inc. + * Copyright (C) 2004, 2005 Paul Mundt + * + * SuperH SH4-202 MicroDev board support. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ioport.h> +#include <video/s1d13xxxfb.h> +#include <mach/microdev.h> +#include <asm/io.h> +#include <asm/machvec.h> +#include <asm/sizes.h> + +static struct resource smc91x_resources[] = { + [0] = { + .start = 0x300, + .end = 0x300 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MICRODEV_LINUX_IRQ_ETHERNET, + .end = MICRODEV_LINUX_IRQ_ETHERNET, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct s1d13xxxfb_regval s1d13806_initregs[] = { + { S1DREG_MISC, 0x00 }, + { S1DREG_COM_DISP_MODE, 0x00 }, + { S1DREG_GPIO_CNF0, 0x00 }, + { S1DREG_GPIO_CNF1, 0x00 }, + { S1DREG_GPIO_CTL0, 0x00 }, + { S1DREG_GPIO_CTL1, 0x00 }, + { S1DREG_CLK_CNF, 0x02 }, + { S1DREG_LCD_CLK_CNF, 0x01 }, + { S1DREG_CRT_CLK_CNF, 0x03 }, + { S1DREG_MPLUG_CLK_CNF, 0x03 }, + { S1DREG_CPU2MEM_WST_SEL, 0x02 }, + { S1DREG_SDRAM_REF_RATE, 0x03 }, + { S1DREG_SDRAM_TC0, 0x00 }, + { S1DREG_SDRAM_TC1, 0x01 }, + { S1DREG_MEM_CNF, 0x80 }, + { S1DREG_PANEL_TYPE, 0x25 }, + { S1DREG_MOD_RATE, 0x00 }, + { S1DREG_LCD_DISP_HWIDTH, 0x63 }, + { S1DREG_LCD_NDISP_HPER, 0x1e }, + { S1DREG_TFT_FPLINE_START, 0x06 }, + { S1DREG_TFT_FPLINE_PWIDTH, 0x03 }, + { S1DREG_LCD_DISP_VHEIGHT0, 0x57 }, + { S1DREG_LCD_DISP_VHEIGHT1, 0x02 }, + { S1DREG_LCD_NDISP_VPER, 0x00 }, + { S1DREG_TFT_FPFRAME_START, 0x0a }, + { S1DREG_TFT_FPFRAME_PWIDTH, 0x81 }, + { S1DREG_LCD_DISP_MODE, 0x03 }, + { S1DREG_LCD_MISC, 0x00 }, + { S1DREG_LCD_DISP_START0, 0x00 }, + { S1DREG_LCD_DISP_START1, 0x00 }, + { S1DREG_LCD_DISP_START2, 0x00 }, + { S1DREG_LCD_MEM_OFF0, 0x90 }, + { S1DREG_LCD_MEM_OFF1, 0x01 }, + { S1DREG_LCD_PIX_PAN, 0x00 }, + { S1DREG_LCD_DISP_FIFO_HTC, 0x00 }, + { S1DREG_LCD_DISP_FIFO_LTC, 0x00 }, + { S1DREG_CRT_DISP_HWIDTH, 0x63 }, + { S1DREG_CRT_NDISP_HPER, 0x1f }, + { S1DREG_CRT_HRTC_START, 0x04 }, + { S1DREG_CRT_HRTC_PWIDTH, 0x8f }, + { S1DREG_CRT_DISP_VHEIGHT0, 0x57 }, + { S1DREG_CRT_DISP_VHEIGHT1, 0x02 }, + { S1DREG_CRT_NDISP_VPER, 0x1b }, + { S1DREG_CRT_VRTC_START, 0x00 }, + { S1DREG_CRT_VRTC_PWIDTH, 0x83 }, + { S1DREG_TV_OUT_CTL, 0x10 }, + { S1DREG_CRT_DISP_MODE, 0x05 }, + { S1DREG_CRT_DISP_START0, 0x00 }, + { S1DREG_CRT_DISP_START1, 0x00 }, + { S1DREG_CRT_DISP_START2, 0x00 }, + { S1DREG_CRT_MEM_OFF0, 0x20 }, + { S1DREG_CRT_MEM_OFF1, 0x03 }, + { S1DREG_CRT_PIX_PAN, 0x00 }, + { S1DREG_CRT_DISP_FIFO_HTC, 0x00 }, + { S1DREG_CRT_DISP_FIFO_LTC, 0x00 }, + { S1DREG_LCD_CUR_CTL, 0x00 }, + { S1DREG_LCD_CUR_START, 0x01 }, + { S1DREG_LCD_CUR_XPOS0, 0x00 }, + { S1DREG_LCD_CUR_XPOS1, 0x00 }, + { S1DREG_LCD_CUR_YPOS0, 0x00 }, + { S1DREG_LCD_CUR_YPOS1, 0x00 }, + { S1DREG_LCD_CUR_BCTL0, 0x00 }, + { S1DREG_LCD_CUR_GCTL0, 0x00 }, + { S1DREG_LCD_CUR_RCTL0, 0x00 }, + { S1DREG_LCD_CUR_BCTL1, 0x1f }, + { S1DREG_LCD_CUR_GCTL1, 0x3f }, + { S1DREG_LCD_CUR_RCTL1, 0x1f }, + { S1DREG_LCD_CUR_FIFO_HTC, 0x00 }, + { S1DREG_CRT_CUR_CTL, 0x00 }, + { S1DREG_CRT_CUR_START, 0x01 }, + { S1DREG_CRT_CUR_XPOS0, 0x00 }, + { S1DREG_CRT_CUR_XPOS1, 0x00 }, + { S1DREG_CRT_CUR_YPOS0, 0x00 }, + { S1DREG_CRT_CUR_YPOS1, 0x00 }, + { S1DREG_CRT_CUR_BCTL0, 0x00 }, + { S1DREG_CRT_CUR_GCTL0, 0x00 }, + { S1DREG_CRT_CUR_RCTL0, 0x00 }, + { S1DREG_CRT_CUR_BCTL1, 0x1f }, + { S1DREG_CRT_CUR_GCTL1, 0x3f }, + { S1DREG_CRT_CUR_RCTL1, 0x1f }, + { S1DREG_CRT_CUR_FIFO_HTC, 0x00 }, + { S1DREG_BBLT_CTL0, 0x00 }, + { S1DREG_BBLT_CTL1, 0x00 }, + { S1DREG_BBLT_CC_EXP, 0x00 }, + { S1DREG_BBLT_OP, 0x00 }, + { S1DREG_BBLT_SRC_START0, 0x00 }, + { S1DREG_BBLT_SRC_START1, 0x00 }, + { S1DREG_BBLT_SRC_START2, 0x00 }, + { S1DREG_BBLT_DST_START0, 0x00 }, + { S1DREG_BBLT_DST_START1, 0x00 }, + { S1DREG_BBLT_DST_START2, 0x00 }, + { S1DREG_BBLT_MEM_OFF0, 0x00 }, + { S1DREG_BBLT_MEM_OFF1, 0x00 }, + { S1DREG_BBLT_WIDTH0, 0x00 }, + { S1DREG_BBLT_WIDTH1, 0x00 }, + { S1DREG_BBLT_HEIGHT0, 0x00 }, + { S1DREG_BBLT_HEIGHT1, 0x00 }, + { S1DREG_BBLT_BGC0, 0x00 }, + { S1DREG_BBLT_BGC1, 0x00 }, + { S1DREG_BBLT_FGC0, 0x00 }, + { S1DREG_BBLT_FGC1, 0x00 }, + { S1DREG_LKUP_MODE, 0x00 }, + { S1DREG_LKUP_ADDR, 0x00 }, + { S1DREG_PS_CNF, 0x10 }, + { S1DREG_PS_STATUS, 0x00 }, + { S1DREG_CPU2MEM_WDOGT, 0x00 }, + { S1DREG_COM_DISP_MODE, 0x02 }, +}; + +static struct s1d13xxxfb_pdata s1d13806_platform_data = { + .initregs = s1d13806_initregs, + .initregssize = ARRAY_SIZE(s1d13806_initregs), +}; + +static struct resource s1d13806_resources[] = { + [0] = { + .start = 0x07200000, + .end = 0x07200000 + SZ_2M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x07000000, + .end = 0x07000000 + SZ_2M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device s1d13806_device = { + .name = "s1d13806fb", + .id = -1, + .num_resources = ARRAY_SIZE(s1d13806_resources), + .resource = s1d13806_resources, + + .dev = { + .platform_data = &s1d13806_platform_data, + }, +}; + +static struct platform_device *microdev_devices[] __initdata = { + &smc91x_device, + &s1d13806_device, +}; + +static int __init microdev_devices_setup(void) +{ + return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); +} +device_initcall(microdev_devices_setup); + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_sh4202_microdev __initmv = { + .mv_name = "SH4-202 MicroDev", + .mv_nr_irqs = 72, + .mv_ioport_map = microdev_ioport_map, + .mv_init_irq = init_microdev_irq, +}; diff --git a/arch/sh/boards/mach-migor/Kconfig b/arch/sh/boards/mach-migor/Kconfig new file mode 100644 index 00000000000..a7b3b728ec3 --- /dev/null +++ b/arch/sh/boards/mach-migor/Kconfig @@ -0,0 +1,15 @@ +if SH_MIGOR + +choice + prompt "Migo-R LCD Panel Board Selection" + default SH_MIGOR_QVGA + +config SH_MIGOR_QVGA + bool "QVGA (320x240)" + +config SH_MIGOR_RTA_WVGA + bool "RTA WVGA (800x480)" + +endchoice + +endif diff --git a/arch/sh/boards/mach-migor/Makefile b/arch/sh/boards/mach-migor/Makefile new file mode 100644 index 00000000000..4601a89e5ac --- /dev/null +++ b/arch/sh/boards/mach-migor/Makefile @@ -0,0 +1,2 @@ +obj-y := setup.o sdram.o +obj-$(CONFIG_SH_MIGOR_QVGA) += lcd_qvga.o diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c new file mode 100644 index 00000000000..de9014a8a93 --- /dev/null +++ b/arch/sh/boards/mach-migor/lcd_qvga.c @@ -0,0 +1,167 @@ +/* + * Support for SuperH MigoR Quarter VGA LCD Panel + * + * Copyright (C) 2008 Magnus Damm + * + * Based on lcd_powertip.c from Kenati Technologies Pvt Ltd. + * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/gpio.h> +#include <video/sh_mobile_lcdc.h> +#include <cpu/sh7722.h> +#include <mach/migor.h> + +/* LCD Module is a PH240320T according to board schematics. This module + * is made up of a 240x320 LCD hooked up to a R61505U (or HX8347-A01?) + * Driver IC. This IC is connected to the SH7722 built-in LCDC using a + * SYS-80 interface configured in 16 bit mode. + * + * Index 0: "Device Code Read" returns 0x1505. + */ + +static void reset_lcd_module(void) +{ + gpio_set_value(GPIO_PTH2, 0); + mdelay(2); + gpio_set_value(GPIO_PTH2, 1); + mdelay(1); +} + +/* DB0-DB7 are connected to D1-D8, and DB8-DB15 to D10-D17 */ + +static unsigned long adjust_reg18(unsigned short data) +{ + unsigned long tmp1, tmp2; + + tmp1 = (data<<1 | 0x00000001) & 0x000001FF; + tmp2 = (data<<2 | 0x00000200) & 0x0003FE00; + return tmp1 | tmp2; +} + +static void write_reg(void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops, + unsigned short reg, unsigned short data) +{ + sys_ops->write_index(sys_ops_handle, adjust_reg18(reg << 8 | data)); +} + +static void write_reg16(void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops, + unsigned short reg, unsigned short data) +{ + sys_ops->write_index(sys_ops_handle, adjust_reg18(reg)); + sys_ops->write_data(sys_ops_handle, adjust_reg18(data)); +} + +static unsigned long read_reg16(void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops, + unsigned short reg) +{ + unsigned long data; + + sys_ops->write_index(sys_ops_handle, adjust_reg18(reg)); + data = sys_ops->read_data(sys_ops_handle); + return ((data >> 1) & 0xff) | ((data >> 2) & 0xff00); +} + +static void migor_lcd_qvga_seq(void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops, + unsigned short const *data, int no_data) +{ + int i; + + for (i = 0; i < no_data; i += 2) + write_reg16(sys_ops_handle, sys_ops, data[i], data[i + 1]); +} + +static const unsigned short sync_data[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; + +static const unsigned short magic0_data[] = { + 0x0060, 0x2700, 0x0008, 0x0808, 0x0090, 0x001A, 0x0007, 0x0001, + 0x0017, 0x0001, 0x0019, 0x0000, 0x0010, 0x17B0, 0x0011, 0x0116, + 0x0012, 0x0198, 0x0013, 0x1400, 0x0029, 0x000C, 0x0012, 0x01B8, +}; + +static const unsigned short magic1_data[] = { + 0x0030, 0x0307, 0x0031, 0x0303, 0x0032, 0x0603, 0x0033, 0x0202, + 0x0034, 0x0202, 0x0035, 0x0202, 0x0036, 0x1F1F, 0x0037, 0x0303, + 0x0038, 0x0303, 0x0039, 0x0603, 0x003A, 0x0202, 0x003B, 0x0102, + 0x003C, 0x0204, 0x003D, 0x0000, 0x0001, 0x0100, 0x0002, 0x0300, + 0x0003, 0x5028, 0x0020, 0x00ef, 0x0021, 0x0000, 0x0004, 0x0000, + 0x0009, 0x0000, 0x000A, 0x0008, 0x000C, 0x0000, 0x000D, 0x0000, + 0x0015, 0x8000, +}; + +static const unsigned short magic2_data[] = { + 0x0061, 0x0001, 0x0092, 0x0100, 0x0093, 0x0001, 0x0007, 0x0021, +}; + +static const unsigned short magic3_data[] = { + 0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061, +}; + +int migor_lcd_qvga_setup(void *board_data, void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + unsigned long xres = 320; + unsigned long yres = 240; + int k; + + reset_lcd_module(); + migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data)); + + if (read_reg16(sohandle, so, 0) != 0x1505) + return -ENODEV; + + pr_info("Migo-R QVGA LCD Module detected.\n"); + + migor_lcd_qvga_seq(sohandle, so, sync_data, ARRAY_SIZE(sync_data)); + write_reg16(sohandle, so, 0x00A4, 0x0001); + mdelay(10); + + migor_lcd_qvga_seq(sohandle, so, magic0_data, ARRAY_SIZE(magic0_data)); + mdelay(100); + + migor_lcd_qvga_seq(sohandle, so, magic1_data, ARRAY_SIZE(magic1_data)); + write_reg16(sohandle, so, 0x0050, 0xef - (yres - 1)); + write_reg16(sohandle, so, 0x0051, 0x00ef); + write_reg16(sohandle, so, 0x0052, 0x0000); + write_reg16(sohandle, so, 0x0053, xres - 1); + + migor_lcd_qvga_seq(sohandle, so, magic2_data, ARRAY_SIZE(magic2_data)); + mdelay(10); + + migor_lcd_qvga_seq(sohandle, so, magic3_data, ARRAY_SIZE(magic3_data)); + mdelay(40); + + /* clear GRAM to avoid displaying garbage */ + + write_reg16(sohandle, so, 0x0020, 0x0000); /* horiz addr */ + write_reg16(sohandle, so, 0x0021, 0x0000); /* vert addr */ + + for (k = 0; k < (xres * 256); k++) /* yes, 256 words per line */ + write_reg16(sohandle, so, 0x0022, 0x0000); + + write_reg16(sohandle, so, 0x0020, 0x0000); /* reset horiz addr */ + write_reg16(sohandle, so, 0x0021, 0x0000); /* reset vert addr */ + write_reg16(sohandle, so, 0x0007, 0x0173); + mdelay(40); + + /* enable display */ + write_reg(sohandle, so, 0x00, 0x22); + mdelay(100); + return 0; +} diff --git a/arch/sh/boards/mach-migor/sdram.S b/arch/sh/boards/mach-migor/sdram.S new file mode 100644 index 00000000000..614aa3a1398 --- /dev/null +++ b/arch/sh/boards/mach-migor/sdram.S @@ -0,0 +1,69 @@ +/* + * Migo-R sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(migor_sdram_enter_start) + + /* SBSC: disable power down and put in self-refresh mode */ + mov.l 1f, r4 + mov.l 2f, r1 + mov.l @r4, r2 + or r1, r2 + mov.l 3f, r3 + and r3, r2 + mov.l r2, @r4 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +2: .long 0x00000400 +3: .long 0xffff7fff +ENTRY(migor_sdram_enter_end) + + .balign 4 +ENTRY(migor_sdram_leave_start) + + /* SBSC: set auto-refresh mode */ + mov.l 1f, r4 + mov.l @r4, r0 + mov.l 4f, r1 + and r1, r0 + mov.l r0, @r4 + mov.l 6f, r4 + mov.l 8f, r0 + mov.l @r4, r1 + mov #-1, r4 + add r4, r1 + or r1, r0 + mov.l 7f, r1 + mov.l r0, @r1 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +4: .long 0xfffffbff +6: .long 0xfe40001c /* RTCOR */ +7: .long 0xfe400018 /* RTCNT */ +8: .long 0xa55a0000 +ENTRY(migor_sdram_leave_end) diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c new file mode 100644 index 00000000000..d37ba272052 --- /dev/null +++ b/arch/sh/boards/mach-migor/setup.c @@ -0,0 +1,663 @@ +/* + * Renesas System Solutions Asia Pte. Ltd - Migo-R + * + * Copyright (C) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/input.h> +#include <linux/input/sh_keysc.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mobile_sdhi.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/nand.h> +#include <linux/i2c.h> +#include <linux/smc91x.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/videodev2.h> +#include <video/sh_mobile_lcdc.h> +#include <media/sh_mobile_ceu.h> +#include <media/ov772x.h> +#include <media/soc_camera.h> +#include <media/tw9910.h> +#include <asm/clock.h> +#include <asm/machvec.h> +#include <asm/io.h> +#include <asm/suspend.h> +#include <mach/migor.h> +#include <cpu/sh7722.h> + +/* Address IRQ Size Bus Description + * 0x00000000 64MB 16 NOR Flash (SP29PL256N) + * 0x0c000000 64MB 64 SDRAM (2xK4M563233G) + * 0x10000000 IRQ0 16 Ethernet (SMC91C111) + * 0x14000000 IRQ4 16 USB 2.0 Host Controller (M66596) + * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A) + */ + +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, +}; + +static struct resource smc91x_eth_resources[] = { + [0] = { + .name = "SMC91C111" , + .start = 0x10000300, + .end = 0x1000030f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 32, /* IRQ0 */ + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device smc91x_eth_device = { + .name = "smc91x", + .num_resources = ARRAY_SIZE(smc91x_eth_resources), + .resource = smc91x_eth_resources, + .dev = { + .platform_data = &smc91x_info, + }, +}; + +static struct sh_keysc_info sh_keysc_info = { + .mode = SH_KEYSC_MODE_2, /* KEYOUT0->4, KEYIN1->5 */ + .scan_timing = 3, + .delay = 5, + .keycodes = { + 0, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER, + 0, KEY_F, KEY_C, KEY_D, KEY_H, KEY_1, + 0, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, + 0, KEY_7, KEY_8, KEY_9, KEY_S, KEY_0, + 0, KEY_P, KEY_STOP, KEY_REWIND, KEY_PLAY, KEY_FASTFORWARD, + }, +}; + +static struct resource sh_keysc_resources[] = { + [0] = { + .start = 0x044b0000, + .end = 0x044b000f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 79, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sh_keysc_device = { + .name = "sh_keysc", + .id = 0, /* "keysc0" clock */ + .num_resources = ARRAY_SIZE(sh_keysc_resources), + .resource = sh_keysc_resources, + .dev = { + .platform_data = &sh_keysc_info, + }, +}; + +static struct mtd_partition migor_nor_flash_partitions[] = +{ + { + .name = "uboot", + .offset = 0, + .size = (1 * 1024 * 1024), + .mask_flags = MTD_WRITEABLE, /* Read-only */ + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = (15 * 1024 * 1024), + }, + { + .name = "other", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct physmap_flash_data migor_nor_flash_data = { + .width = 2, + .parts = migor_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(migor_nor_flash_partitions), +}; + +static struct resource migor_nor_flash_resources[] = { + [0] = { + .name = "NOR Flash", + .start = 0x00000000, + .end = 0x03ffffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device migor_nor_flash_device = { + .name = "physmap-flash", + .resource = migor_nor_flash_resources, + .num_resources = ARRAY_SIZE(migor_nor_flash_resources), + .dev = { + .platform_data = &migor_nor_flash_data, + }, +}; + +static struct mtd_partition migor_nand_flash_partitions[] = { + { + .name = "nanddata1", + .offset = 0x0, + .size = 512 * 1024 * 1024, + }, + { + .name = "nanddata2", + .offset = MTDPART_OFS_APPEND, + .size = 512 * 1024 * 1024, + }, +}; + +static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nand_chip *chip = mtd->priv; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, chip->IO_ADDR_W + 0x00400000); + else if (ctrl & NAND_ALE) + writeb(cmd, chip->IO_ADDR_W + 0x00800000); + else + writeb(cmd, chip->IO_ADDR_W); +} + +static int migor_nand_flash_ready(struct mtd_info *mtd) +{ + return gpio_get_value(GPIO_PTA1); /* NAND_RBn */ +} + +static struct platform_nand_data migor_nand_flash_data = { + .chip = { + .nr_chips = 1, + .partitions = migor_nand_flash_partitions, + .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions), + .chip_delay = 20, + .part_probe_types = (const char *[]) { "cmdlinepart", NULL }, + }, + .ctrl = { + .dev_ready = migor_nand_flash_ready, + .cmd_ctrl = migor_nand_flash_cmd_ctl, + }, +}; + +static struct resource migor_nand_flash_resources[] = { + [0] = { + .name = "NAND Flash", + .start = 0x18000000, + .end = 0x18ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device migor_nand_flash_device = { + .name = "gen_nand", + .resource = migor_nand_flash_resources, + .num_resources = ARRAY_SIZE(migor_nand_flash_resources), + .dev = { + .platform_data = &migor_nand_flash_data, + } +}; + +static const struct fb_videomode migor_lcd_modes[] = { + { +#if defined(CONFIG_SH_MIGOR_RTA_WVGA) + .name = "LB070WV1", + .xres = 800, + .yres = 480, + .left_margin = 64, + .right_margin = 16, + .hsync_len = 120, + .sync = 0, +#elif defined(CONFIG_SH_MIGOR_QVGA) + .name = "PH240320T", + .xres = 320, + .yres = 240, + .left_margin = 0, + .right_margin = 16, + .hsync_len = 8, + .sync = FB_SYNC_HOR_HIGH_ACT, +#endif + .upper_margin = 1, + .lower_margin = 17, + .vsync_len = 2, + }, +}; + +static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = { +#if defined(CONFIG_SH_MIGOR_RTA_WVGA) + .clock_source = LCDC_CLK_BUS, + .ch[0] = { + .chan = LCDC_CHAN_MAINLCD, + .fourcc = V4L2_PIX_FMT_RGB565, + .interface_type = RGB16, + .clock_divider = 2, + .lcd_cfg = migor_lcd_modes, + .num_cfg = ARRAY_SIZE(migor_lcd_modes), + .lcd_size_cfg = { /* 7.0 inch */ + .width = 152, + .height = 91, + }, + } +#elif defined(CONFIG_SH_MIGOR_QVGA) + .clock_source = LCDC_CLK_PERIPHERAL, + .ch[0] = { + .chan = LCDC_CHAN_MAINLCD, + .fourcc = V4L2_PIX_FMT_RGB565, + .interface_type = SYS16A, + .clock_divider = 10, + .lcd_cfg = migor_lcd_modes, + .num_cfg = ARRAY_SIZE(migor_lcd_modes), + .lcd_size_cfg = { /* 2.4 inch */ + .width = 49, + .height = 37, + }, + .board_cfg = { + .setup_sys = migor_lcd_qvga_setup, + }, + .sys_bus_cfg = { + .ldmt2r = 0x06000a09, + .ldmt3r = 0x180e3418, + /* set 1s delay to encourage fsync() */ + .deferred_io_msec = 1000, + }, + } +#endif +}; + +static struct resource migor_lcdc_resources[] = { + [0] = { + .name = "LCDC", + .start = 0xfe940000, /* P4-only space */ + .end = 0xfe942fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 28, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device migor_lcdc_device = { + .name = "sh_mobile_lcdc_fb", + .num_resources = ARRAY_SIZE(migor_lcdc_resources), + .resource = migor_lcdc_resources, + .dev = { + .platform_data = &sh_mobile_lcdc_info, + }, +}; + +static struct clk *camera_clk; +static DEFINE_MUTEX(camera_lock); + +static void camera_power_on(int is_tw) +{ + mutex_lock(&camera_lock); + + /* Use 10 MHz VIO_CKO instead of 24 MHz to work + * around signal quality issues on Panel Board V2.1. + */ + camera_clk = clk_get(NULL, "video_clk"); + clk_set_rate(camera_clk, 10000000); + clk_enable(camera_clk); /* start VIO_CKO */ + + /* use VIO_RST to take camera out of reset */ + mdelay(10); + if (is_tw) { + gpio_set_value(GPIO_PTT2, 0); + gpio_set_value(GPIO_PTT0, 0); + } else { + gpio_set_value(GPIO_PTT0, 1); + } + gpio_set_value(GPIO_PTT3, 0); + mdelay(10); + gpio_set_value(GPIO_PTT3, 1); + mdelay(10); /* wait to let chip come out of reset */ +} + +static void camera_power_off(void) +{ + clk_disable(camera_clk); /* stop VIO_CKO */ + clk_put(camera_clk); + + gpio_set_value(GPIO_PTT3, 0); + mutex_unlock(&camera_lock); +} + +static int ov7725_power(struct device *dev, int mode) +{ + if (mode) + camera_power_on(0); + else + camera_power_off(); + + return 0; +} + +static int tw9910_power(struct device *dev, int mode) +{ + if (mode) + camera_power_on(1); + else + camera_power_off(); + + return 0; +} + +static struct sh_mobile_ceu_info sh_mobile_ceu_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, +}; + +static struct resource migor_ceu_resources[] = { + [0] = { + .name = "CEU", + .start = 0xfe910000, + .end = 0xfe91009f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 52, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device migor_ceu_device = { + .name = "sh_mobile_ceu", + .id = 0, /* "ceu0" clock */ + .num_resources = ARRAY_SIZE(migor_ceu_resources), + .resource = migor_ceu_resources, + .dev = { + .platform_data = &sh_mobile_ceu_info, + }, +}; + +static struct resource sdhi_cn9_resources[] = { + [0] = { + .name = "SDHI", + .start = 0x04ce0000, + .end = 0x04ce00ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 100, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_mobile_sdhi_info sh7724_sdhi_data = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, + .tmio_caps = MMC_CAP_SDIO_IRQ, +}; + +static struct platform_device sdhi_cn9_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi_cn9_resources), + .resource = sdhi_cn9_resources, + .dev = { + .platform_data = &sh7724_sdhi_data, + }, +}; + +static struct i2c_board_info migor_i2c_devices[] = { + { + I2C_BOARD_INFO("rs5c372b", 0x32), + }, + { + I2C_BOARD_INFO("migor_ts", 0x51), + .irq = 38, /* IRQ6 */ + }, + { + I2C_BOARD_INFO("wm8978", 0x1a), + }, +}; + +static struct i2c_board_info migor_i2c_camera[] = { + { + I2C_BOARD_INFO("ov772x", 0x21), + }, + { + I2C_BOARD_INFO("tw9910", 0x45), + }, +}; + +static struct ov772x_camera_info ov7725_info; + +static struct soc_camera_link ov7725_link = { + .power = ov7725_power, + .board_info = &migor_i2c_camera[0], + .i2c_adapter_id = 0, + .priv = &ov7725_info, +}; + +static struct tw9910_video_info tw9910_info = { + .buswidth = SOCAM_DATAWIDTH_8, + .mpout = TW9910_MPO_FIELD, +}; + +static struct soc_camera_link tw9910_link = { + .power = tw9910_power, + .board_info = &migor_i2c_camera[1], + .i2c_adapter_id = 0, + .priv = &tw9910_info, +}; + +static struct platform_device migor_camera[] = { + { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &ov7725_link, + }, + }, { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &tw9910_link, + }, + }, +}; + +static struct platform_device *migor_devices[] __initdata = { + &smc91x_eth_device, + &sh_keysc_device, + &migor_lcdc_device, + &migor_ceu_device, + &migor_nor_flash_device, + &migor_nand_flash_device, + &sdhi_cn9_device, + &migor_camera[0], + &migor_camera[1], +}; + +extern char migor_sdram_enter_start; +extern char migor_sdram_enter_end; +extern char migor_sdram_leave_start; +extern char migor_sdram_leave_end; + +static int __init migor_devices_setup(void) +{ + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + &migor_sdram_enter_start, + &migor_sdram_enter_end, + &migor_sdram_leave_start, + &migor_sdram_leave_end); + /* Let D11 LED show STATUS0 */ + gpio_request(GPIO_FN_STATUS0, NULL); + + /* Lit D12 LED show PDSTATUS */ + gpio_request(GPIO_FN_PDSTATUS, NULL); + + /* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */ + gpio_request(GPIO_FN_IRQ0, NULL); + __raw_writel(0x00003400, BSC_CS4BCR); + __raw_writel(0x00110080, BSC_CS4WCR); + + /* KEYSC */ + gpio_request(GPIO_FN_KEYOUT0, NULL); + gpio_request(GPIO_FN_KEYOUT1, NULL); + gpio_request(GPIO_FN_KEYOUT2, NULL); + gpio_request(GPIO_FN_KEYOUT3, NULL); + gpio_request(GPIO_FN_KEYOUT4_IN6, NULL); + gpio_request(GPIO_FN_KEYIN1, NULL); + gpio_request(GPIO_FN_KEYIN2, NULL); + gpio_request(GPIO_FN_KEYIN3, NULL); + gpio_request(GPIO_FN_KEYIN4, NULL); + gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); + + /* NAND Flash */ + gpio_request(GPIO_FN_CS6A_CE2B, NULL); + __raw_writel((__raw_readl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR); + gpio_request(GPIO_PTA1, NULL); + gpio_direction_input(GPIO_PTA1); + + /* SDHI */ + gpio_request(GPIO_FN_SDHICD, NULL); + gpio_request(GPIO_FN_SDHIWP, NULL); + gpio_request(GPIO_FN_SDHID3, NULL); + gpio_request(GPIO_FN_SDHID2, NULL); + gpio_request(GPIO_FN_SDHID1, NULL); + gpio_request(GPIO_FN_SDHID0, NULL); + gpio_request(GPIO_FN_SDHICMD, NULL); + gpio_request(GPIO_FN_SDHICLK, NULL); + + /* Touch Panel */ + gpio_request(GPIO_FN_IRQ6, NULL); + + /* LCD Panel */ +#ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */ + gpio_request(GPIO_FN_LCDD17, NULL); + gpio_request(GPIO_FN_LCDD16, NULL); + gpio_request(GPIO_FN_LCDD15, NULL); + gpio_request(GPIO_FN_LCDD14, NULL); + gpio_request(GPIO_FN_LCDD13, NULL); + gpio_request(GPIO_FN_LCDD12, NULL); + gpio_request(GPIO_FN_LCDD11, NULL); + gpio_request(GPIO_FN_LCDD10, NULL); + gpio_request(GPIO_FN_LCDD8, NULL); + gpio_request(GPIO_FN_LCDD7, NULL); + gpio_request(GPIO_FN_LCDD6, NULL); + gpio_request(GPIO_FN_LCDD5, NULL); + gpio_request(GPIO_FN_LCDD4, NULL); + gpio_request(GPIO_FN_LCDD3, NULL); + gpio_request(GPIO_FN_LCDD2, NULL); + gpio_request(GPIO_FN_LCDD1, NULL); + gpio_request(GPIO_FN_LCDRS, NULL); + gpio_request(GPIO_FN_LCDCS, NULL); + gpio_request(GPIO_FN_LCDRD, NULL); + gpio_request(GPIO_FN_LCDWR, NULL); + gpio_request(GPIO_PTH2, NULL); /* LCD_DON */ + gpio_direction_output(GPIO_PTH2, 1); +#endif +#ifdef CONFIG_SH_MIGOR_RTA_WVGA /* LCDC - WVGA - Enable RGB Interface signals */ + gpio_request(GPIO_FN_LCDD15, NULL); + gpio_request(GPIO_FN_LCDD14, NULL); + gpio_request(GPIO_FN_LCDD13, NULL); + gpio_request(GPIO_FN_LCDD12, NULL); + gpio_request(GPIO_FN_LCDD11, NULL); + gpio_request(GPIO_FN_LCDD10, NULL); + gpio_request(GPIO_FN_LCDD9, NULL); + gpio_request(GPIO_FN_LCDD8, NULL); + gpio_request(GPIO_FN_LCDD7, NULL); + gpio_request(GPIO_FN_LCDD6, NULL); + gpio_request(GPIO_FN_LCDD5, NULL); + gpio_request(GPIO_FN_LCDD4, NULL); + gpio_request(GPIO_FN_LCDD3, NULL); + gpio_request(GPIO_FN_LCDD2, NULL); + gpio_request(GPIO_FN_LCDD1, NULL); + gpio_request(GPIO_FN_LCDD0, NULL); + gpio_request(GPIO_FN_LCDLCLK, NULL); + gpio_request(GPIO_FN_LCDDCK, NULL); + gpio_request(GPIO_FN_LCDVEPWC, NULL); + gpio_request(GPIO_FN_LCDVCPWC, NULL); + gpio_request(GPIO_FN_LCDVSYN, NULL); + gpio_request(GPIO_FN_LCDHSYN, NULL); + gpio_request(GPIO_FN_LCDDISP, NULL); + gpio_request(GPIO_FN_LCDDON, NULL); +#endif + + /* CEU */ + gpio_request(GPIO_FN_VIO_CLK2, NULL); + gpio_request(GPIO_FN_VIO_VD2, NULL); + gpio_request(GPIO_FN_VIO_HD2, NULL); + gpio_request(GPIO_FN_VIO_FLD, NULL); + gpio_request(GPIO_FN_VIO_CKO, NULL); + gpio_request(GPIO_FN_VIO_D15, NULL); + gpio_request(GPIO_FN_VIO_D14, NULL); + gpio_request(GPIO_FN_VIO_D13, NULL); + gpio_request(GPIO_FN_VIO_D12, NULL); + gpio_request(GPIO_FN_VIO_D11, NULL); + gpio_request(GPIO_FN_VIO_D10, NULL); + gpio_request(GPIO_FN_VIO_D9, NULL); + gpio_request(GPIO_FN_VIO_D8, NULL); + + gpio_request(GPIO_PTT3, NULL); /* VIO_RST */ + gpio_direction_output(GPIO_PTT3, 0); + gpio_request(GPIO_PTT2, NULL); /* TV_IN_EN */ + gpio_direction_output(GPIO_PTT2, 1); + gpio_request(GPIO_PTT0, NULL); /* CAM_EN */ +#ifdef CONFIG_SH_MIGOR_RTA_WVGA + gpio_direction_output(GPIO_PTT0, 0); +#else + gpio_direction_output(GPIO_PTT0, 1); +#endif + __raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */ + + platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20); + + /* SIU: Port B */ + gpio_request(GPIO_FN_SIUBOLR, NULL); + gpio_request(GPIO_FN_SIUBOBT, NULL); + gpio_request(GPIO_FN_SIUBISLD, NULL); + gpio_request(GPIO_FN_SIUBOSLD, NULL); + gpio_request(GPIO_FN_SIUMCKB, NULL); + + /* + * The original driver sets SIUB OLR/OBT, ILR/IBT, and SIUA OLR/OBT to + * output. Need only SIUB, set to output for master mode (table 34.2) + */ + __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA); + + i2c_register_board_info(0, migor_i2c_devices, + ARRAY_SIZE(migor_i2c_devices)); + + return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); +} +arch_initcall(migor_devices_setup); + +/* Return the board specific boot mode pin configuration */ +static int migor_mode_pins(void) +{ + /* MD0=1, MD1=1, MD2=0: Clock Mode 3 + * MD3=0: 16-bit Area0 Bus Width + * MD5=1: Little Endian + * TSTMD=1, MD8=0: Test Mode Disabled + */ + return MODE_PIN0 | MODE_PIN1 | MODE_PIN5; +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_migor __initmv = { + .mv_name = "Migo-R", + .mv_mode_pins = migor_mode_pins, +}; diff --git a/arch/sh/boards/mach-r2d/Kconfig b/arch/sh/boards/mach-r2d/Kconfig new file mode 100644 index 00000000000..8122a9667fc --- /dev/null +++ b/arch/sh/boards/mach-r2d/Kconfig @@ -0,0 +1,23 @@ +if SH_RTS7751R2D + +menu "RTS7751R2D Board Revision" + +config RTS7751R2D_PLUS + bool "R2D-PLUS" + help + Selecting this option will configure the kernel for R2D-PLUS. + + R2D-PLUS is the smaller of the two R2D board versions, equipped + with a single PCI slot. + +config RTS7751R2D_1 + bool "R2D-1" + help + Selecting this option will configure the kernel for R2D-1. + + R2D-1 is the larger of the two R2D board versions, equipped + with two PCI slots. +endmenu + +endif + diff --git a/arch/sh/boards/mach-r2d/Makefile b/arch/sh/boards/mach-r2d/Makefile new file mode 100644 index 00000000000..0d4c75a72be --- /dev/null +++ b/arch/sh/boards/mach-r2d/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the RTS7751R2D specific parts of the kernel +# + +obj-y := setup.o irq.o diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c new file mode 100644 index 00000000000..574f009c3c3 --- /dev/null +++ b/arch/sh/boards/mach-r2d/irq.c @@ -0,0 +1,155 @@ +/* + * linux/arch/sh/boards/renesas/rts7751r2d/irq.c + * + * Copyright (C) 2007 Magnus Damm + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales RTS7751R2D Support, R2D-PLUS and R2D-1. + * + * Modified for RTS7751R2D by + * Atom Create Engineering Co., Ltd. 2002. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <mach/r2d.h> + +#define R2D_NR_IRL 13 + +enum { + UNUSED = 0, + + /* board specific interrupt sources (R2D-1 and R2D-PLUS) */ + EXT, /* EXT_INT0-3 */ + RTC_T, RTC_A, /* Real Time Clock */ + AX88796, /* Ethernet controller (R2D-1 board) */ + KEY, /* Key input (R2D-PLUS board) */ + SDCARD, /* SD Card */ + CF_CD, CF_IDE, /* CF Card Detect + CF IDE */ + SM501, /* SM501 aka Voyager */ + PCI_INTD_RTL8139, /* Ethernet controller */ + PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */ + PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */ + PCI_INTB_SLOT, /* PCI Slot 3.3v (R2D-1 board) */ + PCI_INTA_SLOT, /* PCI Slot 3.3v */ + TP, /* Touch Panel */ +}; + +#ifdef CONFIG_RTS7751R2D_1 + +/* Vectors for R2D-1 */ +static struct intc_vect vectors_r2d_1[] __initdata = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */ + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-1 */ +static struct intc_mask_reg mask_registers_r2d_1[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_SLOT, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, AX88796, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-1 */ +static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1, + NULL, mask_registers_r2d_1, NULL, NULL); + +#endif /* CONFIG_RTS7751R2D_1 */ + +#ifdef CONFIG_RTS7751R2D_PLUS + +/* Vectors for R2D-PLUS */ +static struct intc_vect vectors_r2d_plus[] __initdata = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-PLUS */ +static struct intc_mask_reg mask_registers_r2d_plus[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, KEY, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-PLUS */ +static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus, + NULL, mask_registers_r2d_plus, NULL, NULL); + +#endif /* CONFIG_RTS7751R2D_PLUS */ + +static unsigned char irl2irq[R2D_NR_IRL]; + +int rts7751r2d_irq_demux(int irq) +{ + if (irq >= R2D_NR_IRL || irq < 0 || !irl2irq[irq]) + return irq; + + return irl2irq[irq]; +} + +/* + * Initialize IRQ setting + */ +void __init init_rts7751r2d_IRQ(void) +{ + struct intc_desc *d; + + switch (__raw_readw(PA_VERREG) & 0xf0) { +#ifdef CONFIG_RTS7751R2D_PLUS + case 0x10: + printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n"); + d = &intc_desc_r2d_plus; + memcpy(irl2irq, irl2irq_r2d_plus, R2D_NR_IRL); + break; +#endif +#ifdef CONFIG_RTS7751R2D_1 + case 0x00: /* according to manual */ + case 0x30: /* in reality */ + printk(KERN_INFO "Using R2D-1 interrupt controller.\n"); + d = &intc_desc_r2d_1; + memcpy(irl2irq, irl2irq_r2d_1, R2D_NR_IRL); + break; +#endif + default: + printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n", + __raw_readw(PA_VERREG)); + return; + } + + register_intc_controller(d); +} diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c new file mode 100644 index 00000000000..4b98a5251f8 --- /dev/null +++ b/arch/sh/boards/mach-r2d/setup.c @@ -0,0 +1,308 @@ +/* + * Renesas Technology Sales RTS7751R2D Support. + * + * Copyright (C) 2002 - 2006 Atom Create Engineering Co., Ltd. + * Copyright (C) 2004 - 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/ata_platform.h> +#include <linux/sm501.h> +#include <linux/sm501-regs.h> +#include <linux/pm.h> +#include <linux/fb.h> +#include <linux/spi/spi.h> +#include <linux/spi/spi_bitbang.h> +#include <asm/machvec.h> +#include <mach/r2d.h> +#include <asm/io.h> +#include <asm/io_trapped.h> +#include <asm/spi.h> + +static struct resource cf_ide_resources[] = { + [0] = { + .start = PA_AREA5_IO + 0x1000, + .end = PA_AREA5_IO + 0x1000 + 0x10 - 0x2, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PA_AREA5_IO + 0x80c, + .end = PA_AREA5_IO + 0x80c, + .flags = IORESOURCE_MEM, + }, +#ifndef CONFIG_RTS7751R2D_1 /* For R2D-1 polling is preferred */ + [2] = { + .start = IRQ_CF_IDE, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + +static struct pata_platform_info pata_info = { + .ioport_shift = 1, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, + .dev = { + .platform_data = &pata_info, + }, +}; + +static struct spi_board_info spi_bus[] = { + { + .modalias = "rtc-r9701", + .max_speed_hz = 1000000, + .mode = SPI_MODE_3, + }, +}; + +static void r2d_chip_select(struct sh_spi_info *spi, int cs, int state) +{ + BUG_ON(cs != 0); /* Single Epson RTC-9701JE attached on CS0 */ + __raw_writew(state == BITBANG_CS_ACTIVE, PA_RTCCE); +} + +static struct sh_spi_info spi_info = { + .num_chipselect = 1, + .chip_select = r2d_chip_select, +}; + +static struct resource spi_sh_sci_resources[] = { + { + .start = 0xffe00000, + .end = 0xffe0001f, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device spi_sh_sci_device = { + .name = "spi_sh_sci", + .id = -1, + .num_resources = ARRAY_SIZE(spi_sh_sci_resources), + .resource = spi_sh_sci_resources, + .dev = { + .platform_data = &spi_info, + }, +}; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_OUTPORT, + .end = PA_OUTPORT, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +static struct resource sm501_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x13e00000 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x13e00000, + .end = 0x13ffffff, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_VOYAGER, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fb_videomode sm501_default_mode = { + .pixclock = 35714, + .xres = 640, + .yres = 480, + .left_margin = 105, + .right_margin = 50, + .upper_margin = 35, + .lower_margin = 0, + .hsync_len = 96, + .vsync_len = 2, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +}; + +static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = { + .def_bpp = 16, + .def_mode = &sm501_default_mode, + .flags = SM501FB_FLAG_USE_INIT_MODE | + SM501FB_FLAG_USE_HWCURSOR | + SM501FB_FLAG_USE_HWACCEL | + SM501FB_FLAG_DISABLE_AT_EXIT, +}; + +static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = { + .flags = (SM501FB_FLAG_USE_INIT_MODE | + SM501FB_FLAG_USE_HWCURSOR | + SM501FB_FLAG_USE_HWACCEL | + SM501FB_FLAG_DISABLE_AT_EXIT), + +}; + +static struct sm501_platdata_fb sm501_fb_pdata = { + .fb_route = SM501_FB_OWN, + .fb_crt = &sm501_pdata_fbsub_crt, + .fb_pnl = &sm501_pdata_fbsub_pnl, + .flags = SM501_FBPD_SWAP_FB_ENDIAN, +}; + +static struct sm501_initdata sm501_initdata = { + .devices = SM501_USE_USB_HOST | SM501_USE_UART0, +}; + +static struct sm501_platdata sm501_platform_data = { + .init = &sm501_initdata, + .fb = &sm501_fb_pdata, +}; + +static struct platform_device sm501_device = { + .name = "sm501", + .id = -1, + .dev = { + .platform_data = &sm501_platform_data, + }, + .num_resources = ARRAY_SIZE(sm501_resources), + .resource = sm501_resources, +}; + +static struct mtd_partition r2d_partitions[] = { + { + .name = "U-Boot", + .offset = 0x00000000, + .size = 0x00040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Environment", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x00040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x001c0000, + }, { + .name = "Flash_FS", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data flash_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(r2d_partitions), + .parts = r2d_partitions, +}; + +static struct resource flash_resource = { + .start = 0x00000000, + .end = 0x02000000, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = &flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &flash_data, + }, +}; + +static struct platform_device *rts7751r2d_devices[] __initdata = { + &sm501_device, + &heartbeat_device, + &spi_sh_sci_device, +}; + +/* + * The CF is connected with a 16-bit bus where 8-bit operations are + * unsupported. The linux ata driver is however using 8-bit operations, so + * insert a trapped io filter to convert 8-bit operations into 16-bit. + */ +static struct trapped_io cf_trapped_io = { + .resource = cf_ide_resources, + .num_resources = 2, + .minimum_bus_width = 16, +}; + +static int __init rts7751r2d_devices_setup(void) +{ + if (register_trapped_io(&cf_trapped_io) == 0) + platform_device_register(&cf_ide_device); + + if (mach_is_r2d_plus()) + platform_device_register(&flash_device); + + spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); + + return platform_add_devices(rts7751r2d_devices, + ARRAY_SIZE(rts7751r2d_devices)); +} +device_initcall(rts7751r2d_devices_setup); + +static void rts7751r2d_power_off(void) +{ + __raw_writew(0x0001, PA_POWOFF); +} + +/* + * Initialize the board + */ +static void __init rts7751r2d_setup(char **cmdline_p) +{ + void __iomem *sm501_reg; + u16 ver = __raw_readw(PA_VERREG); + + printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); + + printk(KERN_INFO "FPGA version:%d (revision:%d)\n", + (ver >> 4) & 0xf, ver & 0xf); + + __raw_writew(0x0000, PA_OUTPORT); + pm_power_off = rts7751r2d_power_off; + + /* sm501 dram configuration: + * ColSizeX = 11 - External Memory Column Size: 256 words. + * APX = 1 - External Memory Active to Pre-Charge Delay: 7 clocks. + * RstX = 1 - External Memory Reset: Normal. + * Rfsh = 1 - Local Memory Refresh to Command Delay: 12 clocks. + * BwC = 1 - Local Memory Block Write Cycle Time: 2 clocks. + * BwP = 1 - Local Memory Block Write to Pre-Charge Delay: 1 clock. + * AP = 1 - Internal Memory Active to Pre-Charge Delay: 7 clocks. + * Rst = 1 - Internal Memory Reset: Normal. + * RA = 1 - Internal Memory Remain in Active State: Do not remain. + */ + + sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL; + writel(readl(sm501_reg) | 0x00f107c0, sm501_reg); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_rts7751r2d __initmv = { + .mv_name = "RTS7751R2D", + .mv_setup = rts7751r2d_setup, + .mv_init_irq = init_rts7751r2d_IRQ, + .mv_irq_demux = rts7751r2d_irq_demux, +}; diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig new file mode 100644 index 00000000000..aeff3b04220 --- /dev/null +++ b/arch/sh/boards/mach-rsk/Kconfig @@ -0,0 +1,18 @@ +if SH_RSK + +choice + prompt "RSK+ options" + default SH_RSK7203 + +config SH_RSK7201 + bool "RSK7201" + depends on CPU_SUBTYPE_SH7201 + +config SH_RSK7203 + bool "RSK7203" + select ARCH_REQUIRE_GPIOLIB + depends on CPU_SUBTYPE_SH7203 + +endchoice + +endif diff --git a/arch/sh/boards/mach-rsk/Makefile b/arch/sh/boards/mach-rsk/Makefile new file mode 100644 index 00000000000..498da75ce38 --- /dev/null +++ b/arch/sh/boards/mach-rsk/Makefile @@ -0,0 +1,2 @@ +obj-y := setup.o +obj-$(CONFIG_SH_RSK7203) += devices-rsk7203.o diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c new file mode 100644 index 00000000000..a8089f79d05 --- /dev/null +++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c @@ -0,0 +1,140 @@ +/* + * Renesas Technology Europe RSK+ 7203 Support. + * + * Copyright (C) 2008 - 2010 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/smsc911x.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/leds.h> +#include <asm/machvec.h> +#include <asm/io.h> +#include <cpu/sh7203.h> + +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT | SMSC911X_SWAP_FIFO, +}; + +static struct resource smsc911x_resources[] = { + [0] = { + .start = 0x24000000, + .end = 0x240000ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 64, + .end = 64, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static struct gpio_led rsk7203_gpio_leds[] = { + { + .name = "green", + .gpio = GPIO_PE10, + .active_low = 1, + }, { + .name = "orange", + .default_trigger = "nand-disk", + .gpio = GPIO_PE12, + .active_low = 1, + }, { + .name = "red:timer", + .default_trigger = "timer", + .gpio = GPIO_PC14, + .active_low = 1, + }, { + .name = "red:heartbeat", + .default_trigger = "heartbeat", + .gpio = GPIO_PE11, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data rsk7203_gpio_leds_info = { + .leds = rsk7203_gpio_leds, + .num_leds = ARRAY_SIZE(rsk7203_gpio_leds), +}; + +static struct platform_device led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &rsk7203_gpio_leds_info, + }, +}; + +static struct gpio_keys_button rsk7203_gpio_keys_table[] = { + { + .code = BTN_0, + .gpio = GPIO_PB0, + .active_low = 1, + .desc = "SW1", + }, { + .code = BTN_1, + .gpio = GPIO_PB1, + .active_low = 1, + .desc = "SW2", + }, { + .code = BTN_2, + .gpio = GPIO_PB2, + .active_low = 1, + .desc = "SW3", + }, +}; + +static struct gpio_keys_platform_data rsk7203_gpio_keys_info = { + .buttons = rsk7203_gpio_keys_table, + .nbuttons = ARRAY_SIZE(rsk7203_gpio_keys_table), + .poll_interval = 50, /* default to 50ms */ +}; + +static struct platform_device keys_device = { + .name = "gpio-keys-polled", + .dev = { + .platform_data = &rsk7203_gpio_keys_info, + }, +}; + +static struct platform_device *rsk7203_devices[] __initdata = { + &smsc911x_device, + &led_device, + &keys_device, +}; + +static int __init rsk7203_devices_setup(void) +{ + /* Select pins for SCIF0 */ + gpio_request(GPIO_FN_TXD0, NULL); + gpio_request(GPIO_FN_RXD0, NULL); + + /* Setup LAN9118: CS1 in 16-bit Big Endian Mode, IRQ0 at Port B */ + __raw_writel(0x36db0400, 0xfffc0008); /* CS1BCR */ + gpio_request(GPIO_FN_IRQ0_PB, NULL); + + return platform_add_devices(rsk7203_devices, + ARRAY_SIZE(rsk7203_devices)); +} +device_initcall(rsk7203_devices_setup); diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c new file mode 100644 index 00000000000..895f030070d --- /dev/null +++ b/arch/sh/boards/mach-rsk/setup.c @@ -0,0 +1,80 @@ +/* + * Renesas Technology Europe RSK+ Support. + * + * Copyright (C) 2008 Paul Mundt + * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/map.h> +#include <asm/machvec.h> +#include <asm/io.h> + +static const char *part_probes[] = { "cmdlinepart", NULL }; + +static struct mtd_partition rsk_partitions[] = { + { + .name = "Bootloader", + .offset = 0x00000000, + .size = 0x00040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x001c0000, + }, { + .name = "Flash_FS", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data flash_data = { + .parts = rsk_partitions, + .nr_parts = ARRAY_SIZE(rsk_partitions), + .width = 2, + .part_probe_types = part_probes, +}; + +static struct resource flash_resource = { + .start = 0x20000000, + .end = 0x20400000, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = &flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &flash_data, + }, +}; + +static struct platform_device *rsk_devices[] __initdata = { + &flash_device, +}; + +static int __init rsk_devices_setup(void) +{ + return platform_add_devices(rsk_devices, + ARRAY_SIZE(rsk_devices)); +} +device_initcall(rsk_devices_setup); + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_rsk __initmv = { + .mv_name = "RSK+", +}; diff --git a/arch/sh/boards/mach-sdk7780/Kconfig b/arch/sh/boards/mach-sdk7780/Kconfig new file mode 100644 index 00000000000..065f1df09bf --- /dev/null +++ b/arch/sh/boards/mach-sdk7780/Kconfig @@ -0,0 +1,16 @@ +if SH_SDK7780 + +choice + prompt "SDK7780 options" + default SH_SDK7780_BASE + +config SH_SDK7780_BASE + bool "SDK7780 with base-board support" + depends on CPU_SUBTYPE_SH7780 + help + Selecting this option will enable support for the expansion + baseboard devices. If in doubt, say Y. + +endchoice + +endif diff --git a/arch/sh/boards/mach-sdk7780/Makefile b/arch/sh/boards/mach-sdk7780/Makefile new file mode 100644 index 00000000000..3d8f0befc35 --- /dev/null +++ b/arch/sh/boards/mach-sdk7780/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the SDK7780 specific parts of the kernel +# +obj-y := setup.o irq.o + diff --git a/arch/sh/boards/mach-sdk7780/irq.c b/arch/sh/boards/mach-sdk7780/irq.c new file mode 100644 index 00000000000..e5f7564f251 --- /dev/null +++ b/arch/sh/boards/mach-sdk7780/irq.c @@ -0,0 +1,46 @@ +/* + * linux/arch/sh/boards/renesas/sdk7780/irq.c + * + * Renesas Technology Europe SDK7780 Support. + * + * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/sdk7780.h> + +enum { + UNUSED = 0, + /* board specific interrupt sources */ + SMC91C111, /* Ethernet controller */ +}; + +static struct intc_vect fpga_vectors[] __initdata = { + INTC_IRQ(SMC91C111, IRQ_ETHERNET), +}; + +static struct intc_mask_reg fpga_mask_registers[] __initdata = { + { 0, FPGA_IRQ0MR, 16, + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, SMC91C111, 0, 0, 0, 0 } }, +}; + +static DECLARE_INTC_DESC(fpga_intc_desc, "sdk7780-irq", fpga_vectors, + NULL, fpga_mask_registers, NULL, NULL); + +void __init init_sdk7780_IRQ(void) +{ + printk(KERN_INFO "Using SDK7780 interrupt controller.\n"); + + __raw_writew(0xFFFF, FPGA_IRQ0MR); + /* Setup IRL 0-3 */ + __raw_writew(0x0003, FPGA_IMSR); + plat_irq_setup_pins(IRQ_MODE_IRL3210); + + register_intc_controller(&fpga_intc_desc); +} diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c new file mode 100644 index 00000000000..4da38db4b5f --- /dev/null +++ b/arch/sh/boards/mach-sdk7780/setup.c @@ -0,0 +1,100 @@ +/* + * arch/sh/boards/renesas/sdk7780/setup.c + * + * Renesas Solutions SH7780 SDK Support + * Copyright (C) 2008 Nicholas Beck <nbeck@mpc-data.co.uk> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <asm/machvec.h> +#include <mach/sdk7780.h> +#include <asm/heartbeat.h> +#include <asm/io.h> +#include <asm/addrspace.h> + +#define GPIO_PECR 0xFFEA0008 + +/* Heartbeat */ +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +/* SMC91x */ +static struct resource smc91x_eth_resources[] = { + [0] = { + .name = "smc91x-regs" , + .start = PA_LAN + 0x300, + .end = PA_LAN + 0x300 + 0x10 , + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_ETHERNET, + .end = IRQ_ETHERNET, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_eth_device = { + .name = "smc91x", + .id = 0, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(smc91x_eth_resources), + .resource = smc91x_eth_resources, +}; + +static struct platform_device *sdk7780_devices[] __initdata = { + &heartbeat_device, + &smc91x_eth_device, +}; + +static int __init sdk7780_devices_setup(void) +{ + return platform_add_devices(sdk7780_devices, + ARRAY_SIZE(sdk7780_devices)); +} +device_initcall(sdk7780_devices_setup); + +static void __init sdk7780_setup(char **cmdline_p) +{ + u16 ver = __raw_readw(FPGA_FPVERR); + u16 dateStamp = __raw_readw(FPGA_FPDATER); + + printk(KERN_INFO "Renesas Technology Europe SDK7780 support.\n"); + printk(KERN_INFO "Board version: %d (revision %d), " + "FPGA version: %d (revision %d), datestamp : %d\n", + (ver >> 12) & 0xf, (ver >> 8) & 0xf, + (ver >> 4) & 0xf, ver & 0xf, + dateStamp); + + /* Setup pin mux'ing for PCIC */ + __raw_writew(0x0000, GPIO_PECR); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_se7780 __initmv = { + .mv_name = "Renesas SDK7780-R3" , + .mv_setup = sdk7780_setup, + .mv_nr_irqs = 111, + .mv_init_irq = init_sdk7780_IRQ, +}; + diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile new file mode 100644 index 00000000000..8ae56e9560a --- /dev/null +++ b/arch/sh/boards/mach-sdk7786/Makefile @@ - |